Updating branches/google/testing to r297704

git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/testing@298143 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 422beda..a095d2b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,7 +16,8 @@
       "--libdir"
       "--includedir"
       "--prefix"
-      "--src-root")
+      "--src-root"
+      "--cmakedir")
     execute_process(
       COMMAND ${CONFIG_COMMAND}
       RESULT_VARIABLE HAD_ERROR
@@ -41,6 +42,7 @@
   list(GET CONFIG_OUTPUT 3 INCLUDE_DIR)
   list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT)
   list(GET CONFIG_OUTPUT 5 MAIN_SRC_DIR)
+  list(GET CONFIG_OUTPUT 6 LLVM_CONFIG_CMAKE_PATH)
 
   if(NOT MSVC_IDE)
     set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS}
@@ -55,10 +57,13 @@
   set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree")
   set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")
 
+  # Normalize LLVM_CMAKE_PATH. --cmakedir might contain backslashes.
+  # CMake assumes slashes as PATH.
+  file(TO_CMAKE_PATH ${LLVM_CONFIG_CMAKE_PATH} LLVM_CMAKE_PATH)
+
   find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR}
     NO_DEFAULT_PATH)
 
-  set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
   set(LLVMCONFIG_FILE "${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
   if(EXISTS ${LLVMCONFIG_FILE})
     list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
@@ -77,6 +82,7 @@
     set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
   endif()
 
+  option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
   option(LLVM_INSTALL_TOOLCHAIN_ONLY
     "Only include toolchain files in the 'install' target." OFF)
 
@@ -198,6 +204,9 @@
 set(ENABLE_X86_RELAX_RELOCATIONS OFF CACHE BOOL
     "enable x86 relax relocations by default")
 
+set(CLANG_DEFAULT_LINKER "" CACHE STRING
+  "Default linker to use (linker name or absolute path, empty for platform default)")
+
 set(CLANG_DEFAULT_CXX_STDLIB "" CACHE STRING
   "Default C++ stdlib to use (\"libstdc++\" or \"libc++\", empty for platform default")
 if (NOT(CLANG_DEFAULT_CXX_STDLIB STREQUAL "" OR
@@ -360,18 +369,7 @@
   "Build the Clang tools. If OFF, just generate build targets." ON)
 
 option(CLANG_ENABLE_ARCMT "Build ARCMT." ON)
-if (CLANG_ENABLE_ARCMT)
-  set(ENABLE_CLANG_ARCMT "1")
-else()
-  set(ENABLE_CLANG_ARCMT "0")
-endif()
-
 option(CLANG_ENABLE_STATIC_ANALYZER "Build static analyzer." ON)
-if (CLANG_ENABLE_STATIC_ANALYZER)
-  set(ENABLE_CLANG_STATIC_ANALYZER "1")
-else()
-  set(ENABLE_CLANG_STATIC_ANALYZER "0")
-endif()
 
 if (NOT CLANG_ENABLE_STATIC_ANALYZER AND CLANG_ENABLE_ARCMT)
   message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT")
@@ -411,13 +409,31 @@
 add_subdirectory(runtime)
 
 option(CLANG_BUILD_EXAMPLES "Build CLANG example programs by default." OFF)
-if (CLANG_BUILD_EXAMPLES)
-  set(ENABLE_CLANG_EXAMPLES "1")
-else()
-  set(ENABLE_CLANG_EXAMPLES "0")
-endif()
 add_subdirectory(examples)
 
+if(APPLE)
+  # this line is needed as a cleanup to ensure that any CMakeCaches with the old
+  # default value get updated to the new default.
+  if(CLANG_ORDER_FILE STREQUAL "")
+    unset(CLANG_ORDER_FILE CACHE)
+    unset(CLANG_ORDER_FILE)
+  endif()
+
+
+  set(CLANG_ORDER_FILE ${CMAKE_CURRENT_BINARY_DIR}/clang.order CACHE FILEPATH
+    "Order file to use when compiling clang in order to improve startup time (Darwin Only - requires ld64).")
+
+  if(NOT EXISTS ${CLANG_ORDER_FILE})
+    string(FIND "${CLANG_ORDER_FILE}" "${CMAKE_CURRENT_BINARY_DIR}" PATH_START)
+    if(PATH_START EQUAL 0)
+      file(WRITE ${CLANG_ORDER_FILE} "\n")
+    else()
+      message(FATAL_ERROR "Specified order file '${CLANG_ORDER_FILE}' does not exist.")
+    endif()
+  endif()
+endif()
+
+
 if( CLANG_INCLUDE_TESTS )
   if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include/gtest/gtest.h)
     add_subdirectory(unittests)
@@ -452,29 +468,6 @@
   add_subdirectory(docs)
 endif()
 
-
-if(APPLE)
-  # this line is needed as a cleanup to ensure that any CMakeCaches with the old
-  # default value get updated to the new default.
-  if(CLANG_ORDER_FILE STREQUAL "")
-    unset(CLANG_ORDER_FILE CACHE)
-    unset(CLANG_ORDER_FILE)
-  endif()
-
-
-  set(CLANG_ORDER_FILE ${CMAKE_CURRENT_BINARY_DIR}/clang.order CACHE FILEPATH
-    "Order file to use when compiling clang in order to improve startup time (Darwin Only - requires ld64).")
-
-  if(CLANG_ORDER_FILE AND NOT EXISTS ${CLANG_ORDER_FILE})
-    string(FIND "${CLANG_ORDER_FILE}" "${CMAKE_CURRENT_BINARY_DIR}" PATH_START)
-    if(PATH_START EQUAL 0)
-      file(WRITE ${CLANG_ORDER_FILE} "\n")
-    else()
-      message(FATAL_ERROR "Specified order file '${CLANG_ORDER_FILE}' does not exist.")
-    endif()
-  endif()
-endif()
-
 add_subdirectory(cmake/modules)
 
 if(CLANG_STAGE)
@@ -511,6 +504,10 @@
   set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-stamps/)
   set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-bins/)
 
+  if(BOOTSTRAP_LLVM_ENABLE_LLD)
+    add_dependencies(clang-bootstrap-deps lld)
+  endif()
+
   # If the next stage is LTO we need to depend on LTO and possibly lld or LLVMgold
   if(BOOTSTRAP_LLVM_ENABLE_LTO OR LLVM_ENABLE_LTO AND NOT LLVM_BUILD_INSTRUMENTED)
     if(APPLE)
@@ -527,9 +524,7 @@
         -DDYLD_LIBRARY_PATH=${LLVM_LIBRARY_OUTPUT_INTDIR})
     elseif(NOT WIN32)
       add_dependencies(clang-bootstrap-deps llvm-ar llvm-ranlib)
-      if(BOOTSTRAP_LLVM_ENABLE_LLD)
-        add_dependencies(clang-bootstrap-deps lld)
-      elseif(LLVM_BINUTILS_INCDIR)
+      if(NOT BOOTSTRAP_LLVM_ENABLE_LLD AND LLVM_BINUTILS_INCDIR)
         add_dependencies(clang-bootstrap-deps LLVMgold)
       endif()
       set(LTO_AR -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar)
diff --git a/bindings/python/clang/__init__.py b/bindings/python/clang/__init__.py
index 88f3081..fba49e3 100644
--- a/bindings/python/clang/__init__.py
+++ b/bindings/python/clang/__init__.py
@@ -20,5 +20,13 @@
     Bindings for the Clang indexing library.
 """
 
+
+# Python 3 uses unicode for strings. The bindings, in particular the interaction
+# with ctypes, need modifying to handle conversions between unicode and
+# c-strings.
+import sys 
+if sys.version_info[0] != 2: 
+    raise Exception("Only Python 2 is supported.")
+
 __all__ = ['cindex']
 
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index c22d251..48fc8b1 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -64,7 +64,6 @@
 
 from ctypes import *
 import collections
-import sys
 
 import clang.enumerations
 
@@ -74,33 +73,6 @@
 # this by marshalling object arguments as void**.
 c_object_p = POINTER(c_void_p)
 
-if sys.version_info[0] > 2:
-# Python 3 strings are unicode, translate them to/from utf8 for C-interop
-# Python 3 replaces xrange with range, we want xrange behaviour
-    xrange = range
-
-    class c_string_p(c_char_p):
-        def __init__(self, p=None):
-            if type(p) == str:
-                p = p.encode("utf8")
-            super(c_char_p, self).__init__(p)
-
-        def __str__(self):
-            return str(self.value)
-
-        @property
-        def value(self):
-            if super(c_char_p, self).value is None:
-                return None
-            return super(c_char_p, self).value.decode("utf8")
-
-        @classmethod
-        def from_param(cls, param):
-                return cls(param)
-else:
-    c_string_p = c_char_p
-
-
 callbacks = {}
 
 ### Exception Classes ###
@@ -175,7 +147,7 @@
 class _CXString(Structure):
     """Helper for transforming CXString results."""
 
-    _fields_ = [("spelling", c_string_p), ("free", c_int)]
+    _fields_ = [("spelling", c_char_p), ("free", c_int)]
 
     def __del__(self):
         conf.lib.clang_disposeString(self)
@@ -357,7 +329,7 @@
 
     @property
     def spelling(self):
-        return str(conf.lib.clang_getDiagnosticSpelling(self))
+        return conf.lib.clang_getDiagnosticSpelling(self)
 
     @property
     def ranges(self):
@@ -386,8 +358,8 @@
 
             def __getitem__(self, key):
                 range = SourceRange()
-                value = str(conf.lib.clang_getDiagnosticFixIt(self.diag, key,
-                        byref(range)))
+                value = conf.lib.clang_getDiagnosticFixIt(self.diag, key,
+                        byref(range))
                 if len(value) == 0:
                     raise IndexError
 
@@ -420,12 +392,12 @@
     @property
     def category_name(self):
         """The string name of the category for this diagnostic."""
-        return str(conf.lib.clang_getDiagnosticCategoryText(self))
+        return conf.lib.clang_getDiagnosticCategoryText(self)
 
     @property
     def option(self):
         """The command-line option that enables this diagnostic."""
-        return str(conf.lib.clang_getDiagnosticOption(self, None))
+        return conf.lib.clang_getDiagnosticOption(self, None)
 
     @property
     def disable_option(self):
@@ -433,7 +405,7 @@
         disable = _CXString()
         conf.lib.clang_getDiagnosticOption(self, byref(disable))
 
-        return str(conf.lib.clang_getCString(disable))
+        return conf.lib.clang_getCString(disable)
 
     def format(self, options=None):
         """
@@ -600,7 +572,7 @@
             for key, value in self.__class__.__dict__.items():
                 if isinstance(value, self.__class__):
                     self._name_map[value] = key
-        return str(self._name_map[self])
+        return self._name_map[self]
 
     @classmethod
     def from_id(cls, id):
@@ -624,7 +596,7 @@
     @staticmethod
     def get_all_kinds():
         """Return all CursorKind enumeration instances."""
-        return [x for x in CursorKind._kinds if x]
+        return filter(None, CursorKind._kinds)
 
     def is_declaration(self):
         """Test if this is a declaration kind."""
@@ -1457,9 +1429,9 @@
     def spelling(self):
         """Return the spelling of the entity pointed at by the cursor."""
         if not hasattr(self, '_spelling'):
-            self._spelling = str(conf.lib.clang_getCursorSpelling(self))
+            self._spelling = conf.lib.clang_getCursorSpelling(self)
 
-        return str(self._spelling)
+        return self._spelling
 
     @property
     def displayname(self):
@@ -1471,7 +1443,7 @@
         arguments of a class template specialization.
         """
         if not hasattr(self, '_displayname'):
-            self._displayname = str(conf.lib.clang_getCursorDisplayName(self))
+            self._displayname = conf.lib.clang_getCursorDisplayName(self)
 
         return self._displayname
 
@@ -1479,7 +1451,7 @@
     def mangled_name(self):
         """Return the mangled name for the entity referenced by this cursor."""
         if not hasattr(self, '_mangled_name'):
-            self._mangled_name = str(conf.lib.clang_Cursor_getMangling(self))
+            self._mangled_name = conf.lib.clang_Cursor_getMangling(self)
 
         return self._mangled_name
 
@@ -1618,7 +1590,7 @@
             self._objc_type_encoding = \
               conf.lib.clang_getDeclObjCTypeEncoding(self)
 
-        return str(self._objc_type_encoding)
+        return self._objc_type_encoding
 
     @property
     def hash(self):
@@ -1665,23 +1637,17 @@
     @property
     def brief_comment(self):
         """Returns the brief comment text associated with that Cursor"""
-        r = conf.lib.clang_Cursor_getBriefCommentText(self)
-        if not r:
-            return None    
-        return str(r)
+        return conf.lib.clang_Cursor_getBriefCommentText(self)
 
     @property
     def raw_comment(self):
         """Returns the raw comment text associated with that Cursor"""
-        r = conf.lib.clang_Cursor_getRawCommentText(self)
-        if not r:
-            return None
-        return str(r)
+        return conf.lib.clang_Cursor_getRawCommentText(self)
 
     def get_arguments(self):
         """Return an iterator for accessing the arguments of this cursor."""
         num_args = conf.lib.clang_Cursor_getNumArguments(self)
-        for i in xrange(0, num_args):
+        for i in range(0, num_args):
             yield conf.lib.clang_Cursor_getArgument(self, i)
 
     def get_num_template_arguments(self):
@@ -1885,7 +1851,7 @@
     @property
     def spelling(self):
         """Retrieve the spelling of this TypeKind."""
-        return str(conf.lib.clang_getTypeKindSpelling(self.value))
+        return conf.lib.clang_getTypeKindSpelling(self.value)
 
     def __repr__(self):
         return 'TypeKind.%s' % (self.name,)
@@ -1921,6 +1887,7 @@
 TypeKind.OBJCCLASS = TypeKind(28)
 TypeKind.OBJCSEL = TypeKind(29)
 TypeKind.FLOAT128 = TypeKind(30)
+TypeKind.HALF = TypeKind(31)
 TypeKind.COMPLEX = TypeKind(100)
 TypeKind.POINTER = TypeKind(101)
 TypeKind.BLOCKPOINTER = TypeKind(102)
@@ -2161,7 +2128,7 @@
         """
         Retrieve the offset of a field in the record.
         """
-        return conf.lib.clang_Type_getOffsetOf(self, fieldname)
+        return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname))
 
     def get_ref_qualifier(self):
         """
@@ -2188,7 +2155,7 @@
     @property
     def spelling(self):
         """Retrieve the spelling of this Type."""
-        return str(conf.lib.clang_getTypeSpelling(self))
+        return conf.lib.clang_getTypeSpelling(self)
 
     def __eq__(self, other):
         if type(other) != type(self):
@@ -2220,7 +2187,7 @@
 
 class _CXUnsavedFile(Structure):
     """Helper for passing unsaved file arguments."""
-    _fields_ = [("name", c_string_p), ("contents", c_string_p), ('length', c_ulong)]
+    _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
 
 # Functions calls through the python interface are rather slow. Fortunately,
 # for most symboles, we do not need to perform a function call. Their spelling
@@ -2266,7 +2233,7 @@
         self.__kindNumberCache = -1
 
     def __repr__(self):
-        return "{'" + str(self.spelling) + "', " + str(self.kind) + "}"
+        return "{'" + self.spelling + "', " + str(self.kind) + "}"
 
     @CachedProperty
     def spelling(self):
@@ -2575,9 +2542,7 @@
 
         args_array = None
         if len(args) > 0:
-            args_array = (c_string_p * len(args))()
-            for i,a in enumerate(args):
-                args_array[i] = c_string_p(a)
+            args_array = (c_char_p * len(args))(* args)
 
         unsaved_array = None
         if len(unsaved_files) > 0:
@@ -2586,8 +2551,8 @@
                 if hasattr(contents, "read"):
                     contents = contents.read()
 
-                unsaved_array[i].name = c_string_p(name)
-                unsaved_array[i].contents = c_string_p(contents)
+                unsaved_array[i].name = name
+                unsaved_array[i].contents = contents
                 unsaved_array[i].length = len(contents)
 
         ptr = conf.lib.clang_parseTranslationUnit(index, filename, args_array,
@@ -2642,7 +2607,7 @@
     @property
     def spelling(self):
         """Get the original translation unit source file name."""
-        return str(conf.lib.clang_getTranslationUnitSpelling(self))
+        return conf.lib.clang_getTranslationUnitSpelling(self)
 
     def get_includes(self):
         """
@@ -2832,8 +2797,8 @@
                     print(value)
                 if not isinstance(value, str):
                     raise TypeError('Unexpected unsaved file contents.')
-                unsaved_files_array[i].name = c_string_p(name)
-                unsaved_files_array[i].contents = c_string_p(value)
+                unsaved_files_array[i].name = name
+                unsaved_files_array[i].contents = value
                 unsaved_files_array[i].length = len(value)
         ptr = conf.lib.clang_codeCompleteAt(self, path, line, column,
                 unsaved_files_array, len(unsaved_files), options)
@@ -2868,7 +2833,7 @@
     @property
     def name(self):
         """Return the complete file and path name of the file."""
-        return str(conf.lib.clang_getCString(conf.lib.clang_getFileName(self)))
+        return conf.lib.clang_getCString(conf.lib.clang_getFileName(self))
 
     @property
     def time(self):
@@ -2876,7 +2841,7 @@
         return conf.lib.clang_getFileTime(self)
 
     def __str__(self):
-        return str(self.name)
+        return self.name
 
     def __repr__(self):
         return "<File: %s>" % (self.name)
@@ -2945,12 +2910,12 @@
     @property
     def directory(self):
         """Get the working directory for this CompileCommand"""
-        return str(conf.lib.clang_CompileCommand_getDirectory(self.cmd))
+        return conf.lib.clang_CompileCommand_getDirectory(self.cmd)
 
     @property
     def filename(self):
         """Get the working filename for this CompileCommand"""
-        return str(conf.lib.clang_CompileCommand_getFilename(self.cmd))
+        return conf.lib.clang_CompileCommand_getFilename(self.cmd)
 
     @property
     def arguments(self):
@@ -2962,7 +2927,7 @@
         """
         length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd)
         for i in xrange(length):
-            yield str(conf.lib.clang_CompileCommand_getArg(self.cmd, i))
+            yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
 
 class CompileCommands(object):
     """
@@ -3056,7 +3021,7 @@
 
         This is the textual representation of the token in source.
         """
-        return str(conf.lib.clang_getTokenSpelling(self._tu, self))
+        return conf.lib.clang_getTokenSpelling(self._tu, self)
 
     @property
     def kind(self):
@@ -3099,7 +3064,7 @@
    [c_object_p]),
 
   ("clang_CompilationDatabase_fromDirectory",
-   [c_string_p, POINTER(c_uint)],
+   [c_char_p, POINTER(c_uint)],
    c_object_p,
    CompilationDatabase.from_result),
 
@@ -3109,7 +3074,7 @@
    CompileCommands.from_result),
 
   ("clang_CompilationDatabase_getCompileCommands",
-   [c_object_p, c_string_p],
+   [c_object_p, c_char_p],
    c_object_p,
    CompileCommands.from_result),
 
@@ -3144,7 +3109,7 @@
    c_uint),
 
   ("clang_codeCompleteAt",
-   [TranslationUnit, c_string_p, c_int, c_int, c_void_p, c_int, c_int],
+   [TranslationUnit, c_char_p, c_int, c_int, c_void_p, c_int, c_int],
    POINTER(CCRStructure)),
 
   ("clang_codeCompleteGetDiagnostic",
@@ -3160,7 +3125,7 @@
    c_object_p),
 
   ("clang_createTranslationUnit",
-   [Index, c_string_p],
+   [Index, c_char_p],
    c_object_p),
 
   ("clang_CXXConstructor_isConvertingConstructor",
@@ -3310,7 +3275,7 @@
 
   ("clang_getCString",
    [_CXString],
-   c_string_p),
+   c_char_p),
 
   ("clang_getCursor",
    [TranslationUnit, SourceLocation],
@@ -3457,7 +3422,7 @@
    Type.from_result),
 
   ("clang_getFile",
-   [TranslationUnit, c_string_p],
+   [TranslationUnit, c_char_p],
    c_object_p),
 
   ("clang_getFileName",
@@ -3586,7 +3551,7 @@
 
   ("clang_getTUResourceUsageName",
    [c_uint],
-   c_string_p),
+   c_char_p),
 
   ("clang_getTypeDeclaration",
    [Type],
@@ -3681,7 +3646,7 @@
    bool),
 
   ("clang_parseTranslationUnit",
-   [Index, c_string_p, c_void_p, c_int, c_void_p, c_int, c_int],
+   [Index, c_char_p, c_void_p, c_int, c_void_p, c_int, c_int],
    c_object_p),
 
   ("clang_reparseTranslationUnit",
@@ -3689,7 +3654,7 @@
    c_int),
 
   ("clang_saveTranslationUnit",
-   [TranslationUnit, c_string_p, c_uint],
+   [TranslationUnit, c_char_p, c_uint],
    c_int),
 
   ("clang_tokenize",
@@ -3761,7 +3726,7 @@
    Type.from_result),
 
   ("clang_Type_getOffsetOf",
-   [Type, c_string_p],
+   [Type, c_char_p],
    c_longlong),
 
   ("clang_Type_getSizeOf",
@@ -3820,8 +3785,7 @@
     def register(item):
         return register_function(lib, item, ignore_errors)
 
-    for f in functionList:
-        register(f)
+    map(register, functionList)
 
 class Config:
     library_path = None
diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py
index f959cf4..be6cd67 100644
--- a/bindings/python/tests/cindex/test_translation_unit.py
+++ b/bindings/python/tests/cindex/test_translation_unit.py
@@ -59,13 +59,9 @@
     assert spellings[-1] == 'y'
 
 def test_unsaved_files_2():
-    try:
-        from StringIO import StringIO
-    except:
-        from io import StringIO
-
+    import StringIO
     tu = TranslationUnit.from_source('fake.c', unsaved_files = [
-            ('fake.c', StringIO('int x;'))])
+            ('fake.c', StringIO.StringIO('int x;'))])
     spellings = [c.spelling for c in tu.cursor.get_children()]
     assert spellings[-1] == 'x'
 
diff --git a/cmake/caches/Apple-stage2-ThinLTO.cmake b/cmake/caches/Apple-stage2-ThinLTO.cmake
new file mode 100644
index 0000000..54e54e3
--- /dev/null
+++ b/cmake/caches/Apple-stage2-ThinLTO.cmake
@@ -0,0 +1,6 @@
+# This file sets up a CMakeCache for Apple-style stage2 ThinLTO bootstrap. It is
+# specified by the stage1 build.
+
+
+set(LLVM_ENABLE_LTO THIN CACHE BOOL "")
+include(${CMAKE_CURRENT_LIST_DIR}/Apple-stage2.cmake)
diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake
new file mode 100644
index 0000000..dcbeae8
--- /dev/null
+++ b/cmake/caches/Fuchsia-stage2.cmake
@@ -0,0 +1,62 @@
+# This file sets up a CMakeCache for the second stage of a Fuchsia toolchain
+# build.
+
+set(LLVM_TARGETS_TO_BUILD X86;AArch64 CACHE STRING "")
+
+set(PACKAGE_VENDOR Fuchsia CACHE STRING "")
+
+set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "")
+set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "")
+set(LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD OFF CACHE BOOL "")
+set(LLVM_ENABLE_ZLIB ON CACHE BOOL "")
+set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "")
+set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "")
+set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
+
+set(LLVM_ENABLE_LTO ON CACHE BOOL "")
+if(NOT APPLE)
+  set(LLVM_ENABLE_LLD ON CACHE BOOL "")
+  set(CLANG_DEFAULT_LINKER lld CACHE STRING "")
+endif()
+
+set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "")
+
+set(LLVM_BUILTIN_TARGETS "x86_64-fuchsia-none;aarch64-fuchsia-none" CACHE STRING "")
+set(BUILTINS_x86_64-fuchsia-none_CMAKE_SYSROOT ${FUCHSIA_SYSROOT} CACHE STRING "")
+set(BUILTINS_x86_64-fuchsia-none_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
+set(BUILTINS_aarch64-fuchsia-none_CMAKE_SYSROOT ${FUCHSIA_SYSROOT} CACHE STRING "")
+set(BUILTINS_aarch64-fuchsia-none_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
+
+# Setup toolchain.
+set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
+set(LLVM_TOOLCHAIN_TOOLS
+  llvm-ar
+  llvm-cov
+  llvm-cxxfilt
+  llvm-dwarfdump
+  llvm-dsymutil
+  llvm-lib
+  llvm-nm
+  llvm-objdump
+  llvm-profdata
+  llvm-ranlib
+  llvm-readobj
+  llvm-size
+  llvm-symbolizer
+  CACHE STRING "")
+
+set(LLVM_DISTRIBUTION_COMPONENTS
+  clang
+  lld
+  lldb
+  liblldb
+  LTO
+  clang-format
+  clang-headers
+  builtins-x86_64-fuchsia-none
+  builtins-aarch64-fuchsia-none
+  runtimes
+  ${LLVM_TOOLCHAIN_TOOLS}
+  CACHE STRING "")
diff --git a/cmake/caches/Fuchsia.cmake b/cmake/caches/Fuchsia.cmake
new file mode 100644
index 0000000..a90647e
--- /dev/null
+++ b/cmake/caches/Fuchsia.cmake
@@ -0,0 +1,44 @@
+# This file sets up a CMakeCache for a Fuchsia toolchain build.
+
+set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "")
+
+set(PACKAGE_VENDOR Fuchsia CACHE STRING "")
+
+set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "")
+set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
+set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "")
+set(CLANG_INCLUDE_TESTS OFF CACHE BOOL "")
+set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "")
+set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "")
+set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
+
+set(CMAKE_BUILD_TYPE Release CACHE STRING "")
+
+set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "")
+if(NOT APPLE)
+  set(BOOTSTRAP_LLVM_ENABLE_LLD ON CACHE BOOL "")
+endif()
+
+set(CLANG_BOOTSTRAP_TARGETS
+  check-all
+  check-llvm
+  check-clang
+  llvm-config
+  test-suite
+  test-depends
+  llvm-test-depends
+  clang-test-depends
+  distribution
+  install-distribution
+  clang CACHE STRING "")
+
+if(FUCHSIA_SYSROOT)
+  set(EXTRA_ARGS -DFUCHSIA_SYSROOT=${FUCHSIA_SYSROOT})
+endif()
+
+# Setup the bootstrap build.
+set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "")
+set(CLANG_BOOTSTRAP_CMAKE_ARGS
+  ${EXTRA_ARGS}
+  -C ${CMAKE_CURRENT_LIST_DIR}/Fuchsia-stage2.cmake
+  CACHE STRING "")
diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt
index b784c0d..59176a2 100644
--- a/cmake/modules/CMakeLists.txt
+++ b/cmake/modules/CMakeLists.txt
@@ -4,17 +4,27 @@
 set(CLANG_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/clang)
 set(clang_cmake_builddir "${CMAKE_BINARY_DIR}/${CLANG_INSTALL_PACKAGE_DIR}")
 
+# Keep this in sync with llvm/cmake/CMakeLists.txt!
+set(LLVM_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm)
+set(llvm_cmake_builddir "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}")
+
 get_property(CLANG_EXPORTS GLOBAL PROPERTY CLANG_EXPORTS)
 export(TARGETS ${CLANG_EXPORTS} FILE ${clang_cmake_builddir}/ClangTargets.cmake)
 
 # Generate ClangConfig.cmake for the build tree.
 set(CLANG_CONFIG_CMAKE_DIR "${clang_cmake_builddir}")
+set(CLANG_CONFIG_LLVM_CMAKE_DIR "${llvm_cmake_builddir}")
 set(CLANG_CONFIG_EXPORTS_FILE "${clang_cmake_builddir}/ClangTargets.cmake")
+set(CLANG_CONFIG_INCLUDE_DIRS
+  "${CLANG_SOURCE_DIR}/include"
+  "${CLANG_BINARY_DIR}/include"
+  )
 configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/ClangConfig.cmake.in
   ${clang_cmake_builddir}/ClangConfig.cmake
   @ONLY)
 set(CLANG_CONFIG_CMAKE_DIR)
+set(CLANG_CONFIG_LLVM_CMAKE_DIR)
 set(CLANG_CONFIG_EXPORTS_FILE)
 
 # Generate ClangConfig.cmake for the install tree.
@@ -29,7 +39,11 @@
 get_filename_component(CLANG_INSTALL_PREFIX \"\${CLANG_INSTALL_PREFIX}\" PATH)")
 endforeach(p)
 set(CLANG_CONFIG_CMAKE_DIR "\${CLANG_INSTALL_PREFIX}/${CLANG_INSTALL_PACKAGE_DIR}")
+set(CLANG_CONFIG_LLVM_CMAKE_DIR "\${CLANG_INSTALL_PREFIX}/${LLVM_INSTALL_PACKAGE_DIR}")
 set(CLANG_CONFIG_EXPORTS_FILE "\${CLANG_CMAKE_DIR}/ClangTargets.cmake")
+set(CLANG_CONFIG_INCLUDE_DIRS
+  "${CLANG_INSTALL_PREFIX}/include"
+  )
 configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/ClangConfig.cmake.in
   ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ClangConfig.cmake
diff --git a/cmake/modules/ClangConfig.cmake.in b/cmake/modules/ClangConfig.cmake.in
index a946944..03bca69 100644
--- a/cmake/modules/ClangConfig.cmake.in
+++ b/cmake/modules/ClangConfig.cmake.in
@@ -1,11 +1,13 @@
 # This file allows users to call find_package(Clang) and pick up our targets.
 
-find_package(LLVM REQUIRED CONFIG)
-
 @CLANG_CONFIG_CODE@
 
+find_package(LLVM REQUIRED CONFIG
+             HINTS "@CLANG_CONFIG_LLVM_CMAKE_DIR@")
+
 set(CLANG_EXPORTED_TARGETS "@CLANG_EXPORTS@")
 set(CLANG_CMAKE_DIR "@CLANG_CONFIG_CMAKE_DIR@")
+set(CLANG_INCLUDE_DIRS "@CLANG_CONFIG_INCLUDE_DIRS@")
 
 # Provide all our library targets to users.
 include("@CLANG_CONFIG_EXPORTS_FILE@")
diff --git a/docs/AddressSanitizer.rst b/docs/AddressSanitizer.rst
index f64f60d..ed28ad4 100644
--- a/docs/AddressSanitizer.rst
+++ b/docs/AddressSanitizer.rst
@@ -49,16 +49,16 @@
     }
 
     # Compile and link
-    % clang -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc
+    % clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc
 
 or:
 
 .. code-block:: console
 
     # Compile
-    % clang -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc
+    % clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc
     # Link
-    % clang -g -fsanitize=address example_UseAfterFree.o
+    % clang++ -g -fsanitize=address example_UseAfterFree.o
 
 If a bug is detected, the program will print an error message to stderr and
 exit with a non-zero exit code. AddressSanitizer exits on the first detected error.
diff --git a/docs/AutomaticReferenceCounting.rst b/docs/AutomaticReferenceCounting.rst
index aa2a283..fbd1ba4 100644
--- a/docs/AutomaticReferenceCounting.rst
+++ b/docs/AutomaticReferenceCounting.rst
@@ -2258,16 +2258,13 @@
 
 .. code-block:: objc
 
-  id objc_storeStrong(id *object, id value) {
-    value = [value retain];
+  void objc_storeStrong(id *object, id value) {
     id oldValue = *object;
+    value = [value retain];
     *object = value;
     [oldValue release];
-    return value;
   }
 
-Always returns ``value``.
-
 .. [*] This does not imply that a ``__strong`` object of block type is an
    invalid argument to this function. Rather it implies that an ``objc_retain``
    and not an ``objc_retainBlock`` operation will be emitted if the argument is
diff --git a/docs/Block-ABI-Apple.rst b/docs/Block-ABI-Apple.rst
index 08f3464..628e6f3 100644
--- a/docs/Block-ABI-Apple.rst
+++ b/docs/Block-ABI-Apple.rst
@@ -530,13 +530,13 @@
 
 .. code-block:: c
 
-    struct _block_byref_i i = {( .forwarding=&i, .flags=0, .size=sizeof(struct _block_byref_i) )};
+    struct _block_byref_i i = {( .isa=NULL, .forwarding=&i, .flags=0, .size=sizeof(struct _block_byref_i), .captured_i=2 )};
     struct __block_literal_5 _block_literal = {
           &_NSConcreteStackBlock,
           (1<<25)|(1<<29), <uninitialized>,
           __block_invoke_5,
           &__block_descriptor_5,
-          2,
+          &i,
     };
 
 Importing ``__attribute__((NSObject))`` ``__block`` variables
diff --git a/docs/ClangCommandLineReference.rst b/docs/ClangCommandLineReference.rst
new file mode 100644
index 0000000..c7aead9
--- /dev/null
+++ b/docs/ClangCommandLineReference.rst
@@ -0,0 +1,2545 @@
+..
+  -------------------------------------------------------------------
+  NOTE: This file is automatically generated by running clang-tblgen
+  -gen-opt-docs. Do not edit this file by hand!!
+  -------------------------------------------------------------------
+
+=====================================
+Clang command line argument reference
+=====================================
+.. contents::
+   :local:
+
+Introduction
+============
+
+This page lists the command line arguments currently supported by the
+GCC-compatible ``clang`` and ``clang++`` drivers.
+
+
+.. program:: clang
+.. option:: -B<dir>, --prefix <arg>, --prefix=<arg>
+
+Add <dir> to search path for binaries and object files used implicitly
+
+.. option:: -F<arg>
+
+Add directory to framework include search path
+
+.. option:: -ObjC
+
+Treat source input files as Objective-C inputs
+
+.. program:: clang1
+.. option:: -ObjC++
+.. program:: clang
+
+Treat source input files as Objective-C++ inputs
+
+.. option:: -Qunused-arguments
+
+Don't emit warning for unused driver arguments
+
+.. option:: -Wa,<arg>,<arg2>...
+
+Pass the comma separated arguments in <arg> to the assembler
+
+.. option:: -Wlarge-by-value-copy=<arg>
+
+.. option:: -Xarch\_<arg1> <arg2>
+
+.. option:: -Xcuda-fatbinary <arg>
+
+Pass <arg> to fatbinary invocation
+
+.. option:: -Xcuda-ptxas <arg>
+
+Pass <arg> to the ptxas assembler
+
+.. option:: -Z<arg>
+
+.. option:: -a<arg>, --profile-blocks
+
+.. option:: -all\_load
+
+.. option:: -allowable\_client <arg>
+
+.. option:: --analyze
+
+Run the static analyzer
+
+.. option:: --analyze-auto
+
+.. option:: --analyzer-no-default-checks
+
+.. option:: --analyzer-output<arg>
+
+Static analyzer report output format (html\|plist\|plist-multi-file\|plist-html\|text).
+
+.. option:: -ansi, --ansi
+
+.. option:: -arch <arg>
+
+.. program:: clang1
+.. option:: -arch\_errors\_fatal
+.. program:: clang
+
+.. program:: clang2
+.. option:: -arch\_only <arg>
+.. program:: clang
+
+.. option:: -arcmt-migrate-emit-errors
+
+Emit ARC errors even if the migrator can fix them
+
+.. option:: -arcmt-migrate-report-output <arg>
+
+Output path for the plist report
+
+.. option:: -bind\_at\_load
+
+.. option:: -bundle
+
+.. program:: clang1
+.. option:: -bundle\_loader <arg>
+.. program:: clang
+
+.. option:: -client\_name<arg>
+
+.. option:: -compatibility\_version<arg>
+
+.. option:: --constant-cfstrings
+
+.. option:: -coverage, --coverage
+
+.. option:: --cuda-compile-host-device
+
+Compile CUDA code for both host and device (default).  Has no effect on non-CUDA compilations.
+
+.. option:: --cuda-device-only
+
+Compile CUDA code for device only
+
+.. option:: --cuda-gpu-arch=<arg>, --no-cuda-gpu-arch=<arg>
+
+CUDA GPU architecture (e.g. sm\_35).  May be specified more than once.
+
+.. option:: --cuda-host-only
+
+Compile CUDA code for host only.  Has no effect on non-CUDA compilations.
+
+.. option:: --cuda-noopt-device-debug, --no-cuda-noopt-device-debug
+
+Enable device-side debug info generation. Disables ptxas optimizations.
+
+.. option:: -current\_version<arg>
+
+.. option:: -dead\_strip
+
+.. option:: -dependency-dot <arg>
+
+Filename to write DOT-formatted header dependencies to
+
+.. option:: -dependency-file <arg>
+
+Filename (or -) to write dependency output to
+
+.. option:: -dumpmachine
+
+.. option:: -dumpversion
+
+.. option:: --dyld-prefix=<arg>, --dyld-prefix <arg>
+
+.. option:: -dylib\_file <arg>
+
+.. option:: -dylinker
+
+.. program:: clang1
+.. option:: -dylinker\_install\_name<arg>
+.. program:: clang
+
+.. option:: -dynamic
+
+.. option:: -dynamiclib
+
+.. option:: -emit-ast
+
+Emit Clang AST files for source inputs
+
+.. option:: -exported\_symbols\_list <arg>
+
+.. option:: -faligned-new=<arg>
+
+.. option:: -fcuda-approx-transcendentals, -fno-cuda-approx-transcendentals
+
+Use approximate transcendental functions
+
+.. option:: -fcuda-flush-denormals-to-zero, -fno-cuda-flush-denormals-to-zero
+
+Flush denormal floating point values to zero in CUDA device mode.
+
+.. option:: -fheinous-gnu-extensions
+
+.. option:: -flat\_namespace
+
+.. option:: -fopenmp-targets=<arg1>,<arg2>...
+
+Specify comma-separated list of triples OpenMP offloading targets to be supported
+
+.. option:: -force\_cpusubtype\_ALL
+
+.. program:: clang1
+.. option:: -force\_flat\_namespace
+.. program:: clang
+
+.. program:: clang2
+.. option:: -force\_load <arg>
+.. program:: clang
+
+.. option:: -framework <arg>
+
+.. option:: --gcc-toolchain=<arg>, -gcc-toolchain <arg>
+
+Use the gcc toolchain at the given directory
+
+.. option:: -gcodeview
+
+Generate CodeView debug information
+
+.. option:: -headerpad\_max\_install\_names<arg>
+
+.. option:: -help, --help
+
+Display available options
+
+.. option:: --help-hidden
+
+.. option:: -image\_base <arg>
+
+.. option:: -index-header-map
+
+Make the next included directory (-I or -F) an indexer header map
+
+.. option:: -init <arg>
+
+.. option:: -install\_name <arg>
+
+.. option:: -keep\_private\_externs
+
+.. option:: -lazy\_framework <arg>
+
+.. program:: clang1
+.. option:: -lazy\_library <arg>
+.. program:: clang
+
+.. option:: -mbig-endian, -EB
+
+.. option:: --migrate
+
+Run the migrator
+
+.. option:: -mlinker-version=<arg>
+
+.. option:: -mlittle-endian, -EL
+
+.. option:: -mllvm <arg>
+
+Additional arguments to forward to LLVM's option processing
+
+.. option:: -module-dependency-dir <arg>
+
+Directory to dump module dependencies to
+
+.. option:: -multi\_module
+
+.. option:: -multiply\_defined <arg>
+
+.. program:: clang1
+.. option:: -multiply\_defined\_unused <arg>
+.. program:: clang
+
+.. option:: --no-cuda-version-check
+
+Don't error out if the detected version of the CUDA install is too low for the requested CUDA gpu architecture.
+
+.. option:: -no-integrated-cpp, --no-integrated-cpp
+
+.. option:: -no\_dead\_strip\_inits\_and\_terms
+
+.. option:: -nobuiltininc
+
+Disable builtin #include directories
+
+.. option:: -nocudainc
+
+.. option:: -nocudalib
+
+.. option:: -nodefaultlibs
+
+.. option:: -nofixprebinding
+
+.. option:: -nolibc
+
+.. option:: -nomultidefs
+
+.. option:: -nopie
+
+.. option:: -noprebind
+
+.. option:: -noseglinkedit
+
+.. option:: -nostartfiles
+
+.. option:: -nostdinc, --no-standard-includes
+
+.. program:: clang1
+.. option:: -nostdinc++
+.. program:: clang
+
+Disable standard #include directories for the C++ standard library
+
+.. option:: -nostdlib, --no-standard-libraries
+
+.. option:: -nostdlibinc
+
+.. option:: -o<file>, --output <arg>, --output=<arg>
+
+Write output to <file>
+
+.. option:: -objcmt-atomic-property
+
+Make migration to 'atomic' properties
+
+.. option:: -objcmt-migrate-all
+
+Enable migration to modern ObjC
+
+.. option:: -objcmt-migrate-annotation
+
+Enable migration to property and method annotations
+
+.. option:: -objcmt-migrate-designated-init
+
+Enable migration to infer NS\_DESIGNATED\_INITIALIZER for initializer methods
+
+.. option:: -objcmt-migrate-instancetype
+
+Enable migration to infer instancetype for method result type
+
+.. option:: -objcmt-migrate-literals
+
+Enable migration to modern ObjC literals
+
+.. option:: -objcmt-migrate-ns-macros
+
+Enable migration to NS\_ENUM/NS\_OPTIONS macros
+
+.. option:: -objcmt-migrate-property
+
+Enable migration to modern ObjC property
+
+.. option:: -objcmt-migrate-property-dot-syntax
+
+Enable migration of setter/getter messages to property-dot syntax
+
+.. option:: -objcmt-migrate-protocol-conformance
+
+Enable migration to add protocol conformance on classes
+
+.. option:: -objcmt-migrate-readonly-property
+
+Enable migration to modern ObjC readonly property
+
+.. option:: -objcmt-migrate-readwrite-property
+
+Enable migration to modern ObjC readwrite property
+
+.. option:: -objcmt-migrate-subscripting
+
+Enable migration to modern ObjC subscripting
+
+.. option:: -objcmt-ns-nonatomic-iosonly
+
+Enable migration to use NS\_NONATOMIC\_IOSONLY macro for setting property's 'atomic' attribute
+
+.. option:: -objcmt-returns-innerpointer-property
+
+Enable migration to annotate property with NS\_RETURNS\_INNER\_POINTER
+
+.. option:: -objcmt-whitelist-dir-path=<arg>, -objcmt-white-list-dir-path=<arg>
+
+Only modify files with a filename contained in the provided directory path
+
+.. option:: -object
+
+.. option:: -p, --profile
+
+.. option:: -pagezero\_size<arg>
+
+.. option:: -pg
+
+Enable mcount instrumentation
+
+.. option:: -pie
+
+.. option:: -pipe, --pipe
+
+Use pipes between commands, when possible
+
+.. option:: -prebind
+
+.. program:: clang1
+.. option:: -prebind\_all\_twolevel\_modules
+.. program:: clang
+
+.. option:: -preload
+
+.. option:: --print-diagnostic-categories
+
+.. option:: -print-file-name=<file>, --print-file-name=<file>, --print-file-name <arg>
+
+Print the full library path of <file>
+
+.. option:: -print-ivar-layout
+
+Enable Objective-C Ivar layout bitmap print trace
+
+.. option:: -print-libgcc-file-name, --print-libgcc-file-name
+
+Print the library path for the currently used compiler runtime library ("libgcc.a" or "libclang\_rt.builtins.\*.a")
+
+.. option:: -print-multi-directory, --print-multi-directory
+
+.. option:: -print-multi-lib, --print-multi-lib
+
+.. option:: -print-prog-name=<name>, --print-prog-name=<name>, --print-prog-name <arg>
+
+Print the full program path of <name>
+
+.. option:: -print-search-dirs, --print-search-dirs
+
+Print the paths used for finding libraries and programs
+
+.. option:: -private\_bundle
+
+.. option:: -pthread, -no-pthread
+
+Support POSIX threads in generated code
+
+.. option:: -pthreads
+
+.. option:: -rdynamic
+
+.. option:: -read\_only\_relocs <arg>
+
+.. option:: -relocatable-pch, --relocatable-pch
+
+Whether to build a relocatable precompiled header
+
+.. option:: -remap
+
+.. option:: -rewrite-legacy-objc
+
+Rewrite Legacy Objective-C source to C++
+
+.. option:: -rtlib=<arg>, --rtlib=<arg>, --rtlib <arg>
+
+Compiler runtime library to use
+
+.. option:: -save-stats=<arg>, --save-stats=<arg>, -save-stats (equivalent to -save-stats=cwd), --save-stats (equivalent to -save-stats=cwd)
+
+Save llvm statistics.
+
+.. option:: -save-temps=<arg>, --save-temps=<arg>, -save-temps (equivalent to -save-temps=cwd), --save-temps (equivalent to -save-temps=cwd)
+
+Save intermediate compilation results.
+
+.. option:: -sectalign <arg1> <arg2> <arg3>
+
+.. option:: -sectcreate <arg1> <arg2> <arg3>
+
+.. option:: -sectobjectsymbols <arg1> <arg2>
+
+.. option:: -sectorder <arg1> <arg2> <arg3>
+
+.. option:: -seg1addr<arg>
+
+.. option:: -seg\_addr\_table <arg>
+
+.. program:: clang1
+.. option:: -seg\_addr\_table\_filename <arg>
+.. program:: clang
+
+.. option:: -segaddr <arg1> <arg2>
+
+.. option:: -segcreate <arg1> <arg2> <arg3>
+
+.. option:: -seglinkedit
+
+.. option:: -segprot <arg1> <arg2> <arg3>
+
+.. option:: -segs\_read\_<arg>
+
+.. program:: clang1
+.. option:: -segs\_read\_only\_addr <arg>
+.. program:: clang
+
+.. program:: clang2
+.. option:: -segs\_read\_write\_addr <arg>
+.. program:: clang
+
+.. option:: -serialize-diagnostics <arg>, --serialize-diagnostics <arg>
+
+Serialize compiler diagnostics to a file
+
+.. option:: -shared, --shared
+
+.. option:: -shared-libasan
+
+.. option:: -shared-libgcc
+
+.. option:: -single\_module
+
+.. option:: -specs=<arg>, --specs=<arg>
+
+.. option:: -static, --static
+
+.. option:: -static-libgcc
+
+.. option:: -static-libstdc++
+
+.. option:: -std-default=<arg>
+
+.. option:: -stdlib=<arg>, --stdlib=<arg>, --stdlib <arg>
+
+C++ standard library to use
+
+.. option:: -sub\_library<arg>
+
+.. program:: clang1
+.. option:: -sub\_umbrella<arg>
+.. program:: clang
+
+.. option:: --sysroot=<arg>, --sysroot <arg>
+
+.. option:: --target-help
+
+.. option:: --target=<arg>, -target <arg>
+
+Generate code for the given target
+
+.. option:: -time
+
+Time individual commands
+
+.. option:: -traditional, --traditional
+
+.. option:: -traditional-cpp, --traditional-cpp
+
+Enable some traditional CPP emulation
+
+.. option:: -twolevel\_namespace
+
+.. program:: clang1
+.. option:: -twolevel\_namespace\_hints
+.. program:: clang
+
+.. option:: -umbrella <arg>
+
+.. option:: -unexported\_symbols\_list <arg>
+
+.. option:: -v, --verbose
+
+Show commands to run and use verbose output
+
+.. option:: --verify-debug-info
+
+Verify the binary representation of debug output
+
+.. option:: --version
+
+.. option:: -w, --no-warnings
+
+Suppress all warnings
+
+.. option:: -weak-l<arg>
+
+.. option:: -weak\_framework <arg>
+
+.. program:: clang1
+.. option:: -weak\_library <arg>
+.. program:: clang
+
+.. program:: clang2
+.. option:: -weak\_reference\_mismatches <arg>
+.. program:: clang
+
+.. option:: -whatsloaded
+
+.. option:: -whyload
+
+.. option:: -working-directory<arg>, -working-directory=<arg>
+
+Resolve file paths relative to the specified directory
+
+.. option:: -x<language>, --language <arg>, --language=<arg>
+
+Treat subsequent input files as having type <language>
+
+.. option:: -y<arg>
+
+Actions
+=======
+The action to perform on the input.
+
+.. option:: -E, --preprocess
+
+Only run the preprocessor
+
+.. option:: -S, --assemble
+
+Only run preprocess and compilation steps
+
+.. option:: -c, --compile
+
+Only run preprocess, compile, and assemble steps
+
+.. option:: -emit-llvm
+
+Use the LLVM representation for assembler and object files
+
+.. option:: -fsyntax-only
+
+.. option:: -module-file-info
+
+Provide information about a particular module file
+
+.. option:: --precompile
+
+Only precompile the input
+
+.. option:: -rewrite-objc
+
+Rewrite Objective-C source to C++
+
+.. option:: -verify-pch
+
+Load and verify that a pre-compiled header file is not stale
+
+Compilation flags
+=================
+
+Flags controlling the behavior of Clang during compilation. These flags have
+no effect during actions that do not perform compilation.
+
+.. option:: -Xassembler <arg>
+
+Pass <arg> to the assembler
+
+.. option:: -Xclang <arg>
+
+Pass <arg> to the clang compiler
+
+.. option:: -fcomment-block-commands=<arg>,<arg2>...
+
+Treat each comma separated argument in <arg> as a documentation comment block command
+
+.. option:: -fdeclspec, -fno-declspec
+
+Allow \_\_declspec as a keyword
+
+.. option:: -fdepfile-entry=<arg>
+
+.. option:: -fdiagnostics-fixit-info, -fno-diagnostics-fixit-info
+
+.. option:: -fdiagnostics-format=<arg>
+
+.. option:: -fdiagnostics-parseable-fixits
+
+Print fix-its in machine parseable form
+
+.. option:: -fdiagnostics-print-source-range-info
+
+Print source range spans in numeric form
+
+.. option:: -fdiagnostics-show-category=<arg>
+
+.. option:: -fexperimental-new-pass-manager, -fno-experimental-new-pass-manager
+
+Enables an experimental new pass manager in LLVM.
+
+.. option:: -finline-functions, -fno-inline-functions
+
+Inline suitable functions
+
+.. option:: -finline-hint-functions
+
+Inline functions which are (explicitly or implicitly) marked inline
+
+.. option:: -fno-crash-diagnostics
+
+.. option:: -fno-sanitize-blacklist
+
+Don't use blacklist file for sanitizers
+
+.. option:: -fparse-all-comments
+
+.. option:: -fsanitize-address-field-padding=<arg>
+
+Level of field padding for AddressSanitizer
+
+.. option:: -fsanitize-address-use-after-scope, -fno-sanitize-address-use-after-scope
+
+Enable use-after-scope detection in AddressSanitizer
+
+.. option:: -fsanitize-blacklist=<arg>
+
+Path to blacklist file for sanitizers
+
+.. option:: -fsanitize-cfi-cross-dso, -fno-sanitize-cfi-cross-dso
+
+Enable control flow integrity (CFI) checks for cross-DSO calls.
+
+.. option:: -fsanitize-coverage=<arg1>,<arg2>..., -fno-sanitize-coverage=<arg1>,<arg2>...
+
+Specify the type of coverage instrumentation for Sanitizers
+
+.. option:: -fsanitize-link-c++-runtime
+
+.. option:: -fsanitize-memory-track-origins, -fno-sanitize-memory-track-origins
+
+Enable origins tracking in MemorySanitizer
+
+.. program:: clang1
+.. option:: -fsanitize-memory-track-origins=<arg>
+.. program:: clang
+
+Enable origins tracking in MemorySanitizer
+
+.. option:: -fsanitize-memory-use-after-dtor
+
+Enable use-after-destroy detection in MemorySanitizer
+
+.. option:: -fsanitize-recover, -fno-sanitize-recover
+
+.. program:: clang1
+.. option:: -fsanitize-recover=<arg1>,<arg2>..., -fno-sanitize-recover=<arg1>,<arg2>...
+.. program:: clang
+
+Enable recovery for specified sanitizers
+
+.. option:: -fsanitize-stats, -fno-sanitize-stats
+
+Enable sanitizer statistics gathering.
+
+.. option:: -fsanitize-thread-atomics, -fno-sanitize-thread-atomics
+
+Enable atomic operations instrumentation in ThreadSanitizer (default)
+
+.. option:: -fsanitize-thread-func-entry-exit, -fno-sanitize-thread-func-entry-exit
+
+Enable function entry/exit instrumentation in ThreadSanitizer (default)
+
+.. option:: -fsanitize-thread-memory-access, -fno-sanitize-thread-memory-access
+
+Enable memory access instrumentation in ThreadSanitizer (default)
+
+.. option:: -fsanitize-trap=<arg1>,<arg2>..., -fno-sanitize-trap=<arg1>,<arg2>...
+
+Enable trapping for specified sanitizers
+
+.. option:: -fsanitize-undefined-strip-path-components=<number>
+
+Strip (or keep only, if negative) a given number of path components when emitting check metadata.
+
+.. option:: -fsanitize-undefined-trap-on-error, -fno-sanitize-undefined-trap-on-error
+
+.. option:: -fsanitize=<check>,<arg2>..., -fno-sanitize=<arg1>,<arg2>...
+
+Turn on runtime checks for various forms of undefined or suspicious behavior. See user manual for available checks
+
+.. option:: --param <arg>, --param=<arg>
+
+.. option:: -std=<arg>, --std=<arg>, --std <arg>
+
+Language standard to compile for
+
+Preprocessor flags
+~~~~~~~~~~~~~~~~~~
+
+Flags controlling the behavior of the Clang preprocessor.
+
+.. option:: -C, --comments
+
+Include comments in preprocessed output
+
+.. option:: -CC, --comments-in-macros
+
+Include comments from within macros in preprocessed output
+
+.. option:: -D<macro>=<value>, --define-macro <arg>, --define-macro=<arg>
+
+Define <macro> to <value> (or 1 if <value> omitted)
+
+.. option:: -H, --trace-includes
+
+Show header includes and nesting depth
+
+.. option:: -P, --no-line-commands
+
+Disable linemarker output in -E mode
+
+.. option:: -U<macro>, --undefine-macro <arg>, --undefine-macro=<arg>
+
+Undefine macro <macro>
+
+.. option:: -Wp,<arg>,<arg2>...
+
+Pass the comma separated arguments in <arg> to the preprocessor
+
+.. option:: -Xpreprocessor <arg>
+
+Pass <arg> to the preprocessor
+
+Include path management
+-----------------------
+
+Flags controlling how ``#include``\s are resolved to files.
+
+.. option:: -I<dir>, --include-directory <arg>, --include-directory=<arg>
+
+Add directory to include search path
+
+.. option:: -I-, --include-barrier
+
+Restrict all prior -I flags to double-quoted inclusion and remove current directory from include path
+
+.. option:: --cuda-path=<arg>
+
+CUDA installation path
+
+.. option:: -cxx-isystem<directory>
+
+Add directory to the C++ SYSTEM include search path
+
+.. option:: -fbuild-session-file=<file>
+
+Use the last modification time of <file> as the build session timestamp
+
+.. option:: -fbuild-session-timestamp=<time since Epoch in seconds>
+
+Time when the current build session started
+
+.. option:: -fmodules-cache-path=<directory>
+
+Specify the module cache path
+
+.. option:: -fmodules-disable-diagnostic-validation
+
+Disable validation of the diagnostic options when loading the module
+
+.. option:: -fmodules-prune-after=<seconds>
+
+Specify the interval (in seconds) after which a module file will be considered unused
+
+.. option:: -fmodules-prune-interval=<seconds>
+
+Specify the interval (in seconds) between attempts to prune the module cache
+
+.. option:: -fmodules-user-build-path <directory>
+
+Specify the module user build path
+
+.. option:: -fmodules-validate-once-per-build-session
+
+Don't verify input files for the modules if the module has been successfully validated or loaded during this build session
+
+.. option:: -fmodules-validate-system-headers
+
+Validate the system headers that a module depends on when loading the module
+
+.. option:: -fprebuilt-module-path=<directory>
+
+Specify the prebuilt module path
+
+.. option:: -i<arg>
+
+.. option:: -idirafter<arg>, --include-directory-after <arg>, --include-directory-after=<arg>
+
+Add directory to AFTER include search path
+
+.. option:: -iframework<arg>
+
+Add directory to SYSTEM framework search path
+
+.. option:: -imacros<file>, --imacros<file>, --imacros=<arg>
+
+Include macros from file before parsing
+
+.. option:: -include<file>, --include<file>, --include=<arg>
+
+Include file before parsing
+
+.. option:: -include-pch <file>
+
+Include precompiled header file
+
+.. option:: -iprefix<dir>, --include-prefix <arg>, --include-prefix=<arg>
+
+Set the -iwithprefix/-iwithprefixbefore prefix
+
+.. option:: -iquote<directory>
+
+Add directory to QUOTE include search path
+
+.. option:: -isysroot<dir>
+
+Set the system root directory (usually /)
+
+.. option:: -isystem<directory>
+
+Add directory to SYSTEM include search path
+
+.. option:: -isystem-after<directory>
+
+Add directory to end of the SYSTEM include search path
+
+.. option:: -ivfsoverlay<arg>
+
+Overlay the virtual filesystem described by file over the real file system
+
+.. option:: -iwithprefix<dir>, --include-with-prefix <arg>, --include-with-prefix-after <arg>, --include-with-prefix-after=<arg>, --include-with-prefix=<arg>
+
+Set directory to SYSTEM include search path with prefix
+
+.. option:: -iwithprefixbefore<dir>, --include-with-prefix-before <arg>, --include-with-prefix-before=<arg>
+
+Set directory to include search path with prefix
+
+.. option:: -iwithsysroot<directory>
+
+Add directory to SYSTEM include search path, absolute paths are relative to -isysroot
+
+.. option:: --ptxas-path=<arg>
+
+Path to ptxas (used for compiling CUDA code)
+
+.. option:: --system-header-prefix=<prefix>, --no-system-header-prefix=<prefix>, --system-header-prefix <arg>
+
+Treat all #include paths starting with <prefix> as including a system header.
+
+Dependency file generation
+--------------------------
+
+Flags controlling generation of a dependency file for ``make``-like build
+systems.
+
+.. option:: -M, --dependencies
+
+Like -MD, but also implies -E and writes to stdout by default
+
+.. option:: -MD, --write-dependencies
+
+Write a depfile containing user and system headers
+
+.. option:: -MF<file>
+
+Write depfile output from -MMD, -MD, -MM, or -M to <file>
+
+.. option:: -MG, --print-missing-file-dependencies
+
+Add missing headers to depfile
+
+.. option:: -MJ<arg>
+
+Write a compilation database entry per input
+
+.. option:: -MM, --user-dependencies
+
+Like -MMD, but also implies -E and writes to stdout by default
+
+.. option:: -MMD, --write-user-dependencies
+
+Write a depfile containing user headers
+
+.. option:: -MP
+
+Create phony target for each dependency (other than main file)
+
+.. option:: -MQ<arg>
+
+Specify name of main file output to quote in depfile
+
+.. option:: -MT<arg>
+
+Specify name of main file output in depfile
+
+.. option:: -MV
+
+Use NMake/Jom format for the depfile
+
+Dumping preprocessor state
+--------------------------
+
+Flags allowing the state of the preprocessor to be dumped in various ways.
+
+.. option:: -d
+
+.. program:: clang1
+.. option:: -d<arg>
+.. program:: clang
+
+.. option:: -dA
+
+.. option:: -dD
+
+Print macro definitions in -E mode in addition to normal output
+
+.. option:: -dI
+
+Print include directives in -E mode in addition to normal output
+
+.. option:: -dM
+
+Print macro definitions in -E mode instead of normal output
+
+Diagnostic flags
+~~~~~~~~~~~~~~~~
+
+Flags controlling which warnings, errors, and remarks Clang will generate.
+See the :doc:`full list of warning and remark flags <DiagnosticsReference>`.
+
+.. option:: -R<remark>
+
+Enable the specified remark
+
+.. option:: -Rpass-analysis=<arg>
+
+Report transformation analysis from optimization passes whose name matches the given POSIX regular expression
+
+.. option:: -Rpass-missed=<arg>
+
+Report missed transformations by optimization passes whose name matches the given POSIX regular expression
+
+.. option:: -Rpass=<arg>
+
+Report transformations performed by optimization passes whose name matches the given POSIX regular expression
+
+.. option:: -W<warning>, --extra-warnings, --warn-<arg>, --warn-=<arg>
+
+Enable the specified warning
+
+.. option:: -Wdeprecated, -Wno-deprecated
+
+Enable warnings for deprecated constructs and define \_\_DEPRECATED
+
+.. option:: -Wnonportable-cfstrings<arg>, -Wno-nonportable-cfstrings<arg>
+
+Target-independent compilation options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. option:: -Wframe-larger-than=<arg>
+
+.. option:: -fPIC, -fno-PIC
+
+.. option:: -fPIE, -fno-PIE
+
+.. option:: -faccess-control, -fno-access-control
+
+.. program:: clang1
+.. option:: -faligned-allocation, -faligned-new, -fno-aligned-allocation
+.. program:: clang
+
+Enable C++17 aligned allocation functions
+
+.. option:: -fallow-unsupported
+
+.. option:: -faltivec, -fno-altivec, -maltivec
+
+Enable AltiVec vector initializer syntax
+
+.. option:: -fansi-escape-codes
+
+Use ANSI escape codes for diagnostics
+
+.. option:: -fapple-kext, -findirect-virtual-calls, -fterminated-vtables
+
+Use Apple's kernel extensions ABI
+
+.. option:: -fapple-pragma-pack, -fno-apple-pragma-pack
+
+Enable Apple gcc-compatible #pragma pack handling
+
+.. option:: -fapplication-extension, -fno-application-extension
+
+Restrict code to those available for App Extensions
+
+.. option:: -fasm, -fno-asm
+
+.. option:: -fasm-blocks, -fno-asm-blocks
+
+.. option:: -fassociative-math, -fno-associative-math
+
+.. option:: -fassume-sane-operator-new, -fno-assume-sane-operator-new
+
+.. option:: -fast
+
+.. option:: -fastcp
+
+.. option:: -fastf
+
+.. option:: -fasynchronous-unwind-tables, -fno-asynchronous-unwind-tables
+
+.. option:: -fautolink, -fno-autolink
+
+.. option:: -fblocks, -fno-blocks
+
+Enable the 'blocks' language feature
+
+.. option:: -fbootclasspath=<arg>, --bootclasspath <arg>, --bootclasspath=<arg>
+
+.. option:: -fborland-extensions, -fno-borland-extensions
+
+Accept non-standard constructs supported by the Borland compiler
+
+.. option:: -fbracket-depth=<arg>
+
+.. option:: -fbuiltin, -fno-builtin
+
+.. option:: -fbuiltin-module-map
+
+Load the clang builtins module map file.
+
+.. option:: -fcaret-diagnostics, -fno-caret-diagnostics
+
+.. option:: -fclasspath=<arg>, --CLASSPATH <arg>, --CLASSPATH=<arg>, --classpath <arg>, --classpath=<arg>
+
+.. option:: -fcolor-diagnostics, -fno-color-diagnostics
+
+Use colors in diagnostics
+
+.. option:: -fcommon, -fno-common
+
+.. option:: -fcompile-resource=<arg>, --resource <arg>, --resource=<arg>
+
+.. option:: -fconstant-cfstrings, -fno-constant-cfstrings
+
+.. option:: -fconstant-string-class=<arg>
+
+.. option:: -fconstexpr-backtrace-limit=<arg>
+
+.. option:: -fconstexpr-depth=<arg>
+
+.. option:: -fconstexpr-steps=<arg>
+
+.. option:: -fcoroutines-ts, -fno-coroutines-ts
+
+Enable support for the C++ Coroutines TS
+
+.. option:: -fcoverage-mapping, -fno-coverage-mapping
+
+Generate coverage mapping to enable code coverage analysis
+
+.. option:: -fcreate-profile
+
+.. option:: -fcxx-exceptions, -fno-cxx-exceptions
+
+Enable C++ exceptions
+
+.. option:: -fcxx-modules, -fno-cxx-modules
+
+.. option:: -fdata-sections, -fno-data-sections
+
+Place each data in its own section (ELF Only)
+
+.. option:: -fdebug-info-for-profiling, -fno-debug-info-for-profiling
+
+Emit extra debug info to make sample profile more accurate.
+
+.. option:: -fdebug-pass-arguments
+
+.. option:: -fdebug-pass-structure
+
+.. option:: -fdebug-prefix-map=<arg>
+
+remap file source paths in debug info
+
+.. option:: -fdebug-types-section, -fno-debug-types-section
+
+Place debug types in their own section (ELF Only)
+
+.. option:: -fdelayed-template-parsing, -fno-delayed-template-parsing
+
+Parse templated function definitions at the end of the translation unit
+
+.. option:: -fdenormal-fp-math=<arg>
+
+.. option:: -fdiagnostics-absolute-paths
+
+Print absolute paths in diagnostics
+
+.. option:: -fdiagnostics-color, -fno-diagnostics-color
+
+.. program:: clang1
+.. option:: -fdiagnostics-color=<arg>
+.. program:: clang
+
+.. option:: -fdiagnostics-show-hotness, -fno-diagnostics-show-hotness
+
+Enable profile hotness information in diagnostic line
+
+.. option:: -fdiagnostics-show-note-include-stack, -fno-diagnostics-show-note-include-stack
+
+Display include stacks for diagnostic notes
+
+.. option:: -fdiagnostics-show-option, -fno-diagnostics-show-option
+
+Print option name with mappable diagnostics
+
+.. option:: -fdiagnostics-show-template-tree
+
+Print a template comparison tree for differing templates
+
+.. option:: -fdollars-in-identifiers, -fno-dollars-in-identifiers
+
+Allow '$' in identifiers
+
+.. option:: -fdwarf-directory-asm, -fno-dwarf-directory-asm
+
+.. option:: -felide-constructors, -fno-elide-constructors
+
+.. option:: -feliminate-unused-debug-symbols, -fno-eliminate-unused-debug-symbols
+
+.. option:: -fembed-bitcode=<option>, -fembed-bitcode (equivalent to -fembed-bitcode=all), -fembed-bitcode-marker (equivalent to -fembed-bitcode=marker)
+
+Embed LLVM bitcode (option: off, all, bitcode, marker)
+
+.. option:: -femit-all-decls
+
+Emit all declarations, even if unused
+
+.. option:: -femulated-tls, -fno-emulated-tls
+
+Use emutls functions to access thread\_local variables
+
+.. option:: -fencoding=<arg>, --encoding <arg>, --encoding=<arg>
+
+.. option:: -ferror-limit=<arg>
+
+.. option:: -fexceptions, -fno-exceptions
+
+Enable support for exception handling
+
+.. option:: -fexec-charset=<arg>
+
+.. option:: -fextdirs=<arg>, --extdirs <arg>, --extdirs=<arg>
+
+.. option:: -ffast-math, -fno-fast-math
+
+Allow aggressive, lossy floating-point optimizations
+
+.. option:: -ffinite-math-only, -fno-finite-math-only
+
+.. option:: -ffor-scope, -fno-for-scope
+
+.. option:: -ffp-contract=<arg>
+
+Form fused FP ops (e.g. FMAs): fast (everywhere) \| on (according to FP\_CONTRACT pragma, default) \| off (never fuse)
+
+.. option:: -ffreestanding
+
+Assert that the compilation takes place in a freestanding environment
+
+.. option:: -ffunction-sections, -fno-function-sections
+
+Place each function in its own section (ELF Only)
+
+.. option:: -fgnu-inline-asm, -fno-gnu-inline-asm
+
+.. option:: -fgnu-keywords, -fno-gnu-keywords
+
+Allow GNU-extension keywords regardless of language standard
+
+.. option:: -fgnu-runtime
+
+Generate output compatible with the standard GNU Objective-C runtime
+
+.. option:: -fgnu89-inline, -fno-gnu89-inline
+
+Use the gnu89 inline semantics
+
+.. option:: -fhonor-infinities, -fhonor-infinites, -fno-honor-infinities
+
+.. option:: -fhonor-nans, -fno-honor-nans
+
+.. option:: -fhosted
+
+.. option:: -fimplicit-module-maps, -fmodule-maps, -fno-implicit-module-maps
+
+Implicitly search the file system for module map files.
+
+.. option:: -fimplicit-modules, -fno-implicit-modules
+
+.. option:: -finput-charset=<arg>
+
+.. option:: -finstrument-functions
+
+Generate calls to instrument function entry and exit
+
+.. option:: -fintegrated-as, -fno-integrated-as, -integrated-as
+
+Enable the integrated assembler
+
+.. option:: -fjump-tables, -fno-jump-tables
+
+.. option:: -flax-vector-conversions, -fno-lax-vector-conversions
+
+.. option:: -flimited-precision=<arg>
+
+.. option:: -flto, -fno-lto
+
+Enable LTO in 'full' mode
+
+.. option:: -flto-jobs=<arg>
+
+Controls the backend parallelism of -flto=thin (default of 0 means the number of threads will be derived from the number of CPUs detected)
+
+.. program:: clang1
+.. option:: -flto=<arg>
+.. program:: clang
+
+Set LTO mode to either 'full' or 'thin'
+
+.. option:: -fmacro-backtrace-limit=<arg>
+
+.. option:: -fmath-errno, -fno-math-errno
+
+Require math functions to indicate errors by setting errno
+
+.. option:: -fmax-type-align=<arg>
+
+Specify the maximum alignment to enforce on pointers lacking an explicit alignment
+
+.. option:: -fmerge-all-constants, -fno-merge-all-constants
+
+.. option:: -fmessage-length=<arg>
+
+.. option:: -fmodule-file-deps, -fno-module-file-deps
+
+.. option:: -fmodule-file=<file>
+
+Load this precompiled module file
+
+.. option:: -fmodule-map-file=<file>
+
+Load this module map file
+
+.. option:: -fmodule-name=<name>, -fmodule-implementation-of <arg>, -fmodule-name <arg>
+
+Specify the name of the module to build
+
+.. option:: -fmodules, -fno-modules
+
+Enable the 'modules' language feature
+
+.. option:: -fmodules-decluse, -fno-modules-decluse
+
+Require declaration of modules used within a module
+
+.. option:: -fmodules-ignore-macro=<arg>
+
+Ignore the definition of the given macro when building and loading modules
+
+.. option:: -fmodules-search-all, -fno-modules-search-all
+
+Search even non-imported modules to resolve references
+
+.. option:: -fmodules-strict-decluse
+
+Like -fmodules-decluse but requires all headers to be in modules
+
+.. option:: -fmodules-ts
+
+Enable support for the C++ Modules TS
+
+.. option:: -fms-compatibility, -fno-ms-compatibility
+
+Enable full Microsoft Visual C++ compatibility
+
+.. option:: -fms-compatibility-version=<arg>
+
+Dot-separated value representing the Microsoft compiler version number to report in \_MSC\_VER (0 = don't define it (default))
+
+.. option:: -fms-extensions, -fno-ms-extensions
+
+Accept some non-standard constructs supported by the Microsoft compiler
+
+.. option:: -fms-memptr-rep=<arg>
+
+.. option:: -fms-volatile<arg>
+
+.. option:: -fmsc-version=<arg>
+
+Microsoft compiler version number to report in \_MSC\_VER (0 = don't define it (default))
+
+.. option:: -fmudflap
+
+.. option:: -fmudflapth
+
+.. option:: -fnested-functions
+
+.. option:: -fnew-alignment=<align>, -fnew-alignment <arg>
+
+Specifies the largest alignment guaranteed by '::operator new(size\_t)'
+
+.. option:: -fnext-runtime
+
+.. option:: -fno-builtin-<arg>
+
+Disable implicit builtin knowledge of a specific function
+
+.. option:: -fno-elide-type
+
+Do not elide types when printing diagnostics
+
+.. option:: -fno-max-type-align
+
+.. option:: -fno-operator-names
+
+Do not treat C++ operator name keywords as synonyms for operators
+
+.. option:: -fno-strict-modules-decluse
+
+.. option:: -fno-working-directory
+
+.. option:: -fnoopenmp-use-tls
+
+.. option:: -fobjc-abi-version=<arg>
+
+.. option:: -fobjc-arc, -fno-objc-arc
+
+Synthesize retain and release calls for Objective-C pointers
+
+.. option:: -fobjc-arc-exceptions, -fno-objc-arc-exceptions
+
+Use EH-safe code when synthesizing retains and releases in -fobjc-arc
+
+.. option:: -fobjc-exceptions, -fno-objc-exceptions
+
+Enable Objective-C exceptions
+
+.. option:: -fobjc-infer-related-result-type, -fno-objc-infer-related-result-type
+
+.. option:: -fobjc-legacy-dispatch, -fno-objc-legacy-dispatch
+
+.. option:: -fobjc-link-runtime
+
+.. option:: -fobjc-nonfragile-abi, -fno-objc-nonfragile-abi
+
+.. option:: -fobjc-nonfragile-abi-version=<arg>
+
+.. option:: -fobjc-runtime=<arg>
+
+Specify the target Objective-C runtime kind and version
+
+.. option:: -fobjc-sender-dependent-dispatch
+
+.. option:: -fobjc-weak, -fno-objc-weak
+
+Enable ARC-style weak references in Objective-C
+
+.. option:: -fomit-frame-pointer, -fno-omit-frame-pointer
+
+.. option:: -fopenmp, -fno-openmp
+
+.. option:: -fopenmp-dump-offload-linker-script
+
+.. option:: -fopenmp-use-tls
+
+.. option:: -fopenmp-version=<arg>
+
+.. program:: clang1
+.. option:: -fopenmp=<arg>
+.. program:: clang
+
+.. option:: -foperator-arrow-depth=<arg>
+
+.. option:: -foptimization-record-file=<arg>
+
+Specify the file name of any generated YAML optimization record
+
+.. option:: -foptimize-sibling-calls, -fno-optimize-sibling-calls
+
+.. option:: -foutput-class-dir=<arg>, --output-class-directory <arg>, --output-class-directory=<arg>
+
+.. option:: -fpack-struct, -fno-pack-struct
+
+.. program:: clang1
+.. option:: -fpack-struct=<arg>
+.. program:: clang
+
+Specify the default maximum struct packing alignment
+
+.. option:: -fpascal-strings, -fno-pascal-strings, -mpascal-strings
+
+Recognize and construct Pascal-style string literals
+
+.. option:: -fpcc-struct-return
+
+Override the default ABI to return all structs on the stack
+
+.. option:: -fpch-preprocess
+
+.. option:: -fpic, -fno-pic
+
+.. option:: -fpie, -fno-pie
+
+.. option:: -fplugin=<dsopath>
+
+Load the named plugin (dynamic shared object)
+
+.. option:: -fpreserve-as-comments, -fno-preserve-as-comments
+
+.. option:: -fprofile-arcs, -fno-profile-arcs
+
+.. option:: -fprofile-dir=<arg>
+
+.. option:: -fprofile-generate, -fno-profile-generate
+
+Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM\_PROFILE\_FILE env var)
+
+.. program:: clang1
+.. option:: -fprofile-generate=<directory>
+.. program:: clang
+
+Generate instrumented code to collect execution counts into <directory>/default.profraw (overridden by LLVM\_PROFILE\_FILE env var)
+
+.. option:: -fprofile-instr-generate, -fno-profile-instr-generate
+
+Generate instrumented code to collect execution counts into default.profraw file (overridden by '=' form of option or LLVM\_PROFILE\_FILE env var)
+
+.. program:: clang1
+.. option:: -fprofile-instr-generate=<file>
+.. program:: clang
+
+Generate instrumented code to collect execution counts into <file> (overridden by LLVM\_PROFILE\_FILE env var)
+
+.. option:: -fprofile-instr-use, -fno-profile-instr-use, -fprofile-use
+
+.. program:: clang1
+.. option:: -fprofile-instr-use=<arg>
+.. program:: clang
+
+Use instrumentation data for profile-guided optimization
+
+.. option:: -fprofile-sample-use=<arg>, -fauto-profile=<arg>
+
+Enable sample-based profile guided optimizations
+
+.. program:: clang1
+.. option:: -fprofile-use=<pathname>
+.. program:: clang
+
+Use instrumentation data for profile-guided optimization. If pathname is a directory, it reads from <pathname>/default.profdata. Otherwise, it reads from file <pathname>.
+
+.. option:: -freciprocal-math, -fno-reciprocal-math
+
+Allow division operations to be reassociated
+
+.. option:: -freg-struct-return
+
+Override the default ABI to return small structs in registers
+
+.. option:: -frelaxed-template-template-args, -fno-relaxed-template-template-args
+
+Enable C++17 relaxed template template argument matching
+
+.. option:: -freroll-loops, -fno-reroll-loops
+
+Turn on loop reroller
+
+.. option:: -fretain-comments-from-system-headers
+
+.. option:: -frewrite-includes, -fno-rewrite-includes
+
+.. option:: -frewrite-map-file <arg>
+
+.. program:: clang1
+.. option:: -frewrite-map-file=<arg>
+.. program:: clang
+
+.. option:: -fropi, -fno-ropi
+
+.. option:: -frtti, -fno-rtti
+
+.. option:: -frwpi, -fno-rwpi
+
+.. option:: -fsave-optimization-record, -fno-save-optimization-record
+
+Generate a YAML optimization record file
+
+.. option:: -fshort-enums, -fno-short-enums
+
+Allocate to an enum type only as many bytes as it needs for the declared range of possible values
+
+.. option:: -fshort-wchar, -fno-short-wchar
+
+Force wchar\_t to be a short unsigned int
+
+.. option:: -fshow-column, -fno-show-column
+
+.. option:: -fshow-overloads=<arg>
+
+Which overload candidates to show when overload resolution fails: best\|all; defaults to all
+
+.. option:: -fshow-source-location, -fno-show-source-location
+
+.. option:: -fsignaling-math, -fno-signaling-math
+
+.. option:: -fsigned-bitfields
+
+.. option:: -fsigned-char, -fno-signed-char, --signed-char
+
+.. option:: -fsigned-zeros, -fno-signed-zeros
+
+.. option:: -fsized-deallocation, -fno-sized-deallocation
+
+Enable C++14 sized global deallocation functions
+
+.. option:: -fsjlj-exceptions
+
+Use SjLj style exceptions
+
+.. option:: -fslp-vectorize, -fno-slp-vectorize, -ftree-slp-vectorize
+
+Enable the superword-level parallelism vectorization passes
+
+.. option:: -fslp-vectorize-aggressive, -fno-slp-vectorize-aggressive
+
+Enable the BB vectorization passes
+
+.. option:: -fspell-checking, -fno-spell-checking
+
+.. option:: -fspell-checking-limit=<arg>
+
+.. option:: -fsplit-dwarf-inlining, -fno-split-dwarf-inlining
+
+Place debug types in their own section (ELF Only)
+
+.. option:: -fsplit-stack
+
+.. option:: -fstack-protector, -fno-stack-protector
+
+Enable stack protectors for functions potentially vulnerable to stack smashing
+
+.. option:: -fstack-protector-all
+
+Force the usage of stack protectors for all functions
+
+.. option:: -fstack-protector-strong
+
+Use a strong heuristic to apply stack protectors to functions
+
+.. option:: -fstandalone-debug, -fno-limit-debug-info, -fno-standalone-debug
+
+Emit full debug info for all types used by the program
+
+.. option:: -fstrict-aliasing, -fno-strict-aliasing
+
+.. option:: -fstrict-enums, -fno-strict-enums
+
+Enable optimizations based on the strict definition of an enum's value range
+
+.. option:: -fstrict-overflow, -fno-strict-overflow
+
+.. option:: -fstrict-return, -fno-strict-return
+
+Always treat control flow paths that fall off the end of a non-voidfunction as unreachable
+
+.. option:: -fstrict-vtable-pointers, -fno-strict-vtable-pointers
+
+Enable optimizations based on the strict rules for overwriting polymorphic C++ objects
+
+.. option:: -fstruct-path-tbaa, -fno-struct-path-tbaa
+
+.. option:: -ftabstop=<arg>
+
+.. option:: -ftemplate-backtrace-limit=<arg>
+
+.. option:: -ftemplate-depth-<arg>
+
+.. option:: -ftemplate-depth=<arg>
+
+.. option:: -ftest-coverage
+
+.. option:: -fthinlto-index=<arg>
+
+Perform ThinLTO importing using provided function summary index
+
+.. option:: -fthreadsafe-statics, -fno-threadsafe-statics
+
+.. option:: -ftime-report
+
+.. option:: -ftls-model=<arg>
+
+.. option:: -ftrap-function=<arg>
+
+Issue call to specified function rather than a trap instruction
+
+.. option:: -ftrapping-math, -fno-trapping-math
+
+.. option:: -ftrapv
+
+Trap on integer overflow
+
+.. option:: -ftrapv-handler <arg>
+
+.. program:: clang1
+.. option:: -ftrapv-handler=<function name>
+.. program:: clang
+
+Specify the function to be called on overflow
+
+.. option:: -ftrigraphs, -fno-trigraphs, -trigraphs, --trigraphs
+
+Process trigraph sequences
+
+.. option:: -funique-section-names, -fno-unique-section-names
+
+Use unique names for text and data sections (ELF Only)
+
+.. option:: -funit-at-a-time, -fno-unit-at-a-time
+
+.. option:: -funroll-loops, -fno-unroll-loops
+
+Turn on loop unroller
+
+.. option:: -funsafe-math-optimizations, -fno-unsafe-math-optimizations
+
+.. option:: -funsigned-bitfields
+
+.. option:: -funsigned-char, -fno-unsigned-char, --unsigned-char
+
+.. option:: -funwind-tables, -fno-unwind-tables
+
+.. option:: -fuse-cxa-atexit, -fno-use-cxa-atexit
+
+.. option:: -fuse-init-array, -fno-use-init-array
+
+Use .init\_array instead of .ctors
+
+.. option:: -fuse-ld=<arg>
+
+.. option:: -fuse-line-directives, -fno-use-line-directives
+
+.. option:: -fveclib=<arg>
+
+Use the given vector functions library
+
+.. option:: -fvectorize, -fno-vectorize, -ftree-vectorize
+
+Enable the loop vectorization passes
+
+.. option:: -fverbose-asm, -fno-verbose-asm
+
+.. option:: -fvisibility-inlines-hidden
+
+Give inline C++ member functions default visibility by default
+
+.. option:: -fvisibility-ms-compat
+
+Give global types 'default' visibility and global functions and variables 'hidden' visibility by default
+
+.. option:: -fvisibility=<arg>
+
+Set the default symbol visibility for all global declarations
+
+.. option:: -fwhole-program-vtables, -fno-whole-program-vtables
+
+Enables whole-program vtable optimization. Requires -flto
+
+.. option:: -fwrapv, -fno-wrapv
+
+Treat signed integer overflow as two's complement
+
+.. option:: -fwritable-strings
+
+Store string literals as writable data
+
+.. option:: -fxray-instruction-threshold<arg>
+
+.. program:: clang1
+.. option:: -fxray-instruction-threshold=<arg>
+.. program:: clang
+
+Sets the minimum function size to instrument with XRay
+
+.. option:: -fxray-instrument, -fno-xray-instrument
+
+Generate XRay instrumentation sleds on function entry and exit
+
+.. option:: -fzero-initialized-in-bss, -fno-zero-initialized-in-bss
+
+.. option:: -fzvector, -fno-zvector, -mzvector
+
+Enable System z vector language extension
+
+.. option:: -pedantic, --pedantic, -no-pedantic, --no-pedantic
+
+.. option:: -pedantic-errors, --pedantic-errors
+
+OpenCL flags
+------------
+.. option:: -cl-denorms-are-zero
+
+OpenCL only. Allow denormals to be flushed to zero.
+
+.. option:: -cl-fast-relaxed-math
+
+OpenCL only. Sets -cl-finite-math-only and -cl-unsafe-math-optimizations, and defines \_\_FAST\_RELAXED\_MATH\_\_.
+
+.. option:: -cl-finite-math-only
+
+OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.
+
+.. option:: -cl-fp32-correctly-rounded-divide-sqrt
+
+OpenCL only. Specify that single precision floating-point divide and sqrt used in the program source are correctly rounded.
+
+.. option:: -cl-kernel-arg-info
+
+OpenCL only. Generate kernel argument metadata.
+
+.. option:: -cl-mad-enable
+
+OpenCL only. Allow use of less precise MAD computations in the generated binary.
+
+.. option:: -cl-no-signed-zeros
+
+OpenCL only. Allow use of less precise no signed zeros computations in the generated binary.
+
+.. option:: -cl-opt-disable
+
+OpenCL only. This option disables all optimizations. By default optimizations are enabled.
+
+.. option:: -cl-single-precision-constant
+
+OpenCL only. Treat double precision floating-point constant as single precision constant.
+
+.. option:: -cl-std=<arg>
+
+OpenCL language standard to compile for.
+
+.. option:: -cl-strict-aliasing
+
+OpenCL only. This option is added for compatibility with OpenCL 1.0.
+
+.. option:: -cl-unsafe-math-optimizations
+
+OpenCL only. Allow unsafe floating-point optimizations.  Also implies -cl-no-signed-zeros and -cl-mad-enable.
+
+Target-dependent compilation options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. option:: -G<size>, -G=<arg>, -msmall-data-threshold=<arg>
+
+Put objects of at most <size> bytes into small data section (MIPS / Hexagon)
+
+.. option:: -m16
+
+.. option:: -m32
+
+.. option:: -m64
+
+.. option:: -mabi=<arg>
+
+.. option:: -mabicalls, -mno-abicalls
+
+Enable SVR4-style position-independent code (Mips only)
+
+.. option:: -malign-double
+
+Align doubles to two words in structs (x86 only)
+
+.. option:: -march=<arg>
+
+.. option:: -masm=<arg>
+
+.. option:: -mbackchain, -mno-backchain
+
+Link stack frames through backchain on System Z
+
+.. option:: -mcheck-zero-division, -mno-check-zero-division
+
+.. option:: -mcmodel=<arg>
+
+.. option:: -mcompact-branches=<arg>
+
+.. option:: -mconsole<arg>
+
+.. option:: -mcpu=<arg>, -mv4 (equivalent to -mcpu=hexagonv4), -mv5 (equivalent to -mcpu=hexagonv5), -mv55 (equivalent to -mcpu=hexagonv55), -mv60 (equivalent to -mcpu=hexagonv60)
+
+.. option:: -mdll<arg>
+
+.. option:: -mdouble-float
+
+.. option:: -mdsp, -mno-dsp
+
+.. option:: -mdspr2, -mno-dspr2
+
+.. option:: -mdynamic-no-pic<arg>
+
+.. option:: -meabi <arg>
+
+Set EABI type, e.g. 4, 5 or gnu (default depends on triple)
+
+.. option:: -mfloat-abi=<arg>
+
+.. option:: -mfp32
+
+Use 32-bit floating point registers (MIPS only)
+
+.. option:: -mfp64
+
+Use 64-bit floating point registers (MIPS only)
+
+.. option:: -mfpmath=<arg>
+
+.. option:: -mfpu=<arg>
+
+.. option:: -mglobal-merge, -mno-global-merge
+
+Enable merging of globals
+
+.. option:: -mhard-float
+
+.. option:: -mhwdiv=<arg>, --mhwdiv <arg>, --mhwdiv=<arg>
+
+.. option:: -miamcu, -mno-iamcu
+
+Use Intel MCU ABI
+
+.. option:: -mimplicit-float, -mno-implicit-float
+
+.. option:: -mimplicit-it=<arg>
+
+.. option:: -mincremental-linker-compatible, -mno-incremental-linker-compatible
+
+(integrated-as) Emit an object file which can be used with an incremental linker
+
+.. option:: -miphoneos-version-min=<arg>, -mios-simulator-version-min=<arg>, -mios-version-min=<arg>, -miphonesimulator-version-min=<arg>
+
+.. option:: -mips16
+
+.. option:: -mkernel
+
+.. option:: -mldc1-sdc1, -mno-ldc1-sdc1
+
+.. option:: -mlong-calls, -mno-long-calls
+
+Generate branches with extended addressability, usually via indirect jumps.
+
+.. option:: -mmacosx-version-min=<arg>
+
+Set Mac OS X deployment target
+
+.. option:: -mmicromips, -mno-micromips
+
+.. option:: -mms-bitfields, -mno-ms-bitfields
+
+Set the default structure layout to be compatible with the Microsoft compiler standard
+
+.. option:: -mmsa, -mno-msa
+
+Enable MSA ASE (MIPS only)
+
+.. option:: -mnan=<arg>
+
+.. option:: -mno-mips16
+
+.. option:: -momit-leaf-frame-pointer, -mno-omit-leaf-frame-pointer
+
+Omit frame pointer setup for leaf functions
+
+.. option:: -moslib=<arg>
+
+.. option:: -mpie-copy-relocations, -mno-pie-copy-relocations
+
+Use copy relocations support for PIE builds
+
+.. option:: -mqdsp6-compat
+
+Enable hexagon-qdsp6 backward compatibility
+
+.. option:: -mrecip
+
+.. program:: clang1
+.. option:: -mrecip=<arg1>,<arg2>...
+.. program:: clang
+
+.. option:: -mred-zone, -mno-red-zone
+
+.. option:: -mregparm=<arg>
+
+.. option:: -mrelax-all, -mno-relax-all
+
+(integrated-as) Relax all machine instructions
+
+.. option:: -mrtd, -mno-rtd
+
+Make StdCall calling convention the default
+
+.. option:: -msingle-float
+
+.. option:: -msoft-float, -mno-soft-float
+
+Use software floating point
+
+.. option:: -mstack-alignment=<arg>
+
+Set the stack alignment
+
+.. option:: -mstack-probe-size=<arg>
+
+Set the stack probe size
+
+.. option:: -mstackrealign, -mno-stackrealign
+
+Force realign the stack at entry to every function
+
+.. option:: -mthread-model <arg>
+
+The thread model to use, e.g. posix, single (posix by default)
+
+.. option:: -mthreads<arg>
+
+.. option:: -mthumb, -mno-thumb
+
+.. option:: -mtune=<arg>
+
+.. option:: -mtvos-version-min=<arg>, -mappletvos-version-min=<arg>, -mappletvsimulator-version-min=<arg>, -mtvos-simulator-version-min=<arg>
+
+.. option:: -municode<arg>
+
+.. option:: -mvx, -mno-vx
+
+.. option:: -mwarn-nonportable-cfstrings, -mno-warn-nonportable-cfstrings
+
+.. option:: -mwatchos-version-min=<arg>, -mwatchos-simulator-version-min=<arg>, -mwatchsimulator-version-min=<arg>
+
+.. option:: -mwindows<arg>
+
+.. option:: -mx32
+
+.. option:: -mxgot, -mno-xgot
+
+AARCH64
+-------
+.. option:: -ffixed-x18
+
+Reserve the x18 register (AArch64 only)
+
+.. option:: -mfix-cortex-a53-835769, -mno-fix-cortex-a53-835769
+
+Workaround Cortex-A53 erratum 835769 (AArch64 only)
+
+.. option:: -mgeneral-regs-only
+
+Generate code which only uses the general purpose registers (AArch64 only)
+
+AMDGPU
+------
+ARM
+---
+.. option:: -ffixed-r9
+
+Reserve the r9 register (ARM only)
+
+.. option:: -mcrc
+
+Allow use of CRC instructions (ARM only)
+
+.. option:: -mexecute-only, -mno-execute-only, -mpure-code
+
+Disallow generation of data access to code sections (ARM only)
+
+.. option:: -mno-movt
+
+Disallow use of movt/movw pairs (ARM only)
+
+.. option:: -mnocrc
+
+Disallow use of CRC instructions (ARM only)
+
+.. option:: -mrestrict-it, -mno-restrict-it
+
+Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.
+
+.. option:: -munaligned-access, -mno-unaligned-access
+
+Allow memory accesses to be unaligned (AArch32/AArch64 only)
+
+Hexagon
+-------
+.. option:: -mhvx, -mno-hvx
+
+Enable Hexagon Vector eXtensions
+
+.. option:: -mhvx-double, -mno-hvx-double
+
+Enable Hexagon Double Vector eXtensions
+
+.. option:: -mieee-rnd-near
+
+PowerPC
+-------
+.. option:: -mcmpb, -mno-cmpb
+
+.. option:: -mcrbits, -mno-crbits
+
+.. option:: -mcrypto, -mno-crypto
+
+.. option:: -mdirect-move, -mno-direct-move
+
+.. option:: -mfloat128, -mno-float128
+
+.. option:: -mfprnd, -mno-fprnd
+
+.. option:: -mhtm, -mno-htm
+
+.. option:: -minvariant-function-descriptors, -mno-invariant-function-descriptors
+
+.. option:: -misel, -mno-isel
+
+.. option:: -mlongcall, -mno-longcall
+
+.. option:: -mmfocrf, -mmfcrf, -mno-mfocrf
+
+.. option:: -mpopcntd, -mno-popcntd
+
+.. option:: -mpower8-vector, -mno-power8-vector
+
+.. option:: -mpower9-vector, -mno-power9-vector
+
+.. option:: -mqpx, -mno-qpx
+
+.. option:: -mvsx, -mno-vsx
+
+WebAssembly
+-----------
+.. option:: -msimd128, -mno-simd128
+
+X86
+---
+.. option:: -m3dnow, -mno-3dnow
+
+.. option:: -m3dnowa, -mno-3dnowa
+
+.. option:: -madx, -mno-adx
+
+.. option:: -maes, -mno-aes
+
+.. option:: -mavx, -mno-avx
+
+.. option:: -mavx2, -mno-avx2
+
+.. option:: -mavx512bw, -mno-avx512bw
+
+.. option:: -mavx512cd, -mno-avx512cd
+
+.. option:: -mavx512dq, -mno-avx512dq
+
+.. option:: -mavx512er, -mno-avx512er
+
+.. option:: -mavx512f, -mno-avx512f
+
+.. option:: -mavx512ifma, -mno-avx512ifma
+
+.. option:: -mavx512pf, -mno-avx512pf
+
+.. option:: -mavx512vbmi, -mno-avx512vbmi
+
+.. option:: -mavx512vl, -mno-avx512vl
+
+.. option:: -mbmi, -mno-bmi
+
+.. option:: -mbmi2, -mno-bmi2
+
+.. option:: -mclflushopt, -mno-clflushopt
+
+.. option:: -mclwb, -mno-clwb
+
+.. option:: -mcx16, -mno-cx16
+
+.. option:: -mf16c, -mno-f16c
+
+.. option:: -mfma, -mno-fma
+
+.. option:: -mfma4, -mno-fma4
+
+.. option:: -mfsgsbase, -mno-fsgsbase
+
+.. option:: -mfxsr, -mno-fxsr
+
+.. option:: -mlzcnt, -mno-lzcnt
+
+.. option:: -mmmx, -mno-mmx
+
+.. option:: -mmovbe, -mno-movbe
+
+.. option:: -mmpx, -mno-mpx
+
+.. option:: -mmwaitx, -mno-mwaitx
+
+.. option:: -mpclmul, -mno-pclmul
+
+.. option:: -mpku, -mno-pku
+
+.. option:: -mpopcnt, -mno-popcnt
+
+.. option:: -mprefetchwt1, -mno-prefetchwt1
+
+.. option:: -mprfchw, -mno-prfchw
+
+.. option:: -mrdrnd, -mno-rdrnd
+
+.. option:: -mrdseed, -mno-rdseed
+
+.. option:: -mrtm, -mno-rtm
+
+.. option:: -msgx, -mno-sgx
+
+.. option:: -msha, -mno-sha
+
+.. option:: -msse, -mno-sse
+
+.. option:: -msse2, -mno-sse2
+
+.. option:: -msse3, -mno-sse3
+
+.. option:: -msse4.1, -mno-sse4.1
+
+.. program:: clang1
+.. option:: -msse4.2, -mno-sse4.2, -msse4
+.. program:: clang
+
+.. option:: -msse4a, -mno-sse4a
+
+.. option:: -mssse3, -mno-ssse3
+
+.. option:: -mtbm, -mno-tbm
+
+.. option:: -mx87, -m80387, -mno-x87
+
+.. option:: -mxop, -mno-xop
+
+.. option:: -mxsave, -mno-xsave
+
+.. option:: -mxsavec, -mno-xsavec
+
+.. option:: -mxsaveopt, -mno-xsaveopt
+
+.. option:: -mxsaves, -mno-xsaves
+
+Optimization level
+~~~~~~~~~~~~~~~~~~
+
+Flags controlling how much optimization should be performed.
+
+.. option:: -O<arg>, -O (equivalent to -O2), --optimize, --optimize=<arg>
+
+.. option:: -Ofast<arg>
+
+Debug information generation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Flags controlling how much and what kind of debug information should be
+generated.
+
+Kind and level of debug information
+-----------------------------------
+.. option:: -g, --debug, --debug=<arg>
+
+Generate source-level debug information
+
+.. option:: -gdwarf-2
+
+Generate source-level debug information with dwarf version 2
+
+.. option:: -gdwarf-3
+
+Generate source-level debug information with dwarf version 3
+
+.. option:: -gdwarf-4, -gdwarf
+
+Generate source-level debug information with dwarf version 4
+
+.. option:: -gdwarf-5
+
+Generate source-level debug information with dwarf version 5
+
+.. option:: -gfull
+
+.. option:: -gused
+
+Debug level
+___________
+.. option:: -g0
+
+.. option:: -g2
+
+.. option:: -g3
+
+.. option:: -ggdb0
+
+.. option:: -ggdb1
+
+.. option:: -ggdb2
+
+.. option:: -ggdb3
+
+.. option:: -gline-tables-only, -g1, -gmlt
+
+Emit debug line number tables only
+
+.. option:: -gmodules
+
+Generate debug info with external references to clang modules or precompiled headers
+
+Debugger to tune debug information for
+______________________________________
+.. option:: -ggdb
+
+.. option:: -glldb
+
+.. option:: -gsce
+
+Debug information flags
+-----------------------
+.. option:: -gcolumn-info, -gno-column-info
+
+.. option:: -gdwarf-aranges
+
+.. option:: -ggnu-pubnames
+
+.. option:: -grecord-gcc-switches, -gno-record-gcc-switches
+
+.. option:: -gsplit-dwarf
+
+.. option:: -gstrict-dwarf, -gno-strict-dwarf
+
+Static analyzer flags
+=====================
+
+Flags controlling the behavior of the Clang Static Analyzer.
+
+.. option:: -Xanalyzer <arg>
+
+Pass <arg> to the static analyzer
+
+Fortran compilation flags
+=========================
+
+Flags that will be passed onto the ``gfortran`` compiler when Clang is given
+a Fortran input.
+
+.. option:: -A<arg>, --assert <arg>, --assert=<arg>
+
+.. option:: -A-<arg>
+
+.. option:: -J<arg>
+
+.. option:: -cpp
+
+.. option:: -faggressive-function-elimination, -fno-aggressive-function-elimination
+
+.. option:: -falign-commons, -fno-align-commons
+
+.. option:: -fall-intrinsics, -fno-all-intrinsics
+
+.. option:: -fautomatic, -fno-automatic
+
+.. option:: -fbackslash, -fno-backslash
+
+.. option:: -fbacktrace, -fno-backtrace
+
+.. option:: -fblas-matmul-limit=<arg>
+
+.. option:: -fbounds-check, -fno-bounds-check
+
+.. option:: -fcheck-array-temporaries, -fno-check-array-temporaries
+
+.. option:: -fcheck=<arg>
+
+.. option:: -fcoarray=<arg>
+
+.. option:: -fconvert=<arg>
+
+.. option:: -fcray-pointer, -fno-cray-pointer
+
+.. option:: -fd-lines-as-code, -fno-d-lines-as-code
+
+.. option:: -fd-lines-as-comments, -fno-d-lines-as-comments
+
+.. option:: -fdefault-double-8, -fno-default-double-8
+
+.. option:: -fdefault-integer-8, -fno-default-integer-8
+
+.. option:: -fdefault-real-8, -fno-default-real-8
+
+.. option:: -fdollar-ok, -fno-dollar-ok
+
+.. option:: -fdump-fortran-optimized, -fno-dump-fortran-optimized
+
+.. option:: -fdump-fortran-original, -fno-dump-fortran-original
+
+.. option:: -fdump-parse-tree, -fno-dump-parse-tree
+
+.. option:: -fexternal-blas, -fno-external-blas
+
+.. option:: -ff2c, -fno-f2c
+
+.. option:: -ffixed-form, -fno-fixed-form
+
+.. option:: -ffixed-line-length-<arg>
+
+.. option:: -ffpe-trap=<arg>
+
+.. option:: -ffree-form, -fno-free-form
+
+.. option:: -ffree-line-length-<arg>
+
+.. option:: -ffrontend-optimize, -fno-frontend-optimize
+
+.. option:: -fimplicit-none, -fno-implicit-none
+
+.. option:: -finit-character=<arg>
+
+.. option:: -finit-integer=<arg>
+
+.. option:: -finit-local-zero, -fno-init-local-zero
+
+.. option:: -finit-logical=<arg>
+
+.. option:: -finit-real=<arg>
+
+.. option:: -finteger-4-integer-8, -fno-integer-4-integer-8
+
+.. option:: -fintrinsic-modules-path, -fno-intrinsic-modules-path
+
+.. option:: -fmax-array-constructor=<arg>
+
+.. option:: -fmax-errors=<arg>
+
+.. option:: -fmax-identifier-length, -fno-max-identifier-length
+
+.. option:: -fmax-stack-var-size=<arg>
+
+.. option:: -fmax-subrecord-length=<arg>
+
+.. option:: -fmodule-private, -fno-module-private
+
+.. option:: -fpack-derived, -fno-pack-derived
+
+.. option:: -fprotect-parens, -fno-protect-parens
+
+.. option:: -frange-check, -fno-range-check
+
+.. option:: -freal-4-real-10, -fno-real-4-real-10
+
+.. option:: -freal-4-real-16, -fno-real-4-real-16
+
+.. option:: -freal-4-real-8, -fno-real-4-real-8
+
+.. option:: -freal-8-real-10, -fno-real-8-real-10
+
+.. option:: -freal-8-real-16, -fno-real-8-real-16
+
+.. option:: -freal-8-real-4, -fno-real-8-real-4
+
+.. option:: -frealloc-lhs, -fno-realloc-lhs
+
+.. option:: -frecord-marker=<arg>
+
+.. option:: -frecursive, -fno-recursive
+
+.. option:: -frepack-arrays, -fno-repack-arrays
+
+.. option:: -fsecond-underscore, -fno-second-underscore
+
+.. option:: -fsign-zero, -fno-sign-zero
+
+.. option:: -fstack-arrays, -fno-stack-arrays
+
+.. option:: -funderscoring, -fno-underscoring
+
+.. option:: -fwhole-file, -fno-whole-file
+
+.. option:: -nocpp
+
+.. option:: -static-libgfortran
+
+Linker flags
+============
+Flags that are passed on to the linker
+
+.. option:: -L<dir>, --library-directory <arg>, --library-directory=<arg>
+
+Add directory to library search path
+
+.. option:: -Mach
+
+.. option:: -T<script>
+
+Specify <script> as linker script
+
+.. option:: -Tbss<addr
+
+Set starting address of BSS to <addr>
+
+.. option:: -Tdata<addr
+
+Set starting address of BSS to <addr>
+
+.. option:: -Ttext<addr
+
+Set starting address of BSS to <addr>
+
+.. option:: -Wl,<arg>,<arg2>...
+
+Pass the comma separated arguments in <arg> to the linker
+
+.. option:: -X
+
+.. option:: -Xlinker <arg>, --for-linker <arg>, --for-linker=<arg>
+
+Pass <arg> to the linker
+
+.. program:: clang1
+.. option:: -Z
+.. program:: clang
+
+.. option:: -e<arg>, --entry
+
+.. option:: -filelist <arg>
+
+.. option:: -l<arg>
+
+.. option:: -r
+
+.. option:: -rpath <arg>
+
+.. option:: -s
+
+.. option:: -t
+
+.. option:: -u<arg>, --force-link <arg>, --force-link=<arg>
+
+.. option:: -undef
+
+undef all system defines
+
+.. option:: -undefined<arg>, --no-undefined
+
+.. option:: -z <arg>
+
+Pass -z <arg> to the linker
+
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
index 3f76da6..7b13a7d 100644
--- a/docs/ClangFormatStyleOptions.rst
+++ b/docs/ClangFormatStyleOptions.rst
@@ -213,6 +213,20 @@
   If ``true``, aligns escaped newlines as far left as possible.
   Otherwise puts them into the right-most column.
 
+  .. code-block:: c++
+
+    true:
+    #define A   \
+      int aaaa; \
+      int b;    \
+      int dddddddddd;
+
+    false:
+    #define A                                                                      \
+      int aaaa;                                                                    \
+      int b;                                                                       \
+      int dddddddddd;
+
 **AlignOperands** (``bool``)
   If ``true``, horizontally align operands of binary and ternary
   expressions.
@@ -228,10 +242,23 @@
 **AlignTrailingComments** (``bool``)
   If ``true``, aligns trailing comments.
 
+  .. code-block:: c++
+
+    true:                                   false:
+    int a;     // My comment a      vs.     int a; // My comment a
+    int b = 2; // comment  b                int b = 2; // comment about b
+
 **AllowAllParametersOfDeclarationOnNextLine** (``bool``)
   Allow putting all parameters of a function declaration onto
   the next line even if ``BinPackParameters`` is ``false``.
 
+  .. code-block:: c++
+
+    true:                                   false:
+    myFunction(foo,                 vs.     myFunction(foo, bar, plop);
+               bar,
+               plop);
+
 **AllowShortBlocksOnASingleLine** (``bool``)
   Allows contracting simple braced statements to a single line.
 
@@ -240,6 +267,17 @@
 **AllowShortCaseLabelsOnASingleLine** (``bool``)
   If ``true``, short case labels will be contracted to a single line.
 
+  .. code-block:: c++
+
+    true:                                   false:
+    switch (a) {                    vs.     switch (a) {
+    case 1: x = 1; break;                   case 1:
+    case 2: return;                           x = 1;
+    }                                         break;
+                                            case 2:
+                                              return;
+                                            }
+
 **AllowShortFunctionsOnASingleLine** (``ShortFunctionStyle``)
   Dependent on the value, ``int f() { return 0; }`` can be put on a
   single line.
@@ -252,12 +290,32 @@
   * ``SFS_Empty`` (in configuration: ``Empty``)
     Only merge empty functions.
 
+    .. code-block:: c++
+
+      void f() { bar(); }
+      void f2() {
+        bar2();
+      }
+
   * ``SFS_Inline`` (in configuration: ``Inline``)
     Only merge functions defined inside a class. Implies "empty".
 
+    .. code-block:: c++
+
+      class {
+        void f() { foo(); }
+      };
+
   * ``SFS_All`` (in configuration: ``All``)
     Merge all functions fitting on a single line.
 
+    .. code-block:: c++
+
+      class {
+        void f() { foo(); }
+      };
+      void f() { bar(); }
+
 
 
 **AllowShortIfStatementsOnASingleLine** (``bool``)
@@ -294,18 +352,78 @@
     Break after return type automatically.
     ``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
 
+    .. code-block:: c++
+
+      class A {
+        int f() { return 0; };
+      };
+      int f();
+      int f() { return 1; }
+
   * ``RTBS_All`` (in configuration: ``All``)
     Always break after the return type.
 
+    .. code-block:: c++
+
+      class A {
+        int
+        f() {
+          return 0;
+        };
+      };
+      int
+      f();
+      int
+      f() {
+        return 1;
+      }
+
   * ``RTBS_TopLevel`` (in configuration: ``TopLevel``)
     Always break after the return types of top-level functions.
 
+    .. code-block:: c++
+
+      class A {
+        int f() { return 0; };
+      };
+      int
+      f();
+      int
+      f() {
+        return 1;
+      }
+
   * ``RTBS_AllDefinitions`` (in configuration: ``AllDefinitions``)
     Always break after the return type of function definitions.
 
+    .. code-block:: c++
+
+      class A {
+        int
+        f() {
+          return 0;
+        };
+      };
+      int f();
+      int
+      f() {
+        return 1;
+      }
+
   * ``RTBS_TopLevelDefinitions`` (in configuration: ``TopLevelDefinitions``)
     Always break after the return type of top-level definitions.
 
+    .. code-block:: c++
+
+      class A {
+        int f() { return 0; };
+      };
+      int f();
+      int
+      f() {
+        return 1;
+      }
+
 
 
 **AlwaysBreakBeforeMultilineStrings** (``bool``)
@@ -316,10 +434,23 @@
   the string at that point leads to it being indented
   ``ContinuationIndentWidth`` spaces from the start of the line.
 
+  .. code-block:: c++
+
+     true:                                  false:
+     aaaa =                         vs.     aaaa = "bbbb"
+         "bbbb"                                    "cccc";
+         "cccc";
+
 **AlwaysBreakTemplateDeclarations** (``bool``)
   If ``true``, always break after the ``template<...>`` of a template
   declaration.
 
+  .. code-block:: c++
+
+     true:                                  false:
+     template <typename T>          vs.     template <typename T> class C {};
+     class C {};
+
 **BinPackArguments** (``bool``)
   If ``false``, a function call's arguments will either be all on the
   same line or will have one line each.
@@ -336,16 +467,148 @@
 
   Nested configuration flags:
 
+
   * ``bool AfterClass`` Wrap class definitions.
+
+  .. code-block:: c++
+
+    true:
+    class foo {};
+
+    false:
+    class foo
+    {};
+
   * ``bool AfterControlStatement`` Wrap control statements (``if``/``for``/``while``/``switch``/..).
+
+  .. code-block:: c++
+
+    true:
+    if (foo())
+    {
+    } else
+    {}
+    for (int i = 0; i < 10; ++i)
+    {}
+
+    false:
+    if (foo()) {
+    } else {
+    }
+    for (int i = 0; i < 10; ++i) {
+    }
+
   * ``bool AfterEnum`` Wrap enum definitions.
+
+  .. code-block:: c++
+
+    true:
+    enum X : int
+    {
+      B
+    };
+
+    false:
+    enum X : int { B };
+
   * ``bool AfterFunction`` Wrap function definitions.
+
+  .. code-block:: c++
+
+    true:
+    void foo()
+    {
+      bar();
+      bar2();
+    }
+
+    false:
+    void foo() {
+      bar();
+      bar2();
+    }
+
   * ``bool AfterNamespace`` Wrap namespace definitions.
+
+  .. code-block:: c++
+
+    true:
+    namespace
+    {
+    int foo();
+    int bar();
+    }
+
+    false:
+    namespace {
+    int foo();
+    int bar();
+    }
+
   * ``bool AfterObjCDeclaration`` Wrap ObjC definitions (``@autoreleasepool``, interfaces, ..).
+
   * ``bool AfterStruct`` Wrap struct definitions.
+
+  .. code-block:: c++
+
+    true:
+    struct foo
+    {
+      int x;
+    }
+
+    false:
+    struct foo {
+      int x;
+    }
+
   * ``bool AfterUnion`` Wrap union definitions.
+
+  .. code-block:: c++
+
+    true:
+    union foo
+    {
+      int x;
+    }
+
+    false:
+    union foo {
+      int x;
+    }
+
   * ``bool BeforeCatch`` Wrap before ``catch``.
+
+  .. code-block:: c++
+
+    true:
+    try {
+      foo();
+    }
+    catch () {
+    }
+
+    false:
+    try {
+      foo();
+    } catch () {
+    }
+
   * ``bool BeforeElse`` Wrap before ``else``.
+
+  .. code-block:: c++
+
+    true:
+    if (foo()) {
+    }
+    else {
+    }
+
+    false:
+    if (foo()) {
+    } else {
+    }
+
   * ``bool IndentBraces`` Indent the wrapped braces themselves.
 
 
@@ -376,41 +639,190 @@
   * ``BS_Attach`` (in configuration: ``Attach``)
     Always attach braces to surrounding context.
 
+    .. code-block:: c++
+
+      try {
+        foo();
+      } catch () {
+      }
+      void foo() { bar(); }
+      class foo {};
+      if (foo()) {
+      } else {
+      }
+      enum X : int { A, B };
+
   * ``BS_Linux`` (in configuration: ``Linux``)
     Like ``Attach``, but break before braces on function, namespace and
     class definitions.
 
+    .. code-block:: c++
+
+      try {
+        foo();
+      } catch () {
+      }
+      void foo() { bar(); }
+      class foo
+      {
+      };
+      if (foo()) {
+      } else {
+      }
+      enum X : int { A, B };
+
   * ``BS_Mozilla`` (in configuration: ``Mozilla``)
     Like ``Attach``, but break before braces on enum, function, and record
     definitions.
 
+    .. code-block:: c++
+
+      try {
+        foo();
+      } catch () {
+      }
+      void foo() { bar(); }
+      class foo
+      {
+      };
+      if (foo()) {
+      } else {
+      }
+      enum X : int { A, B };
+
   * ``BS_Stroustrup`` (in configuration: ``Stroustrup``)
     Like ``Attach``, but break before function definitions, ``catch``, and
     ``else``.
 
+    .. code-block:: c++
+
+      try {
+        foo();
+      } catch () {
+      }
+      void foo() { bar(); }
+      class foo
+      {
+      };
+      if (foo()) {
+      } else {
+      }
+      enum X : int
+      {
+        A,
+        B
+      };
+
   * ``BS_Allman`` (in configuration: ``Allman``)
     Always break before braces.
 
+    .. code-block:: c++
+
+      try {
+        foo();
+      }
+      catch () {
+      }
+      void foo() { bar(); }
+      class foo {
+      };
+      if (foo()) {
+      }
+      else {
+      }
+      enum X : int { A, B };
+
   * ``BS_GNU`` (in configuration: ``GNU``)
     Always break before braces and add an extra level of indentation to
     braces of control statements, not to those of class, function
     or other definitions.
 
+    .. code-block:: c++
+
+      try
+        {
+          foo();
+        }
+      catch ()
+        {
+        }
+      void foo() { bar(); }
+      class foo
+      {
+      };
+      if (foo())
+        {
+        }
+      else
+        {
+        }
+      enum X : int
+      {
+        A,
+        B
+      };
+
   * ``BS_WebKit`` (in configuration: ``WebKit``)
     Like ``Attach``, but break before functions.
 
+    .. code-block:: c++
+
+      try {
+        foo();
+      } catch () {
+      }
+      void foo() { bar(); }
+      class foo {
+      };
+      if (foo()) {
+      } else {
+      }
+      enum X : int { A, B };
+
   * ``BS_Custom`` (in configuration: ``Custom``)
     Configure each individual brace in `BraceWrapping`.
 
 
 
+**BreakBeforeInheritanceComma** (``bool``)
+  If ``true``, in the class inheritance expression clang-format will
+  break before ``:`` and ``,`` if there is multiple inheritance.
+
+  .. code-block:: c++
+
+     true:                                  false:
+     class MyClass                  vs.     class MyClass : public X, public Y {
+         : public X                         };
+         , public Y {
+     };
+
 **BreakBeforeTernaryOperators** (``bool``)
   If ``true``, ternary operators will be placed after line breaks.
 
+  .. code-block:: c++
+
+     true:
+     veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription
+         ? firstValue
+         : SecondValueVeryVeryVeryVeryLong;
+
+     true:
+     veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription ?
+         firstValue :
+         SecondValueVeryVeryVeryVeryLong;
+
 **BreakConstructorInitializersBeforeComma** (``bool``)
   Always break constructor initializers before commas and align
   the commas with the colon.
 
+  .. code-block:: c++
+
+     true:                                  false:
+     SomeClass::Constructor()       vs.     SomeClass::Constructor() : a(a),
+         : a(a)                                                   b(b),
+         , b(b)                                                   c(c) {}
+         , c(c) {}
+
 **BreakStringLiterals** (``bool``)
   Allow breaking string literals when formatting.
 
@@ -429,6 +841,21 @@
   If the constructor initializers don't fit on a line, put each
   initializer on its own line.
 
+  .. code-block:: c++
+
+    true:
+    SomeClass::Constructor()
+        : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) {
+      return 0;
+    }
+
+    false:
+    SomeClass::Constructor()
+        : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa),
+          aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) {
+      return 0;
+    }
+
 **ConstructorInitializerIndentWidth** (``unsigned``)
   The number of characters to use for indentation of constructor
   initializer lists.
@@ -453,7 +880,7 @@
 
 **DerivePointerAlignment** (``bool``)
   If ``true``, analyze the formatted file for the most common
-  alignment of ``&`` and ``\*``. ``PointerAlignment`` is then used only as
+  alignment of ``&`` and ``*``. ``PointerAlignment`` is then used only as
   fallback.
 
 **DisableFormat** (``bool``)
@@ -471,6 +898,17 @@
   NOTE: This is an experimental flag, that might go away or be renamed. Do
   not use this in config files, etc. Use at your own risk.
 
+**FixNamespaceComments** (``bool``)
+  If ``true``, clang-format adds missing namespace end comments and
+  fixes invalid existing ones.
+
+  .. code-block:: c++
+
+     true:                                  false:
+     namespace a {                  vs.     namespace a {
+     foo();                                 foo();
+     } // namespace a;                      }
+
 **ForEachMacros** (``std::vector<std::string>``)
   A vector of macros that should be interpreted as foreach loops
   instead of as function calls.
@@ -516,7 +954,7 @@
         Priority:        2
       - Regex:           '^(<|"(gtest|isl|json)/)'
         Priority:        3
-      - Regex:           '.\*'
+      - Regex:           '.*'
         Priority:        1
 
 **IncludeIsMainRegex** (``std::string``)
@@ -561,6 +999,9 @@
 
 
 
+**JavaScriptWrapImports** (``bool``)
+  Whether to wrap JavaScript import/export statements.
+
 **KeepEmptyLinesAtTheStartOfBlocks** (``bool``)
   If true, empty lines at the start of blocks are kept.
 
@@ -573,7 +1014,7 @@
     Do not use.
 
   * ``LK_Cpp`` (in configuration: ``Cpp``)
-    Should be used for C, C++, ObjectiveC, ObjectiveC++.
+    Should be used for C, C++.
 
   * ``LK_Java`` (in configuration: ``Java``)
     Should be used for Java.
@@ -581,6 +1022,9 @@
   * ``LK_JavaScript`` (in configuration: ``JavaScript``)
     Should be used for JavaScript.
 
+  * ``LK_ObjC`` (in configuration: ``ObjC``)
+    Should be used for Objective-C, Objective-C++.
+
   * ``LK_Proto`` (in configuration: ``Proto``)
     Should be used for Protocol Buffers
     (https://developers.google.com/protocol-buffers/).
@@ -653,12 +1097,24 @@
   * ``PAS_Left`` (in configuration: ``Left``)
     Align pointer to the left.
 
+    .. code-block:: c++
+
+      int* a;
+
   * ``PAS_Right`` (in configuration: ``Right``)
     Align pointer to the right.
 
+    .. code-block:: c++
+
+      int *a;
+
   * ``PAS_Middle`` (in configuration: ``Middle``)
     Align pointer in the middle.
 
+    .. code-block:: c++
+
+      int * a;
+
 
 
 **ReflowComments** (``bool``)
@@ -667,15 +1123,37 @@
 **SortIncludes** (``bool``)
   If ``true``, clang-format will sort ``#includes``.
 
+  .. code-block:: c++
+
+     false:                                 true:
+     #include "b.h"                 vs.     #include "a.h"
+     #include "a.h"                         #include "b.h"
+
 **SpaceAfterCStyleCast** (``bool``)
-  If ``true``, a space may be inserted after C style casts.
+  If ``true``, a space is inserted after C style casts.
+
+  .. code-block:: c++
+
+     true:                                  false:
+     (int)i;                        vs.     (int) i;
 
 **SpaceAfterTemplateKeyword** (``bool``)
   If ``true``, a space will be inserted after the 'template' keyword.
 
+  .. code-block:: c++
+
+     true:                                  false:
+     template <int> void foo();     vs.     template<int> void foo();
+
 **SpaceBeforeAssignmentOperators** (``bool``)
   If ``false``, spaces will be removed before assignment operators.
 
+  .. code-block:: c++
+
+     true:                                  false:
+     int a = 5;                     vs.     int a=5;
+     a += 42                                a+=42;
+
 **SpaceBeforeParens** (``SpaceBeforeParensOptions``)
   Defines in which cases to put a space before opening parentheses.
 
@@ -711,9 +1189,20 @@
   If ``true``, spaces will be inserted after ``<`` and before ``>``
   in template argument lists.
 
+  .. code-block:: c++
+
+     true:                                  false:
+     static_cast< int >(arg);       vs.     static_cast<int>(arg);
+     std::function< void(int) > fct;        std::function<void(int)> fct;
+
 **SpacesInCStyleCastParentheses** (``bool``)
   If ``true``, spaces may be inserted into C style casts.
 
+  .. code-block:: c++
+
+     true:                                  false:
+     x = ( int32 )y                 vs.     x = (int32)y
+
 **SpacesInContainerLiterals** (``bool``)
   If ``true``, spaces are inserted inside container literals (e.g.
   ObjC and Javascript array and dict literals).
@@ -721,8 +1210,20 @@
 **SpacesInParentheses** (``bool``)
   If ``true``, spaces will be inserted after ``(`` and before ``)``.
 
+  .. code-block:: c++
+
+     true:                                  false:
+     t f( Deleted & ) & = delete;   vs.     t f(Deleted &) & = delete;
+
 **SpacesInSquareBrackets** (``bool``)
   If ``true``, spaces will be inserted after ``[`` and before ``]``.
+  Lambdas or unspecified size array declarations will not be affected.
+
+  .. code-block:: c++
+
+     true:                                  false:
+     int a[ 5 ];                    vs.     int a[5];
+     std::unique_ptr<int[]> foo() {} // Won't be affected
 
 **Standard** (``LanguageStandard``)
   Format compatible with this standard, e.g. use ``A<A<int> >``
@@ -755,6 +1256,9 @@
   * ``UT_ForIndentation`` (in configuration: ``ForIndentation``)
     Use tabs only for indentation.
 
+  * ``UT_ForContinuationAndIndentation`` (in configuration: ``ForContinuationAndIndentation``)
+    Use tabs only for line continuation and indentation.
+
   * ``UT_Always`` (in configuration: ``Always``)
     Use tabs whenever we need to fill whitespace that spans at least from
     one tab stop to the next one.
diff --git a/docs/ControlFlowIntegrityDesign.rst b/docs/ControlFlowIntegrityDesign.rst
index a9f0b28..552e891 100644
--- a/docs/ControlFlowIntegrityDesign.rst
+++ b/docs/ControlFlowIntegrityDesign.rst
@@ -540,7 +540,7 @@
            Jump(kFailedCheckTarget);
   }
 
-An alternative and more compact enconding would not use `kFailedCheckTarget`,
+An alternative and more compact encoding would not use `kFailedCheckTarget`,
 and will trap on check failure instead.
 This will allow us to fit the instruction into **8-9 bytes**.
 The cross-DSO checks will be performed by a trap handler and
diff --git a/docs/DiagnosticsReference.rst b/docs/DiagnosticsReference.rst
index 7294c36..ce100cb 100644
--- a/docs/DiagnosticsReference.rst
+++ b/docs/DiagnosticsReference.rst
@@ -251,6 +251,28 @@
 Controls `-Wmost`_, `-Wparentheses`_, `-Wswitch`_, `-Wswitch-bool`_.
 
 
+-Walloca-with-align-alignof
+---------------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++--------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`second argument to \_\_builtin\_alloca\_with\_align is supposed to be in bits`|
++--------------------------------------------------------------------------------------------------------------------+
+
+
+-Wambiguous-delete
+------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`multiple suitable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`functions for` |nbsp| :placeholder:`B`:diagtext:`; no 'operator delete' function will be invoked if initialization throws an exception`|
++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+
 -Wambiguous-ellipsis
 --------------------
 This diagnostic is enabled by default.
@@ -482,7 +504,24 @@
 
 -Wasm
 -----
-Synonym for `-Wasm-operand-widths`_.
+This diagnostic is enabled by default.
+
+Controls `-Wasm-ignored-qualifier`_, `-Wasm-operand-widths`_.
+
+
+-Wasm-ignored-qualifier
+-----------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++----------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`ignored` |nbsp| :placeholder:`A` |nbsp| :diagtext:`qualifier on asm`|
++----------------------------------------------------------------------------------------------------------+
+
++-------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`meaningless 'volatile' on asm outside function`|
++-------------------------------------------------------------------------------------+
 
 
 -Wasm-operand-widths
@@ -697,21 +736,6 @@
 +-------------------------------------------------------------------------------+
 
 
--Wbad-array-new-length
-----------------------
-This diagnostic is enabled by default.
-
-**Diagnostic text:**
-
-+--------------------------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`array is too large (`:placeholder:`A` |nbsp| :diagtext:`elements)`|
-+--------------------------------------------------------------------------------------------------------+
-
-+-------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`array size is negative`|
-+-------------------------------------------------------------+
-
-
 -Wbad-function-cast
 -------------------
 **Diagnostic text:**
@@ -768,9 +792,9 @@
 
 **Diagnostic text:**
 
-+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`implicit truncation from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to bitfield changes value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`|
-+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`implicit truncation from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to bit-field changes value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`|
++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 
 -Wbitfield-width
@@ -807,6 +831,15 @@
 +-----------------------------------------------------------------------------------------------------------+
 
 
+-Wblock-capture-autoreleasing
+-----------------------------
+**Diagnostic text:**
+
++-----------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`block captures an autoreleasing out-parameter, which may result in use-after-free bugs`|
++-----------------------------------------------------------------------------------------------------------------------------+
+
+
 -Wbool-conversion
 -----------------
 This diagnostic is enabled by default.
@@ -1306,7 +1339,13 @@
 --------------
 This diagnostic is enabled by default.
 
-Controls `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_.
+Also controls `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_.
+
+**Diagnostic text:**
+
++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`mangled name of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will change in C++17 due to non-throwing exception specification in function signature`|
++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 
 -Wc++1z-extensions
@@ -1343,10 +1382,22 @@
 |:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are a C++1z feature`|
 +----------------------------------------------------------------------------------------+
 
++----------------------------------------+--------------------+-------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`'`|+------------------+|:diagtext:`' initialization statements are a C++1z extension`|
+|                                        ||:diagtext:`if`    ||                                                             |
+|                                        |+------------------+|                                                             |
+|                                        ||:diagtext:`switch`||                                                             |
+|                                        |+------------------+|                                                             |
++----------------------------------------+--------------------+-------------------------------------------------------------+
+
 +-----------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`inline variables are a C++1z extension`|
 +-----------------------------------------------------------------------------+
 
++---------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`use of multiple declarators in a single using declaration is a C++1z extension`|
++---------------------------------------------------------------------------------------------------------------------+
+
 +-------------------------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`nested namespace definition is a C++1z extension; define each namespace separately`|
 +-------------------------------------------------------------------------------------------------------------------------+
@@ -1367,6 +1418,10 @@
 |:warning:`warning:` |nbsp| :diagtext:`default scope specifier for attributes is a C++1z extension`|
 +--------------------------------------------------------------------------------------------------+
 
++-----------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`pack expansion of using declaration is a C++1z extension`|
++-----------------------------------------------------------------------------------------------+
+
 
 -Wc++98-c++11-c++14-compat
 --------------------------
@@ -1396,6 +1451,14 @@
 |:warning:`warning:` |nbsp| :diagtext:`pack fold expression is incompatible with C++ standards before C++1z`|
 +-----------------------------------------------------------------------------------------------------------+
 
++---------------------------+--------------------+----------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| |+------------------+| |nbsp| :diagtext:`initialization statements are incompatible with C++ standards before C++1z`|
+|                           ||:diagtext:`if`    ||                                                                                              |
+|                           |+------------------+|                                                                                              |
+|                           ||:diagtext:`switch`||                                                                                              |
+|                           |+------------------+|                                                                                              |
++---------------------------+--------------------+----------------------------------------------------------------------------------------------+
+
 +--------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`inline variables are incompatible with C++ standards before C++1z`|
 +--------------------------------------------------------------------------------------------------------+
@@ -1412,6 +1475,10 @@
 |:warning:`warning:` |nbsp| :diagtext:`static\_assert with no message is incompatible with C++ standards before C++1z`|
 +---------------------------------------------------------------------------------------------------------------------+
 
++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`non-type template parameters declared with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`are incompatible with C++ standards before C++1z`|
++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
 +-----------------------------------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`template template parameter using 'typename' is incompatible with C++ standards before C++1z`|
 +-----------------------------------------------------------------------------------------------------------------------------------+
@@ -1424,6 +1491,14 @@
 |:warning:`warning:` |nbsp| :diagtext:`default scope specifier for attributes is incompatible with C++ standards before C++1z`|
 +-----------------------------------------------------------------------------------------------------------------------------+
 
++------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`use of multiple declarators in a single using declaration is incompatible with C++ standards before C++1z`|
++------------------------------------------------------------------------------------------------------------------------------------------------+
+
++-----------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`pack expansion using declaration is incompatible with C++ standards before C++1z`|
++-----------------------------------------------------------------------------------------------------------------------+
+
 +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`'begin' and 'end' returning different types (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`) is incompatible with C++ standards before C++1z`|
 +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -1436,7 +1511,7 @@
 **Diagnostic text:**
 
 +---------------------------------------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`hexidecimal floating literals are incompatible with C++ standards before C++1z`|
+|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are incompatible with C++ standards before C++1z`|
 +---------------------------------------------------------------------------------------------------------------------+
 
 
@@ -2176,10 +2251,6 @@
 |:warning:`warning:` |nbsp| :diagtext:`comparison of distinct pointer types`|
 +---------------------------------------------------------------------------+
 
-+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`comparison of distinct pointer types (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`) uses non-standard composite pointer type` |nbsp| :placeholder:`C`|
-+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-
 
 -Wcomplex-component-init
 ------------------------
@@ -2343,17 +2414,6 @@
 Synonym for `-Wnull-conversion`_.
 
 
--Wcoreturn-without-coawait
---------------------------
-This diagnostic is enabled by default.
-
-**Diagnostic text:**
-
-+--------------------------------------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`'co\_return' used in a function that uses neither 'co\_await' nor 'co\_yield'`|
-+--------------------------------------------------------------------------------------------------------------------+
-
-
 -Wcovered-switch-default
 ------------------------
 **Diagnostic text:**
@@ -2390,6 +2450,10 @@
 |:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute parameter` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is negative and will be ignored`|
 +-------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
++---------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`nvcc does not allow '\_\_`:placeholder:`A`:diagtext:`\_\_' to appear after '()' in lambdas`|
++---------------------------------------------------------------------------------------------------------------------------------+
+
 +------------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`ignored 'inline' attribute on kernel function` |nbsp| :placeholder:`A`|
 +------------------------------------------------------------------------------------------------------------+
@@ -2558,7 +2622,7 @@
 ------------
 Some of the diagnostics controlled by this flag are enabled by default.
 
-Also controls `-Wdeprecated-attributes`_, `-Wdeprecated-declarations`_, `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_, `-Wdeprecated-writable-strings`_.
+Also controls `-Wdeprecated-attributes`_, `-Wdeprecated-declarations`_, `-Wdeprecated-dynamic-exception-spec`_, `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_, `-Wdeprecated-writable-strings`_.
 
 **Diagnostic text:**
 
@@ -2596,10 +2660,6 @@
 |:warning:`warning:` |nbsp| :diagtext:`treating '`:placeholder:`A`:diagtext:`' input as '`:placeholder:`B`:diagtext:`' when in C++ mode, this behavior is deprecated`|
 +--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
-+--------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`dynamic exception specifications are deprecated`|
-+--------------------------------------------------------------------------------------+
-
 +-----------------------------------------------------------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`OpenCL version` |nbsp| :placeholder:`A` |nbsp| :diagtext:`does not support the option '`:placeholder:`B`:diagtext:`'`|
 +-----------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -2647,6 +2707,15 @@
 +-------------------------------------------------------------------------------------------------------------------------------------+
 
 
+-Wdeprecated-dynamic-exception-spec
+-----------------------------------
+**Diagnostic text:**
+
++--------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`dynamic exception specifications are deprecated`|
++--------------------------------------------------------------------------------------+
+
+
 -Wdeprecated-implementations
 ----------------------------
 **Diagnostic text:**
@@ -3089,6 +3158,17 @@
 +-----------------------------------------------------------------------------------------------------------------------------------+
 
 
+-Wduplicate-protocol
+--------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++-----------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`duplicate protocol definition of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is ignored`|
++-----------------------------------------------------------------------------------------------------------------------------+
+
+
 -Wdynamic-class-memaccess
 -------------------------
 This diagnostic is enabled by default.
@@ -3108,6 +3188,19 @@
 +---------------------------+-------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------+---------------------------------------------------------------------------------------------+-------------------------+
 
 
+-Wdynamic-exception-spec
+------------------------
+Some of the diagnostics controlled by this flag are enabled by default.
+
+Also controls `-Wdeprecated-dynamic-exception-spec`_.
+
+**Diagnostic text:**
+
++--------------------------------------------------------------------------------------------+
+|:error:`error:` |nbsp| :diagtext:`ISO C++1z does not allow dynamic exception specifications`|
++--------------------------------------------------------------------------------------------+
+
+
 -Weffc++
 --------
 Synonym for `-Wnon-virtual-dtor`_.
@@ -3328,7 +3421,13 @@
 -------
 Some of the diagnostics controlled by this flag are enabled by default.
 
-Controls `-Wignored-qualifiers`_, `-Winitializer-overrides`_, `-Wmissing-field-initializers`_, `-Wmissing-method-return-type`_, `-Wsemicolon-before-method-body`_, `-Wsign-compare`_, `-Wunused-parameter`_.
+Also controls `-Wignored-qualifiers`_, `-Winitializer-overrides`_, `-Wmissing-field-initializers`_, `-Wmissing-method-return-type`_, `-Wsemicolon-before-method-body`_, `-Wsign-compare`_, `-Wunused-parameter`_.
+
+**Diagnostic text:**
+
++-----------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`call to function without interrupt attribute could clobber interruptee's VFP registers`|
++-----------------------------------------------------------------------------------------------------------------------------+
 
 
 -Wextra-qualification
@@ -3498,6 +3597,10 @@
 
 **Diagnostic text:**
 
++-------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`using '%%P' format specifier without precision`|
++-------------------------------------------------------------------------------------+
+
 +---------------------------+----------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| |+--------------------------------------------+| |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' should not be used as format arguments; add an explicit cast to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`instead`|
 |                           ||:diagtext:`values of type`                  ||                                                                                                                                                                     |
@@ -3514,6 +3617,10 @@
 |                                                                                                                                    |+---------------------------+|                        |
 +------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+
 
++----------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`using '`:placeholder:`A`:diagtext:`' format specifier annotation outside of os\_log()/os\_trace()`|
++----------------------------------------------------------------------------------------------------------------------------------------+
+
 +-----------------------------------------------------------------------------+-----------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`invalid position specified for` |nbsp| |+---------------------------+|
 |                                                                             ||:diagtext:`field width`    ||
@@ -3756,6 +3863,10 @@
 
 **Diagnostic text:**
 
++--------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`'diagnose\_if' is a clang extension`|
++--------------------------------------------------------------------------+
+
 +------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`'enable\_if' is a clang extension`|
 +------------------------------------------------------------------------+
@@ -4268,6 +4379,8 @@
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 |                                                                                                ||:diagtext:`variables and functions`                                                                             ||
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
+|                                                                                                ||:diagtext:`functions and global variables`                                                                      ||
+|                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 |                                                                                                ||:diagtext:`functions, variables, and Objective-C interfaces`                                                    ||
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 |                                                                                                ||:diagtext:`functions and methods`                                                                               ||
@@ -4280,6 +4393,8 @@
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 |                                                                                                ||:diagtext:`functions, methods, and parameters`                                                                  ||
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
+|                                                                                                ||:diagtext:`functions, methods, and global variables`                                                            ||
+|                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 |                                                                                                ||:diagtext:`classes`                                                                                             ||
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 |                                                                                                ||:diagtext:`enums`                                                                                               ||
@@ -4326,7 +4441,7 @@
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 |                                                                                                ||:diagtext:`variables with static or thread storage duration`                                                    ||
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
-|                                                                                                ||:diagtext:`functions and global variables`                                                                      ||
+|                                                                                                ||:diagtext:`functions, methods, properties, and global variables`                                                ||
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 |                                                                                                ||:diagtext:`structs, unions, and typedefs`                                                                       ||
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
@@ -4346,6 +4461,8 @@
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 |                                                                                                ||:diagtext:`variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members`||
 |                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
+|                                                                                                ||:diagtext:`classes and enumerations`                                                                            ||
+|                                                                                                |+----------------------------------------------------------------------------------------------------------------+|
 +------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
 
 +--------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -4516,10 +4633,27 @@
 +--------------------------------------------------------------------------------------------------------+
 
 
+-Wignored-pragma-intrinsic
+--------------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++------------------------------------------------------------------------------------------+------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not a recognized builtin`|+----------------------------------------------------------------------------+|
+|                                                                                          ||                                                                            ||
+|                                                                                          |+----------------------------------------------------------------------------+|
+|                                                                                          ||:diagtext:`; consider including <intrin.h> to access non-builtin intrinsics`||
+|                                                                                          |+----------------------------------------------------------------------------+|
++------------------------------------------------------------------------------------------+------------------------------------------------------------------------------+
+
+
 -Wignored-pragmas
 -----------------
 This diagnostic is enabled by default.
 
+Also controls `-Wignored-pragma-intrinsic`_.
+
 **Diagnostic text:**
 
 +------------------------------------------------------------------------------+---------------------------+-----------------------+
@@ -4538,6 +4672,10 @@
 |                                                                                   |+-------------------------+|                       |
 +-----------------------------------------------------------------------------------+---------------------------+-----------------------+
 
++-----------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`OpenCL extension end directive mismatches begin directive - ignoring`|
++-----------------------------------------------------------------------------------------------------------+
+
 +----------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`'#pragma comment` |nbsp| :placeholder:`A`:diagtext:`' ignored`|
 +----------------------------------------------------------------------------------------------------+
@@ -4562,10 +4700,6 @@
 |:warning:`warning:` |nbsp| :diagtext:`missing ':' or ')' after` |nbsp| :placeholder:`A` |nbsp| :diagtext:`- ignoring`|
 +---------------------------------------------------------------------------------------------------------------------+
 
-+--------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`expected 'enable' or 'disable' - ignoring`|
-+--------------------------------------------------------------------------------+
-
 +---------------------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`expected identifier in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`|
 +---------------------------------------------------------------------------------------------------------------------+
@@ -4586,6 +4720,14 @@
 |:warning:`warning:` |nbsp| :diagtext:`expected non-wide string literal in '#pragma` |nbsp| :placeholder:`A`:diagtext:`'`|
 +------------------------------------------------------------------------------------------------------------------------+
 
++-------------------------------------------------------+---------------------------------------------------+------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`expected` |nbsp| |+-------------------------------------------------+| |nbsp| :diagtext:`- ignoring`|
+|                                                       ||:diagtext:`'enable', 'disable', 'begin' or 'end'`||                              |
+|                                                       |+-------------------------------------------------+|                              |
+|                                                       ||:diagtext:`'disable'`                            ||                              |
+|                                                       |+-------------------------------------------------+|                              |
++-------------------------------------------------------+---------------------------------------------------+------------------------------+
+
 +-----------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`expected ')' or ',' in '#pragma` |nbsp| :placeholder:`A`:diagtext:`'`|
 +-----------------------------------------------------------------------------------------------------------+
@@ -4610,18 +4752,14 @@
 |:warning:`warning:` |nbsp| :diagtext:`extra tokens at end of '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`|
 +---------------------------------------------------------------------------------------------------------------------+
 
++----------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`incorrect use of #pragma clang force\_cuda\_host\_device begin\|end`|
++----------------------------------------------------------------------------------------------------------+
+
 +-------------------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`'#pragma init\_seg' is only supported when targeting a Microsoft environment`|
 +-------------------------------------------------------------------------------------------------------------------+
 
-+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not a recognized builtin`|+----------------------------------------------------------------------------+|
-|                                                                                          ||                                                                            ||
-|                                                                                          |+----------------------------------------------------------------------------+|
-|                                                                                          ||:diagtext:`; consider including <intrin.h> to access non-builtin intrinsics`||
-|                                                                                          |+----------------------------------------------------------------------------+|
-+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------+
-
 +-----------------------------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`unknown action for '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`|
 +-----------------------------------------------------------------------------------------------------------------+
@@ -4894,6 +5032,25 @@
 +----------------------------------------------------------------------------+
 
 
+-Wincompatible-exception-spec
+-----------------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++--------------------------------------------------------------------------+----------------------+--------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`exception specifications of` |nbsp| |+--------------------+| |nbsp| :diagtext:`types differ`|
+|                                                                          ||:diagtext:`return`  ||                                |
+|                                                                          |+--------------------+|                                |
+|                                                                          ||:diagtext:`argument`||                                |
+|                                                                          |+--------------------+|                                |
++--------------------------------------------------------------------------+----------------------+--------------------------------+
+
++-----------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`target exception specification is not superset of source`|
++-----------------------------------------------------------------------------------------------+
+
+
 -Wincompatible-function-pointer-types
 -------------------------------------
 This diagnostic is enabled by default.
@@ -5133,6 +5290,21 @@
 +---------------------------------------------------------------------------------------------------------------------------------------+
 
 
+-Winjected-class-name
+---------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------+--------------------------------------------------------------+------------------------+---------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`ISO C++ specifies that qualified reference to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is a constructor name rather than a` |nbsp| |+-------------------------+| |nbsp| :diagtext:`in this context, despite preceding` |nbsp| |+----------------------+| |nbsp| :diagtext:`keyword`|
+|                                                                                                                                                                           ||:diagtext:`template name`||                                                              ||:diagtext:`'typename'`||                           |
+|                                                                                                                                                                           |+-------------------------+|                                                              |+----------------------+|                           |
+|                                                                                                                                                                           ||:diagtext:`type`         ||                                                              ||:diagtext:`'template'`||                           |
+|                                                                                                                                                                           |+-------------------------+|                                                              |+----------------------+|                           |
++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------+--------------------------------------------------------------+------------------------+---------------------------+
+
+
 -Winline
 --------
 This diagnostic flag exists for GCC compatibility, and has no effect in Clang.
@@ -5354,6 +5526,21 @@
 +------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 
+-Winvalid-partial-specialization
+--------------------------------
+This diagnostic is an error by default, but the flag ``-Wno-invalid-partial-specialization`` can be used to disable the error.
+
+**Diagnostic text:**
+
++-----------------------+----------------------+-----------------------------------------------------------------------------------------------------+
+|:error:`error:` |nbsp| |+--------------------+| |nbsp| :diagtext:`template partial specialization is not more specialized than the primary template`|
+|                       ||:diagtext:`class`   ||                                                                                                     |
+|                       |+--------------------+|                                                                                                     |
+|                       ||:diagtext:`variable`||                                                                                                     |
+|                       |+--------------------+|                                                                                                     |
++-----------------------+----------------------+-----------------------------------------------------------------------------------------------------+
+
+
 -Winvalid-pch
 -------------
 This diagnostic flag exists for GCC compatibility, and has no effect in Clang.
@@ -5475,14 +5662,7 @@
 
 -Wliblto
 --------
-This diagnostic is enabled by default.
-
-**Diagnostic text:**
-
-+-------------------------------------------------------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead`|
-+-------------------------------------------------------------------------------------------------------------------------------------+
-
+This diagnostic flag exists for GCC compatibility, and has no effect in Clang.
 
 -Wliteral-conversion
 --------------------
@@ -5529,9 +5709,13 @@
 
 **Diagnostic text:**
 
-+-----------------------------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`logical not is only applied to the left hand side of this comparison`|
-+-----------------------------------------------------------------------------------------------------------+
++--------------------------------------------------------------------------------------------------------+------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`logical not is only applied to the left hand side of this` |nbsp| |+----------------------------+|
+|                                                                                                        ||:diagtext:`comparison`      ||
+|                                                                                                        |+----------------------------+|
+|                                                                                                        ||:diagtext:`bitwise operator`||
+|                                                                                                        |+----------------------------+|
++--------------------------------------------------------------------------------------------------------+------------------------------+
 
 
 -Wlogical-op-parentheses
@@ -5598,6 +5782,10 @@
 |:warning:`warning:` |nbsp| :diagtext:`variable named 'main' with external linkage has undefined behavior`|
 +---------------------------------------------------------------------------------------------------------+
 
++------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`bool literal returned from 'main'`|
++------------------------------------------------------------------------+
+
 +---------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`'main' should not be declared static`|
 +---------------------------------------------------------------------------+
@@ -5636,6 +5824,21 @@
 +--------------------------------------------------------------------------------+
 
 
+-Wmax-unsigned-zero
+-------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++----------------------------------------------------------------+---------------------------------------+------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`taking the max of` |nbsp| |+-------------------------------------+| |nbsp| :diagtext:`is always equal to the other value`|
+|                                                                ||:diagtext:`a value and unsigned zero`||                                                      |
+|                                                                |+-------------------------------------+|                                                      |
+|                                                                ||:diagtext:`unsigned zero and a value`||                                                      |
+|                                                                |+-------------------------------------+|                                                      |
++----------------------------------------------------------------+---------------------------------------+------------------------------------------------------+
+
+
 -Wmemsize-comparison
 --------------------
 This diagnostic is enabled by default.
@@ -6340,7 +6543,7 @@
 ------
 Some of the diagnostics controlled by this flag are enabled by default.
 
-Controls `-Wcast-of-sel-type`_, `-Wchar-subscripts`_, `-Wcomment`_, `-Wdelete-non-virtual-dtor`_, `-Wextern-c-compat`_, `-Wfor-loop-analysis`_, `-Wformat`_, `-Wimplicit`_, `-Winfinite-recursion`_, `-Wmismatched-tags`_, `-Wmissing-braces`_, `-Wmove`_, `-Wmultichar`_, `-Wobjc-designated-initializers`_, `-Wobjc-missing-super-calls`_, `-Woverloaded-virtual`_, `-Wprivate-extern`_, `-Wreorder`_, `-Wreturn-type`_, `-Wself-assign`_, `-Wself-move`_, `-Wsizeof-array-argument`_, `-Wsizeof-array-decay`_, `-Wstring-plus-int`_, `-Wtrigraphs`_, `-Wuninitialized`_, `-Wunknown-pragmas`_, `-Wunused`_, `-Wvolatile-register-var`_.
+Controls `-Wcast-of-sel-type`_, `-Wchar-subscripts`_, `-Wcomment`_, `-Wdelete-non-virtual-dtor`_, `-Wextern-c-compat`_, `-Wfor-loop-analysis`_, `-Wformat`_, `-Wimplicit`_, `-Winfinite-recursion`_, `-Wmismatched-tags`_, `-Wmissing-braces`_, `-Wmove`_, `-Wmultichar`_, `-Wobjc-designated-initializers`_, `-Wobjc-missing-super-calls`_, `-Woverloaded-virtual`_, `-Wprivate-extern`_, `-Wreorder`_, `-Wreturn-type`_, `-Wself-assign`_, `-Wself-move`_, `-Wsizeof-array-argument`_, `-Wsizeof-array-decay`_, `-Wstring-plus-int`_, `-Wtrigraphs`_, `-Wuninitialized`_, `-Wunknown-pragmas`_, `-Wunused`_, `-Wuser-defined-warnings`_, `-Wvolatile-register-var`_.
 
 
 -Wmove
@@ -6447,9 +6650,9 @@
 -----------------------------------------
 **Diagnostic text:**
 
-+---------------------------------------------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`include of non-modular header inside framework module '`:placeholder:`A`:diagtext:`'`|
-+---------------------------------------------------------------------------------------------------------------------------+
++-----------------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`include of non-modular header inside framework module '`:placeholder:`A`:diagtext:`': '`:placeholder:`B`:diagtext:`'`|
++-----------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 
 -Wnon-modular-include-in-module
@@ -6458,9 +6661,9 @@
 
 **Diagnostic text:**
 
-+-----------------------------------------------------------------------------------------------------------------+
-|:warning:`warning:` |nbsp| :diagtext:`include of non-modular header inside module '`:placeholder:`A`:diagtext:`'`|
-+-----------------------------------------------------------------------------------------------------------------+
++-------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`include of non-modular header inside module '`:placeholder:`A`:diagtext:`': '`:placeholder:`B`:diagtext:`'`|
++-------------------------------------------------------------------------------------------------------------------------------------------------+
 
 
 -Wnon-pod-varargs
@@ -6668,6 +6871,8 @@
 --------------------------
 This diagnostic is enabled by default.
 
+Also controls `-Wnullability-completeness-on-arrays`_.
+
 **Diagnostic text:**
 
 +---------------------------+----------------------------+-----------------------------------------------------------------------------------------------------------+
@@ -6681,6 +6886,17 @@
 +---------------------------+----------------------------+-----------------------------------------------------------------------------------------------------------+
 
 
+-Wnullability-completeness-on-arrays
+------------------------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++----------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`array parameter is missing a nullability type specifier (\_Nonnull, \_Nullable, or \_Null\_unspecified)`|
++----------------------------------------------------------------------------------------------------------------------------------------------+
+
+
 -Wnullability-declspec
 ----------------------
 This diagnostic is an error by default, but the flag ``-Wno-nullability-declspec`` can be used to disable the error.
@@ -6711,6 +6927,21 @@
 +---------------------------------------------------------------------------------------------------------------------------------+
 
 
+-Wnullability-inferred-on-nested-type
+-------------------------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++--------------------------------------------------------------------------------------------+-----------------------+---------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`inferring '\_Nonnull' for pointer type within` |nbsp| |+---------------------+| |nbsp| :diagtext:`is deprecated`|
+|                                                                                            ||:diagtext:`array`    ||                                 |
+|                                                                                            |+---------------------+|                                 |
+|                                                                                            ||:diagtext:`reference`||                                 |
+|                                                                                            |+---------------------+|                                 |
++--------------------------------------------------------------------------------------------+-----------------------+---------------------------------+
+
+
 -Wnullable-to-nonnull-conversion
 --------------------------------
 **Diagnostic text:**
@@ -7188,6 +7419,10 @@
 
 **Diagnostic text:**
 
++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`The OpenMP offloading target '`:placeholder:`A`:diagtext:`' is similar to target '`:placeholder:`B`:diagtext:`' already specified - will be ignored.`|
++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
 +-----------------------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`declaration is not declared in any declare target region`|
 +-----------------------------------------------------------------------------------------------+
@@ -7468,6 +7703,10 @@
 |:warning:`warning:` |nbsp| :diagtext:`'enable\_if' is a clang extension`|
 +------------------------------------------------------------------------+
 
++--------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`'diagnose\_if' is a clang extension`|
++--------------------------------------------------------------------------+
+
 +--------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`designated initializers are a C99 feature`|
 +--------------------------------------------------------------------------------+
@@ -8040,6 +8279,17 @@
 +----------------------------------------------------------------------------------------------------------------+
 
 
+-Wprivate-module
+----------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`top-level module '`:placeholder:`A`:diagtext:`' in private module map, expected a submodule of '`:placeholder:`B`:diagtext:`'`|
++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+
 -Wprofile-instr-out-of-date
 ---------------------------
 This diagnostic is enabled by default.
@@ -8364,6 +8614,10 @@
 |                                                   |+--------------------+|                                                                 |
 +---------------------------------------------------+----------------------+-----------------------------------------------------------------+
 
++--------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`control reaches end of non-void coroutine`|
++--------------------------------------------------------------------------------+
+
 +-------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`control reaches end of non-void function`|
 +-------------------------------------------------------------------------------+
@@ -8372,6 +8626,10 @@
 |:warning:`warning:` |nbsp| :diagtext:`control reaches end of non-void lambda`|
 +-----------------------------------------------------------------------------+
 
++----------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`control may reach end of non-void coroutine`|
++----------------------------------------------------------------------------------+
+
 +---------------------------------------------------------------------------------+
 |:warning:`warning:` |nbsp| :diagtext:`control may reach end of non-void function`|
 +---------------------------------------------------------------------------------+
@@ -8593,7 +8851,7 @@
 ------------
 Some of the diagnostics controlled by this flag are enabled by default.
 
-Controls `-Wshadow`_, `-Wshadow-field-in-constructor`_.
+Controls `-Wshadow`_, `-Wshadow-field-in-constructor`_, `-Wshadow-uncaptured-local`_.
 
 
 -Wshadow-field-in-constructor
@@ -8627,6 +8885,29 @@
 +------------------------------------------------------------------------------------------------------------------------------+
 
 
+-Wshadow-uncaptured-local
+-------------------------
+**Diagnostic text:**
+
++--------------------------------------------------------------------+-------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`declaration shadows a` |nbsp| |+-----------------------------------------------------------+|
+|                                                                    ||:diagtext:`local variable`                                 ||
+|                                                                    |+-----------------------------------------------------------+|
+|                                                                    ||+-----------------------------------------------+          ||
+|                                                                    |||:diagtext:`variable in` |nbsp| :placeholder:`C`|          ||
+|                                                                    ||+-----------------------------------------------+          ||
+|                                                                    |+-----------------------------------------------------------+|
+|                                                                    ||+---------------------------------------------------------+||
+|                                                                    |||:diagtext:`static data member of` |nbsp| :placeholder:`C`|||
+|                                                                    ||+---------------------------------------------------------+||
+|                                                                    |+-----------------------------------------------------------+|
+|                                                                    ||+--------------------------------------------+             ||
+|                                                                    |||:diagtext:`field of` |nbsp| :placeholder:`C`|             ||
+|                                                                    ||+--------------------------------------------+             ||
+|                                                                    |+-----------------------------------------------------------+|
++--------------------------------------------------------------------+-------------------------------------------------------------+
+
+
 -Wshift-count-negative
 ----------------------
 This diagnostic is enabled by default.
@@ -8726,6 +9007,15 @@
 ------------
 This diagnostic flag exists for GCC compatibility, and has no effect in Clang.
 
+-Wsigned-enum-bitfield
+----------------------
+**Diagnostic text:**
+
++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`enums in the Microsoft ABI are signed integers by default; consider giving the enum` |nbsp| :placeholder:`A` |nbsp| :diagtext:`an unsigned underlying type to make this code portable`|
++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+
 -Wsizeof-array-argument
 -----------------------
 This diagnostic is enabled by default.
@@ -8957,7 +9247,29 @@
 
 -Wstrict-prototypes
 -------------------
-This diagnostic flag exists for GCC compatibility, and has no effect in Clang.
+**Diagnostic text:**
+
++---------------------------------------------------+--------------------------------------------------------------+-------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`this` |nbsp| |+------------------------------------------------------------+| |nbsp| :diagtext:`a prototype`|
+|                                                   ||:diagtext:`function declaration is not`                     ||                               |
+|                                                   |+------------------------------------------------------------+|                               |
+|                                                   ||:diagtext:`old-style function definition is not preceded by`||                               |
+|                                                   |+------------------------------------------------------------+|                               |
++---------------------------------------------------+--------------------------------------------------------------+-------------------------------+
+
+
+-Wstrict-prototypes
+-------------------
+**Diagnostic text:**
+
++---------------------------------------------------+--------------------------------------------------------------+-------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`this` |nbsp| |+------------------------------------------------------------+| |nbsp| :diagtext:`a prototype`|
+|                                                   ||:diagtext:`function declaration is not`                     ||                               |
+|                                                   |+------------------------------------------------------------+|                               |
+|                                                   ||:diagtext:`old-style function definition is not preceded by`||                               |
+|                                                   |+------------------------------------------------------------+|                               |
++---------------------------------------------------+--------------------------------------------------------------+-------------------------------+
+
 
 -Wstrict-selector-match
 -----------------------
@@ -9587,6 +9899,17 @@
 +-------------------------------------------------------------------------------------------------------------------------------------+
 
 
+-Wunable-to-open-stats-file
+---------------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
++-------------------------------------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`unable to open statistics output file '`:placeholder:`A`:diagtext:`': '`:placeholder:`B`:diagtext:`'`|
++-------------------------------------------------------------------------------------------------------------------------------------------+
+
+
 -Wunavailable-declarations
 --------------------------
 This diagnostic is enabled by default.
@@ -10113,11 +10436,26 @@
 +------------------------------------------------------------------------------------------------------+
 
 
+-Wunusable-partial-specialization
+---------------------------------
+This diagnostic is an error by default, but the flag ``-Wno-unusable-partial-specialization`` can be used to disable the error.
+
+**Diagnostic text:**
+
++-----------------------+----------------------+--------------------------------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------+
+|:error:`error:` |nbsp| |+--------------------+| |nbsp| :diagtext:`template partial specialization contains` |nbsp| |+--------------------------------+| |nbsp| :diagtext:`that cannot be deduced; this partial specialization will never be used`|
+|                       ||:diagtext:`class`   ||                                                                    ||:diagtext:`a template parameter`||                                                                                          |
+|                       |+--------------------+|                                                                    |+--------------------------------+|                                                                                          |
+|                       ||:diagtext:`variable`||                                                                    ||:diagtext:`template parameters` ||                                                                                          |
+|                       |+--------------------+|                                                                    |+--------------------------------+|                                                                                          |
++-----------------------+----------------------+--------------------------------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------+
+
+
 -Wunused
 --------
 Some of the diagnostics controlled by this flag are enabled by default.
 
-Controls `-Wunused-argument`_, `-Wunused-function`_, `-Wunused-label`_, `-Wunused-local-typedef`_, `-Wunused-private-field`_, `-Wunused-property-ivar`_, `-Wunused-value`_, `-Wunused-variable`_.
+Controls `-Wunused-argument`_, `-Wunused-function`_, `-Wunused-label`_, `-Wunused-lambda-capture`_, `-Wunused-local-typedef`_, `-Wunused-private-field`_, `-Wunused-property-ivar`_, `-Wunused-value`_, `-Wunused-variable`_.
 
 
 -Wunused-argument
@@ -10237,6 +10575,19 @@
 +---------------------------------------------------------------------------+
 
 
+-Wunused-lambda-capture
+-----------------------
+**Diagnostic text:**
+
++---------------------------------------------------------------------------------------------------------------+--------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`lambda capture` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not` |nbsp| |+------------------------------------------------+|
+|                                                                                                               ||:diagtext:`used`                                ||
+|                                                                                                               |+------------------------------------------------+|
+|                                                                                                               ||:diagtext:`required to be captured for this use`||
+|                                                                                                               |+------------------------------------------------+|
++---------------------------------------------------------------------------------------------------------------+--------------------------------------------------+
+
+
 -Wunused-local-typedef
 ----------------------
 **Diagnostic text:**
@@ -10384,6 +10735,15 @@
 +--------------------------------------------------------------------------------------------------------+----------------------------------------------------+
 
 
+-Wuser-defined-warnings
+-----------------------
+This diagnostic is enabled by default.
+
+**Diagnostic text:**
+
+The text of this diagnostic is not controlled by Clang.
+
+
 -Wvarargs
 ---------
 This diagnostic is enabled by default.
@@ -10422,6 +10782,17 @@
 +------------------------------------------------------------------------+
 
 
+-Wvec-elem-size
+---------------
+This diagnostic is an error by default, but the flag ``-Wno-vec-elem-size`` can be used to disable the error.
+
+**Diagnostic text:**
+
++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|:error:`error:` |nbsp| :diagtext:`vector operands do not have the same elements sizes (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`)`|
++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+
 -Wvector-conversion
 -------------------
 **Diagnostic text:**
diff --git a/docs/ExternalClangExamples.rst b/docs/ExternalClangExamples.rst
index e6076a5..c9734ec 100644
--- a/docs/ExternalClangExamples.rst
+++ b/docs/ExternalClangExamples.rst
@@ -85,3 +85,8 @@
     errors, fixit hints).  See also `<http://l.rw.rw/clang_plugin>`_ for
     step-by-step instructions."
 
+`<https://phabricator.kde.org/source/clazy>`_
+   "clazy is a compiler plugin which allows clang to understand Qt semantics.
+   You get more than 50 Qt related compiler warnings, ranging from unneeded
+   memory allocations to misusage of API, including fix-its for automatic
+   refactoring."
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index 64e6ffb..164dfc5 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -1776,6 +1776,46 @@
 <http://llvm.org/docs/LangRef.html#llvm-canonicalize-intrinsic>`_ for
 more information on the semantics.
 
+String builtins
+---------------
+
+Clang provides constant expression evaluation support for builtins forms of
+the following functions from the C standard library ``<string.h>`` header:
+
+* ``memchr``
+* ``memcmp``
+* ``strchr``
+* ``strcmp``
+* ``strlen``
+* ``strncmp``
+* ``wcschr``
+* ``wcscmp``
+* ``wcslen``
+* ``wcsncmp``
+* ``wmemchr``
+* ``wmemcmp``
+
+In each case, the builtin form has the name of the C library function prefixed
+by ``__builtin_``. Example:
+
+.. code-block:: c
+
+  void *p = __builtin_memchr("foobar", 'b', 5);
+
+In addition to the above, one further builtin is provided:
+
+.. code-block:: c
+
+  char *__builtin_char_memchr(const char *haystack, int needle, size_t size);
+
+``__builtin_char_memchr(a, b, c)`` is identical to
+``(char*)__builtin_memchr(a, b, c)`` except that its use is permitted within
+constant expressions in C++11 onwards (where a cast from ``void*`` to ``char*``
+is disallowed in general).
+
+Support for constant expression evaluation for the above builtins be detected
+with ``__has_feature(cxx_constexpr_string_builtins)``.
+
 .. _langext-__c11_atomic:
 
 __c11_atomic builtins
diff --git a/docs/LibASTMatchers.rst b/docs/LibASTMatchers.rst
index 738de79..aea9f32 100644
--- a/docs/LibASTMatchers.rst
+++ b/docs/LibASTMatchers.rst
@@ -103,7 +103,7 @@
 processing.
 
 ``VariadicDynCastAllOfMatchers`` are callable classes that model variadic
-template functions in C++03.  They take an aribtrary number of
+template functions in C++03.  They take an arbitrary number of
 ``Matcher<Derived>`` and return a ``Matcher<Base>``.
 
 ``AST_MATCHER_P(Type, Name, ParamType, Param)``
diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html
index 2a8d864..0fd7a74 100644
--- a/docs/LibASTMatchersReference.html
+++ b/docs/LibASTMatchersReference.html
@@ -2430,7 +2430,8 @@
 
 
 <tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>&gt;</td><td class="name" onclick="toggle('hasBitWidth0')"><a name="hasBitWidth0Anchor">hasBitWidth</a></td><td>unsigned Width</td></tr>
-<tr><td colspan="4" class="doc" id="hasBitWidth0"><pre>Matches non-static data members that are bit-fields.
+<tr><td colspan="4" class="doc" id="hasBitWidth0"><pre>Matches non-static data members that are bit-fields of the specified
+bit width.
 
 Given
   class C {
@@ -2438,7 +2439,7 @@
     int b : 4;
     int c : 2;
   };
-fieldDecl(isBitField())
+fieldDecl(hasBitWidth(2))
   matches 'int a;' and 'int c;' but not 'int b;'.
 </pre></td></tr>
 
@@ -4750,6 +4751,22 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>&gt;</td><td class="name" onclick="toggle('hasInClassInitializer0')"><a name="hasInClassInitializer0Anchor">hasInClassInitializer</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasInClassInitializer0"><pre>Matches non-static data members that have an in-class initializer.
+
+Given
+  class C {
+    int a = 2;
+    int b = 3;
+    int c;
+  };
+fieldDecl(hasInClassInitializer(integerLiteral(equals(2))))
+  matches 'int a;' but not 'int b;'.
+fieldDecl(hasInClassInitializer(anything()))
+  matches 'int a;' and 'int b;' but not 'int c;'.
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>&gt;</td><td class="name" onclick="toggle('hasBody1')"><a name="hasBody1Anchor">hasBody</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="hasBody1"><pre>Matches a 'for', 'while', 'do while' statement or a function
 definition that has a given body.
@@ -5402,7 +5419,7 @@
 
 
 <tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('forFunction0')"><a name="forFunction0Anchor">forFunction</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="forFunction0"><pre>Matches declaration of the function the statemenet belongs to
+<tr><td colspan="4" class="doc" id="forFunction0"><pre>Matches declaration of the function the statement belongs to
 
 Given:
 F&amp; operator=(const F&amp; o) {
diff --git a/docs/LibASTMatchersTutorial.rst b/docs/LibASTMatchersTutorial.rst
index 603b2fa..baf2c1c 100644
--- a/docs/LibASTMatchersTutorial.rst
+++ b/docs/LibASTMatchersTutorial.rst
@@ -496,9 +496,9 @@
 
       void LoopPrinter::run(const MatchFinder::MatchResult &Result) {
         ASTContext *Context = Result.Context;
-        const ForStmt *FS = Result.Nodes.getStmtAs<ForStmt>("forLoop");
+        const ForStmt *FS = Result.Nodes.getNodeAs<ForStmt>("forLoop");
         // We do not want to convert header files!
-        if (!FS || !Context->getSourceManager().isFromMainFile(FS->getForLoc()))
+        if (!FS || !Context->getSourceManager().isWrittenInMainFile(FS->getForLoc()))
           return;
         const VarDecl *IncVar = Result.Nodes.getNodeAs<VarDecl>("incVarName");
         const VarDecl *CondVar = Result.Nodes.getNodeAs<VarDecl>("condVarName");
diff --git a/docs/MSVCCompatibility.rst b/docs/MSVCCompatibility.rst
index ead0ae8..b82869b 100644
--- a/docs/MSVCCompatibility.rst
+++ b/docs/MSVCCompatibility.rst
@@ -72,14 +72,11 @@
 .. _/vm: http://msdn.microsoft.com/en-us/library/yad46a6z.aspx
 .. _pointer to a member of a virtual base class: http://llvm.org/PR15713
 
-* Debug info: :partial:`Minimal`.  Clang emits both CodeView line tables
-  (similar to what MSVC emits when given the ``/Z7`` flag) and DWARF debug
-  information into the object file.
-  Microsoft's link.exe will transform the CodeView line tables into a PDB,
-  enabling stack traces in all modern Windows debuggers.  Clang does not emit
-  any CodeView-compatible type info or description of variable layout.
-  Binaries linked with either binutils' ld or LLVM's lld should be usable with
-  GDB however sophisticated C++ expressions are likely to fail.
+* Debug info: :good:`Mostly complete`.  Clang emits relatively complete CodeView
+  debug information if ``/Z7`` or ``/Zi`` is passed. Microsoft's link.exe will
+  transform the CodeView debug information into a PDB that works in Windows
+  debuggers and other tools that consume PDB files like ETW. Work to teach lld
+  about CodeView and PDBs is ongoing.
 
 * RTTI: :good:`Complete`.  Generation of RTTI data structures has been
   finished, along with support for the ``/GR`` flag.
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 11ee88f..d22857e 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,5 +1,5 @@
 =======================================
-Clang 4.0.0 (In-Progress) Release Notes
+Clang 5.0.0 (In-Progress) Release Notes
 =======================================
 
 .. contents::
@@ -10,15 +10,15 @@
 
 .. warning::
 
-   These are in-progress notes for the upcoming Clang 4.0.0 release. You may
-   prefer the `Clang 3.9 Release Notes
-   <http://llvm.org/releases/3.9.0/tools/clang/docs/ReleaseNotes.html>`_.
+   These are in-progress notes for the upcoming Clang 5 release.
+   Release notes for previous releases can be found on
+   `the Download Page <http://releases.llvm.org/download.html>`_.
 
 Introduction
 ============
 
 This document contains the release notes for the Clang C/C++/Objective-C
-frontend, part of the LLVM Compiler Infrastructure, release 4.0.0. Here we
+frontend, part of the LLVM Compiler Infrastructure, release 5.0.0. Here we
 describe the status of Clang in some detail, including major
 improvements from the previous release and new feature work. For the
 general LLVM release notes, see `the LLVM
@@ -36,7 +36,7 @@
 the current one. To see the release notes for a specific release, please
 see the `releases page <http://llvm.org/releases/>`_.
 
-What's New in Clang 4.0.0?
+What's New in Clang 5.0.0?
 ==========================
 
 Some of the major new features and improvements to Clang are listed
@@ -52,16 +52,12 @@
 Improvements to Clang's diagnostics
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
--  ...
+-  -Wunused-lambda-capture warns when a variable explicitly captured
+   by a lambda is not used in the body of the lambda.
 
 New Compiler Flags
 ------------------
 
-The option -Og has been added to optimize the debugging experience.
-For now, this option is exactly the same as -O1. However, in the future,
-some other optimizations might be enabled or disabled.
-
-
 The option ....
 
 New Pragmas in Clang
@@ -121,7 +117,7 @@
 Internal API Changes
 --------------------
 
-These are major API changes that have happened since the 3.9 release of
+These are major API changes that have happened since the 4.0.0 release of
 Clang. If upgrading an external codebase that uses Clang as a library,
 this section should help get you past the largest hurdles of upgrading.
 
@@ -137,9 +133,6 @@
 
 ...
 
-With the option --show-description, scan-build's list of defects will also
-show the description of the defects.
-
 
 Static Analyzer
 ---------------
diff --git a/docs/SanitizerCoverage.rst b/docs/SanitizerCoverage.rst
index 3e8102a..8ff5bdf 100644
--- a/docs/SanitizerCoverage.rst
+++ b/docs/SanitizerCoverage.rst
@@ -227,7 +227,8 @@
 Caller-callee coverage
 ======================
 
-(Experimental!)
+**Deprecated, don't use**
+
 Every indirect function call is instrumented with a run-time function call that
 captures caller and callee.  At the shutdown time the process dumps a separate
 file called ``caller-callee.PID.sancov`` which contains caller/callee pairs as
@@ -253,6 +254,8 @@
 Coverage counters
 =================
 
+**Deprecated, don't use**
+
 This experimental feature is inspired by
 `AFL <http://lcamtuf.coredump.cx/afl/technical_details.txt>`__'s coverage
 instrumentation. With additional compile-time and run-time flags you can get
@@ -296,6 +299,9 @@
 
 Tracing basic blocks
 ====================
+
+**Deprecated, don't use**
+
 Experimental support for basic block (or edge) tracing.
 With ``-fsanitize-coverage=trace-bb`` the compiler will insert
 ``__sanitizer_cov_trace_basic_block(s32 *id)`` before every function, basic block, or edge
@@ -319,6 +325,9 @@
 
 Tracing PCs
 ===========
+
+**Deprecated, don't use**
+
 *Experimental* feature similar to tracing basic blocks, but with a different API.
 With ``-fsanitize-coverage=trace-pc`` the compiler will insert
 ``__sanitizer_cov_trace_pc()`` on every edge.
@@ -331,16 +340,13 @@
 
 Tracing PCs with guards
 =======================
-Another *experimental* feature that tries to combine the functionality of `trace-pc`,
-`8bit-counters` and boolean coverage.
 
 With ``-fsanitize-coverage=trace-pc-guard`` the compiler will insert the following code
 on every edge:
 
 .. code-block:: none
 
-   if (guard_variable)
-     __sanitizer_cov_trace_pc_guard(&guard_variable)
+   __sanitizer_cov_trace_pc_guard(&guard_variable)
 
 Every edge will have its own `guard_variable` (uint32_t).
 
@@ -349,10 +355,11 @@
 .. code-block:: c++
 
    // The guards are [start, stop).
-   // This function may be called multiple times with the same values of start/stop.
+   // This function will be called at least once per DSO and may be called
+   // more than once with the same values of start/stop.
    __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop);
 
-Similarly to `trace-pc,indirect-calls`, with `trace-pc-guards,indirect-calls`
+With `trace-pc-guards,indirect-calls`
 ``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call.
 
 The functions `__sanitizer_cov_trace_pc_*` should be defined by the user.
@@ -367,10 +374,10 @@
   #include <sanitizer/coverage_interface.h>
 
   // This callback is inserted by the compiler as a module constructor
-  // into every compilation unit. 'start' and 'stop' correspond to the
+  // into every DSO. 'start' and 'stop' correspond to the
   // beginning and end of the section with the guards for the entire
-  // binary (executable or DSO) and so it will be called multiple times
-  // with the same parameters.
+  // binary (executable or DSO). The callback will be called at least
+  // once per DSO and may be called multiple times with the same parameters.
   extern "C" void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
                                                       uint32_t *stop) {
     static uint64_t N;  // Counter for the guards.
diff --git a/docs/SourceBasedCodeCoverage.rst b/docs/SourceBasedCodeCoverage.rst
index abb6823..474af30 100644
--- a/docs/SourceBasedCodeCoverage.rst
+++ b/docs/SourceBasedCodeCoverage.rst
@@ -18,6 +18,7 @@
   various sanitizers. It can provide up to edge-level coverage.
 
 * gcov - A GCC-compatible coverage implementation which operates on DebugInfo.
+  This is enabled by ``-ftest-coverage`` or ``--coverage``.
 
 From this point onwards "code coverage" will refer to the source-based kind.
 
@@ -256,6 +257,8 @@
   otherwise. Calling this function multiple times appends profile data to an
   existing on-disk raw profile.
 
+In C++ files, declare these as ``extern "C"``.
+
 Collecting coverage reports for the llvm project
 ================================================
 
diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst
index 09ee78f..f9111ee 100644
--- a/docs/UndefinedBehaviorSanitizer.rst
+++ b/docs/UndefinedBehaviorSanitizer.rst
@@ -92,6 +92,12 @@
      parameter which is declared to never be null.
   -  ``-fsanitize=null``: Use of a null pointer or creation of a null
      reference.
+  -  ``-fsanitize=nullability-arg``: Passing null as a function parameter
+     which is annotated with ``_Nonnull``.
+  -  ``-fsanitize=nullability-assign``: Assigning null to an lvalue which
+     is annotated with ``_Nonnull``.
+  -  ``-fsanitize=nullability-return``: Returning null from a function with
+     a return type annotated with ``_Nonnull``.
   -  ``-fsanitize=object-size``: An attempt to potentially use bytes which
      the optimizer can determine are not part of the object being accessed.
      This will also detect some types of undefined behavior that may not
@@ -117,7 +123,9 @@
   -  ``-fsanitize=unreachable``: If control flow reaches
      ``__builtin_unreachable``.
   -  ``-fsanitize=unsigned-integer-overflow``: Unsigned integer
-     overflows.
+     overflows. Note that unlike signed integer overflow, unsigned integer
+     is not undefined behavior. However, while it has well-defined semantics,
+     it is often unintentional, so UBSan offers to catch it.
   -  ``-fsanitize=vla-bound``: A variable-length array whose bound
      does not evaluate to a positive value.
   -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that
@@ -128,11 +136,15 @@
 
 You can also use the following check groups:
   -  ``-fsanitize=undefined``: All of the checks listed above other than
-     ``unsigned-integer-overflow``.
+     ``unsigned-integer-overflow`` and the ``nullability-*`` checks.
   -  ``-fsanitize=undefined-trap``: Deprecated alias of
      ``-fsanitize=undefined``.
   -  ``-fsanitize=integer``: Checks for undefined or suspicious integer
      behavior (e.g. unsigned integer overflow).
+  -  ``-fsanitize=nullability``: Enables ``nullability-arg``,
+     ``nullability-assign``, and ``nullability-return``. While violating
+     nullability does not have undefined behavior, it is often unintentional,
+     so UBSan offers to catch it.
 
 Stack traces and report symbolization
 =====================================
diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst
index 26c8521..beb55ca 100644
--- a/docs/UsersManual.rst
+++ b/docs/UsersManual.rst
@@ -41,6 +41,7 @@
    variants depending on base language.
 -  :ref:`C++ Language <cxx>`
 -  :ref:`Objective C++ Language <objcxx>`
+-  :ref:`OpenCL C Language <opencl>`: v1.0, v1.1, v1.2, v2.0.
 
 In addition to these base languages and their dialects, Clang supports a
 broad variety of language extensions, which are documented in the
@@ -756,6 +757,7 @@
   #if foo
   #endif foo // warning: extra tokens at end of #endif directive
 
+  #pragma clang diagnostic push
   #pragma clang diagnostic ignored "-Wextra-tokens"
 
   #if foo
@@ -1096,6 +1098,14 @@
    the behavior of sanitizers in the ``cfi`` group to allow checking
    of cross-DSO virtual and indirect calls.
 
+
+.. option:: -fstrict-vtable-pointers
+
+   Enable optimizations based on the strict rules for overwriting polymorphic
+   C++ objects, i.e. the vptr is invariant during an object's lifetime.
+   This enables better devirtualization. Turned off by default, because it is
+   still experimental.
+
 .. option:: -ffast-math
 
    Enable fast-math mode. This defines the ``__FAST_MATH__`` preprocessor
@@ -1686,6 +1696,22 @@
 
   Generate complete debug info.
 
+Controlling Macro Debug Info Generation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Debug info for C preprocessor macros increases the size of debug information in
+the binary. Macro debug info generated by Clang can be controlled by the flags
+listed below.
+
+.. option:: -fdebug-macro
+
+  Generate debug info for preprocessor macros. This flag is discarded when
+  **-g0** is enabled.
+
+.. option:: -fno-debug-macro
+
+  Do not generate debug info for preprocessor macros (default).
+
 Controlling Debugger "Tuning"
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1830,6 +1856,10 @@
      ...
      local_function(1);
 
+-  clang only supports global register variables when the register specified
+   is non-allocatable (e.g. the stack pointer). Support for general global
+   register variables is unlikely to be implemented soon because it requires
+   additional LLVM backend support.
 -  clang does not support static initialization of flexible array
    members. This appears to be a rarely used extension, but could be
    implemented pending user demand.
@@ -1849,7 +1879,7 @@
 currently excludes C++; see :ref:`C++ Language Features <cxx>`. Also, this
 list does not include bugs in mostly-implemented features; please see
 the `bug
-tracker <http://llvm.org/bugs/buglist.cgi?quicksearch=product%3Aclang+component%3A-New%2BBugs%2CAST%2CBasic%2CDriver%2CHeaders%2CLLVM%2BCodeGen%2Cparser%2Cpreprocessor%2CSemantic%2BAnalyzer>`_
+tracker <https://bugs.llvm.org/buglist.cgi?quicksearch=product%3Aclang+component%3A-New%2BBugs%2CAST%2CBasic%2CDriver%2CHeaders%2CLLVM%2BCodeGen%2Cparser%2Cpreprocessor%2CSemantic%2BAnalyzer>`_
 for known existing bugs (FIXME: Is there a section for bug-reporting
 guidelines somewhere?).
 
@@ -1969,6 +1999,402 @@
  is provided or target does not support TLS, code generation for threadprivate
  variables relies on OpenMP runtime library.
 
+.. _opencl:
+
+OpenCL Features
+===============
+
+Clang can be used to compile OpenCL kernels for execution on a device
+(e.g. GPU). It is possible to compile the kernel into a binary (e.g. for AMD or
+Nvidia targets) that can be uploaded to run directly on a device (e.g. using
+`clCreateProgramWithBinary
+<https://www.khronos.org/registry/OpenCL/specs/opencl-1.1.pdf#111>`_) or
+into generic bitcode files loadable into other toolchains.
+
+Compiling to a binary using the default target from the installation can be done
+as follows:
+
+   .. code-block:: console
+
+     $ echo "kernel void k(){}" > test.cl
+     $ clang test.cl
+
+Compiling for a specific target can be done by specifying the triple corresponding
+to the target, for example:
+
+   .. code-block:: console
+
+     $ clang -target nvptx64-unknown-unknown test.cl
+     $ clang -target amdgcn-amd-amdhsa-opencl test.cl
+
+Compiling to bitcode can be done as follows:
+
+   .. code-block:: console
+
+     $ clang -c -emit-llvm test.cl
+
+This will produce a generic test.bc file that can be used in vendor toolchains
+to perform machine code generation.
+
+Clang currently supports OpenCL C language standards up to v2.0.
+
+OpenCL Specific Options
+-----------------------
+
+Most of the OpenCL build options from `the specification v2.0 section 5.8.4
+<https://www.khronos.org/registry/cl/specs/opencl-2.0.pdf#200>`_ are available.
+
+Examples:
+
+   .. code-block:: console
+
+     $ clang -cl-std=CL2.0 -cl-single-precision-constant test.cl
+
+Some extra options are available to support special OpenCL features.
+
+.. option:: -finclude-default-header
+
+Loads standard includes during compilations. By default OpenCL headers are not
+loaded and therefore standard library includes are not available. To load them
+automatically a flag has been added to the frontend (see also :ref:`the section
+on the OpenCL Header <opencl_header>`):
+
+   .. code-block:: console
+
+     $ clang -Xclang -finclude-default-header test.cl
+
+Alternatively ``-include`` or ``-I`` followed by the path to the header location
+can be given manually.
+
+   .. code-block:: console
+
+     $ clang -I<path to clang>/lib/Headers/opencl-c.h test.cl
+
+In this case the kernel code should contain ``#include <opencl-c.h>`` just as a
+regular C include.
+
+.. _opencl_cl_ext:
+
+.. option:: -cl-ext
+
+Disables support of OpenCL extensions. All OpenCL targets provide a list
+of extensions that they support. Clang allows to amend this using the ``-cl-ext``
+flag with a comma-separated list of extensions prefixed with ``'+'`` or ``'-'``.
+The syntax: ``-cl-ext=<(['-'|'+']<extension>[,])+>``,  where extensions
+can be either one of `the OpenCL specification extensions
+<https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/EXTENSION.html>`_
+or any known vendor extension. Alternatively, ``'all'`` can be used to enable
+or disable all known extensions.
+Example disabling double support for the 64-bit SPIR target:
+
+   .. code-block:: console
+
+     $ clang -cc1 -triple spir64-unknown-unknown -cl-ext=-cl_khr_fp64 test.cl
+
+Enabling all extensions except double support in R600 AMD GPU can be done using:
+
+   .. code-block:: console
+
+     $ clang -cc1 -triple r600-unknown-unknown -cl-ext=-all,+cl_khr_fp16 test.cl
+
+.. _opencl_fake_address_space_map:
+
+.. option:: -ffake-address-space-map
+
+Overrides the target address space map with a fake map.
+This allows adding explicit address space IDs to the bitcode for non-segmented
+memory architectures that don't have separate IDs for each of the OpenCL
+logical address spaces by default. Passing ``-ffake-address-space-map`` will
+add/override address spaces of the target compiled for with the following values:
+``1-global``, ``2-constant``, ``3-local``, ``4-generic``. The private address
+space is represented by the absence of an address space attribute in the IR (see
+also :ref:`the section on the address space attribute <opencl_addrsp>`).
+
+   .. code-block:: console
+
+     $ clang -ffake-address-space-map test.cl
+
+Some other flags used for the compilation for C can also be passed while
+compiling for OpenCL, examples: ``-c``, ``-O<1-4|s>``, ``-o``, ``-emit-llvm``, etc.
+
+OpenCL Targets
+--------------
+
+OpenCL targets are derived from the regular Clang target classes. The OpenCL
+specific parts of the target representation provide address space mapping as
+well as a set of supported extensions.
+
+Specific Targets
+^^^^^^^^^^^^^^^^
+
+There is a set of concrete HW architectures that OpenCL can be compiled for.
+
+- For AMD target:
+
+   .. code-block:: console
+
+     $ clang -target amdgcn-amd-amdhsa-opencl test.cl
+
+- For Nvidia architectures:
+
+   .. code-block:: console
+
+     $ clang -target nvptx64-unknown-unknown test.cl
+
+
+Generic Targets
+^^^^^^^^^^^^^^^
+
+- SPIR is available as a generic target to allow portable bitcode to be produced
+  that can be used across GPU toolchains. The implementation follows `the SPIR
+  specification <https://www.khronos.org/spir>`_. There are two flavors
+  available for 32 and 64 bits.
+
+   .. code-block:: console
+
+    $ clang -target spir-unknown-unknown test.cl
+    $ clang -target spir64-unknown-unknown test.cl
+
+  All known OpenCL extensions are supported in the SPIR targets. Clang will
+  generate SPIR v1.2 compatible IR for OpenCL versions up to 2.0 and SPIR v2.0
+  for OpenCL v2.0.
+
+- x86 is used by some implementations that are x86 compatible and currently
+  remains for backwards compatibility (with older implementations prior to
+  SPIR target support). For "non-SPMD" targets which cannot spawn multiple
+  work-items on the fly using hardware, which covers practically all non-GPU
+  devices such as CPUs and DSPs, additional processing is needed for the kernels
+  to support multiple work-item execution. For this, a 3rd party toolchain,
+  such as for example `POCL <http://portablecl.org/>`_, can be used.
+
+  This target does not support multiple memory segments and, therefore, the fake
+  address space map can be added using the :ref:`-ffake-address-space-map
+  <opencl_fake_address_space_map>` flag.
+
+.. _opencl_header:
+
+OpenCL Header
+-------------
+
+By default Clang will not include standard headers and therefore OpenCL builtin
+functions and some types (i.e. vectors) are unknown. The default CL header is,
+however, provided in the Clang installation and can be enabled by passing the
+``-finclude-default-header`` flag to the Clang frontend.
+
+   .. code-block:: console
+
+     $ echo "bool is_wg_uniform(int i){return get_enqueued_local_size(i)==get_local_size(i);}" > test.cl
+     $ clang -Xclang -finclude-default-header -cl-std=CL2.0 test.cl
+
+Because the header is very large and long to parse, PCH (:doc:`PCHInternals`)
+and modules (:doc:`Modules`) are used internally to improve the compilation
+speed.
+
+To enable modules for OpenCL:
+
+   .. code-block:: console
+
+     $ clang -target spir-unknown-unknown -c -emit-llvm -Xclang -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=<path to the generated module> test.cl
+
+OpenCL Extensions
+-----------------
+
+All of the ``cl_khr_*`` extensions from `the official OpenCL specification
+<https://www.khronos.org/registry/OpenCL/sdk/2.0/docs/man/xhtml/EXTENSION.html>`_
+up to and including version 2.0 are available and set per target depending on the
+support available in the specific architecture.
+
+It is possible to alter the default extensions setting per target using
+``-cl-ext`` flag. (See :ref:`flags description <opencl_cl_ext>` for more details).
+
+Vendor extensions can be added flexibly by declaring the list of types and
+functions associated with each extensions enclosed within the following
+compiler pragma directives:
+
+  .. code-block:: c
+
+       #pragma OPENCL EXTENSION the_new_extension_name : begin
+       // declare types and functions associated with the extension here
+       #pragma OPENCL EXTENSION the_new_extension_name : end
+
+For example, parsing the following code adds ``my_t`` type and ``my_func``
+function to the custom ``my_ext`` extension.
+
+  .. code-block:: c
+
+       #pragma OPENCL EXTENSION my_ext : begin
+       typedef struct{
+         int a;
+       }my_t;
+       void my_func(my_t);
+       #pragma OPENCL EXTENSION my_ext : end
+
+Declaring the same types in different vendor extensions is disallowed.
+
+OpenCL Metadata
+---------------
+
+Clang uses metadata to provide additional OpenCL semantics in IR needed for
+backends and OpenCL runtime.
+
+Each kernel will have function metadata attached to it, specifying the arguments.
+Kernel argument metadata is used to provide source level information for querying
+at runtime, for example using the `clGetKernelArgInfo 
+<https://www.khronos.org/registry/OpenCL/specs/opencl-1.2.pdf#167>`_
+call.
+
+Note that ``-cl-kernel-arg-info`` enables more information about the original CL
+code to be added e.g. kernel parameter names will appear in the OpenCL metadata
+along with other information. 
+
+The IDs used to encode the OpenCL's logical address spaces in the argument info
+metadata follows the SPIR address space mapping as defined in the SPIR
+specification `section 2.2
+<https://www.khronos.org/registry/spir/specs/spir_spec-2.0.pdf#18>`_
+
+OpenCL-Specific Attributes
+--------------------------
+
+OpenCL support in Clang contains a set of attribute taken directly from the
+specification as well as additional attributes.
+
+See also :doc:`AttributeReference`.
+
+nosvm
+^^^^^
+
+Clang supports this attribute to comply to OpenCL v2.0 conformance, but it
+does not have any effect on the IR. For more details reffer to the specification
+`section 6.7.2
+<https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#49>`_
+
+
+opencl_unroll_hint
+^^^^^^^^^^^^^^^^^^
+
+The implementation of this feature mirrors the unroll hint for C.
+More details on the syntax can be found in the specification
+`section 6.11.5
+<https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#61>`_
+
+convergent
+^^^^^^^^^^
+
+To make sure no invalid optimizations occur for single program multiple data
+(SPMD) / single instruction multiple thread (SIMT) Clang provides attributes that
+can be used for special functions that have cross work item semantics.
+An example is the subgroup operations such as `intel_sub_group_shuffle 
+<https://www.khronos.org/registry/cl/extensions/intel/cl_intel_subgroups.txt>`_
+
+   .. code-block:: c
+
+     // Define custom my_sub_group_shuffle(data, c)
+     // that makes use of intel_sub_group_shuffle
+     r1 = ... 
+     if (r0) r1 = computeA();
+     // Shuffle data from r1 into r3
+     // of threads id r2.
+     r3 = my_sub_group_shuffle(r1, r2);
+     if (r0) r3 = computeB();
+
+with non-SPMD semantics this is optimized to the following equivalent code:
+
+   .. code-block:: c
+
+     r1 = ...
+     if (!r0)
+       // Incorrect functionality! The data in r1
+       // have not been computed by all threads yet.
+       r3 = my_sub_group_shuffle(r1, r2);
+     else {
+       r1 = computeA();
+       r3 = my_sub_group_shuffle(r1, r2);
+       r3 = computeB();
+     }
+
+Declaring the function ``my_sub_group_shuffle`` with the convergent attribute
+would prevent this:
+
+   .. code-block:: c
+
+     my_sub_group_shuffle() __attribute__((convergent));
+
+Using ``convergent`` guarantees correct execution by keeping CFG equivalence
+wrt operations marked as ``convergent``. CFG ``G´`` is equivalent to ``G`` wrt
+node ``Ni`` : ``iff ∀ Nj (i≠j)`` domination and post-domination relations with
+respect to ``Ni`` remain the same in both ``G`` and ``G´``. 
+
+noduplicate
+^^^^^^^^^^^
+
+``noduplicate`` is more restrictive with respect to optimizations than
+``convergent`` because a convergent function only preserves CFG equivalence.
+This allows some optimizations to happen as long as the control flow remains
+unmodified.
+
+   .. code-block:: c
+
+     for (int i=0; i<4; i++)
+       my_sub_group_shuffle()
+
+can be modified to:
+
+   .. code-block:: c
+
+     my_sub_group_shuffle();
+     my_sub_group_shuffle();
+     my_sub_group_shuffle();
+     my_sub_group_shuffle();
+
+while using ``noduplicate`` would disallow this. Also ``noduplicate`` doesn't
+have the same safe semantics of CFG as ``convergent`` and can cause changes in
+CFG that modify semantics of the original program.
+
+``noduplicate`` is kept for backwards compatibility only and it considered to be
+deprecated for future uses.
+
+.. _opencl_addrsp:
+
+address_space
+^^^^^^^^^^^^^
+
+Clang has arbitrary address space support using the ``address_space(N)``
+attribute, where ``N`` is an integer number in the range ``0`` to ``16777215``
+(``0xffffffu``).
+
+An OpenCL implementation provides a list of standard address spaces using
+keywords: ``private``, ``local``, ``global``, and ``generic``. In the AST and
+in the IR local, global, or generic will be represented by the address space
+attribute with the corresponding unique number. Note that private does not have
+any corresponding attribute added and, therefore, is represented by the absence
+of an address space number. The specific IDs for an address space do not have to
+match between the AST and the IR. Typically in the AST address space numbers
+represent logical segments while in the IR they represent physical segments.
+Therefore, machines with flat memory segments can map all AST address space
+numbers to the same physical segment ID or skip address space attribute
+completely while generating the IR. However, if the address space information
+is needed by the IR passes e.g. to improve alias analysis, it is recommended
+to keep it and only lower to reflect physical memory segments in the late
+machine passes.
+
+OpenCL builtins
+---------------
+
+There are some standard OpenCL functions that are implemented as Clang builtins:
+
+- All pipe functions from `section 6.13.16.2/6.13.16.3
+  <https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#160>`_ of
+  the OpenCL v2.0 kernel language specification. `
+
+- Address space qualifier conversion functions ``to_global``/``to_local``/``to_private``
+  from `section 6.13.9
+  <https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#101>`_.
+
+- All the ``enqueue_kernel`` functions from `section 6.13.17.1
+  <https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#164>`_ and
+  enqueue query functions from `section 6.13.17.5
+  <https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#171>`_.
+
 .. _target_features:
 
 Target-Specific Features and Limitations
@@ -2090,7 +2516,7 @@
 Clang expects the GCC executable "gcc.exe" compiled for
 ``i686-w64-mingw32`` (or ``x86_64-w64-mingw32``) to be present on PATH.
 
-`Some tests might fail <http://llvm.org/bugs/show_bug.cgi?id=9072>`_ on
+`Some tests might fail <https://bugs.llvm.org/show_bug.cgi?id=9072>`_ on
 ``x86_64-w64-mingw32``.
 
 .. _clang-cl:
@@ -2098,7 +2524,7 @@
 clang-cl
 ========
 
-clang-cl is an alternative command-line interface to Clang driver, designed for
+clang-cl is an alternative command-line interface to Clang, designed for
 compatibility with the Visual C++ compiler, cl.exe.
 
 To enable clang-cl to find system headers, libraries, and the linker when run
@@ -2106,7 +2532,7 @@
 Command Prompt or a regular Command Prompt where the environment has been set
 up using e.g. `vcvars32.bat <http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx>`_.
 
-clang-cl can also be used from inside Visual Studio  by using an LLVM Platform
+clang-cl can also be used from inside Visual Studio by using an LLVM Platform
 Toolset.
 
 Command-Line Options
@@ -2133,7 +2559,7 @@
 
     clang-cl.exe: error: no such file or directory: '/foobar'
 
-Please `file a bug <http://llvm.org/bugs/enter_bug.cgi?product=clang&component=Driver>`_
+Please `file a bug <https://bugs.llvm.org/enter_bug.cgi?product=clang&component=Driver>`_
 for any valid cl.exe flags that clang-cl does not understand.
 
 Execute ``clang-cl /?`` to see a list of supported options:
@@ -2141,116 +2567,125 @@
   ::
 
     CL.EXE COMPATIBILITY OPTIONS:
-      /?                     Display available options
-      /arch:<value>          Set architecture for code generation
-      /Brepro-               Emit an object file which cannot be reproduced over time
-      /Brepro                Emit an object file which can be reproduced over time
-      /C                     Don't discard comments when preprocessing
-      /c                     Compile only
-      /D <macro[=value]>     Define macro
-      /EH<value>             Exception handling model
-      /EP                    Disable linemarker output and preprocess to stdout
-      /E                     Preprocess to stdout
-      /fallback              Fall back to cl.exe if clang-cl fails to compile
-      /FA                    Output assembly code file during compilation
-      /Fa<file or directory> Output assembly code to this file during compilation (with /FA)
-      /Fe<file or directory> Set output executable file or directory (ends in / or \)
-      /FI <value>            Include file before parsing
-      /Fi<file>              Set preprocess output file name (with /P)
-      /Fo<file or directory> Set output object file, or directory (ends in / or \) (with /c)
+      /?                      Display available options
+      /arch:<value>           Set architecture for code generation
+      /Brepro-                Emit an object file which cannot be reproduced over time
+      /Brepro                 Emit an object file which can be reproduced over time
+      /C                      Don't discard comments when preprocessing
+      /c                      Compile only
+      /D <macro[=value]>      Define macro
+      /EH<value>              Exception handling model
+      /EP                     Disable linemarker output and preprocess to stdout
+      /execution-charset:<value>
+                              Runtime encoding, supports only UTF-8
+      /E                      Preprocess to stdout
+      /fallback               Fall back to cl.exe if clang-cl fails to compile
+      /FA                     Output assembly code file during compilation
+      /Fa<file or directory>  Output assembly code to this file during compilation (with /FA)
+      /Fe<file or directory>  Set output executable file or directory (ends in / or \)
+      /FI <value>             Include file before parsing
+      /Fi<file>               Set preprocess output file name (with /P)
+      /Fo<file or directory>  Set output object file, or directory (ends in / or \) (with /c)
       /fp:except-
       /fp:except
       /fp:fast
       /fp:precise
       /fp:strict
-      /Fp<filename>          Set pch filename (with /Yc and /Yu)
-      /GA                    Assume thread-local variables are defined in the executable
-      /Gd                    Set __cdecl as a default calling convention
-      /GF-                   Disable string pooling
-      /GR-                   Disable emission of RTTI data
-      /GR                    Enable emission of RTTI data
-      /Gr                    Set __fastcall as a default calling convention
-      /GS-                   Disable buffer security check
-      /GS                    Enable buffer security check
-      /Gs<value>             Set stack probe size
-      /Gv                    Set __vectorcall as a default calling convention
-      /Gw-                   Don't put each data item in its own section
-      /Gw                    Put each data item in its own section
-      /GX-                   Enable exception handling
-      /GX                    Enable exception handling
-      /Gy-                   Don't put each function in its own section
-      /Gy                    Put each function in its own section
-      /Gz                    Set __stdcall as a default calling convention
-      /help                  Display available options
-      /imsvc <dir>           Add directory to system include search path, as if part of %INCLUDE%
-      /I <dir>               Add directory to include search path
-      /J                     Make char type unsigned
-      /LDd                   Create debug DLL
-      /LD                    Create DLL
-      /link <options>        Forward options to the linker
-      /MDd                   Use DLL debug run-time
-      /MD                    Use DLL run-time
-      /MTd                   Use static debug run-time
-      /MT                    Use static run-time
-      /Od                    Disable optimization
-      /Oi-                   Disable use of builtin functions
-      /Oi                    Enable use of builtin functions
-      /Os                    Optimize for size
-      /Ot                    Optimize for speed
-      /O<value>              Optimization level
-      /o <file or directory> Set output file or directory (ends in / or \)
-      /P                     Preprocess to file
-      /Qvec-                 Disable the loop vectorization passes
-      /Qvec                  Enable the loop vectorization passes
-      /showIncludes          Print info about included files to stderr
-      /std:<value>           Language standard to compile for
-      /TC                    Treat all source files as C
-      /Tc <filename>         Specify a C source file
-      /TP                    Treat all source files as C++
-      /Tp <filename>         Specify a C++ source file
-      /U <macro>             Undefine macro
-      /vd<value>             Control vtordisp placement
-      /vmb                   Use a best-case representation method for member pointers
-      /vmg                   Use a most-general representation for member pointers
-      /vmm                   Set the default most-general representation to multiple inheritance
-      /vms                   Set the default most-general representation to single inheritance
-      /vmv                   Set the default most-general representation to virtual inheritance
-      /volatile:iso          Volatile loads and stores have standard semantics
-      /volatile:ms           Volatile loads and stores have acquire and release semantics
-      /W0                    Disable all warnings
-      /W1                    Enable -Wall
-      /W2                    Enable -Wall
-      /W3                    Enable -Wall
-      /W4                    Enable -Wall and -Wextra
-      /Wall                  Enable -Wall and -Wextra
-      /WX-                   Do not treat warnings as errors
-      /WX                    Treat warnings as errors
-      /w                     Disable all warnings
-      /Y-                    Disable precompiled headers, overrides /Yc and /Yu
-      /Yc<filename>          Generate a pch file for all code up to and including <filename>
-      /Yu<filename>          Load a pch file and use it instead of all code up to and including <filename>
-      /Z7                    Enable CodeView debug information in object files
-      /Zc:sizedDealloc-      Disable C++14 sized global deallocation functions
-      /Zc:sizedDealloc       Enable C++14 sized global deallocation functions
-      /Zc:strictStrings      Treat string literals as const
-      /Zc:threadSafeInit-    Disable thread-safe initialization of static variables
-      /Zc:threadSafeInit     Enable thread-safe initialization of static variables
-      /Zc:trigraphs-         Disable trigraphs (default)
-      /Zc:trigraphs          Enable trigraphs
-      /Zd                    Emit debug line number tables only
-      /Zi                    Alias for /Z7. Does not produce PDBs.
-      /Zl                    Don't mention any default libraries in the object file
-      /Zp                    Set the default maximum struct packing alignment to 1
-      /Zp<value>             Specify the default maximum struct packing alignment
-      /Zs                    Syntax-check only
+      /Fp<filename>           Set pch filename (with /Yc and /Yu)
+      /GA                     Assume thread-local variables are defined in the executable
+      /Gd                     Set __cdecl as a default calling convention
+      /GF-                    Disable string pooling
+      /GR-                    Disable emission of RTTI data
+      /GR                     Enable emission of RTTI data
+      /Gr                     Set __fastcall as a default calling convention
+      /GS-                    Disable buffer security check
+      /GS                     Enable buffer security check
+      /Gs<value>              Set stack probe size
+      /Gv                     Set __vectorcall as a default calling convention
+      /Gw-                    Don't put each data item in its own section
+      /Gw                     Put each data item in its own section
+      /GX-                    Enable exception handling
+      /GX                     Enable exception handling
+      /Gy-                    Don't put each function in its own section
+      /Gy                     Put each function in its own section
+      /Gz                     Set __stdcall as a default calling convention
+      /help                   Display available options
+      /imsvc <dir>            Add directory to system include search path, as if part of %INCLUDE%
+      /I <dir>                Add directory to include search path
+      /J                      Make char type unsigned
+      /LDd                    Create debug DLL
+      /LD                     Create DLL
+      /link <options>         Forward options to the linker
+      /MDd                    Use DLL debug run-time
+      /MD                     Use DLL run-time
+      /MTd                    Use static debug run-time
+      /MT                     Use static run-time
+      /Od                     Disable optimization
+      /Oi-                    Disable use of builtin functions
+      /Oi                     Enable use of builtin functions
+      /Os                     Optimize for size
+      /Ot                     Optimize for speed
+      /O<value>               Optimization level
+      /o <file or directory>  Set output file or directory (ends in / or \)
+      /P                      Preprocess to file
+      /Qvec-                  Disable the loop vectorization passes
+      /Qvec                   Enable the loop vectorization passes
+      /showIncludes           Print info about included files to stderr
+      /source-charset:<value> Source encoding, supports only UTF-8
+      /std:<value>            Language standard to compile for
+      /TC                     Treat all source files as C
+      /Tc <filename>          Specify a C source file
+      /TP                     Treat all source files as C++
+      /Tp <filename>          Specify a C++ source file
+      /utf-8                  Set source and runtime encoding to UTF-8 (default)
+      /U <macro>              Undefine macro
+      /vd<value>              Control vtordisp placement
+      /vmb                    Use a best-case representation method for member pointers
+      /vmg                    Use a most-general representation for member pointers
+      /vmm                    Set the default most-general representation to multiple inheritance
+      /vms                    Set the default most-general representation to single inheritance
+      /vmv                    Set the default most-general representation to virtual inheritance
+      /volatile:iso           Volatile loads and stores have standard semantics
+      /volatile:ms            Volatile loads and stores have acquire and release semantics
+      /W0                     Disable all warnings
+      /W1                     Enable -Wall
+      /W2                     Enable -Wall
+      /W3                     Enable -Wall
+      /W4                     Enable -Wall and -Wextra
+      /Wall                   Enable -Wall and -Wextra
+      /WX-                    Do not treat warnings as errors
+      /WX                     Treat warnings as errors
+      /w                      Disable all warnings
+      /Y-                     Disable precompiled headers, overrides /Yc and /Yu
+      /Yc<filename>           Generate a pch file for all code up to and including <filename>
+      /Yu<filename>           Load a pch file and use it instead of all code up to and including <filename>
+      /Z7                     Enable CodeView debug information in object files
+      /Zc:sizedDealloc-       Disable C++14 sized global deallocation functions
+      /Zc:sizedDealloc        Enable C++14 sized global deallocation functions
+      /Zc:strictStrings       Treat string literals as const
+      /Zc:threadSafeInit-     Disable thread-safe initialization of static variables
+      /Zc:threadSafeInit      Enable thread-safe initialization of static variables
+      /Zc:trigraphs-          Disable trigraphs (default)
+      /Zc:trigraphs           Enable trigraphs
+      /Zd                     Emit debug line number tables only
+      /Zi                     Alias for /Z7. Does not produce PDBs.
+      /Zl                     Don't mention any default libraries in the object file
+      /Zp                     Set the default maximum struct packing alignment to 1
+      /Zp<value>              Specify the default maximum struct packing alignment
+      /Zs                     Syntax-check only
 
     OPTIONS:
       -###                    Print (but do not run) the commands to run for this compilation
       --analyze               Run the static analyzer
       -fansi-escape-codes     Use ANSI escape codes for diagnostics
       -fcolor-diagnostics     Use colors in diagnostics
+      -fdelayed-template-parsing
+                              Parse templated function definitions at the end of the translation unit
+      -fdiagnostics-absolute-paths
+                              Print absolute paths in diagnostics
       -fdiagnostics-parseable-fixits
                               Print fix-its in machine parseable form
+      -flto                   Enable LTO in 'full' mode
       -fms-compatibility-version=<value>
                               Dot-separated value representing the Microsoft compiler version
                               number to report in _MSC_VER (0 = don't define it (default))
@@ -2258,12 +2693,23 @@
       -fms-extensions         Accept some non-standard constructs supported by the Microsoft compiler
       -fmsc-version=<value>   Microsoft compiler version number to report in _MSC_VER
                               (0 = don't define it (default))
+      -fno-delayed-template-parsing
+                              Disable delayed template parsing
       -fno-sanitize-coverage=<value>
                               Disable specified features of coverage instrumentation for Sanitizers
       -fno-sanitize-recover=<value>
                               Disable recovery for specified sanitizers
       -fno-sanitize-trap=<value>
                               Disable trapping for specified sanitizers
+      -fno-standalone-debug   Limit debug information produced to reduce size of debug binary
+      -fprofile-instr-generate=<file>
+                              Generate instrumented code to collect execution counts into <file>
+                              (overridden by LLVM_PROFILE_FILE env var)
+      -fprofile-instr-generate
+                              Generate instrumented code to collect execution counts into default.profraw file
+                              (overridden by '=' form of option or LLVM_PROFILE_FILE env var)
+      -fprofile-instr-use=<value>
+                              Use instrumentation data for profile-guided optimization
       -fsanitize-blacklist=<value>
                               Path to blacklist file for sanitizers
       -fsanitize-coverage=<value>
@@ -2273,6 +2719,7 @@
       -fsanitize-trap=<value> Enable trapping for specified sanitizers
       -fsanitize=<check>      Turn on runtime checks for various forms of undefined or suspicious
                               behavior. See user manual for available checks
+      -fstandalone-debug      Emit full debug info for all types used by the program
       -gcodeview              Generate CodeView debug information
       -gline-tables-only      Emit debug line number tables only
       -miamcu                 Use Intel MCU ABI
diff --git a/docs/analyzer/DebugChecks.rst b/docs/analyzer/DebugChecks.rst
index ecf11ca..880dcfc 100644
--- a/docs/analyzer/DebugChecks.rst
+++ b/docs/analyzer/DebugChecks.rst
@@ -178,15 +178,21 @@
   This function explains the value of its argument in a human-readable manner
   in the warning message. You can make as many overrides of its prototype
   in the test code as necessary to explain various integral, pointer,
-  or even record-type values.
+  or even record-type values. To simplify usage in C code (where overloading
+  the function declaration is not allowed), you may append an arbitrary suffix
+  to the function name, without affecting functionality.
 
   Example usage::
 
     void clang_analyzer_explain(int);
     void clang_analyzer_explain(void *);
 
+    // Useful in C code
+    void clang_analyzer_explain_int(int);
+
     void foo(int param, void *ptr) {
       clang_analyzer_explain(param); // expected-warning{{argument 'param'}}
+      clang_analyzer_explain_int(param); // expected-warning{{argument 'param'}}
       if (!ptr)
         clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}
     }
diff --git a/docs/analyzer/conf.py b/docs/analyzer/conf.py
index 6b54b06..c40af7a 100644
--- a/docs/analyzer/conf.py
+++ b/docs/analyzer/conf.py
@@ -48,10 +48,10 @@
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
-# The short X.Y version.
-version = '4.0'
+# The short version.
+version = '5'
 # The full version, including alpha/beta/rc tags.
-release = '4.0'
+release = '5'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/docs/conf.py b/docs/conf.py
index 4683ca5..a9861cd 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -48,10 +48,10 @@
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
-# The short X.Y version.
-version = '4.0'
+# The short version.
+version = '5'
 # The full version, including alpha/beta/rc tags.
-release = '4.0'
+release = '5'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in
index c96ab49..ef96605 100644
--- a/docs/doxygen.cfg.in
+++ b/docs/doxygen.cfg.in
@@ -1885,7 +1885,7 @@
 # The default value is: NO.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-MACRO_EXPANSION        = NO
+MACRO_EXPANSION        = YES
 
 # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
 # the macro expansion is limited to the macros specified with the PREDEFINED and
@@ -1893,7 +1893,7 @@
 # The default value is: NO.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-EXPAND_ONLY_PREDEF     = NO
+EXPAND_ONLY_PREDEF     = YES
 
 # If the SEARCH_INCLUDES tag is set to YES the includes files in the
 # INCLUDE_PATH will be searched if a #include is found.
@@ -1925,7 +1925,7 @@
 # recursively expanded use the := operator instead of the = operator.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-PREDEFINED             =
+PREDEFINED             = LLVM_ALIGNAS(x)=
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
diff --git a/docs/index.rst b/docs/index.rst
index 61f9c2c..0097ebb 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -19,6 +19,7 @@
    UsersManual
    Toolchain
    LanguageExtensions
+   ClangCommandLineReference
    AttributeReference
    DiagnosticsReference
    CrossCompilation
diff --git a/docs/tools/dump_format_style.py b/docs/tools/dump_format_style.py
index 6e14939..81a5af6 100755
--- a/docs/tools/dump_format_style.py
+++ b/docs/tools/dump_format_style.py
@@ -19,7 +19,6 @@
   return re.sub(pattern, '%s', text, flags=re.S) % replacement
 
 def doxygen2rst(text):
-  text = re.sub(r'([^/\*])\*', r'\1\\*', text)
   text = re.sub(r'<tt>\s*(.*?)\s*<\/tt>', r'``\1``', text)
   text = re.sub(r'\\c ([^ ,;\.]+)', r'``\1``', text)
   text = re.sub(r'\\\w+ ', '', text)
@@ -65,7 +64,7 @@
     self.comment = comment.strip()
 
   def __str__(self):
-    return '* ``%s`` %s' % (self.name, doxygen2rst(self.comment))
+    return '\n* ``%s`` %s' % (self.name, doxygen2rst(self.comment))
 
 class Enum:
   def __init__(self, name, comment):
diff --git a/examples/clang-interpreter/CMakeLists.txt b/examples/clang-interpreter/CMakeLists.txt
index 4c6db12..e7e59d9 100644
--- a/examples/clang-interpreter/CMakeLists.txt
+++ b/examples/clang-interpreter/CMakeLists.txt
@@ -3,6 +3,7 @@
   ExecutionEngine
   MC
   MCJIT
+  Option
   Support
   native
   )
diff --git a/examples/clang-interpreter/main.cpp b/examples/clang-interpreter/main.cpp
index 9b4a257..f783229 100644
--- a/examples/clang-interpreter/main.cpp
+++ b/examples/clang-interpreter/main.cpp
@@ -145,7 +145,7 @@
 
   // Create a compiler instance to handle the actual work.
   CompilerInstance Clang;
-  Clang.setInvocation(CI.release());
+  Clang.setInvocation(std::move(CI));
 
   // Create the compilers actual diagnostics engine.
   Clang.createDiagnostics();
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index f5d44f8..d466fce 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -326,7 +326,7 @@
  *
  * \param tu the translation unit
  *
-* \param file_name the name of the file.
+ * \param file_name the name of the file.
  *
  * \returns the file handle for the named file in the translation unit \p tu,
  * or a NULL file handle if the file was not a part of this translation unit.
@@ -2354,7 +2354,27 @@
    */
   CXCursor_OMPTeamsDistributeParallelForDirective = 274,
 
-  CXCursor_LastStmt = CXCursor_OMPTeamsDistributeParallelForDirective,
+  /** \brief OpenMP target teams directive.
+   */
+  CXCursor_OMPTargetTeamsDirective = 275,
+
+  /** \brief OpenMP target teams distribute directive.
+   */
+  CXCursor_OMPTargetTeamsDistributeDirective = 276,
+
+  /** \brief OpenMP target teams distribute parallel for directive.
+   */
+  CXCursor_OMPTargetTeamsDistributeParallelForDirective = 277,
+
+  /** \brief OpenMP target teams distribute parallel for simd directive.
+   */
+  CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective = 278,
+
+  /** \brief OpenMP target teams distribute simd directive.
+   */
+  CXCursor_OMPTargetTeamsDistributeSimdDirective = 279,
+
+  CXCursor_LastStmt = CXCursor_OMPTargetTeamsDistributeSimdDirective,
 
   /**
    * \brief Cursor that represents the translation unit itself.
@@ -2991,8 +3011,9 @@
   CXType_ObjCClass = 28,
   CXType_ObjCSel = 29,
   CXType_Float128 = 30,
+  CXType_Half = 31,
   CXType_FirstBuiltin = CXType_Void,
-  CXType_LastBuiltin  = CXType_ObjCSel,
+  CXType_LastBuiltin  = CXType_Half,
 
   CXType_Complex = 100,
   CXType_Pointer = 101,
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index e58c219..7c431f3 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -135,14 +135,15 @@
   }
   APValue(const APValue &RHS);
   APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
-  APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
+  APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
+          bool IsNullPtr = false)
       : Kind(Uninitialized) {
-    MakeLValue(); setLValue(B, O, N, CallIndex);
+    MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
   }
   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
-          bool OnePastTheEnd, unsigned CallIndex)
+          bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
       : Kind(Uninitialized) {
-    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
+    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
   }
   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
     MakeArray(InitElts, Size);
@@ -254,6 +255,7 @@
   bool hasLValuePath() const;
   ArrayRef<LValuePathEntry> getLValuePath() const;
   unsigned getLValueCallIndex() const;
+  bool isNullPointer() const;
 
   APValue &getVectorElt(unsigned I) {
     assert(isVector() && "Invalid accessor");
@@ -374,10 +376,10 @@
     ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
   }
   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
-                 unsigned CallIndex);
+                 unsigned CallIndex, bool IsNullPtr);
   void setLValue(LValueBase B, const CharUnits &O,
                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
-                 unsigned CallIndex);
+                 unsigned CallIndex, bool IsNullPtr);
   void setUnion(const FieldDecl *Field, const APValue &Value) {
     assert(isUnion() && "Invalid accessor");
     ((UnionData*)(char*)Data.buffer)->Field = Field;
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 4f35508..5fa515d 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -66,6 +66,7 @@
 #include <memory>
 #include <new>
 #include <string>
+#include <type_traits>
 #include <utility>
 #include <vector>
 
@@ -167,6 +168,8 @@
   mutable llvm::FoldingSet<DependentUnaryTransformType>
     DependentUnaryTransformTypes;
   mutable llvm::FoldingSet<AutoType> AutoTypes;
+  mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
+    DeducedTemplateSpecializationTypes;
   mutable llvm::FoldingSet<AtomicType> AtomicTypes;
   llvm::FoldingSet<AttributedType> AttributedTypes;
   mutable llvm::FoldingSet<PipeType> PipeTypes;
@@ -398,11 +401,11 @@
   llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
   TemplateOrInstantiation;
 
-  /// \brief Keeps track of the declaration from which a UsingDecl was
+  /// \brief Keeps track of the declaration from which a using declaration was
   /// created during instantiation.
   ///
-  /// The source declaration is always a UsingDecl, an UnresolvedUsingValueDecl,
-  /// or an UnresolvedUsingTypenameDecl.
+  /// The source and target declarations are always a UsingDecl, an
+  /// UnresolvedUsingValueDecl, or an UnresolvedUsingTypenameDecl.
   ///
   /// For example:
   /// \code
@@ -421,7 +424,7 @@
   ///
   /// This mapping will contain an entry that maps from the UsingDecl in
   /// B<int> to the UnresolvedUsingDecl in B<T>.
-  llvm::DenseMap<UsingDecl *, NamedDecl *> InstantiatedFromUsingDecl;
+  llvm::DenseMap<NamedDecl *, NamedDecl *> InstantiatedFromUsingDecl;
 
   llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>
     InstantiatedFromUsingShadowDecl;
@@ -849,11 +852,11 @@
   /// \brief If the given using decl \p Inst is an instantiation of a
   /// (possibly unresolved) using decl from a template instantiation,
   /// return it.
-  NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst);
+  NamedDecl *getInstantiatedFromUsingDecl(NamedDecl *Inst);
 
   /// \brief Remember that the using decl \p Inst is an instantiation
   /// of the using decl \p Pattern of a class template.
-  void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern);
+  void setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern);
 
   void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
                                           UsingShadowDecl *Pattern);
@@ -973,7 +976,7 @@
   CanQualType SingletonId;
 #include "clang/Basic/OpenCLImageTypes.def"
   CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
-  CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
+  CanQualType OCLQueueTy, OCLReserveIDTy;
   CanQualType OMPArraySectionTy;
 
   // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
@@ -1109,6 +1112,10 @@
   /// \brief Change the result type of a function type once it is deduced.
   void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
 
+  /// \brief Determine whether two function types are the same, ignoring
+  /// exception specifications in cases where they're part of the type.
+  bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U);
+
   /// \brief Change the exception specification on a function once it is
   /// delay-parsed, instantiated, or computed.
   void adjustExceptionSpec(FunctionDecl *FD,
@@ -1351,6 +1358,14 @@
       ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
       const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
 
+  TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl);
+
+  /// Get a template argument list with one argument per template parameter
+  /// in a template parameter list, such as for the injected class name of
+  /// a class template.
+  void getInjectedTemplateArgs(const TemplateParameterList *Params,
+                               SmallVectorImpl<TemplateArgument> &Args);
+
   QualType getPackExpansionType(QualType Pattern,
                                 Optional<unsigned> NumExpansions);
 
@@ -1402,6 +1417,11 @@
   /// \brief C++11 deduction pattern for 'auto &&' type.
   QualType getAutoRRefDeductType() const;
 
+  /// \brief C++1z deduced class template specialization type.
+  QualType getDeducedTemplateSpecializationType(TemplateName Template,
+                                                QualType DeducedType,
+                                                bool IsDependent) const;
+
   /// \brief Return the unique reference to the type for the specified TagDecl
   /// (struct/union/class/enum) decl.
   QualType getTagDeclType(const TagDecl *Decl) const;
@@ -2295,6 +2315,10 @@
       return (*AddrSpaceMap)[AS - LangAS::Offset];
   }
 
+  /// Get target-dependent integer value for null pointer which is used for
+  /// constant folding.
+  uint64_t getTargetNullPointerValue(QualType QT) const;
+
   bool addressSpaceMapManglingFor(unsigned AS) const {
     return AddrSpaceMapMangling || 
            AS < LangAS::Offset || 
@@ -2464,6 +2488,16 @@
   /// when it is called.
   void AddDeallocation(void (*Callback)(void*), void *Data);
 
+  /// If T isn't trivially destructible, calls AddDeallocation to register it
+  /// for destruction.
+  template <typename T>
+  void addDestruction(T *Ptr) {
+    if (!std::is_trivially_destructible<T>::value) {
+      auto DestroyPtr = [](void *V) { static_cast<T *>(V)->~T(); };
+      AddDeallocation(DestroyPtr, Ptr);
+    }
+  }
+
   GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
   GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
 
@@ -2473,7 +2507,7 @@
   ///
   /// \returns true if the function/var must be CodeGen'ed/deserialized even if
   /// it is not used.
-  bool DeclMustBeEmitted(const Decl *D);
+  bool DeclMustBeEmitted(const Decl *D, bool ForModularCodegen = false);
 
   const CXXConstructorDecl *
   getCopyConstructorForExceptionObject(CXXRecordDecl *RD);
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 9ae5fd6..717a9e9 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -22,6 +22,7 @@
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/Support/type_traits.h"
 #include <algorithm>
+#include <cstddef>
 #include <cstring>
 #include <memory>
 
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
index c0c6819..181131a 100644
--- a/include/clang/AST/BuiltinTypes.def
+++ b/include/clang/AST/BuiltinTypes.def
@@ -169,9 +169,6 @@
 // OpenCL queue_t.
 BUILTIN_TYPE(OCLQueue, OCLQueueTy)
 
-// OpenCL ndrange_t.
-BUILTIN_TYPE(OCLNDRange, OCLNDRangeTy)
-
 // OpenCL reserve_id_t.
 BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy)
 
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 432b4fc..d1c77f5 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -1601,18 +1601,18 @@
   /// no formals.
   ParmVarDecl **ParamInfo;
 
-  /// DeclsInPrototypeScope - Array of pointers to NamedDecls for
-  /// decls defined in the function prototype that are not parameters. E.g.
-  /// 'enum Y' in 'void f(enum Y {AA} x) {}'.
-  ArrayRef<NamedDecl *> DeclsInPrototypeScope;
-
   LazyDeclStmtPtr Body;
 
   // FIXME: This can be packed into the bitfields in DeclContext.
   // NOTE: VC++ packs bitfields poorly if the types differ.
-  unsigned SClass : 2;
+  unsigned SClass : 3;
   unsigned IsInline : 1;
   unsigned IsInlineSpecified : 1;
+protected:
+  // This is shared by CXXConstructorDecl, CXXConversionDecl, and
+  // CXXDeductionGuideDecl.
+  unsigned IsExplicitSpecified : 1;
+private:
   unsigned IsVirtualAsWritten : 1;
   unsigned IsPure : 1;
   unsigned HasInheritedPrototype : 1;
@@ -1713,8 +1713,9 @@
                        StartLoc),
         DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(),
         SClass(S), IsInline(isInlineSpecified),
-        IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false),
-        IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true),
+        IsInlineSpecified(isInlineSpecified), IsExplicitSpecified(false),
+        IsVirtualAsWritten(false), IsPure(false),
+        HasInheritedPrototype(false), HasWrittenPrototype(true),
         IsDeleted(false), IsTrivial(false), IsDefaulted(false),
         IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
         IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
@@ -2050,11 +2051,6 @@
     setParams(getASTContext(), NewParamInfo);
   }
 
-  ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const {
-    return DeclsInPrototypeScope;
-  }
-  void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
-
   /// getMinRequiredArguments - Returns the minimum number of arguments
   /// needed to call this function. This may be fewer than the number of
   /// function parameters, if some of the parameters have default
@@ -2071,6 +2067,10 @@
   /// limited representation in the AST.
   SourceRange getReturnTypeSourceRange() const;
 
+  /// \brief Attempt to compute an informative source range covering the
+  /// function exception specification, if any.
+  SourceRange getExceptionSpecSourceRange() const;
+
   /// \brief Determine the type of an expression that calls this function.
   QualType getCallResultType() const {
     assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 5de1d05..c88cb6a 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -654,20 +654,19 @@
   /// a precompiled header or module) rather than having been parsed.
   bool isFromASTFile() const { return FromASTFile; }
 
-  /// \brief Retrieve the global declaration ID associated with this 
-  /// declaration, which specifies where in the 
-  unsigned getGlobalID() const { 
+  /// \brief Retrieve the global declaration ID associated with this
+  /// declaration, which specifies where this Decl was loaded from.
+  unsigned getGlobalID() const {
     if (isFromASTFile())
       return *((const unsigned*)this - 1);
     return 0;
   }
-  
+
   /// \brief Retrieve the global ID of the module that owns this particular
   /// declaration.
   unsigned getOwningModuleID() const {
     if (isFromASTFile())
       return *((const unsigned*)this - 2);
-    
     return 0;
   }
 
@@ -1030,7 +1029,7 @@
   void dump() const;
   // Same as dump(), but forces color printing.
   void dumpColor() const;
-  void dump(raw_ostream &Out) const;
+  void dump(raw_ostream &Out, bool Deserialize = false) const;
 
   /// \brief Looks through the Decl's underlying type to extract a FunctionType
   /// when possible. Will return null if the type underlying the Decl does not
@@ -1811,7 +1810,8 @@
 
   void dumpDeclContext() const;
   void dumpLookups() const;
-  void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false) const;
+  void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false,
+                   bool Deserialize = false) const;
 
 private:
   void reconcileExternalVisibleStorage() const;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index b40ca28..d663dbe 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -203,6 +203,11 @@
   SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
   SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
 
+  /// \brief Get the location at which the base class type was written.
+  SourceLocation getBaseTypeLoc() const LLVM_READONLY {
+    return BaseTypeInfo->getTypeLoc().getLocStart();
+  }
+
   /// \brief Determines whether the base class is a virtual base class (or not).
   bool isVirtual() const { return Virtual; }
 
@@ -436,9 +441,10 @@
     /// either by the user or implicitly.
     unsigned DeclaredSpecialMembers : 6;
 
-    /// \brief Whether an implicit copy constructor would have a const-qualified
-    /// parameter.
-    unsigned ImplicitCopyConstructorHasConstParam : 1;
+    /// \brief Whether an implicit copy constructor could have a const-qualified
+    /// parameter, for initializing virtual bases and for other subobjects.
+    unsigned ImplicitCopyConstructorCanHaveConstParamForVBase : 1;
+    unsigned ImplicitCopyConstructorCanHaveConstParamForNonVBase : 1;
 
     /// \brief Whether an implicit copy assignment operator would have a
     /// const-qualified parameter.
@@ -458,6 +464,9 @@
     /// \brief Whether we are currently parsing base specifiers.
     unsigned IsParsingBaseSpecifiers : 1;
 
+    /// \brief A hash of parts of the class to help in ODR checking.
+    unsigned ODRHash;
+
     /// \brief The number of base class specifiers in Bases.
     unsigned NumBases;
 
@@ -703,6 +712,9 @@
     return data().IsParsingBaseSpecifiers;
   }
 
+  void computeODRHash();
+  unsigned getODRHash() const { return data().ODRHash; }
+
   /// \brief Sets the base classes of this struct or class.
   void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
 
@@ -871,7 +883,9 @@
   /// \brief Determine whether an implicit copy constructor for this type
   /// would have a parameter with a const-qualified reference type.
   bool implicitCopyConstructorHasConstParam() const {
-    return data().ImplicitCopyConstructorHasConstParam;
+    return data().ImplicitCopyConstructorCanHaveConstParamForNonVBase &&
+           (isAbstract() ||
+            data().ImplicitCopyConstructorCanHaveConstParamForVBase);
   }
 
   /// \brief Determine whether this class has a copy constructor with
@@ -1738,6 +1752,58 @@
   friend class ASTWriter;
 };
 
+/// \brief Represents a C++ deduction guide declaration.
+///
+/// \code
+/// template<typename T> struct A { A(); A(T); };
+/// A() -> A<int>;
+/// \endcode
+///
+/// In this example, there will be an explicit deduction guide from the
+/// second line, and implicit deduction guide templates synthesized from
+/// the constructors of \c A.
+class CXXDeductionGuideDecl : public FunctionDecl {
+  void anchor() override;
+private:
+  CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+                        bool IsExplicit, const DeclarationNameInfo &NameInfo,
+                        QualType T, TypeSourceInfo *TInfo,
+                        SourceLocation EndLocation)
+      : FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
+                     SC_None, false, false) {
+    if (EndLocation.isValid())
+      setRangeEnd(EndLocation);
+    IsExplicitSpecified = IsExplicit;
+  }
+
+public:
+  static CXXDeductionGuideDecl *Create(ASTContext &C, DeclContext *DC,
+                                       SourceLocation StartLoc, bool IsExplicit,
+                                       const DeclarationNameInfo &NameInfo,
+                                       QualType T, TypeSourceInfo *TInfo,
+                                       SourceLocation EndLocation);
+
+  static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  /// Whether this deduction guide is explicit.
+  bool isExplicit() const { return IsExplicitSpecified; }
+
+  /// Whether this deduction guide was declared with the 'explicit' specifier.
+  bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
+  /// Get the template for which this guide performs deduction.
+  TemplateDecl *getDeducedTemplate() const {
+    return getDeclName().getCXXDeductionGuideTemplate();
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == CXXDeductionGuide; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
 /// \brief Represents a static or instance method of a struct/union/class.
 ///
 /// In the terminology of the C++ Standard, these are the (static and
@@ -1928,8 +1994,7 @@
 ///   B(A& a) : A(a), f(3.14159) { }
 /// };
 /// \endcode
-class CXXCtorInitializer final
-    : private llvm::TrailingObjects<CXXCtorInitializer, VarDecl *> {
+class CXXCtorInitializer final {
   /// \brief Either the base class name/delegating constructor type (stored as
   /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
   /// (IndirectFieldDecl*) being initialized.
@@ -1967,14 +2032,8 @@
   unsigned IsWritten : 1;
 
   /// If IsWritten is true, then this number keeps track of the textual order
-  /// of this initializer in the original sources, counting from 0; otherwise,
-  /// it stores the number of array index variables stored after this object
-  /// in memory.
-  unsigned SourceOrderOrNumArrayIndices : 13;
-
-  CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
-                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
-                     SourceLocation R, VarDecl **Indices, unsigned NumIndices);
+  /// of this initializer in the original sources, counting from 0.
+  unsigned SourceOrder : 13;
 
 public:
   /// \brief Creates a new base-class initializer.
@@ -2000,13 +2059,6 @@
   CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
                      SourceLocation L, Expr *Init, SourceLocation R);
 
-  /// \brief Creates a new member initializer that optionally contains
-  /// array indices used to describe an elementwise initialization.
-  static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
-                                    SourceLocation MemberLoc, SourceLocation L,
-                                    Expr *Init, SourceLocation R,
-                                    VarDecl **Indices, unsigned NumIndices);
-
   /// \brief Determine whether this initializer is initializing a base class.
   bool isBaseInitializer() const {
     return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
@@ -2111,7 +2163,7 @@
   /// \brief Return the source position of the initializer, counting from 0.
   /// If the initializer was implicit, -1 is returned.
   int getSourceOrder() const {
-    return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
+    return IsWritten ? static_cast<int>(SourceOrder) : -1;
   }
 
   /// \brief Set the source order of this initializer.
@@ -2121,49 +2173,22 @@
   ///
   /// This assumes that the initializer was written in the source code, and
   /// ensures that isWritten() returns true.
-  void setSourceOrder(int pos) {
+  void setSourceOrder(int Pos) {
     assert(!IsWritten &&
+           "setSourceOrder() used on implicit initializer");
+    assert(SourceOrder == 0 &&
            "calling twice setSourceOrder() on the same initializer");
-    assert(SourceOrderOrNumArrayIndices == 0 &&
-           "setSourceOrder() used when there are implicit array indices");
-    assert(pos >= 0 &&
+    assert(Pos >= 0 &&
            "setSourceOrder() used to make an initializer implicit");
     IsWritten = true;
-    SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
+    SourceOrder = static_cast<unsigned>(Pos);
   }
 
   SourceLocation getLParenLoc() const { return LParenLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
 
-  /// \brief Determine the number of implicit array indices used while
-  /// described an array member initialization.
-  unsigned getNumArrayIndices() const {
-    return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
-  }
-
-  /// \brief Retrieve a particular array index variable used to
-  /// describe an array member initialization.
-  VarDecl *getArrayIndex(unsigned I) {
-    assert(I < getNumArrayIndices() && "Out of bounds member array index");
-    return getTrailingObjects<VarDecl *>()[I];
-  }
-  const VarDecl *getArrayIndex(unsigned I) const {
-    assert(I < getNumArrayIndices() && "Out of bounds member array index");
-    return getTrailingObjects<VarDecl *>()[I];
-  }
-  void setArrayIndex(unsigned I, VarDecl *Index) {
-    assert(I < getNumArrayIndices() && "Out of bounds member array index");
-    getTrailingObjects<VarDecl *>()[I] = Index;
-  }
-  ArrayRef<VarDecl *> getArrayIndices() {
-    return llvm::makeArrayRef(getTrailingObjects<VarDecl *>(),
-                              getNumArrayIndices());
-  }
-
   /// \brief Get the initializer.
   Expr *getInit() const { return static_cast<Expr*>(Init); }
-
-  friend TrailingObjects;
 };
 
 /// Description of a constructor that was inherited from a base class.
@@ -2202,13 +2227,9 @@
   /// \{
   /// \brief The arguments used to initialize the base or member.
   LazyCXXCtorInitializersPtr CtorInitializers;
-  unsigned NumCtorInitializers : 30;
+  unsigned NumCtorInitializers : 31;
   /// \}
 
-  /// \brief Whether this constructor declaration has the \c explicit keyword
-  /// specified.
-  unsigned IsExplicitSpecified : 1;
-
   /// \brief Whether this constructor declaration is an implicitly-declared
   /// inheriting constructor.
   unsigned IsInheritingConstructor : 1;
@@ -2222,11 +2243,11 @@
     : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
                     SC_None, isInline, isConstexpr, SourceLocation()),
       CtorInitializers(nullptr), NumCtorInitializers(0),
-      IsExplicitSpecified(isExplicitSpecified),
       IsInheritingConstructor((bool)Inherited) {
     setImplicit(isImplicitlyDeclared);
     if (Inherited)
       *getTrailingObjects<InheritedConstructor>() = Inherited;
+    IsExplicitSpecified = isExplicitSpecified;
   }
 
 public:
@@ -2239,15 +2260,6 @@
          bool isConstexpr,
          InheritedConstructor Inherited = InheritedConstructor());
 
-  /// \brief Determine whether this constructor declaration has the
-  /// \c explicit keyword specified.
-  bool isExplicitSpecified() const { return IsExplicitSpecified; }
-
-  /// \brief Determine whether this constructor was marked "explicit" or not.
-  bool isExplicit() const {
-    return cast<CXXConstructorDecl>(getFirstDecl())->isExplicitSpecified();
-  }
-
   /// \brief Iterates through the member/base initializer list.
   typedef CXXCtorInitializer **init_iterator;
 
@@ -2311,6 +2323,14 @@
     CtorInitializers = Initializers;
   }
 
+  /// Whether this function is marked as explicit explicitly.
+  bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
+  /// Whether this function is explicit.
+  bool isExplicit() const {
+    return getCanonicalDecl()->isExplicitSpecified();
+  }
+
   /// \brief Determine whether this constructor is a delegating constructor.
   bool isDelegatingConstructor() const {
     return (getNumCtorInitializers() == 1) &&
@@ -2446,7 +2466,14 @@
 
   void setOperatorDelete(FunctionDecl *OD);
   const FunctionDecl *getOperatorDelete() const {
-    return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
+    return getCanonicalDecl()->OperatorDelete;
+  }
+
+  CXXDestructorDecl *getCanonicalDecl() override {
+    return cast<CXXDestructorDecl>(FunctionDecl::getCanonicalDecl());
+  }
+  const CXXDestructorDecl *getCanonicalDecl() const {
+    return const_cast<CXXDestructorDecl*>(this)->getCanonicalDecl();
   }
 
   // Implement isa/cast/dyncast/etc.
@@ -2469,19 +2496,16 @@
 /// \endcode
 class CXXConversionDecl : public CXXMethodDecl {
   void anchor() override;
-  /// Whether this conversion function declaration is marked
-  /// "explicit", meaning that it can only be applied when the user
-  /// explicitly wrote a cast. This is a C++11 feature.
-  bool IsExplicitSpecified : 1;
 
   CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
-                    const DeclarationNameInfo &NameInfo,
-                    QualType T, TypeSourceInfo *TInfo,
-                    bool isInline, bool isExplicitSpecified,
-                    bool isConstexpr, SourceLocation EndLocation)
-    : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
-                    SC_None, isInline, isConstexpr, EndLocation),
-      IsExplicitSpecified(isExplicitSpecified) { }
+                    const DeclarationNameInfo &NameInfo, QualType T,
+                    TypeSourceInfo *TInfo, bool isInline,
+                    bool isExplicitSpecified, bool isConstexpr,
+                    SourceLocation EndLocation)
+      : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
+                      SC_None, isInline, isConstexpr, EndLocation) {
+    IsExplicitSpecified = isExplicitSpecified;
+  }
 
 public:
   static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
@@ -2493,17 +2517,12 @@
                                    SourceLocation EndLocation);
   static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
-  /// Whether this conversion function declaration is marked
-  /// "explicit", meaning that it can only be used for direct initialization
-  /// (including explitly written casts).  This is a C++11 feature.
+  /// Whether this function is marked as explicit explicitly.
   bool isExplicitSpecified() const { return IsExplicitSpecified; }
 
-  /// \brief Whether this is an explicit conversion operator (C++11 and later).
-  ///
-  /// Explicit conversion operators are only considered for direct
-  /// initialization, e.g., when the user has explicitly written a cast.
+  /// Whether this function is explicit.
   bool isExplicit() const {
-    return cast<CXXConversionDecl>(getFirstDecl())->isExplicitSpecified();
+    return getCanonicalDecl()->isExplicitSpecified();
   }
 
   /// \brief Returns the type that this conversion function is converting to.
@@ -2515,6 +2534,13 @@
   /// a lambda closure type to a block pointer.
   bool isLambdaToBlockPointerConversion() const;
   
+  CXXConversionDecl *getCanonicalDecl() override {
+    return cast<CXXConversionDecl>(FunctionDecl::getCanonicalDecl());
+  }
+  const CXXConversionDecl *getCanonicalDecl() const {
+    return const_cast<CXXConversionDecl*>(this)->getCanonicalDecl();
+  }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == CXXConversion; }
@@ -3181,6 +3207,77 @@
   friend class ASTDeclWriter;
 };
 
+/// Represents a pack of using declarations that a single
+/// using-declarator pack-expanded into.
+///
+/// \code
+/// template<typename ...T> struct X : T... {
+///   using T::operator()...;
+///   using T::operator T...;
+/// };
+/// \endcode
+///
+/// In the second case above, the UsingPackDecl will have the name
+/// 'operator T' (which contains an unexpanded pack), but the individual
+/// UsingDecls and UsingShadowDecls will have more reasonable names.
+class UsingPackDecl final
+    : public NamedDecl, public Mergeable<UsingPackDecl>,
+      private llvm::TrailingObjects<UsingPackDecl, NamedDecl *> {
+  void anchor() override;
+
+  /// The UnresolvedUsingValueDecl or UnresolvedUsingTypenameDecl from
+  /// which this waas instantiated.
+  NamedDecl *InstantiatedFrom;
+
+  /// The number of using-declarations created by this pack expansion.
+  unsigned NumExpansions;
+
+  UsingPackDecl(DeclContext *DC, NamedDecl *InstantiatedFrom,
+                ArrayRef<NamedDecl *> UsingDecls)
+      : NamedDecl(UsingPack, DC,
+                  InstantiatedFrom ? InstantiatedFrom->getLocation()
+                                   : SourceLocation(),
+                  InstantiatedFrom ? InstantiatedFrom->getDeclName()
+                                   : DeclarationName()),
+        InstantiatedFrom(InstantiatedFrom), NumExpansions(UsingDecls.size()) {
+    std::uninitialized_copy(UsingDecls.begin(), UsingDecls.end(),
+                            getTrailingObjects<NamedDecl *>());
+  }
+
+public:
+  /// Get the using declaration from which this was instantiated. This will
+  /// always be an UnresolvedUsingValueDecl or an UnresolvedUsingTypenameDecl
+  /// that is a pack expansion.
+  NamedDecl *getInstantiatedFromUsingDecl() const { return InstantiatedFrom; }
+
+  /// Get the set of using declarations that this pack expanded into. Note that
+  /// some of these may still be unresolved.
+  ArrayRef<NamedDecl *> expansions() const {
+    return llvm::makeArrayRef(getTrailingObjects<NamedDecl *>(), NumExpansions);
+  }
+
+  static UsingPackDecl *Create(ASTContext &C, DeclContext *DC,
+                               NamedDecl *InstantiatedFrom,
+                               ArrayRef<NamedDecl *> UsingDecls);
+
+  static UsingPackDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+                                           unsigned NumExpansions);
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return InstantiatedFrom->getSourceRange();
+  }
+
+  UsingPackDecl *getCanonicalDecl() override { return getFirstDecl(); }
+  const UsingPackDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == UsingPack; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+  friend TrailingObjects;
+};
+
 /// \brief Represents a dependent using declaration which was not marked with
 /// \c typename.
 ///
@@ -3199,6 +3296,9 @@
   /// \brief The source location of the 'using' keyword
   SourceLocation UsingLocation;
 
+  /// \brief If this is a pack expansion, the location of the '...'.
+  SourceLocation EllipsisLoc;
+
   /// \brief The nested-name-specifier that precedes the name.
   NestedNameSpecifierLoc QualifierLoc;
 
@@ -3209,11 +3309,12 @@
   UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
                            SourceLocation UsingLoc,
                            NestedNameSpecifierLoc QualifierLoc,
-                           const DeclarationNameInfo &NameInfo)
+                           const DeclarationNameInfo &NameInfo,
+                           SourceLocation EllipsisLoc)
     : ValueDecl(UnresolvedUsingValue, DC,
                 NameInfo.getLoc(), NameInfo.getName(), Ty),
-      UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
-      DNLoc(NameInfo.getInfo())
+      UsingLocation(UsingLoc), EllipsisLoc(EllipsisLoc),
+      QualifierLoc(QualifierLoc), DNLoc(NameInfo.getInfo())
   { }
 
 public:
@@ -3239,10 +3340,20 @@
     return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
   }
 
+  /// \brief Determine whether this is a pack expansion.
+  bool isPackExpansion() const {
+    return EllipsisLoc.isValid();
+  }
+
+  /// \brief Get the location of the ellipsis if this is a pack expansion.
+  SourceLocation getEllipsisLoc() const {
+    return EllipsisLoc;
+  }
+
   static UnresolvedUsingValueDecl *
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
            NestedNameSpecifierLoc QualifierLoc,
-           const DeclarationNameInfo &NameInfo);
+           const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc);
 
   static UnresolvedUsingValueDecl *
   CreateDeserialized(ASTContext &C, unsigned ID);
@@ -3283,6 +3394,9 @@
   /// \brief The source location of the 'typename' keyword
   SourceLocation TypenameLocation;
 
+  /// \brief If this is a pack expansion, the location of the '...'.
+  SourceLocation EllipsisLoc;
+
   /// \brief The nested-name-specifier that precedes the name.
   NestedNameSpecifierLoc QualifierLoc;
 
@@ -3290,10 +3404,12 @@
                               SourceLocation TypenameLoc,
                               NestedNameSpecifierLoc QualifierLoc,
                               SourceLocation TargetNameLoc,
-                              IdentifierInfo *TargetName)
+                              IdentifierInfo *TargetName,
+                              SourceLocation EllipsisLoc)
     : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
                UsingLoc),
-      TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
+      TypenameLocation(TypenameLoc), EllipsisLoc(EllipsisLoc),
+      QualifierLoc(QualifierLoc) { }
 
   friend class ASTDeclReader;
 
@@ -3313,10 +3429,25 @@
     return QualifierLoc.getNestedNameSpecifier();
   }
 
+  DeclarationNameInfo getNameInfo() const {
+    return DeclarationNameInfo(getDeclName(), getLocation());
+  }
+
+  /// \brief Determine whether this is a pack expansion.
+  bool isPackExpansion() const {
+    return EllipsisLoc.isValid();
+  }
+
+  /// \brief Get the location of the ellipsis if this is a pack expansion.
+  SourceLocation getEllipsisLoc() const {
+    return EllipsisLoc;
+  }
+
   static UnresolvedUsingTypenameDecl *
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
            SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
-           SourceLocation TargetNameLoc, DeclarationName TargetName);
+           SourceLocation TargetNameLoc, DeclarationName TargetName,
+           SourceLocation EllipsisLoc);
 
   static UnresolvedUsingTypenameDecl *
   CreateDeserialized(ASTContext &C, unsigned ID);
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index f5098f0..a445042 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -2320,11 +2320,9 @@
 protected:
   ObjCImplDecl(Kind DK, DeclContext *DC,
                ObjCInterfaceDecl *classInterface,
+               IdentifierInfo *Id,
                SourceLocation nameLoc, SourceLocation atStartLoc)
-    : ObjCContainerDecl(DK, DC,
-                        classInterface? classInterface->getIdentifier()
-                                      : nullptr,
-                        nameLoc, atStartLoc),
+    : ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc),
       ClassInterface(classInterface) {}
 
 public:
@@ -2386,9 +2384,6 @@
 class ObjCCategoryImplDecl : public ObjCImplDecl {
   void anchor() override;
 
-  // Category name
-  IdentifierInfo *Id;
-
   // Category name location
   SourceLocation CategoryNameLoc;
 
@@ -2396,8 +2391,9 @@
                        ObjCInterfaceDecl *classInterface,
                        SourceLocation nameLoc, SourceLocation atStartLoc,
                        SourceLocation CategoryNameLoc)
-    : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
-      Id(Id), CategoryNameLoc(CategoryNameLoc) {}
+    : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id,
+                   nameLoc, atStartLoc),
+      CategoryNameLoc(CategoryNameLoc) {}
 public:
   static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
                                       IdentifierInfo *Id,
@@ -2407,37 +2403,10 @@
                                       SourceLocation CategoryNameLoc);
   static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
-  /// getIdentifier - Get the identifier that names the category
-  /// interface associated with this implementation.
-  /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
-  /// with a different meaning. For example:
-  /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
-  /// returns the class interface name, whereas
-  /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
-  /// returns the category name.
-  IdentifierInfo *getIdentifier() const {
-    return Id;
-  }
-  void setIdentifier(IdentifierInfo *II) { Id = II; }
-
   ObjCCategoryDecl *getCategoryDecl() const;
 
   SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
 
-  /// getName - Get the name of identifier for the class interface associated
-  /// with this implementation as a StringRef.
-  //
-  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
-  // meaning.
-  StringRef getName() const { return Id ? Id->getName() : StringRef(); }
-
-  /// @brief Get the name of the class associated with this interface.
-  //
-  // FIXME: Deprecated, move clients to getName().
-  std::string getNameAsString() const {
-    return getName();
-  }
-
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
 
@@ -2493,7 +2462,10 @@
                          SourceLocation superLoc = SourceLocation(),
                          SourceLocation IvarLBraceLoc=SourceLocation(), 
                          SourceLocation IvarRBraceLoc=SourceLocation())
-    : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
+    : ObjCImplDecl(ObjCImplementation, DC, classInterface,
+                   classInterface ? classInterface->getIdentifier()
+                                  : nullptr,
+                   nameLoc, atStartLoc),
        SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
        IvarRBraceLoc(IvarRBraceLoc),
        IvarInitializers(nullptr), NumIvarInitializers(0),
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 1975bc5..30ca79e 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -173,18 +173,21 @@
   void anchor() override;
 
   OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
-                      QualType Type)
-      : VarDecl(OMPCapturedExpr, C, DC, SourceLocation(), SourceLocation(), Id,
-                Type, nullptr, SC_None) {
+                      QualType Type, SourceLocation StartLoc)
+      : VarDecl(OMPCapturedExpr, C, DC, StartLoc, SourceLocation(), Id, Type,
+                nullptr, SC_None) {
     setImplicit();
   }
 
 public:
   static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
-                                     IdentifierInfo *Id, QualType T);
+                                     IdentifierInfo *Id, QualType T,
+                                     SourceLocation StartLoc);
 
   static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 2af95c0..2879452 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -344,6 +344,32 @@
 // Kinds of Templates
 //===----------------------------------------------------------------------===//
 
+/// \brief Stores the template parameter list and associated constraints for
+/// \c TemplateDecl objects that track associated constraints.
+class ConstrainedTemplateDeclInfo {
+  friend TemplateDecl;
+
+public:
+  ConstrainedTemplateDeclInfo() : TemplateParams(), AssociatedConstraints() {}
+
+  TemplateParameterList *getTemplateParameters() const {
+    return TemplateParams;
+  }
+
+  Expr *getAssociatedConstraints() const { return AssociatedConstraints; }
+
+protected:
+  void setTemplateParameters(TemplateParameterList *TParams) {
+    TemplateParams = TParams;
+  }
+
+  void setAssociatedConstraints(Expr *AC) { AssociatedConstraints = AC; }
+
+  TemplateParameterList *TemplateParams;
+  Expr *AssociatedConstraints;
+};
+
+
 /// \brief The base class of all kinds of template declarations (e.g.,
 /// class, function, etc.).
 ///
@@ -352,33 +378,53 @@
 class TemplateDecl : public NamedDecl {
   void anchor() override;
 protected:
-  // This is probably never used.
-  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name)
-      : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false),
-        TemplateParams(nullptr) {}
-
   // Construct a template decl with the given name and parameters.
-  // Used when there is not templated element (tt-params).
-  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
+  // Used when there is no templated element (e.g., for tt-params).
+  TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
+               SourceLocation L, DeclarationName Name,
                TemplateParameterList *Params)
       : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false),
-        TemplateParams(Params) {}
+        TemplateParams(CTDI) {
+    this->setTemplateParameters(Params);
+  }
+
+  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
+               TemplateParameterList *Params)
+      : TemplateDecl(nullptr, DK, DC, L, Name, Params) {}
 
   // Construct a template decl with name, parameters, and templated element.
-  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
+  TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
+               SourceLocation L, DeclarationName Name,
                TemplateParameterList *Params, NamedDecl *Decl)
       : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl, false),
-        TemplateParams(Params) {}
+        TemplateParams(CTDI) {
+    this->setTemplateParameters(Params);
+  }
+
+  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
+               TemplateParameterList *Params, NamedDecl *Decl)
+      : TemplateDecl(nullptr, DK, DC, L, Name, Params, Decl) {}
 
 public:
   /// Get the list of template parameters
   TemplateParameterList *getTemplateParameters() const {
-    return TemplateParams;
+    const auto *const CTDI =
+        TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
+    return CTDI ? CTDI->getTemplateParameters()
+                : TemplateParams.get<TemplateParameterList *>();
   }
 
   /// Get the constraint-expression from the associated requires-clause (if any)
   const Expr *getRequiresClause() const {
-    return TemplateParams ? TemplateParams->getRequiresClause() : nullptr;
+    const TemplateParameterList *const TP = getTemplateParameters();
+    return TP ? TP->getRequiresClause() : nullptr;
+  }
+
+  Expr *getAssociatedConstraints() const {
+    const TemplateDecl *const C = cast<TemplateDecl>(getCanonicalDecl());
+    const auto *const CTDI =
+        C->TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
+    return CTDI ? CTDI->getAssociatedConstraints() : nullptr;
   }
 
   /// Get the underlying, templated declaration.
@@ -391,7 +437,7 @@
   }
 
   SourceRange getSourceRange() const override LLVM_READONLY {
-    return SourceRange(TemplateParams->getTemplateLoc(),
+    return SourceRange(getTemplateParameters()->getTemplateLoc(),
                        TemplatedDecl.getPointer()->getSourceRange().getEnd());
   }
 
@@ -407,7 +453,29 @@
   /// (function or variable) is a concept.
   llvm::PointerIntPair<NamedDecl *, 1, bool> TemplatedDecl;
 
-  TemplateParameterList* TemplateParams;
+  /// \brief The template parameter list and optional requires-clause
+  /// associated with this declaration; alternatively, a
+  /// \c ConstrainedTemplateDeclInfo if the associated constraints of the
+  /// template are being tracked by this particular declaration.
+  llvm::PointerUnion<TemplateParameterList *,
+                     ConstrainedTemplateDeclInfo *>
+      TemplateParams;
+
+  void setTemplateParameters(TemplateParameterList *TParams) {
+    if (auto *const CTDI =
+            TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>()) {
+      CTDI->setTemplateParameters(TParams);
+    } else {
+      TemplateParams = TParams;
+    }
+  }
+
+  void setAssociatedConstraints(Expr *AC) {
+    assert(isCanonicalDecl() &&
+           "Attaching associated constraints to non-canonical Decl");
+    TemplateParams.get<ConstrainedTemplateDeclInfo *>()
+        ->setAssociatedConstraints(AC);
+  }
 
 public:
   /// \brief Initialize the underlying templated declaration and
@@ -737,11 +805,17 @@
   virtual CommonBase *newCommon(ASTContext &C) const = 0;
 
   // Construct a template decl with name, parameters, and templated element.
+  RedeclarableTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK,
+                           ASTContext &C, DeclContext *DC, SourceLocation L,
+                           DeclarationName Name, TemplateParameterList *Params,
+                           NamedDecl *Decl)
+      : TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C),
+        Common() {}
+
   RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
                            SourceLocation L, DeclarationName Name,
                            TemplateParameterList *Params, NamedDecl *Decl)
-      : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
-        Common() {}
+      : RedeclarableTemplateDecl(nullptr, DK, C, DC, L, Name, Params, Decl) {}
 
 public:
   template <class decl_type> friend class RedeclarableTemplate;
@@ -863,8 +937,6 @@
 
 /// Declaration of a template function.
 class FunctionTemplateDecl : public RedeclarableTemplateDecl {
-  static void DeallocateCommon(void *Ptr);
-
 protected:
   /// \brief Data that is common to all of the declarations of a given
   /// function template.
@@ -1407,7 +1479,9 @@
                                                       unsigned NumExpansions);
   
   using TemplateParmPosition::getDepth;
+  using TemplateParmPosition::setDepth;
   using TemplateParmPosition::getPosition;
+  using TemplateParmPosition::setPosition;
   using TemplateParmPosition::getIndex;
 
   /// \brief Whether this template template parameter is a template
@@ -1960,8 +2034,6 @@
 
 /// Declaration of a class template.
 class ClassTemplateDecl : public RedeclarableTemplateDecl {
-  static void DeallocateCommon(void *Ptr);
-
 protected:
   /// \brief Data that is common to all of the declarations of a given
   /// class template.
@@ -1997,10 +2069,16 @@
   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
   getPartialSpecializations();
 
+  ClassTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, ASTContext &C,
+                    DeclContext *DC, SourceLocation L, DeclarationName Name,
+                    TemplateParameterList *Params, NamedDecl *Decl)
+      : RedeclarableTemplateDecl(CTDI, ClassTemplate, C, DC, L, Name, Params,
+                                 Decl) {}
+
   ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
                     DeclarationName Name, TemplateParameterList *Params,
                     NamedDecl *Decl)
-      : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
+      : ClassTemplateDecl(nullptr, C, DC, L, Name, Params, Decl) {}
 
   CommonBase *newCommon(ASTContext &C) const override;
 
@@ -2023,13 +2101,14 @@
     return getTemplatedDecl()->isThisDeclarationADefinition();
   }
 
+  // FIXME: remove default argument for AssociatedConstraints
   /// \brief Create a class template node.
   static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
                                    SourceLocation L,
                                    DeclarationName Name,
                                    TemplateParameterList *Params,
                                    NamedDecl *Decl,
-                                   ClassTemplateDecl *PrevDecl);
+                                   Expr *AssociatedConstraints = nullptr);
 
   /// \brief Create an empty class template node.
   static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2248,8 +2327,6 @@
 /// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
 /// \endcode
 class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
-  static void DeallocateCommon(void *Ptr);
-
 protected:
   typedef CommonBase Common;
 
@@ -2774,8 +2851,6 @@
 
 /// Declaration of a variable template.
 class VarTemplateDecl : public RedeclarableTemplateDecl {
-  static void DeallocateCommon(void *Ptr);
-
 protected:
   /// \brief Data that is common to all of the declarations of a given
   /// variable template.
@@ -2947,6 +3022,16 @@
   return P.get<TemplateTemplateParmDecl*>();
 }
 
+inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
+  auto *TD = dyn_cast<TemplateDecl>(D);
+  return TD && (isa<ClassTemplateDecl>(TD) ||
+                isa<ClassTemplatePartialSpecializationDecl>(TD) ||
+                isa<TypeAliasTemplateDecl>(TD) ||
+                isa<TemplateTemplateParmDecl>(TD))
+             ? TD
+             : nullptr;
+}
+
 } /* end of namespace clang */
 
 #endif
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 2d3cfe2..5e773c9 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -23,6 +23,7 @@
 
 namespace clang {
   class ASTContext;
+  class CXXDeductionGuideNameExtra;
   class CXXLiteralOperatorIdName;
   class CXXOperatorIdName;
   class CXXSpecialName;
@@ -32,6 +33,7 @@
   enum OverloadedOperatorKind : int;
   struct PrintingPolicy;
   class QualType;
+  class TemplateDecl;
   class Type;
   class TypeSourceInfo;
   class UsingDirectiveDecl;
@@ -56,6 +58,7 @@
     CXXConstructorName,
     CXXDestructorName,
     CXXConversionFunctionName,
+    CXXDeductionGuideName,
     CXXOperatorName,
     CXXLiteralOperatorName,
     CXXUsingDirective
@@ -118,42 +121,36 @@
   CXXSpecialName *getAsCXXSpecialName() const {
     NameKind Kind = getNameKind();
     if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
-      return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
+      return reinterpret_cast<CXXSpecialName *>(getExtra());
+    return nullptr;
+  }
+
+  /// If the stored pointer is actually a CXXDeductionGuideNameExtra, returns a
+  /// pointer to it. Otherwise, returns a NULL pointer.
+  CXXDeductionGuideNameExtra *getAsCXXDeductionGuideNameExtra() const {
+    if (getNameKind() == CXXDeductionGuideName)
+      return reinterpret_cast<CXXDeductionGuideNameExtra *>(getExtra());
     return nullptr;
   }
 
   /// getAsCXXOperatorIdName
   CXXOperatorIdName *getAsCXXOperatorIdName() const {
     if (getNameKind() == CXXOperatorName)
-      return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
+      return reinterpret_cast<CXXOperatorIdName *>(getExtra());
     return nullptr;
   }
 
   CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
     if (getNameKind() == CXXLiteralOperatorName)
-      return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
+      return reinterpret_cast<CXXLiteralOperatorIdName *>(getExtra());
     return nullptr;
   }
 
   // Construct a declaration name from the name of a C++ constructor,
   // destructor, or conversion function.
-  DeclarationName(CXXSpecialName *Name)
+  DeclarationName(DeclarationNameExtra *Name)
     : Ptr(reinterpret_cast<uintptr_t>(Name)) {
-    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
-    Ptr |= StoredDeclarationNameExtra;
-  }
-
-  // Construct a declaration name from the name of a C++ overloaded
-  // operator.
-  DeclarationName(CXXOperatorIdName *Name)
-    : Ptr(reinterpret_cast<uintptr_t>(Name)) {
-    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId");
-    Ptr |= StoredDeclarationNameExtra;
-  }
-
-  DeclarationName(CXXLiteralOperatorIdName *Name)
-    : Ptr(reinterpret_cast<uintptr_t>(Name)) {
-    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra");
     Ptr |= StoredDeclarationNameExtra;
   }
 
@@ -252,6 +249,10 @@
   /// type associated with that name.
   QualType getCXXNameType() const;
 
+  /// If this name is the name of a C++ deduction guide, return the
+  /// template associated with that name.
+  TemplateDecl *getCXXDeductionGuideTemplate() const;
+
   /// getCXXOverloadedOperator - If this name is the name of an
   /// overloadable operator in C++ (e.g., @c operator+), retrieve the
   /// kind of overloaded operator.
@@ -346,6 +347,7 @@
   void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
   CXXOperatorIdName *CXXOperatorNames; // Operator names
   void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
+  void *CXXDeductionGuideNames; // FoldingSet<CXXDeductionGuideNameExtra> *
 
   DeclarationNameTable(const DeclarationNameTable&) = delete;
   void operator=(const DeclarationNameTable&) = delete;
@@ -368,6 +370,9 @@
   /// for the given Type.
   DeclarationName getCXXDestructorName(CanQualType Ty);
 
+  /// Returns the name of a C++ deduction guide for the given template.
+  DeclarationName getCXXDeductionGuideName(TemplateDecl *TD);
+
   /// getCXXConversionFunctionName - Returns the name of a C++
   /// conversion function for the given Type.
   DeclarationName getCXXConversionFunctionName(CanQualType Ty);
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 895ac2b..a7ca03f 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -115,6 +115,7 @@
     ExprBits.InstantiationDependent = ID;
     ExprBits.ValueKind = VK;
     ExprBits.ObjectKind = OK;
+    assert(ExprBits.ObjectKind == OK && "truncated kind");
     ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
     setType(T);
   }
@@ -651,7 +652,8 @@
   /// constant.
   bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
                                 const FunctionDecl *Callee,
-                                ArrayRef<const Expr*> Args) const;
+                                ArrayRef<const Expr*> Args,
+                                const Expr *This = nullptr) const;
 
   /// \brief If the current Expr is a pointer, this will try to statically
   /// determine the number of bytes available where the pointer is pointing.
@@ -4333,6 +4335,98 @@
   }
 };
 
+/// \brief Represents a loop initializing the elements of an array.
+///
+/// The need to initialize the elements of an array occurs in a number of
+/// contexts:
+///
+///  * in the implicit copy/move constructor for a class with an array member
+///  * when a lambda-expression captures an array by value
+///  * when a decomposition declaration decomposes an array
+///
+/// There are two subexpressions: a common expression (the source array)
+/// that is evaluated once up-front, and a per-element initializer that
+/// runs once for each array element.
+///
+/// Within the per-element initializer, the common expression may be referenced
+/// via an OpaqueValueExpr, and the current index may be obtained via an
+/// ArrayInitIndexExpr.
+class ArrayInitLoopExpr : public Expr {
+  Stmt *SubExprs[2];
+
+  explicit ArrayInitLoopExpr(EmptyShell Empty)
+      : Expr(ArrayInitLoopExprClass, Empty), SubExprs{} {}
+
+public:
+  explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr *ElementInit)
+      : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false,
+             CommonInit->isValueDependent() || ElementInit->isValueDependent(),
+             T->isInstantiationDependentType(),
+             CommonInit->containsUnexpandedParameterPack() ||
+                 ElementInit->containsUnexpandedParameterPack()),
+        SubExprs{CommonInit, ElementInit} {}
+
+  /// Get the common subexpression shared by all initializations (the source
+  /// array).
+  OpaqueValueExpr *getCommonExpr() const {
+    return cast<OpaqueValueExpr>(SubExprs[0]);
+  }
+
+  /// Get the initializer to use for each array element.
+  Expr *getSubExpr() const { return cast<Expr>(SubExprs[1]); }
+
+  llvm::APInt getArraySize() const {
+    return cast<ConstantArrayType>(getType()->castAsArrayTypeUnsafe())
+        ->getSize();
+  }
+
+  static bool classof(const Stmt *S) {
+    return S->getStmtClass() == ArrayInitLoopExprClass;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getCommonExpr()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getCommonExpr()->getLocEnd();
+  }
+
+  child_range children() {
+    return child_range(SubExprs, SubExprs + 2);
+  }
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// \brief Represents the index of the current element of an array being
+/// initialized by an ArrayInitLoopExpr. This can only appear within the
+/// subexpression of an ArrayInitLoopExpr.
+class ArrayInitIndexExpr : public Expr {
+  explicit ArrayInitIndexExpr(EmptyShell Empty)
+      : Expr(ArrayInitIndexExprClass, Empty) {}
+
+public:
+  explicit ArrayInitIndexExpr(QualType T)
+      : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary,
+             false, false, false, false) {}
+
+  static bool classof(const Stmt *S) {
+    return S->getStmtClass() == ArrayInitIndexExprClass;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+};
+
 /// \brief Represents an implicitly-generated value initialization of
 /// an object of a given type.
 ///
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 4778b6c..f4ff5bb 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1470,7 +1470,8 @@
 public:
   CXXTemporaryObjectExpr(const ASTContext &C,
                          CXXConstructorDecl *Cons,
-                         TypeSourceInfo *Type,
+                         QualType Type,
+                         TypeSourceInfo *TSI,
                          ArrayRef<Expr *> Args,
                          SourceRange ParenOrBraceRange,
                          bool HadMultipleCandidates,
@@ -1513,9 +1514,8 @@
 /// C++1y introduces a new form of "capture" called an init-capture that
 /// includes an initializing expression (rather than capturing a variable),
 /// and which can never occur implicitly.
-class LambdaExpr final
-    : public Expr,
-      private llvm::TrailingObjects<LambdaExpr, Stmt *, unsigned, VarDecl *> {
+class LambdaExpr final : public Expr,
+                         private llvm::TrailingObjects<LambdaExpr, Stmt *> {
   /// \brief The source range that covers the lambda introducer ([...]).
   SourceRange IntroducerRange;
 
@@ -1536,10 +1536,6 @@
   /// \brief Whether this lambda had the result type explicitly specified.
   unsigned ExplicitResultType : 1;
   
-  /// \brief Whether there are any array index variables stored at the end of
-  /// this lambda expression.
-  unsigned HasArrayIndexVars : 1;
-  
   /// \brief The location of the closing brace ('}') that completes
   /// the lambda.
   /// 
@@ -1550,28 +1546,19 @@
   /// module file just to determine the source range.
   SourceLocation ClosingBrace;
 
-  size_t numTrailingObjects(OverloadToken<Stmt *>) const {
-    return NumCaptures + 1;
-  }
-
-  size_t numTrailingObjects(OverloadToken<unsigned>) const {
-    return HasArrayIndexVars ? NumCaptures + 1 : 0;
-  }
-
   /// \brief Construct a lambda expression.
   LambdaExpr(QualType T, SourceRange IntroducerRange,
              LambdaCaptureDefault CaptureDefault,
              SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
              bool ExplicitParams, bool ExplicitResultType,
-             ArrayRef<Expr *> CaptureInits, ArrayRef<VarDecl *> ArrayIndexVars,
-             ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
+             ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
              bool ContainsUnexpandedParameterPack);
 
   /// \brief Construct an empty lambda expression.
-  LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool HasArrayIndexVars)
+  LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
     : Expr(LambdaExprClass, Empty),
       NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
-      ExplicitResultType(false), HasArrayIndexVars(true) { 
+      ExplicitResultType(false) { 
     getStoredStmts()[NumCaptures] = nullptr;
   }
 
@@ -1579,21 +1566,6 @@
 
   Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
 
-  /// \brief Retrieve the mapping from captures to the first array index
-  /// variable.
-  unsigned *getArrayIndexStarts() { return getTrailingObjects<unsigned>(); }
-
-  const unsigned *getArrayIndexStarts() const {
-    return getTrailingObjects<unsigned>();
-  }
-
-  /// \brief Retrieve the complete set of array-index variables.
-  VarDecl **getArrayIndexVars() { return getTrailingObjects<VarDecl *>(); }
-
-  VarDecl *const *getArrayIndexVars() const {
-    return getTrailingObjects<VarDecl *>();
-  }
-
 public:
   /// \brief Construct a new lambda expression.
   static LambdaExpr *
@@ -1601,15 +1573,12 @@
          LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
          ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
          bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
-         ArrayRef<VarDecl *> ArrayIndexVars,
-         ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
-         bool ContainsUnexpandedParameterPack);
+         SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
 
   /// \brief Construct a new lambda expression that will be deserialized from
   /// an external source.
   static LambdaExpr *CreateDeserialized(const ASTContext &C,
-                                        unsigned NumCaptures,
-                                        unsigned NumArrayIndexVars);
+                                        unsigned NumCaptures);
 
   /// \brief Determine the default capture kind for this lambda.
   LambdaCaptureDefault getCaptureDefault() const {
@@ -1708,14 +1677,6 @@
     return capture_init_begin() + NumCaptures;
   }
 
-  /// \brief Retrieve the set of index variables used in the capture
-  /// initializer of an array captured by copy.
-  ///
-  /// \param Iter The iterator that points at the capture initializer for
-  /// which we are extracting the corresponding index variables.
-  ArrayRef<VarDecl *>
-  getCaptureInitIndexVars(const_capture_init_iterator Iter) const;
-
   /// \brief Retrieve the source range covering the lambda introducer,
   /// which contains the explicit capture list surrounded by square
   /// brackets ([...]).
@@ -4162,16 +4123,18 @@
 
   enum SubExpr { Common, Ready, Suspend, Resume, Count };
   Stmt *SubExprs[SubExpr::Count];
+  OpaqueValueExpr *OpaqueValue = nullptr;
 
   friend class ASTStmtReader;
 public:
   CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
-                       Expr *Ready, Expr *Suspend, Expr *Resume)
+                       Expr *Ready, Expr *Suspend, Expr *Resume,
+                       OpaqueValueExpr *OpaqueValue)
       : Expr(SC, Resume->getType(), Resume->getValueKind(),
              Resume->getObjectKind(), Resume->isTypeDependent(),
              Resume->isValueDependent(), Common->isInstantiationDependent(),
              Common->containsUnexpandedParameterPack()),
-        KeywordLoc(KeywordLoc) {
+        KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) {
     SubExprs[SubExpr::Common] = Common;
     SubExprs[SubExpr::Ready] = Ready;
     SubExprs[SubExpr::Suspend] = Suspend;
@@ -4200,6 +4163,8 @@
   Expr *getCommonExpr() const {
     return static_cast<Expr*>(SubExprs[SubExpr::Common]);
   }
+  /// \brief getOpaqueValue - Return the opaque value placeholder.
+  OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
 
   Expr *getReadyExpr() const {
     return static_cast<Expr*>(SubExprs[SubExpr::Ready]);
@@ -4233,11 +4198,17 @@
   friend class ASTStmtReader;
 public:
   CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
-              Expr *Suspend, Expr *Resume)
+              Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue,
+              bool IsImplicit = false)
       : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready,
-                             Suspend, Resume) {}
-  CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand)
-      : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {}
+                             Suspend, Resume, OpaqueValue) {
+    CoawaitBits.IsImplicit = IsImplicit;
+  }
+  CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand,
+              bool IsImplicit = false)
+      : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {
+    CoawaitBits.IsImplicit = IsImplicit;
+  }
   CoawaitExpr(EmptyShell Empty)
       : CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
 
@@ -4246,19 +4217,67 @@
     return getCommonExpr();
   }
 
+  bool isImplicit() const { return CoawaitBits.IsImplicit; }
+  void setIsImplicit(bool value = true) { CoawaitBits.IsImplicit = value; }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CoawaitExprClass;
   }
 };
 
+/// \brief Represents a 'co_await' expression while the type of the promise
+/// is dependent.
+class DependentCoawaitExpr : public Expr {
+  SourceLocation KeywordLoc;
+  Stmt *SubExprs[2];
+
+  friend class ASTStmtReader;
+
+public:
+  DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op,
+                       UnresolvedLookupExpr *OpCoawait)
+      : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary,
+             /*TypeDependent*/ true, /*ValueDependent*/ true,
+             /*InstantiationDependent*/ true,
+             Op->containsUnexpandedParameterPack()),
+        KeywordLoc(KeywordLoc) {
+    // NOTE: A co_await expression is dependent on the coroutines promise
+    // type and may be dependent even when the `Op` expression is not.
+    assert(Ty->isDependentType() &&
+           "wrong constructor for non-dependent co_await/co_yield expression");
+    SubExprs[0] = Op;
+    SubExprs[1] = OpCoawait;
+  }
+
+  DependentCoawaitExpr(EmptyShell Empty)
+      : Expr(DependentCoawaitExprClass, Empty) {}
+
+  Expr *getOperand() const { return cast<Expr>(SubExprs[0]); }
+  UnresolvedLookupExpr *getOperatorCoawaitLookup() const {
+    return cast<UnresolvedLookupExpr>(SubExprs[1]);
+  }
+  SourceLocation getKeywordLoc() const { return KeywordLoc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getOperand()->getLocEnd();
+  }
+
+  child_range children() { return child_range(SubExprs, SubExprs + 2); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DependentCoawaitExprClass;
+  }
+};
+
 /// \brief Represents a 'co_yield' expression.
 class CoyieldExpr : public CoroutineSuspendExpr {
   friend class ASTStmtReader;
 public:
   CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
-              Expr *Suspend, Expr *Resume)
+              Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue)
       : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready,
-                             Suspend, Resume) {}
+                             Suspend, Resume, OpaqueValue) {}
   CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand)
       : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {}
   CoyieldExpr(EmptyShell Empty)
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 2e99f39..40c54b2 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -16,6 +16,7 @@
 
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclBase.h"
+#include "clang/Basic/Module.h"
 #include "llvm/ADT/DenseMap.h"
 
 namespace clang {
@@ -149,26 +150,30 @@
     StringRef PCHModuleName;
     StringRef Path;
     StringRef ASTFile;
-    uint64_t Signature = 0;
+    ASTFileSignature Signature;
     const Module *ClangModule = nullptr;
 
   public:
     ASTSourceDescriptor(){};
     ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
-                        uint64_t Signature)
+                        ASTFileSignature Signature)
         : PCHModuleName(std::move(Name)), Path(std::move(Path)),
           ASTFile(std::move(ASTFile)), Signature(Signature){};
     ASTSourceDescriptor(const Module &M);
     std::string getModuleName() const;
     StringRef getPath() const { return Path; }
     StringRef getASTFile() const { return ASTFile; }
-    uint64_t getSignature() const { return Signature; }
+    ASTFileSignature getSignature() const { return Signature; }
     const Module *getModuleOrNull() const { return ClangModule; }
   };
 
   /// Return a descriptor for the corresponding module, if one exists.
   virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
 
+  enum ExtKind { EK_Always, EK_Never, EK_ReplyHazy };
+
+  virtual ExtKind hasExternalDefinitions(unsigned ID);
+
   /// \brief Finds all declarations lexically contained within the given
   /// DeclContext, after applying an optional filter predicate.
   ///
diff --git a/include/clang/AST/ODRHash.h b/include/clang/AST/ODRHash.h
new file mode 100644
index 0000000..9af8488
--- /dev/null
+++ b/include/clang/AST/ODRHash.h
@@ -0,0 +1,84 @@
+//===-- ODRHash.h - Hashing to diagnose ODR failures ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declaration of the ODRHash class, which calculates
+/// a hash based on AST nodes, which is stable across different runs.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TemplateBase.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class Decl;
+class IdentifierInfo;
+class NestedNameSpecifer;
+class Stmt;
+class TemplateParameterList;
+
+// ODRHash is used to calculate a hash based on AST node contents that
+// does not rely on pointer addresses.  This allows the hash to not vary
+// between runs and is usable to detect ODR problems in modules.  To use,
+// construct an ODRHash object, then call Add* methods over the nodes that
+// need to be hashed.  Then call CalculateHash to get the hash value.
+// Typically, only one Add* call is needed.  clear can be called to reuse the
+// object.
+class ODRHash {
+  // Use DenseMaps to convert between Decl and Type pointers and an index value.
+  llvm::DenseMap<const Decl*, unsigned> DeclMap;
+  llvm::DenseMap<const Type*, unsigned> TypeMap;
+
+  // Save space by processing bools at the end.
+  llvm::SmallVector<bool, 128> Bools;
+
+  llvm::FoldingSetNodeID ID;
+
+public:
+  ODRHash() {}
+
+  // Use this for ODR checking classes between modules.  This method compares
+  // more information than the AddDecl class.
+  void AddCXXRecordDecl(const CXXRecordDecl *Record);
+
+  // Process SubDecls of the main Decl.  This method calls the DeclVisitor
+  // while AddDecl does not.
+  void AddSubDecl(const Decl *D);
+
+  // Reset the object for reuse.
+  void clear();
+
+  // Add booleans to ID and uses it to calculate the hash.
+  unsigned CalculateHash();
+
+  // Add AST nodes that need to be processed.
+  void AddDecl(const Decl *D);
+  void AddType(const Type *T);
+  void AddQualType(QualType T);
+  void AddStmt(const Stmt *S);
+  void AddIdentifierInfo(const IdentifierInfo *II);
+  void AddNestedNameSpecifier(const NestedNameSpecifier *NNS);
+  void AddTemplateName(TemplateName Name);
+  void AddDeclarationName(DeclarationName Name);
+  void AddTemplateArgument(TemplateArgument TA);
+  void AddTemplateParameterList(const TemplateParameterList *TPL);
+
+  // Save booleans until the end to lower the size of data to process.
+  void AddBoolean(bool value);
+
+  static bool isWhitelistedDecl(const Decl* D, const CXXRecordDecl *Record);
+};
+
+}  // end namespace clang
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index 3e4c4bc..f977e63 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -76,10 +76,17 @@
   friend class OMPClauseReader;
   /// Pre-initialization statement for the clause.
   Stmt *PreInit;
+  /// Region that captures the associated stmt.
+  OpenMPDirectiveKind CaptureRegion;
+
 protected:
   /// Set pre-initialization statement for the clause.
-  void setPreInitStmt(Stmt *S) { PreInit = S; }
-  OMPClauseWithPreInit(const OMPClause *This) : PreInit(nullptr) {
+  void setPreInitStmt(Stmt *S, OpenMPDirectiveKind ThisRegion = OMPD_unknown) {
+    PreInit = S;
+    CaptureRegion = ThisRegion;
+  }
+  OMPClauseWithPreInit(const OMPClause *This)
+      : PreInit(nullptr), CaptureRegion(OMPD_unknown) {
     assert(get(This) && "get is not tuned for pre-init.");
   }
 
@@ -88,6 +95,8 @@
   const Stmt *getPreInitStmt() const { return PreInit; }
   /// Get pre-initialization statement for the clause.
   Stmt *getPreInitStmt() { return PreInit; }
+  /// Get capture region for the stmt in the clause.
+  OpenMPDirectiveKind getCaptureRegion() { return CaptureRegion; }
   static OMPClauseWithPreInit *get(OMPClause *C);
   static const OMPClauseWithPreInit *get(const OMPClause *C);
 };
@@ -194,7 +203,7 @@
 /// In this example directive '#pragma omp parallel' has simple 'if' clause with
 /// condition 'a > 5' and directive name modifier 'parallel'.
 ///
-class OMPIfClause : public OMPClause {
+class OMPIfClause : public OMPClause, public OMPClauseWithPreInit {
   friend class OMPClauseReader;
   /// \brief Location of '('.
   SourceLocation LParenLoc;
@@ -225,26 +234,31 @@
   ///
   /// \param NameModifier [OpenMP 4.1] Directive name modifier of clause.
   /// \param Cond Condition of the clause.
+  /// \param HelperCond Helper condition for the clause.
+  /// \param CaptureRegion Innermost OpenMP region where expressions in this
+  /// clause must be captured.
   /// \param StartLoc Starting location of the clause.
   /// \param LParenLoc Location of '('.
   /// \param NameModifierLoc Location of directive name modifier.
   /// \param ColonLoc [OpenMP 4.1] Location of ':'.
   /// \param EndLoc Ending location of the clause.
   ///
-  OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond,
-              SourceLocation StartLoc, SourceLocation LParenLoc,
-              SourceLocation NameModifierLoc, SourceLocation ColonLoc,
-              SourceLocation EndLoc)
-      : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
-        Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier),
-        NameModifierLoc(NameModifierLoc) {}
+  OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, Stmt *HelperCond,
+              OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
+              SourceLocation LParenLoc, SourceLocation NameModifierLoc,
+              SourceLocation ColonLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this),
+        LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc),
+        NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) {
+    setPreInitStmt(HelperCond, CaptureRegion);
+  }
 
   /// \brief Build an empty clause.
   ///
   OMPIfClause()
-      : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(),
-        Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown),
-        NameModifierLoc() {}
+      : OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
+        OMPClauseWithPreInit(this), LParenLoc(), Condition(nullptr), ColonLoc(),
+        NameModifier(OMPD_unknown), NameModifierLoc() {}
 
   /// \brief Sets the location of '('.
   void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -331,7 +345,7 @@
 /// In this example directive '#pragma omp parallel' has simple 'num_threads'
 /// clause with number of threads '6'.
 ///
-class OMPNumThreadsClause : public OMPClause {
+class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit {
   friend class OMPClauseReader;
   /// \brief Location of '('.
   SourceLocation LParenLoc;
@@ -346,20 +360,29 @@
   /// \brief Build 'num_threads' clause with condition \a NumThreads.
   ///
   /// \param NumThreads Number of threads for the construct.
+  /// \param HelperNumThreads Helper Number of threads for the construct.
+  /// \param CaptureRegion Innermost OpenMP region where expressions in this
+  /// clause must be captured.
   /// \param StartLoc Starting location of the clause.
   /// \param LParenLoc Location of '('.
   /// \param EndLoc Ending location of the clause.
   ///
-  OMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc,
-                      SourceLocation LParenLoc, SourceLocation EndLoc)
-      : OMPClause(OMPC_num_threads, StartLoc, EndLoc), LParenLoc(LParenLoc),
-        NumThreads(NumThreads) {}
+  OMPNumThreadsClause(Expr *NumThreads, Stmt *HelperNumThreads,
+                      OpenMPDirectiveKind CaptureRegion,
+                      SourceLocation StartLoc, SourceLocation LParenLoc,
+                      SourceLocation EndLoc)
+      : OMPClause(OMPC_num_threads, StartLoc, EndLoc),
+        OMPClauseWithPreInit(this), LParenLoc(LParenLoc),
+        NumThreads(NumThreads) {
+    setPreInitStmt(HelperNumThreads, CaptureRegion);
+  }
 
   /// \brief Build an empty clause.
   ///
   OMPNumThreadsClause()
       : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
-        LParenLoc(SourceLocation()), NumThreads(nullptr) {}
+        OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
+        NumThreads(nullptr) {}
 
   /// \brief Sets the location of '('.
   void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -3456,7 +3479,7 @@
 /// In this example directive '#pragma omp teams' has clause 'num_teams'
 /// with single expression 'n'.
 ///
-class OMPNumTeamsClause : public OMPClause {
+class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit {
   friend class OMPClauseReader;
   /// \brief Location of '('.
   SourceLocation LParenLoc;
@@ -3472,20 +3495,27 @@
   /// \brief Build 'num_teams' clause.
   ///
   /// \param E Expression associated with this clause.
+  /// \param HelperE Helper Expression associated with this clause.
+  /// \param CaptureRegion Innermost OpenMP region where expressions in this
+  /// clause must be captured.
   /// \param StartLoc Starting location of the clause.
   /// \param LParenLoc Location of '('.
   /// \param EndLoc Ending location of the clause.
   ///
-  OMPNumTeamsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
+  OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion,
+                    SourceLocation StartLoc, SourceLocation LParenLoc,
                     SourceLocation EndLoc)
-      : OMPClause(OMPC_num_teams, StartLoc, EndLoc), LParenLoc(LParenLoc), 
-        NumTeams(E) {}
+      : OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this),
+        LParenLoc(LParenLoc), NumTeams(E) {
+    setPreInitStmt(HelperE, CaptureRegion);
+  }
 
   /// \brief Build an empty clause.
   ///
   OMPNumTeamsClause()
-      : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), 
-        LParenLoc(SourceLocation()), NumTeams(nullptr) {}
+      : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
+        OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
+        NumTeams(nullptr) {}
   /// \brief Sets the location of '('.
   void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
   /// \brief Returns the location of '('.
@@ -3511,7 +3541,7 @@
 /// In this example directive '#pragma omp teams' has clause 'thread_limit'
 /// with single expression 'n'.
 ///
-class OMPThreadLimitClause : public OMPClause {
+class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit {
   friend class OMPClauseReader;
   /// \brief Location of '('.
   SourceLocation LParenLoc;
@@ -3527,20 +3557,28 @@
   /// \brief Build 'thread_limit' clause.
   ///
   /// \param E Expression associated with this clause.
+  /// \param HelperE Helper Expression associated with this clause.
+  /// \param CaptureRegion Innermost OpenMP region where expressions in this
+  /// clause must be captured.
   /// \param StartLoc Starting location of the clause.
   /// \param LParenLoc Location of '('.
   /// \param EndLoc Ending location of the clause.
   ///
-  OMPThreadLimitClause(Expr *E, SourceLocation StartLoc,
-                       SourceLocation LParenLoc, SourceLocation EndLoc)
-      : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), LParenLoc(LParenLoc),
-        ThreadLimit(E) {}
+  OMPThreadLimitClause(Expr *E, Stmt *HelperE,
+                       OpenMPDirectiveKind CaptureRegion,
+                       SourceLocation StartLoc, SourceLocation LParenLoc,
+                       SourceLocation EndLoc)
+      : OMPClause(OMPC_thread_limit, StartLoc, EndLoc),
+        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) {
+    setPreInitStmt(HelperE, CaptureRegion);
+  }
 
   /// \brief Build an empty clause.
   ///
   OMPThreadLimitClause()
       : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()),
-        LParenLoc(SourceLocation()), ThreadLimit(nullptr) {}
+        OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
+        ThreadLimit(nullptr) {}
   /// \brief Sets the location of '('.
   void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
   /// \brief Returns the location of '('.
diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def
index 03a61e9..2d48a7d 100644
--- a/include/clang/AST/OperationKinds.def
+++ b/include/clang/AST/OperationKinds.def
@@ -321,6 +321,9 @@
 // Convert a zero value for OpenCL event_t initialization.
 CAST_OPERATION(ZeroToOCLEvent)
 
+// Convert a zero value for OpenCL queue_t initialization.
+CAST_OPERATION(ZeroToOCLQueue)
+
 // Convert a pointer to a different address space.
 CAST_OPERATION(AddressSpaceConversion)
 
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index de712f1..1b5850a 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -774,6 +774,11 @@
       TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
     break;
 
+  case DeclarationName::CXXDeductionGuideName:
+    TRY_TO(TraverseTemplateName(
+        TemplateName(NameInfo.getName().getCXXDeductionGuideTemplate())));
+    break;
+
   case DeclarationName::Identifier:
   case DeclarationName::ObjCZeroArgSelector:
   case DeclarationName::ObjCOneArgSelector:
@@ -886,16 +891,6 @@
   if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
     TRY_TO(TraverseStmt(Init->getInit()));
 
-  if (getDerived().shouldVisitImplicitCode())
-    // The braces for this one-line loop are required for MSVC2013.  It
-    // refuses to compile
-    //     for (int i : int_vec)
-    //       do {} while(false);
-    // without braces on the for loop.
-    for (VarDecl *VD : Init->getArrayIndices()) {
-      TRY_TO(TraverseDecl(VD));
-    }
-
   return true;
 }
 
@@ -1018,6 +1013,10 @@
 })
 
 DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
+DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
+  TRY_TO(TraverseTemplateName(T->getTemplateName()));
+  TRY_TO(TraverseType(T->getDeducedType()));
+})
 
 DEF_TRAVERSE_TYPE(RecordType, {})
 DEF_TRAVERSE_TYPE(EnumType, {})
@@ -1242,6 +1241,11 @@
   TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
 })
 
+DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
+  TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+  TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+})
+
 DEF_TRAVERSE_TYPELOC(RecordType, {})
 DEF_TRAVERSE_TYPELOC(EnumType, {})
 DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
@@ -1515,6 +1519,8 @@
   TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
 })
 
+DEF_TRAVERSE_DECL(UsingPackDecl, {})
+
 DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
 })
@@ -1940,6 +1946,13 @@
   ReturnValue = TraverseFunctionHelper(D);
 })
 
+DEF_TRAVERSE_DECL(CXXDeductionGuideDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  ShouldVisitChildren = false;
+  ReturnValue = TraverseFunctionHelper(D);
+})
+
 DEF_TRAVERSE_DECL(CXXMethodDecl, {
   // We skip decls_begin/decls_end, which are already covered by
   // TraverseFunctionHelper().
@@ -2399,6 +2412,13 @@
 DEF_TRAVERSE_STMT(GNUNullExpr, {})
 DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
 DEF_TRAVERSE_STMT(NoInitExpr, {})
+DEF_TRAVERSE_STMT(ArrayInitLoopExpr, {
+  // FIXME: The source expression of the OVE should be listed as
+  // a child of the ArrayInitLoopExpr.
+  if (OpaqueValueExpr *OVE = S->getCommonExpr())
+    TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
+})
+DEF_TRAVERSE_STMT(ArrayInitIndexExpr, {})
 DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
 
 DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
@@ -2496,6 +2516,12 @@
     ShouldVisitChildren = false;
   }
 })
+DEF_TRAVERSE_STMT(DependentCoawaitExpr, {
+  if (!getDerived().shouldVisitImplicitCode()) {
+    TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
+    ShouldVisitChildren = false;
+  }
+})
 DEF_TRAVERSE_STMT(CoyieldExpr, {
   if (!getDerived().shouldVisitImplicitCode()) {
     TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
@@ -2661,6 +2687,21 @@
 DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
 // OpenMP clauses.
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
@@ -2697,6 +2738,7 @@
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
+  TRY_TO(VisitOMPClauseWithPreInit(C));
   TRY_TO(TraverseStmt(C->getCondition()));
   return true;
 }
@@ -2710,6 +2752,7 @@
 template <typename Derived>
 bool
 RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
+  TRY_TO(VisitOMPClauseWithPreInit(C));
   TRY_TO(TraverseStmt(C->getNumThreads()));
   return true;
 }
@@ -2979,6 +3022,7 @@
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
     OMPNumTeamsClause *C) {
+  TRY_TO(VisitOMPClauseWithPreInit(C));
   TRY_TO(TraverseStmt(C->getNumTeams()));
   return true;
 }
@@ -2986,6 +3030,7 @@
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause(
     OMPThreadLimitClause *C) {
+  TRY_TO(VisitOMPClauseWithPreInit(C));
   TRY_TO(TraverseStmt(C->getThreadLimit()));
   return true;
 }
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index e28675d..c210bd1 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -39,6 +39,7 @@
   class Expr;
   class IdentifierInfo;
   class LabelDecl;
+  class ODRHash;
   class ParmVarDecl;
   class PrinterHelper;
   struct PrintingPolicy;
@@ -126,13 +127,13 @@
     unsigned : NumStmtBits;
 
     unsigned ValueKind : 2;
-    unsigned ObjectKind : 2;
+    unsigned ObjectKind : 3;
     unsigned TypeDependent : 1;
     unsigned ValueDependent : 1;
     unsigned InstantiationDependent : 1;
     unsigned ContainsUnexpandedParameterPack : 1;
   };
-  enum { NumExprBits = 16 };
+  enum { NumExprBits = 17 };
 
   class CharacterLiteralBitfields {
     friend class CharacterLiteral;
@@ -252,6 +253,14 @@
     unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
   };
 
+  class CoawaitExprBitfields {
+    friend class CoawaitExpr;
+
+    unsigned : NumExprBits;
+
+    unsigned IsImplicit : 1;
+  };
+
   union {
     StmtBitfields StmtBits;
     CompoundStmtBitfields CompoundStmtBits;
@@ -268,6 +277,7 @@
     ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
     InitListExprBitfields InitListExprBits;
     TypeTraitExprBitfields TypeTraitExprBits;
+    CoawaitExprBitfields CoawaitBits;
   };
 
   friend class ASTStmtReader;
@@ -340,6 +350,8 @@
 
 public:
   Stmt(StmtClass SC) {
+    static_assert(sizeof(*this) == sizeof(void *),
+                  "changing bitfields changed sizeof(Stmt)");
     static_assert(sizeof(*this) % alignof(void *) == 0,
                   "Insufficient alignment!");
     StmtBits.sClass = SC;
@@ -436,6 +448,15 @@
   /// written in the source.
   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
                bool Canonical) const;
+
+  /// \brief Calculate a unique representation for a statement that is
+  /// stable across compiler invocations.
+  ///
+  /// \param ID profile information will be stored in ID.
+  ///
+  /// \param Hash an ODRHash object which will be called where pointers would
+  /// have been used in the Profile function.
+  void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash& Hash) const;
 };
 
 /// DeclStmt - Adaptor class for mixing declarations with statements and
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 8eef34c..ac440a9 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -296,7 +296,9 @@
 /// \brief Represents the body of a coroutine. This wraps the normal function
 /// body and holds the additional semantic context required to set up and tear
 /// down the coroutine frame.
-class CoroutineBodyStmt : public Stmt {
+class CoroutineBodyStmt final
+    : public Stmt,
+      private llvm::TrailingObjects<CoroutineBodyStmt, Stmt *> {
   enum SubStmt {
     Body,          ///< The body of the coroutine.
     Promise,       ///< The promise statement.
@@ -309,63 +311,89 @@
     ReturnValue,   ///< Return value for thunk function.
     FirstParamMove ///< First offset for move construction of parameter copies.
   };
-  Stmt *SubStmts[SubStmt::FirstParamMove];
+  unsigned NumParams;
 
   friend class ASTStmtReader;
+  friend TrailingObjects;
+
+  Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
+
+  Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
+
 public:
-  CoroutineBodyStmt(Stmt *Body, Stmt *Promise, Stmt *InitSuspend,
-                    Stmt *FinalSuspend, Stmt *OnException, Stmt *OnFallthrough,
-                    Expr *Allocate, Stmt *Deallocate,
-                    Expr *ReturnValue, ArrayRef<Expr *> ParamMoves)
-      : Stmt(CoroutineBodyStmtClass) {
-    SubStmts[CoroutineBodyStmt::Body] = Body;
-    SubStmts[CoroutineBodyStmt::Promise] = Promise;
-    SubStmts[CoroutineBodyStmt::InitSuspend] = InitSuspend;
-    SubStmts[CoroutineBodyStmt::FinalSuspend] = FinalSuspend;
-    SubStmts[CoroutineBodyStmt::OnException] = OnException;
-    SubStmts[CoroutineBodyStmt::OnFallthrough] = OnFallthrough;
-    SubStmts[CoroutineBodyStmt::Allocate] = Allocate;
-    SubStmts[CoroutineBodyStmt::Deallocate] = Deallocate;
-    SubStmts[CoroutineBodyStmt::ReturnValue] = ReturnValue;
-    // FIXME: Tail-allocate space for parameter move expressions and store them.
-    assert(ParamMoves.empty() && "not implemented yet");
-  }
+
+  struct CtorArgs {
+    Stmt *Body = nullptr;
+    Stmt *Promise = nullptr;
+    Expr *InitialSuspend = nullptr;
+    Expr *FinalSuspend = nullptr;
+    Stmt *OnException = nullptr;
+    Stmt *OnFallthrough = nullptr;
+    Expr *Allocate = nullptr;
+    Expr *Deallocate = nullptr;
+    Stmt *ReturnValue = nullptr;
+    ArrayRef<Stmt *> ParamMoves;
+  };
+
+private:
+
+  CoroutineBodyStmt(CtorArgs const& Args);
+
+public:
+  static CoroutineBodyStmt *Create(const ASTContext &C, CtorArgs const &Args);
 
   /// \brief Retrieve the body of the coroutine as written. This will be either
   /// a CompoundStmt or a TryStmt.
   Stmt *getBody() const {
-    return SubStmts[SubStmt::Body];
+    return getStoredStmts()[SubStmt::Body];
   }
 
-  Stmt *getPromiseDeclStmt() const { return SubStmts[SubStmt::Promise]; }
+  Stmt *getPromiseDeclStmt() const {
+    return getStoredStmts()[SubStmt::Promise];
+  }
   VarDecl *getPromiseDecl() const {
     return cast<VarDecl>(cast<DeclStmt>(getPromiseDeclStmt())->getSingleDecl());
   }
 
-  Stmt *getInitSuspendStmt() const { return SubStmts[SubStmt::InitSuspend]; }
-  Stmt *getFinalSuspendStmt() const { return SubStmts[SubStmt::FinalSuspend]; }
-
-  Stmt *getExceptionHandler() const { return SubStmts[SubStmt::OnException]; }
-  Stmt *getFallthroughHandler() const {
-    return SubStmts[SubStmt::OnFallthrough];
+  Stmt *getInitSuspendStmt() const {
+    return getStoredStmts()[SubStmt::InitSuspend];
+  }
+  Stmt *getFinalSuspendStmt() const {
+    return getStoredStmts()[SubStmt::FinalSuspend];
   }
 
-  Expr *getAllocate() const { return cast<Expr>(SubStmts[SubStmt::Allocate]); }
-  Stmt *getDeallocate() const { return SubStmts[SubStmt::Deallocate]; }
+  Stmt *getExceptionHandler() const {
+    return getStoredStmts()[SubStmt::OnException];
+  }
+  Stmt *getFallthroughHandler() const {
+    return getStoredStmts()[SubStmt::OnFallthrough];
+  }
+
+  Expr *getAllocate() const {
+    return cast_or_null<Expr>(getStoredStmts()[SubStmt::Allocate]);
+  }
+  Expr *getDeallocate() const {
+    return cast_or_null<Expr>(getStoredStmts()[SubStmt::Deallocate]);
+  }
 
   Expr *getReturnValueInit() const {
-    return cast<Expr>(SubStmts[SubStmt::ReturnValue]);
+    return cast_or_null<Expr>(getStoredStmts()[SubStmt::ReturnValue]);
+  }
+  ArrayRef<Stmt const *> getParamMoves() const {
+    return {getStoredStmts() + SubStmt::FirstParamMove, NumParams};
   }
 
   SourceLocation getLocStart() const LLVM_READONLY {
-    return getBody()->getLocStart();
+    return getBody() ? getBody()->getLocStart()
+            : getPromiseDecl()->getLocStart();
   }
   SourceLocation getLocEnd() const LLVM_READONLY {
-    return getBody()->getLocEnd();
+    return getBody() ? getBody()->getLocEnd() : getPromiseDecl()->getLocEnd();
   }
 
   child_range children() {
-    return child_range(SubStmts, SubStmts + SubStmt::FirstParamMove);
+    return child_range(getStoredStmts(),
+                       getStoredStmts() + SubStmt::FirstParamMove + NumParams);
   }
 
   static bool classof(const Stmt *T) {
@@ -390,10 +418,14 @@
   enum SubStmt { Operand, PromiseCall, Count };
   Stmt *SubStmts[SubStmt::Count];
 
+  bool IsImplicit : 1;
+
   friend class ASTStmtReader;
 public:
-  CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall)
-      : Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc) {
+  CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall,
+               bool IsImplicit = false)
+      : Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc),
+        IsImplicit(IsImplicit) {
     SubStmts[SubStmt::Operand] = Operand;
     SubStmts[SubStmt::PromiseCall] = PromiseCall;
   }
@@ -411,6 +443,9 @@
     return static_cast<Expr*>(SubStmts[PromiseCall]);
   }
 
+  bool isImplicit() const { return IsImplicit; }
+  void setIsImplicit(bool value = true) { IsImplicit = value; }
+
   SourceLocation getLocStart() const LLVM_READONLY { return CoreturnLoc; }
   SourceLocation getLocEnd() const LLVM_READONLY {
     return getOperand() ? getOperand()->getLocEnd() : getLocStart();
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index 78b7f63..13af142 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -198,6 +198,26 @@
     return const_cast<Stmt *>(*child_begin());
   }
 
+  /// \brief Returns the captured statement associated with the
+  /// component region within the (combined) directive.
+  //
+  // \param RegionKind Component region kind.
+  CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
+    SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
+    getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
+    assert(std::any_of(
+               CaptureRegions.begin(), CaptureRegions.end(),
+               [=](const OpenMPDirectiveKind K) { return K == RegionKind; }) &&
+           "RegionKind not found in OpenMP CaptureRegions.");
+    auto *CS = cast<CapturedStmt>(getAssociatedStmt());
+    for (auto ThisCaptureRegion : CaptureRegions) {
+      if (ThisCaptureRegion == RegionKind)
+        return CS;
+      CS = cast<CapturedStmt>(CS->getCapturedStmt());
+    }
+    llvm_unreachable("Incorrect RegionKind specified for directive.");
+  }
+
   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
 
   static bool classof(const Stmt *S) {
@@ -304,6 +324,11 @@
   /// allocated: loop counters, their updates and final values.
   /// PrevLowerBound and PrevUpperBound are used to communicate blocking
   /// information in composite constructs which require loop blocking
+  /// DistInc is used to generate the increment expression for the distribute
+  /// loop when combined with a further nested loop
+  /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
+  /// for loop when combined with a previous distribute loop in the same pragma
+  /// (e.g. 'distribute parallel for')
   ///
   enum {
     AssociatedStmtOffset = 0,
@@ -319,7 +344,7 @@
     // specify the offset to the end (and start of the following counters/
     // updates/finals arrays).
     DefaultEnd = 9,
-    // The following 7 exprs are used by worksharing loops only.
+    // The following 12 exprs are used by worksharing and distribute loops only.
     IsLastIterVariableOffset = 9,
     LowerBoundVariableOffset = 10,
     UpperBoundVariableOffset = 11,
@@ -330,9 +355,11 @@
     NumIterationsOffset = 16,
     PrevLowerBoundVariableOffset = 17,
     PrevUpperBoundVariableOffset = 18,
+    DistIncOffset = 19,
+    PrevEnsureUpperBoundOffset = 20,
     // Offset to the end (and start of the following counters/updates/finals
     // arrays) for worksharing loop directives.
-    WorksharingEnd = 19,
+    WorksharingEnd = 21,
   };
 
   /// \brief Get the counters storage.
@@ -501,6 +528,20 @@
            "expected worksharing loop directive");
     *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
   }
+  void setDistInc(Expr *DistInc) {
+    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
+            isOpenMPDistributeDirective(getDirectiveKind())) &&
+           "expected worksharing loop directive");
+    *std::next(child_begin(), DistIncOffset) = DistInc;
+  }
+  void setPrevEnsureUpperBound(Expr *PrevEUB) {
+    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
+            isOpenMPDistributeDirective(getDirectiveKind())) &&
+           "expected worksharing loop directive");
+    *std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB;
+  }
   void setCounters(ArrayRef<Expr *> A);
   void setPrivateCounters(ArrayRef<Expr *> A);
   void setInits(ArrayRef<Expr *> A);
@@ -535,7 +576,7 @@
     Expr *UB;
     /// \brief Stride - local variable passed to runtime.
     Expr *ST;
-    /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
+    /// \brief EnsureUpperBound -- expression UB = min(UB, NumIterations).
     Expr *EUB;
     /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
     Expr *NLB;
@@ -547,6 +588,16 @@
     /// \brief PreviousUpperBound - local variable passed to runtime in the
     /// enclosing schedule or null if that does not apply.
     Expr *PrevUB;
+    /// \brief DistInc - increment expression for distribute loop when found
+    /// combined with a further loop level (e.g. in 'distribute parallel for')
+    /// expression IV = IV + ST
+    Expr *DistInc;
+    /// \brief PrevEUB - expression similar to EUB but to be used when loop
+    /// scheduling uses PrevLB and PrevUB (e.g.  in 'distribute parallel for'
+    /// when ensuring that the UB is either the calculated UB by the runtime or
+    /// the end of the assigned distribute chunk)
+    /// expression UB = min (UB, PrevUB)
+    Expr *PrevEUB;
     /// \brief Counters Loop counters.
     SmallVector<Expr *, 4> Counters;
     /// \brief PrivateCounters Loop counters.
@@ -588,6 +639,8 @@
       NumIterations = nullptr;
       PrevLB = nullptr;
       PrevUB = nullptr;
+      DistInc = nullptr;
+      PrevEUB = nullptr;
       Counters.resize(Size);
       PrivateCounters.resize(Size);
       Inits.resize(Size);
@@ -719,6 +772,22 @@
     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
         *std::next(child_begin(), PrevUpperBoundVariableOffset)));
   }
+  Expr *getDistInc() const {
+    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
+            isOpenMPDistributeDirective(getDirectiveKind())) &&
+           "expected worksharing loop directive");
+    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+        *std::next(child_begin(), DistIncOffset)));
+  }
+  Expr *getPrevEnsureUpperBound() const {
+    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
+            isOpenMPDistributeDirective(getDirectiveKind())) &&
+           "expected worksharing loop directive");
+    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+        *std::next(child_begin(), PrevEnsureUpperBoundOffset)));
+  }
   const Stmt *getBody() const {
     // This relies on the loop form is already checked by Sema.
     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
@@ -3439,6 +3508,347 @@
   }
 };
 
+/// This represents '#pragma omp target teams' directive.
+///
+/// \code
+/// #pragma omp target teams if(a>0)
+/// \endcode
+/// In this example directive '#pragma omp target teams' has clause 'if' with
+/// condition 'a>0'.
+///
+class OMPTargetTeamsDirective final : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// 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.
+  ///
+  OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                          unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
+                               OMPD_target_teams, StartLoc, EndLoc, NumClauses,
+                               1) {}
+
+  /// Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPTargetTeamsDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
+                               OMPD_target_teams, SourceLocation(),
+                               SourceLocation(), NumClauses, 1) {}
+
+public:
+  /// 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 OMPTargetTeamsDirective *Create(const ASTContext &C,
+                                         SourceLocation StartLoc,
+                                         SourceLocation EndLoc,
+                                         ArrayRef<OMPClause *> Clauses,
+                                         Stmt *AssociatedStmt);
+
+  /// Creates an empty directive with the place for \a NumClauses clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
+                                              unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
+  }
+};
+
+/// This represents '#pragma omp target teams distribute' combined directive.
+///
+/// \code
+/// #pragma omp target teams distribute private(x)
+/// \endcode
+/// In this example directive '#pragma omp target teams distribute' has clause
+/// 'private' with the variables 'x'
+///
+class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
+  friend class ASTStmtReader;
+
+  /// 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.
+  ///
+  OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
+                                    SourceLocation EndLoc,
+                                    unsigned CollapsedNum, unsigned NumClauses)
+      : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
+                         OMPD_target_teams_distribute, StartLoc, EndLoc,
+                         CollapsedNum, NumClauses) {}
+
+  /// Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum,
+                                             unsigned NumClauses)
+      : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
+                         OMPD_target_teams_distribute, SourceLocation(),
+                         SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+  /// 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.
+  /// \param Exprs Helper expressions for CodeGen.
+  ///
+  static OMPTargetTeamsDistributeDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+         Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+  /// 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 OMPTargetTeamsDistributeDirective *
+  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+              EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
+  }
+};
+
+/// This represents '#pragma omp target teams distribute parallel for' combined
+/// directive.
+///
+/// \code
+/// #pragma omp target teams distribute parallel for private(x)
+/// \endcode
+/// In this example directive '#pragma omp target teams distribute parallel
+/// for' has clause 'private' with the variables 'x'
+///
+class OMPTargetTeamsDistributeParallelForDirective final
+    : public OMPLoopDirective {
+  friend class ASTStmtReader;
+
+  /// 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.
+  ///
+  OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
+                                               SourceLocation EndLoc,
+                                               unsigned CollapsedNum,
+                                               unsigned NumClauses)
+      : OMPLoopDirective(this,
+                         OMPTargetTeamsDistributeParallelForDirectiveClass,
+                         OMPD_target_teams_distribute_parallel_for, StartLoc,
+                         EndLoc, CollapsedNum, NumClauses) {}
+
+  /// Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum,
+                                                        unsigned NumClauses)
+      : OMPLoopDirective(
+            this, OMPTargetTeamsDistributeParallelForDirectiveClass,
+            OMPD_target_teams_distribute_parallel_for, SourceLocation(),
+            SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+  /// 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.
+  /// \param Exprs Helper expressions for CodeGen.
+  ///
+  static OMPTargetTeamsDistributeParallelForDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+         Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+  /// 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 OMPTargetTeamsDistributeParallelForDirective *
+  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+              EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() ==
+           OMPTargetTeamsDistributeParallelForDirectiveClass;
+  }
+};
+
+/// This represents '#pragma omp target teams distribute parallel for simd'
+/// combined directive.
+///
+/// \code
+/// #pragma omp target teams distribute parallel for simd private(x)
+/// \endcode
+/// In this example directive '#pragma omp target teams distribute parallel
+/// for simd' has clause 'private' with the variables 'x'
+///
+class OMPTargetTeamsDistributeParallelForSimdDirective final
+    : public OMPLoopDirective {
+  friend class ASTStmtReader;
+
+  /// 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.
+  ///
+  OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
+                                                   SourceLocation EndLoc,
+                                                   unsigned CollapsedNum,
+                                                   unsigned NumClauses)
+      : OMPLoopDirective(this,
+                         OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
+                         OMPD_target_teams_distribute_parallel_for_simd,
+                         StartLoc, EndLoc, CollapsedNum, NumClauses) {}
+
+  /// Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPTargetTeamsDistributeParallelForSimdDirective(
+      unsigned CollapsedNum, unsigned NumClauses)
+      : OMPLoopDirective(
+            this, OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
+            OMPD_target_teams_distribute_parallel_for_simd, SourceLocation(),
+            SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+  /// 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.
+  /// \param Exprs Helper expressions for CodeGen.
+  ///
+  static OMPTargetTeamsDistributeParallelForSimdDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+         Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+  /// 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 OMPTargetTeamsDistributeParallelForSimdDirective *
+  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+              EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() ==
+           OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
+  }
+};
+
+/// This represents '#pragma omp target teams distribute simd' combined
+/// directive.
+///
+/// \code
+/// #pragma omp target teams distribute simd private(x)
+/// \endcode
+/// In this example directive '#pragma omp target teams distribute simd'
+/// has clause 'private' with the variables 'x'
+///
+class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
+  friend class ASTStmtReader;
+
+  /// 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.
+  ///
+  OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
+                                        SourceLocation EndLoc,
+                                        unsigned CollapsedNum,
+                                        unsigned NumClauses)
+      : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
+                         OMPD_target_teams_distribute_simd, StartLoc, EndLoc,
+                         CollapsedNum, NumClauses) {}
+
+  /// Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum,
+                                                 unsigned NumClauses)
+      : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
+                         OMPD_target_teams_distribute_simd, SourceLocation(),
+                         SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+  /// 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.
+  /// \param Exprs Helper expressions for CodeGen.
+  ///
+  static OMPTargetTeamsDistributeSimdDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+         Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+  /// 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 OMPTargetTeamsDistributeSimdDirective *
+  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+              EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
+  }
+};
+
 } // end namespace clang
 
 #endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index bccb578..84fbcda 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -119,10 +119,7 @@
   
 public:
   /// \brief Construct an empty, invalid template argument.
-  TemplateArgument() {
-    TypeOrValue.Kind = Null;
-    TypeOrValue.V = 0;
-  }
+  constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
 
   /// \brief Construct a template type argument.
   TemplateArgument(QualType T, bool isNullPtr = false) {
@@ -301,6 +298,10 @@
     Integer.Type = T.getAsOpaquePtr();
   }
 
+  /// \brief If this is a non-type template argument, get its type. Otherwise,
+  /// returns a null QualType.
+  QualType getNonTypeTemplateArgumentType() const;
+
   /// \brief Retrieve the template argument as an expression.
   Expr *getAsExpr() const {
     assert(getKind() == Expression && "Unexpected kind");
@@ -326,8 +327,8 @@
 
   /// \brief Iterator range referencing all of the elements of a template
   /// argument pack.
-  llvm::iterator_range<pack_iterator> pack_elements() const {
-    return llvm::make_range(pack_begin(), pack_end());
+  ArrayRef<TemplateArgument> pack_elements() const {
+    return llvm::makeArrayRef(pack_begin(), pack_end());
   }
 
   /// \brief The number of template arguments in the given template argument
@@ -384,8 +385,8 @@
   };
 
 public:
-  TemplateArgumentLocInfo();
-  
+  constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {}
+
   TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
   
   TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
@@ -429,7 +430,7 @@
   TemplateArgumentLocInfo LocInfo;
 
 public:
-  TemplateArgumentLoc() {}
+  constexpr TemplateArgumentLoc() {}
 
   TemplateArgumentLoc(const TemplateArgument &Argument,
                       TemplateArgumentLocInfo Opaque)
@@ -574,6 +575,7 @@
                                     TemplateArgumentLoc> {
 private:
   friend TrailingObjects;
+  friend class ASTNodeImporter;
 
   ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
 
@@ -592,6 +594,10 @@
     return getTrailingObjects<TemplateArgumentLoc>();
   }
 
+  llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
+    return llvm::makeArrayRef(getTemplateArgs(), NumTemplateArgs);
+  }
+
   const TemplateArgumentLoc &operator[](unsigned I) const {
     return getTemplateArgs()[I];
   }
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index d6b7107..9c1d110 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1744,7 +1744,6 @@
   bool isEventT() const;                        // OpenCL event_t
   bool isClkEventT() const;                     // OpenCL clk_event_t
   bool isQueueT() const;                        // OpenCL queue_t
-  bool isNDRangeT() const;                      // OpenCL ndrange_t
   bool isReserveIDT() const;                    // OpenCL reserve_id_t
 
   bool isPipeType() const;                      // OpenCL pipe type
@@ -1785,7 +1784,8 @@
   }
 
   /// \brief Determine whether this type is an undeduced type, meaning that
-  /// it somehow involves a C++11 'auto' type which has not yet been deduced.
+  /// it somehow involves a C++11 'auto' type or similar which has not yet been
+  /// deduced.
   bool isUndeducedType() const;
 
   /// \brief Whether this type is a variably-modified type (C99 6.7.5).
@@ -1862,10 +1862,22 @@
   /// not refer to a CXXRecordDecl, returns NULL.
   const CXXRecordDecl *getPointeeCXXRecordDecl() const;
 
+  /// Get the DeducedType whose type will be deduced for a variable with
+  /// an initializer of this type. This looks through declarators like pointer
+  /// types, but not through decltype or typedefs.
+  DeducedType *getContainedDeducedType() const;
+
   /// Get the AutoType whose type will be deduced for a variable with
   /// an initializer of this type. This looks through declarators like pointer
   /// types, but not through decltype or typedefs.
-  AutoType *getContainedAutoType() const;
+  AutoType *getContainedAutoType() const {
+    return dyn_cast_or_null<AutoType>(getContainedDeducedType());
+  }
+
+  /// Determine whether this type was written with a leading 'auto'
+  /// corresponding to a trailing return type (possibly for a nested
+  /// function type within a pointer to function type or similar).
+  bool hasAutoForTrailingReturnType() const;
 
   /// Member-template getAs<specific type>'.  Look through sugar for
   /// an instance of \<specific type>.   This scheme will eventually
@@ -1875,6 +1887,13 @@
   /// immediately following this class.
   template <typename T> const T *getAs() const;
 
+  /// Member-template getAsAdjusted<specific type>. Look through specific kinds
+  /// of sugar (parens, attributes, etc) for an instance of \<specific type>.
+  /// This is used when you need to walk over sugar nodes that represent some
+  /// kind of type adjustment from a type that was written as a \<specific type>
+  /// to another type that is still canonically a \<specific type>.
+  template <typename T> const T *getAsAdjusted() const;
+
   /// A variant of getAs<> for array types which silently discards
   /// qualifiers from the outermost type.
   const ArrayType *getAsArrayTypeUnsafe() const;
@@ -3097,9 +3116,11 @@
   class ExtParameterInfo {
     enum {
       ABIMask         = 0x0F,
-      IsConsumed      = 0x10
+      IsConsumed      = 0x10,
+      HasPassObjSize  = 0x20,
     };
     unsigned char Data;
+
   public:
     ExtParameterInfo() : Data(0) {}
 
@@ -3128,6 +3149,15 @@
       return copy;
     }
 
+    bool hasPassObjectSize() const {
+      return Data & HasPassObjSize;
+    }
+    ExtParameterInfo withHasPassObjectSize() const {
+      ExtParameterInfo Copy = *this;
+      Copy.Data |= HasPassObjSize;
+      return Copy;
+    }
+
     unsigned char getOpaqueValue() const { return Data; }
     static ExtParameterInfo getFromOpaqueValue(unsigned char data) {
       ExtParameterInfo result;
@@ -3827,13 +3857,13 @@
 
   friend class ASTContext; // creates these
 
-  AttributedType(QualType canon, Kind attrKind,
-                 QualType modified, QualType equivalent)
-    : Type(Attributed, canon, canon->isDependentType(),
-           canon->isInstantiationDependentType(),
-           canon->isVariablyModifiedType(),
-           canon->containsUnexpandedParameterPack()),
-      ModifiedType(modified), EquivalentType(equivalent) {
+  AttributedType(QualType canon, Kind attrKind, QualType modified,
+                 QualType equivalent)
+      : Type(Attributed, canon, equivalent->isDependentType(),
+             equivalent->isInstantiationDependentType(),
+             equivalent->isVariablyModifiedType(),
+             equivalent->containsUnexpandedParameterPack()),
+        ModifiedType(modified), EquivalentType(equivalent) {
     AttributedTypeBits.AttrKind = attrKind;
   }
 
@@ -4089,21 +4119,60 @@
   }
 };
 
-/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
+/// \brief Common base class for placeholders for types that get replaced by
+/// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced
+/// class template types, and (eventually) constrained type names from the C++
+/// Concepts TS.
 ///
 /// These types are usually a placeholder for a deduced type. However, before
-/// the initializer is attached, or if the initializer is type-dependent, there
-/// is no deduced type and an auto type is canonical. In the latter case, it is
-/// also a dependent type.
-class AutoType : public Type, public llvm::FoldingSetNode {
-  AutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent)
-    : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
-           /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
-           /*VariablyModified=*/false,
-           /*ContainsParameterPack=*/DeducedType.isNull()
-               ? false : DeducedType->containsUnexpandedParameterPack()) {
-    assert((DeducedType.isNull() || !IsDependent) &&
-           "auto deduced to dependent type");
+/// the initializer is attached, or (usually) if the initializer is
+/// type-dependent, there is no deduced type and the type is canonical. In
+/// the latter case, it is also a dependent type.
+class DeducedType : public Type {
+protected:
+  DeducedType(TypeClass TC, QualType DeducedAsType, bool IsDependent,
+              bool IsInstantiationDependent, bool ContainsParameterPack)
+      : Type(TC,
+             // FIXME: Retain the sugared deduced type?
+             DeducedAsType.isNull() ? QualType(this, 0)
+                                    : DeducedAsType.getCanonicalType(),
+             IsDependent, IsInstantiationDependent,
+             /*VariablyModified=*/false, ContainsParameterPack) {
+    if (!DeducedAsType.isNull()) {
+      if (DeducedAsType->isDependentType())
+        setDependent();
+      if (DeducedAsType->isInstantiationDependentType())
+        setInstantiationDependent();
+      if (DeducedAsType->containsUnexpandedParameterPack())
+        setContainsUnexpandedParameterPack();
+    }
+  }
+
+public:
+  bool isSugared() const { return !isCanonicalUnqualified(); }
+  QualType desugar() const { return getCanonicalTypeInternal(); }
+
+  /// \brief Get the type deduced for this placeholder type, or null if it's
+  /// either not been deduced or was deduced to a dependent type.
+  QualType getDeducedType() const {
+    return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
+  }
+  bool isDeduced() const {
+    return !isCanonicalUnqualified() || isDependentType();
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Auto ||
+           T->getTypeClass() == DeducedTemplateSpecialization;
+  }
+};
+
+/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
+class AutoType : public DeducedType, public llvm::FoldingSetNode {
+  AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
+           bool IsDeducedAsDependent)
+      : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent,
+                    IsDeducedAsDependent, /*ContainsPack=*/false) {
     AutoTypeBits.Keyword = (unsigned)Keyword;
   }
 
@@ -4117,18 +4186,6 @@
     return (AutoTypeKeyword)AutoTypeBits.Keyword;
   }
 
-  bool isSugared() const { return !isCanonicalUnqualified(); }
-  QualType desugar() const { return getCanonicalTypeInternal(); }
-
-  /// \brief Get the type deduced for this auto type, or null if it's either
-  /// not been deduced or was deduced to a dependent type.
-  QualType getDeducedType() const {
-    return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
-  }
-  bool isDeduced() const {
-    return !isCanonicalUnqualified() || isDependentType();
-  }
-
   void Profile(llvm::FoldingSetNodeID &ID) {
     Profile(ID, getDeducedType(), getKeyword(), isDependentType());
   }
@@ -4145,6 +4202,43 @@
   }
 };
 
+/// \brief Represents a C++17 deduced template specialization type.
+class DeducedTemplateSpecializationType : public DeducedType,
+                                          public llvm::FoldingSetNode {
+  /// The name of the template whose arguments will be deduced.
+  TemplateName Template;
+
+  DeducedTemplateSpecializationType(TemplateName Template,
+                                    QualType DeducedAsType,
+                                    bool IsDeducedAsDependent)
+      : DeducedType(DeducedTemplateSpecialization, DeducedAsType,
+                    IsDeducedAsDependent || Template.isDependent(),
+                    IsDeducedAsDependent || Template.isInstantiationDependent(),
+                    Template.containsUnexpandedParameterPack()),
+        Template(Template) {}
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  /// Retrieve the name of the template that we are deducing.
+  TemplateName getTemplateName() const { return Template;}
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getTemplateName(), getDeducedType(), isDependentType());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
+                      QualType Deduced, bool IsDependent) {
+    Template.Profile(ID);
+    ID.AddPointer(Deduced.getAsOpaquePtr());
+    ID.AddBoolean(IsDependent);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DeducedTemplateSpecialization;
+  }
+};
+
 /// \brief Represents a type template specialization; the template
 /// must be a class template, a type alias template, or a template
 /// template parameter.  A template which cannot be resolved to one of
@@ -4341,6 +4435,9 @@
   const TemplateSpecializationType *getInjectedTST() const {
     return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
   }
+  TemplateName getTemplateName() const {
+    return getInjectedTST()->getTemplateName();
+  }
 
   CXXRecordDecl *getDecl() const;
 
@@ -5714,10 +5811,6 @@
   return isSpecificBuiltinType(BuiltinType::OCLQueue);
 }
 
-inline bool Type::isNDRangeT() const {
-  return isSpecificBuiltinType(BuiltinType::OCLNDRange);
-}
-
 inline bool Type::isReserveIDT() const {
   return isSpecificBuiltinType(BuiltinType::OCLReserveID);
 }
@@ -5735,7 +5828,7 @@
 
 inline bool Type::isOpenCLSpecificType() const {
   return isSamplerT() || isEventT() || isImageType() || isClkEventT() ||
-         isQueueT() || isNDRangeT() || isReserveIDT() || isPipeType();
+         isQueueT() || isReserveIDT() || isPipeType();
 }
 
 inline bool Type::isTemplateTypeParmType() const {
@@ -5845,8 +5938,8 @@
 }
 
 inline bool Type::isUndeducedType() const {
-  const AutoType *AT = getContainedAutoType();
-  return AT && !AT->isDeduced();
+  auto *DT = getContainedDeducedType();
+  return DT && !DT->isDeduced();
 }
 
 /// \brief Determines whether this is a type for which one can define
@@ -5928,6 +6021,38 @@
   return cast<T>(getUnqualifiedDesugaredType());
 }
 
+template <typename T> const T *Type::getAsAdjusted() const {
+  static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!");
+
+  // If this is directly a T type, return it.
+  if (const T *Ty = dyn_cast<T>(this))
+    return Ty;
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (!isa<T>(CanonicalType))
+    return nullptr;
+
+  // Strip off type adjustments that do not modify the underlying nature of the
+  // type.
+  const Type *Ty = this;
+  while (Ty) {
+    if (const auto *A = dyn_cast<AttributedType>(Ty))
+      Ty = A->getModifiedType().getTypePtr();
+    else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
+      Ty = E->desugar().getTypePtr();
+    else if (const auto *P = dyn_cast<ParenType>(Ty))
+      Ty = P->desugar().getTypePtr();
+    else if (const auto *A = dyn_cast<AdjustedType>(Ty))
+      Ty = A->desugar().getTypePtr();
+    else
+      break;
+  }
+
+  // Just because the canonical type is correct does not mean we can use cast<>,
+  // since we may not have stripped off all the sugar down to the base type.
+  return dyn_cast<T>(Ty);
+}
+
 inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
   // If this is directly an array type, return it.
   if (const ArrayType *arr = dyn_cast<ArrayType>(this))
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 7de6668..525f848 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -70,6 +70,13 @@
     return t;
   }
 
+  /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
+  /// this TypeLock is not of the desired type. It will consider type
+  /// adjustments from a type that wad written as a T to another type that is
+  /// still canonically a T (ignores parens, attributes, elaborated types, etc).
+  template <typename T>
+  T getAsAdjusted() const;
+
   /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
   /// except it also defines a Qualified enum that corresponds to the
   /// QualifiedLoc class.
@@ -1351,6 +1358,19 @@
                                                FunctionTypeLoc,
                                                FunctionType,
                                                FunctionLocInfo> {
+  bool hasExceptionSpec() const {
+    if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
+      return FPT->hasExceptionSpec();
+    }
+    return false;
+  }
+
+  SourceRange *getExceptionSpecRangePtr() const {
+    assert(hasExceptionSpec() && "No exception spec range");
+    // After the Info comes the ParmVarDecl array, and after that comes the
+    // exception specification information.
+    return (SourceRange *)(getParmArray() + getNumParams());
+  }
 public:
   SourceLocation getLocalRangeBegin() const {
     return getLocalData()->LocalRangeBegin;
@@ -1384,6 +1404,16 @@
     return SourceRange(getLParenLoc(), getRParenLoc());
   }
 
+  SourceRange getExceptionSpecRange() const {
+    if (hasExceptionSpec())
+      return *getExceptionSpecRangePtr();
+    return SourceRange();
+  }
+  void setExceptionSpecRange(SourceRange R) {
+    if (hasExceptionSpec())
+      *getExceptionSpecRangePtr() = R;
+  }
+
   ArrayRef<ParmVarDecl *> getParams() const {
     return llvm::makeArrayRef(getParmArray(), getNumParams());
   }
@@ -1416,12 +1446,15 @@
     setLocalRangeEnd(Loc);
     for (unsigned i = 0, e = getNumParams(); i != e; ++i)
       setParam(i, nullptr);
+    if (hasExceptionSpec())
+      setExceptionSpecRange(Loc);
   }
 
   /// \brief Returns the size of the type source info data block that is
   /// specific to this type.
   unsigned getExtraLocalDataSize() const {
-    return getNumParams() * sizeof(ParmVarDecl *);
+    unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
+    return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
   }
 
   unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
@@ -1801,9 +1834,25 @@
   }
 };
 
-class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
-                                                        AutoTypeLoc,
-                                                        AutoType> {
+class DeducedTypeLoc
+    : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
+                                       DeducedType> {};
+
+class AutoTypeLoc
+    : public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> {
+};
+
+class DeducedTemplateSpecializationTypeLoc
+    : public InheritingConcreteTypeLoc<DeducedTypeLoc,
+                                       DeducedTemplateSpecializationTypeLoc,
+                                       DeducedTemplateSpecializationType> {
+public:
+  SourceLocation getTemplateNameLoc() const {
+    return getNameLoc();
+  }
+  void setTemplateNameLoc(SourceLocation Loc) {
+    setNameLoc(Loc);
+  }
 };
 
 struct ElaboratedLocInfo {
@@ -2146,6 +2195,24 @@
 
   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
 };
+
+template <typename T>
+inline T TypeLoc::getAsAdjusted() const {
+  TypeLoc Cur = *this;
+  while (!T::isKind(Cur)) {
+    if (auto PTL = Cur.getAs<ParenTypeLoc>())
+      Cur = PTL.getInnerLoc();
+    else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
+      Cur = ATL.getModifiedLoc();
+    else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
+      Cur = ETL.getNamedTypeLoc();
+    else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
+      Cur = ATL.getOriginalLoc();
+    else
+      break;
+  }
+  return Cur.getAs<T>();
+}
 }
 
 #endif
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 27ab21b..9d1d09e 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -96,7 +96,9 @@
 NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
 DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
-TYPE(Auto, Type)
+ABSTRACT_TYPE(Deduced, Type)
+TYPE(Auto, DeducedType)
+TYPE(DeducedTemplateSpecialization, DeducedType)
 DEPENDENT_TYPE(InjectedClassName, Type)
 DEPENDENT_TYPE(DependentName, Type)
 DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
index 8f0feed..5cbcf51 100644
--- a/include/clang/AST/VTableBuilder.h
+++ b/include/clang/AST/VTableBuilder.h
@@ -218,52 +218,77 @@
 class VTableLayout {
 public:
   typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
-  typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
+  struct AddressPointLocation {
+    unsigned VTableIndex, AddressPointIndex;
+  };
+  typedef llvm::DenseMap<BaseSubobject, AddressPointLocation>
+      AddressPointsMapTy;
 
 private:
-  uint64_t NumVTableComponents;
-  std::unique_ptr<VTableComponent[]> VTableComponents;
+  // Stores the component indices of the first component of each virtual table in
+  // the virtual table group. To save a little memory in the common case where
+  // the vtable group contains a single vtable, an empty vector here represents
+  // the vector {0}.
+  OwningArrayRef<size_t> VTableIndices;
+
+  OwningArrayRef<VTableComponent> VTableComponents;
 
   /// \brief Contains thunks needed by vtables, sorted by indices.
-  uint64_t NumVTableThunks;
-  std::unique_ptr<VTableThunkTy[]> VTableThunks;
+  OwningArrayRef<VTableThunkTy> VTableThunks;
 
   /// \brief Address points for all vtables.
   AddressPointsMapTy AddressPoints;
 
-  bool IsMicrosoftABI;
-
 public:
-  VTableLayout(uint64_t NumVTableComponents,
-               const VTableComponent *VTableComponents,
-               uint64_t NumVTableThunks,
-               const VTableThunkTy *VTableThunks,
-               const AddressPointsMapTy &AddressPoints,
-               bool IsMicrosoftABI);
+  VTableLayout(ArrayRef<size_t> VTableIndices,
+               ArrayRef<VTableComponent> VTableComponents,
+               ArrayRef<VTableThunkTy> VTableThunks,
+               const AddressPointsMapTy &AddressPoints);
   ~VTableLayout();
 
   ArrayRef<VTableComponent> vtable_components() const {
-    return {VTableComponents.get(), size_t(NumVTableComponents)};
+    return VTableComponents;
   }
 
   ArrayRef<VTableThunkTy> vtable_thunks() const {
-    return {VTableThunks.get(), size_t(NumVTableThunks)};
+    return VTableThunks;
   }
 
-  uint64_t getAddressPoint(BaseSubobject Base) const {
-    assert(AddressPoints.count(Base) &&
-           "Did not find address point!");
-
-    uint64_t AddressPoint = AddressPoints.lookup(Base);
-    assert(AddressPoint != 0 || IsMicrosoftABI);
-    (void)IsMicrosoftABI;
-
-    return AddressPoint;
+  AddressPointLocation getAddressPoint(BaseSubobject Base) const {
+    assert(AddressPoints.count(Base) && "Did not find address point!");
+    return AddressPoints.find(Base)->second;
   }
 
   const AddressPointsMapTy &getAddressPoints() const {
     return AddressPoints;
   }
+
+  size_t getNumVTables() const {
+    if (VTableIndices.empty())
+      return 1;
+    return VTableIndices.size();
+  }
+
+  size_t getVTableOffset(size_t i) const {
+    if (VTableIndices.empty()) {
+      assert(i == 0);
+      return 0;
+    }
+    return VTableIndices[i];
+  }
+
+  size_t getVTableSize(size_t i) const {
+    if (VTableIndices.empty()) {
+      assert(i == 0);
+      return vtable_components().size();
+    }
+
+    size_t thisIndex = VTableIndices[i];
+    size_t nextIndex = (i + 1 == VTableIndices.size())
+                           ? vtable_components().size()
+                           : VTableIndices[i + 1];
+    return nextIndex - thisIndex;
+  }
 };
 
 class VTableContextBase {
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index ce01f45..6c1c8e4 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -75,18 +75,6 @@
     return MyBoundNodes.getNodeAs<T>(ID);
   }
 
-  /// \brief Deprecated. Please use \c getNodeAs instead.
-  /// @{
-  template <typename T>
-  const T *getDeclAs(StringRef ID) const {
-    return getNodeAs<T>(ID);
-  }
-  template <typename T>
-  const T *getStmtAs(StringRef ID) const {
-    return getNodeAs<T>(ID);
-  }
-  /// @}
-
   /// \brief Type of mapping from binding identifiers to bound nodes. This type
   /// is an associative container with a key type of \c std::string and a value
   /// type of \c clang::ast_type_traits::DynTypedNode
@@ -545,7 +533,8 @@
   return Node.isBitField();
 }
 
-/// \brief Matches non-static data members that are bit-fields.
+/// \brief Matches non-static data members that are bit-fields of the specified
+/// bit width.
 ///
 /// Given
 /// \code
@@ -555,13 +544,34 @@
 ///     int c : 2;
 ///   };
 /// \endcode
-/// fieldDecl(isBitField())
+/// fieldDecl(hasBitWidth(2))
 ///   matches 'int a;' and 'int c;' but not 'int b;'.
 AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) {
   return Node.isBitField() &&
          Node.getBitWidthValue(Finder->getASTContext()) == Width;
 }
 
+/// \brief Matches non-static data members that have an in-class initializer.
+///
+/// Given
+/// \code
+///   class C {
+///     int a = 2;
+///     int b = 3;
+///     int c;
+///   };
+/// \endcode
+/// fieldDecl(hasInClassInitializer(integerLiteral(equals(2))))
+///   matches 'int a;' but not 'int b;'.
+/// fieldDecl(hasInClassInitializer(anything()))
+///   matches 'int a;' and 'int b;' but not 'int c;'.
+AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher<Expr>,
+              InnerMatcher) {
+  const Expr *Initializer = Node.getInClassInitializer();
+  return (Initializer != nullptr &&
+          InnerMatcher.matches(*Initializer, Finder, Builder));
+}
+
 /// \brief Matches a declaration that has been implicitly added
 /// by the compiler (eg. implicit default/copy constructors).
 AST_MATCHER(Decl, isImplicit) {
@@ -5497,7 +5507,7 @@
       integerLiteral(equals(0), hasParent(expr(hasType(pointerType())))));
 }
 
-/// \brief Matches declaration of the function the statemenet belongs to
+/// \brief Matches declaration of the function the statement belongs to
 ///
 /// Given:
 /// \code
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 547e6bc..bc75e80 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1421,18 +1421,18 @@
 template <>
 inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
     const FloatingLiteral &Node) const {
-  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
+  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
     return Node.getValue().convertToFloat() == ExpectedValue;
-  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
+  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
     return Node.getValue().convertToDouble() == ExpectedValue;
   return false;
 }
 template <>
 inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
     const FloatingLiteral &Node) const {
-  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
+  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
     return Node.getValue().convertToFloat() == ExpectedValue;
-  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
+  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
     return Node.getValue().convertToDouble() == ExpectedValue;
   return false;
 }
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
index 5296edd..2c80b51 100644
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -119,9 +119,9 @@
   /// \brief Payload interface to be specialized by each matcher type.
   ///
   /// It follows a similar interface as VariantMatcher itself.
-  class Payload : public RefCountedBaseVPTR {
+  class Payload {
   public:
-    ~Payload() override;
+    virtual ~Payload();
     virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
     virtual std::string getTypeAsString() const = 0;
     virtual llvm::Optional<DynTypedMatcher>
@@ -208,7 +208,8 @@
   std::string getTypeAsString() const;
 
 private:
-  explicit VariantMatcher(Payload *Value) : Value(Value) {}
+  explicit VariantMatcher(std::shared_ptr<Payload> Value)
+      : Value(std::move(Value)) {}
 
   template <typename T> struct TypedMatcherOps;
 
@@ -216,7 +217,7 @@
   class PolymorphicPayload;
   class VariadicOpPayload;
 
-  IntrusiveRefCntPtr<const Payload> Value;
+  std::shared_ptr<const Payload> Value;
 };
 
 template <typename T>
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index 6813da9..8c531d6 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -211,6 +211,8 @@
         return false;
       case PercentArg:
         return false;
+      case InvalidSpecifier:
+        return false;
       default:
         return true;
     }
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index ea1c4a0..a2a27a8 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -98,7 +98,7 @@
   bool VisitFunctionDecl(FunctionDecl *FD) {
     // We skip function template definitions, as their semantics is
     // only determined when they are instantiated.
-    if (includeInGraph(FD)) {
+    if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) {
       // Add all blocks declared inside this function to the graph.
       addNodesForBlocks(FD);
       // If this function has external linkage, anything could call it.
@@ -157,7 +157,7 @@
   inline bool empty() const {return CalledFunctions.empty(); }
   inline unsigned size() const {return CalledFunctions.size(); }
 
-  void addCallee(CallGraphNode *N, CallGraph *CG) {
+  void addCallee(CallGraphNode *N) {
     CalledFunctions.push_back(N);
   }
 
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 4692495..5960cca 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -140,12 +140,15 @@
   bit Fake = fake;
 }
 
-class BoolArgument<string name, bit opt = 0> : Argument<name, opt>;
+class BoolArgument<string name, bit opt = 0, bit fake = 0> : Argument<name, opt,
+                                                                      fake>;
 class IdentifierArgument<string name, bit opt = 0> : Argument<name, opt>;
 class IntArgument<string name, bit opt = 0> : Argument<name, opt>;
 class StringArgument<string name, bit opt = 0> : Argument<name, opt>;
 class ExprArgument<string name, bit opt = 0> : Argument<name, opt>;
-class FunctionArgument<string name, bit opt = 0> : Argument<name, opt>;
+class FunctionArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
+                                                                          opt,
+                                                                          fake>;
 class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
 class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
 class VariadicUnsignedArgument<string name> : Argument<name, 1>;
@@ -255,6 +258,7 @@
   list<string> CXXABIs;
 }
 def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
+def TargetAVR : TargetArch<["avr"]>;
 def TargetMips : TargetArch<["mips", "mipsel"]>;
 def TargetMSP430 : TargetArch<["msp430"]>;
 def TargetX86 : TargetArch<["x86"]>;
@@ -337,7 +341,7 @@
   // should contain a shared value between the attributes.
   //
   // Target-specific attributes which use this feature should ensure that the
-  // spellings match exactly betweeen the attributes, and if the arguments or
+  // spellings match exactly between the attributes, and if the arguments or
   // subjects differ, should specify HasCustomParsing = 1 and implement their
   // own parsing and semantic handling requirements as-needed.
   string ParseKind;
@@ -446,6 +450,15 @@
   let Documentation = [XRayDocs];
 }
 
+def XRayLogArgs : InheritableAttr {
+  let Spellings = [GNU<"xray_log_args">, CXX11<"clang", "xray_log_args">];
+  let Subjects = SubjectList<
+      [CXXMethod, ObjCMethod, Function], WarnDiag, "ExpectedFunctionOrMethod"
+  >;
+  let Args = [UnsignedArgument<"ArgumentCount">];
+  let Documentation = [XRayDocs];
+}
+
 def TLSModel : InheritableAttr {
   let Spellings = [GCC<"tls_model">];
   let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">;
@@ -477,6 +490,19 @@
   let Documentation = [ARMInterruptDocs];
 }
 
+def AVRInterrupt : InheritableAttr, TargetSpecificAttr<TargetAVR> {
+  let Spellings = [GNU<"interrupt">];
+  let Subjects = SubjectList<[Function]>;
+  let ParseKind = "Interrupt";
+  let Documentation = [AVRInterruptDocs];
+}
+
+def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> {
+  let Spellings = [GNU<"signal">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [AVRSignalDocs];
+}
+
 def AsmLabel : InheritableAttr {
   let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
   let Args = [StringArgument<"Label">];
@@ -510,6 +536,17 @@
   let Documentation = [AvailabilityDocs];
 }
 
+def ExternalSourceSymbol : InheritableAttr {
+  let Spellings = [GNU<"external_source_symbol">,
+                   CXX11<"clang", "external_source_symbol">];
+  let Args = [StringArgument<"language", 1>,
+              StringArgument<"definedIn", 1>,
+              BoolArgument<"generatedDeclaration", 1>];
+  let HasCustomParsing = 1;
+//  let Subjects = SubjectList<[Named]>;
+  let Documentation = [ExternalSourceSymbolDocs];
+}
+
 def Blocks : InheritableAttr {
   let Spellings = [GNU<"blocks">];
   let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
@@ -601,49 +638,53 @@
   let Documentation = [Undocumented];
 }
 
+// CUDA attributes are spelled __attribute__((attr)) or __declspec(__attr__).
+
 def CUDAConstant : InheritableAttr {
-  let Spellings = [GNU<"constant">];
+  let Spellings = [GNU<"constant">, Declspec<"__constant__">];
   let Subjects = SubjectList<[Var]>;
   let LangOpts = [CUDA];
   let Documentation = [Undocumented];
 }
 
 def CUDACudartBuiltin : IgnoredAttr {
-  let Spellings = [GNU<"cudart_builtin">];
+  let Spellings = [GNU<"cudart_builtin">, Declspec<"__cudart_builtin__">];
   let LangOpts = [CUDA];
 }
 
 def CUDADevice : InheritableAttr {
-  let Spellings = [GNU<"device">];
+  let Spellings = [GNU<"device">, Declspec<"__device__">];
   let Subjects = SubjectList<[Function, Var]>;
   let LangOpts = [CUDA];
   let Documentation = [Undocumented];
 }
 
 def CUDADeviceBuiltin : IgnoredAttr {
-  let Spellings = [GNU<"device_builtin">];
+  let Spellings = [GNU<"device_builtin">, Declspec<"__device_builtin__">];
   let LangOpts = [CUDA];
 }
 
 def CUDADeviceBuiltinSurfaceType : IgnoredAttr {
-  let Spellings = [GNU<"device_builtin_surface_type">];
+  let Spellings = [GNU<"device_builtin_surface_type">,
+                   Declspec<"__device_builtin_surface_type__">];
   let LangOpts = [CUDA];
 }
 
 def CUDADeviceBuiltinTextureType : IgnoredAttr {
-  let Spellings = [GNU<"device_builtin_texture_type">];
+  let Spellings = [GNU<"device_builtin_texture_type">,
+                   Declspec<"__device_builtin_texture_type__">];
   let LangOpts = [CUDA];
 }
 
 def CUDAGlobal : InheritableAttr {
-  let Spellings = [GNU<"global">];
+  let Spellings = [GNU<"global">, Declspec<"__global__">];
   let Subjects = SubjectList<[Function]>;
   let LangOpts = [CUDA];
   let Documentation = [Undocumented];
 }
 
 def CUDAHost : InheritableAttr {
-  let Spellings = [GNU<"host">];
+  let Spellings = [GNU<"host">, Declspec<"__host__">];
   let Subjects = SubjectList<[Function]>;
   let LangOpts = [CUDA];
   let Documentation = [Undocumented];
@@ -657,7 +698,7 @@
 }
 
 def CUDALaunchBounds : InheritableAttr {
-  let Spellings = [GNU<"launch_bounds">];
+  let Spellings = [GNU<"launch_bounds">, Declspec<"__launch_bounds__">];
   let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>];
   let LangOpts = [CUDA];
   let Subjects = SubjectList<[ObjCMethod, FunctionLike], WarnDiag,
@@ -669,7 +710,7 @@
 }
 
 def CUDAShared : InheritableAttr {
-  let Spellings = [GNU<"shared">];
+  let Spellings = [GNU<"shared">, Declspec<"__shared__">];
   let Subjects = SubjectList<[Var]>;
   let LangOpts = [CUDA];
   let Documentation = [Undocumented];
@@ -780,6 +821,14 @@
   let Documentation = [EmptyBasesDocs];
 }
 
+def AllocSize : InheritableAttr {
+  let Spellings = [GCC<"alloc_size">];
+  let Subjects = SubjectList<[Function]>;
+  let Args = [IntArgument<"ElemSizeParam">, IntArgument<"NumElemsParam", 1>];
+  let TemplateDependent = 1;
+  let Documentation = [AllocSizeDocs];
+}
+
 def EnableIf : InheritableAttr {
   let Spellings = [GNU<"enable_if">];
   let Subjects = SubjectList<[Function]>;
@@ -1100,7 +1149,7 @@
   let Documentation = [NoSplitStackDocs];
 }
 
-def NonNull : InheritableAttr {
+def NonNull : InheritableParamAttr {
   let Spellings = [GCC<"nonnull">];
   let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
                              "ExpectedFunctionMethodOrParameter">;
@@ -1187,6 +1236,8 @@
 }
 
 def NvWeak : IgnoredAttr {
+  // No Declspec spelling of this attribute; the CUDA headers use
+  // __attribute__((nv_weak)) unconditionally.
   let Spellings = [GNU<"nv_weak">];
   let LangOpts = [CUDA];
 }
@@ -1577,6 +1628,26 @@
   let Documentation = [Undocumented];
 }
 
+def DiagnoseIf : InheritableAttr {
+  let Spellings = [GNU<"diagnose_if">];
+  let Subjects = SubjectList<[Function]>;
+  let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
+              EnumArgument<"DiagnosticType",
+                           "DiagnosticType",
+                           ["error", "warning"],
+                           ["DT_Error", "DT_Warning"]>,
+              BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
+              FunctionArgument<"Parent", 0, /*fake*/ 1>];
+  let DuplicatesAllowedWhileMerging = 1;
+  let LateParsed = 1;
+  let AdditionalMembers = [{
+    bool isError() const { return diagnosticType == DT_Error; }
+    bool isWarning() const { return diagnosticType == DT_Warning; }
+  }];
+  let TemplateDependent = 1;
+  let Documentation = [DiagnoseIfDocs];
+}
+
 def ArcWeakrefUnavailable : InheritableAttr {
   let Spellings = [GNU<"objc_arc_weak_reference_unavailable">];
   let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
@@ -1618,7 +1689,9 @@
 def Uuid : InheritableAttr {
   let Spellings = [Declspec<"uuid">, Microsoft<"uuid">];
   let Args = [StringArgument<"Guid">];
-//  let Subjects = SubjectList<[CXXRecord]>;
+  let Subjects = SubjectList<[Record, Enum], WarnDiag, "ExpectedEnumOrClass">;
+  // FIXME: Allow expressing logical AND for LangOpts. Our condition should be:
+  // CPlusPlus && (MicrosoftExt || Borland)
   let LangOpts = [MicrosoftExt, Borland];
   let Documentation = [Undocumented];
 }
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 5502af2..df299e0 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -206,6 +206,44 @@
   }];
 }
 
+def AllocSizeDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``alloc_size`` attribute can be placed on functions that return pointers in
+order to hint to the compiler how many bytes of memory will be available at the
+returned poiner. ``alloc_size`` takes one or two arguments.
+
+- ``alloc_size(N)`` implies that argument number N equals the number of
+  available bytes at the returned pointer.
+- ``alloc_size(N, M)`` implies that the product of argument number N and
+  argument number M equals the number of available bytes at the returned
+  pointer.
+
+Argument numbers are 1-based.
+
+An example of how to use ``alloc_size``
+
+.. code-block:: c
+
+  void *my_malloc(int a) __attribute__((alloc_size(1)));
+  void *my_calloc(int a, int b) __attribute__((alloc_size(1, 2)));
+
+  int main() {
+    void *const p = my_malloc(100);
+    assert(__builtin_object_size(p, 0) == 100);
+    void *const a = my_calloc(20, 5);
+    assert(__builtin_object_size(a, 0) == 100);
+  }
+
+.. Note:: This attribute works differently in clang than it does in GCC.
+  Specifically, clang will only trace ``const`` pointers (as above); we give up
+  on pointers that are not marked as ``const``. In the vast majority of cases,
+  this is unimportant, because LLVM has support for the ``alloc_size``
+  attribute. However, this may cause mildly unintuitive behavior when used with
+  other attributes, such as ``enable_if``.
+  }];
+}
+
 def EnableIfDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
@@ -340,6 +378,66 @@
   }];
 }
 
+def DiagnoseIfDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``diagnose_if`` attribute can be placed on function declarations to emit
+warnings or errors at compile-time if calls to the attributed function meet
+certain user-defined criteria. For example:
+
+.. code-block:: c
+
+  void abs(int a)
+    __attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning")));
+  void must_abs(int a)
+    __attribute__((diagnose_if(a >= 0, "Redundant abs call", "error")));
+
+  int val = abs(1); // warning: Redundant abs call
+  int val2 = must_abs(1); // error: Redundant abs call
+  int val3 = abs(val);
+  int val4 = must_abs(val); // Because run-time checks are not emitted for
+                            // diagnose_if attributes, this executes without
+                            // issue.
+
+
+``diagnose_if`` is closely related to ``enable_if``, with a few key differences:
+
+* Overload resolution is not aware of ``diagnose_if`` attributes: they're
+  considered only after we select the best candidate from a given candidate set.
+* Function declarations that differ only in their ``diagnose_if`` attributes are
+  considered to be redeclarations of the same function (not overloads).
+* If the condition provided to ``diagnose_if`` cannot be evaluated, no
+  diagnostic will be emitted.
+
+Otherwise, ``diagnose_if`` is essentially the logical negation of ``enable_if``.
+
+As a result of bullet number two, ``diagnose_if`` attributes will stack on the
+same function. For example:
+
+.. code-block:: c
+
+  int foo() __attribute__((diagnose_if(1, "diag1", "warning")));
+  int foo() __attribute__((diagnose_if(1, "diag2", "warning")));
+
+  int bar = foo(); // warning: diag1
+                   // warning: diag2
+  int (*fooptr)(void) = foo; // warning: diag1
+                             // warning: diag2
+
+  constexpr int supportsAPILevel(int N) { return N < 5; }
+  int baz(int a)
+    __attribute__((diagnose_if(!supportsAPILevel(10),
+                               "Upgrade to API level 10 to use baz", "error")));
+  int baz(int a)
+    __attribute__((diagnose_if(!a, "0 is not recommended.", "warning")));
+
+  int (*bazptr)(int) = baz; // error: Upgrade to API level 10 to use baz
+  int v = baz(0); // error: Upgrade to API level 10 to use baz
+
+Query for this feature with ``__has_attribute(diagnose_if)``.
+  }];
+}
+
 def PassObjectSizeDocs : Documentation {
   let Category = DocCatVariable; // Technically it's a parameter doc, but eh.
   let Content = [{
@@ -862,6 +960,63 @@
   }];
 }
 
+def ExternalSourceSymbolDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``external_source_symbol`` attribute specifies that a declaration originates
+from an external source and describes the nature of that source.
+
+The fact that Clang is capable of recognizing declarations that were defined
+externally can be used to provide better tooling support for mixed-language
+projects or projects that rely on auto-generated code. For instance, an IDE that
+uses Clang and that supports mixed-language projects can use this attribute to
+provide a correct 'jump-to-definition' feature. For a concrete example,
+consider a protocol that's defined in a Swift file:
+
+.. code-block:: swift
+
+  @objc public protocol SwiftProtocol {
+    func method()
+  }
+
+This protocol can be used from Objective-C code by including a header file that
+was generated by the Swift compiler. The declarations in that header can use
+the ``external_source_symbol`` attribute to make Clang aware of the fact
+that ``SwiftProtocol`` actually originates from a Swift module:
+
+.. code-block:: objc
+
+  __attribute__((external_source_symbol(language="Swift",defined_in="module")))
+  @protocol SwiftProtocol
+  @required
+  - (void) method;
+  @end
+
+Consequently, when 'jump-to-definition' is performed at a location that
+references ``SwiftProtocol``, the IDE can jump to the original definition in
+the Swift source file rather than jumping to the Objective-C declaration in the
+auto-generated header file.
+
+The ``external_source_symbol`` attribute is a comma-separated list that includes
+clauses that describe the origin and the nature of the particular declaration.
+Those clauses can be:
+
+language=\ *string-literal*
+  The name of the source language in which this declaration was defined.
+
+defined_in=\ *string-literal*
+  The name of the source container in which the declaration was defined. The
+  exact definition of source container is language-specific, e.g. Swift's
+  source containers are modules, so ``defined_in`` should specify the Swift
+  module name.
+
+generated_declaration
+  This declaration was automatically generated by some tool.
+
+The clauses can be specified in any order. The clauses that are listed above are
+all optional, but the attribute has to have at least one clause.
+  }];
+}
 
 def RequireConstantInitDocs : Documentation {
   let Category = DocCatVariable;
@@ -1084,6 +1239,33 @@
   }];
 }
 
+def AVRInterruptDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt))`` attribute on
+AVR targets. This attribute may be attached to a function definition and instructs
+the backend to generate appropriate function entry/exit code so that it can be used
+directly as an interrupt service routine.
+
+On the AVR, the hardware globally disables interrupts when an interrupt is executed.
+The first instruction of an interrupt handler declared with this attribute is a SEI
+instruction to re-enable interrupts. See also the signal attribute that
+does not insert a SEI instruction.
+  }];
+}
+
+def AVRSignalDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Clang supports the GNU style ``__attribute__((signal))`` attribute on
+AVR targets. This attribute may be attached to a function definition and instructs
+the backend to generate appropriate function entry/exit code so that it can be used
+directly as an interrupt service routine.
+
+Interrupt handler functions defined with the signal attribute do not re-enable interrupts.
+}];
+}
+
 def TargetDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
@@ -2679,13 +2861,15 @@
 
 def XRayDocs : Documentation {
   let Category = DocCatFunction;
-  let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument)";
+  let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument), xray_log_args (clang::xray_log_args)";
   let Content = [{
 ``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching.
 
 Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points.
 
 If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise.
+
+``__attribute__((xray_log_args(N)))`` or ``[[clang::xray_log_args(N)]]`` is used to preserve N function arguments for the logging function.  Currently, only N==1 is supported.
   }];
 }
 
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 731d856..e7084de 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -702,7 +702,7 @@
 #undef ATOMIC_BUILTIN
 
 // Non-overloaded atomic builtins.
-BUILTIN(__sync_synchronize, "v.", "n")
+BUILTIN(__sync_synchronize, "v", "n")
 // GCC does not support these, they are a Clang extension.
 BUILTIN(__sync_fetch_and_min, "iiD*i", "n")
 BUILTIN(__sync_fetch_and_max, "iiD*i", "n")
@@ -773,6 +773,7 @@
 LANGBUILTIN(_lrotr,  "ULiULii",   "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__va_start,       "vc**.", "nt", ALL_MS_LANGUAGES)
+LANGBUILTIN(__fastfail, "vUi",    "nr", ALL_MS_LANGUAGES)
 
 // Microsoft library builtins.
 LIBBUILTIN(_setjmpex, "iJ", "fj",   "setjmpex.h", ALL_MS_LANGUAGES)
@@ -813,7 +814,7 @@
 LIBBUILTIN(snprintf, "ic*zcC*.",  "fp:2:", "stdio.h", ALL_LANGUAGES)
 LIBBUILTIN(sprintf, "ic*cC*.",    "fp:1:", "stdio.h", ALL_LANGUAGES)
 LIBBUILTIN(vprintf, "icC*a",      "fP:0:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vfprintf, "i.",        "fP:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(vfprintf, "iP*cC*a",   "fP:1:", "stdio.h", ALL_LANGUAGES)
 LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h", ALL_LANGUAGES)
 LIBBUILTIN(vsprintf, "ic*cC*a",   "fP:1:", "stdio.h", ALL_LANGUAGES)
 LIBBUILTIN(scanf, "icC*R.",       "fs:0:", "stdio.h", ALL_LANGUAGES)
@@ -1086,9 +1087,11 @@
 LIBBUILTIN(ilogbf, "if", "fne", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(ilogbl, "iLd", "fne", "math.h", ALL_LANGUAGES)
 
-LIBBUILTIN(lgamma, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lgammaf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+// POSIX math.h declares a global, signgam, that lgamma writes to, so these
+// shouldn't have "e" or "c" attributes
+LIBBUILTIN(lgamma, "dd", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lgammaf, "ff", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lgammal, "LdLd", "fn", "math.h", ALL_LANGUAGES)
 
 LIBBUILTIN(llrint, "LLid", "fne", "math.h", ALL_LANGUAGES)
 LIBBUILTIN(llrintf, "LLif", "fne", "math.h", ALL_LANGUAGES)
@@ -1339,6 +1342,7 @@
 BUILTIN(__builtin_addressof, "v*v&", "nct")
 BUILTIN(__builtin_operator_new, "v*z", "c")
 BUILTIN(__builtin_operator_delete, "vv*", "n")
+BUILTIN(__builtin_char_memchr, "c*cC*iz", "n")
 
 // Safestack builtins
 BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")
@@ -1361,7 +1365,7 @@
 BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n")
 BUILTIN(__builtin_coro_alloc, "b", "n")
 BUILTIN(__builtin_coro_begin, "v*v*", "n")
-BUILTIN(__builtin_coro_end, "vv*Ib", "n")
+BUILTIN(__builtin_coro_end, "bv*Ib", "n")
 BUILTIN(__builtin_coro_suspend, "cIb", "n")
 BUILTIN(__builtin_coro_param, "bv*v*", "n")
 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def
index f0f63fa..a8ab657 100644
--- a/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/include/clang/Basic/BuiltinsAMDGPU.def
@@ -35,8 +35,14 @@
 //===----------------------------------------------------------------------===//
 // Instruction builtins.
 //===----------------------------------------------------------------------===//
+BUILTIN(__builtin_amdgcn_s_getreg, "UiIi", "n")
+BUILTIN(__builtin_amdgcn_s_waitcnt, "vIi", "n")
+BUILTIN(__builtin_amdgcn_s_sendmsg, "vIiUi", "n")
+BUILTIN(__builtin_amdgcn_s_sendmsghalt, "vIiUi", "n")
 BUILTIN(__builtin_amdgcn_s_barrier, "v", "n")
 BUILTIN(__builtin_amdgcn_wave_barrier, "v", "n")
+BUILTIN(__builtin_amdgcn_s_dcache_inv, "v", "n")
+BUILTIN(__builtin_amdgcn_buffer_wbinvl1, "v", "n")
 BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n")
 BUILTIN(__builtin_amdgcn_div_scalef, "fffbb*", "n")
 BUILTIN(__builtin_amdgcn_div_fmas, "ddddb", "nc")
@@ -80,6 +86,11 @@
 BUILTIN(__builtin_amdgcn_fcmp, "LUiddIi", "nc")
 BUILTIN(__builtin_amdgcn_fcmpf, "LUiffIi", "nc")
 BUILTIN(__builtin_amdgcn_ds_swizzle, "iiIi", "nc")
+BUILTIN(__builtin_amdgcn_ds_permute, "iii", "nc")
+BUILTIN(__builtin_amdgcn_ds_bpermute, "iii", "nc")
+BUILTIN(__builtin_amdgcn_readfirstlane, "ii", "nc")
+BUILTIN(__builtin_amdgcn_readlane, "iii", "nc")
+BUILTIN(__builtin_amdgcn_fmed3f, "ffff", "nc")
 
 //===----------------------------------------------------------------------===//
 // VI+ only builtins.
@@ -96,6 +107,13 @@
 TARGET_BUILTIN(__builtin_amdgcn_fracth, "hh", "nc", "16-bit-insts")
 TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts")
 TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime")
+TARGET_BUILTIN(__builtin_amdgcn_mov_dpp, "iiIiIiIiIb", "nc", "dpp")
+
+//===----------------------------------------------------------------------===//
+// GFX9+ only builtins.
+//===----------------------------------------------------------------------===//
+
+TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
 
 //===----------------------------------------------------------------------===//
 // Special builtins.
diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def
index b6329fb..afea6cb 100644
--- a/include/clang/Basic/BuiltinsNVPTX.def
+++ b/include/clang/Basic/BuiltinsNVPTX.def
@@ -64,24 +64,10 @@
 
 // MISC
 
-BUILTIN(__nvvm_clz_i, "ii", "")
-BUILTIN(__nvvm_clz_ll, "iLLi", "")
-BUILTIN(__nvvm_popc_i, "ii", "")
-BUILTIN(__nvvm_popc_ll, "iLLi", "")
 BUILTIN(__nvvm_prmt, "UiUiUiUi", "")
 
 // Min Max
 
-BUILTIN(__nvvm_min_i, "iii", "")
-BUILTIN(__nvvm_min_ui, "UiUiUi", "")
-BUILTIN(__nvvm_min_ll, "LLiLLiLLi", "")
-BUILTIN(__nvvm_min_ull, "ULLiULLiULLi", "")
-
-BUILTIN(__nvvm_max_i, "iii", "")
-BUILTIN(__nvvm_max_ui, "UiUiUi", "")
-BUILTIN(__nvvm_max_ll, "LLiLLiLLi", "")
-BUILTIN(__nvvm_max_ull, "ULLiULLiULLi", "")
-
 BUILTIN(__nvvm_fmax_ftz_f, "fff",  "")
 BUILTIN(__nvvm_fmax_f, "fff",  "")
 BUILTIN(__nvvm_fmin_ftz_f, "fff",  "")
@@ -133,11 +119,6 @@
 BUILTIN(__nvvm_div_rm_d,  "ddd", "")
 BUILTIN(__nvvm_div_rp_d,  "ddd", "")
 
-// Brev
-
-BUILTIN(__nvvm_brev32, "UiUi", "")
-BUILTIN(__nvvm_brev64, "ULLiULLi", "")
-
 // Sad
 
 BUILTIN(__nvvm_sad_i, "iiii", "")
@@ -155,9 +136,6 @@
 
 // Abs
 
-BUILTIN(__nvvm_abs_i, "ii", "")
-BUILTIN(__nvvm_abs_ll, "LLiLLi", "")
-
 BUILTIN(__nvvm_fabs_ftz_f, "ff", "")
 BUILTIN(__nvvm_fabs_f, "ff", "")
 BUILTIN(__nvvm_fabs_d, "dd", "")
@@ -385,8 +363,6 @@
 BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "")
 BUILTIN(__nvvm_f2h_rn, "Usf", "")
 
-BUILTIN(__nvvm_h2f, "fUs", "")
-
 // Bitcast
 
 BUILTIN(__nvvm_bitcast_f2i, "if", "")
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
index 657ea42..f7cddc0 100644
--- a/include/clang/Basic/BuiltinsPPC.def
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -417,6 +417,9 @@
 BUILTIN(__builtin_vsx_xvtstdcdp, "V2ULLiV2dIi", "")
 BUILTIN(__builtin_vsx_xvtstdcsp, "V4UiV4fIi", "")
 
+BUILTIN(__builtin_vsx_insertword, "V16UcV4UiV16UcIi", "")
+BUILTIN(__builtin_vsx_extractuword, "V2ULLiV16UcIi", "")
+
 // HTM builtins
 BUILTIN(__builtin_tbegin, "UiUIi", "")
 BUILTIN(__builtin_tend, "UiUIi", "")
diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def
index 97b59a1..de56908 100644
--- a/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/include/clang/Basic/BuiltinsWebAssembly.def
@@ -16,9 +16,9 @@
 
 // The format of this database matches clang/Basic/Builtins.def.
 
-// Note that current_memory is not "c" (readnone) because it must be sequenced with
-// respect to grow_memory calls.
+// Note that current_memory is not "c" (readnone) because it must be sequenced
+// with respect to grow_memory calls.
 BUILTIN(__builtin_wasm_current_memory, "z", "n")
-BUILTIN(__builtin_wasm_grow_memory, "vz", "n")
+BUILTIN(__builtin_wasm_grow_memory, "zz", "n")
 
 #undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 9b3d942..2400b44 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -832,8 +832,6 @@
 TARGET_BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "", "xop")
 TARGET_BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "", "xop")
 TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcmov, "V2LLiV2LLiV2LLiV2LLi", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcmov_256, "V4LLiV4LLiV4LLiV4LLi", "", "xop")
 TARGET_BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "", "xop")
 TARGET_BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "", "xop")
 TARGET_BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "", "xop")
@@ -974,8 +972,8 @@
 TARGET_BUILTIN(__builtin_ia32_pminsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_pminud512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmuldq512_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmuludq512_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "", "avx512f")
@@ -997,22 +995,22 @@
 TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "", "avx512f")
 
-TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUci","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUcIi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUcIi","","avx512vl")
 TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8ddC*V8iUcIi", "", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16ffC*V16fUsIi", "", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8ddC*V8LLiUcIi", "", "avx512f")
@@ -1068,10 +1066,10 @@
 
 TARGET_BUILTIN(__builtin_ia32_pabsb512_mask, "V64cV64cV64cULLi", "", "avx512bw")
 TARGET_BUILTIN(__builtin_ia32_pabsw512_mask, "V32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packssdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packsswb512_mask, "V64cV32sV32sV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packusdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packuswb512_mask, "V64cV32sV32sV64cULLi", "", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_packuswb512, "V64cV32sV32s", "", "avx512bw")
 TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
 TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
 TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
@@ -1086,7 +1084,7 @@
 TARGET_BUILTIN(__builtin_ia32_pminsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
 TARGET_BUILTIN(__builtin_ia32_pminub512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
 TARGET_BUILTIN(__builtin_ia32_pminuw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pshufb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "", "avx512bw")
 TARGET_BUILTIN(__builtin_ia32_psubsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
 TARGET_BUILTIN(__builtin_ia32_psubsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
 TARGET_BUILTIN(__builtin_ia32_psubusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
@@ -1489,16 +1487,12 @@
 TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
 TARGET_BUILTIN(__builtin_ia32_vpermi2varps512_mask, "V16fV16fV16iV16fUs","","avx512f")
 TARGET_BUILTIN(__builtin_ia32_vpermi2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps512_mask, "V16fV16fV16iV16fUs","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8LLi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarps512, "V16fV16fV16i","","avx512f")
 TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_maskz, "V16iV16iV16iV16iUs","","avx512f")
 TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_maskz, "V8dV8LLiV8dV8dUc","","avx512f")
 TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_maskz, "V16fV16iV16fV16fUs","","avx512f")
 TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd_mask, "V2dV2dV2LLiV2dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256_mask, "V4dV4dV4LLiV4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps_mask, "V4fV4fV4iV4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps256_mask, "V8fV8fV8iV8fUc","","avx512vl")
 TARGET_BUILTIN(__builtin_ia32_ptestmb512, "ULLiV64cV64cULLi","","avx512bw")
 TARGET_BUILTIN(__builtin_ia32_ptestmw512, "UiV32sV32sUi","","avx512bw")
 TARGET_BUILTIN(__builtin_ia32_ptestnmb512, "ULLiV64cV64cULLi","","avx512bw")
@@ -1594,27 +1588,15 @@
 TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi","","avx512dq,avx512vl")
 TARGET_BUILTIN(__builtin_ia32_broadcastmb512, "V8LLiUc","","avx512cd")
 TARGET_BUILTIN(__builtin_ia32_broadcastmw512, "V16iUs","","avx512cd")
-TARGET_BUILTIN(__builtin_ia32_broadcastf32x4_512, "V16fV4fV16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_broadcastf64x4_512, "V8dV4dV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_broadcasti32x4_512, "V16iV4iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_broadcasti64x4_512, "V8LLiV4LLiV8LLiUc","","avx512f")
 TARGET_BUILTIN(__builtin_ia32_broadcastmb128, "V2LLiUc","","avx512cd,avx512vl")
 TARGET_BUILTIN(__builtin_ia32_broadcastmb256, "V4LLiUc","","avx512cd,avx512vl")
 TARGET_BUILTIN(__builtin_ia32_broadcastmw128, "V4iUs","","avx512cd,avx512vl")
 TARGET_BUILTIN(__builtin_ia32_broadcastmw256, "V8iUs","","avx512cd,avx512vl")
 TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_512_mask, "V16fV4fV16fUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_broadcastf32x8_512_mask, "V16fV8fV16fUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_broadcastf64x2_512_mask, "V8dV2dV8dUc","","avx512dq")
 TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_512_mask, "V16iV4iV16iUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_broadcasti32x8_512_mask, "V16iV8iV16iUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_broadcasti64x2_512_mask, "V8LLiV2LLiV8LLiUc","","avx512dq")
 TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_256_mask, "V8fV4fV8fUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcastf64x2_256_mask, "V4dV2dV4dUc","","avx512dq,avx512vl")
 TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_128_mask, "V4iV4iV4iUc","","avx512dq,avx512vl")
 TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_256_mask, "V8iV4iV8iUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcasti64x2_256_mask, "V4LLiV2LLiV4LLiUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcastf32x4_256_mask, "V8fV4fV8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcasti32x4_256_mask, "V8iV4iV8iUc","","avx512vl")
 TARGET_BUILTIN(__builtin_ia32_pbroadcastw512_gpr_mask, "V32shV32sUi","","avx512bw")
 TARGET_BUILTIN(__builtin_ia32_pbroadcastw256_gpr_mask, "V16shV16sUs","","avx512bw,avx512vl")
 TARGET_BUILTIN(__builtin_ia32_pbroadcastw128_gpr_mask, "V8ssV8sUc","","avx512bw,avx512vl")
@@ -1830,6 +1812,9 @@
 TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx")
 TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx")
 
+// CLZERO
+TARGET_BUILTIN(__builtin_ia32_clzero, "vv*", "", "clzero")
+
 // MSVC
 TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
@@ -1844,6 +1829,8 @@
 TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 
 TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__int2c, "v",       "nr", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__ud2,   "v",       "nr", "intrin.h", ALL_MS_LANGUAGES, "")
 
 #undef BUILTIN
 #undef TARGET_BUILTIN
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
index 6da2c2c..3298a80 100644
--- a/include/clang/Basic/DeclNodes.td
+++ b/include/clang/Basic/DeclNodes.td
@@ -45,6 +45,7 @@
         def ObjCAtDefsField : DDecl<Field>;
       def MSProperty : DDecl<Declarator>;
       def Function : DDecl<Declarator>, DeclContext;
+        def CXXDeductionGuide : DDecl<Function>;
         def CXXMethod : DDecl<Function>;
           def CXXConstructor : DDecl<CXXMethod>;
           def CXXDestructor : DDecl<CXXMethod>;
@@ -67,6 +68,7 @@
     def TemplateTemplateParm : DDecl<Template>;
     def BuiltinTemplate : DDecl<Template>;
   def Using : DDecl<Named>;
+  def UsingPack : DDecl<Named>;
   def UsingShadow : DDecl<Named>;
     def ConstructorUsingShadow : DDecl<UsingShadow>;
   def ObjCMethod : DDecl<Named>, DeclContext;
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index b83ef4d..ffce99b 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -29,6 +29,7 @@
 #include <cassert>
 #include <cstdint>
 #include <list>
+#include <map>
 #include <memory>
 #include <string>
 #include <type_traits>
@@ -232,59 +233,97 @@
   /// \brief Keeps and automatically disposes all DiagStates that we create.
   std::list<DiagState> DiagStates;
 
-  /// \brief Represents a point in source where the diagnostic state was
-  /// modified because of a pragma.
-  ///
-  /// 'Loc' can be null if the point represents the diagnostic state
-  /// modifications done through the command-line.
-  struct DiagStatePoint {
-    DiagState *State;
-    FullSourceLoc Loc;
-    DiagStatePoint(DiagState *State, FullSourceLoc Loc)
-      : State(State), Loc(Loc) { } 
-    
-    bool operator<(const DiagStatePoint &RHS) const {
-      // If Loc is invalid it means it came from <command-line>, in which case
-      // we regard it as coming before any valid source location.
-      if (RHS.Loc.isInvalid())
-        return false;
-      if (Loc.isInvalid())
-        return true;
-      return Loc.isBeforeInTranslationUnitThan(RHS.Loc);
+  /// A mapping from files to the diagnostic states for those files. Lazily
+  /// built on demand for files in which the diagnostic state has not changed.
+  class DiagStateMap {
+  public:
+    /// Add an initial diagnostic state.
+    void appendFirst(DiagState *State);
+    /// Add a new latest state point.
+    void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
+    /// Look up the diagnostic state at a given source location.
+    DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
+    /// Determine whether this map is empty.
+    bool empty() const { return Files.empty(); }
+    /// Clear out this map.
+    void clear() {
+      Files.clear();
+      FirstDiagState = CurDiagState = nullptr;
+      CurDiagStateLoc = SourceLocation();
     }
+
+    /// Grab the most-recently-added state point.
+    DiagState *getCurDiagState() const { return CurDiagState; }
+    /// Get the location at which a diagnostic state was last added.
+    SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
+
+  private:
+    /// \brief Represents a point in source where the diagnostic state was
+    /// modified because of a pragma.
+    ///
+    /// 'Loc' can be null if the point represents the diagnostic state
+    /// modifications done through the command-line.
+    struct DiagStatePoint {
+      DiagState *State;
+      unsigned Offset;
+      DiagStatePoint(DiagState *State, unsigned Offset)
+        : State(State), Offset(Offset) { } 
+    };
+
+    /// Description of the diagnostic states and state transitions for a
+    /// particular FileID.
+    struct File {
+      /// The diagnostic state for the parent file. This is strictly redundant,
+      /// as looking up the DecomposedIncludedLoc for the FileID in the Files
+      /// map would give us this, but we cache it here for performance.
+      File *Parent = nullptr;
+      /// The offset of this file within its parent.
+      unsigned ParentOffset = 0;
+      /// Whether this file has any local (not imported from an AST file)
+      /// diagnostic state transitions.
+      bool HasLocalTransitions = false;
+      /// The points within the file where the state changes. There will always
+      /// be at least one of these (the state on entry to the file).
+      llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
+
+      DiagState *lookup(unsigned Offset) const;
+    };
+
+    /// The diagnostic states for each file.
+    mutable std::map<FileID, File> Files;
+
+    /// The initial diagnostic state.
+    DiagState *FirstDiagState;
+    /// The current diagnostic state.
+    DiagState *CurDiagState;
+    /// The location at which the current diagnostic state was established.
+    SourceLocation CurDiagStateLoc;
+
+    /// Get the diagnostic state information for a file.
+    File *getFile(SourceManager &SrcMgr, FileID ID) const;
+
+    friend class ASTReader;
+    friend class ASTWriter;
   };
 
-  /// \brief A sorted vector of all DiagStatePoints representing changes in
-  /// diagnostic state due to diagnostic pragmas.
-  ///
-  /// The vector is always sorted according to the SourceLocation of the
-  /// DiagStatePoint.
-  typedef std::vector<DiagStatePoint> DiagStatePointsTy;
-  mutable DiagStatePointsTy DiagStatePoints;
+  DiagStateMap DiagStatesByLoc;
 
   /// \brief Keeps the DiagState that was active during each diagnostic 'push'
   /// so we can get back at it when we 'pop'.
   std::vector<DiagState *> DiagStateOnPushStack;
 
   DiagState *GetCurDiagState() const {
-    assert(!DiagStatePoints.empty());
-    return DiagStatePoints.back().State;
+    return DiagStatesByLoc.getCurDiagState();
   }
 
-  void PushDiagStatePoint(DiagState *State, SourceLocation L) {
-    FullSourceLoc Loc(L, getSourceManager());
-    // Make sure that DiagStatePoints is always sorted according to Loc.
-    assert(Loc.isValid() && "Adding invalid loc point");
-    assert(!DiagStatePoints.empty() &&
-           (DiagStatePoints.back().Loc.isInvalid() ||
-            DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
-           "Previous point loc comes after or is the same as new one");
-    DiagStatePoints.push_back(DiagStatePoint(State, Loc));
-  }
+  void PushDiagStatePoint(DiagState *State, SourceLocation L);
 
   /// \brief Finds the DiagStatePoint that contains the diagnostic state of
   /// the given source location.
-  DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
+  DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
+    return SourceMgr ? DiagStatesByLoc.lookup(*SourceMgr, Loc)
+                     : DiagStatesByLoc.getCurDiagState();
+  }
 
   /// \brief Sticky flag set to \c true when an error is emitted.
   bool ErrorOccurred;
@@ -390,7 +429,11 @@
     assert(SourceMgr && "SourceManager not set!");
     return *SourceMgr;
   }
-  void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; }
+  void setSourceManager(SourceManager *SrcMgr) {
+    assert(DiagStatesByLoc.empty() &&
+           "Leftover diag state from a different SourceManager.");
+    SourceMgr = SrcMgr;
+  }
 
   //===--------------------------------------------------------------------===//
   //  DiagnosticsEngine characterization methods, used by a client to customize
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 03ed8aa..652d062 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -44,7 +44,8 @@
 def note_constexpr_uninitialized : Note<
   "%select{|sub}0object of type %1 is not initialized">;
 def note_constexpr_array_index : Note<"cannot refer to element %0 of "
-  "%select{array of %2 elements|non-array object}1 in a constant expression">;
+  "%select{array of %2 element%plural{1:|:s}2|non-array object}1 "
+  "in a constant expression">;
 def note_constexpr_float_arithmetic : Note<
   "floating point arithmetic produces %select{an infinity|a NaN}0">;
 def note_constexpr_pointer_subtraction_not_same_array : Note<
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index adc74d9..b8293f0 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -45,7 +45,9 @@
   "must end with ':'">;
 def err_expected_string_literal : Error<"expected string literal "
   "%select{in %1|for diagnostic message in static_assert|"
-          "for optional message in 'availability' attribute}0">;
+          "for optional message in 'availability' attribute|"
+          "for %select{language|source container}1 name in "
+          "'external_source_symbol' attribute}0">;
 def err_invalid_string_udl : Error<
   "string literal with user-defined suffix cannot be used here">;
 def err_invalid_character_udl : Error<
@@ -161,6 +163,8 @@
   InGroup<CXX11Compat>;
 def ext_clang_enable_if : Extension<"'enable_if' is a clang extension">,
                           InGroup<GccCompat>;
+def ext_clang_diagnose_if : Extension<"'diagnose_if' is a clang extension">,
+                            InGroup<GccCompat>;
 
 // SEH
 def err_seh_expected_handler : Error<
@@ -190,6 +194,8 @@
     "the '%0' unit is not supported with this instruction set">;
 def err_target_unsupported_unaligned : Error<
   "the %0 sub-architecture does not support unaligned accesses">;
+def err_target_unsupported_execute_only : Error<
+  "execute only is not supported for the %0 sub-architecture">;
 def err_opt_not_valid_with_opt : Error<
   "option '%0' cannot be specified with '%1'">;
 
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 2fcd3a5..b02599c 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -133,6 +133,7 @@
     "invalid output type '%0' for use with gcc tool">;
 def err_drv_cc_print_options_failure : Error<
     "unable to open CC_PRINT_OPTIONS file: %0">;
+def err_drv_lto_without_lld : Error<"LTO requires -fuse-ld=lld">;
 def err_drv_preamble_format : Error<
     "incorrect format for -preamble-bytes=N,END">;
 def err_drv_conflicting_deployment_targets : Error<
@@ -230,6 +231,7 @@
   "The last /TC or /TP option takes precedence over earlier instances">;
 def note_drv_address_sanitizer_debug_runtime : Note<
   "AddressSanitizer doesn't support linking with debug runtime libraries yet">;
+def note_drv_use_standard : Note<"use '%0' for '%1' standard">;
 
 def err_analyzer_config_no_value : Error<
   "analyzer-config option '%0' has a key but no value">;
@@ -247,6 +249,10 @@
 def warn_drv_invoking_fallback : Warning<"falling back to %0">,
   InGroup<Fallback>;
 
+def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">,
+  InGroup<DiagGroup<"slash-u-filename">>;
+def note_use_dashdash : Note<"Use '--' to treat subsequent arguments as filenames">;
+
 def err_drv_ropi_rwpi_incompatible_with_pic : Error<
   "embedded and GOT-based position independence are incompatible">;
 def err_drv_ropi_incompatible_with_cxx : Error<
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index c1b831b..6153b8e 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -175,6 +175,8 @@
 
 def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
 
+def CXX11WarnOverrideDestructor :
+  DiagGroup<"inconsistent-missing-destructor-override">;
 def CXX11WarnOverrideMethod : DiagGroup<"inconsistent-missing-override">;
 
 // Original name of this warning in Clang
@@ -243,6 +245,7 @@
                                           [NonModularIncludeInFrameworkModule]>;
 def IncompleteModule : DiagGroup<"incomplete-module",
     [IncompleteUmbrella, NonModularIncludeInModule]>;
+def PrivateModule : DiagGroup<"private-module">;
 
 def CXX11InlineNamespace : DiagGroup<"c++11-inline-namespace">;
 def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
@@ -354,6 +357,7 @@
 def Sentinel : DiagGroup<"sentinel">;
 def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
 
+def ShadowField : DiagGroup<"shadow-field">;
 def ShadowFieldInConstructorModified : DiagGroup<"shadow-field-in-constructor-modified">;
 def ShadowFieldInConstructor : DiagGroup<"shadow-field-in-constructor",
                                          [ShadowFieldInConstructorModified]>;
@@ -365,7 +369,7 @@
 def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified,
                                   ShadowIvar]>;
 def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor,
-                                         ShadowUncapturedLocal]>;
+                                         ShadowUncapturedLocal, ShadowField]>;
 
 def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
 def : DiagGroup<"sign-promo">;
@@ -479,6 +483,7 @@
 def UnusedMemberFunction : DiagGroup<"unused-member-function",
                                      [UnneededMemberFunction]>;
 def UnusedLabel : DiagGroup<"unused-label">;
+def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">;
 def UnusedParameter : DiagGroup<"unused-parameter">;
 def UnusedResult : DiagGroup<"unused-result">;
 def PotentiallyEvaluatedExpression : DiagGroup<"potentially-evaluated-expression">;
@@ -494,6 +499,7 @@
 def UnusedGetterReturnValue : DiagGroup<"unused-getter-return-value">;
 def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
 def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
+def UserDefinedWarnings : DiagGroup<"user-defined-warnings">;
 def Reorder : DiagGroup<"reorder">;
 def UndeclaredSelector : DiagGroup<"undeclared-selector">;
 def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
@@ -615,8 +621,9 @@
                        [UnusedArgument, UnusedFunction, UnusedLabel,
                         // UnusedParameter, (matches GCC's behavior)
                         // UnusedMemberFunction, (clean-up llvm before enabling)
-                        UnusedPrivateField, UnusedLocalTypedef,
-                        UnusedValue, UnusedVariable, UnusedPropertyIvar]>,
+                        UnusedPrivateField, UnusedLambdaCapture,
+                        UnusedLocalTypedef, UnusedValue, UnusedVariable,
+                        UnusedPropertyIvar]>,
                         DiagCategory<"Unused Entity Issue">;
 
 // Format settings.
@@ -682,7 +689,8 @@
     OverloadedVirtual,
     PrivateExtern,
     SelTypeCast,
-    ExternCCompat
+    ExternCCompat,
+    UserDefinedWarnings
  ]>;
 
 // Thread Safety warnings 
@@ -878,7 +886,7 @@
 def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
 def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
 
-// AddressSanitizer frontent instrumentation remarks.
+// AddressSanitizer frontend instrumentation remarks.
 def SanitizeAddressRemarks : DiagGroup<"sanitize-address">;
 
 // Issues with serialized diagnostics.
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 8bcbc21..7f7022b 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -642,6 +642,11 @@
 def err_mmap_expected_attribute : Error<"expected an attribute name">;
 def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">,
   InGroup<IgnoredAttributes>;
+def warn_mmap_mismatched_top_level_private : Warning<
+  "top-level module '%0' in private module map, expected a submodule of '%1'">,
+  InGroup<PrivateModule>;
+def note_mmap_rename_top_level_private_as_submodule : Note<
+  "make '%0' a submodule of '%1' to ensure it can be found by name">;
 
 def warn_auto_module_import : Warning<
   "treating #%select{include|import|include_next|__include_macros}0 as an "
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index ecebda9..b486e62 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -176,6 +176,9 @@
 def warn_attribute_no_decl : Warning<
   "attribute %0 ignored, because it is not attached to a declaration">, 
   InGroup<IgnoredAttributes>;
+def err_ms_attributes_not_enabled : Error<
+  "'__declspec' attributes are not enabled; use '-fdeclspec' or "
+  "'-fms-extensions' to enable support for __declspec attributes">;
 def err_expected_method_body : Error<"expected method body">;
 def err_declspec_after_virtspec : Error<
   "'%0' qualifier may not appear after the virtual specifier '%1'">;
@@ -347,8 +350,6 @@
 def warn_cxx98_compat_static_assert : Warning<
   "static_assert declarations are incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
-def err_paren_after_colon_colon : Error<
-  "unexpected parenthesis after '::'">;
 def err_function_definition_not_allowed : Error<
   "function definition is not allowed here">;
 def err_expected_end_of_enumerator : Error<
@@ -400,7 +401,7 @@
   "expected selector for Objective-C %select{setter|getter}0">;
 def err_objc_property_requires_field_name : Error<
   "property requires fields to be named">;
-def err_objc_property_bitfield : Error<"property name cannot be a bitfield">;
+def err_objc_property_bitfield : Error<"property name cannot be a bit-field">;
 def err_objc_expected_property_attr : Error<"unknown property attribute %0">;
 def err_objc_properties_require_objc2 : Error<
   "properties are an Objective-C 2 feature">;
@@ -671,9 +672,6 @@
 // Constructor template diagnostics.
 def err_out_of_line_constructor_template_id : Error<
   "out-of-line constructor for %0 cannot have template arguments">;
-def err_out_of_line_template_id_type_names_constructor : Error<
-  "qualified reference to %0 is a constructor name rather than a "
-  "%select{template name|type}1 wherever a constructor can be declared">;
 
 def err_expected_qualified_after_typename : Error<
   "expected a qualified name after 'typename'">;
@@ -728,7 +726,7 @@
   "in-class initialization of non-static data members is incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
 def err_bitfield_member_init: Error<
-  "bitfield member cannot have an in-class initializer">;
+  "bit-field member cannot have an in-class initializer">;
 def err_incomplete_array_member_init: Error<
   "array bound cannot be deduced from an in-class initializer">;
 
@@ -742,6 +740,22 @@
   "name defined in alias declaration must be an identifier">;
 def err_alias_declaration_specialization : Error<
   "%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">;
+def err_alias_declaration_pack_expansion : Error<
+  "alias declaration cannot be a pack expansion">;
+
+// C++1z using-declaration pack expansions
+def ext_multi_using_declaration : ExtWarn<
+  "use of multiple declarators in a single using declaration is "
+  "a C++1z extension">, InGroup<CXX1z>;
+def warn_cxx1z_compat_multi_using_declaration : Warning<
+  "use of multiple declarators in a single using declaration is "
+  "incompatible with C++ standards before C++1z">,
+  InGroup<CXXPre1zCompat>, DefaultIgnore;
+def ext_using_declaration_pack : ExtWarn<
+  "pack expansion of using declaration is a C++1z extension">, InGroup<CXX1z>;
+def warn_cxx1z_compat_using_declaration_pack : Warning<
+  "pack expansion using declaration is incompatible with C++ standards "
+  "before C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore;
 
 // C++11 override control
 def ext_override_control_keyword : ExtWarn<
@@ -845,6 +859,12 @@
 def err_availability_query_repeated_star : Error<
   "'*' query has already been specified">;
 
+// External source symbol attribute
+def err_external_source_symbol_expected_keyword : Error<
+  "expected 'language', 'defined_in', or 'generated_declaration'">;
+def err_external_source_symbol_duplicate_clause : Error<
+  "duplicate %0 clause in an 'external_source_symbol' attribute">;
+
 // Type safety attributes
 def err_type_safety_unknown_flag : Error<
   "invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'">;
@@ -961,8 +981,10 @@
 // OpenCL EXTENSION pragma (OpenCL 1.1 [9.1])
 def warn_pragma_expected_colon : Warning<
   "missing ':' after %0 - ignoring">, InGroup<IgnoredPragmas>;
-def warn_pragma_expected_enable_disable : Warning<
-  "expected 'enable' or 'disable' - ignoring">, InGroup<IgnoredPragmas>;
+def warn_pragma_expected_predicate : Warning<
+  "expected %select{'enable', 'disable', 'begin' or 'end'|'disable'}0 - ignoring">, InGroup<IgnoredPragmas>;
+def warn_pragma_begin_end_mismatch : Warning<
+  "OpenCL extension end directive mismatches begin directive - ignoring">, InGroup<IgnoredPragmas>;
 def warn_pragma_unknown_extension : Warning<
   "unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
 def warn_pragma_unsupported_extension : Warning<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 85f600d..9764c9e 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -259,6 +259,9 @@
   "a pointer as the first parameter|a %2 type as the second parameter}1">;
 def err_anyx86_interrupt_called : Error<
   "interrupt service routine cannot be called directly">;
+def warn_arm_interrupt_calling_convention : Warning<
+   "call to function without interrupt attribute could clobber interruptee's VFP registers">,
+   InGroup<Extra>;
 def warn_mips_interrupt_attribute : Warning<
    "MIPS 'interrupt' attribute only applies to functions that have "
    "%select{no parameters|a 'void' return type}0">,
@@ -316,6 +319,9 @@
   InGroup<UnneededMemberFunction>, DefaultIgnore;
 def warn_unused_private_field: Warning<"private field %0 is not used">,
   InGroup<UnusedPrivateField>, DefaultIgnore;
+def warn_unused_lambda_capture: Warning<"lambda capture %0 is not "
+  "%select{used|required to be captured for this use}1">,
+  InGroup<UnusedLambdaCapture>, DefaultIgnore;
 
 def warn_parameter_size: Warning<
   "%0 is a large (%1 bytes) pass-by-value argument; "
@@ -398,8 +404,6 @@
   "decomposition declaration must be the only declaration in its group">;
 def err_decomp_decl_requires_init : Error<
   "decomposition declaration %0 requires an initializer">;
-def err_decomp_decl_paren_init : Error<
-  "decomposition declaration %0 cannot have a parenthesized initializer">;
 def err_decomp_decl_wrong_number_bindings : Error<
   "type %0 decomposes into %2 elements, but %select{only |}3%1 "
   "names were provided">;
@@ -476,6 +480,8 @@
 def err_using_decl_conflict_reverse : Error<
   "declaration conflicts with target of using declaration already in scope">;
 def note_using_decl : Note<"%select{|previous }0using declaration">;
+def err_using_decl_redeclaration_expansion : Error<
+  "using declaration pack expansion at block scope produces multiple values">;
 
 def warn_access_decl_deprecated : Warning<
   "access declarations are deprecated; use using declarations instead">,
@@ -1201,8 +1207,9 @@
 def err_qualified_friend_not_found : Error<
   "no function named %0 with type %1 was found in the specified scope">;
 def err_introducing_special_friend : Error<
-  "must use a qualified name when declaring a %select{constructor|"
-  "destructor|conversion operator}0 as a friend">;
+  "%plural{[0,2]:must use a qualified name when declaring|3:cannot declare}0"
+  " a %select{constructor|destructor|conversion operator|deduction guide}0 "
+  "as a friend">;
 def err_tagless_friend_type_template : Error<
   "friend type templates must use an elaborated type">;
 def err_no_matching_local_friend : Error<
@@ -1447,6 +1454,15 @@
 def ext_nested_name_spec_is_enum : ExtWarn<
   "use of enumeration in a nested name specifier is a C++11 extension">,
   InGroup<CXX11>;
+def err_out_of_line_qualified_id_type_names_constructor : Error<
+  "qualified reference to %0 is a constructor name rather than a "
+  "%select{template name|type}1 in this context">;
+def ext_out_of_line_qualified_id_type_names_constructor : ExtWarn<
+  "ISO C++ specifies that "
+  "qualified reference to %0 is a constructor name rather than a "
+  "%select{template name|type}1 in this context, despite preceding "
+  "%select{'typename'|'template'}2 keyword">, SFINAEFailure,
+  InGroup<DiagGroup<"injected-class-name">>;
 
 // C++ class members
 def err_storageclass_invalid_for_member : Error<
@@ -1608,7 +1624,14 @@
   "return type of virtual function %0 is not covariant with the return type of "
   "the function it overrides (class type %1 is more qualified than class "
   "type %2">;
-  
+
+// C++ implicit special member functions
+def note_in_declaration_of_implicit_special_member : Note<
+  "while declaring the implicit "
+  "%select{default constructor|copy constructor|move constructor|"
+  "copy assignment operator|move assignment operator|destructor}1"
+  " for %0">;
+
 // C++ constructors
 def err_constructor_cannot_be : Error<"constructor cannot be declared '%0'">;
 def err_invalid_qualified_constructor : Error<
@@ -1833,8 +1856,8 @@
   InGroup<CXX98CompatBindToTemporaryCopy>, DefaultIgnore;
 def err_selected_explicit_constructor : Error<
   "chosen constructor is explicit in copy-initialization">;
-def note_constructor_declared_here : Note<
-  "constructor declared here">;
+def note_explicit_ctor_deduction_guide_here : Note<
+  "explicit %select{constructor|deduction guide}0 declared here">;
 
 // C++11 decltype
 def err_decltype_in_declarator : Error<
@@ -1845,8 +1868,8 @@
   "'auto' type specifier is incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
 def err_auto_variable_cannot_appear_in_own_initializer : Error<
-  "variable %0 declared with %select{'auto'|'decltype(auto)'|'__auto_type'}1 "
-  "type cannot appear in its own initializer">;
+  "variable %0 declared with deduced type %1 "
+  "cannot appear in its own initializer">;
 def err_binding_cannot_appear_in_own_initializer : Error<
   "binding %0 cannot appear in the initializer of its own "
   "decomposition declaration">;
@@ -1855,20 +1878,29 @@
 def err_new_array_of_auto : Error<
   "cannot allocate array of 'auto'">;
 def err_auto_not_allowed : Error<
-  "%select{'auto'|'decltype(auto)'|'__auto_type'}0 not allowed "
+  "%select{'auto'|'decltype(auto)'|'__auto_type'|"
+  "use of "
+  "%select{class template|function template|variable template|alias template|"
+  "template template parameter|template}2 %3 requires template arguments; "
+  "argument deduction}0 not allowed "
   "%select{in function prototype"
   "|in non-static struct member|in struct member"
   "|in non-static union member|in union member"
   "|in non-static class member|in interface member"
-  "|in exception declaration|in template parameter|in block literal"
+  "|in exception declaration|in template parameter until C++1z|in block literal"
   "|in template argument|in typedef|in type alias|in function return type"
   "|in conversion function type|here|in lambda parameter"
-  "|in type allocated by 'new'|in K&R-style function parameter}1"
-  "%select{|||||||| until C++1z||||||||||}1">;
+  "|in type allocated by 'new'|in K&R-style function parameter"
+  "|in template parameter|in friend declaration}1">;
+def err_dependent_deduced_tst : Error<
+  "typename specifier refers to "
+  "%select{class template|function template|variable template|alias template|"
+  "template template parameter|template}0 member in %1; "
+  "argument deduction not allowed here">;
 def err_auto_not_allowed_var_inst : Error<
   "'auto' variable template instantiation is not allowed">;
 def err_auto_var_requires_init : Error<
-  "declaration of variable %0 with type %1 requires an initializer">;
+  "declaration of variable %0 with deduced type %1 requires an initializer">;
 def err_auto_new_requires_ctor_arg : Error<
   "new expression for type %0 requires a constructor argument">;
 def err_auto_new_list_init : Error<
@@ -1898,8 +1930,13 @@
 def err_auto_new_deduction_failure : Error<
   "new expression for type %0 has incompatible constructor argument of type %1">;
 def err_auto_different_deductions : Error<
-  "'%select{auto|decltype(auto)|__auto_type}0' deduced as %1 in declaration "
-  "of %2 and deduced as %3 in declaration of %4">;
+  "%select{'auto'|'decltype(auto)'|'__auto_type'|template arguments}0 "
+  "deduced as %1 in declaration of %2 and "
+  "deduced as %3 in declaration of %4">;
+def err_auto_non_deduced_not_alone : Error<
+  "%select{function with deduced return type|"
+  "declaration with trailing return type}0 "
+  "must be the only declaration in its group">;
 def err_implied_std_initializer_list_not_found : Error<
   "cannot deduce type of initializer list because std::initializer_list was "
   "not found; include <initializer_list>">;
@@ -1915,6 +1952,8 @@
   "cannot pass bit-field as __auto_type initializer in C">;
 
 // C++1y decltype(auto) type
+def err_decltype_auto_invalid : Error<
+  "'decltype(auto)' not allowed here">;
 def err_decltype_auto_cannot_be_combined : Error<
   "'decltype(auto)' cannot be combined with other type specifiers">;
 def err_decltype_auto_function_declarator_not_declaration : Error<
@@ -1925,6 +1964,56 @@
 def err_decltype_auto_initializer_list : Error<
   "cannot deduce 'decltype(auto)' from initializer list">;
 
+// C++1z deduced class template specialization types
+def err_deduced_class_template_compound_type : Error<
+  "cannot %select{form pointer to|form reference to|form array of|"
+  "form function returning|use parentheses when declaring variable with}0 "
+  "deduced class template specialization type">;
+def err_deduced_non_class_template_specialization_type : Error<
+  "%select{<error>|function template|variable template|alias template|"
+  "template template parameter|template}0 %1 requires template arguments; "
+  "argument deduction only allowed for class templates">;
+def err_deduced_class_template_ctor_ambiguous : Error<
+  "ambiguous deduction for template arguments of %0">;
+def err_deduced_class_template_ctor_no_viable : Error<
+  "no viable constructor or deduction guide for deduction of "
+  "template arguments of %0">;
+def err_deduced_class_template_incomplete : Error<
+  "template %0 has no definition and no %select{|viable }1deduction guides "
+  "for deduction of template arguments">;
+def err_deduced_class_template_deleted : Error<
+  "class template argument deduction for %0 selected a deleted constructor">;
+def err_deduced_class_template_explicit : Error<
+  "class template argument deduction for %0 selected an explicit "
+  "%select{constructor|deduction guide}1 for copy-list-initialization">;
+def err_deduction_guide_no_trailing_return_type : Error<
+  "deduction guide declaration without trailing return type">;
+def err_deduction_guide_bad_trailing_return_type : Error<
+  "deduced type %1 of deduction guide is not %select{|written as }2"
+  "a specialization of template %0">;
+def err_deduction_guide_with_complex_decl : Error<
+  "cannot specify any part of a return type in the "
+  "declaration of a deduction guide">;
+def err_deduction_guide_invalid_specifier : Error<
+  "deduction guide cannot be declared '%0'">;
+def err_deduction_guide_name_not_class_template : Error<
+  "cannot specify deduction guide for "
+  "%select{<error>|function template|variable template|alias template|"
+  "template template parameter|dependent template name}0 %1">;
+def err_deduction_guide_wrong_scope : Error<
+  "deduction guide must be declared in the same scope as template %q0">;
+def err_deduction_guide_defines_function : Error<
+  "deduction guide cannot have a function definition">;
+def err_deduction_guide_explicit_mismatch : Error<
+  "deduction guide is %select{not |}0declared 'explicit' but "
+  "previous declaration was%select{ not|}0">;
+def err_deduction_guide_specialized : Error<"deduction guide cannot be "
+  "%select{explicitly instantiated|explicitly specialized}0">;
+def err_deduction_guide_template_not_deducible : Error<
+    "deduction guide template contains "
+    "%select{a template parameter|template parameters}0 that cannot be "
+    "deduced">;
+
 // C++1y deduced return types
 def err_auto_fn_deduction_failure : Error<
   "cannot deduce return type %0 from returned value of type %1">;
@@ -1950,6 +2039,9 @@
   "%select{function|functions}1">;
 def err_function_marked_override_not_overriding : Error<
   "%0 marked 'override' but does not override any member functions">;
+def warn_destructor_marked_not_override_overriding : Warning <
+  "%0 overrides a destructor but is not marked 'override'">,
+  InGroup<CXX11WarnOverrideDestructor>, DefaultIgnore;
 def warn_function_marked_not_override_overriding : Warning <
   "%0 overrides a member function but is not marked 'override'">,
   InGroup<CXX11WarnOverrideMethod>;
@@ -2141,8 +2233,11 @@
 def ext_constexpr_function_never_constant_expr : ExtWarn<
   "constexpr %select{function|constructor}0 never produces a "
   "constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
-def err_enable_if_never_constant_expr : Error<
-  "'enable_if' attribute expression never produces a constant expression">;
+def err_attr_cond_never_constant_expr : Error<
+  "%0 attribute expression never produces a constant expression">;
+def err_diagnose_if_invalid_diagnostic_type : Error<
+  "invalid diagnostic type for 'diagnose_if'; use \"error\" or \"warning\" "
+  "instead">;
 def err_constexpr_body_no_return : Error<
   "no return statement in constexpr function">;
 def err_constexpr_return_missing_expr : Error<
@@ -2212,6 +2307,9 @@
   "%select{function|variable}0 concept cannot be "
   "%select{explicitly instantiated|explicitly specialized|partially specialized}1">;
 
+def err_template_different_associated_constraints : Error<
+  "associated constraints differ in template redeclaration">;
+
 // C++11 char16_t/char32_t
 def warn_cxx98_compat_unicode_type : Warning<
   "'%0' type specifier is incompatible with C++98">,
@@ -2258,7 +2356,7 @@
     InGroup<IgnoredAttributes>;
 def err_attribute_unsupported
     : Error<"%0 attribute is not supported for this target">;
-// The err_*_attribute_argument_not_int are seperate because they're used by
+// The err_*_attribute_argument_not_int are separate because they're used by
 // VerifyIntegerConstantExpression.
 def err_aligned_attribute_argument_not_int : Error<
   "'aligned' attribute requires integer constant">;
@@ -2299,6 +2397,9 @@
   "%0 attribute only applies to%select{| constant}1 pointer arguments">,
   InGroup<IgnoredAttributes>;
 def err_attribute_pointers_only : Error<warn_attribute_pointers_only.Text>;
+def err_attribute_integers_only : Error<
+  "%0 attribute argument may only refer to a function parameter of integer "
+  "type">;
 def warn_attribute_return_pointers_only : Warning<
   "%0 attribute only applies to return values that are pointers">,
   InGroup<IgnoredAttributes>;
@@ -2652,7 +2753,9 @@
   "|variables, enums, fields and typedefs"
   "|functions, methods, enums, and classes"
   "|structs, classes, variables, functions, and inline namespaces"
-  "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members}1">,
+  "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members"
+  "|classes and enumerations"
+  "|named declarations}1">,
   InGroup<IgnoredAttributes>;
 def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
 def warn_type_attribute_wrong_type : Warning<
@@ -2928,7 +3031,7 @@
   "implicit conversion from %2 to %3 changes value from %0 to %1">,
   InGroup<ConstantConversion>;
 def warn_impcast_bitfield_precision_constant : Warning<
-  "implicit truncation from %2 to bitfield changes value from %0 to %1">,
+  "implicit truncation from %2 to bit-field changes value from %0 to %1">,
   InGroup<BitFieldConstantConversion>;
 
 def warn_impcast_literal_float_to_integer : Warning<
@@ -3314,21 +3417,24 @@
     "is the implicit copy assignment operator|"
     "is the implicit move assignment operator|"
     "inherited constructor|"
-    "inherited constructor }0%1"
-    "%select{| has different class%diff{ (expected $ but has $)|}3,4"
-    "| has different number of parameters (expected %3 but has %4)"
-    "| has type mismatch at %ordinal3 parameter"
-    "%diff{ (expected $ but has $)|}4,5"
-    "| has different return type%diff{ ($ expected but has $)|}3,4"
+    "inherited constructor }0%2"
+    "%select{| has different class%diff{ (expected $ but has $)|}4,5"
+    "| has different number of parameters (expected %4 but has %5)"
+    "| has type mismatch at %ordinal4 parameter"
+    "%diff{ (expected $ but has $)|}5,6"
+    "| has different return type%diff{ ($ expected but has $)|}4,5"
     "| has different qualifiers (expected "
     "%select{none|const|restrict|const and restrict|volatile|const and volatile"
-    "|volatile and restrict|const, volatile, and restrict}3 but found "
+    "|volatile and restrict|const, volatile, and restrict}4 but found "
     "%select{none|const|restrict|const and restrict|volatile|const and volatile"
-    "|volatile and restrict|const, volatile, and restrict}4)"
-    "| has different exception specification}2">;
+    "|volatile and restrict|const, volatile, and restrict}5)"
+    "| has different exception specification}3">;
 
 def note_ovl_candidate_inherited_constructor : Note<
     "constructor from base class %0 inherited here">;
+def note_ovl_candidate_inherited_constructor_slice : Note<
+    "candidate %select{constructor|template}0 ignored: "
+    "inherited constructor cannot be used to %select{copy|move}1 object">;
 def note_ovl_candidate_illegal_constructor : Note<
     "candidate %select{constructor|template}0 ignored: "
     "instantiation %select{takes|would take}0 its own class type by value">;
@@ -3339,6 +3445,10 @@
 def note_ovl_candidate_inconsistent_deduction : Note<
     "candidate template ignored: deduced conflicting %select{types|values|"
     "templates}0 for parameter %1%diff{ ($ vs. $)|}2,3">;
+def note_ovl_candidate_inconsistent_deduction_types : Note<
+    "candidate template ignored: deduced values %diff{"
+    "of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|"
+    "%1 and %3 of conflicting types for parameter %0}2,4">;
 def note_ovl_candidate_explicit_arg_mismatch_named : Note<
     "candidate template ignored: invalid explicitly-specified argument "
     "for template parameter %0">;
@@ -3358,20 +3468,24 @@
 def note_ovl_candidate_has_pass_object_size_params: Note<
     "candidate address cannot be taken because parameter %0 has "
     "pass_object_size attribute">;
-def note_ovl_candidate_disabled_by_enable_if_attr : Note<
+def err_diagnose_if_succeeded : Error<"%0">;
+def warn_diagnose_if_succeeded : Warning<"%0">, InGroup<UserDefinedWarnings>,
+    ShowInSystemHeader;
+def note_ovl_candidate_disabled_by_function_cond_attr : Note<
     "candidate disabled: %0">;
+def note_ovl_candidate_disabled_by_extension : Note<
+    "candidate disabled due to OpenCL extension">;
 def err_addrof_function_disabled_by_enable_if_attr : Error<
-    "cannot take address of function %0 becuase it has one or more "
+    "cannot take address of function %0 because it has one or more "
     "non-tautological enable_if conditions">;
 def note_addrof_ovl_candidate_disabled_by_enable_if_attr : Note<
     "candidate function made ineligible by enable_if">;
-def note_ovl_candidate_failed_overload_resolution : Note<
-    "candidate template ignored: couldn't resolve reference to overloaded "
-    "function %0">;
 def note_ovl_candidate_deduced_mismatch : Note<
     "candidate template ignored: deduced type "
-    "%diff{$ of %ordinal0 parameter does not match adjusted type $ of argument"
-    "|of %ordinal0 parameter does not match adjusted type of argument}1,2%3">;
+    "%diff{$ of %select{|element of }4%ordinal0 parameter does not match "
+    "adjusted type $ of %select{|element of }4argument"
+    "|of %select{|element of }4%ordinal0 parameter does not match "
+    "adjusted type of %select{|element of }4argument}1,2%3">;
 def note_ovl_candidate_non_deduced_mismatch : Note<
     "candidate template ignored: could not match %diff{$ against $|types}0,1">;
 // This note is needed because the above note would sometimes print two
@@ -3771,11 +3885,13 @@
 
 // C++ Template Argument Lists
 def err_template_missing_args : Error<
-  "use of class template %0 requires template arguments">;
+  "use of "
+  "%select{class template|function template|variable template|alias template|"
+  "template template parameter|template}0 %1 requires template arguments">;
 def err_template_arg_list_different_arity : Error<
   "%select{too few|too many}0 template arguments for "
-  "%select{class template|function template|template template parameter"
-  "|template}1 %2">;
+  "%select{class template|function template|variable template|alias template|"
+  "template template parameter|template}1 %2">;
 def note_template_decl_here : Note<"template is declared here">;
 def err_template_arg_must_be_type : Error<
   "template argument for template type parameter must be a type">;
@@ -3834,7 +3950,7 @@
   "non-type template parameter %0 with type %1 has incompatible initializer of type %2">;
 def err_deduced_non_type_template_arg_type_mismatch : Error<
   "deduced non-type template argument does not have the same type as the "
-  "its corresponding template parameter%diff{ ($ vs $)|}0,1">;
+  "corresponding template parameter%diff{ ($ vs $)|}0,1">;
 def err_non_type_template_arg_subobject : Error<
   "non-type template argument refers to subobject '%0'">;
 def err_non_type_template_arg_addr_label_diff : Error<
@@ -3911,6 +4027,8 @@
 def ext_ms_delayed_template_argument: ExtWarn<
   "using the undeclared type %0 as a default template argument is a "
   "Microsoft extension">, InGroup<MicrosoftTemplate>;
+def err_template_arg_deduced_incomplete_pack : Error<
+  "deduced incomplete pack %0 for template parameter %1">;
 
 // C++ template specialization
 def err_template_spec_unknown_kind : Error<
@@ -4022,8 +4140,8 @@
 def err_default_arg_in_partial_spec : Error<
     "default template argument in a class template partial specialization">;
 def err_dependent_non_type_arg_in_partial_spec : Error<
-    "non-type template argument depends on a template parameter of the "
-    "partial specialization">;
+    "type of specialized non-type template argument depends on a template "
+    "parameter of the partial specialization">;
 def note_dependent_non_type_default_arg_in_partial_spec : Note<
     "template parameter is used in default argument declared here">;
 def err_dependent_typed_non_type_arg_in_partial_spec : Error<
@@ -4033,11 +4151,17 @@
     "%select{class|variable}0 template partial specialization does not "
     "specialize any template argument; to %select{declare|define}1 the "
     "primary template, remove the template argument list">; 
-def warn_partial_specs_not_deducible : Warning<
+def ext_partial_spec_not_more_specialized_than_primary : ExtWarn<
+    "%select{class|variable}0 template partial specialization is not "
+    "more specialized than the primary template">, DefaultError,
+    InGroup<DiagGroup<"invalid-partial-specialization">>;
+def note_partial_spec_not_more_specialized_than_primary : Note<"%0">;
+def ext_partial_specs_not_deducible : ExtWarn<
     "%select{class|variable}0 template partial specialization contains "
     "%select{a template parameter|template parameters}1 that cannot be "
-    "deduced; this partial specialization will never be used">;
-def note_partial_spec_unused_parameter : Note<
+    "deduced; this partial specialization will never be used">,
+    DefaultError, InGroup<DiagGroup<"unusable-partial-specialization">>;
+def note_non_deducible_parameter : Note<
     "non-deducible template parameter %0">;
 def err_partial_spec_ordering_ambiguous : Error<
     "ambiguous partial specializations of %0">;
@@ -4070,7 +4194,7 @@
     "function template; explicitly specify%select{| additional}1 template "
     "arguments to identify a particular function template">;
 def note_function_template_spec_matched : Note<
-    "function template matches specialization %0">;
+    "function template %q0 matches specialization %1">;
 def err_function_template_partial_spec : Error<
     "function template partial specialization is not allowed">;
 
@@ -4093,9 +4217,9 @@
 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">;
+  "in instantiation of template class %q0 requested here">;
 def note_template_member_class_here : Note<
-  "in instantiation of member class %0 requested here">;
+  "in instantiation of member class %q0 requested here">;
 def note_template_member_function_here : Note<
   "in instantiation of member function %q0 requested here">;
 def note_function_template_spec_here : Note<
@@ -4135,9 +4259,9 @@
 def note_function_template_deduction_instantiation_here : Note<
   "while substituting deduced template arguments into function template %0 "
   "%1">;
-def note_partial_spec_deduct_instantiation_here : Note<
-  "during template argument deduction for class template partial "
-  "specialization %0 %1">;
+def note_deduced_template_arg_substitution_here : Note<
+  "during template argument deduction for %select{class|variable}0 template "
+  "%select{partial specialization |}1%2 %3">;
 def note_prior_template_arg_substitution : Note<
   "while substituting prior template arguments into %select{non-type|template}0"
   " template parameter%1 %2">;
@@ -4154,6 +4278,9 @@
 def err_nested_name_spec_non_tag : Error<
   "type %0 cannot be used prior to '::' because it has no members">;
 
+def err_using_pack_expansion_empty : Error<
+  "%select{|member}0 using declaration %1 instantiates to an empty pack">;
+
 // C++ Explicit Instantiation
 def err_explicit_instantiation_duplicate : Error<
     "duplicate explicit instantiation of %0">;
@@ -4205,7 +4332,7 @@
 def err_explicit_instantiation_ambiguous : Error<
   "partial ordering for explicit instantiation of %0 is ambiguous">;
 def note_explicit_instantiation_candidate : Note<
-  "explicit instantiation candidate function template here %0">;
+  "explicit instantiation candidate function %q0 template here %1">;
 def err_explicit_instantiation_inline : Error<
   "explicit instantiation cannot be 'inline'">;
 def warn_explicit_instantiation_inline_0x : Warning<
@@ -4257,6 +4384,8 @@
     "referenced member %0 is declared here">;
 def err_typename_missing : Error<
   "missing 'typename' prior to dependent type name '%0%1'">;
+def err_typename_missing_template : Error<
+  "missing 'typename' prior to dependent type template name '%0%1'">;
 def ext_typename_missing : ExtWarn<
   "missing 'typename' prior to dependent type name '%0%1'">,
   InGroup<DiagGroup<"typename-missing">>;
@@ -4275,7 +4404,7 @@
   "%0 following the 'template' keyword does not refer to a template">;
 def err_template_kw_refers_to_class_template : Error<
   "'%0%1' instantiated to a class template, not a function template">;
-def note_referenced_class_template : Error<
+def note_referenced_class_template : Note<
   "class template declared here">;
 def err_template_kw_missing : Error<
   "missing 'template' keyword prior to dependent template name '%0%1'">;
@@ -4375,6 +4504,7 @@
 def err_undeclared_use : Error<"use of undeclared %0">;
 def warn_deprecated : Warning<"%0 is deprecated">,
     InGroup<DeprecatedDeclarations>;
+def note_from_diagnose_if : Note<"from 'diagnose_if' attribute on %0:">;
 def warn_property_method_deprecated :
     Warning<"property access is using %0 method which is deprecated">,
     InGroup<DeprecatedDeclarations>;
@@ -4564,10 +4694,15 @@
   "%select{typedef|type alias|type alias template}0 "
   "redefinition with different types%diff{ ($ vs $)|}1,2">;
 def err_tag_reference_non_tag : Error<
-  "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template|a template template argument}0">;
+  "%select{non-struct type|non-class type|non-union type|non-enum "
+  "type|typedef|type alias|template|type alias template|template "
+  "template argument}1 %0 cannot be referenced with a "
+  "%select{struct|interface|union|class|enum}2 specifier">;
 def err_tag_reference_conflict : Error<
-  "implicit declaration introduced by elaborated type conflicts with "
-  "%select{a declaration|a typedef|a type alias|a template}0 of the same name">;
+  "implicit declaration introduced by elaborated type conflicts with a "
+  "%select{non-struct type|non-class type|non-union type|non-enum "
+  "type|typedef|type alias|template|type alias template|template "
+  "template argument}0 of the same name">;
 def err_dependent_tag_decl : Error<
   "%select{declaration|definition}0 of "
   "%select{struct|interface|union|class|enum}1 in a dependent scope">;
@@ -5129,7 +5264,7 @@
 def warn_block_capture_autoreleasing : Warning<
   "block captures an autoreleasing out-parameter, which may result in "
   "use-after-free bugs">,
-  InGroup<BlockCaptureAutoReleasing>, DefaultIgnore;
+  InGroup<BlockCaptureAutoReleasing>;
 def note_declare_parameter_autoreleasing : Note<
   "declare the parameter __autoreleasing explicitly to suppress this warning">;
 def note_declare_parameter_strong : Note<
@@ -5690,8 +5825,8 @@
 def err_invalid_member_use_in_static_method : Error<
   "invalid use of member %0 in static member function">;
 def err_invalid_qualified_function_type : Error<
-  "%select{static |non-}0member function %select{of type %2 |}1"
-  "cannot have '%3' qualifier">;
+  "%select{non-member function|static member function|deduction guide}0 "
+  "%select{of type %2 |}1cannot have '%3' qualifier">;
 def err_compound_qualified_function_type : Error<
   "%select{block pointer|pointer|reference}0 to function type %select{%2 |}1"
   "cannot have '%3' qualifier">;
@@ -5881,6 +6016,12 @@
   "adding '%0' to '%1' might cause circular dependency in container">,
   InGroup<DiagGroup<"objc-circular-container">>;
 def note_objc_circular_container_declared_here : Note<"'%0' declared here">;
+def warn_objc_unsafe_perform_selector : Warning<
+  "%0 is incompatible with selectors that return a "
+  "%select{struct|union|vector}1 type">,
+  InGroup<DiagGroup<"objc-unsafe-perform-selector">>;
+def note_objc_unsafe_perform_selector_method_declared_here :  Note<
+  "method %0 that returns %1 declared here">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
@@ -6966,7 +7107,7 @@
 def err_require_constant_init_failed : Error<
   "variable does not have a constant initializer">;
 def note_declared_required_constant_init_here : Note<
-  "required by 'require_constant_initializer' attribute here">;
+  "required by 'require_constant_initialization' attribute here">;
 
 def err_dimension_expr_not_constant_integer : Error<
   "dimension expression does not evaluate to a constant unsigned int">;
@@ -7051,6 +7192,10 @@
     "constraint '%0' is already present here">;
 }
 
+  def error_inoutput_conflict_with_clobber : Error<
+    "asm-specifier for input or output variable conflicts with asm"
+    " clobber list">;
+
 let CategoryName = "Semantic Issue" in {
 
 def err_invalid_conversion_between_vectors : Error<
@@ -7860,6 +8005,8 @@
   "this builtin is only available on x86-64 targets">;
 def err_x86_builtin_invalid_rounding : Error<
   "invalid rounding argument">;
+def err_x86_builtin_invalid_scale : Error<
+  "scale argument must be 1, 2, 4, or 8">;
 
 def err_builtin_longjmp_unsupported : Error<
   "__builtin_longjmp is not supported for the current target">;
@@ -7932,8 +8079,6 @@
 def err_c99_array_usage_cxx : Error<
   "%select{qualifier in |static |}0array size %select{||'[*] '}0is a C99 "
   "feature, not permitted in C++">;
- def err_type_requires_extension : Error<
-  "use of type %0 requires %1 extension to be enabled">;
 def err_type_unsupported : Error<
   "%0 is not supported on this target">;
 def err_nsconsumed_attribute_mismatch : Error<
@@ -8073,14 +8218,15 @@
   "kernel functions cannot be declared static">;
 def err_opencl_ptrptr_kernel_param : Error<
   "kernel parameter cannot be declared as a pointer to a pointer">;
-def err_opencl_private_ptr_kernel_param : Error<
-  "kernel parameter cannot be declared as a pointer to the __private address space">;
+def err_kernel_arg_address_space : Error<
+  "pointer arguments to kernel functions must reside in '__global', "
+  "'__constant' or '__local' address space">;
 def err_opencl_function_variable : Error<
   "%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">;
 def err_static_function_scope : Error<
   "variables in function scope cannot be declared static">;
 def err_opencl_bitfields : Error<
-  "bitfields are not supported in OpenCL">;
+  "bit-fields are not supported in OpenCL">;
 def err_opencl_vla : Error<
   "variable length arrays are not supported in OpenCL">;
 def err_bad_kernel_param_type : Error<
@@ -8138,6 +8284,8 @@
   InGroup<IgnoredAttributes>;
 def err_opencl_variadic_function : Error<
   "invalid prototype, variadic arguments are not allowed in OpenCL">;
+def err_opencl_requires_extension : Error<
+  "use of %select{type |declaration}0%1 requires %2 extension to be enabled">;
 
 // OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions
 def err_opencl_builtin_pipe_first_arg : Error<
@@ -8170,6 +8318,8 @@
   "invalid block variable declaration - must be %select{const qualified|initialized}0">;
 def err_opencl_extern_block_declaration : Error<
   "invalid block variable declaration - using 'extern' storage class is disallowed">;
+def err_opencl_block_ref_block : Error<
+  "cannot refer to a block inside block">;
 
 // OpenCL v2.0 s6.13.9 - Address space qualifier functions. 
 def err_opencl_builtin_to_addr_arg_num : Error<
@@ -8187,9 +8337,9 @@
 def err_opencl_enqueue_kernel_invalid_local_size_type : Error<
   "illegal call to enqueue_kernel, parameter needs to be specified as integer type">;
 def err_opencl_enqueue_kernel_blocks_non_local_void_args : Error<
-  "blocks used in device side enqueue are expected to have parameters of type 'local void*'">;
+  "blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'">;
 def err_opencl_enqueue_kernel_blocks_no_args : Error<
-  "blocks in this form of device side enqueue call are expected to have have no parameters">;
+  "blocks with parameters are not accepted in this prototype of enqueue_kernel call">;
 
 // OpenCL v2.2 s2.1.2.3 - Vector Component Access
 def ext_opencl_ext_vector_type_rgba_selector: ExtWarn<
@@ -8668,8 +8818,7 @@
 def err_return_in_coroutine : Error<
   "return statement not allowed in coroutine; did you mean 'co_return'?">;
 def note_declared_coroutine_here : Note<
-  "function is a coroutine due to use of "
-  "'%select{co_await|co_yield|co_return}0' here">;
+  "function is a coroutine due to use of '%0' here">;
 def err_coroutine_objc_method : Error<
   "Objective-C methods as coroutines are not yet supported">;
 def err_coroutine_unevaluated_context : Error<
@@ -8681,19 +8830,22 @@
   "|a copy assignment operator|a move assignment operator|the 'main' function"
   "|a constexpr function|a function with a deduced return type"
   "|a varargs function}0">;
-def ext_coroutine_without_co_await_co_yield : ExtWarn<
-  "'co_return' used in a function "
-  "that uses neither 'co_await' nor 'co_yield'">,
-  InGroup<DiagGroup<"coreturn-without-coawait">>;
-def err_implied_std_coroutine_traits_not_found : Error<
-  "you need to include <experimental/coroutine> before defining a coroutine">;
+def err_implied_coroutine_type_not_found : Error<
+  "%0 type was not found; include <experimental/coroutine> before defining "
+  "a coroutine">;
+def err_malformed_std_coroutine_handle : Error<
+  "std::experimental::coroutine_handle must be a class template">;
+def err_coroutine_handle_missing_member : Error<
+  "std::experimental::coroutine_handle missing a member named '%0'">;
 def err_malformed_std_coroutine_traits : Error<
   "'std::experimental::coroutine_traits' must be a class template">;
 def err_implied_std_coroutine_traits_promise_type_not_found : Error<
   "this function cannot be a coroutine: %q0 has no member named 'promise_type'">;
 def err_implied_std_coroutine_traits_promise_type_not_class : Error<
   "this function cannot be a coroutine: %0 is not a class">;
-def err_coroutine_traits_missing_specialization : Error<
+def err_coroutine_promise_type_incomplete : Error<
+  "this function cannot be a coroutine: %0 is an incomplete type">;
+def err_coroutine_type_missing_specialization : Error<
   "this function cannot be a coroutine: missing definition of "
   "specialization %q0">;
 def err_implied_std_current_exception_not_found : Error<
@@ -8703,6 +8855,11 @@
   "'std::current_exception' must be a function">;
 def err_coroutine_promise_return_ill_formed : Error<
   "%0 declares both 'return_value' and 'return_void'">;
+def note_coroutine_promise_implicit_await_transform_required_here : Note<
+  "call to 'await_transform' implicitly required by 'co_await' here">;
+def note_coroutine_promise_call_implicitly_required : Note<
+  "call to '%select{initial_suspend|final_suspend}0' implicitly "
+  "required by the %select{initial suspend point|final suspend point}0">;
 }
 
 let CategoryName = "Documentation Issue" in {
@@ -8763,6 +8920,10 @@
   "array parameter is missing a nullability type specifier (_Nonnull, "
   "_Nullable, or _Null_unspecified)">,
   InGroup<NullabilityCompletenessOnArrays>;
+def note_nullability_fix_it : Note<
+  "insert '%select{_Nonnull|_Nullable|_Null_unspecified}0' if the "
+  "%select{pointer|block pointer|member pointer|array parameter}1 "
+  "%select{should never be null|may be null|should not declare nullability}0">;
 
 def warn_nullability_inferred_on_nested_type : Warning<
   "inferring '_Nonnull' for pointer type within %select{array|reference}0 is "
@@ -8865,4 +9026,9 @@
   "__final is a GNU extension, consider using C++11 final">,
   InGroup<GccCompat>;
 
+def warn_shadow_field :
+  Warning<"non-static data member '%0' of '%1' shadows member inherited from type '%2'">,
+  InGroup<ShadowField>, DefaultIgnore;
+def note_shadow_field : Note<"declared here">;
+
 } // end of sema component.
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 066a1f5..d6e040a 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -117,6 +117,57 @@
 def err_module_odr_violation_different_instantiations : Error<
   "instantiation of %q0 is different in different modules">;
 
+def err_module_odr_violation_mismatch_decl : Error<
+  "%q0 has different definitions in different modules; first difference is "
+  "%select{definition in module '%2'|defined here}1 found "
+  "%select{end of class|public access specifier|private access specifier|"
+  "protected access specifier|static assert|field|method}3">;
+def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
+  "%select{end of class|public access specifier|private access specifier|"
+  "protected access specifier|static assert|field|method}1">;
+
+def err_module_odr_violation_mismatch_decl_diff : Error<
+  "%q0 has different definitions in different modules; first difference is "
+  "%select{definition in module '%2'|defined here}1 found "
+  "%select{"
+  "static assert with condition|"
+  "static assert with message|"
+  "static assert with %select{|no }4message|"
+  "field %4|"
+  "field %4 with type %5|"
+  "%select{non-|}5bitfield %4|"
+  "bitfield %4 with one width expression|"
+  "%select{non-|}5mutable field %4|"
+  "field %4 with %select{no|an}5 initalizer|"
+  "field %4 with an initializer|"
+  "method %4|"
+  "method %4 is %select{not deleted|deleted}5|"
+  "method %4 is %select{|pure }5%select{not virtual|virtual}6|"
+  "method %4 is %select{not static|static}5|"
+  "method %4 is %select{not volatile|volatile}5|"
+  "method %4 is %select{not const|const}5|"
+  "method %4 is %select{not inline|inline}5}3">;
+
+def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
+  "%select{"
+  "static assert with different condition|"
+  "static assert with different message|"
+  "static assert with %select{|no }2message|"
+  "field %2|"
+  "field %2 with type %3|"
+  "%select{non-|}3bitfield %2|"
+  "bitfield %2 with different width expression|"
+  "%select{non-|}3mutable field %2|"
+  "field %2 with %select{no|an}3 initializer|"
+  "field %2 with a different initializer|"
+  "method %2|"
+  "method %2 is %select{not deleted|deleted}3|"
+  "method %2 is %select{|pure }3%select{not virtual|virtual}4|"
+  "method %2 is %select{not static|static}3|"
+  "method %2 is %select{not volatile|volatile}3|"
+  "method %2 is %select{not const|const}3|"
+  "method %2 is %select{not inline|inline}3}1">;
+
 def warn_module_uses_date_time : Warning<
   "%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
   InGroup<DiagGroup<"pch-date-time">>;
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 3001d0b..aaed481 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -818,6 +818,7 @@
 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
     CXXOperator##Name,
 #include "clang/Basic/OperatorKinds.def"
+    CXXDeductionGuide,
     CXXLiteralOperator,
     CXXUsingDirective,
     NUM_EXTRA_KINDS
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index 0e6ff92..f32ab5e 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -30,6 +30,7 @@
   class Twine;
   template<typename T> class ArrayRef;
   template<typename T> class MutableArrayRef;
+  template<typename T> class OwningArrayRef;
   template<unsigned InternalLen> class SmallString;
   template<typename T, unsigned N> class SmallVector;
   template<typename T> class SmallVectorImpl;
@@ -42,7 +43,6 @@
   template <typename T> class IntrusiveRefCntPtr;
   template <typename T> struct IntrusiveRefCntPtrInfo;
   template <class Derived> class RefCountedBase;
-  class RefCountedBaseVPTR;
 
   class raw_ostream;
   class raw_pwrite_stream;
@@ -65,6 +65,7 @@
   using llvm::Twine;
   using llvm::ArrayRef;
   using llvm::MutableArrayRef;
+  using llvm::OwningArrayRef;
   using llvm::SmallString;
   using llvm::SmallVector;
   using llvm::SmallVectorImpl;
@@ -74,7 +75,6 @@
   using llvm::IntrusiveRefCntPtr;
   using llvm::IntrusiveRefCntPtrInfo;
   using llvm::RefCountedBase;
-  using llvm::RefCountedBaseVPTR;
 
   using llvm::raw_ostream;
   using llvm::raw_pwrite_stream;
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index e65811b..7126275 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -107,7 +107,7 @@
 LANGOPT(DeclSpecKeyword   , 1, 0, "__declspec keyword")
 BENIGN_LANGOPT(DollarIdents   , 1, 1, "'$' in identifiers")
 BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
-BENIGN_LANGOPT(GNUMode        , 1, 1, "GNU extensions")
+LANGOPT(GNUMode           , 1, 1, "GNU extensions")
 LANGOPT(GNUKeywords       , 1, 1, "GNU keywords")
 BENIGN_LANGOPT(ImplicitInt, 1, !C99 && !CPlusPlus, "C89 implicit 'int'")
 LANGOPT(Digraphs          , 1, 0, "digraphs")
@@ -134,6 +134,7 @@
 LANGOPT(NoMathBuiltin     , 1, 0, "disable math builtin functions")
 LANGOPT(GNUAsm            , 1, 1, "GNU-style inline assembly")
 LANGOPT(CoroutinesTS      , 1, 0, "C++ coroutines TS")
+LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
 
 BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers")
 LANGOPT(POSIXThreads      , 1, 0, "POSIX thread support")
@@ -145,6 +146,7 @@
 COMPATIBLE_LANGOPT(ModulesTS  , 1, 0, "C++ Modules TS")
 BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None,
                     "compiling a module interface")
+BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch")
 COMPATIBLE_LANGOPT(ModulesDeclUse    , 1, 0, "require declaration of module uses")
 BENIGN_LANGOPT(ModulesSearchAll  , 1, 1, "searching even non-imported modules to find unresolved references")
 COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules")
@@ -199,6 +201,7 @@
 LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
 LANGOPT(NewAlignOverride  , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'")
 LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts")
+BENIGN_LANGOPT(ModularCodegen , 1, 0, "Modular codegen")
 BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
 BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
 BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form")
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 31c5c7e..51ad109 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -42,7 +42,17 @@
   
 /// \brief Describes the name of a module.
 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
-  
+
+/// The signature of a module, which is a hash of the AST content.
+struct ASTFileSignature : std::array<uint32_t, 5> {
+  ASTFileSignature(std::array<uint32_t, 5> S = {{0}})
+      : std::array<uint32_t, 5>(std::move(S)) {}
+
+  explicit operator bool() const {
+    return *this != std::array<uint32_t, 5>({{0}});
+  }
+};
+
 /// \brief Describes a module or submodule.
 class Module {
 public:
@@ -65,7 +75,7 @@
   llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
 
   /// \brief The module signature.
-  uint64_t Signature;
+  ASTFileSignature Signature;
 
   /// \brief The name of the umbrella entry, as written in the module map.
   std::string UmbrellaAsWritten;
@@ -205,6 +215,8 @@
   /// and headers from used modules.
   unsigned NoUndeclaredIncludes : 1;
 
+  unsigned WithCodegen : 1;
+
   /// \brief Describes the visibility of the various names within a
   /// particular module.
   enum NameVisibilityKind {
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index 6975b6c..78fc899 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -312,6 +312,7 @@
   bool hasARCUnsafeClaimAutoreleasedReturnValue() const {
     switch (getKind()) {
     case MacOSX:
+    case FragileMacOSX:
       return getVersion() >= VersionTuple(10, 11);
     case iOS:
       return getVersion() >= VersionTuple(9);
diff --git a/include/clang/Basic/OpenCLImageTypes.def b/include/clang/Basic/OpenCLImageTypes.def
index 26db4ce..0efed99 100644
--- a/include/clang/Basic/OpenCLImageTypes.def
+++ b/include/clang/Basic/OpenCLImageTypes.def
@@ -7,73 +7,79 @@
 //
 //===----------------------------------------------------------------------===//
 //  This file extends builtin types database with OpenCL image singleton types.
-//  Custom code should define one of those two macros:
-//    GENERIC_IMAGE_TYPE(Type, Id) - a generic image with its Id without an 
+//  Custom code should define one of those three macros:
+//    GENERIC_IMAGE_TYPE(Type, Id) - a generic image with its Id without an
 //      access type
 //    IMAGE_TYPE(Type, Id, SingletonId, AccessType, CGSuffix) - an image type
-//      with given ID, singleton ID access type and a codegen suffix  
+//      with given ID, singleton ID access type and a codegen suffix
+//    GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) - a generic image with its Id and
+//      required extension without an access type
 
 #ifdef GENERIC_IMAGE_TYPE
 
-#define IMAGE_READ_TYPE(Type, Id) GENERIC_IMAGE_TYPE(Type, Id)
-#define IMAGE_WRITE_TYPE(Type, Id) 
-#define IMAGE_READ_WRITE_TYPE(Type, Id) 
+#define IMAGE_READ_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE(Type, Id)
+#define IMAGE_WRITE_TYPE(Type, Id, Ext)
+#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
+
+#elif defined(GENERIC_IMAGE_TYPE_EXT)
+#define IMAGE_READ_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE_EXT(Type, Id##ROTy, Ext)
+#define IMAGE_WRITE_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE_EXT(Type, Id##WOTy, Ext)
+#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE_EXT(Type, Id##RWTy, Ext)
 
 #else
-
 #ifndef IMAGE_READ_TYPE
-#define IMAGE_READ_TYPE(Type, Id) \
+#define IMAGE_READ_TYPE(Type, Id, Ext) \
           IMAGE_TYPE(Type, Id##RO, Id##ROTy,  read_only, ro)
 #endif
 #ifndef IMAGE_WRITE_TYPE
-#define IMAGE_WRITE_TYPE(Type, Id) \
+#define IMAGE_WRITE_TYPE(Type, Id, Ext) \
           IMAGE_TYPE(Type, Id##WO, Id##WOTy, write_only, wo)
 #endif
 #ifndef IMAGE_READ_WRITE_TYPE
-#define IMAGE_READ_WRITE_TYPE(Type, Id) \
+#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext) \
           IMAGE_TYPE(Type, Id##RW, Id##RWTy, read_write, rw)
 #endif
 
 #endif
 
-IMAGE_READ_TYPE(image1d, OCLImage1d)
-IMAGE_READ_TYPE(image1d_array, OCLImage1dArray)
-IMAGE_READ_TYPE(image1d_buffer, OCLImage1dBuffer)
-IMAGE_READ_TYPE(image2d, OCLImage2d)
-IMAGE_READ_TYPE(image2d_array, OCLImage2dArray)
-IMAGE_READ_TYPE(image2d_depth, OCLImage2dDepth)
-IMAGE_READ_TYPE(image2d_array_depth, OCLImage2dArrayDepth)
-IMAGE_READ_TYPE(image2d_msaa, OCLImage2dMSAA)
-IMAGE_READ_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA)
-IMAGE_READ_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth)
-IMAGE_READ_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth)
-IMAGE_READ_TYPE(image3d, OCLImage3d)
+IMAGE_READ_TYPE(image1d, OCLImage1d, "")
+IMAGE_READ_TYPE(image1d_array, OCLImage1dArray, "")
+IMAGE_READ_TYPE(image1d_buffer, OCLImage1dBuffer, "")
+IMAGE_READ_TYPE(image2d, OCLImage2d, "")
+IMAGE_READ_TYPE(image2d_array, OCLImage2dArray, "")
+IMAGE_READ_TYPE(image2d_depth, OCLImage2dDepth, "")
+IMAGE_READ_TYPE(image2d_array_depth, OCLImage2dArrayDepth, "")
+IMAGE_READ_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_TYPE(image3d, OCLImage3d, "")
 
-IMAGE_WRITE_TYPE(image1d, OCLImage1d)
-IMAGE_WRITE_TYPE(image1d_array, OCLImage1dArray)
-IMAGE_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer)
-IMAGE_WRITE_TYPE(image2d, OCLImage2d)
-IMAGE_WRITE_TYPE(image2d_array, OCLImage2dArray)
-IMAGE_WRITE_TYPE(image2d_depth, OCLImage2dDepth)
-IMAGE_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth)
-IMAGE_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA)
-IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA)
-IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth)
-IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth)
-IMAGE_WRITE_TYPE(image3d, OCLImage3d)
+IMAGE_WRITE_TYPE(image1d, OCLImage1d, "")
+IMAGE_WRITE_TYPE(image1d_array, OCLImage1dArray, "")
+IMAGE_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer, "")
+IMAGE_WRITE_TYPE(image2d, OCLImage2d, "")
+IMAGE_WRITE_TYPE(image2d_array, OCLImage2dArray, "")
+IMAGE_WRITE_TYPE(image2d_depth, OCLImage2dDepth, "")
+IMAGE_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth, "")
+IMAGE_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_WRITE_TYPE(image3d, OCLImage3d, "cl_khr_3d_image_writes")
 
-IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d)
-IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray)
-IMAGE_READ_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer)
-IMAGE_READ_WRITE_TYPE(image2d, OCLImage2d)
-IMAGE_READ_WRITE_TYPE(image2d_array, OCLImage2dArray)
-IMAGE_READ_WRITE_TYPE(image2d_depth, OCLImage2dDepth)
-IMAGE_READ_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth)
-IMAGE_READ_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA)
-IMAGE_READ_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA)
-IMAGE_READ_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth)
-IMAGE_READ_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth)
-IMAGE_READ_WRITE_TYPE(image3d, OCLImage3d)
+IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d, "")
+IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray, "")
+IMAGE_READ_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer, "")
+IMAGE_READ_WRITE_TYPE(image2d, OCLImage2d, "")
+IMAGE_READ_WRITE_TYPE(image2d_array, OCLImage2dArray, "")
+IMAGE_READ_WRITE_TYPE(image2d_depth, OCLImage2dDepth, "")
+IMAGE_READ_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth, "")
+IMAGE_READ_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_WRITE_TYPE(image3d, OCLImage3d, "")
 
 #undef IMAGE_TYPE
 #undef GENERIC_IMAGE_TYPE
diff --git a/include/clang/Basic/OpenCLOptions.h b/include/clang/Basic/OpenCLOptions.h
index fa52ae7..cc850f0 100644
--- a/include/clang/Basic/OpenCLOptions.h
+++ b/include/clang/Basic/OpenCLOptions.h
@@ -15,81 +15,122 @@
 #ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
 #define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
 
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
 
 namespace clang {
 
 /// \brief OpenCL supported extensions and optional core features
 class OpenCLOptions {
+  struct Info {
+    bool Supported; // Is this option supported
+    bool Enabled;   // Is this option enabled
+    unsigned Avail; // Option starts to be available in this OpenCL version
+    unsigned Core;  // Option becomes (optional) core feature in this OpenCL
+                    // version
+    Info(bool S = false, bool E = false, unsigned A = 100, unsigned C = ~0U)
+      :Supported(S), Enabled(E), Avail(A), Core(C){}
+  };
+  llvm::StringMap<Info> OptMap;
 public:
-#define OPENCLEXT(nm) unsigned nm : 1;
-#include "clang/Basic/OpenCLExtensions.def"
-
-  OpenCLOptions() {
-#define OPENCLEXT(nm)   nm = 0;
-#include "clang/Basic/OpenCLExtensions.def"
+  bool isKnown(llvm::StringRef Ext) const {
+    return OptMap.find(Ext) != OptMap.end();
   }
 
-  // Enable or disable all options.
-  void setAll(bool Enable = true) {
-#define OPENCLEXT(nm)   nm = Enable;
-#include "clang/Basic/OpenCLExtensions.def"
+  bool isEnabled(llvm::StringRef Ext) const {
+    return OptMap.find(Ext)->second.Enabled;
+  }
+
+  // Is supported as either an extension or an (optional) core feature for
+  // OpenCL version \p CLVer.
+  bool isSupported(llvm::StringRef Ext, unsigned CLVer) const {
+    auto I = OptMap.find(Ext)->getValue();
+    return I.Supported && I.Avail <= CLVer;
+  }
+
+  // Is supported (optional) OpenCL core features for OpenCL version \p CLVer.
+  // For supported extension, return false.
+  bool isSupportedCore(llvm::StringRef Ext, unsigned CLVer) const {
+    auto I = OptMap.find(Ext)->getValue();
+    return I.Supported && I.Avail <= CLVer &&
+      I.Core != ~0U && CLVer >= I.Core;
+  }
+
+  // Is supported OpenCL extension for OpenCL version \p CLVer.
+  // For supported (optional) core feature, return false.
+ bool isSupportedExtension(llvm::StringRef Ext, unsigned CLVer) const {
+    auto I = OptMap.find(Ext)->getValue();
+    return I.Supported && I.Avail <= CLVer &&
+      (I.Core == ~0U || CLVer < I.Core);
+  }
+
+  void enable(llvm::StringRef Ext, bool V = true) {
+    OptMap[Ext].Enabled = V;
   }
 
   /// \brief Enable or disable support for OpenCL extensions
   /// \param Ext name of the extension optionally prefixed with
   ///        '+' or '-'
-  /// \param Enable used when \p Ext is not prefixed by '+' or '-'
-  void set(llvm::StringRef Ext, bool Enable = true) {
+  /// \param V used when \p Ext is not prefixed by '+' or '-'
+  void support(llvm::StringRef Ext, bool V = true) {
     assert(!Ext.empty() && "Extension is empty.");
 
     switch (Ext[0]) {
     case '+':
-      Enable = true;
+      V = true;
       Ext = Ext.drop_front();
       break;
     case '-':
-      Enable = false;
+      V = false;
       Ext = Ext.drop_front();
       break;
     }
 
     if (Ext.equals("all")) {
-      setAll(Enable);
+      supportAll(V);
       return;
     }
+    OptMap[Ext].Supported = V;
+  }
 
-#define OPENCLEXT(nm)       \
-    if (Ext.equals(#nm)) {  \
-      nm = Enable;          \
-    }
+  OpenCLOptions(){
+#define OPENCLEXT_INTERNAL(Ext, AvailVer, CoreVer) \
+    OptMap[#Ext].Avail = AvailVer; \
+    OptMap[#Ext].Core = CoreVer;
 #include "clang/Basic/OpenCLExtensions.def"
   }
 
-  // Is supported with OpenCL version \p OCLVer.
-#define OPENCLEXT_INTERNAL(Ext, Avail, ...) \
-  bool is_##Ext##_supported(unsigned OCLVer) const { \
-    return Ext && OCLVer >= Avail; \
+  void addSupport(const OpenCLOptions &Opts) {
+    for (auto &I:Opts.OptMap)
+      if (I.second.Supported)
+        OptMap[I.getKey()].Supported = true;
   }
-#include "clang/Basic/OpenCLExtensions.def"
 
-
-  // Is supported OpenCL extension with OpenCL version \p OCLVer.
-  // For supported optional core feature, return false.
-#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \
-  bool is_##Ext##_supported_extension(unsigned CLVer) const { \
-    return is_##Ext##_supported(CLVer) && (Core == ~0U || CLVer < Core); \
+  void copy(const OpenCLOptions &Opts) {
+    OptMap = Opts.OptMap;
   }
-#include "clang/Basic/OpenCLExtensions.def"
 
-  // Is supported OpenCL core features with OpenCL version \p OCLVer.
-  // For supported extension, return false.
-#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \
-  bool is_##Ext##_supported_core(unsigned CLVer) const { \
-    return is_##Ext##_supported(CLVer) && Core != ~0U && CLVer >= Core; \
+  // Turn on or off support of all options.
+  void supportAll(bool On = true) {
+    for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
+         E = OptMap.end(); I != E; ++I)
+      I->second.Supported = On;
   }
-#include "clang/Basic/OpenCLExtensions.def"
 
+  void disableAll() {
+    for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
+         E = OptMap.end(); I != E; ++I)
+      I->second.Enabled = false;
+  }
+
+  void enableSupportedCore(unsigned CLVer) {
+    for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
+         E = OptMap.end(); I != E; ++I)
+      if (isSupportedCore(I->getKey(), CLVer))
+        I->second.Enabled = true;
+  }
+
+  friend class ASTWriter;
+  friend class ASTReader;
 };
 
 }  // end namespace clang
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index ec6cf6b..74ec26f 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -153,6 +153,21 @@
 #ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
 #define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name)
 #endif
+#ifndef OPENMP_TARGET_TEAMS_CLAUSE
+#define OPENMP_TARGET_TEAMS_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name)
+#endif
 
 // OpenMP directives.
 OPENMP_DIRECTIVE(threadprivate)
@@ -202,6 +217,11 @@
 OPENMP_DIRECTIVE_EXT(teams_distribute_simd, "teams distribute simd")
 OPENMP_DIRECTIVE_EXT(teams_distribute_parallel_for_simd, "teams distribute parallel for simd")
 OPENMP_DIRECTIVE_EXT(teams_distribute_parallel_for, "teams distribute parallel for")
+OPENMP_DIRECTIVE_EXT(target_teams, "target teams")
+OPENMP_DIRECTIVE_EXT(target_teams_distribute, "target teams distribute")
+OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for, "target teams distribute parallel for")
+OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for_simd, "target teams distribute parallel for simd")
+OPENMP_DIRECTIVE_EXT(target_teams_distribute_simd, "target teams distribute simd")
 
 // OpenMP clauses.
 OPENMP_CLAUSE(if, OMPIfClause)
@@ -430,7 +450,6 @@
 OPENMP_TARGET_CLAUSE(is_device_ptr)
 
 // Clauses allowed for OpenMP directive 'target data'.
-// TODO More clauses for 'target data' directive.
 OPENMP_TARGET_DATA_CLAUSE(if)
 OPENMP_TARGET_DATA_CLAUSE(device)
 OPENMP_TARGET_DATA_CLAUSE(map)
@@ -451,7 +470,6 @@
 OPENMP_TARGET_EXIT_DATA_CLAUSE(depend)
 
 // Clauses allowed for OpenMP directive 'target parallel'.
-// TODO: add target clauses 'is_device_ptr'
 OPENMP_TARGET_PARALLEL_CLAUSE(if)
 OPENMP_TARGET_PARALLEL_CLAUSE(device)
 OPENMP_TARGET_PARALLEL_CLAUSE(map)
@@ -465,9 +483,9 @@
 OPENMP_TARGET_PARALLEL_CLAUSE(proc_bind)
 OPENMP_TARGET_PARALLEL_CLAUSE(shared)
 OPENMP_TARGET_PARALLEL_CLAUSE(reduction)
+OPENMP_TARGET_PARALLEL_CLAUSE(is_device_ptr)
 
 // Clauses allowed for OpenMP directive 'target parallel for'.
-// TODO: add target clauses 'is_device_ptr'
 OPENMP_TARGET_PARALLEL_FOR_CLAUSE(if)
 OPENMP_TARGET_PARALLEL_FOR_CLAUSE(device)
 OPENMP_TARGET_PARALLEL_FOR_CLAUSE(map)
@@ -486,9 +504,9 @@
 OPENMP_TARGET_PARALLEL_FOR_CLAUSE(schedule)
 OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered)
 OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear)
+OPENMP_TARGET_PARALLEL_FOR_CLAUSE(is_device_ptr)
 
 // Clauses allowed for OpenMP directive 'target update'.
-// TODO More clauses for 'target update' directive.
 OPENMP_TARGET_UPDATE_CLAUSE(if)
 OPENMP_TARGET_UPDATE_CLAUSE(device)
 OPENMP_TARGET_UPDATE_CLAUSE(to)
@@ -497,7 +515,6 @@
 OPENMP_TARGET_UPDATE_CLAUSE(depend)
 
 // Clauses allowed for OpenMP directive 'teams'.
-// TODO More clauses for 'teams' directive.
 OPENMP_TEAMS_CLAUSE(default)
 OPENMP_TEAMS_CLAUSE(private)
 OPENMP_TEAMS_CLAUSE(firstprivate)
@@ -507,7 +524,6 @@
 OPENMP_TEAMS_CLAUSE(thread_limit)
 
 // Clauses allowed for OpenMP directive 'ordered'.
-// TODO More clauses for 'ordered' directive.
 OPENMP_ORDERED_CLAUSE(threads)
 OPENMP_ORDERED_CLAUSE(simd)
 OPENMP_ORDERED_CLAUSE(depend)
@@ -617,7 +633,6 @@
 OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction)
 
 // Clauses allowed for OpenMP directive 'target parallel for simd'.
-// TODO: add target clauses 'is_device_ptr'
 OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if)
 OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(device)
 OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(map)
@@ -639,6 +654,7 @@
 OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen)
 OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
 OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned)
+OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr)
 
 // Clauses allowed for OpenMP directive 'target simd'.
 OPENMP_TARGET_SIMD_CLAUSE(if)
@@ -723,6 +739,113 @@
 OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams)
 OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit)
 
+// Clauses allowed for OpenMP directive 'target teams'.
+OPENMP_TARGET_TEAMS_CLAUSE(if)
+OPENMP_TARGET_TEAMS_CLAUSE(device)
+OPENMP_TARGET_TEAMS_CLAUSE(map)
+OPENMP_TARGET_TEAMS_CLAUSE(private)
+OPENMP_TARGET_TEAMS_CLAUSE(nowait)
+OPENMP_TARGET_TEAMS_CLAUSE(depend)
+OPENMP_TARGET_TEAMS_CLAUSE(defaultmap)
+OPENMP_TARGET_TEAMS_CLAUSE(firstprivate)
+OPENMP_TARGET_TEAMS_CLAUSE(is_device_ptr)
+OPENMP_TARGET_TEAMS_CLAUSE(default)
+OPENMP_TARGET_TEAMS_CLAUSE(shared)
+OPENMP_TARGET_TEAMS_CLAUSE(reduction)
+OPENMP_TARGET_TEAMS_CLAUSE(num_teams)
+OPENMP_TARGET_TEAMS_CLAUSE(thread_limit)
+
+// Clauses allowed for OpenMP directive 'target teams distribute'.
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(if)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(device)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(map)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(private)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(nowait)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(depend)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(defaultmap)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(firstprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(is_device_ptr)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(default)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(shared)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(reduction)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(num_teams)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(thread_limit)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(lastprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(collapse)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule)
+
+// Clauses allowed for OpenMP directive 'target teams distribute parallel for'.
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(device)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(map)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(nowait)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(depend)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(defaultmap)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(is_device_ptr)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(linear)
+
+// Clauses allowed for OpenMP directive
+// 'target teams distribute parallel for simd'.
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(device)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(map)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nowait)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(depend)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(defaultmap)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
+
+// Clauses allowed for OpenMP directive 'target teams distribute simd'.
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(device)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(map)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nowait)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(depend)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(defaultmap)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(is_device_ptr)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen)
+
 #undef OPENMP_TASKLOOP_SIMD_CLAUSE
 #undef OPENMP_TASKLOOP_CLAUSE
 #undef OPENMP_LINEAR_KIND
@@ -770,3 +893,8 @@
 #undef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE
 #undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
 #undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
+#undef OPENMP_TARGET_TEAMS_CLAUSE
+#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE
+#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
+#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
+#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
index 105a156..e003331 100644
--- a/include/clang/Basic/OpenMPKinds.h
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -179,10 +179,18 @@
 /// otherwise - false.
 bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind);
 
-/// \brief Checks if the specified directive is a teams-kind directive.
+/// Checks if the specified composite/combined directive constitutes a teams
+/// directive in the outermost nest.  For example
+/// 'omp teams distribute' or 'omp teams distribute parallel for'.
 /// \param DKind Specified directive.
-/// \return true - the directive is a teams-like directive like 'omp teams',
-/// otherwise - false.
+/// \return true - the directive has teams on the outermost nest, otherwise -
+/// false.
+bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind);
+
+/// Checks if the specified directive is a teams-kind directive.  For example,
+/// 'omp teams distribute' or 'omp target teams'.
+/// \param DKind Specified directive.
+/// \return true - the directive is a teams-like directive, otherwise - false.
 bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind);
 
 /// \brief Checks if the specified directive is a simd directive.
@@ -226,6 +234,11 @@
 /// directives that need loop bound sharing across loops outlined in nested
 /// functions
 bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind);
+
+/// Return the captured regions of an OpenMP directive.
+void getOpenMPCaptureRegions(
+    llvm::SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
+    OpenMPDirectiveKind DKind);
 }
 
 #endif
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index c81273e..c574045 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -64,6 +64,11 @@
 SANITIZER("integer-divide-by-zero", IntegerDivideByZero)
 SANITIZER("nonnull-attribute", NonnullAttribute)
 SANITIZER("null", Null)
+SANITIZER("nullability-arg", NullabilityArg)
+SANITIZER("nullability-assign", NullabilityAssign)
+SANITIZER("nullability-return", NullabilityReturn)
+SANITIZER_GROUP("nullability", Nullability,
+                NullabilityArg | NullabilityAssign | NullabilityReturn)
 SANITIZER("object-size", ObjectSize)
 SANITIZER("return", Return)
 SANITIZER("returns-nonnull-attribute", ReturnsNonnullAttribute)
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 369a36f..33952f8 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -82,11 +82,12 @@
   /// \brief Structure that packs information about the type specifiers that
   /// were written in a particular type specifier sequence.
   struct WrittenBuiltinSpecs {
-    /*DeclSpec::TST*/ unsigned Type  : 5;
+    static_assert(TST_error < 1 << 6, "Type bitfield not wide enough for TST");
+    /*DeclSpec::TST*/ unsigned Type  : 6;
     /*DeclSpec::TSS*/ unsigned Sign  : 2;
     /*DeclSpec::TSW*/ unsigned Width : 2;
     unsigned ModeAttr : 1;
-  };  
+  };
 
   /// \brief A C++ access specifier (public, private, protected), plus the
   /// special value "none" which means different things in different contexts.
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index a7916ef..0d21845 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -43,7 +43,7 @@
 def ObjCForCollectionStmt : Stmt;
 def ObjCAutoreleasePoolStmt : Stmt;
 
-// C++ statments
+// C++ statements
 def CXXCatchStmt : Stmt;
 def CXXTryStmt : Stmt;
 def CXXForRangeStmt : Stmt;
@@ -85,6 +85,8 @@
 def DesignatedInitUpdateExpr : DStmt<Expr>;
 def ImplicitValueInitExpr : DStmt<Expr>;
 def NoInitExpr : DStmt<Expr>;
+def ArrayInitLoopExpr : DStmt<Expr>;
+def ArrayInitIndexExpr : DStmt<Expr>;
 def ParenListExpr : DStmt<Expr>;
 def VAArgExpr : DStmt<Expr>;
 def GenericSelectionExpr : DStmt<Expr>;
@@ -148,6 +150,7 @@
 // C++ Coroutines TS expressions
 def CoroutineSuspendExpr : DStmt<Expr, 1>;
 def CoawaitExpr : DStmt<CoroutineSuspendExpr>;
+def DependentCoawaitExpr : DStmt<Expr>;
 def CoyieldExpr : DStmt<CoroutineSuspendExpr>;
 
 // Obj-C Expressions.
@@ -238,3 +241,8 @@
 def OMPTeamsDistributeSimdDirective : DStmt<OMPLoopDirective>;
 def OMPTeamsDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
 def OMPTeamsDistributeParallelForDirective : DStmt<OMPLoopDirective>;
+def OMPTargetTeamsDirective : DStmt<OMPExecutableDirective>;
+def OMPTargetTeamsDistributeDirective : DStmt<OMPLoopDirective>;
+def OMPTargetTeamsDistributeParallelForDirective : DStmt<OMPLoopDirective>;
+def OMPTargetTeamsDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
+def OMPTargetTeamsDistributeSimdDirective : DStmt<OMPLoopDirective>;
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index b6b9aea..46db895 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -42,6 +42,7 @@
 class LangOptions;
 class CodeGenOptions;
 class MacroBuilder;
+class QualType;
 class SourceLocation;
 class SourceManager;
 
@@ -300,6 +301,12 @@
     return PointerWidth;
   }
 
+  /// \brief Get integer value for null pointer.
+  /// \param AddrSpace address space of pointee in source language.
+  virtual uint64_t getNullPointerValue(unsigned AddrSpace) const {
+    return 0;
+  }
+
   /// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits.
   unsigned getBoolWidth() const { return BoolWidth; }
 
@@ -598,8 +605,16 @@
 
   /// \brief Returns the "normalized" GCC register name.
   ///
-  /// For example, on x86 it will return "ax" when "eax" is passed in.
-  StringRef getNormalizedGCCRegisterName(StringRef Name) const;
+  /// ReturnCannonical true will return the register name without any additions
+  /// such as "{}" or "%" in it's canonical form, for example:
+  /// ReturnCanonical = true and Name = "rax", will return "ax".
+  StringRef getNormalizedGCCRegisterName(StringRef Name,
+                                         bool ReturnCanonical = false) const;
+ 
+  virtual StringRef getConstraintRegister(const StringRef &Constraint,
+                                          const StringRef &Expression) const {
+    return "";
+  }
 
   struct ConstraintInfo {
     enum {
@@ -998,7 +1013,7 @@
   /// \brief Set supported OpenCL extensions as written on command line
   virtual void setOpenCLExtensionOpts() {
     for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
-      getTargetOpts().SupportedOpenCLOptions.set(Ext);
+      getTargetOpts().SupportedOpenCLOptions.support(Ext);
     }
   }
 
@@ -1017,6 +1032,21 @@
     return LangAS::opencl_global;
   }
 
+  /// \returns Target specific vtbl ptr address space.
+  virtual unsigned getVtblPtrAddressSpace() const {
+    return 0;
+  }
+
+  /// \returns If a target requires an address within a target specific address
+  /// space \p AddressSpace to be converted in order to be used, then return the
+  /// corresponding target specific DWARF address space.
+  ///
+  /// \returns Otherwise return None and no conversion will be emitted in the
+  /// DWARF.
+  virtual Optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const {
+    return None;
+  }
+
   /// \brief Check the target is valid after it is fully initialized.
   virtual bool validateTarget(DiagnosticsEngine &Diags) const {
     return true;
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
index 1d52ba3..e52b345 100644
--- a/include/clang/Basic/VirtualFileSystem.h
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -161,7 +161,7 @@
   directory_iterator &increment(std::error_code &EC) {
     assert(Impl && "attempting to increment past end");
     EC = Impl->increment();
-    if (EC || !Impl->CurrentEntry.isStatusKnown())
+    if (!Impl->CurrentEntry.isStatusKnown())
       Impl.reset(); // Normalize the end iterator to Impl == nullptr.
     return *this;
   }
@@ -362,6 +362,16 @@
   std::string RPath;
 };
 
+/// \brief Collect all pairs of <virtual path, real path> entries from the
+/// \p YAMLFilePath. This is used by the module dependency collector to forward
+/// the entries into the reproducer output VFS YAML file.
+void collectVFSFromYAML(
+    std::unique_ptr<llvm::MemoryBuffer> Buffer,
+    llvm::SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath,
+    SmallVectorImpl<YAMLVFSEntry> &CollectedEntries,
+    void *DiagContext = nullptr,
+    IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
+
 class YAMLVFSWriter {
   std::vector<YAMLVFSEntry> Mappings;
   Optional<bool> IsCaseSensitive;
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
index 5605fc6..ad8d679 100644
--- a/include/clang/Basic/arm_neon.td
+++ b/include/clang/Basic/arm_neon.td
@@ -1362,7 +1362,7 @@
 def SCALAR_QSHL: SInst<"vqshl", "sss", "ScSsSiSlSUcSUsSUiSUl">;
 // Scalar Saturating Rounding Shift Left
 def SCALAR_QRSHL: SInst<"vqrshl", "sss", "ScSsSiSlSUcSUsSUiSUl">;
-// Scalar Shift Rouding Left
+// Scalar Shift Rounding Left
 def SCALAR_RSHL: SInst<"vrshl", "sss", "SlSUl">;
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
index 01721d3..bb105cb 100644
--- a/include/clang/CodeGen/BackendUtil.h
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -15,12 +15,15 @@
 #include <memory>
 
 namespace llvm {
+  class BitcodeModule;
+  template <typename T> class Expected;
   class Module;
   class MemoryBufferRef;
 }
 
 namespace clang {
   class DiagnosticsEngine;
+  class HeaderSearchOptions;
   class CodeGenOptions;
   class TargetOptions;
   class LangOptions;
@@ -34,7 +37,8 @@
     Backend_EmitObj        ///< Emit native object files
   };
 
-  void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts,
+  void EmitBackendOutput(DiagnosticsEngine &Diags, const HeaderSearchOptions &,
+                         const CodeGenOptions &CGOpts,
                          const TargetOptions &TOpts, const LangOptions &LOpts,
                          const llvm::DataLayout &TDesc, llvm::Module *M,
                          BackendAction Action,
@@ -42,6 +46,9 @@
 
   void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
                     llvm::MemoryBufferRef Buf);
+
+  llvm::Expected<llvm::BitcodeModule>
+  FindThinLTOModule(llvm::MemoryBufferRef MBRef);
 }
 
 #endif
diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
index cc38e24..5a18a9d 100644
--- a/include/clang/CodeGen/CodeGenAction.h
+++ b/include/clang/CodeGen/CodeGenAction.h
@@ -23,14 +23,36 @@
 
 class CodeGenAction : public ASTFrontendAction {
 private:
+  // Let BackendConsumer access LinkModule.
+  friend class BackendConsumer;
+
+  /// Info about module to link into a module we're generating.
+  struct LinkModule {
+    /// The module to link in.
+    std::unique_ptr<llvm::Module> Module;
+
+    /// If true, we set attributes on Module's functions according to our
+    /// CodeGenOptions and LangOptions, as though we were generating the
+    /// function ourselves.
+    bool PropagateAttrs;
+
+    /// If true, we use LLVM module internalizer.
+    bool Internalize;
+
+    /// Bitwise combination of llvm::LinkerFlags used when we link the module.
+    unsigned LinkFlags;
+  };
+
   unsigned Act;
   std::unique_ptr<llvm::Module> TheModule;
-  // Vector of {Linker::Flags, Module*} pairs to specify bitcode
-  // modules to link in using corresponding linker flags.
-  SmallVector<std::pair<unsigned, llvm::Module *>, 4> LinkModules;
+
+  /// Bitcode modules to link in to our module.
+  SmallVector<LinkModule, 4> LinkModules;
   llvm::LLVMContext *VMContext;
   bool OwnsVMContext;
 
+  std::unique_ptr<llvm::Module> loadModule(llvm::MemoryBufferRef MBRef);
+
 protected:
   /// Create a new code generation action.  If the optional \p _VMContext
   /// parameter is supplied, the action uses it without taking ownership,
@@ -49,13 +71,6 @@
 public:
   ~CodeGenAction() override;
 
-  /// setLinkModule - Set the link module to be used by this action.  If a link
-  /// module is not provided, and CodeGenOptions::LinkBitcodeFile is non-empty,
-  /// the action will load it from the specified file.
-  void addLinkModule(llvm::Module *Mod, unsigned LinkFlags) {
-    LinkModules.push_back(std::make_pair(LinkFlags, Mod));
-  }
-
   /// Take the generated LLVM module, for use after the action has been run.
   /// The result may be null on failure.
   std::unique_ptr<llvm::Module> takeModule();
diff --git a/include/clang/CodeGen/ConstantInitBuilder.h b/include/clang/CodeGen/ConstantInitBuilder.h
new file mode 100644
index 0000000..113d86d
--- /dev/null
+++ b/include/clang/CodeGen/ConstantInitBuilder.h
@@ -0,0 +1,561 @@
+//===- ConstantInitBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class provides a convenient interface for building complex
+// global initializers of the sort that are frequently required for
+// language ABIs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
+#define LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalValue.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/CodeGen/ConstantInitFuture.h"
+
+#include <vector>
+
+namespace clang {
+namespace CodeGen {
+
+class CodeGenModule;
+
+/// A convenience builder class for complex constant initializers,
+/// especially for anonymous global structures used by various language
+/// runtimes.
+///
+/// The basic usage pattern is expected to be something like:
+///    ConstantInitBuilder builder(CGM);
+///    auto toplevel = builder.beginStruct();
+///    toplevel.addInt(CGM.SizeTy, widgets.size());
+///    auto widgetArray = builder.beginArray();
+///    for (auto &widget : widgets) {
+///      auto widgetDesc = widgetArray.beginStruct();
+///      widgetDesc.addInt(CGM.SizeTy, widget.getPower());
+///      widgetDesc.add(CGM.GetAddrOfConstantString(widget.getName()));
+///      widgetDesc.add(CGM.GetAddrOfGlobal(widget.getInitializerDecl()));
+///      widgetDesc.finishAndAddTo(widgetArray);
+///    }
+///    widgetArray.finishAndAddTo(toplevel);
+///    auto global = toplevel.finishAndCreateGlobal("WIDGET_LIST", Align,
+///                                                 /*constant*/ true);
+class ConstantInitBuilderBase {
+  struct SelfReference {
+    llvm::GlobalVariable *Dummy;
+    llvm::SmallVector<llvm::Constant*, 4> Indices;
+
+    SelfReference(llvm::GlobalVariable *dummy) : Dummy(dummy) {}
+  };
+  CodeGenModule &CGM;
+  llvm::SmallVector<llvm::Constant*, 16> Buffer;
+  std::vector<SelfReference> SelfReferences;
+  bool Frozen = false;
+
+  friend class ConstantInitFuture;
+  friend class ConstantAggregateBuilderBase;
+  template <class, class>
+  friend class ConstantAggregateBuilderTemplateBase;
+
+protected:
+  explicit ConstantInitBuilderBase(CodeGenModule &CGM) : CGM(CGM) {}
+
+  ~ConstantInitBuilderBase() {
+    assert(Buffer.empty() && "didn't claim all values out of buffer");
+    assert(SelfReferences.empty() && "didn't apply all self-references");
+  }
+
+private:
+  llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,
+                                     const llvm::Twine &name,
+                                     CharUnits alignment,
+                                     bool constant = false,
+                                     llvm::GlobalValue::LinkageTypes linkage
+                                       = llvm::GlobalValue::InternalLinkage,
+                                     unsigned addressSpace = 0);
+
+  ConstantInitFuture createFuture(llvm::Constant *initializer);
+
+  void setGlobalInitializer(llvm::GlobalVariable *GV,
+                            llvm::Constant *initializer);
+
+  void resolveSelfReferences(llvm::GlobalVariable *GV);
+
+  void abandon(size_t newEnd);
+};
+
+/// A concrete base class for struct and array aggregate
+/// initializer builders.
+class ConstantAggregateBuilderBase {
+protected:
+  ConstantInitBuilderBase &Builder;
+  ConstantAggregateBuilderBase *Parent;
+  size_t Begin;
+  mutable size_t CachedOffsetEnd = 0;
+  bool Finished = false;
+  bool Frozen = false;
+  bool Packed = false;
+  mutable CharUnits CachedOffsetFromGlobal;
+
+  llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() {
+    return Builder.Buffer;
+  }
+
+  const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const {
+    return Builder.Buffer;
+  }
+
+  ConstantAggregateBuilderBase(ConstantInitBuilderBase &builder,
+                               ConstantAggregateBuilderBase *parent)
+      : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {
+    if (parent) {
+      assert(!parent->Frozen && "parent already has child builder active");
+      parent->Frozen = true;
+    } else {
+      assert(!builder.Frozen && "builder already has child builder active");
+      builder.Frozen = true;
+    }
+  }
+
+  ~ConstantAggregateBuilderBase() {
+    assert(Finished && "didn't finish aggregate builder");
+  }
+
+  void markFinished() {
+    assert(!Frozen && "child builder still active");
+    assert(!Finished && "builder already finished");
+    Finished = true;
+    if (Parent) {
+      assert(Parent->Frozen &&
+             "parent not frozen while child builder active");
+      Parent->Frozen = false;
+    } else {
+      assert(Builder.Frozen &&
+             "builder not frozen while child builder active");
+      Builder.Frozen = false;
+    }
+  }
+
+public:
+  // Not copyable.
+  ConstantAggregateBuilderBase(const ConstantAggregateBuilderBase &) = delete;
+  ConstantAggregateBuilderBase &operator=(const ConstantAggregateBuilderBase &)
+    = delete;
+
+  // Movable, mostly to allow returning.  But we have to write this out
+  // properly to satisfy the assert in the destructor.
+  ConstantAggregateBuilderBase(ConstantAggregateBuilderBase &&other)
+    : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),
+      CachedOffsetEnd(other.CachedOffsetEnd),
+      Finished(other.Finished), Frozen(other.Frozen), Packed(other.Packed),
+      CachedOffsetFromGlobal(other.CachedOffsetFromGlobal) {
+    other.Finished = true;
+  }
+  ConstantAggregateBuilderBase &operator=(ConstantAggregateBuilderBase &&other)
+    = delete;
+
+  /// Return the number of elements that have been added to
+  /// this struct or array.
+  size_t size() const {
+    assert(!this->Finished && "cannot query after finishing builder");
+    assert(!this->Frozen && "cannot query while sub-builder is active");
+    assert(this->Begin <= this->getBuffer().size());
+    return this->getBuffer().size() - this->Begin;
+  }
+
+  /// Return true if no elements have yet been added to this struct or array.
+  bool empty() const {
+    return size() == 0;
+  }
+
+  /// Abandon this builder completely.
+  void abandon() {
+    markFinished();
+    Builder.abandon(Begin);
+  }
+
+  /// Add a new value to this initializer.
+  void add(llvm::Constant *value) {
+    assert(value && "adding null value to constant initializer");
+    assert(!Finished && "cannot add more values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    Builder.Buffer.push_back(value);
+  }
+
+  /// Add an integer value of type size_t.
+  void addSize(CharUnits size);
+
+  /// Add an integer value of a specific type.
+  void addInt(llvm::IntegerType *intTy, uint64_t value,
+              bool isSigned = false) {
+    add(llvm::ConstantInt::get(intTy, value, isSigned));
+  }
+
+  /// Add a null pointer of a specific type.
+  void addNullPointer(llvm::PointerType *ptrTy) {
+    add(llvm::ConstantPointerNull::get(ptrTy));
+  }
+
+  /// Add a bitcast of a value to a specific type.
+  void addBitCast(llvm::Constant *value, llvm::Type *type) {
+    add(llvm::ConstantExpr::getBitCast(value, type));
+  }
+
+  /// Add a bunch of new values to this initializer.
+  void addAll(llvm::ArrayRef<llvm::Constant *> values) {
+    assert(!Finished && "cannot add more values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    Builder.Buffer.append(values.begin(), values.end());
+  }
+
+  /// Add a relative offset to the given target address, i.e. the
+  /// static difference between the target address and the address
+  /// of the relative offset.  The target must be known to be defined
+  /// in the current linkage unit.  The offset will have the given
+  /// integer type, which must be no wider than intptr_t.  Some
+  /// targets may not fully support this operation.
+  void addRelativeOffset(llvm::IntegerType *type, llvm::Constant *target) {
+    add(getRelativeOffset(type, target));
+  }
+
+  /// Add a relative offset to the target address, plus a small
+  /// constant offset.  This is primarily useful when the relative
+  /// offset is known to be a multiple of (say) four and therefore
+  /// the tag can be used to express an extra two bits of information.
+  void addTaggedRelativeOffset(llvm::IntegerType *type,
+                               llvm::Constant *address,
+                               unsigned tag) {
+    llvm::Constant *offset = getRelativeOffset(type, address);
+    if (tag) {
+      offset = llvm::ConstantExpr::getAdd(offset,
+                                          llvm::ConstantInt::get(type, tag));
+    }
+    add(offset);
+  }
+
+  /// Return the offset from the start of the initializer to the
+  /// next position, assuming no padding is required prior to it.
+  ///
+  /// This operation will not succeed if any unsized placeholders are
+  /// currently in place in the initializer.
+  CharUnits getNextOffsetFromGlobal() const {
+    assert(!Finished && "cannot add more values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    return getOffsetFromGlobalTo(Builder.Buffer.size());
+  }
+
+  /// An opaque class to hold the abstract position of a placeholder.
+  class PlaceholderPosition {
+    size_t Index;
+    friend class ConstantAggregateBuilderBase;
+    PlaceholderPosition(size_t index) : Index(index) {}
+  };
+
+  /// Add a placeholder value to the structure.  The returned position
+  /// can be used to set the value later; it will not be invalidated by
+  /// any intermediate operations except (1) filling the same position or
+  /// (2) finishing the entire builder.
+  ///
+  /// This is useful for emitting certain kinds of structure which
+  /// contain some sort of summary field, generaly a count, before any
+  /// of the data.  By emitting a placeholder first, the structure can
+  /// be emitted eagerly.
+  PlaceholderPosition addPlaceholder() {
+    assert(!Finished && "cannot add more values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    Builder.Buffer.push_back(nullptr);
+    return Builder.Buffer.size() - 1;
+  }
+
+  /// Add a placeholder, giving the expected type that will be filled in.
+  PlaceholderPosition addPlaceholderWithSize(llvm::Type *expectedType);
+
+  /// Fill a previously-added placeholder.
+  void fillPlaceholderWithInt(PlaceholderPosition position,
+                              llvm::IntegerType *type, uint64_t value,
+                              bool isSigned = false) {
+    fillPlaceholder(position, llvm::ConstantInt::get(type, value, isSigned));
+  }
+
+  /// Fill a previously-added placeholder.
+  void fillPlaceholder(PlaceholderPosition position, llvm::Constant *value) {
+    assert(!Finished && "cannot change values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    llvm::Constant *&slot = Builder.Buffer[position.Index];
+    assert(slot == nullptr && "placeholder already filled");
+    slot = value;
+  }
+
+  /// Produce an address which will eventually point to the the next
+  /// position to be filled.  This is computed with an indexed
+  /// getelementptr rather than by computing offsets.
+  ///
+  /// The returned pointer will have type T*, where T is the given
+  /// position.
+  llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type);
+
+  llvm::ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
+                           llvm::SmallVectorImpl<llvm::Constant*> &indices) {
+    getGEPIndicesTo(indices, Builder.Buffer.size());
+    return indices;
+  }
+
+protected:
+  llvm::Constant *finishArray(llvm::Type *eltTy);
+  llvm::Constant *finishStruct(llvm::StructType *structTy);
+
+private:
+  void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
+                       size_t position) const;
+
+  llvm::Constant *getRelativeOffset(llvm::IntegerType *offsetType,
+                                    llvm::Constant *target);
+
+  CharUnits getOffsetFromGlobalTo(size_t index) const;
+};
+
+template <class Impl, class Traits>
+class ConstantAggregateBuilderTemplateBase
+    : public Traits::AggregateBuilderBase {
+  using super = typename Traits::AggregateBuilderBase;
+public:
+  using InitBuilder = typename Traits::InitBuilder;
+  using ArrayBuilder = typename Traits::ArrayBuilder;
+  using StructBuilder = typename Traits::StructBuilder;
+  using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
+
+protected:
+  ConstantAggregateBuilderTemplateBase(InitBuilder &builder,
+                                       AggregateBuilderBase *parent)
+    : super(builder, parent) {}
+
+  Impl &asImpl() { return *static_cast<Impl*>(this); }
+
+public:
+  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
+    return ArrayBuilder(static_cast<InitBuilder&>(this->Builder), this, eltTy);
+  }
+
+  StructBuilder beginStruct(llvm::StructType *ty = nullptr) {
+    return StructBuilder(static_cast<InitBuilder&>(this->Builder), this, ty);
+  }
+
+  /// Given that this builder was created by beginning an array or struct
+  /// component on the given parent builder, finish the array/struct
+  /// component and add it to the parent.
+  ///
+  /// It is an intentional choice that the parent is passed in explicitly
+  /// despite it being redundant with information already kept in the
+  /// builder.  This aids in readability by making it easier to find the
+  /// places that add components to a builder, as well as "bookending"
+  /// the sub-builder more explicitly.
+  void finishAndAddTo(AggregateBuilderBase &parent) {
+    assert(this->Parent == &parent && "adding to non-parent builder");
+    parent.add(asImpl().finishImpl());
+  }
+
+  /// Given that this builder was created by beginning an array or struct
+  /// directly on a ConstantInitBuilder, finish the array/struct and
+  /// create a global variable with it as the initializer.
+  template <class... As>
+  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
+    assert(!this->Parent && "finishing non-root builder");
+    return this->Builder.createGlobal(asImpl().finishImpl(),
+                                      std::forward<As>(args)...);
+  }
+
+  /// Given that this builder was created by beginning an array or struct
+  /// directly on a ConstantInitBuilder, finish the array/struct and
+  /// set it as the initializer of the given global variable.
+  void finishAndSetAsInitializer(llvm::GlobalVariable *global) {
+    assert(!this->Parent && "finishing non-root builder");
+    return this->Builder.setGlobalInitializer(global, asImpl().finishImpl());
+  }
+
+  /// Given that this builder was created by beginning an array or struct
+  /// directly on a ConstantInitBuilder, finish the array/struct and
+  /// return a future which can be used to install the initializer in
+  /// a global later.
+  ///
+  /// This is useful for allowing a finished initializer to passed to
+  /// an API which will build the global.  However, the "future" preserves
+  /// a dependency on the original builder; it is an error to pass it aside.
+  ConstantInitFuture finishAndCreateFuture() {
+    assert(!this->Parent && "finishing non-root builder");
+    return this->Builder.createFuture(asImpl().finishImpl());
+  }
+};
+
+template <class Traits>
+class ConstantArrayBuilderTemplateBase
+  : public ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder,
+                                                Traits> {
+  using super =
+    ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder, Traits>;
+
+public:
+  using InitBuilder = typename Traits::InitBuilder;
+  using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
+
+private:
+  llvm::Type *EltTy;
+
+  template <class, class>
+  friend class ConstantAggregateBuilderTemplateBase;
+
+protected:
+  ConstantArrayBuilderTemplateBase(InitBuilder &builder,
+                                   AggregateBuilderBase *parent,
+                                   llvm::Type *eltTy)
+    : super(builder, parent), EltTy(eltTy) {}
+
+private:
+  /// Form an array constant from the values that have been added to this
+  /// builder.
+  llvm::Constant *finishImpl() {
+    return AggregateBuilderBase::finishArray(EltTy);
+  }
+};
+
+/// A template class designed to allow other frontends to
+/// easily customize the builder classes used by ConstantInitBuilder,
+/// and thus to extend the API to work with the abstractions they
+/// prefer.  This would probably not be necessary if C++ just
+/// supported extension methods.
+template <class Traits>
+class ConstantStructBuilderTemplateBase
+  : public ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,
+                                                Traits> {
+  using super =
+    ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,Traits>;
+
+public:
+  using InitBuilder = typename Traits::InitBuilder;
+  using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
+
+private:
+  llvm::StructType *StructTy;
+
+  template <class, class>
+  friend class ConstantAggregateBuilderTemplateBase;
+
+protected:
+  ConstantStructBuilderTemplateBase(InitBuilder &builder,
+                                    AggregateBuilderBase *parent,
+                                    llvm::StructType *structTy)
+    : super(builder, parent), StructTy(structTy) {
+    if (structTy) this->Packed = structTy->isPacked();
+  }
+
+public:
+  void setPacked(bool packed) {
+    this->Packed = packed;
+  }
+
+  /// Use the given type for the struct if its element count is correct.
+  /// Don't add more elements after calling this.
+  void suggestType(llvm::StructType *structTy) {
+    if (this->size() == structTy->getNumElements()) {
+      StructTy = structTy;
+    }
+  }
+
+private:
+  /// Form an array constant from the values that have been added to this
+  /// builder.
+  llvm::Constant *finishImpl() {
+    return AggregateBuilderBase::finishStruct(StructTy);
+  }
+};
+
+/// A template class designed to allow other frontends to
+/// easily customize the builder classes used by ConstantInitBuilder,
+/// and thus to extend the API to work with the abstractions they
+/// prefer.  This would probably not be necessary if C++ just
+/// supported extension methods.
+template <class Traits>
+class ConstantInitBuilderTemplateBase : public ConstantInitBuilderBase {
+protected:
+  ConstantInitBuilderTemplateBase(CodeGenModule &CGM)
+    : ConstantInitBuilderBase(CGM) {}
+
+public:
+  using InitBuilder = typename Traits::InitBuilder;
+  using ArrayBuilder = typename Traits::ArrayBuilder;
+  using StructBuilder = typename Traits::StructBuilder;
+
+  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
+    return ArrayBuilder(static_cast<InitBuilder&>(*this), nullptr, eltTy);
+  }
+
+  StructBuilder beginStruct(llvm::StructType *structTy = nullptr) {
+    return StructBuilder(static_cast<InitBuilder&>(*this), nullptr, structTy);
+  }
+};
+
+class ConstantInitBuilder;
+class ConstantStructBuilder;
+class ConstantArrayBuilder;
+
+struct ConstantInitBuilderTraits {
+  using InitBuilder = ConstantInitBuilder;
+  using AggregateBuilderBase = ConstantAggregateBuilderBase;
+  using ArrayBuilder = ConstantArrayBuilder;
+  using StructBuilder = ConstantStructBuilder;
+};
+
+/// The standard implementation of ConstantInitBuilder used in Clang.
+class ConstantInitBuilder
+    : public ConstantInitBuilderTemplateBase<ConstantInitBuilderTraits> {
+public:
+  explicit ConstantInitBuilder(CodeGenModule &CGM) :
+    ConstantInitBuilderTemplateBase(CGM) {}
+};
+
+/// A helper class of ConstantInitBuilder, used for building constant
+/// array initializers.
+class ConstantArrayBuilder
+    : public ConstantArrayBuilderTemplateBase<ConstantInitBuilderTraits> {
+  template <class Traits>
+  friend class ConstantInitBuilderTemplateBase;
+
+  // The use of explicit qualification is a GCC workaround.
+  template <class Impl, class Traits>
+  friend class CodeGen::ConstantAggregateBuilderTemplateBase;
+
+  ConstantArrayBuilder(ConstantInitBuilder &builder,
+                       ConstantAggregateBuilderBase *parent,
+                       llvm::Type *eltTy)
+    : ConstantArrayBuilderTemplateBase(builder, parent, eltTy) {}
+};
+
+/// A helper class of ConstantInitBuilder, used for building constant
+/// struct initializers.
+class ConstantStructBuilder
+    : public ConstantStructBuilderTemplateBase<ConstantInitBuilderTraits> {
+  template <class Traits>
+  friend class ConstantInitBuilderTemplateBase;
+
+  // The use of explicit qualification is a GCC workaround.
+  template <class Impl, class Traits>
+  friend class CodeGen::ConstantAggregateBuilderTemplateBase;
+
+  ConstantStructBuilder(ConstantInitBuilder &builder,
+                        ConstantAggregateBuilderBase *parent,
+                        llvm::StructType *structTy)
+    : ConstantStructBuilderTemplateBase(builder, parent, structTy) {}
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/ConstantInitFuture.h b/include/clang/CodeGen/ConstantInitFuture.h
new file mode 100644
index 0000000..ef1a5d2
--- /dev/null
+++ b/include/clang/CodeGen/ConstantInitFuture.h
@@ -0,0 +1,111 @@
+//===- ConstantInitFuture.h - "Future" constant initializers ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines the ConstantInitFuture class.  This is split out
+// from ConstantInitBuilder.h in order to allow APIs to work with it
+// without having to include that entire header.  This is particularly
+// important because it is often useful to be able to default-construct
+// a future in, say, a default argument.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
+#define LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/IR/Constant.h"
+
+// Forward-declare ConstantInitBuilderBase and give it a
+// PointerLikeTypeTraits specialization so that we can safely use it
+// in a PointerUnion below.
+namespace clang {
+namespace CodeGen {
+class ConstantInitBuilderBase;
+}
+}
+namespace llvm {
+template <>
+class PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> {
+public:
+  using T = ::clang::CodeGen::ConstantInitBuilderBase*;
+
+  static inline void *getAsVoidPointer(T p) { return p; }
+  static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);}
+  enum { NumLowBitsAvailable = 2 };
+};
+}
+
+namespace clang {
+namespace CodeGen {
+
+/// A "future" for a completed constant initializer, which can be passed
+/// around independently of any sub-builders (but not the original parent).
+class ConstantInitFuture {
+  using PairTy = llvm::PointerUnion<ConstantInitBuilderBase*, llvm::Constant*>;
+
+  PairTy Data;
+
+  friend class ConstantInitBuilderBase;
+  explicit ConstantInitFuture(ConstantInitBuilderBase *builder);
+
+public:
+  ConstantInitFuture() {}
+
+  /// A future can be explicitly created from a fixed initializer.
+  explicit ConstantInitFuture(llvm::Constant *initializer) : Data(initializer) {
+    assert(initializer && "creating null future");
+  }
+
+  /// Is this future non-null?
+  explicit operator bool() const { return bool(Data); }
+
+  /// Return the type of the initializer.
+  llvm::Type *getType() const;
+
+  /// Abandon this initializer.
+  void abandon();
+
+  /// Install the initializer into a global variable.  This cannot
+  /// be called multiple times.
+  void installInGlobal(llvm::GlobalVariable *global);
+
+  void *getOpaqueValue() const { return Data.getOpaqueValue(); }
+  static ConstantInitFuture getFromOpaqueValue(void *value) {
+    ConstantInitFuture result;
+    result.Data = PairTy::getFromOpaqueValue(value);
+    return result;
+  }
+  enum {
+    NumLowBitsAvailable =
+      llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable
+  };
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+namespace llvm {
+
+template <>
+class PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> {
+public:
+  using T = ::clang::CodeGen::ConstantInitFuture;
+
+  static inline void *getAsVoidPointer(T future) {
+    return future.getOpaqueValue();
+  }
+  static inline T getFromVoidPointer(void *p) {
+    return T::getFromOpaqueValue(p);
+  }
+  enum { NumLowBitsAvailable = T::NumLowBitsAvailable };
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index 5863834..6f81ea9 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -35,6 +35,7 @@
 
 namespace CodeGen {
   class CodeGenModule;
+  class CGDebugInfo;
 }
 
 /// The primary public interface to the Clang code generator.
@@ -65,6 +66,9 @@
   /// CodeGenerator after releasing its module.
   llvm::Module *ReleaseModule();
 
+  /// Return debug info code generator.
+  CodeGen::CGDebugInfo *getCGDebugInfo();
+
   /// Given a mangled name, return a declaration which mangles that way
   /// which has been added to this code generator via a Handle method.
   ///
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index 9bf9ea5..55f0ca9 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -8,6 +8,9 @@
 /* Bug report URL. */
 #define BUG_REPORT_URL "${BUG_REPORT_URL}"
 
+/* Default linker to use. */
+#define CLANG_DEFAULT_LINKER "${CLANG_DEFAULT_LINKER}"
+
 /* Default C++ stdlib to use. */
 #define CLANG_DEFAULT_CXX_STDLIB "${CLANG_DEFAULT_CXX_STDLIB}"
 
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 5ebe083..acc76f6 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -136,6 +136,8 @@
 let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
 
 def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
+def debug_info_macro : Flag<["-"], "debug-info-macro">,
+  HelpText<"Emit macro debug information">;
 def dwarf_version_EQ : Joined<["-"], "dwarf-version=">;
 def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">;
 def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
@@ -160,13 +162,16 @@
   HelpText<"Disable implicit builtin knowledge of math functions">;
 }
 
-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_llvm_passes : Flag<["-"], "disable-llvm-passes">,
   HelpText<"Use together with -emit-llvm to get pristine LLVM IR from the "
            "frontend by not running any LLVM passes at all">;
+def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
+  Alias<disable_llvm_passes>;
+def disable_lifetimemarkers : Flag<["-"], "disable-lifetime-markers">,
+  HelpText<"Disable lifetime-markers emission even when optimizations are "
+           "enabled">;
 def disable_red_zone : Flag<["-"], "disable-red-zone">,
   HelpText<"Do not emit code that uses the red zone.">;
 def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
@@ -304,6 +309,9 @@
 def flto_visibility_public_std:
     Flag<["-"], "flto-visibility-public-std">,
     HelpText<"Use public LTO visibility for classes in std and stdext namespaces">;
+def flto_unit: Flag<["-"], "flto-unit">,
+    HelpText<"Emit IR to support LTO unit features (CFI, whole program vtable opt)">;
+def fno_lto_unit: Flag<["-"], "fno-lto-unit">;
 
 //===----------------------------------------------------------------------===//
 // Dependency Output Options
@@ -426,6 +434,10 @@
   Flag<["-"], "fmodules-local-submodule-visibility">,
   HelpText<"Enforce name visibility rules across submodules of the same "
            "top-level module.">;
+def fmodule_codegen :
+  Flag<["-"], "fmodules-codegen">,
+  HelpText<"Generate code for uses of this module that assumes an explicit "
+           "object file will be built for the module">;
 def fmodule_format_EQ : Joined<["-"], "fmodule-format=">,
   HelpText<"Select the container format for clang modules and PCH. "
            "Supported options are 'raw' and 'obj'.">;
@@ -463,6 +475,8 @@
   HelpText<"Build ASTs and print the list of declaration node qualified names">;
 def ast_dump : Flag<["-"], "ast-dump">,
   HelpText<"Build ASTs and then debug dump them">;
+def ast_dump_all : Flag<["-"], "ast-dump-all">,
+  HelpText<"Build ASTs and then debug dump them, forcing deserialization">;
 def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">,
   HelpText<"Build ASTs and then debug dump their name lookup tables">;
 def ast_view : Flag<["-"], "ast-view">,
@@ -576,6 +590,8 @@
   HelpText<"File is for a position independent executable">;
 def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
   HelpText<"Disable validation of precompiled headers">;
+def fallow_pch_with_errors : Flag<["-"], "fallow-pch-with-compiler-errors">,
+  HelpText<"Accept a PCH file that was created with compiler errors">;
 def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">,
   HelpText<"Dump declarations that are deserialized from PCH, for testing">;
 def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">,
@@ -655,6 +671,8 @@
   HelpText<"Disable standard system #include directories">;
 def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">,
   HelpText<"Disable the module hash">;
+def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">,
+  HelpText<"Enable hashing the content of a module file">;
 def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">,
   HelpText<"Add directory to the C SYSTEM include search path">;
 def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index cb2745a..9b6ab3a 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-def cl_Group : OptionGroup<"<clang-cl options>">,
+def cl_Group : OptionGroup<"<clang-cl options>">, Flags<[CLOption]>,
   HelpText<"CL.EXE COMPATIBILITY OPTIONS">;
 
 def cl_compile_Group : OptionGroup<"<clang-cl compile-only options>">,
@@ -27,7 +27,7 @@
   Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>;
 
 class CLIgnoredFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
-  Group<cl_ignored_Group>, Flags<[CLOption, DriverOption, HelpHidden]>;
+  Group<cl_ignored_Group>, Flags<[CLOption, DriverOption]>;
 
 class CLJoined<string name> : Option<["/", "-"], name, KIND_JOINED>,
   Group<cl_Group>, Flags<[CLOption, DriverOption]>;
@@ -299,7 +299,7 @@
 def _SLASH_errorReport : CLIgnoredJoined<"errorReport">;
 def _SLASH_FC : CLIgnoredFlag<"FC">;
 def _SLASH_Fd : CLIgnoredJoined<"Fd">;
-def _SLASH_FS : CLIgnoredFlag<"FS">, HelpText<"Force synchronous PDB writes">;
+def _SLASH_FS : CLIgnoredFlag<"FS">;
 def _SLASH_GF : CLIgnoredFlag<"GF">;
 def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
 def _SLASH_nologo : CLIgnoredFlag<"nologo">;
@@ -308,7 +308,8 @@
 def _SLASH_RTC : CLIgnoredJoined<"RTC">;
 def _SLASH_sdl : CLIgnoredFlag<"sdl">;
 def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
-def _SLASH_utf8 : CLIgnoredFlag<"utf-8">;
+def _SLASH_utf8 : CLIgnoredFlag<"utf-8">,
+  HelpText<"Set source and runtime encoding to UTF-8 (default)">;
 def _SLASH_w : CLIgnoredJoined<"w">;
 def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">;
 def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;
diff --git a/include/clang/Driver/ClangOptionDocs.td b/include/clang/Driver/ClangOptionDocs.td
new file mode 100644
index 0000000..97c4469
--- /dev/null
+++ b/include/clang/Driver/ClangOptionDocs.td
@@ -0,0 +1,36 @@
+//==--- ClangOptionDocs.td - Option documentation -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+def GlobalDocumentation {
+  code Intro =[{..
+  -------------------------------------------------------------------
+  NOTE: This file is automatically generated by running clang-tblgen
+  -gen-opt-docs. Do not edit this file by hand!!
+  -------------------------------------------------------------------
+
+=====================================
+Clang command line argument reference
+=====================================
+.. contents::
+   :local:
+
+Introduction
+============
+
+This page lists the command line arguments currently supported by the
+GCC-compatible ``clang`` and ``clang++`` drivers.
+
+}];
+
+  string Program = "clang";
+  list<string> ExcludedFlags = ["HelpHidden", "NoDriverOption",
+                                "CLOption", "Unsupported", "Ignored"];
+}
+
+include "Options.td"
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 0ce461c..e653c7c 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -14,6 +14,7 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Driver/Action.h"
 #include "clang/Driver/Phases.h"
+#include "clang/Driver/ToolChain.h"
 #include "clang/Driver/Types.h"
 #include "clang/Driver/Util.h"
 #include "llvm/ADT/StringMap.h"
@@ -62,7 +63,7 @@
 /// Driver - Encapsulate logic for constructing compilation processes
 /// from a set of gcc-driver-like command line arguments.
 class Driver {
-  llvm::opt::OptTable *Opts;
+  std::unique_ptr<llvm::opt::OptTable> Opts;
 
   DiagnosticsEngine &Diags;
 
@@ -227,7 +228,7 @@
   /// This maps from the string representation of a triple to a ToolChain
   /// created targeting that triple. The driver owns all the ToolChain objects
   /// stored in it, and will clean them up when torn down.
-  mutable llvm::StringMap<ToolChain *> ToolChains;
+  mutable llvm::StringMap<std::unique_ptr<ToolChain>> ToolChains;
 
 private:
   /// TranslateInputArgs - Create a new derived argument list from the input
@@ -264,7 +265,6 @@
   Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
          DiagnosticsEngine &Diags,
          IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
-  ~Driver();
 
   /// @name Accessors
   /// @{
@@ -304,13 +304,8 @@
   bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }
 
   bool embedBitcodeEnabled() const { return BitcodeEmbed != EmbedNone; }
-  bool embedBitcodeInObject() const {
-    // LTO has no object file output so ignore embed bitcode option in LTO.
-    return (BitcodeEmbed == EmbedBitcode) && !isUsingLTO();
-  }
-  bool embedBitcodeMarkerOnly() const {
-    return (BitcodeEmbed == EmbedMarker) && !isUsingLTO();
-  }
+  bool embedBitcodeInObject() const { return (BitcodeEmbed == EmbedBitcode); }
+  bool embedBitcodeMarkerOnly() const { return (BitcodeEmbed == EmbedMarker); }
 
   /// Compute the desired OpenMP runtime from the flags provided.
   OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const;
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
index 2716fa9..57e4452 100644
--- a/include/clang/Driver/Options.h
+++ b/include/clang/Driver/Options.h
@@ -10,6 +10,8 @@
 #ifndef LLVM_CLANG_DRIVER_OPTIONS_H
 #define LLVM_CLANG_DRIVER_OPTIONS_H
 
+#include <memory>
+
 namespace llvm {
 namespace opt {
 class OptTable;
@@ -31,7 +33,8 @@
   CLOption = (1 << 9),
   CC1Option = (1 << 10),
   CC1AsOption = (1 << 11),
-  NoDriverOption = (1 << 12)
+  NoDriverOption = (1 << 12),
+  Ignored = (1 << 13)
 };
 
 enum ID {
@@ -44,7 +47,7 @@
   };
 }
 
-llvm::opt::OptTable *createDriverOptTable();
+std::unique_ptr<llvm::opt::OptTable> createDriverOptTable();
 }
 }
 
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index f67c81a..7952b33 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -33,6 +33,9 @@
 // lines that use it.
 def Unsupported : OptionFlag;
 
+// Ignored - The option is unsupported, and the driver will silently ignore it.
+def Ignored : OptionFlag;
+
 // CoreOption - This is considered a "core" Clang option, available in both
 // clang and clang-cl modes.
 def CoreOption : OptionFlag;
@@ -50,72 +53,150 @@
 // NoDriverOption - This option should not be accepted by the driver.
 def NoDriverOption : OptionFlag;
 
+// A short name to show in documentation. The name will be interpreted as rST.
+class DocName<string name> { string DocName = name; }
+
+// A brief description to show in documentation, interpreted as rST.
+class DocBrief<code descr> { code DocBrief = descr; }
+
+// Indicates that this group should be flattened into its parent when generating
+// documentation.
+class DocFlatten { bit DocFlatten = 1; }
+
+// Indicates that this warning is ignored, but accepted with a warning for
+// GCC compatibility.
+class IgnoredGCCCompat : Flags<[HelpHidden]> {}
+
 /////////
 // Groups
 
+def Action_Group : OptionGroup<"<action group>">, DocName<"Actions">,
+                   DocBrief<[{The action to perform on the input.}]>;
+
 // Meta-group for options which are only used for compilation,
 // and not linking etc.
-def CompileOnly_Group     : OptionGroup<"<CompileOnly group>">;
+def CompileOnly_Group : OptionGroup<"<CompileOnly group>">,
+                        DocName<"Compilation flags">, DocBrief<[{
+Flags controlling the behavior of Clang during compilation. These flags have
+no effect during actions that do not perform compilation.}]>;
 
-def Action_Group          : OptionGroup<"<action group>">;
+def Preprocessor_Group : OptionGroup<"<Preprocessor group>">,
+                         Group<CompileOnly_Group>,
+                         DocName<"Preprocessor flags">, DocBrief<[{
+Flags controlling the behavior of the Clang preprocessor.}]>;
 
-def I_Group               : OptionGroup<"<I group>">, Group<CompileOnly_Group>;
-def M_Group               : OptionGroup<"<M group>">, Group<CompileOnly_Group>;
-def T_Group               : OptionGroup<"<T group>">;
-def O_Group               : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
-def R_Group               : OptionGroup<"<R group>">, Group<CompileOnly_Group>;
-def R_value_Group         : OptionGroup<"<R (with value) group>">, Group<R_Group>;
-def W_Group               : OptionGroup<"<W group>">, Group<CompileOnly_Group>;
-def W_value_Group         : OptionGroup<"<W (with value) group>">, Group<W_Group>;
-def d_Group               : OptionGroup<"<d group>">;
-def f_Group               : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
-def f_clang_Group         : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>;
-def g_Group               : OptionGroup<"<g group>">;
-def gN_Group              : OptionGroup<"<gN group>">, Group<g_Group>;
-def ggdbN_Group           : OptionGroup<"<ggdbN group>">, Group<gN_Group>;
-def gTune_Group           : OptionGroup<"<gTune group>">, Group<g_Group>;
-def g_flags_Group         : OptionGroup<"<g flags group>">;
-def i_Group               : OptionGroup<"<i group>">, Group<CompileOnly_Group>;
-def clang_i_Group         : OptionGroup<"<clang i group>">, Group<i_Group>;
-def m_Group               : OptionGroup<"<m group>">, Group<CompileOnly_Group>;
-def opencl_Group          : OptionGroup<"<opencl group>">, Group<CompileOnly_Group>;
+def IncludePath_Group : OptionGroup<"<I/i group>">, Group<Preprocessor_Group>,
+                        DocName<"Include path management">,
+                        DocBrief<[{
+Flags controlling how ``#include``\s are resolved to files.}]>;
+
+def I_Group : OptionGroup<"<I group>">, Group<IncludePath_Group>, DocFlatten;
+def i_Group : OptionGroup<"<i group>">, Group<IncludePath_Group>, DocFlatten;
+def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>, DocFlatten;
+
+def M_Group : OptionGroup<"<M group>">, Group<Preprocessor_Group>,
+              DocName<"Dependency file generation">, DocBrief<[{
+Flags controlling generation of a dependency file for ``make``-like build
+systems.}]>;
+
+def d_Group : OptionGroup<"<d group>">, Group<Preprocessor_Group>,
+              DocName<"Dumping preprocessor state">, DocBrief<[{
+Flags allowing the state of the preprocessor to be dumped in various ways.}]>;
+
+def Diag_Group : OptionGroup<"<W/R group>">, Group<CompileOnly_Group>,
+                 DocName<"Diagnostic flags">, DocBrief<[{
+Flags controlling which warnings, errors, and remarks Clang will generate.
+See the :doc:`full list of warning and remark flags <DiagnosticsReference>`.}]>;
+
+def R_Group : OptionGroup<"<R group>">, Group<Diag_Group>, DocFlatten;
+def R_value_Group : OptionGroup<"<R (with value) group>">, Group<R_Group>,
+                    DocFlatten;
+def W_Group : OptionGroup<"<W group>">, Group<Diag_Group>, DocFlatten;
+def W_value_Group : OptionGroup<"<W (with value) group>">, Group<W_Group>,
+                    DocFlatten;
+
+def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>,
+              DocName<"Target-independent compilation options">;
+
+def f_clang_Group : OptionGroup<"<f (clang-only) group>">,
+                    Group<CompileOnly_Group>, DocFlatten;
+def pedantic_Group : OptionGroup<"<pedantic group>">, Group<f_Group>,
+                     DocFlatten;
+def opencl_Group : OptionGroup<"<opencl group>">, Group<f_Group>,
+                   DocName<"OpenCL flags">;
+
+def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>,
+              DocName<"Target-dependent compilation options">;
 
 // Feature groups - these take command line options that correspond directly to
 // target specific features and can be translated directly from command line
 // options.
-def m_x86_Features_Group : OptionGroup<"<x86 features group>">,
-                           Group<m_Group>,
-                           Flags<[CoreOption]>;
-def m_hexagon_Features_Group : OptionGroup<"<hexagon features group>">,
-                               Group<m_Group>;
-def m_arm_Features_Group : OptionGroup<"<arm features group>">,
-                           Group<m_Group>;
 def m_aarch64_Features_Group : OptionGroup<"<aarch64 features group>">,
-                               Group<m_Group>;
-def m_ppc_Features_Group : OptionGroup<"<ppc features group>">,
-                           Group<m_Group>;
-def m_wasm_Features_Group : OptionGroup<"<wasm features group>">,
-                            Group<m_Group>;
+                               Group<m_Group>, DocName<"AARCH64">;
 def m_amdgpu_Features_Group : OptionGroup<"<amdgpu features group>">,
-                              Group<m_Group>;
+                              Group<m_Group>, DocName<"AMDGPU">;
+def m_arm_Features_Group : OptionGroup<"<arm features group>">,
+                           Group<m_Group>, DocName<"ARM">;
+def m_hexagon_Features_Group : OptionGroup<"<hexagon features group>">,
+                               Group<m_Group>, DocName<"Hexagon">;
+def m_ppc_Features_Group : OptionGroup<"<ppc features group>">,
+                           Group<m_Group>, DocName<"PowerPC">;
+def m_wasm_Features_Group : OptionGroup<"<wasm features group>">,
+                            Group<m_Group>, DocName<"WebAssembly">;
+def m_x86_Features_Group : OptionGroup<"<x86 features group>">,
+                           Group<m_Group>, Flags<[CoreOption]>, DocName<"X86">;
 
-def m_libc_Group          : OptionGroup<"<m libc group>">, Group<m_Group>;
-def u_Group               : OptionGroup<"<u group>">;
+def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_Group>,
+                   Flags<[HelpHidden]>;
 
-def pedantic_Group        : OptionGroup<"<pedantic group>">,
-  Group<CompileOnly_Group>;
-def reserved_lib_Group   : OptionGroup<"<reserved libs group>">;
+def O_Group : OptionGroup<"<O group>">, Group<CompileOnly_Group>,
+              DocName<"Optimization level">, DocBrief<[{
+Flags controlling how much optimization should be performed.}]>;
+
+def DebugInfo_Group : OptionGroup<"<g group>">, Group<CompileOnly_Group>,
+                      DocName<"Debug information generation">, DocBrief<[{
+Flags controlling how much and what kind of debug information should be
+generated.}]>;
+
+def g_Group : OptionGroup<"<g group>">, Group<DebugInfo_Group>,
+              DocName<"Kind and level of debug information">;
+def gN_Group : OptionGroup<"<gN group>">, Group<g_Group>,
+               DocName<"Debug level">;
+def ggdbN_Group : OptionGroup<"<ggdbN group>">, Group<gN_Group>, DocFlatten;
+def gTune_Group : OptionGroup<"<gTune group>">, Group<g_Group>,
+                  DocName<"Debugger to tune debug information for">;
+def g_flags_Group : OptionGroup<"<g flags group>">, Group<DebugInfo_Group>,
+                    DocName<"Debug information flags">;
+
+def StaticAnalyzer_Group : OptionGroup<"<Static analyzer group>">,
+                           DocName<"Static analyzer flags">, DocBrief<[{
+Flags controlling the behavior of the Clang Static Analyzer.}]>;
+
+// gfortran options that we recognize in the driver and pass along when
+// invoking GCC to compile Fortran code.
+def gfortran_Group : OptionGroup<"<gfortran group>">,
+                     DocName<"Fortran compilation flags">, DocBrief<[{
+Flags that will be passed onto the ``gfortran`` compiler when Clang is given
+a Fortran input.}]>;
+
+def Link_Group : OptionGroup<"<T/e/s/t/u group>">, DocName<"Linker flags">,
+                 DocBrief<[{Flags that are passed on to the linker}]>;
+def T_Group : OptionGroup<"<T group>">, Group<Link_Group>, DocFlatten;
+def u_Group : OptionGroup<"<u group>">, Group<Link_Group>, DocFlatten;
+
+def reserved_lib_Group : OptionGroup<"<reserved libs group>">,
+                         Flags<[Unsupported]>;
 
 // Temporary groups for clang options which we know we don't support,
 // but don't want to verbosely warn the user about.
 def clang_ignored_f_Group : OptionGroup<"<clang ignored f group>">,
-  Group<f_Group>;
+  Group<f_Group>, Flags<[Ignored]>;
 def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
-  Group<m_Group>;
+  Group<m_Group>, Flags<[Ignored]>;
 
 // Group that ignores all gcc optimizations that won't be implemented
 def clang_ignored_gcc_optimization_f_Group : OptionGroup<
-  "<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>;
+  "<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>, Flags<[Ignored]>;
 
 /////////
 // Options
@@ -141,7 +222,7 @@
 
 // Developer Driver Options
 
-def internal_Group : OptionGroup<"<clang internal options>">;
+def internal_Group : OptionGroup<"<clang internal options>">, Flags<[HelpHidden]>;
 def internal_driver_Group : OptionGroup<"<clang driver internal options>">,
   Group<internal_Group>, HelpText<"DRIVER OPTIONS">;
 def internal_debug_Group :
@@ -236,23 +317,34 @@
     HelpText<"Print (but do not run) the commands to run for this compilation">;
 def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>,
     Flags<[DriverOption, CoreOption]>;
-def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>;
-def B : JoinedOrSeparate<["-"], "B">;
-def CC : Flag<["-"], "CC">, Flags<[CC1Option]>;
-def C : Flag<["-"], "C">, Flags<[CC1Option]>;
-def D : JoinedOrSeparate<["-"], "D">, Group<CompileOnly_Group>, Flags<[CC1Option]>;
+def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>, Group<gfortran_Group>;
+def B : JoinedOrSeparate<["-"], "B">, MetaVarName<"<dir>">,
+    HelpText<"Add <dir> to search path for binaries and object files used implicitly">;
+def CC : Flag<["-"], "CC">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
+    HelpText<"Include comments from within macros in preprocessed output">;
+def C : Flag<["-"], "C">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
+    HelpText<"Include comments in preprocessed output">;
+def D : JoinedOrSeparate<["-"], "D">, Group<Preprocessor_Group>,
+    Flags<[CC1Option]>, MetaVarName<"<macro>=<value>">,
+    HelpText<"Define <macro> to <value> (or 1 if <value> omitted)">;
 def E : Flag<["-"], "E">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
-  HelpText<"Only run the preprocessor">;
+    HelpText<"Only run the preprocessor">;
 def F : JoinedOrSeparate<["-"], "F">, Flags<[RenderJoined,CC1Option]>,
     HelpText<"Add directory to framework include search path">;
-def G : JoinedOrSeparate<["-"], "G">, Flags<[DriverOption]>;
-def G_EQ : Joined<["-"], "G=">, Flags<[DriverOption]>;
-def H : Flag<["-"], "H">, Flags<[CC1Option]>,
+def G : JoinedOrSeparate<["-"], "G">, Flags<[DriverOption]>, Group<m_Group>,
+    MetaVarName<"<size>">, HelpText<"Put objects of at most <size> bytes "
+    "into small data section (MIPS / Hexagon)">;
+def G_EQ : Joined<["-"], "G=">, Flags<[DriverOption]>, Group<m_Group>, Alias<G>;
+def H : Flag<["-"], "H">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
     HelpText<"Show header includes and nesting depth">;
-def I_ : Flag<["-"], "I-">, Group<I_Group>;
-def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>, Flags<[CC1Option,CC1AsOption]>,
+def I_ : Flag<["-"], "I-">, Group<I_Group>,
+    HelpText<"Restrict all prior -I flags to double-quoted inclusion and "
+             "remove current directory from include path">;
+def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>,
+    Flags<[CC1Option,CC1AsOption]>, MetaVarName<"<dir>">,
     HelpText<"Add directory to include search path">;
-def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>;
+def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>, Group<Link_Group>,
+    MetaVarName<"<dir>">, HelpText<"Add directory to library search path">;
 def MD : Flag<["-"], "MD">, Group<M_Group>,
     HelpText<"Write a depfile containing user and system headers">;
 def MMD : Flag<["-"], "MMD">, Group<M_Group>,
@@ -276,9 +368,9 @@
     HelpText<"Specify name of main file output in depfile">;
 def MV : Flag<["-"], "MV">, Group<M_Group>, Flags<[CC1Option]>,
     HelpText<"Use NMake/Jom format for the depfile">;
-def Mach : Flag<["-"], "Mach">;
-def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>;
-def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option]>;
+def Mach : Flag<["-"], "Mach">, Group<Link_Group>;
+def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;
+def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;
 def ObjCXX : Flag<["-"], "ObjC++">, Flags<[DriverOption]>,
   HelpText<"Treat source input files as Objective-C++ inputs">;
 def ObjC : Flag<["-"], "ObjC">, Flags<[DriverOption]>,
@@ -286,12 +378,12 @@
 def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option]>;
 def O_flag : Flag<["-"], "O">, Flags<[CC1Option]>, Alias<O>, AliasArgs<["2"]>;
 def Ofast : Joined<["-"], "Ofast">, Group<O_Group>, Flags<[CC1Option]>;
-def P : Flag<["-"], "P">, Flags<[CC1Option]>,
+def P : Flag<["-"], "P">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
   HelpText<"Disable linemarker output in -E mode">;
-def Qn : Flag<["-"], "Qn">;
+def Qn : Flag<["-"], "Qn">, IgnoredGCCCompat;
 def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption, CoreOption]>,
   HelpText<"Don't emit warning for unused driver arguments">;
-def Q : Flag<["-"], "Q">;
+def Q : Flag<["-"], "Q">, IgnoredGCCCompat;
 def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_value_Group>, Flags<[CC1Option]>,
   HelpText<"Report transformations performed by optimization passes whose "
            "name matches the given POSIX regular expression">;
@@ -307,23 +399,28 @@
   MetaVarName<"<remark>">, HelpText<"Enable the specified remark">;
 def S : Flag<["-"], "S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
   HelpText<"Only run preprocess and compilation steps">;
-def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>;
-def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group<T_Group>;
-def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group<T_Group>;
-def T : JoinedOrSeparate<["-"], "T">, Group<T_Group>;
-def U : JoinedOrSeparate<["-"], "U">, Group<CompileOnly_Group>, Flags<[CC1Option]>;
+def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>,
+  MetaVarName<"<addr">, HelpText<"Set starting address of BSS to <addr>">;
+def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group<T_Group>,
+  MetaVarName<"<addr">, HelpText<"Set starting address of BSS to <addr>">;
+def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group<T_Group>,
+  MetaVarName<"<addr">, HelpText<"Set starting address of BSS to <addr>">;
+def T : JoinedOrSeparate<["-"], "T">, Group<T_Group>,
+  MetaVarName<"<script>">, HelpText<"Specify <script> as linker script">;
+def U : JoinedOrSeparate<["-"], "U">, Group<Preprocessor_Group>,
+  Flags<[CC1Option]>, MetaVarName<"<macro>">, HelpText<"Undefine macro <macro>">;
 def V : JoinedOrSeparate<["-"], "V">, Flags<[DriverOption, Unsupported]>;
 def Wa_COMMA : CommaJoined<["-"], "Wa,">,
   HelpText<"Pass the comma separated arguments in <arg> to the assembler">,
   MetaVarName<"<arg>">;
-def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[CC1Option]>;
-def WCL4 : Flag<["-"], "WCL4">, Group<W_Group>, Flags<[CC1Option]>;
-def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>, Flags<[CC1Option]>;
+def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
+def WCL4 : Flag<["-"], "WCL4">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
+def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>, Flags<[CC1Option]>,
+  HelpText<"Enable warnings for deprecated constructs and define __DEPRECATED">;
 def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group<W_Group>, Flags<[CC1Option]>;
-def Wextra : Flag<["-"], "Wextra">, Group<W_Group>, Flags<[CC1Option]>;
 def Wl_COMMA : CommaJoined<["-"], "Wl,">, Flags<[LinkerInput, RenderAsInput]>,
   HelpText<"Pass the comma separated arguments in <arg> to the linker">,
-  MetaVarName<"<arg>">;
+  MetaVarName<"<arg>">, Group<Link_Group>;
 // FIXME: This is broken; these should not be Joined arguments.
 def Wno_nonportable_cfstrings : Joined<["-"], "Wno-nonportable-cfstrings">, Group<W_Group>,
   Flags<[CC1Option]>;
@@ -331,16 +428,18 @@
   Flags<[CC1Option]>;
 def Wp_COMMA : CommaJoined<["-"], "Wp,">,
   HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
-  MetaVarName<"<arg>">;
-def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option]>;
-def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option]>;
+  MetaVarName<"<arg>">, Group<Preprocessor_Group>;
+def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
+def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
 def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>,
   MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
 def Xanalyzer : Separate<["-"], "Xanalyzer">,
-  HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">;
+  HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">,
+  Group<StaticAnalyzer_Group>;
 def Xarch__ : JoinedAndSeparate<["-"], "Xarch_">, Flags<[DriverOption]>;
 def Xassembler : Separate<["-"], "Xassembler">,
-  HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">;
+  HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">,
+  Group<CompileOnly_Group>;
 def Xclang : Separate<["-"], "Xclang">,
   HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">,
   Flags<[DriverOption, CoreOption]>, Group<CompileOnly_Group>;
@@ -349,14 +448,17 @@
 def Xcuda_ptxas : Separate<["-"], "Xcuda-ptxas">,
   HelpText<"Pass <arg> to the ptxas assembler">, MetaVarName<"<arg>">;
 def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>,
-  HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">;
+  HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">,
+  Group<Link_Group>;
 def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
-  HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
-def Xpreprocessor : Separate<["-"], "Xpreprocessor">,
+  HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">,
+  Group<Link_Group>;
+def Xpreprocessor : Separate<["-"], "Xpreprocessor">, Group<Preprocessor_Group>,
   HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">;
-def X_Flag : Flag<["-"], "X">;
-def X_Joined : Joined<["-"], "X">;
-def Z_Flag : Flag<["-"], "Z">;
+def X_Flag : Flag<["-"], "X">, Group<Link_Group>;
+def X_Joined : Joined<["-"], "X">, IgnoredGCCCompat;
+def Z_Flag : Flag<["-"], "Z">, Group<Link_Group>;
+// FIXME: All we do with this is reject it. Remove.
 def Z_Joined : Joined<["-"], "Z">;
 def all__load : Flag<["-"], "all_load">;
 def allowable__client : Separate<["-"], "allowable_client">;
@@ -402,7 +504,7 @@
 def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
   HelpText<"Add directory to the C++ SYSTEM include search path">, Flags<[CC1Option]>,
   MetaVarName<"<directory>">;
-def c : Flag<["-"], "c">, Flags<[DriverOption]>,
+def c : Flag<["-"], "c">, Flags<[DriverOption]>, Group<Action_Group>,
   HelpText<"Only run preprocess, compile, and assemble steps">;
 def cuda_device_only : Flag<["--"], "cuda-device-only">,
   HelpText<"Compile CUDA code for device only">;
@@ -414,6 +516,9 @@
            "effect on non-CUDA compilations.">;
 def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>,
   HelpText<"CUDA GPU architecture (e.g. sm_35).  May be specified more than once.">;
+def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>,
+  HelpText<"Remove GPU architecture (e.g. sm_35) from the list of GPUs to compile for. "
+           "'all' resets the list to its default value.">;
 def cuda_noopt_device_debug : Flag<["--"], "cuda-noopt-device-debug">,
   HelpText<"Enable device-side debug info generation. Disables ptxas optimizations.">;
 def no_cuda_version_check : Flag<["--"], "no-cuda-version-check">,
@@ -422,6 +527,8 @@
 def no_cuda_noopt_device_debug : Flag<["--"], "no-cuda-noopt-device-debug">;
 def cuda_path_EQ : Joined<["--"], "cuda-path=">, Group<i_Group>,
   HelpText<"CUDA installation path">;
+def ptxas_path_EQ : Joined<["--"], "ptxas-path=">, Group<i_Group>,
+  HelpText<"Path to ptxas (used for compiling CUDA code)">;
 def fcuda_flush_denormals_to_zero : Flag<["-"], "fcuda-flush-denormals-to-zero">,
   Flags<[CC1Option]>, HelpText<"Flush denormal floating point values to zero in CUDA device mode.">;
 def fno_cuda_flush_denormals_to_zero : Flag<["-"], "fno-cuda-flush-denormals-to-zero">;
@@ -457,7 +564,7 @@
 def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option]>, Group<Action_Group>,
   HelpText<"Use the LLVM representation for assembler and object files">;
 def exported__symbols__list : Separate<["-"], "exported_symbols_list">;
-def e : JoinedOrSeparate<["-"], "e">;
+def e : JoinedOrSeparate<["-"], "e">, Group<Link_Group>;
 def fPIC : Flag<["-"], "fPIC">, Group<f_Group>;
 def fno_PIC : Flag<["-"], "fno-PIC">, Group<f_Group>;
 def fPIE : Flag<["-"], "fPIE">, Group<f_Group>;
@@ -511,9 +618,15 @@
     HelpText<"Enable sample-based profile guided optimizations">;
 def fauto_profile_EQ : Joined<["-"], "fauto-profile=">,
     Alias<fprofile_sample_use_EQ>;
+def fdebug_info_for_profiling : Flag<["-"], "fdebug-info-for-profiling">, Group<f_Group>,
+    Flags<[CC1Option]>,
+    HelpText<"Emit extra debug info to make sample profile more accurate.">;
+def fno_debug_info_for_profiling : Flag<["-"], "fno-debug-info-for-profiling">, Group<f_Group>,
+    Flags<[DriverOption]>,
+    HelpText<"Do not emit extra debug info for sample profiler.">;
 def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
     Group<f_Group>, Flags<[CoreOption]>,
-    HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overriden by '=' form of option or LLVM_PROFILE_FILE env var)">;
+    HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
 def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">,
     Group<f_Group>, Flags<[CoreOption]>, MetaVarName<"<file>">,
     HelpText<"Generate instrumented code to collect execution counts into <file> (overridden by LLVM_PROFILE_FILE env var)">;
@@ -811,13 +924,17 @@
 def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>,
   HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
 def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>;
-def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>;
+def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>,
+               Group<Link_Group>;
 def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
 def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
   HelpText<"Inline suitable functions">;
 def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
-  HelpText<"Inline functions wich are (explicitly or implicitly) marked inline">;
+  HelpText<"Inline functions which are (explicitly or implicitly) marked inline">;
 def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
+def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">,
+  Group<f_clang_Group>, Flags<[CC1Option]>,
+  HelpText<"Enables an experimental new pass manager in LLVM.">;
 def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>;
 def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
 def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
@@ -840,7 +957,7 @@
 def flat__namespace : Flag<["-"], "flat_namespace">;
 def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
 def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
-def flto_EQ : Joined<["-"], "flto=">, Flags<[CC1Option]>, Group<f_Group>,
+def flto_EQ : Joined<["-"], "flto=">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
   HelpText<"Set LTO mode to either 'full' or 'thin'">;
 def flto : Flag<["-"], "flto">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
   HelpText<"Enable LTO in 'full' mode">;
@@ -874,7 +991,7 @@
                "(default))">;
 def fdelayed_template_parsing : Flag<["-"], "fdelayed-template-parsing">, Group<f_Group>,
   HelpText<"Parse templated function definitions at the end of the "
-           "translation unit">,  Flags<[CC1Option]>;
+           "translation unit">,  Flags<[CC1Option, CoreOption]>;
 def fms_memptr_rep_EQ : Joined<["-"], "fms-memptr-rep=">, Group<f_Group>, Flags<[CC1Option]>;
 def fmodules_cache_path : Joined<["-"], "fmodules-cache-path=">, Group<i_Group>,
   Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
@@ -995,6 +1112,9 @@
 def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>;
 def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>;
 def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>;
+def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-manager">,
+  Group<f_clang_Group>, Flags<[CC1Option]>,
+  HelpText<"Disables an experimental new pass manager in LLVM.">;
 def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>,
     HelpText<"Use the given vector functions library">;
 def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
@@ -1020,7 +1140,9 @@
   Flags<[CoreOption]>;
 def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>,
   Flags<[CoreOption]>;
-def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>;
+def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>,
+  HelpText<"Disable delayed template parsing">,
+  Flags<[DriverOption, CoreOption]>;
 def fno_objc_exceptions: Flag<["-"], "fno-objc-exceptions">, Group<f_Group>;
 def fno_objc_legacy_dispatch : Flag<["-"], "fno-objc-legacy-dispatch">, Group<f_Group>;
 def fno_objc_weak : Flag<["-"], "fno-objc-weak">, Group<f_Group>, Flags<[CC1Option]>;
@@ -1077,6 +1199,11 @@
   HelpText<"Restrict code to those available for App Extensions">;
 def fno_application_extension : Flag<["-"], "fno-application-extension">,
   Group<f_Group>;
+def frelaxed_template_template_args : Flag<["-"], "frelaxed-template-template-args">,
+  Flags<[CC1Option]>, HelpText<"Enable C++17 relaxed template template argument matching">,
+  Group<f_Group>;
+def fno_relaxed_template_template_args : Flag<["-"], "fno-relaxed-template-template-args">,
+  Group<f_Group>;
 def fsized_deallocation : Flag<["-"], "fsized-deallocation">, Flags<[CC1Option]>,
   HelpText<"Enable C++14 sized global deallocation functions">, Group<f_Group>;
 def fno_sized_deallocation: Flag<["-"], "fno-sized-deallocation">, Group<f_Group>;
@@ -1195,6 +1322,10 @@
   HelpText<"Limit debug information produced to reduce size of debug binary">;
 def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Flags<[CoreOption]>, Alias<fno_standalone_debug>;
 def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Flags<[CoreOption]>, Alias<fstandalone_debug>;
+def fdebug_macro : Flag<["-"], "fdebug-macro">, Group<f_Group>, Flags<[CoreOption]>,
+  HelpText<"Emit macro debug information">;
+def fno_debug_macro : Flag<["-"], "fno-debug-macro">, Group<f_Group>, Flags<[CoreOption]>,
+  HelpText<"Do not emit macro debug information">;
 def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>,
   Flags<[DriverOption, CoreOption]>;
 def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>,
@@ -1315,6 +1446,12 @@
 def fno_unique_section_names : Flag <["-"], "fno-unique-section-names">,
   Group<f_Group>, Flags<[CC1Option]>;
 
+def fstrict_return : Flag<["-"], "fstrict-return">, Group<f_Group>,
+  Flags<[CC1Option]>,
+  HelpText<"Always treat control flow paths that fall off the end of a "
+           "non-void function as unreachable">;
+def fno_strict_return : Flag<["-"], "fno-strict-return">, Group<f_Group>,
+  Flags<[CC1Option]>;
 
 def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
   Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
@@ -1387,6 +1524,11 @@
   HelpText<"Add directory to AFTER include search path">;
 def iframework : JoinedOrSeparate<["-"], "iframework">, Group<clang_i_Group>, Flags<[CC1Option]>,
   HelpText<"Add directory to SYSTEM framework search path">;
+def iframeworkwithsysroot : JoinedOrSeparate<["-"], "iframeworkwithsysroot">,
+  Group<clang_i_Group>,
+  HelpText<"Add directory to SYSTEM framework search path, "
+           "absolute paths are relative to -isysroot">,
+  MetaVarName<"<directory>">, Flags<[CC1Option]>;
 def imacros : JoinedOrSeparate<["-", "--"], "imacros">, Group<clang_i_Group>, Flags<[CC1Option]>,
   HelpText<"Include macros from file before parsing">, MetaVarName<"<file>">;
 def image__base : Separate<["-"], "image_base">;
@@ -1425,7 +1567,8 @@
   HelpText<"Overlay the virtual filesystem described by file over the real file system">;
 def i : Joined<["-"], "i">, Group<i_Group>;
 def keep__private__externs : Flag<["-"], "keep_private_externs">;
-def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>;
+def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>,
+        Group<Link_Group>;
 def lazy__framework : Separate<["-"], "lazy_framework">, Flags<[LinkerInput]>;
 def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>;
 def mlittle_endian : Flag<["-"], "mlittle-endian">, Flags<[DriverOption]>;
@@ -1452,6 +1595,12 @@
   HelpText<"Generate branches with extended addressability, usually via indirect jumps.">;
 def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_Group>,
   HelpText<"Restore the default behaviour of not generating long calls">;
+def mexecute_only : Flag<["-"], "mexecute-only">, Group<m_arm_Features_Group>,
+  HelpText<"Disallow generation of data access to code sections (ARM only)">;
+def mno_execute_only : Flag<["-"], "mno-execute-only">, Group<m_arm_Features_Group>,
+  HelpText<"Allow generation of data access to code sections (ARM only)">;
+def mpure_code : Flag<["-"], "mpure-code">, Alias<mexecute_only>; // Alias for GCC compatibility
+def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias<mno_execute_only>;
 def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>;
 def mappletvos_version_min_EQ : Joined<["-"], "mappletvos-version-min=">, Alias<mtvos_version_min_EQ>;
 def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">, Alias<mtvos_version_min_EQ>;
@@ -1574,7 +1723,14 @@
 def mno_xsavec : Flag<["-"], "mno-xsavec">, Group<m_x86_Features_Group>;
 def mno_xsaves : Flag<["-"], "mno-xsaves">, Group<m_x86_Features_Group>;
 def mno_mwaitx : Flag<["-"], "mno-mwaitx">, Group<m_x86_Features_Group>;
+def mno_clzero : Flag<["-"], "mno-clzero">, Group<m_x86_Features_Group>;
 def mno_pku : Flag<["-"], "mno-pku">, Group<m_x86_Features_Group>;
+def mno_clflushopt : Flag<["-"], "mno-clflushopt">, Group<m_x86_Features_Group>;
+def mno_clwb : Flag<["-"], "mno-clwb">, Group<m_x86_Features_Group>;
+def mno_movbe : Flag<["-"], "mno-movbe">, Group<m_x86_Features_Group>;
+def mno_mpx : Flag<["-"], "mno-mpx">, Group<m_x86_Features_Group>;
+def mno_sgx : Flag<["-"], "mno-sgx">, Group<m_x86_Features_Group>;
+def mno_prefetchwt1 : Flag<["-"], "mno-prefetchwt1">, Group<m_x86_Features_Group>;
 
 def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
   HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">;
@@ -1705,7 +1861,8 @@
   HelpText<"(integrated-as) Emit an object file which cannot be used with an incremental linker">;
 def mrtd : Flag<["-"], "mrtd">, Group<m_Group>, Flags<[CC1Option]>,
   HelpText<"Make StdCall calling convention the default">;
-def msmall_data_threshold_EQ : Joined <["-"], "msmall-data-threshold=">, Group<m_Group>;
+def msmall_data_threshold_EQ : Joined <["-"], "msmall-data-threshold=">,
+  Group<m_Group>, Alias<G>;
 def msoft_float : Flag<["-"], "msoft-float">, Group<m_Group>, Flags<[CC1Option]>,
   HelpText<"Use software floating point">;
 def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>,
@@ -1717,6 +1874,8 @@
   Flags<[CC1Option]>,
   HelpText<"Use copy relocations support for PIE builds">;
 def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, Group<m_Group>;
+def mfentry : Flag<["-"], "mfentry">, HelpText<"insert calls to fentry at function entry (x86 only)">,
+  Flags<[CC1Option]>, Group<m_Group>;
 def mx87 : Flag<["-"], "mx87">, Group<m_x86_Features_Group>;
 def m80387 : Flag<["-"], "m80387">, Alias<mx87>;
 def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>;
@@ -1764,6 +1923,13 @@
 def mxsavec : Flag<["-"], "mxsavec">, Group<m_x86_Features_Group>;
 def mxsaves : Flag<["-"], "mxsaves">, Group<m_x86_Features_Group>;
 def mmwaitx : Flag<["-"], "mmwaitx">, Group<m_x86_Features_Group>;
+def mclzero : Flag<["-"], "mclzero">, Group<m_x86_Features_Group>;
+def mclflushopt : Flag<["-"], "mclflushopt">, Group<m_x86_Features_Group>;
+def mclwb : Flag<["-"], "mclwb">, Group<m_x86_Features_Group>;
+def mmovbe : Flag<["-"], "mmovbe">, Group<m_x86_Features_Group>;
+def mmpx : Flag<["-"], "mmpx">, Group<m_x86_Features_Group>;
+def msgx : Flag<["-"], "msgx">, Group<m_x86_Features_Group>;
+def mprefetchwt1 : Flag<["-"], "mprefetchwt1">, Group<m_x86_Features_Group>;
 def mips16 : Flag<["-"], "mips16">, Group<m_Group>;
 def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>;
 def mmicromips : Flag<["-"], "mmicromips">, Group<m_Group>;
@@ -1851,7 +2017,8 @@
   Flags<[HelpHidden]>;
 def mglibc : Flag<["-"], "mglibc">, Group<m_libc_Group>, Flags<[HelpHidden]>;
 def muclibc : Flag<["-"], "muclibc">, Group<m_libc_Group>, Flags<[HelpHidden]>;
-def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>;
+def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
+  HelpText<"Provide information about a particular module file">;
 def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
 def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>;
 def multi__module : Flag<["-"], "multi_module">;
@@ -1928,10 +2095,11 @@
   HelpText<"The directory which holds the compiler resource files">;
 def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption, CoreOption]>,
   Alias<resource_dir>;
-def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>;
+def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>, Group<Link_Group>;
 def rtlib_EQ : Joined<["-", "--"], "rtlib=">,
   HelpText<"Compiler runtime library to use">;
-def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>;
+def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>,
+        Group<Link_Group>;
 def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[DriverOption]>,
   HelpText<"Save intermediate compilation results.">;
 def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>,
@@ -1983,7 +2151,7 @@
   HelpText<"Treat all #include paths starting with <prefix> as not including a "
            "system header.">;
 def : Separate<["--"], "no-system-header-prefix">, Alias<no_system_header_prefix>;
-def s : Flag<["-"], "s">;
+def s : Flag<["-"], "s">, Group<Link_Group>;
 def target : Joined<["--"], "target=">, Flags<[DriverOption, CoreOption]>,
   HelpText<"Generate code for the given target">;
 def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[DriverOption]>,
@@ -1997,7 +2165,7 @@
   HelpText<"Process trigraph sequences">;
 def twolevel__namespace__hints : Flag<["-"], "twolevel_namespace_hints">;
 def twolevel__namespace : Flag<["-"], "twolevel_namespace">;
-def t : Flag<["-"], "t">;
+def t : Flag<["-"], "t">, Group<Link_Group>;
 def umbrella : Separate<["-"], "umbrella">;
 def undefined : JoinedOrSeparate<["-"], "undefined">, Group<u_Group>;
 def undef : Flag<["-"], "undef">, Group<u_Group>, Flags<[CC1Option]>,
@@ -2291,10 +2459,6 @@
 defm devirtualize_speculatively : BooleanFFlag<"devirtualize-speculatively">,
     Group<clang_ignored_gcc_optimization_f_Group>;
 
-// gfortran options that we recognize in the driver and pass along when
-// invoking GCC to compile Fortran code.
-def gfortran_Group : OptionGroup<"gfortran Group">;
-
 // Generic gfortran options.
 def A_DASH : Joined<["-"], "A-">, Group<gfortran_Group>;
 def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined]>, Group<gfortran_Group>;
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 53b8fbc..7dbe7a9 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -105,7 +105,6 @@
 
 protected:
   MultilibSet Multilibs;
-  const char *DefaultLinker = "ld";
 
   ToolChain(const Driver &D, const llvm::Triple &T,
             const llvm::opt::ArgList &Args);
@@ -140,6 +139,13 @@
   vfs::FileSystem &getVFS() const;
   const llvm::Triple &getTriple() const { return Triple; }
 
+  /// Get the toolchain's aux triple, if it has one.
+  ///
+  /// Exactly what the aux triple represents depends on the toolchain, but for
+  /// example when compiling CUDA code for the GPU, the triple might be NVPTX,
+  /// while the aux triple is the host (CPU) toolchain, e.g. x86-linux-gnu.
+  virtual const llvm::Triple *getAuxTriple() const { return nullptr; }
+
   llvm::Triple::ArchType getArch() const { return Triple.getArch(); }
   StringRef getArchName() const { return Triple.getArchName(); }
   StringRef getPlatform() const { return Triple.getVendorName(); }
@@ -272,6 +278,11 @@
     return 0;
   }
 
+  /// GetDefaultLinker - Get the default linker to use.
+  virtual const char *getDefaultLinker() const {
+    return "ld";
+  }
+
   /// GetDefaultRuntimeLibType - Get the default runtime library variant to use.
   virtual RuntimeLibType GetDefaultRuntimeLibType() const {
     return ToolChain::RLT_Libgcc;
@@ -288,6 +299,11 @@
   const char *getCompilerRTArgString(const llvm::opt::ArgList &Args,
                                      StringRef Component,
                                      bool Shared = false) const;
+
+  // Returns <ResourceDir>/lib/<OSName>/<arch>.  This is used by runtimes (such
+  // as OpenMP) to find arch-specific libraries.
+  std::string getArchSpecificLibPath() const;
+
   /// needsProfileRT - returns true if instrumentation profile is on.
   static bool needsProfileRT(const llvm::opt::ArgList &Args);
 
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index d34ca2f..b856bfd 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -100,6 +100,19 @@
 
   /// \brief If ``true``, aligns escaped newlines as far left as possible.
   /// Otherwise puts them into the right-most column.
+  /// \code
+  ///   true:
+  ///   #define A   \
+  ///     int aaaa; \
+  ///     int b;    \
+  ///     int dddddddddd;
+  ///
+  ///   false:
+  ///   #define A                                                                      \
+  ///     int aaaa;                                                                    \
+  ///     int b;                                                                       \
+  ///     int dddddddddd;
+  /// \endcode
   bool AlignEscapedNewlinesLeft;
 
   /// \brief If ``true``, horizontally align operands of binary and ternary
@@ -114,10 +127,21 @@
   bool AlignOperands;
 
   /// \brief If ``true``, aligns trailing comments.
+  /// \code
+  ///   true:                                   false:
+  ///   int a;     // My comment a      vs.     int a; // My comment a
+  ///   int b = 2; // comment  b                int b = 2; // comment about b
+  /// \endcode
   bool AlignTrailingComments;
 
   /// \brief Allow putting all parameters of a function declaration onto
   /// the next line even if ``BinPackParameters`` is ``false``.
+  /// \code
+  ///   true:                                   false:
+  ///   myFunction(foo,                 vs.     myFunction(foo, bar, plop);
+  ///              bar,
+  ///              plop);
+  /// \endcode
   bool AllowAllParametersOfDeclarationOnNextLine;
 
   /// \brief Allows contracting simple braced statements to a single line.
@@ -126,6 +150,16 @@
   bool AllowShortBlocksOnASingleLine;
 
   /// \brief If ``true``, short case labels will be contracted to a single line.
+  /// \code
+  ///   true:                                   false:
+  ///   switch (a) {                    vs.     switch (a) {
+  ///   case 1: x = 1; break;                   case 1:
+  ///   case 2: return;                           x = 1;
+  ///   }                                         break;
+  ///                                           case 2:
+  ///                                             return;
+  ///                                           }
+  /// \endcode
   bool AllowShortCaseLabelsOnASingleLine;
 
   /// \brief Different styles for merging short functions containing at most one
@@ -134,10 +168,27 @@
     /// \brief Never merge functions into a single line.
     SFS_None,
     /// \brief Only merge empty functions.
+    /// \code
+    ///   void f() { bar(); }
+    ///   void f2() {
+    ///     bar2();
+    ///   }
+    /// \endcode
     SFS_Empty,
     /// \brief Only merge functions defined inside a class. Implies "empty".
+    /// \code
+    ///   class {
+    ///     void f() { foo(); }
+    ///   };
+    /// \endcode
     SFS_Inline,
     /// \brief Merge all functions fitting on a single line.
+    /// \code
+    ///   class {
+    ///     void f() { foo(); }
+    ///   };
+    ///   void f() { bar(); }
+    /// \endcode
     SFS_All,
   };
 
@@ -153,6 +204,7 @@
   bool AllowShortLoopsOnASingleLine;
 
   /// \brief Different ways to break after the function definition return type.
+  /// This option is deprecated and is retained for backwards compatibility.
   enum DefinitionReturnTypeBreakingStyle {
     /// Break after return type automatically.
     /// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
@@ -168,14 +220,69 @@
   enum ReturnTypeBreakingStyle {
     /// Break after return type automatically.
     /// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
+    /// \code
+    ///   class A {
+    ///     int f() { return 0; };
+    ///   };
+    ///   int f();
+    ///   int f() { return 1; }
+    /// \endcode
     RTBS_None,
     /// Always break after the return type.
+    /// \code
+    ///   class A {
+    ///     int
+    ///     f() {
+    ///       return 0;
+    ///     };
+    ///   };
+    ///   int
+    ///   f();
+    ///   int
+    ///   f() {
+    ///     return 1;
+    ///   }
+    /// \endcode
     RTBS_All,
     /// Always break after the return types of top-level functions.
+    /// \code
+    ///   class A {
+    ///     int f() { return 0; };
+    ///   };
+    ///   int
+    ///   f();
+    ///   int
+    ///   f() {
+    ///     return 1;
+    ///   }
+    /// \endcode
     RTBS_TopLevel,
     /// Always break after the return type of function definitions.
+    /// \code
+    ///   class A {
+    ///     int
+    ///     f() {
+    ///       return 0;
+    ///     };
+    ///   };
+    ///   int f();
+    ///   int
+    ///   f() {
+    ///     return 1;
+    ///   }
+    /// \endcode
     RTBS_AllDefinitions,
     /// Always break after the return type of top-level definitions.
+    /// \code
+    ///   class A {
+    ///     int f() { return 0; };
+    ///   };
+    ///   int f();
+    ///   int
+    ///   f() {
+    ///     return 1;
+    ///   }
+    /// \endcode
     RTBS_TopLevelDefinitions,
   };
 
@@ -192,10 +299,21 @@
   /// in a file look more consistent. Thus, it will only take effect if wrapping
   /// the string at that point leads to it being indented
   /// ``ContinuationIndentWidth`` spaces from the start of the line.
+  /// \code
+  ///    true:                                  false:
+  ///    aaaa =                         vs.     aaaa = "bbbb"
+  ///        "bbbb"                                    "cccc";
+  ///        "cccc";
+  /// \endcode
   bool AlwaysBreakBeforeMultilineStrings;
 
   /// \brief If ``true``, always break after the ``template<...>`` of a template
   /// declaration.
+  /// \code
+  ///    true:                                  false:
+  ///    template <typename T>          vs.     template <typename T> class C {};
+  ///    class C {};
+  /// \endcode
   bool AlwaysBreakTemplateDeclarations;
 
   /// \brief If ``false``, a function call's arguments will either be all on the
@@ -222,23 +340,133 @@
   /// \brief Different ways to attach braces to their surrounding context.
   enum BraceBreakingStyle {
     /// Always attach braces to surrounding context.
+    /// \code
+    ///   try {
+    ///     foo();
+    ///   } catch () {
+    ///   }
+    ///   void foo() { bar(); }
+    ///   class foo {};
+    ///   if (foo()) {
+    ///   } else {
+    ///   }
+    ///   enum X : int { A, B };
+    /// \endcode
     BS_Attach,
     /// Like ``Attach``, but break before braces on function, namespace and
     /// class definitions.
+    /// \code
+    ///   try {
+    ///     foo();
+    ///   } catch () {
+    ///   }
+    ///   void foo() { bar(); }
+    ///   class foo
+    ///   {
+    ///   };
+    ///   if (foo()) {
+    ///   } else {
+    ///   }
+    ///   enum X : int { A, B };
+    /// \endcode
     BS_Linux,
     /// Like ``Attach``, but break before braces on enum, function, and record
     /// definitions.
+    /// \code
+    ///   try {
+    ///     foo();
+    ///   } catch () {
+    ///   }
+    ///   void foo() { bar(); }
+    ///   class foo
+    ///   {
+    ///   };
+    ///   if (foo()) {
+    ///   } else {
+    ///   }
+    ///   enum X : int { A, B };
+    /// \endcode
     BS_Mozilla,
     /// Like ``Attach``, but break before function definitions, ``catch``, and
     /// ``else``.
+    /// \code
+    ///   try {
+    ///     foo();
+    ///   } catch () {
+    ///   }
+    ///   void foo() { bar(); }
+    ///   class foo
+    ///   {
+    ///   };
+    ///   if (foo()) {
+    ///   } else {
+    ///   }
+    ///   enum X : int
+    ///   {
+    ///     A,
+    ///     B
+    ///   };
+    /// \endcode
     BS_Stroustrup,
     /// Always break before braces.
+    /// \code
+    ///   try {
+    ///     foo();
+    ///   }
+    ///   catch () {
+    ///   }
+    ///   void foo() { bar(); }
+    ///   class foo {
+    ///   };
+    ///   if (foo()) {
+    ///   }
+    ///   else {
+    ///   }
+    ///   enum X : int { A, B };
+    /// \endcode
     BS_Allman,
     /// Always break before braces and add an extra level of indentation to
     /// braces of control statements, not to those of class, function
     /// or other definitions.
+    /// \code
+    ///   try
+    ///     {
+    ///       foo();
+    ///     }
+    ///   catch ()
+    ///     {
+    ///     }
+    ///   void foo() { bar(); }
+    ///   class foo
+    ///   {
+    ///   };
+    ///   if (foo())
+    ///     {
+    ///     }
+    ///   else
+    ///     {
+    ///     }
+    ///   enum X : int
+    ///   {
+    ///     A,
+    ///     B
+    ///   };
+    /// \endcode
     BS_GNU,
     /// Like ``Attach``, but break before functions.
+    /// \code
+    ///   try {
+    ///     foo();
+    ///   } catch () {
+    ///   }
+    ///   void foo() { bar(); }
+    ///   class foo {
+    ///   };
+    ///   if (foo()) {
+    ///   } else {
+    ///   }
+    ///   enum X : int { A, B };
+    /// \endcode
     BS_WebKit,
     /// Configure each individual brace in `BraceWrapping`.
     BS_Custom
@@ -248,26 +476,144 @@
   BraceBreakingStyle BreakBeforeBraces;
 
   /// \brief Precise control over the wrapping of braces.
+  /// \code
+  ///   # Should be declared this way:
+  ///   BreakBeforeBraces: Custom
+  ///   BraceWrapping:
+  ///       AfterClass: true
+  /// \endcode
   struct BraceWrappingFlags {
     /// \brief Wrap class definitions.
+    /// \code
+    ///   true:
+    ///   class foo {};
+    ///
+    ///   false:
+    ///   class foo
+    ///   {};
+    /// \endcode
     bool AfterClass;
     /// \brief Wrap control statements (``if``/``for``/``while``/``switch``/..).
+    /// \code
+    ///   true:
+    ///   if (foo())
+    ///   {
+    ///   } else
+    ///   {}
+    ///   for (int i = 0; i < 10; ++i)
+    ///   {}
+    ///
+    ///   false:
+    ///   if (foo()) {
+    ///   } else {
+    ///   }
+    ///   for (int i = 0; i < 10; ++i) {
+    ///   }
+    /// \endcode
     bool AfterControlStatement;
     /// \brief Wrap enum definitions.
+    /// \code
+    ///   true:
+    ///   enum X : int
+    ///   {
+    ///     B
+    ///   };
+    ///
+    ///   false:
+    ///   enum X : int { B };
+    /// \endcode
     bool AfterEnum;
     /// \brief Wrap function definitions.
+    /// \code
+    ///   true:
+    ///   void foo()
+    ///   {
+    ///     bar();
+    ///     bar2();
+    ///   }
+    ///
+    ///   false:
+    ///   void foo() {
+    ///     bar();
+    ///     bar2();
+    ///   }
+    /// \endcode
     bool AfterFunction;
     /// \brief Wrap namespace definitions.
+    /// \code
+    ///   true:
+    ///   namespace
+    ///   {
+    ///   int foo();
+    ///   int bar();
+    ///   }
+    ///
+    ///   false:
+    ///   namespace {
+    ///   int foo();
+    ///   int bar();
+    ///   }
+    /// \endcode
     bool AfterNamespace;
     /// \brief Wrap ObjC definitions (``@autoreleasepool``, interfaces, ..).
     bool AfterObjCDeclaration;
     /// \brief Wrap struct definitions.
+    /// \code
+    ///   true:
+    ///   struct foo
+    ///   {
+    ///     int x;
+    ///   }
+    ///
+    ///   false:
+    ///   struct foo {
+    ///     int x;
+    ///   }
+    /// \endcode
     bool AfterStruct;
     /// \brief Wrap union definitions.
+    /// \code
+    ///   true:
+    ///   union foo
+    ///   {
+    ///     int x;
+    ///   }
+    ///
+    ///   false:
+    ///   union foo {
+    ///     int x;
+    ///   }
+    /// \endcode
     bool AfterUnion;
     /// \brief Wrap before ``catch``.
+    /// \code
+    ///   true:
+    ///   try {
+    ///     foo();
+    ///   }
+    ///   catch () {
+    ///   }
+    ///
+    ///   false:
+    ///   try {
+    ///     foo();
+    ///   } catch () {
+    ///   }
+    /// \endcode
     bool BeforeCatch;
     /// \brief Wrap before ``else``.
+    /// \code
+    ///   true:
+    ///   if (foo()) {
+    ///   }
+    ///   else {
+    ///   }
+    ///
+    ///   false:
+    ///   if (foo()) {
+    ///   } else {
+    ///   }
+    /// \endcode
     bool BeforeElse;
     /// \brief Indent the wrapped braces themselves.
     bool IndentBraces;
@@ -280,10 +626,28 @@
   BraceWrappingFlags BraceWrapping;
 
   /// \brief If ``true``, ternary operators will be placed after line breaks.
+  /// \code
+  ///    true:
+  ///    veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription
+  ///        ? firstValue
+  ///        : SecondValueVeryVeryVeryVeryLong;
+  ///
+  ///    true:
+  ///    veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription ?
+  ///        firstValue :
+  ///        SecondValueVeryVeryVeryVeryLong;
+  /// \endcode
   bool BreakBeforeTernaryOperators;
 
   /// \brief Always break constructor initializers before commas and align
   /// the commas with the colon.
+  /// \code
+  ///    true:                                  false:
+  ///    SomeClass::Constructor()       vs.     SomeClass::Constructor() : a(a),
+  ///        : a(a)                                                   b(b),
+  ///        , b(b)                                                   c(c) {}
+  ///        , c(c) {}
+  /// \endcode
   bool BreakConstructorInitializersBeforeComma;
 
   /// \brief Break after each annotation on a field in Java files.
@@ -303,8 +667,33 @@
   /// which should not be split into lines or otherwise changed.
   std::string CommentPragmas;
 
+  /// \brief If ``true``, in the class inheritance expression clang-format will
+  /// break before ``:`` and ``,`` if there is multiple inheritance.
+  /// \code
+  ///    true:                                  false:
+  ///    class MyClass                  vs.     class MyClass : public X, public Y {
+  ///        : public X                         };
+  ///        , public Y {
+  ///    };
+  /// \endcode
+  bool BreakBeforeInheritanceComma;
+
   /// \brief If the constructor initializers don't fit on a line, put each
   /// initializer on its own line.
+  /// \code
+  ///   true:
+  ///   SomeClass::Constructor()
+  ///       : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) {
+  ///     return 0;
+  ///   }
+  ///
+  ///   false:
+  ///   SomeClass::Constructor()
+  ///       : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa),
+  ///         aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) {
+  ///     return 0;
+  ///   }
+  /// \endcode
   bool ConstructorInitializerAllOnOneLineOrOnePerLine;
 
   /// \brief The number of characters to use for indentation of constructor
@@ -349,6 +738,16 @@
   /// not use this in config files, etc. Use at your own risk.
   bool ExperimentalAutoDetectBinPacking;
 
+  /// \brief If ``true``, clang-format adds missing namespace end comments and
+  /// fixes invalid existing ones.
+  /// \code
+  ///    true:                                  false:
+  ///    namespace a {                  vs.     namespace a {
+  ///    foo();                                 foo();
+  ///    } // namespace a;                      }
+  /// \endcode
+  bool FixNamespaceComments;
+
   /// \brief A vector of macros that should be interpreted as foreach loops
   /// instead of as function calls.
   ///
@@ -459,18 +858,21 @@
   enum LanguageKind {
     /// Do not use.
     LK_None,
-    /// Should be used for C, C++, ObjectiveC, ObjectiveC++.
+    /// Should be used for C, C++.
     LK_Cpp,
     /// Should be used for Java.
     LK_Java,
     /// Should be used for JavaScript.
     LK_JavaScript,
+    /// Should be used for Objective-C, Objective-C++.
+    LK_ObjC,
     /// Should be used for Protocol Buffers
     /// (https://developers.google.com/protocol-buffers/).
     LK_Proto,
     /// Should be used for TableGen code.
     LK_TableGen
   };
+  bool IsCpp() const { return Language == LK_Cpp || Language == LK_ObjC; }
 
   /// \brief Language, this format style is targeted at.
   LanguageKind Language;
@@ -530,10 +932,19 @@
   /// \brief The ``&`` and ``*`` alignment style.
   enum PointerAlignmentStyle {
     /// Align pointer to the left.
+    /// \code
+    ///   int* a;
+    /// \endcode
     PAS_Left,
     /// Align pointer to the right.
+    /// \code
+    ///   int *a;
+    /// \endcode
     PAS_Right,
     /// Align pointer in the middle.
+    /// \code
+    ///   int * a;
+    /// \endcode
     PAS_Middle
   };
 
@@ -544,15 +955,33 @@
   bool ReflowComments;
 
   /// \brief If ``true``, clang-format will sort ``#includes``.
+  /// \code
+  ///    false:                                 true:
+  ///    #include "b.h"                 vs.     #include "a.h"
+  ///    #include "a.h"                         #include "b.h"
+  /// \endcode
   bool SortIncludes;
 
-  /// \brief If ``true``, a space may be inserted after C style casts.
+  /// \brief If ``true``, a space is inserted after C style casts.
+  /// \code
+  ///    true:                                  false:
+  ///    (int)i;                        vs.     (int) i;
+  /// \endcode
   bool SpaceAfterCStyleCast;
 
   /// \brief If \c true, a space will be inserted after the 'template' keyword.
+  /// \code
+  ///    true:                                  false:
+  ///    template <int> void foo();     vs.     template<int> void foo();
+  /// \endcode
   bool SpaceAfterTemplateKeyword;
 
   /// \brief If ``false``, spaces will be removed before assignment operators.
+  /// \code
+  ///    true:                                  false:
+  ///    int a = 5;                     vs.     int a=5;
+  ///    a += 42                                a+=42;
+  /// \endcode
   bool SpaceBeforeAssignmentOperators;
 
   /// \brief Different ways to put a space before opening parentheses.
@@ -585,6 +1014,11 @@
 
   /// \brief If ``true``, spaces will be inserted after ``<`` and before ``>``
   /// in template argument lists.
+  /// \code
+  ///    true:                                  false:
+  ///    static_cast< int >(arg);       vs.     static_cast<int>(arg);
+  ///    std::function< void(int) > fct;        std::function<void(int)> fct;
+  /// \endcode
   bool SpacesInAngles;
 
   /// \brief If ``true``, spaces are inserted inside container literals (e.g.
@@ -592,12 +1026,26 @@
   bool SpacesInContainerLiterals;
 
   /// \brief If ``true``, spaces may be inserted into C style casts.
+  /// \code
+  ///    true:                                  false:
+  ///    x = ( int32 )y                 vs.     x = (int32)y
+  /// \endcode
   bool SpacesInCStyleCastParentheses;
 
   /// \brief If ``true``, spaces will be inserted after ``(`` and before ``)``.
+  /// \code
+  ///    true:                                  false:
+  ///    t f( Deleted & ) & = delete;   vs.     t f(Deleted &) & = delete;
+  /// \endcode
   bool SpacesInParentheses;
 
   /// \brief If ``true``, spaces will be inserted after ``[`` and before ``]``.
+  /// Lambdas or unspecified size array declarations will not be affected.
+  /// \code
+  ///    true:                                  false:
+  ///    int a[ 5 ];                    vs.     int a[5];
+  ///    std::unique_ptr<int[]> foo() {} // Won't be affected
+  /// \endcode
   bool SpacesInSquareBrackets;
 
   /// \brief Supported language standards.
@@ -666,6 +1114,7 @@
            BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations &&
            BreakStringLiterals == R.BreakStringLiterals &&
            ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas &&
+           BreakBeforeInheritanceComma == R.BreakBeforeInheritanceComma &&
            ConstructorInitializerAllOnOneLineOrOnePerLine ==
                R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
            ConstructorInitializerIndentWidth ==
@@ -676,6 +1125,7 @@
            DisableFormat == R.DisableFormat &&
            ExperimentalAutoDetectBinPacking ==
                R.ExperimentalAutoDetectBinPacking &&
+           FixNamespaceComments == R.FixNamespaceComments &&
            ForEachMacros == R.ForEachMacros &&
            IncludeCategories == R.IncludeCategories &&
            IndentCaseLabels == R.IndentCaseLabels &&
@@ -826,6 +1276,15 @@
                               ArrayRef<tooling::Range> Ranges,
                               StringRef FileName = "<stdin>");
 
+/// \brief Fix namespace end comments in the given \p Ranges in \p Code.
+///
+/// Returns the ``Replacements`` that fix the namespace comments in all
+/// \p Ranges in \p Code.
+tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style,
+                                              StringRef Code,
+                                              ArrayRef<tooling::Range> Ranges,
+                                              StringRef FileName = "<stdin>");
+
 /// \brief Returns the ``LangOpts`` that the formatter expects you to set.
 ///
 /// \param Style determines specific settings for lexing mode.
@@ -851,20 +1310,27 @@
 /// \param[in] FileName Path to start search for .clang-format if ``StyleName``
 /// == "file".
 /// \param[in] FallbackStyle The name of a predefined style used to fallback to
-/// in case the style can't be determined from \p StyleName.
+/// in case \p StyleName is "file" and no file can be found.
+/// \param[in] Code The actual code to be formatted. Used to determine the
+/// language if the filename isn't sufficient.
 /// \param[in] FS The underlying file system, in which the file resides. By
 /// default, the file system is the real file system.
 ///
-/// \returns FormatStyle as specified by ``StyleName``. If no style could be
-/// determined, the default is LLVM Style (see ``getLLVMStyle()``).
-FormatStyle getStyle(StringRef StyleName, StringRef FileName,
-                     StringRef FallbackStyle, vfs::FileSystem *FS = nullptr);
+/// \returns FormatStyle as specified by ``StyleName``. If ``StyleName`` is
+/// "file" and no file is found, returns ``FallbackStyle``. If no style could be
+/// determined, returns an Error.
+llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
+                                     StringRef FallbackStyle,
+                                     StringRef Code = "",
+                                     vfs::FileSystem *FS = nullptr);
 
 // \brief Returns a string representation of ``Language``.
 inline StringRef getLanguageName(FormatStyle::LanguageKind Language) {
   switch (Language) {
   case FormatStyle::LK_Cpp:
     return "C++";
+  case FormatStyle::LK_ObjC:
+    return "Objective-C";
   case FormatStyle::LK_Java:
     return "Java";
   case FormatStyle::LK_JavaScript:
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index b76bfcb..53975a0 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -37,7 +37,7 @@
 // AST dumper: dumps the raw AST in human-readable form to stderr; this is
 // intended for debugging.
 std::unique_ptr<ASTConsumer> CreateASTDumper(StringRef FilterString,
-                                             bool DumpDecls,
+                                             bool DumpDecls, bool Deserialize,
                                              bool DumpLookups);
 
 // AST Decl node lister: prints qualified names of all filterable AST Decl
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index cc8d4e6..03961f1 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -86,10 +86,10 @@
   IntrusiveRefCntPtr<SourceManager>       SourceMgr;
   std::unique_ptr<HeaderSearch>           HeaderInfo;
   IntrusiveRefCntPtr<TargetInfo>          Target;
-  IntrusiveRefCntPtr<Preprocessor>        PP;
+  std::shared_ptr<Preprocessor>           PP;
   IntrusiveRefCntPtr<ASTContext>          Ctx;
   std::shared_ptr<TargetOptions>          TargetOpts;
-  IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
+  std::shared_ptr<HeaderSearchOptions>    HSOpts;
   IntrusiveRefCntPtr<ASTReader> Reader;
   bool HadModuleLoaderFatalFailure;
 
@@ -108,8 +108,8 @@
 
   /// Optional owned invocation, just used to make the invocation used in
   /// LoadFromCommandLine available.
-  IntrusiveRefCntPtr<CompilerInvocation> Invocation;
-  
+  std::shared_ptr<CompilerInvocation> Invocation;
+
   // OnlyLocalDecls - when true, walking this AST should only visit declarations
   // that come from the AST itself, not from included precompiled headers.
   // FIXME: This is temporary; eventually, CIndex will always do this.
@@ -358,22 +358,21 @@
   }
   
   /// \brief Retrieve the allocator used to cache global code completions.
-  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
+  std::shared_ptr<GlobalCodeCompletionAllocator>
   getCachedCompletionAllocator() {
     return CachedCompletionAllocator;
   }
 
   CodeCompletionTUInfo &getCodeCompletionTUInfo() {
     if (!CCTUInfo)
-      CCTUInfo.reset(new CodeCompletionTUInfo(
-                                            new GlobalCodeCompletionAllocator));
+      CCTUInfo = llvm::make_unique<CodeCompletionTUInfo>(
+          std::make_shared<GlobalCodeCompletionAllocator>());
     return *CCTUInfo;
   }
 
 private:
   /// \brief Allocator used to store cached code completions.
-  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
-    CachedCompletionAllocator;
+  std::shared_ptr<GlobalCodeCompletionAllocator> CachedCompletionAllocator;
 
   std::unique_ptr<CodeCompletionTUInfo> CCTUInfo;
 
@@ -496,12 +495,13 @@
 
   const Preprocessor &getPreprocessor() const { return *PP; }
         Preprocessor &getPreprocessor()       { return *PP; }
+  std::shared_ptr<Preprocessor> getPreprocessorPtr() const { return PP; }
 
   const ASTContext &getASTContext() const { return *Ctx; }
         ASTContext &getASTContext()       { return *Ctx; }
 
   void setASTContext(ASTContext *ctx) { Ctx = ctx; }
-  void setPreprocessor(Preprocessor *pp);
+  void setPreprocessor(std::shared_ptr<Preprocessor> pp);
 
   bool hasSema() const { return (bool)TheSema; }
   Sema &getSema() const { 
@@ -519,6 +519,8 @@
 
   const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
 
+  IntrusiveRefCntPtr<ASTReader> getASTReader() const;
+
   StringRef getOriginalSourceFileName() {
     return OriginalSourceFile;
   }
@@ -701,11 +703,11 @@
   /// remapped contents of that file.
   typedef std::pair<std::string, llvm::MemoryBuffer *> RemappedFile;
 
-  /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation. 
-  static ASTUnit *create(CompilerInvocation *CI,
-                         IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-                         bool CaptureDiagnostics,
-                         bool UserFilesAreVolatile);
+  /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
+  static std::unique_ptr<ASTUnit>
+  create(std::shared_ptr<CompilerInvocation> CI,
+         IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool CaptureDiagnostics,
+         bool UserFilesAreVolatile);
 
   /// \brief Create a ASTUnit from an AST file.
   ///
@@ -770,7 +772,7 @@
   /// created ASTUnit was passed in \p Unit then the caller can check that.
   ///
   static ASTUnit *LoadFromCompilerInvocationAction(
-      CompilerInvocation *CI,
+      std::shared_ptr<CompilerInvocation> CI,
       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
       IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
       FrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
@@ -797,7 +799,7 @@
   // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
   // shouldn't need to specify them at construction time.
   static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation(
-      CompilerInvocation *CI,
+      std::shared_ptr<CompilerInvocation> CI,
       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
       IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
       bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index e33ec9e..172380c 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -49,13 +49,12 @@
 CODEGENOPT(DisableFree       , 1, 0) ///< Don't free memory.
 CODEGENOPT(DiscardValueNames , 1, 0) ///< Discard Value Names from the IR (LLVMContext flag)
 CODEGENOPT(DisableGCov       , 1, 0) ///< Don't run the GCov pass, for testing.
-CODEGENOPT(DisableLLVMOpts   , 1, 0) ///< Don't run any optimizations, for use in
-                                     ///< getting .bc files that correspond to the
-                                     ///< internal state before optimizations are
-                                     ///< done.
 CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get
                                      ///< the pristine IR generated by the
                                      ///< frontend.
+CODEGENOPT(DisableLifetimeMarkers, 1, 0) ///< Don't emit any lifetime markers
+CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental
+                                             ///< pass manager.
 CODEGENOPT(DisableRedZone    , 1, 0) ///< Set when -mno-red-zone is enabled.
 CODEGENOPT(DisableTailCalls  , 1, 0) ///< Do not emit tail calls.
 CODEGENOPT(EmitDeclMetadata  , 1, 0) ///< Emit special metadata indicating what
@@ -84,12 +83,15 @@
 VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
 
 CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
+CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled.
 CODEGENOPT(LessPreciseFPMAD  , 1, 0) ///< Enable less precise MAD instructions to
                                      ///< be generated.
 CODEGENOPT(PrepareForLTO     , 1, 0) ///< Set when -flto is enabled on the
                                      ///< compile step.
 CODEGENOPT(EmitSummaryIndex, 1, 0)   ///< Set when -flto=thin is enabled on the
                                      ///< compile step.
+CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole
+                          ///< program vtable opt).
 CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
                                               ///< be used with an incremental
                                               ///< linker.
@@ -108,8 +110,6 @@
 CODEGENOPT(NoSignedZeros     , 1, 0) ///< Allow ignoring the signedness of FP zero
 CODEGENOPT(ReciprocalMath    , 1, 0) ///< Allow FP divisions to be reassociated.
 CODEGENOPT(NoTrappingMath    , 1, 0) ///< Set when -fno-trapping-math is enabled.
-CODEGENOPT(NoInline          , 1, 0) ///< Set when -fno-inline is enabled.
-                                     ///< Disables use of the inline keyword.
 CODEGENOPT(NoNaNsFPMath      , 1, 0) ///< Assume FP arguments, results not NaN.
 CODEGENOPT(FlushDenorm       , 1, 0) ///< Allow FP denorm numbers to be flushed to zero
 CODEGENOPT(CorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt
@@ -224,6 +224,9 @@
 /// The kind of generated debug info.
 ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 3, codegenoptions::NoDebugInfo)
 
+/// Whether to generate macro debug info.
+CODEGENOPT(MacroDebugInfo, 1, 0)
+
 /// Tune the debug info for this debugger.
 ENUM_CODEGENOPT(DebuggerTuning, llvm::DebuggerKind, 2,
                 llvm::DebuggerKind::Default)
@@ -237,7 +240,7 @@
 CODEGENOPT(EmitCodeView, 1, 0)
 
 /// The kind of inlining to perform.
-ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining)
+ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining)
 
 // Vector functions library to use.
 ENUM_CODEGENOPT(VecLib, VectorLibrary, 2, NoLibrary)
@@ -255,6 +258,13 @@
 /// Whether copy relocations support is available when building as PIE.
 CODEGENOPT(PIECopyRelocations, 1, 0)
 
+/// Whether we should use the undefined behaviour optimization for control flow
+/// paths that reach the end of a function without executing a required return.
+CODEGENOPT(StrictReturn, 1, 1)
+
+/// Whether emit extra debug info for sample pgo profile collection.
+CODEGENOPT(DebugInfoForProfiling, 1, 0)
+
 #undef CODEGENOPT
 #undef ENUM_CODEGENOPT
 #undef VALUE_CODEGENOPT
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 22d2d4d..f8f3266 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -44,7 +44,6 @@
 class CodeGenOptions : public CodeGenOptionsBase {
 public:
   enum InliningMethod {
-    NoInlining,         // Perform no inlining whatsoever.
     NormalInlining,     // Use the standard function inlining pass.
     OnlyHintInlining,   // Inline only (implicitly) hinted functions.
     OnlyAlwaysInlining  // Only run the always inlining pass.
@@ -131,8 +130,21 @@
   /// The float precision limit to use, if non-empty.
   std::string LimitFloatPrecision;
 
-  /// The name of the bitcode file to link before optzns.
-  std::vector<std::pair<unsigned, std::string>> LinkBitcodeFiles;
+  struct BitcodeFileToLink {
+    /// The filename of the bitcode file to link in.
+    std::string Filename;
+    /// If true, we set attributes functions in the bitcode library according to
+    /// our CodeGenOptions, much as we set attrs on functions that we generate
+    /// ourselves.
+    bool PropagateAttrs = false;
+    /// If true, we use LLVM module internalizer.
+    bool Internalize = false;
+    /// Bitwise combination of llvm::Linker::Flags, passed to the LLVM linker.
+    unsigned LinkFlags = 0;
+  };
+
+  /// The files specified here are linked in to the module before optimizations.
+  std::vector<BitcodeFileToLink> LinkBitcodeFiles;
 
   /// The user provided name for the "main file", if non-empty. This is useful
   /// in situations where the input file name does not match the original input
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 3f754d9..91d9198 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -70,7 +70,7 @@
 /// and a long form that takes explicit instances of any required objects.
 class CompilerInstance : public ModuleLoader {
   /// The options used in this compiler instance.
-  IntrusiveRefCntPtr<CompilerInvocation> Invocation;
+  std::shared_ptr<CompilerInvocation> Invocation;
 
   /// The diagnostics engine instance.
   IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
@@ -91,7 +91,7 @@
   IntrusiveRefCntPtr<SourceManager> SourceMgr;
 
   /// The preprocessor.
-  IntrusiveRefCntPtr<Preprocessor> PP;
+  std::shared_ptr<Preprocessor> PP;
 
   /// The AST context.
   IntrusiveRefCntPtr<ASTContext> Context;
@@ -142,13 +142,13 @@
 
   /// \brief Whether we should (re)build the global module index once we
   /// have finished with this translation unit.
-  bool BuildGlobalModuleIndex;
+  bool BuildGlobalModuleIndex = false;
 
   /// \brief We have a full global module index, with all modules.
-  bool HaveFullGlobalModuleIndex;
+  bool HaveFullGlobalModuleIndex = false;
 
   /// \brief One or more modules failed to build.
-  bool ModuleBuildFailed;
+  bool ModuleBuildFailed = false;
 
   /// \brief Holds information about the output file.
   ///
@@ -228,7 +228,7 @@
   }
 
   /// setInvocation - Replace the current invocation.
-  void setInvocation(CompilerInvocation *Value);
+  void setInvocation(std::shared_ptr<CompilerInvocation> Value);
 
   /// \brief Indicates whether we should (re)build the global module index.
   bool shouldBuildGlobalModuleIndex() const;
@@ -288,6 +288,9 @@
   const HeaderSearchOptions &getHeaderSearchOpts() const {
     return Invocation->getHeaderSearchOpts();
   }
+  std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() const {
+    return Invocation->getHeaderSearchOptsPtr();
+  }
 
   LangOptions &getLangOpts() {
     return *Invocation->getLangOpts();
@@ -433,13 +436,14 @@
     return *PP;
   }
 
+  std::shared_ptr<Preprocessor> getPreprocessorPtr() { return PP; }
+
   void resetAndLeakPreprocessor() {
-    BuryPointer(PP.get());
-    PP.resetWithoutRelease();
+    BuryPointer(new std::shared_ptr<Preprocessor>(PP));
   }
 
   /// Replace the current preprocessor.
-  void setPreprocessor(Preprocessor *Value);
+  void setPreprocessor(std::shared_ptr<Preprocessor> Value);
 
   /// }
   /// @name ASTContext
@@ -653,7 +657,7 @@
       StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
       bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
       const PCHContainerReader &PCHContainerRdr,
-      ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
+      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
       void *DeserializationListener, bool OwnDeserializationListener,
       bool Preamble, bool UseGlobalModuleIndex);
 
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index cb037c2..cef7f73 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -51,7 +51,7 @@
                          bool DefaultDiagColor = true,
                          bool DefaultShowOpt = true);
 
-class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> {
+class CompilerInvocationBase {
   void operator=(const CompilerInvocationBase &) = delete;
 
 public:
@@ -65,10 +65,10 @@
   IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts;
 
   /// Options controlling the \#include directive.
-  IntrusiveRefCntPtr<HeaderSearchOptions> HeaderSearchOpts;
+  std::shared_ptr<HeaderSearchOptions> HeaderSearchOpts;
 
   /// Options controlling the preprocessor (aside from \#include handling).
-  IntrusiveRefCntPtr<PreprocessorOptions> PreprocessorOpts;
+  std::shared_ptr<PreprocessorOptions> PreprocessorOpts;
 
   CompilerInvocationBase();
   ~CompilerInvocationBase();
@@ -89,7 +89,13 @@
   const HeaderSearchOptions &getHeaderSearchOpts() const {
     return *HeaderSearchOpts;
   }
+  std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() const {
+    return HeaderSearchOpts;
+  }
 
+  std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() {
+    return PreprocessorOpts;
+  }
   PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; }
   const PreprocessorOptions &getPreprocessorOpts() const {
     return *PreprocessorOpts;
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index a073ca5..778b40b 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -80,6 +80,8 @@
 
   bool hasASTFileSupport() const override { return false; }
 
+  bool shouldEraseOutputFiles() override;
+
 public:
   /// \brief Compute the AST consumer arguments that will be used to
   /// create the PCHGenerator instance returned by CreateASTConsumer.
@@ -88,6 +90,8 @@
   static std::unique_ptr<raw_pwrite_stream>
   ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile,
                               std::string &Sysroot, std::string &OutputFile);
+
+  bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
 };
 
 class GenerateModuleAction : public ASTFrontendAction {
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index aad3975..4fd0f82 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -81,7 +81,7 @@
   IK_LLVM_IR
 };
 
-  
+
 /// \brief An input file for the front end.
 class FrontendInputFile {
   /// \brief The file name, or "-" to read from standard input.
@@ -109,6 +109,13 @@
   bool isEmpty() const { return File.empty() && Buffer == nullptr; }
   bool isFile() const { return !isBuffer(); }
   bool isBuffer() const { return Buffer != nullptr; }
+  bool isPreprocessed() const {
+    return Kind == IK_PreprocessedC ||
+           Kind == IK_PreprocessedCXX ||
+           Kind == IK_PreprocessedObjC ||
+           Kind == IK_PreprocessedObjCXX ||
+           Kind == IK_PreprocessedCuda;
+  }
 
   StringRef getFile() const {
     assert(isFile());
@@ -150,6 +157,8 @@
                                            ///< global module index if needed.
   unsigned ASTDumpDecls : 1;               ///< Whether we include declaration
                                            ///< dumps in AST dumps.
+  unsigned ASTDumpAll : 1;                 ///< Whether we deserialize all decls
+                                           ///< when forming AST dumps.
   unsigned ASTDumpLookups : 1;             ///< Whether we include lookup table
                                            ///< dumps in AST dumps.
   unsigned BuildingImplicitModule : 1;     ///< Whether we are performing an
@@ -243,7 +252,7 @@
   std::vector<std::string> Plugins;
 
   /// The list of module file extensions.
-  std::vector<IntrusiveRefCntPtr<ModuleFileExtension>> ModuleFileExtensions;
+  std::vector<std::shared_ptr<ModuleFileExtension>> ModuleFileExtensions;
 
   /// \brief The list of module map files to load before processing the input.
   std::vector<std::string> ModuleMapFiles;
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
index 8021d08..5ead90f 100644
--- a/include/clang/Frontend/LangStandard.h
+++ b/include/clang/Frontend/LangStandard.h
@@ -29,7 +29,8 @@
   Digraphs = (1 << 8),
   GNUMode = (1 << 9),
   HexFloat = (1 << 10),
-  ImplicitInt = (1 << 11)
+  ImplicitInt = (1 << 11),
+  OpenCL = (1 << 12)
 };
 
 }
@@ -91,6 +92,9 @@
   /// hasImplicitInt - Language allows variables to be typed as int implicitly.
   bool hasImplicitInt() const { return Flags & frontend::ImplicitInt; }
 
+  /// isOpenCL - Language is a OpenCL variant.
+  bool isOpenCL() const { return Flags & frontend::OpenCL; }
+
   static const LangStandard &getLangStandardForKind(Kind K);
   static const LangStandard *getLangStandardForName(StringRef Name);
 };
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index 06fe1a3..425ac84 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -142,16 +142,16 @@
 // OpenCL
 LANGSTANDARD(opencl, "cl",
              "OpenCL 1.0",
-             LineComment | C99 | Digraphs | HexFloat)
+             LineComment | C99 | Digraphs | HexFloat | OpenCL)
 LANGSTANDARD(opencl11, "cl1.1",
              "OpenCL 1.1",
-             LineComment | C99 | Digraphs | HexFloat)
+             LineComment | C99 | Digraphs | HexFloat | OpenCL)
 LANGSTANDARD(opencl12, "cl1.2",
              "OpenCL 1.2",
-             LineComment | C99 | Digraphs | HexFloat)
+             LineComment | C99 | Digraphs | HexFloat | OpenCL)
 LANGSTANDARD(opencl20, "cl2.0",
              "OpenCL 2.0",
-             LineComment | C99 | Digraphs | HexFloat)
+             LineComment | C99 | Digraphs | HexFloat | OpenCL)
 
 LANGSTANDARD_ALIAS(opencl, "CL")
 LANGSTANDARD_ALIAS(opencl11, "CL1.1")
diff --git a/include/clang/Frontend/PCHContainerOperations.h b/include/clang/Frontend/PCHContainerOperations.h
index d323fb3..f9a7350 100644
--- a/include/clang/Frontend/PCHContainerOperations.h
+++ b/include/clang/Frontend/PCHContainerOperations.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
 #define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
 
+#include "clang/Basic/Module.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -29,7 +30,7 @@
 class CompilerInstance;
 
 struct PCHBuffer {
-  uint64_t Signature;
+  ASTFileSignature Signature;
   llvm::SmallVector<char, 0> Data;
   bool IsComplete;
 };
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index cf943a5..0ee4684 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -128,11 +128,11 @@
   llvm::StringMap<std::string> SymLinkMap;
 
   bool getRealPath(StringRef SrcPath, SmallVectorImpl<char> &Result);
-  std::error_code copyToRoot(StringRef Src);
+  std::error_code copyToRoot(StringRef Src, StringRef Dst = "");
 public:
   StringRef getDest() { return DestDir; }
   bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; }
-  void addFile(StringRef Filename);
+  void addFile(StringRef Filename, StringRef FileDst = "");
   void addFileMapping(StringRef VPath, StringRef RPath) {
     VFSWriter.addFileMapping(VPath, RPath);
   }
@@ -184,10 +184,10 @@
 ///
 /// \return A CompilerInvocation, or 0 if none was built for the given
 /// argument vector.
-CompilerInvocation *
+std::unique_ptr<CompilerInvocation>
 createInvocationFromCommandLine(ArrayRef<const char *> Args,
-                            IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-                                IntrusiveRefCntPtr<DiagnosticsEngine>());
+                                IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+                                    IntrusiveRefCntPtr<DiagnosticsEngine>());
 
 /// Return the value of the last argument as an integer, or a default. If Diags
 /// is non-null, emits an error if the argument is given, but non-integral.
diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h
index cac0b53..eb718d7 100644
--- a/include/clang/Index/IndexSymbol.h
+++ b/include/clang/Index/IndexSymbol.h
@@ -51,6 +51,8 @@
   Constructor,
   Destructor,
   ConversionFunction,
+
+  Parameter,
 };
 
 enum class SymbolLanguage {
@@ -59,6 +61,15 @@
   CXX,
 };
 
+/// Language specific sub-kinds.
+enum class SymbolSubKind {
+  None,
+  CXXCopyConstructor,
+  CXXMoveConstructor,
+  AccessorGetter,
+  AccessorSetter,
+};
+
 /// Set of properties that provide additional info about a symbol.
 enum class SymbolProperty : uint8_t {
   Generic                       = 1 << 0,
@@ -68,12 +79,13 @@
   IBAnnotated                   = 1 << 4,
   IBOutletCollection            = 1 << 5,
   GKInspectable                 = 1 << 6,
+  Local                         = 1 << 7,
 };
-static const unsigned SymbolPropertyBitNum = 7;
+static const unsigned SymbolPropertyBitNum = 8;
 typedef unsigned SymbolPropertySet;
 
 /// Set of roles that are attributed to symbol occurrences.
-enum class SymbolRole : uint16_t {
+enum class SymbolRole : uint32_t {
   Declaration = 1 << 0,
   Definition  = 1 << 1,
   Reference   = 1 << 2,
@@ -92,8 +104,10 @@
   RelationCalledBy    = 1 << 13,
   RelationExtendedBy  = 1 << 14,
   RelationAccessorOf  = 1 << 15,
+  RelationContainedBy = 1 << 16,
+  RelationIBTypeOf    = 1 << 17,
 };
-static const unsigned SymbolRoleBitNum = 16;
+static const unsigned SymbolRoleBitNum = 18;
 typedef unsigned SymbolRoleSet;
 
 /// Represents a relation to another symbol for a symbol occurrence.
@@ -107,12 +121,15 @@
 
 struct SymbolInfo {
   SymbolKind Kind;
+  SymbolSubKind SubKind;
   SymbolPropertySet Properties;
   SymbolLanguage Lang;
 };
 
 SymbolInfo getSymbolInfo(const Decl *D);
 
+bool isFunctionLocalSymbol(const Decl *D);
+
 void applyForEachSymbolRole(SymbolRoleSet Roles,
                             llvm::function_ref<void(SymbolRole)> Fn);
 void printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS);
@@ -121,6 +138,7 @@
 bool printSymbolName(const Decl *D, const LangOptions &LO, raw_ostream &OS);
 
 StringRef getSymbolKindString(SymbolKind K);
+StringRef getSymbolSubKindString(SymbolSubKind K);
 StringRef getSymbolLanguageString(SymbolLanguage K);
 
 void applyForEachSymbolProperty(SymbolPropertySet Props,
diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h
index e2e63dc..8eed33c 100644
--- a/include/clang/Index/IndexingAction.h
+++ b/include/clang/Index/IndexingAction.h
@@ -14,9 +14,14 @@
 #include <memory>
 
 namespace clang {
+  class ASTReader;
   class ASTUnit;
   class FrontendAction;
 
+namespace serialization {
+  class ModuleFile;
+}
+
 namespace index {
   class IndexDataConsumer;
 
@@ -42,6 +47,11 @@
                   std::shared_ptr<IndexDataConsumer> DataConsumer,
                   IndexingOptions Opts);
 
+void indexModuleFile(serialization::ModuleFile &Mod,
+                     ASTReader &Reader,
+                     std::shared_ptr<IndexDataConsumer> DataConsumer,
+                     IndexingOptions Opts);
+
 } // namespace index
 } // namespace clang
 
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
index be89068..61f2c9d 100644
--- a/include/clang/Index/USRGeneration.h
+++ b/include/clang/Index/USRGeneration.h
@@ -16,6 +16,7 @@
 namespace clang {
 class Decl;
 class MacroDefinitionRecord;
+class SourceLocation;
 class SourceManager;
 
 namespace index {
@@ -54,6 +55,8 @@
 /// \returns true on error, false on success.
 bool generateUSRForMacro(const MacroDefinitionRecord *MD,
                          const SourceManager &SM, SmallVectorImpl<char> &Buf);
+bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
+                         const SourceManager &SM, SmallVectorImpl<char> &Buf);
 
 } // namespace index
 } // namespace clang
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index faba661..51983b9 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -147,7 +147,7 @@
   };
 
   /// \brief Header-search options used to initialize this header search.
-  IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
+  std::shared_ptr<HeaderSearchOptions> HSOpts;
 
   DiagnosticsEngine &Diags;
   FileManager &FileMgr;
@@ -248,7 +248,7 @@
   friend class DirectoryLookup;
   
 public:
-  HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
+  HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
                SourceManager &SourceMgr, DiagnosticsEngine &Diags,
                const LangOptions &LangOpts, const TargetInfo *Target);
   ~HeaderSearch();
@@ -406,7 +406,8 @@
   /// \return false if \#including the file will have no effect or true
   /// if we should include it.
   bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
-                              bool isImport, Module *CorrespondingModule);
+                              bool isImport, bool ModulesEnabled,
+                              Module *CorrespondingModule);
 
   /// \brief Return whether the specified file is a normal header,
   /// a system header, or a C++ friendly system header.
@@ -464,6 +465,9 @@
   /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
   const HeaderMap *CreateHeaderMap(const FileEntry *FE);
 
+  /// \brief Get filenames for all registered header maps.
+  void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const;
+
   /// \brief Retrieve the name of the module file that should be used to 
   /// load the given module.
   ///
@@ -544,6 +548,19 @@
   void loadTopLevelSystemModules();
 
 private:
+
+  /// \brief Lookup a module with the given module name and search-name.
+  ///
+  /// \param ModuleName The name of the module we're looking for.
+  ///
+  /// \param SearchName The "search-name" to derive filesystem paths from
+  /// when looking for the module map; this is usually equal to ModuleName,
+  /// but for compatibility with some buggy frameworks, additional attempts
+  /// may be made to find the module under a related-but-different search-name.
+  ///
+  /// \returns The module named ModuleName.
+  Module *lookupModule(StringRef ModuleName, StringRef SearchName);
+
   /// \brief Retrieve a module with the given name, which may be part of the
   /// given framework.
   ///
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index 815b68c..ca3a84e 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -44,7 +44,7 @@
 
 /// HeaderSearchOptions - Helper class for storing options related to the
 /// initialization of the HeaderSearch object.
-class HeaderSearchOptions : public RefCountedBase<HeaderSearchOptions> {
+class HeaderSearchOptions {
 public:
   struct Entry {
     std::string Path;
@@ -178,6 +178,8 @@
 
   unsigned ModulesValidateDiagnosticOptions : 1;
 
+  unsigned ModulesHashContent : 1;
+
   HeaderSearchOptions(StringRef _Sysroot = "/")
       : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0),
         ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0),
@@ -186,8 +188,8 @@
         UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
         UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
         ModulesValidateOncePerBuildSession(false),
-        ModulesValidateSystemHeaders(false),
-        UseDebugInfo(false), ModulesValidateDiagnosticOptions(true) {}
+        ModulesValidateSystemHeaders(false), UseDebugInfo(false),
+        ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {}
 
   /// AddPath - Add the \p Path path to the specified \p Group list.
   void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 5f946fc..b66581b 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -259,6 +259,8 @@
     return UDSuffixOffset;
   }
 
+  static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix);
+
 private:
   void init(ArrayRef<Token> StringToks);
   bool CopyStringFragment(const Token &Tok, const char *TokBegin,
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index b3a2421..4613672 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -316,6 +316,14 @@
     BuiltinIncludeDir = Dir;
   }
 
+  /// \brief Get the directory that contains Clang-supplied include files.
+  const DirectoryEntry *getBuiltinDir() const {
+    return BuiltinIncludeDir;
+  }
+
+  /// \brief Is this a compiler builtin header?
+  static bool isBuiltinHeader(StringRef FileName);
+
   /// \brief Add a module map callback.
   void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) {
     Callbacks.push_back(std::move(Callback));
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index ccef9ee..26efa8b 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -94,8 +94,8 @@
 /// Lexers know only about tokens within a single source file, and don't
 /// know anything about preprocessor-level issues like the \#include stack,
 /// token expansion, etc.
-class Preprocessor : public RefCountedBase<Preprocessor> {
-  IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
+class Preprocessor {
+  std::shared_ptr<PreprocessorOptions> PPOpts;
   DiagnosticsEngine        *Diags;
   LangOptions       &LangOpts;
   const TargetInfo  *Target;
@@ -650,10 +650,9 @@
   void updateOutOfDateIdentifier(IdentifierInfo &II) const;
 
 public:
-  Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
-               DiagnosticsEngine &diags, LangOptions &opts,
-               SourceManager &SM, HeaderSearch &Headers,
-               ModuleLoader &TheModuleLoader,
+  Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
+               DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,
+               HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
                IdentifierInfoLookup *IILookup = nullptr,
                bool OwnsHeaderSearch = false,
                TranslationUnitKind TUKind = TU_Complete);
@@ -887,7 +886,8 @@
     return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
   }
   /// \brief Set a MacroDirective that was loaded from a PCH file.
-  void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
+  void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED,
+                               MacroDirective *MD);
 
   /// \brief Register an exported macro for a module and identifier.
   ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro,
@@ -1077,6 +1077,24 @@
   /// \brief Disable the last EnableBacktrackAtThisPos call.
   void CommitBacktrackedTokens();
 
+  struct CachedTokensRange {
+    CachedTokensTy::size_type Begin, End;
+  };
+
+private:
+  /// \brief A range of cached tokens that should be erased after lexing
+  /// when backtracking requires the erasure of such cached tokens.
+  Optional<CachedTokensRange> CachedTokenRangeToErase;
+
+public:
+  /// \brief Returns the range of cached tokens that were lexed since
+  /// EnableBacktrackAtThisPos() was previously called.
+  CachedTokensRange LastCachedTokenRange();
+
+  /// \brief Erase the range of cached tokens that were lexed since
+  /// EnableBacktrackAtThisPos() was previously called.
+  void EraseCachedTokens(CachedTokensRange TokenRange);
+
   /// \brief Make Preprocessor re-lex the tokens that were lexed since
   /// EnableBacktrackAtThisPos() was previously called.
   void Backtrack();
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index de652cc..58d79f7 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -40,7 +40,7 @@
   
 /// PreprocessorOptions - This class is used for passing the various options
 /// used in preprocessor initialization to InitializePreprocessor().
-class PreprocessorOptions : public RefCountedBase<PreprocessorOptions> {
+class PreprocessorOptions {
 public:
   std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
   std::vector<std::string> Includes;
@@ -117,7 +117,7 @@
   ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary;
     
   /// \brief Records the set of modules
-  class FailedModulesSet : public RefCountedBase<FailedModulesSet> {
+  class FailedModulesSet {
     llvm::StringSet<> Failed;
 
   public:
@@ -136,7 +136,7 @@
   /// to (re)build modules, so that once a module fails to build anywhere,
   /// other instances will see that the module has failed and won't try to
   /// build it again.
-  IntrusiveRefCntPtr<FailedModulesSet> FailedModules;
+  std::shared_ptr<FailedModulesSet> FailedModules;
 
 public:
   PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 40eb579..70381e5 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -142,6 +142,10 @@
   /// \brief Identifier for "replacement".
   IdentifierInfo *Ident_replacement;
 
+  /// Identifiers used by the 'external_source_symbol' attribute.
+  IdentifierInfo *Ident_language, *Ident_defined_in,
+      *Ident_generated_declaration;
+
   /// C++0x contextual keywords.
   mutable IdentifierInfo *Ident_final;
   mutable IdentifierInfo *Ident_GNU_final;
@@ -600,11 +604,8 @@
 public:
   // If NeedType is true, then TryAnnotateTypeOrScopeToken will try harder to
   // find a type name by attempting typo correction.
-  bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false,
-                                   bool NeedType = false);
-  bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext,
-                                                 bool NeedType,
-                                                 CXXScopeSpec &SS,
+  bool TryAnnotateTypeOrScopeToken();
+  bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS,
                                                  bool IsNewScope);
   bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
 
@@ -1261,6 +1262,11 @@
     ParsedAttributesWithRange(AttributeFactory &factory)
       : ParsedAttributes(factory) {}
 
+    void clear() {
+      ParsedAttributes::clear();
+      Range = SourceRange();
+    }
+
     SourceRange Range;
   };
 
@@ -1530,8 +1536,6 @@
                                       bool IsTypename = false,
                                       IdentifierInfo **LastII = nullptr);
 
-  void CheckForLParenAfterColonColon();
-
   //===--------------------------------------------------------------------===//
   // C++0x 5.1.2: Lambda expressions
 
@@ -1834,6 +1838,26 @@
     llvm_unreachable("Missing DeclSpecContext case");
   }
 
+  /// Is this a context in which we can perform class template argument
+  /// deduction?
+  static bool isClassTemplateDeductionContext(DeclSpecContext DSC) {
+    switch (DSC) {
+    case DSC_normal:
+    case DSC_class:
+    case DSC_top_level:
+    case DSC_condition:
+    case DSC_type_specifier:
+      return true;
+
+    case DSC_objc_method_result:
+    case DSC_template_type_arg:
+    case DSC_trailing:
+    case DSC_alias_declaration:
+      return false;
+    }
+    llvm_unreachable("Missing DeclSpecContext case");
+  }
+
   /// Information on a C++0x for-range-initializer found while parsing a
   /// declaration which turns out to be a for-range-declaration.
   struct ForRangeInit {
@@ -1947,7 +1971,7 @@
   /// \brief Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(bool Unqualified);
+  bool isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false);
 
   /// \brief Specifies the context in which type-id/expression
   /// disambiguation will occur.
@@ -2177,6 +2201,12 @@
                              Declarator *D);
   IdentifierLoc *ParseIdentifierLoc();
 
+  unsigned
+  ParseClangAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+                          ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                          IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+                          AttributeList::Syntax Syntax);
+
   void MaybeParseCXX11Attributes(Declarator &D) {
     if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
       ParsedAttributesWithRange attrs(AttrFactory);
@@ -2266,6 +2296,14 @@
   Optional<AvailabilitySpec> ParseAvailabilitySpec();
   ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
 
+  void ParseExternalSourceSymbolAttribute(IdentifierInfo &ExternalSourceSymbol,
+                                          SourceLocation Loc,
+                                          ParsedAttributes &Attrs,
+                                          SourceLocation *EndLoc,
+                                          IdentifierInfo *ScopeName,
+                                          SourceLocation ScopeLoc,
+                                          AttributeList::Syntax Syntax);
+
   void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
                                        SourceLocation ObjCBridgeRelatedLoc,
                                        ParsedAttributes &attrs,
@@ -2365,10 +2403,10 @@
                                 AR_DeclspecAttributesParsed
   };
 
-  void ParseTypeQualifierListOpt(DeclSpec &DS,
-                                 unsigned AttrReqs = AR_AllAttributesParsed,
-                                 bool AtomicAllowed = true,
-                                 bool IdentifierRequired = false);
+  void ParseTypeQualifierListOpt(
+      DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
+      bool AtomicAllowed = true, bool IdentifierRequired = false,
+      Optional<llvm::function_ref<void()>> CodeCompletionHandler = None);
   void ParseDirectDeclarator(Declarator &D);
   void ParseDecompositionDeclarator(Declarator &D);
   void ParseParenDeclarator(Declarator &D);
@@ -2420,21 +2458,39 @@
                            BalancedDelimiterTracker &Tracker);
   Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
   Decl *ParseExportDeclaration();
-  Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
-                                         const ParsedTemplateInfo &TemplateInfo,
-                                         SourceLocation &DeclEnd,
-                                         ParsedAttributesWithRange &attrs,
-                                         Decl **OwnedType = nullptr);
+  DeclGroupPtrTy ParseUsingDirectiveOrDeclaration(
+      unsigned Context, const ParsedTemplateInfo &TemplateInfo,
+      SourceLocation &DeclEnd, ParsedAttributesWithRange &attrs);
   Decl *ParseUsingDirective(unsigned Context,
                             SourceLocation UsingLoc,
                             SourceLocation &DeclEnd,
                             ParsedAttributes &attrs);
-  Decl *ParseUsingDeclaration(unsigned Context,
-                              const ParsedTemplateInfo &TemplateInfo,
-                              SourceLocation UsingLoc,
-                              SourceLocation &DeclEnd,
-                              AccessSpecifier AS = AS_none,
-                              Decl **OwnedType = nullptr);
+
+  struct UsingDeclarator {
+    SourceLocation TypenameLoc;
+    CXXScopeSpec SS;
+    SourceLocation TemplateKWLoc;
+    UnqualifiedId Name;
+    SourceLocation EllipsisLoc;
+
+    void clear() {
+      TypenameLoc = TemplateKWLoc = EllipsisLoc = SourceLocation();
+      SS.clear();
+      Name.clear();
+    }
+  };
+
+  bool ParseUsingDeclarator(unsigned Context, UsingDeclarator &D);
+  DeclGroupPtrTy ParseUsingDeclaration(unsigned Context,
+                                       const ParsedTemplateInfo &TemplateInfo,
+                                       SourceLocation UsingLoc,
+                                       SourceLocation &DeclEnd,
+                                       AccessSpecifier AS = AS_none);
+  Decl *ParseAliasDeclarationAfterDeclarator(
+      const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
+      UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,
+      ParsedAttributes &Attrs, Decl **OwnedType = nullptr);
+
   Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
   Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
                             SourceLocation AliasLoc, IdentifierInfo *Alias,
@@ -2596,6 +2652,7 @@
   bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
                           bool AllowDestructorName,
                           bool AllowConstructorName,
+                          bool AllowDeductionGuide,
                           ParsedType ObjectType,
                           SourceLocation& TemplateKWLoc,
                           UnqualifiedId &Result);
@@ -2656,7 +2713,7 @@
                                SourceLocation TemplateKWLoc,
                                UnqualifiedId &TemplateName,
                                bool AllowTypeAnnotation = true);
-  void AnnotateTemplateIdTokenAsType();
+  void AnnotateTemplateIdTokenAsType(bool IsClassName = false);
   bool IsTemplateArgumentList(unsigned Skip = 0);
   bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
   ParsedTemplateArgument ParseTemplateTemplateArgument();
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 0c56b3f..7c16780 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -925,7 +925,9 @@
   ExpectedVariableEnumFieldOrTypedef,
   ExpectedFunctionMethodEnumOrClass,
   ExpectedStructClassVariableFunctionOrInlineNamespace,
-  ExpectedForMaybeUnused
+  ExpectedForMaybeUnused,
+  ExpectedEnumOrClass,
+  ExpectedNamedDecl,
 };
 
 }  // end namespace clang
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index b80924e..dee53dc 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -509,23 +509,18 @@
 };
 
 /// \brief Allocator for a cached set of global code completions.
-class GlobalCodeCompletionAllocator 
-  : public CodeCompletionAllocator,
-    public RefCountedBase<GlobalCodeCompletionAllocator>
-{
-
-};
+class GlobalCodeCompletionAllocator : public CodeCompletionAllocator {};
 
 class CodeCompletionTUInfo {
   llvm::DenseMap<const DeclContext *, StringRef> ParentNames;
-  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> AllocatorRef;
+  std::shared_ptr<GlobalCodeCompletionAllocator> AllocatorRef;
 
 public:
   explicit CodeCompletionTUInfo(
-      IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> Allocator)
+      std::shared_ptr<GlobalCodeCompletionAllocator> Allocator)
       : AllocatorRef(std::move(Allocator)) {}
 
-  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> getAllocatorRef() const {
+  std::shared_ptr<GlobalCodeCompletionAllocator> getAllocatorRef() const {
     return AllocatorRef;
   }
   CodeCompletionAllocator &getAllocator() const {
@@ -965,8 +960,8 @@
   /// results to the given raw output stream.
   PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
                                raw_ostream &OS)
-    : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS),
-      CCTUInfo(new GlobalCodeCompletionAllocator) {}
+      : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS),
+        CCTUInfo(std::make_shared<GlobalCodeCompletionAllocator>()) {}
 
   /// \brief Prints the finalized code-completion results.
   void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 75f18b8..82f04a5 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -519,7 +519,7 @@
   SourceRange getTypeofParensRange() const { return TypeofParensRange; }
   void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; }
 
-  bool containsPlaceholderType() const {
+  bool hasAutoTypeSpec() const {
     return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type ||
             TypeSpecType == TST_decltype_auto);
   }
@@ -819,7 +819,9 @@
     : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
       Nullability(0), GetterName(nullptr), SetterName(nullptr) { }
 
-  ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
+  ObjCDeclQualifier getObjCDeclQualifier() const {
+    return (ObjCDeclQualifier)objcDeclQualifier;
+  }
   void setObjCDeclQualifier(ObjCDeclQualifier DQVal) {
     objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal);
   }
@@ -869,7 +871,7 @@
   // 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 : 7;
+  unsigned objcDeclQualifier : 7;
 
   // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
   unsigned PropertyAttributes : 15;
@@ -908,7 +910,9 @@
     /// \brief A template-id, e.g., f<int>.
     IK_TemplateId,
     /// \brief An implicit 'self' parameter
-    IK_ImplicitSelfParam
+    IK_ImplicitSelfParam,
+    /// \brief A deduction-guide name (a template-name)
+    IK_DeductionGuideName
   } Kind;
 
   struct OFI {
@@ -928,8 +932,8 @@
   /// \brief Anonymous union that holds extra data associated with the
   /// parsed unqualified-id.
   union {
-    /// \brief When Kind == IK_Identifier, the parsed identifier, or when Kind
-    /// == IK_UserLiteralId, the identifier suffix.
+    /// \brief When Kind == IK_Identifier, the parsed identifier, or when
+    /// Kind == IK_UserLiteralId, the identifier suffix.
     IdentifierInfo *Identifier;
     
     /// \brief When Kind == IK_OperatorFunctionId, the overloaded operator
@@ -947,6 +951,9 @@
     /// \brief When Kind == IK_DestructorName, the type referred to by the
     /// class-name.
     UnionParsedType DestructorName;
+
+    /// \brief When Kind == IK_DeductionGuideName, the parsed template-name.
+    UnionParsedTemplateTy TemplateName;
     
     /// \brief When Kind == IK_TemplateId or IK_ConstructorTemplateId,
     /// the template-id annotation that contains the template name and
@@ -1085,6 +1092,18 @@
   /// \p TemplateId and will free it on destruction.
   void setTemplateId(TemplateIdAnnotation *TemplateId);
 
+  /// \brief Specify that this unqualified-id was parsed as a template-name for
+  /// a deduction-guide.
+  ///
+  /// \param Template The parsed template-name.
+  /// \param TemplateLoc The location of the parsed template-name.
+  void setDeductionGuideName(ParsedTemplateTy Template,
+                             SourceLocation TemplateLoc) {
+    Kind = IK_DeductionGuideName;
+    TemplateName = Template;
+    StartLocation = EndLocation = TemplateLoc;
+  }
+  
   /// \brief Return the source range that covers this unqualified-id.
   SourceRange getSourceRange() const LLVM_READONLY { 
     return SourceRange(StartLocation, EndLocation); 
@@ -1248,9 +1267,10 @@
     /// declarator.
     unsigned NumParams;
 
-    /// NumExceptions - This is the number of types in the dynamic-exception-
-    /// decl, if the function has one.
-    unsigned NumExceptions;
+    /// NumExceptionsOrDecls - This is the number of types in the
+    /// dynamic-exception-decl, if the function has one. In C, this is the
+    /// number of declarations in the function prototype.
+    unsigned NumExceptionsOrDecls;
 
     /// \brief The location of the ref-qualifier, if any.
     ///
@@ -1300,6 +1320,11 @@
       /// \brief Pointer to the cached tokens for an exception-specification
       /// that has not yet been parsed.
       CachedTokens *ExceptionSpecTokens;
+
+      /// Pointer to a new[]'d array of declarations that need to be available
+      /// for lookup inside the function body, if one exists. Does not exist in
+      /// C++.
+      NamedDecl **DeclsInPrototype;
     };
 
     /// \brief If HasTrailingReturnType is true, this is the trailing return
@@ -1322,10 +1347,20 @@
     void destroy() {
       if (DeleteParams)
         delete[] Params;
-      if (getExceptionSpecType() == EST_Dynamic)
+      switch (getExceptionSpecType()) {
+      default:
+        break;
+      case EST_Dynamic:
         delete[] Exceptions;
-      else if (getExceptionSpecType() == EST_Unparsed)
+        break;
+      case EST_Unparsed:
         delete ExceptionSpecTokens;
+        break;
+      case EST_None:
+        if (NumExceptionsOrDecls != 0)
+          delete[] DeclsInPrototype;
+        break;
+      }
     }
 
     /// isKNRPrototype - Return true if this is a K&R style identifier list,
@@ -1395,6 +1430,19 @@
       return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
     }
 
+    /// \brief Get the number of dynamic exception specifications.
+    unsigned getNumExceptions() const {
+      assert(ExceptionSpecType != EST_None);
+      return NumExceptionsOrDecls;
+    }
+
+    /// \brief Get the non-parameter decls defined within this function
+    /// prototype. Typically these are tag declarations.
+    ArrayRef<NamedDecl *> getDeclsInPrototype() const {
+      assert(ExceptionSpecType == EST_None);
+      return llvm::makeArrayRef(DeclsInPrototype, NumExceptionsOrDecls);
+    }
+
     /// \brief Determine whether this function declarator had a
     /// trailing-return-type.
     bool hasTrailingReturnType() const { return HasTrailingReturnType; }
@@ -1540,6 +1588,7 @@
                                      unsigned NumExceptions,
                                      Expr *NoexceptExpr,
                                      CachedTokens *ExceptionSpecTokens,
+                                     ArrayRef<NamedDecl *> DeclsInPrototype,
                                      SourceLocation LocalRangeBegin,
                                      SourceLocation LocalRangeEnd,
                                      Declarator &TheDeclarator,
@@ -1679,6 +1728,7 @@
     ObjCParameterContext,// An ObjC method parameter type.
     KNRTypeListContext,  // K&R type definition list for formals.
     TypeNameContext,     // Abstract declarator for types.
+    FunctionalCastContext, // Type in a C++ functional cast expression.
     MemberContext,       // Struct/Union field.
     BlockContext,        // Declaration within a block in a function.
     ForContext,          // Declaration within first part of a for loop.
@@ -1881,6 +1931,7 @@
       return false;
 
     case TypeNameContext:
+    case FunctionalCastContext:
     case AliasDeclContext:
     case AliasTemplateContext:
     case PrototypeContext:
@@ -1921,6 +1972,7 @@
       return true;
 
     case TypeNameContext:
+    case FunctionalCastContext:
     case CXXNewContext:
     case AliasDeclContext:
     case AliasTemplateContext:
@@ -1953,6 +2005,7 @@
     case CXXCatchContext:
     case ObjCCatchContext:
     case TypeNameContext:
+    case FunctionalCastContext:
     case ConversionIdContext:
     case ObjCParameterContext:
     case ObjCResultContext:
@@ -1991,6 +2044,7 @@
     // These contexts don't allow any kind of non-abstract declarator.
     case KNRTypeListContext:
     case TypeNameContext:
+    case FunctionalCastContext:
     case AliasDeclContext:
     case AliasTemplateContext:
     case LambdaExprParameterContext:
@@ -2048,6 +2102,7 @@
     case CXXCatchContext:
     case ObjCCatchContext:
     case TypeNameContext:
+    case FunctionalCastContext: // FIXME
     case CXXNewContext:
     case AliasDeclContext:
     case AliasTemplateContext:
@@ -2249,6 +2304,7 @@
     case ConditionContext:
     case KNRTypeListContext:
     case TypeNameContext:
+    case FunctionalCastContext:
     case AliasDeclContext:
     case AliasTemplateContext:
     case PrototypeContext:
@@ -2282,6 +2338,16 @@
     return true;
   }
 
+  /// \brief Determine whether a trailing return type was written (at any
+  /// level) within this declarator.
+  bool hasTrailingReturnType() const {
+    for (const auto &Chunk : type_objects())
+      if (Chunk.Kind == DeclaratorChunk::Function &&
+          Chunk.Fun.hasTrailingReturnType())
+        return true;
+    return false;
+  }
+
   /// takeAttributes - Takes attributes from the given parsed-attributes
   /// set and add them to this declarator.
   ///
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 75e59c2..7b13867 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -120,6 +120,16 @@
     bool NRVO;
   };
 
+  struct VD {
+    /// \brief The VarDecl, FieldDecl, or BindingDecl being initialized.
+    ValueDecl *VariableOrMember;
+
+    /// \brief When Kind == EK_Member, whether this is an implicit member
+    /// initialization in a copy or move constructor. These can perform array
+    /// copies.
+    bool IsImplicitFieldInit;
+  };
+
   struct C {
     /// \brief The name of the variable being captured by an EK_LambdaCapture.
     IdentifierInfo *VarID;
@@ -129,9 +139,8 @@
   };
 
   union {
-    /// \brief When Kind == EK_Variable, EK_Member or EK_Binding, the VarDecl,
-    /// FieldDecl or BindingDecl, respectively.
-    ValueDecl *VariableOrMember;
+    /// \brief When Kind == EK_Variable, EK_Member or EK_Binding, the variable.
+    VD Variable;
     
     /// \brief When Kind == EK_RelatedResult, the ObjectiveC method where
     /// result type was implicitly changed to accommodate ARC semantics.
@@ -165,7 +174,7 @@
   /// \brief Create the initialization entity for a variable.
   InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
     : Kind(EK), Parent(nullptr), Type(Var->getType()),
-      ManglingNumber(0), VariableOrMember(Var) { }
+      ManglingNumber(0), Variable{Var, false} { }
   
   /// \brief Create the initialization entity for the result of a
   /// function, throwing an object, performing an explicit cast, or
@@ -179,9 +188,11 @@
   }
   
   /// \brief Create the initialization entity for a member subobject.
-  InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent) 
+  InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
+                    bool Implicit) 
     : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
-      ManglingNumber(0), VariableOrMember(Member) { }
+      ManglingNumber(0), Variable{Member, Implicit} {
+  }
   
   /// \brief Create the initialization entity for an array element.
   InitializedEntity(ASTContext &Context, unsigned Index, 
@@ -204,14 +215,14 @@
 
   /// \brief Create the initialization entity for a parameter.
   static InitializedEntity InitializeParameter(ASTContext &Context,
-                                               ParmVarDecl *Parm) {
+                                               const ParmVarDecl *Parm) {
     return InitializeParameter(Context, Parm, Parm->getType());
   }
 
   /// \brief Create the initialization entity for a parameter, but use
   /// another type.
   static InitializedEntity InitializeParameter(ASTContext &Context,
-                                               ParmVarDecl *Parm,
+                                               const ParmVarDecl *Parm,
                                                QualType Type) {
     bool Consumed = (Context.getLangOpts().ObjCAutoRefCount &&
                      Parm->hasAttr<NSConsumedAttr>());
@@ -263,15 +274,18 @@
   
   /// \brief Create the initialization entity for a temporary.
   static InitializedEntity InitializeTemporary(QualType Type) {
-    InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
-    Result.TypeInfo = nullptr;
-    return Result;
+    return InitializeTemporary(nullptr, Type);
   }
 
   /// \brief Create the initialization entity for a temporary.
   static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) {
-    InitializedEntity Result(EK_Temporary, SourceLocation(), 
-                             TypeInfo->getType());
+    return InitializeTemporary(TypeInfo, TypeInfo->getType());
+  }
+  
+  /// \brief Create the initialization entity for a temporary.
+  static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo,
+                                               QualType Type) {
+    InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
     Result.TypeInfo = TypeInfo;
     return Result;
   }
@@ -299,15 +313,17 @@
   /// \brief Create the initialization entity for a member subobject.
   static InitializedEntity
   InitializeMember(FieldDecl *Member,
-                   const InitializedEntity *Parent = nullptr) {
-    return InitializedEntity(Member, Parent);
+                   const InitializedEntity *Parent = nullptr,
+                   bool Implicit = false) {
+    return InitializedEntity(Member, Parent, Implicit);
   }
   
   /// \brief Create the initialization entity for a member subobject.
   static InitializedEntity
   InitializeMember(IndirectFieldDecl *Member,
-                   const InitializedEntity *Parent = nullptr) {
-    return InitializedEntity(Member->getAnonField(), Parent);
+                   const InitializedEntity *Parent = nullptr,
+                   bool Implicit = false) {
+    return InitializedEntity(Member->getAnonField(), Parent, Implicit);
   }
 
   /// \brief Create the initialization entity for an array element.
@@ -401,6 +417,12 @@
                                       getType()->getAsArrayTypeUnsafe());
   }
 
+  /// \brief Is this the implicit initialization of a member of a class from
+  /// a defaulted constructor?
+  bool isImplicitMemberInitializer() const {
+    return getKind() == EK_Member && Variable.IsImplicitFieldInit;
+  }
+
   /// \brief Determine the location of the 'return' keyword when initializing
   /// the result of a function call.
   SourceLocation getReturnLoc() const {
@@ -560,6 +582,16 @@
     return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal,
                               InitLoc, LParenLoc, RParenLoc);
   }
+
+  /// \brief Create an initialization from an initializer (which, for direct
+  /// initialization from a parenthesized list, will be a ParenListExpr).
+  static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit,
+                                          Expr *Init) {
+    if (!Init) return CreateDefault(Loc);
+    if (!DirectInit) return CreateCopy(Loc, Init->getLocStart());
+    if (isa<InitListExpr>(Init)) return CreateDirectList(Loc);
+    return CreateDirect(Loc, Init->getLocStart(), Init->getLocEnd());
+  }
   
   /// \brief Determine the initialization kind.
   InitKind getKind() const {
@@ -668,6 +700,9 @@
     /// temporary object, which is permitted (but not required) by
     /// C++98/03 but not C++0x.
     SK_ExtraneousCopyToTemporary,
+    /// \brief Direct-initialization from a reference-related object in the
+    /// final stage of class copy-initialization.
+    SK_FinalCopy,
     /// \brief Perform a user-defined conversion, either via a conversion
     /// function or via a constructor.
     SK_UserConversion,
@@ -705,9 +740,14 @@
     /// \brief An initialization that "converts" an Objective-C object
     /// (not a point to an object) to another Objective-C object type.
     SK_ObjCObjectConversion,
+    /// \brief Array indexing for initialization by elementwise copy.
+    SK_ArrayLoopIndex,
+    /// \brief Array initialization by elementwise copy.
+    SK_ArrayLoopInit,
     /// \brief Array initialization (from an array rvalue).
-    /// This is a GNU C extension.
     SK_ArrayInit,
+    /// \brief Array initialization (from an array rvalue) as a GNU extension.
+    SK_GNUArrayInit,
     /// \brief Array initialization from a parenthesized initializer list.
     /// This is a GNU C++ extension.
     SK_ParenthesizedArrayInit,
@@ -724,6 +764,8 @@
     SK_StdInitializerListConstructorCall,
     /// \brief Initialize an OpenCL sampler from an integer.
     SK_OCLSamplerInit,
+    /// \brief Initialize queue_t from 0.
+    SK_OCLZeroQueue,
     /// \brief Passing zero to a function where OpenCL event_t is expected.
     SK_OCLZeroEvent
   };
@@ -805,6 +847,10 @@
     FK_ReferenceInitOverloadFailed,
     /// \brief Non-const lvalue reference binding to a temporary.
     FK_NonConstLValueReferenceBindingToTemporary,
+    /// \brief Non-const lvalue reference binding to a bit-field.
+    FK_NonConstLValueReferenceBindingToBitfield,
+    /// \brief Non-const lvalue reference binding to a vector element.
+    FK_NonConstLValueReferenceBindingToVectorElement,
     /// \brief Non-const lvalue reference binding to an lvalue of unrelated
     /// type.
     FK_NonConstLValueReferenceBindingToUnrelated,
@@ -1028,6 +1074,10 @@
   /// \param T The type of the temporary being created.
   void AddExtraneousCopyToTemporary(QualType T);
 
+  /// \brief Add a new step that makes a copy of the input to an object of
+  /// the given type, as the final step in class copy-initialization.
+  void AddFinalCopy(QualType T);
+
   /// \brief Add a new step invoking a conversion function, which is either
   /// a constructor or a conversion function.
   void AddUserConversionStep(FunctionDecl *Function,
@@ -1085,8 +1135,11 @@
   /// always a no-op.
   void AddObjCObjectConversionStep(QualType T);
 
+  /// \brief Add an array initialization loop step.
+  void AddArrayInitLoopStep(QualType T, QualType EltTy);
+
   /// \brief Add an array initialization step.
-  void AddArrayInitStep(QualType T);
+  void AddArrayInitStep(QualType T, bool IsGNUExtension);
 
   /// \brief Add a parenthesized array initialization step.
   void AddParenthesizedArrayInitStep(QualType T);
@@ -1110,6 +1163,9 @@
   /// constant.
   void AddOCLZeroEventStep(QualType T);
 
+  /// \brief Add a step to initialize an OpenCL queue_t from 0.
+  void AddOCLZeroQueueStep(QualType T);
+
   /// \brief Add steps to unwrap a initializer list for a reference around a
   /// single element and rewrap it at the end.
   void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index 3715720..93e83dc 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -90,6 +90,8 @@
   /// initializers themselves.
   CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override;
 
+  ExtKind hasExternalDefinitions(unsigned ID) override;
+
   /// \brief Find all declarations with the given name in the
   /// given context.
   bool FindExternalVisibleDeclsByName(const DeclContext *DC,
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index f677afe..5220d98 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -83,6 +83,7 @@
     ICK_TransparentUnionConversion, ///< Transparent Union Conversions
     ICK_Writeback_Conversion,  ///< Objective-C ARC writeback conversion
     ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10)
+    ICK_Zero_Queue_Conversion, ///< Zero constant to queue
     ICK_C_Only_Conversion,     ///< Conversions allowed in C, but not C++
     ICK_Incompatible_Pointer_Conversion, ///< C-only conversion between pointers
                                          ///  with incompatible types
@@ -121,7 +122,11 @@
 
     /// A narrowing conversion, because a non-constant-expression variable might
     /// have got narrowed.
-    NK_Variable_Narrowing
+    NK_Variable_Narrowing,
+
+    /// Cannot tell whether this is a narrowing conversion because the
+    /// expression is value-dependent.
+    NK_Dependent_Narrowing,
   };
 
   /// StandardConversionSequence - represents a standard conversion
@@ -526,6 +531,13 @@
       Ambiguous.construct();
     }
 
+    void setAsIdentityConversion(QualType T) {
+      setStandard();
+      Standard.setAsIdentityConversion();
+      Standard.setFromType(T);
+      Standard.setAllToTypes(T);
+    }
+
     /// \brief Whether the target is really a std::initializer_list, and the
     /// sequence only represents the worst element conversion.
     bool isStdInitializerListElement() const {
@@ -592,9 +604,21 @@
     ovl_fail_enable_if,
 
     /// This candidate was not viable because its address could not be taken.
-    ovl_fail_addr_not_available
+    ovl_fail_addr_not_available,
+
+    /// This candidate was not viable because its OpenCL extension is disabled.
+    ovl_fail_ext_disabled,
+
+    /// This inherited constructor is not viable because it would slice the
+    /// argument.
+    ovl_fail_inhctor_slice,
   };
 
+  /// A list of implicit conversion sequences for the arguments of an
+  /// OverloadCandidate.
+  typedef llvm::MutableArrayRef<ImplicitConversionSequence>
+      ConversionSequenceList;
+
   /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
   struct OverloadCandidate {
     /// Function - The actual function that this candidate
@@ -619,18 +643,13 @@
     /// is a surrogate, but only if IsSurrogate is true.
     CXXConversionDecl *Surrogate;
 
-    /// Conversions - The conversion sequences used to convert the
-    /// function arguments to the function parameters, the pointer points to a
-    /// fixed size array with NumConversions elements. The memory is owned by
-    /// the OverloadCandidateSet.
-    ImplicitConversionSequence *Conversions;
+    /// The conversion sequences used to convert the function arguments
+    /// to the function parameters.
+    ConversionSequenceList Conversions;
 
     /// The FixIt hints which can be used to fix the Bad candidate.
     ConversionFixItGenerator Fix;
 
-    /// NumConversions - The number of elements in the Conversions array.
-    unsigned NumConversions;
-
     /// Viable - True to indicate that this overload candidate is viable.
     bool Viable;
 
@@ -669,9 +688,9 @@
     /// hasAmbiguousConversion - Returns whether this overload
     /// candidate requires an ambiguous conversion or not.
     bool hasAmbiguousConversion() const {
-      for (unsigned i = 0, e = NumConversions; i != e; ++i) {
-        if (!Conversions[i].isInitialized()) return false;
-        if (Conversions[i].isAmbiguous()) return true;
+      for (auto &C : Conversions) {
+        if (!C.isInitialized()) return false;
+        if (C.isAmbiguous()) return true;
       }
       return false;
     }
@@ -720,17 +739,43 @@
     SmallVector<OverloadCandidate, 16> Candidates;
     llvm::SmallPtrSet<Decl *, 16> Functions;
 
-    // Allocator for OverloadCandidate::Conversions. We store the first few
-    // elements inline to avoid allocation for small sets.
-    llvm::BumpPtrAllocator ConversionSequenceAllocator;
+    // Allocator for ConversionSequenceLists. We store the first few of these
+    // inline to avoid allocation for small sets.
+    llvm::BumpPtrAllocator SlabAllocator;
 
     SourceLocation Loc;
     CandidateSetKind Kind;
 
-    unsigned NumInlineSequences;
-    llvm::AlignedCharArray<alignof(ImplicitConversionSequence),
-                           16 * sizeof(ImplicitConversionSequence)>
-        InlineSpace;
+    constexpr static unsigned NumInlineBytes =
+        24 * sizeof(ImplicitConversionSequence);
+    unsigned NumInlineBytesUsed;
+    llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace;
+
+    /// If we have space, allocates from inline storage. Otherwise, allocates
+    /// from the slab allocator.
+    /// FIXME: It would probably be nice to have a SmallBumpPtrAllocator
+    /// instead.
+    /// FIXME: Now that this only allocates ImplicitConversionSequences, do we
+    /// want to un-generalize this?
+    template <typename T>
+    T *slabAllocate(unsigned N) {
+      // It's simpler if this doesn't need to consider alignment.
+      static_assert(alignof(T) == alignof(void *),
+                    "Only works for pointer-aligned types.");
+      static_assert(std::is_trivial<T>::value ||
+                        std::is_same<ImplicitConversionSequence, T>::value,
+                    "Add destruction logic to OverloadCandidateSet::clear().");
+
+      unsigned NBytes = sizeof(T) * N;
+      if (NBytes > NumInlineBytes - NumInlineBytesUsed)
+        return SlabAllocator.Allocate<T>(N);
+      char *FreeSpaceStart = InlineSpace.buffer + NumInlineBytesUsed;
+      assert(uintptr_t(FreeSpaceStart) % alignof(void *) == 0 &&
+             "Misaligned storage!");
+
+      NumInlineBytesUsed += NBytes;
+      return reinterpret_cast<T *>(FreeSpaceStart);
+    }
 
     OverloadCandidateSet(const OverloadCandidateSet &) = delete;
     void operator=(const OverloadCandidateSet &) = delete;
@@ -739,7 +784,7 @@
 
   public:
     OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK)
-        : Loc(Loc), Kind(CSK), NumInlineSequences(0) {}
+        : Loc(Loc), Kind(CSK), NumInlineBytesUsed(0) {}
     ~OverloadCandidateSet() { destroyCandidates(); }
 
     SourceLocation getLocation() const { return Loc; }
@@ -761,30 +806,32 @@
     size_t size() const { return Candidates.size(); }
     bool empty() const { return Candidates.empty(); }
 
-    /// \brief Add a new candidate with NumConversions conversion sequence slots
-    /// to the overload set.
-    OverloadCandidate &addCandidate(unsigned NumConversions = 0) {
-      Candidates.push_back(OverloadCandidate());
-      OverloadCandidate &C = Candidates.back();
-
-      // Assign space from the inline array if there are enough free slots
-      // available.
-      if (NumConversions + NumInlineSequences <= 16) {
-        ImplicitConversionSequence *I =
-            (ImplicitConversionSequence *)InlineSpace.buffer;
-        C.Conversions = &I[NumInlineSequences];
-        NumInlineSequences += NumConversions;
-      } else {
-        // Otherwise get memory from the allocator.
-        C.Conversions = ConversionSequenceAllocator
-                          .Allocate<ImplicitConversionSequence>(NumConversions);
-      }
+    /// \brief Allocate storage for conversion sequences for NumConversions
+    /// conversions.
+    ConversionSequenceList
+    allocateConversionSequences(unsigned NumConversions) {
+      ImplicitConversionSequence *Conversions =
+          slabAllocate<ImplicitConversionSequence>(NumConversions);
 
       // Construct the new objects.
-      for (unsigned i = 0; i != NumConversions; ++i)
-        new (&C.Conversions[i]) ImplicitConversionSequence();
+      for (unsigned I = 0; I != NumConversions; ++I)
+        new (&Conversions[I]) ImplicitConversionSequence();
 
-      C.NumConversions = NumConversions;
+      return ConversionSequenceList(Conversions, NumConversions);
+    }
+
+    /// \brief Add a new candidate with NumConversions conversion sequence slots
+    /// to the overload set.
+    OverloadCandidate &addCandidate(unsigned NumConversions = 0,
+                                    ConversionSequenceList Conversions = None) {
+      assert((Conversions.empty() || Conversions.size() == NumConversions) &&
+             "preallocated conversion sequence has wrong length");
+
+      Candidates.push_back(OverloadCandidate());
+      OverloadCandidate &C = Candidates.back();
+      C.Conversions = Conversions.empty()
+                          ? allocateConversionSequences(NumConversions)
+                          : Conversions;
       return C;
     }
 
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index 92ea529..848837a 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -153,8 +153,8 @@
     ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
 
     // These two overloads prevent void* -> bool conversions.
-    ActionResult(const void *);
-    ActionResult(volatile void *);
+    ActionResult(const void *) = delete;
+    ActionResult(volatile void *) = delete;
 
     bool isInvalid() const { return Invalid; }
     bool isUsable() const { return !Invalid && Val; }
@@ -192,8 +192,8 @@
     ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { }
 
     // These two overloads prevent void* -> bool conversions.
-    ActionResult(const void *);
-    ActionResult(volatile void *);
+    ActionResult(const void *) = delete;
+    ActionResult(volatile void *) = delete;
 
     bool isInvalid() const { return PtrWithInvalid & 0x01; }
     bool isUsable() const { return PtrWithInvalid > 0x01; }
@@ -257,6 +257,7 @@
 
   typedef ActionResult<Decl*> DeclResult;
   typedef OpaquePtr<TemplateName> ParsedTemplateTy;
+  typedef UnionOpaquePtr<TemplateName> UnionParsedTemplateTy;
 
   typedef MutableArrayRef<Expr*> MultiExprArg;
   typedef MutableArrayRef<Stmt*> MultiStmtArg;
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 4b54807..4487c7c 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -24,6 +24,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
 #include <algorithm>
 
 namespace clang {
@@ -135,6 +136,18 @@
   /// false if there is an invocation of an initializer on 'self'.
   bool ObjCWarnForNoInitDelegation : 1;
 
+  /// \brief True only when this function has not already built, or attempted
+  /// to build, the initial and final coroutine suspend points
+  bool NeedsCoroutineSuspends : 1;
+
+  /// \brief An enumeration represeting the kind of the first coroutine statement
+  /// in the function. One of co_return, co_await, or co_yield.
+  unsigned char FirstCoroutineStmtKind : 2;
+
+  /// First coroutine statement in the current function.
+  /// (ex co_return, co_await, co_yield)
+  SourceLocation FirstCoroutineStmtLoc;
+
   /// First 'return' statement in the current function.
   SourceLocation FirstReturnLoc;
 
@@ -157,12 +170,10 @@
   SmallVector<ReturnStmt*, 4> Returns;
 
   /// \brief The promise object for this coroutine, if any.
-  VarDecl *CoroutinePromise;
+  VarDecl *CoroutinePromise = nullptr;
 
-  /// \brief The list of coroutine control flow constructs (co_await, co_yield,
-  /// co_return) that occur within the function or block. Empty if and only if
-  /// this function or block is not (yet known to be) a coroutine.
-  SmallVector<Stmt*, 4> CoroutineStmts;
+  /// \brief The initial and final coroutine suspend points.
+  std::pair<Stmt *, Stmt *> CoroutineSuspends;
 
   /// \brief The stack of currently active compound stamement scopes in the
   /// function.
@@ -376,7 +387,47 @@
         (HasIndirectGoto ||
           (HasBranchProtectedScope && HasBranchIntoScope));
   }
-  
+
+  void setFirstCoroutineStmt(SourceLocation Loc, StringRef Keyword) {
+    assert(FirstCoroutineStmtLoc.isInvalid() &&
+                   "first coroutine statement location already set");
+    FirstCoroutineStmtLoc = Loc;
+    FirstCoroutineStmtKind = llvm::StringSwitch<unsigned char>(Keyword)
+            .Case("co_return", 0)
+            .Case("co_await", 1)
+            .Case("co_yield", 2);
+  }
+
+  StringRef getFirstCoroutineStmtKeyword() const {
+    assert(FirstCoroutineStmtLoc.isValid()
+                   && "no coroutine statement available");
+    switch (FirstCoroutineStmtKind) {
+    case 0: return "co_return";
+    case 1: return "co_await";
+    case 2: return "co_yield";
+    default:
+      llvm_unreachable("FirstCoroutineStmtKind has an invalid value");
+    };
+  }
+
+  void setNeedsCoroutineSuspends(bool value = true) {
+    assert((!value || CoroutineSuspends.first == nullptr) &&
+            "we already have valid suspend points");
+    NeedsCoroutineSuspends = value;
+  }
+
+  bool hasInvalidCoroutineSuspends() const {
+    return !NeedsCoroutineSuspends && CoroutineSuspends.first == nullptr;
+  }
+
+  void setCoroutineSuspends(Stmt *Initial, Stmt *Final) {
+    assert(Initial && Final && "suspend points cannot be null");
+    assert(CoroutineSuspends.first == nullptr && "suspend points already set");
+    NeedsCoroutineSuspends = false;
+    CoroutineSuspends.first = Initial;
+    CoroutineSuspends.second = Final;
+  }
+
   FunctionScopeInfo(DiagnosticsEngine &Diag)
     : Kind(SK_Function),
       HasBranchProtectedScope(false),
@@ -391,6 +442,7 @@
       ObjCWarnForNoDesignatedInitChain(false),
       ObjCIsSecondaryInit(false),
       ObjCWarnForNoInitDelegation(false),
+      NeedsCoroutineSuspends(true),
       ErrorTrap(Diag) { }
 
   virtual ~FunctionScopeInfo();
@@ -452,6 +504,14 @@
     /// non-static data member that would hold the capture.
     QualType CaptureType;
 
+    /// \brief Whether an explicit capture has been odr-used in the body of the
+    /// lambda.
+    bool ODRUsed;
+
+    /// \brief Whether an explicit capture has been non-odr-used in the body of
+    /// the lambda.
+    bool NonODRUsed;
+
   public:
     Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
             SourceLocation Loc, SourceLocation EllipsisLoc,
@@ -460,7 +520,8 @@
           InitExprAndCaptureKind(
               Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
                                                               : Cap_ByCopy),
-          Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
+          Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType),
+          ODRUsed(false), NonODRUsed(false) {}
 
     enum IsThisCapture { ThisCapture };
     Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
@@ -468,7 +529,8 @@
         : VarAndNestedAndThis(
               nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
           InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
-          Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {}
+          Loc(Loc), EllipsisLoc(), CaptureType(CaptureType), ODRUsed(false),
+          NonODRUsed(false) {}
 
     bool isThisCapture() const {
       return VarAndNestedAndThis.getInt() & IsThisCaptured;
@@ -491,6 +553,9 @@
     bool isNested() const {
       return VarAndNestedAndThis.getInt() & IsNestedCapture;
     }
+    bool isODRUsed() const { return ODRUsed; }
+    bool isNonODRUsed() const { return NonODRUsed; }
+    void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
 
     VarDecl *getVariable() const {
       return VarAndNestedAndThis.getPointer();
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 8afa6e1..6995740 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -26,7 +26,9 @@
 #include "clang/AST/MangleNumberingContext.h"
 #include "clang/AST/NSAPI.h"
 #include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/StmtCXX.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/ExpressionTraits.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Module.h"
@@ -100,6 +102,7 @@
   class CodeCompletionAllocator;
   class CodeCompletionTUInfo;
   class CodeCompletionResult;
+  class CoroutineBodyStmt;
   class Decl;
   class DeclAccessPair;
   class DeclContext;
@@ -119,6 +122,7 @@
   class FunctionProtoType;
   class FunctionTemplateDecl;
   class ImplicitConversionSequence;
+  typedef MutableArrayRef<ImplicitConversionSequence> ConversionSequenceList;
   class InitListExpr;
   class InitializationKind;
   class InitializationSequence;
@@ -455,9 +459,9 @@
   /// \brief Store a list of either DeclRefExprs or MemberExprs
   ///  that contain a reference to a variable (constant) that may or may not
   ///  be odr-used in this Expr, and we won't know until all lvalue-to-rvalue
-  ///  and discarded value conversions have been applied to all subexpressions 
-  ///  of the enclosing full expression.  This is cleared at the end of each 
-  ///  full expression. 
+  ///  and discarded value conversions have been applied to all subexpressions
+  ///  of the enclosing full expression.  This is cleared at the end of each
+  ///  full expression.
   llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs;
 
   /// \brief Stack containing information about each of the nested
@@ -671,15 +675,15 @@
   class SynthesizedFunctionScope {
     Sema &S;
     Sema::ContextRAII SavedContext;
-    
+
   public:
     SynthesizedFunctionScope(Sema &S, DeclContext *DC)
-      : S(S), SavedContext(S, DC) 
+      : S(S), SavedContext(S, DC)
     {
       S.PushFunctionScope();
       S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
     }
-    
+
     ~SynthesizedFunctionScope() {
       S.PopExpressionEvaluationContext();
       S.PopFunctionScopeInfo();
@@ -793,7 +797,7 @@
   bool GlobalNewDeleteDeclared;
 
   /// A flag to indicate that we're in a context that permits abstract
-  /// references to fields.  This is really a 
+  /// references to fields.  This is really a
   bool AllowAbstractFieldReference;
 
   /// \brief Describes how the expressions currently being parsed are
@@ -806,6 +810,12 @@
     /// run time.
     Unevaluated,
 
+    /// \brief The current expression occurs within a braced-init-list within
+    /// an unevaluated operand. This is mostly like a regular unevaluated
+    /// context, except that we still instantiate constexpr functions that are
+    /// referenced here so that we can perform narrowing checks correctly.
+    UnevaluatedList,
+
     /// \brief The current expression occurs within a discarded statement.
     /// This behaves largely similarly to an unevaluated operand in preventing
     /// definitions from being required, but not in other ways.
@@ -898,7 +908,8 @@
     MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx);
 
     bool isUnevaluated() const {
-      return Context == Unevaluated || Context == UnevaluatedAbstract;
+      return Context == Unevaluated || Context == UnevaluatedAbstract ||
+             Context == UnevaluatedList;
     }
   };
 
@@ -922,7 +933,7 @@
   ///
   /// This is basically a wrapper around PointerIntPair. The lowest bits of the
   /// integer are used to determine whether overload resolution succeeded.
-  class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
+  class SpecialMemberOverloadResult {
   public:
     enum Kind {
       NoMemberOrDeleted,
@@ -934,9 +945,9 @@
     llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
 
   public:
-    SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID)
-      : FastFoldingSetNode(ID)
-    {}
+    SpecialMemberOverloadResult() : Pair() {}
+    SpecialMemberOverloadResult(CXXMethodDecl *MD)
+        : Pair(MD, MD->isDeleted() ? NoMemberOrDeleted : Success) {}
 
     CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
     void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
@@ -945,9 +956,18 @@
     void setKind(Kind K) { Pair.setInt(K); }
   };
 
+  class SpecialMemberOverloadResultEntry
+      : public llvm::FastFoldingSetNode,
+        public SpecialMemberOverloadResult {
+  public:
+    SpecialMemberOverloadResultEntry(const llvm::FoldingSetNodeID &ID)
+      : FastFoldingSetNode(ID)
+    {}
+  };
+
   /// \brief A cache of special member function overload resolution results
   /// for C++ records.
-  llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache;
+  llvm::FoldingSet<SpecialMemberOverloadResultEntry> SpecialMemberCache;
 
   /// \brief A cache of the flags available in enumerations with the flag_bits
   /// attribute.
@@ -1184,7 +1204,7 @@
   /// is during Parsing.  Currently it is used to pass on the depth
   /// when parsing generic lambda 'auto' parameters.
   void RecordParsingTemplateParameterDepth(unsigned Depth);
-  
+
   void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD,
                                RecordDecl *RD,
                                CapturedRegionKind K);
@@ -1196,11 +1216,11 @@
   sema::FunctionScopeInfo *getCurFunction() const {
     return FunctionScopes.back();
   }
-  
+
   sema::FunctionScopeInfo *getEnclosingFunction() const {
     if (FunctionScopes.empty())
       return nullptr;
-    
+
     for (int e = FunctionScopes.size()-1; e >= 0; --e) {
       if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
         continue;
@@ -1208,13 +1228,13 @@
     }
     return nullptr;
   }
-  
+
   template <typename ExprT>
   void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
     if (!isUnevaluatedContext())
       getCurFunction()->recordUseOfWeak(E, IsRead);
   }
-  
+
   void PushCompoundScope();
   void PopCompoundScope();
 
@@ -1226,9 +1246,11 @@
   sema::BlockScopeInfo *getCurBlock();
 
   /// Retrieve the current lambda scope info, if any.
-  /// \param IgnoreCapturedRegions true if should find the top-most lambda scope
-  /// info ignoring all inner captured regions scope infos.
-  sema::LambdaScopeInfo *getCurLambda(bool IgnoreCapturedRegions = false);
+  /// \param IgnoreNonLambdaCapturingScope true if should find the top-most
+  /// lambda scope info ignoring all inner capturing scopes that are not
+  /// lambda scopes.
+  sema::LambdaScopeInfo *
+  getCurLambda(bool IgnoreNonLambdaCapturingScope = false);
 
   /// \brief Retrieve the current generic lambda info, if any.
   sema::LambdaScopeInfo *getCurGenericLambda();
@@ -1527,12 +1549,6 @@
     NamedDecl *Previous;
   };
 
-  /// List of decls defined in a function prototype. This contains EnumConstants
-  /// that incorrectly end up in translation unit scope because there is no
-  /// function to pin them on. ActOnFunctionDeclarator reads this list and patches
-  /// them into the FunctionDecl.
-  std::vector<NamedDecl*> DeclsInPrototypeScope;
-
   DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr);
 
   void DiagnoseUseOfUnimplementedSelectors();
@@ -1545,6 +1561,7 @@
                          ParsedType ObjectType = nullptr,
                          bool IsCtorOrDtorName = false,
                          bool WantNontrivialTypeSourceInfo = false,
+                         bool IsClassTemplateDeductionContext = true,
                          IdentifierInfo **CorrectedII = nullptr);
   TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
   bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S);
@@ -1686,6 +1703,18 @@
                bool IsAddressOfOperand,
                std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
 
+  /// Describes the detailed kind of a template name. Used in diagnostics.
+  enum class TemplateNameKindForDiagnostics {
+    ClassTemplate,
+    FunctionTemplate,
+    VarTemplate,
+    AliasTemplate,
+    TemplateTemplateParam,
+    DependentTemplate
+  };
+  TemplateNameKindForDiagnostics
+  getTemplateNameKindForDiagnostics(TemplateName Name);
+
   Decl *ActOnDeclarator(Scope *S, Declarator &D);
 
   NamedDecl *HandleDeclarator(Scope *S, Declarator &D,
@@ -1706,7 +1735,8 @@
 
   static bool adjustContextForLocalExternDecl(DeclContext *&DC);
   void DiagnoseFunctionSpecifiers(const DeclSpec &DS);
-  void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
+  NamedDecl *getShadowedDeclaration(const VarDecl *D, const LookupResult &R);
+  void CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl, const LookupResult &R);
   void CheckShadow(Scope *S, VarDecl *D);
 
   /// Warn if 'E', which is an expression that is about to be modified, refers
@@ -1743,6 +1773,8 @@
   // Returns true if the variable declaration is a redeclaration
   bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
   void CheckVariableDeclarationType(VarDecl *NewVD);
+  bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
+                                     Expr *Init);
   void CheckCompleteVariableDeclaration(VarDecl *VD);
   void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD);
   void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
@@ -1765,7 +1797,7 @@
   // Returns true if the function declaration is a redeclaration
   bool CheckFunctionDeclaration(Scope *S,
                                 FunctionDecl *NewFD, LookupResult &Previous,
-                                bool IsExplicitSpecialization);
+                                bool IsMemberSpecialization);
   bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl);
   void CheckMain(FunctionDecl *FD, const DeclSpec &D);
   void CheckMSVCRTEntryPoint(FunctionDecl *FD);
@@ -1787,9 +1819,8 @@
   bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
                                SourceLocation EqualLoc);
 
-  void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit,
-                            bool TypeMayContainAuto);
-  void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto);
+  void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit);
+  void ActOnUninitializedDecl(Decl *dcl);
   void ActOnInitializerError(Decl *Dcl);
   bool canInitializeWithParenthesizedList(QualType TargetType);
 
@@ -1804,8 +1835,7 @@
   void FinalizeDeclaration(Decl *D);
   DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
                                          ArrayRef<Decl *> Group);
-  DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
-                                      bool TypeMayContainAuto = true);
+  DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group);
 
   /// Should be called on all declarations that might have attached
   /// documentation comments.
@@ -1982,7 +2012,10 @@
   /// Common ways to introduce type names without a tag for use in diagnostics.
   /// Keep in sync with err_tag_reference_non_tag.
   enum NonTagKind {
-    NTK_Unknown,
+    NTK_NonStruct,
+    NTK_NonClass,
+    NTK_NonUnion,
+    NTK_NonEnum,
     NTK_Typedef,
     NTK_TypeAlias,
     NTK_Template,
@@ -1992,7 +2025,7 @@
 
   /// Given a non-tag type declaration, returns an enum useful for indicating
   /// what kind of non-tag type this is.
-  NonTagKind getNonTagTypeDeclKind(const Decl *D);
+  NonTagKind getNonTagTypeDeclKind(const Decl *D, TagTypeKind TTK);
 
   bool isAcceptableTagRedeclaration(const TagDecl *Previous,
                                     TagTypeKind NewTag, bool isDefinition,
@@ -2513,10 +2546,11 @@
   void AddOverloadCandidate(FunctionDecl *Function,
                             DeclAccessPair FoundDecl,
                             ArrayRef<Expr *> Args,
-                            OverloadCandidateSet& CandidateSet,
+                            OverloadCandidateSet &CandidateSet,
                             bool SuppressUserConversions = false,
                             bool PartialOverloading = false,
-                            bool AllowExplicit = false);
+                            bool AllowExplicit = false,
+                            ConversionSequenceList EarlyConversions = None);
   void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
                       ArrayRef<Expr *> Args,
                       OverloadCandidateSet &CandidateSet,
@@ -2536,7 +2570,8 @@
                           ArrayRef<Expr *> Args,
                           OverloadCandidateSet& CandidateSet,
                           bool SuppressUserConversions = false,
-                          bool PartialOverloading = false);
+                          bool PartialOverloading = false,
+                          ConversionSequenceList EarlyConversions = None);
   void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
                                   DeclAccessPair FoundDecl,
                                   CXXRecordDecl *ActingContext,
@@ -2554,6 +2589,16 @@
                                     OverloadCandidateSet& CandidateSet,
                                     bool SuppressUserConversions = false,
                                     bool PartialOverloading = false);
+  bool CheckNonDependentConversions(FunctionTemplateDecl *FunctionTemplate,
+                                    ArrayRef<QualType> ParamTypes,
+                                    ArrayRef<Expr *> Args,
+                                    OverloadCandidateSet &CandidateSet,
+                                    ConversionSequenceList &Conversions,
+                                    bool SuppressUserConversions,
+                                    CXXRecordDecl *ActingContext = nullptr,
+                                    QualType ObjectType = QualType(),
+                                    Expr::Classification
+                                        ObjectClassification = {});
   void AddConversionCandidate(CXXConversionDecl *Conversion,
                               DeclAccessPair FoundDecl,
                               CXXRecordDecl *ActingContext,
@@ -2577,7 +2622,7 @@
                                    OverloadCandidateSet& CandidateSet,
                                    SourceRange OpRange = SourceRange());
   void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
-                           ArrayRef<Expr *> Args, 
+                           ArrayRef<Expr *> Args,
                            OverloadCandidateSet& CandidateSet,
                            bool IsAssignmentOperator = false,
                            unsigned NumContextualBoolArguments = 0);
@@ -2606,6 +2651,28 @@
   EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
                               bool MissingImplicitThis = false);
 
+  /// Emit diagnostics for the diagnose_if attributes on Function, ignoring any
+  /// non-ArgDependent DiagnoseIfAttrs.
+  ///
+  /// Argument-dependent diagnose_if attributes should be checked each time a
+  /// function is used as a direct callee of a function call.
+  ///
+  /// Returns true if any errors were emitted.
+  bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function,
+                                           const Expr *ThisArg,
+                                           ArrayRef<const Expr *> Args,
+                                           SourceLocation Loc);
+
+  /// Emit diagnostics for the diagnose_if attributes on Function, ignoring any
+  /// ArgDependent DiagnoseIfAttrs.
+  ///
+  /// Argument-independent diagnose_if attributes should be checked on every use
+  /// of a function.
+  ///
+  /// Returns true if any errors were emitted.
+  bool diagnoseArgIndependentDiagnoseIfAttrs(const FunctionDecl *Function,
+                                             SourceLocation Loc);
+
   /// Returns whether the given function's address can be taken or not,
   /// optionally emitting a diagnostic if the address can't be taken.
   ///
@@ -2837,13 +2904,13 @@
     LOLR_StringTemplate
   };
 
-  SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D,
-                                                   CXXSpecialMember SM,
-                                                   bool ConstArg,
-                                                   bool VolatileArg,
-                                                   bool RValueThis,
-                                                   bool ConstThis,
-                                                   bool VolatileThis);
+  SpecialMemberOverloadResult LookupSpecialMember(CXXRecordDecl *D,
+                                                  CXXSpecialMember SM,
+                                                  bool ConstArg,
+                                                  bool VolatileArg,
+                                                  bool RValueThis,
+                                                  bool ConstThis,
+                                                  bool VolatileThis);
 
   typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator;
   typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)>
@@ -3059,6 +3126,8 @@
   void ProcessPragmaWeak(Scope *S, Decl *D);
   // Decl attributes - this routine is the top level dispatcher.
   void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
+  // Helper for delayed proccessing of attributes.
+  void ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList);
   void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
                                 bool IncludeCXX11Attributes = true);
   bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
@@ -3073,7 +3142,7 @@
   bool isValidPointerAttrType(QualType T, bool RefOkay = false);
 
   bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
-  bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 
+  bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
                             const FunctionDecl *FD = nullptr);
   bool CheckNoReturnAttr(const AttributeList &attr);
   bool checkStringLiteralArgumentAttr(const AttributeList &Attr,
@@ -3145,7 +3214,6 @@
                              bool IsProtocolMethodDecl);
 
   typedef llvm::SmallPtrSet<Selector, 8> SelectorSet;
-  typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap;
 
   /// CheckImplementationIvars - This routine checks if the instance variables
   /// listed in the implelementation match those listed in the interface.
@@ -3179,18 +3247,18 @@
   /// declared in class 'IFace'.
   bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace,
                                       ObjCMethodDecl *Method, ObjCIvarDecl *IV);
-  
+
   /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which
   /// backs the property is not used in the property's accessor.
   void DiagnoseUnusedBackingIvarInAccessor(Scope *S,
                                            const ObjCImplementationDecl *ImplD);
-  
+
   /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and
   /// it property has a backing ivar, returns this ivar; otherwise, returns NULL.
   /// It also returns ivar's property on success.
   ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
                                                const ObjCPropertyDecl *&PDecl) const;
-  
+
   /// Called by ActOnProperty to handle \@property declarations in
   /// class extensions.
   ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S,
@@ -3290,12 +3358,12 @@
                                      SmallVectorImpl<ObjCMethodDecl*>& Methods,
                                      bool InstanceFirst, bool CheckTheOther,
                                      const ObjCObjectType *TypeBound = nullptr);
-    
+
   bool
   AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod,
                                  SourceRange R, bool receiverIdOrClass,
                                  SmallVectorImpl<ObjCMethodDecl*>& Methods);
-      
+
   void
   DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods,
                                      Selector Sel, SourceRange R,
@@ -3307,7 +3375,7 @@
   ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args,
                                    bool IsInstance,
                                    SmallVectorImpl<ObjCMethodDecl*>& Methods);
-    
+
 
   /// \brief Record the typo correction failure and return an empty correction.
   TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc,
@@ -3780,16 +3848,16 @@
   ///
   /// \param FunctionScopeIndexToStopAt If non-null, it points to the index
   /// of the FunctionScopeInfo stack beyond which we do not attempt to capture.
-  /// This is useful when enclosing lambdas must speculatively capture 
+  /// This is useful when enclosing lambdas must speculatively capture
   /// variables that may or may not be used in certain specializations of
   /// a nested generic lambda.
-  /// 
+  ///
   /// \returns true if an error occurred (i.e., the variable cannot be
   /// captured) and false if the capture succeeded.
   bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind,
                           SourceLocation EllipsisLoc, bool BuildAndDiagnose,
                           QualType &CaptureType,
-                          QualType &DeclRefType, 
+                          QualType &DeclRefType,
                           const unsigned *const FunctionScopeIndexToStopAt);
 
   /// \brief Try to capture the given variable.
@@ -3804,6 +3872,9 @@
   /// variable will have in the given scope.
   QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc);
 
+  /// Mark all of the declarations referenced within a particular AST node as
+  /// referenced. Used when template instantiation instantiates a non-dependent
+  /// type -- entities referenced by the type are now referenced.
   void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
   void MarkDeclarationsReferencedInExpr(Expr *E,
                                         bool SkipLocalVariables = false);
@@ -4286,7 +4357,7 @@
 
   /// \brief Determine whether Ctor is an initializer-list constructor, as
   /// defined in [dcl.init.list]p2.
-  bool isInitListConstructor(const CXXConstructorDecl *Ctor);
+  bool isInitListConstructor(const FunctionDecl *Ctor);
 
   Decl *ActOnUsingDirective(Scope *CurScope,
                             SourceLocation UsingLoc,
@@ -4320,18 +4391,22 @@
                                    SourceLocation NameLoc,
                                    const LookupResult &Previous);
   bool CheckUsingDeclQualifier(SourceLocation UsingLoc,
+                               bool HasTypename,
                                const CXXScopeSpec &SS,
                                const DeclarationNameInfo &NameInfo,
                                SourceLocation NameLoc);
 
   NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
                                    SourceLocation UsingLoc,
+                                   bool HasTypenameKeyword,
+                                   SourceLocation TypenameLoc,
                                    CXXScopeSpec &SS,
                                    DeclarationNameInfo NameInfo,
+                                   SourceLocation EllipsisLoc,
                                    AttributeList *AttrList,
-                                   bool IsInstantiation,
-                                   bool HasTypenameKeyword,
-                                   SourceLocation TypenameLoc);
+                                   bool IsInstantiation);
+  NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom,
+                                ArrayRef<NamedDecl *> Expansions);
 
   bool CheckInheritingConstructorUsingDecl(UsingDecl *UD);
 
@@ -4344,13 +4419,12 @@
 
   Decl *ActOnUsingDeclaration(Scope *CurScope,
                               AccessSpecifier AS,
-                              bool HasUsingKeyword,
                               SourceLocation UsingLoc,
+                              SourceLocation TypenameLoc,
                               CXXScopeSpec &SS,
                               UnqualifiedId &Name,
-                              AttributeList *AttrList,
-                              bool HasTypenameKeyword,
-                              SourceLocation TypenameLoc);
+                              SourceLocation EllipsisLoc,
+                              AttributeList *AttrList);
   Decl *ActOnAliasDeclaration(Scope *CurScope,
                               AccessSpecifier AS,
                               MultiTemplateParamsArg TemplateParams,
@@ -4692,7 +4766,8 @@
                                ParsedType ObjectType,
                                bool EnteringContext);
 
-  ParsedType getDestructorType(const DeclSpec& DS, ParsedType ObjectType);
+  ParsedType getDestructorTypeForDecltype(const DeclSpec &DS,
+                                          ParsedType ObjectType);
 
   // Checks that reinterpret casts don't have undefined behavior.
   void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
@@ -4798,12 +4873,12 @@
   ///
   /// \param FunctionScopeIndexToStopAt If non-null, it points to the index
   /// of the FunctionScopeInfo stack beyond which we do not attempt to capture.
-  /// This is useful when enclosing lambdas must speculatively capture 
+  /// This is useful when enclosing lambdas must speculatively capture
   /// 'this' that may or may not be used in certain specializations of
-  /// a nested generic lambda (depending on whether the name resolves to 
+  /// a nested generic lambda (depending on whether the name resolves to
   /// a non-static member function or a static function).
   /// \return returns 'true' if failed, 'false' if success.
-  bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, 
+  bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false,
       bool BuildAndDiagnose = true,
       const unsigned *const FunctionScopeIndexToStopAt = nullptr,
       bool ByCopy = false);
@@ -4863,8 +4938,7 @@
                          TypeSourceInfo *AllocTypeInfo,
                          Expr *ArraySize,
                          SourceRange DirectInitRange,
-                         Expr *Initializer,
-                         bool TypeMayContainAuto = true);
+                         Expr *Initializer);
 
   bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
                           SourceRange R);
@@ -5193,7 +5267,7 @@
   /// \brief Create a new lambda closure type.
   CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange,
                                          TypeSourceInfo *Info,
-                                         bool KnownDependent, 
+                                         bool KnownDependent,
                                          LambdaCaptureDefault CaptureDefault);
 
   /// \brief Start the definition of a lambda expression.
@@ -5201,11 +5275,11 @@
                                        SourceRange IntroducerRange,
                                        TypeSourceInfo *MethodType,
                                        SourceLocation EndLoc,
-                                       ArrayRef<ParmVarDecl *> Params, 
+                                       ArrayRef<ParmVarDecl *> Params,
                                        bool IsConstexprSpecified);
 
   /// \brief Endow the lambda scope info with the relevant properties.
-  void buildLambdaScope(sema::LambdaScopeInfo *LSI, 
+  void buildLambdaScope(sema::LambdaScopeInfo *LSI,
                         CXXMethodDecl *CallOperator,
                         SourceRange IntroducerRange,
                         LambdaCaptureDefault CaptureDefault,
@@ -5229,7 +5303,7 @@
 
   /// \brief Create a dummy variable within the declcontext of the lambda's
   ///  call operator, for name lookup purposes for a lambda init capture.
-  ///  
+  ///
   ///  CodeGen handles emission of lambda captures, ignoring these dummy
   ///  variables appropriately.
   VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc,
@@ -5268,6 +5342,12 @@
   ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
                              Scope *CurScope);
 
+  /// \brief Does copying/destroying the captured variable have side effects?
+  bool CaptureHasSideEffects(const sema::LambdaScopeInfo::Capture &From);
+
+  /// \brief Diagnose if an explicit lambda capture is unused.
+  void DiagnoseUnusedLambdaCapture(const sema::LambdaScopeInfo::Capture &From);
+
   /// \brief Complete a lambda-expression having processed and attached the
   /// lambda body.
   ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
@@ -5560,6 +5640,9 @@
   void CheckConversionDeclarator(Declarator &D, QualType &R,
                                  StorageClass& SC);
   Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
+  void CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
+                                     StorageClass &SC);
+  void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD);
 
   void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD);
   void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD,
@@ -5628,7 +5711,7 @@
 
   /// CheckOverrideControl - Check C++11 override control semantics.
   void CheckOverrideControl(NamedDecl *D);
-    
+
   /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was
   /// not used in the declaration of an overriding method.
   void DiagnoseAbsenceOfOverrideControl(NamedDecl *D);
@@ -5763,6 +5846,12 @@
                                   TemplateTy &Template,
                                   bool &MemberOfUnknownSpecialization);
 
+  /// Determine whether a particular identifier might be the name in a C++1z
+  /// deduction-guide declaration.
+  bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name,
+                            SourceLocation NameLoc,
+                            ParsedTemplateTy *Template = nullptr);
+
   bool DiagnoseUnknownTemplateName(const IdentifierInfo &II,
                                    SourceLocation IILoc,
                                    Scope *S,
@@ -5790,7 +5879,10 @@
                            SourceLocation EqualLoc,
                            ParsedType DefaultArg);
 
+  QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI,
+                                             SourceLocation Loc);
   QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
+
   Decl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
                                       unsigned Depth,
                                       unsigned Position,
@@ -5835,7 +5927,7 @@
       SourceLocation DeclStartLoc, SourceLocation DeclLoc,
       const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId,
       ArrayRef<TemplateParameterList *> ParamLists,
-      bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid);
+      bool IsFriend, bool &IsMemberSpecialization, bool &Invalid);
 
   DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
                                 SourceLocation KWLoc, CXXScopeSpec &SS,
@@ -5864,11 +5956,13 @@
 
   TypeResult
   ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
-                      TemplateTy Template, SourceLocation TemplateLoc,
+                      TemplateTy Template, IdentifierInfo *TemplateII,
+                      SourceLocation TemplateIILoc,
                       SourceLocation LAngleLoc,
                       ASTTemplateArgsPtr TemplateArgs,
                       SourceLocation RAngleLoc,
-                      bool IsCtorOrDtorName = false);
+                      bool IsCtorOrDtorName = false,
+                      bool IsClassName = false);
 
   /// \brief Parsed an elaborated-type-specifier that refers to a template-id,
   /// such as \c class T::template apply<U>.
@@ -5910,13 +6004,10 @@
                                const DeclarationNameInfo &NameInfo,
                                const TemplateArgumentListInfo *TemplateArgs);
 
-  TemplateNameKind ActOnDependentTemplateName(Scope *S,
-                                              CXXScopeSpec &SS,
-                                              SourceLocation TemplateKWLoc,
-                                              UnqualifiedId &Name,
-                                              ParsedType ObjectType,
-                                              bool EnteringContext,
-                                              TemplateTy &Template);
+  TemplateNameKind ActOnDependentTemplateName(
+      Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
+      UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext,
+      TemplateTy &Template, bool AllowInjectedClassName = false);
 
   DeclResult
   ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
@@ -5927,6 +6018,15 @@
                                  MultiTemplateParamsArg TemplateParameterLists,
                                    SkipBodyInfo *SkipBody = nullptr);
 
+  bool CheckTemplatePartialSpecializationArgs(SourceLocation Loc,
+                                              TemplateDecl *PrimaryTemplate,
+                                              unsigned NumExplicitArgs,
+                                              ArrayRef<TemplateArgument> Args);
+  void CheckTemplatePartialSpecialization(
+      ClassTemplatePartialSpecializationDecl *Partial);
+  void CheckTemplatePartialSpecialization(
+      VarTemplatePartialSpecializationDecl *Partial);
+
   Decl *ActOnTemplateDeclarator(Scope *S,
                                 MultiTemplateParamsArg TemplateParameterLists,
                                 Declarator &D);
@@ -6032,12 +6132,17 @@
   /// \param Converted Will receive the converted, canonicalized template
   /// arguments.
   ///
+  /// \param UpdateArgsWithConversions If \c true, update \p TemplateArgs to
+  /// contain the converted forms of the template arguments as written.
+  /// Otherwise, \p TemplateArgs will not be modified.
+  ///
   /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(TemplateDecl *Template,
                                  SourceLocation TemplateLoc,
                                  TemplateArgumentListInfo &TemplateArgs,
                                  bool PartialTemplateArgs,
-                           SmallVectorImpl<TemplateArgument> &Converted);
+                                 SmallVectorImpl<TemplateArgument> &Converted,
+                                 bool UpdateArgsWithConversions = true);
 
   bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
                                  TemplateArgumentLoc &Arg,
@@ -6126,7 +6231,8 @@
   /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
   /// \param TemplateLoc the location of the 'template' keyword, if any.
   /// \param TemplateName The template name.
-  /// \param TemplateNameLoc The location of the template name.
+  /// \param TemplateII The identifier used to name the template.
+  /// \param TemplateIILoc The location of the template name.
   /// \param LAngleLoc The location of the opening angle bracket  ('<').
   /// \param TemplateArgs The template arguments.
   /// \param RAngleLoc The location of the closing angle bracket  ('>').
@@ -6135,7 +6241,8 @@
                     const CXXScopeSpec &SS,
                     SourceLocation TemplateLoc,
                     TemplateTy TemplateName,
-                    SourceLocation TemplateNameLoc,
+                    IdentifierInfo *TemplateII,
+                    SourceLocation TemplateIILoc,
                     SourceLocation LAngleLoc,
                     ASTTemplateArgsPtr TemplateArgs,
                     SourceLocation RAngleLoc);
@@ -6353,9 +6460,9 @@
   /// \brief Collect the set of unexpanded parameter packs within the given
   /// nested-name-specifier.
   ///
-  /// \param SS The nested-name-specifier that will be traversed to find
+  /// \param NNS The nested-name-specifier that will be traversed to find
   /// unexpanded parameter packs.
-  void collectUnexpandedParameterPacks(CXXScopeSpec &SS,
+  void collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS,
                          SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
 
   /// \brief Collect the set of unexpanded parameter packs within the given
@@ -6552,6 +6659,10 @@
     /// \brief After substituting deduced template arguments, a dependent
     /// parameter type did not match the corresponding argument.
     TDK_DeducedMismatch,
+    /// \brief After substituting deduced template arguments, an element of
+    /// a dependent parameter type did not match the corresponding element
+    /// of the corresponding argument (when deducing from an initializer list).
+    TDK_DeducedMismatchNested,
     /// \brief A non-depnedent component of the parameter did not match the
     /// corresponding component of the argument.
     TDK_NonDeducedMismatch,
@@ -6564,9 +6675,8 @@
     /// \brief The explicitly-specified template arguments were not valid
     /// template arguments for the given template.
     TDK_InvalidExplicitArguments,
-    /// \brief The arguments included an overloaded function name that could
-    /// not be resolved to a suitable function.
-    TDK_FailedOverloadResolution,
+    /// \brief Checking non-dependent argument conversions failed.
+    TDK_NonDependentConversionFailure,
     /// \brief Deduction failed; that's all we know.
     TDK_MiscellaneousDeductionFailure,
     /// \brief CUDA Target attributes do not match.
@@ -6593,33 +6703,33 @@
   /// brief A function argument from which we performed template argument
   // deduction for a call.
   struct OriginalCallArg {
-    OriginalCallArg(QualType OriginalParamType,
-                    unsigned ArgIdx,
-                    QualType OriginalArgType)
-      : OriginalParamType(OriginalParamType), ArgIdx(ArgIdx),
-        OriginalArgType(OriginalArgType) { }
+    OriginalCallArg(QualType OriginalParamType, bool DecomposedParam,
+                    unsigned ArgIdx, QualType OriginalArgType)
+        : OriginalParamType(OriginalParamType),
+          DecomposedParam(DecomposedParam), ArgIdx(ArgIdx),
+          OriginalArgType(OriginalArgType) {}
 
     QualType OriginalParamType;
+    bool DecomposedParam;
     unsigned ArgIdx;
     QualType OriginalArgType;
   };
 
-  TemplateDeductionResult
-  FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
-                      SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                                  unsigned NumExplicitlySpecified,
-                                  FunctionDecl *&Specialization,
-                                  sema::TemplateDeductionInfo &Info,
-           SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr,
-                                  bool PartialOverloading = false);
+  TemplateDeductionResult FinishTemplateArgumentDeduction(
+      FunctionTemplateDecl *FunctionTemplate,
+      SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+      unsigned NumExplicitlySpecified, FunctionDecl *&Specialization,
+      sema::TemplateDeductionInfo &Info,
+      SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr,
+      bool PartialOverloading = false,
+      llvm::function_ref<bool()> CheckNonDependent = []{ return false; });
 
-  TemplateDeductionResult
-  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
-                          TemplateArgumentListInfo *ExplicitTemplateArgs,
-                          ArrayRef<Expr *> Args,
-                          FunctionDecl *&Specialization,
-                          sema::TemplateDeductionInfo &Info,
-                          bool PartialOverloading = false);
+  TemplateDeductionResult DeduceTemplateArguments(
+      FunctionTemplateDecl *FunctionTemplate,
+      TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
+      FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info,
+      bool PartialOverloading,
+      llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent);
 
   TemplateDeductionResult
   DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
@@ -6645,8 +6755,11 @@
   /// \brief Substitute Replacement for \p auto in \p TypeWithAuto
   QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement);
   /// \brief Substitute Replacement for auto in TypeWithAuto
-  TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, 
+  TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
                                           QualType Replacement);
+  /// \brief Completely replace the \c auto in \p TypeWithAuto by
+  /// \p Replacement. This does not retain any \c auto type sugar.
+  QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement);
 
   /// \brief Result type of DeduceAutoType.
   enum DeduceAutoResult {
@@ -6655,14 +6768,25 @@
     DAR_FailedAlreadyDiagnosed
   };
 
-  DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer,
-                                  QualType &Result);
-  DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer,
-                                  QualType &Result);
+  DeduceAutoResult
+  DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result,
+                 Optional<unsigned> DependentDeductionDepth = None);
+  DeduceAutoResult
+  DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result,
+                 Optional<unsigned> DependentDeductionDepth = None);
   void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
   bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
                         bool Diagnose = true);
 
+  /// \brief Declare implicit deduction guides for a class template if we've
+  /// not already done so.
+  void DeclareImplicitDeductionGuides(TemplateDecl *Template,
+                                      SourceLocation Loc);
+
+  QualType DeduceTemplateSpecializationFromInitializer(
+      TypeSourceInfo *TInfo, const InitializedEntity &Entity,
+      const InitializationKind &Kind, MultiExprArg Init);
+
   QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
                                         QualType Type, TypeSourceInfo *TSI,
                                         SourceRange Range, bool DirectInit,
@@ -6695,10 +6819,19 @@
                                   ClassTemplatePartialSpecializationDecl *PS2,
                                   SourceLocation Loc);
 
+  bool isMoreSpecializedThanPrimary(ClassTemplatePartialSpecializationDecl *T,
+                                    sema::TemplateDeductionInfo &Info);
+
   VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization(
       VarTemplatePartialSpecializationDecl *PS1,
       VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc);
 
+  bool isMoreSpecializedThanPrimary(VarTemplatePartialSpecializationDecl *T,
+                                    sema::TemplateDeductionInfo &Info);
+
+  bool isTemplateTemplateParameterAtLeastAsSpecializedAs(
+      TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc);
+
   void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
                                   bool OnlyDeduced,
                                   unsigned Depth,
@@ -6722,10 +6855,12 @@
                                bool RelativeToPrimary = false,
                                const FunctionDecl *Pattern = nullptr);
 
-  /// \brief A template instantiation that is currently in progress.
-  struct ActiveTemplateInstantiation {
+  /// A context in which code is being synthesized (where a source location
+  /// alone is not sufficient to identify the context). This covers template
+  /// instantiation and various forms of implicitly-generated functions.
+  struct CodeSynthesisContext {
     /// \brief The kind of template instantiation we are performing
-    enum InstantiationKind {
+    enum SynthesisKind {
       /// We are instantiating a template declaration. The entity is
       /// the declaration we're instantiating (e.g., a CXXRecordDecl).
       TemplateInstantiation,
@@ -6749,8 +6884,8 @@
       /// We are substituting template argument determined as part of
       /// template argument deduction for either a class template
       /// partial specialization or a function template. The
-      /// Entity is either a ClassTemplatePartialSpecializationDecl or
-      /// a FunctionTemplateDecl.
+      /// Entity is either a {Class|Var}TemplatePartialSpecializationDecl or
+      /// a TemplateDecl.
       DeducedTemplateArgumentSubstitution,
 
       /// We are substituting prior template arguments into a new
@@ -6764,28 +6899,42 @@
 
       /// We are instantiating the exception specification for a function
       /// template which was deferred until it was needed.
-      ExceptionSpecInstantiation
+      ExceptionSpecInstantiation,
+
+      /// We are declaring an implicit special member function.
+      DeclaringSpecialMember,
     } Kind;
 
-    /// \brief The point of instantiation within the source code.
+    /// \brief Was the enclosing context a non-instantiation SFINAE context?
+    bool SavedInNonInstantiationSFINAEContext;
+
+    /// \brief The point of instantiation or synthesis within the source code.
     SourceLocation PointOfInstantiation;
 
+    /// \brief The entity that is being synthesized.
+    Decl *Entity;
+
     /// \brief The template (or partial specialization) in which we are
     /// performing the instantiation, for substitutions of prior template
     /// arguments.
     NamedDecl *Template;
 
-    /// \brief The entity that is being instantiated.
-    Decl *Entity;
-
     /// \brief The list of template arguments we are substituting, if they
     /// are not part of the entity.
     const TemplateArgument *TemplateArgs;
 
-    /// \brief The number of template arguments in TemplateArgs.
-    unsigned NumTemplateArgs;
+    // FIXME: Wrap this union around more members, or perhaps store the
+    // kind-specific members in the RAII object owning the context.
+    union {
+      /// \brief The number of template arguments in TemplateArgs.
+      unsigned NumTemplateArgs;
+
+      /// \brief The special member being declared or defined.
+      CXXSpecialMember SpecialMember;
+    };
 
     ArrayRef<TemplateArgument> template_arguments() const {
+      assert(Kind != DeclaringSpecialMember);
       return {TemplateArgs, NumTemplateArgs};
     }
 
@@ -6798,63 +6947,31 @@
     /// template instantiation.
     SourceRange InstantiationRange;
 
-    ActiveTemplateInstantiation()
-      : Kind(TemplateInstantiation), Template(nullptr), Entity(nullptr),
+    CodeSynthesisContext()
+      : Kind(TemplateInstantiation), Entity(nullptr), Template(nullptr),
         TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {}
 
     /// \brief Determines whether this template is an actual instantiation
     /// that should be counted toward the maximum instantiation depth.
     bool isInstantiationRecord() const;
-
-    friend bool operator==(const ActiveTemplateInstantiation &X,
-                           const ActiveTemplateInstantiation &Y) {
-      if (X.Kind != Y.Kind)
-        return false;
-
-      if (X.Entity != Y.Entity)
-        return false;
-
-      switch (X.Kind) {
-      case TemplateInstantiation:
-      case ExceptionSpecInstantiation:
-        return true;
-
-      case PriorTemplateArgumentSubstitution:
-      case DefaultTemplateArgumentChecking:
-        return X.Template == Y.Template && X.TemplateArgs == Y.TemplateArgs;
-
-      case DefaultTemplateArgumentInstantiation:
-      case ExplicitTemplateArgumentSubstitution:
-      case DeducedTemplateArgumentSubstitution:
-      case DefaultFunctionArgumentInstantiation:
-        return X.TemplateArgs == Y.TemplateArgs;
-
-      }
-
-      llvm_unreachable("Invalid InstantiationKind!");
-    }
-
-    friend bool operator!=(const ActiveTemplateInstantiation &X,
-                           const ActiveTemplateInstantiation &Y) {
-      return !(X == Y);
-    }
   };
 
-  /// \brief List of active template instantiations.
+  /// \brief List of active code synthesis contexts.
   ///
-  /// This vector is treated as a stack. As one template instantiation
-  /// requires another template instantiation, additional
-  /// instantiations are pushed onto the stack up to a
-  /// user-configurable limit LangOptions::InstantiationDepth.
-  SmallVector<ActiveTemplateInstantiation, 16>
-    ActiveTemplateInstantiations;
+  /// This vector is treated as a stack. As synthesis of one entity requires
+  /// synthesis of another, additional contexts are pushed onto the stack.
+  SmallVector<CodeSynthesisContext, 16> CodeSynthesisContexts;
 
   /// Specializations whose definitions are currently being instantiated.
   llvm::DenseSet<std::pair<Decl *, unsigned>> InstantiatingSpecializations;
 
+  /// Non-dependent types used in templates that have already been instantiated
+  /// by some template instantiation.
+  llvm::DenseSet<QualType> InstantiatedNonDependentTypes;
+
   /// \brief Extra modules inspected when performing a lookup during a template
   /// instantiation. Computed lazily.
-  SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules;
+  SmallVector<Module*, 16> CodeSynthesisContextLookupModules;
 
   /// \brief Cache of additional modules that should be used for name lookup
   /// within the current template instantiation. Computed lazily; use
@@ -6877,19 +6994,22 @@
   /// of a template instantiation or template argument deduction.
   bool InNonInstantiationSFINAEContext;
 
-  /// \brief The number of ActiveTemplateInstantiation entries in
-  /// \c ActiveTemplateInstantiations that are not actual instantiations and,
-  /// therefore, should not be counted as part of the instantiation depth.
+  /// \brief The number of \p CodeSynthesisContexts that are not template
+  /// instantiations and, therefore, should not be counted as part of the
+  /// instantiation depth.
+  ///
+  /// When the instantiation depth reaches the user-configurable limit
+  /// \p LangOptions::InstantiationDepth we will abort instantiation.
+  // FIXME: Should we have a similar limit for other forms of synthesis?
   unsigned NonInstantiationEntries;
 
-  /// \brief The last template from which a template instantiation
+  /// \brief The depth of the context stack at the point when the most recent
   /// error or warning was produced.
   ///
-  /// This value is used to suppress printing of redundant template
-  /// instantiation backtraces when there are multiple errors in the
-  /// same instantiation. FIXME: Does this belong in Sema? It's tough
-  /// to implement it anywhere else.
-  ActiveTemplateInstantiation LastTemplateInstantiationErrorContext;
+  /// This value is used to suppress printing of redundant context stacks
+  /// when there are multiple errors or warnings in the same instantiation.
+  // FIXME: Does this belong in Sema? It's tough to implement it anywhere else.
+  unsigned LastEmittedCodeSynthesisContextDepth = 0;
 
   /// \brief The current index into pack expansion arguments that will be
   /// used for substitution of parameter packs.
@@ -6967,7 +7087,15 @@
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           FunctionTemplateDecl *FunctionTemplate,
                           ArrayRef<TemplateArgument> TemplateArgs,
-                          ActiveTemplateInstantiation::InstantiationKind Kind,
+                          CodeSynthesisContext::SynthesisKind Kind,
+                          sema::TemplateDeductionInfo &DeductionInfo,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are instantiating as part of template
+    /// argument deduction for a class template declaration.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          TemplateDecl *Template,
+                          ArrayRef<TemplateArgument> TemplateArgs,
                           sema::TemplateDeductionInfo &DeductionInfo,
                           SourceRange InstantiationRange = SourceRange());
 
@@ -7038,12 +7166,11 @@
     Sema &SemaRef;
     bool Invalid;
     bool AlreadyInstantiating;
-    bool SavedInNonInstantiationSFINAEContext;
     bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
                                  SourceRange InstantiationRange);
 
     InstantiatingTemplate(
-        Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind,
+        Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind,
         SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
         Decl *Entity, NamedDecl *Template = nullptr,
         ArrayRef<TemplateArgument> TemplateArgs = None,
@@ -7055,6 +7182,21 @@
     operator=(const InstantiatingTemplate&) = delete;
   };
 
+  void pushCodeSynthesisContext(CodeSynthesisContext Ctx);
+  void popCodeSynthesisContext();
+
+  /// Determine whether we are currently performing template instantiation.
+  bool inTemplateInstantiation() const {
+    return CodeSynthesisContexts.size() > NonInstantiationEntries;
+  }
+
+  void PrintContextStack() {
+    if (!CodeSynthesisContexts.empty() &&
+        CodeSynthesisContexts.size() != LastEmittedCodeSynthesisContextDepth) {
+      PrintInstantiationStack();
+      LastEmittedCodeSynthesisContextDepth = CodeSynthesisContexts.size();
+    }
+  }
   void PrintInstantiationStack();
 
   /// \brief Determines whether we are currently in a context where
@@ -7233,7 +7375,7 @@
 
   public:
     /// Set the ExtParameterInfo for the parameter at the given index,
-    /// 
+    ///
     void set(unsigned index, FunctionProtoType::ExtParameterInfo info) {
       assert(Infos.size() <= index);
       Infos.resize(index);
@@ -7257,7 +7399,8 @@
 
   TypeSourceInfo *SubstType(TypeSourceInfo *T,
                             const MultiLevelTemplateArgumentList &TemplateArgs,
-                            SourceLocation Loc, DeclarationName Entity);
+                            SourceLocation Loc, DeclarationName Entity,
+                            bool AllowDeducedTST = false);
 
   QualType SubstType(QualType T,
                      const MultiLevelTemplateArgumentList &TemplateArgs,
@@ -7472,7 +7615,7 @@
                                  const SourceLocation *ProtoLocs,
                                  SourceLocation EndProtoLoc,
                                  AttributeList *AttrList);
-    
+
   void ActOnSuperClassOfClassInterface(Scope *S,
                                        SourceLocation AtInterfaceLoc,
                                        ObjCInterfaceDecl *IDecl,
@@ -7482,7 +7625,7 @@
                                        SourceLocation SuperLoc,
                                        ArrayRef<ParsedType> SuperTypeArgs,
                                        SourceRange SuperTypeArgsRange);
-  
+
   void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
                                SmallVectorImpl<SourceLocation> &ProtocolLocs,
                                IdentifierInfo *SuperName,
@@ -7809,14 +7952,14 @@
                                   ParsedType Type,
                                   SourceLocation RParenLoc,
                                   Expr *SubExpr);
-  
+
   void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr);
-  
+
   void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr);
-  
+
   bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
                                      CastKind &Kind);
-  
+
   bool checkObjCBridgeRelatedComponents(SourceLocation Loc,
                                         QualType DestType, QualType SrcType,
                                         ObjCInterfaceDecl *&RelatedClass,
@@ -8047,15 +8190,72 @@
   //
   ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E);
   ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E);
-  StmtResult ActOnCoreturnStmt(SourceLocation KwLoc, Expr *E);
+  StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E);
 
-  ExprResult BuildCoawaitExpr(SourceLocation KwLoc, Expr *E);
+  ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *E,
+                                      bool IsImplicit = false);
+  ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *E,
+                                        UnresolvedLookupExpr* Lookup);
   ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E);
-  StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E);
-
+  StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E,
+                               bool IsImplicit = false);
+  StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs);
+  VarDecl *buildCoroutinePromise(SourceLocation Loc);
   void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
 
   //===--------------------------------------------------------------------===//
+  // OpenCL extensions.
+  //
+private:
+  std::string CurrOpenCLExtension;
+  /// Extensions required by an OpenCL type.
+  llvm::DenseMap<const Type*, std::set<std::string>> OpenCLTypeExtMap;
+  /// Extensions required by an OpenCL declaration.
+  llvm::DenseMap<const Decl*, std::set<std::string>> OpenCLDeclExtMap;
+public:
+  llvm::StringRef getCurrentOpenCLExtension() const {
+    return CurrOpenCLExtension;
+  }
+  void setCurrentOpenCLExtension(llvm::StringRef Ext) {
+    CurrOpenCLExtension = Ext;
+  }
+
+  /// \brief Set OpenCL extensions for a type which can only be used when these
+  /// OpenCL extensions are enabled. If \p Exts is empty, do nothing.
+  /// \param Exts A space separated list of OpenCL extensions.
+  void setOpenCLExtensionForType(QualType T, llvm::StringRef Exts);
+
+  /// \brief Set OpenCL extensions for a declaration which can only be
+  /// used when these OpenCL extensions are enabled. If \p Exts is empty, do
+  /// nothing.
+  /// \param Exts A space separated list of OpenCL extensions.
+  void setOpenCLExtensionForDecl(Decl *FD, llvm::StringRef Exts);
+
+  /// \brief Set current OpenCL extensions for a type which can only be used
+  /// when these OpenCL extensions are enabled. If current OpenCL extension is
+  /// empty, do nothing.
+  void setCurrentOpenCLExtensionForType(QualType T);
+
+  /// \brief Set current OpenCL extensions for a declaration which
+  /// can only be used when these OpenCL extensions are enabled. If current
+  /// OpenCL extension is empty, do nothing.
+  void setCurrentOpenCLExtensionForDecl(Decl *FD);
+
+  bool isOpenCLDisabledDecl(Decl *FD);
+
+  /// \brief Check if type \p T corresponding to declaration specifier \p DS
+  /// is disabled due to required OpenCL extensions being disabled. If so,
+  /// emit diagnostics.
+  /// \return true if type is disabled.
+  bool checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType T);
+
+  /// \brief Check if declaration \p D used by expression \p E
+  /// is disabled due to required OpenCL extensions being disabled. If so,
+  /// emit diagnostics.
+  /// \return true if type is disabled.
+  bool checkOpenCLDisabledDecl(const Decl &D, const Expr &E);
+
+  //===--------------------------------------------------------------------===//
   // OpenMP directives and clauses.
   //
 private:
@@ -8071,6 +8271,21 @@
   /// Returns OpenMP nesting level for current directive.
   unsigned getOpenMPNestingLevel() const;
 
+  /// Checks if a type or a declaration is disabled due to the owning extension
+  /// being disabled, and emits diagnostic messages if it is disabled.
+  /// \param D type or declaration to be checked.
+  /// \param DiagLoc source location for the diagnostic message.
+  /// \param DiagInfo information to be emitted for the diagnostic message.
+  /// \param SrcRange source range of the declaration.
+  /// \param Map maps type or declaration to the extensions.
+  /// \param Selector selects diagnostic message: 0 for type and 1 for
+  ///        declaration.
+  /// \return true if the type or declaration is disabled.
+  template <typename T, typename DiagLocT, typename DiagInfoT, typename MapT>
+  bool checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc, DiagInfoT DiagInfo,
+                                     MapT &Map, unsigned Selector = 0,
+                                     SourceRange SrcRange = SourceRange());
+
 public:
   /// \brief Return true if the provided declaration \a VD should be captured by
   /// reference.
@@ -8165,6 +8380,9 @@
     return IsInOpenMPDeclareTargetContext;
   }
 
+  /// Return the number of captured regions created for an OpenMP directive.
+  static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind);
+
   /// \brief Initialization of captured region for OpenMP region.
   void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);
   /// \brief End of OpenMP region.
@@ -8398,6 +8616,36 @@
       ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
       SourceLocation EndLoc,
       llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+  /// Called on well-formed '\#pragma omp target teams' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
+                                             Stmt *AStmt,
+                                             SourceLocation StartLoc,
+                                             SourceLocation EndLoc);
+  /// Called on well-formed '\#pragma omp target teams distribute' after parsing
+  /// of the associated statement.
+  StmtResult ActOnOpenMPTargetTeamsDistributeDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+  /// Called on well-formed '\#pragma omp target teams distribute parallel for'
+  /// after parsing of the associated statement.
+  StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+  /// Called on well-formed '\#pragma omp target teams distribute parallel for
+  /// simd' after parsing of the associated statement.
+  StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+  /// Called on well-formed '\#pragma omp target teams distribute simd' after
+  /// parsing of the associated statement.
+  StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
 
   /// Checks correctness of linear modifiers.
   bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
@@ -9078,7 +9326,7 @@
   ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr,
                                 CastKind &Kind);
 
-  ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
+  ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, QualType Type,
                                         SourceLocation LParenLoc,
                                         Expr *CastExpr,
                                         SourceLocation RParenLoc);
@@ -9598,6 +9846,8 @@
   void CodeCompletePostfixExpression(Scope *S, ExprResult LHS);
   void CodeCompleteTag(Scope *S, unsigned TagSpec);
   void CodeCompleteTypeQualifiers(DeclSpec &DS);
+  void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D,
+                                      const VirtSpecifiers *VS = nullptr);
   void CodeCompleteBracketDeclarator(Scope *S);
   void CodeCompleteCase(Scope *S);
   void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args);
@@ -9724,8 +9974,8 @@
                             SourceLocation Loc);
 
   void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
-                 ArrayRef<const Expr *> Args, bool IsMemberFunction, 
-                 SourceLocation Loc, SourceRange Range, 
+                 const Expr *ThisArg, ArrayRef<const Expr *> Args,
+                 bool IsMemberFunction, SourceLocation Loc, SourceRange Range,
                  VariadicCallType CallType);
 
   bool CheckObjCString(Expr *Arg);
@@ -9743,6 +9993,7 @@
   bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
 
@@ -9797,7 +10048,7 @@
   static FormatStringType GetFormatStringType(const FormatAttr *Format);
 
   bool FormatStringHasSArg(const StringLiteral *FExpr);
-  
+
   static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx);
 
 private:
@@ -9849,6 +10100,11 @@
   void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field,
                                    Expr *Init);
 
+  /// Check if there is a field shadowing.
+  void CheckShadowInheritedFields(const SourceLocation &Loc,
+                                  DeclarationName FieldName,
+                                  const CXXRecordDecl *RD);
+
   /// \brief Check if the given expression contains 'break' or 'continue'
   /// statement that produces control flow different from GCC.
   void CheckBreakContinueBinding(Expr *E);
@@ -10032,7 +10288,8 @@
   /// local diagnostics like in reference binding.
   void RefersToMemberWithReducedAlignment(
       Expr *E,
-      std::function<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action);
+      llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)>
+          Action);
 };
 
 /// \brief RAII object that enters a new expression evaluation context.
@@ -10056,11 +10313,27 @@
                                    Sema::ReuseLambdaContextDecl_t,
                                    bool IsDecltype = false)
     : Actions(Actions) {
-    Actions.PushExpressionEvaluationContext(NewContext, 
+    Actions.PushExpressionEvaluationContext(NewContext,
                                             Sema::ReuseLambdaContextDecl,
                                             IsDecltype);
   }
 
+  enum InitListTag { InitList };
+  EnterExpressionEvaluationContext(Sema &Actions, InitListTag,
+                                   bool ShouldEnter = true)
+      : Actions(Actions), Entered(false) {
+    // In C++11 onwards, narrowing checks are performed on the contents of
+    // braced-init-lists, even when they occur within unevaluated operands.
+    // Therefore we still need to instantiate constexpr functions used in such
+    // a context.
+    if (ShouldEnter && Actions.isUnevaluatedContext() &&
+        Actions.getLangOpts().CPlusPlus11) {
+      Actions.PushExpressionEvaluationContext(Sema::UnevaluatedList, nullptr,
+                                              false);
+      Entered = true;
+    }
+  }
+
   ~EnterExpressionEvaluationContext() {
     if (Entered)
       Actions.PopExpressionEvaluationContext();
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index 0d12880..644d55b 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -46,6 +46,10 @@
     /// \brief The template argument lists, stored from the innermost template
     /// argument list (first) to the outermost template argument list (last).
     SmallVector<ArgList, 4> TemplateArgumentLists;
+
+    /// \brief The number of outer levels of template arguments that are not
+    /// being substituted.
+    unsigned NumRetainedOuterLevels = 0;
     
   public:
     /// \brief Construct an empty set of template argument lists.
@@ -59,11 +63,19 @@
     
     /// \brief Determine the number of levels in this template argument
     /// list.
-    unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
-    
+    unsigned getNumLevels() const {
+      return TemplateArgumentLists.size() + NumRetainedOuterLevels;
+    }
+
+    /// \brief Determine the number of substituted levels in this template
+    /// argument list.
+    unsigned getNumSubstitutedLevels() const {
+      return TemplateArgumentLists.size();
+    }
+
     /// \brief Retrieve the template argument at a given depth and index.
     const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
-      assert(Depth < TemplateArgumentLists.size());
+      assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
       assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
       return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
     }
@@ -73,7 +85,10 @@
     ///
     /// There must exist a template argument list at the given depth.
     bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
-      assert(Depth < TemplateArgumentLists.size());
+      assert(Depth < getNumLevels());
+
+      if (Depth < NumRetainedOuterLevels)
+        return false;
       
       if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
         return false;
@@ -84,7 +99,7 @@
     /// \brief Clear out a specific template argument.
     void setArgument(unsigned Depth, unsigned Index,
                      TemplateArgument Arg) {
-      assert(Depth < TemplateArgumentLists.size());
+      assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
       assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
       const_cast<TemplateArgument&>(
                 TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
@@ -101,9 +116,18 @@
     /// \brief Add a new outmost level to the multi-level template argument
     /// list.
     void addOuterTemplateArguments(ArgList Args) {
+      assert(!NumRetainedOuterLevels &&
+             "substituted args outside retained args?");
       TemplateArgumentLists.push_back(Args);
     }
 
+    /// \brief Add an outermost level that we are not substituting. We have no
+    /// arguments at this level, and do not remove it from the depth of inner
+    /// template parameters that we instantiate.
+    void addOuterRetainedLevel() {
+      ++NumRetainedOuterLevels;
+    }
+
     /// \brief Retrieve the innermost template argument list.
     const ArgList &getInnermost() const { 
       return TemplateArgumentLists.front(); 
@@ -515,6 +539,11 @@
         VarTemplateDecl *VarTemplate,
         VarTemplatePartialSpecializationDecl *PartialSpec);
     void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
+
+  private:
+    template<typename T>
+    Decl *instantiateUnresolvedUsingDecl(T *D,
+                                         bool InstantiatingPackElement = false);
   };  
 }
 
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index 8a64b8b..d92cbab 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -40,6 +40,9 @@
   /// \brief Have we suppressed an error during deduction?
   bool HasSFINAEDiagnostic;
 
+  /// \brief The template parameter depth for which we're performing deduction.
+  unsigned DeducedDepth;
+
   /// \brief Warnings (and follow-on notes) that were suppressed due to
   /// SFINAE while performing template argument deduction.
   SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
@@ -48,9 +51,9 @@
   void operator=(const TemplateDeductionInfo &) = delete;
 
 public:
-  TemplateDeductionInfo(SourceLocation Loc)
+  TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
     : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
-      Expression(nullptr) {}
+      DeducedDepth(DeducedDepth), CallArgIndex(0) {}
 
   /// \brief Returns the location at which template argument is
   /// occurring.
@@ -58,6 +61,12 @@
     return Loc;
   }
 
+  /// \brief The depth of template parameters for which deduction is being
+  /// performed.
+  unsigned getDeducedDepth() const {
+    return DeducedDepth;
+  }
+
   /// \brief Take ownership of the deduced template argument list.
   TemplateArgumentList *take() {
     TemplateArgumentList *Result = Deduced;
@@ -70,6 +79,11 @@
     assert(HasSFINAEDiagnostic);
     PD.first = SuppressedDiagnostics.front().first;
     PD.second.swap(SuppressedDiagnostics.front().second);
+    clearSFINAEDiagnostic();
+  }
+
+  /// \brief Discard any SFINAE diagnostics.
+  void clearSFINAEDiagnostic() {
     SuppressedDiagnostics.clear();
     HasSFINAEDiagnostic = false;
   }
@@ -161,21 +175,12 @@
   /// FIXME: Finish documenting this.
   TemplateArgument SecondArg;
 
-  union {
-    /// \brief The expression which caused a deduction failure.
-    ///
-    ///   TDK_FailedOverloadResolution: this argument is the reference to
-    ///   an overloaded function which could not be resolved to a specific
-    ///   function.
-    Expr *Expression;
-
-    /// \brief The index of the function argument that caused a deduction
-    /// failure.
-    ///
-    ///   TDK_DeducedMismatch: this is the index of the argument that had a
-    ///   different argument type from its substituted parameter type.
-    unsigned CallArgIndex;
-  };
+  /// \brief The index of the function argument that caused a deduction
+  /// failure.
+  ///
+  ///   TDK_DeducedMismatch: this is the index of the argument that had a
+  ///   different argument type from its substituted parameter type.
+  unsigned CallArgIndex;
 
   /// \brief Information on packs that we're currently expanding.
   ///
@@ -221,10 +226,6 @@
   /// refers to, if any.
   const TemplateArgument *getSecondArg();
 
-  /// \brief Return the expression this deduction failure refers to,
-  /// if any.
-  Expr *getExpr();
-
   /// \brief Return the index of the call argument that this deduction
   /// failure refers to, if any.
   llvm::Optional<unsigned> getCallArgIndex();
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 48d76b0..de8e2a8 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -226,7 +226,7 @@
 
       /// \brief The block containing the detailed preprocessing record.
       PREPROCESSOR_DETAIL_BLOCK_ID,
-      
+
       /// \brief The block containing the submodule structure.
       SUBMODULE_BLOCK_ID,
 
@@ -253,6 +253,12 @@
 
       /// \brief A block containing a module file extension.
       EXTENSION_BLOCK_ID,
+
+      /// A block with unhashed content.
+      ///
+      /// These records should not change the \a ASTFileSignature.  See \a
+      /// UnhashedControlBlockRecordTypes for the list of records.
+      UNHASHED_CONTROL_BLOCK_ID,
     };
 
     /// \brief Record types that occur within the control block.
@@ -288,9 +294,6 @@
       /// AST file.
       MODULE_MAP_FILE,
 
-      /// \brief Record code for the signature that identifiers this AST file.
-      SIGNATURE,
-
       /// \brief Record code for the module build directory.
       MODULE_DIRECTORY,
     };
@@ -309,9 +312,6 @@
       /// \brief Record code for the target options table.
       TARGET_OPTIONS,
 
-      /// \brief Record code for the diagnostic options table.
-      DIAGNOSTIC_OPTIONS,
-
       /// \brief Record code for the filesystem options table.
       FILE_SYSTEM_OPTIONS,
 
@@ -322,6 +322,18 @@
       PREPROCESSOR_OPTIONS,
     };
 
+    /// Record codes for the unhashed control block.
+    enum UnhashedControlBlockRecordTypes {
+      /// Record code for the signature that identifiers this AST file.
+      SIGNATURE = 1,
+
+      /// Record code for the diagnostic options table.
+      DIAGNOSTIC_OPTIONS,
+
+      /// Record code for \#pragma diagnostic mappings.
+      DIAG_PRAGMA_MAPPINGS,
+    };
+
     /// \brief Record code for extension blocks.
     enum ExtensionBlockRecordTypes {
       /// Metadata describing this particular extension.
@@ -344,7 +356,7 @@
       ///
       /// The TYPE_OFFSET constant describes the record that occurs
       /// within the AST block. The record itself is an array of offsets that
-      /// point into the declarations and types block (identified by 
+      /// point into the declarations and types block (identified by
       /// DECLTYPES_BLOCK_ID). The index into the array is based on the ID
       /// of a type. For a given type ID @c T, the lower three bits of
       /// @c T are its qualifiers (const, volatile, restrict), as in
@@ -446,10 +458,10 @@
 
       /// \brief Record code for the set of ext_vector type names.
       EXT_VECTOR_DECLS = 16,
-      
+
       /// \brief Record code for the array of unused file scoped decls.
       UNUSED_FILESCOPED_DECLS = 17,
-      
+
       /// \brief Record code for the table of offsets to entries in the
       /// preprocessing record.
       PPD_ENTITIES_OFFSETS = 18,
@@ -465,7 +477,7 @@
       /// \brief Record code for an update to the TU's lexically contained
       /// declarations.
       TU_UPDATE_LEXICAL = 22,
-      
+
       // ID 23 used to be for a list of local redeclarations.
 
       /// \brief Record code for declarations that Sema keeps references of.
@@ -490,15 +502,14 @@
 
       // ID 30 used to be a decl update record. These are now in the DECLTYPES
       // block.
-      
+
       // ID 31 used to be a list of offsets to DECL_CXX_BASE_SPECIFIERS records.
 
-      /// \brief Record code for \#pragma diagnostic mappings.
-      DIAG_PRAGMA_MAPPINGS = 32,
+      // ID 32 used to be the code for \#pragma diagnostic mappings.
 
       /// \brief Record code for special CUDA declarations.
       CUDA_SPECIAL_DECL_REFS = 33,
-      
+
       /// \brief Record code for header search information.
       HEADER_SEARCH_TABLE = 34,
 
@@ -516,7 +527,7 @@
       KNOWN_NAMESPACES = 38,
 
       /// \brief Record code for the remapping information used to relate
-      /// loaded modules to the various offsets and IDs(e.g., source location 
+      /// loaded modules to the various offsets and IDs(e.g., source location
       /// offests, declaration and type IDs) that are used in that module to
       /// refer to other modules.
       MODULE_OFFSET_MAP = 39,
@@ -525,20 +536,20 @@
       /// which stores information about \#line directives.
       SOURCE_MANAGER_LINE_TABLE = 40,
 
-      /// \brief Record code for map of Objective-C class definition IDs to the 
+      /// \brief Record code for map of Objective-C class definition IDs to the
       /// ObjC categories in a module that are attached to that class.
       OBJC_CATEGORIES_MAP = 41,
 
       /// \brief Record code for a file sorted array of DeclIDs in a module.
       FILE_SORTED_DECLS = 42,
-      
+
       /// \brief Record code for an array of all of the (sub)modules that were
       /// imported by the AST file.
       IMPORTED_MODULES = 43,
-      
+
       // ID 44 used to be a table of merged canonical declarations.
       // ID 45 used to be a list of declaration IDs of local redeclarations.
-      
+
       /// \brief Record code for the array of Objective-C categories (including
       /// extensions).
       ///
@@ -585,6 +596,14 @@
       /// \brief Number of unmatched #pragma clang cuda_force_host_device begin
       /// directives we've seen.
       CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH = 57,
+
+      /// \brief Record code for types associated with OpenCL extensions.
+      OPENCL_EXTENSION_TYPES = 58,
+
+      /// \brief Record code for declarations associated with OpenCL extensions.
+      OPENCL_EXTENSION_DECLS = 59,
+
+      MODULAR_CODEGEN_DECLS = 60,
     };
 
     /// \brief Record types used within a source manager block.
@@ -795,14 +814,12 @@
       PREDEF_TYPE_SAMPLER_ID    = 39,
       /// \brief OpenCL queue type.
       PREDEF_TYPE_QUEUE_ID      = 40,
-      /// \brief OpenCL ndrange type.
-      PREDEF_TYPE_NDRANGE_ID    = 41,
       /// \brief OpenCL reserve_id type.
-      PREDEF_TYPE_RESERVE_ID_ID = 42,
+      PREDEF_TYPE_RESERVE_ID_ID = 41,
       /// \brief The placeholder type for OpenMP array section.
-      PREDEF_TYPE_OMP_ARRAY_SECTION = 43,
+      PREDEF_TYPE_OMP_ARRAY_SECTION = 42,
       /// \brief The '__float128' type
-      PREDEF_TYPE_FLOAT128_ID = 44,
+      PREDEF_TYPE_FLOAT128_ID = 43,
       /// \brief OpenCL image types with auto numeration
 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
       PREDEF_TYPE_##Id##_ID,
@@ -908,7 +925,9 @@
       /// \brief A PipeType record.
       TYPE_PIPE                  = 43,
       /// \brief An ObjCTypeParamType record.
-      TYPE_OBJC_TYPE_PARAM       = 44
+      TYPE_OBJC_TYPE_PARAM       = 44,
+      /// \brief A DeducedTemplateSpecializationType record.
+      TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45
     };
 
     /// \brief The type IDs for special types constructed by semantic
@@ -1097,6 +1116,8 @@
       DECL_NAMESPACE_ALIAS,
       /// \brief A UsingDecl record.
       DECL_USING,
+      /// \brief A UsingPackDecl record.
+      DECL_USING_PACK,
       /// \brief A UsingShadowDecl record.
       DECL_USING_SHADOW,
       /// \brief A ConstructorUsingShadowDecl record.
@@ -1113,6 +1134,8 @@
       DECL_EXPORT,
       /// \brief A CXXRecordDecl record.
       DECL_CXX_RECORD,
+      /// \brief A CXXDeductionGuideDecl record.
+      DECL_CXX_DEDUCTION_GUIDE,
       /// \brief A CXXMethodDecl record.
       DECL_CXX_METHOD,
       /// \brief A CXXConstructorDecl record.
@@ -1292,10 +1315,14 @@
       EXPR_DESIGNATED_INIT,
       /// \brief A DesignatedInitUpdateExpr record.
       EXPR_DESIGNATED_INIT_UPDATE,
-      /// \brief An ImplicitValueInitExpr record.
-      EXPR_IMPLICIT_VALUE_INIT,
       /// \brief An NoInitExpr record.
       EXPR_NO_INIT,
+      /// \brief An ArrayInitLoopExpr record.
+      EXPR_ARRAY_INIT_LOOP,
+      /// \brief An ArrayInitIndexExpr record.
+      EXPR_ARRAY_INIT_INDEX,
+      /// \brief An ImplicitValueInitExpr record.
+      EXPR_IMPLICIT_VALUE_INIT,
       /// \brief A VAArgExpr record.
       EXPR_VA_ARG,
       /// \brief An AddrLabelExpr record.
@@ -1501,6 +1528,11 @@
       STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE,
       STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE,
       STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE,
+      STMT_OMP_TARGET_TEAMS_DIRECTIVE,
+      STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE,
+      STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE,
+      STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE,
+      STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE,
       EXPR_OMP_ARRAY_SECTION,
 
       // ARC
@@ -1607,7 +1639,8 @@
 
       IdentifierInfo *getIdentifier() const {
         assert(Kind == DeclarationName::Identifier ||
-               Kind == DeclarationName::CXXLiteralOperatorName);
+               Kind == DeclarationName::CXXLiteralOperatorName ||
+               Kind == DeclarationName::CXXDeductionGuideName);
         return (IdentifierInfo *)Data;
       }
       Selector getSelector() const {
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
index 4b10c39..c26f3e0 100644
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -26,6 +26,7 @@
 class MacroDefinitionRecord;
 class MacroInfo;
 class Module;
+class SourceLocation;
 
 class ASTDeserializationListener {
 public:
@@ -52,6 +53,9 @@
                                    MacroDefinitionRecord *MD) {}
   /// \brief A module definition was read from the AST file.
   virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) {}
+  /// \brief A module import was read from the AST file.
+  virtual void ModuleImportRead(serialization::SubmoduleID ID,
+                                SourceLocation ImportLoc) {}
 };
 }
 
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 49dad3e..5a1514a 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -47,6 +47,7 @@
 #include <vector>
 
 namespace llvm {
+  class BitstreamCursor;
   class MemoryBuffer;
   class APInt;
   class APSInt;
@@ -88,6 +89,7 @@
 class ASTReader;
 class ASTDeclReader;
 class ASTStmtReader;
+class ASTRecordReader;
 class TypeLocReader;
 struct HeaderFileInfo;
 class VersionTuple;
@@ -356,7 +358,7 @@
     /// \brief The AST file has errors.
     HadErrors
   };
-  
+
   /// \brief Types of AST files.
   friend class PCHValidator;
   friend class ASTDeclReader;
@@ -364,6 +366,7 @@
   friend class ASTIdentifierIterator;
   friend class serialization::reader::ASTIdentifierLookupTrait;
   friend class TypeLocReader;
+  friend class ASTRecordReader;
   friend class ASTWriter;
   friend class ASTUnit; // ASTUnit needs to remap source locations.
   friend class serialization::ReadMethodPoolVisitor;
@@ -381,8 +384,8 @@
   std::unique_ptr<ASTReaderListener> Listener;
 
   /// \brief The receiver of deserialization events.
-  ASTDeserializationListener *DeserializationListener;
-  bool OwnsDeserializationListener;
+  ASTDeserializationListener *DeserializationListener = nullptr;
+  bool OwnsDeserializationListener = false;
 
   SourceManager &SourceMgr;
   FileManager &FileMgr;
@@ -391,7 +394,7 @@
 
   /// \brief The semantic analysis object that will be processing the
   /// AST files and the translation unit that uses it.
-  Sema *SemaObj;
+  Sema *SemaObj = nullptr;
 
   /// \brief The preprocessor that will be loading the source file.
   Preprocessor &PP;
@@ -400,7 +403,7 @@
   ASTContext &Context;
 
   /// \brief The AST consumer.
-  ASTConsumer *Consumer;
+  ASTConsumer *Consumer = nullptr;
 
   /// \brief The module manager which manages modules and their dependencies
   ModuleManager ModuleMgr;
@@ -411,7 +414,7 @@
   IdentifierResolver DummyIdResolver;
 
   /// A mapping from extension block names to module file extensions.
-  llvm::StringMap<IntrusiveRefCntPtr<ModuleFileExtension>> ModuleFileExtensions;
+  llvm::StringMap<std::shared_ptr<ModuleFileExtension>> ModuleFileExtensions;
 
   /// \brief A timer used to track the time spent deserializing.
   std::unique_ptr<llvm::Timer> ReadTimer;
@@ -799,14 +802,20 @@
   SourceLocation OptimizeOffPragmaLocation;
 
   /// \brief The PragmaMSStructKind pragma ms_struct state if set, or -1.
-  int PragmaMSStructState;
+  int PragmaMSStructState = -1;
 
   /// \brief The PragmaMSPointersToMembersKind pragma pointers_to_members state.
-  int PragmaMSPointersToMembersState;
+  int PragmaMSPointersToMembersState = -1;
   SourceLocation PointersToMembersPragmaLocation;
 
   /// \brief The OpenCL extension settings.
-  SmallVector<uint64_t, 1> OpenCLExtensions;
+  OpenCLOptions OpenCLExtensions;
+
+  /// \brief Extensions required by an OpenCL type.
+  llvm::DenseMap<const Type *, std::set<std::string>> OpenCLTypeExtMap;
+
+  /// \brief Extensions required by an OpenCL declaration.
+  llvm::DenseMap<const Decl *, std::set<std::string>> OpenCLDeclExtMap;
 
   /// \brief A list of the namespaces we've seen.
   SmallVector<uint64_t, 4> KnownNamespaces;
@@ -821,6 +830,7 @@
   // \brief A list of late parsed template function data.
   SmallVector<uint64_t, 1> LateParsedTemplates;
 
+public:
   struct ImportedSubmodule {
     serialization::SubmoduleID ID;
     SourceLocation ImportLoc;
@@ -829,6 +839,7 @@
       : ID(ID), ImportLoc(ImportLoc) {}
   };
 
+private:
   /// \brief A list of modules that were imported by precompiled headers or
   /// any other non-module AST file.
   SmallVector<ImportedSubmodule, 2> ImportedModules;
@@ -859,10 +870,10 @@
   bool UseGlobalIndex;
 
   /// \brief Whether we have tried loading the global module index yet.
-  bool TriedLoadingGlobalIndex;
+  bool TriedLoadingGlobalIndex = false;
 
   ///\brief Whether we are currently processing update records.
-  bool ProcessingUpdateRecords;
+  bool ProcessingUpdateRecords = false;
 
   typedef llvm::DenseMap<unsigned, SwitchCase *> SwitchCaseMapTy;
   /// \brief Mapping from switch-case IDs in the chain to switch-case statements
@@ -875,73 +886,73 @@
 
   /// \brief The number of source location entries de-serialized from
   /// the PCH file.
-  unsigned NumSLocEntriesRead;
+  unsigned NumSLocEntriesRead = 0;
 
   /// \brief The number of source location entries in the chain.
-  unsigned TotalNumSLocEntries;
+  unsigned TotalNumSLocEntries = 0;
 
   /// \brief The number of statements (and expressions) de-serialized
   /// from the chain.
-  unsigned NumStatementsRead;
+  unsigned NumStatementsRead = 0;
 
   /// \brief The total number of statements (and expressions) stored
   /// in the chain.
-  unsigned TotalNumStatements;
+  unsigned TotalNumStatements = 0;
 
   /// \brief The number of macros de-serialized from the chain.
-  unsigned NumMacrosRead;
+  unsigned NumMacrosRead = 0;
 
   /// \brief The total number of macros stored in the chain.
-  unsigned TotalNumMacros;
+  unsigned TotalNumMacros = 0;
 
   /// \brief The number of lookups into identifier tables.
-  unsigned NumIdentifierLookups;
+  unsigned NumIdentifierLookups = 0;
 
   /// \brief The number of lookups into identifier tables that succeed.
-  unsigned NumIdentifierLookupHits;
+  unsigned NumIdentifierLookupHits = 0;
 
   /// \brief The number of selectors that have been read.
-  unsigned NumSelectorsRead;
+  unsigned NumSelectorsRead = 0;
 
   /// \brief The number of method pool entries that have been read.
-  unsigned NumMethodPoolEntriesRead;
+  unsigned NumMethodPoolEntriesRead = 0;
 
   /// \brief The number of times we have looked up a selector in the method
   /// pool.
-  unsigned NumMethodPoolLookups;
+  unsigned NumMethodPoolLookups = 0;
 
   /// \brief The number of times we have looked up a selector in the method
   /// pool and found something.
-  unsigned NumMethodPoolHits;
+  unsigned NumMethodPoolHits = 0;
 
   /// \brief The number of times we have looked up a selector in the method
   /// pool within a specific module.
-  unsigned NumMethodPoolTableLookups;
+  unsigned NumMethodPoolTableLookups = 0;
 
   /// \brief The number of times we have looked up a selector in the method
   /// pool within a specific module and found something.
-  unsigned NumMethodPoolTableHits;
+  unsigned NumMethodPoolTableHits = 0;
 
   /// \brief The total number of method pool entries in the selector table.
-  unsigned TotalNumMethodPoolEntries;
+  unsigned TotalNumMethodPoolEntries = 0;
 
   /// Number of lexical decl contexts read/total.
-  unsigned NumLexicalDeclContextsRead, TotalLexicalDeclContexts;
+  unsigned NumLexicalDeclContextsRead = 0, TotalLexicalDeclContexts = 0;
 
   /// Number of visible decl contexts read/total.
-  unsigned NumVisibleDeclContextsRead, TotalVisibleDeclContexts;
+  unsigned NumVisibleDeclContextsRead = 0, TotalVisibleDeclContexts = 0;
 
   /// Total size of modules, in bits, currently loaded
-  uint64_t TotalModulesSizeInBits;
+  uint64_t TotalModulesSizeInBits = 0;
 
   /// \brief Number of Decl/types that are currently deserializing.
-  unsigned NumCurrentElementsDeserializing;
+  unsigned NumCurrentElementsDeserializing = 0;
 
   /// \brief Set true while we are in the process of passing deserialized
   /// "interesting" decls to consumer inside FinishedDeserializing().
   /// This is used as a guard to avoid recursively repeating the process of
   /// passing decls to consumer.
-  bool PassingDeclsToConsumer;
+  bool PassingDeclsToConsumer = false;
 
   /// \brief The set of identifiers that were read while the AST reader was
   /// (recursively) loading declarations.
@@ -1044,7 +1055,7 @@
   };
 
   /// \brief What kind of records we are reading.
-  ReadingKind ReadingKind;
+  ReadingKind ReadingKind = Read_None;
 
   /// \brief RAII object to change the reading kind.
   class ReadingKindTracker {
@@ -1163,7 +1174,7 @@
                             SourceLocation ImportLoc, ModuleFile *ImportedBy,
                             SmallVectorImpl<ImportedModule> &Loaded,
                             off_t ExpectedSize, time_t ExpectedModTime,
-                            serialization::ASTFileSignature ExpectedSignature,
+                            ASTFileSignature ExpectedSignature,
                             unsigned ClientLoadCapabilities);
   ASTReadResult ReadControlBlock(ModuleFile &F,
                                  SmallVectorImpl<ImportedModule> &Loaded,
@@ -1172,9 +1183,25 @@
   static ASTReadResult ReadOptionsBlock(
       llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
       bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
-      std::string &SuggestedPredefines, bool ValidateDiagnosticOptions);
+      std::string &SuggestedPredefines);
+
+  /// Read the unhashed control block.
+  ///
+  /// This has no effect on \c F.Stream, instead creating a fresh cursor from
+  /// \c F.Data and reading ahead.
+  ASTReadResult readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
+                                         unsigned ClientLoadCapabilities);
+
+  static ASTReadResult
+  readUnhashedControlBlockImpl(ModuleFile *F, llvm::StringRef StreamData,
+                               unsigned ClientLoadCapabilities,
+                               bool AllowCompatibleConfigurationMismatch,
+                               ASTReaderListener *Listener,
+                               bool ValidateDiagnosticOptions);
+
   ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
   ASTReadResult ReadExtensionBlock(ModuleFile &F);
+  void ReadModuleOffsetMap(ModuleFile &F) const;
   bool ParseLineTable(ModuleFile &F, const RecordData &Record);
   bool ReadSourceManagerBlock(ModuleFile &F);
   llvm::BitstreamCursor &SLocCursorForID(int ID);
@@ -1257,6 +1284,7 @@
   llvm::iterator_range<PreprocessingRecord::iterator>
   getModulePreprocessedEntities(ModuleFile &Mod) const;
 
+public:
   class ModuleDeclIterator
       : public llvm::iterator_adaptor_base<
             ModuleDeclIterator, const serialization::LocalDeclID *,
@@ -1287,6 +1315,7 @@
   llvm::iterator_range<ModuleDeclIterator>
   getModuleFileLevelDecls(ModuleFile &Mod);
 
+private:
   void PassInterestingDeclsToConsumer();
   void PassInterestingDeclToConsumer(Decl *D);
 
@@ -1307,9 +1336,9 @@
   ///
   /// This routine should only be used for fatal errors that have to
   /// do with non-routine failures (e.g., corrupted AST file).
-  void Error(StringRef Msg);
+  void Error(StringRef Msg) const;
   void Error(unsigned DiagID, StringRef Arg1 = StringRef(),
-             StringRef Arg2 = StringRef());
+             StringRef Arg2 = StringRef()) const;
 
   ASTReader(const ASTReader &) = delete;
   void operator=(const ASTReader &) = delete;
@@ -1355,7 +1384,7 @@
   /// deserializing.
   ASTReader(Preprocessor &PP, ASTContext &Context,
             const PCHContainerReader &PCHContainerRdr,
-            ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
+            ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
             StringRef isysroot = "", bool DisableValidation = false,
             bool AllowASTWithCompilerErrors = false,
             bool AllowConfigurationMismatch = false,
@@ -1404,9 +1433,13 @@
   /// \param ClientLoadCapabilities The set of client load-failure
   /// capabilities, represented as a bitset of the enumerators of
   /// LoadFailureCapabilities.
+  ///
+  /// \param Imported optional out-parameter to append the list of modules
+  /// that were imported by precompiled headers or any other non-module AST file
   ASTReadResult ReadAST(StringRef FileName, ModuleKind Type,
                         SourceLocation ImportLoc,
-                        unsigned ClientLoadCapabilities);
+                        unsigned ClientLoadCapabilities,
+                        SmallVectorImpl<ImportedSubmodule> *Imported = nullptr);
 
   /// \brief Make the entities in the given module and any of its (non-explicit)
   /// submodules visible to name lookup.
@@ -1616,11 +1649,8 @@
   /// reader.
   unsigned getTotalNumPreprocessedEntities() const {
     unsigned Result = 0;
-    for (ModuleConstIterator I = ModuleMgr.begin(),
-        E = ModuleMgr.end(); I != E; ++I) {
-      Result += (*I)->NumPreprocessedEntities;
-    }
-
+    for (const auto &M : ModuleMgr)
+      Result += M.NumPreprocessedEntities;
     return Result;
   }
 
@@ -1889,10 +1919,10 @@
                                SmallVectorImpl<Decl *> *Decls = nullptr);
 
   /// \brief Report a diagnostic.
-  DiagnosticBuilder Diag(unsigned DiagID);
+  DiagnosticBuilder Diag(unsigned DiagID) const;
 
   /// \brief Report a diagnostic.
-  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const;
 
   IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID);
 
@@ -1933,7 +1963,7 @@
   /// number.
   serialization::SubmoduleID 
   getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID);
-  
+
   /// \brief Retrieve the submodule that corresponds to a global submodule ID.
   ///
   Module *getSubmodule(serialization::SubmoduleID GlobalID);
@@ -1953,6 +1983,8 @@
   /// \brief Return a descriptor for the corresponding module.
   llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override;
 
+  ExtKind hasExternalDefinitions(unsigned ID) override;
+
   /// \brief Retrieve a selector from the given module with its local ID
   /// number.
   Selector getLocalSelector(ModuleFile &M, unsigned LocalID);
@@ -2042,6 +2074,8 @@
   /// location space into ours.
   SourceLocation TranslateSourceLocation(ModuleFile &ModuleFile,
                                          SourceLocation Loc) const {
+    if (!ModuleFile.ModuleOffsetMap.empty())
+      ReadModuleOffsetMap(ModuleFile);
     assert(ModuleFile.SLocRemap.find(Loc.getOffset()) !=
                ModuleFile.SLocRemap.end() &&
            "Cannot find offset to remap.");
@@ -2083,8 +2117,7 @@
                                  unsigned &Idx);
 
   /// \brief Reads attributes from the current stream position.
-  void ReadAttributes(ModuleFile &F, AttrVec &Attrs,
-                      const RecordData &Record, unsigned &Idx);
+  void ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs);
 
   /// \brief Reads a statement.
   Stmt *ReadStmt(ModuleFile &F);
@@ -2174,9 +2207,304 @@
   /// \brief Loads comments ranges.
   void ReadComments() override;
 
+  /// Visit all the input files of the given module file.
+  void visitInputFiles(serialization::ModuleFile &MF,
+                       bool IncludeSystem, bool Complain,
+          llvm::function_ref<void(const serialization::InputFile &IF,
+                                  bool isSystem)> Visitor);
+
   bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
 };
 
+/// \brief An object for streaming information from a record.
+class ASTRecordReader {
+  typedef serialization::ModuleFile ModuleFile;
+
+  ASTReader *Reader;
+  ModuleFile *F;
+  unsigned Idx = 0;
+  ASTReader::RecordData Record;
+
+  typedef ASTReader::RecordData RecordData;
+  typedef ASTReader::RecordDataImpl RecordDataImpl;
+
+public:
+  /// Construct an ASTRecordReader that uses the default encoding scheme.
+  ASTRecordReader(ASTReader &Reader, ModuleFile &F)
+      : Reader(&Reader), F(&F) {}
+
+  /// \brief Reads a record with id AbbrevID from Cursor, resetting the
+  /// internal state.
+  unsigned readRecord(llvm::BitstreamCursor &Cursor, unsigned AbbrevID);
+
+  /// \brief Is this a module file for a module (rather than a PCH or similar).
+  bool isModule() const { return F->isModule(); }
+
+  /// \brief Retrieve the AST context that this AST reader supplements.
+  ASTContext &getContext() { return Reader->getContext(); }
+
+  /// \brief The current position in this record.
+  unsigned getIdx() const { return Idx; }
+  /// \brief The length of this record.
+  size_t size() const { return Record.size(); }
+
+  /// \brief An arbitrary index in this record.
+  const uint64_t &operator[](size_t N) { return Record[N]; }
+  /// \brief The last element in this record.
+  const uint64_t &back() const { return Record.back(); }
+
+  /// \brief Returns the current value in this record, and advances to the
+  /// next value.
+  const uint64_t &readInt() { return Record[Idx++]; }
+  /// \brief Returns the current value in this record, without advancing.
+  const uint64_t &peekInt() { return Record[Idx]; }
+
+  /// \brief Skips the specified number of values.
+  void skipInts(unsigned N) { Idx += N; }
+
+  /// \brief Retrieve the global submodule ID its local ID number.
+  serialization::SubmoduleID
+  getGlobalSubmoduleID(unsigned LocalID) {
+    return Reader->getGlobalSubmoduleID(*F, LocalID);
+  }
+
+  /// \brief Retrieve the submodule that corresponds to a global submodule ID.
+  Module *getSubmodule(serialization::SubmoduleID GlobalID) {
+    return Reader->getSubmodule(GlobalID);
+  }
+
+  /// \brief Read the record that describes the lexical contents of a DC.
+  bool readLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) {
+    return Reader->ReadLexicalDeclContextStorage(*F, F->DeclsCursor, Offset,
+                                                 DC);
+  }
+
+  /// \brief Read the record that describes the visible contents of a DC.
+  bool readVisibleDeclContextStorage(uint64_t Offset,
+                                     serialization::DeclID ID) {
+    return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset,
+                                                 ID);
+  }
+
+  void readExceptionSpec(SmallVectorImpl<QualType> &ExceptionStorage,
+                         FunctionProtoType::ExceptionSpecInfo &ESI) {
+    return Reader->readExceptionSpec(*F, ExceptionStorage, ESI, Record, Idx);
+  }
+
+  /// \brief Get the global offset corresponding to a local offset.
+  uint64_t getGlobalBitOffset(uint32_t LocalOffset) {
+    return Reader->getGlobalBitOffset(*F, LocalOffset);
+  }
+
+  /// \brief Reads a statement.
+  Stmt *readStmt() { return Reader->ReadStmt(*F); }
+
+  /// \brief Reads an expression.
+  Expr *readExpr() { return Reader->ReadExpr(*F); }
+
+  /// \brief Reads a sub-statement operand during statement reading.
+  Stmt *readSubStmt() { return Reader->ReadSubStmt(); }
+
+  /// \brief Reads a sub-expression operand during statement reading.
+  Expr *readSubExpr() { return Reader->ReadSubExpr(); }
+
+  /// \brief Reads a declaration with the given local ID in the given module.
+  ///
+  /// \returns The requested declaration, casted to the given return type.
+  template<typename T>
+  T *GetLocalDeclAs(uint32_t LocalID) {
+    return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID));
+  }
+
+  /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+  /// given TemplateArgument kind, advancing Idx.
+  TemplateArgumentLocInfo
+  getTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind) {
+    return Reader->GetTemplateArgumentLocInfo(*F, Kind, Record, Idx);
+  }
+
+  /// \brief Reads a TemplateArgumentLoc, advancing Idx.
+  TemplateArgumentLoc
+  readTemplateArgumentLoc() {
+    return Reader->ReadTemplateArgumentLoc(*F, Record, Idx);
+  }
+
+  const ASTTemplateArgumentListInfo*
+  readASTTemplateArgumentListInfo() {
+    return Reader->ReadASTTemplateArgumentListInfo(*F, Record, Idx);
+  }
+
+  /// \brief Reads a declarator info from the given record, advancing Idx.
+  TypeSourceInfo *getTypeSourceInfo() {
+    return Reader->GetTypeSourceInfo(*F, Record, Idx);
+  }
+
+  /// \brief Map a local type ID within a given AST file to a global type ID.
+  serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
+    return Reader->getGlobalTypeID(*F, LocalID);
+  }
+
+  /// \brief Read a type from the current position in the record.
+  QualType readType() {
+    return Reader->readType(*F, Record, Idx);
+  }
+
+  /// \brief Reads a declaration ID from the given position in this record.
+  ///
+  /// \returns The declaration ID read from the record, adjusted to a global ID.
+  serialization::DeclID readDeclID() {
+    return Reader->ReadDeclID(*F, Record, Idx);
+  }
+
+  /// \brief Reads a declaration from the given position in a record in the
+  /// given module, advancing Idx.
+  Decl *readDecl() {
+    return Reader->ReadDecl(*F, Record, Idx);
+  }
+
+  /// \brief Reads a declaration from the given position in the record,
+  /// advancing Idx.
+  ///
+  /// \returns The declaration read from this location, casted to the given
+  /// result type.
+  template<typename T>
+  T *readDeclAs() {
+    return Reader->ReadDeclAs<T>(*F, Record, Idx);
+  }
+
+  IdentifierInfo *getIdentifierInfo() {
+    return Reader->GetIdentifierInfo(*F, Record, Idx);
+  }
+
+  /// \brief Read a selector from the Record, advancing Idx.
+  Selector readSelector() {
+    return Reader->ReadSelector(*F, Record, Idx);
+  }
+
+  /// \brief Read a declaration name, advancing Idx.
+  DeclarationName readDeclarationName() {
+    return Reader->ReadDeclarationName(*F, Record, Idx);
+  }
+  void readDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name) {
+    return Reader->ReadDeclarationNameLoc(*F, DNLoc, Name, Record, Idx);
+  }
+  void readDeclarationNameInfo(DeclarationNameInfo &NameInfo) {
+    return Reader->ReadDeclarationNameInfo(*F, NameInfo, Record, Idx);
+  }
+
+  void readQualifierInfo(QualifierInfo &Info) {
+    return Reader->ReadQualifierInfo(*F, Info, Record, Idx);
+  }
+
+  NestedNameSpecifier *readNestedNameSpecifier() {
+    return Reader->ReadNestedNameSpecifier(*F, Record, Idx);
+  }
+
+  NestedNameSpecifierLoc readNestedNameSpecifierLoc() {
+    return Reader->ReadNestedNameSpecifierLoc(*F, Record, Idx);
+  }
+
+  /// \brief Read a template name, advancing Idx.
+  TemplateName readTemplateName() {
+    return Reader->ReadTemplateName(*F, Record, Idx);
+  }
+
+  /// \brief Read a template argument, advancing Idx.
+  TemplateArgument readTemplateArgument(bool Canonicalize = false) {
+    return Reader->ReadTemplateArgument(*F, Record, Idx, Canonicalize);
+  }
+
+  /// \brief Read a template parameter list, advancing Idx.
+  TemplateParameterList *readTemplateParameterList() {
+    return Reader->ReadTemplateParameterList(*F, Record, Idx);
+  }
+
+  /// \brief Read a template argument array, advancing Idx.
+  void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
+                                bool Canonicalize = false) {
+    return Reader->ReadTemplateArgumentList(TemplArgs, *F, Record, Idx,
+                                            Canonicalize);
+  }
+
+  /// \brief Read a UnresolvedSet structure, advancing Idx.
+  void readUnresolvedSet(LazyASTUnresolvedSet &Set) {
+    return Reader->ReadUnresolvedSet(*F, Set, Record, Idx);
+  }
+
+  /// \brief Read a C++ base specifier, advancing Idx.
+  CXXBaseSpecifier readCXXBaseSpecifier() {
+    return Reader->ReadCXXBaseSpecifier(*F, Record, Idx);
+  }
+
+  /// \brief Read a CXXCtorInitializer array, advancing Idx.
+  CXXCtorInitializer **readCXXCtorInitializers() {
+    return Reader->ReadCXXCtorInitializers(*F, Record, Idx);
+  }
+
+  CXXTemporary *readCXXTemporary() {
+    return Reader->ReadCXXTemporary(*F, Record, Idx);
+  }
+
+  /// \brief Read a source location, advancing Idx.
+  SourceLocation readSourceLocation() {
+    return Reader->ReadSourceLocation(*F, Record, Idx);
+  }
+
+  /// \brief Read a source range, advancing Idx.
+  SourceRange readSourceRange() {
+    return Reader->ReadSourceRange(*F, Record, Idx);
+  }
+
+  /// \brief Read an integral value, advancing Idx.
+  llvm::APInt readAPInt() {
+    return Reader->ReadAPInt(Record, Idx);
+  }
+
+  /// \brief Read a signed integral value, advancing Idx.
+  llvm::APSInt readAPSInt() {
+    return Reader->ReadAPSInt(Record, Idx);
+  }
+
+  /// \brief Read a floating-point value, advancing Idx.
+  llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem) {
+    return Reader->ReadAPFloat(Record, Sem,Idx);
+  }
+
+  /// \brief Read a string, advancing Idx.
+  std::string readString() {
+    return Reader->ReadString(Record, Idx);
+  }
+
+  /// \brief Read a path, advancing Idx.
+  std::string readPath() {
+    return Reader->ReadPath(*F, Record, Idx);
+  }
+
+  /// \brief Read a version tuple, advancing Idx.
+  VersionTuple readVersionTuple() {
+    return ASTReader::ReadVersionTuple(Record, Idx);
+  }
+
+  /// \brief Reads attributes from the current stream position, advancing Idx.
+  void readAttributes(AttrVec &Attrs) {
+    return Reader->ReadAttributes(*this, Attrs);
+  }
+
+  /// \brief Reads a token out of a record, advancing Idx.
+  Token readToken() {
+    return Reader->ReadToken(*F, Record, Idx);
+  }
+
+  void recordSwitchCaseID(SwitchCase *SC, unsigned ID) {
+    Reader->RecordSwitchCaseID(SC, ID);
+  }
+
+  /// \brief Retrieve the switch-case statement with the given ID.
+  SwitchCase *getSwitchCaseWithID(unsigned ID) {
+    return Reader->getSwitchCaseWithID(ID);
+  }
+};
+
 /// \brief Helper class that saves the current stream position and
 /// then restores it when destroyed.
 struct SavedStreamPosition {
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 2462900..f3c644b 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -106,17 +106,20 @@
   /// \brief The bitstream writer used to emit this precompiled header.
   llvm::BitstreamWriter &Stream;
 
+  /// The buffer associated with the bitstream.
+  const SmallVectorImpl<char> &Buffer;
+
   /// \brief The ASTContext we're writing.
-  ASTContext *Context;
+  ASTContext *Context = nullptr;
 
   /// \brief The preprocessor we're writing.
-  Preprocessor *PP;
+  Preprocessor *PP = nullptr;
 
   /// \brief The reader of existing AST files, if we're chaining.
-  ASTReader *Chain;
+  ASTReader *Chain = nullptr;
 
   /// \brief The module we're currently writing, if any.
-  Module *WritingModule;
+  Module *WritingModule = nullptr;
 
   /// \brief The base directory for any relative paths we emit.
   std::string BaseDirectory;
@@ -129,14 +132,14 @@
 
   /// \brief Indicates when the AST writing is actively performing
   /// serialization, rather than just queueing updates.
-  bool WritingAST;
+  bool WritingAST = false;
 
   /// \brief Indicates that we are done serializing the collection of decls
   /// and types to emit.
-  bool DoneWritingDeclsAndTypes;
+  bool DoneWritingDeclsAndTypes = false;
 
   /// \brief Indicates that the AST contained compiler errors.
-  bool ASTHasCompilerErrors;
+  bool ASTHasCompilerErrors = false;
 
   /// \brief Mapping from input file entries to the index into the
   /// offset table where information about that input file is stored.
@@ -170,10 +173,10 @@
   std::queue<DeclOrType> DeclTypesToEmit;
 
   /// \brief The first ID number we can use for our own declarations.
-  serialization::DeclID FirstDeclID;
+  serialization::DeclID FirstDeclID = serialization::NUM_PREDEF_DECL_IDS;
 
   /// \brief The decl ID that will be assigned to the next new decl.
-  serialization::DeclID NextDeclID;
+  serialization::DeclID NextDeclID = FirstDeclID;
 
   /// \brief Map that provides the ID numbers of each declaration within
   /// the output stream, as well as those deserialized from a chained PCH.
@@ -205,10 +208,10 @@
   void associateDeclWithFile(const Decl *D, serialization::DeclID);
 
   /// \brief The first ID number we can use for our own types.
-  serialization::TypeID FirstTypeID;
+  serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS;
 
   /// \brief The type ID that will be assigned to the next new type.
-  serialization::TypeID NextTypeID;
+  serialization::TypeID NextTypeID = FirstTypeID;
 
   /// \brief Map that provides the ID numbers of each type within the
   /// output stream, plus those deserialized from a chained PCH.
@@ -226,10 +229,10 @@
   std::vector<uint32_t> TypeOffsets;
 
   /// \brief The first ID number we can use for our own identifiers.
-  serialization::IdentID FirstIdentID;
+  serialization::IdentID FirstIdentID = serialization::NUM_PREDEF_IDENT_IDS;
 
   /// \brief The identifier ID that will be assigned to the next new identifier.
-  serialization::IdentID NextIdentID;
+  serialization::IdentID NextIdentID = FirstIdentID;
 
   /// \brief Map that provides the ID numbers of each identifier in
   /// the output stream.
@@ -240,10 +243,10 @@
   llvm::MapVector<const IdentifierInfo *, serialization::IdentID> IdentifierIDs;
 
   /// \brief The first ID number we can use for our own macros.
-  serialization::MacroID FirstMacroID;
+  serialization::MacroID FirstMacroID = serialization::NUM_PREDEF_MACRO_IDS;
 
   /// \brief The identifier ID that will be assigned to the next new identifier.
-  serialization::MacroID NextMacroID;
+  serialization::MacroID NextMacroID = FirstMacroID;
 
   /// \brief Map that provides the ID numbers of each macro.
   llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs;
@@ -275,16 +278,18 @@
   std::vector<uint32_t> IdentifierOffsets;
 
   /// \brief The first ID number we can use for our own submodules.
-  serialization::SubmoduleID FirstSubmoduleID;
-  
+  serialization::SubmoduleID FirstSubmoduleID =
+      serialization::NUM_PREDEF_SUBMODULE_IDS;
+
   /// \brief The submodule ID that will be assigned to the next new submodule.
-  serialization::SubmoduleID NextSubmoduleID;
+  serialization::SubmoduleID NextSubmoduleID = FirstSubmoduleID;
 
   /// \brief The first ID number we can use for our own selectors.
-  serialization::SelectorID FirstSelectorID;
+  serialization::SelectorID FirstSelectorID =
+      serialization::NUM_PREDEF_SELECTOR_IDS;
 
   /// \brief The selector ID that will be assigned to the next new selector.
-  serialization::SelectorID NextSelectorID;
+  serialization::SelectorID NextSelectorID = FirstSelectorID;
 
   /// \brief Map that provides the ID numbers of each Selector.
   llvm::MapVector<Selector, serialization::SelectorID> SelectorIDs;
@@ -363,6 +368,7 @@
   /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS
   /// record.
   SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
+  SmallVector<uint64_t, 16> ModularCodegenDecls;
 
   /// \brief DeclContexts that have received extensions since their serialized
   /// form.
@@ -394,18 +400,18 @@
   llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs;
 
   /// \brief The number of statements written to the AST file.
-  unsigned NumStatements;
+  unsigned NumStatements = 0;
 
   /// \brief The number of macros written to the AST file.
-  unsigned NumMacros;
+  unsigned NumMacros = 0;
 
   /// \brief The number of lexical declcontexts written to the AST
   /// file.
-  unsigned NumLexicalDeclContexts;
+  unsigned NumLexicalDeclContexts = 0;
 
   /// \brief The number of visible declcontexts written to the AST
   /// file.
-  unsigned NumVisibleDeclContexts;
+  unsigned NumVisibleDeclContexts = 0;
 
   /// \brief A mapping from each known submodule to its ID number, which will
   /// be a positive integer.
@@ -422,8 +428,16 @@
   void WriteSubStmt(Stmt *S);
 
   void WriteBlockInfoBlock();
-  uint64_t WriteControlBlock(Preprocessor &PP, ASTContext &Context,
-                             StringRef isysroot, const std::string &OutputFile);
+  void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+                         StringRef isysroot, const std::string &OutputFile);
+
+  /// Write out the signature and diagnostic options, and return the signature.
+  ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP,
+                                             ASTContext &Context);
+
+  /// Calculate hash of the pcm content.
+  static ASTFileSignature createSignature(StringRef Bytes);
+
   void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts,
                        bool Modules);
   void WriteSourceManagerBlock(SourceManager &SourceMgr,
@@ -436,8 +450,8 @@
   void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
                                      bool isModule);
 
-  unsigned TypeExtQualAbbrev;
-  unsigned TypeFunctionProtoAbbrev;
+  unsigned TypeExtQualAbbrev = 0;
+  unsigned TypeFunctionProtoAbbrev = 0;
   void WriteTypeAbbrevs();
   void WriteType(QualType T);
 
@@ -459,6 +473,8 @@
   void WriteDeclContextVisibleUpdate(const DeclContext *DC);
   void WriteFPPragmaOptions(const FPOptions &Opts);
   void WriteOpenCLExtensions(Sema &SemaRef);
+  void WriteOpenCLExtensionTypes(Sema &SemaRef);
+  void WriteOpenCLExtensionDecls(Sema &SemaRef);
   void WriteCUDAPragmas(Sema &SemaRef);
   void WriteObjCCategories();
   void WriteLateParsedTemplates(Sema &SemaRef);
@@ -468,35 +484,35 @@
   void WriteModuleFileExtension(Sema &SemaRef,
                                 ModuleFileExtensionWriter &Writer);
 
-  unsigned DeclParmVarAbbrev;
-  unsigned DeclContextLexicalAbbrev;
-  unsigned DeclContextVisibleLookupAbbrev;
-  unsigned UpdateVisibleAbbrev;
-  unsigned DeclRecordAbbrev;
-  unsigned DeclTypedefAbbrev;
-  unsigned DeclVarAbbrev;
-  unsigned DeclFieldAbbrev;
-  unsigned DeclEnumAbbrev;
-  unsigned DeclObjCIvarAbbrev;
-  unsigned DeclCXXMethodAbbrev;
+  unsigned DeclParmVarAbbrev = 0;
+  unsigned DeclContextLexicalAbbrev = 0;
+  unsigned DeclContextVisibleLookupAbbrev = 0;
+  unsigned UpdateVisibleAbbrev = 0;
+  unsigned DeclRecordAbbrev = 0;
+  unsigned DeclTypedefAbbrev = 0;
+  unsigned DeclVarAbbrev = 0;
+  unsigned DeclFieldAbbrev = 0;
+  unsigned DeclEnumAbbrev = 0;
+  unsigned DeclObjCIvarAbbrev = 0;
+  unsigned DeclCXXMethodAbbrev = 0;
 
-  unsigned DeclRefExprAbbrev;
-  unsigned CharacterLiteralAbbrev;
-  unsigned IntegerLiteralAbbrev;
-  unsigned ExprImplicitCastAbbrev;
+  unsigned DeclRefExprAbbrev = 0;
+  unsigned CharacterLiteralAbbrev = 0;
+  unsigned IntegerLiteralAbbrev = 0;
+  unsigned ExprImplicitCastAbbrev = 0;
 
   void WriteDeclAbbrevs();
   void WriteDecl(ASTContext &Context, Decl *D);
 
-  uint64_t WriteASTCore(Sema &SemaRef,
-                        StringRef isysroot, const std::string &OutputFile,
-                        Module *WritingModule);
+  ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot,
+                                const std::string &OutputFile,
+                                Module *WritingModule);
 
 public:
   /// \brief Create a new precompiled header writer that outputs to
   /// the given bitstream.
-  ASTWriter(llvm::BitstreamWriter &Stream,
-            ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
+  ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
+            ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
             bool IncludeTimestamps = true);
   ~ASTWriter() override;
 
@@ -521,9 +537,9 @@
   ///
   /// \return the module signature, which eventually will be a hash of
   /// the module but currently is merely a random 32-bit number.
-  uint64_t WriteAST(Sema &SemaRef, const std::string &OutputFile,
-                    Module *WritingModule, StringRef isysroot,
-                    bool hasErrors = false);
+  ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile,
+                            Module *WritingModule, StringRef isysroot,
+                            bool hasErrors = false);
 
   /// \brief Emit a token.
   void AddToken(const Token &Tok, RecordDataImpl &Record);
@@ -932,13 +948,10 @@
   SmallVectorImpl<char> &getPCH() const { return Buffer->Data; }
 
 public:
-  PCHGenerator(
-    const Preprocessor &PP, StringRef OutputFile,
-    StringRef isysroot,
-    std::shared_ptr<PCHBuffer> Buffer,
-    ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
-    bool AllowASTWithErrors = false,
-    bool IncludeTimestamps = true);
+  PCHGenerator(const Preprocessor &PP, StringRef OutputFile, StringRef isysroot,
+               std::shared_ptr<PCHBuffer> Buffer,
+               ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
+               bool AllowASTWithErrors = false, bool IncludeTimestamps = true);
   ~PCHGenerator() override;
   void InitializeSema(Sema &S) override { SemaPtr = &S; }
   void HandleTranslationUnit(ASTContext &Ctx) override;
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 58b3149..c1d4a9f 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_SERIALIZATION_MODULE_H
 
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/Module.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Serialization/ASTBitCodes.h"
 #include "clang/Serialization/ContinuousRangeMap.h"
@@ -89,8 +90,6 @@
   bool isNotFound() const { return Val.getInt() == NotFound; }
 };
 
-typedef unsigned ASTFileSignature;
-
 /// \brief Information about a module that has been loaded by the ASTReader.
 ///
 /// Each instance of the Module class corresponds to a single AST file, which
@@ -100,13 +99,14 @@
 /// other modules.
 class ModuleFile {
 public:
-  ModuleFile(ModuleKind Kind, unsigned Generation);
+  ModuleFile(ModuleKind Kind, unsigned Generation)
+      : Kind(Kind), Generation(Generation) {}
   ~ModuleFile();
 
   // === General information ===
 
   /// \brief The index of this module in the list of modules.
-  unsigned Index;
+  unsigned Index = 0;
 
   /// \brief The type of this module.
   ModuleKind Kind;
@@ -144,21 +144,21 @@
   std::string ModuleMapPath;
 
   /// \brief Whether this precompiled header is a relocatable PCH file.
-  bool RelocatablePCH;
+  bool RelocatablePCH = false;
 
   /// \brief Whether timestamps are included in this module file.
-  bool HasTimestamps;
+  bool HasTimestamps = false;
 
   /// \brief The file entry for the module file.
-  const FileEntry *File;
+  const FileEntry *File = nullptr;
 
-  /// \brief The signature of the module file, which may be used along with size
+  /// The signature of the module file, which may be used instead of the size
   /// and modification time to identify this particular file.
   ASTFileSignature Signature;
 
   /// \brief Whether this module has been directly imported by the
   /// user.
-  bool DirectlyImported;
+  bool DirectlyImported = false;
 
   /// \brief The generation of which this module file is a part.
   unsigned Generation;
@@ -168,10 +168,10 @@
   std::unique_ptr<llvm::MemoryBuffer> Buffer;
 
   /// \brief The size of this file, in bits.
-  uint64_t SizeInBits;
+  uint64_t SizeInBits = 0;
 
   /// \brief The global bit offset (or base) of this module
-  uint64_t GlobalBitOffset;
+  uint64_t GlobalBitOffset = 0;
 
   /// \brief The serialized bitstream data for this file.
   StringRef Data;
@@ -200,21 +200,29 @@
   /// file.
   std::vector<std::unique_ptr<ModuleFileExtensionReader>> ExtensionReaders;
 
+  /// The module offset map data for this file. If non-empty, the various
+  /// ContinuousRangeMaps described below have not yet been populated.
+  StringRef ModuleOffsetMap;
+
   // === Input Files ===
   /// \brief The cursor to the start of the input-files block.
   llvm::BitstreamCursor InputFilesCursor;
 
   /// \brief Offsets for all of the input file entries in the AST file.
-  const llvm::support::unaligned_uint64_t *InputFileOffsets;
+  const llvm::support::unaligned_uint64_t *InputFileOffsets = nullptr;
 
   /// \brief The input files that have been loaded from this AST file.
   std::vector<InputFile> InputFilesLoaded;
 
+  // All user input files reside at the index range [0, NumUserInputFiles), and
+  // system input files reside at [NumUserInputFiles, InputFilesLoaded.size()).
+  unsigned NumUserInputFiles = 0;
+
   /// \brief If non-zero, specifies the time when we last validated input
   /// files.  Zero means we never validated them.
   ///
   /// The time is specified in seconds since the start of the Epoch.
-  uint64_t InputFilesValidationTimestamp;
+  uint64_t InputFilesValidationTimestamp = 0;
 
   // === Source Locations ===
 
@@ -222,17 +230,17 @@
   llvm::BitstreamCursor SLocEntryCursor;
 
   /// \brief The number of source location entries in this AST file.
-  unsigned LocalNumSLocEntries;
+  unsigned LocalNumSLocEntries = 0;
 
   /// \brief The base ID in the source manager's view of this module.
-  int SLocEntryBaseID;
+  int SLocEntryBaseID = 0;
 
   /// \brief The base offset in the source manager's view of this module.
-  unsigned SLocEntryBaseOffset;
+  unsigned SLocEntryBaseOffset = 0;
 
   /// \brief Offsets for all of the source location entries in the
   /// AST file.
-  const uint32_t *SLocEntryOffsets;
+  const uint32_t *SLocEntryOffsets = nullptr;
 
   /// \brief SLocEntries that we're going to preload.
   SmallVector<uint64_t, 4> PreloadSLocEntries;
@@ -243,17 +251,17 @@
   // === Identifiers ===
 
   /// \brief The number of identifiers in this AST file.
-  unsigned LocalNumIdentifiers;
+  unsigned LocalNumIdentifiers = 0;
 
   /// \brief Offsets into the identifier table data.
   ///
   /// This array is indexed by the identifier ID (-1), and provides
   /// the offset into IdentifierTableData where the string data is
   /// stored.
-  const uint32_t *IdentifierOffsets;
+  const uint32_t *IdentifierOffsets = nullptr;
 
   /// \brief Base identifier ID for identifiers local to this module.
-  serialization::IdentID BaseIdentifierID;
+  serialization::IdentID BaseIdentifierID = 0;
 
   /// \brief Remapping table for identifier IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap;
@@ -262,11 +270,11 @@
   ///
   /// This pointer points into a memory buffer, where the on-disk hash
   /// table for identifiers actually lives.
-  const char *IdentifierTableData;
+  const char *IdentifierTableData = nullptr;
 
   /// \brief A pointer to an on-disk hash table of opaque type
   /// IdentifierHashTable.
-  void *IdentifierLookupTable;
+  void *IdentifierLookupTable = nullptr;
 
   /// \brief Offsets of identifiers that we're going to preload within
   /// IdentifierTableData.
@@ -279,23 +287,23 @@
   llvm::BitstreamCursor MacroCursor;
 
   /// \brief The number of macros in this AST file.
-  unsigned LocalNumMacros;
+  unsigned LocalNumMacros = 0;
 
   /// \brief Offsets of macros in the preprocessor block.
   ///
   /// This array is indexed by the macro ID (-1), and provides
   /// the offset into the preprocessor block where macro definitions are
   /// stored.
-  const uint32_t *MacroOffsets;
+  const uint32_t *MacroOffsets = nullptr;
 
   /// \brief Base macro ID for macros local to this module.
-  serialization::MacroID BaseMacroID;
+  serialization::MacroID BaseMacroID = 0;
 
   /// \brief Remapping table for macro IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> MacroRemap;
 
   /// \brief The offset of the start of the set of defined macros.
-  uint64_t MacroStartOffset;
+  uint64_t MacroStartOffset = 0;
 
   // === Detailed PreprocessingRecord ===
 
@@ -304,40 +312,40 @@
   llvm::BitstreamCursor PreprocessorDetailCursor;
 
   /// \brief The offset of the start of the preprocessor detail cursor.
-  uint64_t PreprocessorDetailStartOffset;
+  uint64_t PreprocessorDetailStartOffset = 0;
 
   /// \brief Base preprocessed entity ID for preprocessed entities local to
   /// this module.
-  serialization::PreprocessedEntityID BasePreprocessedEntityID;
+  serialization::PreprocessedEntityID BasePreprocessedEntityID = 0;
 
   /// \brief Remapping table for preprocessed entity IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap;
 
-  const PPEntityOffset *PreprocessedEntityOffsets;
-  unsigned NumPreprocessedEntities;
+  const PPEntityOffset *PreprocessedEntityOffsets = nullptr;
+  unsigned NumPreprocessedEntities = 0;
 
   // === Header search information ===
 
   /// \brief The number of local HeaderFileInfo structures.
-  unsigned LocalNumHeaderFileInfos;
+  unsigned LocalNumHeaderFileInfos = 0;
 
   /// \brief Actual data for the on-disk hash table of header file
   /// information.
   ///
   /// This pointer points into a memory buffer, where the on-disk hash
   /// table for header file information actually lives.
-  const char *HeaderFileInfoTableData;
+  const char *HeaderFileInfoTableData = nullptr;
 
   /// \brief The on-disk hash table that contains information about each of
   /// the header files.
-  void *HeaderFileInfoTable;
+  void *HeaderFileInfoTable = nullptr;
 
   // === Submodule information ===  
   /// \brief The number of submodules in this module.
-  unsigned LocalNumSubmodules;
+  unsigned LocalNumSubmodules = 0;
   
   /// \brief Base submodule ID for submodules local to this module.
-  serialization::SubmoduleID BaseSubmoduleID;
+  serialization::SubmoduleID BaseSubmoduleID = 0;
   
   /// \brief Remapping table for submodule IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap;
@@ -347,14 +355,14 @@
   /// \brief The number of selectors new to this file.
   ///
   /// This is the number of entries in SelectorOffsets.
-  unsigned LocalNumSelectors;
+  unsigned LocalNumSelectors = 0;
 
   /// \brief Offsets into the selector lookup table's data array
   /// where each selector resides.
-  const uint32_t *SelectorOffsets;
+  const uint32_t *SelectorOffsets = nullptr;
 
   /// \brief Base selector ID for selectors local to this module.
-  serialization::SelectorID BaseSelectorID;
+  serialization::SelectorID BaseSelectorID = 0;
 
   /// \brief Remapping table for selector IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> SelectorRemap;
@@ -362,14 +370,14 @@
   /// \brief A pointer to the character data that comprises the selector table
   ///
   /// The SelectorOffsets table refers into this memory.
-  const unsigned char *SelectorLookupTableData;
+  const unsigned char *SelectorLookupTableData = nullptr;
 
   /// \brief A pointer to an on-disk hash table of opaque type
   /// ASTSelectorLookupTable.
   ///
   /// This hash table provides the IDs of all selectors, and the associated
   /// instance and factory methods.
-  void *SelectorLookupTable;
+  void *SelectorLookupTable = nullptr;
 
   // === Declarations ===
 
@@ -379,14 +387,14 @@
   llvm::BitstreamCursor DeclsCursor;
 
   /// \brief The number of declarations in this AST file.
-  unsigned LocalNumDecls;
+  unsigned LocalNumDecls = 0;
 
   /// \brief Offset of each declaration within the bitstream, indexed
   /// by the declaration ID (-1).
-  const DeclOffset *DeclOffsets;
+  const DeclOffset *DeclOffsets = nullptr;
 
   /// \brief Base declaration ID for declarations local to this module.
-  serialization::DeclID BaseDeclID;
+  serialization::DeclID BaseDeclID = 0;
 
   /// \brief Remapping table for declaration IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> DeclRemap;
@@ -401,15 +409,15 @@
   llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;
 
   /// \brief Array of file-level DeclIDs sorted by file.
-  const serialization::DeclID *FileSortedDecls;
-  unsigned NumFileSortedDecls;
+  const serialization::DeclID *FileSortedDecls = nullptr;
+  unsigned NumFileSortedDecls = 0;
 
   /// \brief Array of category list location information within this 
   /// module file, sorted by the definition ID.
-  const serialization::ObjCCategoriesInfo *ObjCCategoriesMap;
+  const serialization::ObjCCategoriesInfo *ObjCCategoriesMap = nullptr;
   
   /// \brief The number of redeclaration info entries in ObjCCategoriesMap.
-  unsigned LocalNumObjCCategoriesInMap;
+  unsigned LocalNumObjCCategoriesInMap = 0;
   
   /// \brief The Objective-C category lists for categories known to this
   /// module.
@@ -418,15 +426,15 @@
   // === Types ===
 
   /// \brief The number of types in this AST file.
-  unsigned LocalNumTypes;
+  unsigned LocalNumTypes = 0;
 
   /// \brief Offset of each type within the bitstream, indexed by the
   /// type ID, or the representation of a Type*.
-  const uint32_t *TypeOffsets;
+  const uint32_t *TypeOffsets = nullptr;
 
   /// \brief Base type ID for types local to this module as represented in
   /// the global type ID space.
-  serialization::TypeID BaseTypeIndex;
+  serialization::TypeID BaseTypeIndex = 0;
 
   /// \brief Remapping table for type IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> TypeRemap;
diff --git a/include/clang/Serialization/ModuleFileExtension.h b/include/clang/Serialization/ModuleFileExtension.h
index ba2e2fd..f7bdcec 100644
--- a/include/clang/Serialization/ModuleFileExtension.h
+++ b/include/clang/Serialization/ModuleFileExtension.h
@@ -60,7 +60,7 @@
 /// compiled module files (.pcm) and precompiled headers (.pch) via a
 /// custom writer that can then be accessed via a custom reader when
 /// the module file or precompiled header is loaded.
-class ModuleFileExtension : public llvm::RefCountedBase<ModuleFileExtension> {
+class ModuleFileExtension {
 public:
   virtual ~ModuleFileExtension();
 
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index 1c4d88e..70c9d9e 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -19,6 +19,7 @@
 #include "clang/Serialization/Module.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/iterator.h"
 
 namespace clang { 
 
@@ -32,7 +33,7 @@
 class ModuleManager {
   /// \brief The chain of AST files, in the order in which we started to load
   /// them (this order isn't really useful for anything).
-  SmallVector<ModuleFile *, 2> Chain;
+  SmallVector<std::unique_ptr<ModuleFile>, 2> Chain;
 
   /// \brief The chain of non-module PCH files. The first entry is the one named
   /// by the user, the last one is the one that doesn't depend on anything
@@ -111,9 +112,15 @@
   void returnVisitState(VisitState *State);
 
 public:
-  typedef SmallVectorImpl<ModuleFile*>::iterator ModuleIterator;
-  typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator;
-  typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator;
+  typedef llvm::pointee_iterator<
+      SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator>
+      ModuleIterator;
+  typedef llvm::pointee_iterator<
+      SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator>
+      ModuleConstIterator;
+  typedef llvm::pointee_iterator<
+      SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>
+      ModuleReverseIterator;
   typedef std::pair<uint32_t, StringRef> ModuleOffset;
 
   explicit ModuleManager(FileManager &FileMgr,
@@ -136,7 +143,8 @@
   ModuleReverseIterator rend() { return Chain.rend(); }
 
   /// \brief A range covering the PCH and preamble module files loaded.
-  llvm::iterator_range<ModuleConstIterator> pch_modules() const {
+  llvm::iterator_range<SmallVectorImpl<ModuleFile *>::const_iterator>
+  pch_modules() const {
     return llvm::make_range(PCHChain.begin(), PCHChain.end());
   }
 
@@ -152,10 +160,10 @@
   ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
   
   /// \brief Returns the module associated with the given name
-  ModuleFile *lookup(StringRef Name);
+  ModuleFile *lookup(StringRef Name) const;
 
   /// \brief Returns the module associated with the given module file.
-  ModuleFile *lookup(const FileEntry *File);
+  ModuleFile *lookup(const FileEntry *File) const;
 
   /// \brief Returns the in-memory (virtual file) buffer with the given name
   std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name);
@@ -220,8 +228,8 @@
                             ModuleFile *&Module,
                             std::string &ErrorStr);
 
-  /// \brief Remove the given set of modules.
-  void removeModules(ModuleIterator first, ModuleIterator last,
+  /// \brief Remove the modules starting from First (to the end).
+  void removeModules(ModuleIterator First,
                      llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
                      ModuleMap *modMap);
 
diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 6ea500f..ab33c76 100644
--- a/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -42,9 +42,9 @@
 
 def Cplusplus : Package<"cplusplus">;
 def CplusplusAlpha : Package<"cplusplus">, InPackage<Alpha>, Hidden;
+def CplusplusOptIn : Package<"cplusplus">, InPackage<OptIn>;
 
 def Valist : Package<"valist">;
-def ValistAlpha : Package<"valist">, InPackage<Alpha>, Hidden;
 
 def DeadCode : Package<"deadcode">;
 def DeadCodeAlpha : Package<"deadcode">, InPackage<Alpha>, Hidden;
@@ -78,6 +78,13 @@
 def MPI : Package<"mpi">, InPackage<OptIn>;
 
 def LLVM : Package<"llvm">;
+
+// The APIModeling package is for checkers that model APIs and don't perform
+// any diagnostics. These checkers are always turned on; this package is
+// intended for API modeling that is not controlled by the the target triple.
+def APIModeling : Package<"apiModeling">, Hidden;
+def GoogleAPIModeling : Package<"google">, InPackage<APIModeling>;
+
 def Debug : Package<"debug">;
 
 def CloneDetectionAlpha : Package<"clone">, InPackage<Alpha>, Hidden;
@@ -262,12 +269,20 @@
 
 } // end: "cplusplus"
 
-let ParentPackage = CplusplusAlpha in {
+let ParentPackage = CplusplusOptIn in {
 
 def VirtualCallChecker : Checker<"VirtualCall">,
   HelpText<"Check virtual function calls during construction or destruction">,
   DescFile<"VirtualCallChecker.cpp">;
 
+} // end: "optin.cplusplus"
+
+let ParentPackage = CplusplusAlpha in {
+
+def IteratorPastEndChecker : Checker<"IteratorPastEnd">,
+  HelpText<"Check iterators used past end">,
+  DescFile<"IteratorPastEndChecker.cpp">;
+
 } // end: "alpha.cplusplus"
 
 
@@ -275,7 +290,7 @@
 // Valist checkers.
 //===----------------------------------------------------------------------===//
 
-let ParentPackage = ValistAlpha in {
+let ParentPackage = Valist in {
 
 def UninitializedChecker : Checker<"Uninitialized">,
   HelpText<"Check for usages of uninitialized (or already released) va_lists.">,
@@ -289,7 +304,7 @@
   HelpText<"Check for va_lists which are copied onto itself.">,
   DescFile<"ValistChecker.cpp">;
 
-} // end : "alpha.valist"
+} // end : "valist"
 
 //===----------------------------------------------------------------------===//
 // Deadcode checkers.
@@ -479,20 +494,21 @@
 let ParentPackage = OSX in {
 
 def NumberObjectConversionChecker : Checker<"NumberObjectConversion">,
-  InPackage<OSX>,
   HelpText<"Check for erroneous conversions of objects representing numbers into numbers">,
   DescFile<"NumberObjectConversionChecker.cpp">;
 
 def MacOSXAPIChecker : Checker<"API">,
-  InPackage<OSX>,
   HelpText<"Check for proper uses of various Apple APIs">,
   DescFile<"MacOSXAPIChecker.cpp">;
 
 def MacOSKeychainAPIChecker : Checker<"SecKeychainAPI">,
-  InPackage<OSX>,
   HelpText<"Check for proper uses of Secure Keychain APIs">,
   DescFile<"MacOSKeychainAPIChecker.cpp">;
 
+def ObjCPropertyChecker : Checker<"ObjCProperty">,
+  HelpText<"Check for proper uses of Objective-C properties">,
+  DescFile<"ObjCPropertyChecker.cpp">;
+
 } // end "osx"
 
 let ParentPackage = Cocoa in {
@@ -641,6 +657,17 @@
   HelpText<"Check code for LLVM codebase conventions">,
   DescFile<"LLVMConventionsChecker.cpp">;
 
+
+
+//===----------------------------------------------------------------------===//
+// Checkers modeling Google APIs.
+//===----------------------------------------------------------------------===//
+
+def GTestChecker : Checker<"GTest">,
+  InPackage<GoogleAPIModeling>,
+  HelpText<"Model gtest assertion APIs">,
+  DescFile<"GTestChecker.cpp">;
+
 //===----------------------------------------------------------------------===//
 // Debugging checkers (for analyzer development).
 //===----------------------------------------------------------------------===//
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 73f4dd5..0f1eb09 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -66,8 +66,7 @@
   typedef SmallVector<std::unique_ptr<BugReporterVisitor>, 8> VisitorList;
   typedef VisitorList::iterator visitor_iterator;
   typedef SmallVector<StringRef, 2> ExtraTextList;
-  typedef SmallVector<llvm::IntrusiveRefCntPtr<PathDiagnosticNotePiece>, 4>
-      NoteList;
+  typedef SmallVector<std::shared_ptr<PathDiagnosticNotePiece>, 4> NoteList;
 
 protected:
   friend class BugReporter;
@@ -268,12 +267,12 @@
   /// the extra note should appear.
   void addNote(StringRef Msg, const PathDiagnosticLocation &Pos,
                ArrayRef<SourceRange> Ranges) {
-    PathDiagnosticNotePiece *P = new PathDiagnosticNotePiece(Pos, Msg);
+    auto P = std::make_shared<PathDiagnosticNotePiece>(Pos, Msg);
 
     for (const auto &R : Ranges)
       P->addRange(R);
 
-    Notes.push_back(P);
+    Notes.push_back(std::move(P));
   }
 
   // FIXME: Instead of making an override, we could have default-initialized
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index fdff747..b72bce5 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -59,10 +59,9 @@
   ///
   /// The last parameter can be used to register a new visitor with the given
   /// BugReport while processing a node.
-  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
-                                         const ExplodedNode *Pred,
-                                         BugReporterContext &BRC,
-                                         BugReport &BR) = 0;
+  virtual std::shared_ptr<PathDiagnosticPiece>
+  VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred,
+            BugReporterContext &BRC, BugReport &BR) = 0;
 
   /// \brief Provide custom definition for the final diagnostic piece on the
   /// path - the piece, which is displayed before the path is expanded.
@@ -121,10 +120,10 @@
 
   void Profile(llvm::FoldingSetNodeID &ID) const override;
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *PrevN,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 };
 
 class TrackConstraintBRVisitor final
@@ -150,10 +149,10 @@
   /// to make all PathDiagnosticPieces created by this visitor.
   static const char *getTag();
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *PrevN,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 
 private:
   /// Checks if the constraint is valid in the current state.
@@ -172,10 +171,10 @@
     ID.AddPointer(&x);
   }
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *PrevN,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 
   /// If the statement is a message send expression with nil receiver, returns
   /// the receiver expression. Returns NULL otherwise.
@@ -200,51 +199,41 @@
   /// to make all PathDiagnosticPieces created by this visitor.
   static const char *getTag();
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *Prev,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *Prev,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 
-  PathDiagnosticPiece *VisitNodeImpl(const ExplodedNode *N,
-                                     const ExplodedNode *Prev,
-                                     BugReporterContext &BRC,
-                                     BugReport &BR);
-  
-  PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
-                                       const ExplodedNode *N,
-                                       const CFGBlock *srcBlk,
-                                       const CFGBlock *dstBlk,
-                                       BugReport &R,
-                                       BugReporterContext &BRC);
+  std::shared_ptr<PathDiagnosticPiece> VisitNodeImpl(const ExplodedNode *N,
+                                                     const ExplodedNode *Prev,
+                                                     BugReporterContext &BRC,
+                                                     BugReport &BR);
 
-  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
-                                     bool tookTrue,
-                                     BugReporterContext &BRC,
-                                     BugReport &R,
-                                     const ExplodedNode *N);
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitTerminator(const Stmt *Term, const ExplodedNode *N,
+                  const CFGBlock *srcBlk, const CFGBlock *dstBlk, BugReport &R,
+                  BugReporterContext &BRC);
 
-  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
-                                     const DeclRefExpr *DR,
-                                     const bool tookTrue,
-                                     BugReporterContext &BRC,
-                                     BugReport &R,
-                                     const ExplodedNode *N);
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitTrueTest(const Expr *Cond, bool tookTrue, BugReporterContext &BRC,
+                BugReport &R, const ExplodedNode *N);
 
-  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
-                                     const BinaryOperator *BExpr,
-                                     const bool tookTrue,
-                                     BugReporterContext &BRC,
-                                     BugReport &R,
-                                     const ExplodedNode *N);
-  
-  PathDiagnosticPiece *VisitConditionVariable(StringRef LhsString,
-                                              const Expr *CondVarExpr,
-                                              const bool tookTrue,
-                                              BugReporterContext &BRC,
-                                              BugReport &R,
-                                              const ExplodedNode *N);
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitTrueTest(const Expr *Cond, const DeclRefExpr *DR, const bool tookTrue,
+                BugReporterContext &BRC, BugReport &R, const ExplodedNode *N);
+
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitTrueTest(const Expr *Cond, const BinaryOperator *BExpr,
+                const bool tookTrue, BugReporterContext &BRC, BugReport &R,
+                const ExplodedNode *N);
+
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr,
+                         const bool tookTrue, BugReporterContext &BRC,
+                         BugReport &R, const ExplodedNode *N);
 
   bool patternMatch(const Expr *Ex,
+                    const Expr *ParentEx,
                     raw_ostream &Out,
                     BugReporterContext &BRC,
                     BugReport &R,
@@ -269,10 +258,10 @@
     ID.AddPointer(getTag());
   }
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *Prev,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override {
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *Prev,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override {
     return nullptr;
   }
 
@@ -301,10 +290,10 @@
     ID.AddPointer(R);
   }
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *PrevN,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 };
 
 class SuppressInlineDefensiveChecksVisitor final
@@ -332,10 +321,10 @@
   /// to make all PathDiagnosticPieces created by this visitor.
   static const char *getTag();
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
-                                 const ExplodedNode *Pred,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+                                                 const ExplodedNode *Pred,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 };
 
 class CXXSelfAssignmentBRVisitor final
@@ -348,10 +337,10 @@
 
   void Profile(llvm::FoldingSetNodeID &ID) const override {}
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
-                                 const ExplodedNode *Pred,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+                                                 const ExplodedNode *Pred,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 };
 
 namespace bugreporter {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index 1cc3cae..dc6e54a 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -334,7 +334,7 @@
 // Path "pieces" for path-sensitive diagnostics.
 //===----------------------------------------------------------------------===//
 
-class PathDiagnosticPiece : public RefCountedBaseVPTR {
+class PathDiagnosticPiece {
 public:
   enum Kind { ControlFlow, Event, Macro, Call, Note };
   enum DisplayHint { Above, Below };
@@ -366,7 +366,7 @@
   PathDiagnosticPiece(Kind k, DisplayHint hint = Below);
 
 public:
-  ~PathDiagnosticPiece() override;
+  virtual ~PathDiagnosticPiece();
 
   StringRef getString() const { return str; }
 
@@ -416,9 +416,8 @@
 
   virtual void dump() const = 0;
 };
-  
-  
-class PathPieces : public std::list<IntrusiveRefCntPtr<PathDiagnosticPiece> > {
+
+class PathPieces : public std::list<std::shared_ptr<PathDiagnosticPiece>> {
   void flattenTo(PathPieces &Primary, PathPieces &Current,
                  bool ShouldFlattenMacros) const;
 public:
@@ -590,11 +589,11 @@
   PathDiagnosticLocation getLocation() const override {
     return callEnter;
   }
-  
-  IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallEnterEvent() const;
-  IntrusiveRefCntPtr<PathDiagnosticEventPiece>
-    getCallEnterWithinCallerEvent() const;
-  IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallExitEvent() const;
+
+  std::shared_ptr<PathDiagnosticEventPiece> getCallEnterEvent() const;
+  std::shared_ptr<PathDiagnosticEventPiece>
+  getCallEnterWithinCallerEvent() const;
+  std::shared_ptr<PathDiagnosticEventPiece> getCallExitEvent() const;
 
   void flattenLocations() override {
     callEnter.flatten();
@@ -602,11 +601,11 @@
     for (PathPieces::iterator I = path.begin(), 
          E = path.end(); I != E; ++I) (*I)->flattenLocations();
   }
-  
-  static PathDiagnosticCallPiece *construct(const ExplodedNode *N,
-                                            const CallExitEnd &CE,
-                                            const SourceManager &SM);
-  
+
+  static std::shared_ptr<PathDiagnosticCallPiece>
+  construct(const ExplodedNode *N, const CallExitEnd &CE,
+            const SourceManager &SM);
+
   static PathDiagnosticCallPiece *construct(PathPieces &pieces,
                                             const Decl *caller);
 
@@ -787,7 +786,7 @@
     assert(!Loc.isValid() && "End location already set!");
     Loc = EndPiece->getLocation();
     assert(Loc.isValid() && "Invalid location for end-of-path piece");
-    getActivePath().push_back(EndPiece.release());
+    getActivePath().push_back(std::move(EndPiece));
   }
 
   void appendToDesc(StringRef S) {
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index dd7a6c8..f947776 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -321,9 +321,11 @@
                       const InvalidatedSymbols *invalidated,
                       ArrayRef<const MemRegion *> Explicits,
                       ArrayRef<const MemRegion *> Regions,
+                      const LocationContext *LCtx,
                       const CallEvent *Call) {
-    return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
-                                                      Explicits, Regions, Call);
+    return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
+                                                           Explicits, Regions,
+                                                           LCtx, Call);
   }
 
 public:
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 5af717d..52ed260 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -102,12 +102,12 @@
 
 class CheckerManager {
   const LangOptions LangOpts;
-  AnalyzerOptionsRef AOptions;
+  AnalyzerOptions &AOptions;
   CheckName CurrentCheckName;
 
 public:
-  CheckerManager(const LangOptions &langOpts, AnalyzerOptionsRef AOptions)
-      : LangOpts(langOpts), AOptions(std::move(AOptions)) {}
+  CheckerManager(const LangOptions &langOpts, AnalyzerOptions &AOptions)
+      : LangOpts(langOpts), AOptions(AOptions) {}
 
   ~CheckerManager();
 
@@ -119,7 +119,7 @@
   void finishedCheckerRegistration();
 
   const LangOptions &getLangOpts() const { return LangOpts; }
-  AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
+  AnalyzerOptions &getAnalyzerOptions() { return AOptions; }
 
   typedef CheckerBase *CheckerRef;
   typedef const void *CheckerTag;
@@ -338,6 +338,7 @@
                               const InvalidatedSymbols *invalidated,
                               ArrayRef<const MemRegion *> ExplicitRegions,
                               ArrayRef<const MemRegion *> Regions,
+                              const LocationContext *LCtx,
                               const CallEvent *Call);
 
   /// \brief Run checkers when pointers escape.
@@ -443,10 +444,11 @@
   typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
   
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
-                                const InvalidatedSymbols *symbols,
-                                ArrayRef<const MemRegion *> ExplicitRegions,
-                                ArrayRef<const MemRegion *> Regions,
-                                const CallEvent *Call)>
+                                     const InvalidatedSymbols *symbols,
+                                     ArrayRef<const MemRegion *> ExplicitRegions,
+                                     ArrayRef<const MemRegion *> Regions,
+                                     const LocationContext *LCtx,
+                                     const CallEvent *Call)>
       CheckRegionChangesFunc;
   
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 5b007f1..0d1a120 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -59,6 +59,29 @@
   void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
 };
 
+class PointerToMemberData: public llvm::FoldingSetNode {
+  const DeclaratorDecl *D;
+  llvm::ImmutableList<const CXXBaseSpecifier *> L;
+
+public:
+  PointerToMemberData(const DeclaratorDecl *D,
+                      llvm::ImmutableList<const CXXBaseSpecifier *> L)
+    : D(D), L(L) {}
+
+  typedef llvm::ImmutableList<const CXXBaseSpecifier *>::iterator iterator;
+  iterator begin() const { return L.begin(); }
+  iterator end() const { return L.end(); }
+
+  static void Profile(llvm::FoldingSetNodeID& ID, const DeclaratorDecl *D,
+                      llvm::ImmutableList<const CXXBaseSpecifier *> L);
+
+  void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, D, L); }
+  const DeclaratorDecl *getDeclaratorDecl() const {return D;}
+  llvm::ImmutableList<const CXXBaseSpecifier *> getCXXBaseList() const {
+    return L;
+  }
+};
+
 class BasicValueFactory {
   typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
           APSIntSetTy;
@@ -71,8 +94,10 @@
   void *        PersistentSValPairs;
 
   llvm::ImmutableList<SVal>::Factory SValListFactory;
+  llvm::ImmutableList<const CXXBaseSpecifier*>::Factory CXXBaseListFactory;
   llvm::FoldingSet<CompoundValData>  CompoundValDataSet;
   llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
+  llvm::FoldingSet<PointerToMemberData> PointerToMemberDataSet;
 
   // This is private because external clients should use the factory
   // method that takes a QualType.
@@ -81,7 +106,8 @@
 public:
   BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
     : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(nullptr),
-      PersistentSValPairs(nullptr), SValListFactory(Alloc) {}
+      PersistentSValPairs(nullptr), SValListFactory(Alloc),
+      CXXBaseListFactory(Alloc) {}
 
   ~BasicValueFactory();
 
@@ -172,14 +198,32 @@
   const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store,
                                             const TypedValueRegion *region);
 
+  const PointerToMemberData *getPointerToMemberData(
+      const DeclaratorDecl *DD,
+      llvm::ImmutableList<const CXXBaseSpecifier *> L);
+
   llvm::ImmutableList<SVal> getEmptySValList() {
     return SValListFactory.getEmptyList();
   }
 
-  llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) {
+  llvm::ImmutableList<SVal> prependSVal(SVal X, llvm::ImmutableList<SVal> L) {
     return SValListFactory.add(X, L);
   }
 
+  llvm::ImmutableList<const CXXBaseSpecifier *> getEmptyCXXBaseList() {
+    return CXXBaseListFactory.getEmptyList();
+  }
+
+  llvm::ImmutableList<const CXXBaseSpecifier *> prependCXXBase(
+      const CXXBaseSpecifier *CBS,
+      llvm::ImmutableList<const CXXBaseSpecifier *> L) {
+    return CXXBaseListFactory.add(CBS, L);
+  }
+
+  const clang::ento::PointerToMemberData *accumCXXBase(
+      llvm::iterator_range<CastExpr::path_const_iterator> PathRange,
+      const nonloc::PointerToMember &PTM);
+
   const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op,
                                      const llvm::APSInt& V1,
                                      const llvm::APSInt& V2);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 89610ef..aaecf38 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -55,6 +55,7 @@
 class CallDescription {
   friend CallEvent;
   mutable IdentifierInfo *II;
+  mutable bool IsLookupDone;
   StringRef FuncName;
   unsigned RequiredArgs;
 
@@ -68,7 +69,8 @@
   /// call. Omit this parameter to match every occurance of call with a given
   /// name regardless the number of arguments.
   CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement)
-      : II(nullptr), FuncName(FuncName), RequiredArgs(RequiredArgs) {}
+      : II(nullptr), IsLookupDone(false), FuncName(FuncName),
+        RequiredArgs(RequiredArgs) {}
 
   /// \brief Get the name of the function that this object matches.
   StringRef getFunctionName() const { return FuncName; }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index 6651382..fa12d77 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -139,6 +139,8 @@
     return nullptr;
   }
 
+  /// Scan all symbols referenced by the constraints. If the symbol is not
+  /// alive, remove it.
   virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
                                                  SymbolReaper& SymReaper) = 0;
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 9877a18..fa7769b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -293,6 +293,7 @@
                        const InvalidatedSymbols *invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) override;
 
   /// printState - Called by ProgramStateManager to print checker-specific data.
@@ -479,6 +480,22 @@
     return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
   }
 
+  ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex,
+                                      const LocationContext *LCtx, QualType T,
+                                      QualType ExTy, const CastExpr *CastE,
+                                      StmtNodeBuilder &Bldr,
+                                      ExplodedNode *Pred);
+
+  ProgramStateRef handleLVectorSplat(ProgramStateRef state,
+                                     const LocationContext *LCtx,
+                                     const CastExpr *CastE,
+                                     StmtNodeBuilder &Bldr,
+                                     ExplodedNode *Pred);
+
+  void handleUOExtension(ExplodedNodeSet::iterator I,
+                         const UnaryOperator* U,
+                         StmtNodeBuilder &Bldr);
+
 public:
 
   SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
@@ -506,7 +523,9 @@
 
   /// Call PointerEscape callback when a value escapes as a result of bind.
   ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
-                                              SVal Loc, SVal Val) override;
+                                              SVal Loc,
+                                              SVal Val,
+                                              const LocationContext *LCtx) override;
   /// Call PointerEscape callback when a value escapes as a result of
   /// region invalidation.
   /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 463b375..2910ef4 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -229,11 +229,12 @@
 
   ProgramStateRef bindLoc(Loc location,
                           SVal V,
+                          const LocationContext *LCtx,
                           bool notifyChanges = true) const;
 
-  ProgramStateRef bindLoc(SVal location, SVal V) const;
+  ProgramStateRef bindLoc(SVal location, SVal V, const LocationContext *LCtx) const;
 
-  ProgramStateRef bindDefault(SVal loc, SVal V) const;
+  ProgramStateRef bindDefault(SVal loc, SVal V, const LocationContext *LCtx) const;
 
   ProgramStateRef killBinding(Loc LV) const;
 
@@ -681,9 +682,9 @@
       this, Val.castAs<NonLoc>(), From, To);
 }
 
-inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
+inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V, const LocationContext *LCtx) const {
   if (Optional<Loc> L = LV.getAs<Loc>())
-    return bindLoc(*L, V);
+    return bindLoc(*L, V, LCtx);
   return this;
 }
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 9b55b3c..a4c01fc 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -204,6 +204,8 @@
                                    const LocationContext *LCtx,
                                    unsigned count);
 
+  DefinedSVal getMemberPointer(const DeclaratorDecl *DD);
+
   DefinedSVal getFunctionPointer(const FunctionDecl *func);
   
   DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy,
@@ -226,6 +228,14 @@
         BasicVals.getLazyCompoundValData(store, region));
   }
 
+  NonLoc makePointerToMember(const DeclaratorDecl *DD) {
+    return nonloc::PointerToMember(DD);
+  }
+
+  NonLoc makePointerToMember(const PointerToMemberData *PTMD) {
+    return nonloc::PointerToMember(PTMD);
+  }
+
   NonLoc makeZeroArrayIndex() {
     return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
   }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
index 2faec67..a0e3099 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
@@ -66,6 +66,7 @@
       NONLOC_SVAL(LazyCompoundVal, NonLoc)
       NONLOC_SVAL(LocAsInteger, NonLoc)
       NONLOC_SVAL(SymbolVal, NonLoc)
+      NONLOC_SVAL(PointerToMember, NonLoc)
 
 #undef NONLOC_SVAL
 #undef LOC_SVAL
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index dbc7c99..cc3c02a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -32,6 +32,7 @@
 
 class CompoundValData;
 class LazyCompoundValData;
+class PointerToMemberData;
 class ProgramState;
 class BasicValueFactory;
 class MemRegion;
@@ -459,6 +460,51 @@
   }
 };
 
+/// \brief Value representing pointer-to-member.
+///
+/// This value is qualified as NonLoc because neither loading nor storing
+/// operations are aplied to it. Instead, the analyzer uses the L-value coming
+/// from pointer-to-member applied to an object.
+/// This SVal is represented by a DeclaratorDecl which can be a member function
+/// pointer or a member data pointer and a list of CXXBaseSpecifiers. This list
+/// is required to accumulate the pointer-to-member cast history to figure out
+/// the correct subobject field.
+class PointerToMember : public NonLoc {
+  friend class ento::SValBuilder;
+
+public:
+  typedef llvm::PointerUnion<const DeclaratorDecl *,
+                             const PointerToMemberData *> PTMDataType;
+  const PTMDataType getPTMData() const {
+    return PTMDataType::getFromOpaqueValue(const_cast<void *>(Data));
+  }
+  bool isNullMemberPointer() const {
+    return getPTMData().isNull();
+  }
+  const DeclaratorDecl *getDecl() const;
+  template<typename AdjustedDecl>
+  const AdjustedDecl* getDeclAs() const {
+    return dyn_cast_or_null<AdjustedDecl>(getDecl());
+  }
+  typedef llvm::ImmutableList<const CXXBaseSpecifier *>::iterator iterator;
+  iterator begin() const;
+  iterator end() const;
+
+private:
+  explicit PointerToMember(const PTMDataType D)
+    : NonLoc(PointerToMemberKind, D.getOpaqueValue()) {}
+  friend class SVal;
+  PointerToMember() {}
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == NonLocKind &&
+           V.getSubKind() == PointerToMemberKind;
+  }
+
+  static bool isKind(const NonLoc& V) {
+    return V.getSubKind() == PointerToMemberKind;
+  }
+};
+
 } // end namespace ento::nonloc
 
 //==------------------------------------------------------------------------==//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
new file mode 100644
index 0000000..2c9802b
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
@@ -0,0 +1,92 @@
+//== SimpleConstraintManager.h ----------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Simplified constraint manager backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SIMPLECONSTRAINTMANAGER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SIMPLECONSTRAINTMANAGER_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+
+namespace clang {
+
+namespace ento {
+
+class SimpleConstraintManager : public ConstraintManager {
+  SubEngine *SU;
+  SValBuilder &SVB;
+
+public:
+  SimpleConstraintManager(SubEngine *subengine, SValBuilder &SB)
+      : SU(subengine), SVB(SB) {}
+
+  ~SimpleConstraintManager() override;
+
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from ConstraintManager.
+  //===------------------------------------------------------------------===//
+
+  /// Ensures that the DefinedSVal conditional is expressed as a NonLoc by
+  /// creating boolean casts to handle Loc's.
+  ProgramStateRef assume(ProgramStateRef State, DefinedSVal Cond,
+                         bool Assumption) override;
+
+  ProgramStateRef assumeInclusiveRange(ProgramStateRef State, NonLoc Value,
+                                       const llvm::APSInt &From,
+                                       const llvm::APSInt &To,
+                                       bool InRange) override;
+
+protected:
+  //===------------------------------------------------------------------===//
+  // Interface that subclasses must implement.
+  //===------------------------------------------------------------------===//
+
+  /// Given a symbolic expression that can be reasoned about, assume that it is
+  /// true/false and generate the new program state.
+  virtual ProgramStateRef assumeSym(ProgramStateRef State, SymbolRef Sym,
+                                    bool Assumption) = 0;
+
+  /// Given a symbolic expression within the range [From, To], assume that it is
+  /// true/false and generate the new program state.
+  /// This function is used to handle case ranges produced by a language
+  /// extension for switch case statements.
+  virtual ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State,
+                                                  SymbolRef Sym,
+                                                  const llvm::APSInt &From,
+                                                  const llvm::APSInt &To,
+                                                  bool InRange) = 0;
+
+  /// Given a symbolic expression that cannot be reasoned about, assume that
+  /// it is zero/nonzero and add it directly to the solver state.
+  virtual ProgramStateRef assumeSymUnsupported(ProgramStateRef State,
+                                               SymbolRef Sym,
+                                               bool Assumption) = 0;
+
+  //===------------------------------------------------------------------===//
+  // Internal implementation.
+  //===------------------------------------------------------------------===//
+
+  BasicValueFactory &getBasicVals() const { return SVB.getBasicValueFactory(); }
+  SymbolManager &getSymbolManager() const { return SVB.getSymbolManager(); }
+
+private:
+  ProgramStateRef assume(ProgramStateRef State, NonLoc Cond, bool Assumption);
+
+  ProgramStateRef assumeAux(ProgramStateRef State, NonLoc Cond,
+                            bool Assumption);
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index fa7d3f7..7fa7515 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -59,6 +59,30 @@
   /// \return The value bound to the location \c loc.
   virtual SVal getBinding(Store store, Loc loc, QualType T = QualType()) = 0;
 
+  /// Return the default value bound to a region in a given store. The default
+  /// binding is the value of sub-regions that were not initialized separately
+  /// from their base region. For example, if the structure is zero-initialized
+  /// upon construction, this method retrieves the concrete zero value, even if
+  /// some or all fields were later overwritten manually. Default binding may be
+  /// an unknown, undefined, concrete, or symbolic value.
+  /// \param[in] store The store in which to make the lookup.
+  /// \param[in] R The region to find the default binding for.
+  /// \return The default value bound to the region in the store, if a default
+  /// binding exists.
+  virtual Optional<SVal> getDefaultBinding(Store store, const MemRegion *R) = 0;
+
+  /// Return the default value bound to a LazyCompoundVal. The default binding
+  /// is used to represent the value of any fields or elements within the
+  /// structure represented by the LazyCompoundVal which were not initialized
+  /// explicitly separately from the whole structure. Default binding may be an
+  /// unknown, undefined, concrete, or symbolic value.
+  /// \param[in] lcv The lazy compound value.
+  /// \return The default value bound to the LazyCompoundVal \c lcv, if a
+  /// default binding exists.
+  Optional<SVal> getDefaultBinding(nonloc::LazyCompoundVal lcv) {
+    return getDefaultBinding(lcv.getStore(), lcv.getRegion());
+  }
+
   /// Return a state with the specified value bound to the given location.
   /// \param[in] store The analysis state.
   /// \param[in] loc The symbolic memory location.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index 581ef20..e16df13 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -131,17 +131,19 @@
                        const InvalidatedSymbols *invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) = 0;
 
 
   inline ProgramStateRef 
   processRegionChange(ProgramStateRef state,
-                      const MemRegion* MR) {
-    return processRegionChanges(state, nullptr, MR, MR, nullptr);
+                      const MemRegion* MR,
+                      const LocationContext *LCtx) {
+    return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr);
   }
 
   virtual ProgramStateRef
-  processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0;
+  processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val, const LocationContext *LCtx) = 0;
 
   virtual ProgramStateRef
   notifyCheckersOfPointerEscape(ProgramStateRef State,
diff --git a/include/clang/Tooling/Core/Diagnostic.h b/include/clang/Tooling/Core/Diagnostic.h
new file mode 100644
index 0000000..d657f16
--- /dev/null
+++ b/include/clang/Tooling/Core/Diagnostic.h
@@ -0,0 +1,100 @@
+//===--- Diagnostic.h - Framework for clang diagnostics tools --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+//  Structures supporting diagnostics and refactorings that span multiple
+//  translation units. Indicate diagnostics reports and replacements
+//  suggestions for the analyzed sources.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_CORE_DIAGNOSTIC_H
+#define LLVM_CLANG_TOOLING_CORE_DIAGNOSTIC_H
+
+#include "Replacement.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace clang {
+namespace tooling {
+
+/// \brief Represents the diagnostic message with the error message associated
+/// and the information on the location of the problem.
+struct DiagnosticMessage {
+  DiagnosticMessage(llvm::StringRef Message = "");
+
+  /// \brief Constructs a diagnostic message with anoffset to the diagnostic
+  /// within the file where the problem occured.
+  ///
+  /// \param Loc Should be a file location, it is not meaningful for a macro
+  /// location.
+  ///
+  DiagnosticMessage(llvm::StringRef Message, const SourceManager &Sources,
+                    SourceLocation Loc);
+  std::string Message;
+  std::string FilePath;
+  unsigned FileOffset;
+};
+
+/// \brief Represents the diagnostic with the level of severity and possible
+/// fixes to be applied.
+struct Diagnostic {
+  enum Level {
+    Warning = DiagnosticsEngine::Warning,
+    Error = DiagnosticsEngine::Error
+  };
+
+  Diagnostic() = default;
+
+  Diagnostic(llvm::StringRef DiagnosticName, Level DiagLevel,
+             StringRef BuildDirectory);
+
+  Diagnostic(llvm::StringRef DiagnosticName, DiagnosticMessage &Message,
+             llvm::StringMap<Replacements> &Fix,
+             SmallVector<DiagnosticMessage, 1> &Notes, Level DiagLevel,
+             llvm::StringRef BuildDirectory);
+
+  /// \brief Name identifying the Diagnostic.
+  std::string DiagnosticName;
+
+  /// \brief Message associated to the diagnostic.
+  DiagnosticMessage Message;
+
+  /// \brief Fixes to apply, grouped by file path.
+  llvm::StringMap<Replacements> Fix;
+
+  /// \brief Potential notes about the diagnostic.
+  SmallVector<DiagnosticMessage, 1> Notes;
+
+  /// \brief Diagnostic level. Can indicate either an error or a warning.
+  Level DiagLevel;
+
+  /// \brief A build directory of the diagnostic source file.
+  ///
+  /// It's an absolute path which is `directory` field of the source file in
+  /// compilation database. If users don't specify the compilation database
+  /// directory, it is the current directory where clang-tidy runs.
+  ///
+  /// Note: it is empty in unittest.
+  std::string BuildDirectory;
+};
+
+/// \brief Collection of Diagnostics generated from a single translation unit.
+struct TranslationUnitDiagnostics {
+  /// Name of the main source for the translation unit.
+  std::string MainSourceFile;
+  std::vector<Diagnostic> Diagnostics;
+};
+
+} // end namespace tooling
+} // end namespace clang
+#endif // LLVM_CLANG_TOOLING_CORE_DIAGNOSTIC_H
diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h
index 95dc3cd..8d4a22a 100644
--- a/include/clang/Tooling/Core/Replacement.h
+++ b/include/clang/Tooling/Core/Replacement.h
@@ -329,12 +329,6 @@
 struct TranslationUnitReplacements {
   /// Name of the main source for the translation unit.
   std::string MainSourceFile;
-
-  /// A freeform chunk of text to describe the context of the replacements.
-  /// Will be printed, for example, when detecting conflicts during replacement
-  /// deduplication.
-  std::string Context;
-
   std::vector<Replacement> Replacements;
 };
 
diff --git a/include/clang/Tooling/DiagnosticsYaml.h b/include/clang/Tooling/DiagnosticsYaml.h
new file mode 100644
index 0000000..f32b9fa
--- /dev/null
+++ b/include/clang/Tooling/DiagnosticsYaml.h
@@ -0,0 +1,101 @@
+//===-- DiagnosticsYaml.h -- Serialiazation for Diagnosticss ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file defines the structure of a YAML document for serializing
+/// diagnostics.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_DIAGNOSTICSYAML_H
+#define LLVM_CLANG_TOOLING_DIAGNOSTICSYAML_H
+
+#include "clang/Tooling/Core/Diagnostic.h"
+#include "clang/Tooling/ReplacementsYaml.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <string>
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Diagnostic)
+
+namespace llvm {
+namespace yaml {
+
+template <> struct MappingTraits<clang::tooling::Diagnostic> {
+  /// \brief Helper to (de)serialize a Diagnostic since we don't have direct
+  /// access to its data members.
+  class NormalizedDiagnostic {
+  public:
+    NormalizedDiagnostic(const IO &)
+        : DiagLevel(clang::tooling::Diagnostic::Level::Warning) {}
+
+    NormalizedDiagnostic(const IO &, const clang::tooling::Diagnostic &D)
+        : DiagnosticName(D.DiagnosticName), Message(D.Message), Fix(D.Fix),
+          Notes(D.Notes), DiagLevel(D.DiagLevel),
+          BuildDirectory(D.BuildDirectory) {}
+
+    clang::tooling::Diagnostic denormalize(const IO &) {
+      return clang::tooling::Diagnostic(DiagnosticName, Message, Fix, Notes,
+                                        DiagLevel, BuildDirectory);
+    }
+
+    std::string DiagnosticName;
+    clang::tooling::DiagnosticMessage Message;
+    llvm::StringMap<clang::tooling::Replacements> Fix;
+    SmallVector<clang::tooling::DiagnosticMessage, 1> Notes;
+    clang::tooling::Diagnostic::Level DiagLevel;
+    std::string BuildDirectory;
+  };
+
+  static void mapping(IO &Io, clang::tooling::Diagnostic &D) {
+    MappingNormalization<NormalizedDiagnostic, clang::tooling::Diagnostic> Keys(
+        Io, D);
+    Io.mapRequired("DiagnosticName", Keys->DiagnosticName);
+
+    // FIXME: Export properly all the different fields.
+
+    std::vector<clang::tooling::Replacement> Fixes;
+    for (auto &Replacements : Keys->Fix) {
+      for (auto &Replacement : Replacements.second) {
+        Fixes.push_back(Replacement);
+      }
+    }
+    Io.mapRequired("Replacements", Fixes);
+    for (auto &Fix : Fixes) {
+      llvm::Error Err = Keys->Fix[Fix.getFilePath()].add(Fix);
+      if (Err) {
+        // FIXME: Implement better conflict handling.
+        llvm::errs() << "Fix conflicts with existing fix: "
+                     << llvm::toString(std::move(Err)) << "\n";
+      }
+    }
+  }
+};
+
+/// \brief Specialized MappingTraits to describe how a
+/// TranslationUnitDiagnostics is (de)serialized.
+template <> struct MappingTraits<clang::tooling::TranslationUnitDiagnostics> {
+  static void mapping(IO &Io, clang::tooling::TranslationUnitDiagnostics &Doc) {
+    Io.mapRequired("MainSourceFile", Doc.MainSourceFile);
+
+    std::vector<clang::tooling::Diagnostic> Diagnostics;
+    for (auto &Diagnostic : Doc.Diagnostics) {
+      // FIXME: Export all diagnostics, not just the ones with fixes.
+      // Update MappingTraits<clang::tooling::Diagnostic>::mapping.
+      if (Diagnostic.Fix.size() > 0) {
+        Diagnostics.push_back(Diagnostic);
+      }
+    }
+    Io.mapRequired("Diagnostics", Diagnostics);
+    Doc.Diagnostics = Diagnostics;
+  }
+};
+} // end namespace yaml
+} // end namespace llvm
+
+#endif // LLVM_CLANG_TOOLING_DIAGNOSTICSYAML_H
diff --git a/include/clang/Tooling/Refactoring/AtomicChange.h b/include/clang/Tooling/Refactoring/AtomicChange.h
new file mode 100644
index 0000000..f437c4b
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/AtomicChange.h
@@ -0,0 +1,129 @@
+//===--- AtomicChange.h - AtomicChange class --------------------*- 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 AtomicChange which is used to create a set of source
+//  changes, e.g. replacements and header insertions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H
+#define LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H
+
+#include "clang/Basic/SourceManager.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace tooling {
+
+/// \brief An atomic change is used to create and group a set of source edits,
+/// e.g. replacements or header insertions. Edits in an AtomicChange should be
+/// related, e.g. replacements for the same type reference and the corresponding
+/// header insertion/deletion.
+///
+/// An AtomicChange is uniquely identified by a key and will either be fully
+/// applied or not applied at all.
+///
+/// Calling setError on an AtomicChange stores the error message and marks it as
+/// bad, i.e. none of its source edits will be applied.
+class AtomicChange {
+public:
+  /// \brief Creates an atomic change around \p KeyPosition with the key being a
+  /// concatenation of the file name and the offset of \p KeyPosition.
+  /// \p KeyPosition should be the location of the key syntactical element that
+  /// is being changed, e.g. the call to a refactored method.
+  AtomicChange(const SourceManager &SM, SourceLocation KeyPosition);
+
+  /// \brief Creates an atomic change for \p FilePath with a customized key.
+  AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key)
+      : Key(Key), FilePath(FilePath) {}
+
+  /// \brief Returns the atomic change as a YAML string.
+  std::string toYAMLString();
+
+  /// \brief Converts a YAML-encoded automic change to AtomicChange.
+  static AtomicChange convertFromYAML(llvm::StringRef YAMLContent);
+
+  /// \brief Returns the key of this change, which is a concatenation of the
+  /// file name and offset of the key position.
+  const std::string &getKey() const { return Key; }
+
+  /// \brief Returns the path of the file containing this atomic change.
+  const std::string &getFilePath() const { return FilePath; }
+
+  /// \brief If this change could not be created successfully, e.g. because of
+  /// conflicts among replacements, use this to set an error description.
+  /// Thereby, places that cannot be fixed automatically can be gathered when
+  /// applying changes.
+  void setError(llvm::StringRef Error) { this->Error = Error; }
+
+  /// \brief Returns whether an error has been set on this list.
+  bool hasError() const { return !Error.empty(); }
+
+  /// \brief Returns the error message or an empty string if it does not exist.
+  const std::string &getError() const { return Error; }
+
+  /// \brief Adds a replacement that replaces range [Loc, Loc+Length) with
+  /// \p Text.
+  /// \returns An llvm::Error carrying ReplacementError on error.
+  llvm::Error replace(const SourceManager &SM, SourceLocation Loc,
+                      unsigned Length, llvm::StringRef Text);
+
+  /// \brief Adds a replacement that inserts \p Text at \p Loc. If this
+  /// insertion conflicts with an existing insertion (at the same position),
+  /// this will be inserted before/after the existing insertion depending on
+  /// \p InsertAfter. Users should use `replace` with `Length=0` instead if they
+  /// do not want conflict resolving by default. If the conflicting replacement
+  /// is not an insertion, an error is returned.
+  ///
+  /// \returns An llvm::Error carrying ReplacementError on error.
+  llvm::Error insert(const SourceManager &SM, SourceLocation Loc,
+                     llvm::StringRef Text, bool InsertAfter = true);
+
+  /// \brief Adds a header into the file that contains the key position.
+  /// Header can be in angle brackets or double quotation marks. By default
+  /// (header is not quoted), header will be surrounded with double quotes.
+  void addHeader(llvm::StringRef Header);
+
+  /// \brief Removes a header from the file that contains the key position.
+  void removeHeader(llvm::StringRef Header);
+
+  /// \brief Returns a const reference to existing replacements.
+  const Replacements &getReplacements() const { return Replaces; }
+
+  llvm::ArrayRef<std::string> getInsertedHeaders() const {
+    return InsertedHeaders;
+  }
+
+  llvm::ArrayRef<std::string> getRemovedHeaders() const {
+    return RemovedHeaders;
+  }
+
+private:
+  AtomicChange() {}
+
+  AtomicChange(std::string Key, std::string FilePath, std::string Error,
+               std::vector<std::string> InsertedHeaders,
+               std::vector<std::string> RemovedHeaders,
+               clang::tooling::Replacements Replaces);
+
+  // This uniquely identifies an AtomicChange.
+  std::string Key;
+  std::string FilePath;
+  std::string Error;
+  std::vector<std::string> InsertedHeaders;
+  std::vector<std::string> RemovedHeaders;
+  tooling::Replacements Replaces;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H
diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h
index 47b7f3f..0b1dc4c 100644
--- a/include/clang/Tooling/ReplacementsYaml.h
+++ b/include/clang/Tooling/ReplacementsYaml.h
@@ -65,7 +65,6 @@
   static void mapping(IO &Io,
                       clang::tooling::TranslationUnitReplacements &Doc) {
     Io.mapRequired("MainSourceFile", Doc.MainSourceFile);
-    Io.mapOptional("Context", Doc.Context, std::string());
     Io.mapRequired("Replacements", Doc.Replacements);
   }
 };
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index ca232f4..10e26ac 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -69,7 +69,8 @@
 
   /// \brief Perform an action for an invocation.
   virtual bool
-  runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
+  runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
+                FileManager *Files,
                 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
                 DiagnosticConsumer *DiagConsumer) = 0;
 };
@@ -85,7 +86,8 @@
   ~FrontendActionFactory() override;
 
   /// \brief Invokes the compiler with a FrontendAction created by create().
-  bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
+  bool runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
+                     FileManager *Files,
                      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
                      DiagnosticConsumer *DiagConsumer) override;
 
@@ -261,7 +263,7 @@
 
   bool runInvocation(const char *BinaryName,
                      clang::driver::Compilation *Compilation,
-                     clang::CompilerInvocation *Invocation,
+                     std::shared_ptr<clang::CompilerInvocation> Invocation,
                      std::shared_ptr<PCHContainerOperations> PCHContainerOps);
 
   std::vector<std::string> CommandLine;
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index 680aa3e..cf7cdde 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -271,7 +271,7 @@
   Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
 
   std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction(
-      CInvok.release(), PCHContainerOps, Diags));
+      std::move(CInvok), PCHContainerOps, Diags));
   if (!Unit) {
     errRec.FinishCapture();
     return true;
@@ -547,7 +547,7 @@
   ASTAction.reset(new ARCMTMacroTrackerAction(ARCMTMacroLocs));
 
   std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction(
-      CInvok.release(), PCHContainerOps, Diags, ASTAction.get()));
+      std::move(CInvok), PCHContainerOps, Diags, ASTAction.get()));
   if (!Unit) {
     errRec.FinishCapture();
     return true;
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index 5e1938c..488ad33 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -27,6 +27,7 @@
     CharUnits Offset;
     unsigned PathLength;
     unsigned CallIndex;
+    bool IsNullPtr;
   };
 }
 
@@ -149,10 +150,11 @@
     MakeLValue();
     if (RHS.hasLValuePath())
       setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
-                RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex());
+                RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex(),
+                RHS.isNullPointer());
     else
       setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
-                RHS.getLValueCallIndex());
+                RHS.getLValueCallIndex(), RHS.isNullPointer());
     break;
   case Array:
     MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
@@ -261,7 +263,7 @@
 static double GetApproxValue(const llvm::APFloat &F) {
   llvm::APFloat V = F;
   bool ignored;
-  V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
+  V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
             &ignored);
   return V.convertToDouble();
 }
@@ -579,8 +581,13 @@
   return ((const LV*)(const char*)Data.buffer)->CallIndex;
 }
 
+bool APValue::isNullPointer() const {
+  assert(isLValue() && "Invalid usage");
+  return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
+}
+
 void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
-                        unsigned CallIndex) {
+                        unsigned CallIndex, bool IsNullPtr) {
   assert(isLValue() && "Invalid accessor");
   LV &LVal = *((LV*)(char*)Data.buffer);
   LVal.BaseAndIsOnePastTheEnd.setPointer(B);
@@ -588,11 +595,12 @@
   LVal.Offset = O;
   LVal.CallIndex = CallIndex;
   LVal.resizePath((unsigned)-1);
+  LVal.IsNullPtr = IsNullPtr;
 }
 
 void APValue::setLValue(LValueBase B, const CharUnits &O,
                         ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
-                        unsigned CallIndex) {
+                        unsigned CallIndex, bool IsNullPtr) {
   assert(isLValue() && "Invalid accessor");
   LV &LVal = *((LV*)(char*)Data.buffer);
   LVal.BaseAndIsOnePastTheEnd.setPointer(B);
@@ -601,6 +609,7 @@
   LVal.CallIndex = CallIndex;
   LVal.resizePath(Path.size());
   memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
+  LVal.IsNullPtr = IsNullPtr;
 }
 
 const ValueDecl *APValue::getMemberPointerDecl() const {
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 22be71a..e8f9892 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -704,8 +704,8 @@
     // language-specific address space.
     static const unsigned FakeAddrSpaceMap[] = {
       1, // opencl_global
-      2, // opencl_local
-      3, // opencl_constant
+      3, // opencl_local
+      2, // opencl_constant
       4, // opencl_generic
       5, // cuda_device
       6, // cuda_constant
@@ -1167,7 +1167,6 @@
     InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);
     InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent);
     InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
-    InitBuiltinType(OCLNDRangeTy, BuiltinType::OCLNDRange);
     InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);
   }
   
@@ -1270,9 +1269,8 @@
 }
 
 NamedDecl *
-ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) {
-  llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
-    = InstantiatedFromUsingDecl.find(UUD);
+ASTContext::getInstantiatedFromUsingDecl(NamedDecl *UUD) {
+  auto Pos = InstantiatedFromUsingDecl.find(UUD);
   if (Pos == InstantiatedFromUsingDecl.end())
     return nullptr;
 
@@ -1280,11 +1278,15 @@
 }
 
 void
-ASTContext::setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern) {
+ASTContext::setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern) {
   assert((isa<UsingDecl>(Pattern) ||
           isa<UnresolvedUsingValueDecl>(Pattern) ||
           isa<UnresolvedUsingTypenameDecl>(Pattern)) && 
          "pattern decl is not a using decl");
+  assert((isa<UsingDecl>(Inst) ||
+          isa<UnresolvedUsingValueDecl>(Inst) ||
+          isa<UnresolvedUsingTypenameDecl>(Inst)) && 
+         "instantiation did not produce a using decl");
   assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists");
   InstantiatedFromUsingDecl[Inst] = Pattern;
 }
@@ -1455,7 +1457,9 @@
         T = getPointerType(RT->getPointeeType());
     }
     QualType BaseT = getBaseElementType(T);
-    if (!BaseT->isIncompleteType() && !T->isFunctionType()) {
+    if (T->isFunctionType())
+      Align = getTypeInfoImpl(T.getTypePtr()).Align;
+    else if (!BaseT->isIncompleteType()) {
       // Adjust alignments of declarations with array type by the
       // large-array alignment on the target.
       if (const ArrayType *arrayType = getAsArrayType(T)) {
@@ -1469,6 +1473,8 @@
         }
       }
       Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
+      if (BaseT.getQualifiers().hasUnaligned())
+        Align = Target->getCharWidth();
       if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
         if (VD->hasGlobalStorage() && !ForAlignof)
           Align = std::max(Align, getTargetInfo().getMinGlobalAlign());
@@ -1770,7 +1776,6 @@
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
-    case BuiltinType::OCLNDRange:
     case BuiltinType::OCLReserveID:
       // Currently these types are pointers to opaque types.
       Width = Target->getPointerWidth(0);
@@ -1872,8 +1877,9 @@
     return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->
                        getReplacementType().getTypePtr());
 
-  case Type::Auto: {
-    const AutoType *A = cast<AutoType>(T);
+  case Type::Auto:
+  case Type::DeducedTemplateSpecialization: {
+    const DeducedType *A = cast<DeducedType>(T);
     assert(!A->getDeducedType().isNull() &&
            "cannot request the size of an undeduced or dependent auto type");
     return getTypeInfo(A->getDeducedType().getTypePtr());
@@ -2382,6 +2388,14 @@
       Proto->getExtProtoInfo().withExceptionSpec(ESI));
 }
 
+bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T,
+                                                          QualType U) {
+  return hasSameType(T, U) ||
+         (getLangOpts().CPlusPlus1z &&
+          hasSameType(getFunctionTypeWithExceptionSpec(*this, T, EST_None),
+                      getFunctionTypeWithExceptionSpec(*this, U, EST_None)));
+}
+
 void ASTContext::adjustExceptionSpec(
     FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI,
     bool AsWritten) {
@@ -2752,6 +2766,7 @@
   case Type::TemplateTypeParm:
   case Type::SubstTemplateTypeParmPack:
   case Type::Auto:
+  case Type::DeducedTemplateSpecialization:
   case Type::PackExpansion:
     llvm_unreachable("type should never be variably-modified");
 
@@ -3772,12 +3787,8 @@
                                           QualType Canon) const {
   if (Canon.isNull()) {
     NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
-    ElaboratedTypeKeyword CanonKeyword = Keyword;
-    if (Keyword == ETK_None)
-      CanonKeyword = ETK_Typename;
-    
-    if (CanonNNS != NNS || CanonKeyword != Keyword)
-      Canon = getDependentNameType(CanonKeyword, CanonNNS, Name);
+    if (CanonNNS != NNS)
+      Canon = getDependentNameType(Keyword, CanonNNS, Name);
   }
 
   llvm::FoldingSetNodeID ID;
@@ -3861,6 +3872,47 @@
   return QualType(T, 0);
 }
 
+TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
+  TemplateArgument Arg;
+  if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
+    QualType ArgType = getTypeDeclType(TTP);
+    if (TTP->isParameterPack())
+      ArgType = getPackExpansionType(ArgType, None);
+
+    Arg = TemplateArgument(ArgType);
+  } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+    Expr *E = new (*this) DeclRefExpr(
+        NTTP, /*enclosing*/false,
+        NTTP->getType().getNonLValueExprType(*this),
+        Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation());
+
+    if (NTTP->isParameterPack())
+      E = new (*this) PackExpansionExpr(DependentTy, E, NTTP->getLocation(),
+                                        None);
+    Arg = TemplateArgument(E);
+  } else {
+    auto *TTP = cast<TemplateTemplateParmDecl>(Param);
+    if (TTP->isParameterPack())
+      Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
+    else
+      Arg = TemplateArgument(TemplateName(TTP));
+  }
+
+  if (Param->isTemplateParameterPack())
+    Arg = TemplateArgument::CreatePackCopy(*this, Arg);
+
+  return Arg;
+}
+
+void
+ASTContext::getInjectedTemplateArgs(const TemplateParameterList *Params,
+                                    SmallVectorImpl<TemplateArgument> &Args) {
+  Args.reserve(Args.size() + Params->size());
+
+  for (NamedDecl *Param : *Params)
+    Args.push_back(getInjectedTemplateArg(Param));
+}
+
 QualType ASTContext::getPackExpansionType(QualType Pattern,
                                           Optional<unsigned> NumExpansions) {
   llvm::FoldingSetNodeID ID;
@@ -4388,6 +4440,28 @@
   return QualType(AT, 0);
 }
 
+/// Return the uniqued reference to the deduced template specialization type
+/// which has been deduced to the given type, or to the canonical undeduced
+/// such type, or the canonical deduced-but-dependent such type.
+QualType ASTContext::getDeducedTemplateSpecializationType(
+    TemplateName Template, QualType DeducedType, bool IsDependent) const {
+  // Look in the folding set for an existing type.
+  void *InsertPos = nullptr;
+  llvm::FoldingSetNodeID ID;
+  DeducedTemplateSpecializationType::Profile(ID, Template, DeducedType,
+                                             IsDependent);
+  if (DeducedTemplateSpecializationType *DTST =
+          DeducedTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(DTST, 0);
+
+  DeducedTemplateSpecializationType *DTST = new (*this, TypeAlignment)
+      DeducedTemplateSpecializationType(Template, DeducedType, IsDependent);
+  Types.push_back(DTST);
+  if (InsertPos)
+    DeducedTemplateSpecializationTypes.InsertNode(DTST, InsertPos);
+  return QualType(DTST, 0);
+}
+
 /// getAtomicType - Return the uniqued reference to the atomic type for
 /// the given value type.
 QualType ASTContext::getAtomicType(QualType T) const {
@@ -5871,7 +5945,6 @@
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
-    case BuiltinType::OCLNDRange:
     case BuiltinType::OCLReserveID:
     case BuiltinType::OCLSampler:
     case BuiltinType::Dependent:
@@ -6286,6 +6359,7 @@
   // We could see an undeduced auto type here during error recovery.
   // Just ignore it.
   case Type::Auto:
+  case Type::DeducedTemplateSpecialization:
     return;
 
   case Type::Pipe:
@@ -7992,20 +8066,12 @@
   Qualifiers LQuals = LHSCan.getLocalQualifiers();
   Qualifiers RQuals = RHSCan.getLocalQualifiers();
   if (LQuals != RQuals) {
-    if (getLangOpts().OpenCL) {
-      if (LHSCan.getUnqualifiedType() != RHSCan.getUnqualifiedType() ||
-          LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers())
-        return QualType();
-      if (LQuals.isAddressSpaceSupersetOf(RQuals))
-        return LHS;
-      if (RQuals.isAddressSpaceSupersetOf(LQuals))
-        return RHS;
-    }
     // If any of these qualifiers are different, we have a type
     // mismatch.
     if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() ||
         LQuals.getAddressSpace() != RQuals.getAddressSpace() ||
-        LQuals.getObjCLifetime() != RQuals.getObjCLifetime())
+        LQuals.getObjCLifetime() != RQuals.getObjCLifetime() ||
+        LQuals.hasUnaligned() != RQuals.hasUnaligned())
       return QualType();
 
     // Exactly one GC qualifier difference is allowed: __strong is
@@ -8085,6 +8151,7 @@
     llvm_unreachable("Non-canonical and dependent types shouldn't get here");
 
   case Type::Auto:
+  case Type::DeducedTemplateSpecialization:
   case Type::LValueReference:
   case Type::RValueReference:
   case Type::MemberPointer:
@@ -8124,6 +8191,20 @@
       LHSPointee = LHSPointee.getUnqualifiedType();
       RHSPointee = RHSPointee.getUnqualifiedType();
     }
+    if (getLangOpts().OpenCL) {
+      Qualifiers LHSPteeQual = LHSPointee.getQualifiers();
+      Qualifiers RHSPteeQual = RHSPointee.getQualifiers();
+      // Blocks can't be an expression in a ternary operator (OpenCL v2.0
+      // 6.12.5) thus the following check is asymmetric.
+      if (!LHSPteeQual.isAddressSpaceSupersetOf(RHSPteeQual))
+        return QualType();
+      LHSPteeQual.removeAddressSpace();
+      RHSPteeQual.removeAddressSpace();
+      LHSPointee =
+          QualType(LHSPointee.getTypePtr(), LHSPteeQual.getAsOpaqueValue());
+      RHSPointee =
+          QualType(RHSPointee.getTypePtr(), RHSPteeQual.getAsOpaqueValue());
+    }
     QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer,
                                      Unqualified);
     if (ResultType.isNull()) return QualType();
@@ -8718,8 +8799,8 @@
 
   bool Variadic = (TypeStr[0] == '.');
 
-  // We really shouldn't be making a no-proto type here, especially in C++.
-  if (ArgTypes.empty() && Variadic)
+  // We really shouldn't be making a no-proto type here.
+  if (ArgTypes.empty() && Variadic && !getLangOpts().CPlusPlus)
     return getFunctionNoProtoType(ResType, EI);
 
   FunctionProtoType::ExtProtoInfo EPI;
@@ -8737,7 +8818,7 @@
   if (!FD->isExternallyVisible())
     return GVA_Internal;
 
-  GVALinkage External = GVA_StrongExternal;
+  GVALinkage External;
   switch (FD->getTemplateSpecializationKind()) {
   case TSK_Undeclared:
   case TSK_ExplicitSpecialization:
@@ -8809,8 +8890,22 @@
 }
 
 GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
-  return adjustGVALinkageForAttributes(
+  auto L = adjustGVALinkageForAttributes(
       *this, basicGVALinkageForFunction(*this, FD), FD);
+  auto EK = ExternalASTSource::EK_ReplyHazy;
+  if (auto *Ext = getExternalSource())
+    EK = Ext->hasExternalDefinitions(FD->getOwningModuleID());
+  switch (EK) {
+  case ExternalASTSource::EK_Never:
+    if (L == GVA_DiscardableODR)
+      return GVA_StrongODR;
+    break;
+  case ExternalASTSource::EK_Always:
+    return GVA_AvailableExternally;
+  case ExternalASTSource::EK_ReplyHazy:
+    break;
+  }
+  return L;
 }
 
 static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
@@ -8819,22 +8914,30 @@
     return GVA_Internal;
 
   if (VD->isStaticLocal()) {
-    GVALinkage StaticLocalLinkage = GVA_DiscardableODR;
     const DeclContext *LexicalContext = VD->getParentFunctionOrMethod();
     while (LexicalContext && !isa<FunctionDecl>(LexicalContext))
       LexicalContext = LexicalContext->getLexicalParent();
 
-    // Let the static local variable inherit its linkage from the nearest
-    // enclosing function.
-    if (LexicalContext)
-      StaticLocalLinkage =
-          Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
+    // ObjC Blocks can create local variables that don't have a FunctionDecl
+    // LexicalContext.
+    if (!LexicalContext)
+      return GVA_DiscardableODR;
 
-    // GVA_StrongODR function linkage is stronger than what we need,
-    // downgrade to GVA_DiscardableODR.
-    // This allows us to discard the variable if we never end up needing it.
-    return StaticLocalLinkage == GVA_StrongODR ? GVA_DiscardableODR
-                                               : StaticLocalLinkage;
+    // Otherwise, let the static local variable inherit its linkage from the
+    // nearest enclosing function.
+    auto StaticLocalLinkage =
+        Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
+
+    // Itanium ABI 5.2.2: "Each COMDAT group [for a static local variable] must
+    // be emitted in any object with references to the symbol for the object it
+    // contains, whether inline or out-of-line."
+    // Similar behavior is observed with MSVC. An alternative ABI could use
+    // StrongODR/AvailableExternally to match the function, but none are
+    // known/supported currently.
+    if (StaticLocalLinkage == GVA_StrongODR ||
+        StaticLocalLinkage == GVA_AvailableExternally)
+      return GVA_DiscardableODR;
+    return StaticLocalLinkage;
   }
 
   // MSVC treats in-class initialized static data members as definitions.
@@ -8887,7 +8990,7 @@
       *this, basicGVALinkageForVariable(*this, VD), VD);
 }
 
-bool ASTContext::DeclMustBeEmitted(const Decl *D) {
+bool ASTContext::DeclMustBeEmitted(const Decl *D, bool ForModularCodegen) {
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
     if (!VD->isFileVarDecl())
       return false;
@@ -8951,10 +9054,15 @@
       }
     }
 
+    GVALinkage Linkage = GetGVALinkageForFunction(FD);
+
+    if (Linkage == GVA_DiscardableODR && ForModularCodegen)
+      return true;
+
     // static, static inline, always_inline, and extern inline functions can
     // always be deferred.  Normal inline functions can be deferred in C99/C++.
     // Implicit template instantiations can also be deferred in C++.
-    return !isDiscardableGVALinkage(GetGVALinkageForFunction(FD));
+    return !isDiscardableGVALinkage(Linkage);
   }
   
   const VarDecl *VD = cast<VarDecl>(D);
@@ -8974,7 +9082,8 @@
 
   // Variables that have initialization with side-effects are required.
   if (VD->getInit() && VD->getInit()->HasSideEffects(*this) &&
-      !VD->evaluateValue())
+      // We can get a value-dependent initializer during error recovery.
+      (VD->getInit()->isValueDependent() || !VD->evaluateValue()))
     return true;
 
   // Likewise, variables with tuple-like bindings are required if their
@@ -9426,6 +9535,16 @@
   
 }
 
+uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const {
+  unsigned AS;
+  if (QT->getUnqualifiedDesugaredType()->isNullPtrType())
+    AS = 0;
+  else
+    AS = QT->getPointeeType().getAddressSpace();
+
+  return getTargetInfo().getNullPointerValue(AS);
+}
+
 // Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
 // doesn't include ASTContext.h
 template
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index a3bdd61..ef491ab 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -102,22 +102,26 @@
     /// Pending[i] is an action to dump an entity at level i.
     llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending;
 
+    /// Indicates whether we should trigger deserialization of nodes that had
+    /// not already been loaded.
+    bool Deserialize = false;
+
     /// Indicates whether we're at the top level.
-    bool TopLevel;
+    bool TopLevel = true;
 
     /// Indicates if we're handling the first child after entering a new depth.
-    bool FirstChild;
+    bool FirstChild = true;
 
     /// Prefix for currently-being-dumped entity.
     std::string Prefix;
 
     /// Keep track of the last location we print out so that we can
     /// print out deltas from then on out.
-    const char *LastLocFilename;
-    unsigned LastLocLine;
+    const char *LastLocFilename = "";
+    unsigned LastLocLine = ~0U;
 
     /// The \c FullComment parent of the comment being dumped.
-    const FullComment *FC;
+    const FullComment *FC = nullptr;
 
     bool ShowColors;
 
@@ -203,15 +207,14 @@
   public:
     ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
               const SourceManager *SM)
-      : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true),
-        LastLocFilename(""), LastLocLine(~0U), FC(nullptr),
+      : OS(OS), Traits(Traits), SM(SM),
         ShowColors(SM && SM->getDiagnostics().getShowColors()) { }
 
     ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
               const SourceManager *SM, bool ShowColors)
-      : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true),
-        LastLocFilename(""), LastLocLine(~0U),
-        ShowColors(ShowColors) { }
+      : OS(OS), Traits(Traits), SM(SM), ShowColors(ShowColors) {}
+
+    void setDeserialize(bool D) { Deserialize = D; }
 
     void dumpDecl(const Decl *D);
     void dumpStmt(const Stmt *S);
@@ -517,6 +520,8 @@
     void VisitFloatingLiteral(const FloatingLiteral *Node);
     void VisitStringLiteral(const StringLiteral *Str);
     void VisitInitListExpr(const InitListExpr *ILE);
+    void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *ILE);
+    void VisitArrayInitIndexExpr(const ArrayInitIndexExpr *ILE);
     void VisitUnaryOperator(const UnaryOperator *Node);
     void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
     void VisitMemberExpr(const MemberExpr *Node);
@@ -762,14 +767,15 @@
     return false;
 
   return DC->hasExternalLexicalStorage() ||
-         DC->noload_decls_begin() != DC->noload_decls_end();
+         (Deserialize ? DC->decls_begin() != DC->decls_end()
+                      : DC->noload_decls_begin() != DC->noload_decls_end());
 }
 
 void ASTDumper::dumpDeclContext(const DeclContext *DC) {
   if (!DC)
     return;
 
-  for (auto *D : DC->noload_decls())
+  for (auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
     dumpDecl(D);
 
   if (DC->hasExternalLexicalStorage()) {
@@ -793,11 +799,13 @@
 
     bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
 
-    DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(),
-                                      E = Primary->noload_lookups_end();
-    while (I != E) {
+    for (auto I = Deserialize ? Primary->lookups_begin()
+                              : Primary->noload_lookups_begin(),
+              E = Deserialize ? Primary->lookups_end()
+                              : Primary->noload_lookups_end();
+         I != E; ++I) {
       DeclarationName Name = I.getLookupName();
-      DeclContextLookupResult R = *I++;
+      DeclContextLookupResult R = *I;
 
       dumpChild([=] {
         OS << "DeclarationName ";
@@ -1164,11 +1172,6 @@
           D->getTemplateSpecializationInfo())
     dumpTemplateArgumentList(*FTSI->TemplateArguments);
 
-  for (ArrayRef<NamedDecl *>::iterator
-       I = D->getDeclsInPrototypeScope().begin(),
-       E = D->getDeclsInPrototypeScope().end(); I != E; ++I)
-    dumpDecl(*I);
-
   if (!D->param_begin() && D->getNumParams())
     dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; });
   else
@@ -1466,6 +1469,7 @@
     OS << " typename";
   else
     OS << " class";
+  OS << " depth " << D->getDepth() << " index " << D->getIndex();
   if (D->isParameterPack())
     OS << " ...";
   dumpName(D);
@@ -1475,6 +1479,7 @@
 
 void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
   dumpType(D->getType());
+  OS << " depth " << D->getDepth() << " index " << D->getIndex();
   if (D->isParameterPack())
     OS << " ...";
   dumpName(D);
@@ -1484,6 +1489,7 @@
 
 void ASTDumper::VisitTemplateTemplateParmDecl(
     const TemplateTemplateParmDecl *D) {
+  OS << " depth " << D->getDepth() << " index " << D->getIndex();
   if (D->isParameterPack())
     OS << " ...";
   dumpName(D);
@@ -2029,6 +2035,14 @@
   }
 }
 
+void ASTDumper::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
+  VisitExpr(E);
+}
+
+void ASTDumper::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) {
+  VisitExpr(E);
+}
+
 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
   VisitExpr(Node);
   OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
@@ -2499,9 +2513,10 @@
 
 LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
 
-LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const {
+LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize) const {
   ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
               &getASTContext().getSourceManager());
+  P.setDeserialize(Deserialize);
   P.dumpDecl(this);
 }
 
@@ -2516,12 +2531,14 @@
 }
 
 LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
-                                               bool DumpDecls) const {
+                                               bool DumpDecls,
+                                               bool Deserialize) const {
   const DeclContext *DC = this;
   while (!DC->isTranslationUnit())
     DC = DC->getParent();
   ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
   ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager());
+  P.setDeserialize(Deserialize);
   P.dumpLookups(this, DumpDecls);
 }
 
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 1a7522d..2a7768a 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -72,7 +72,7 @@
     QualType VisitEnumType(const EnumType *T);
     QualType VisitAttributedType(const AttributedType *T);
     QualType VisitTemplateTypeParmType(const TemplateTypeParmType *T);
-    // FIXME: SubstTemplateTypeParmType
+    QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T);
     QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
     QualType VisitElaboratedType(const ElaboratedType *T);
     // FIXME: DependentNameType
@@ -274,8 +274,12 @@
     Expr *VisitMemberExpr(MemberExpr *E);
     Expr *VisitCallExpr(CallExpr *E);
     Expr *VisitInitListExpr(InitListExpr *E);
+    Expr *VisitArrayInitLoopExpr(ArrayInitLoopExpr *E);
+    Expr *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E);
     Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E);
     Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
+    Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E);
+
 
     template<typename IIter, typename OIter>
     void ImportArray(IIter Ibegin, IIter Iend, OIter Obegin) {
@@ -395,6 +399,9 @@
                                      QualType T1, QualType T2);
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                                      Decl *D1, Decl *D2);
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     const TemplateArgument &Arg1,
+                                     const TemplateArgument &Arg2);
 
 /// \brief Determine structural equivalence of two expressions.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
@@ -419,8 +426,103 @@
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                                      NestedNameSpecifier *NNS1,
                                      NestedNameSpecifier *NNS2) {
-  // FIXME: Implement!
-  return true;
+  if (NNS1->getKind() != NNS2->getKind())
+    return false;
+
+  NestedNameSpecifier *Prefix1 = NNS1->getPrefix(),
+      *Prefix2 = NNS2->getPrefix();
+  if ((bool)Prefix1 != (bool)Prefix2)
+    return false;
+
+  if (Prefix1)
+    if (!IsStructurallyEquivalent(Context, Prefix1, Prefix2))
+      return false;
+
+  switch (NNS1->getKind()) {
+  case NestedNameSpecifier::Identifier:
+    return IsStructurallyEquivalent(NNS1->getAsIdentifier(),
+                                    NNS2->getAsIdentifier());
+  case NestedNameSpecifier::Namespace:
+    return IsStructurallyEquivalent(Context, NNS1->getAsNamespace(),
+                                    NNS2->getAsNamespace());
+  case NestedNameSpecifier::NamespaceAlias:
+    return IsStructurallyEquivalent(Context, NNS1->getAsNamespaceAlias(),
+                                    NNS2->getAsNamespaceAlias());
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    return IsStructurallyEquivalent(Context, QualType(NNS1->getAsType(), 0),
+                                    QualType(NNS2->getAsType(), 0));
+  case NestedNameSpecifier::Global:
+    return true;
+  case NestedNameSpecifier::Super:
+    return IsStructurallyEquivalent(Context, NNS1->getAsRecordDecl(),
+                                    NNS2->getAsRecordDecl());
+  }
+  return false;
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     const TemplateName &N1,
+                                     const TemplateName &N2) {
+  if (N1.getKind() != N2.getKind())
+    return false;
+  switch (N1.getKind()) {
+  case TemplateName::Template:
+    return IsStructurallyEquivalent(Context, N1.getAsTemplateDecl(),
+                                    N2.getAsTemplateDecl());
+
+  case TemplateName::OverloadedTemplate: {
+    OverloadedTemplateStorage *OS1 = N1.getAsOverloadedTemplate(),
+        *OS2 = N2.getAsOverloadedTemplate();
+    OverloadedTemplateStorage::iterator I1 = OS1->begin(), I2 = OS2->begin(),
+        E1 = OS1->end(), E2 = OS2->end();
+    for (; I1 != E1 && I2 != E2; ++I1, ++I2)
+      if (!IsStructurallyEquivalent(Context, *I1, *I2))
+        return false;
+    return I1 == E1 && I2 == E2;
+  }
+
+  case TemplateName::QualifiedTemplate: {
+    QualifiedTemplateName *QN1 = N1.getAsQualifiedTemplateName(),
+        *QN2 = N2.getAsQualifiedTemplateName();
+    return IsStructurallyEquivalent(Context, QN1->getDecl(), QN2->getDecl()) &&
+        IsStructurallyEquivalent(Context, QN1->getQualifier(),
+                                 QN2->getQualifier());
+  }
+
+  case TemplateName::DependentTemplate: {
+      DependentTemplateName *DN1 = N1.getAsDependentTemplateName(),
+          *DN2 = N2.getAsDependentTemplateName();
+      if (!IsStructurallyEquivalent(Context, DN1->getQualifier(),
+                                    DN2->getQualifier()))
+        return false;
+      if (DN1->isIdentifier() && DN2->isIdentifier())
+        return IsStructurallyEquivalent(DN1->getIdentifier(),
+                                        DN2->getIdentifier());
+      else if (DN1->isOverloadedOperator() && DN2->isOverloadedOperator())
+        return DN1->getOperator() == DN2->getOperator();
+      return false;
+  }
+
+  case TemplateName::SubstTemplateTemplateParm: {
+    SubstTemplateTemplateParmStorage *TS1 = N1.getAsSubstTemplateTemplateParm(),
+        *TS2 = N2.getAsSubstTemplateTemplateParm();
+    return IsStructurallyEquivalent(Context, TS1->getParameter(),
+                                    TS2->getParameter()) &&
+        IsStructurallyEquivalent(Context, TS1->getReplacement(),
+                                 TS2->getReplacement());
+    }
+  case TemplateName::SubstTemplateTemplateParmPack: {
+    SubstTemplateTemplateParmPackStorage
+        *P1 = N1.getAsSubstTemplateTemplateParmPack(),
+        *P2 = N2.getAsSubstTemplateTemplateParmPack();
+    return IsStructurallyEquivalent(Context, P1->getArgumentPack(),
+                                    P2->getArgumentPack()) &&
+        IsStructurallyEquivalent(Context, P1->getParameterPack(),
+                                 P2->getParameterPack());
+  }
+  }
+  return false;
 }
 
 /// \brief Determine whether two template arguments are equivalent.
@@ -781,6 +883,20 @@
       return false;
     break;
 
+  case Type::DeducedTemplateSpecialization: {
+    auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
+    auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  DT1->getTemplateName(),
+                                  DT2->getTemplateName()))
+      return false;
+    if (!IsStructurallyEquivalent(Context,
+                                  DT1->getDeducedType(),
+                                  DT2->getDeducedType()))
+      return false;
+    break;
+  }
+
   case Type::Record:
   case Type::Enum:
     if (!IsStructurallyEquivalent(Context,
@@ -1974,6 +2090,23 @@
         T->getDepth(), T->getIndex(), T->isParameterPack(), ParmDecl);
 }
 
+QualType ASTNodeImporter::VisitSubstTemplateTypeParmType(
+    const SubstTemplateTypeParmType *T) {
+  const TemplateTypeParmType *Replaced =
+      cast_or_null<TemplateTypeParmType>(Importer.Import(
+        QualType(T->getReplacedParameter(), 0)).getTypePtr());
+  if (!Replaced)
+    return QualType();
+
+  QualType Replacement = Importer.Import(T->getReplacementType());
+  if (Replacement.isNull())
+    return QualType();
+  Replacement = Replacement.getCanonicalType();
+
+  return Importer.getToContext().getSubstTemplateTypeParmType(
+        Replaced, Replacement);
+}
+
 QualType ASTNodeImporter::VisitTemplateSpecializationType(
                                        const TemplateSpecializationType *T) {
   TemplateName ToTemplate = Importer.Import(T->getTemplateName());
@@ -2131,6 +2264,7 @@
   case DeclarationName::ObjCOneArgSelector:
   case DeclarationName::ObjCMultiArgSelector:
   case DeclarationName::CXXUsingDirective:
+  case DeclarationName::CXXDeductionGuideName:
     return;
 
   case DeclarationName::CXXOperatorName: {
@@ -2229,8 +2363,10 @@
     ToData.UserProvidedDefaultConstructor
       = FromData.UserProvidedDefaultConstructor;
     ToData.DeclaredSpecialMembers = FromData.DeclaredSpecialMembers;
-    ToData.ImplicitCopyConstructorHasConstParam
-      = FromData.ImplicitCopyConstructorHasConstParam;
+    ToData.ImplicitCopyConstructorCanHaveConstParamForVBase
+      = FromData.ImplicitCopyConstructorCanHaveConstParamForVBase;
+    ToData.ImplicitCopyConstructorCanHaveConstParamForNonVBase
+      = FromData.ImplicitCopyConstructorCanHaveConstParamForNonVBase;
     ToData.ImplicitCopyAssignmentHasConstParam
       = FromData.ImplicitCopyAssignmentHasConstParam;
     ToData.HasDeclaredCopyConstructorWithConstParam
@@ -3669,6 +3805,9 @@
   if (ImportDefinition(D, ToVar))
     return nullptr;
 
+  if (D->isConstexpr())
+    ToVar->setConstexpr(true);
+
   return ToVar;
 }
 
@@ -3722,8 +3861,27 @@
                                      Importer.Import(D->getInnerLocStart()),
                                             Loc, Name.getAsIdentifierInfo(),
                                             T, TInfo, D->getStorageClass(),
-                                            /*FIXME: Default argument*/nullptr);
+                                            /*DefaultArg*/ nullptr);
+
+  // Set the default argument.
   ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
+  ToParm->setKNRPromoted(D->isKNRPromoted());
+
+  Expr *ToDefArg = nullptr;
+  Expr *FromDefArg = nullptr;
+  if (D->hasUninstantiatedDefaultArg()) {
+    FromDefArg = D->getUninstantiatedDefaultArg();
+    ToDefArg = Importer.Import(FromDefArg);
+    ToParm->setUninstantiatedDefaultArg(ToDefArg);
+  } else if (D->hasUnparsedDefaultArg()) {
+    ToParm->setUnparsedDefaultArg();
+  } else if (D->hasDefaultArg()) {
+    FromDefArg = D->getDefaultArg();
+    ToDefArg = Importer.Import(FromDefArg);
+    ToParm->setDefaultArg(ToDefArg);
+  }
+  if (FromDefArg && !ToDefArg)
+    return nullptr;
 
   if (D->isUsed())
     ToParm->setIsUsed();
@@ -4669,8 +4827,7 @@
 
   ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC, 
                                                     Loc, Name, TemplateParams, 
-                                                    D2Templated, 
-                                                    /*PrevDecl=*/nullptr);
+                                                    D2Templated);
   D2Templated->setDescribedClassTemplate(D2);    
   
   D2->setAccess(D->getAccess());
@@ -4752,12 +4909,46 @@
     }
   } else {
     // Create a new specialization.
-    D2 = ClassTemplateSpecializationDecl::Create(Importer.getToContext(), 
-                                                 D->getTagKind(), DC, 
-                                                 StartLoc, IdLoc,
-                                                 ClassTemplate,
-                                                 TemplateArgs,
-                                                 /*PrevDecl=*/nullptr);
+    if (ClassTemplatePartialSpecializationDecl *PartialSpec =
+        dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
+
+      // Import TemplateArgumentListInfo
+      TemplateArgumentListInfo ToTAInfo;
+      auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
+      for (unsigned I = 0, E = ASTTemplateArgs.NumTemplateArgs; I < E; ++I) {
+        bool Error = false;
+        auto ToLoc = ImportTemplateArgumentLoc(ASTTemplateArgs[I], Error);
+        if (Error)
+          return nullptr;
+        ToTAInfo.addArgument(ToLoc);
+      }
+
+      QualType CanonInjType = Importer.Import(
+            PartialSpec->getInjectedSpecializationType());
+      if (CanonInjType.isNull())
+        return nullptr;
+      CanonInjType = CanonInjType.getCanonicalType();
+
+      TemplateParameterList *ToTPList = ImportTemplateParameterList(
+            PartialSpec->getTemplateParameters());
+      if (!ToTPList && PartialSpec->getTemplateParameters())
+        return nullptr;
+
+      D2 = ClassTemplatePartialSpecializationDecl::Create(
+            Importer.getToContext(), D->getTagKind(), DC, StartLoc, IdLoc,
+            ToTPList, ClassTemplate,
+            llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
+            ToTAInfo, CanonInjType, nullptr);
+
+    } else {
+      D2 = ClassTemplateSpecializationDecl::Create(Importer.getToContext(),
+                                                   D->getTagKind(), DC,
+                                                   StartLoc, IdLoc,
+                                                   ClassTemplate,
+                                                   TemplateArgs,
+                                                   /*PrevDecl=*/nullptr);
+    }
+
     D2->setSpecializationKind(D->getSpecializationKind());
 
     // Add this specialization to the class template.
@@ -4765,13 +4956,31 @@
     
     // Import the qualifier, if any.
     D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
-    
+
+    Importer.Imported(D, D2);
+
+    if (auto *TSI = D->getTypeAsWritten()) {
+      TypeSourceInfo *TInfo = Importer.Import(TSI);
+      if (!TInfo)
+        return nullptr;
+      D2->setTypeAsWritten(TInfo);
+      D2->setTemplateKeywordLoc(Importer.Import(D->getTemplateKeywordLoc()));
+      D2->setExternLoc(Importer.Import(D->getExternLoc()));
+    }
+
+    SourceLocation POI = Importer.Import(D->getPointOfInstantiation());
+    if (POI.isValid())
+      D2->setPointOfInstantiation(POI);
+    else if (D->getPointOfInstantiation().isValid())
+      return nullptr;
+
+    D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
+
     // Add the specialization to this context.
     D2->setLexicalDeclContext(LexicalDC);
     LexicalDC->addDeclInternal(D2);
   }
   Importer.Imported(D, D2);
-  
   if (D->isCompleteDefinition() && ImportDefinition(D, D2))
     return nullptr;
 
@@ -5009,13 +5218,17 @@
   SmallVector<IdentifierInfo *, 4> Names;
   for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
     IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(I));
-    if (!ToII)
+    // ToII is nullptr when no symbolic name is given for output operand
+    // see ParseStmtAsm::ParseAsmOperandsOpt
+    if (!ToII && S->getOutputIdentifier(I))
       return nullptr;
     Names.push_back(ToII);
   }
   for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) {
     IdentifierInfo *ToII = Importer.Import(S->getInputIdentifier(I));
-    if (!ToII)
+    // ToII is nullptr when no symbolic name is given for input operand
+    // see ParseStmtAsm::ParseAsmOperandsOpt
+    if (!ToII && S->getInputIdentifier(I))
       return nullptr;
     Names.push_back(ToII);
   }
@@ -6564,6 +6777,30 @@
   return To;
 }
 
+Expr *ASTNodeImporter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
+  QualType ToType = Importer.Import(E->getType());
+  if (ToType.isNull())
+    return nullptr;
+
+  Expr *ToCommon = Importer.Import(E->getCommonExpr());
+  if (!ToCommon && E->getCommonExpr())
+    return nullptr;
+
+  Expr *ToSubExpr = Importer.Import(E->getSubExpr());
+  if (!ToSubExpr && E->getSubExpr())
+    return nullptr;
+
+  return new (Importer.getToContext())
+      ArrayInitLoopExpr(ToType, ToCommon, ToSubExpr);
+}
+
+Expr *ASTNodeImporter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
+  QualType ToType = Importer.Import(E->getType());
+  if (ToType.isNull())
+    return nullptr;
+  return new (Importer.getToContext()) ArrayInitIndexExpr(ToType);
+}
+
 Expr *ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
   FieldDecl *ToField = llvm::dyn_cast_or_null<FieldDecl>(
       Importer.Import(DIE->getField()));
@@ -6608,6 +6845,27 @@
   }
 }
 
+
+Expr *ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
+    SubstNonTypeTemplateParmExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+
+  NonTypeTemplateParmDecl *Param = cast_or_null<NonTypeTemplateParmDecl>(
+        Importer.Import(E->getParameter()));
+  if (!Param)
+    return nullptr;
+
+  Expr *Replacement = Importer.Import(E->getReplacement());
+  if (!Replacement)
+    return nullptr;
+
+  return new (Importer.getToContext()) SubstNonTypeTemplateParmExpr(
+        T, E->getValueKind(), Importer.Import(E->getExprLoc()), Param,
+        Replacement);
+}
+
 ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                          ASTContext &FromContext, FileManager &FromFileManager,
                          bool MinimalImport)
@@ -6814,14 +7072,14 @@
 
   case NestedNameSpecifier::Namespace:
     if (NamespaceDecl *NS = 
-          cast<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
+          cast_or_null<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
       return NestedNameSpecifier::Create(ToContext, prefix, NS);
     }
     return nullptr;
 
   case NestedNameSpecifier::NamespaceAlias:
     if (NamespaceAliasDecl *NSAD = 
-          cast<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
+          cast_or_null<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
       return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
     }
     return nullptr;
@@ -6831,7 +7089,7 @@
 
   case NestedNameSpecifier::Super:
     if (CXXRecordDecl *RD =
-            cast<CXXRecordDecl>(Import(FromNNS->getAsRecordDecl()))) {
+            cast_or_null<CXXRecordDecl>(Import(FromNNS->getAsRecordDecl()))) {
       return NestedNameSpecifier::SuperSpecifier(ToContext, RD);
     }
     return nullptr;
@@ -6853,8 +7111,74 @@
 }
 
 NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
-  // FIXME: Implement!
-  return NestedNameSpecifierLoc();
+  // Copied from NestedNameSpecifier mostly.
+  SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
+  NestedNameSpecifierLoc NNS = FromNNS;
+
+  // Push each of the nested-name-specifiers's onto a stack for
+  // serialization in reverse order.
+  while (NNS) {
+    NestedNames.push_back(NNS);
+    NNS = NNS.getPrefix();
+  }
+
+  NestedNameSpecifierLocBuilder Builder;
+
+  while (!NestedNames.empty()) {
+    NNS = NestedNames.pop_back_val();
+    NestedNameSpecifier *Spec = Import(NNS.getNestedNameSpecifier());
+    if (!Spec)
+      return NestedNameSpecifierLoc();
+
+    NestedNameSpecifier::SpecifierKind Kind = Spec->getKind();
+    switch (Kind) {
+    case NestedNameSpecifier::Identifier:
+      Builder.Extend(getToContext(),
+                     Spec->getAsIdentifier(),
+                     Import(NNS.getLocalBeginLoc()),
+                     Import(NNS.getLocalEndLoc()));
+      break;
+
+    case NestedNameSpecifier::Namespace:
+      Builder.Extend(getToContext(),
+                     Spec->getAsNamespace(),
+                     Import(NNS.getLocalBeginLoc()),
+                     Import(NNS.getLocalEndLoc()));
+      break;
+
+    case NestedNameSpecifier::NamespaceAlias:
+      Builder.Extend(getToContext(),
+                     Spec->getAsNamespaceAlias(),
+                     Import(NNS.getLocalBeginLoc()),
+                     Import(NNS.getLocalEndLoc()));
+      break;
+
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate: {
+      TypeSourceInfo *TSI = getToContext().getTrivialTypeSourceInfo(
+            QualType(Spec->getAsType(), 0));
+      Builder.Extend(getToContext(),
+                     Import(NNS.getLocalBeginLoc()),
+                     TSI->getTypeLoc(),
+                     Import(NNS.getLocalEndLoc()));
+      break;
+    }
+
+    case NestedNameSpecifier::Global:
+      Builder.MakeGlobal(getToContext(), Import(NNS.getLocalBeginLoc()));
+      break;
+
+    case NestedNameSpecifier::Super: {
+      SourceRange ToRange = Import(NNS.getSourceRange());
+      Builder.MakeSuper(getToContext(),
+                        Spec->getAsRecordDecl(),
+                        ToRange.getBegin(),
+                        ToRange.getEnd());
+    }
+  }
+  }
+
+  return Builder.getWithLocInContext(getToContext());
 }
 
 TemplateName ASTImporter::Import(TemplateName From) {
@@ -7054,25 +7378,6 @@
     return new (ToContext)
         CXXCtorInitializer(ToContext, ToTInfo, Import(From->getLParenLoc()),
                            ToExpr, Import(From->getRParenLoc()));
-  } else if (unsigned NumArrayIndices = From->getNumArrayIndices()) {
-    FieldDecl *ToField =
-        llvm::cast_or_null<FieldDecl>(Import(From->getMember()));
-    if (!ToField && From->getMember())
-      return nullptr;
-
-    SmallVector<VarDecl *, 4> ToAIs(NumArrayIndices);
-
-    for (unsigned AII = 0; AII < NumArrayIndices; ++AII) {
-      VarDecl *ToArrayIndex =
-          dyn_cast_or_null<VarDecl>(Import(From->getArrayIndex(AII)));
-      if (!ToArrayIndex && From->getArrayIndex(AII))
-        return nullptr;
-    }
-
-    return CXXCtorInitializer::Create(
-        ToContext, ToField, Import(From->getMemberLocation()),
-        Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc()),
-        ToAIs.data(), NumArrayIndices);
   } else {
     return nullptr;
   }
@@ -7169,6 +7474,14 @@
                                                ToContext.getCanonicalType(T));
   }
 
+  case DeclarationName::CXXDeductionGuideName: {
+    TemplateDecl *Template = cast_or_null<TemplateDecl>(
+        Import(FromName.getCXXDeductionGuideTemplate()));
+    if (!Template)
+      return DeclarationName();
+    return ToContext.DeclarationNames.getCXXDeductionGuideName(Template);
+  }
+
   case DeclarationName::CXXConversionFunctionName: {
     QualType T = Import(FromName.getCXXNameType());
     if (T.isNull())
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index e28bd2e..2e98f52 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -40,6 +40,7 @@
   MicrosoftMangle.cpp
   NestedNameSpecifier.cpp
   NSAPI.cpp
+  ODRHash.cpp
   OpenMPClause.cpp
   ParentMap.cpp
   RawCommentList.cpp
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index a97d6a2..56fb046 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -88,7 +88,7 @@
   const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
   // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7.
   return lookupInBases(
-      [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
+      [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
         return FindBaseClass(Specifier, Path, BaseDecl);
       },
       Paths);
@@ -109,7 +109,7 @@
   const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
   // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7.
   return lookupInBases(
-      [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
+      [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
         return FindVirtualBaseClass(Specifier, Path, BaseDecl);
       },
       Paths);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 2c80615..cc6f2fa 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1414,6 +1414,11 @@
                                    const PrintingPolicy &P) const {
   const DeclContext *Ctx = getDeclContext();
 
+  // For ObjC methods, look through categories and use the interface as context.
+  if (auto *MD = dyn_cast<ObjCMethodDecl>(this))
+    if (auto *ID = MD->getClassInterface())
+      Ctx = ID;
+
   if (Ctx->isFunctionOrMethod()) {
     printName(OS);
     return;
@@ -2143,13 +2148,6 @@
   return evaluateValue(Notes);
 }
 
-namespace {
-// Destroy an APValue that was allocated in an ASTContext.
-void DestroyAPValue(void* UntypedValue) {
-  static_cast<APValue*>(UntypedValue)->~APValue();
-}
-} // namespace
-
 APValue *VarDecl::evaluateValue(
     SmallVectorImpl<PartialDiagnosticAt> &Notes) const {
   EvaluatedStmt *Eval = ensureEvaluatedStmt();
@@ -2181,7 +2179,7 @@
   if (!Result)
     Eval->Evaluated = APValue();
   else if (Eval->Evaluated.needsCleanup())
-    getASTContext().AddDeallocation(DestroyAPValue, &Eval->Evaluated);
+    getASTContext().addDestruction(&Eval->Evaluated);
 
   Eval->IsEvaluating = false;
   Eval->WasEvaluated = true;
@@ -2510,7 +2508,7 @@
 
 bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
   for (auto I : redecls()) {
-    if (I->Body || I->IsLateTemplateParsed) {
+    if (I->doesThisDeclarationHaveABody()) {
       Definition = I;
       return true;
     }
@@ -2840,28 +2838,6 @@
   }
 }
 
-void FunctionDecl::setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls) {
-  assert(DeclsInPrototypeScope.empty() && "Already has prototype decls!");
-
-  if (!NewDecls.empty()) {
-    NamedDecl **A = new (getASTContext()) NamedDecl*[NewDecls.size()];
-    std::copy(NewDecls.begin(), NewDecls.end(), A);
-    DeclsInPrototypeScope = llvm::makeArrayRef(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);
-      }
-    }
-  }
-}
-
 /// getMinRequiredArguments - Returns the minimum number of arguments
 /// needed to call this function. This may be fewer than the number of
 /// function parameters, if some of the parameters have default
@@ -3012,6 +2988,18 @@
   return RTRange;
 }
 
+SourceRange FunctionDecl::getExceptionSpecSourceRange() const {
+  const TypeSourceInfo *TSI = getTypeSourceInfo();
+  if (!TSI)
+    return SourceRange();
+  FunctionTypeLoc FTL =
+    TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
+  if (!FTL)
+    return SourceRange();
+
+  return FTL.getExceptionSpecRange();
+}
+
 const Attr *FunctionDecl::getUnusedResultAttr() const {
   QualType RetType = getReturnType();
   if (RetType->isRecordType()) {
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 8deef33..cda70c5 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -619,6 +619,7 @@
 unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
   switch (DeclKind) {
     case Function:
+    case CXXDeductionGuide:
     case CXXMethod:
     case CXXConstructor:
     case ConstructorUsingShadow:
@@ -651,11 +652,13 @@
     case Typedef:
     case TypeAlias:
     case TypeAliasTemplate:
-    case UnresolvedUsingTypename:
     case TemplateTypeParm:
     case ObjCTypeParam:
       return IDNS_Ordinary | IDNS_Type;
 
+    case UnresolvedUsingTypename:
+      return IDNS_Ordinary | IDNS_Type | IDNS_Using;
+
     case UsingShadow:
       return 0; // we'll actually overwrite this later
 
@@ -663,6 +666,7 @@
       return IDNS_Ordinary | IDNS_Using;
 
     case Using:
+    case UsingPack:
       return IDNS_Using;
 
     case ObjCProtocol:
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index f1848e8..7418370 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/ODRHash.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "llvm/ADT/STLExtras.h"
@@ -67,12 +68,13 @@
       HasConstexprDefaultConstructor(false),
       HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
       UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0),
-      ImplicitCopyConstructorHasConstParam(true),
+      ImplicitCopyConstructorCanHaveConstParamForVBase(true),
+      ImplicitCopyConstructorCanHaveConstParamForNonVBase(true),
       ImplicitCopyAssignmentHasConstParam(true),
       HasDeclaredCopyConstructorWithConstParam(false),
       HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false),
-      IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0), Bases(),
-      VBases(), Definition(D), FirstFriend() {}
+      IsParsingBaseSpecifiers(false), ODRHash(0), NumBases(0), NumVBases(0),
+      Bases(), VBases(), Definition(D), FirstFriend() {}
 
 CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const {
   return Bases.get(Definition->getASTContext().getExternalSource());
@@ -226,7 +228,7 @@
         //   'const B&' or 'const volatile B&' [...]
         if (CXXRecordDecl *VBaseDecl = VBase.getType()->getAsCXXRecordDecl())
           if (!VBaseDecl->hasCopyConstructorWithConstParam())
-            data().ImplicitCopyConstructorHasConstParam = false;
+            data().ImplicitCopyConstructorCanHaveConstParamForVBase = false;
 
         // C++1z [dcl.init.agg]p1:
         //   An aggregate is a class with [...] no virtual base classes
@@ -263,6 +265,14 @@
       //   In the definition of a constexpr constructor [...]
       //    -- the class shall not have any virtual base classes
       data().DefaultedDefaultConstructorIsConstexpr = false;
+
+      // C++1z [class.copy]p8:
+      //   The implicitly-declared copy constructor for a class X will have
+      //   the form 'X::X(const X&)' if each potentially constructed subobject
+      //   has a copy constructor whose first parameter is of type
+      //   'const B&' or 'const volatile B&' [...]
+      if (!BaseClassDecl->hasCopyConstructorWithConstParam())
+        data().ImplicitCopyConstructorCanHaveConstParamForVBase = false;
     } else {
       // C++ [class.ctor]p5:
       //   A default constructor is trivial [...] if:
@@ -305,6 +315,14 @@
       //   default constructor is constexpr.
       if (!BaseClassDecl->hasConstexprDefaultConstructor())
         data().DefaultedDefaultConstructorIsConstexpr = false;
+
+      // C++1z [class.copy]p8:
+      //   The implicitly-declared copy constructor for a class X will have
+      //   the form 'X::X(const X&)' if each potentially constructed subobject
+      //   has a copy constructor whose first parameter is of type
+      //   'const B&' or 'const volatile B&' [...]
+      if (!BaseClassDecl->hasCopyConstructorWithConstParam())
+        data().ImplicitCopyConstructorCanHaveConstParamForNonVBase = false;
     }
 
     // C++ [class.ctor]p3:
@@ -324,14 +342,6 @@
     if (!BaseClassDecl->hasCopyAssignmentWithConstParam())
       data().ImplicitCopyAssignmentHasConstParam = false;
 
-    // C++11 [class.copy]p8:
-    //   The implicitly-declared copy constructor for a class X will have
-    //   the form 'X::X(const X&)' if each direct [...] base class B of X
-    //   has a copy constructor whose first parameter is of type
-    //   'const B&' or 'const volatile B&' [...]
-    if (!BaseClassDecl->hasCopyConstructorWithConstParam())
-      data().ImplicitCopyConstructorHasConstParam = false;
-
     // A class has an Objective-C object member if... or any of its bases
     // has an Objective-C object member.
     if (BaseClassDecl->hasObjectMember())
@@ -371,6 +381,16 @@
   data().IsParsingBaseSpecifiers = false;
 }
 
+void CXXRecordDecl::computeODRHash() {
+  if (!DefinitionData)
+    return;
+
+  ODRHash Hash;
+  Hash.AddCXXRecordDecl(this);
+
+  DefinitionData->ODRHash = Hash.CalculateHash();
+}
+
 void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
   // C++11 [class.copy]p11:
   //   A defaulted copy/move constructor for a class X is defined as
@@ -534,15 +554,10 @@
         SMKind |= SMF_MoveConstructor;
     }
 
-    // C++ [dcl.init.aggr]p1:
-    //   An aggregate is an array or a class with no user-declared
-    //   constructors [...].
     // C++11 [dcl.init.aggr]p1: DR1518
-    //  An aggregate is an array or a class with no user-provided, explicit, or
-    //  inherited constructors
-    if (getASTContext().getLangOpts().CPlusPlus11
-            ? (Constructor->isUserProvided() || Constructor->isExplicit())
-            : !Constructor->isImplicit())
+    //   An aggregate is an array or a class with no user-provided, explicit, or
+    //   inherited constructors
+    if (Constructor->isUserProvided() || Constructor->isExplicit())
       data().Aggregate = false;
   }
 
@@ -910,12 +925,11 @@
 
         // C++11 [class.copy]p8:
         //   The implicitly-declared copy constructor for a class X will have
-        //   the form 'X::X(const X&)' if [...] for all the non-static data
-        //   members of X that are of a class type M (or array thereof), each
-        //   such class type has a copy constructor whose first parameter is
-        //   of type 'const M&' or 'const volatile M&'.
+        //   the form 'X::X(const X&)' if each potentially constructed subobject
+        //   of a class type M (or array thereof) has a copy constructor whose
+        //   first parameter is of type 'const M&' or 'const volatile M&'.
         if (!FieldRec->hasCopyConstructorWithConstParam())
-          data().ImplicitCopyConstructorHasConstParam = false;
+          data().ImplicitCopyConstructorCanHaveConstParamForNonVBase = false;
 
         // C++11 [class.copy]p18:
         //   The implicitly-declared copy assignment oeprator for a class X will
@@ -1477,6 +1491,23 @@
   return false;
 }
 
+void CXXDeductionGuideDecl::anchor() { }
+
+CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create(
+    ASTContext &C, DeclContext *DC, SourceLocation StartLoc, bool IsExplicit,
+    const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+    SourceLocation EndLocation) {
+  return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, IsExplicit,
+                                           NameInfo, T, TInfo, EndLocation);
+}
+
+CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C,
+                                                                 unsigned ID) {
+  return new (C, ID) CXXDeductionGuideDecl(C, nullptr, SourceLocation(), false,
+                                           DeclarationNameInfo(), QualType(),
+                                           nullptr, SourceLocation());
+}
+
 void CXXMethodDecl::anchor() { }
 
 bool CXXMethodDecl::isStatic() const {
@@ -1739,7 +1770,7 @@
                                        SourceLocation EllipsisLoc)
   : Initializee(TInfo), MemberOrEllipsisLocation(EllipsisLoc), Init(Init), 
     LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual), 
-    IsWritten(false), SourceOrderOrNumArrayIndices(0)
+    IsWritten(false), SourceOrder(0)
 {
 }
 
@@ -1750,7 +1781,7 @@
                                        SourceLocation R)
   : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
     LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
-    IsWritten(false), SourceOrderOrNumArrayIndices(0)
+    IsWritten(false), SourceOrder(0)
 {
 }
 
@@ -1761,7 +1792,7 @@
                                        SourceLocation R)
   : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
     LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
-    IsWritten(false), SourceOrderOrNumArrayIndices(0)
+    IsWritten(false), SourceOrder(0)
 {
 }
 
@@ -1771,38 +1802,10 @@
                                        SourceLocation R)
   : Initializee(TInfo), MemberOrEllipsisLocation(), Init(Init),
     LParenLoc(L), RParenLoc(R), IsDelegating(true), IsVirtual(false),
-    IsWritten(false), SourceOrderOrNumArrayIndices(0)
+    IsWritten(false), SourceOrder(0)
 {
 }
 
-CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
-                                       FieldDecl *Member,
-                                       SourceLocation MemberLoc,
-                                       SourceLocation L, Expr *Init,
-                                       SourceLocation R,
-                                       VarDecl **Indices,
-                                       unsigned NumIndices)
-  : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), 
-    LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
-    IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
-{
-  std::uninitialized_copy(Indices, Indices + NumIndices,
-                          getTrailingObjects<VarDecl *>());
-}
-
-CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,
-                                               FieldDecl *Member, 
-                                               SourceLocation MemberLoc,
-                                               SourceLocation L, Expr *Init,
-                                               SourceLocation R,
-                                               VarDecl **Indices,
-                                               unsigned NumIndices) {
-  void *Mem = Context.Allocate(totalSizeToAlloc<VarDecl *>(NumIndices),
-                               alignof(CXXCtorInitializer));
-  return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R,
-                                      Indices, NumIndices);
-}
-
 TypeLoc CXXCtorInitializer::getBaseClassLoc() const {
   if (isBaseInitializer())
     return Initializee.get<TypeSourceInfo*>()->getTypeLoc();
@@ -2278,15 +2281,37 @@
   return SourceRange(Begin, getNameInfo().getEndLoc());
 }
 
+void UsingPackDecl::anchor() { }
+
+UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC,
+                                     NamedDecl *InstantiatedFrom,
+                                     ArrayRef<NamedDecl *> UsingDecls) {
+  size_t Extra = additionalSizeToAlloc<NamedDecl *>(UsingDecls.size());
+  return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls);
+}
+
+UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, unsigned ID,
+                                                 unsigned NumExpansions) {
+  size_t Extra = additionalSizeToAlloc<NamedDecl *>(NumExpansions);
+  auto *Result = new (C, ID, Extra) UsingPackDecl(nullptr, nullptr, None);
+  Result->NumExpansions = NumExpansions;
+  auto *Trail = Result->getTrailingObjects<NamedDecl *>();
+  for (unsigned I = 0; I != NumExpansions; ++I)
+    new (Trail + I) NamedDecl*(nullptr);
+  return Result;
+}
+
 void UnresolvedUsingValueDecl::anchor() { }
 
 UnresolvedUsingValueDecl *
 UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation UsingLoc,
                                  NestedNameSpecifierLoc QualifierLoc,
-                                 const DeclarationNameInfo &NameInfo) {
+                                 const DeclarationNameInfo &NameInfo,
+                                 SourceLocation EllipsisLoc) {
   return new (C, DC) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
-                                              QualifierLoc, NameInfo);
+                                              QualifierLoc, NameInfo,
+                                              EllipsisLoc);
 }
 
 UnresolvedUsingValueDecl *
@@ -2294,7 +2319,8 @@
   return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(),
                                               SourceLocation(),
                                               NestedNameSpecifierLoc(),
-                                              DeclarationNameInfo());
+                                              DeclarationNameInfo(),
+                                              SourceLocation());
 }
 
 SourceRange UnresolvedUsingValueDecl::getSourceRange() const {
@@ -2311,17 +2337,18 @@
                                     SourceLocation TypenameLoc,
                                     NestedNameSpecifierLoc QualifierLoc,
                                     SourceLocation TargetNameLoc,
-                                    DeclarationName TargetName) {
+                                    DeclarationName TargetName,
+                                    SourceLocation EllipsisLoc) {
   return new (C, DC) UnresolvedUsingTypenameDecl(
       DC, UsingLoc, TypenameLoc, QualifierLoc, TargetNameLoc,
-      TargetName.getAsIdentifierInfo());
+      TargetName.getAsIdentifierInfo(), EllipsisLoc);
 }
 
 UnresolvedUsingTypenameDecl *
 UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
   return new (C, ID) UnresolvedUsingTypenameDecl(
       nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(),
-      SourceLocation(), nullptr);
+      SourceLocation(), nullptr, SourceLocation());
 }
 
 void StaticAssertDecl::anchor() { }
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 60d05f6..a1ef58a 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -162,10 +162,10 @@
         return nullptr;
   }
 
-  // If context is class, then lookup property in its extensions.
+  // If context is class, then lookup property in its visible extensions.
   // This comes before property is looked up in primary class.
   if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) {
-    for (const auto *Ext : IDecl->known_extensions())
+    for (const auto *Ext : IDecl->visible_extensions())
       if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext,
                                                        propertyID,
                                                        queryKind))
@@ -979,11 +979,12 @@
     break;
       
   case OMF_performSelector:
-    if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
+    if (!isInstanceMethod() ||
+        !(getReturnType()->isObjCIdType() || getReturnType()->isVoidType()))
       family = OMF_None;
     else {
       unsigned noParams = param_size();
-      if (noParams < 1 || noParams > 3)
+      if (noParams < 1 || noParams > 5)
         family = OMF_None;
       else {
         ObjCMethodDecl::param_type_iterator it = param_type_begin();
@@ -992,10 +993,11 @@
           family = OMF_None;
           break;
         }
-        while (--noParams) {
-          it++;
-          ArgT = (*it);
-          if (!ArgT->isObjCIdType()) {
+        // The first type should generally always be 'id' or 'Thread *', the
+        // other types can vary.
+        if (noParams > 1) {
+          ArgT = *(it + 1);
+          if (!ArgT->isObjCObjectPointerType()) {
             family = OMF_None;
             break;
           }
diff --git a/lib/AST/DeclOpenMP.cpp b/lib/AST/DeclOpenMP.cpp
index 5b06ce0..95e44ac 100644
--- a/lib/AST/DeclOpenMP.cpp
+++ b/lib/AST/DeclOpenMP.cpp
@@ -90,13 +90,18 @@
 void OMPCapturedExprDecl::anchor() {}
 
 OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC,
-                                                 IdentifierInfo *Id,
-                                                 QualType T) {
-  return new (C, DC) OMPCapturedExprDecl(C, DC, Id, T);
+                                                 IdentifierInfo *Id, QualType T,
+                                                 SourceLocation StartLoc) {
+  return new (C, DC) OMPCapturedExprDecl(C, DC, Id, T, StartLoc);
 }
 
 OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C,
                                                              unsigned ID) {
-  return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType());
+  return new (C, ID)
+      OMPCapturedExprDecl(C, nullptr, nullptr, QualType(), SourceLocation());
 }
 
+SourceRange OMPCapturedExprDecl::getSourceRange() const {
+  assert(hasInit());
+  return SourceRange(getInit()->getLocStart(), getInit()->getLocEnd());
+}
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index b8ebe1c..aedc35b 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -464,6 +464,7 @@
 
 void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
   Out << *D;
+  prettyPrintAttributes(D);
   if (Expr *Init = D->getInitExpr()) {
     Out << " = ";
     Init->printPretty(Out, nullptr, Policy, Indentation);
@@ -480,6 +481,7 @@
 
   CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
   CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
+  CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
   if (!Policy.SuppressSpecifiers) {
     switch (D->getStorageClass()) {
     case SC_None: break;
@@ -495,13 +497,16 @@
     if (D->isModulePrivate())    Out << "__module_private__ ";
     if (D->isConstexpr() && !D->isExplicitlyDefaulted()) Out << "constexpr ";
     if ((CDecl && CDecl->isExplicitSpecified()) ||
-        (ConversionDecl && ConversionDecl->isExplicit()))
+        (ConversionDecl && ConversionDecl->isExplicitSpecified()) ||
+        (GuideDecl && GuideDecl->isExplicitSpecified()))
       Out << "explicit ";
   }
 
   PrintingPolicy SubPolicy(Policy);
   SubPolicy.SuppressSpecifiers = false;
   std::string Proto = D->getNameInfo().getAsString();
+  if (GuideDecl)
+    Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
   if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {
     llvm::raw_string_ostream POut(Proto);
     DeclPrinter TArgPrinter(POut, SubPolicy, Indentation);
@@ -651,7 +656,9 @@
       }
     } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) {
       if (FT && FT->hasTrailingReturn()) {
-        Out << "auto " << Proto << " -> ";
+        if (!GuideDecl)
+          Out << "auto ";
+        Out << Proto << " -> ";
         Proto.clear();
       }
       AFT->getReturnType().print(Out, Policy, Proto);
@@ -1043,7 +1050,10 @@
   prettyPrintPragmas(D->getTemplatedDecl());
   VisitRedeclarableTemplateDecl(D);
 
-  if (PrintInstantiation) {
+  // Never print "instantiations" for deduction guides (they don't really
+  // have them).
+  if (PrintInstantiation &&
+      !isa<CXXDeductionGuideDecl>(D->getTemplatedDecl())) {
     FunctionDecl *PrevDecl = D->getTemplatedDecl();
     const FunctionDecl *Def;
     if (PrevDecl->isDefined(Def) && Def != PrevDecl)
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 8e3b783..00a6739 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -204,52 +204,10 @@
                                       SETraits::getDecl(Entry));
 }
 
-/// \brief Generate the injected template arguments for the given template
-/// parameter list, e.g., for the injected-class-name of a class template.
-static void GenerateInjectedTemplateArgs(ASTContext &Context,
-                                         TemplateParameterList *Params,
-                                         TemplateArgument *Args) {
-  for (NamedDecl *Param : *Params) {
-    TemplateArgument Arg;
-    if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
-      QualType ArgType = Context.getTypeDeclType(TTP);
-      if (TTP->isParameterPack())
-        ArgType = Context.getPackExpansionType(ArgType, None);
-
-      Arg = TemplateArgument(ArgType);
-    } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
-      Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
-                                  NTTP->getType().getNonLValueExprType(Context),
-                                  Expr::getValueKindForType(NTTP->getType()),
-                                          NTTP->getLocation());
-
-      if (NTTP->isParameterPack())
-        E = new (Context) PackExpansionExpr(Context.DependentTy, E,
-                                            NTTP->getLocation(), None);
-      Arg = TemplateArgument(E);
-    } else {
-      auto *TTP = cast<TemplateTemplateParmDecl>(Param);
-      if (TTP->isParameterPack())
-        Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
-      else
-        Arg = TemplateArgument(TemplateName(TTP));
-    }
-
-    if (Param->isTemplateParameterPack())
-      Arg = TemplateArgument::CreatePackCopy(Context, Arg);
-
-    *Args++ = Arg;
-  }
-}
-
 //===----------------------------------------------------------------------===//
 // FunctionTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
-void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
-  static_cast<Common *>(Ptr)->~Common();
-}
-
 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
                                                    DeclContext *DC,
                                                    SourceLocation L,
@@ -269,7 +227,7 @@
 RedeclarableTemplateDecl::CommonBase *
 FunctionTemplateDecl::newCommon(ASTContext &C) const {
   Common *CommonPtr = new (C) Common;
-  C.AddDeallocation(DeallocateCommon, CommonPtr);
+  C.addDestruction(CommonPtr);
   return CommonPtr;
 }
 
@@ -310,10 +268,13 @@
   TemplateParameterList *Params = getTemplateParameters();
   Common *CommonPtr = getCommonPtr();
   if (!CommonPtr->InjectedArgs) {
-    CommonPtr->InjectedArgs
-      = new (getASTContext()) TemplateArgument[Params->size()];
-    GenerateInjectedTemplateArgs(getASTContext(), Params,
-                                 CommonPtr->InjectedArgs);
+    auto &Context = getASTContext();
+    SmallVector<TemplateArgument, 16> TemplateArgs;
+    Context.getInjectedTemplateArgs(Params, TemplateArgs);
+    CommonPtr->InjectedArgs =
+        new (Context) TemplateArgument[TemplateArgs.size()];
+    std::copy(TemplateArgs.begin(), TemplateArgs.end(),
+              CommonPtr->InjectedArgs);
   }
 
   return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
@@ -323,21 +284,23 @@
 // ClassTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
-void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
-  static_cast<Common *>(Ptr)->~Common();
-}
-
 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
                                              DeclContext *DC,
                                              SourceLocation L,
                                              DeclarationName Name,
                                              TemplateParameterList *Params,
                                              NamedDecl *Decl,
-                                             ClassTemplateDecl *PrevDecl) {
+                                             Expr *AssociatedConstraints) {
   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
-  ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
-                                                         Params, Decl);
-  New->setPreviousDecl(PrevDecl);
+
+  if (!AssociatedConstraints) {
+    return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
+  }
+
+  ConstrainedTemplateDeclInfo *const CTDI = new (C) ConstrainedTemplateDeclInfo;
+  ClassTemplateDecl *const New =
+      new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
+  New->setAssociatedConstraints(AssociatedConstraints);
   return New;
 }
 
@@ -377,7 +340,7 @@
 RedeclarableTemplateDecl::CommonBase *
 ClassTemplateDecl::newCommon(ASTContext &C) const {
   Common *CommonPtr = new (C) Common;
-  C.AddDeallocation(DeallocateCommon, CommonPtr);
+  C.addDestruction(CommonPtr);
   return CommonPtr;
 }
 
@@ -464,8 +427,7 @@
   ASTContext &Context = getASTContext();
   TemplateParameterList *Params = getTemplateParameters();
   SmallVector<TemplateArgument, 16> TemplateArgs;
-  TemplateArgs.resize(Params->size());
-  GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
+  Context.getInjectedTemplateArgs(Params, TemplateArgs);
   CommonPtr->InjectedClassNameType
     = Context.getTemplateSpecializationType(TemplateName(this),
                                             TemplateArgs);
@@ -761,9 +723,16 @@
     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
 
-  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
-  TemplateSpecializationType::PrintTemplateArgumentList(
-      OS, TemplateArgs.asArray(), Policy);
+  auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
+  if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
+          PS ? PS->getTemplateArgsAsWritten() : nullptr) {
+    TemplateSpecializationType::PrintTemplateArgumentList(
+        OS, ArgsAsWritten->arguments(), Policy);
+  } else {
+    const TemplateArgumentList &TemplateArgs = getTemplateArgs();
+    TemplateSpecializationType::PrintTemplateArgumentList(
+        OS, TemplateArgs.asArray(), Policy);
+  }
 }
 
 ClassTemplateDecl *
@@ -911,13 +880,10 @@
                                            DeclarationName(), nullptr, nullptr);
 }
 
-void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
-  static_cast<Common *>(Ptr)->~Common();
-}
 RedeclarableTemplateDecl::CommonBase *
 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
   Common *CommonPtr = new (C) Common;
-  C.AddDeallocation(DeallocateCommon, CommonPtr);
+  C.addDestruction(CommonPtr);
   return CommonPtr;
 }
 
@@ -938,10 +904,6 @@
 // VarTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
-void VarTemplateDecl::DeallocateCommon(void *Ptr) {
-  static_cast<Common *>(Ptr)->~Common();
-}
-
 VarTemplateDecl *VarTemplateDecl::getDefinition() {
   VarTemplateDecl *CurD = this;
   while (CurD) {
@@ -997,7 +959,7 @@
 RedeclarableTemplateDecl::CommonBase *
 VarTemplateDecl::newCommon(ASTContext &C) const {
   Common *CommonPtr = new (C) Common;
-  C.AddDeallocation(DeallocateCommon, CommonPtr);
+  C.addDestruction(CommonPtr);
   return CommonPtr;
 }
 
@@ -1093,9 +1055,16 @@
     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
 
-  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
-  TemplateSpecializationType::PrintTemplateArgumentList(
-      OS, TemplateArgs.asArray(), Policy);
+  auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
+  if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
+          PS ? PS->getTemplateArgsAsWritten() : nullptr) {
+    TemplateSpecializationType::PrintTemplateArgumentList(
+        OS, ArgsAsWritten->arguments(), Policy);
+  } else {
+    const TemplateArgumentList &TemplateArgs = getTemplateArgs();
+    TemplateSpecializationType::PrintTemplateArgumentList(
+        OS, TemplateArgs.asArray(), Policy);
+  }
 }
 
 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 52791e5..6053bd7 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeOrdering.h"
@@ -43,6 +44,22 @@
   }
 };
 
+/// Contains extra information for the name of a C++ deduction guide.
+class CXXDeductionGuideNameExtra : public DeclarationNameExtra,
+                                   public llvm::FoldingSetNode {
+public:
+  /// The template named by the deduction guide.
+  TemplateDecl *Template;
+
+  /// FETokenInfo - Extra information associated with this operator
+  /// name that can be used by the front end.
+  void *FETokenInfo;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    ID.AddPointer(Template);
+  }
+};
+
 /// CXXOperatorIdName - Contains extra information for the name of an
 /// overloaded operator in C++, such as "operator+.
 class CXXOperatorIdName : public DeclarationNameExtra {
@@ -122,7 +139,13 @@
     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
       return 1;
     return 0;
-              
+
+  case DeclarationName::CXXDeductionGuideName:
+    // We never want to compare deduction guide names for templates from
+    // different scopes, so just compare the template-name.
+    return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
+                   RHS.getCXXDeductionGuideTemplate()->getDeclName());
+
   case DeclarationName::CXXOperatorName:
     return compareInt(LHS.getCXXOverloadedOperator(),
                       RHS.getCXXOverloadedOperator());
@@ -179,6 +202,12 @@
     return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
   }
 
+  case DeclarationName::CXXDeductionGuideName:
+    OS << "<deduction guide for ";
+    getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
+    OS << '>';
+    return;
+
   case DeclarationName::CXXOperatorName: {
     static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
       nullptr,
@@ -243,6 +272,9 @@
     case DeclarationNameExtra::CXXDestructor:
       return CXXDestructorName;
 
+    case DeclarationNameExtra::CXXDeductionGuide:
+      return CXXDeductionGuideName;
+
     case DeclarationNameExtra::CXXConversionFunction:
       return CXXConversionFunctionName;
 
@@ -268,7 +300,15 @@
 
 bool DeclarationName::isDependentName() const {
   QualType T = getCXXNameType();
-  return !T.isNull() && T->isDependentType();
+  if (!T.isNull() && T->isDependentType())
+    return true;
+
+  // A class-scope deduction guide in a dependent context has a dependent name.
+  auto *TD = getCXXDeductionGuideTemplate();
+  if (TD && TD->getDeclContext()->isDependentContext())
+    return true;
+
+  return false;
 }
 
 std::string DeclarationName::getAsString() const {
@@ -285,6 +325,12 @@
     return QualType();
 }
 
+TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const {
+  if (auto *Guide = getAsCXXDeductionGuideNameExtra())
+    return Guide->Template;
+  return nullptr;
+}
+
 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
   if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
     unsigned value
@@ -312,6 +358,9 @@
   case CXXConversionFunctionName:
     return getAsCXXSpecialName()->FETokenInfo;
 
+  case CXXDeductionGuideName:
+    return getAsCXXDeductionGuideNameExtra()->FETokenInfo;
+
   case CXXOperatorName:
     return getAsCXXOperatorIdName()->FETokenInfo;
 
@@ -335,6 +384,10 @@
     getAsCXXSpecialName()->FETokenInfo = T;
     break;
 
+  case CXXDeductionGuideName:
+    getAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
+    break;
+
   case CXXOperatorName:
     getAsCXXOperatorIdName()->FETokenInfo = T;
     break;
@@ -366,6 +419,7 @@
 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
   CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
+  CXXDeductionGuideNames = new llvm::FoldingSet<CXXDeductionGuideNameExtra>;
 
   // Initialize the overloaded operator names.
   CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
@@ -377,14 +431,18 @@
 }
 
 DeclarationNameTable::~DeclarationNameTable() {
-  llvm::FoldingSet<CXXSpecialName> *SpecialNames =
-    static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
-  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
-    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
-        (CXXLiteralOperatorNames);
+  auto *SpecialNames =
+      static_cast<llvm::FoldingSet<CXXSpecialName> *>(CXXSpecialNamesImpl);
+  auto *LiteralNames =
+      static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName> *>(
+          CXXLiteralOperatorNames);
+  auto *DeductionGuideNames =
+      static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>(
+          CXXDeductionGuideNames);
 
   delete SpecialNames;
   delete LiteralNames;
+  delete DeductionGuideNames;
 }
 
 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
@@ -398,6 +456,30 @@
 }
 
 DeclarationName
+DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
+  Template = cast<TemplateDecl>(Template->getCanonicalDecl());
+
+  auto *DeductionGuideNames =
+      static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>(
+          CXXDeductionGuideNames);
+
+  llvm::FoldingSetNodeID ID;
+  ID.AddPointer(Template);
+
+  void *InsertPos = nullptr;
+  if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos))
+    return DeclarationName(Name);
+
+  auto *Name = new (Ctx) CXXDeductionGuideNameExtra;
+  Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide;
+  Name->Template = Template;
+  Name->FETokenInfo = nullptr;
+
+  DeductionGuideNames->InsertNode(Name, InsertPos);
+  return DeclarationName(Name);
+}
+
+DeclarationName
 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
   return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
 }
@@ -477,6 +559,7 @@
 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
   switch (Name.getNameKind()) {
   case DeclarationName::Identifier:
+  case DeclarationName::CXXDeductionGuideName:
     break;
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
@@ -509,6 +592,7 @@
   case DeclarationName::CXXOperatorName:
   case DeclarationName::CXXLiteralOperatorName:
   case DeclarationName::CXXUsingDirective:
+  case DeclarationName::CXXDeductionGuideName:
     return false;
 
   case DeclarationName::CXXConstructorName:
@@ -531,6 +615,7 @@
   case DeclarationName::CXXOperatorName:
   case DeclarationName::CXXLiteralOperatorName:
   case DeclarationName::CXXUsingDirective:
+  case DeclarationName::CXXDeductionGuideName:
     return false;
     
   case DeclarationName::CXXConstructorName:
@@ -560,6 +645,7 @@
   case DeclarationName::CXXOperatorName:
   case DeclarationName::CXXLiteralOperatorName:
   case DeclarationName::CXXUsingDirective:
+  case DeclarationName::CXXDeductionGuideName:
     OS << Name;
     return;
 
@@ -585,6 +671,7 @@
 SourceLocation DeclarationNameInfo::getEndLoc() const {
   switch (Name.getNameKind()) {
   case DeclarationName::Identifier:
+  case DeclarationName::CXXDeductionGuideName:
     return NameLoc;
 
   case DeclarationName::CXXOperatorName: {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 776a7f9..224dec1 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -562,8 +562,7 @@
       FT = dyn_cast<FunctionProtoType>(AFT);
 
     if (IT == FuncSig) {
-      assert(FT && "We must have a written prototype in this case.");
-      switch (FT->getCallConv()) {
+      switch (AFT->getCallConv()) {
       case CC_C: POut << "__cdecl "; break;
       case CC_X86StdCall: POut << "__stdcall "; break;
       case CC_X86FastCall: POut << "__fastcall "; break;
@@ -587,12 +586,15 @@
       if (FT->isVariadic()) {
         if (FD->getNumParams()) POut << ", ";
         POut << "...";
+      } else if ((IT == FuncSig || !Context.getLangOpts().CPlusPlus) &&
+                 !Decl->getNumParams()) {
+        POut << "void";
       }
     }
     POut << ")";
 
     if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
-      const FunctionType *FT = MD->getType()->castAs<FunctionType>();
+      assert(FT && "We must have a written prototype in this case.");
       if (FT->isConst())
         POut << " const";
       if (FT->isVolatile())
@@ -782,33 +784,33 @@
 const llvm::fltSemantics &FloatingLiteral::getSemantics() const {
   switch(FloatingLiteralBits.Semantics) {
   case IEEEhalf:
-    return llvm::APFloat::IEEEhalf;
+    return llvm::APFloat::IEEEhalf();
   case IEEEsingle:
-    return llvm::APFloat::IEEEsingle;
+    return llvm::APFloat::IEEEsingle();
   case IEEEdouble:
-    return llvm::APFloat::IEEEdouble;
+    return llvm::APFloat::IEEEdouble();
   case x87DoubleExtended:
-    return llvm::APFloat::x87DoubleExtended;
+    return llvm::APFloat::x87DoubleExtended();
   case IEEEquad:
-    return llvm::APFloat::IEEEquad;
+    return llvm::APFloat::IEEEquad();
   case PPCDoubleDouble:
-    return llvm::APFloat::PPCDoubleDouble;
+    return llvm::APFloat::PPCDoubleDouble();
   }
   llvm_unreachable("Unrecognised floating semantics");
 }
 
 void FloatingLiteral::setSemantics(const llvm::fltSemantics &Sem) {
-  if (&Sem == &llvm::APFloat::IEEEhalf)
+  if (&Sem == &llvm::APFloat::IEEEhalf())
     FloatingLiteralBits.Semantics = IEEEhalf;
-  else if (&Sem == &llvm::APFloat::IEEEsingle)
+  else if (&Sem == &llvm::APFloat::IEEEsingle())
     FloatingLiteralBits.Semantics = IEEEsingle;
-  else if (&Sem == &llvm::APFloat::IEEEdouble)
+  else if (&Sem == &llvm::APFloat::IEEEdouble())
     FloatingLiteralBits.Semantics = IEEEdouble;
-  else if (&Sem == &llvm::APFloat::x87DoubleExtended)
+  else if (&Sem == &llvm::APFloat::x87DoubleExtended())
     FloatingLiteralBits.Semantics = x87DoubleExtended;
-  else if (&Sem == &llvm::APFloat::IEEEquad)
+  else if (&Sem == &llvm::APFloat::IEEEquad())
     FloatingLiteralBits.Semantics = IEEEquad;
-  else if (&Sem == &llvm::APFloat::PPCDoubleDouble)
+  else if (&Sem == &llvm::APFloat::PPCDoubleDouble())
     FloatingLiteralBits.Semantics = PPCDoubleDouble;
   else
     llvm_unreachable("Unknown floating semantics");
@@ -820,7 +822,7 @@
 double FloatingLiteral::getValueAsApproximateDouble() const {
   llvm::APFloat V = getValue();
   bool ignored;
-  V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
+  V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
             &ignored);
   return V.convertToDouble();
 }
@@ -1569,8 +1571,9 @@
     goto CheckNoBasePath;
 
   case CK_AddressSpaceConversion:
-    assert(getType()->isPointerType());
-    assert(getSubExpr()->getType()->isPointerType());
+    assert(getType()->isPointerType() || getType()->isBlockPointerType());
+    assert(getSubExpr()->getType()->isPointerType() ||
+           getSubExpr()->getType()->isBlockPointerType());
     assert(getType()->getPointeeType().getAddressSpace() !=
            getSubExpr()->getType()->getPointeeType().getAddressSpace());
   // These should not have an inheritance path.
@@ -1603,6 +1606,7 @@
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
   case CK_ZeroToOCLEvent:
+  case CK_ZeroToOCLQueue:
   case CK_IntToOCLSampler:
     assert(!getType()->isBooleanType() && "unheralded conversion to bool");
     goto CheckNoBasePath;
@@ -1878,6 +1882,11 @@
   if (getNumInits() != 1 || !getInit(0))
     return false;
 
+  // Don't confuse aggregate initialization of a struct X { X &x; }; with a
+  // transparent struct copy.
+  if (!getInit(0)->isRValue() && getType()->isRecordType())
+    return false;
+
   return getType().getCanonicalType() ==
          getInit(0)->getType().getCanonicalType();
 }
@@ -2899,6 +2908,7 @@
   case UnaryExprOrTypeTraitExprClass:
   case AddrLabelExprClass:
   case GNUNullExprClass:
+  case ArrayInitIndexExprClass:
   case NoInitExprClass:
   case CXXBoolLiteralExprClass:
   case CXXNullPtrLiteralExprClass:
@@ -2948,6 +2958,7 @@
   case CXXNewExprClass:
   case CXXDeleteExprClass:
   case CoawaitExprClass:
+  case DependentCoawaitExprClass:
   case CoyieldExprClass:
     // These always have a side-effect.
     return true;
@@ -2975,6 +2986,7 @@
   case ExtVectorElementExprClass:
   case DesignatedInitExprClass:
   case DesignatedInitUpdateExprClass:
+  case ArrayInitLoopExprClass:
   case ParenListExprClass:
   case CXXPseudoDestructorExprClass:
   case CXXStdInitializerListExprClass:
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 5ad014f..6713fca 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -734,23 +734,23 @@
 
 CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C,
                                                CXXConstructorDecl *Cons,
-                                               TypeSourceInfo *Type,
+                                               QualType Type,
+                                               TypeSourceInfo *TSI,
                                                ArrayRef<Expr*> Args,
                                                SourceRange ParenOrBraceRange,
                                                bool HadMultipleCandidates,
                                                bool ListInitialization,
                                                bool StdInitListInitialization,
                                                bool ZeroInitialization)
-  : CXXConstructExpr(C, CXXTemporaryObjectExprClass, 
-                     Type->getType().getNonReferenceType(), 
-                     Type->getTypeLoc().getBeginLoc(),
+  : CXXConstructExpr(C, CXXTemporaryObjectExprClass, Type,
+                     TSI->getTypeLoc().getBeginLoc(),
                      Cons, false, Args,
                      HadMultipleCandidates,
                      ListInitialization,
                      StdInitListInitialization,
                      ZeroInitialization,
                      CXXConstructExpr::CK_Complete, ParenOrBraceRange),
-    Type(Type) {
+    Type(TSI) {
 }
 
 SourceLocation CXXTemporaryObjectExpr::getLocStart() const {
@@ -869,8 +869,6 @@
                        SourceLocation CaptureDefaultLoc,
                        ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
                        bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
-                       ArrayRef<VarDecl *> ArrayIndexVars,
-                       ArrayRef<unsigned> ArrayIndexStarts,
                        SourceLocation ClosingBrace,
                        bool ContainsUnexpandedParameterPack)
     : Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary, T->isDependentType(),
@@ -907,17 +905,6 @@
   
   // Copy the body of the lambda.
   *Stored++ = getCallOperator()->getBody();
-
-  // Copy the array index variables, if any.
-  HasArrayIndexVars = !ArrayIndexVars.empty();
-  if (HasArrayIndexVars) {
-    assert(ArrayIndexStarts.size() == NumCaptures);
-    memcpy(getArrayIndexVars(), ArrayIndexVars.data(),
-           sizeof(VarDecl *) * ArrayIndexVars.size());
-    memcpy(getArrayIndexStarts(), ArrayIndexStarts.data(), 
-           sizeof(unsigned) * Captures.size());
-    getArrayIndexStarts()[Captures.size()] = ArrayIndexVars.size();
-  }
 }
 
 LambdaExpr *LambdaExpr::Create(
@@ -925,31 +912,24 @@
     SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault,
     SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
     bool ExplicitParams, bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
-    ArrayRef<VarDecl *> ArrayIndexVars, ArrayRef<unsigned> ArrayIndexStarts,
     SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack) {
   // Determine the type of the expression (i.e., the type of the
   // function object we're creating).
   QualType T = Context.getTypeDeclType(Class);
 
-  unsigned Size = totalSizeToAlloc<Stmt *, unsigned, VarDecl *>(
-      Captures.size() + 1, ArrayIndexVars.empty() ? 0 : Captures.size() + 1,
-      ArrayIndexVars.size());
+  unsigned Size = totalSizeToAlloc<Stmt *>(Captures.size() + 1);
   void *Mem = Context.Allocate(Size);
-  return new (Mem) LambdaExpr(T, IntroducerRange,
-                              CaptureDefault, CaptureDefaultLoc, Captures,
-                              ExplicitParams, ExplicitResultType,
-                              CaptureInits, ArrayIndexVars, ArrayIndexStarts,
-                              ClosingBrace, ContainsUnexpandedParameterPack);
+  return new (Mem)
+      LambdaExpr(T, IntroducerRange, CaptureDefault, CaptureDefaultLoc,
+                 Captures, ExplicitParams, ExplicitResultType, CaptureInits,
+                 ClosingBrace, ContainsUnexpandedParameterPack);
 }
 
 LambdaExpr *LambdaExpr::CreateDeserialized(const ASTContext &C,
-                                           unsigned NumCaptures,
-                                           unsigned NumArrayIndexVars) {
-  unsigned Size = totalSizeToAlloc<Stmt *, unsigned, VarDecl *>(
-      NumCaptures + 1, NumArrayIndexVars ? NumCaptures + 1 : 0,
-      NumArrayIndexVars);
+                                           unsigned NumCaptures) {
+  unsigned Size = totalSizeToAlloc<Stmt *>(NumCaptures + 1);
   void *Mem = C.Allocate(Size);
-  return new (Mem) LambdaExpr(EmptyShell(), NumCaptures, NumArrayIndexVars > 0);
+  return new (Mem) LambdaExpr(EmptyShell(), NumCaptures);
 }
 
 bool LambdaExpr::isInitCapture(const LambdaCapture *C) const {
@@ -995,19 +975,6 @@
   return capture_range(implicit_capture_begin(), implicit_capture_end());
 }
 
-ArrayRef<VarDecl *>
-LambdaExpr::getCaptureInitIndexVars(const_capture_init_iterator Iter) const {
-  assert(HasArrayIndexVars && "No array index-var data?");
-  
-  unsigned Index = Iter - capture_init_begin();
-  assert(Index < getLambdaClass()->getLambdaData().NumCaptures &&
-         "Capture index out-of-range");
-  VarDecl *const *IndexVars = getArrayIndexVars();
-  const unsigned *IndexStarts = getArrayIndexStarts();
-  return llvm::makeArrayRef(IndexVars + IndexStarts[Index],
-                            IndexVars + IndexStarts[Index + 1]);
-}
-
 CXXRecordDecl *LambdaExpr::getLambdaClass() const {
   return getType()->getAsCXXRecordDecl();
 }
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index aa4651d..76c548f 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -129,6 +129,7 @@
   case Expr::UnresolvedLookupExprClass:
   case Expr::UnresolvedMemberExprClass:
   case Expr::TypoExprClass:
+  case Expr::DependentCoawaitExprClass:
   case Expr::CXXDependentScopeMemberExprClass:
   case Expr::DependentScopeDeclRefExprClass:
     // ObjC instance variables are lvalues
@@ -185,6 +186,8 @@
   case Expr::ObjCIndirectCopyRestoreExprClass:
   case Expr::AtomicExprClass:
   case Expr::CXXFoldExprClass:
+  case Expr::ArrayInitLoopExprClass:
+  case Expr::ArrayInitIndexExprClass:
   case Expr::NoInitExprClass:
   case Expr::DesignatedInitUpdateExprClass:
   case Expr::CoyieldExprClass:
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index fa5cb8c..a1b508f7 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -76,8 +76,8 @@
       const Expr *Inner = Temp->skipRValueSubobjectAdjustments(CommaLHSs,
                                                                Adjustments);
       // Keep any cv-qualifiers from the reference if we generated a temporary
-      // for it.
-      if (Inner != Temp)
+      // for it directly. Otherwise use the type after adjustment.
+      if (!Adjustments.empty())
         return Inner->getType();
     }
 
@@ -109,19 +109,57 @@
     return getAsBaseOrMember(E).getInt();
   }
 
+  /// Given a CallExpr, try to get the alloc_size attribute. May return null.
+  static const AllocSizeAttr *getAllocSizeAttr(const CallExpr *CE) {
+    const FunctionDecl *Callee = CE->getDirectCallee();
+    return Callee ? Callee->getAttr<AllocSizeAttr>() : nullptr;
+  }
+
+  /// Attempts to unwrap a CallExpr (with an alloc_size attribute) from an Expr.
+  /// This will look through a single cast.
+  ///
+  /// Returns null if we couldn't unwrap a function with alloc_size.
+  static const CallExpr *tryUnwrapAllocSizeCall(const Expr *E) {
+    if (!E->getType()->isPointerType())
+      return nullptr;
+
+    E = E->IgnoreParens();
+    // If we're doing a variable assignment from e.g. malloc(N), there will
+    // probably be a cast of some kind. Ignore it.
+    if (const auto *Cast = dyn_cast<CastExpr>(E))
+      E = Cast->getSubExpr()->IgnoreParens();
+
+    if (const auto *CE = dyn_cast<CallExpr>(E))
+      return getAllocSizeAttr(CE) ? CE : nullptr;
+    return nullptr;
+  }
+
+  /// Determines whether or not the given Base contains a call to a function
+  /// with the alloc_size attribute.
+  static bool isBaseAnAllocSizeCall(APValue::LValueBase Base) {
+    const auto *E = Base.dyn_cast<const Expr *>();
+    return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
+  }
+
+  /// Determines if an LValue with the given LValueBase will have an unsized
+  /// array in its designator.
   /// Find the path length and type of the most-derived subobject in the given
   /// path, and find the size of the containing array, if any.
-  static
-  unsigned findMostDerivedSubobject(ASTContext &Ctx, QualType Base,
-                                    ArrayRef<APValue::LValuePathEntry> Path,
-                                    uint64_t &ArraySize, QualType &Type,
-                                    bool &IsArray) {
+  static unsigned
+  findMostDerivedSubobject(ASTContext &Ctx, APValue::LValueBase Base,
+                           ArrayRef<APValue::LValuePathEntry> Path,
+                           uint64_t &ArraySize, QualType &Type, bool &IsArray) {
+    // This only accepts LValueBases from APValues, and APValues don't support
+    // arrays that lack size info.
+    assert(!isBaseAnAllocSizeCall(Base) &&
+           "Unsized arrays shouldn't appear here");
     unsigned MostDerivedLength = 0;
-    Type = Base;
+    Type = getType(Base);
+
     for (unsigned I = 0, N = Path.size(); I != N; ++I) {
       if (Type->isArrayType()) {
         const ConstantArrayType *CAT =
-          cast<ConstantArrayType>(Ctx.getAsArrayType(Type));
+            cast<ConstantArrayType>(Ctx.getAsArrayType(Type));
         Type = CAT->getElementType();
         ArraySize = CAT->getSize().getZExtValue();
         MostDerivedLength = I + 1;
@@ -162,17 +200,23 @@
     /// Is this a pointer one past the end of an object?
     unsigned IsOnePastTheEnd : 1;
 
+    /// Indicator of whether the first entry is an unsized array.
+    unsigned FirstEntryIsAnUnsizedArray : 1;
+
     /// Indicator of whether the most-derived object is an array element.
     unsigned MostDerivedIsArrayElement : 1;
 
     /// The length of the path to the most-derived object of which this is a
     /// subobject.
-    unsigned MostDerivedPathLength : 29;
+    unsigned MostDerivedPathLength : 28;
 
     /// The size of the array of which the most-derived object is an element.
     /// This will always be 0 if the most-derived object is not an array
     /// element. 0 is not an indicator of whether or not the most-derived object
     /// is an array, however, because 0-length arrays are allowed.
+    ///
+    /// If the current array is an unsized array, the value of this is
+    /// undefined.
     uint64_t MostDerivedArraySize;
 
     /// The type of the most derived object referred to by this address.
@@ -187,23 +231,24 @@
 
     explicit SubobjectDesignator(QualType T)
         : Invalid(false), IsOnePastTheEnd(false),
-          MostDerivedIsArrayElement(false), MostDerivedPathLength(0),
-          MostDerivedArraySize(0), MostDerivedType(T) {}
+          FirstEntryIsAnUnsizedArray(false), MostDerivedIsArrayElement(false),
+          MostDerivedPathLength(0), MostDerivedArraySize(0),
+          MostDerivedType(T) {}
 
     SubobjectDesignator(ASTContext &Ctx, const APValue &V)
         : Invalid(!V.isLValue() || !V.hasLValuePath()), IsOnePastTheEnd(false),
-          MostDerivedIsArrayElement(false), MostDerivedPathLength(0),
-          MostDerivedArraySize(0) {
+          FirstEntryIsAnUnsizedArray(false), MostDerivedIsArrayElement(false),
+          MostDerivedPathLength(0), MostDerivedArraySize(0) {
+      assert(V.isLValue() && "Non-LValue used to make an LValue designator?");
       if (!Invalid) {
         IsOnePastTheEnd = V.isLValueOnePastTheEnd();
         ArrayRef<PathEntry> VEntries = V.getLValuePath();
         Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
         if (V.getLValueBase()) {
           bool IsArray = false;
-          MostDerivedPathLength =
-              findMostDerivedSubobject(Ctx, getType(V.getLValueBase()),
-                                       V.getLValuePath(), MostDerivedArraySize,
-                                       MostDerivedType, IsArray);
+          MostDerivedPathLength = findMostDerivedSubobject(
+              Ctx, V.getLValueBase(), V.getLValuePath(), MostDerivedArraySize,
+              MostDerivedType, IsArray);
           MostDerivedIsArrayElement = IsArray;
         }
       }
@@ -214,12 +259,26 @@
       Entries.clear();
     }
 
+    /// Determine whether the most derived subobject is an array without a
+    /// known bound.
+    bool isMostDerivedAnUnsizedArray() const {
+      assert(!Invalid && "Calling this makes no sense on invalid designators");
+      return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
+    }
+
+    /// Determine what the most derived array's size is. Results in an assertion
+    /// failure if the most derived array lacks a size.
+    uint64_t getMostDerivedArraySize() const {
+      assert(!isMostDerivedAnUnsizedArray() && "Unsized array has no size");
+      return MostDerivedArraySize;
+    }
+
     /// Determine whether this is a one-past-the-end pointer.
     bool isOnePastTheEnd() const {
       assert(!Invalid);
       if (IsOnePastTheEnd)
         return true;
-      if (MostDerivedIsArrayElement &&
+      if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
           Entries[MostDerivedPathLength - 1].ArrayIndex == MostDerivedArraySize)
         return true;
       return false;
@@ -247,6 +306,21 @@
       MostDerivedArraySize = CAT->getSize().getZExtValue();
       MostDerivedPathLength = Entries.size();
     }
+    /// Update this designator to refer to the first element within the array of
+    /// elements of type T. This is an array of unknown size.
+    void addUnsizedArrayUnchecked(QualType ElemTy) {
+      PathEntry Entry;
+      Entry.ArrayIndex = 0;
+      Entries.push_back(Entry);
+
+      MostDerivedType = ElemTy;
+      MostDerivedIsArrayElement = true;
+      // The value in MostDerivedArraySize is undefined in this case. So, set it
+      // to an arbitrary value that's likely to loudly break things if it's
+      // used.
+      MostDerivedArraySize = std::numeric_limits<uint64_t>::max() / 2;
+      MostDerivedPathLength = Entries.size();
+    }
     /// Update this designator to refer to the given base or member of this
     /// object.
     void addDeclUnchecked(const Decl *D, bool Virtual = false) {
@@ -276,30 +350,48 @@
       MostDerivedArraySize = 2;
       MostDerivedPathLength = Entries.size();
     }
-    void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E, uint64_t N);
+    void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E, APSInt N);
     /// Add N to the address of this subobject.
-    void adjustIndex(EvalInfo &Info, const Expr *E, uint64_t N) {
-      if (Invalid) return;
-      if (MostDerivedPathLength == Entries.size() &&
-          MostDerivedIsArrayElement) {
-        Entries.back().ArrayIndex += N;
-        if (Entries.back().ArrayIndex > MostDerivedArraySize) {
-          diagnosePointerArithmetic(Info, E, Entries.back().ArrayIndex);
-          setInvalid();
-        }
+    void adjustIndex(EvalInfo &Info, const Expr *E, APSInt N) {
+      if (Invalid || !N) return;
+      uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
+      if (isMostDerivedAnUnsizedArray()) {
+        // Can't verify -- trust that the user is doing the right thing (or if
+        // not, trust that the caller will catch the bad behavior).
+        // FIXME: Should we reject if this overflows, at least?
+        Entries.back().ArrayIndex += TruncatedN;
         return;
       }
+
       // [expr.add]p4: For the purposes of these operators, a pointer to a
       // nonarray object behaves the same as a pointer to the first element of
       // an array of length one with the type of the object as its element type.
-      if (IsOnePastTheEnd && N == (uint64_t)-1)
-        IsOnePastTheEnd = false;
-      else if (!IsOnePastTheEnd && N == 1)
-        IsOnePastTheEnd = true;
-      else if (N != 0) {
-        diagnosePointerArithmetic(Info, E, uint64_t(IsOnePastTheEnd) + N);
+      bool IsArray = MostDerivedPathLength == Entries.size() &&
+                     MostDerivedIsArrayElement;
+      uint64_t ArrayIndex =
+          IsArray ? Entries.back().ArrayIndex : (uint64_t)IsOnePastTheEnd;
+      uint64_t ArraySize =
+          IsArray ? getMostDerivedArraySize() : (uint64_t)1;
+
+      if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
+        // Calculate the actual index in a wide enough type, so we can include
+        // it in the note.
+        N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
+        (llvm::APInt&)N += ArrayIndex;
+        assert(N.ugt(ArraySize) && "bounds check failed for in-bounds index");
+        diagnosePointerArithmetic(Info, E, N);
         setInvalid();
+        return;
       }
+
+      ArrayIndex += TruncatedN;
+      assert(ArrayIndex <= ArraySize &&
+             "bounds check succeeded for out-of-bounds index");
+
+      if (IsArray)
+        Entries.back().ArrayIndex = ArrayIndex;
+      else
+        IsOnePastTheEnd = (ArrayIndex != 0);
     }
   };
 
@@ -333,6 +425,17 @@
     /// Index - The call index of this call.
     unsigned Index;
 
+    // FIXME: Adding this to every 'CallStackFrame' may have a nontrivial impact
+    // on the overall stack usage of deeply-recursing constexpr evaluataions.
+    // (We should cache this map rather than recomputing it repeatedly.)
+    // But let's try this and see how it goes; we can look into caching the map
+    // as a later change.
+
+    /// LambdaCaptureFields - Mapping from captured variables/this to
+    /// corresponding data members in the closure class.
+    llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
+    FieldDecl *LambdaThisCaptureField;
+
     CallStackFrame(EvalInfo &Info, SourceLocation CallLoc,
                    const FunctionDecl *Callee, const LValue *This,
                    APValue *Arguments);
@@ -433,7 +536,7 @@
   /// rules.  For example, the RHS of (0 && foo()) is not evaluated.  We can
   /// evaluate the expression regardless of what the RHS is, but C only allows
   /// certain things in certain situations.
-  struct EvalInfo {
+  struct LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) EvalInfo {
     ASTContext &Ctx;
 
     /// EvalStatus - Contains information about the evaluation.
@@ -469,6 +572,10 @@
     /// declaration whose initializer is being evaluated, if any.
     APValue *EvaluatingDeclValue;
 
+    /// The current array initialization index, if we're performing array
+    /// initialization.
+    uint64_t ArrayInitIndex = -1;
+
     /// HasActiveDiagnostic - Was the previous diagnostic stored? If so, further
     /// notes attached to it will also be stored, otherwise they will not be.
     bool HasActiveDiagnostic;
@@ -520,9 +627,17 @@
       /// gets a chance to look at it.
       EM_PotentialConstantExpressionUnevaluated,
 
-      /// Evaluate as a constant expression. Continue evaluating if we find a
-      /// MemberExpr with a base that can't be evaluated.
-      EM_DesignatorFold,
+      /// Evaluate as a constant expression. In certain scenarios, if:
+      /// - we find a MemberExpr with a base that can't be evaluated, or
+      /// - we find a variable initialized with a call to a function that has
+      ///   the alloc_size attribute on it
+      /// then we may consider evaluation to have succeeded.
+      ///
+      /// In either case, the LValue returned shall have an invalid base; in the
+      /// former, the base will be the invalid MemberExpr, in the latter, the
+      /// base will be either the alloc_size CallExpr or a CastExpr wrapping
+      /// said CallExpr.
+      EM_OffsetFold,
     } EvalMode;
 
     /// Are we checking whether the expression is a potential constant
@@ -624,7 +739,7 @@
           case EM_PotentialConstantExpression:
           case EM_ConstantExpressionUnevaluated:
           case EM_PotentialConstantExpressionUnevaluated:
-          case EM_DesignatorFold:
+          case EM_OffsetFold:
             HasActiveDiagnostic = false;
             return OptionalDiagnostic();
           }
@@ -716,7 +831,7 @@
       case EM_ConstantExpression:
       case EM_ConstantExpressionUnevaluated:
       case EM_ConstantFold:
-      case EM_DesignatorFold:
+      case EM_OffsetFold:
         return false;
       }
       llvm_unreachable("Missed EvalMode case");
@@ -735,7 +850,7 @@
       case EM_EvaluateForOverflow:
       case EM_IgnoreSideEffects:
       case EM_ConstantFold:
-      case EM_DesignatorFold:
+      case EM_OffsetFold:
         return true;
 
       case EM_PotentialConstantExpression:
@@ -771,7 +886,7 @@
       case EM_ConstantExpressionUnevaluated:
       case EM_ConstantFold:
       case EM_IgnoreSideEffects:
-      case EM_DesignatorFold:
+      case EM_OffsetFold:
         return false;
       }
       llvm_unreachable("Missed EvalMode case");
@@ -800,9 +915,19 @@
       return KeepGoing;
     }
 
-    bool allowInvalidBaseExpr() const {
-      return EvalMode == EM_DesignatorFold;
-    }
+    class ArrayInitLoopIndex {
+      EvalInfo &Info;
+      uint64_t OuterIndex;
+
+    public:
+      ArrayInitLoopIndex(EvalInfo &Info)
+          : Info(Info), OuterIndex(Info.ArrayInitIndex) {
+        Info.ArrayInitIndex = 0;
+      }
+      ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
+
+      operator uint64_t&() { return Info.ArrayInitIndex; }
+    };
   };
 
   /// Object used to treat all foldable expressions as constant expressions.
@@ -838,11 +963,10 @@
   struct FoldOffsetRAII {
     EvalInfo &Info;
     EvalInfo::EvaluationMode OldMode;
-    explicit FoldOffsetRAII(EvalInfo &Info, bool Subobject)
+    explicit FoldOffsetRAII(EvalInfo &Info)
         : Info(Info), OldMode(Info.EvalMode) {
       if (!Info.checkingPotentialConstantExpression())
-        Info.EvalMode = Subobject ? EvalInfo::EM_DesignatorFold
-                                  : EvalInfo::EM_ConstantFold;
+        Info.EvalMode = EvalInfo::EM_OffsetFold;
     }
 
     ~FoldOffsetRAII() { Info.EvalMode = OldMode; }
@@ -947,14 +1071,16 @@
 }
 
 void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
-                                                    const Expr *E, uint64_t N) {
+                                                    const Expr *E, APSInt N) {
+  // If we're complaining, we must be able to statically determine the size of
+  // the most derived array.
   if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
     Info.CCEDiag(E, diag::note_constexpr_array_index)
-      << static_cast<int>(N) << /*array*/ 0
-      << static_cast<unsigned>(MostDerivedArraySize);
+      << N << /*array*/ 0
+      << static_cast<unsigned>(getMostDerivedArraySize());
   else
     Info.CCEDiag(E, diag::note_constexpr_array_index)
-      << static_cast<int>(N) << /*non-array*/ 1;
+      << N << /*non-array*/ 1;
   setInvalid();
 }
 
@@ -1032,7 +1158,7 @@
     APSInt IntReal, IntImag;
     APFloat FloatReal, FloatImag;
 
-    ComplexValue() : FloatReal(APFloat::Bogus), FloatImag(APFloat::Bogus) {}
+    ComplexValue() : FloatReal(APFloat::Bogus()), FloatImag(APFloat::Bogus()) {}
 
     void makeComplexFloat() { IsInt = false; }
     bool isComplexFloat() const { return !IsInt; }
@@ -1070,6 +1196,7 @@
     unsigned InvalidBase : 1;
     unsigned CallIndex : 31;
     SubobjectDesignator Designator;
+    bool IsNullPtr;
 
     const APValue::LValueBase getLValueBase() const { return Base; }
     CharUnits &getLValueOffset() { return Offset; }
@@ -1077,29 +1204,47 @@
     unsigned getLValueCallIndex() const { return CallIndex; }
     SubobjectDesignator &getLValueDesignator() { return Designator; }
     const SubobjectDesignator &getLValueDesignator() const { return Designator;}
+    bool isNullPointer() const { return IsNullPtr;}
 
     void moveInto(APValue &V) const {
       if (Designator.Invalid)
-        V = APValue(Base, Offset, APValue::NoLValuePath(), CallIndex);
-      else
+        V = APValue(Base, Offset, APValue::NoLValuePath(), CallIndex,
+                    IsNullPtr);
+      else {
+        assert(!InvalidBase && "APValues can't handle invalid LValue bases");
+        assert(!Designator.FirstEntryIsAnUnsizedArray &&
+               "Unsized array with a valid base?");
         V = APValue(Base, Offset, Designator.Entries,
-                    Designator.IsOnePastTheEnd, CallIndex);
+                    Designator.IsOnePastTheEnd, CallIndex, IsNullPtr);
+      }
     }
     void setFrom(ASTContext &Ctx, const APValue &V) {
-      assert(V.isLValue());
+      assert(V.isLValue() && "Setting LValue from a non-LValue?");
       Base = V.getLValueBase();
       Offset = V.getLValueOffset();
       InvalidBase = false;
       CallIndex = V.getLValueCallIndex();
       Designator = SubobjectDesignator(Ctx, V);
+      IsNullPtr = V.isNullPointer();
     }
 
-    void set(APValue::LValueBase B, unsigned I = 0, bool BInvalid = false) {
+    void set(APValue::LValueBase B, unsigned I = 0, bool BInvalid = false,
+             bool IsNullPtr_ = false, uint64_t Offset_ = 0) {
+#ifndef NDEBUG
+      // We only allow a few types of invalid bases. Enforce that here.
+      if (BInvalid) {
+        const auto *E = B.get<const Expr *>();
+        assert((isa<MemberExpr>(E) || tryUnwrapAllocSizeCall(E)) &&
+               "Unexpected type of invalid base");
+      }
+#endif
+
       Base = B;
-      Offset = CharUnits::Zero();
+      Offset = CharUnits::fromQuantity(Offset_);
       InvalidBase = BInvalid;
       CallIndex = I;
       Designator = SubobjectDesignator(getType(B));
+      IsNullPtr = IsNullPtr_;
     }
 
     void setInvalid(APValue::LValueBase B, unsigned I = 0) {
@@ -1112,7 +1257,7 @@
                           CheckSubobjectKind CSK) {
       if (Designator.Invalid)
         return false;
-      if (!Base) {
+      if (IsNullPtr) {
         Info.CCEDiag(E, diag::note_constexpr_null_subobject)
           << CSK;
         Designator.setInvalid();
@@ -1133,6 +1278,13 @@
       if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
         Designator.addDeclUnchecked(D, Virtual);
     }
+    void addUnsizedArray(EvalInfo &Info, QualType ElemTy) {
+      assert(Designator.Entries.empty() && getType(Base)->isPointerType());
+      assert(isBaseAnAllocSizeCall(Base) &&
+             "Only alloc_size bases can have unsized arrays");
+      Designator.FirstEntryIsAnUnsizedArray = true;
+      Designator.addUnsizedArrayUnchecked(ElemTy);
+    }
     void addArray(EvalInfo &Info, const Expr *E, const ConstantArrayType *CAT) {
       if (checkSubobject(Info, E, CSK_ArrayToPointer))
         Designator.addArrayUnchecked(CAT);
@@ -1141,9 +1293,32 @@
       if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
         Designator.addComplexUnchecked(EltTy, Imag);
     }
-    void adjustIndex(EvalInfo &Info, const Expr *E, uint64_t N) {
-      if (N && checkNullPointer(Info, E, CSK_ArrayIndex))
-        Designator.adjustIndex(Info, E, N);
+    void clearIsNullPointer() {
+      IsNullPtr = false;
+    }
+    void adjustOffsetAndIndex(EvalInfo &Info, const Expr *E, APSInt Index,
+                              CharUnits ElementSize) {
+      // An index of 0 has no effect. (In C, adding 0 to a null pointer is UB,
+      // but we're not required to diagnose it and it's valid in C++.)
+      if (!Index)
+        return;
+
+      // Compute the new offset in the appropriate width, wrapping at 64 bits.
+      // FIXME: When compiling for a 32-bit target, we should use 32-bit
+      // offsets.
+      uint64_t Offset64 = Offset.getQuantity();
+      uint64_t ElemSize64 = ElementSize.getQuantity();
+      uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
+      Offset = CharUnits::fromQuantity(Offset64 + ElemSize64 * Index64);
+
+      if (checkNullPointer(Info, E, CSK_ArrayIndex))
+        Designator.adjustIndex(Info, E, Index);
+      clearIsNullPointer();
+    }
+    void adjustOffset(CharUnits N) {
+      Offset += N;
+      if (N.getQuantity())
+        clearIsNullPointer();
     }
   };
 
@@ -1250,8 +1425,10 @@
 static bool EvaluateInPlace(APValue &Result, EvalInfo &Info,
                             const LValue &This, const Expr *E,
                             bool AllowNonLiteralTypes = false);
-static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info);
-static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info);
+static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info,
+                           bool InvalidBaseOK = false);
+static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info,
+                            bool InvalidBaseOK = false);
 static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result,
                                   EvalInfo &Info);
 static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info);
@@ -1260,13 +1437,24 @@
                                     EvalInfo &Info);
 static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
 static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info);
-static bool EvaluateAtomic(const Expr *E, APValue &Result, EvalInfo &Info);
+static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
+                           EvalInfo &Info);
 static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
 
 //===----------------------------------------------------------------------===//
 // Misc utilities
 //===----------------------------------------------------------------------===//
 
+/// Negate an APSInt in place, converting it to a signed form if necessary, and
+/// preserving its value (by extending by up to one bit as needed).
+static void negateAsSigned(APSInt &Int) {
+  if (Int.isUnsigned() || Int.isMinSignedValue()) {
+    Int = Int.extend(Int.getBitWidth() + 1);
+    Int.setIsSigned(true);
+  }
+  Int = -Int;
+}
+
 /// Produce a string describing the given constexpr call.
 static void describeCall(CallStackFrame *Frame, raw_ostream &Out) {
   unsigned ArgIndex = 0;
@@ -1314,13 +1502,6 @@
   return true;
 }
 
-/// Sign- or zero-extend a value to 64 bits. If it's already 64 bits, just
-/// return its existing value.
-static int64_t getExtValue(const APSInt &Value) {
-  return Value.isSigned() ? Value.getSExtValue()
-                          : static_cast<int64_t>(Value.getZExtValue());
-}
-
 /// Should this call expression be treated as a string literal?
 static bool IsStringLiteralCall(const CallExpr *E) {
   unsigned Builtin = E->getBuiltinCallee();
@@ -1483,8 +1664,17 @@
   // C++1y: A constant initializer for an object o [...] may also invoke
   // constexpr constructors for o and its subobjects even if those objects
   // are of non-literal class types.
-  if (Info.getLangOpts().CPlusPlus14 && This &&
-      Info.EvaluatingDecl == This->getLValueBase())
+  //
+  // C++11 missed this detail for aggregates, so classes like this:
+  //   struct foo_t { union { int i; volatile int j; } u; };
+  // are not (obviously) initializable like so:
+  //   __attribute__((__require_constant_initialization__))
+  //   static const foo_t x = {{0}};
+  // because "i" is a subobject with non-literal initialization (due to the
+  // volatile member of the union). See:
+  //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1677
+  // Therefore, we use the C++1y behavior.
+  if (This && Info.EvaluatingDecl == This->getLValueBase())
     return true;
 
   // Prvalue constant expressions must be of literal types.
@@ -2018,7 +2208,7 @@
   }
 
   unsigned I = FD->getFieldIndex();
-  LVal.Offset += Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I));
+  LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
   LVal.addDecl(Info, E, FD);
   return true;
 }
@@ -2067,17 +2257,22 @@
 /// \param Adjustment - The adjustment, in objects of type EltTy, to add.
 static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E,
                                         LValue &LVal, QualType EltTy,
-                                        int64_t Adjustment) {
+                                        APSInt Adjustment) {
   CharUnits SizeOfPointee;
   if (!HandleSizeof(Info, E->getExprLoc(), EltTy, SizeOfPointee))
     return false;
 
-  // Compute the new offset in the appropriate width.
-  LVal.Offset += Adjustment * SizeOfPointee;
-  LVal.adjustIndex(Info, E, Adjustment);
+  LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
   return true;
 }
 
+static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E,
+                                        LValue &LVal, QualType EltTy,
+                                        int64_t Adjustment) {
+  return HandleLValueArrayAdjustment(Info, E, LVal, EltTy,
+                                     APSInt::get(Adjustment));
+}
+
 /// Update an lvalue to refer to a component of a complex number.
 /// \param Info - Information about the ongoing evaluation.
 /// \param LVal - The lvalue to be updated.
@@ -2096,6 +2291,10 @@
   return true;
 }
 
+static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,
+                                           QualType Type, const LValue &LVal,
+                                           APValue &RVal);
+
 /// Try to evaluate the initializer for a variable declaration.
 ///
 /// \param Info   Information about the ongoing evaluation.
@@ -2107,6 +2306,7 @@
 static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
                                 const VarDecl *VD, CallStackFrame *Frame,
                                 APValue *&Result) {
+
   // If this is a parameter to an active constexpr function call, perform
   // argument substitution.
   if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) {
@@ -2211,7 +2411,14 @@
 /// Extract the value of a character from a string literal.
 static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit,
                                             uint64_t Index) {
-  // FIXME: Support ObjCEncodeExpr, MakeStringConstant
+  // FIXME: Support MakeStringConstant
+  if (const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
+    std::string Str;
+    Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
+    assert(Index <= Str.size() && "Index too large");
+    return APSInt::getUnsigned(Str.c_str()[Index]);
+  }
+
   if (auto PE = dyn_cast<PredefinedExpr>(Lit))
     Lit = PE->getFunctionName();
   const StringLiteral *S = cast<StringLiteral>(Lit);
@@ -2786,6 +2993,9 @@
         } else {
           Info.CCEDiag(E);
         }
+      } else if (BaseType.isConstQualified() && VD->hasDefinition(Info.Ctx)) {
+        Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr) << VD;
+        // Keep evaluating to see what we can do.
       } else {
         // FIXME: Allow folding of values of any literal type in all languages.
         if (Info.checkingPotentialConstantExpression() &&
@@ -3030,9 +3240,9 @@
       return false;
     }
 
-    int64_t Offset = getExtValue(RHS.getInt());
+    APSInt Offset = RHS.getInt();
     if (Opcode == BO_Sub)
-      Offset = -Offset;
+      negateAsSigned(Offset);
 
     LValue LVal;
     LVal.setFrom(Info.Ctx, Subobj);
@@ -3987,6 +4197,10 @@
       return false;
     This->moveInto(Result);
     return true;
+  } else if (MD && isLambdaCallOperator(MD)) {
+    // We're in a lambda; determine the lambda capture field maps.
+    MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields,
+                                      Frame.LambdaThisCaptureField);
   }
 
   StmtResult Ret = {Result, ResultSlot};
@@ -4398,6 +4612,12 @@
                              Call.getLValueBase().dyn_cast<const ValueDecl*>());
       if (!FD)
         return Error(Callee);
+      // Don't call function pointers which have been cast to some other type.
+      // Per DR (no number yet), the caller and callee can differ in noexcept.
+      if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
+        CalleeType->getPointeeType(), FD->getType())) {
+        return Error(E);
+      }
 
       // Overloaded operator calls to member functions are represented as normal
       // calls with '*this' as the first argument.
@@ -4413,11 +4633,42 @@
           return false;
         This = &ThisVal;
         Args = Args.slice(1);
+      } else if (MD && MD->isLambdaStaticInvoker()) {   
+        // Map the static invoker for the lambda back to the call operator.
+        // Conveniently, we don't have to slice out the 'this' argument (as is
+        // being done for the non-static case), since a static member function
+        // doesn't have an implicit argument passed in.
+        const CXXRecordDecl *ClosureClass = MD->getParent();
+        assert(
+            ClosureClass->captures_begin() == ClosureClass->captures_end() &&
+            "Number of captures must be zero for conversion to function-ptr");
+
+        const CXXMethodDecl *LambdaCallOp =
+            ClosureClass->getLambdaCallOperator();
+
+        // Set 'FD', the function that will be called below, to the call
+        // operator.  If the closure object represents a generic lambda, find
+        // the corresponding specialization of the call operator.
+
+        if (ClosureClass->isGenericLambda()) {
+          assert(MD->isFunctionTemplateSpecialization() &&
+                 "A generic lambda's static-invoker function must be a "
+                 "template specialization");
+          const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
+          FunctionTemplateDecl *CallOpTemplate =
+              LambdaCallOp->getDescribedFunctionTemplate();
+          void *InsertPos = nullptr;
+          FunctionDecl *CorrespondingCallOpSpecialization =
+              CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
+          assert(CorrespondingCallOpSpecialization &&
+                 "We must always have a function call operator specialization "
+                 "that corresponds to our static invoker specialization");
+          FD = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
+        } else
+          FD = LambdaCallOp;
       }
 
-      // Don't call function pointers which have been cast to some other type.
-      if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
-        return Error(E);
+      
     } else
       return Error(E);
 
@@ -4493,7 +4744,10 @@
 
     case CK_AtomicToNonAtomic: {
       APValue AtomicVal;
-      if (!EvaluateAtomic(E->getSubExpr(), AtomicVal, Info))
+      // This does not need to be done in place even for class/array types:
+      // atomic-to-non-atomic conversion implies copying the object
+      // representation.
+      if (!Evaluate(AtomicVal, Info, E->getSubExpr()))
         return false;
       return DerivedSuccess(AtomicVal, E);
     }
@@ -4605,6 +4859,7 @@
   : public ExprEvaluatorBase<Derived> {
 protected:
   LValue &Result;
+  bool InvalidBaseOK;
   typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
   typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
 
@@ -4613,9 +4868,14 @@
     return true;
   }
 
+  bool evaluatePointer(const Expr *E, LValue &Result) {
+    return EvaluatePointer(E, Result, this->Info, InvalidBaseOK);
+  }
+
 public:
-  LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result) :
-    ExprEvaluatorBaseTy(Info), Result(Result) {}
+  LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result, bool InvalidBaseOK)
+      : ExprEvaluatorBaseTy(Info), Result(Result),
+        InvalidBaseOK(InvalidBaseOK) {}
 
   bool Success(const APValue &V, const Expr *E) {
     Result.setFrom(this->Info.Ctx, V);
@@ -4627,7 +4887,7 @@
     QualType BaseTy;
     bool EvalOK;
     if (E->isArrow()) {
-      EvalOK = EvaluatePointer(E->getBase(), Result, this->Info);
+      EvalOK = evaluatePointer(E->getBase(), Result);
       BaseTy = E->getBase()->getType()->castAs<PointerType>()->getPointeeType();
     } else if (E->getBase()->isRValue()) {
       assert(E->getBase()->getType()->isRecordType());
@@ -4638,7 +4898,7 @@
       BaseTy = E->getBase()->getType();
     }
     if (!EvalOK) {
-      if (!this->Info.allowInvalidBaseExpr())
+      if (!InvalidBaseOK)
         return false;
       Result.setInvalid(E);
       return true;
@@ -4732,8 +4992,8 @@
 class LValueExprEvaluator
   : public LValueExprEvaluatorBase<LValueExprEvaluator> {
 public:
-  LValueExprEvaluator(EvalInfo &Info, LValue &Result) :
-    LValueExprEvaluatorBaseTy(Info, Result) {}
+  LValueExprEvaluator(EvalInfo &Info, LValue &Result, bool InvalidBaseOK) :
+    LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
 
   bool VisitVarDecl(const Expr *E, const VarDecl *VD);
   bool VisitUnaryPreIncDec(const UnaryOperator *UO);
@@ -4786,10 +5046,11 @@
 ///  * function designators in C, and
 ///  * "extern void" objects
 ///  * @selector() expressions in Objective-C
-static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info) {
+static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info,
+                           bool InvalidBaseOK) {
   assert(E->isGLValue() || E->getType()->isFunctionType() ||
          E->getType()->isVoidType() || isa<ObjCSelectorExpr>(E));
-  return LValueExprEvaluator(Info, Result).Visit(E);
+  return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
 }
 
 bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
@@ -4804,6 +5065,33 @@
 
 
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
+
+  // If we are within a lambda's call operator, check whether the 'VD' referred
+  // to within 'E' actually represents a lambda-capture that maps to a
+  // data-member/field within the closure object, and if so, evaluate to the
+  // field or what the field refers to.
+  if (Info.CurrentCall && isLambdaCallOperator(Info.CurrentCall->Callee)) {
+    if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
+      if (Info.checkingPotentialConstantExpression())
+        return false;
+      // Start with 'Result' referring to the complete closure object...
+      Result = *Info.CurrentCall->This;
+      // ... then update it to refer to the field of the closure object
+      // that represents the capture.
+      if (!HandleLValueMember(Info, E, Result, FD))
+        return false;
+      // And if the field is of reference type, update 'Result' to refer to what
+      // the field refers to.
+      if (FD->getType()->isReferenceType()) {
+        APValue RVal;
+        if (!handleLValueToRValueConversion(Info, E, FD->getType(), Result,
+                                            RVal))
+          return false;
+        Result.setFrom(Info.Ctx, RVal);
+      }
+      return true;
+    }
+  }
   CallStackFrame *Frame = nullptr;
   if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) {
     // Only if a local variable was declared in the function currently being
@@ -4950,19 +5238,18 @@
   if (E->getBase()->getType()->isVectorType())
     return Error(E);
 
-  if (!EvaluatePointer(E->getBase(), Result, Info))
+  if (!evaluatePointer(E->getBase(), Result))
     return false;
 
   APSInt Index;
   if (!EvaluateInteger(E->getIdx(), Index, Info))
     return false;
 
-  return HandleLValueArrayAdjustment(Info, E, Result, E->getType(),
-                                     getExtValue(Index));
+  return HandleLValueArrayAdjustment(Info, E, Result, E->getType(), Index);
 }
 
 bool LValueExprEvaluator::VisitUnaryDeref(const UnaryOperator *E) {
-  return EvaluatePointer(E->getSubExpr(), Result, Info);
+  return evaluatePointer(E->getSubExpr(), Result);
 }
 
 bool LValueExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
@@ -5041,26 +5328,139 @@
 // Pointer Evaluation
 //===----------------------------------------------------------------------===//
 
+/// \brief Attempts to compute the number of bytes available at the pointer
+/// returned by a function with the alloc_size attribute. Returns true if we
+/// were successful. Places an unsigned number into `Result`.
+///
+/// This expects the given CallExpr to be a call to a function with an
+/// alloc_size attribute.
+static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx,
+                                            const CallExpr *Call,
+                                            llvm::APInt &Result) {
+  const AllocSizeAttr *AllocSize = getAllocSizeAttr(Call);
+
+  // alloc_size args are 1-indexed, 0 means not present.
+  assert(AllocSize && AllocSize->getElemSizeParam() != 0);
+  unsigned SizeArgNo = AllocSize->getElemSizeParam() - 1;
+  unsigned BitsInSizeT = Ctx.getTypeSize(Ctx.getSizeType());
+  if (Call->getNumArgs() <= SizeArgNo)
+    return false;
+
+  auto EvaluateAsSizeT = [&](const Expr *E, APSInt &Into) {
+    if (!E->EvaluateAsInt(Into, Ctx, Expr::SE_AllowSideEffects))
+      return false;
+    if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
+      return false;
+    Into = Into.zextOrSelf(BitsInSizeT);
+    return true;
+  };
+
+  APSInt SizeOfElem;
+  if (!EvaluateAsSizeT(Call->getArg(SizeArgNo), SizeOfElem))
+    return false;
+
+  if (!AllocSize->getNumElemsParam()) {
+    Result = std::move(SizeOfElem);
+    return true;
+  }
+
+  APSInt NumberOfElems;
+  // Argument numbers start at 1
+  unsigned NumArgNo = AllocSize->getNumElemsParam() - 1;
+  if (!EvaluateAsSizeT(Call->getArg(NumArgNo), NumberOfElems))
+    return false;
+
+  bool Overflow;
+  llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
+  if (Overflow)
+    return false;
+
+  Result = std::move(BytesAvailable);
+  return true;
+}
+
+/// \brief Convenience function. LVal's base must be a call to an alloc_size
+/// function.
+static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx,
+                                            const LValue &LVal,
+                                            llvm::APInt &Result) {
+  assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
+         "Can't get the size of a non alloc_size function");
+  const auto *Base = LVal.getLValueBase().get<const Expr *>();
+  const CallExpr *CE = tryUnwrapAllocSizeCall(Base);
+  return getBytesReturnedByAllocSizeCall(Ctx, CE, Result);
+}
+
+/// \brief Attempts to evaluate the given LValueBase as the result of a call to
+/// a function with the alloc_size attribute. If it was possible to do so, this
+/// function will return true, make Result's Base point to said function call,
+/// and mark Result's Base as invalid.
+static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base,
+                                      LValue &Result) {
+  if (Base.isNull())
+    return false;
+
+  // Because we do no form of static analysis, we only support const variables.
+  //
+  // Additionally, we can't support parameters, nor can we support static
+  // variables (in the latter case, use-before-assign isn't UB; in the former,
+  // we have no clue what they'll be assigned to).
+  const auto *VD =
+      dyn_cast_or_null<VarDecl>(Base.dyn_cast<const ValueDecl *>());
+  if (!VD || !VD->isLocalVarDecl() || !VD->getType().isConstQualified())
+    return false;
+
+  const Expr *Init = VD->getAnyInitializer();
+  if (!Init)
+    return false;
+
+  const Expr *E = Init->IgnoreParens();
+  if (!tryUnwrapAllocSizeCall(E))
+    return false;
+
+  // Store E instead of E unwrapped so that the type of the LValue's base is
+  // what the user wanted.
+  Result.setInvalid(E);
+
+  QualType Pointee = E->getType()->castAs<PointerType>()->getPointeeType();
+  Result.addUnsizedArray(Info, Pointee);
+  return true;
+}
+
 namespace {
 class PointerExprEvaluator
   : public ExprEvaluatorBase<PointerExprEvaluator> {
   LValue &Result;
+  bool InvalidBaseOK;
 
   bool Success(const Expr *E) {
     Result.set(E);
     return true;
   }
+
+  bool evaluateLValue(const Expr *E, LValue &Result) {
+    return EvaluateLValue(E, Result, Info, InvalidBaseOK);
+  }
+
+  bool evaluatePointer(const Expr *E, LValue &Result) {
+    return EvaluatePointer(E, Result, Info, InvalidBaseOK);
+  }
+
+  bool visitNonBuiltinCallExpr(const CallExpr *E);
 public:
 
-  PointerExprEvaluator(EvalInfo &info, LValue &Result)
-    : ExprEvaluatorBaseTy(info), Result(Result) {}
+  PointerExprEvaluator(EvalInfo &info, LValue &Result, bool InvalidBaseOK)
+      : ExprEvaluatorBaseTy(info), Result(Result),
+        InvalidBaseOK(InvalidBaseOK) {}
 
   bool Success(const APValue &V, const Expr *E) {
     Result.setFrom(Info.Ctx, V);
     return true;
   }
   bool ZeroInitialization(const Expr *E) {
-    return Success((Expr*)nullptr);
+    auto Offset = Info.Ctx.getTargetNullPointerValue(E->getType());
+    Result.set((Expr*)nullptr, 0, false, true, Offset);
+    return true;
   }
 
   bool VisitBinaryOperator(const BinaryOperator *E);
@@ -5091,6 +5491,27 @@
       return false;
     }
     Result = *Info.CurrentCall->This;
+    // If we are inside a lambda's call operator, the 'this' expression refers
+    // to the enclosing '*this' object (either by value or reference) which is
+    // either copied into the closure object's field that represents the '*this'
+    // or refers to '*this'.
+    if (isLambdaCallOperator(Info.CurrentCall->Callee)) {
+      // Update 'Result' to refer to the data member/field of the closure object
+      // that represents the '*this' capture.
+      if (!HandleLValueMember(Info, E, Result,
+                             Info.CurrentCall->LambdaThisCaptureField)) 
+        return false;
+      // If we captured '*this' by reference, replace the field with its referent.
+      if (Info.CurrentCall->LambdaThisCaptureField->getType()
+              ->isPointerType()) {
+        APValue RVal;
+        if (!handleLValueToRValueConversion(Info, E, E->getType(), Result,
+                                            RVal))
+          return false;
+
+        Result.setFrom(Info.Ctx, RVal);
+      }
+    }
     return true;
   }
 
@@ -5098,9 +5519,10 @@
 };
 } // end anonymous namespace
 
-static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info) {
+static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info,
+                            bool InvalidBaseOK) {
   assert(E->isRValue() && E->getType()->hasPointerRepresentation());
-  return PointerExprEvaluator(Info, Result).Visit(E);
+  return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
 }
 
 bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
@@ -5113,7 +5535,7 @@
   if (IExp->getType()->isPointerType())
     std::swap(PExp, IExp);
 
-  bool EvalPtrOK = EvaluatePointer(PExp, Result, Info);
+  bool EvalPtrOK = evaluatePointer(PExp, Result);
   if (!EvalPtrOK && !Info.noteFailure())
     return false;
 
@@ -5121,17 +5543,15 @@
   if (!EvaluateInteger(IExp, Offset, Info) || !EvalPtrOK)
     return false;
 
-  int64_t AdditionalOffset = getExtValue(Offset);
   if (E->getOpcode() == BO_Sub)
-    AdditionalOffset = -AdditionalOffset;
+    negateAsSigned(Offset);
 
   QualType Pointee = PExp->getType()->castAs<PointerType>()->getPointeeType();
-  return HandleLValueArrayAdjustment(Info, E, Result, Pointee,
-                                     AdditionalOffset);
+  return HandleLValueArrayAdjustment(Info, E, Result, Pointee, Offset);
 }
 
 bool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
-  return EvaluateLValue(E->getSubExpr(), Result, Info);
+  return evaluateLValue(E->getSubExpr(), Result);
 }
 
 bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
@@ -5159,11 +5579,13 @@
       else
         CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
     }
+    if (E->getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
+      ZeroInitialization(E);
     return true;
 
   case CK_DerivedToBase:
   case CK_UncheckedDerivedToBase:
-    if (!EvaluatePointer(E->getSubExpr(), Result, Info))
+    if (!evaluatePointer(E->getSubExpr(), Result))
       return false;
     if (!Result.Base && Result.Offset.isZero())
       return true;
@@ -5200,6 +5622,7 @@
       Result.Offset = CharUnits::fromQuantity(N);
       Result.CallIndex = 0;
       Result.Designator.setInvalid();
+      Result.IsNullPtr = false;
       return true;
     } else {
       // Cast is of an lvalue, no need to change value.
@@ -5209,7 +5632,7 @@
   }
   case CK_ArrayToPointerDecay:
     if (SubExpr->isGLValue()) {
-      if (!EvaluateLValue(SubExpr, Result, Info))
+      if (!evaluateLValue(SubExpr, Result))
         return false;
     } else {
       Result.set(SubExpr, Info.CurrentCall->Index);
@@ -5226,7 +5649,21 @@
     return true;
 
   case CK_FunctionToPointerDecay:
-    return EvaluateLValue(SubExpr, Result, Info);
+    return evaluateLValue(SubExpr, Result);
+
+  case CK_LValueToRValue: {
+    LValue LVal;
+    if (!evaluateLValue(E->getSubExpr(), LVal))
+      return false;
+
+    APValue RVal;
+    // Note, we use the subexpression's type in order to retain cv-qualifiers.
+    if (!handleLValueToRValueConversion(Info, E, E->getSubExpr()->getType(),
+                                        LVal, RVal))
+      return InvalidBaseOK &&
+             evaluateLValueAsAllocSize(Info, LVal.Base, Result);
+    return Success(RVal, E);
+  }
   }
 
   return ExprEvaluatorBaseTy::VisitCastExpr(E);
@@ -5240,6 +5677,8 @@
     T = Ref->getPointeeType();
 
   // __alignof is defined to return the preferred alignment.
+  if (T.getQualifiers().hasUnaligned())
+    return CharUnits::One();
   return Info.Ctx.toCharUnitsFromBits(
     Info.Ctx.getPreferredTypeAlign(T.getTypePtr()));
 }
@@ -5264,6 +5703,20 @@
   return GetAlignOfType(Info, E->getType());
 }
 
+// To be clear: this happily visits unsupported builtins. Better name welcomed.
+bool PointerExprEvaluator::visitNonBuiltinCallExpr(const CallExpr *E) {
+  if (ExprEvaluatorBaseTy::VisitCallExpr(E))
+    return true;
+
+  if (!(InvalidBaseOK && getAllocSizeAttr(E)))
+    return false;
+
+  Result.setInvalid(E);
+  QualType PointeeTy = E->getType()->castAs<PointerType>()->getPointeeType();
+  Result.addUnsizedArray(Info, PointeeTy);
+  return true;
+}
+
 bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) {
   if (IsStringLiteralCall(E))
     return Success(E);
@@ -5271,33 +5724,33 @@
   if (unsigned BuiltinOp = E->getBuiltinCallee())
     return VisitBuiltinCallExpr(E, BuiltinOp);
 
-  return ExprEvaluatorBaseTy::VisitCallExpr(E);
+  return visitNonBuiltinCallExpr(E);
 }
 
 bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
                                                 unsigned BuiltinOp) {
   switch (BuiltinOp) {
   case Builtin::BI__builtin_addressof:
-    return EvaluateLValue(E->getArg(0), Result, Info);
+    return evaluateLValue(E->getArg(0), Result);
   case Builtin::BI__builtin_assume_aligned: {
     // We need to be very careful here because: if the pointer does not have the
     // asserted alignment, then the behavior is undefined, and undefined
     // behavior is non-constant.
-    if (!EvaluatePointer(E->getArg(0), Result, Info))
+    if (!evaluatePointer(E->getArg(0), Result))
       return false;
 
     LValue OffsetResult(Result);
     APSInt Alignment;
     if (!EvaluateInteger(E->getArg(1), Alignment, Info))
       return false;
-    CharUnits Align = CharUnits::fromQuantity(getExtValue(Alignment));
+    CharUnits Align = CharUnits::fromQuantity(Alignment.getZExtValue());
 
     if (E->getNumArgs() > 2) {
       APSInt Offset;
       if (!EvaluateInteger(E->getArg(2), Offset, Info))
         return false;
 
-      int64_t AdditionalOffset = -getExtValue(Offset);
+      int64_t AdditionalOffset = -Offset.getZExtValue();
       OffsetResult.Offset += CharUnits::fromQuantity(AdditionalOffset);
     }
 
@@ -5314,12 +5767,11 @@
 
       if (BaseAlignment < Align) {
         Result.Designator.setInvalid();
-        // FIXME: Quantities here cast to integers because the plural modifier
-        // does not work on APSInts yet.
+        // FIXME: Add support to Diagnostic for long / long long.
         CCEDiag(E->getArg(0),
                 diag::note_constexpr_baa_insufficient_alignment) << 0
-          << (int) BaseAlignment.getQuantity()
-          << (unsigned) getExtValue(Alignment);
+          << (unsigned)BaseAlignment.getQuantity()
+          << (unsigned)Align.getQuantity();
         return false;
       }
     }
@@ -5327,18 +5779,14 @@
     // The offset must also have the correct alignment.
     if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
       Result.Designator.setInvalid();
-      APSInt Offset(64, false);
-      Offset = OffsetResult.Offset.getQuantity();
 
-      if (OffsetResult.Base)
-        CCEDiag(E->getArg(0),
-                diag::note_constexpr_baa_insufficient_alignment) << 1
-          << (int) getExtValue(Offset) << (unsigned) getExtValue(Alignment);
-      else
-        CCEDiag(E->getArg(0),
-                diag::note_constexpr_baa_value_insufficient_alignment)
-          << Offset << (unsigned) getExtValue(Alignment);
-
+      (OffsetResult.Base
+           ? CCEDiag(E->getArg(0),
+                     diag::note_constexpr_baa_insufficient_alignment) << 1
+           : CCEDiag(E->getArg(0),
+                     diag::note_constexpr_baa_value_insufficient_alignment))
+        << (int)OffsetResult.Offset.getQuantity()
+        << (unsigned)Align.getQuantity();
       return false;
     }
 
@@ -5359,6 +5807,7 @@
   case Builtin::BI__builtin_strchr:
   case Builtin::BI__builtin_wcschr:
   case Builtin::BI__builtin_memchr:
+  case Builtin::BI__builtin_char_memchr:
   case Builtin::BI__builtin_wmemchr: {
     if (!Visit(E->getArg(0)))
       return false;
@@ -5396,6 +5845,7 @@
       // Fall through.
     case Builtin::BImemchr:
     case Builtin::BI__builtin_memchr:
+    case Builtin::BI__builtin_char_memchr:
       // memchr compares by converting both sides to unsigned char. That's also
       // correct for strchr if we get this far (to cope with plain char being
       // unsigned in the strchr case).
@@ -5430,7 +5880,7 @@
   }
 
   default:
-    return ExprEvaluatorBaseTy::VisitCallExpr(E);
+    return visitNonBuiltinCallExpr(E);
   }
 }
 
@@ -5553,6 +6003,7 @@
     bool VisitCXXConstructExpr(const CXXConstructExpr *E) {
       return VisitCXXConstructExpr(E, E->getType());
     }
+    bool VisitLambdaExpr(const LambdaExpr *E);
     bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);
     bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T);
     bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E);
@@ -5887,6 +6338,47 @@
   return true;
 }
 
+bool RecordExprEvaluator::VisitLambdaExpr(const LambdaExpr *E) {
+  const CXXRecordDecl *ClosureClass = E->getLambdaClass();
+  if (ClosureClass->isInvalidDecl()) return false;
+
+  if (Info.checkingPotentialConstantExpression()) return true;
+  
+  const size_t NumFields =
+      std::distance(ClosureClass->field_begin(), ClosureClass->field_end());
+
+  assert(NumFields == (size_t)std::distance(E->capture_init_begin(),
+                                            E->capture_init_end()) &&
+         "The number of lambda capture initializers should equal the number of "
+         "fields within the closure type");
+
+  Result = APValue(APValue::UninitStruct(), /*NumBases*/0, NumFields);
+  // Iterate through all the lambda's closure object's fields and initialize
+  // them.
+  auto *CaptureInitIt = E->capture_init_begin();
+  const LambdaCapture *CaptureIt = ClosureClass->captures_begin();
+  bool Success = true;
+  for (const auto *Field : ClosureClass->fields()) {
+    assert(CaptureInitIt != E->capture_init_end());
+    // Get the initializer for this field
+    Expr *const CurFieldInit = *CaptureInitIt++;
+    
+    // If there is no initializer, either this is a VLA or an error has
+    // occurred.
+    if (!CurFieldInit)
+      return Error(E);
+
+    APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
+    if (!EvaluateInPlace(FieldVal, Info, This, CurFieldInit)) {
+      if (!Info.keepEvaluatingAfterFailure())
+        return false;
+      Success = false;
+    }
+    ++CaptureIt;
+  }
+  return Success;
+}
+
 static bool EvaluateRecord(const Expr *E, const LValue &This,
                            APValue &Result, EvalInfo &Info) {
   assert(E->isRValue() && E->getType()->isRecordType() &&
@@ -5906,7 +6398,7 @@
   : public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
 public:
   TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
-    LValueExprEvaluatorBaseTy(Info, Result) {}
+    LValueExprEvaluatorBaseTy(Info, Result, false) {}
 
   /// Visit an expression which constructs the value of this temporary.
   bool VisitConstructExpr(const Expr *E) {
@@ -5936,6 +6428,9 @@
   bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E) {
     return VisitConstructExpr(E);
   }
+  bool VisitLambdaExpr(const LambdaExpr *E) {
+    return VisitConstructExpr(E);
+  }
 };
 } // end anonymous namespace
 
@@ -6028,7 +6523,7 @@
     if (EltTy->isRealFloatingType()) {
       const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
       unsigned FloatEltSize = EltSize;
-      if (&Sem == &APFloat::x87DoubleExtended)
+      if (&Sem == &APFloat::x87DoubleExtended())
         FloatEltSize = 80;
       for (unsigned i = 0; i < NElts; i++) {
         llvm::APInt Elt;
@@ -6168,6 +6663,7 @@
       return handleCallExpr(E, Result, &This);
     }
     bool VisitInitListExpr(const InitListExpr *E);
+    bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E);
     bool VisitCXXConstructExpr(const CXXConstructExpr *E);
     bool VisitCXXConstructExpr(const CXXConstructExpr *E,
                                const LValue &Subobject,
@@ -6250,6 +6746,35 @@
                          FillerExpr) && Success;
 }
 
+bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
+  if (E->getCommonExpr() &&
+      !Evaluate(Info.CurrentCall->createTemporary(E->getCommonExpr(), false),
+                Info, E->getCommonExpr()->getSourceExpr()))
+    return false;
+
+  auto *CAT = cast<ConstantArrayType>(E->getType()->castAsArrayTypeUnsafe());
+
+  uint64_t Elements = CAT->getSize().getZExtValue();
+  Result = APValue(APValue::UninitArray(), Elements, Elements);
+
+  LValue Subobject = This;
+  Subobject.addArray(Info, E, CAT);
+
+  bool Success = true;
+  for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
+    if (!EvaluateInPlace(Result.getArrayInitializedElt(Index),
+                         Info, Subobject, E->getSubExpr()) ||
+        !HandleLValueArrayAdjustment(Info, E, Subobject,
+                                     CAT->getElementType(), 1)) {
+      if (!Info.noteFailure())
+        return false;
+      Success = false;
+    }
+  }
+
+  return Success;
+}
+
 bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
   return VisitCXXConstructExpr(E, This, &Result, E->getType());
 }
@@ -6405,6 +6930,16 @@
   bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
     return Success(E->getValue(), E);
   }
+
+  bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) {
+    if (Info.ArrayInitIndex == uint64_t(-1)) {
+      // We were asked to evaluate this subexpression independent of the
+      // enclosing ArrayInitLoopExpr. We can't do that.
+      Info.FFDiag(E);
+      return false;
+    }
+    return Success(Info.ArrayInitIndex, E);
+  }
     
   // Note, GNU defines __null as an integer, not a pointer.
   bool VisitGNUNullExpr(const GNUNullExpr *E) {
@@ -6429,8 +6964,6 @@
   bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E);
   bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
 
-private:
-  bool TryEvaluateBuiltinObjectSize(const CallExpr *E, unsigned Type);
   // FIXME: Missing: array subscript of vector, member of vector
 };
 } // end anonymous namespace
@@ -6562,7 +7095,6 @@
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
-    case BuiltinType::OCLNDRange:
     case BuiltinType::OCLReserveID:
     case BuiltinType::Dependent:
       llvm_unreachable("CallExpr::isBuiltinClassifyType(): unimplemented type");
@@ -6621,6 +7153,7 @@
   case Type::Vector:
   case Type::ExtVector:
   case Type::Auto:
+  case Type::DeducedTemplateSpecialization:
   case Type::ObjCObject:
   case Type::ObjCInterface:
   case Type::ObjCObjectPointer:
@@ -6702,7 +7235,7 @@
 }
 
 /// A more selective version of E->IgnoreParenCasts for
-/// TryEvaluateBuiltinObjectSize. This ignores some casts/parens that serve only
+/// tryEvaluateBuiltinObjectSize. This ignores some casts/parens that serve only
 /// to change the type of E.
 /// Ex. For E = `(short*)((char*)(&foo))`, returns `&foo`
 ///
@@ -6769,165 +7302,138 @@
     }
   }
 
+  unsigned I = 0;
   QualType BaseType = getType(Base);
-  for (int I = 0, E = LVal.Designator.Entries.size(); I != E; ++I) {
+  if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
+    assert(isBaseAnAllocSizeCall(Base) &&
+           "Unsized array in non-alloc_size call?");
+    // If this is an alloc_size base, we should ignore the initial array index
+    ++I;
+    BaseType = BaseType->castAs<PointerType>()->getPointeeType();
+  }
+
+  for (unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
+    const auto &Entry = LVal.Designator.Entries[I];
     if (BaseType->isArrayType()) {
       // Because __builtin_object_size treats arrays as objects, we can ignore
       // the index iff this is the last array in the Designator.
       if (I + 1 == E)
         return true;
-      auto *CAT = cast<ConstantArrayType>(Ctx.getAsArrayType(BaseType));
-      uint64_t Index = LVal.Designator.Entries[I].ArrayIndex;
+      const auto *CAT = cast<ConstantArrayType>(Ctx.getAsArrayType(BaseType));
+      uint64_t Index = Entry.ArrayIndex;
       if (Index + 1 != CAT->getSize())
         return false;
       BaseType = CAT->getElementType();
     } else if (BaseType->isAnyComplexType()) {
-      auto *CT = BaseType->castAs<ComplexType>();
-      uint64_t Index = LVal.Designator.Entries[I].ArrayIndex;
+      const auto *CT = BaseType->castAs<ComplexType>();
+      uint64_t Index = Entry.ArrayIndex;
       if (Index != 1)
         return false;
       BaseType = CT->getElementType();
-    } else if (auto *FD = getAsField(LVal.Designator.Entries[I])) {
+    } else if (auto *FD = getAsField(Entry)) {
       bool Invalid;
       if (!IsLastOrInvalidFieldDecl(FD, Invalid))
         return Invalid;
       BaseType = FD->getType();
     } else {
-      assert(getAsBaseClass(LVal.Designator.Entries[I]) != nullptr &&
-             "Expecting cast to a base class");
+      assert(getAsBaseClass(Entry) && "Expecting cast to a base class");
       return false;
     }
   }
   return true;
 }
 
-/// Tests to see if the LValue has a designator (that isn't necessarily valid).
+/// Tests to see if the LValue has a user-specified designator (that isn't
+/// necessarily valid). Note that this always returns 'true' if the LValue has
+/// an unsized array as its first designator entry, because there's currently no
+/// way to tell if the user typed *foo or foo[0].
 static bool refersToCompleteObject(const LValue &LVal) {
-  if (LVal.Designator.Invalid || !LVal.Designator.Entries.empty())
+  if (LVal.Designator.Invalid)
     return false;
 
+  if (!LVal.Designator.Entries.empty())
+    return LVal.Designator.isMostDerivedAnUnsizedArray();
+
   if (!LVal.InvalidBase)
     return true;
 
-  auto *E = LVal.Base.dyn_cast<const Expr *>();
-  (void)E;
-  assert(E != nullptr && isa<MemberExpr>(E));
-  return false;
+  // If `E` is a MemberExpr, then the first part of the designator is hiding in
+  // the LValueBase.
+  const auto *E = LVal.Base.dyn_cast<const Expr *>();
+  return !E || !isa<MemberExpr>(E);
 }
 
-/// Tries to evaluate the __builtin_object_size for @p E. If successful, returns
-/// true and stores the result in @p Size.
+/// Attempts to detect a user writing into a piece of memory that's impossible
+/// to figure out the size of by just using types.
+static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal) {
+  const SubobjectDesignator &Designator = LVal.Designator;
+  // Notes:
+  // - Users can only write off of the end when we have an invalid base. Invalid
+  //   bases imply we don't know where the memory came from.
+  // - We used to be a bit more aggressive here; we'd only be conservative if
+  //   the array at the end was flexible, or if it had 0 or 1 elements. This
+  //   broke some common standard library extensions (PR30346), but was
+  //   otherwise seemingly fine. It may be useful to reintroduce this behavior
+  //   with some sort of whitelist. OTOH, it seems that GCC is always
+  //   conservative with the last element in structs (if it's an array), so our
+  //   current behavior is more compatible than a whitelisting approach would
+  //   be.
+  return LVal.InvalidBase &&
+         Designator.Entries.size() == Designator.MostDerivedPathLength &&
+         Designator.MostDerivedIsArrayElement &&
+         isDesignatorAtObjectEnd(Ctx, LVal);
+}
+
+/// Converts the given APInt to CharUnits, assuming the APInt is unsigned.
+/// Fails if the conversion would cause loss of precision.
+static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int,
+                                            CharUnits &Result) {
+  auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
+  if (Int.ugt(CharUnitsMax))
+    return false;
+  Result = CharUnits::fromQuantity(Int.getZExtValue());
+  return true;
+}
+
+/// Helper for tryEvaluateBuiltinObjectSize -- Given an LValue, this will
+/// determine how many bytes exist from the beginning of the object to either
+/// the end of the current subobject, or the end of the object itself, depending
+/// on what the LValue looks like + the value of Type.
 ///
-/// If @p WasError is non-null, this will report whether the failure to evaluate
-/// is to be treated as an Error in IntExprEvaluator.
-static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
-                                         EvalInfo &Info, uint64_t &Size,
-                                         bool *WasError = nullptr) {
-  if (WasError != nullptr)
-    *WasError = false;
+/// If this returns false, the value of Result is undefined.
+static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc,
+                               unsigned Type, const LValue &LVal,
+                               CharUnits &EndOffset) {
+  bool DetermineForCompleteObject = refersToCompleteObject(LVal);
 
-  auto Error = [&](const Expr *E) {
-    if (WasError != nullptr)
-      *WasError = true;
-    return false;
-  };
-
-  auto Success = [&](uint64_t S, const Expr *E) {
-    Size = S;
-    return true;
-  };
-
-  // Determine the denoted object.
-  LValue Base;
-  {
-    // The operand of __builtin_object_size is never evaluated for side-effects.
-    // If there are any, but we can determine the pointed-to object anyway, then
-    // ignore the side-effects.
-    SpeculativeEvaluationRAII SpeculativeEval(Info);
-    FoldOffsetRAII Fold(Info, Type & 1);
-
-    if (E->isGLValue()) {
-      // It's possible for us to be given GLValues if we're called via
-      // Expr::tryEvaluateObjectSize.
-      APValue RVal;
-      if (!EvaluateAsRValue(Info, E, RVal))
-        return false;
-      Base.setFrom(Info.Ctx, RVal);
-    } else if (!EvaluatePointer(ignorePointerCastsAndParens(E), Base, Info))
+  auto CheckedHandleSizeof = [&](QualType Ty, CharUnits &Result) {
+    if (Ty.isNull() || Ty->isIncompleteType() || Ty->isFunctionType())
       return false;
+    return HandleSizeof(Info, ExprLoc, Ty, Result);
+  };
+
+  // We want to evaluate the size of the entire object. This is a valid fallback
+  // for when Type=1 and the designator is invalid, because we're asked for an
+  // upper-bound.
+  if (!(Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
+    // Type=3 wants a lower bound, so we can't fall back to this.
+    if (Type == 3 && !DetermineForCompleteObject)
+      return false;
+
+    llvm::APInt APEndOffset;
+    if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
+        getBytesReturnedByAllocSizeCall(Info.Ctx, LVal, APEndOffset))
+      return convertUnsignedAPIntToCharUnits(APEndOffset, EndOffset);
+
+    if (LVal.InvalidBase)
+      return false;
+
+    QualType BaseTy = getObjectType(LVal.getLValueBase());
+    return CheckedHandleSizeof(BaseTy, EndOffset);
   }
 
-  CharUnits BaseOffset = Base.getLValueOffset();
-  // If we point to before the start of the object, there are no accessible
-  // bytes.
-  if (BaseOffset.isNegative())
-    return Success(0, E);
-
-  // In the case where we're not dealing with a subobject, we discard the
-  // subobject bit.
-  bool SubobjectOnly = (Type & 1) != 0 && !refersToCompleteObject(Base);
-
-  // If Type & 1 is 0, we need to be able to statically guarantee that the bytes
-  // exist. If we can't verify the base, then we can't do that.
-  //
-  // As a special case, we produce a valid object size for an unknown object
-  // with a known designator if Type & 1 is 1. For instance:
-  //
-  //   extern struct X { char buff[32]; int a, b, c; } *p;
-  //   int a = __builtin_object_size(p->buff + 4, 3); // returns 28
-  //   int b = __builtin_object_size(p->buff + 4, 2); // returns 0, not 40
-  //
-  // This matches GCC's behavior.
-  if (Base.InvalidBase && !SubobjectOnly)
-    return Error(E);
-
-  // If we're not examining only the subobject, then we reset to a complete
-  // object designator
-  //
-  // If Type is 1 and we've lost track of the subobject, just find the complete
-  // object instead. (If Type is 3, that's not correct behavior and we should
-  // return 0 instead.)
-  LValue End = Base;
-  if (!SubobjectOnly || (End.Designator.Invalid && Type == 1)) {
-    QualType T = getObjectType(End.getLValueBase());
-    if (T.isNull())
-      End.Designator.setInvalid();
-    else {
-      End.Designator = SubobjectDesignator(T);
-      End.Offset = CharUnits::Zero();
-    }
-  }
-
-  // If it is not possible to determine which objects ptr points to at compile
-  // time, __builtin_object_size should return (size_t) -1 for type 0 or 1
-  // and (size_t) 0 for type 2 or 3.
-  if (End.Designator.Invalid)
-    return false;
-
-  // According to the GCC documentation, we want the size of the subobject
-  // denoted by the pointer. But that's not quite right -- what we actually
-  // want is the size of the immediately-enclosing array, if there is one.
-  int64_t AmountToAdd = 1;
-  if (End.Designator.MostDerivedIsArrayElement &&
-      End.Designator.Entries.size() == End.Designator.MostDerivedPathLength) {
-    // We got a pointer to an array. Step to its end.
-    AmountToAdd = End.Designator.MostDerivedArraySize -
-                  End.Designator.Entries.back().ArrayIndex;
-  } else if (End.Designator.isOnePastTheEnd()) {
-    // We're already pointing at the end of the object.
-    AmountToAdd = 0;
-  }
-
-  QualType PointeeType = End.Designator.MostDerivedType;
-  assert(!PointeeType.isNull());
-  if (PointeeType->isIncompleteType() || PointeeType->isFunctionType())
-    return Error(E);
-
-  if (!HandleLValueArrayAdjustment(Info, E, End, End.Designator.MostDerivedType,
-                                   AmountToAdd))
-    return false;
-
-  auto EndOffset = End.getLValueOffset();
+  // We want to evaluate the size of a subobject.
+  const SubobjectDesignator &Designator = LVal.Designator;
 
   // The following is a moderately common idiom in C:
   //
@@ -6935,39 +7441,89 @@
   // struct Foo *F = (struct Foo *)malloc(sizeof(struct Foo) + strlen(Bar));
   // strcpy(&F->c[0], Bar);
   //
-  // So, if we see that we're examining an array at the end of a struct with an
-  // unknown base, we give up instead of breaking code that behaves this way.
-  // Note that we only do this when Type=1, because Type=3 is a lower bound, so
-  // answering conservatively is fine.
-  //
-  // We used to be a bit more aggressive here; we'd only be conservative if the
-  // array at the end was flexible, or if it had 0 or 1 elements. This broke
-  // some common standard library extensions (PR30346), but was otherwise
-  // seemingly fine. It may be useful to reintroduce this behavior with some
-  // sort of whitelist. OTOH, it seems that GCC is always conservative with the
-  // last element in structs (if it's an array), so our current behavior is more
-  // compatible than a whitelisting approach would be.
-  if (End.InvalidBase && SubobjectOnly && Type == 1 &&
-      End.Designator.Entries.size() == End.Designator.MostDerivedPathLength &&
-      End.Designator.MostDerivedIsArrayElement &&
-      isDesignatorAtObjectEnd(Info.Ctx, End))
+  // In order to not break too much legacy code, we need to support it.
+  if (isUserWritingOffTheEnd(Info.Ctx, LVal)) {
+    // If we can resolve this to an alloc_size call, we can hand that back,
+    // because we know for certain how many bytes there are to write to.
+    llvm::APInt APEndOffset;
+    if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
+        getBytesReturnedByAllocSizeCall(Info.Ctx, LVal, APEndOffset))
+      return convertUnsignedAPIntToCharUnits(APEndOffset, EndOffset);
+
+    // If we cannot determine the size of the initial allocation, then we can't
+    // given an accurate upper-bound. However, we are still able to give
+    // conservative lower-bounds for Type=3.
+    if (Type == 1)
+      return false;
+  }
+
+  CharUnits BytesPerElem;
+  if (!CheckedHandleSizeof(Designator.MostDerivedType, BytesPerElem))
     return false;
 
-  if (BaseOffset > EndOffset)
-    return Success(0, E);
+  // According to the GCC documentation, we want the size of the subobject
+  // denoted by the pointer. But that's not quite right -- what we actually
+  // want is the size of the immediately-enclosing array, if there is one.
+  int64_t ElemsRemaining;
+  if (Designator.MostDerivedIsArrayElement &&
+      Designator.Entries.size() == Designator.MostDerivedPathLength) {
+    uint64_t ArraySize = Designator.getMostDerivedArraySize();
+    uint64_t ArrayIndex = Designator.Entries.back().ArrayIndex;
+    ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
+  } else {
+    ElemsRemaining = Designator.isOnePastTheEnd() ? 0 : 1;
+  }
 
-  return Success((EndOffset - BaseOffset).getQuantity(), E);
+  EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
+  return true;
 }
 
-bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(const CallExpr *E,
-                                                    unsigned Type) {
-  uint64_t Size;
-  bool WasError;
-  if (::tryEvaluateBuiltinObjectSize(E->getArg(0), Type, Info, Size, &WasError))
-    return Success(Size, E);
-  if (WasError)
-    return Error(E);
-  return false;
+/// \brief Tries to evaluate the __builtin_object_size for @p E. If successful,
+/// returns true and stores the result in @p Size.
+///
+/// If @p WasError is non-null, this will report whether the failure to evaluate
+/// is to be treated as an Error in IntExprEvaluator.
+static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
+                                         EvalInfo &Info, uint64_t &Size) {
+  // Determine the denoted object.
+  LValue LVal;
+  {
+    // The operand of __builtin_object_size is never evaluated for side-effects.
+    // If there are any, but we can determine the pointed-to object anyway, then
+    // ignore the side-effects.
+    SpeculativeEvaluationRAII SpeculativeEval(Info);
+    FoldOffsetRAII Fold(Info);
+
+    if (E->isGLValue()) {
+      // It's possible for us to be given GLValues if we're called via
+      // Expr::tryEvaluateObjectSize.
+      APValue RVal;
+      if (!EvaluateAsRValue(Info, E, RVal))
+        return false;
+      LVal.setFrom(Info.Ctx, RVal);
+    } else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info,
+                                /*InvalidBaseOK=*/true))
+      return false;
+  }
+
+  // If we point to before the start of the object, there are no accessible
+  // bytes.
+  if (LVal.getLValueOffset().isNegative()) {
+    Size = 0;
+    return true;
+  }
+
+  CharUnits EndOffset;
+  if (!determineEndOffset(Info, E->getExprLoc(), Type, LVal, EndOffset))
+    return false;
+
+  // If we've fallen outside of the end offset, just pretend there's nothing to
+  // write to/read from.
+  if (EndOffset <= LVal.getLValueOffset())
+    Size = 0;
+  else
+    Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
+  return true;
 }
 
 bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
@@ -6989,8 +7545,9 @@
         E->getArg(1)->EvaluateKnownConstInt(Info.Ctx).getZExtValue();
     assert(Type <= 3 && "unexpected type");
 
-    if (TryEvaluateBuiltinObjectSize(E, Type))
-      return true;
+    uint64_t Size;
+    if (tryEvaluateBuiltinObjectSize(E->getArg(0), Type, Info, Size))
+      return Success(Size, E);
 
     if (E->getArg(0)->HasSideEffects(Info.Ctx))
       return Success((Type & 2) ? 0 : -1, E);
@@ -7003,7 +7560,7 @@
     case EvalInfo::EM_ConstantFold:
     case EvalInfo::EM_EvaluateForOverflow:
     case EvalInfo::EM_IgnoreSideEffects:
-    case EvalInfo::EM_DesignatorFold:
+    case EvalInfo::EM_OffsetFold:
       // Leave it to IR generation.
       return Error(E);
     case EvalInfo::EM_ConstantExpressionUnevaluated:
@@ -7515,6 +8072,18 @@
   return true;
 }
 
+static void addOrSubLValueAsInteger(APValue &LVal, APSInt Index, bool IsSub) {
+  // Compute the new offset in the appropriate width, wrapping at 64 bits.
+  // FIXME: When compiling for a 32-bit target, we should use 32-bit
+  // offsets.
+  assert(!LVal.hasLValuePath() && "have designator for integer lvalue");
+  CharUnits &Offset = LVal.getLValueOffset();
+  uint64_t Offset64 = Offset.getQuantity();
+  uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
+  Offset = CharUnits::fromQuantity(IsSub ? Offset64 - Index64
+                                         : Offset64 + Index64);
+}
+
 bool DataRecursiveIntBinOpEvaluator::
        VisitBinOp(const EvalResult &LHSResult, const EvalResult &RHSResult,
                   const BinaryOperator *E, APValue &Result) {
@@ -7561,12 +8130,7 @@
   // Handle cases like (unsigned long)&a + 4.
   if (E->isAdditiveOp() && LHSVal.isLValue() && RHSVal.isInt()) {
     Result = LHSVal;
-    CharUnits AdditionalOffset =
-        CharUnits::fromQuantity(RHSVal.getInt().getZExtValue());
-    if (E->getOpcode() == BO_Add)
-      Result.getLValueOffset() += AdditionalOffset;
-    else
-      Result.getLValueOffset() -= AdditionalOffset;
+    addOrSubLValueAsInteger(Result, RHSVal.getInt(), E->getOpcode() == BO_Sub);
     return true;
   }
   
@@ -7574,8 +8138,7 @@
   if (E->getOpcode() == BO_Add &&
       RHSVal.isLValue() && LHSVal.isInt()) {
     Result = RHSVal;
-    Result.getLValueOffset() +=
-        CharUnits::fromQuantity(LHSVal.getInt().getZExtValue());
+    addOrSubLValueAsInteger(Result, LHSVal.getInt(), /*IsSub*/false);
     return true;
   }
   
@@ -8257,6 +8820,7 @@
   case CK_IntegralComplexToFloatingComplex:
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
+  case CK_ZeroToOCLQueue:
   case CK_NonAtomicToAtomic:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
@@ -8334,8 +8898,13 @@
       return true;
     }
 
-    APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(), 
-                                         SrcType);
+    uint64_t V;
+    if (LV.isNullPointer())
+      V = Info.Ctx.getTargetNullPointerValue(SrcType);
+    else
+      V = LV.getLValueOffset().getQuantity();
+
+    APSInt AsInt = Info.Ctx.MakeIntValue(V, SrcType);
     return Success(HandleIntToIntCast(Info, E, DestType, SrcType, AsInt), E);
   }
 
@@ -8749,6 +9318,7 @@
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
+  case CK_ZeroToOCLQueue:
   case CK_NonAtomicToAtomic:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
@@ -9125,10 +9695,11 @@
 namespace {
 class AtomicExprEvaluator :
     public ExprEvaluatorBase<AtomicExprEvaluator> {
+  const LValue *This;
   APValue &Result;
 public:
-  AtomicExprEvaluator(EvalInfo &Info, APValue &Result)
-      : ExprEvaluatorBaseTy(Info), Result(Result) {}
+  AtomicExprEvaluator(EvalInfo &Info, const LValue *This, APValue &Result)
+      : ExprEvaluatorBaseTy(Info), This(This), Result(Result) {}
 
   bool Success(const APValue &V, const Expr *E) {
     Result = V;
@@ -9138,7 +9709,10 @@
   bool ZeroInitialization(const Expr *E) {
     ImplicitValueInitExpr VIE(
         E->getType()->castAs<AtomicType>()->getValueType());
-    return Evaluate(Result, Info, &VIE);
+    // For atomic-qualified class (and array) types in C++, initialize the
+    // _Atomic-wrapped subobject directly, in-place.
+    return This ? EvaluateInPlace(Result, Info, *This, &VIE)
+                : Evaluate(Result, Info, &VIE);
   }
 
   bool VisitCastExpr(const CastExpr *E) {
@@ -9146,15 +9720,17 @@
     default:
       return ExprEvaluatorBaseTy::VisitCastExpr(E);
     case CK_NonAtomicToAtomic:
-      return Evaluate(Result, Info, E->getSubExpr());
+      return This ? EvaluateInPlace(Result, Info, *This, E->getSubExpr())
+                  : Evaluate(Result, Info, E->getSubExpr());
     }
   }
 };
 } // end anonymous namespace
 
-static bool EvaluateAtomic(const Expr *E, APValue &Result, EvalInfo &Info) {
+static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
+                           EvalInfo &Info) {
   assert(E->isRValue() && E->getType()->isAtomicType());
-  return AtomicExprEvaluator(Info, Result).Visit(E);
+  return AtomicExprEvaluator(Info, This, Result).Visit(E);
 }
 
 //===----------------------------------------------------------------------===//
@@ -9259,8 +9835,17 @@
     if (!EvaluateVoid(E, Info))
       return false;
   } else if (T->isAtomicType()) {
-    if (!EvaluateAtomic(E, Result, Info))
-      return false;
+    QualType Unqual = T.getAtomicUnqualifiedType();
+    if (Unqual->isArrayType() || Unqual->isRecordType()) {
+      LValue LV;
+      LV.set(E, Info.CurrentCall->Index);
+      APValue &Value = Info.CurrentCall->createTemporary(E, false);
+      if (!EvaluateAtomic(E, &LV, Value, Info))
+        return false;
+    } else {
+      if (!EvaluateAtomic(E, nullptr, Result, Info))
+        return false;
+    }
   } else if (Info.getLangOpts().CPlusPlus11) {
     Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->getType();
     return false;
@@ -9285,10 +9870,16 @@
   if (E->isRValue()) {
     // Evaluate arrays and record types in-place, so that later initializers can
     // refer to earlier-initialized members of the object.
-    if (E->getType()->isArrayType())
+    QualType T = E->getType();
+    if (T->isArrayType())
       return EvaluateArray(E, This, Result, Info);
-    else if (E->getType()->isRecordType())
+    else if (T->isRecordType())
       return EvaluateRecord(E, This, Result, Info);
+    else if (T->isAtomicType()) {
+      QualType Unqual = T.getAtomicUnqualifiedType();
+      if (Unqual->isArrayType() || Unqual->isRecordType())
+        return EvaluateAtomic(E, &This, Result, Info);
+    }
   }
 
   // For any other type, in-place evaluation is unimportant.
@@ -9505,7 +10096,7 @@
 // Note that to reduce code duplication, this helper does no evaluation
 // itself; the caller checks whether the expression is evaluatable, and
 // in the rare cases where CheckICE actually cares about the evaluated
-// value, it calls into Evalute.
+// value, it calls into Evaluate.
 
 namespace {
 
@@ -9563,6 +10154,8 @@
   case Expr::CompoundLiteralExprClass:
   case Expr::ExtVectorElementExprClass:
   case Expr::DesignatedInitExprClass:
+  case Expr::ArrayInitLoopExprClass:
+  case Expr::ArrayInitIndexExprClass:
   case Expr::NoInitExprClass:
   case Expr::DesignatedInitUpdateExprClass:
   case Expr::ImplicitValueInitExprClass:
@@ -9625,6 +10218,7 @@
   case Expr::LambdaExprClass:
   case Expr::CXXFoldExprClass:
   case Expr::CoawaitExprClass:
+  case Expr::DependentCoawaitExprClass:
   case Expr::CoyieldExprClass:
     return ICEDiag(IK_NotICE, E->getLocStart());
 
@@ -10006,10 +10600,25 @@
 
 bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
                                     const FunctionDecl *Callee,
-                                    ArrayRef<const Expr*> Args) const {
+                                    ArrayRef<const Expr*> Args,
+                                    const Expr *This) const {
   Expr::EvalStatus Status;
   EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
 
+  LValue ThisVal;
+  const LValue *ThisPtr = nullptr;
+  if (This) {
+#ifndef NDEBUG
+    auto *MD = dyn_cast<CXXMethodDecl>(Callee);
+    assert(MD && "Don't provide `this` for non-methods.");
+    assert(!MD->isStatic() && "Don't provide `this` for static methods.");
+#endif
+    if (EvaluateObjectArgument(Info, This, ThisVal))
+      ThisPtr = &ThisVal;
+    if (Info.EvalStatus.HasSideEffects)
+      return false;
+  }
+
   ArgVector ArgValues(Args.size());
   for (ArrayRef<const Expr*>::iterator I = Args.begin(), E = Args.end();
        I != E; ++I) {
@@ -10022,7 +10631,7 @@
   }
 
   // Build fake call to Callee.
-  CallStackFrame Frame(Info, Callee->getLocation(), Callee, /*This*/nullptr,
+  CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
                        ArgValues.data());
   return Evaluate(Value, Info, this) && !Info.EvalStatus.HasSideEffects;
 }
@@ -10099,5 +10708,5 @@
 
   Expr::EvalStatus Status;
   EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
-  return ::tryEvaluateBuiltinObjectSize(this, Type, Info, Result);
+  return tryEvaluateBuiltinObjectSize(this, Type, Info, Result);
 }
diff --git a/lib/AST/ExternalASTSource.cpp b/lib/AST/ExternalASTSource.cpp
index e3de8c5..26b1aef 100644
--- a/lib/AST/ExternalASTSource.cpp
+++ b/lib/AST/ExternalASTSource.cpp
@@ -28,6 +28,11 @@
   return None;
 }
 
+ExternalASTSource::ExtKind
+ExternalASTSource::hasExternalDefinitions(unsigned ID) {
+  return EK_ReplyHazy;
+}
+
 ExternalASTSource::ASTSourceDescriptor::ASTSourceDescriptor(const Module &M)
   : Signature(M.Signature), ClangModule(&M) {
   if (M.Directory)
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 0916c01..dd99f20 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1190,6 +1190,8 @@
       llvm_unreachable("Can't mangle a constructor name!");
     case DeclarationName::CXXUsingDirective:
       llvm_unreachable("Can't mangle a using directive name!");
+    case DeclarationName::CXXDeductionGuideName:
+      llvm_unreachable("Can't mangle a deduction guide name!");
     case DeclarationName::ObjCMultiArgSelector:
     case DeclarationName::ObjCOneArgSelector:
     case DeclarationName::ObjCZeroArgSelector:
@@ -1419,6 +1421,9 @@
     writeAbiTags(ND, AdditionalAbiTags);
     break;
 
+  case DeclarationName::CXXDeductionGuideName:
+    llvm_unreachable("Can't mangle a deduction guide name!");
+
   case DeclarationName::CXXUsingDirective:
     llvm_unreachable("Can't mangle a using directive name!");
   }
@@ -1870,6 +1875,7 @@
   case Type::Paren:
   case Type::Attributed:
   case Type::Auto:
+  case Type::DeducedTemplateSpecialization:
   case Type::PackExpansion:
   case Type::ObjCObject:
   case Type::ObjCInterface:
@@ -1996,6 +2002,7 @@
   switch (Name.getNameKind()) {
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXDeductionGuideName:
   case DeclarationName::CXXUsingDirective:
   case DeclarationName::Identifier:
   case DeclarationName::ObjCMultiArgSelector:
@@ -2152,10 +2159,12 @@
     } else {
       switch (AS) {
       default: llvm_unreachable("Not a language specific address space");
-      //  <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" ]
+      //  <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant |
+      //                                "generic" ]
       case LangAS::opencl_global:   ASString = "CLglobal";   break;
       case LangAS::opencl_local:    ASString = "CLlocal";    break;
       case LangAS::opencl_constant: ASString = "CLconstant"; break;
+      case LangAS::opencl_generic:  ASString = "CLgeneric";  break;
       //  <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
       case LangAS::cuda_device:     ASString = "CUdevice";   break;
       case LangAS::cuda_constant:   ASString = "CUconstant"; break;
@@ -2493,9 +2502,6 @@
   case BuiltinType::OCLQueue:
     Out << "9ocl_queue";
     break;
-  case BuiltinType::OCLNDRange:
-    Out << "11ocl_ndrange";
-    break;
   case BuiltinType::OCLReserveID:
     Out << "13ocl_reserveid";
     break;
@@ -3043,6 +3049,7 @@
   //                   ::= Te <name> # dependent elaborated type specifier using
   //                                 # 'enum'
   switch (T->getKeyword()) {
+    case ETK_None:
     case ETK_Typename:
       break;
     case ETK_Struct:
@@ -3056,8 +3063,6 @@
     case ETK_Enum:
       Out << "Te";
       break;
-    default:
-      llvm_unreachable("unexpected keyword for dependent type name");
   }
   // Typename types are always nested
   Out << 'N';
@@ -3146,6 +3151,16 @@
     mangleType(D);
 }
 
+void CXXNameMangler::mangleType(const DeducedTemplateSpecializationType *T) {
+  // FIXME: This is not the right mangling. We also need to include a scope
+  // here in some cases.
+  QualType D = T->getDeducedType();
+  if (D.isNull())
+    mangleUnscopedTemplateName(T->getTemplateName(), nullptr);
+  else
+    mangleType(D);
+}
+
 void CXXNameMangler::mangleType(const AtomicType *T) {
   // <type> ::= U <source-name> <type>  # vendor extended type qualifier
   // (Until there's a standardized mangling...)
@@ -3301,6 +3316,8 @@
   case Expr::AddrLabelExprClass:
   case Expr::DesignatedInitUpdateExprClass:
   case Expr::ImplicitValueInitExprClass:
+  case Expr::ArrayInitLoopExprClass:
+  case Expr::ArrayInitIndexExprClass:
   case Expr::NoInitExprClass:
   case Expr::ParenListExprClass:
   case Expr::LambdaExprClass:
@@ -4019,6 +4036,12 @@
     mangleExpression(cast<CoawaitExpr>(E)->getOperand());
     break;
 
+  case Expr::DependentCoawaitExprClass:
+    // FIXME: Propose a non-vendor mangling.
+    Out << "v18co_await";
+    mangleExpression(cast<DependentCoawaitExpr>(E)->getOperand());
+    break;
+
   case Expr::CoyieldExprClass:
     // FIXME: Propose a non-vendor mangling.
     Out << "v18co_yield";
diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp
index 05dd886..00d50c0 100644
--- a/lib/AST/Mangle.cpp
+++ b/lib/AST/Mangle.cpp
@@ -262,9 +262,13 @@
   const ObjCContainerDecl *CD =
   dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
   assert (CD && "Missing container decl in GetNameForMethod");
-  OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
-  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
+  OS << (MD->isInstanceMethod() ? '-' : '+') << '[';
+  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD)) {
+    OS << CID->getClassInterface()->getName();
     OS << '(' << *CID << ')';
+  } else {
+    OS << CD->getName();
+  }
   OS << ' ';
   MD->getSelector().print(OS);
   OS << ']';
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 27806a7..6e14dd0 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -109,13 +109,13 @@
 
 static const FunctionDecl *getStructor(const NamedDecl *ND) {
   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
-    return FTD->getTemplatedDecl();
+    return FTD->getTemplatedDecl()->getCanonicalDecl();
 
   const auto *FD = cast<FunctionDecl>(ND);
   if (const auto *FTD = FD->getPrimaryTemplate())
-    return FTD->getTemplatedDecl();
+    return FTD->getTemplatedDecl()->getCanonicalDecl();
 
-  return FD;
+  return FD->getCanonicalDecl();
 }
 
 /// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
@@ -312,6 +312,10 @@
   void mangleNestedName(const NamedDecl *ND);
 
 private:
+  bool isStructorDecl(const NamedDecl *ND) const {
+    return ND == Structor || getStructor(ND) == Structor;
+  }
+
   void mangleUnqualifiedName(const NamedDecl *ND) {
     mangleUnqualifiedName(ND, ND->getDeclName());
   }
@@ -863,21 +867,28 @@
         }
       }
 
-      llvm::SmallString<64> Name("<unnamed-type-");
+      llvm::SmallString<64> Name;
       if (DeclaratorDecl *DD =
               Context.getASTContext().getDeclaratorForUnnamedTagDecl(TD)) {
         // Anonymous types without a name for linkage purposes have their
         // declarator mangled in if they have one.
+        Name += "<unnamed-type-";
         Name += DD->getName();
       } else if (TypedefNameDecl *TND =
                      Context.getASTContext().getTypedefNameForUnnamedTagDecl(
                          TD)) {
         // Anonymous types without a name for linkage purposes have their
         // associate typedef mangled in if they have one.
+        Name += "<unnamed-type-";
         Name += TND->getName();
+      } else if (auto *ED = dyn_cast<EnumDecl>(TD)) {
+        auto EnumeratorI = ED->enumerator_begin();
+        assert(EnumeratorI != ED->enumerator_end());
+        Name += "<unnamed-enum-";
+        Name += EnumeratorI->getName();
       } else {
         // Otherwise, number the types using a $S prefix.
-        Name += "$S";
+        Name += "<unnamed-type-$S";
         Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
       }
       Name += ">";
@@ -891,7 +902,7 @@
       llvm_unreachable("Can't mangle Objective-C selector names here!");
 
     case DeclarationName::CXXConstructorName:
-      if (Structor == getStructor(ND)) {
+      if (isStructorDecl(ND)) {
         if (StructorType == Ctor_CopyingClosure) {
           Out << "?_O";
           return;
@@ -905,7 +916,7 @@
       return;
 
     case DeclarationName::CXXDestructorName:
-      if (ND == Structor)
+      if (isStructorDecl(ND))
         // If the named decl is the C++ destructor we're mangling,
         // use the type we were given.
         mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
@@ -931,6 +942,9 @@
       break;
     }
 
+    case DeclarationName::CXXDeductionGuideName:
+      llvm_unreachable("Can't mangle a deduction guide name!");
+
     case DeclarationName::CXXUsingDirective:
       llvm_unreachable("Can't mangle a using directive name!");
   }
@@ -1786,10 +1800,6 @@
     Out << "PA";
     mangleArtificalTagType(TTK_Struct, "ocl_queue");
     break;
-  case BuiltinType::OCLNDRange:
-    Out << "PA";
-    mangleArtificalTagType(TTK_Struct, "ocl_ndrange");
-    break;
   case BuiltinType::OCLReserveID:
     Out << "PA";
     mangleArtificalTagType(TTK_Struct, "ocl_reserveid");
@@ -1855,7 +1865,7 @@
       IsStructor = true;
       IsCtorClosure = (StructorType == Ctor_CopyingClosure ||
                        StructorType == Ctor_DefaultClosure) &&
-                      getStructor(MD) == Structor;
+                      isStructorDecl(MD);
       if (IsCtorClosure)
         CC = getASTContext().getDefaultCallingConvention(
             /*IsVariadic=*/false, /*IsCXXMethod=*/true);
@@ -1876,14 +1886,18 @@
   // <return-type> ::= <type>
   //               ::= @ # structors (they have no declared return type)
   if (IsStructor) {
-    if (isa<CXXDestructorDecl>(D) && D == Structor &&
-        StructorType == Dtor_Deleting) {
-      // The scalar deleting destructor takes an extra int argument.
-      // However, the FunctionType generated has 0 arguments.
-      // FIXME: This is a temporary hack.
-      // Maybe should fix the FunctionType creation instead?
-      Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
-      return;
+    if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
+      // The scalar deleting destructor takes an extra int argument which is not
+      // reflected in the AST.
+      if (StructorType == Dtor_Deleting) {
+        Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
+        return;
+      }
+      // The vbase destructor returns void which is not reflected in the AST.
+      if (StructorType == Dtor_Complete) {
+        Out << "XXZ";
+        return;
+      }
     }
     if (IsCtorClosure) {
       // Default constructor closure and copy constructor closure both return
@@ -1943,7 +1957,7 @@
     // Happens for function pointer type arguments for example.
     for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {
       mangleArgumentType(Proto->getParamType(I), Range);
-      // Mangle each pass_object_size parameter as if it's a paramater of enum
+      // Mangle each pass_object_size parameter as if it's a parameter of enum
       // type passed directly after the parameter with the pass_object_size
       // attribute. The aforementioned enum's name is __pass_object_size, and we
       // pretend it resides in a top-level namespace called __clang.
@@ -1991,13 +2005,20 @@
   // <global-function> ::= Y # global near
   //                   ::= Z # global far
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+    bool IsVirtual = MD->isVirtual();
+    // When mangling vbase destructor variants, ignore whether or not the
+    // underlying destructor was defined to be virtual.
+    if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
+        StructorType == Dtor_Complete) {
+      IsVirtual = false;
+    }
     switch (MD->getAccess()) {
       case AS_none:
         llvm_unreachable("Unsupported access specifier");
       case AS_private:
         if (MD->isStatic())
           Out << 'C';
-        else if (MD->isVirtual())
+        else if (IsVirtual)
           Out << 'E';
         else
           Out << 'A';
@@ -2005,7 +2026,7 @@
       case AS_protected:
         if (MD->isStatic())
           Out << 'K';
-        else if (MD->isVirtual())
+        else if (IsVirtual)
           Out << 'M';
         else
           Out << 'I';
@@ -2013,7 +2034,7 @@
       case AS_public:
         if (MD->isStatic())
           Out << 'S';
-        else if (MD->isVirtual())
+        else if (IsVirtual)
           Out << 'U';
         else
           Out << 'Q';
@@ -2463,6 +2484,17 @@
     << Range;
 }
 
+void MicrosoftCXXNameMangler::mangleType(
+    const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {
+  assert(T->getDeducedType().isNull() && "expecting a dependent type!");
+
+  DiagnosticsEngine &Diags = Context.getDiags();
+  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+    "cannot mangle this deduced class template specialization type yet");
+  Diags.Report(Range.getBegin(), DiagID)
+    << Range;
+}
+
 void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers,
                                          SourceRange Range) {
   QualType ValueType = T->getValueType();
@@ -2986,14 +3018,14 @@
   // N.B. The length is in terms of bytes, not characters.
   Mangler.mangleNumber(SL->getByteLength() + SL->getCharByteWidth());
 
-  auto GetLittleEndianByte = [&Mangler, &SL](unsigned Index) {
+  auto GetLittleEndianByte = [&SL](unsigned Index) {
     unsigned CharByteWidth = SL->getCharByteWidth();
     uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
     unsigned OffsetInCodeUnit = Index % CharByteWidth;
     return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
   };
 
-  auto GetBigEndianByte = [&Mangler, &SL](unsigned Index) {
+  auto GetBigEndianByte = [&SL](unsigned Index) {
     unsigned CharByteWidth = SL->getCharByteWidth();
     uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
     unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index ac2a8d3..e7c8c16 100644
--- a/lib/AST/NSAPI.cpp
+++ b/lib/AST/NSAPI.cpp
@@ -453,7 +453,6 @@
   case BuiltinType::OCLEvent:
   case BuiltinType::OCLClkEvent:
   case BuiltinType::OCLQueue:
-  case BuiltinType::OCLNDRange:
   case BuiltinType::OCLReserveID:
   case BuiltinType::BoundMember:
   case BuiltinType::Dependent:
diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp
new file mode 100644
index 0000000..d72eebb
--- /dev/null
+++ b/lib/AST/ODRHash.cpp
@@ -0,0 +1,361 @@
+//===-- ODRHash.cpp - Hashing to diagnose ODR failures ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements the ODRHash class, which calculates a hash based
+/// on AST nodes, which is stable across different runs.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ODRHash.h"
+
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeVisitor.h"
+
+using namespace clang;
+
+void ODRHash::AddStmt(const Stmt *S) {
+  assert(S && "Expecting non-null pointer.");
+  S->ProcessODRHash(ID, *this);
+}
+
+void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {
+  assert(II && "Expecting non-null pointer.");
+  ID.AddString(II->getName());
+}
+
+void ODRHash::AddDeclarationName(DeclarationName Name) {
+  AddBoolean(Name.isEmpty());
+  if (Name.isEmpty())
+    return;
+
+  auto Kind = Name.getNameKind();
+  ID.AddInteger(Kind);
+  switch (Kind) {
+  case DeclarationName::Identifier:
+    AddIdentifierInfo(Name.getAsIdentifierInfo());
+    break;
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector: {
+    Selector S = Name.getObjCSelector();
+    AddBoolean(S.isNull());
+    AddBoolean(S.isKeywordSelector());
+    AddBoolean(S.isUnarySelector());
+    unsigned NumArgs = S.getNumArgs();
+    for (unsigned i = 0; i < NumArgs; ++i) {
+      AddIdentifierInfo(S.getIdentifierInfoForSlot(i));
+    }
+    break;
+  }
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+    AddQualType(Name.getCXXNameType());
+    break;
+  case DeclarationName::CXXOperatorName:
+    ID.AddInteger(Name.getCXXOverloadedOperator());
+    break;
+  case DeclarationName::CXXLiteralOperatorName:
+    AddIdentifierInfo(Name.getCXXLiteralIdentifier());
+    break;
+  case DeclarationName::CXXConversionFunctionName:
+    AddQualType(Name.getCXXNameType());
+    break;
+  case DeclarationName::CXXUsingDirective:
+    break;
+  case DeclarationName::CXXDeductionGuideName: {
+    auto *Template = Name.getCXXDeductionGuideTemplate();
+    AddBoolean(Template);
+    if (Template) {
+      AddDecl(Template);
+    }
+  }
+  }
+}
+
+void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {}
+void ODRHash::AddTemplateName(TemplateName Name) {}
+void ODRHash::AddTemplateArgument(TemplateArgument TA) {}
+void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {}
+
+void ODRHash::clear() {
+  DeclMap.clear();
+  TypeMap.clear();
+  Bools.clear();
+  ID.clear();
+}
+
+unsigned ODRHash::CalculateHash() {
+  // Append the bools to the end of the data segment backwards.  This allows
+  // for the bools data to be compressed 32 times smaller compared to using
+  // ID.AddBoolean
+  const unsigned unsigned_bits = sizeof(unsigned) * CHAR_BIT;
+  const unsigned size = Bools.size();
+  const unsigned remainder = size % unsigned_bits;
+  const unsigned loops = size / unsigned_bits;
+  auto I = Bools.rbegin();
+  unsigned value = 0;
+  for (unsigned i = 0; i < remainder; ++i) {
+    value <<= 1;
+    value |= *I;
+    ++I;
+  }
+  ID.AddInteger(value);
+
+  for (unsigned i = 0; i < loops; ++i) {
+    value = 0;
+    for (unsigned j = 0; j < unsigned_bits; ++j) {
+      value <<= 1;
+      value |= *I;
+      ++I;
+    }
+    ID.AddInteger(value);
+  }
+
+  assert(I == Bools.rend());
+  Bools.clear();
+  return ID.ComputeHash();
+}
+
+// Process a Decl pointer.  Add* methods call back into ODRHash while Visit*
+// methods process the relevant parts of the Decl.
+class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
+  typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;
+  llvm::FoldingSetNodeID &ID;
+  ODRHash &Hash;
+
+public:
+  ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
+      : ID(ID), Hash(Hash) {}
+
+  void AddStmt(const Stmt *S) {
+    Hash.AddBoolean(S);
+    if (S) {
+      Hash.AddStmt(S);
+    }
+  }
+
+  void AddIdentifierInfo(const IdentifierInfo *II) {
+    Hash.AddBoolean(II);
+    if (II) {
+      Hash.AddIdentifierInfo(II);
+    }
+  }
+
+  void AddQualType(QualType T) {
+    Hash.AddQualType(T);
+  }
+
+  void Visit(const Decl *D) {
+    ID.AddInteger(D->getKind());
+    Inherited::Visit(D);
+  }
+
+  void VisitNamedDecl(const NamedDecl *D) {
+    Hash.AddDeclarationName(D->getDeclName());
+    Inherited::VisitNamedDecl(D);
+  }
+
+  void VisitValueDecl(const ValueDecl *D) {
+    AddQualType(D->getType());
+    Inherited::VisitValueDecl(D);
+  }
+
+  void VisitAccessSpecDecl(const AccessSpecDecl *D) {
+    ID.AddInteger(D->getAccess());
+    Inherited::VisitAccessSpecDecl(D);
+  }
+
+  void VisitStaticAssertDecl(const StaticAssertDecl *D) {
+    AddStmt(D->getAssertExpr());
+    AddStmt(D->getMessage());
+
+    Inherited::VisitStaticAssertDecl(D);
+  }
+
+  void VisitFieldDecl(const FieldDecl *D) {
+    const bool IsBitfield = D->isBitField();
+    Hash.AddBoolean(IsBitfield);
+
+    if (IsBitfield) {
+      AddStmt(D->getBitWidth());
+    }
+
+    Hash.AddBoolean(D->isMutable());
+    AddStmt(D->getInClassInitializer());
+
+    Inherited::VisitFieldDecl(D);
+  }
+
+  void VisitFunctionDecl(const FunctionDecl *D) {
+    ID.AddInteger(D->getStorageClass());
+    Hash.AddBoolean(D->isInlineSpecified());
+    Hash.AddBoolean(D->isVirtualAsWritten());
+    Hash.AddBoolean(D->isPure());
+    Hash.AddBoolean(D->isDeletedAsWritten());
+
+    Inherited::VisitFunctionDecl(D);
+  }
+
+  void VisitCXXMethodDecl(const CXXMethodDecl *D) {
+    Hash.AddBoolean(D->isConst());
+    Hash.AddBoolean(D->isVolatile());
+
+    Inherited::VisitCXXMethodDecl(D);
+  }
+
+  void VisitTypedefNameDecl(const TypedefNameDecl *D) {
+    AddQualType(D->getUnderlyingType());
+
+    Inherited::VisitTypedefNameDecl(D);
+  }
+
+  void VisitTypedefDecl(const TypedefDecl *D) {
+    Inherited::VisitTypedefDecl(D);
+  }
+
+  void VisitTypeAliasDecl(const TypeAliasDecl *D) {
+    Inherited::VisitTypeAliasDecl(D);
+  }
+};
+
+// Only allow a small portion of Decl's to be processed.  Remove this once
+// all Decl's can be handled.
+bool ODRHash::isWhitelistedDecl(const Decl *D, const CXXRecordDecl *Parent) {
+  if (D->isImplicit()) return false;
+  if (D->getDeclContext() != Parent) return false;
+
+  switch (D->getKind()) {
+    default:
+      return false;
+    case Decl::AccessSpec:
+    case Decl::CXXMethod:
+    case Decl::Field:
+    case Decl::StaticAssert:
+    case Decl::TypeAlias:
+    case Decl::Typedef:
+      return true;
+  }
+}
+
+void ODRHash::AddSubDecl(const Decl *D) {
+  assert(D && "Expecting non-null pointer.");
+  AddDecl(D);
+
+  ODRDeclVisitor(ID, *this).Visit(D);
+}
+
+void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
+  assert(Record && Record->hasDefinition() &&
+         "Expected non-null record to be a definition.");
+  AddDecl(Record);
+
+  // Filter out sub-Decls which will not be processed in order to get an
+  // accurate count of Decl's.
+  llvm::SmallVector<const Decl *, 16> Decls;
+  for (const Decl *SubDecl : Record->decls()) {
+    if (isWhitelistedDecl(SubDecl, Record)) {
+      Decls.push_back(SubDecl);
+    }
+  }
+
+  ID.AddInteger(Decls.size());
+  for (auto SubDecl : Decls) {
+    AddSubDecl(SubDecl);
+  }
+}
+
+void ODRHash::AddDecl(const Decl *D) {
+  assert(D && "Expecting non-null pointer.");
+  auto Result = DeclMap.insert(std::make_pair(D, DeclMap.size()));
+  ID.AddInteger(Result.first->second);
+  // On first encounter of a Decl pointer, process it.  Every time afterwards,
+  // only the index value is needed.
+  if (!Result.second) {
+    return;
+  }
+
+  ID.AddInteger(D->getKind());
+
+  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+    AddDeclarationName(ND->getDeclName());
+  }
+}
+
+// Process a Type pointer.  Add* methods call back into ODRHash while Visit*
+// methods process the relevant parts of the Type.
+class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
+  typedef TypeVisitor<ODRTypeVisitor> Inherited;
+  llvm::FoldingSetNodeID &ID;
+  ODRHash &Hash;
+
+public:
+  ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
+      : ID(ID), Hash(Hash) {}
+
+  void AddStmt(Stmt *S) {
+    Hash.AddBoolean(S);
+    if (S) {
+      Hash.AddStmt(S);
+    }
+  }
+
+  void AddDecl(Decl *D) {
+    Hash.AddBoolean(D);
+    if (D) {
+      Hash.AddDecl(D);
+    }
+  }
+
+  void Visit(const Type *T) {
+    ID.AddInteger(T->getTypeClass());
+    Inherited::Visit(T);
+  }
+
+  void VisitType(const Type *T) {}
+
+  void VisitBuiltinType(const BuiltinType *T) {
+    ID.AddInteger(T->getKind());
+    VisitType(T);
+  }
+
+  void VisitTypedefType(const TypedefType *T) {
+    AddDecl(T->getDecl());
+    Hash.AddQualType(T->getDecl()->getUnderlyingType());
+    VisitType(T);
+  }
+};
+
+void ODRHash::AddType(const Type *T) {
+  assert(T && "Expecting non-null pointer.");
+  auto Result = TypeMap.insert(std::make_pair(T, TypeMap.size()));
+  ID.AddInteger(Result.first->second);
+  // On first encounter of a Type pointer, process it.  Every time afterwards,
+  // only the index value is needed.
+  if (!Result.second) {
+    return;
+  }
+
+  ODRTypeVisitor(ID, *this).Visit(T);
+}
+
+void ODRHash::AddQualType(QualType T) {
+  AddBoolean(T.isNull());
+  if (T.isNull())
+    return;
+  SplitQualType split = T.split();
+  ID.AddInteger(split.Quals.getAsOpaqueValue());
+  AddType(split.Ty);
+}
+
+void ODRHash::AddBoolean(bool Value) {
+  Bools.push_back(Value);
+}
diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp
index a28b9f3..77470a9 100644
--- a/lib/AST/OpenMPClause.cpp
+++ b/lib/AST/OpenMPClause.cpp
@@ -48,11 +48,17 @@
     return static_cast<const OMPReductionClause *>(C);
   case OMPC_linear:
     return static_cast<const OMPLinearClause *>(C);
+  case OMPC_if:
+    return static_cast<const OMPIfClause *>(C);
+  case OMPC_num_threads:
+    return static_cast<const OMPNumThreadsClause *>(C);
+  case OMPC_num_teams:
+    return static_cast<const OMPNumTeamsClause *>(C);
+  case OMPC_thread_limit:
+    return static_cast<const OMPThreadLimitClause *>(C);
   case OMPC_default:
   case OMPC_proc_bind:
-  case OMPC_if:
   case OMPC_final:
-  case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_simdlen:
   case OMPC_collapse:
@@ -77,8 +83,6 @@
   case OMPC_threads:
   case OMPC_simd:
   case OMPC_map:
-  case OMPC_num_teams:
-  case OMPC_thread_limit:
   case OMPC_priority:
   case OMPC_grainsize:
   case OMPC_nogroup:
diff --git a/lib/AST/StmtCXX.cpp b/lib/AST/StmtCXX.cpp
index 4a04fc2..5c7686c 100644
--- a/lib/AST/StmtCXX.cpp
+++ b/lib/AST/StmtCXX.cpp
@@ -86,3 +86,28 @@
 const VarDecl *CXXForRangeStmt::getLoopVariable() const {
   return const_cast<CXXForRangeStmt *>(this)->getLoopVariable();
 }
+
+CoroutineBodyStmt *CoroutineBodyStmt::Create(
+    const ASTContext &C, CoroutineBodyStmt::CtorArgs const& Args) {
+  std::size_t Size = totalSizeToAlloc<Stmt *>(
+      CoroutineBodyStmt::FirstParamMove + Args.ParamMoves.size());
+
+  void *Mem = C.Allocate(Size, alignof(CoroutineBodyStmt));
+  return new (Mem) CoroutineBodyStmt(Args);
+}
+
+CoroutineBodyStmt::CoroutineBodyStmt(CoroutineBodyStmt::CtorArgs const &Args)
+    : Stmt(CoroutineBodyStmtClass), NumParams(Args.ParamMoves.size()) {
+  Stmt **SubStmts = getStoredStmts();
+  SubStmts[CoroutineBodyStmt::Body] = Args.Body;
+  SubStmts[CoroutineBodyStmt::Promise] = Args.Promise;
+  SubStmts[CoroutineBodyStmt::InitSuspend] = Args.InitialSuspend;
+  SubStmts[CoroutineBodyStmt::FinalSuspend] = Args.FinalSuspend;
+  SubStmts[CoroutineBodyStmt::OnException] = Args.OnException;
+  SubStmts[CoroutineBodyStmt::OnFallthrough] = Args.OnFallthrough;
+  SubStmts[CoroutineBodyStmt::Allocate] = Args.Allocate;
+  SubStmts[CoroutineBodyStmt::Deallocate] = Args.Deallocate;
+  SubStmts[CoroutineBodyStmt::ReturnValue] = Args.ReturnValue;
+  std::copy(Args.ParamMoves.begin(), Args.ParamMoves.end(),
+            const_cast<Stmt **>(getParamMoves().data()));
+}
\ No newline at end of file
diff --git a/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp
index 7209407..a812884 100644
--- a/lib/AST/StmtOpenMP.cpp
+++ b/lib/AST/StmtOpenMP.cpp
@@ -149,6 +149,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -201,6 +203,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -366,6 +370,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -417,6 +423,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -753,6 +761,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -896,6 +906,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -947,6 +959,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -997,6 +1011,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1071,6 +1087,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1127,6 +1145,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1182,6 +1202,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1236,6 +1258,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1330,6 +1354,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1383,6 +1409,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1438,6 +1466,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1496,6 +1526,8 @@
   Dir->setNumIterations(Exprs.NumIterations);
   Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
   Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1520,3 +1552,267 @@
       OMPTeamsDistributeParallelForDirective(CollapsedNum, NumClauses);
 }
 
+OMPTargetTeamsDirective *OMPTargetTeamsDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+  auto Size =
+      llvm::alignTo(sizeof(OMPTargetTeamsDirective), alignof(OMPClause *));
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPTargetTeamsDirective *Dir =
+      new (Mem) OMPTargetTeamsDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPTargetTeamsDirective *
+OMPTargetTeamsDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                     EmptyShell) {
+  auto Size =
+      llvm::alignTo(sizeof(OMPTargetTeamsDirective), alignof(OMPClause *));
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPTargetTeamsDirective(NumClauses);
+}
+
+OMPTargetTeamsDistributeDirective *OMPTargetTeamsDistributeDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+    const HelperExprs &Exprs) {
+  auto Size = llvm::alignTo(sizeof(OMPTargetTeamsDistributeDirective),
+                            alignof(OMPClause *));
+  void *Mem = C.Allocate(
+      Size + sizeof(OMPClause *) * Clauses.size() +
+      sizeof(Stmt *) *
+          numLoopChildren(CollapsedNum, OMPD_target_teams_distribute));
+  OMPTargetTeamsDistributeDirective *Dir =
+      new (Mem) OMPTargetTeamsDistributeDirective(StartLoc, EndLoc, CollapsedNum,
+                                                  Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  Dir->setIterationVariable(Exprs.IterationVarRef);
+  Dir->setLastIteration(Exprs.LastIteration);
+  Dir->setCalcLastIteration(Exprs.CalcLastIteration);
+  Dir->setPreCond(Exprs.PreCond);
+  Dir->setCond(Exprs.Cond);
+  Dir->setInit(Exprs.Init);
+  Dir->setInc(Exprs.Inc);
+  Dir->setIsLastIterVariable(Exprs.IL);
+  Dir->setLowerBoundVariable(Exprs.LB);
+  Dir->setUpperBoundVariable(Exprs.UB);
+  Dir->setStrideVariable(Exprs.ST);
+  Dir->setEnsureUpperBound(Exprs.EUB);
+  Dir->setNextLowerBound(Exprs.NLB);
+  Dir->setNextUpperBound(Exprs.NUB);
+  Dir->setNumIterations(Exprs.NumIterations);
+  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
+  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
+  Dir->setCounters(Exprs.Counters);
+  Dir->setPrivateCounters(Exprs.PrivateCounters);
+  Dir->setInits(Exprs.Inits);
+  Dir->setUpdates(Exprs.Updates);
+  Dir->setFinals(Exprs.Finals);
+  Dir->setPreInits(Exprs.PreInits);
+  return Dir;
+}
+
+OMPTargetTeamsDistributeDirective *
+OMPTargetTeamsDistributeDirective::CreateEmpty(const ASTContext &C,
+                                               unsigned NumClauses,
+                                               unsigned CollapsedNum,
+                                               EmptyShell) {
+  auto Size = llvm::alignTo(sizeof(OMPTargetTeamsDistributeDirective),
+                            alignof(OMPClause *));
+  void *Mem = C.Allocate(
+      Size + sizeof(OMPClause *) * NumClauses +
+      sizeof(Stmt *) *
+           numLoopChildren(CollapsedNum, OMPD_target_teams_distribute));
+  return new (Mem) OMPTargetTeamsDistributeDirective(CollapsedNum, NumClauses);
+}
+
+OMPTargetTeamsDistributeParallelForDirective *
+OMPTargetTeamsDistributeParallelForDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+    const HelperExprs &Exprs) {
+  auto Size =
+      llvm::alignTo(sizeof(OMPTargetTeamsDistributeParallelForDirective),
+                    alignof(OMPClause *));
+  void *Mem = C.Allocate(
+      Size + sizeof(OMPClause *) * Clauses.size() +
+      sizeof(Stmt *) *
+          numLoopChildren(CollapsedNum,
+                          OMPD_target_teams_distribute_parallel_for));
+  OMPTargetTeamsDistributeParallelForDirective *Dir =
+      new (Mem) OMPTargetTeamsDistributeParallelForDirective(
+           StartLoc, EndLoc, CollapsedNum, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  Dir->setIterationVariable(Exprs.IterationVarRef);
+  Dir->setLastIteration(Exprs.LastIteration);
+  Dir->setCalcLastIteration(Exprs.CalcLastIteration);
+  Dir->setPreCond(Exprs.PreCond);
+  Dir->setCond(Exprs.Cond);
+  Dir->setInit(Exprs.Init);
+  Dir->setInc(Exprs.Inc);
+  Dir->setIsLastIterVariable(Exprs.IL);
+  Dir->setLowerBoundVariable(Exprs.LB);
+  Dir->setUpperBoundVariable(Exprs.UB);
+  Dir->setStrideVariable(Exprs.ST);
+  Dir->setEnsureUpperBound(Exprs.EUB);
+  Dir->setNextLowerBound(Exprs.NLB);
+  Dir->setNextUpperBound(Exprs.NUB);
+  Dir->setNumIterations(Exprs.NumIterations);
+  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
+  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
+  Dir->setCounters(Exprs.Counters);
+  Dir->setPrivateCounters(Exprs.PrivateCounters);
+  Dir->setInits(Exprs.Inits);
+  Dir->setUpdates(Exprs.Updates);
+  Dir->setFinals(Exprs.Finals);
+  Dir->setPreInits(Exprs.PreInits);
+  return Dir;
+}
+
+OMPTargetTeamsDistributeParallelForDirective *
+OMPTargetTeamsDistributeParallelForDirective::CreateEmpty(const ASTContext &C,
+                                                          unsigned NumClauses,
+                                                          unsigned CollapsedNum,
+                                                          EmptyShell) {
+  auto Size =
+      llvm::alignTo(sizeof(OMPTargetTeamsDistributeParallelForDirective),
+                    alignof(OMPClause *));
+  void *Mem = C.Allocate(
+      Size + sizeof(OMPClause *) * NumClauses +
+      sizeof(Stmt *) *
+           numLoopChildren(CollapsedNum,
+                           OMPD_target_teams_distribute_parallel_for));
+  return new (Mem)
+      OMPTargetTeamsDistributeParallelForDirective(CollapsedNum, NumClauses);
+}
+
+OMPTargetTeamsDistributeParallelForSimdDirective *
+OMPTargetTeamsDistributeParallelForSimdDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+    const HelperExprs &Exprs) {
+  auto Size =
+      llvm::alignTo(sizeof(OMPTargetTeamsDistributeParallelForSimdDirective),
+                    alignof(OMPClause *));
+  void *Mem = C.Allocate(
+      Size + sizeof(OMPClause *) * Clauses.size() +
+      sizeof(Stmt *) *
+          numLoopChildren(CollapsedNum,
+                          OMPD_target_teams_distribute_parallel_for_simd));
+  OMPTargetTeamsDistributeParallelForSimdDirective *Dir =
+      new (Mem) OMPTargetTeamsDistributeParallelForSimdDirective(
+           StartLoc, EndLoc, CollapsedNum, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  Dir->setIterationVariable(Exprs.IterationVarRef);
+  Dir->setLastIteration(Exprs.LastIteration);
+  Dir->setCalcLastIteration(Exprs.CalcLastIteration);
+  Dir->setPreCond(Exprs.PreCond);
+  Dir->setCond(Exprs.Cond);
+  Dir->setInit(Exprs.Init);
+  Dir->setInc(Exprs.Inc);
+  Dir->setIsLastIterVariable(Exprs.IL);
+  Dir->setLowerBoundVariable(Exprs.LB);
+  Dir->setUpperBoundVariable(Exprs.UB);
+  Dir->setStrideVariable(Exprs.ST);
+  Dir->setEnsureUpperBound(Exprs.EUB);
+  Dir->setNextLowerBound(Exprs.NLB);
+  Dir->setNextUpperBound(Exprs.NUB);
+  Dir->setNumIterations(Exprs.NumIterations);
+  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
+  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
+  Dir->setCounters(Exprs.Counters);
+  Dir->setPrivateCounters(Exprs.PrivateCounters);
+  Dir->setInits(Exprs.Inits);
+  Dir->setUpdates(Exprs.Updates);
+  Dir->setFinals(Exprs.Finals);
+  Dir->setPreInits(Exprs.PreInits);
+  return Dir;
+}
+
+OMPTargetTeamsDistributeParallelForSimdDirective *
+OMPTargetTeamsDistributeParallelForSimdDirective::CreateEmpty(
+    const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+    EmptyShell) {
+  auto Size =
+      llvm::alignTo(sizeof(OMPTargetTeamsDistributeParallelForSimdDirective),
+                    alignof(OMPClause *));
+  void *Mem = C.Allocate(
+      Size + sizeof(OMPClause *) * NumClauses +
+      sizeof(Stmt *) *
+          numLoopChildren(CollapsedNum,
+                          OMPD_target_teams_distribute_parallel_for_simd));
+  return new (Mem) OMPTargetTeamsDistributeParallelForSimdDirective(
+      CollapsedNum, NumClauses);
+}
+
+OMPTargetTeamsDistributeSimdDirective *
+OMPTargetTeamsDistributeSimdDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+    const HelperExprs &Exprs) {
+  auto Size = llvm::alignTo(sizeof(OMPTargetTeamsDistributeSimdDirective),
+                            alignof(OMPClause *));
+  void *Mem = C.Allocate(
+      Size + sizeof(OMPClause *) * Clauses.size() +
+      sizeof(Stmt *) *
+          numLoopChildren(CollapsedNum, OMPD_target_teams_distribute_simd));
+  OMPTargetTeamsDistributeSimdDirective *Dir = new (Mem)
+      OMPTargetTeamsDistributeSimdDirective(StartLoc, EndLoc, CollapsedNum,
+                                            Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  Dir->setIterationVariable(Exprs.IterationVarRef);
+  Dir->setLastIteration(Exprs.LastIteration);
+  Dir->setCalcLastIteration(Exprs.CalcLastIteration);
+  Dir->setPreCond(Exprs.PreCond);
+  Dir->setCond(Exprs.Cond);
+  Dir->setInit(Exprs.Init);
+  Dir->setInc(Exprs.Inc);
+  Dir->setIsLastIterVariable(Exprs.IL);
+  Dir->setLowerBoundVariable(Exprs.LB);
+  Dir->setUpperBoundVariable(Exprs.UB);
+  Dir->setStrideVariable(Exprs.ST);
+  Dir->setEnsureUpperBound(Exprs.EUB);
+  Dir->setNextLowerBound(Exprs.NLB);
+  Dir->setNextUpperBound(Exprs.NUB);
+  Dir->setNumIterations(Exprs.NumIterations);
+  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
+  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
+  Dir->setDistInc(Exprs.DistInc);
+  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
+  Dir->setCounters(Exprs.Counters);
+  Dir->setPrivateCounters(Exprs.PrivateCounters);
+  Dir->setInits(Exprs.Inits);
+  Dir->setUpdates(Exprs.Updates);
+  Dir->setFinals(Exprs.Finals);
+  Dir->setPreInits(Exprs.PreInits);
+  return Dir;
+}
+
+OMPTargetTeamsDistributeSimdDirective *
+OMPTargetTeamsDistributeSimdDirective::CreateEmpty(const ASTContext &C,
+                                                   unsigned NumClauses,
+                                                   unsigned CollapsedNum,
+                                                   EmptyShell) {
+  auto Size = llvm::alignTo(sizeof(OMPTargetTeamsDistributeSimdDirective),
+                            alignof(OMPClause *));
+  void *Mem = C.Allocate(
+      Size + sizeof(OMPClause *) * NumClauses +
+      sizeof(Stmt *) *
+          numLoopChildren(CollapsedNum, OMPD_target_teams_distribute_simd));
+  return new (Mem)
+      OMPTargetTeamsDistributeSimdDirective(CollapsedNum, NumClauses);
+}
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 2c0b74a..21f5259 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1227,6 +1227,35 @@
   PrintOMPExecutableDirective(Node);
 }
 
+void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
+  Indent() << "#pragma omp target teams ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
+    OMPTargetTeamsDistributeDirective *Node) {
+  Indent() << "#pragma omp target teams distribute ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
+    OMPTargetTeamsDistributeParallelForDirective *Node) {
+  Indent() << "#pragma omp target teams distribute parallel for ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
+    OMPTargetTeamsDistributeParallelForSimdDirective *Node) {
+  Indent() << "#pragma omp target teams distribute parallel for simd ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
+    OMPTargetTeamsDistributeSimdDirective *Node) {
+  Indent() << "#pragma omp target teams distribute simd ";
+  PrintOMPExecutableDirective(Node);
+}
+
 //===----------------------------------------------------------------------===//
 //  Expr printing methods.
 //===----------------------------------------------------------------------===//
@@ -1705,6 +1734,18 @@
   OS << "}";
 }
 
+void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
+  // There's no way to express this expression in any of our supported
+  // languages, so just emit something terse and (hopefully) clear.
+  OS << "{";
+  PrintExpr(Node->getSubExpr());
+  OS << "}";
+}
+
+void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
+  OS << "*";
+}
+
 void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
   OS << "(";
   for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
@@ -2434,6 +2475,13 @@
   PrintExpr(S->getOperand());
 }
 
+
+void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
+  OS << "co_await ";
+  PrintExpr(S->getOperand());
+}
+
+
 void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
   OS << "co_yield ";
   PrintExpr(S->getOperand());
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index d8185d3..f1fbe28 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -19,20 +19,22 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprOpenMP.h"
+#include "clang/AST/ODRHash.h"
 #include "clang/AST/StmtVisitor.h"
 #include "llvm/ADT/FoldingSet.h"
 using namespace clang;
 
 namespace {
   class StmtProfiler : public ConstStmtVisitor<StmtProfiler> {
+  protected:
     llvm::FoldingSetNodeID &ID;
-    const ASTContext &Context;
     bool Canonical;
 
   public:
-    StmtProfiler(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
-                 bool Canonical)
-      : ID(ID), Context(Context), Canonical(Canonical) { }
+    StmtProfiler(llvm::FoldingSetNodeID &ID, bool Canonical)
+        : ID(ID), Canonical(Canonical) {}
+
+    virtual ~StmtProfiler() {}
 
     void VisitStmt(const Stmt *S);
 
@@ -41,22 +43,25 @@
 
     /// \brief Visit a declaration that is referenced within an expression
     /// or statement.
-    void VisitDecl(const Decl *D);
+    virtual void VisitDecl(const Decl *D) = 0;
 
     /// \brief Visit a type that is referenced within an expression or
     /// statement.
-    void VisitType(QualType T);
+    virtual void VisitType(QualType T) = 0;
 
     /// \brief Visit a name that occurs within an expression or statement.
-    void VisitName(DeclarationName Name);
+    virtual void VisitName(DeclarationName Name) = 0;
+
+    /// \brief Visit identifiers that are not in Decl's or Type's.
+    virtual void VisitIdentifierInfo(IdentifierInfo *II) = 0;
 
     /// \brief Visit a nested-name-specifier that occurs within an expression
     /// or statement.
-    void VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
+    virtual void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) = 0;
 
     /// \brief Visit a template name that occurs within an expression or
     /// statement.
-    void VisitTemplateName(TemplateName Name);
+    virtual void VisitTemplateName(TemplateName Name) = 0;
 
     /// \brief Visit template arguments that occur within an expression or
     /// statement.
@@ -66,6 +71,127 @@
     /// \brief Visit a single template argument.
     void VisitTemplateArgument(const TemplateArgument &Arg);
   };
+
+  class StmtProfilerWithPointers : public StmtProfiler {
+    const ASTContext &Context;
+
+  public:
+    StmtProfilerWithPointers(llvm::FoldingSetNodeID &ID,
+                             const ASTContext &Context, bool Canonical)
+        : StmtProfiler(ID, Canonical), Context(Context) {}
+  private:
+    void VisitDecl(const Decl *D) override {
+      ID.AddInteger(D ? D->getKind() : 0);
+
+      if (Canonical && D) {
+        if (const NonTypeTemplateParmDecl *NTTP =
+                dyn_cast<NonTypeTemplateParmDecl>(D)) {
+          ID.AddInteger(NTTP->getDepth());
+          ID.AddInteger(NTTP->getIndex());
+          ID.AddBoolean(NTTP->isParameterPack());
+          VisitType(NTTP->getType());
+          return;
+        }
+
+        if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
+          // The Itanium C++ ABI uses the type, scope depth, and scope
+          // index of a parameter when mangling expressions that involve
+          // function parameters, so we will use the parameter's type for
+          // establishing function parameter identity. That way, our
+          // definition of "equivalent" (per C++ [temp.over.link]) is at
+          // least as strong as the definition of "equivalent" used for
+          // name mangling.
+          VisitType(Parm->getType());
+          ID.AddInteger(Parm->getFunctionScopeDepth());
+          ID.AddInteger(Parm->getFunctionScopeIndex());
+          return;
+        }
+
+        if (const TemplateTypeParmDecl *TTP =
+                dyn_cast<TemplateTypeParmDecl>(D)) {
+          ID.AddInteger(TTP->getDepth());
+          ID.AddInteger(TTP->getIndex());
+          ID.AddBoolean(TTP->isParameterPack());
+          return;
+        }
+
+        if (const TemplateTemplateParmDecl *TTP =
+                dyn_cast<TemplateTemplateParmDecl>(D)) {
+          ID.AddInteger(TTP->getDepth());
+          ID.AddInteger(TTP->getIndex());
+          ID.AddBoolean(TTP->isParameterPack());
+          return;
+        }
+      }
+
+      ID.AddPointer(D ? D->getCanonicalDecl() : nullptr);
+    }
+
+    void VisitType(QualType T) override {
+      if (Canonical && !T.isNull())
+        T = Context.getCanonicalType(T);
+
+      ID.AddPointer(T.getAsOpaquePtr());
+    }
+
+    void VisitName(DeclarationName Name) override {
+      ID.AddPointer(Name.getAsOpaquePtr());
+    }
+
+    void VisitIdentifierInfo(IdentifierInfo *II) override {
+      ID.AddPointer(II);
+    }
+
+    void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
+      if (Canonical)
+        NNS = Context.getCanonicalNestedNameSpecifier(NNS);
+      ID.AddPointer(NNS);
+    }
+
+    void VisitTemplateName(TemplateName Name) override {
+      if (Canonical)
+        Name = Context.getCanonicalTemplateName(Name);
+
+      Name.Profile(ID);
+    }
+  };
+
+  class StmtProfilerWithoutPointers : public StmtProfiler {
+    ODRHash &Hash;
+  public:
+    StmtProfilerWithoutPointers(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
+        : StmtProfiler(ID, false), Hash(Hash) {}
+
+  private:
+    void VisitType(QualType T) override {
+      Hash.AddQualType(T);
+    }
+
+    void VisitName(DeclarationName Name) override {
+      Hash.AddDeclarationName(Name);
+    }
+    void VisitIdentifierInfo(IdentifierInfo *II) override {
+      ID.AddBoolean(II);
+      if (II) {
+        Hash.AddIdentifierInfo(II);
+      }
+    }
+    void VisitDecl(const Decl *D) override {
+      ID.AddBoolean(D);
+      if (D) {
+        Hash.AddDecl(D);
+      }
+    }
+    void VisitTemplateName(TemplateName Name) override {
+      Hash.AddTemplateName(Name);
+    }
+    void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
+      ID.AddBoolean(NNS);
+      if (NNS) {
+        Hash.AddNestedNameSpecifier(NNS);
+      }
+    }
+  };
 }
 
 void StmtProfiler::VisitStmt(const Stmt *S) {
@@ -283,6 +409,7 @@
 }
 
 void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) {
+  VistOMPClauseWithPreInit(C);
   if (C->getCondition())
     Profiler->VisitStmt(C->getCondition());
 }
@@ -293,6 +420,7 @@
 }
 
 void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
+  VistOMPClauseWithPreInit(C);
   if (C->getNumThreads())
     Profiler->VisitStmt(C->getNumThreads());
 }
@@ -495,11 +623,13 @@
   VisitOMPClauseList(C);
 }
 void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
+  VistOMPClauseWithPreInit(C);
   if (C->getNumTeams())
     Profiler->VisitStmt(C->getNumTeams());
 }
 void OMPClauseProfiler::VisitOMPThreadLimitClause(
     const OMPThreadLimitClause *C) {
+  VistOMPClauseWithPreInit(C);
   if (C->getThreadLimit())
     Profiler->VisitStmt(C->getThreadLimit());
 }
@@ -748,6 +878,31 @@
   VisitOMPLoopDirective(S);
 }
 
+void StmtProfiler::VisitOMPTargetTeamsDirective(
+    const OMPTargetTeamsDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPTargetTeamsDistributeDirective(
+    const OMPTargetTeamsDistributeDirective *S) {
+  VisitOMPLoopDirective(S);
+}
+
+void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForDirective(
+    const OMPTargetTeamsDistributeParallelForDirective *S) {
+  VisitOMPLoopDirective(S);
+}
+
+void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
+    const OMPTargetTeamsDistributeParallelForSimdDirective *S) {
+  VisitOMPLoopDirective(S);
+}
+
+void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective(
+    const OMPTargetTeamsDistributeSimdDirective *S) {
+  VisitOMPLoopDirective(S);
+}
+
 void StmtProfiler::VisitExpr(const Expr *S) {
   VisitStmt(S);
 }
@@ -824,7 +979,7 @@
       break;
 
     case OffsetOfNode::Identifier:
-      ID.AddPointer(ON.getFieldName());
+      VisitIdentifierInfo(ON.getFieldName());
       break;
 
     case OffsetOfNode::Base:
@@ -832,7 +987,7 @@
       break;
     }
   }
-  
+
   VisitExpr(S);
 }
 
@@ -972,6 +1127,14 @@
                    "initializer");
 }
 
+void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *S) {
+  VisitExpr(S);
+}
+
+void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *S) {
+  VisitExpr(S);
+}
+
 void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
   llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
 }
@@ -1414,7 +1577,7 @@
   if (S->getDestroyedTypeInfo())
     VisitType(S->getDestroyedType());
   else
-    ID.AddPointer(S->getDestroyedTypeIdentifier());
+    VisitIdentifierInfo(S->getDestroyedTypeIdentifier());
 }
 
 void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
@@ -1562,6 +1725,10 @@
   VisitExpr(S);
 }
 
+void StmtProfiler::VisitDependentCoawaitExpr(const DependentCoawaitExpr *S) {
+  VisitExpr(S);
+}
+
 void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr *S) {
   VisitExpr(S);
 }
@@ -1664,77 +1831,6 @@
   VisitExpr(S);
 }
 
-void StmtProfiler::VisitDecl(const Decl *D) {
-  ID.AddInteger(D? D->getKind() : 0);
-
-  if (Canonical && D) {
-    if (const NonTypeTemplateParmDecl *NTTP =
-          dyn_cast<NonTypeTemplateParmDecl>(D)) {
-      ID.AddInteger(NTTP->getDepth());
-      ID.AddInteger(NTTP->getIndex());
-      ID.AddBoolean(NTTP->isParameterPack());
-      VisitType(NTTP->getType());
-      return;
-    }
-
-    if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
-      // The Itanium C++ ABI uses the type, scope depth, and scope
-      // index of a parameter when mangling expressions that involve
-      // function parameters, so we will use the parameter's type for
-      // establishing function parameter identity. That way, our
-      // definition of "equivalent" (per C++ [temp.over.link]) is at
-      // least as strong as the definition of "equivalent" used for
-      // name mangling.
-      VisitType(Parm->getType());
-      ID.AddInteger(Parm->getFunctionScopeDepth());
-      ID.AddInteger(Parm->getFunctionScopeIndex());
-      return;
-    }
-
-    if (const TemplateTypeParmDecl *TTP =
-          dyn_cast<TemplateTypeParmDecl>(D)) {
-      ID.AddInteger(TTP->getDepth());
-      ID.AddInteger(TTP->getIndex());
-      ID.AddBoolean(TTP->isParameterPack());
-      return;
-    }
-
-    if (const TemplateTemplateParmDecl *TTP =
-          dyn_cast<TemplateTemplateParmDecl>(D)) {
-      ID.AddInteger(TTP->getDepth());
-      ID.AddInteger(TTP->getIndex());
-      ID.AddBoolean(TTP->isParameterPack());
-      return;
-    }
-  }
-
-  ID.AddPointer(D? D->getCanonicalDecl() : nullptr);
-}
-
-void StmtProfiler::VisitType(QualType T) {
-  if (Canonical)
-    T = Context.getCanonicalType(T);
-
-  ID.AddPointer(T.getAsOpaquePtr());
-}
-
-void StmtProfiler::VisitName(DeclarationName Name) {
-  ID.AddPointer(Name.getAsOpaquePtr());
-}
-
-void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
-  if (Canonical)
-    NNS = Context.getCanonicalNestedNameSpecifier(NNS);
-  ID.AddPointer(NNS);
-}
-
-void StmtProfiler::VisitTemplateName(TemplateName Name) {
-  if (Canonical)
-    Name = Context.getCanonicalTemplateName(Name);
-
-  Name.Profile(ID);
-}
-
 void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
                                           unsigned NumArgs) {
   ID.AddInteger(NumArgs);
@@ -1784,6 +1880,12 @@
 
 void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
                    bool Canonical) const {
-  StmtProfiler Profiler(ID, Context, Canonical);
+  StmtProfilerWithPointers Profiler(ID, Context, Canonical);
+  Profiler.Visit(this);
+}
+
+void Stmt::ProcessODRHash(llvm::FoldingSetNodeID &ID,
+                          class ODRHash &Hash) const {
+  StmtProfilerWithoutPointers Profiler(ID, Hash);
   Profiler.Visit(this);
 }
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index b1c88f9..e4998c3 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -243,6 +243,31 @@
   return None; 
 }
 
+QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
+  switch (getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Type:
+  case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
+  case TemplateArgument::Pack:
+    return QualType();
+
+  case TemplateArgument::Integral:
+    return getIntegralType();
+
+  case TemplateArgument::Expression:
+    return getAsExpr()->getType();
+
+  case TemplateArgument::Declaration:
+    return getParamTypeForDecl();
+
+  case TemplateArgument::NullPtr:
+    return getNullPtrType();
+  }
+
+  llvm_unreachable("Invalid TemplateArgument Kind!");
+}
+
 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
                                const ASTContext &Context) const {
   ID.AddInteger(getKind());
@@ -428,10 +453,6 @@
 // TemplateArgumentLoc Implementation
 //===----------------------------------------------------------------------===//
 
-TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
-  memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
-}
-
 SourceRange TemplateArgumentLoc::getSourceRange() const {
   switch (Argument.getKind()) {
   case TemplateArgument::Expression:
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 0d0cd2e..50bebd5 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1559,61 +1559,79 @@
 }
 
 namespace {
-  class GetContainedAutoVisitor :
-    public TypeVisitor<GetContainedAutoVisitor, AutoType*> {
+  class GetContainedDeducedTypeVisitor :
+    public TypeVisitor<GetContainedDeducedTypeVisitor, Type*> {
+    bool Syntactic;
   public:
-    using TypeVisitor<GetContainedAutoVisitor, AutoType*>::Visit;
-    AutoType *Visit(QualType T) {
+    GetContainedDeducedTypeVisitor(bool Syntactic = false)
+        : Syntactic(Syntactic) {}
+
+    using TypeVisitor<GetContainedDeducedTypeVisitor, Type*>::Visit;
+    Type *Visit(QualType T) {
       if (T.isNull())
         return nullptr;
       return Visit(T.getTypePtr());
     }
 
-    // The 'auto' type itself.
-    AutoType *VisitAutoType(const AutoType *AT) {
-      return const_cast<AutoType*>(AT);
+    // The deduced type itself.
+    Type *VisitDeducedType(const DeducedType *AT) {
+      return const_cast<DeducedType*>(AT);
     }
 
     // Only these types can contain the desired 'auto' type.
-    AutoType *VisitPointerType(const PointerType *T) {
+    Type *VisitElaboratedType(const ElaboratedType *T) {
+      return Visit(T->getNamedType());
+    }
+    Type *VisitPointerType(const PointerType *T) {
       return Visit(T->getPointeeType());
     }
-    AutoType *VisitBlockPointerType(const BlockPointerType *T) {
+    Type *VisitBlockPointerType(const BlockPointerType *T) {
       return Visit(T->getPointeeType());
     }
-    AutoType *VisitReferenceType(const ReferenceType *T) {
+    Type *VisitReferenceType(const ReferenceType *T) {
       return Visit(T->getPointeeTypeAsWritten());
     }
-    AutoType *VisitMemberPointerType(const MemberPointerType *T) {
+    Type *VisitMemberPointerType(const MemberPointerType *T) {
       return Visit(T->getPointeeType());
     }
-    AutoType *VisitArrayType(const ArrayType *T) {
+    Type *VisitArrayType(const ArrayType *T) {
       return Visit(T->getElementType());
     }
-    AutoType *VisitDependentSizedExtVectorType(
+    Type *VisitDependentSizedExtVectorType(
       const DependentSizedExtVectorType *T) {
       return Visit(T->getElementType());
     }
-    AutoType *VisitVectorType(const VectorType *T) {
+    Type *VisitVectorType(const VectorType *T) {
       return Visit(T->getElementType());
     }
-    AutoType *VisitFunctionType(const FunctionType *T) {
+    Type *VisitFunctionProtoType(const FunctionProtoType *T) {
+      if (Syntactic && T->hasTrailingReturn())
+        return const_cast<FunctionProtoType*>(T);
+      return VisitFunctionType(T);
+    }
+    Type *VisitFunctionType(const FunctionType *T) {
       return Visit(T->getReturnType());
     }
-    AutoType *VisitParenType(const ParenType *T) {
+    Type *VisitParenType(const ParenType *T) {
       return Visit(T->getInnerType());
     }
-    AutoType *VisitAttributedType(const AttributedType *T) {
+    Type *VisitAttributedType(const AttributedType *T) {
       return Visit(T->getModifiedType());
     }
-    AutoType *VisitAdjustedType(const AdjustedType *T) {
+    Type *VisitAdjustedType(const AdjustedType *T) {
       return Visit(T->getOriginalType());
     }
   };
 }
 
-AutoType *Type::getContainedAutoType() const {
-  return GetContainedAutoVisitor().Visit(this);
+DeducedType *Type::getContainedDeducedType() const {
+  return cast_or_null<DeducedType>(
+      GetContainedDeducedTypeVisitor().Visit(this));
+}
+
+bool Type::hasAutoForTrailingReturnType() const {
+  return dyn_cast_or_null<FunctionType>(
+      GetContainedDeducedTypeVisitor(true).Visit(this));
 }
 
 bool Type::hasIntegerRepresentation() const {
@@ -2630,8 +2648,6 @@
     return "clk_event_t";
   case OCLQueue:
     return "queue_t";
-  case OCLNDRange:
-    return "ndrange_t";
   case OCLReserveID:
     return "reserve_id_t";
   case OMPArraySection:
@@ -3365,6 +3381,7 @@
     return CachedProperties(ExternalLinkage, false);
 
   case Type::Auto:
+  case Type::DeducedTemplateSpecialization:
     // Give non-deduced 'auto' types external linkage. We should only see them
     // here in error recovery.
     return CachedProperties(ExternalLinkage, false);
@@ -3472,6 +3489,7 @@
     return LinkageInfo::external();
 
   case Type::Auto:
+  case Type::DeducedTemplateSpecialization:
     return LinkageInfo::external();
 
   case Type::Record:
@@ -3608,7 +3626,8 @@
 
   // auto is considered dependent when it isn't deduced.
   case Type::Auto:
-    return !cast<AutoType>(type.getTypePtr())->isDeduced();
+  case Type::DeducedTemplateSpecialization:
+    return !cast<DeducedType>(type.getTypePtr())->isDeduced();
 
   case Type::Builtin:
     switch (cast<BuiltinType>(type.getTypePtr())->getKind()) {
@@ -3640,7 +3659,6 @@
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
-    case BuiltinType::OCLNDRange:
     case BuiltinType::OCLReserveID:
     case BuiltinType::BuiltinFn:
     case BuiltinType::NullPtr:
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index 7242858..c9a2686 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -340,7 +340,6 @@
   case BuiltinType::OCLEvent:
   case BuiltinType::OCLClkEvent:
   case BuiltinType::OCLQueue:
-  case BuiltinType::OCLNDRange:
   case BuiltinType::OCLReserveID:
   case BuiltinType::BuiltinFn:
   case BuiltinType::OMPArraySection:
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index cccc908..84aa7dc 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -96,7 +96,7 @@
 
     static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);
     void spaceBeforePlaceHolder(raw_ostream &OS);
-    void printTypeSpec(const NamedDecl *D, raw_ostream &OS);
+    void printTypeSpec(NamedDecl *D, raw_ostream &OS);
 
     void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
     void printBefore(QualType T, raw_ostream &OS);
@@ -189,6 +189,7 @@
     case Type::Elaborated:
     case Type::TemplateTypeParm:
     case Type::SubstTemplateTypeParmPack:
+    case Type::DeducedTemplateSpecialization:
     case Type::TemplateSpecialization:
     case Type::InjectedClassName:
     case Type::DependentName:
@@ -797,7 +798,14 @@
   printAfter(T->getReturnType(), OS);
 }
 
-void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) {
+void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
+
+  // Compute the full nested-name-specifier for this type.
+  // In C, this will always be empty except when the type
+  // being printed is anonymous within other Record.
+  if (!Policy.SuppressScope)
+    AppendScope(D->getDeclContext(), OS);
+
   IdentifierInfo *II = D->getIdentifier();
   OS << II->getName();
   spaceBeforePlaceHolder(OS);
@@ -888,6 +896,24 @@
     printAfter(T->getDeducedType(), OS);
 }
 
+void TypePrinter::printDeducedTemplateSpecializationBefore(
+    const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
+  // If the type has been deduced, print the deduced type.
+  if (!T->getDeducedType().isNull()) {
+    printBefore(T->getDeducedType(), OS);
+  } else {
+    IncludeStrongLifetimeRAII Strong(Policy);
+    T->getTemplateName().print(OS, Policy);
+    spaceBeforePlaceHolder(OS);
+  }
+}
+void TypePrinter::printDeducedTemplateSpecializationAfter(
+    const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
+  // If the type has been deduced, print the deduced type.
+  if (!T->getDeducedType().isNull())
+    printAfter(T->getDeducedType(), OS);
+}
+
 void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
   IncludeStrongLifetimeRAII Strong(Policy);
 
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index 46308c2..e60ae33 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -777,9 +777,8 @@
   
   typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> 
     VBaseOffsetOffsetsMapTy;
-  
-  typedef llvm::DenseMap<BaseSubobject, uint64_t> 
-    AddressPointsMapTy;
+
+  typedef VTableLayout::AddressPointsMapTy AddressPointsMapTy;
 
   typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
 
@@ -817,7 +816,7 @@
   /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for
   /// the most derived class.
   VBaseOffsetOffsetsMapTy VBaseOffsetOffsets;
-  
+
   /// Components - The components of the vtable being built.
   SmallVector<VTableComponent, 64> Components;
 
@@ -982,6 +981,10 @@
   }
 
 public:
+  /// Component indices of the first component of each of the vtables in the
+  /// vtable group.
+  SmallVector<size_t, 4> VTableIndices;
+
   ItaniumVTableBuilder(ItaniumVTableContext &VTables,
                        const CXXRecordDecl *MostDerivedClass,
                        CharUnits MostDerivedClassOffset,
@@ -1028,20 +1031,8 @@
     return MethodVTableIndices.end();
   }
 
-  /// getNumVTableComponents - Return the number of components in the vtable
-  /// currently built.
-  uint64_t getNumVTableComponents() const {
-    return Components.size();
-  }
+  ArrayRef<VTableComponent> vtable_components() const { return Components; }
 
-  const VTableComponent *vtable_component_begin() const {
-    return Components.begin();
-  }
-  
-  const VTableComponent *vtable_component_end() const {
-    return Components.end();
-  }
-  
   AddressPointsMapTy::const_iterator address_points_begin() const {
     return AddressPoints.begin();
   }
@@ -1639,6 +1630,9 @@
     bool BaseIsVirtualInLayoutClass, CharUnits OffsetInLayoutClass) {
   assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!");
 
+  unsigned VTableIndex = Components.size();
+  VTableIndices.push_back(VTableIndex);
+
   // Add vcall and vbase offsets for this vtable.
   VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders,
                                      Base, BaseIsVirtualInLayoutClass, 
@@ -1695,9 +1689,11 @@
 
   // Add all address points.
   while (true) {
-    AddressPoints.insert(std::make_pair(
-      BaseSubobject(RD, OffsetInLayoutClass),
-      AddressPoint));
+    AddressPoints.insert(
+        std::make_pair(BaseSubobject(RD, OffsetInLayoutClass),
+                       VTableLayout::AddressPointLocation{
+                           unsigned(VTableIndices.size() - 1),
+                           unsigned(AddressPoint - VTableIndex)}));
 
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
     const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
@@ -1901,7 +1897,8 @@
   std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex;
   for (const auto &AP : AddressPoints) {
     const BaseSubobject &Base = AP.first;
-    uint64_t Index = AP.second;
+    uint64_t Index =
+        VTableIndices[AP.second.VTableIndex] + AP.second.AddressPointIndex;
 
     AddressPointsByIndex.insert(std::make_pair(Index, Base));
   }
@@ -2203,30 +2200,24 @@
 }
 }
 
-VTableLayout::VTableLayout(uint64_t NumVTableComponents,
-                           const VTableComponent *VTableComponents,
-                           uint64_t NumVTableThunks,
-                           const VTableThunkTy *VTableThunks,
-                           const AddressPointsMapTy &AddressPoints,
-                           bool IsMicrosoftABI)
-  : NumVTableComponents(NumVTableComponents),
-    VTableComponents(new VTableComponent[NumVTableComponents]),
-    NumVTableThunks(NumVTableThunks),
-    VTableThunks(new VTableThunkTy[NumVTableThunks]),
-    AddressPoints(AddressPoints),
-    IsMicrosoftABI(IsMicrosoftABI) {
-  std::copy(VTableComponents, VTableComponents+NumVTableComponents,
-            this->VTableComponents.get());
-  std::copy(VTableThunks, VTableThunks+NumVTableThunks,
-            this->VTableThunks.get());
-  std::sort(this->VTableThunks.get(),
-            this->VTableThunks.get() + NumVTableThunks,
+VTableLayout::VTableLayout(ArrayRef<size_t> VTableIndices,
+                           ArrayRef<VTableComponent> VTableComponents,
+                           ArrayRef<VTableThunkTy> VTableThunks,
+                           const AddressPointsMapTy &AddressPoints)
+    : VTableComponents(VTableComponents), VTableThunks(VTableThunks),
+      AddressPoints(AddressPoints) {
+  if (VTableIndices.size() <= 1)
+    assert(VTableIndices.size() == 1 && VTableIndices[0] == 0);
+  else
+    this->VTableIndices = OwningArrayRef<size_t>(VTableIndices);
+
+  std::sort(this->VTableThunks.begin(), this->VTableThunks.end(),
             [](const VTableLayout::VTableThunkTy &LHS,
                const VTableLayout::VTableThunkTy &RHS) {
-    assert((LHS.first != RHS.first || LHS.second == RHS.second) &&
-           "Different thunks should have unique indices!");
-    return LHS.first < RHS.first;
-  });
+              assert((LHS.first != RHS.first || LHS.second == RHS.second) &&
+                     "Different thunks should have unique indices!");
+              return LHS.first < RHS.first;
+            });
 }
 
 VTableLayout::~VTableLayout() { }
@@ -2284,9 +2275,8 @@
     VTableThunks(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
 
   return llvm::make_unique<VTableLayout>(
-      Builder.getNumVTableComponents(), Builder.vtable_component_begin(),
-      VTableThunks.size(), VTableThunks.data(), Builder.getAddressPoints(),
-      /*IsMicrosoftABI=*/false);
+      Builder.VTableIndices, Builder.vtable_components(), VTableThunks,
+      Builder.getAddressPoints());
 }
 
 void
@@ -2568,15 +2558,7 @@
                                   MethodVFTableLocations.end());
   }
 
-  uint64_t getNumVTableComponents() const { return Components.size(); }
-
-  const VTableComponent *vtable_component_begin() const {
-    return Components.begin();
-  }
-
-  const VTableComponent *vtable_component_end() const {
-    return Components.end();
-  }
+  ArrayRef<VTableComponent> vtable_components() const { return Components; }
 
   VTableThunksMapTy::const_iterator vtable_thunks_begin() const {
     return VTableThunks.begin();
@@ -3591,8 +3573,8 @@
     SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks(
         Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
     VFTableLayouts[id] = llvm::make_unique<VTableLayout>(
-        Builder.getNumVTableComponents(), Builder.vtable_component_begin(),
-        VTableThunks.size(), VTableThunks.data(), EmptyAddressPointsMap, true);
+        ArrayRef<size_t>{0}, Builder.vtable_components(), VTableThunks,
+        EmptyAddressPointsMap);
     Thunks.insert(Builder.thunks_begin(), Builder.thunks_end());
 
     for (const auto &Loc : Builder.vtable_locations()) {
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index b1309bc..d1cab80 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -232,6 +232,7 @@
   REGISTER_MATCHER(hasFalseExpression);
   REGISTER_MATCHER(hasGlobalStorage);
   REGISTER_MATCHER(hasImplicitDestinationType);
+  REGISTER_MATCHER(hasInClassInitializer);
   REGISTER_MATCHER(hasIncrement);
   REGISTER_MATCHER(hasIndex);
   REGISTER_MATCHER(hasInitializer);
diff --git a/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 8f3c70c..f0339ed 100644
--- a/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -216,18 +216,20 @@
 VariantMatcher::VariantMatcher() {}
 
 VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
-  return VariantMatcher(new SinglePayload(Matcher));
+  return VariantMatcher(std::make_shared<SinglePayload>(Matcher));
 }
 
 VariantMatcher
 VariantMatcher::PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers) {
-  return VariantMatcher(new PolymorphicPayload(std::move(Matchers)));
+  return VariantMatcher(
+      std::make_shared<PolymorphicPayload>(std::move(Matchers)));
 }
 
 VariantMatcher VariantMatcher::VariadicOperatorMatcher(
     DynTypedMatcher::VariadicOperator Op,
     std::vector<VariantMatcher> Args) {
-  return VariantMatcher(new VariadicOpPayload(Op, std::move(Args)));
+  return VariantMatcher(
+      std::make_shared<VariadicOpPayload>(Op, std::move(Args)));
 }
 
 llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp
index d202a04..56c812c 100644
--- a/lib/Analysis/BodyFarm.cpp
+++ b/lib/Analysis/BodyFarm.cpp
@@ -467,6 +467,8 @@
   ASTMaker M(Ctx);
 
   const VarDecl *selfVar = Prop->getGetterMethodDecl()->getSelfDecl();
+  if (!selfVar)
+    return nullptr;
 
   Expr *loadedIVar =
     M.makeObjCIvarRef(
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index a4470c1..2a2b3d7 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -1164,7 +1164,8 @@
 /// \brief Retrieve the type of the temporary object whose lifetime was 
 /// extended by a local reference with the given initializer.
 static QualType getReferenceInitTemporaryType(ASTContext &Context,
-                                              const Expr *Init) {
+                                              const Expr *Init,
+                                              bool *FoundMTE = nullptr) {
   while (true) {
     // Skip parentheses.
     Init = Init->IgnoreParens();
@@ -1179,6 +1180,8 @@
     if (const MaterializeTemporaryExpr *MTE
           = dyn_cast<MaterializeTemporaryExpr>(Init)) {
       Init = MTE->GetTemporaryExpr();
+      if (FoundMTE)
+        *FoundMTE = true;
       continue;
     }
     
@@ -1370,13 +1373,12 @@
     const Expr *Init = VD->getInit();
     if (!Init)
       return Scope;
-    if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init))
-      Init = EWC->getSubExpr();
-    if (!isa<MaterializeTemporaryExpr>(Init))
-      return Scope;
 
     // Lifetime-extending a temporary.
-    QT = getReferenceInitTemporaryType(*Context, Init);
+    bool FoundMTE = false;
+    QT = getReferenceInitTemporaryType(*Context, Init, &FoundMTE);
+    if (!FoundMTE)
+      return Scope;
   }
 
   // Check for constant size array. Set type to array element type.
@@ -1388,7 +1390,7 @@
 
   // Check if type is a C++ class with non-trivial destructor.
   if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl())
-    if (!CD->hasTrivialDestructor()) {
+    if (CD->hasDefinition() && !CD->hasTrivialDestructor()) {
       // Add the variable to scope
       Scope = createOrReuseLocalScope(Scope);
       Scope->addVar(VD);
@@ -1688,15 +1690,19 @@
     // we have been provided.
     ExitBlock = RHSBlock = createBlock(false);
 
+    // Even though KnownVal is only used in the else branch of the next
+    // conditional, tryEvaluateBool performs additional checking on the
+    // Expr, so it should be called unconditionally.
+    TryResult KnownVal = tryEvaluateBool(RHS);
+    if (!KnownVal.isKnown())
+      KnownVal = tryEvaluateBool(B);
+
     if (!Term) {
       assert(TrueBlock == FalseBlock);
       addSuccessor(RHSBlock, TrueBlock);
     }
     else {
       RHSBlock->setTerminator(Term);
-      TryResult KnownVal = tryEvaluateBool(RHS);
-      if (!KnownVal.isKnown())
-        KnownVal = tryEvaluateBool(B);
       addSuccessor(RHSBlock, TrueBlock, !KnownVal.isFalse());
       addSuccessor(RHSBlock, FalseBlock, !KnownVal.isTrue());
     }
@@ -2169,19 +2175,15 @@
   SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
 
   // Create local scope for C++17 if init-stmt if one exists.
-  if (Stmt *Init = I->getInit()) {
-    LocalScope::const_iterator BeginScopePos = ScopePos;
+  if (Stmt *Init = I->getInit())
     addLocalScopeForStmt(Init);
-    addAutomaticObjDtors(ScopePos, BeginScopePos, I);
-  }
 
   // Create local scope for possible condition variable.
   // Store scope position. Add implicit destructor.
-  if (VarDecl *VD = I->getConditionVariable()) {
-    LocalScope::const_iterator BeginScopePos = ScopePos;
+  if (VarDecl *VD = I->getConditionVariable())
     addLocalScopeForVarDecl(VD);
-    addAutomaticObjDtors(ScopePos, BeginScopePos, I);
-  }
+
+  addAutomaticObjDtors(ScopePos, save_scope_pos.get(), I);
 
   // The block we were processing is now finished.  Make it the successor
   // block.
@@ -2250,36 +2252,39 @@
   // removes infeasible paths from the control-flow graph by having the
   // control-flow transfer of '&&' or '||' go directly into the then/else
   // blocks directly.
-  if (!I->getConditionVariable())
-    if (BinaryOperator *Cond =
-            dyn_cast<BinaryOperator>(I->getCond()->IgnoreParens()))
-      if (Cond->isLogicalOp())
-        return VisitLogicalOperator(Cond, I, ThenBlock, ElseBlock).first;
+  BinaryOperator *Cond =
+      I->getConditionVariable()
+          ? nullptr
+          : dyn_cast<BinaryOperator>(I->getCond()->IgnoreParens());
+  CFGBlock *LastBlock;
+  if (Cond && Cond->isLogicalOp())
+    LastBlock = VisitLogicalOperator(Cond, I, ThenBlock, ElseBlock).first;
+  else {
+    // Now create a new block containing the if statement.
+    Block = createBlock(false);
 
-  // Now create a new block containing the if statement.
-  Block = createBlock(false);
+    // Set the terminator of the new block to the If statement.
+    Block->setTerminator(I);
 
-  // Set the terminator of the new block to the If statement.
-  Block->setTerminator(I);
+    // See if this is a known constant.
+    const TryResult &KnownVal = tryEvaluateBool(I->getCond());
 
-  // See if this is a known constant.
-  const TryResult &KnownVal = tryEvaluateBool(I->getCond());
+    // Add the successors.  If we know that specific branches are
+    // unreachable, inform addSuccessor() of that knowledge.
+    addSuccessor(Block, ThenBlock, /* isReachable = */ !KnownVal.isFalse());
+    addSuccessor(Block, ElseBlock, /* isReachable = */ !KnownVal.isTrue());
 
-  // Add the successors.  If we know that specific branches are
-  // unreachable, inform addSuccessor() of that knowledge.
-  addSuccessor(Block, ThenBlock, /* isReachable = */ !KnownVal.isFalse());
-  addSuccessor(Block, ElseBlock, /* isReachable = */ !KnownVal.isTrue());
+    // Add the condition as the last statement in the new block.  This may
+    // create new blocks as the condition may contain control-flow.  Any newly
+    // created blocks will be pointed to be "Block".
+    LastBlock = addStmt(I->getCond());
 
-  // Add the condition as the last statement in the new block.  This may create
-  // new blocks as the condition may contain control-flow.  Any newly created
-  // blocks will be pointed to be "Block".
-  CFGBlock *LastBlock = addStmt(I->getCond());
-
-  // If the IfStmt contains a condition variable, add it and its
-  // initializer to the CFG.
-  if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) {
-    autoCreateBlock();
-    LastBlock = addStmt(const_cast<DeclStmt *>(DS));
+    // If the IfStmt contains a condition variable, add it and its
+    // initializer to the CFG.
+    if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) {
+      autoCreateBlock();
+      LastBlock = addStmt(const_cast<DeclStmt *>(DS));
+    }
   }
 
   // Finally, if the IfStmt contains a C++17 init-stmt, add it to the CFG.
@@ -3072,19 +3077,15 @@
   SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
 
   // Create local scope for C++17 switch init-stmt if one exists.
-  if (Stmt *Init = Terminator->getInit()) {
-    LocalScope::const_iterator BeginScopePos = ScopePos;
+  if (Stmt *Init = Terminator->getInit())
     addLocalScopeForStmt(Init);
-    addAutomaticObjDtors(ScopePos, BeginScopePos, Terminator);
-  }
 
   // Create local scope for possible condition variable.
   // Store scope position. Add implicit destructor.
-  if (VarDecl *VD = Terminator->getConditionVariable()) {
-    LocalScope::const_iterator SwitchBeginScopePos = ScopePos;
+  if (VarDecl *VD = Terminator->getConditionVariable())
     addLocalScopeForVarDecl(VD);
-    addAutomaticObjDtors(ScopePos, SwitchBeginScopePos, Terminator);
-  }
+
+  addAutomaticObjDtors(ScopePos, save_scope_pos.get(), Terminator);
 
   if (Block) {
     if (badCFG)
diff --git a/lib/Analysis/CallGraph.cpp b/lib/Analysis/CallGraph.cpp
index 0cb5a3f..6d9530b 100644
--- a/lib/Analysis/CallGraph.cpp
+++ b/lib/Analysis/CallGraph.cpp
@@ -55,13 +55,14 @@
   void addCalledDecl(Decl *D) {
     if (G->includeInGraph(D)) {
       CallGraphNode *CalleeNode = G->getOrInsertNode(D);
-      CallerNode->addCallee(CalleeNode, G);
+      CallerNode->addCallee(CalleeNode);
     }
   }
 
   void VisitCallExpr(CallExpr *CE) {
     if (Decl *D = getDeclFromCall(CE))
       addCalledDecl(D);
+    VisitChildren(CE);
   }
 
   // Adds may-call edges for the ObjC message sends.
@@ -154,7 +155,7 @@
   Node = llvm::make_unique<CallGraphNode>(F);
   // Make Root node a parent of all functions to make sure all are reachable.
   if (F)
-    Root->addCallee(Node.get(), this);
+    Root->addCallee(Node.get());
   return Node.get();
 }
 
diff --git a/lib/Analysis/OSLog.cpp b/lib/Analysis/OSLog.cpp
index 0418388..b298393 100644
--- a/lib/Analysis/OSLog.cpp
+++ b/lib/Analysis/OSLog.cpp
@@ -10,11 +10,11 @@
 #include "llvm/ADT/SmallBitVector.h"
 
 using namespace clang;
-using llvm::APInt;
 
 using clang::analyze_os_log::OSLogBufferItem;
 using clang::analyze_os_log::OSLogBufferLayout;
 
+namespace {
 class OSLogFormatStringHandler
     : public analyze_format_string::FormatStringHandler {
 private:
@@ -22,6 +22,9 @@
     const Expr *E = nullptr;
     Optional<OSLogBufferItem::Kind> Kind;
     Optional<unsigned> Size;
+    Optional<const Expr *> Count;
+    Optional<const Expr *> Precision;
+    Optional<const Expr *> FieldWidth;
     unsigned char Flags = 0;
   };
   SmallVector<ArgData, 4> ArgsData;
@@ -84,7 +87,7 @@
         ArgsData.back().Size = precision.getConstantAmount();
         break;
       case clang::analyze_format_string::OptionalAmount::Arg: // "%.*s"
-        ArgsData.back().Kind = OSLogBufferItem::CountKind;
+        ArgsData.back().Count = Args[precision.getArgIndex()];
         break;
       case clang::analyze_format_string::OptionalAmount::Invalid:
         return false;
@@ -100,7 +103,7 @@
         ArgsData.back().Size = precision.getConstantAmount();
         break;
       case clang::analyze_format_string::OptionalAmount::Arg: // "%.*P"
-        ArgsData.back().Kind = OSLogBufferItem::CountKind;
+        ArgsData.back().Count = Args[precision.getArgIndex()];
         break;
       case clang::analyze_format_string::OptionalAmount::Invalid:
         return false;
@@ -108,8 +111,14 @@
       break;
     }
     default:
+      if (FS.getPrecision().hasDataArgument()) {
+        ArgsData.back().Precision = Args[FS.getPrecision().getArgIndex()];
+      }
       break;
     }
+    if (FS.getFieldWidth().hasDataArgument()) {
+      ArgsData.back().FieldWidth = Args[FS.getFieldWidth().getArgIndex()];
+    }
 
     if (FS.isPrivate()) {
       ArgsData.back().Flags |= OSLogBufferItem::IsPrivate;
@@ -123,6 +132,22 @@
   void computeLayout(ASTContext &Ctx, OSLogBufferLayout &Layout) const {
     Layout.Items.clear();
     for (auto &Data : ArgsData) {
+      if (Data.FieldWidth) {
+        CharUnits Size = Ctx.getTypeSizeInChars((*Data.FieldWidth)->getType());
+        Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.FieldWidth,
+                                  Size, 0);
+      }
+      if (Data.Precision) {
+        CharUnits Size = Ctx.getTypeSizeInChars((*Data.Precision)->getType());
+        Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.Precision,
+                                  Size, 0);
+      }
+      if (Data.Count) {
+        // "%.*P" has an extra "count" that we insert before the argument.
+        CharUnits Size = Ctx.getTypeSizeInChars((*Data.Count)->getType());
+        Layout.Items.emplace_back(OSLogBufferItem::CountKind, *Data.Count, Size,
+                                  0);
+      }
       if (Data.Size)
         Layout.Items.emplace_back(Ctx, CharUnits::fromQuantity(*Data.Size),
                                   Data.Flags);
@@ -141,6 +166,7 @@
     }
   }
 };
+} // end anonymous namespace
 
 bool clang::analyze_os_log::computeOSLogBufferLayout(
     ASTContext &Ctx, const CallExpr *E, OSLogBufferLayout &Layout) {
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index 69d000c..a2f3203 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -218,11 +218,21 @@
     }
     case Stmt::UnaryOperatorClass: {
       const UnaryOperator *UO = cast<UnaryOperator>(S);
-      if (SilenceableCondVal) 
-        *SilenceableCondVal = UO->getSourceRange();      
-      return UO->getOpcode() == UO_LNot &&
-             isConfigurationValue(UO->getSubExpr(), PP, SilenceableCondVal,
-                                  IncludeIntegers, WrappedInParens);
+      if (UO->getOpcode() != UO_LNot)
+        return false;
+      bool SilenceableCondValNotSet =
+          SilenceableCondVal && SilenceableCondVal->getBegin().isInvalid();
+      bool IsSubExprConfigValue =
+          isConfigurationValue(UO->getSubExpr(), PP, SilenceableCondVal,
+                               IncludeIntegers, WrappedInParens);
+      // Update the silenceable condition value source range only if the range
+      // was set directly by the child expression.
+      if (SilenceableCondValNotSet &&
+          SilenceableCondVal->getBegin().isValid() &&
+          *SilenceableCondVal ==
+              UO->getSubExpr()->IgnoreCasts()->getSourceRange())
+        *SilenceableCondVal = UO->getSourceRange();
+      return IsSubExprConfigValue;
     }
     default:
       return false;
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 1f4316a..0c27ae4 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -16,6 +16,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CrashRecoveryContext.h"
@@ -131,13 +132,13 @@
 
   // Clear state related to #pragma diagnostic.
   DiagStates.clear();
-  DiagStatePoints.clear();
+  DiagStatesByLoc.clear();
   DiagStateOnPushStack.clear();
 
   // Create a DiagState and DiagStatePoint representing diagnostic changes
   // through command-line.
   DiagStates.emplace_back();
-  DiagStatePoints.push_back(DiagStatePoint(&DiagStates.back(), FullSourceLoc()));
+  DiagStatesByLoc.appendFirst(&DiagStates.back());
 }
 
 void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
@@ -157,27 +158,94 @@
   DelayedDiagArg2.clear();
 }
 
-DiagnosticsEngine::DiagStatePointsTy::iterator
-DiagnosticsEngine::GetDiagStatePointForLoc(SourceLocation L) const {
-  assert(!DiagStatePoints.empty());
-  assert(DiagStatePoints.front().Loc.isInvalid() &&
-         "Should have created a DiagStatePoint for command-line");
+void DiagnosticsEngine::DiagStateMap::appendFirst(
+                                             DiagState *State) {
+  assert(Files.empty() && "not first");
+  FirstDiagState = CurDiagState = State;
+  CurDiagStateLoc = SourceLocation();
+}
 
-  if (!SourceMgr)
-    return DiagStatePoints.end() - 1;
+void DiagnosticsEngine::DiagStateMap::append(SourceManager &SrcMgr,
+                                             SourceLocation Loc,
+                                             DiagState *State) {
+  CurDiagState = State;
+  CurDiagStateLoc = Loc;
 
-  FullSourceLoc Loc(L, *SourceMgr);
-  if (Loc.isInvalid())
-    return DiagStatePoints.end() - 1;
+  std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
+  unsigned Offset = Decomp.second;
+  for (File *F = getFile(SrcMgr, Decomp.first); F;
+       Offset = F->ParentOffset, F = F->Parent) {
+    F->HasLocalTransitions = true;
+    auto &Last = F->StateTransitions.back();
+    assert(Last.Offset <= Offset && "state transitions added out of order");
 
-  DiagStatePointsTy::iterator Pos = DiagStatePoints.end();
-  FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
-  if (LastStateChangePos.isValid() &&
-      Loc.isBeforeInTranslationUnitThan(LastStateChangePos))
-    Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(),
-                           DiagStatePoint(nullptr, Loc));
-  --Pos;
-  return Pos;
+    if (Last.Offset == Offset) {
+      if (Last.State == State)
+        break;
+      Last.State = State;
+      continue;
+    }
+
+    F->StateTransitions.push_back({State, Offset});
+  }
+}
+
+DiagnosticsEngine::DiagState *
+DiagnosticsEngine::DiagStateMap::lookup(SourceManager &SrcMgr,
+                                        SourceLocation Loc) const {
+  // Common case: we have not seen any diagnostic pragmas.
+  if (Files.empty())
+    return FirstDiagState;
+
+  std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
+  const File *F = getFile(SrcMgr, Decomp.first);
+  return F->lookup(Decomp.second);
+}
+
+DiagnosticsEngine::DiagState *
+DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const {
+  auto OnePastIt = std::upper_bound(
+      StateTransitions.begin(), StateTransitions.end(), Offset,
+      [](unsigned Offset, const DiagStatePoint &P) {
+        return Offset < P.Offset;
+      });
+  assert(OnePastIt != StateTransitions.begin() && "missing initial state");
+  return OnePastIt[-1].State;
+}
+
+DiagnosticsEngine::DiagStateMap::File *
+DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr,
+                                         FileID ID) const {
+  // Get or insert the File for this ID.
+  auto Range = Files.equal_range(ID);
+  if (Range.first != Range.second)
+    return &Range.first->second;
+  auto &F = Files.insert(Range.first, std::make_pair(ID, File()))->second;
+
+  // We created a new File; look up the diagnostic state at the start of it and
+  // initialize it.
+  if (ID.isValid()) {
+    std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedIncludedLoc(ID);
+    F.Parent = getFile(SrcMgr, Decomp.first);
+    F.ParentOffset = Decomp.second;
+    F.StateTransitions.push_back({F.Parent->lookup(Decomp.second), 0});
+  } else {
+    // This is the (imaginary) root file into which we pretend all top-level
+    // files are included; it descends from the initial state.
+    //
+    // FIXME: This doesn't guarantee that we use the same ordering as
+    // isBeforeInTranslationUnit in the cases where someone invented another
+    // top-level file and added diagnostic pragmas to it. See the code at the
+    // end of isBeforeInTranslationUnit for the quirks it deals with.
+    F.StateTransitions.push_back({FirstDiagState, 0});
+  }
+  return &F;
+}
+
+void DiagnosticsEngine::PushDiagStatePoint(DiagState *State,
+                                           SourceLocation Loc) {
+  assert(Loc.isValid() && "Adding invalid loc point");
+  DiagStatesByLoc.append(*SourceMgr, Loc, State);
 }
 
 void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
@@ -187,11 +255,8 @@
   assert((Diags->isBuiltinWarningOrExtension(Diag) ||
           (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
          "Cannot map errors into warnings!");
-  assert(!DiagStatePoints.empty());
   assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
 
-  FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc();
-  FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
   // Don't allow a mapping to a warning override an error/fatal mapping.
   if (Map == diag::Severity::Warning) {
     DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
@@ -202,50 +267,22 @@
   DiagnosticMapping Mapping = makeUserMapping(Map, L);
 
   // Common case; setting all the diagnostics of a group in one place.
-  if (Loc.isInvalid() || Loc == LastStateChangePos) {
-    GetCurDiagState()->setMapping(Diag, Mapping);
+  if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) &&
+      DiagStatesByLoc.getCurDiagState()) {
+    // FIXME: This is theoretically wrong: if the current state is shared with
+    // some other location (via push/pop) we will change the state for that
+    // other location as well. This cannot currently happen, as we can't update
+    // the diagnostic state at the same location at which we pop.
+    DiagStatesByLoc.getCurDiagState()->setMapping(Diag, Mapping);
     return;
   }
 
-  // Another common case; modifying diagnostic state in a source location
-  // after the previous one.
-  if ((Loc.isValid() && LastStateChangePos.isInvalid()) ||
-      LastStateChangePos.isBeforeInTranslationUnitThan(Loc)) {
-    // A diagnostic pragma occurred, create a new DiagState initialized with
-    // the current one and a new DiagStatePoint to record at which location
-    // the new state became active.
-    DiagStates.push_back(*GetCurDiagState());
-    PushDiagStatePoint(&DiagStates.back(), Loc);
-    GetCurDiagState()->setMapping(Diag, Mapping);
-    return;
-  }
-
-  // We allow setting the diagnostic state in random source order for
-  // completeness but it should not be actually happening in normal practice.
-
-  DiagStatePointsTy::iterator Pos = GetDiagStatePointForLoc(Loc);
-  assert(Pos != DiagStatePoints.end());
-
-  // Update all diagnostic states that are active after the given location.
-  for (DiagStatePointsTy::iterator
-         I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) {
-    I->State->setMapping(Diag, Mapping);
-  }
-
-  // If the location corresponds to an existing point, just update its state.
-  if (Pos->Loc == Loc) {
-    Pos->State->setMapping(Diag, Mapping);
-    return;
-  }
-
-  // Create a new state/point and fit it into the vector of DiagStatePoints
-  // so that the vector is always ordered according to location.
-  assert(Pos->Loc.isBeforeInTranslationUnitThan(Loc));
-  DiagStates.push_back(*Pos->State);
-  DiagState *NewState = &DiagStates.back();
-  NewState->setMapping(Diag, Mapping);
-  DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState,
-                                               FullSourceLoc(Loc, *SourceMgr)));
+  // A diagnostic pragma occurred, create a new DiagState initialized with
+  // the current one and a new DiagStatePoint to record at which location
+  // the new state became active.
+  DiagStates.push_back(*GetCurDiagState());
+  DiagStates.back().setMapping(Diag, Mapping);
+  PushDiagStatePoint(&DiagStates.back(), L);
 }
 
 bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
@@ -742,7 +779,10 @@
         //   "%diff{compare $ to $|other text}1,2"
         // treat it as:
         //   "compare %1 to %2"
-        const char *Pipe = ScanFormat(Argument, Argument + ArgumentLen, '|');
+        const char *ArgumentEnd = Argument + ArgumentLen;
+        const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|');
+        assert(ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd &&
+               "Found too many '|'s in a %diff modifier!");
         const char *FirstDollar = ScanFormat(Argument, Pipe, '$');
         const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$');
         const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) };
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 3c370f6..e0580af 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -411,11 +411,8 @@
   // to error.  Errors can only be mapped to fatal.
   diag::Severity Result = diag::Severity::Fatal;
 
-  DiagnosticsEngine::DiagStatePointsTy::iterator
-    Pos = Diag.GetDiagStatePointForLoc(Loc);
-  DiagnosticsEngine::DiagState *State = Pos->State;
-
   // Get the mapping information, or compute it lazily.
+  DiagnosticsEngine::DiagState *State = Diag.GetDiagStateForLoc(Loc);
   DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID);
 
   // TODO: Can a null severity really get here?
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index af424cd..5caa8a6 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -487,8 +487,10 @@
     if (name == "self") return OMF_self;
     if (name == "initialize") return OMF_initialize;
   }
- 
-  if (name == "performSelector") return OMF_performSelector;
+
+  if (name == "performSelector" || name == "performSelectorInBackground" ||
+      name == "performSelectorOnMainThread")
+    return OMF_performSelector;
 
   // The other method families may begin with a prefix of underscores.
   while (!name.empty() && name.front() == '_')
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index 80bbc24..ad814fd 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -27,13 +27,13 @@
 Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
-      Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID),
+      Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID),
       IsMissingRequirement(false), HasIncompatibleModuleFile(false),
       IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
       IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
       IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
       InferExportWildcard(false), ConfigMacrosExhaustive(false),
-      NoUndeclaredIncludes(false), NameVisibility(Hidden) {
+      NoUndeclaredIncludes(false), WithCodegen(false), NameVisibility(Hidden) {
   if (Parent) {
     if (!Parent->isAvailable())
       IsAvailable = false;
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index 025936e..5a8bb61 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -660,6 +660,56 @@
       break;
     }
     break;
+  case OMPD_target_teams:
+    switch (CKind) {
+#define OPENMP_TARGET_TEAMS_CLAUSE(Name)                                       \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_target_teams_distribute:
+    switch (CKind) {
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name)                            \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_target_teams_distribute_parallel_for:
+    switch (CKind) {
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name)               \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_target_teams_distribute_parallel_for_simd:
+    switch (CKind) {
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name)          \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_target_teams_distribute_simd:
+    switch (CKind) {
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name)                       \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
   case OMPD_declare_target:
   case OMPD_end_declare_target:
   case OMPD_unknown:
@@ -689,8 +739,11 @@
          DKind == OMPD_teams_distribute ||
          DKind == OMPD_teams_distribute_simd ||
          DKind == OMPD_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_teams_distribute_parallel_for;
-  // TODO add next directives.
+         DKind == OMPD_teams_distribute_parallel_for ||
+         DKind == OMPD_target_teams_distribute ||
+         DKind == OMPD_target_teams_distribute_parallel_for ||
+         DKind == OMPD_target_teams_distribute_parallel_for_simd ||
+         DKind == OMPD_target_teams_distribute_simd;
 }
 
 bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
@@ -703,8 +756,9 @@
          DKind == OMPD_distribute_parallel_for_simd ||
          DKind == OMPD_target_parallel_for_simd ||
          DKind == OMPD_teams_distribute_parallel_for_simd ||
-         DKind == OMPD_teams_distribute_parallel_for;
-  // TODO add next directives.
+         DKind == OMPD_teams_distribute_parallel_for ||
+         DKind == OMPD_target_teams_distribute_parallel_for ||
+         DKind == OMPD_target_teams_distribute_parallel_for_simd;
 }
 
 bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
@@ -719,15 +773,19 @@
          DKind == OMPD_distribute_parallel_for_simd ||
          DKind == OMPD_target_parallel_for_simd ||
          DKind == OMPD_teams_distribute_parallel_for ||
-         DKind == OMPD_teams_distribute_parallel_for_simd;
-  // TODO add next directives.
+         DKind == OMPD_teams_distribute_parallel_for_simd ||
+         DKind == OMPD_target_teams_distribute_parallel_for ||
+         DKind == OMPD_target_teams_distribute_parallel_for_simd;
 }
 
 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
-  // TODO add next directives.
   return DKind == OMPD_target || DKind == OMPD_target_parallel ||
          DKind == OMPD_target_parallel_for || 
-         DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd;
+         DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
+         DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute ||
+         DKind == OMPD_target_teams_distribute_parallel_for ||
+         DKind == OMPD_target_teams_distribute_parallel_for_simd ||
+         DKind == OMPD_target_teams_distribute_simd;
 }
 
 bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
@@ -735,12 +793,19 @@
          DKind == OMPD_target_exit_data || DKind == OMPD_target_update;
 }
 
-bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
+bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
   return DKind == OMPD_teams || DKind == OMPD_teams_distribute ||
          DKind == OMPD_teams_distribute_simd ||
          DKind == OMPD_teams_distribute_parallel_for_simd ||
          DKind == OMPD_teams_distribute_parallel_for;
-  // TODO add next directives.
+}
+
+bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
+  return isOpenMPNestingTeamsDirective(DKind) ||
+         DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute ||
+         DKind == OMPD_target_teams_distribute_parallel_for ||
+         DKind == OMPD_target_teams_distribute_parallel_for_simd ||
+         DKind == OMPD_target_teams_distribute_simd;
 }
 
 bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
@@ -749,8 +814,9 @@
          DKind == OMPD_distribute_parallel_for_simd ||
          DKind == OMPD_distribute_simd || DKind == OMPD_target_simd ||
          DKind == OMPD_teams_distribute_simd ||
-         DKind == OMPD_teams_distribute_parallel_for_simd;
-  // TODO add next directives.
+         DKind == OMPD_teams_distribute_parallel_for_simd ||
+         DKind == OMPD_target_teams_distribute_parallel_for_simd ||
+         DKind == OMPD_target_teams_distribute_simd;
 }
 
 bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) {
@@ -764,8 +830,11 @@
   return isOpenMPNestingDistributeDirective(Kind) ||
          Kind == OMPD_teams_distribute || Kind == OMPD_teams_distribute_simd ||
          Kind == OMPD_teams_distribute_parallel_for_simd ||
-         Kind == OMPD_teams_distribute_parallel_for;
-  // TODO add next directives.
+         Kind == OMPD_teams_distribute_parallel_for ||
+         Kind == OMPD_target_teams_distribute ||
+         Kind == OMPD_target_teams_distribute_parallel_for ||
+         Kind == OMPD_target_teams_distribute_parallel_for_simd ||
+         Kind == OMPD_target_teams_distribute_simd;
 }
 
 bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
@@ -788,5 +857,82 @@
          Kind == OMPD_distribute_simd || Kind == OMPD_teams_distribute ||
          Kind == OMPD_teams_distribute_simd ||
          Kind == OMPD_teams_distribute_parallel_for_simd ||
-         Kind == OMPD_teams_distribute_parallel_for;
+         Kind == OMPD_teams_distribute_parallel_for ||
+         Kind == OMPD_target_teams_distribute ||
+         Kind == OMPD_target_teams_distribute_parallel_for ||
+         Kind == OMPD_target_teams_distribute_parallel_for_simd ||
+         Kind == OMPD_target_teams_distribute_simd;
+}
+
+void clang::getOpenMPCaptureRegions(
+    SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
+    OpenMPDirectiveKind DKind) {
+  assert(DKind <= OMPD_unknown);
+  switch (DKind) {
+  case OMPD_parallel:
+  case OMPD_parallel_for:
+  case OMPD_parallel_for_simd:
+  case OMPD_parallel_sections:
+  case OMPD_distribute_parallel_for:
+    CaptureRegions.push_back(OMPD_parallel);
+    break;
+  case OMPD_target_teams:
+    CaptureRegions.push_back(OMPD_target);
+    CaptureRegions.push_back(OMPD_teams);
+    break;
+  case OMPD_teams:
+  case OMPD_simd:
+  case OMPD_for:
+  case OMPD_for_simd:
+  case OMPD_sections:
+  case OMPD_section:
+  case OMPD_single:
+  case OMPD_master:
+  case OMPD_critical:
+  case OMPD_taskgroup:
+  case OMPD_distribute:
+  case OMPD_ordered:
+  case OMPD_atomic:
+  case OMPD_target_data:
+  case OMPD_target:
+  case OMPD_target_parallel_for:
+  case OMPD_target_parallel_for_simd:
+  case OMPD_target_simd:
+  case OMPD_task:
+  case OMPD_taskloop:
+  case OMPD_taskloop_simd:
+  case OMPD_distribute_parallel_for_simd:
+  case OMPD_distribute_simd:
+  case OMPD_teams_distribute:
+  case OMPD_teams_distribute_simd:
+  case OMPD_teams_distribute_parallel_for_simd:
+  case OMPD_teams_distribute_parallel_for:
+  case OMPD_target_teams_distribute:
+  case OMPD_target_teams_distribute_parallel_for:
+  case OMPD_target_teams_distribute_parallel_for_simd:
+  case OMPD_target_teams_distribute_simd:
+    CaptureRegions.push_back(DKind);
+    break;
+  case OMPD_target_parallel:
+    CaptureRegions.push_back(OMPD_target);
+    CaptureRegions.push_back(OMPD_parallel);
+    break;
+  case OMPD_threadprivate:
+  case OMPD_taskyield:
+  case OMPD_barrier:
+  case OMPD_taskwait:
+  case OMPD_cancellation_point:
+  case OMPD_cancel:
+  case OMPD_flush:
+  case OMPD_target_enter_data:
+  case OMPD_target_exit_data:
+  case OMPD_declare_reduction:
+  case OMPD_declare_simd:
+  case OMPD_declare_target:
+  case OMPD_end_declare_target:
+  case OMPD_target_update:
+    llvm_unreachable("OpenMP Directive is not allowed");
+  case OMPD_unknown:
+    llvm_unreachable("Unknown OpenMP directive");
+  }
 }
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index 19cab14..b1b01e5 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -77,11 +77,11 @@
   UseZeroLengthBitfieldAlignment = false;
   UseExplicitBitFieldAlignment = true;
   ZeroLengthBitfieldBoundary = 0;
-  HalfFormat = &llvm::APFloat::IEEEhalf;
-  FloatFormat = &llvm::APFloat::IEEEsingle;
-  DoubleFormat = &llvm::APFloat::IEEEdouble;
-  LongDoubleFormat = &llvm::APFloat::IEEEdouble;
-  Float128Format = &llvm::APFloat::IEEEquad;
+  HalfFormat = &llvm::APFloat::IEEEhalf();
+  FloatFormat = &llvm::APFloat::IEEEsingle();
+  DoubleFormat = &llvm::APFloat::IEEEdouble();
+  LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+  Float128Format = &llvm::APFloat::IEEEquad();
   MCountName = "mcount";
   RegParmMax = 0;
   SSERegParmMax = 0;
@@ -227,12 +227,12 @@
 
   switch (BitWidth) {
   case 96:
-    if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended)
+    if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended())
       return LongDouble;
     break;
   case 128:
-    if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble ||
-        &getLongDoubleFormat() == &llvm::APFloat::IEEEquad)
+    if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() ||
+        &getLongDoubleFormat() == &llvm::APFloat::IEEEquad())
       return LongDouble;
     if (hasFloat128Type())
       return Float128;
@@ -309,7 +309,7 @@
     // to generating illegal code that uses 64bit doubles.
     if (DoubleWidth != FloatWidth) {
       DoubleWidth = DoubleAlign = 64;
-      DoubleFormat = &llvm::APFloat::IEEEdouble;
+      DoubleFormat = &llvm::APFloat::IEEEdouble();
     }
     LongDoubleWidth = LongDoubleAlign = 128;
 
@@ -323,9 +323,9 @@
     IntMaxType = SignedLongLong;
     Int64Type = SignedLong;
 
-    HalfFormat = &llvm::APFloat::IEEEhalf;
-    FloatFormat = &llvm::APFloat::IEEEsingle;
-    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    HalfFormat = &llvm::APFloat::IEEEhalf();
+    FloatFormat = &llvm::APFloat::IEEEsingle();
+    LongDoubleFormat = &llvm::APFloat::IEEEquad();
   }
 
   if (Opts.NewAlignOverride)
@@ -410,8 +410,8 @@
   return false;
 }
 
-StringRef
-TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const {
+StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name,
+                                                   bool ReturnCanonical) const {
   assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
 
   // Get rid of any register prefix.
@@ -436,7 +436,7 @@
       // Make sure the register that the additional name is for is within
       // the bounds of the register names from above.
       if (AN == Name && ARN.RegNum < Names.size())
-        return Name;
+        return ReturnCanonical ? Names[ARN.RegNum] : Name;
     }
 
   // Now check aliases.
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 9a74cdf..21d9ea1 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -512,7 +512,7 @@
     Builder.defineMacro("__unix__");
     Builder.defineMacro("__ELF__");
     if (Opts.POSIXThreads)
-      Builder.defineMacro("_POSIX_THREADS");
+      Builder.defineMacro("_REENTRANT");
 
     switch (Triple.getArch()) {
     default:
@@ -545,6 +545,8 @@
     Builder.defineMacro("__ELF__");
     if (Opts.POSIXThreads)
       Builder.defineMacro("_REENTRANT");
+    if (this->HasFloat128)
+      Builder.defineMacro("__FLOAT128__");
   }
 public:
   OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
@@ -552,11 +554,11 @@
     this->TLSSupported = false;
 
       switch (Triple.getArch()) {
-        default:
         case llvm::Triple::x86:
         case llvm::Triple::x86_64:
-        case llvm::Triple::arm:
-        case llvm::Triple::sparc:
+          this->HasFloat128 = true;
+          // FALLTHROUGH
+        default:
           this->MCountName = "__mcount";
           break;
         case llvm::Triple::mips64:
@@ -809,7 +811,7 @@
     this->PtrDiffType = TargetInfo::SignedInt;
     this->IntPtrType = TargetInfo::SignedInt;
     // RegParmMax is inherited from the underlying architecture.
-    this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+    this->LongDoubleFormat = &llvm::APFloat::IEEEdouble();
     if (Triple.getArch() == llvm::Triple::arm) {
       // Handled in ARM's setABI().
     } else if (Triple.getArch() == llvm::Triple::x86) {
@@ -906,7 +908,7 @@
       HasBPERMD(false), HasExtDiv(false), HasP9Vector(false) {
     SimdDefaultAlign = 128;
     LongDoubleWidth = LongDoubleAlign = 128;
-    LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
+    LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble();
   }
 
   /// \brief Flags for architecture specific defines.
@@ -1146,7 +1148,7 @@
 
   bool useFloat128ManglingForLongDouble() const override {
     return LongDoubleWidth == 128 &&
-           LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble &&
+           LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble() &&
            getTriple().isOSBinFormatELF();
   }
 };
@@ -1232,6 +1234,11 @@
   if (LongDoubleWidth == 128)
     Builder.defineMacro("__LONG_DOUBLE_128__");
 
+  // Define this for elfv2 (64-bit only) or 64-bit darwin.
+  if (ABI == "elfv2" ||
+      (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64))
+    Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
+
   if (Opts.AltiVec) {
     Builder.defineMacro("__VEC__", "10206");
     Builder.defineMacro("__ALTIVEC__");
@@ -1650,7 +1657,7 @@
 
     if (getTriple().getOS() == llvm::Triple::FreeBSD) {
       LongDoubleWidth = LongDoubleAlign = 64;
-      LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+      LongDoubleFormat = &llvm::APFloat::IEEEdouble();
     }
 
     // PPC32 supports atomics up to 4 bytes.
@@ -1684,7 +1691,7 @@
     switch (getTriple().getOS()) {
     case llvm::Triple::FreeBSD:
       LongDoubleWidth = LongDoubleAlign = 64;
-      LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+      LongDoubleFormat = &llvm::APFloat::IEEEdouble();
       break;
     case llvm::Triple::NetBSD:
       IntMaxType = SignedLongLong;
@@ -1751,30 +1758,57 @@
   static const char *const GCCRegNames[];
   static const Builtin::Info BuiltinInfo[];
   CudaArch GPU;
+  std::unique_ptr<TargetInfo> HostTarget;
 
 public:
-  NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+  NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts,
+                  unsigned TargetPointerWidth)
       : TargetInfo(Triple) {
+    assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) &&
+           "NVPTX only supports 32- and 64-bit modes.");
+
     TLSSupported = false;
-    LongWidth = LongAlign = 64;
     AddrSpaceMap = &NVPTXAddrSpaceMap;
     UseAddrSpaceMapMangling = true;
+
     // Define available target features
     // These must be defined in sorted order!
     NoAsmVariants = true;
     GPU = CudaArch::SM_20;
 
+    if (TargetPointerWidth == 32)
+      resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64");
+    else
+      resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64");
+
     // If possible, get a TargetInfo for our host triple, so we can match its
     // types.
     llvm::Triple HostTriple(Opts.HostTriple);
-    if (HostTriple.isNVPTX())
-      return;
-    std::unique_ptr<TargetInfo> HostTarget(
-        AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
+    if (!HostTriple.isNVPTX())
+      HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
+
+    // If no host target, make some guesses about the data layout and return.
     if (!HostTarget) {
+      LongWidth = LongAlign = TargetPointerWidth;
+      PointerWidth = PointerAlign = TargetPointerWidth;
+      switch (TargetPointerWidth) {
+      case 32:
+        SizeType = TargetInfo::UnsignedInt;
+        PtrDiffType = TargetInfo::SignedInt;
+        IntPtrType = TargetInfo::SignedInt;
+        break;
+      case 64:
+        SizeType = TargetInfo::UnsignedLong;
+        PtrDiffType = TargetInfo::SignedLong;
+        IntPtrType = TargetInfo::SignedLong;
+        break;
+      default:
+        llvm_unreachable("TargetPointerWidth must be 32 or 64");
+      }
       return;
     }
 
+    // Copy properties from host target.
     PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0);
     PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0);
     BoolWidth = HostTarget->getBoolWidth();
@@ -1924,16 +1958,26 @@
   }
   void setSupportedOpenCLOpts() override {
     auto &Opts = getSupportedOpenCLOpts();
-    Opts.cl_clang_storage_class_specifiers = 1;
-    Opts.cl_khr_gl_sharing = 1;
-    Opts.cl_khr_icd = 1;
+    Opts.support("cl_clang_storage_class_specifiers");
+    Opts.support("cl_khr_gl_sharing");
+    Opts.support("cl_khr_icd");
 
-    Opts.cl_khr_fp64 = 1;
-    Opts.cl_khr_byte_addressable_store = 1;
-    Opts.cl_khr_global_int32_base_atomics = 1;
-    Opts.cl_khr_global_int32_extended_atomics = 1;
-    Opts.cl_khr_local_int32_base_atomics = 1;
-    Opts.cl_khr_local_int32_extended_atomics = 1;
+    Opts.support("cl_khr_fp64");
+    Opts.support("cl_khr_byte_addressable_store");
+    Opts.support("cl_khr_global_int32_base_atomics");
+    Opts.support("cl_khr_global_int32_extended_atomics");
+    Opts.support("cl_khr_local_int32_base_atomics");
+    Opts.support("cl_khr_local_int32_extended_atomics");
+  }
+
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+    // CUDA compilations support all of the host's calling conventions.
+    //
+    // TODO: We should warn if you apply a non-default CC to anything other than
+    // a host function.
+    if (HostTarget)
+      return HostTarget->checkCallingConvention(CC);
+    return CCCR_Warning;
   }
 };
 
@@ -1953,31 +1997,6 @@
   return llvm::makeArrayRef(GCCRegNames);
 }
 
-class NVPTX32TargetInfo : public NVPTXTargetInfo {
-public:
-  NVPTX32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
-      : NVPTXTargetInfo(Triple, Opts) {
-    LongWidth = LongAlign = 32;
-    PointerWidth = PointerAlign = 32;
-    SizeType = TargetInfo::UnsignedInt;
-    PtrDiffType = TargetInfo::SignedInt;
-    IntPtrType = TargetInfo::SignedInt;
-    resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64");
-  }
-};
-
-class NVPTX64TargetInfo : public NVPTXTargetInfo {
-public:
-  NVPTX64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
-      : NVPTXTargetInfo(Triple, Opts) {
-    PointerWidth = PointerAlign = 64;
-    SizeType = TargetInfo::UnsignedLong;
-    PtrDiffType = TargetInfo::SignedLong;
-    IntPtrType = TargetInfo::SignedLong;
-    resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64");
-  }
-};
-
 static const unsigned AMDGPUAddrSpaceMap[] = {
   1,    // opencl_global
   3,    // opencl_local
@@ -2017,7 +2036,8 @@
     GK_CAYMAN,
     GK_GFX6,
     GK_GFX7,
-    GK_GFX8
+    GK_GFX8,
+    GK_GFX9
   } GPU;
 
   bool hasFP64:1;
@@ -2101,15 +2121,15 @@
     for (auto &I : TargetOpts.FeaturesAsWritten) {
       if (I == "+fp32-denormals" || I == "-fp32-denormals")
         hasFP32Denormals = true;
-      if (I == "+fp64-denormals" || I == "-fp64-denormals")
+      if (I == "+fp64-fp16-denormals" || I == "-fp64-fp16-denormals")
         hasFP64Denormals = true;
     }
     if (!hasFP32Denormals)
       TargetOpts.Features.push_back((Twine(hasFullSpeedFP32Denorms &&
           !CGOpts.FlushDenorm ? '+' : '-') + Twine("fp32-denormals")).str());
-    // Always do not flush fp64 denorms.
+    // Always do not flush fp64 or fp16 denorms.
     if (!hasFP64Denormals && hasFP64)
-      TargetOpts.Features.push_back("+fp64-denormals");
+      TargetOpts.Features.push_back("+fp64-fp16-denormals");
   }
 
   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
@@ -2194,6 +2214,8 @@
       .Case("gfx803",    GK_GFX8)
       .Case("gfx804",    GK_GFX8)
       .Case("gfx810",    GK_GFX8)
+      .Case("gfx900",    GK_GFX9)
+      .Case("gfx901",    GK_GFX9)
       .Default(GK_NONE);
   }
 
@@ -2208,27 +2230,27 @@
 
   void setSupportedOpenCLOpts() override {
     auto &Opts = getSupportedOpenCLOpts();
-    Opts.cl_clang_storage_class_specifiers = 1;
-    Opts.cl_khr_icd = 1;
+    Opts.support("cl_clang_storage_class_specifiers");
+    Opts.support("cl_khr_icd");
 
     if (hasFP64)
-      Opts.cl_khr_fp64 = 1;
+      Opts.support("cl_khr_fp64");
     if (GPU >= GK_EVERGREEN) {
-      Opts.cl_khr_byte_addressable_store = 1;
-      Opts.cl_khr_global_int32_base_atomics = 1;
-      Opts.cl_khr_global_int32_extended_atomics = 1;
-      Opts.cl_khr_local_int32_base_atomics = 1;
-      Opts.cl_khr_local_int32_extended_atomics = 1;
+      Opts.support("cl_khr_byte_addressable_store");
+      Opts.support("cl_khr_global_int32_base_atomics");
+      Opts.support("cl_khr_global_int32_extended_atomics");
+      Opts.support("cl_khr_local_int32_base_atomics");
+      Opts.support("cl_khr_local_int32_extended_atomics");
     }
     if (GPU >= GK_GFX6) {
-      Opts.cl_khr_fp16 = 1;
-      Opts.cl_khr_int64_base_atomics = 1;
-      Opts.cl_khr_int64_extended_atomics = 1;
-      Opts.cl_khr_mipmap_image = 1;
-      Opts.cl_khr_subgroups = 1;
-      Opts.cl_khr_3d_image_writes = 1;
-      Opts.cl_amd_media_ops = 1;
-      Opts.cl_amd_media_ops2 = 1;
+      Opts.support("cl_khr_fp16");
+      Opts.support("cl_khr_int64_base_atomics");
+      Opts.support("cl_khr_int64_extended_atomics");
+      Opts.support("cl_khr_mipmap_image");
+      Opts.support("cl_khr_subgroups");
+      Opts.support("cl_khr_3d_image_writes");
+      Opts.support("cl_amd_media_ops");
+      Opts.support("cl_amd_media_ops2");
     }
   }
 
@@ -2236,6 +2258,32 @@
     return LangAS::opencl_constant;
   }
 
+  /// \returns Target specific vtbl ptr address space.
+  unsigned getVtblPtrAddressSpace() const override {
+    // \todo: We currently have address spaces defined in AMDGPU Backend. It
+    // would be nice if we could use it here instead of using bare numbers (same
+    // applies to getDWARFAddressSpace).
+    return 2; // constant.
+  }
+
+  /// \returns If a target requires an address within a target specific address
+  /// space \p AddressSpace to be converted in order to be used, then return the
+  /// corresponding target specific DWARF address space.
+  ///
+  /// \returns Otherwise return None and no conversion will be emitted in the
+  /// DWARF.
+  Optional<unsigned> getDWARFAddressSpace(
+      unsigned AddressSpace) const override {
+    switch (AddressSpace) {
+    case 0: // LLVM Private.
+      return 1; // DWARF Private.
+    case 3: // LLVM Local.
+      return 2; // DWARF Local.
+    default:
+      return None;
+    }
+  }
+
   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
     switch (CC) {
       default:
@@ -2245,6 +2293,13 @@
         return CCCR_OK;
     }
   }
+
+  // In amdgcn target the null pointer in global, constant, and generic
+  // address space has value 0 but in private and local address space has
+  // value ~0.
+  uint64_t getNullPointerValue(unsigned AS) const override {
+    return AS == LangAS::opencl_local ? ~0 : 0;
+  }
 };
 
 const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = {
@@ -2326,9 +2381,13 @@
     case GK_GFX7:
       break;
 
+    case GK_GFX9:
+      Features["gfx9-insts"] = true;
+      LLVM_FALLTHROUGH;
     case GK_GFX8:
       Features["s-memrealtime"] = true;
       Features["16-bit-insts"] = true;
+      Features["dpp"] = true;
       break;
 
     case GK_NONE:
@@ -2470,11 +2529,10 @@
   bool HasXSAVEC = false;
   bool HasXSAVES = false;
   bool HasMWAITX = false;
+  bool HasCLZERO = false;
   bool HasPKU = false;
   bool HasCLFLUSHOPT = false;
-  bool HasPCOMMIT = false;
   bool HasCLWB = false;
-  bool HasUMIP = false;
   bool HasMOVBE = false;
   bool HasPREFETCHWT1 = false;
 
@@ -2644,6 +2702,12 @@
     CK_BDVER4,
     //@}
 
+    /// \name zen
+    /// Zen architecture processors.
+    //@{
+    CK_ZNVER1,
+    //@}
+
     /// This specification is deprecated and will be removed in the future.
     /// Users should prefer \see CK_K8.
     // FIXME: Warn on this when the CPU is set to it.
@@ -2725,6 +2789,7 @@
         .Case("bdver2", CK_BDVER2)
         .Case("bdver3", CK_BDVER3)
         .Case("bdver4", CK_BDVER4)
+        .Case("znver1", CK_ZNVER1)
         .Case("x86-64", CK_x86_64)
         .Case("geode", CK_Geode)
         .Default(CK_Generic);
@@ -2739,7 +2804,7 @@
 public:
   X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
       : TargetInfo(Triple) {
-    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
+    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
   }
   unsigned getFloatEvalMethod() const override {
     // X87 evaluates with 80 bits "long double" precision.
@@ -2782,6 +2847,40 @@
   const char *getClobbers() const override {
     return "~{dirflag},~{fpsr},~{flags}";
   }
+
+  StringRef getConstraintRegister(const StringRef &Constraint,
+                                  const StringRef &Expression) const override {
+    StringRef::iterator I, E;
+    for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
+      if (isalpha(*I))
+        break;
+    }
+    if (I == E)
+      return "";
+    switch (*I) {
+    // For the register constraints, return the matching register name
+    case 'a':
+      return "ax";
+    case 'b':
+      return "bx";
+    case 'c':
+      return "cx";
+    case 'd':
+      return "dx";
+    case 'S':
+      return "si";
+    case 'D':
+      return "di";
+    // In case the constraint is 'r' we need to return Expression
+    case 'r':
+      return Expression;
+    default:
+      // Default value if there is no constraint for the register
+      return "";
+    }
+    return "";
+  }
+
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override;
   static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level,
@@ -2890,6 +2989,7 @@
     case CK_BDVER2:
     case CK_BDVER3:
     case CK_BDVER4:
+    case CK_ZNVER1:
     case CK_x86_64:
       return true;
     }
@@ -2925,7 +3025,7 @@
   }
 
   void setSupportedOpenCLOpts() override {
-    getSupportedOpenCLOpts().setAll();
+    getSupportedOpenCLOpts().supportAll();
   }
 };
 
@@ -3006,8 +3106,7 @@
     setFeatureEnabledImpl(Features, "avx512ifma", true);
     setFeatureEnabledImpl(Features, "avx512vbmi", true);
     setFeatureEnabledImpl(Features, "sha", true);
-    setFeatureEnabledImpl(Features, "umip", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_SkylakeServer:
     setFeatureEnabledImpl(Features, "avx512f", true);
     setFeatureEnabledImpl(Features, "avx512cd", true);
@@ -3015,20 +3114,19 @@
     setFeatureEnabledImpl(Features, "avx512bw", true);
     setFeatureEnabledImpl(Features, "avx512vl", true);
     setFeatureEnabledImpl(Features, "pku", true);
-    setFeatureEnabledImpl(Features, "pcommit", true);
     setFeatureEnabledImpl(Features, "clwb", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_SkylakeClient:
     setFeatureEnabledImpl(Features, "xsavec", true);
     setFeatureEnabledImpl(Features, "xsaves", true);
     setFeatureEnabledImpl(Features, "mpx", true);
     setFeatureEnabledImpl(Features, "sgx", true);
     setFeatureEnabledImpl(Features, "clflushopt", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_Broadwell:
     setFeatureEnabledImpl(Features, "rdseed", true);
     setFeatureEnabledImpl(Features, "adx", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_Haswell:
     setFeatureEnabledImpl(Features, "avx2", true);
     setFeatureEnabledImpl(Features, "lzcnt", true);
@@ -3037,22 +3135,22 @@
     setFeatureEnabledImpl(Features, "rtm", true);
     setFeatureEnabledImpl(Features, "fma", true);
     setFeatureEnabledImpl(Features, "movbe", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_IvyBridge:
     setFeatureEnabledImpl(Features, "rdrnd", true);
     setFeatureEnabledImpl(Features, "f16c", true);
     setFeatureEnabledImpl(Features, "fsgsbase", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_SandyBridge:
     setFeatureEnabledImpl(Features, "avx", true);
     setFeatureEnabledImpl(Features, "xsave", true);
     setFeatureEnabledImpl(Features, "xsaveopt", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_Westmere:
   case CK_Silvermont:
     setFeatureEnabledImpl(Features, "aes", true);
     setFeatureEnabledImpl(Features, "pclmul", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_Nehalem:
     setFeatureEnabledImpl(Features, "sse4.2", true);
     setFeatureEnabledImpl(Features, "fxsr", true);
@@ -3112,7 +3210,7 @@
     setFeatureEnabledImpl(Features, "sse4a", true);
     setFeatureEnabledImpl(Features, "lzcnt", true);
     setFeatureEnabledImpl(Features, "popcnt", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_K8SSE3:
   case CK_OpteronSSE3:
   case CK_Athlon64SSE3:
@@ -3127,7 +3225,7 @@
     setFeatureEnabledImpl(Features, "bmi", true);
     setFeatureEnabledImpl(Features, "f16c", true);
     setFeatureEnabledImpl(Features, "xsaveopt", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_BTVER1:
     setFeatureEnabledImpl(Features, "ssse3", true);
     setFeatureEnabledImpl(Features, "sse4a", true);
@@ -3137,21 +3235,49 @@
     setFeatureEnabledImpl(Features, "cx16", true);
     setFeatureEnabledImpl(Features, "fxsr", true);
     break;
+  case CK_ZNVER1:
+    setFeatureEnabledImpl(Features, "adx", true);
+    setFeatureEnabledImpl(Features, "aes", true);
+    setFeatureEnabledImpl(Features, "avx2", true);
+    setFeatureEnabledImpl(Features, "bmi", true);
+    setFeatureEnabledImpl(Features, "bmi2", true);
+    setFeatureEnabledImpl(Features, "clflushopt", true);
+    setFeatureEnabledImpl(Features, "clzero", true);
+    setFeatureEnabledImpl(Features, "cx16", true);
+    setFeatureEnabledImpl(Features, "f16c", true);
+    setFeatureEnabledImpl(Features, "fma", true);
+    setFeatureEnabledImpl(Features, "fsgsbase", true);
+    setFeatureEnabledImpl(Features, "fxsr", true);
+    setFeatureEnabledImpl(Features, "lzcnt", true);
+    setFeatureEnabledImpl(Features, "mwaitx", true);
+    setFeatureEnabledImpl(Features, "movbe", true);
+    setFeatureEnabledImpl(Features, "pclmul", true);
+    setFeatureEnabledImpl(Features, "popcnt", true);
+    setFeatureEnabledImpl(Features, "prfchw", true);
+    setFeatureEnabledImpl(Features, "rdrnd", true);
+    setFeatureEnabledImpl(Features, "rdseed", true);
+    setFeatureEnabledImpl(Features, "sha", true);
+    setFeatureEnabledImpl(Features, "sse4a", true);
+    setFeatureEnabledImpl(Features, "xsave", true);
+    setFeatureEnabledImpl(Features, "xsavec", true);
+    setFeatureEnabledImpl(Features, "xsaveopt", true);
+    setFeatureEnabledImpl(Features, "xsaves", true);
+    break;
   case CK_BDVER4:
     setFeatureEnabledImpl(Features, "avx2", true);
     setFeatureEnabledImpl(Features, "bmi2", true);
     setFeatureEnabledImpl(Features, "mwaitx", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_BDVER3:
     setFeatureEnabledImpl(Features, "fsgsbase", true);
     setFeatureEnabledImpl(Features, "xsaveopt", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_BDVER2:
     setFeatureEnabledImpl(Features, "bmi", true);
     setFeatureEnabledImpl(Features, "fma", true);
     setFeatureEnabledImpl(Features, "f16c", true);
     setFeatureEnabledImpl(Features, "tbm", true);
-    // FALLTHROUGH
+    LLVM_FALLTHROUGH;
   case CK_BDVER1:
     // xop implies avx, sse4a and fma4.
     setFeatureEnabledImpl(Features, "xop", true);
@@ -3472,14 +3598,12 @@
       HasPKU = true;
     } else if (Feature == "+clflushopt") {
       HasCLFLUSHOPT = true;
-    } else if (Feature == "+pcommit") {
-      HasPCOMMIT = true;
     } else if (Feature == "+clwb") {
       HasCLWB = true;
-    } else if (Feature == "+umip") {
-      HasUMIP = true;
     } else if (Feature == "+prefetchwt1") {
       HasPREFETCHWT1 = true;
+    } else if (Feature == "+clzero") {
+      HasCLZERO = true;
     }
 
     X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
@@ -3688,6 +3812,9 @@
   case CK_BDVER4:
     defineCPUMacros(Builder, "bdver4");
     break;
+  case CK_ZNVER1:
+    defineCPUMacros(Builder, "znver1");
+    break;
   case CK_Geode:
     defineCPUMacros(Builder, "geode");
     break;
@@ -3794,6 +3921,18 @@
     Builder.defineMacro("__PKU__");
   if (HasCX16)
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
+  if (HasCLFLUSHOPT)
+    Builder.defineMacro("__CLFLUSHOPT__");
+  if (HasCLWB)
+    Builder.defineMacro("__CLWB__");
+  if (HasMPX)
+    Builder.defineMacro("__MPX__");
+  if (HasSGX)
+    Builder.defineMacro("__SGX__");
+  if (HasPREFETCHWT1)
+    Builder.defineMacro("__PREFETCHWT1__");
+  if (HasCLZERO)
+    Builder.defineMacro("__CLZERO__");
 
   // Each case falls through to the previous one here.
   switch (SSELevel) {
@@ -3880,6 +4019,7 @@
       .Case("bmi2", HasBMI2)
       .Case("clflushopt", HasCLFLUSHOPT)
       .Case("clwb", HasCLWB)
+      .Case("clzero", HasCLZERO)
       .Case("cx16", HasCX16)
       .Case("f16c", HasF16C)
       .Case("fma", HasFMA)
@@ -3893,7 +4033,6 @@
       .Case("movbe", HasMOVBE)
       .Case("mpx", HasMPX)
       .Case("pclmul", HasPCLMUL)
-      .Case("pcommit", HasPCOMMIT)
       .Case("pku", HasPKU)
       .Case("popcnt", HasPOPCNT)
       .Case("prefetchwt1", HasPREFETCHWT1)
@@ -3911,7 +4050,6 @@
       .Case("sse4.2", SSELevel >= SSE42)
       .Case("sse4a", XOPLevel >= SSE4A)
       .Case("tbm", HasTBM)
-      .Case("umip", HasUMIP)
       .Case("x86", true)
       .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
       .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
@@ -4290,7 +4428,7 @@
                             const TargetOptions &Opts)
       : WindowsX86_32TargetInfo(Triple, Opts) {
     LongDoubleWidth = LongDoubleAlign = 64;
-    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
   }
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override {
@@ -4389,7 +4527,7 @@
   MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
       : X86_32TargetInfo(Triple, Opts) {
     LongDoubleWidth = 64;
-    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
     resetDataLayout("e-m:e-p:32:32-i64:32-f64:32-f128:32-n8:16:32-a:0:32-S32");
     WIntType = UnsignedInt;
   }
@@ -4609,7 +4747,7 @@
                             const TargetOptions &Opts)
       : WindowsX86_64TargetInfo(Triple, Opts) {
     LongDoubleWidth = LongDoubleAlign = 64;
-    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
   }
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override {
@@ -4628,7 +4766,7 @@
     // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
     // with x86 FP ops. Weird.
     LongDoubleWidth = LongDoubleAlign = 128;
-    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
+    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
   }
 
   void getTargetDefines(const LangOptions &Opts,
@@ -4965,6 +5103,8 @@
       return "7M";
     case llvm::ARM::AK_ARMV7EM:
       return "7EM";
+    case llvm::ARM::AK_ARMV7VE:
+      return "7VE";
     case llvm::ARM::AK_ARMV8A:
       return "8A";
     case llvm::ARM::AK_ARMV8_1A:
@@ -5053,6 +5193,8 @@
       default:
         if (Triple.getOS() == llvm::Triple::NetBSD)
           setABI("apcs-gnu");
+        else if (Triple.getOS() == llvm::Triple::OpenBSD)
+          setABI("aapcs-linux");
         else
           setABI("aapcs");
         break;
@@ -5384,6 +5526,8 @@
         Builder.defineMacro("__ARM_VFPV3__");
       if (FPU & VFP4FPU)
         Builder.defineMacro("__ARM_VFPV4__");
+      if (FPU & FPARMV8)
+        Builder.defineMacro("__ARM_FPV5__");
     }
 
     // This only gets set when Neon instructions are actually available, unlike
@@ -5832,7 +5976,8 @@
 public:
   AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
       : TargetInfo(Triple), ABI("aapcs") {
-    if (getTriple().getOS() == llvm::Triple::NetBSD) {
+    if (getTriple().getOS() == llvm::Triple::NetBSD ||
+        getTriple().getOS() == llvm::Triple::OpenBSD) {
       WCharType = SignedInt;
 
       // NetBSD apparently prefers consistency across ARM targets to consistency
@@ -5851,7 +5996,7 @@
     MaxAtomicPromoteWidth = 128;
 
     LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
-    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad();
 
     // {} in inline assembly are neon specifiers, not assembly variant
     // specifiers.
@@ -5867,8 +6012,9 @@
     // AArch64 targets default to using the ARM C++ ABI.
     TheCXXABI.set(TargetCXXABI::GenericAArch64);
 
-    if (Triple.getOS() == llvm::Triple::Linux ||
-        Triple.getOS() == llvm::Triple::UnknownOS)
+    if (Triple.getOS() == llvm::Triple::Linux)
+      this->MCountName = "\01_mcount";
+    else if (Triple.getOS() == llvm::Triple::UnknownOS)
       this->MCountName = Opts.EABIVersion == "gnu" ? "\01_mcount" : "mcount";
   }
 
@@ -6210,7 +6356,7 @@
     UseSignedCharForObjCBool = false;
 
     LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
-    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
 
     TheCXXABI.set(TargetCXXABI::iOS64);
   }
@@ -6888,7 +7034,7 @@
     // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
     LongDoubleWidth = 128;
     LongDoubleAlign = 128;
-    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad();
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
 
@@ -6931,7 +7077,7 @@
     PointerWidth = PointerAlign = 64;
     LongDoubleWidth = 128;
     LongDoubleAlign = 64;
-    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad();
     DefaultAlignForAttributeAligned = 64;
     MinGlobalAlign = 16;
     resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64");
@@ -6944,6 +7090,15 @@
     Builder.defineMacro("__zarch__");
     Builder.defineMacro("__LONG_DOUBLE_128__");
 
+    const std::string ISARev = llvm::StringSwitch<std::string>(CPU)
+                                   .Cases("arch8", "z10", "8")
+                                   .Cases("arch9", "z196", "9")
+                                   .Cases("arch10", "zEC12", "10")
+                                   .Cases("arch11", "z13", "11")
+                                   .Default("");
+    if (!ISARev.empty())
+      Builder.defineMacro("__ARCH__", ISARev);
+
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
@@ -6951,6 +7106,8 @@
 
     if (HasTransactionalExecution)
       Builder.defineMacro("__HTM__");
+    if (HasVector)
+      Builder.defineMacro("__VX__");
     if (Opts.ZVector)
       Builder.defineMacro("__VEC__", "10301");
   }
@@ -7207,9 +7364,9 @@
     DoubleAlign = 32;
     LongDoubleWidth = 32;
     LongDoubleAlign = 32;
-    FloatFormat = &llvm::APFloat::IEEEsingle;
-    DoubleFormat = &llvm::APFloat::IEEEsingle;
-    LongDoubleFormat = &llvm::APFloat::IEEEsingle;
+    FloatFormat = &llvm::APFloat::IEEEsingle();
+    DoubleFormat = &llvm::APFloat::IEEEsingle();
+    LongDoubleFormat = &llvm::APFloat::IEEEsingle();
     resetDataLayout("E-p:32:32:32-i1:8:8-i8:8:32-"
                     "i16:16:32-i32:32:32-i64:32:32-"
                     "f32:32:32-f64:32:32-v64:32:32-"
@@ -7341,6 +7498,8 @@
   bool IsMicromips;
   bool IsNan2008;
   bool IsSingleFloat;
+  bool IsNoABICalls;
+  bool CanUseBSDABICalls;
   enum MipsFloatABI {
     HardFloat, SoftFloat
   } FloatABI;
@@ -7356,8 +7515,9 @@
 public:
   MipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
       : TargetInfo(Triple), IsMips16(false), IsMicromips(false),
-        IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat),
-        DspRev(NoDSP), HasMSA(false), HasFP64(false) {
+        IsNan2008(false), IsSingleFloat(false), IsNoABICalls(false),
+        CanUseBSDABICalls(false), FloatABI(HardFloat), DspRev(NoDSP),
+        HasMSA(false), HasFP64(false) {
     TheCXXABI.set(TargetCXXABI::GenericMIPS);
 
     setABI((getTriple().getArch() == llvm::Triple::mips ||
@@ -7366,6 +7526,9 @@
                : "n64");
 
     CPU = ABI == "o32" ? "mips32r2" : "mips64r2";
+
+    CanUseBSDABICalls = Triple.getOS() == llvm::Triple::FreeBSD ||
+                        Triple.getOS() == llvm::Triple::OpenBSD;
   }
 
   bool isNaN2008Default() const {
@@ -7419,7 +7582,7 @@
   void setO32ABITypes() {
     Int64Type = SignedLongLong;
     IntMaxType = Int64Type;
-    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
     LongDoubleWidth = LongDoubleAlign = 64;
     LongWidth = LongAlign = 32;
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
@@ -7431,10 +7594,10 @@
 
   void setN32N64ABITypes() {
     LongDoubleWidth = LongDoubleAlign = 128;
-    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad();
     if (getTriple().getOS() == llvm::Triple::FreeBSD) {
       LongDoubleWidth = LongDoubleAlign = 64;
-      LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+      LongDoubleFormat = &llvm::APFloat::IEEEdouble();
     }
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
     SuitableAlign = 128;
@@ -7442,7 +7605,11 @@
 
   void setN64ABITypes() {
     setN32N64ABITypes();
-    Int64Type = SignedLong;
+    if (getTriple().getOS() == llvm::Triple::OpenBSD) {
+      Int64Type = SignedLongLong;
+    } else {
+      Int64Type = SignedLong;
+    }
     IntMaxType = Int64Type;
     LongWidth = LongAlign = 64;
     PointerWidth = PointerAlign = 64;
@@ -7546,6 +7713,12 @@
     } else
       llvm_unreachable("Invalid ABI.");
 
+    if (!IsNoABICalls) {
+      Builder.defineMacro("__mips_abicalls");
+      if (CanUseBSDABICalls)
+        Builder.defineMacro("__ABICALLS__");
+    }
+
     Builder.defineMacro("__REGISTER_PREFIX__", "");
 
     switch (FloatABI) {
@@ -7760,6 +7933,8 @@
         IsNan2008 = true;
       else if (Feature == "-nan2008")
         IsNan2008 = false;
+      else if (Feature == "+noabicalls")
+        IsNoABICalls = true;
     }
 
     setDataLayout();
@@ -7980,7 +8155,7 @@
     SimdDefaultAlign = 128;
     SigAtomicType = SignedLong;
     LongDoubleWidth = LongDoubleAlign = 128;
-    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad();
     SizeType = UnsignedInt;
     PtrDiffType = SignedInt;
     IntPtrType = SignedInt;
@@ -8181,7 +8356,7 @@
   void setSupportedOpenCLOpts() override {
     // Assume all OpenCL extensions and optional core features are supported
     // for SPIR since it is a generic target.
-    getSupportedOpenCLOpts().setAll();
+    getSupportedOpenCLOpts().supportAll();
   }
 };
 
@@ -8287,7 +8462,7 @@
       : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
     SuitableAlign = 32;
     LongDoubleWidth = 64;
-    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
   }
 };
 
@@ -8296,7 +8471,7 @@
 public:
   AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
       : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
-    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad();
   }
 
   bool useFloat128ManglingForLongDouble() const override {
@@ -8342,6 +8517,451 @@
   }
 };
 
+/// Information about a specific microcontroller.
+struct MCUInfo {
+  const char *Name;
+  const char *DefineName;
+};
+
+// This list should be kept up-to-date with AVRDevices.td in LLVM.
+static ArrayRef<MCUInfo> AVRMcus = {
+  { "at90s1200", "__AVR_AT90S1200__" },
+  { "attiny11", "__AVR_ATtiny11__" },
+  { "attiny12", "__AVR_ATtiny12__" },
+  { "attiny15", "__AVR_ATtiny15__" },
+  { "attiny28", "__AVR_ATtiny28__" },
+  { "at90s2313", "__AVR_AT90S2313__" },
+  { "at90s2323", "__AVR_AT90S2323__" },
+  { "at90s2333", "__AVR_AT90S2333__" },
+  { "at90s2343", "__AVR_AT90S2343__" },
+  { "attiny22", "__AVR_ATtiny22__" },
+  { "attiny26", "__AVR_ATtiny26__" },
+  { "at86rf401", "__AVR_AT86RF401__" },
+  { "at90s4414", "__AVR_AT90S4414__" },
+  { "at90s4433", "__AVR_AT90S4433__" },
+  { "at90s4434", "__AVR_AT90S4434__" },
+  { "at90s8515", "__AVR_AT90S8515__" },
+  { "at90c8534", "__AVR_AT90c8534__" },
+  { "at90s8535", "__AVR_AT90S8535__" },
+  { "ata5272", "__AVR_ATA5272__" },
+  { "attiny13", "__AVR_ATtiny13__" },
+  { "attiny13a", "__AVR_ATtiny13A__" },
+  { "attiny2313", "__AVR_ATtiny2313__" },
+  { "attiny2313a", "__AVR_ATtiny2313A__" },
+  { "attiny24", "__AVR_ATtiny24__" },
+  { "attiny24a", "__AVR_ATtiny24A__" },
+  { "attiny4313", "__AVR_ATtiny4313__" },
+  { "attiny44", "__AVR_ATtiny44__" },
+  { "attiny44a", "__AVR_ATtiny44A__" },
+  { "attiny84", "__AVR_ATtiny84__" },
+  { "attiny84a", "__AVR_ATtiny84A__" },
+  { "attiny25", "__AVR_ATtiny25__" },
+  { "attiny45", "__AVR_ATtiny45__" },
+  { "attiny85", "__AVR_ATtiny85__" },
+  { "attiny261", "__AVR_ATtiny261__" },
+  { "attiny261a", "__AVR_ATtiny261A__" },
+  { "attiny461", "__AVR_ATtiny461__" },
+  { "attiny461a", "__AVR_ATtiny461A__" },
+  { "attiny861", "__AVR_ATtiny861__" },
+  { "attiny861a", "__AVR_ATtiny861A__" },
+  { "attiny87", "__AVR_ATtiny87__" },
+  { "attiny43u", "__AVR_ATtiny43U__" },
+  { "attiny48", "__AVR_ATtiny48__" },
+  { "attiny88", "__AVR_ATtiny88__" },
+  { "attiny828", "__AVR_ATtiny828__" },
+  { "at43usb355", "__AVR_AT43USB355__" },
+  { "at76c711", "__AVR_AT76C711__" },
+  { "atmega103", "__AVR_ATmega103__" },
+  { "at43usb320", "__AVR_AT43USB320__" },
+  { "attiny167", "__AVR_ATtiny167__" },
+  { "at90usb82", "__AVR_AT90USB82__" },
+  { "at90usb162", "__AVR_AT90USB162__" },
+  { "ata5505", "__AVR_ATA5505__" },
+  { "atmega8u2", "__AVR_ATmega8U2__" },
+  { "atmega16u2", "__AVR_ATmega16U2__" },
+  { "atmega32u2", "__AVR_ATmega32U2__" },
+  { "attiny1634", "__AVR_ATtiny1634__" },
+  { "atmega8", "__AVR_ATmega8__" },
+  { "ata6289", "__AVR_ATA6289__" },
+  { "atmega8a", "__AVR_ATmega8A__" },
+  { "ata6285", "__AVR_ATA6285__" },
+  { "ata6286", "__AVR_ATA6286__" },
+  { "atmega48", "__AVR_ATmega48__" },
+  { "atmega48a", "__AVR_ATmega48A__" },
+  { "atmega48pa", "__AVR_ATmega48PA__" },
+  { "atmega48p", "__AVR_ATmega48P__" },
+  { "atmega88", "__AVR_ATmega88__" },
+  { "atmega88a", "__AVR_ATmega88A__" },
+  { "atmega88p", "__AVR_ATmega88P__" },
+  { "atmega88pa", "__AVR_ATmega88PA__" },
+  { "atmega8515", "__AVR_ATmega8515__" },
+  { "atmega8535", "__AVR_ATmega8535__" },
+  { "atmega8hva", "__AVR_ATmega8HVA__" },
+  { "at90pwm1", "__AVR_AT90PWM1__" },
+  { "at90pwm2", "__AVR_AT90PWM2__" },
+  { "at90pwm2b", "__AVR_AT90PWM2B__" },
+  { "at90pwm3", "__AVR_AT90PWM3__" },
+  { "at90pwm3b", "__AVR_AT90PWM3B__" },
+  { "at90pwm81", "__AVR_AT90PWM81__" },
+  { "ata5790", "__AVR_ATA5790__" },
+  { "ata5795", "__AVR_ATA5795__" },
+  { "atmega16", "__AVR_ATmega16__" },
+  { "atmega16a", "__AVR_ATmega16A__" },
+  { "atmega161", "__AVR_ATmega161__" },
+  { "atmega162", "__AVR_ATmega162__" },
+  { "atmega163", "__AVR_ATmega163__" },
+  { "atmega164a", "__AVR_ATmega164A__" },
+  { "atmega164p", "__AVR_ATmega164P__" },
+  { "atmega164pa", "__AVR_ATmega164PA__" },
+  { "atmega165", "__AVR_ATmega165__" },
+  { "atmega165a", "__AVR_ATmega165A__" },
+  { "atmega165p", "__AVR_ATmega165P__" },
+  { "atmega165pa", "__AVR_ATmega165PA__" },
+  { "atmega168", "__AVR_ATmega168__" },
+  { "atmega168a", "__AVR_ATmega168A__" },
+  { "atmega168p", "__AVR_ATmega168P__" },
+  { "atmega168pa", "__AVR_ATmega168PA__" },
+  { "atmega169", "__AVR_ATmega169__" },
+  { "atmega169a", "__AVR_ATmega169A__" },
+  { "atmega169p", "__AVR_ATmega169P__" },
+  { "atmega169pa", "__AVR_ATmega169PA__" },
+  { "atmega32", "__AVR_ATmega32__" },
+  { "atmega32a", "__AVR_ATmega32A__" },
+  { "atmega323", "__AVR_ATmega323__" },
+  { "atmega324a", "__AVR_ATmega324A__" },
+  { "atmega324p", "__AVR_ATmega324P__" },
+  { "atmega324pa", "__AVR_ATmega324PA__" },
+  { "atmega325", "__AVR_ATmega325__" },
+  { "atmega325a", "__AVR_ATmega325A__" },
+  { "atmega325p", "__AVR_ATmega325P__" },
+  { "atmega325pa", "__AVR_ATmega325PA__" },
+  { "atmega3250", "__AVR_ATmega3250__" },
+  { "atmega3250a", "__AVR_ATmega3250A__" },
+  { "atmega3250p", "__AVR_ATmega3250P__" },
+  { "atmega3250pa", "__AVR_ATmega3250PA__" },
+  { "atmega328", "__AVR_ATmega328__" },
+  { "atmega328p", "__AVR_ATmega328P__" },
+  { "atmega329", "__AVR_ATmega329__" },
+  { "atmega329a", "__AVR_ATmega329A__" },
+  { "atmega329p", "__AVR_ATmega329P__" },
+  { "atmega329pa", "__AVR_ATmega329PA__" },
+  { "atmega3290", "__AVR_ATmega3290__" },
+  { "atmega3290a", "__AVR_ATmega3290A__" },
+  { "atmega3290p", "__AVR_ATmega3290P__" },
+  { "atmega3290pa", "__AVR_ATmega3290PA__" },
+  { "atmega406", "__AVR_ATmega406__" },
+  { "atmega64", "__AVR_ATmega64__" },
+  { "atmega64a", "__AVR_ATmega64A__" },
+  { "atmega640", "__AVR_ATmega640__" },
+  { "atmega644", "__AVR_ATmega644__" },
+  { "atmega644a", "__AVR_ATmega644A__" },
+  { "atmega644p", "__AVR_ATmega644P__" },
+  { "atmega644pa", "__AVR_ATmega644PA__" },
+  { "atmega645", "__AVR_ATmega645__" },
+  { "atmega645a", "__AVR_ATmega645A__" },
+  { "atmega645p", "__AVR_ATmega645P__" },
+  { "atmega649", "__AVR_ATmega649__" },
+  { "atmega649a", "__AVR_ATmega649A__" },
+  { "atmega649p", "__AVR_ATmega649P__" },
+  { "atmega6450", "__AVR_ATmega6450__" },
+  { "atmega6450a", "__AVR_ATmega6450A__" },
+  { "atmega6450p", "__AVR_ATmega6450P__" },
+  { "atmega6490", "__AVR_ATmega6490__" },
+  { "atmega6490a", "__AVR_ATmega6490A__" },
+  { "atmega6490p", "__AVR_ATmega6490P__" },
+  { "atmega64rfr2", "__AVR_ATmega64RFR2__" },
+  { "atmega644rfr2", "__AVR_ATmega644RFR2__" },
+  { "atmega16hva", "__AVR_ATmega16HVA__" },
+  { "atmega16hva2", "__AVR_ATmega16HVA2__" },
+  { "atmega16hvb", "__AVR_ATmega16HVB__" },
+  { "atmega16hvbrevb", "__AVR_ATmega16HVBREVB__" },
+  { "atmega32hvb", "__AVR_ATmega32HVB__" },
+  { "atmega32hvbrevb", "__AVR_ATmega32HVBREVB__" },
+  { "atmega64hve", "__AVR_ATmega64HVE__" },
+  { "at90can32", "__AVR_AT90CAN32__" },
+  { "at90can64", "__AVR_AT90CAN64__" },
+  { "at90pwm161", "__AVR_AT90PWM161__" },
+  { "at90pwm216", "__AVR_AT90PWM216__" },
+  { "at90pwm316", "__AVR_AT90PWM316__" },
+  { "atmega32c1", "__AVR_ATmega32C1__" },
+  { "atmega64c1", "__AVR_ATmega64C1__" },
+  { "atmega16m1", "__AVR_ATmega16M1__" },
+  { "atmega32m1", "__AVR_ATmega32M1__" },
+  { "atmega64m1", "__AVR_ATmega64M1__" },
+  { "atmega16u4", "__AVR_ATmega16U4__" },
+  { "atmega32u4", "__AVR_ATmega32U4__" },
+  { "atmega32u6", "__AVR_ATmega32U6__" },
+  { "at90usb646", "__AVR_AT90USB646__" },
+  { "at90usb647", "__AVR_AT90USB647__" },
+  { "at90scr100", "__AVR_AT90SCR100__" },
+  { "at94k", "__AVR_AT94K__" },
+  { "m3000", "__AVR_AT000__" },
+  { "atmega128", "__AVR_ATmega128__" },
+  { "atmega128a", "__AVR_ATmega128A__" },
+  { "atmega1280", "__AVR_ATmega1280__" },
+  { "atmega1281", "__AVR_ATmega1281__" },
+  { "atmega1284", "__AVR_ATmega1284__" },
+  { "atmega1284p", "__AVR_ATmega1284P__" },
+  { "atmega128rfa1", "__AVR_ATmega128RFA1__" },
+  { "atmega128rfr2", "__AVR_ATmega128RFR2__" },
+  { "atmega1284rfr2", "__AVR_ATmega1284RFR2__" },
+  { "at90can128", "__AVR_AT90CAN128__" },
+  { "at90usb1286", "__AVR_AT90USB1286__" },
+  { "at90usb1287", "__AVR_AT90USB1287__" },
+  { "atmega2560", "__AVR_ATmega2560__" },
+  { "atmega2561", "__AVR_ATmega2561__" },
+  { "atmega256rfr2", "__AVR_ATmega256RFR2__" },
+  { "atmega2564rfr2", "__AVR_ATmega2564RFR2__" },
+  { "atxmega16a4", "__AVR_ATxmega16A4__" },
+  { "atxmega16a4u", "__AVR_ATxmega16a4U__" },
+  { "atxmega16c4", "__AVR_ATxmega16C4__" },
+  { "atxmega16d4", "__AVR_ATxmega16D4__" },
+  { "atxmega32a4", "__AVR_ATxmega32A4__" },
+  { "atxmega32a4u", "__AVR_ATxmega32A4U__" },
+  { "atxmega32c4", "__AVR_ATxmega32C4__" },
+  { "atxmega32d4", "__AVR_ATxmega32D4__" },
+  { "atxmega32e5", "__AVR_ATxmega32E5__" },
+  { "atxmega16e5", "__AVR_ATxmega16E5__" },
+  { "atxmega8e5", "__AVR_ATxmega8E5__" },
+  { "atxmega32x1", "__AVR_ATxmega32X1__" },
+  { "atxmega64a3", "__AVR_ATxmega64A3__" },
+  { "atxmega64a3u", "__AVR_ATxmega64A3U__" },
+  { "atxmega64a4u", "__AVR_ATxmega64A4U__" },
+  { "atxmega64b1", "__AVR_ATxmega64B1__" },
+  { "atxmega64b3", "__AVR_ATxmega64B3__" },
+  { "atxmega64c3", "__AVR_ATxmega64C3__" },
+  { "atxmega64d3", "__AVR_ATxmega64D3__" },
+  { "atxmega64d4", "__AVR_ATxmega64D4__" },
+  { "atxmega64a1", "__AVR_ATxmega64A1__" },
+  { "atxmega64a1u", "__AVR_ATxmega64A1U__" },
+  { "atxmega128a3", "__AVR_ATxmega128A3__" },
+  { "atxmega128a3u", "__AVR_ATxmega128A3U__" },
+  { "atxmega128b1", "__AVR_ATxmega128B1__" },
+  { "atxmega128b3", "__AVR_ATxmega128B3__" },
+  { "atxmega128c3", "__AVR_ATxmega128C3__" },
+  { "atxmega128d3", "__AVR_ATxmega128D3__" },
+  { "atxmega128d4", "__AVR_ATxmega128D4__" },
+  { "atxmega192a3", "__AVR_ATxmega192A3__" },
+  { "atxmega192a3u", "__AVR_ATxmega192A3U__" },
+  { "atxmega192c3", "__AVR_ATxmega192C3__" },
+  { "atxmega192d3", "__AVR_ATxmega192D3__" },
+  { "atxmega256a3", "__AVR_ATxmega256A3__" },
+  { "atxmega256a3u", "__AVR_ATxmega256A3U__" },
+  { "atxmega256a3b", "__AVR_ATxmega256A3B__" },
+  { "atxmega256a3bu", "__AVR_ATxmega256A3BU__" },
+  { "atxmega256c3", "__AVR_ATxmega256C3__" },
+  { "atxmega256d3", "__AVR_ATxmega256D3__" },
+  { "atxmega384c3", "__AVR_ATxmega384C3__" },
+  { "atxmega384d3", "__AVR_ATxmega384D3__" },
+  { "atxmega128a1", "__AVR_ATxmega128A1__" },
+  { "atxmega128a1u", "__AVR_ATxmega128A1U__" },
+  { "atxmega128a4u", "__AVR_ATxmega128a4U__" },
+  { "attiny4", "__AVR_ATtiny4__" },
+  { "attiny5", "__AVR_ATtiny5__" },
+  { "attiny9", "__AVR_ATtiny9__" },
+  { "attiny10", "__AVR_ATtiny10__" },
+  { "attiny20", "__AVR_ATtiny20__" },
+  { "attiny40", "__AVR_ATtiny40__" },
+  { "attiny102", "__AVR_ATtiny102__" },
+  { "attiny104", "__AVR_ATtiny104__" },
+};
+
+// AVR Target
+class AVRTargetInfo : public TargetInfo {
+public:
+  AVRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+      : TargetInfo(Triple) {
+    TLSSupported = false;
+    PointerWidth = 16;
+    PointerAlign = 8;
+    IntWidth = 16;
+    IntAlign = 8;
+    LongWidth = 32;
+    LongAlign = 8;
+    LongLongWidth = 64;
+    LongLongAlign = 8;
+    SuitableAlign = 8;
+    DefaultAlignForAttributeAligned = 8;
+    HalfWidth = 16;
+    HalfAlign = 8;
+    FloatWidth = 32;
+    FloatAlign = 8;
+    DoubleWidth = 32;
+    DoubleAlign = 8;
+    DoubleFormat = &llvm::APFloat::IEEEsingle();
+    LongDoubleWidth = 32;
+    LongDoubleAlign = 8;
+    LongDoubleFormat = &llvm::APFloat::IEEEsingle();
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+    IntPtrType = SignedInt;
+    Char16Type = UnsignedInt;
+    WCharType = SignedInt;
+    WIntType = SignedInt;
+    Char32Type = UnsignedLong;
+    SigAtomicType = SignedChar;
+    resetDataLayout("e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64"
+		    "-f32:32:32-f64:64:64-n8");
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
+    Builder.defineMacro("AVR");
+    Builder.defineMacro("__AVR");
+    Builder.defineMacro("__AVR__");
+
+    if (!this->CPU.empty()) {
+      auto It = std::find_if(AVRMcus.begin(), AVRMcus.end(),
+        [&](const MCUInfo &Info) { return Info.Name == this->CPU; });
+
+      if (It != AVRMcus.end())
+        Builder.defineMacro(It->DefineName);
+    }
+  }
+
+  ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+    return None;
+  }
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::VoidPtrBuiltinVaList;
+  }
+
+  const char *getClobbers() const override {
+    return "";
+  }
+
+  ArrayRef<const char *> getGCCRegNames() const override {
+    static const char * const GCCRegNames[] = {
+      "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
+      "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",
+      "r16",  "r17",  "r18",  "r19",  "r20",  "r21",  "r22",  "r23",
+      "r24",  "r25",  "X",    "Y",    "Z",    "SP"
+    };
+    return llvm::makeArrayRef(GCCRegNames);
+  }
+
+  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
+    return None;
+  }
+
+  ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override {
+    static const TargetInfo::AddlRegName AddlRegNames[] = {
+      { { "r26", "r27"}, 26 },
+      { { "r28", "r29"}, 27 },
+      { { "r30", "r31"}, 28 },
+      { { "SPL", "SPH"}, 29 },
+    };
+    return llvm::makeArrayRef(AddlRegNames);
+  }
+
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
+    // There aren't any multi-character AVR specific constraints.
+    if (StringRef(Name).size() > 1) return false;
+
+    switch (*Name) {
+      default: return false;
+      case 'a': // Simple upper registers
+      case 'b': // Base pointer registers pairs
+      case 'd': // Upper register
+      case 'l': // Lower registers
+      case 'e': // Pointer register pairs
+      case 'q': // Stack pointer register
+      case 'r': // Any register
+      case 'w': // Special upper register pairs
+      case 't': // Temporary register
+      case 'x': case 'X': // Pointer register pair X
+      case 'y': case 'Y': // Pointer register pair Y
+      case 'z': case 'Z': // Pointer register pair Z
+        Info.setAllowsRegister();
+        return true;
+      case 'I': // 6-bit positive integer constant
+        Info.setRequiresImmediate(0, 63);
+        return true;
+      case 'J': // 6-bit negative integer constant
+        Info.setRequiresImmediate(-63, 0);
+        return true;
+      case 'K': // Integer constant (Range: 2)
+        Info.setRequiresImmediate(2);
+        return true;
+      case 'L': // Integer constant (Range: 0)
+        Info.setRequiresImmediate(0);
+        return true;
+      case 'M': // 8-bit integer constant
+        Info.setRequiresImmediate(0, 0xff);
+        return true;
+      case 'N': // Integer constant (Range: -1)
+        Info.setRequiresImmediate(-1);
+        return true;
+      case 'O': // Integer constant (Range: 8, 16, 24)
+        Info.setRequiresImmediate({8, 16, 24});
+        return true;
+      case 'P': // Integer constant (Range: 1)
+        Info.setRequiresImmediate(1);
+        return true;
+      case 'R': // Integer constant (Range: -6 to 5)
+        Info.setRequiresImmediate(-6, 5);
+        return true;
+      case 'G': // Floating point constant
+      case 'Q': // A memory address based on Y or Z pointer with displacement.
+        return true;
+    }
+
+    return false;
+  }
+
+  IntType getIntTypeByWidth(unsigned BitWidth,
+                            bool IsSigned) const final {
+    // AVR prefers int for 16-bit integers.
+    return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt)
+                          : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
+  }
+
+  IntType getLeastIntTypeByWidth(unsigned BitWidth,
+                                 bool IsSigned) const final {
+    // AVR uses int for int_least16_t and int_fast16_t.
+    return BitWidth == 16
+               ? (IsSigned ? SignedInt : UnsignedInt)
+               : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
+  }
+
+  bool setCPU(const std::string &Name) override {
+    bool IsFamily = llvm::StringSwitch<bool>(Name)
+      .Case("avr1", true)
+      .Case("avr2", true)
+      .Case("avr25", true)
+      .Case("avr3", true)
+      .Case("avr31", true)
+      .Case("avr35", true)
+      .Case("avr4", true)
+      .Case("avr5", true)
+      .Case("avr51", true)
+      .Case("avr6", true)
+      .Case("avrxmega1", true)
+      .Case("avrxmega2", true)
+      .Case("avrxmega3", true)
+      .Case("avrxmega4", true)
+      .Case("avrxmega5", true)
+      .Case("avrxmega6", true)
+      .Case("avrxmega7", true)
+      .Case("avrtiny", true)
+      .Default(false);
+
+    if (IsFamily) this->CPU = Name;
+
+    bool IsMCU = std::find_if(AVRMcus.begin(), AVRMcus.end(),
+      [&](const MCUInfo &Info) { return Info.Name == Name; }) != AVRMcus.end();
+
+    if (IsMCU) this->CPU = Name;
+
+    return IsFamily || IsMCU;
+  }
+
+protected:
+  std::string CPU;
+};
+
 } // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
@@ -8380,6 +9000,8 @@
       return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts);
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
+    case llvm::Triple::OpenBSD:
+      return new OpenBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
     default:
       return new AArch64leTargetInfo(Triple, Opts);
     }
@@ -8410,8 +9032,6 @@
       return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts);
     case llvm::Triple::FreeBSD:
       return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
-    case llvm::Triple::Fuchsia:
-      return new FuchsiaTargetInfo<ARMleTargetInfo>(Triple, Opts);
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
     case llvm::Triple::OpenBSD:
@@ -8448,8 +9068,6 @@
       return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts);
     case llvm::Triple::FreeBSD:
       return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
-    case llvm::Triple::Fuchsia:
-      return new FuchsiaTargetInfo<ARMbeTargetInfo>(Triple, Opts);
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
     case llvm::Triple::OpenBSD:
@@ -8464,6 +9082,8 @@
       return new ARMbeTargetInfo(Triple, Opts);
     }
 
+  case llvm::Triple::avr:
+    return new AVRTargetInfo(Triple, Opts);
   case llvm::Triple::bpfeb:
   case llvm::Triple::bpfel:
     return new BPFTargetInfo(Triple, Opts);
@@ -8589,9 +9209,9 @@
     }
 
   case llvm::Triple::nvptx:
-    return new NVPTX32TargetInfo(Triple, Opts);
+    return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/32);
   case llvm::Triple::nvptx64:
-    return new NVPTX64TargetInfo(Triple, Opts);
+    return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/64);
 
   case llvm::Triple::amdgcn:
   case llvm::Triple::r600:
@@ -8683,8 +9303,6 @@
       return new BitrigI386TargetInfo(Triple, Opts);
     case llvm::Triple::FreeBSD:
       return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
-    case llvm::Triple::Fuchsia:
-      return new FuchsiaTargetInfo<X86_32TargetInfo>(Triple, Opts);
     case llvm::Triple::KFreeBSD:
       return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
     case llvm::Triple::Minix:
@@ -8780,11 +9398,19 @@
     return new SPIR64TargetInfo(Triple, Opts);
   }
   case llvm::Triple::wasm32:
-    if (!(Triple == llvm::Triple("wasm32-unknown-unknown")))
+    if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
+        Triple.getVendor() != llvm::Triple::UnknownVendor ||
+        Triple.getOS() != llvm::Triple::UnknownOS ||
+        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment ||
+        !(Triple.isOSBinFormatELF() || Triple.isOSBinFormatWasm()))
       return nullptr;
     return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
   case llvm::Triple::wasm64:
-    if (!(Triple == llvm::Triple("wasm64-unknown-unknown")))
+    if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
+        Triple.getVendor() != llvm::Triple::UnknownVendor ||
+        Triple.getOS() != llvm::Triple::UnknownOS ||
+        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment ||
+        !(Triple.isOSBinFormatELF() || Triple.isOSBinFormatWasm()))
       return nullptr;
     return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
 
diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp
index 88d08b4..f5db717 100644
--- a/lib/Basic/VirtualFileSystem.cpp
+++ b/lib/Basic/VirtualFileSystem.cpp
@@ -27,13 +27,6 @@
 #include <memory>
 #include <utility>
 
-// For chdir.
-#ifdef LLVM_ON_WIN32
-#  include <direct.h>
-#else
-#  include <unistd.h>
-#endif
-
 using namespace clang;
 using namespace clang::vfs;
 using namespace llvm;
@@ -235,11 +228,7 @@
   // difference for example on network filesystems, where symlinks might be
   // switched during runtime of the tool. Fixing this depends on having a
   // file system abstraction that allows openat() style interactions.
-  SmallString<256> Storage;
-  StringRef Dir = Path.toNullTerminatedStringRef(Storage);
-  if (int Err = ::chdir(Dir.data()))
-    return std::error_code(Err, std::generic_category());
-  return std::error_code();
+  return llvm::sys::fs::set_current_path(Path);
 }
 
 IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() {
@@ -249,16 +238,13 @@
 
 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) {
+  RealFSDirIter(const Twine &Path, std::error_code &EC) : 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::copyWithNewName(S, Iter->path());
+      CurrentEntry = Status::copyWithNewName(S, Iter->path());
     }
   }
 
@@ -887,9 +873,6 @@
   RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS)
       : ExternalFS(std::move(ExternalFS)) {}
 
-  /// \brief Looks up \p Path in \c Roots.
-  ErrorOr<Entry *> lookupPath(const Twine &Path);
-
   /// \brief Looks up the path <tt>[Start, End)</tt> in \p From, possibly
   /// recursing into the contents of \p From if it is a directory.
   ErrorOr<Entry *> lookupPath(sys::path::const_iterator Start,
@@ -899,6 +882,9 @@
   ErrorOr<Status> status(const Twine &Path, Entry *E);
 
 public:
+  /// \brief Looks up \p Path in \c Roots.
+  ErrorOr<Entry *> lookupPath(const Twine &Path);
+
   /// \brief Parses \p Buffer, which is expected to be in YAML format and
   /// returns a virtual file system representing its contents.
   static RedirectingFileSystem *
@@ -1606,6 +1592,47 @@
                                        std::move(ExternalFS));
 }
 
+static void getVFSEntries(Entry *SrcE, SmallVectorImpl<StringRef> &Path,
+                          SmallVectorImpl<YAMLVFSEntry> &Entries) {
+  auto Kind = SrcE->getKind();
+  if (Kind == EK_Directory) {
+    auto *DE = dyn_cast<RedirectingDirectoryEntry>(SrcE);
+    assert(DE && "Must be a directory");
+    for (std::unique_ptr<Entry> &SubEntry :
+         llvm::make_range(DE->contents_begin(), DE->contents_end())) {
+      Path.push_back(SubEntry->getName());
+      getVFSEntries(SubEntry.get(), Path, Entries);
+      Path.pop_back();
+    }
+    return;
+  }
+
+  assert(Kind == EK_File && "Must be a EK_File");
+  auto *FE = dyn_cast<RedirectingFileEntry>(SrcE);
+  assert(FE && "Must be a file");
+  SmallString<128> VPath;
+  for (auto &Comp : Path)
+    llvm::sys::path::append(VPath, Comp);
+  Entries.push_back(YAMLVFSEntry(VPath.c_str(), FE->getExternalContentsPath()));
+}
+
+void vfs::collectVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer,
+                             SourceMgr::DiagHandlerTy DiagHandler,
+                             StringRef YAMLFilePath,
+                             SmallVectorImpl<YAMLVFSEntry> &CollectedEntries,
+                             void *DiagContext,
+                             IntrusiveRefCntPtr<FileSystem> ExternalFS) {
+  RedirectingFileSystem *VFS = RedirectingFileSystem::create(
+      std::move(Buffer), DiagHandler, YAMLFilePath, DiagContext,
+      std::move(ExternalFS));
+  ErrorOr<Entry *> RootE = VFS->lookupPath("/");
+  if (!RootE)
+    return;
+  SmallVector<StringRef, 8> Components;
+  Components.push_back("/");
+  getVFSEntries(*RootE, Components, CollectedEntries);
+}
+
 UniqueID vfs::getNextVirtualUniqueID() {
   static std::atomic<unsigned> UID;
   unsigned ID = ++UID;
@@ -1828,7 +1855,7 @@
                                                            std::error_code &EC)
     : FS(&FS_) {
   directory_iterator I = FS->dir_begin(Path, EC);
-  if (!EC && I != directory_iterator()) {
+  if (I != directory_iterator()) {
     State = std::make_shared<IterState>();
     State->push(I);
   }
@@ -1841,8 +1868,6 @@
   vfs::directory_iterator End;
   if (State->top()->isDirectory()) {
     vfs::directory_iterator I = FS->dir_begin(State->top()->getName(), EC);
-    if (EC)
-      return *this;
     if (I != End) {
       State->push(I);
       return *this;
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index ac31dfd..c0be60e 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
 #define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
 
+#include "clang/AST/CharUnits.h"
 #include "clang/AST/Type.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Type.h"
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 87937c0..f0e0b71 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -14,25 +14,29 @@
 #include "clang/Frontend/CodeGenOptions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/Utils.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/Bitcode/BitcodeWriterPass.h"
-#include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/Bitcode/BitcodeWriter.h"
+#include "llvm/Bitcode/BitcodeWriterPass.h"
 #include "llvm/CodeGen/RegAllocRegistry.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/IR/DataLayout.h"
-#include "llvm/IR/ModuleSummaryIndex.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/ModuleSummaryIndex.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/LTO/LTOBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Object/ModuleSummaryIndexObjectFile.h"
+#include "llvm/Passes/PassBuilder.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/PrettyStackTrace.h"
@@ -57,8 +61,12 @@
 
 namespace {
 
+// Default filename used for profile generation.
+static constexpr StringLiteral DefaultProfileGenName = "default_%m.profraw";
+
 class EmitAssemblyHelper {
   DiagnosticsEngine &Diags;
+  const HeaderSearchOptions &HSOpts;
   const CodeGenOptions &CodeGenOpts;
   const clang::TargetOptions &TargetOpts;
   const LangOptions &LangOpts;
@@ -68,7 +76,6 @@
 
   std::unique_ptr<raw_pwrite_stream> OS;
 
-private:
   TargetIRAnalysis getTargetIRAnalysis() const {
     if (TM)
       return TM->getTargetIRAnalysis();
@@ -98,11 +105,14 @@
                      raw_pwrite_stream &OS);
 
 public:
-  EmitAssemblyHelper(DiagnosticsEngine &_Diags, const CodeGenOptions &CGOpts,
+  EmitAssemblyHelper(DiagnosticsEngine &_Diags,
+                     const HeaderSearchOptions &HeaderSearchOpts,
+                     const CodeGenOptions &CGOpts,
                      const clang::TargetOptions &TOpts,
                      const LangOptions &LOpts, Module *M)
-      : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
-        TheModule(M), CodeGenerationTime("codegen", "Code Generation Time") {}
+      : Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts),
+        TargetOpts(TOpts), LangOpts(LOpts), TheModule(M),
+        CodeGenerationTime("codegen", "Code Generation Time") {}
 
   ~EmitAssemblyHelper() {
     if (CodeGenOpts.DisableFree)
@@ -113,6 +123,9 @@
 
   void EmitAssembly(BackendAction Action,
                     std::unique_ptr<raw_pwrite_stream> OS);
+
+  void EmitAssemblyWithNewPassManager(BackendAction Action,
+                                      std::unique_ptr<raw_pwrite_stream> OS);
 };
 
 // We need this wrapper to access LangOpts and CGOpts from extension functions
@@ -251,7 +264,7 @@
     TLII->disableAllFunctions();
   else {
     // Disable individual libc/libm calls in TargetLibraryInfo.
-    LibFunc::Func F;
+    LibFunc F;
     for (auto &FuncName : CodeGenOpts.getNoBuiltinFuncs())
       if (TLII->getLibFunc(FuncName, F))
         TLII->setUnavailable(F);
@@ -283,19 +296,11 @@
 
 void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
                                       legacy::FunctionPassManager &FPM) {
+  // Handle disabling of all LLVM passes, where we want to preserve the
+  // internal module before any optimization.
   if (CodeGenOpts.DisableLLVMPasses)
     return;
 
-  unsigned OptLevel = CodeGenOpts.OptimizationLevel;
-  CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();
-
-  // Handle disabling of LLVM optimization, where we want to preserve the
-  // internal module before any optimization.
-  if (CodeGenOpts.DisableLLVMOpts) {
-    OptLevel = 0;
-    Inlining = CodeGenOpts.NoInlining;
-  }
-
   PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);
 
   // Figure out TargetLibraryInfo.  This needs to be added to MPM and FPM
@@ -306,26 +311,18 @@
   std::unique_ptr<TargetLibraryInfoImpl> TLII(
       createTLII(TargetTriple, CodeGenOpts));
 
-  switch (Inlining) {
-  case CodeGenOptions::NoInlining:
-    break;
-  case CodeGenOptions::NormalInlining:
-  case CodeGenOptions::OnlyHintInlining: {
-    PMBuilder.Inliner =
-        createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize);
-    break;
-  }
-  case CodeGenOptions::OnlyAlwaysInlining:
-    // Respect always_inline.
-    if (OptLevel == 0)
-      // Do not insert lifetime intrinsics at -O0.
-      PMBuilder.Inliner = createAlwaysInlinerLegacyPass(false);
-    else
-      PMBuilder.Inliner = createAlwaysInlinerLegacyPass();
-    break;
+  // At O0 and O1 we only run the always inliner which is more efficient. At
+  // higher optimization levels we run the normal inliner.
+  if (CodeGenOpts.OptimizationLevel <= 1) {
+    bool InsertLifetimeIntrinsics = (CodeGenOpts.OptimizationLevel != 0 &&
+                                     !CodeGenOpts.DisableLifetimeMarkers);
+    PMBuilder.Inliner = createAlwaysInlinerLegacyPass(InsertLifetimeIntrinsics);
+  } else {
+    PMBuilder.Inliner = createFunctionInliningPass(
+        CodeGenOpts.OptimizationLevel, CodeGenOpts.OptimizeSize);
   }
 
-  PMBuilder.OptLevel = OptLevel;
+  PMBuilder.OptLevel = CodeGenOpts.OptimizationLevel;
   PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
   PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB;
   PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
@@ -339,16 +336,13 @@
 
   MPM.add(new TargetLibraryInfoWrapperPass(*TLII));
 
-  // Add target-specific passes that need to run as early as possible.
   if (TM)
-    PMBuilder.addExtension(
-        PassManagerBuilder::EP_EarlyAsPossible,
-        [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
-          TM->addEarlyAsPossiblePasses(PM);
-        });
+    TM->adjustPassManager(PMBuilder);
 
-  PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
-                         addAddDiscriminatorsPass);
+  if (CodeGenOpts.DebugInfoForProfiling ||
+      !CodeGenOpts.SampleProfileFile.empty())
+    PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
+                           addAddDiscriminatorsPass);
 
   // In ObjC ARC mode, add the main ARC optimization passes.
   if (LangOpts.ObjCAutoRefCount) {
@@ -459,15 +453,13 @@
     if (!CodeGenOpts.InstrProfileOutput.empty())
       PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput;
     else
-      PMBuilder.PGOInstrGen = "default_%m.profraw";
+      PMBuilder.PGOInstrGen = DefaultProfileGenName;
   }
   if (CodeGenOpts.hasProfileIRUse())
     PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath;
 
-  if (!CodeGenOpts.SampleProfileFile.empty()) {
-    MPM.add(createPruneEHPass());
-    MPM.add(createSampleProfileLoaderPass(CodeGenOpts.SampleProfileFile));
-  }
+  if (!CodeGenOpts.SampleProfileFile.empty())
+    PMBuilder.PGOSampleUse = CodeGenOpts.SampleProfileFile;
 
   PMBuilder.populateFunctionPassManager(FPM);
   PMBuilder.populateModulePassManager(MPM);
@@ -518,27 +510,31 @@
 
   // Keep this synced with the equivalent code in tools/driver/cc1as_main.cpp.
   llvm::Optional<llvm::Reloc::Model> RM;
-  if (CodeGenOpts.RelocationModel == "static") {
-    RM = llvm::Reloc::Static;
-  } else if (CodeGenOpts.RelocationModel == "pic") {
-    RM = llvm::Reloc::PIC_;
-  } else if (CodeGenOpts.RelocationModel == "ropi") {
-    RM = llvm::Reloc::ROPI;
-  } else if (CodeGenOpts.RelocationModel == "rwpi") {
-    RM = llvm::Reloc::RWPI;
-  } else if (CodeGenOpts.RelocationModel == "ropi-rwpi") {
-    RM = llvm::Reloc::ROPI_RWPI;
-  } else {
-    assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
-           "Invalid PIC model!");
-    RM = llvm::Reloc::DynamicNoPIC;
-  }
+  RM = llvm::StringSwitch<llvm::Reloc::Model>(CodeGenOpts.RelocationModel)
+           .Case("static", llvm::Reloc::Static)
+           .Case("pic", llvm::Reloc::PIC_)
+           .Case("ropi", llvm::Reloc::ROPI)
+           .Case("rwpi", llvm::Reloc::RWPI)
+           .Case("ropi-rwpi", llvm::Reloc::ROPI_RWPI)
+           .Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC);
+  assert(RM.hasValue() && "invalid PIC model!");
 
-  CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
+  CodeGenOpt::Level OptLevel;
   switch (CodeGenOpts.OptimizationLevel) {
-  default: break;
-  case 0: OptLevel = CodeGenOpt::None; break;
-  case 3: OptLevel = CodeGenOpt::Aggressive; break;
+  default:
+    llvm_unreachable("Invalid optimization level!");
+  case 0:
+    OptLevel = CodeGenOpt::None;
+    break;
+  case 1:
+    OptLevel = CodeGenOpt::Less;
+    break;
+  case 2:
+    OptLevel = CodeGenOpt::Default;
+    break; // O2/Os/Oz
+  case 3:
+    OptLevel = CodeGenOpt::Aggressive;
+    break;
   }
 
   llvm::TargetOptions Options;
@@ -605,12 +601,18 @@
   Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
   Options.MCOptions.MCIncrementalLinkerCompatible =
       CodeGenOpts.IncrementalLinkerCompatible;
-  Options.MCOptions.MCPIECopyRelocations =
-      CodeGenOpts.PIECopyRelocations;
+  Options.MCOptions.MCPIECopyRelocations = CodeGenOpts.PIECopyRelocations;
   Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
   Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
   Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
   Options.MCOptions.ABIName = TargetOpts.ABI;
+  for (const auto &Entry : HSOpts.UserEntries)
+    if (!Entry.IsFramework &&
+        (Entry.Group == frontend::IncludeDirGroup::Quoted ||
+         Entry.Group == frontend::IncludeDirGroup::Angled ||
+         Entry.Group == frontend::IncludeDirGroup::System))
+      Options.MCOptions.IASSearchPaths.push_back(
+          Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);
 
   TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
                                           Options, RM, CM, OptLevel));
@@ -685,9 +687,11 @@
     break;
 
   case Backend_EmitBC:
-    PerModulePasses.add(createBitcodeWriterPass(
-        *OS, CodeGenOpts.EmitLLVMUseLists, CodeGenOpts.EmitSummaryIndex,
-        CodeGenOpts.EmitSummaryIndex));
+    if (CodeGenOpts.EmitSummaryIndex)
+      PerModulePasses.add(createWriteThinLTOBitcodePass(*OS));
+    else
+      PerModulePasses.add(
+          createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists));
     break;
 
   case Backend_EmitLL:
@@ -727,33 +731,198 @@
   }
 }
 
-static void runThinLTOBackend(const CodeGenOptions &CGOpts, Module *M,
-                              std::unique_ptr<raw_pwrite_stream> OS) {
-  // If we are performing a ThinLTO importing compile, load the function index
-  // into memory and pass it into thinBackend, which will run the function
-  // importer and invoke LTO passes.
-  Expected<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
-      llvm::getModuleSummaryIndexForFile(CGOpts.ThinLTOIndexFile);
-  if (!IndexOrErr) {
-    logAllUnhandledErrors(IndexOrErr.takeError(), errs(),
-                          "Error loading index file '" +
-                              CGOpts.ThinLTOIndexFile + "': ");
-    return;
-  }
-  std::unique_ptr<ModuleSummaryIndex> CombinedIndex = std::move(*IndexOrErr);
+static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
+  switch (Opts.OptimizationLevel) {
+  default:
+    llvm_unreachable("Invalid optimization level!");
 
+  case 1:
+    return PassBuilder::O1;
+
+  case 2:
+    switch (Opts.OptimizeSize) {
+    default:
+      llvm_unreachable("Invalide optimization level for size!");
+
+    case 0:
+      return PassBuilder::O2;
+
+    case 1:
+      return PassBuilder::Os;
+
+    case 2:
+      return PassBuilder::Oz;
+    }
+
+  case 3:
+    return PassBuilder::O3;
+  }
+}
+
+/// A clean version of `EmitAssembly` that uses the new pass manager.
+///
+/// Not all features are currently supported in this system, but where
+/// necessary it falls back to the legacy pass manager to at least provide
+/// basic functionality.
+///
+/// This API is planned to have its functionality finished and then to replace
+/// `EmitAssembly` at some point in the future when the default switches.
+void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
+    BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) {
+  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
+  setCommandLineOpts();
+
+  // The new pass manager always makes a target machine available to passes
+  // during construction.
+  CreateTargetMachine(/*MustCreateTM*/ true);
+  if (!TM)
+    // This will already be diagnosed, just bail.
+    return;
+  TheModule->setDataLayout(TM->createDataLayout());
+
+  PGOOptions PGOOpt;
+
+  // -fprofile-generate.
+  PGOOpt.RunProfileGen = CodeGenOpts.hasProfileIRInstr();
+  if (PGOOpt.RunProfileGen)
+    PGOOpt.ProfileGenFile = CodeGenOpts.InstrProfileOutput.empty() ?
+      DefaultProfileGenName : CodeGenOpts.InstrProfileOutput;
+
+  // -fprofile-use.
+  if (CodeGenOpts.hasProfileIRUse())
+    PGOOpt.ProfileUseFile = CodeGenOpts.ProfileInstrumentUsePath;
+
+  // Only pass a PGO options struct if -fprofile-generate or
+  // -fprofile-use were passed on the cmdline.
+  PassBuilder PB(TM.get(),
+    (PGOOpt.RunProfileGen ||
+      !PGOOpt.ProfileUseFile.empty()) ?
+        Optional<PGOOptions>(PGOOpt) : None);
+
+  LoopAnalysisManager LAM;
+  FunctionAnalysisManager FAM;
+  CGSCCAnalysisManager CGAM;
+  ModuleAnalysisManager MAM;
+
+  // Register the AA manager first so that our version is the one used.
+  FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
+
+  // Register all the basic analyses with the managers.
+  PB.registerModuleAnalyses(MAM);
+  PB.registerCGSCCAnalyses(CGAM);
+  PB.registerFunctionAnalyses(FAM);
+  PB.registerLoopAnalyses(LAM);
+  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+
+  ModulePassManager MPM;
+
+  if (!CodeGenOpts.DisableLLVMPasses) {
+    if (CodeGenOpts.OptimizationLevel == 0) {
+      // Build a minimal pipeline based on the semantics required by Clang,
+      // which is just that always inlining occurs.
+      MPM.addPass(AlwaysInlinerPass());
+    } else {
+      // Otherwise, use the default pass pipeline. We also have to map our
+      // optimization levels into one of the distinct levels used to configure
+      // the pipeline.
+      PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts);
+
+      MPM = PB.buildPerModuleDefaultPipeline(Level);
+    }
+  }
+
+  // FIXME: We still use the legacy pass manager to do code generation. We
+  // create that pass manager here and use it as needed below.
+  legacy::PassManager CodeGenPasses;
+  bool NeedCodeGen = false;
+
+  // Append any output we need to the pass manager.
+  switch (Action) {
+  case Backend_EmitNothing:
+    break;
+
+  case Backend_EmitBC:
+    MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
+                                  CodeGenOpts.EmitSummaryIndex,
+                                  CodeGenOpts.EmitSummaryIndex));
+    break;
+
+  case Backend_EmitLL:
+    MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
+    break;
+
+  case Backend_EmitAssembly:
+  case Backend_EmitMCNull:
+  case Backend_EmitObj:
+    NeedCodeGen = true;
+    CodeGenPasses.add(
+        createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
+    if (!AddEmitPasses(CodeGenPasses, Action, *OS))
+      // FIXME: Should we handle this error differently?
+      return;
+    break;
+  }
+
+  // Before executing passes, print the final values of the LLVM options.
+  cl::PrintOptionValues();
+
+  // Now that we have all of the passes ready, run them.
+  {
+    PrettyStackTraceString CrashInfo("Optimizer");
+    MPM.run(*TheModule, MAM);
+  }
+
+  // Now if needed, run the legacy PM for codegen.
+  if (NeedCodeGen) {
+    PrettyStackTraceString CrashInfo("Code generation");
+    CodeGenPasses.run(*TheModule);
+  }
+}
+
+Expected<BitcodeModule> clang::FindThinLTOModule(MemoryBufferRef MBRef) {
+  Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef);
+  if (!BMsOrErr)
+    return BMsOrErr.takeError();
+
+  // The bitcode file may contain multiple modules, we want the one with a
+  // summary.
+  for (BitcodeModule &BM : *BMsOrErr) {
+    Expected<bool> HasSummary = BM.hasSummary();
+    if (HasSummary && *HasSummary)
+      return BM;
+  }
+
+  return make_error<StringError>("Could not find module summary",
+                                 inconvertibleErrorCode());
+}
+
+static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M,
+                              std::unique_ptr<raw_pwrite_stream> OS,
+                              std::string SampleProfile) {
   StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>>
       ModuleToDefinedGVSummaries;
   CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
 
-  // FIXME: We could simply import the modules mentioned in the combined index
-  // here.
+  // We can simply import the values mentioned in the combined index, since
+  // we should only invoke this using the individual indexes written out
+  // via a WriteIndexesThinBackend.
   FunctionImporter::ImportMapTy ImportList;
-  ComputeCrossModuleImportForModule(M->getModuleIdentifier(), *CombinedIndex,
-                                    ImportList);
+  for (auto &GlobalList : *CombinedIndex) {
+    auto GUID = GlobalList.first;
+    assert(GlobalList.second.size() == 1 &&
+           "Expected individual combined index to have one summary per GUID");
+    auto &Summary = GlobalList.second[0];
+    // Skip the summaries for the importing module. These are included to
+    // e.g. record required linkage changes.
+    if (Summary->modulePath() == M->getModuleIdentifier())
+      continue;
+    // Doesn't matter what value we plug in to the map, just needs an entry
+    // to provoke importing by thinBackend.
+    ImportList[Summary->modulePath()][GUID] = 1;
+  }
 
   std::vector<std::unique_ptr<llvm::MemoryBuffer>> OwnedImports;
-  MapVector<llvm::StringRef, llvm::MemoryBufferRef> ModuleMap;
+  MapVector<llvm::StringRef, llvm::BitcodeModule> ModuleMap;
 
   for (auto &I : ImportList) {
     ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MBOrErr =
@@ -763,13 +932,24 @@
              << "': " << MBOrErr.getError().message() << "\n";
       return;
     }
-    ModuleMap[I.first()] = (*MBOrErr)->getMemBufferRef();
+
+    Expected<BitcodeModule> BMOrErr = FindThinLTOModule(**MBOrErr);
+    if (!BMOrErr) {
+      handleAllErrors(BMOrErr.takeError(), [&](ErrorInfoBase &EIB) {
+        errs() << "Error loading imported file '" << I.first()
+               << "': " << EIB.message() << '\n';
+      });
+      return;
+    }
+    ModuleMap.insert({I.first(), *BMOrErr});
+
     OwnedImports.push_back(std::move(*MBOrErr));
   }
   auto AddStream = [&](size_t Task) {
     return llvm::make_unique<lto::NativeObjectStream>(std::move(OS));
   };
   lto::Config Conf;
+  Conf.SampleProfile = SampleProfile;
   if (Error E = thinBackend(
           Conf, 0, AddStream, *M, *CombinedIndex, ImportList,
           ModuleToDefinedGVSummaries[M->getModuleIdentifier()], ModuleMap)) {
@@ -780,19 +960,43 @@
 }
 
 void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
+                              const HeaderSearchOptions &HeaderOpts,
                               const CodeGenOptions &CGOpts,
                               const clang::TargetOptions &TOpts,
-                              const LangOptions &LOpts, const llvm::DataLayout &TDesc,
-                              Module *M, BackendAction Action,
+                              const LangOptions &LOpts,
+                              const llvm::DataLayout &TDesc, Module *M,
+                              BackendAction Action,
                               std::unique_ptr<raw_pwrite_stream> OS) {
   if (!CGOpts.ThinLTOIndexFile.empty()) {
-    runThinLTOBackend(CGOpts, M, std::move(OS));
-    return;
+    // If we are performing a ThinLTO importing compile, load the function index
+    // into memory and pass it into runThinLTOBackend, which will run the
+    // function importer and invoke LTO passes.
+    Expected<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
+        llvm::getModuleSummaryIndexForFile(CGOpts.ThinLTOIndexFile);
+    if (!IndexOrErr) {
+      logAllUnhandledErrors(IndexOrErr.takeError(), errs(),
+                            "Error loading index file '" +
+                            CGOpts.ThinLTOIndexFile + "': ");
+      return;
+    }
+    std::unique_ptr<ModuleSummaryIndex> CombinedIndex = std::move(*IndexOrErr);
+    // A null CombinedIndex means we should skip ThinLTO compilation
+    // (LLVM will optionally ignore empty index files, returning null instead
+    // of an error).
+    bool DoThinLTOBackend = CombinedIndex != nullptr;
+    if (DoThinLTOBackend) {
+      runThinLTOBackend(CombinedIndex.get(), M, std::move(OS),
+                        CGOpts.SampleProfileFile);
+      return;
+    }
   }
 
-  EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
+  EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M);
 
-  AsmHelper.EmitAssembly(Action, std::move(OS));
+  if (CGOpts.ExperimentalNewPassManager)
+    AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS));
+  else
+    AsmHelper.EmitAssembly(Action, std::move(OS));
 
   // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
   // DataLayout.
@@ -813,6 +1017,7 @@
     return "__LLVM,__bitcode";
   case Triple::COFF:
   case Triple::ELF:
+  case Triple::Wasm:
   case Triple::UnknownObjectFormat:
     return ".llvmbc";
   }
@@ -825,6 +1030,7 @@
     return "__LLVM,__cmdline";
   case Triple::COFF:
   case Triple::ELF:
+  case Triple::Wasm:
   case Triple::UnknownObjectFormat:
     return ".llvmcmd";
   }
diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp
index 9287e46..28e20b5 100644
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
@@ -1181,7 +1181,7 @@
   if (LVal.isBitField())
     return CGF.EmitLoadOfBitfieldLValue(
         LValue::MakeBitfield(addr, LVal.getBitFieldInfo(), LVal.getType(),
-                             LVal.getAlignmentSource()));
+                             LVal.getAlignmentSource()), loc);
   if (LVal.isVectorElt())
     return CGF.EmitLoadOfLValue(
         LValue::MakeVectorElt(addr, LVal.getVectorIdx(), LVal.getType(),
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 50a6d61..31632ab 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -16,7 +16,7 @@
 #include "CGObjCRuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/IR/CallSite.h"
@@ -318,6 +318,19 @@
   elementTypes.push_back(CGM.getBlockDescriptorType());
 }
 
+static QualType getCaptureFieldType(const CodeGenFunction &CGF,
+                                    const BlockDecl::Capture &CI) {
+  const VarDecl *VD = CI.getVariable();
+
+  // If the variable is captured by an enclosing block or lambda expression,
+  // use the type of the capture field.
+  if (CGF.BlockInfo && CI.isNested())
+    return CGF.BlockInfo->getCapture(VD).fieldType();
+  if (auto *FD = CGF.LambdaCaptureFields.lookup(VD))
+    return FD->getType();
+  return VD->getType();
+}
+
 /// Compute the layout of the given block.  Attempts to lay the block
 /// out with minimal space requirements.
 static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
@@ -432,15 +445,7 @@
       }
     }
 
-    QualType VT = variable->getType();
-
-    // If the variable is captured by an enclosing block or lambda expression,
-    // use the type of the capture field.
-    if (CGF->BlockInfo && CI.isNested())
-      VT = CGF->BlockInfo->getCapture(variable).fieldType();
-    else if (auto *FD = CGF->LambdaCaptureFields.lookup(variable))
-      VT = FD->getType();
-
+    QualType VT = getCaptureFieldType(*CGF, CI);
     CharUnits size = C.getTypeSizeInChars(VT);
     CharUnits align = C.getDeclAlign(variable);
     
@@ -606,8 +611,8 @@
     if (capture.isConstant()) continue;
 
     // Ignore objects that aren't destructed.
-    QualType::DestructionKind dtorKind =
-      variable->getType().isDestructedType();
+    QualType VT = getCaptureFieldType(CGF, CI);
+    QualType::DestructionKind dtorKind = VT.isDestructedType();
     if (dtorKind == QualType::DK_none) continue;
 
     CodeGenFunction::Destroyer *destroyer;
@@ -634,7 +639,7 @@
     if (useArrayEHCleanup) 
       cleanupKind = InactiveNormalAndEHCleanup;
 
-    CGF.pushDestroy(cleanupKind, addr, variable->getType(),
+    CGF.pushDestroy(cleanupKind, addr, VT,
                     destroyer, useArrayEHCleanup);
 
     // Remember where that cleanup was.
@@ -686,6 +691,8 @@
   // If the block has no captures, we won't have a pre-computed
   // layout for it.
   if (!blockExpr->getBlockDecl()->hasCaptures()) {
+    if (llvm::Constant *Block = CGM.getAddrOfGlobalBlockIfEmitted(blockExpr))
+      return Block;
     CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName());
     computeBlockInfo(CGM, this, blockInfo);
     blockInfo.BlockExpression = blockExpr;
@@ -716,7 +723,12 @@
 
   // Otherwise, we have to emit this as a local block.
 
-  llvm::Constant *isa = CGM.getNSConcreteStackBlock();
+  llvm::Constant *isa =
+      (!CGM.getContext().getLangOpts().OpenCL)
+          ? CGM.getNSConcreteStackBlock()
+          : CGM.getNullPointer(cast<llvm::PointerType>(
+                                   CGM.getNSConcreteStackBlock()->getType()),
+                               QualType(getContext().VoidPtrTy));
   isa = llvm::ConstantExpr::getBitCast(isa, VoidPtrTy);
 
   // Build the block descriptor.
@@ -904,9 +916,8 @@
 
   // Cast to the converted block-pointer type, which happens (somewhat
   // unfortunately) to be a pointer to function type.
-  llvm::Value *result =
-    Builder.CreateBitCast(blockAddr.getPointer(),
-                          ConvertType(blockInfo.getBlockExpr()->getType()));
+  llvm::Value *result = Builder.CreatePointerCast(
+      blockAddr.getPointer(), ConvertType(blockInfo.getBlockExpr()->getType()));
 
   return result;
 }
@@ -974,21 +985,41 @@
   llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee());
 
   // Get a pointer to the generic block literal.
+  // For OpenCL we generate generic AS void ptr to be able to reuse the same
+  // block definition for blocks with captures generated as private AS local
+  // variables and without captures generated as global AS program scope
+  // variables.
+  unsigned AddrSpace = 0;
+  if (getLangOpts().OpenCL)
+    AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_generic);
+
   llvm::Type *BlockLiteralTy =
-    llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());
+      llvm::PointerType::get(CGM.getGenericBlockLiteralType(), AddrSpace);
 
   // Bitcast the callee to a block literal.
-  BlockPtr = Builder.CreateBitCast(BlockPtr, BlockLiteralTy, "block.literal");
+  BlockPtr =
+      Builder.CreatePointerCast(BlockPtr, BlockLiteralTy, "block.literal");
 
   // Get the function pointer from the literal.
   llvm::Value *FuncPtr =
     Builder.CreateStructGEP(CGM.getGenericBlockLiteralType(), BlockPtr, 3);
 
-  BlockPtr = Builder.CreateBitCast(BlockPtr, VoidPtrTy);
 
   // Add the block literal.
   CallArgList Args;
-  Args.add(RValue::get(BlockPtr), getContext().VoidPtrTy);
+
+  QualType VoidPtrQualTy = getContext().VoidPtrTy;
+  llvm::Type *GenericVoidPtrTy = VoidPtrTy;
+  if (getLangOpts().OpenCL) {
+    GenericVoidPtrTy = Builder.getInt8PtrTy(
+        getContext().getTargetAddressSpace(LangAS::opencl_generic));
+    VoidPtrQualTy =
+        getContext().getPointerType(getContext().getAddrSpaceQualType(
+            getContext().VoidTy, LangAS::opencl_generic));
+  }
+
+  BlockPtr = Builder.CreatePointerCast(BlockPtr, GenericVoidPtrTy);
+  Args.add(RValue::get(BlockPtr), VoidPtrQualTy);
 
   QualType FnType = BPT->getPointeeType();
 
@@ -1047,9 +1078,19 @@
   return addr;
 }
 
+void CodeGenModule::setAddrOfGlobalBlock(const BlockExpr *BE,
+                                         llvm::Constant *Addr) {
+  bool Ok = EmittedGlobalBlocks.insert(std::make_pair(BE, Addr)).second;
+  (void)Ok;
+  assert(Ok && "Trying to replace an already-existing global block!");
+}
+
 llvm::Constant *
 CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE,
                                     StringRef Name) {
+  if (llvm::Constant *Block = getAddrOfGlobalBlockIfEmitted(BE))
+    return Block;
+
   CGBlockInfo blockInfo(BE->getBlockDecl(), Name);
   blockInfo.BlockExpression = BE;
 
@@ -1074,13 +1115,23 @@
                                         const CGBlockInfo &blockInfo,
                                         llvm::Constant *blockFn) {
   assert(blockInfo.CanBeGlobal);
+  // Callers should detect this case on their own: calling this function
+  // generally requires computing layout information, which is a waste of time
+  // if we've already emitted this block.
+  assert(!CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression) &&
+         "Refusing to re-emit a global block.");
 
   // Generate the constants for the block literal initializer.
   ConstantInitBuilder builder(CGM);
   auto fields = builder.beginStruct();
 
   // isa
-  fields.add(CGM.getNSConcreteGlobalBlock());
+  fields.add(
+      (!CGM.getContext().getLangOpts().OpenCL)
+          ? CGM.getNSConcreteGlobalBlock()
+          : CGM.getNullPointer(cast<llvm::PointerType>(
+                                   CGM.getNSConcreteGlobalBlock()->getType()),
+                               QualType(CGM.getContext().VoidPtrTy)));
 
   // __flags
   BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE;
@@ -1097,15 +1148,21 @@
   // Descriptor
   fields.add(buildBlockDescriptor(CGM, blockInfo));
 
-  llvm::Constant *literal =
-    fields.finishAndCreateGlobal("__block_literal_global",
-                                 blockInfo.BlockAlign,
-                                 /*constant*/ true);
+  unsigned AddrSpace = 0;
+  if (CGM.getContext().getLangOpts().OpenCL)
+    AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_global);
+
+  llvm::Constant *literal = fields.finishAndCreateGlobal(
+      "__block_literal_global", blockInfo.BlockAlign,
+      /*constant*/ true, llvm::GlobalVariable::InternalLinkage, AddrSpace);
 
   // Return a constant of the appropriately-casted type.
-  llvm::Type *requiredType =
+  llvm::Type *RequiredType =
     CGM.getTypes().ConvertType(blockInfo.getBlockExpr()->getType());
-  return llvm::ConstantExpr::getBitCast(literal, requiredType);
+  llvm::Constant *Result =
+      llvm::ConstantExpr::getPointerCast(literal, RequiredType);
+  CGM.setAddrOfGlobalBlock(blockInfo.BlockExpression, Result);
+  return Result;
 }
 
 void CodeGenFunction::setBlockContextParameter(const ImplicitParamDecl *D,
@@ -1135,9 +1192,13 @@
 
   // Instead of messing around with LocalDeclMap, just set the value
   // directly as BlockPointer.
-  BlockPointer = Builder.CreateBitCast(arg,
-                                       BlockInfo->StructureType->getPointerTo(),
-                                       "block");
+  BlockPointer = Builder.CreatePointerCast(
+      arg,
+      BlockInfo->StructureType->getPointerTo(
+          getContext().getLangOpts().OpenCL
+              ? getContext().getTargetAddressSpace(LangAS::opencl_generic)
+              : 0),
+      "block");
 }
 
 Address CodeGenFunction::LoadBlockStruct() {
@@ -1176,6 +1237,15 @@
   // The first argument is the block pointer.  Just take it as a void*
   // and cast it later.
   QualType selfTy = getContext().VoidPtrTy;
+
+  // For OpenCL passed block pointer can be private AS local variable or
+  // global AS program scope variable (for the case with and without captures).
+  // Generic AS is used therefore to be able to accomodate both private and
+  // generic AS in one implementation.
+  if (getLangOpts().OpenCL)
+    selfTy = getContext().getPointerType(getContext().getAddrSpaceQualType(
+        getContext().VoidTy, LangAS::opencl_generic));
+
   IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
 
   ImplicitParamDecl selfDecl(getContext(), const_cast<BlockDecl*>(blockDecl),
@@ -1303,23 +1373,102 @@
   return fn;
 }
 
-/*
-    notes.push_back(HelperInfo());
-    HelperInfo &note = notes.back();
-    note.index = capture.getIndex();
-    note.RequiresCopying = (ci->hasCopyExpr() || BlockRequiresCopying(type));
-    note.cxxbar_import = ci->getCopyExpr();
+namespace {
 
-    if (ci->isByRef()) {
-      note.flag = BLOCK_FIELD_IS_BYREF;
-      if (type.isObjCGCWeak())
-        note.flag |= BLOCK_FIELD_IS_WEAK;
-    } else if (type->isBlockPointerType()) {
-      note.flag = BLOCK_FIELD_IS_BLOCK;
-    } else {
-      note.flag = BLOCK_FIELD_IS_OBJECT;
-    }
- */
+/// Represents a type of copy/destroy operation that should be performed for an
+/// entity that's captured by a block.
+enum class BlockCaptureEntityKind {
+  CXXRecord, // Copy or destroy
+  ARCWeak,
+  ARCStrong,
+  BlockObject, // Assign or release
+  None
+};
+
+/// Represents a captured entity that requires extra operations in order for
+/// this entity to be copied or destroyed correctly.
+struct BlockCaptureManagedEntity {
+  BlockCaptureEntityKind Kind;
+  BlockFieldFlags Flags;
+  const BlockDecl::Capture &CI;
+  const CGBlockInfo::Capture &Capture;
+
+  BlockCaptureManagedEntity(BlockCaptureEntityKind Type, BlockFieldFlags Flags,
+                            const BlockDecl::Capture &CI,
+                            const CGBlockInfo::Capture &Capture)
+      : Kind(Type), Flags(Flags), CI(CI), Capture(Capture) {}
+};
+
+} // end anonymous namespace
+
+static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
+computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
+                               const LangOptions &LangOpts) {
+  if (CI.getCopyExpr()) {
+    assert(!CI.isByRef());
+    // don't bother computing flags
+    return std::make_pair(BlockCaptureEntityKind::CXXRecord, BlockFieldFlags());
+  }
+  BlockFieldFlags Flags;
+  if (CI.isByRef()) {
+    Flags = BLOCK_FIELD_IS_BYREF;
+    if (T.isObjCGCWeak())
+      Flags |= BLOCK_FIELD_IS_WEAK;
+    return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
+  }
+  if (!T->isObjCRetainableType())
+    // For all other types, the memcpy is fine.
+    return std::make_pair(BlockCaptureEntityKind::None, Flags);
+
+  Flags = BLOCK_FIELD_IS_OBJECT;
+  bool isBlockPointer = T->isBlockPointerType();
+  if (isBlockPointer)
+    Flags = BLOCK_FIELD_IS_BLOCK;
+
+  // Special rules for ARC captures:
+  Qualifiers QS = T.getQualifiers();
+
+  // We need to register __weak direct captures with the runtime.
+  if (QS.getObjCLifetime() == Qualifiers::OCL_Weak)
+    return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
+
+  // We need to retain the copied value for __strong direct captures.
+  if (QS.getObjCLifetime() == Qualifiers::OCL_Strong) {
+    // If it's a block pointer, we have to copy the block and
+    // assign that to the destination pointer, so we might as
+    // well use _Block_object_assign.  Otherwise we can avoid that.
+    return std::make_pair(!isBlockPointer ? BlockCaptureEntityKind::ARCStrong
+                                          : BlockCaptureEntityKind::BlockObject,
+                          Flags);
+  }
+
+  // Non-ARC captures of retainable pointers are strong and
+  // therefore require a call to _Block_object_assign.
+  if (!QS.getObjCLifetime() && !LangOpts.ObjCAutoRefCount)
+    return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
+
+  // Otherwise the memcpy is fine.
+  return std::make_pair(BlockCaptureEntityKind::None, Flags);
+}
+
+/// Find the set of block captures that need to be explicitly copied or destroy.
+static void findBlockCapturedManagedEntities(
+    const CGBlockInfo &BlockInfo, const LangOptions &LangOpts,
+    SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures,
+    llvm::function_ref<std::pair<BlockCaptureEntityKind, BlockFieldFlags>(
+        const BlockDecl::Capture &, QualType, const LangOptions &)>
+        Predicate) {
+  for (const auto &CI : BlockInfo.getBlockDecl()->captures()) {
+    const VarDecl *Variable = CI.getVariable();
+    const CGBlockInfo::Capture &Capture = BlockInfo.getCapture(Variable);
+    if (Capture.isConstant())
+      continue;
+
+    auto Info = Predicate(CI, Variable->getType(), LangOpts);
+    if (Info.first != BlockCaptureEntityKind::None)
+      ManagedCaptures.emplace_back(Info.first, Info.second, CI, Capture);
+  }
+}
 
 /// Generate the copy-helper function for a block closure object:
 ///   static void block_copy_helper(block_t *dst, block_t *src);
@@ -1379,78 +1528,28 @@
   dst = Address(Builder.CreateLoad(dst), blockInfo.BlockAlign);
   dst = Builder.CreateBitCast(dst, structPtrTy, "block.dest");
 
-  const BlockDecl *blockDecl = blockInfo.getBlockDecl();
+  SmallVector<BlockCaptureManagedEntity, 4> CopiedCaptures;
+  findBlockCapturedManagedEntities(blockInfo, getLangOpts(), CopiedCaptures,
+                                   computeCopyInfoForBlockCapture);
 
-  for (const auto &CI : blockDecl->captures()) {
-    const VarDecl *variable = CI.getVariable();
-    QualType type = variable->getType();
-
-    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
-    if (capture.isConstant()) continue;
-
-    const Expr *copyExpr = CI.getCopyExpr();
-    BlockFieldFlags flags;
-
-    bool useARCWeakCopy = false;
-    bool useARCStrongCopy = false;
-
-    if (copyExpr) {
-      assert(!CI.isByRef());
-      // don't bother computing flags
-
-    } else if (CI.isByRef()) {
-      flags = BLOCK_FIELD_IS_BYREF;
-      if (type.isObjCGCWeak())
-        flags |= BLOCK_FIELD_IS_WEAK;
-
-    } else if (type->isObjCRetainableType()) {
-      flags = BLOCK_FIELD_IS_OBJECT;
-      bool isBlockPointer = type->isBlockPointerType();
-      if (isBlockPointer)
-        flags = BLOCK_FIELD_IS_BLOCK;
-
-      // Special rules for ARC captures:
-      Qualifiers qs = type.getQualifiers();
-
-      // We need to register __weak direct captures with the runtime.
-      if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) {
-        useARCWeakCopy = true;
-
-      // We need to retain the copied value for __strong direct captures.
-      } else if (qs.getObjCLifetime() == Qualifiers::OCL_Strong) {
-        // If it's a block pointer, we have to copy the block and
-        // assign that to the destination pointer, so we might as
-        // well use _Block_object_assign.  Otherwise we can avoid that.
-        if (!isBlockPointer)
-          useARCStrongCopy = true;
-
-      // Non-ARC captures of retainable pointers are strong and
-      // therefore require a call to _Block_object_assign.
-      } else if (!qs.getObjCLifetime() && !getLangOpts().ObjCAutoRefCount) {
-        // fall through
-
-      // Otherwise the memcpy is fine.
-      } else {
-        continue;
-      }
-
-    // For all other types, the memcpy is fine.
-    } else {
-      continue;
-    }
+  for (const auto &CopiedCapture : CopiedCaptures) {
+    const BlockDecl::Capture &CI = CopiedCapture.CI;
+    const CGBlockInfo::Capture &capture = CopiedCapture.Capture;
+    BlockFieldFlags flags = CopiedCapture.Flags;
 
     unsigned index = capture.getIndex();
     Address srcField = Builder.CreateStructGEP(src, index, capture.getOffset());
     Address dstField = Builder.CreateStructGEP(dst, index, capture.getOffset());
 
     // If there's an explicit copy expression, we do that.
-    if (copyExpr) {
-      EmitSynthesizedCXXCopyCtor(dstField, srcField, copyExpr);
-    } else if (useARCWeakCopy) {
+    if (CI.getCopyExpr()) {
+      assert(CopiedCapture.Kind == BlockCaptureEntityKind::CXXRecord);
+      EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.getCopyExpr());
+    } else if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCWeak) {
       EmitARCCopyWeak(dstField, srcField);
     } else {
       llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src");
-      if (useARCStrongCopy) {
+      if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCStrong) {
         // At -O0, store null into the destination field (so that the
         // storeStrong doesn't over-release) and then call storeStrong.
         // This is a workaround to not having an initStrong call.
@@ -1471,6 +1570,7 @@
           cast<llvm::Instruction>(dstField.getPointer())->eraseFromParent();
         }
       } else {
+        assert(CopiedCapture.Kind == BlockCaptureEntityKind::BlockObject);
         srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
         llvm::Value *dstAddr =
           Builder.CreateBitCast(dstField.getPointer(), VoidPtrTy);
@@ -1478,6 +1578,7 @@
           dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask())
         };
 
+        const VarDecl *variable = CI.getVariable();
         bool copyCanThrow = false;
         if (CI.isByRef() && variable->getType()->getAsCXXRecordDecl()) {
           const Expr *copyExpr =
@@ -1501,6 +1602,52 @@
   return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
 }
 
+static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
+computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
+                                  const LangOptions &LangOpts) {
+  BlockFieldFlags Flags;
+  if (CI.isByRef()) {
+    Flags = BLOCK_FIELD_IS_BYREF;
+    if (T.isObjCGCWeak())
+      Flags |= BLOCK_FIELD_IS_WEAK;
+    return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
+  }
+
+  if (const CXXRecordDecl *Record = T->getAsCXXRecordDecl()) {
+    if (Record->hasTrivialDestructor())
+      return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags());
+    return std::make_pair(BlockCaptureEntityKind::CXXRecord, BlockFieldFlags());
+  }
+
+  // Other types don't need to be destroy explicitly.
+  if (!T->isObjCRetainableType())
+    return std::make_pair(BlockCaptureEntityKind::None, Flags);
+
+  Flags = BLOCK_FIELD_IS_OBJECT;
+  if (T->isBlockPointerType())
+    Flags = BLOCK_FIELD_IS_BLOCK;
+
+  // Special rules for ARC captures.
+  Qualifiers QS = T.getQualifiers();
+
+  // Use objc_storeStrong for __strong direct captures; the
+  // dynamic tools really like it when we do this.
+  if (QS.getObjCLifetime() == Qualifiers::OCL_Strong)
+    return std::make_pair(BlockCaptureEntityKind::ARCStrong, Flags);
+
+  // Support __weak direct captures.
+  if (QS.getObjCLifetime() == Qualifiers::OCL_Weak)
+    return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
+
+  // Non-ARC captures are strong, and we need to use
+  // _Block_object_dispose.
+  if (!QS.hasObjCLifetime() && !LangOpts.ObjCAutoRefCount)
+    return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
+
+  // Otherwise, we have nothing to do.
+  return std::make_pair(BlockCaptureEntityKind::None, Flags);
+}
+
 /// Generate the destroy-helper function for a block closure object:
 ///   static void block_destroy_helper(block_t *theBlock);
 ///
@@ -1550,79 +1697,39 @@
   src = Address(Builder.CreateLoad(src), blockInfo.BlockAlign);
   src = Builder.CreateBitCast(src, structPtrTy, "block");
 
-  const BlockDecl *blockDecl = blockInfo.getBlockDecl();
-
   CodeGenFunction::RunCleanupsScope cleanups(*this);
 
-  for (const auto &CI : blockDecl->captures()) {
-    const VarDecl *variable = CI.getVariable();
-    QualType type = variable->getType();
+  SmallVector<BlockCaptureManagedEntity, 4> DestroyedCaptures;
+  findBlockCapturedManagedEntities(blockInfo, getLangOpts(), DestroyedCaptures,
+                                   computeDestroyInfoForBlockCapture);
 
-    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
-    if (capture.isConstant()) continue;
-
-    BlockFieldFlags flags;
-    const CXXDestructorDecl *dtor = nullptr;
-
-    bool useARCWeakDestroy = false;
-    bool useARCStrongDestroy = false;
-
-    if (CI.isByRef()) {
-      flags = BLOCK_FIELD_IS_BYREF;
-      if (type.isObjCGCWeak())
-        flags |= BLOCK_FIELD_IS_WEAK;
-    } else if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) {
-      if (record->hasTrivialDestructor())
-        continue;
-      dtor = record->getDestructor();
-    } else if (type->isObjCRetainableType()) {
-      flags = BLOCK_FIELD_IS_OBJECT;
-      if (type->isBlockPointerType())
-        flags = BLOCK_FIELD_IS_BLOCK;
-
-      // Special rules for ARC captures.
-      Qualifiers qs = type.getQualifiers();
-
-      // Use objc_storeStrong for __strong direct captures; the
-      // dynamic tools really like it when we do this.
-      if (qs.getObjCLifetime() == Qualifiers::OCL_Strong) {
-        useARCStrongDestroy = true;
-
-      // Support __weak direct captures.
-      } else if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) {
-        useARCWeakDestroy = true;
-
-      // Non-ARC captures are strong, and we need to use _Block_object_dispose.
-      } else if (!qs.hasObjCLifetime() && !getLangOpts().ObjCAutoRefCount) {
-        // fall through
-
-      // Otherwise, we have nothing to do.
-      } else {
-        continue;
-      }
-    } else {
-      continue;
-    }
+  for (const auto &DestroyedCapture : DestroyedCaptures) {
+    const BlockDecl::Capture &CI = DestroyedCapture.CI;
+    const CGBlockInfo::Capture &capture = DestroyedCapture.Capture;
+    BlockFieldFlags flags = DestroyedCapture.Flags;
 
     Address srcField =
       Builder.CreateStructGEP(src, capture.getIndex(), capture.getOffset());
 
-    // If there's an explicit copy expression, we do that.
-    if (dtor) {
-      PushDestructorCleanup(dtor, srcField);
+    // If the captured record has a destructor then call it.
+    if (DestroyedCapture.Kind == BlockCaptureEntityKind::CXXRecord) {
+      const auto *Dtor =
+          CI.getVariable()->getType()->getAsCXXRecordDecl()->getDestructor();
+      PushDestructorCleanup(Dtor, srcField);
 
-    // If this is a __weak capture, emit the release directly.
-    } else if (useARCWeakDestroy) {
+      // If this is a __weak capture, emit the release directly.
+    } else if (DestroyedCapture.Kind == BlockCaptureEntityKind::ARCWeak) {
       EmitARCDestroyWeak(srcField);
 
     // Destroy strong objects with a call if requested.
-    } else if (useARCStrongDestroy) {
+    } else if (DestroyedCapture.Kind == BlockCaptureEntityKind::ARCStrong) {
       EmitARCDestroyStrong(srcField, ARCImpreciseLifetime);
 
     // Otherwise we call _Block_object_dispose.  It wouldn't be too
     // hard to just emit this as a cleanup if we wanted to make sure
     // that things were done in reverse.
     } else {
+      assert(DestroyedCapture.Kind == BlockCaptureEntityKind::BlockObject);
       llvm::Value *value = Builder.CreateLoad(srcField);
       value = Builder.CreateBitCast(value, VoidPtrTy);
       BuildBlockRelease(value, flags);
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 7eaf0f7..23b3a80 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -35,6 +35,11 @@
 using namespace CodeGen;
 using namespace llvm;
 
+static
+int64_t clamp(int64_t Value, int64_t Low, int64_t High) {
+  return std::min(High, std::max(Low, Value));
+}
+
 /// getBuiltinLibFunction - Given a builtin id for a function like
 /// "__builtin_fabsf", return a Function* for "fabsf".
 llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
@@ -415,10 +420,11 @@
 
 llvm::Value *
 CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
-                                                 llvm::IntegerType *ResType) {
+                                                 llvm::IntegerType *ResType,
+                                                 llvm::Value *EmittedE) {
   uint64_t ObjectSize;
   if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type))
-    return emitBuiltinObjectSize(E, Type, ResType);
+    return emitBuiltinObjectSize(E, Type, ResType, EmittedE);
   return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true);
 }
 
@@ -427,9 +433,14 @@
 ///   - A llvm::Argument (if E is a param with the pass_object_size attribute on
 ///     it)
 ///   - A call to the @llvm.objectsize intrinsic
+///
+/// EmittedE is the result of emitting `E` as a scalar expr. If it's non-null
+/// and we wouldn't otherwise try to reference a pass_object_size parameter,
+/// we'll call @llvm.objectsize on EmittedE, rather than emitting E.
 llvm::Value *
 CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
-                                       llvm::IntegerType *ResType) {
+                                       llvm::IntegerType *ResType,
+                                       llvm::Value *EmittedE) {
   // We need to reference an argument if the pointer is a parameter with the
   // pass_object_size attribute.
   if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) {
@@ -452,16 +463,17 @@
   // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't
   // evaluate E for side-effects. In either case, we shouldn't lower to
   // @llvm.objectsize.
-  if (Type == 3 || E->HasSideEffects(getContext()))
+  if (Type == 3 || (!EmittedE && E->HasSideEffects(getContext())))
     return getDefaultBuiltinObjectSizeResult(Type, ResType);
 
-  // LLVM only supports 0 and 2, make sure that we pass along that
-  // as a boolean.
+  Value *Ptr = EmittedE ? EmittedE : EmitScalarExpr(E);
+  assert(Ptr->getType()->isPointerTy() &&
+         "Non-pointer passed to __builtin_object_size?");
+
+  // LLVM only supports 0 and 2, make sure that we pass along that as a boolean.
   auto *CI = ConstantInt::get(Builder.getInt1Ty(), (Type & 2) >> 1);
-  // FIXME: Get right address space.
-  llvm::Type *Tys[] = {ResType, Builder.getInt8PtrTy(0)};
-  Value *F = CGM.getIntrinsic(Intrinsic::objectsize, Tys);
-  return Builder.CreateCall(F, {EmitScalarExpr(E), CI});
+  Value *F = CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()});
+  return Builder.CreateCall(F, {Ptr, CI});
 }
 
 // Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we
@@ -477,10 +489,11 @@
   _InterlockedIncrement,
   _InterlockedOr,
   _InterlockedXor,
+  __fastfail,
 };
 
 Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
-  const CallExpr *E) {
+                                            const CallExpr *E) {
   switch (BuiltinID) {
   case MSVCIntrin::_BitScanForward:
   case MSVCIntrin::_BitScanReverse: {
@@ -561,6 +574,37 @@
       llvm::AtomicOrdering::SequentiallyConsistent);
     return Builder.CreateAdd(RMWI, ConstantInt::get(IntTy, 1));
   }
+
+  case MSVCIntrin::__fastfail: {
+    // Request immediate process termination from the kernel. The instruction
+    // sequences to do this are documented on MSDN:
+    // https://msdn.microsoft.com/en-us/library/dn774154.aspx
+    llvm::Triple::ArchType ISA = getTarget().getTriple().getArch();
+    StringRef Asm, Constraints;
+    switch (ISA) {
+    default:
+      ErrorUnsupported(E, "__fastfail call for this architecture");
+      break;
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+      Asm = "int $$0x29";
+      Constraints = "{cx}";
+      break;
+    case llvm::Triple::thumb:
+      Asm = "udf #251";
+      Constraints = "{r0}";
+      break;
+    }
+    llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {Int32Ty}, false);
+    llvm::InlineAsm *IA =
+        llvm::InlineAsm::get(FTy, Asm, Constraints, /*SideEffects=*/true);
+    llvm::AttributeSet NoReturnAttr =
+        AttributeSet::get(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
+                          llvm::Attribute::NoReturn);
+    CallSite CS = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0)));
+    CS.setAttributes(NoReturnAttr);
+    return CS.getInstruction();
+  }
   }
   llvm_unreachable("Incorrect MSVC intrinsic!");
 }
@@ -927,7 +971,8 @@
 
     // We pass this builtin onto the optimizer so that it can figure out the
     // object size in more complex cases.
-    return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType));
+    return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType,
+                                             /*EmittedE=*/nullptr));
   }
   case Builtin::BI__builtin_prefetch: {
     Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
@@ -959,8 +1004,8 @@
       SanitizerScope SanScope(this);
       EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
                                SanitizerKind::Unreachable),
-                "builtin_unreachable", EmitCheckSourceLocation(E->getExprLoc()),
-                None);
+                SanitizerHandler::BuiltinUnreachable,
+                EmitCheckSourceLocation(E->getExprLoc()), None);
     } else
       Builder.CreateUnreachable();
 
@@ -1184,6 +1229,10 @@
     return RValue::get(Dest.getPointer());
   }
 
+  case Builtin::BI__builtin_char_memchr:
+    BuiltinID = Builtin::BI__builtin_memchr;
+    break;
+
   case Builtin::BI__builtin___memcpy_chk: {
     // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
     llvm::APSInt Size, DstSize;
@@ -2214,7 +2263,7 @@
                             llvm::Attribute::ReturnsTwice);
       llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction(
           llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
-          "_setjmpex", ReturnsTwiceAttr);
+          "_setjmpex", ReturnsTwiceAttr, /*Local=*/true);
       llvm::Value *Buf = Builder.CreateBitOrPointerCast(
           EmitScalarExpr(E->getArg(0)), Int8PtrTy);
       llvm::Value *FrameAddr =
@@ -2239,7 +2288,7 @@
         llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy};
         llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction(
             llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true),
-            "_setjmp3", ReturnsTwiceAttr);
+            "_setjmp3", ReturnsTwiceAttr, /*Local=*/true);
         llvm::Value *Count = ConstantInt::get(IntTy, 0);
         llvm::Value *Args[] = {Buf, Count};
         CS = EmitRuntimeCallOrInvoke(SetJmp3, Args);
@@ -2247,7 +2296,7 @@
         llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy};
         llvm::Constant *SetJmp = CGM.CreateRuntimeFunction(
             llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
-            "_setjmp", ReturnsTwiceAttr);
+            "_setjmp", ReturnsTwiceAttr, /*Local=*/true);
         llvm::Value *FrameAddr =
             Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
                                ConstantInt::get(Int32Ty, 0));
@@ -2267,6 +2316,11 @@
     break;
   }
 
+  case Builtin::BI__fastfail: {
+    return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E));
+    break;
+  }
+
   case Builtin::BI__builtin_coro_size: {
     auto & Context = getContext();
     auto SizeTy = Context.getSizeType();
@@ -2483,25 +2537,36 @@
     unsigned NumArgs = E->getNumArgs();
 
     llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy);
-    llvm::Type *RangeTy = ConvertType(getContext().OCLNDRangeTy);
+    llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
+        getContext().getTargetAddressSpace(LangAS::opencl_generic));
 
     llvm::Value *Queue = EmitScalarExpr(E->getArg(0));
     llvm::Value *Flags = EmitScalarExpr(E->getArg(1));
-    llvm::Value *Range = EmitScalarExpr(E->getArg(2));
+    LValue NDRangeL = EmitAggExprToLValue(E->getArg(2));
+    llvm::Value *Range = NDRangeL.getAddress().getPointer();
+    llvm::Type *RangeTy = NDRangeL.getAddress().getType();
 
     if (NumArgs == 4) {
       // The most basic form of the call with parameters:
       // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void)
       Name = "__enqueue_kernel_basic";
-      llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, Int8PtrTy};
+      llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy};
       llvm::FunctionType *FTy = llvm::FunctionType::get(
           Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys, 4), false);
 
-      llvm::Value *Block =
-          Builder.CreateBitCast(EmitScalarExpr(E->getArg(3)), Int8PtrTy);
+      llvm::Value *Block = Builder.CreatePointerCast(
+          EmitScalarExpr(E->getArg(3)), GenericVoidPtrTy);
 
-      return RValue::get(Builder.CreateCall(
-          CGM.CreateRuntimeFunction(FTy, Name), {Queue, Flags, Range, Block}));
+      AttrBuilder B;
+      B.addAttribute(Attribute::ByVal);
+      AttributeSet ByValAttrSet =
+          AttributeSet::get(CGM.getModule().getContext(), 3U, B);
+
+      auto RTCall =
+          Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name, ByValAttrSet),
+                             {Queue, Flags, Range, Block});
+      RTCall->setAttributes(ByValAttrSet);
+      return RValue::get(RTCall);
     }
     assert(NumArgs >= 5 && "Invalid enqueue_kernel signature");
 
@@ -2509,14 +2574,14 @@
     if (E->getArg(3)->getType()->isBlockPointerType()) {
       // No events passed, but has variadic arguments.
       Name = "__enqueue_kernel_vaargs";
-      llvm::Value *Block =
-          Builder.CreateBitCast(EmitScalarExpr(E->getArg(3)), Int8PtrTy);
+      llvm::Value *Block = Builder.CreatePointerCast(
+          EmitScalarExpr(E->getArg(3)), GenericVoidPtrTy);
       // Create a vector of the arguments, as well as a constant value to
       // express to the runtime the number of variadic arguments.
       std::vector<llvm::Value *> Args = {Queue, Flags, Range, Block,
                                          ConstantInt::get(IntTy, NumArgs - 4)};
-      std::vector<llvm::Type *> ArgTys = {QueueTy, IntTy, RangeTy, Int8PtrTy,
-                                          IntTy};
+      std::vector<llvm::Type *> ArgTys = {QueueTy, IntTy, RangeTy,
+                                          GenericVoidPtrTy, IntTy};
 
       // Each of the following arguments specifies the size of the corresponding
       // argument passed to the enqueued block.
@@ -2546,12 +2611,12 @@
       // Convert to generic address space.
       EventList = Builder.CreatePointerCast(EventList, EventPtrTy);
       ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy);
-      llvm::Value *Block =
-          Builder.CreateBitCast(EmitScalarExpr(E->getArg(6)), Int8PtrTy);
+      llvm::Value *Block = Builder.CreatePointerCast(
+          EmitScalarExpr(E->getArg(6)), GenericVoidPtrTy);
 
-      std::vector<llvm::Type *> ArgTys = {QueueTy,  Int32Ty,    RangeTy,
-                                          Int32Ty,  EventPtrTy, EventPtrTy,
-                                          Int8PtrTy};
+      std::vector<llvm::Type *> ArgTys = {
+          QueueTy,    Int32Ty,    RangeTy,         Int32Ty,
+          EventPtrTy, EventPtrTy, GenericVoidPtrTy};
 
       std::vector<llvm::Value *> Args = {Queue,     Flags,    Range, NumEvents,
                                          EventList, ClkEvent, Block};
@@ -2587,26 +2652,30 @@
   // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block
   // parameter.
   case Builtin::BIget_kernel_work_group_size: {
+    llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
+        getContext().getTargetAddressSpace(LangAS::opencl_generic));
     Value *Arg = EmitScalarExpr(E->getArg(0));
-    Arg = Builder.CreateBitCast(Arg, Int8PtrTy);
-    return RValue::get(
-        Builder.CreateCall(CGM.CreateRuntimeFunction(
-                               llvm::FunctionType::get(IntTy, Int8PtrTy, false),
-                               "__get_kernel_work_group_size_impl"),
-                           Arg));
-  }
-  case Builtin::BIget_kernel_preferred_work_group_size_multiple: {
-    Value *Arg = EmitScalarExpr(E->getArg(0));
-    Arg = Builder.CreateBitCast(Arg, Int8PtrTy);
+    Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy);
     return RValue::get(Builder.CreateCall(
         CGM.CreateRuntimeFunction(
-            llvm::FunctionType::get(IntTy, Int8PtrTy, false),
+            llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false),
+            "__get_kernel_work_group_size_impl"),
+        Arg));
+  }
+  case Builtin::BIget_kernel_preferred_work_group_size_multiple: {
+    llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
+        getContext().getTargetAddressSpace(LangAS::opencl_generic));
+    Value *Arg = EmitScalarExpr(E->getArg(0));
+    Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy);
+    return RValue::get(Builder.CreateCall(
+        CGM.CreateRuntimeFunction(
+            llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false),
             "__get_kernel_preferred_work_group_multiple_impl"),
         Arg));
   }
   case Builtin::BIprintf:
-    if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
-      return EmitCUDADevicePrintfCallExpr(E, ReturnValue);
+    if (getTarget().getTriple().isNVPTX())
+      return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue);
     break;
   case Builtin::BI__builtin_canonicalize:
   case Builtin::BI__builtin_canonicalizef:
@@ -4189,7 +4258,7 @@
 
   if (SysReg.empty()) {
     const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts();
-    SysReg = cast<StringLiteral>(SysRegStrExpr)->getString();
+    SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString();
   }
 
   llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) };
@@ -4313,9 +4382,9 @@
   }
 
   if (BuiltinID == ARM::BI__builtin_arm_rbit) {
-    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_rbit),
-                                               EmitScalarExpr(E->getArg(0)),
-                              "rbit");
+    llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
+    return Builder.CreateCall(
+        CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
   }
 
   if (BuiltinID == ARM::BI__clear_cache) {
@@ -5221,14 +5290,14 @@
            "rbit of unusual size!");
     llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
     return Builder.CreateCall(
-        CGM.getIntrinsic(Intrinsic::aarch64_rbit, Arg->getType()), Arg, "rbit");
+        CGM.getIntrinsic(Intrinsic::bitreverse, 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");
+        CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
   }
 
   if (BuiltinID == AArch64::BI__clear_cache) {
@@ -7312,7 +7381,12 @@
   case X86::BI__builtin_ia32_undef128:
   case X86::BI__builtin_ia32_undef256:
   case X86::BI__builtin_ia32_undef512:
-    return UndefValue::get(ConvertType(E->getType()));
+    // The x86 definition of "undef" is not the same as the LLVM definition
+    // (PR32176). We leave optimizing away an unnecessary zero constant to the
+    // IR optimizer and backend.
+    // TODO: If we had a "freeze" IR instruction to generate a fixed undef
+    // value, we should use that here instead of a zero.
+    return llvm::Constant::getNullValue(ConvertType(E->getType()));
   case X86::BI__builtin_ia32_vec_init_v8qi:
   case X86::BI__builtin_ia32_vec_init_v4hi:
   case X86::BI__builtin_ia32_vec_init_v2si:
@@ -7913,6 +7987,21 @@
     // instruction, but it will create a memset that won't be optimized away.
     return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true);
   }
+  case X86::BI__ud2:
+    // llvm.trap makes a ud2a instruction on x86.
+    return EmitTrapCall(Intrinsic::trap);
+  case X86::BI__int2c: {
+    // This syscall signals a driver assertion failure in x86 NT kernels.
+    llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
+    llvm::InlineAsm *IA =
+        llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*SideEffects=*/true);
+    llvm::AttributeSet NoReturnAttr =
+        AttributeSet::get(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
+                          llvm::Attribute::NoReturn);
+    CallSite CS = Builder.CreateCall(IA);
+    CS.setAttributes(NoReturnAttr);
+    return CS.getInstruction();
+  }
   }
 }
 
@@ -8191,6 +8280,85 @@
     llvm_unreachable("Unknown FMA operation");
     return nullptr; // Suppress no-return warning
   }
+
+  case PPC::BI__builtin_vsx_insertword: {
+    llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
+
+    // Third argument is a compile time constant int. It must be clamped to
+    // to the range [0, 12].
+    ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
+    assert(ArgCI &&
+           "Third arg to xxinsertw intrinsic must be constant integer");
+    const int64_t MaxIndex = 12;
+    int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
+
+    // The builtin semantics don't exactly match the xxinsertw instructions
+    // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the
+    // word from the first argument, and inserts it in the second argument. The
+    // instruction extracts the word from its second input register and inserts
+    // it into its first input register, so swap the first and second arguments.
+    std::swap(Ops[0], Ops[1]);
+
+    // Need to cast the second argument from a vector of unsigned int to a
+    // vector of long long.
+    Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
+
+    if (getTarget().isLittleEndian()) {
+      // Create a shuffle mask of (1, 0)
+      Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
+                                   ConstantInt::get(Int32Ty, 0)
+                                 };
+      Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
+
+      // Reverse the double words in the vector we will extract from.
+      Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
+      Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask);
+
+      // Reverse the index.
+      Index = MaxIndex - Index;
+    }
+
+    // Intrinsic expects the first arg to be a vector of int.
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
+    Ops[2] = ConstantInt::getSigned(Int32Ty, Index);
+    return Builder.CreateCall(F, Ops);
+  }
+
+  case PPC::BI__builtin_vsx_extractuword: {
+    llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
+
+    // Intrinsic expects the first argument to be a vector of doublewords.
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
+
+    // The second argument is a compile time constant int that needs to
+    // be clamped to the range [0, 12].
+    ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]);
+    assert(ArgCI &&
+           "Second Arg to xxextractuw intrinsic must be a constant integer!");
+    const int64_t MaxIndex = 12;
+    int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
+
+    if (getTarget().isLittleEndian()) {
+      // Reverse the index.
+      Index = MaxIndex - Index;
+      Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
+
+      // Emit the call, then reverse the double words of the results vector.
+      Value *Call = Builder.CreateCall(F, Ops);
+
+      // Create a shuffle mask of (1, 0)
+      Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
+                                   ConstantInt::get(Int32Ty, 0)
+                                 };
+      Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
+
+      Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask);
+      return ShuffleCall;
+    } else {
+      Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
+      return Builder.CreateCall(F, Ops);
+    }
+  }
   }
 }
 
@@ -8238,6 +8406,14 @@
 
   case AMDGPU::BI__builtin_amdgcn_ds_swizzle:
     return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle);
+  case AMDGPU::BI__builtin_amdgcn_mov_dpp: {
+    llvm::SmallVector<llvm::Value *, 5> Args;
+    for (unsigned I = 0; I != 5; ++I)
+      Args.push_back(EmitScalarExpr(E->getArg(I)));
+    Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_mov_dpp,
+                                    Args[0]->getType());
+    return Builder.CreateCall(F, Args);
+  }
   case AMDGPU::BI__builtin_amdgcn_div_fixup:
   case AMDGPU::BI__builtin_amdgcn_div_fixupf:
   case AMDGPU::BI__builtin_amdgcn_div_fixuph:
@@ -8303,7 +8479,9 @@
   case AMDGPU::BI__builtin_amdgcn_classf:
   case AMDGPU::BI__builtin_amdgcn_classh:
     return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class);
-
+  case AMDGPU::BI__builtin_amdgcn_fmed3f:
+  case AMDGPU::BI__builtin_amdgcn_fmed3h:
+    return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3);
   case AMDGPU::BI__builtin_amdgcn_read_exec: {
     CallInst *CI = cast<CallInst>(
       EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec"));
diff --git a/lib/CodeGen/CGCUDABuiltin.cpp b/lib/CodeGen/CGCUDABuiltin.cpp
deleted file mode 100644
index 44dd003..0000000
--- a/lib/CodeGen/CGCUDABuiltin.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-//===----- CGCUDABuiltin.cpp - Codegen for CUDA builtins ------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Generates code for built-in CUDA calls which are not runtime-specific.
-// (Runtime-specific codegen lives in CGCUDARuntime.)
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "clang/Basic/Builtins.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/Support/MathExtras.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-static llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
-  llvm::Type *ArgTypes[] = {llvm::Type::getInt8PtrTy(M.getContext()),
-                            llvm::Type::getInt8PtrTy(M.getContext())};
-  llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get(
-      llvm::Type::getInt32Ty(M.getContext()), ArgTypes, false);
-
-  if (auto* F = M.getFunction("vprintf")) {
-    // Our CUDA system header declares vprintf with the right signature, so
-    // nobody else should have been able to declare vprintf with a bogus
-    // signature.
-    assert(F->getFunctionType() == VprintfFuncType);
-    return F;
-  }
-
-  // vprintf doesn't already exist; create a declaration and insert it into the
-  // module.
-  return llvm::Function::Create(
-      VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, "vprintf", &M);
-}
-
-// Transforms a call to printf into a call to the NVPTX vprintf syscall (which
-// isn't particularly special; it's invoked just like a regular function).
-// vprintf takes two args: A format string, and a pointer to a buffer containing
-// the varargs.
-//
-// For example, the call
-//
-//   printf("format string", arg1, arg2, arg3);
-//
-// is converted into something resembling
-//
-//   struct Tmp {
-//     Arg1 a1;
-//     Arg2 a2;
-//     Arg3 a3;
-//   };
-//   char* buf = alloca(sizeof(Tmp));
-//   *(Tmp*)buf = {a1, a2, a3};
-//   vprintf("format string", buf);
-//
-// buf is aligned to the max of {alignof(Arg1), ...}.  Furthermore, each of the
-// args is itself aligned to its preferred alignment.
-//
-// Note that by the time this function runs, E's args have already undergone the
-// standard C vararg promotion (short -> int, float -> double, etc.).
-RValue
-CodeGenFunction::EmitCUDADevicePrintfCallExpr(const CallExpr *E,
-                                              ReturnValueSlot ReturnValue) {
-  assert(getLangOpts().CUDA);
-  assert(getLangOpts().CUDAIsDevice);
-  assert(E->getBuiltinCallee() == Builtin::BIprintf);
-  assert(E->getNumArgs() >= 1); // printf always has at least one arg.
-
-  const llvm::DataLayout &DL = CGM.getDataLayout();
-  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
-
-  CallArgList Args;
-  EmitCallArgs(Args,
-               E->getDirectCallee()->getType()->getAs<FunctionProtoType>(),
-               E->arguments(), E->getDirectCallee(),
-               /* ParamsToSkip = */ 0);
-
-  // We don't know how to emit non-scalar varargs.
-  if (std::any_of(Args.begin() + 1, Args.end(),
-                  [](const CallArg &A) { return !A.RV.isScalar(); })) {
-    CGM.ErrorUnsupported(E, "non-scalar arg to printf");
-    return RValue::get(llvm::ConstantInt::get(IntTy, 0));
-  }
-
-  // Construct and fill the args buffer that we'll pass to vprintf.
-  llvm::Value *BufferPtr;
-  if (Args.size() <= 1) {
-    // If there are no args, pass a null pointer to vprintf.
-    BufferPtr = llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(Ctx));
-  } else {
-    llvm::SmallVector<llvm::Type *, 8> ArgTypes;
-    for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I)
-      ArgTypes.push_back(Args[I].RV.getScalarVal()->getType());
-
-    // Using llvm::StructType is correct only because printf doesn't accept
-    // aggregates.  If we had to handle aggregates here, we'd have to manually
-    // compute the offsets within the alloca -- we wouldn't be able to assume
-    // that the alignment of the llvm type was the same as the alignment of the
-    // clang type.
-    llvm::Type *AllocaTy = llvm::StructType::create(ArgTypes, "printf_args");
-    llvm::Value *Alloca = CreateTempAlloca(AllocaTy);
-
-    for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I) {
-      llvm::Value *P = Builder.CreateStructGEP(AllocaTy, Alloca, I - 1);
-      llvm::Value *Arg = Args[I].RV.getScalarVal();
-      Builder.CreateAlignedStore(Arg, P, DL.getPrefTypeAlignment(Arg->getType()));
-    }
-    BufferPtr = Builder.CreatePointerCast(Alloca, llvm::Type::getInt8PtrTy(Ctx));
-  }
-
-  // Invoke vprintf and return.
-  llvm::Function* VprintfFunc = GetVprintfDeclaration(CGM.getModule());
-  return RValue::get(
-      Builder.CreateCall(VprintfFunc, {Args[0].RV.getScalarVal(), BufferPtr}));
-}
diff --git a/lib/CodeGen/CGCUDANV.cpp b/lib/CodeGen/CGCUDANV.cpp
index 83febcb..813cd74 100644
--- a/lib/CodeGen/CGCUDANV.cpp
+++ b/lib/CodeGen/CGCUDANV.cpp
@@ -15,7 +15,7 @@
 #include "CGCUDARuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/Decl.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/CallSite.h"
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 589dea0..59010f4 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -272,10 +272,11 @@
   VTable = CGF.Builder.CreateBitCast(VTable, Ty);
   assert(VTable && "BuildVirtualCall = kext vtbl pointer is null");
   uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
-  uint64_t AddressPoint =
-    CGM.getItaniumVTableContext().getVTableLayout(RD)
-       .getAddressPoint(BaseSubobject(RD, CharUnits::Zero()));
-  VTableIndex += AddressPoint;
+  const VTableLayout &VTLayout = CGM.getItaniumVTableContext().getVTableLayout(RD);
+  VTableLayout::AddressPointLocation AddressPoint =
+      VTLayout.getAddressPoint(BaseSubobject(RD, CharUnits::Zero()));
+  VTableIndex += VTLayout.getVTableOffset(AddressPoint.VTableIndex) +
+                 AddressPoint.AddressPointIndex;
   llvm::Value *VFuncPtr =
     CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt");
   llvm::Value *VFunc =
diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h
index d53fd4c..186abc3 100644
--- a/lib/CodeGen/CGCXXABI.h
+++ b/lib/CodeGen/CGCXXABI.h
@@ -291,11 +291,26 @@
   /// Emit constructor variants required by this ABI.
   virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0;
 
+  /// Notes how many arguments were added to the beginning (Prefix) and ending
+  /// (Suffix) of an arg list.
+  ///
+  /// Note that Prefix actually refers to the number of args *after* the first
+  /// one: `this` arguments always come first.
+  struct AddedStructorArgs {
+    unsigned Prefix = 0;
+    unsigned Suffix = 0;
+    AddedStructorArgs() = default;
+    AddedStructorArgs(unsigned P, unsigned S) : Prefix(P), Suffix(S) {}
+    static AddedStructorArgs prefix(unsigned N) { return {N, 0}; }
+    static AddedStructorArgs suffix(unsigned N) { return {0, N}; }
+  };
+
   /// Build the signature of the given constructor or destructor variant by
   /// adding any required parameters.  For convenience, ArgTys has been
   /// initialized with the type of 'this'.
-  virtual void buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
-                                      SmallVectorImpl<CanQualType> &ArgTys) = 0;
+  virtual AddedStructorArgs
+  buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
+                         SmallVectorImpl<CanQualType> &ArgTys) = 0;
 
   /// Returns true if the given destructor type should be emitted as a linkonce
   /// delegating thunk, regardless of whether the dtor is defined in this TU or
@@ -355,9 +370,9 @@
 
   /// Add any ABI-specific implicit arguments needed to call a constructor.
   ///
-  /// \return The number of args added to the call, which is typically zero or
-  /// one.
-  virtual unsigned
+  /// \return The number of arguments added at the beginning and end of the
+  /// call, which is typically zero or one.
+  virtual AddedStructorArgs
   addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
                              CXXCtorType Type, bool ForVirtualBase,
                              bool Delegating, CallArgList &Args) = 0;
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 8f61f46..5f069bf 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -101,39 +101,64 @@
                                  FTNP->getExtInfo(), {}, RequiredArgs(0));
 }
 
+static void addExtParameterInfosForCall(
+         llvm::SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &paramInfos,
+                                        const FunctionProtoType *proto,
+                                        unsigned prefixArgs,
+                                        unsigned totalArgs) {
+  assert(proto->hasExtParameterInfos());
+  assert(paramInfos.size() <= prefixArgs);
+  assert(proto->getNumParams() + prefixArgs <= totalArgs);
+
+  paramInfos.reserve(totalArgs);
+
+  // Add default infos for any prefix args that don't already have infos.
+  paramInfos.resize(prefixArgs);
+
+  // Add infos for the prototype.
+  for (const auto &ParamInfo : proto->getExtParameterInfos()) {
+    paramInfos.push_back(ParamInfo);
+    // pass_object_size params have no parameter info.
+    if (ParamInfo.hasPassObjectSize())
+      paramInfos.emplace_back();
+  }
+
+  assert(paramInfos.size() <= totalArgs &&
+         "Did we forget to insert pass_object_size args?");
+  // Add default infos for the variadic and/or suffix arguments.
+  paramInfos.resize(totalArgs);
+}
+
 /// Adds the formal paramaters in FPT to the given prefix. If any parameter in
 /// FPT has pass_object_size attrs, then we'll add parameters for those, too.
 static void appendParameterTypes(const CodeGenTypes &CGT,
                                  SmallVectorImpl<CanQualType> &prefix,
               SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &paramInfos,
-                                 CanQual<FunctionProtoType> FPT,
-                                 const FunctionDecl *FD) {
-  // Fill out paramInfos.
-  if (FPT->hasExtParameterInfos() || !paramInfos.empty()) {
-    assert(paramInfos.size() <= prefix.size());
-    auto protoParamInfos = FPT->getExtParameterInfos();
-    paramInfos.reserve(prefix.size() + protoParamInfos.size());
-    paramInfos.resize(prefix.size());
-    paramInfos.append(protoParamInfos.begin(), protoParamInfos.end());
-  }
-
-  // Fast path: unknown target.
-  if (FD == nullptr) {
+                                 CanQual<FunctionProtoType> FPT) {
+  // Fast path: don't touch param info if we don't need to.
+  if (!FPT->hasExtParameterInfos()) {
+    assert(paramInfos.empty() &&
+           "We have paramInfos, but the prototype doesn't?");
     prefix.append(FPT->param_type_begin(), FPT->param_type_end());
     return;
   }
 
-  // In the vast majority cases, we'll have precisely FPT->getNumParams()
+  unsigned PrefixSize = prefix.size();
+  // In the vast majority of cases, we'll have precisely FPT->getNumParams()
   // parameters; the only thing that can change this is the presence of
   // pass_object_size. So, we preallocate for the common case.
   prefix.reserve(prefix.size() + FPT->getNumParams());
 
-  assert(FD->getNumParams() == FPT->getNumParams());
+  auto ExtInfos = FPT->getExtParameterInfos();
+  assert(ExtInfos.size() == FPT->getNumParams());
   for (unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
     prefix.push_back(FPT->getParamType(I));
-    if (FD->getParamDecl(I)->hasAttr<PassObjectSizeAttr>())
+    if (ExtInfos[I].hasPassObjectSize())
       prefix.push_back(CGT.getContext().getSizeType());
   }
+
+  addExtParameterInfosForCall(paramInfos, FPT.getTypePtr(), PrefixSize,
+                              prefix.size());
 }
 
 /// Arrange the LLVM function layout for a value of the given function
@@ -147,7 +172,7 @@
   RequiredArgs Required =
       RequiredArgs::forPrototypePlus(FTP, prefix.size(), FD);
   // FIXME: Kill copy.
-  appendParameterTypes(CGT, prefix, paramInfos, FTP, FD);
+  appendParameterTypes(CGT, prefix, paramInfos, FTP);
   CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
 
   return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod,
@@ -286,9 +311,19 @@
 
   // Add the formal parameters.
   if (PassParams)
-    appendParameterTypes(*this, argTypes, paramInfos, FTP, MD);
+    appendParameterTypes(*this, argTypes, paramInfos, FTP);
 
-  TheCXXABI.buildStructorSignature(MD, Type, argTypes);
+  CGCXXABI::AddedStructorArgs AddedArgs =
+      TheCXXABI.buildStructorSignature(MD, Type, argTypes);
+  if (!paramInfos.empty()) {
+    // Note: prefix implies after the first param.
+    if (AddedArgs.Prefix)
+      paramInfos.insert(paramInfos.begin() + 1, AddedArgs.Prefix,
+                        FunctionProtoType::ExtParameterInfo{});
+    if (AddedArgs.Suffix)
+      paramInfos.append(AddedArgs.Suffix,
+                        FunctionProtoType::ExtParameterInfo{});
+  }
 
   RequiredArgs required =
       (PassParams && MD->isVariadic() ? RequiredArgs(argTypes.size())
@@ -321,26 +356,6 @@
   return argTypes;
 }
 
-static void addExtParameterInfosForCall(
-         llvm::SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &paramInfos,
-                                        const FunctionProtoType *proto,
-                                        unsigned prefixArgs,
-                                        unsigned totalArgs) {
-  assert(proto->hasExtParameterInfos());
-  assert(paramInfos.size() <= prefixArgs);
-  assert(proto->getNumParams() + prefixArgs <= totalArgs);
-
-  // Add default infos for any prefix args that don't already have infos.
-  paramInfos.resize(prefixArgs);
-
-  // Add infos for the prototype.
-  auto protoInfos = proto->getExtParameterInfos();
-  paramInfos.append(protoInfos.begin(), protoInfos.end());
-
-  // Add default infos for the variadic arguments.
-  paramInfos.resize(totalArgs);
-}
-
 static llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16>
 getExtParameterInfosForCall(const FunctionProtoType *proto,
                             unsigned prefixArgs, unsigned totalArgs) {
@@ -352,18 +367,31 @@
 }
 
 /// Arrange a call to a C++ method, passing the given arguments.
+///
+/// ExtraPrefixArgs is the number of ABI-specific args passed after the `this`
+/// parameter.
+/// ExtraSuffixArgs is the number of ABI-specific args passed at the end of
+/// args.
+/// PassProtoArgs indicates whether `args` has args for the parameters in the
+/// given CXXConstructorDecl.
 const CGFunctionInfo &
 CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
                                         const CXXConstructorDecl *D,
                                         CXXCtorType CtorKind,
-                                        unsigned ExtraArgs) {
+                                        unsigned ExtraPrefixArgs,
+                                        unsigned ExtraSuffixArgs,
+                                        bool PassProtoArgs) {
   // FIXME: Kill copy.
   SmallVector<CanQualType, 16> ArgTypes;
   for (const auto &Arg : args)
     ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
 
+  // +1 for implicit this, which should always be args[0].
+  unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
+
   CanQual<FunctionProtoType> FPT = GetFormalType(D);
-  RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, 1 + ExtraArgs, D);
+  RequiredArgs Required =
+      RequiredArgs::forPrototypePlus(FPT, TotalPrefixArgs + ExtraSuffixArgs, D);
   GlobalDecl GD(D, CtorKind);
   CanQualType ResultType = TheCXXABI.HasThisReturn(GD)
                                ? ArgTypes.front()
@@ -372,8 +400,14 @@
                                      : Context.VoidTy;
 
   FunctionType::ExtInfo Info = FPT->getExtInfo();
-  auto ParamInfos = getExtParameterInfosForCall(FPT.getTypePtr(), 1 + ExtraArgs,
-                                                ArgTypes.size());
+  llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> ParamInfos;
+  // If the prototype args are elided, we should only have ABI-specific args,
+  // which never have param info.
+  if (PassProtoArgs && FPT->hasExtParameterInfos()) {
+    // ABI-specific suffix arguments are treated the same as variadic arguments.
+    addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs,
+                                ArgTypes.size());
+  }
   return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true,
                                  /*chainCall=*/false, ArgTypes, Info,
                                  ParamInfos, Required);
@@ -393,15 +427,13 @@
 
   // When declaring a function without a prototype, always use a
   // non-variadic type.
-  if (isa<FunctionNoProtoType>(FTy)) {
-    CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>();
+  if (CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>()) {
     return arrangeLLVMFunctionInfo(
         noProto->getReturnType(), /*instanceMethod=*/false,
         /*chainCall=*/false, None, noProto->getExtInfo(), {},RequiredArgs::All);
   }
 
-  assert(isa<FunctionProtoType>(FTy));
-  return arrangeFreeFunctionType(FTy.getAs<FunctionProtoType>(), FD);
+  return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>(), FD);
 }
 
 /// Arrange the argument and result information for the declaration or
@@ -619,15 +651,20 @@
 }
 
 /// Arrange a call to a C++ method, passing the given arguments.
+///
+/// numPrefixArgs is the number of ABI-specific prefix arguments we have. It
+/// does not count `this`.
 const CGFunctionInfo &
 CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
                                    const FunctionProtoType *proto,
-                                   RequiredArgs required) {
-  unsigned numRequiredArgs =
-    (proto->isVariadic() ? required.getNumRequiredArgs() : args.size());
-  unsigned numPrefixArgs = numRequiredArgs - proto->getNumParams();
+                                   RequiredArgs required,
+                                   unsigned numPrefixArgs) {
+  assert(numPrefixArgs + 1 <= args.size() &&
+         "Emitting a call with less args than the required prefix?");
+  // Add one to account for `this`. It's a bit awkward here, but we don't count
+  // `this` in similar places elsewhere.
   auto paramInfos =
-    getExtParameterInfosForCall(proto, numPrefixArgs, args.size());
+    getExtParameterInfosForCall(proto, numPrefixArgs + 1, args.size());
 
   // FIXME: Kill copy.
   auto argTypes = getArgTypesForCall(Context, args);
@@ -1622,15 +1659,113 @@
     FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
 }
 
+void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
+                                               bool AttrOnCallSite,
+                                               llvm::AttrBuilder &FuncAttrs) {
+  // OptimizeNoneAttr takes precedence over -Os or -Oz. No warning needed.
+  if (!HasOptnone) {
+    if (CodeGenOpts.OptimizeSize)
+      FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
+    if (CodeGenOpts.OptimizeSize == 2)
+      FuncAttrs.addAttribute(llvm::Attribute::MinSize);
+  }
+
+  if (CodeGenOpts.DisableRedZone)
+    FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
+  if (CodeGenOpts.NoImplicitFloat)
+    FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
+
+  if (AttrOnCallSite) {
+    // Attributes that should go on the call site only.
+    if (!CodeGenOpts.SimplifyLibCalls ||
+        CodeGenOpts.isNoBuiltinFunc(Name.data()))
+      FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
+    if (!CodeGenOpts.TrapFuncName.empty())
+      FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName);
+  } else {
+    // Attributes that should go on the function, but not the call site.
+    if (!CodeGenOpts.DisableFPElim) {
+      FuncAttrs.addAttribute("no-frame-pointer-elim", "false");
+    } else if (CodeGenOpts.OmitLeafFramePointer) {
+      FuncAttrs.addAttribute("no-frame-pointer-elim", "false");
+      FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf");
+    } else {
+      FuncAttrs.addAttribute("no-frame-pointer-elim", "true");
+      FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf");
+    }
+
+    FuncAttrs.addAttribute("less-precise-fpmad",
+                           llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
+
+    if (!CodeGenOpts.FPDenormalMode.empty())
+      FuncAttrs.addAttribute("denormal-fp-math", CodeGenOpts.FPDenormalMode);
+
+    FuncAttrs.addAttribute("no-trapping-math",
+                           llvm::toStringRef(CodeGenOpts.NoTrappingMath));
+
+    // TODO: Are these all needed?
+    // unsafe/inf/nan/nsz are handled by instruction-level FastMathFlags.
+    FuncAttrs.addAttribute("no-infs-fp-math",
+                           llvm::toStringRef(CodeGenOpts.NoInfsFPMath));
+    FuncAttrs.addAttribute("no-nans-fp-math",
+                           llvm::toStringRef(CodeGenOpts.NoNaNsFPMath));
+    FuncAttrs.addAttribute("unsafe-fp-math",
+                           llvm::toStringRef(CodeGenOpts.UnsafeFPMath));
+    FuncAttrs.addAttribute("use-soft-float",
+                           llvm::toStringRef(CodeGenOpts.SoftFloat));
+    FuncAttrs.addAttribute("stack-protector-buffer-size",
+                           llvm::utostr(CodeGenOpts.SSPBufferSize));
+    FuncAttrs.addAttribute("no-signed-zeros-fp-math",
+                           llvm::toStringRef(CodeGenOpts.NoSignedZeros));
+    FuncAttrs.addAttribute(
+        "correctly-rounded-divide-sqrt-fp-math",
+        llvm::toStringRef(CodeGenOpts.CorrectlyRoundedDivSqrt));
+
+    // TODO: Reciprocal estimate codegen options should apply to instructions?
+    std::vector<std::string> &Recips = getTarget().getTargetOpts().Reciprocals;
+    if (!Recips.empty())
+      FuncAttrs.addAttribute("reciprocal-estimates",
+                             llvm::join(Recips.begin(), Recips.end(), ","));
+
+    if (CodeGenOpts.StackRealignment)
+      FuncAttrs.addAttribute("stackrealign");
+    if (CodeGenOpts.Backchain)
+      FuncAttrs.addAttribute("backchain");
+  }
+
+  if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice) {
+    // Conservatively, mark all functions and calls in CUDA as convergent
+    // (meaning, they may call an intrinsically convergent op, such as
+    // __syncthreads(), and so can't have certain optimizations applied around
+    // them).  LLVM will remove this attribute where it safely can.
+    FuncAttrs.addAttribute(llvm::Attribute::Convergent);
+
+    // Exceptions aren't supported in CUDA device code.
+    FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
+
+    // Respect -fcuda-flush-denormals-to-zero.
+    if (getLangOpts().CUDADeviceFlushDenormalsToZero)
+      FuncAttrs.addAttribute("nvptx-f32ftz", "true");
+  }
+}
+
+void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) {
+  llvm::AttrBuilder FuncAttrs;
+  ConstructDefaultFnAttrList(F.getName(),
+                             F.hasFnAttribute(llvm::Attribute::OptimizeNone),
+                             /* AttrOnCallsite = */ false, FuncAttrs);
+  llvm::AttributeSet AS = llvm::AttributeSet::get(
+      getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs);
+  F.addAttributes(llvm::AttributeSet::FunctionIndex, AS);
+}
+
 void CodeGenModule::ConstructAttributeList(
     StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo,
     AttributeListType &PAL, unsigned &CallingConv, bool AttrOnCallSite) {
   llvm::AttrBuilder FuncAttrs;
   llvm::AttrBuilder RetAttrs;
-  bool HasOptnone = false;
 
   CallingConv = FI.getEffectiveCallingConvention();
-
   if (FI.isNoReturn())
     FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
 
@@ -1641,7 +1776,7 @@
 
   const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
 
-  bool HasAnyX86InterruptAttr = false;
+  bool HasOptnone = false;
   // FIXME: handle sseregparm someday...
   if (TargetDecl) {
     if (TargetDecl->hasAttr<ReturnsTwiceAttr>())
@@ -1681,90 +1816,30 @@
     if (TargetDecl->hasAttr<ReturnsNonNullAttr>())
       RetAttrs.addAttribute(llvm::Attribute::NonNull);
 
-    HasAnyX86InterruptAttr = TargetDecl->hasAttr<AnyX86InterruptAttr>();
     HasOptnone = TargetDecl->hasAttr<OptimizeNoneAttr>();
+    if (auto *AllocSize = TargetDecl->getAttr<AllocSizeAttr>()) {
+      Optional<unsigned> NumElemsParam;
+      // alloc_size args are base-1, 0 means not present.
+      if (unsigned N = AllocSize->getNumElemsParam())
+        NumElemsParam = N - 1;
+      FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam() - 1,
+                                 NumElemsParam);
+    }
   }
 
-  // OptimizeNoneAttr takes precedence over -Os or -Oz. No warning needed.
-  if (!HasOptnone) {
-    if (CodeGenOpts.OptimizeSize)
-      FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
-    if (CodeGenOpts.OptimizeSize == 2)
-      FuncAttrs.addAttribute(llvm::Attribute::MinSize);
-  }
+  ConstructDefaultFnAttrList(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
 
-  if (CodeGenOpts.DisableRedZone)
-    FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
-  if (CodeGenOpts.NoImplicitFloat)
-    FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
   if (CodeGenOpts.EnableSegmentedStacks &&
       !(TargetDecl && TargetDecl->hasAttr<NoSplitStackAttr>()))
     FuncAttrs.addAttribute("split-stack");
 
-  if (AttrOnCallSite) {
-    // Attributes that should go on the call site only.
-    if (!CodeGenOpts.SimplifyLibCalls ||
-        CodeGenOpts.isNoBuiltinFunc(Name.data()))
-      FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
-    if (!CodeGenOpts.TrapFuncName.empty())
-      FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName);
-  } else {
-    // Attributes that should go on the function, but not the call site.
-    if (!CodeGenOpts.DisableFPElim) {
-      FuncAttrs.addAttribute("no-frame-pointer-elim", "false");
-    } else if (CodeGenOpts.OmitLeafFramePointer) {
-      FuncAttrs.addAttribute("no-frame-pointer-elim", "false");
-      FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf");
-    } else {
-      FuncAttrs.addAttribute("no-frame-pointer-elim", "true");
-      FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf");
-    }
-
+  if (!AttrOnCallSite) {
     bool DisableTailCalls =
-        CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr ||
-        (TargetDecl && TargetDecl->hasAttr<DisableTailCallsAttr>());
-    FuncAttrs.addAttribute(
-        "disable-tail-calls",
-        llvm::toStringRef(DisableTailCalls));
-
-    FuncAttrs.addAttribute("less-precise-fpmad",
-                           llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
-
-    if (!CodeGenOpts.FPDenormalMode.empty())
-      FuncAttrs.addAttribute("denormal-fp-math",
-                             CodeGenOpts.FPDenormalMode);
-
-    FuncAttrs.addAttribute("no-trapping-math",
-                           llvm::toStringRef(CodeGenOpts.NoTrappingMath));
-
-    // TODO: Are these all needed?
-    // unsafe/inf/nan/nsz are handled by instruction-level FastMathFlags.
-    FuncAttrs.addAttribute("no-infs-fp-math",
-                           llvm::toStringRef(CodeGenOpts.NoInfsFPMath));
-    FuncAttrs.addAttribute("no-nans-fp-math",
-                           llvm::toStringRef(CodeGenOpts.NoNaNsFPMath));
-    FuncAttrs.addAttribute("unsafe-fp-math",
-                           llvm::toStringRef(CodeGenOpts.UnsafeFPMath));
-    FuncAttrs.addAttribute("use-soft-float",
-                           llvm::toStringRef(CodeGenOpts.SoftFloat));
-    FuncAttrs.addAttribute("stack-protector-buffer-size",
-                           llvm::utostr(CodeGenOpts.SSPBufferSize));
-    FuncAttrs.addAttribute("no-signed-zeros-fp-math",
-                           llvm::toStringRef(CodeGenOpts.NoSignedZeros));
-    FuncAttrs.addAttribute(
-        "correctly-rounded-divide-sqrt-fp-math",
-        llvm::toStringRef(CodeGenOpts.CorrectlyRoundedDivSqrt));
-
-    // TODO: Reciprocal estimate codegen options should apply to instructions?
-    std::vector<std::string> &Recips = getTarget().getTargetOpts().Reciprocals;
-    if (!Recips.empty())
-      FuncAttrs.addAttribute("reciprocal-estimates",
-                             llvm::join(Recips.begin(), Recips.end(), ","));
-
-    if (CodeGenOpts.StackRealignment)
-      FuncAttrs.addAttribute("stackrealign");
-    if (CodeGenOpts.Backchain)
-      FuncAttrs.addAttribute("backchain");
+        CodeGenOpts.DisableTailCalls ||
+        (TargetDecl && (TargetDecl->hasAttr<DisableTailCallsAttr>() ||
+                        TargetDecl->hasAttr<AnyX86InterruptAttr>()));
+    FuncAttrs.addAttribute("disable-tail-calls",
+                           llvm::toStringRef(DisableTailCalls));
 
     // Add target-cpu and target-features attributes to functions. If
     // we have a decl for the function and it has a target attribute then
@@ -1813,21 +1888,6 @@
     }
   }
 
-  if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice) {
-    // Conservatively, mark all functions and calls in CUDA as convergent
-    // (meaning, they may call an intrinsically convergent op, such as
-    // __syncthreads(), and so can't have certain optimizations applied around
-    // them).  LLVM will remove this attribute where it safely can.
-    FuncAttrs.addAttribute(llvm::Attribute::Convergent);
-
-    // Exceptions aren't supported in CUDA device code.
-    FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
-
-    // Respect -fcuda-flush-denormals-to-zero.
-    if (getLangOpts().CUDADeviceFlushDenormalsToZero)
-      FuncAttrs.addAttribute("nvptx-f32ftz", "true");
-  }
-
   ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI);
 
   QualType RetTy = FI.getReturnType();
@@ -2852,19 +2912,7 @@
 
   llvm::Instruction *Ret;
   if (RV) {
-    if (CurCodeDecl && SanOpts.has(SanitizerKind::ReturnsNonnullAttribute)) {
-      if (auto RetNNAttr = CurCodeDecl->getAttr<ReturnsNonNullAttr>()) {
-        SanitizerScope SanScope(this);
-        llvm::Value *Cond = Builder.CreateICmpNE(
-            RV, llvm::Constant::getNullValue(RV->getType()));
-        llvm::Constant *StaticData[] = {
-            EmitCheckSourceLocation(EndLoc),
-            EmitCheckSourceLocation(RetNNAttr->getLocation()),
-        };
-        EmitCheck(std::make_pair(Cond, SanitizerKind::ReturnsNonnullAttribute),
-                  "nonnull_return", StaticData, None);
-      }
-    }
+    EmitReturnValueCheck(RV, EndLoc);
     Ret = Builder.CreateRet(RV);
   } else {
     Ret = Builder.CreateRetVoid();
@@ -2874,6 +2922,62 @@
     Ret->setDebugLoc(std::move(RetDbgLoc));
 }
 
+void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV,
+                                           SourceLocation EndLoc) {
+  // A current decl may not be available when emitting vtable thunks.
+  if (!CurCodeDecl)
+    return;
+
+  ReturnsNonNullAttr *RetNNAttr = nullptr;
+  if (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute))
+    RetNNAttr = CurCodeDecl->getAttr<ReturnsNonNullAttr>();
+
+  if (!RetNNAttr && !requiresReturnValueNullabilityCheck())
+    return;
+
+  // Prefer the returns_nonnull attribute if it's present.
+  SourceLocation AttrLoc;
+  SanitizerMask CheckKind;
+  if (RetNNAttr) {
+    assert(!requiresReturnValueNullabilityCheck() &&
+           "Cannot check nullability and the nonnull attribute");
+    AttrLoc = RetNNAttr->getLocation();
+    CheckKind = SanitizerKind::ReturnsNonnullAttribute;
+  } else {
+    // FIXME: The runtime shouldn't refer to the 'returns_nonnull' attribute.
+    if (auto *DD = dyn_cast<DeclaratorDecl>(CurCodeDecl))
+      if (auto *TSI = DD->getTypeSourceInfo())
+        if (auto FTL = TSI->getTypeLoc().castAs<FunctionTypeLoc>())
+          AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
+    CheckKind = SanitizerKind::NullabilityReturn;
+  }
+
+  SanitizerScope SanScope(this);
+
+  llvm::BasicBlock *Check = nullptr;
+  llvm::BasicBlock *NoCheck = nullptr;
+  if (requiresReturnValueNullabilityCheck()) {
+    // Before doing the nullability check, make sure that the preconditions for
+    // the check are met.
+    Check = createBasicBlock("nullcheck");
+    NoCheck = createBasicBlock("no.nullcheck");
+    Builder.CreateCondBr(RetValNullabilityPrecondition, Check, NoCheck);
+    EmitBlock(Check);
+  }
+
+  // Now do the null check. If the returns_nonnull attribute is present, this
+  // is done unconditionally.
+  llvm::Value *Cond = Builder.CreateIsNotNull(RV);
+  llvm::Constant *StaticData[] = {
+      EmitCheckSourceLocation(EndLoc), EmitCheckSourceLocation(AttrLoc),
+  };
+  EmitCheck(std::make_pair(Cond, CheckKind), SanitizerHandler::NonnullReturn,
+            StaticData, None);
+
+  if (requiresReturnValueNullabilityCheck())
+    EmitBlock(NoCheck);
+}
+
 static bool isInAllocaArgument(CGCXXABI &ABI, QualType type) {
   const CXXRecordDecl *RD = type->getAsCXXRecordDecl();
   return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
@@ -3182,50 +3286,61 @@
 
 void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
                                           SourceLocation ArgLoc,
-                                          const FunctionDecl *FD,
+                                          AbstractCallee AC,
                                           unsigned ParmNum) {
-  if (!SanOpts.has(SanitizerKind::NonnullAttribute) || !FD)
+  if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) ||
+                         SanOpts.has(SanitizerKind::NullabilityArg)))
     return;
-  auto PVD = ParmNum < FD->getNumParams() ? FD->getParamDecl(ParmNum) : nullptr;
+
+  // The param decl may be missing in a variadic function.
+  auto PVD = ParmNum < AC.getNumParams() ? AC.getParamDecl(ParmNum) : nullptr;
   unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
-  auto NNAttr = getNonNullAttr(FD, PVD, ArgType, ArgNo);
-  if (!NNAttr)
+
+  // Prefer the nonnull attribute if it's present. 
+  const NonNullAttr *NNAttr = nullptr;
+  if (SanOpts.has(SanitizerKind::NonnullAttribute))
+    NNAttr = getNonNullAttr(AC.getDecl(), PVD, ArgType, ArgNo);
+
+  bool CanCheckNullability = false;
+  if (SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD) {
+    auto Nullability = PVD->getType()->getNullability(getContext());
+    CanCheckNullability = Nullability &&
+                          *Nullability == NullabilityKind::NonNull &&
+                          PVD->getTypeSourceInfo();
+  }
+
+  if (!NNAttr && !CanCheckNullability)
     return;
+
+  SourceLocation AttrLoc;
+  SanitizerMask CheckKind;
+  if (NNAttr) {
+    AttrLoc = NNAttr->getLocation();
+    CheckKind = SanitizerKind::NonnullAttribute;
+  } else {
+    AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
+    CheckKind = SanitizerKind::NullabilityArg;
+  }
+
   SanitizerScope SanScope(this);
   assert(RV.isScalar());
   llvm::Value *V = RV.getScalarVal();
   llvm::Value *Cond =
       Builder.CreateICmpNE(V, llvm::Constant::getNullValue(V->getType()));
   llvm::Constant *StaticData[] = {
-      EmitCheckSourceLocation(ArgLoc),
-      EmitCheckSourceLocation(NNAttr->getLocation()),
+      EmitCheckSourceLocation(ArgLoc), EmitCheckSourceLocation(AttrLoc),
       llvm::ConstantInt::get(Int32Ty, ArgNo + 1),
   };
-  EmitCheck(std::make_pair(Cond, SanitizerKind::NonnullAttribute),
-                "nonnull_arg", StaticData, None);
+  EmitCheck(std::make_pair(Cond, CheckKind), SanitizerHandler::NonnullArg,
+            StaticData, None);
 }
 
 void CodeGenFunction::EmitCallArgs(
     CallArgList &Args, ArrayRef<QualType> ArgTypes,
     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
-    const FunctionDecl *CalleeDecl, unsigned ParamsToSkip,
-    EvaluationOrder Order) {
+    AbstractCallee AC, unsigned ParamsToSkip, EvaluationOrder Order) {
   assert((int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
 
-  auto MaybeEmitImplicitObjectSize = [&](unsigned I, const Expr *Arg) {
-    if (CalleeDecl == nullptr || I >= CalleeDecl->getNumParams())
-      return;
-    auto *PS = CalleeDecl->getParamDecl(I)->getAttr<PassObjectSizeAttr>();
-    if (PS == nullptr)
-      return;
-
-    const auto &Context = getContext();
-    auto SizeTy = Context.getSizeType();
-    auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
-    llvm::Value *V = evaluateOrEmitBuiltinObjectSize(Arg, PS->getType(), T);
-    Args.add(RValue::get(V), SizeTy);
-  };
-
   // We *have* to evaluate arguments from right to left in the MS C++ ABI,
   // because arguments are destroyed left to right in the callee. As a special
   // case, there are certain language constructs that require left-to-right
@@ -3236,6 +3351,27 @@
           ? Order == EvaluationOrder::ForceLeftToRight
           : Order != EvaluationOrder::ForceRightToLeft;
 
+  auto MaybeEmitImplicitObjectSize = [&](unsigned I, const Expr *Arg,
+                                         RValue EmittedArg) {
+    if (!AC.hasFunctionDecl() || I >= AC.getNumParams())
+      return;
+    auto *PS = AC.getParamDecl(I)->getAttr<PassObjectSizeAttr>();
+    if (PS == nullptr)
+      return;
+
+    const auto &Context = getContext();
+    auto SizeTy = Context.getSizeType();
+    auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
+    assert(EmittedArg.getScalarVal() && "We emitted nothing for the arg?");
+    llvm::Value *V = evaluateOrEmitBuiltinObjectSize(Arg, PS->getType(), T,
+                                                     EmittedArg.getScalarVal());
+    Args.add(RValue::get(V), SizeTy);
+    // If we're emitting args in reverse, be sure to do so with
+    // pass_object_size, as well.
+    if (!LeftToRight)
+      std::swap(Args.back(), *(&Args.back() - 1));
+  };
+
   // Insert a stack save if we're going to need any inalloca args.
   bool HasInAllocaArgs = false;
   if (CGM.getTarget().getCXXABI().isMicrosoft()) {
@@ -3253,11 +3389,20 @@
   for (unsigned I = 0, E = ArgTypes.size(); I != E; ++I) {
     unsigned Idx = LeftToRight ? I : E - I - 1;
     CallExpr::const_arg_iterator Arg = ArgRange.begin() + Idx;
-    if (!LeftToRight) MaybeEmitImplicitObjectSize(Idx, *Arg);
+    unsigned InitialArgSize = Args.size();
     EmitCallArg(Args, *Arg, ArgTypes[Idx]);
-    EmitNonNullArgCheck(Args.back().RV, ArgTypes[Idx], (*Arg)->getExprLoc(),
-                        CalleeDecl, ParamsToSkip + Idx);
-    if (LeftToRight) MaybeEmitImplicitObjectSize(Idx, *Arg);
+    // In particular, we depend on it being the last arg in Args, and the
+    // objectsize bits depend on there only being one arg if !LeftToRight.
+    assert(InitialArgSize + 1 == Args.size() &&
+           "The code below depends on only adding one arg per EmitCallArg");
+    (void)InitialArgSize;
+    RValue RVArg = Args.back().RV;
+    EmitNonNullArgCheck(RVArg, ArgTypes[Idx], (*Arg)->getExprLoc(), AC,
+                        ParamsToSkip + Idx);
+    // @llvm.objectsize should never have side-effects and shouldn't need
+    // destruction/cleanups, so we can safely "emit" it after its arg,
+    // regardless of right-to-leftness
+    MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
   }
 
   if (!LeftToRight) {
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 635824e..7ba03a0 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -309,8 +309,10 @@
   // just do a bitcast; null checks are unnecessary.
   if (NonVirtualOffset.isZero() && !VBase) {
     if (sanitizePerformTypeCheck()) {
+      SanitizerSet SkippedChecks;
+      SkippedChecks.set(SanitizerKind::Null, !NullCheckValue);
       EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(),
-                    DerivedTy, DerivedAlign, !NullCheckValue);
+                    DerivedTy, DerivedAlign, SkippedChecks);
     }
     return Builder.CreateBitCast(Value, BasePtrTy);
   }
@@ -331,8 +333,10 @@
   }
 
   if (sanitizePerformTypeCheck()) {
+    SanitizerSet SkippedChecks;
+    SkippedChecks.set(SanitizerKind::Null, true);
     EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc,
-                  Value.getPointer(), DerivedTy, DerivedAlign, true);
+                  Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks);
   }
 
   // Compute the virtual offset.
@@ -562,140 +566,6 @@
                                           isBaseVirtual);
 }
 
-/// Initialize a member of aggregate type using the given expression
-/// as an initializer.
-///
-/// The member may be an array.  If so:
-/// - the destination l-value will be a pointer of the *base* element type,
-/// - ArrayIndexVar will be a pointer to a variable containing the current
-///   index within the destination array, and
-/// - ArrayIndexes will be an array of index variables, one for each level
-///   of array nesting, which will need to be updated as appropriate for the
-///   array structure.
-///
-/// On an array, this function will invoke itself recursively.  Each time,
-/// it drills into one nesting level of the member type and sets up a
-/// loop updating the appropriate array index variable.
-static void EmitAggMemberInitializer(CodeGenFunction &CGF,
-                                     LValue LHS,
-                                     Expr *Init,
-                                     Address ArrayIndexVar,
-                                     QualType T,
-                                     ArrayRef<VarDecl *> ArrayIndexes,
-                                     unsigned Index) {
-  assert(ArrayIndexVar.isValid() == (ArrayIndexes.size() != 0));
-
-  if (Index == ArrayIndexes.size()) {
-    LValue LV = LHS;
-
-    Optional<CodeGenFunction::RunCleanupsScope> Scope;
-
-    if (ArrayIndexVar.isValid()) {
-      // When we're processing an array, the temporaries from each
-      // element's construction are destroyed immediately.
-      Scope.emplace(CGF);
-
-      // If we have an array index variable, load it and use it as an offset.
-      // Then, increment the value.
-      llvm::Value *Dest = LHS.getPointer();
-      llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar);
-      Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress");
-      llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1);
-      Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");
-      CGF.Builder.CreateStore(Next, ArrayIndexVar);
-
-      // Update the LValue.
-      CharUnits EltSize = CGF.getContext().getTypeSizeInChars(T);
-      CharUnits Align = LV.getAlignment().alignmentOfArrayElement(EltSize);
-      LV.setAddress(Address(Dest, Align));
-
-      // Enter a partial-array EH cleanup to destroy previous members
-      // of the array if this initialization throws.
-      if (CGF.CGM.getLangOpts().Exceptions) {
-        if (auto DtorKind = T.isDestructedType()) {
-          if (CGF.needsEHCleanup(DtorKind)) {
-            CGF.pushRegularPartialArrayCleanup(LHS.getPointer(),
-                                               LV.getPointer(), T,
-                                               LV.getAlignment(),
-                                               CGF.getDestroyer(DtorKind));
-          }
-        }
-      }
-    }
-
-    switch (CGF.getEvaluationKind(T)) {
-    case TEK_Scalar:
-      CGF.EmitScalarInit(Init, /*decl*/ nullptr, LV, false);
-      break;
-    case TEK_Complex:
-      CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true);
-      break;
-    case TEK_Aggregate: {
-      AggValueSlot Slot =
-        AggValueSlot::forLValue(LV,
-                                AggValueSlot::IsDestructed,
-                                AggValueSlot::DoesNotNeedGCBarriers,
-                                AggValueSlot::IsNotAliased);
-
-      CGF.EmitAggExpr(Init, Slot);
-      break;
-    }
-    }
-
-    return;
-  }
-
-  const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T);
-  assert(Array && "Array initialization without the array type?");
-  Address IndexVar = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]);
-
-  // Initialize this index variable to zero.
-  llvm::Value* Zero
-    = llvm::Constant::getNullValue(IndexVar.getElementType());
-  CGF.Builder.CreateStore(Zero, IndexVar);
-
-  // Start the loop with a block that tests the condition.
-  llvm::BasicBlock *CondBlock = CGF.createBasicBlock("for.cond");
-  llvm::BasicBlock *AfterFor = CGF.createBasicBlock("for.end");
-
-  CGF.EmitBlock(CondBlock);
-
-  llvm::BasicBlock *ForBody = CGF.createBasicBlock("for.body");
-  // Generate: if (loop-index < number-of-elements) fall to the loop body,
-  // otherwise, go to the block after the for-loop.
-  uint64_t NumElements = Array->getSize().getZExtValue();
-  llvm::Value *Counter = CGF.Builder.CreateLoad(IndexVar);
-  llvm::Value *NumElementsPtr =
-    llvm::ConstantInt::get(Counter->getType(), NumElements);
-  llvm::Value *IsLess = CGF.Builder.CreateICmpULT(Counter, NumElementsPtr,
-                                                  "isless");
-
-  // If the condition is true, execute the body.
-  CGF.Builder.CreateCondBr(IsLess, ForBody, AfterFor);
-
-  CGF.EmitBlock(ForBody);
-  llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc");
-
-  // Inside the loop body recurse to emit the inner loop or, eventually, the
-  // constructor call.
-  EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,
-                           Array->getElementType(), ArrayIndexes, Index + 1);
-
-  CGF.EmitBlock(ContinueBlock);
-
-  // Emit the increment of the loop counter.
-  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
-  Counter = CGF.Builder.CreateLoad(IndexVar);
-  NextVal = CGF.Builder.CreateAdd(Counter, NextVal, "inc");
-  CGF.Builder.CreateStore(NextVal, IndexVar);
-
-  // Finally, branch back up to the condition for the next iteration.
-  CGF.EmitBranch(CondBlock);
-
-  // Emit the fall-through block.
-  CGF.EmitBlock(AfterFor, true);
-}
-
 static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D) {
   auto *CD = dyn_cast<CXXConstructorDecl>(D);
   if (!(CD && CD->isCopyOrMoveConstructor()) &&
@@ -779,14 +649,11 @@
     }
   }
 
-  ArrayRef<VarDecl *> ArrayIndexes;
-  if (MemberInit->getNumArrayIndices())
-    ArrayIndexes = MemberInit->getArrayIndices();
-  CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes);
+  CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit());
 }
 
 void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS,
-                                Expr *Init, ArrayRef<VarDecl *> ArrayIndexes) {
+                                              Expr *Init) {
   QualType FieldType = Field->getType();
   switch (getEvaluationKind(FieldType)) {
   case TEK_Scalar:
@@ -801,30 +668,13 @@
     EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true);
     break;
   case TEK_Aggregate: {
-    Address ArrayIndexVar = Address::invalid();
-    if (ArrayIndexes.size()) {
-      // The LHS is a pointer to the first object we'll be constructing, as
-      // a flat array.
-      QualType BaseElementTy = getContext().getBaseElementType(FieldType);
-      llvm::Type *BasePtr = ConvertType(BaseElementTy);
-      BasePtr = llvm::PointerType::getUnqual(BasePtr);
-      Address BaseAddrPtr = Builder.CreateBitCast(LHS.getAddress(), BasePtr);
-      LHS = MakeAddrLValue(BaseAddrPtr, BaseElementTy);
-
-      // Create an array index that will be used to walk over all of the
-      // objects we're constructing.
-      ArrayIndexVar = CreateMemTemp(getContext().getSizeType(), "object.index");
-      llvm::Value *Zero =
-        llvm::Constant::getNullValue(ArrayIndexVar.getElementType());
-      Builder.CreateStore(Zero, ArrayIndexVar);
-
-      // Emit the block variables for the array indices, if any.
-      for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I)
-        EmitAutoVarDecl(*ArrayIndexes[I]);
-    }
-
-    EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType,
-                             ArrayIndexes, 0);
+    AggValueSlot Slot =
+      AggValueSlot::forLValue(LHS,
+                              AggValueSlot::IsDestructed,
+                              AggValueSlot::DoesNotNeedGCBarriers,
+                              AggValueSlot::IsNotAliased);
+    EmitAggExpr(Init, Slot);
+    break;
   }
   }
 
@@ -839,7 +689,8 @@
 /// complete-to-base constructor delegation optimization, i.e.
 /// emitting the complete constructor as a simple call to the base
 /// constructor.
-static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) {
+bool CodeGenFunction::IsConstructorDelegationValid(
+    const CXXConstructorDecl *Ctor) {
 
   // Currently we disable the optimization for classes with virtual
   // bases because (1) the addresses of parameter variables need to be
@@ -1285,10 +1136,11 @@
           RHS = EC->getSubExpr();
         if (!RHS)
           return nullptr;
-        MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS);
-        if (dyn_cast<FieldDecl>(ME2->getMemberDecl()) != Field)
-          return nullptr;
-        return Field;
+        if (MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
+          if (ME2->getMemberDecl() == Field)
+            return Field;
+        }
+        return nullptr;
       } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) {
         CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
         if (!(MD && isMemcpyEquivalentSpecialMember(MD)))
@@ -1538,6 +1390,20 @@
   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
   CXXDtorType DtorType = CurGD.getDtorType();
 
+  // For an abstract class, non-base destructors are never used (and can't
+  // be emitted in general, because vbase dtors may not have been validated
+  // by Sema), but the Itanium ABI doesn't make them optional and Clang may
+  // in fact emit references to them from other compilations, so emit them
+  // as functions containing a trap instruction.
+  if (DtorType != Dtor_Base && Dtor->getParent()->isAbstract()) {
+    llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
+    TrapCall->setDoesNotReturn();
+    TrapCall->setDoesNotThrow();
+    Builder.CreateUnreachable();
+    Builder.ClearInsertionPoint();
+    return;
+  }
+
   Stmt *Body = Dtor->getBody();
   if (Body)
     incrementProfileCounter(Body);
@@ -1570,9 +1436,7 @@
   // we'd introduce *two* handler blocks.  In the Microsoft ABI, we
   // always delegate because we might not have a definition in this TU.
   switch (DtorType) {
-  case Dtor_Comdat:
-    llvm_unreachable("not expecting a COMDAT");
-
+  case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");
   case Dtor_Deleting: llvm_unreachable("already handled deleting case");
 
   case Dtor_Complete:
@@ -1587,7 +1451,9 @@
                             /*Delegating=*/false, LoadCXXThisAddress());
       break;
     }
+
     // Fallthrough: act like we're in the base variant.
+    LLVM_FALLTHROUGH;
 
   case Dtor_Base:
     assert(Body);
@@ -2104,7 +1970,11 @@
 
   // Add the rest of the user-supplied arguments.
   const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
-  EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor());
+  EvaluationOrder Order = E->isListInitialization()
+                              ? EvaluationOrder::ForceLeftToRight
+                              : EvaluationOrder::Default;
+  EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor(),
+               /*ParamsToSkip*/ 0, Order);
 
   EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args);
 }
@@ -2124,7 +1994,7 @@
 
     // Likewise if they're inalloca.
     const CGFunctionInfo &Info =
-        CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0);
+        CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0, 0);
     if (Info.usesInAlloca())
       return false;
   }
@@ -2166,10 +2036,11 @@
     return;
   }
 
+  bool PassPrototypeArgs = true;
   // Check whether we can actually emit the constructor before trying to do so.
   if (auto Inherited = D->getInheritedConstructor()) {
-    if (getTypes().inheritingCtorHasParams(Inherited, Type) &&
-        !canEmitDelegateCallArgs(*this, D, Type, Args)) {
+    PassPrototypeArgs = getTypes().inheritingCtorHasParams(Inherited, Type);
+    if (PassPrototypeArgs && !canEmitDelegateCallArgs(*this, D, Type, Args)) {
       EmitInlinedInheritingCXXConstructorCall(D, Type, ForVirtualBase,
                                               Delegating, Args);
       return;
@@ -2177,14 +2048,15 @@
   }
 
   // Insert any ABI-specific implicit constructor arguments.
-  unsigned ExtraArgs = CGM.getCXXABI().addImplicitConstructorArgs(
-      *this, D, Type, ForVirtualBase, Delegating, Args);
+  CGCXXABI::AddedStructorArgs ExtraArgs =
+      CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase,
+                                                 Delegating, Args);
 
   // Emit the call.
   llvm::Constant *CalleePtr =
     CGM.getAddrOfCXXStructor(D, getFromCtorType(Type));
-  const CGFunctionInfo &Info =
-    CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs);
+  const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(
+      Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs);
   CGCallee Callee = CGCallee::forDirect(CalleePtr, D);
   EmitCall(Info, Callee, ReturnValueSlot(), Args);
 
@@ -2256,7 +2128,9 @@
 void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall(
     const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase,
     bool Delegating, CallArgList &Args) {
-  InlinedInheritingConstructorScope Scope(*this, GlobalDecl(Ctor, CtorType));
+  GlobalDecl GD(Ctor, CtorType);
+  InlinedInheritingConstructorScope Scope(*this, GD);
+  ApplyInlineDebugLocation DebugScope(*this, GD);
 
   // Save the arguments to be passed to the inherited constructor.
   CXXInheritedCtorInitExprArgs = Args;
@@ -2802,8 +2676,8 @@
       llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
   llvm::Value *ValidVtable = Builder.CreateCall(
       CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, AllVtables});
-  EmitCheck(std::make_pair(TypeTest, M), "cfi_check_fail", StaticData,
-            {CastedVTable, ValidVtable});
+  EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
+            StaticData, {CastedVTable, ValidVtable});
 }
 
 bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) {
@@ -2835,7 +2709,7 @@
   llvm::Value *CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
 
   EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall),
-            "cfi_check_fail", nullptr, nullptr);
+            SanitizerHandler::CFICheckFail, nullptr, nullptr);
 
   return Builder.CreateBitCast(
       Builder.CreateExtractValue(CheckedLoad, 0),
diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp
index 3666858..df6741d 100644
--- a/lib/CodeGen/CGCleanup.cpp
+++ b/lib/CodeGen/CGCleanup.cpp
@@ -418,11 +418,15 @@
 }
 
 /// Pops cleanup blocks until the given savepoint is reached.
-void CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old) {
+void CodeGenFunction::PopCleanupBlocks(
+    EHScopeStack::stable_iterator Old,
+    std::initializer_list<llvm::Value **> ValuesToReload) {
   assert(Old.isValid());
 
+  bool HadBranches = false;
   while (EHStack.stable_begin() != Old) {
     EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin());
+    HadBranches |= Scope.hasBranches();
 
     // As long as Old strictly encloses the scope's enclosing normal
     // cleanup, we're going to emit another normal cleanup which
@@ -432,14 +436,41 @@
 
     PopCleanupBlock(FallThroughIsBranchThrough);
   }
+
+  // If we didn't have any branches, the insertion point before cleanups must
+  // dominate the current insertion point and we don't need to reload any
+  // values.
+  if (!HadBranches)
+    return;
+
+  // Spill and reload all values that the caller wants to be live at the current
+  // insertion point.
+  for (llvm::Value **ReloadedValue : ValuesToReload) {
+    auto *Inst = dyn_cast_or_null<llvm::Instruction>(*ReloadedValue);
+    if (!Inst)
+      continue;
+    Address Tmp =
+        CreateDefaultAlignTempAlloca(Inst->getType(), "tmp.exprcleanup");
+
+    // Find an insertion point after Inst and spill it to the temporary.
+    llvm::BasicBlock::iterator InsertBefore;
+    if (auto *Invoke = dyn_cast<llvm::InvokeInst>(Inst))
+      InsertBefore = Invoke->getNormalDest()->getFirstInsertionPt();
+    else
+      InsertBefore = std::next(Inst->getIterator());
+    CGBuilderTy(CGM, &*InsertBefore).CreateStore(Inst, Tmp);
+
+    // Reload the value at the current insertion point.
+    *ReloadedValue = Builder.CreateLoad(Tmp);
+  }
 }
 
 /// Pops cleanup blocks until the given savepoint is reached, then add the
 /// cleanups from the given savepoint in the lifetime-extended cleanups stack.
-void
-CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old,
-                                  size_t OldLifetimeExtendedSize) {
-  PopCleanupBlocks(Old);
+void CodeGenFunction::PopCleanupBlocks(
+    EHScopeStack::stable_iterator Old, size_t OldLifetimeExtendedSize,
+    std::initializer_list<llvm::Value **> ValuesToReload) {
+  PopCleanupBlocks(Old, ValuesToReload);
 
   // Move our deferred cleanups onto the EH stack.
   for (size_t I = OldLifetimeExtendedSize,
diff --git a/lib/CodeGen/CGCleanup.h b/lib/CodeGen/CGCleanup.h
index 2166490..105c562 100644
--- a/lib/CodeGen/CGCleanup.h
+++ b/lib/CodeGen/CGCleanup.h
@@ -616,6 +616,8 @@
   static const EHPersonality GNU_C_SJLJ;
   static const EHPersonality GNU_C_SEH;
   static const EHPersonality GNU_ObjC;
+  static const EHPersonality GNU_ObjC_SJLJ;
+  static const EHPersonality GNU_ObjC_SEH;
   static const EHPersonality GNUstep_ObjC;
   static const EHPersonality GNU_ObjCXX;
   static const EHPersonality NeXT_ObjC;
diff --git a/lib/CodeGen/CGCoroutine.cpp b/lib/CodeGen/CGCoroutine.cpp
index 2fdb127..77497f3 100644
--- a/lib/CodeGen/CGCoroutine.cpp
+++ b/lib/CodeGen/CGCoroutine.cpp
@@ -21,6 +21,13 @@
 namespace CodeGen {
 
 struct CGCoroData {
+
+  // Stores the jump destination just before the final suspend. Coreturn
+  // statements jumps to this point after calling return_xxx promise member.
+  CodeGenFunction::JumpDest FinalJD;
+
+  unsigned CoreturnCount = 0;
+
   // Stores the llvm.coro.id emitted in the function so that we can supply it
   // as the first argument to coro.begin, coro.alloc and coro.free intrinsics.
   // Note: llvm.coro.id returns a token that cannot be directly expressed in a
@@ -59,19 +66,46 @@
   CurCoro.Data->CoroIdExpr = CoroIdExpr;
 }
 
+void CodeGenFunction::EmitCoreturnStmt(CoreturnStmt const &S) {
+  ++CurCoro.Data->CoreturnCount;
+  EmitStmt(S.getPromiseCall());
+  EmitBranchThroughCleanup(CurCoro.Data->FinalJD);
+}
+
 void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) {
   auto *NullPtr = llvm::ConstantPointerNull::get(Builder.getInt8PtrTy());
   auto &TI = CGM.getContext().getTargetInfo();
   unsigned NewAlign = TI.getNewAlign() / TI.getCharWidth();
 
+  auto *FinalBB = createBasicBlock("coro.final");
+
   auto *CoroId = Builder.CreateCall(
       CGM.getIntrinsic(llvm::Intrinsic::coro_id),
       {Builder.getInt32(NewAlign), NullPtr, NullPtr, NullPtr});
   createCoroData(*this, CurCoro, CoroId);
 
   EmitScalarExpr(S.getAllocate());
-  // FIXME: Emit the rest of the coroutine.
+
+  // FIXME: Setup cleanup scopes.
+
+  EmitStmt(S.getPromiseDeclStmt());
+
+  CurCoro.Data->FinalJD = getJumpDestInCurrentScope(FinalBB);
+
+  // FIXME: Emit initial suspend and more before the body.
+
+  EmitStmt(S.getBody());
+
+  // See if we need to generate final suspend.
+  const bool CanFallthrough = Builder.GetInsertBlock();
+  const bool HasCoreturns = CurCoro.Data->CoreturnCount > 0;
+  if (CanFallthrough || HasCoreturns) {
+    EmitBlock(FinalBB);
+    // FIXME: Emit final suspend.
+  }
   EmitStmt(S.getDeallocate());
+
+  // FIXME: Emit return for the coroutine return object.
 }
 
 // Emit coroutine intrinsic and patch up arguments of the token type.
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index c51a1d4..05987be 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -41,6 +41,7 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MD5.h"
 #include "llvm/Support/Path.h"
 using namespace clang;
 using namespace clang::CodeGen;
@@ -106,8 +107,8 @@
 
   // Construct a location that has a valid scope, but no line info.
   assert(!DI->LexicalBlockStack.empty());
-  CGF->Builder.SetCurrentDebugLocation(
-      llvm::DebugLoc::get(0, 0, DI->LexicalBlockStack.back()));
+  CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
+      0, 0, DI->LexicalBlockStack.back(), DI->getInlinedAt()));
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF, const Expr *E)
@@ -133,6 +134,30 @@
     CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
 }
 
+ApplyInlineDebugLocation::ApplyInlineDebugLocation(CodeGenFunction &CGF,
+                                                   GlobalDecl InlinedFn)
+    : CGF(&CGF) {
+  if (!CGF.getDebugInfo()) {
+    this->CGF = nullptr;
+    return;
+  }
+  auto &DI = *CGF.getDebugInfo();
+  SavedLocation = DI.getLocation();
+  assert((DI.getInlinedAt() ==
+          CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
+         "CGDebugInfo and IRBuilder are out of sync");
+
+  DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
+}
+
+ApplyInlineDebugLocation::~ApplyInlineDebugLocation() {
+  if (!CGF)
+    return;
+  auto &DI = *CGF->getDebugInfo();
+  DI.EmitInlineFunctionEnd(CGF->Builder);
+  DI.EmitLocation(CGF->Builder, SavedLocation);
+}
+
 void CGDebugInfo::setLocation(SourceLocation Loc) {
   // If the new location isn't valid return.
   if (Loc.isInvalid())
@@ -248,8 +273,8 @@
          << OC->getIdentifier()->getNameStart() << ')';
     }
   } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
-    OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '('
-       << OCD->getIdentifier()->getNameStart() << ')';
+    OS << OCD->getClassInterface()->getName() << '('
+       << OCD->getName() << ')';
   } else if (isa<ObjCProtocolDecl>(DC)) {
     // We can extract the type of the class from the self pointer.
     if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
@@ -320,11 +345,36 @@
   return StringRef();
 }
 
+llvm::DIFile::ChecksumKind
+CGDebugInfo::computeChecksum(FileID FID, SmallString<32> &Checksum) const {
+  Checksum.clear();
+
+  if (!CGM.getCodeGenOpts().EmitCodeView)
+    return llvm::DIFile::CSK_None;
+
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  bool Invalid;
+  llvm::MemoryBuffer *MemBuffer = SM.getBuffer(FID, &Invalid);
+  if (Invalid)
+    return llvm::DIFile::CSK_None;
+
+  llvm::MD5 Hash;
+  llvm::MD5::MD5Result Result;
+
+  Hash.update(MemBuffer->getBuffer());
+  Hash.final(Result);
+
+  Hash.stringifyResult(Result, Checksum);
+  return llvm::DIFile::CSK_MD5;
+}
+
 llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
   if (!Loc.isValid())
     // If Location is not valid then use main input file.
     return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
-                               remapDIPath(TheCU->getDirectory()));
+                               remapDIPath(TheCU->getDirectory()),
+                               TheCU->getFile()->getChecksumKind(),
+                               TheCU->getFile()->getChecksum());
 
   SourceManager &SM = CGM.getContext().getSourceManager();
   PresumedLoc PLoc = SM.getPresumedLoc(Loc);
@@ -332,7 +382,9 @@
   if (PLoc.isInvalid() || StringRef(PLoc.getFilename()).empty())
     // If the location is not valid then use main input file.
     return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
-                               remapDIPath(TheCU->getDirectory()));
+                               remapDIPath(TheCU->getDirectory()),
+                               TheCU->getFile()->getChecksumKind(),
+                               TheCU->getFile()->getChecksum());
 
   // Cache the results.
   const char *fname = PLoc.getFilename();
@@ -344,8 +396,13 @@
       return cast<llvm::DIFile>(V);
   }
 
+  SmallString<32> Checksum;
+  llvm::DIFile::ChecksumKind CSKind =
+      computeChecksum(SM.getFileID(Loc), Checksum);
+
   llvm::DIFile *F = DBuilder.createFile(remapDIPath(PLoc.getFilename()),
-                                        remapDIPath(getCurrentDirname()));
+                                        remapDIPath(getCurrentDirname()),
+                                        CSKind, Checksum);
 
   DIFileCache[fname].reset(F);
   return F;
@@ -353,7 +410,9 @@
 
 llvm::DIFile *CGDebugInfo::getOrCreateMainFile() {
   return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
-                             remapDIPath(TheCU->getDirectory()));
+                             remapDIPath(TheCU->getDirectory()),
+                             TheCU->getFile()->getChecksumKind(),
+                             TheCU->getFile()->getChecksum());
 }
 
 std::string CGDebugInfo::remapDIPath(StringRef Path) const {
@@ -396,6 +455,8 @@
 }
 
 void CGDebugInfo::CreateCompileUnit() {
+  SmallString<32> Checksum;
+  llvm::DIFile::ChecksumKind CSKind = llvm::DIFile::CSK_None;
 
   // Should we be asking the SourceManager for the main file name, instead of
   // accepting it as an argument? This just causes the main file name to
@@ -422,6 +483,7 @@
       llvm::sys::path::append(MainFileDirSS, MainFileName);
       MainFileName = MainFileDirSS.str();
     }
+    CSKind = computeChecksum(SM.getMainFileID(), Checksum);
   }
 
   llvm::dwarf::SourceLanguage LangTag;
@@ -466,10 +528,13 @@
   // Create new compile unit.
   // FIXME - Eliminate TheCU.
   TheCU = DBuilder.createCompileUnit(
-      LangTag, remapDIPath(MainFileName), remapDIPath(getCurrentDirname()),
+      LangTag, DBuilder.createFile(remapDIPath(MainFileName),
+                                   remapDIPath(getCurrentDirname()), CSKind,
+                                   Checksum),
       Producer, LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers,
       CGM.getCodeGenOpts().SplitDwarfFile, EmissionKind, 0 /* DWOid */,
-      CGM.getCodeGenOpts().SplitDwarfInlining);
+      CGM.getCodeGenOpts().SplitDwarfInlining,
+      CGM.getCodeGenOpts().DebugInfoForProfiling);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
@@ -541,8 +606,6 @@
     return getOrCreateStructPtrType("opencl_clk_event_t", OCLClkEventDITy);
   case BuiltinType::OCLQueue:
     return getOrCreateStructPtrType("opencl_queue_t", OCLQueueDITy);
-  case BuiltinType::OCLNDRange:
-    return getOrCreateStructPtrType("opencl_ndrange_t", OCLNDRangeDITy);
   case BuiltinType::OCLReserveID:
     return getOrCreateStructPtrType("opencl_reserve_id_t", OCLReserveIDDITy);
 
@@ -735,12 +798,6 @@
   uint64_t Size = 0;
   uint32_t Align = 0;
 
-  const RecordDecl *D = RD->getDefinition();
-  if (D && D->isCompleteDefinition()) {
-    Size = CGM.getContext().getTypeSize(Ty);
-    Align = getDeclAlignIfRequired(D, CGM.getContext());
-  }
-
   // Create the type.
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
   llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
@@ -759,17 +816,19 @@
   // Bit size, align and offset of the type.
   // Size is always the size of a pointer. We can't use getTypeSize here
   // because that does not return the correct value for references.
-  unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy);
-  uint64_t Size = CGM.getTarget().getPointerWidth(AS);
+  unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(PointeeTy);
+  uint64_t Size = CGM.getTarget().getPointerWidth(AddressSpace);
   auto Align = getTypeAlignIfRequired(Ty, CGM.getContext());
+  Optional<unsigned> DWARFAddressSpace =
+      CGM.getTarget().getDWARFAddressSpace(AddressSpace);
 
   if (Tag == llvm::dwarf::DW_TAG_reference_type ||
       Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
     return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
-                                        Size, Align);
+                                        Size, Align, DWARFAddressSpace);
   else
     return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
-                                      Align);
+                                      Align, DWARFAddressSpace);
 }
 
 llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
@@ -1574,8 +1633,13 @@
   llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
   llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
   unsigned Size = Context.getTypeSize(Context.VoidPtrTy);
+  unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
+  Optional<unsigned> DWARFAddressSpace =
+      CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
+
   llvm::DIType *vtbl_ptr_type =
-      DBuilder.createPointerType(SubTy, Size, 0, "__vtbl_ptr_type");
+      DBuilder.createPointerType(SubTy, Size, 0, DWARFAddressSpace,
+                                 "__vtbl_ptr_type");
   VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
   return VTablePtrType;
 }
@@ -1614,10 +1678,14 @@
     unsigned VSlotCount =
         VFTLayout.vtable_components().size() - CGM.getLangOpts().RTTIData;
     unsigned VTableWidth = PtrWidth * VSlotCount;
+    unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
+    Optional<unsigned> DWARFAddressSpace =
+        CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
 
     // Create a very wide void* type and insert it directly in the element list.
     llvm::DIType *VTableType =
-        DBuilder.createPointerType(nullptr, VTableWidth, 0, "__vtbl_ptr_type");
+        DBuilder.createPointerType(nullptr, VTableWidth, 0, DWARFAddressSpace,
+                                   "__vtbl_ptr_type");
     EltTys.push_back(VTableType);
 
     // The vptr is a pointer to this special vtable type.
@@ -1680,7 +1748,27 @@
     completeRequiredType(RD);
 }
 
+/// Return true if the class or any of its methods are marked dllimport.
+static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD) {
+  if (RD->hasAttr<DLLImportAttr>())
+    return true;
+  for (const CXXMethodDecl *MD : RD->methods())
+    if (MD->hasAttr<DLLImportAttr>())
+      return true;
+  return false;
+}
+
 void CGDebugInfo::completeClassData(const RecordDecl *RD) {
+  if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+    if (CXXRD->isDynamicClass() &&
+        CGM.getVTableLinkage(CXXRD) ==
+            llvm::GlobalValue::AvailableExternallyLinkage &&
+        !isClassOrMethodDLLImport(CXXRD))
+      return;
+  completeClass(RD);
+}
+
+void CGDebugInfo::completeClass(const RecordDecl *RD) {
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
     return;
   QualType Ty = CGM.getContext().getRecordType(RD);
@@ -1726,16 +1814,6 @@
   return true;
 }
 
-/// Return true if the class or any of its methods are marked dllimport.
-static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD) {
-  if (RD->hasAttr<DLLImportAttr>())
-    return true;
-  for (const CXXMethodDecl *MD : RD->methods())
-    if (MD->hasAttr<DLLImportAttr>())
-      return true;
-  return false;
-}
-
 static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
                                  bool DebugTypeExtRefs, const RecordDecl *RD,
                                  const LangOptions &LangOpts) {
@@ -1975,12 +2053,17 @@
   if (CreateSkeletonCU && IsRootModule) {
     // PCH files don't have a signature field in the control block,
     // but LLVM detects skeleton CUs by looking for a non-zero DWO id.
-    uint64_t Signature = Mod.getSignature() ? Mod.getSignature() : ~1ULL;
+    // We use the lower 64 bits for debug info.
+    uint64_t Signature =
+        Mod.getSignature()
+            ? (uint64_t)Mod.getSignature()[1] << 32 | Mod.getSignature()[0]
+            : ~1ULL;
     llvm::DIBuilder DIB(CGM.getModule());
-    DIB.createCompileUnit(TheCU->getSourceLanguage(), Mod.getModuleName(),
-                          Mod.getPath(), TheCU->getProducer(), true,
-                          StringRef(), 0, Mod.getASTFile(),
-                          llvm::DICompileUnit::FullDebug, Signature);
+    DIB.createCompileUnit(TheCU->getSourceLanguage(),
+                          DIB.createFile(Mod.getModuleName(), Mod.getPath()),
+                          TheCU->getProducer(), true, StringRef(), 0,
+                          Mod.getASTFile(), llvm::DICompileUnit::FullDebug,
+                          Signature);
     DIB.finalize();
   }
   llvm::DIModule *Parent =
@@ -2373,6 +2456,21 @@
                                         FullName);
 }
 
+llvm::DIMacro *CGDebugInfo::CreateMacro(llvm::DIMacroFile *Parent,
+                                        unsigned MType, SourceLocation LineLoc,
+                                        StringRef Name, StringRef Value) {
+  unsigned Line = LineLoc.isInvalid() ? 0 : getLineNumber(LineLoc);
+  return DBuilder.createMacro(Parent, Line, MType, Name, Value);
+}
+
+llvm::DIMacroFile *CGDebugInfo::CreateTempMacroFile(llvm::DIMacroFile *Parent,
+                                                    SourceLocation LineLoc,
+                                                    SourceLocation FileLoc) {
+  llvm::DIFile *FName = getOrCreateFile(FileLoc);
+  unsigned Line = LineLoc.isInvalid() ? 0 : getLineNumber(LineLoc);
+  return DBuilder.createTempMacroFile(Parent, Line, FName);
+}
+
 static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
   Qualifiers Quals;
   do {
@@ -2416,8 +2514,9 @@
     case Type::SubstTemplateTypeParm:
       T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
       break;
-    case Type::Auto: {
-      QualType DT = cast<AutoType>(T)->getDeducedType();
+    case Type::Auto:
+    case Type::DeducedTemplateSpecialization: {
+      QualType DT = cast<DeducedType>(T)->getDeducedType();
       assert(!DT.isNull() && "Undeduced types shouldn't reach here.");
       T = DT;
       break;
@@ -2583,6 +2682,7 @@
   case Type::Attributed:
   case Type::Adjusted:
   case Type::Decayed:
+  case Type::DeducedTemplateSpecialization:
   case Type::Elaborated:
   case Type::Paren:
   case Type::SubstTemplateTypeParm:
@@ -2739,9 +2839,10 @@
   }
   // No need to replicate the linkage name if it isn't different from the
   // subprogram name, no need to have it at all unless coverage is enabled or
-  // debug is set to more than just line tables.
+  // debug is set to more than just line tables or extra debug info is needed.
   if (LinkageName == Name || (!CGM.getCodeGenOpts().EmitGcovArcs &&
                               !CGM.getCodeGenOpts().EmitGcovNotes &&
+                              !CGM.getCodeGenOpts().DebugInfoForProfiling &&
                               DebugKind <= codegenoptions::DebugLineTablesOnly))
     LinkageName = StringRef();
 
@@ -2809,28 +2910,40 @@
  VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
 }
 
-llvm::DISubprogram *
-CGDebugInfo::getFunctionForwardDeclaration(const FunctionDecl *FD) {
+llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
+                                                          bool Stub) {
   llvm::DINodeArray TParamsArray;
   StringRef Name, LinkageName;
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
-  SourceLocation Loc = FD->getLocation();
+  SourceLocation Loc = GD.getDecl()->getLocation();
   llvm::DIFile *Unit = getOrCreateFile(Loc);
   llvm::DIScope *DContext = Unit;
   unsigned Line = getLineNumber(Loc);
-
-  collectFunctionDeclProps(FD, Unit, Name, LinkageName, DContext,
+  collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext,
                            TParamsArray, Flags);
+  auto *FD = dyn_cast<FunctionDecl>(GD.getDecl());
+
   // Build function type.
   SmallVector<QualType, 16> ArgTypes;
-  for (const ParmVarDecl *Parm: FD->parameters())
-    ArgTypes.push_back(Parm->getType());
+  if (FD)
+    for (const ParmVarDecl *Parm : FD->parameters())
+      ArgTypes.push_back(Parm->getType());
   CallingConv CC = FD->getType()->castAs<FunctionType>()->getCallConv();
   QualType FnType = CGM.getContext().getFunctionType(
       FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
+  if (Stub) {
+    return DBuilder.createFunction(
+        DContext, Name, LinkageName, Unit, Line,
+        getOrCreateFunctionType(GD.getDecl(), FnType, Unit),
+        !FD->isExternallyVisible(),
+        /* isDefinition = */ true, 0, Flags, CGM.getLangOpts().Optimize,
+        TParamsArray.get(), getFunctionDeclaration(FD));
+  }
+
   llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
       DContext, Name, LinkageName, Unit, Line,
-      getOrCreateFunctionType(FD, FnType, Unit), !FD->isExternallyVisible(),
+      getOrCreateFunctionType(GD.getDecl(), FnType, Unit),
+      !FD->isExternallyVisible(),
       /* isDefinition = */ false, 0, Flags, CGM.getLangOpts().Optimize,
       TParamsArray.get(), getFunctionDeclaration(FD));
   const auto *CanonDecl = cast<FunctionDecl>(FD->getCanonicalDecl());
@@ -2840,6 +2953,16 @@
   return SP;
 }
 
+llvm::DISubprogram *
+CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
+  return getFunctionFwdDeclOrStub(GD, /* Stub = */ false);
+}
+
+llvm::DISubprogram *
+CGDebugInfo::getFunctionStub(GlobalDecl GD) {
+  return getFunctionFwdDeclOrStub(GD, /* Stub = */ true);
+}
+
 llvm::DIGlobalVariable *
 CGDebugInfo::getGlobalVariableForwardDeclaration(const VarDecl *VD) {
   QualType T;
@@ -2853,7 +2976,7 @@
   auto Align = getDeclAlignIfRequired(VD, CGM.getContext());
   auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
       DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit),
-      !VD->isExternallyVisible(), nullptr, nullptr, Align);
+      !VD->isExternallyVisible(), nullptr, Align);
   FwdDeclReplaceMap.emplace_back(
       std::piecewise_construct,
       std::make_tuple(cast<VarDecl>(VD->getCanonicalDecl())),
@@ -2871,8 +2994,12 @@
                            getOrCreateFile(TD->getLocation()));
   auto I = DeclCache.find(D->getCanonicalDecl());
 
-  if (I != DeclCache.end())
-    return dyn_cast_or_null<llvm::DINode>(I->second);
+  if (I != DeclCache.end()) {
+    auto N = I->second;
+    if (auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
+      return GVE->getVariable();
+    return dyn_cast_or_null<llvm::DINode>(N);
+  }
 
   // No definition for now. Emit a forward definition that might be
   // merged with a potential upcoming definition.
@@ -3107,6 +3234,27 @@
       TParamsArray.get(), getFunctionDeclaration(D)));
 }
 
+void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) {
+  const auto *FD = cast<FunctionDecl>(GD.getDecl());
+  // If there is a subprogram for this function available then use it.
+  auto FI = SPCache.find(FD->getCanonicalDecl());
+  llvm::DISubprogram *SP = nullptr;
+  if (FI != SPCache.end())
+    SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
+  if (!SP)
+    SP = getFunctionStub(GD);
+  FnBeginRegionCount.push_back(LexicalBlockStack.size());
+  LexicalBlockStack.emplace_back(SP);
+  setInlinedAt(Builder.getCurrentDebugLocation());
+  EmitLocation(Builder, FD->getLocation());
+}
+
+void CGDebugInfo::EmitInlineFunctionEnd(CGBuilderTy &Builder) {
+  assert(CurInlinedAt && "unbalanced inline scope stack");
+  EmitFunctionEnd(Builder);
+  setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
+}
+
 void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
   // Update our current location
   setLocation(Loc);
@@ -3116,7 +3264,7 @@
 
   llvm::MDNode *Scope = LexicalBlockStack.back();
   Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
-      getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope));
+      getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope, CurInlinedAt));
 }
 
 void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
@@ -3128,14 +3276,29 @@
       getColumnNumber(CurLoc)));
 }
 
+void CGDebugInfo::AppendAddressSpaceXDeref(
+    unsigned AddressSpace,
+    SmallVectorImpl<int64_t> &Expr) const {
+  Optional<unsigned> DWARFAddressSpace =
+      CGM.getTarget().getDWARFAddressSpace(AddressSpace);
+  if (!DWARFAddressSpace)
+    return;
+
+  Expr.push_back(llvm::dwarf::DW_OP_constu);
+  Expr.push_back(DWARFAddressSpace.getValue());
+  Expr.push_back(llvm::dwarf::DW_OP_swap);
+  Expr.push_back(llvm::dwarf::DW_OP_xderef);
+}
+
 void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder,
                                         SourceLocation Loc) {
   // Set our current location.
   setLocation(Loc);
 
   // Emit a line table change for the current location inside the new scope.
-  Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
-      getLineNumber(Loc), getColumnNumber(Loc), LexicalBlockStack.back()));
+  Builder.SetCurrentDebugLocation(
+      llvm::DebugLoc::get(getLineNumber(Loc), getColumnNumber(Loc),
+                          LexicalBlockStack.back(), CurInlinedAt));
 
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
     return;
@@ -3277,13 +3440,16 @@
     Line = getLineNumber(VD->getLocation());
     Column = getColumnNumber(VD->getLocation());
   }
-  SmallVector<int64_t, 9> Expr;
+  SmallVector<int64_t, 13> Expr;
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   if (VD->isImplicit())
     Flags |= llvm::DINode::FlagArtificial;
 
   auto Align = getDeclAlignIfRequired(VD, CGM.getContext());
 
+  unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(VD->getType());
+  AppendAddressSpaceXDeref(AddressSpace, Expr);
+
   // If this is the first argument and it is implicit then
   // give it an object pointer flag.
   // FIXME: There has to be a better way to do this, but for static
@@ -3321,9 +3487,10 @@
                                                   Line, Ty, Align);
 
       // Insert an llvm.dbg.declare into the current block.
-      DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
-                             llvm::DebugLoc::get(Line, Column, Scope),
-                             Builder.GetInsertBlock());
+      DBuilder.insertDeclare(
+          Storage, D, DBuilder.createExpression(Expr),
+          llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
+          Builder.GetInsertBlock());
       return;
     } else if (isa<VariableArrayType>(VD->getType()))
       Expr.push_back(llvm::dwarf::DW_OP_deref);
@@ -3354,9 +3521,10 @@
             Flags | llvm::DINode::FlagArtificial, FieldAlign);
 
         // Insert an llvm.dbg.declare into the current block.
-        DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
-                               llvm::DebugLoc::get(Line, Column, Scope),
-                               Builder.GetInsertBlock());
+        DBuilder.insertDeclare(
+            Storage, D, DBuilder.createExpression(Expr),
+            llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
+            Builder.GetInsertBlock());
       }
     }
   }
@@ -3372,7 +3540,7 @@
 
   // Insert an llvm.dbg.declare into the current block.
   DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
-                         llvm::DebugLoc::get(Line, Column, Scope),
+                         llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
                          Builder.GetInsertBlock());
 }
 
@@ -3453,7 +3621,8 @@
       Line, Ty, false, llvm::DINode::FlagZero, Align);
 
   // Insert an llvm.dbg.declare into the current block.
-  auto DL = llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back());
+  auto DL =
+      llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back(), CurInlinedAt);
   if (InsertPoint)
     DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(addr), DL,
                            InsertPoint);
@@ -3621,12 +3790,13 @@
     // Insert an llvm.dbg.value into the current block.
     DBuilder.insertDbgValueIntrinsic(
         LocalAddr, 0, debugVar, DBuilder.createExpression(),
-        llvm::DebugLoc::get(line, column, scope), Builder.GetInsertBlock());
+        llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
+        Builder.GetInsertBlock());
   }
 
   // Insert an llvm.dbg.declare into the current block.
   DBuilder.insertDeclare(Arg, debugVar, DBuilder.createExpression(),
-                         llvm::DebugLoc::get(line, column, scope),
+                         llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
                          Builder.GetInsertBlock());
 }
 
@@ -3648,10 +3818,10 @@
   return CreateRecordStaticField(D, Ctxt, cast<RecordDecl>(DC));
 }
 
-llvm::DIGlobalVariable *CGDebugInfo::CollectAnonRecordDecls(
+llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
     const RecordDecl *RD, llvm::DIFile *Unit, unsigned LineNo,
     StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
-  llvm::DIGlobalVariable *GV = nullptr;
+  llvm::DIGlobalVariableExpression *GVE = nullptr;
 
   for (const auto *Field : RD->fields()) {
     llvm::DIType *FieldTy = getOrCreateType(Field->getType(), Unit);
@@ -3660,16 +3830,17 @@
     // Ignore unnamed fields, but recurse into anonymous records.
     if (FieldName.empty()) {
       if (const auto *RT = dyn_cast<RecordType>(Field->getType()))
-        GV = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
+        GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
                                     Var, DContext);
       continue;
     }
     // Use VarDecl's Tag, Scope and Line number.
-    GV = DBuilder.createGlobalVariable(DContext, FieldName, LinkageName, Unit,
-                                       LineNo, FieldTy, Var->hasLocalLinkage());
-    Var->addDebugInfo(GV);
+    GVE = DBuilder.createGlobalVariableExpression(
+        DContext, FieldName, LinkageName, Unit, LineNo, FieldTy,
+        Var->hasLocalLinkage());
+    Var->addDebugInfo(GVE);
   }
-  return GV;
+  return GVE;
 }
 
 void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
@@ -3682,7 +3853,8 @@
   // it to the llvm::GlobalVariable.
   auto Cached = DeclCache.find(D->getCanonicalDecl());
   if (Cached != DeclCache.end())
-    return Var->addDebugInfo(cast<llvm::DIGlobalVariable>(Cached->second));
+    return Var->addDebugInfo(
+        cast<llvm::DIGlobalVariableExpression>(Cached->second));
 
   // Create global variable debug descriptor.
   llvm::DIFile *Unit = nullptr;
@@ -3694,7 +3866,7 @@
 
   // Attempt to store one global variable for the declaration - even if we
   // emit a lot of fields.
-  llvm::DIGlobalVariable *GV = nullptr;
+  llvm::DIGlobalVariableExpression *GVE = nullptr;
 
   // If this is an anonymous union then we'll want to emit a global
   // variable for each member of the anonymous union so that it's possible
@@ -3703,16 +3875,23 @@
     const RecordDecl *RD = T->castAs<RecordType>()->getDecl();
     assert(RD->isAnonymousStructOrUnion() &&
            "unnamed non-anonymous struct or union?");
-    GV = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
+    GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
   } else {
     auto Align = getDeclAlignIfRequired(D, CGM.getContext());
-    GV = DBuilder.createGlobalVariable(
+
+    SmallVector<int64_t, 4> Expr;
+    unsigned AddressSpace =
+        CGM.getContext().getTargetAddressSpace(D->getType());
+    AppendAddressSpaceXDeref(AddressSpace, Expr);
+
+    GVE = DBuilder.createGlobalVariableExpression(
         DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
-        Var->hasLocalLinkage(), /*Expr=*/nullptr,
+        Var->hasLocalLinkage(),
+        Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
         getOrCreateStaticDataMemberDeclarationOrNull(D), Align);
-    Var->addDebugInfo(GV);
+    Var->addDebugInfo(GVE);
   }
-  DeclCache[D->getCanonicalDecl()].reset(GV);
+  DeclCache[D->getCanonicalDecl()].reset(GVE);
 }
 
 void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
@@ -3757,13 +3936,16 @@
   if (GV)
     return;
   llvm::DIExpression *InitExpr = nullptr;
-  if (Init.isInt())
-    InitExpr =
-        DBuilder.createConstantValueExpression(Init.getInt().getExtValue());
-  else if (Init.isFloat() && CGM.getContext().getTypeSize(VD->getType()) <= 64)
-    InitExpr = DBuilder.createConstantValueExpression(
-        Init.getFloat().bitcastToAPInt().getZExtValue());
-  GV.reset(DBuilder.createGlobalVariable(
+  if (CGM.getContext().getTypeSize(VD->getType()) <= 64) {
+    // FIXME: Add a representation for integer constants wider than 64 bits.
+    if (Init.isInt())
+      InitExpr =
+          DBuilder.createConstantValueExpression(Init.getInt().getExtValue());
+    else if (Init.isFloat())
+      InitExpr = DBuilder.createConstantValueExpression(
+          Init.getFloat().bitcastToAPInt().getZExtValue());
+  }
+  GV.reset(DBuilder.createGlobalVariableExpression(
       DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty,
       true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
       Align));
@@ -3910,6 +4092,8 @@
     else
       Repl = it->second;
 
+    if (auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(Repl))
+      Repl = GVE->getVariable();
     DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
   }
 
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 4cf7bb3..c6d1c66 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -61,6 +61,7 @@
   ModuleMap *ClangModuleMap = nullptr;
   ExternalASTSource::ASTSourceDescriptor PCHDescriptor;
   SourceLocation CurLoc;
+  llvm::MDNode *CurInlinedAt = nullptr;
   llvm::DIType *VTablePtrType = nullptr;
   llvm::DIType *ClassTy = nullptr;
   llvm::DICompositeType *ObjTy = nullptr;
@@ -292,6 +293,15 @@
   /// Create a new lexical block node and push it on the stack.
   void CreateLexicalBlock(SourceLocation Loc);
 
+  /// If target-specific LLVM \p AddressSpace directly maps to target-specific
+  /// DWARF address space, appends extended dereferencing mechanism to complex
+  /// expression \p Expr. Otherwise, does nothing.
+  ///
+  /// Extended dereferencing mechanism is has the following format:
+  ///     DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
+  void AppendAddressSpaceXDeref(unsigned AddressSpace,
+                                SmallVectorImpl<int64_t> &Expr) const;
+
 public:
   CGDebugInfo(CodeGenModule &CGM);
   ~CGDebugInfo();
@@ -320,6 +330,17 @@
   /// ignored.
   void setLocation(SourceLocation Loc);
 
+  /// Return the current source location. This does not necessarily correspond
+  /// to the IRBuilder's current DebugLoc.
+  SourceLocation getLocation() const { return CurLoc; }
+
+  /// Update the current inline scope. All subsequent calls to \p EmitLocation
+  /// will create a location with this inlinedAt field.
+  void setInlinedAt(llvm::MDNode *InlinedAt) { CurInlinedAt = InlinedAt; }
+
+  /// \return the current inline scope.
+  llvm::MDNode *getInlinedAt() const { return CurInlinedAt; }
+
   // Converts a SourceLocation to a DebugLoc
   llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc);
 
@@ -336,6 +357,11 @@
                          SourceLocation ScopeLoc, QualType FnType,
                          llvm::Function *Fn, CGBuilderTy &Builder);
 
+  /// Start a new scope for an inlined function.
+  void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD);
+  /// End an inlined function scope.
+  void EmitInlineFunctionEnd(CGBuilderTy &Builder);
+
   /// Emit debug info for a function declaration.
   void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType);
 
@@ -409,9 +435,20 @@
   void completeType(const RecordDecl *RD);
   void completeRequiredType(const RecordDecl *RD);
   void completeClassData(const RecordDecl *RD);
+  void completeClass(const RecordDecl *RD);
 
   void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD);
 
+  /// Create debug info for a macro defined by a #define directive or a macro
+  /// undefined by a #undef directive.
+  llvm::DIMacro *CreateMacro(llvm::DIMacroFile *Parent, unsigned MType,
+                             SourceLocation LineLoc, StringRef Name,
+                             StringRef Value);
+
+  /// Create debug info for a file referenced by an #include directive.
+  llvm::DIMacroFile *CreateTempMacroFile(llvm::DIMacroFile *Parent,
+                                         SourceLocation LineLoc,
+                                         SourceLocation FileLoc);
 private:
   /// Emit call to llvm.dbg.declare for a variable declaration.
   void EmitDeclare(const VarDecl *decl, llvm::Value *AI,
@@ -442,6 +479,10 @@
   /// Remap a given path with the current debug prefix map
   std::string remapDIPath(StringRef) const;
 
+  /// Compute the file checksum debug info for input file ID.
+  llvm::DIFile::ChecksumKind computeChecksum(FileID FID,
+                                             SmallString<32> &Checksum) const;
+
   /// Get the file debug info descriptor for the input location.
   llvm::DIFile *getOrCreateFile(SourceLocation Loc);
 
@@ -487,23 +528,30 @@
   llvm::DIDerivedType *
   getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D);
 
-  /// Create a subprogram describing the forward declaration
-  /// represented in the given FunctionDecl.
-  llvm::DISubprogram *getFunctionForwardDeclaration(const FunctionDecl *FD);
+  /// Helper that either creates a forward declaration or a stub.
+  llvm::DISubprogram *getFunctionFwdDeclOrStub(GlobalDecl GD, bool Stub);
 
-  /// Create a global variable describing the forward decalration
+  /// Create a subprogram describing the forward declaration
+  /// represented in the given FunctionDecl wrapped in a GlobalDecl.
+  llvm::DISubprogram *getFunctionForwardDeclaration(GlobalDecl GD);
+
+  /// Create a DISubprogram describing the function
+  /// represented in the given FunctionDecl wrapped in a GlobalDecl.
+  llvm::DISubprogram *getFunctionStub(GlobalDecl GD);
+
+  /// Create a global variable describing the forward declaration
   /// represented in the given VarDecl.
   llvm::DIGlobalVariable *
   getGlobalVariableForwardDeclaration(const VarDecl *VD);
 
-  /// \brief Return a global variable that represents one of the
-  /// collection of global variables created for an anonmyous union.
+  /// Return a global variable that represents one of the collection of global
+  /// variables created for an anonmyous union.
   ///
   /// Recursively collect all of the member fields of a global
   /// anonymous decl and create static variables for them. The first
   /// time this is called it needs to be on a union and then from
   /// there we can have additional unnamed fields.
-  llvm::DIGlobalVariable *
+  llvm::DIGlobalVariableExpression *
   CollectAnonRecordDecls(const RecordDecl *RD, llvm::DIFile *Unit,
                          unsigned LineNo, StringRef LinkageName,
                          llvm::GlobalVariable *Var, llvm::DIScope *DContext);
@@ -618,6 +666,20 @@
 
 };
 
+/// A scoped helper to set the current debug location to an inlined location.
+class ApplyInlineDebugLocation {
+  SourceLocation SavedLocation;
+  CodeGenFunction *CGF;
+
+public:
+  /// Set up the CodeGenFunction's DebugInfo to produce inline locations for the
+  /// function \p InlinedFn. The current debug location becomes the inlined call
+  /// site of the inlined function.
+  ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn);
+  /// Restore everything back to the orginial state.
+  ~ApplyInlineDebugLocation();
+};
+
 } // namespace CodeGen
 } // namespace clang
 
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 695e92e..cfadce5 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -50,6 +50,7 @@
   case Decl::TemplateTypeParm:
   case Decl::UnresolvedUsingValue:
   case Decl::NonTypeTemplateParm:
+  case Decl::CXXDeductionGuide:
   case Decl::CXXMethod:
   case Decl::CXXConstructor:
   case Decl::CXXDestructor:
@@ -113,6 +114,10 @@
     if (CGDebugInfo *DI = getDebugInfo())
         DI->EmitUsingDecl(cast<UsingDecl>(D));
     return;
+  case Decl::UsingPack:
+    for (auto *Using : cast<UsingPackDecl>(D).expansions())
+      EmitDecl(*Using);
+    return;
   case Decl::UsingDirective: // using namespace X; [C++]
     if (CGDebugInfo *DI = getDebugInfo())
       DI->EmitUsingDirective(cast<UsingDirectiveDecl>(D));
@@ -307,7 +312,7 @@
   if (!Init) {
     if (!getLangOpts().CPlusPlus)
       CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
-    else if (Builder.GetInsertBlock()) {
+    else if (HaveInsertPoint()) {
       // Since we have a static initializer, this global variable can't
       // be constant.
       GV->setConstant(false);
@@ -348,7 +353,7 @@
   GV->setConstant(CGM.isTypeConstant(D.getType(), true));
   GV->setInitializer(Init);
 
-  if (hasNontrivialDestruction(D.getType())) {
+  if (hasNontrivialDestruction(D.getType()) && HaveInsertPoint()) {
     // We have a constant initializer, but a nontrivial destructor. We still
     // need to perform a guarded "initialization" in order to register the
     // destructor.
@@ -667,6 +672,28 @@
   lvalue.setAddress(CGF.emitBlockByrefAddress(lvalue.getAddress(), var));
 }
 
+void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS,
+                                           SourceLocation Loc) {
+  if (!SanOpts.has(SanitizerKind::NullabilityAssign))
+    return;
+
+  auto Nullability = LHS.getType()->getNullability(getContext());
+  if (!Nullability || *Nullability != NullabilityKind::NonNull)
+    return;
+
+  // Check if the right hand side of the assignment is nonnull, if the left
+  // hand side must be nonnull.
+  SanitizerScope SanScope(this);
+  llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS);
+  // FIXME: The runtime shouldn't refer to a 'reference'.
+  llvm::Constant *StaticData[] = {
+      EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()),
+      llvm::ConstantInt::get(Int8Ty, 1),
+      llvm::ConstantInt::get(Int8Ty, TCK_ReferenceBinding)};
+  EmitCheck({{IsNotNull, SanitizerKind::NullabilityAssign}},
+            SanitizerHandler::TypeMismatch, StaticData, RHS);
+}
+
 void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
                                      LValue lvalue, bool capturedByInit) {
   Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
@@ -674,6 +701,7 @@
     llvm::Value *value = EmitScalarExpr(init);
     if (capturedByInit)
       drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
+    EmitNullabilityCheck(lvalue, value, init->getExprLoc());
     EmitStoreThroughLValue(RValue::get(value), lvalue, true);
     return;
   }
@@ -708,7 +736,7 @@
     }
 
     auto ty = cast<llvm::PointerType>(tempLV.getAddress().getElementType());
-    llvm::Value *zero = llvm::ConstantPointerNull::get(ty);
+    llvm::Value *zero = CGM.getNullPointer(ty, tempLV.getType());
 
     // If __weak, we want to use a barrier under certain conditions.
     if (lifetime == Qualifiers::OCL_Weak)
@@ -762,6 +790,8 @@
 
   if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
 
+  EmitNullabilityCheck(lvalue, value, init->getExprLoc());
+
   // If the variable might have been accessed by its initializer, we
   // might have to initialize with a barrier.  We have to do this for
   // both __weak and __strong, but __weak got filtered out above.
@@ -1018,11 +1048,21 @@
       // Emit a lifetime intrinsic if meaningful. There's no point in doing this
       // if we don't have a valid insertion point (?).
       if (HaveInsertPoint() && !IsMSCatchParam) {
-        // goto or switch-case statements can break lifetime into several
-        // regions which need more efforts to handle them correctly. PR28267
-        // This is rare case, but it's better just omit intrinsics than have
-        // them incorrectly placed.
-        if (!Bypasses.IsBypassed(&D)) {
+        // If there's a jump into the lifetime of this variable, its lifetime
+        // gets broken up into several regions in IR, which requires more work
+        // to handle correctly. For now, just omit the intrinsics; this is a
+        // rare case, and it's better to just be conservatively correct.
+        // PR28267.
+        //
+        // We have to do this in all language modes if there's a jump past the
+        // declaration. We also have to do it in C if there's a jump to an
+        // earlier point in the current block because non-VLA lifetimes begin as
+        // soon as the containing block is entered, not when its variables
+        // actually come into scope; suppressing the lifetime annotations
+        // completely in this case is unnecessarily pessimistic, but again, this
+        // is rare.
+        if (!Bypasses.IsBypassed(&D) &&
+            !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) {
           uint64_t size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
           emission.SizeForLifetimeMarkers =
               EmitLifetimeStart(size, address.getPointer());
@@ -1865,6 +1905,19 @@
 
   if (D.hasAttr<AnnotateAttr>())
     EmitVarAnnotations(&D, DeclPtr.getPointer());
+
+  // We can only check return value nullability if all arguments to the
+  // function satisfy their nullability preconditions. This makes it necessary
+  // to emit null checks for args in the function body itself.
+  if (requiresReturnValueNullabilityCheck()) {
+    auto Nullability = Ty->getNullability(getContext());
+    if (Nullability && *Nullability == NullabilityKind::NonNull) {
+      SanitizerScope SanScope(this);
+      RetValNullabilityPrecondition =
+          Builder.CreateAnd(RetValNullabilityPrecondition,
+                            Builder.CreateIsNotNull(Arg.getAnyValue()));
+    }
+  }
 }
 
 void CodeGenModule::EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index eb5d481..f56e182 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -237,7 +237,8 @@
     llvm::FunctionType::get(IntTy, dtorStub->getType(), false);
 
   llvm::Constant *atexit =
-    CGM.CreateRuntimeFunction(atexitTy, "atexit");
+      CGM.CreateRuntimeFunction(atexitTy, "atexit", llvm::AttributeSet(),
+                                /*Local=*/true);
   if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit))
     atexitFn->setDoesNotThrow();
 
@@ -352,9 +353,6 @@
 
   if (D->getTLSKind()) {
     // FIXME: Should we support init_priority for thread_local?
-    // FIXME: Ideally, initialization of instantiated thread_local static data
-    // members of class templates should not trigger initialization of other
-    // entities in the TU.
     // FIXME: We only need to register one __cxa_thread_atexit function for the
     // entire TU.
     CXXThreadLocalInits.push_back(Fn);
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index d155df6..8f999d1 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -97,6 +97,10 @@
 const EHPersonality
 EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
 const EHPersonality
+EHPersonality::GNU_ObjC_SJLJ = {"__gnu_objc_personality_sj0", "objc_exception_throw"};
+const EHPersonality
+EHPersonality::GNU_ObjC_SEH = {"__gnu_objc_personality_seh0", "objc_exception_throw"};
+const EHPersonality
 EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };
 const EHPersonality
 EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };
@@ -137,6 +141,10 @@
     // fallthrough
   case ObjCRuntime::GCC:
   case ObjCRuntime::ObjFW:
+    if (L.SjLjExceptions)
+      return EHPersonality::GNU_ObjC_SJLJ;
+    else if (useLibGCCSEHPersonality(T))
+      return EHPersonality::GNU_ObjC_SEH;
     return EHPersonality::GNU_ObjC;
   }
   llvm_unreachable("bad runtime kind");
@@ -221,10 +229,9 @@
 
 static llvm::Constant *getPersonalityFn(CodeGenModule &CGM,
                                         const EHPersonality &Personality) {
-  llvm::Constant *Fn =
-    CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),
-                              Personality.PersonalityFn);
-  return Fn;
+  return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),
+                                   Personality.PersonalityFn,
+                                   llvm::AttributeSet(), /*Local=*/true);
 }
 
 static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,
@@ -1659,23 +1666,12 @@
 
   QualType RetTy = IsFilter ? getContext().LongTy : getContext().VoidTy;
 
-  llvm::Function *ParentFn = ParentCGF.CurFn;
   const CGFunctionInfo &FnInfo =
     CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
 
   llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
   llvm::Function *Fn = llvm::Function::Create(
       FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());
-  // The filter is either in the same comdat as the function, or it's internal.
-  if (llvm::Comdat *C = ParentFn->getComdat()) {
-    Fn->setComdat(C);
-  } else if (ParentFn->hasWeakLinkage() || ParentFn->hasLinkOnceLinkage()) {
-    llvm::Comdat *C = CGM.getModule().getOrInsertComdat(ParentFn->getName());
-    ParentFn->setComdat(C);
-    Fn->setComdat(C);
-  } else {
-    Fn->setLinkage(llvm::GlobalValue::InternalLinkage);
-  }
 
   IsOutlinedSEHHelper = true;
 
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index bd21a86..ab4448b 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -24,6 +24,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/NSAPI.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringExtras.h"
@@ -36,6 +37,8 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Transforms/Utils/SanitizerStats.h"
 
+#include <string>
+
 using namespace clang;
 using namespace CodeGen;
 
@@ -531,7 +534,8 @@
 
 void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
                                     llvm::Value *Ptr, QualType Ty,
-                                    CharUnits Alignment, bool SkipNullCheck) {
+                                    CharUnits Alignment,
+                                    SanitizerSet SkippedChecks) {
   if (!sanitizePerformTypeCheck())
     return;
 
@@ -549,7 +553,7 @@
   bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
                            TCK == TCK_UpcastToVirtualBase;
   if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
-      !SkipNullCheck) {
+      !SkippedChecks.has(SanitizerKind::Null)) {
     // The glvalue must not be an empty glvalue.
     llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);
 
@@ -565,7 +569,9 @@
     }
   }
 
-  if (SanOpts.has(SanitizerKind::ObjectSize) && !Ty->isIncompleteType()) {
+  if (SanOpts.has(SanitizerKind::ObjectSize) &&
+      !SkippedChecks.has(SanitizerKind::ObjectSize) &&
+      !Ty->isIncompleteType()) {
     uint64_t Size = getContext().getTypeSizeInChars(Ty).getQuantity();
 
     // The glvalue must refer to a large enough storage region.
@@ -584,7 +590,8 @@
 
   uint64_t AlignVal = 0;
 
-  if (SanOpts.has(SanitizerKind::Alignment)) {
+  if (SanOpts.has(SanitizerKind::Alignment) &&
+      !SkippedChecks.has(SanitizerKind::Alignment)) {
     AlignVal = Alignment.getQuantity();
     if (!Ty->isIncompleteType() && !AlignVal)
       AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity();
@@ -601,13 +608,14 @@
   }
 
   if (Checks.size() > 0) {
+    // Make sure we're not losing information. Alignment needs to be a power of
+    // 2
+    assert(!AlignVal || (uint64_t)1 << llvm::Log2_64(AlignVal) == AlignVal);
     llvm::Constant *StaticData[] = {
-     EmitCheckSourceLocation(Loc),
-      EmitCheckTypeDescriptor(Ty),
-      llvm::ConstantInt::get(SizeTy, AlignVal),
-      llvm::ConstantInt::get(Int8Ty, TCK)
-    };
-    EmitCheck(Checks, "type_mismatch", StaticData, Ptr);
+        EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty),
+        llvm::ConstantInt::get(Int8Ty, AlignVal ? llvm::Log2_64(AlignVal) : 1),
+        llvm::ConstantInt::get(Int8Ty, TCK)};
+    EmitCheck(Checks, SanitizerHandler::TypeMismatch, StaticData, Ptr);
   }
 
   // If possible, check that the vptr indicates that there is a subobject of
@@ -620,6 +628,7 @@
   //       or call a non-static member function
   CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
   if (SanOpts.has(SanitizerKind::Vptr) &&
+      !SkippedChecks.has(SanitizerKind::Vptr) &&
       (TCK == TCK_MemberAccess || TCK == TCK_MemberCall ||
        TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||
        TCK == TCK_UpcastToVirtualBase) &&
@@ -675,7 +684,8 @@
       };
       llvm::Value *DynamicData[] = { Ptr, Hash };
       EmitCheck(std::make_pair(EqualHash, SanitizerKind::Vptr),
-                "dynamic_type_cache_miss", StaticData, DynamicData);
+                SanitizerHandler::DynamicTypeCacheMiss, StaticData,
+                DynamicData);
     }
   }
 
@@ -765,8 +775,8 @@
   };
   llvm::Value *Check = Accessed ? Builder.CreateICmpULT(IndexVal, BoundVal)
                                 : Builder.CreateICmpULE(IndexVal, BoundVal);
-  EmitCheck(std::make_pair(Check, SanitizerKind::ArrayBounds), "out_of_bounds",
-            StaticData, Index);
+  EmitCheck(std::make_pair(Check, SanitizerKind::ArrayBounds),
+            SanitizerHandler::OutOfBounds, StaticData, Index);
 }
 
 
@@ -942,15 +952,46 @@
                         E->getType());
 }
 
+bool CodeGenFunction::IsDeclRefOrWrappedCXXThis(const Expr *Obj) {
+  if (isa<DeclRefExpr>(Obj))
+    return true;
+
+  const Expr *Base = Obj;
+  while (!isa<CXXThisExpr>(Base)) {
+    // The result of a dynamic_cast can be null.
+    if (isa<CXXDynamicCastExpr>(Base))
+      return false;
+
+    if (const auto *CE = dyn_cast<CastExpr>(Base)) {
+      Base = CE->getSubExpr();
+    } else if (const auto *PE = dyn_cast<ParenExpr>(Base)) {
+      Base = PE->getSubExpr();
+    } else if (const auto *UO = dyn_cast<UnaryOperator>(Base)) {
+      if (UO->getOpcode() == UO_Extension)
+        Base = UO->getSubExpr();
+      else
+        return false;
+    } else {
+      return false;
+    }
+  }
+  return true;
+}
+
 LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) {
   LValue LV;
   if (SanOpts.has(SanitizerKind::ArrayBounds) && isa<ArraySubscriptExpr>(E))
     LV = EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E), /*Accessed*/true);
   else
     LV = EmitLValue(E);
-  if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
+  if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple()) {
+    SanitizerSet SkippedChecks;
+    if (const auto *ME = dyn_cast<MemberExpr>(E))
+      if (IsDeclRefOrWrappedCXXThis(ME->getBase()))
+        SkippedChecks.set(SanitizerKind::Null, true);
     EmitTypeCheck(TCK, E->getExprLoc(), LV.getPointer(),
-                  E->getType(), LV.getAlignment());
+                  E->getType(), LV.getAlignment(), SkippedChecks);
+  }
   return LV;
 }
 
@@ -1028,7 +1069,19 @@
     const auto *cleanups = cast<ExprWithCleanups>(E);
     enterFullExpression(cleanups);
     RunCleanupsScope Scope(*this);
-    return EmitLValue(cleanups->getSubExpr());
+    LValue LV = EmitLValue(cleanups->getSubExpr());
+    if (LV.isSimple()) {
+      // Defend against branches out of gnu statement expressions surrounded by
+      // cleanups.
+      llvm::Value *V = LV.getPointer();
+      Scope.ForceCleanup({&V});
+      return LValue::MakeAddr(Address(V, LV.getAlignment()), LV.getType(),
+                              getContext(), LV.getAlignmentSource(),
+                              LV.getTBAAInfo());
+    }
+    // FIXME: Is it possible to create an ExprWithCleanups that produces a
+    // bitfield lvalue or some other non-simple lvalue?
+    return LV;
   }
 
   case Expr::CXXDefaultArgExprClass:
@@ -1219,11 +1272,10 @@
 
 static bool getRangeForType(CodeGenFunction &CGF, QualType Ty,
                             llvm::APInt &Min, llvm::APInt &End,
-                            bool StrictEnums) {
+                            bool StrictEnums, bool IsBool) {
   const EnumType *ET = Ty->getAs<EnumType>();
   bool IsRegularCPlusPlusEnum = CGF.getLangOpts().CPlusPlus && StrictEnums &&
                                 ET && !ET->getDecl()->isFixed();
-  bool IsBool = hasBooleanRepresentation(Ty);
   if (!IsBool && !IsRegularCPlusPlusEnum)
     return false;
 
@@ -1253,14 +1305,61 @@
 
 llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
   llvm::APInt Min, End;
-  if (!getRangeForType(*this, Ty, Min, End,
-                       CGM.getCodeGenOpts().StrictEnums))
+  if (!getRangeForType(*this, Ty, Min, End, CGM.getCodeGenOpts().StrictEnums,
+                       hasBooleanRepresentation(Ty)))
     return nullptr;
 
   llvm::MDBuilder MDHelper(getLLVMContext());
   return MDHelper.createRange(Min, End);
 }
 
+bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
+                                           SourceLocation Loc) {
+  bool HasBoolCheck = SanOpts.has(SanitizerKind::Bool);
+  bool HasEnumCheck = SanOpts.has(SanitizerKind::Enum);
+  if (!HasBoolCheck && !HasEnumCheck)
+    return false;
+
+  bool IsBool = hasBooleanRepresentation(Ty) ||
+                NSAPI(CGM.getContext()).isObjCBOOLType(Ty);
+  bool NeedsBoolCheck = HasBoolCheck && IsBool;
+  bool NeedsEnumCheck = HasEnumCheck && Ty->getAs<EnumType>();
+  if (!NeedsBoolCheck && !NeedsEnumCheck)
+    return false;
+
+  // Single-bit booleans don't need to be checked. Special-case this to avoid
+  // a bit width mismatch when handling bitfield values. This is handled by
+  // EmitFromMemory for the non-bitfield case.
+  if (IsBool &&
+      cast<llvm::IntegerType>(Value->getType())->getBitWidth() == 1)
+    return false;
+
+  llvm::APInt Min, End;
+  if (!getRangeForType(*this, Ty, Min, End, /*StrictEnums=*/true, IsBool))
+    return true;
+
+  SanitizerScope SanScope(this);
+  llvm::Value *Check;
+  --End;
+  if (!Min) {
+    Check = Builder.CreateICmpULE(
+        Value, llvm::ConstantInt::get(getLLVMContext(), End));
+  } else {
+    llvm::Value *Upper = Builder.CreateICmpSLE(
+        Value, llvm::ConstantInt::get(getLLVMContext(), End));
+    llvm::Value *Lower = Builder.CreateICmpSGE(
+        Value, llvm::ConstantInt::get(getLLVMContext(), Min));
+    Check = Builder.CreateAnd(Upper, Lower);
+  }
+  llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc),
+                                  EmitCheckTypeDescriptor(Ty)};
+  SanitizerMask Kind =
+      NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool;
+  EmitCheck(std::make_pair(Check, Kind), SanitizerHandler::LoadInvalidValue,
+            StaticArgs, EmitCheckValue(Value));
+  return true;
+}
+
 llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
                                                QualType Ty,
                                                SourceLocation Loc,
@@ -1313,34 +1412,9 @@
                                       false /*ConvertTypeToTag*/);
   }
 
-  bool NeedsBoolCheck =
-      SanOpts.has(SanitizerKind::Bool) && hasBooleanRepresentation(Ty);
-  bool NeedsEnumCheck =
-      SanOpts.has(SanitizerKind::Enum) && Ty->getAs<EnumType>();
-  if (NeedsBoolCheck || NeedsEnumCheck) {
-    SanitizerScope SanScope(this);
-    llvm::APInt Min, End;
-    if (getRangeForType(*this, Ty, Min, End, true)) {
-      --End;
-      llvm::Value *Check;
-      if (!Min)
-        Check = Builder.CreateICmpULE(
-          Load, llvm::ConstantInt::get(getLLVMContext(), End));
-      else {
-        llvm::Value *Upper = Builder.CreateICmpSLE(
-          Load, llvm::ConstantInt::get(getLLVMContext(), End));
-        llvm::Value *Lower = Builder.CreateICmpSGE(
-          Load, llvm::ConstantInt::get(getLLVMContext(), Min));
-        Check = Builder.CreateAnd(Upper, Lower);
-      }
-      llvm::Constant *StaticArgs[] = {
-        EmitCheckSourceLocation(Loc),
-        EmitCheckTypeDescriptor(Ty)
-      };
-      SanitizerMask Kind = NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool;
-      EmitCheck(std::make_pair(Check, Kind), "load_invalid_value", StaticArgs,
-                EmitCheckValue(Load));
-    }
+  if (EmitScalarRangeCheck(Load, Ty, Loc)) {
+    // In order to prevent the optimizer from throwing away the check, don't
+    // attach range metadata to the load.
   } else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
     if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
       Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
@@ -1482,10 +1556,11 @@
     return EmitLoadOfGlobalRegLValue(LV);
 
   assert(LV.isBitField() && "Unknown LValue type!");
-  return EmitLoadOfBitfieldLValue(LV);
+  return EmitLoadOfBitfieldLValue(LV, Loc);
 }
 
-RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) {
+RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
+                                                 SourceLocation Loc) {
   const CGBitFieldInfo &Info = LV.getBitFieldInfo();
 
   // Get the output type.
@@ -1510,7 +1585,7 @@
                               "bf.clear");
   }
   Val = Builder.CreateIntCast(Val, ResLTy, Info.IsSigned, "bf.cast");
-
+  EmitScalarRangeCheck(Val, LV.getType(), Loc);
   return RValue::get(Val);
 }
 
@@ -2499,17 +2574,35 @@
   }
 }
 
+namespace {
+struct SanitizerHandlerInfo {
+  char const *const Name;
+  unsigned Version;
+};
+}
+
+const SanitizerHandlerInfo SanitizerHandlers[] = {
+#define SANITIZER_CHECK(Enum, Name, Version) {#Name, Version},
+    LIST_SANITIZER_CHECKS
+#undef SANITIZER_CHECK
+};
+
 static void emitCheckHandlerCall(CodeGenFunction &CGF,
                                  llvm::FunctionType *FnType,
                                  ArrayRef<llvm::Value *> FnArgs,
-                                 StringRef CheckName,
+                                 SanitizerHandler CheckHandler,
                                  CheckRecoverableKind RecoverKind, bool IsFatal,
                                  llvm::BasicBlock *ContBB) {
   assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
   bool NeedsAbortSuffix =
       IsFatal && RecoverKind != CheckRecoverableKind::Unrecoverable;
-  std::string FnName = ("__ubsan_handle_" + CheckName +
-                        (NeedsAbortSuffix ? "_abort" : "")).str();
+  const SanitizerHandlerInfo &CheckInfo = SanitizerHandlers[CheckHandler];
+  const StringRef CheckName = CheckInfo.Name;
+  std::string FnName =
+      ("__ubsan_handle_" + CheckName +
+       (CheckInfo.Version ? "_v" + llvm::utostr(CheckInfo.Version) : "") +
+       (NeedsAbortSuffix ? "_abort" : ""))
+          .str();
   bool MayReturn =
       !IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable;
 
@@ -2523,7 +2616,8 @@
   llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(
       FnType, FnName,
       llvm::AttributeSet::get(CGF.getLLVMContext(),
-                              llvm::AttributeSet::FunctionIndex, B));
+                              llvm::AttributeSet::FunctionIndex, B),
+      /*Local=*/true);
   llvm::CallInst *HandlerCall = CGF.EmitNounwindRuntimeCall(Fn, FnArgs);
   if (!MayReturn) {
     HandlerCall->setDoesNotReturn();
@@ -2535,10 +2629,13 @@
 
 void CodeGenFunction::EmitCheck(
     ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked,
-    StringRef CheckName, ArrayRef<llvm::Constant *> StaticArgs,
+    SanitizerHandler CheckHandler, ArrayRef<llvm::Constant *> StaticArgs,
     ArrayRef<llvm::Value *> DynamicArgs) {
   assert(IsSanitizerScope);
   assert(Checked.size() > 0);
+  assert(CheckHandler >= 0 &&
+         CheckHandler < sizeof(SanitizerHandlers) / sizeof(*SanitizerHandlers));
+  const StringRef CheckName = SanitizerHandlers[CheckHandler].Name;
 
   llvm::Value *FatalCond = nullptr;
   llvm::Value *RecoverableCond = nullptr;
@@ -2618,7 +2715,7 @@
   if (!FatalCond || !RecoverableCond) {
     // Simple case: we need to generate a single handler call, either
     // fatal, or non-fatal.
-    emitCheckHandlerCall(*this, FnType, Args, CheckName, RecoverKind,
+    emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind,
                          (FatalCond != nullptr), Cont);
   } else {
     // Emit two handler calls: first one for set of unrecoverable checks,
@@ -2628,10 +2725,10 @@
     llvm::BasicBlock *FatalHandlerBB = createBasicBlock("fatal." + CheckName);
     Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
     EmitBlock(FatalHandlerBB);
-    emitCheckHandlerCall(*this, FnType, Args, CheckName, RecoverKind, true,
+    emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, true,
                          NonFatalHandlerBB);
     EmitBlock(NonFatalHandlerBB);
-    emitCheckHandlerCall(*this, FnType, Args, CheckName, RecoverKind, false,
+    emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, false,
                          Cont);
   }
 
@@ -2756,7 +2853,7 @@
     llvm::Value *Cond =
         Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(Int8Ty, Kind));
     if (CGM.getLangOpts().Sanitize.has(Mask))
-      EmitCheck(std::make_pair(Cond, Mask), "cfi_check_fail", {},
+      EmitCheck(std::make_pair(Cond, Mask), SanitizerHandler::CFICheckFail, {},
                 {Data, Addr, ValidVtable});
     else
       EmitTrapCheck(Cond);
@@ -3308,7 +3405,11 @@
     AlignmentSource AlignSource;
     Address Addr = EmitPointerWithAlignment(BaseExpr, &AlignSource);
     QualType PtrTy = BaseExpr->getType()->getPointeeType();
-    EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy);
+    SanitizerSet SkippedChecks;
+    if (IsDeclRefOrWrappedCXXThis(BaseExpr))
+      SkippedChecks.set(SanitizerKind::Null, true);
+    EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy,
+                  /*Alignment=*/CharUnits::Zero(), SkippedChecks);
     BaseLV = MakeAddrLValue(Addr, PtrTy, AlignSource);
   } else
     BaseLV = EmitCheckedLValue(BaseExpr, TCK_MemberAccess);
@@ -3755,6 +3856,8 @@
                                              ConvertType(E->getType()));
     return MakeAddrLValue(V, E->getType(), LV.getAlignmentSource());
   }
+  case CK_ZeroToOCLQueue:
+    llvm_unreachable("NULL to OpenCL queue lvalue cast is not valid");
   case CK_ZeroToOCLEvent:
     llvm_unreachable("NULL to OpenCL event lvalue cast is not valid");
   }
@@ -4126,7 +4229,7 @@
         EmitCheckTypeDescriptor(CalleeType)
       };
       EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
-                "function_type_mismatch", StaticData, CalleePtr);
+                SanitizerHandler::FunctionTypeMismatch, StaticData, CalleePtr);
 
       Builder.CreateBr(Cont);
       EmitBlock(Cont);
@@ -4159,7 +4262,7 @@
                            CastedCallee, StaticData);
     } else {
       EmitCheck(std::make_pair(TypeTest, SanitizerKind::CFIICall),
-                "cfi_check_fail", StaticData,
+                SanitizerHandler::CFICheckFail, StaticData,
                 {CastedCallee, llvm::UndefValue::get(IntPtrTy)});
     }
   }
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 98f476e..0092447 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -164,6 +164,8 @@
   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);
   void VisitChooseExpr(const ChooseExpr *CE);
   void VisitInitListExpr(InitListExpr *E);
+  void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E,
+                              llvm::Value *outerBegin = nullptr);
   void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
   void VisitNoInitExpr(NoInitExpr *E) { } // Do nothing.
   void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
@@ -749,6 +751,7 @@
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
+  case CK_ZeroToOCLQueue:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
     llvm_unreachable("cast kind invalid for aggregate types");
@@ -1050,7 +1053,8 @@
     return true;
   // (int*)0 - Null pointer expressions.
   if (const CastExpr *ICE = dyn_cast<CastExpr>(E))
-    return ICE->getCastKind() == CK_NullToPointer;
+    return ICE->getCastKind() == CK_NullToPointer &&
+        CGF.getTypes().isPointerZeroInitializable(E->getType());
   // '\0'
   if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E))
     return CL->getValue() == 0;
@@ -1307,6 +1311,98 @@
     cleanupDominator->eraseFromParent();
 }
 
+void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E,
+                                            llvm::Value *outerBegin) {
+  // Emit the common subexpression.
+  CodeGenFunction::OpaqueValueMapping binding(CGF, E->getCommonExpr());
+
+  Address destPtr = EnsureSlot(E->getType()).getAddress();
+  uint64_t numElements = E->getArraySize().getZExtValue();
+
+  if (!numElements)
+    return;
+
+  // destPtr is an array*. Construct an elementType* by drilling down a level.
+  llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
+  llvm::Value *indices[] = {zero, zero};
+  llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.getPointer(), indices,
+                                                 "arrayinit.begin");
+
+  // Prepare to special-case multidimensional array initialization: we avoid
+  // emitting multiple destructor loops in that case.
+  if (!outerBegin)
+    outerBegin = begin;
+  ArrayInitLoopExpr *InnerLoop = dyn_cast<ArrayInitLoopExpr>(E->getSubExpr());
+
+  QualType elementType =
+      CGF.getContext().getAsArrayType(E->getType())->getElementType();
+  CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType);
+  CharUnits elementAlign =
+      destPtr.getAlignment().alignmentOfArrayElement(elementSize);
+
+  llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
+  llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");
+
+  // Jump into the body.
+  CGF.EmitBlock(bodyBB);
+  llvm::PHINode *index =
+      Builder.CreatePHI(zero->getType(), 2, "arrayinit.index");
+  index->addIncoming(zero, entryBB);
+  llvm::Value *element = Builder.CreateInBoundsGEP(begin, index);
+
+  // Prepare for a cleanup.
+  QualType::DestructionKind dtorKind = elementType.isDestructedType();
+  EHScopeStack::stable_iterator cleanup;
+  if (CGF.needsEHCleanup(dtorKind) && !InnerLoop) {
+    if (outerBegin->getType() != element->getType())
+      outerBegin = Builder.CreateBitCast(outerBegin, element->getType());
+    CGF.pushRegularPartialArrayCleanup(outerBegin, element, elementType,
+                                       elementAlign,
+                                       CGF.getDestroyer(dtorKind));
+    cleanup = CGF.EHStack.stable_begin();
+  } else {
+    dtorKind = QualType::DK_none;
+  }
+
+  // Emit the actual filler expression.
+  {
+    // Temporaries created in an array initialization loop are destroyed
+    // at the end of each iteration.
+    CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);
+    CodeGenFunction::ArrayInitLoopExprScope Scope(CGF, index);
+    LValue elementLV =
+        CGF.MakeAddrLValue(Address(element, elementAlign), elementType);
+
+    if (InnerLoop) {
+      // If the subexpression is an ArrayInitLoopExpr, share its cleanup.
+      auto elementSlot = AggValueSlot::forLValue(
+          elementLV, AggValueSlot::IsDestructed,
+          AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased);
+      AggExprEmitter(CGF, elementSlot, false)
+          .VisitArrayInitLoopExpr(InnerLoop, outerBegin);
+    } else
+      EmitInitializationToLValue(E->getSubExpr(), elementLV);
+  }
+
+  // Move on to the next element.
+  llvm::Value *nextIndex = Builder.CreateNUWAdd(
+      index, llvm::ConstantInt::get(CGF.SizeTy, 1), "arrayinit.next");
+  index->addIncoming(nextIndex, Builder.GetInsertBlock());
+
+  // Leave the loop if we're done.
+  llvm::Value *done = Builder.CreateICmpEQ(
+      nextIndex, llvm::ConstantInt::get(CGF.SizeTy, numElements),
+      "arrayinit.done");
+  llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");
+  Builder.CreateCondBr(done, endBB, bodyBB);
+
+  CGF.EmitBlock(endBB);
+
+  // Leave the partial-array cleanup if we entered one.
+  if (dtorKind)
+    CGF.DeactivateCleanupBlock(cleanup, index);
+}
+
 void AggExprEmitter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
   AggValueSlot Dest = EnsureSlot(E->getType());
 
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index ab2468e..0482691 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -24,7 +24,15 @@
 using namespace clang;
 using namespace CodeGen;
 
-static RequiredArgs
+namespace {
+struct MemberCallInfo {
+  RequiredArgs ReqArgs;
+  // Number of prefix arguments for the call. Ignores the `this` pointer.
+  unsigned PrefixSize;
+};
+}
+
+static MemberCallInfo
 commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD,
                                   llvm::Value *This, llvm::Value *ImplicitParam,
                                   QualType ImplicitParamTy, const CallExpr *CE,
@@ -48,6 +56,7 @@
 
   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
   RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size(), MD);
+  unsigned PrefixSize = Args.size() - 1;
 
   // And the rest of the call args.
   if (RtlArgs) {
@@ -65,7 +74,7 @@
         FPT->getNumParams() == 0 &&
         "No CallExpr specified for function with non-zero number of arguments");
   }
-  return required;
+  return {required, PrefixSize};
 }
 
 RValue CodeGenFunction::EmitCXXMemberOrOperatorCall(
@@ -75,9 +84,10 @@
     const CallExpr *CE, CallArgList *RtlArgs) {
   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
   CallArgList Args;
-  RequiredArgs required = commonEmitCXXMemberOrOperatorCall(
+  MemberCallInfo CallInfo = commonEmitCXXMemberOrOperatorCall(
       *this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs);
-  auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required);
+  auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall(
+      Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize);
   return EmitCall(FnInfo, Callee, ReturnValue, Args);
 }
 
@@ -290,10 +300,15 @@
   if (CE)
     CallLoc = CE->getExprLoc();
 
-  EmitTypeCheck(isa<CXXConstructorDecl>(CalleeDecl)
-                ? CodeGenFunction::TCK_ConstructorCall
-                : CodeGenFunction::TCK_MemberCall,
-                CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()));
+  SanitizerSet SkippedChecks;
+  if (const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE))
+    if (IsDeclRefOrWrappedCXXThis(CMCE->getImplicitObjectArgument()))
+      SkippedChecks.set(SanitizerKind::Null, true);
+  EmitTypeCheck(
+      isa<CXXConstructorDecl>(CalleeDecl) ? CodeGenFunction::TCK_ConstructorCall
+                                          : CodeGenFunction::TCK_MemberCall,
+      CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()),
+      /*Alignment=*/CharUnits::Zero(), SkippedChecks);
 
   // FIXME: Uses of 'MD' past this point need to be audited. We may need to use
   // 'CalleeDecl' instead.
@@ -420,7 +435,8 @@
 
   // And the rest of the call args
   EmitCallArgs(Args, FPT, E->arguments());
-  return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required),
+  return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required,
+                                                      /*PrefixSize=*/0),
                   Callee, ReturnValue, Args);
 }
 
@@ -659,7 +675,10 @@
   // Emit the array size expression.
   // We multiply the size of all dimensions for NumElements.
   // e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.
-  numElements = CGF.EmitScalarExpr(e->getArraySize());
+  numElements = CGF.CGM.EmitConstantExpr(e->getArraySize(),
+                                         CGF.getContext().getSizeType(), &CGF);
+  if (!numElements)
+    numElements = CGF.EmitScalarExpr(e->getArraySize());
   assert(isa<llvm::IntegerType>(numElements->getType()));
 
   // The number of elements can be have an arbitrary integer type;
@@ -1560,7 +1579,7 @@
 
     // FIXME: Why do we not pass a CalleeDecl here?
     EmitCallArgs(allocatorArgs, allocatorType, E->placement_arguments(),
-                 /*CalleeDecl*/nullptr, /*ParamsToSkip*/ParamsToSkip);
+                 /*AC*/AbstractCallee(), /*ParamsToSkip*/ParamsToSkip);
 
     RValue RV =
       EmitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs);
@@ -2140,10 +2159,7 @@
       auto VAT = CurField->getCapturedVLAType();
       EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
     } else {
-      ArrayRef<VarDecl *> ArrayIndexes;
-      if (CurField->getType()->isArrayType())
-        ArrayIndexes = E->getCaptureInitIndexVars(i);
-      EmitInitializerForField(*CurField, LV, *i, ArrayIndexes);
+      EmitInitializerForField(*CurField, LV, *i);
     }
   }
 }
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index 60bbc5c..22e7fa6 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -198,7 +198,11 @@
   ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) {
     CGF.enterFullExpression(E);
     CodeGenFunction::RunCleanupsScope Scope(CGF);
-    return Visit(E->getSubExpr());
+    ComplexPairTy Vals = Visit(E->getSubExpr());
+    // Defend against dominance problems caused by jumps out of expression
+    // evaluation through the shared cleanup block.
+    Scope.ForceCleanup({&Vals.first, &Vals.second});
+    return Vals;
   }
   ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
     assert(E->getType()->isAnyComplexType() && "Expected complex type!");
@@ -480,6 +484,7 @@
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
+  case CK_ZeroToOCLQueue:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
     llvm_unreachable("invalid cast kind for complex value");
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 27c8386..3db15c6 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -16,6 +16,7 @@
 #include "CGObjCRuntime.h"
 #include "CGRecordLayout.h"
 #include "CodeGenModule.h"
+#include "TargetInfo.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/RecordLayout.h"
@@ -752,6 +753,7 @@
     case CK_FloatingToBoolean:
     case CK_FloatingCast:
     case CK_ZeroToOCLEvent:
+    case CK_ZeroToOCLQueue:
       return nullptr;
     }
     llvm_unreachable("Invalid CastKind");
@@ -1021,16 +1023,17 @@
     switch (E->getStmtClass()) {
     default: break;
     case Expr::CompoundLiteralExprClass: {
-      // Note that due to the nature of compound literals, this is guaranteed
-      // to be the only use of the variable, so we just generate it here.
       CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
+      CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
+      if (llvm::GlobalVariable *Addr =
+              CGM.getAddrOfConstantCompoundLiteralIfEmitted(CLE))
+        return ConstantAddress(Addr, Align);
+
       llvm::Constant* C = CGM.EmitConstantExpr(CLE->getInitializer(),
                                                CLE->getType(), CGF);
       // FIXME: "Leaked" on failure.
       if (!C) return ConstantAddress::invalid();
 
-      CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
-
       auto GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
                                      E->getType().isConstant(CGM.getContext()),
                                      llvm::GlobalValue::InternalLinkage,
@@ -1038,6 +1041,7 @@
                                      llvm::GlobalVariable::NotThreadLocal,
                           CGM.getContext().getTargetAddressSpace(E->getType()));
       GV->setAlignment(Align.getQuantity());
+      CGM.setAddrOfConstantCompoundLiteral(CLE, GV);
       return ConstantAddress(GV, Align);
     }
     case Expr::StringLiteralClass:
@@ -1262,6 +1266,10 @@
   return C;
 }
 
+llvm::Constant *CodeGenModule::getNullPointer(llvm::PointerType *T, QualType QT) {
+  return getTargetCodeGenInfo().getNullPointer(*this, T, QT);
+}
+
 llvm::Constant *CodeGenModule::EmitConstantValue(const APValue &Value,
                                                  QualType DestType,
                                                  CodeGenFunction *CGF) {
@@ -1293,6 +1301,7 @@
       llvm::ConstantInt::get(Int64Ty, Value.getLValueOffset().getQuantity());
 
     llvm::Constant *C = nullptr;
+
     if (APValue::LValueBase LVBase = Value.getLValueBase()) {
       // An array can be represented as an lvalue referring to the base.
       if (isa<llvm::ArrayType>(DestTy)) {
@@ -1323,7 +1332,9 @@
 
       // Convert to the appropriate type; this could be an lvalue for
       // an integer.
-      if (isa<llvm::PointerType>(DestTy)) {
+      if (auto PT = dyn_cast<llvm::PointerType>(DestTy)) {
+        if (Value.isNullPointer())
+          return getNullPointer(PT, DestType);
         // Convert the integer to a pointer-sized integer before converting it
         // to a pointer.
         C = llvm::ConstantExpr::getIntegerCast(
@@ -1357,7 +1368,7 @@
   }
   case APValue::Float: {
     const llvm::APFloat &Init = Value.getFloat();
-    if (&Init.getSemantics() == &llvm::APFloat::IEEEhalf &&
+    if (&Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
         !Context.getLangOpts().NativeHalfType &&
         !Context.getLangOpts().HalfArgsAndReturns)
       return llvm::ConstantInt::get(VMContext, Init.bitcastToAPInt());
@@ -1483,6 +1494,18 @@
   return C;
 }
 
+llvm::GlobalVariable *CodeGenModule::getAddrOfConstantCompoundLiteralIfEmitted(
+    const CompoundLiteralExpr *E) {
+  return EmittedCompoundLiterals.lookup(E);
+}
+
+void CodeGenModule::setAddrOfConstantCompoundLiteral(
+    const CompoundLiteralExpr *CLE, llvm::GlobalVariable *GV) {
+  bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
+  (void)Ok;
+  assert(Ok && "CLE has already been emitted!");
+}
+
 ConstantAddress
 CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
   assert(E->isFileScope() && "not a file-scope compound literal expr");
@@ -1510,7 +1533,7 @@
                                                const CXXRecordDecl *base);
 
 static llvm::Constant *EmitNullConstant(CodeGenModule &CGM,
-                                        const CXXRecordDecl *record,
+                                        const RecordDecl *record,
                                         bool asCompleteObject) {
   const CGRecordLayout &layout = CGM.getTypes().getCGRecordLayout(record);
   llvm::StructType *structure =
@@ -1520,25 +1543,29 @@
   unsigned numElements = structure->getNumElements();
   std::vector<llvm::Constant *> elements(numElements);
 
+  auto CXXR = dyn_cast<CXXRecordDecl>(record);
   // Fill in all the bases.
-  for (const auto &I : record->bases()) {
-    if (I.isVirtual()) {
-      // Ignore virtual bases; if we're laying out for a complete
-      // object, we'll lay these out later.
-      continue;
+  if (CXXR) {
+    for (const auto &I : CXXR->bases()) {
+      if (I.isVirtual()) {
+        // Ignore virtual bases; if we're laying out for a complete
+        // object, we'll lay these out later.
+        continue;
+      }
+
+      const CXXRecordDecl *base =
+        cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+
+      // Ignore empty bases.
+      if (base->isEmpty() ||
+          CGM.getContext().getASTRecordLayout(base).getNonVirtualSize()
+              .isZero())
+        continue;
+
+      unsigned fieldIndex = layout.getNonVirtualBaseLLVMFieldNo(base);
+      llvm::Type *baseType = structure->getElementType(fieldIndex);
+      elements[fieldIndex] = EmitNullConstantForBase(CGM, baseType, base);
     }
-
-    const CXXRecordDecl *base = 
-      cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
-
-    // Ignore empty bases.
-    if (base->isEmpty() ||
-        CGM.getContext().getASTRecordLayout(base).getNonVirtualSize().isZero())
-      continue;
-    
-    unsigned fieldIndex = layout.getNonVirtualBaseLLVMFieldNo(base);
-    llvm::Type *baseType = structure->getElementType(fieldIndex);
-    elements[fieldIndex] = EmitNullConstantForBase(CGM, baseType, base);
   }
 
   // Fill in all the fields.
@@ -1562,8 +1589,8 @@
   }
 
   // Fill in the virtual bases, if we're working with the complete object.
-  if (asCompleteObject) {
-    for (const auto &I : record->vbases()) {
+  if (CXXR && asCompleteObject) {
+    for (const auto &I : CXXR->vbases()) {
       const CXXRecordDecl *base = 
         cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
 
@@ -1605,6 +1632,10 @@
 }
 
 llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
+  if (T->getAs<PointerType>())
+    return getNullPointer(
+        cast<llvm::PointerType>(getTypes().ConvertTypeForMem(T)), T);
+
   if (getTypes().isZeroInitializable(T))
     return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T));
     
@@ -1620,10 +1651,8 @@
     return llvm::ConstantArray::get(ATy, Array);
   }
 
-  if (const RecordType *RT = T->getAs<RecordType>()) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-    return ::EmitNullConstant(*this, RD, /*complete object*/ true);
-  }
+  if (const RecordType *RT = T->getAs<RecordType>())
+    return ::EmitNullConstant(*this, RT->getDecl(), /*complete object*/ true);
 
   assert(T->isMemberDataPointerType() &&
          "Should only see pointers to data members here!");
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index dc81865..67f821f 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "CodeGenFunction.h"
+#include "CGCleanup.h"
 #include "CGCXXABI.h"
 #include "CGDebugInfo.h"
 #include "CGObjCRuntime.h"
@@ -19,10 +20,12 @@
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
@@ -57,6 +60,59 @@
   return E->getType()->isNullPtrType();
 }
 
+/// If \p E is a widened promoted integer, get its base (unpromoted) type.
+static llvm::Optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx,
+                                                        const Expr *E) {
+  const Expr *Base = E->IgnoreImpCasts();
+  if (E == Base)
+    return llvm::None;
+
+  QualType BaseTy = Base->getType();
+  if (!BaseTy->isPromotableIntegerType() ||
+      Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType()))
+    return llvm::None;
+
+  return BaseTy;
+}
+
+/// Check if \p E is a widened promoted integer.
+static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) {
+  return getUnwidenedIntegerType(Ctx, E).hasValue();
+}
+
+/// Check if we can skip the overflow check for \p Op.
+static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) {
+  assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
+         "Expected a unary or binary operator");
+
+  if (const auto *UO = dyn_cast<UnaryOperator>(Op.E))
+    return IsWidenedIntegerOp(Ctx, UO->getSubExpr());
+
+  const auto *BO = cast<BinaryOperator>(Op.E);
+  auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
+  if (!OptionalLHSTy)
+    return false;
+
+  auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
+  if (!OptionalRHSTy)
+    return false;
+
+  QualType LHSTy = *OptionalLHSTy;
+  QualType RHSTy = *OptionalRHSTy;
+
+  // We usually don't need overflow checks for binary operations with widened
+  // operands. Multiplication with promoted unsigned operands is a special case.
+  if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
+      !LHSTy->isUnsignedIntegerType() || !RHSTy->isUnsignedIntegerType())
+    return true;
+
+  // The overflow check can be skipped if either one of the unpromoted types
+  // are less than half the size of the promoted type.
+  unsigned PromotedSize = Ctx.getTypeSize(Op.E->getType());
+  return (2 * Ctx.getTypeSize(LHSTy)) < PromotedSize ||
+         (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize;
+}
+
 class ScalarExprEmitter
   : public StmtVisitor<ScalarExprEmitter, Value*> {
   CodeGenFunction &CGF;
@@ -171,9 +227,9 @@
   }
 
   /// EmitPointerToBoolConversion - Perform a pointer to boolean conversion.
-  Value *EmitPointerToBoolConversion(Value *V) {
-    Value *Zero = llvm::ConstantPointerNull::get(
-                                      cast<llvm::PointerType>(V->getType()));
+  Value *EmitPointerToBoolConversion(Value *V, QualType QT) {
+    Value *Zero = CGF.CGM.getNullPointer(cast<llvm::PointerType>(V->getType()), QT);
+
     return Builder.CreateICmpNE(V, Zero, "tobool");
   }
 
@@ -299,6 +355,24 @@
     return V;
   }
 
+  Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
+    VersionTuple Version = E->getVersion();
+
+    // If we're checking for a platform older than our minimum deployment
+    // target, we can fold the check away.
+    if (Version <= CGF.CGM.getTarget().getPlatformMinVersion())
+      return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
+
+    Optional<unsigned> Min = Version.getMinor(), SMin = Version.getSubminor();
+    llvm::Value *Args[] = {
+        llvm::ConstantInt::get(CGF.CGM.Int32Ty, Version.getMajor()),
+        llvm::ConstantInt::get(CGF.CGM.Int32Ty, Min ? *Min : 0),
+        llvm::ConstantInt::get(CGF.CGM.Int32Ty, SMin ? *SMin : 0),
+    };
+
+    return CGF.EmitBuiltinAvailable(Args);
+  }
+
   Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
   Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
   Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
@@ -310,6 +384,12 @@
 
   Value *VisitInitListExpr(InitListExpr *E);
 
+  Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
+    assert(CGF.getArrayInitIndex() &&
+           "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
+    return CGF.getArrayInitIndex();
+  }
+
   Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
     return EmitNullValue(E->getType());
   }
@@ -398,11 +478,7 @@
     return CGF.LoadCXXThis();
   }
 
-  Value *VisitExprWithCleanups(ExprWithCleanups *E) {
-    CGF.enterFullExpression(E);
-    CodeGenFunction::RunCleanupsScope Scope(CGF);
-    return Visit(E->getSubExpr());
-  }
+  Value *VisitExprWithCleanups(ExprWithCleanups *E);
   Value *VisitCXXNewExpr(const CXXNewExpr *E) {
     return CGF.EmitCXXNewExpr(E);
   }
@@ -457,12 +533,15 @@
           return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
         // Fall through.
       case LangOptions::SOB_Trapping:
+        if (CanElideOverflowCheck(CGF.getContext(), Ops))
+          return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
         return EmitOverflowCheckedBinOp(Ops);
       }
     }
 
     if (Ops.Ty->isUnsignedIntegerType() &&
-        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow))
+        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
+        !CanElideOverflowCheck(CGF.getContext(), Ops))
       return EmitOverflowCheckedBinOp(Ops);
 
     if (Ops.LHS->getType()->isFPOrFPVectorTy())
@@ -591,7 +670,7 @@
     return EmitIntToBoolConversion(Src);
 
   assert(isa<llvm::PointerType>(Src->getType()));
-  return EmitPointerToBoolConversion(Src);
+  return EmitPointerToBoolConversion(Src, SrcType);
 }
 
 void ScalarExprEmitter::EmitFloatConversionCheck(
@@ -724,7 +803,7 @@
                                   CGF.EmitCheckTypeDescriptor(OrigSrcType),
                                   CGF.EmitCheckTypeDescriptor(DstType)};
   CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
-                "float_cast_overflow", StaticArgs, OrigSrc);
+                SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
 }
 
 /// Emit a conversion from the specified type to the specified destination type,
@@ -927,7 +1006,7 @@
 void ScalarExprEmitter::EmitBinOpCheck(
     ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) {
   assert(CGF.IsSanitizerScope);
-  StringRef CheckName;
+  SanitizerHandler Check;
   SmallVector<llvm::Constant *, 4> StaticData;
   SmallVector<llvm::Value *, 2> DynamicData;
 
@@ -938,13 +1017,13 @@
   StaticData.push_back(CGF.EmitCheckSourceLocation(Info.E->getExprLoc()));
   const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
   if (UO && UO->getOpcode() == UO_Minus) {
-    CheckName = "negate_overflow";
+    Check = SanitizerHandler::NegateOverflow;
     StaticData.push_back(CGF.EmitCheckTypeDescriptor(UO->getType()));
     DynamicData.push_back(Info.RHS);
   } else {
     if (BinaryOperator::isShiftOp(Opcode)) {
       // Shift LHS negative or too large, or RHS out of bounds.
-      CheckName = "shift_out_of_bounds";
+      Check = SanitizerHandler::ShiftOutOfBounds;
       const BinaryOperator *BO = cast<BinaryOperator>(Info.E);
       StaticData.push_back(
         CGF.EmitCheckTypeDescriptor(BO->getLHS()->getType()));
@@ -952,14 +1031,14 @@
         CGF.EmitCheckTypeDescriptor(BO->getRHS()->getType()));
     } else if (Opcode == BO_Div || Opcode == BO_Rem) {
       // Divide or modulo by zero, or signed overflow (eg INT_MAX / -1).
-      CheckName = "divrem_overflow";
+      Check = SanitizerHandler::DivremOverflow;
       StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
     } else {
       // Arithmetic overflow (+, -, *).
       switch (Opcode) {
-      case BO_Add: CheckName = "add_overflow"; break;
-      case BO_Sub: CheckName = "sub_overflow"; break;
-      case BO_Mul: CheckName = "mul_overflow"; break;
+      case BO_Add: Check = SanitizerHandler::AddOverflow; break;
+      case BO_Sub: Check = SanitizerHandler::SubOverflow; break;
+      case BO_Mul: Check = SanitizerHandler::MulOverflow; break;
       default: llvm_unreachable("unexpected opcode for bin op check");
       }
       StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
@@ -968,7 +1047,7 @@
     DynamicData.push_back(Info.RHS);
   }
 
-  CGF.EmitCheck(Checks, CheckName, StaticData, DynamicData);
+  CGF.EmitCheck(Checks, Check, StaticData, DynamicData);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1394,11 +1473,23 @@
     return Builder.CreateBitCast(Src, DstTy);
   }
   case CK_AddressSpaceConversion: {
-    Value *Src = Visit(const_cast<Expr*>(E));
+    Expr::EvalResult Result;
+    if (E->EvaluateAsRValue(Result, CGF.getContext()) &&
+        Result.Val.isNullPointer()) {
+      // If E has side effect, it is emitted even if its final result is a
+      // null pointer. In that case, a DCE pass should be able to
+      // eliminate the useless instructions emitted during translating E.
+      if (Result.HasSideEffects)
+        Visit(E);
+      return CGF.CGM.getNullPointer(cast<llvm::PointerType>(
+          ConvertType(DestTy)), DestTy);
+    }
     // Since target may map different address spaces in AST to the same address
     // space, an address space conversion may end up as a bitcast.
-    return Builder.CreatePointerBitCastOrAddrSpaceCast(Src,
-                                                       ConvertType(DestTy));
+    auto *Src = Visit(E);
+    return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(CGF, Src,
+                                                               E->getType(),
+                                                               DestTy);
   }
   case CK_AtomicToNonAtomic:
   case CK_NonAtomicToAtomic:
@@ -1453,8 +1544,8 @@
     if (MustVisitNullValue(E))
       (void) Visit(E);
 
-    return llvm::ConstantPointerNull::get(
-                               cast<llvm::PointerType>(ConvertType(DestTy)));
+    return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),
+                              DestTy);
 
   case CK_NullToMemberPointer: {
     if (MustVisitNullValue(E))
@@ -1547,7 +1638,7 @@
   case CK_IntegralToBoolean:
     return EmitIntToBoolConversion(Visit(E));
   case CK_PointerToBoolean:
-    return EmitPointerToBoolConversion(Visit(E));
+    return EmitPointerToBoolConversion(Visit(E), E->getType());
   case CK_FloatingToBoolean:
     return EmitFloatToBoolConversion(Visit(E));
   case CK_MemberPointerToBoolean: {
@@ -1574,6 +1665,11 @@
     return llvm::Constant::getNullValue(ConvertType(DestTy));
   }
 
+  case CK_ZeroToOCLQueue: {
+    assert(DestTy->isQueueT() && "CK_ZeroToOCLQueue cast on non queue_t type");
+    return llvm::Constant::getNullValue(ConvertType(DestTy));
+  }
+
   case CK_IntToOCLSampler:
     return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);

 
@@ -1592,6 +1688,16 @@
                               E->getExprLoc());
 }
 
+Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
+  CGF.enterFullExpression(E);
+  CodeGenFunction::RunCleanupsScope Scope(CGF);
+  Value *V = Visit(E->getSubExpr());
+  // Defend against dominance problems caused by jumps out of expression
+  // evaluation through the shared cleanup block.
+  Scope.ForceCleanup({&V});
+  return V;
+}
+
 //===----------------------------------------------------------------------===//
 //                             Unary Operators
 //===----------------------------------------------------------------------===//
@@ -1621,6 +1727,8 @@
       return Builder.CreateNSWAdd(InVal, Amount, Name);
     // Fall through.
   case LangOptions::SOB_Trapping:
+    if (IsWidenedIntegerOp(CGF.getContext(), E->getSubExpr()))
+      return Builder.CreateNSWAdd(InVal, Amount, Name);
     return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, InVal, IsInc));
   }
   llvm_unreachable("Unknown SignedOverflowBehaviorTy");
@@ -2239,8 +2347,10 @@
                                     SanitizerKind::IntegerDivideByZero));
   }
 
+  const auto *BO = cast<BinaryOperator>(Ops.E);
   if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
-      Ops.Ty->hasSignedIntegerRepresentation()) {
+      Ops.Ty->hasSignedIntegerRepresentation() &&
+      !IsWidenedIntegerOp(CGF.getContext(), BO->getLHS())) {
     llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
 
     llvm::Value *IntMin =
@@ -2300,12 +2410,12 @@
 
 Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
   // Rem in C can't be a floating point type: C99 6.5.5p2.
-  if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
+  if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
+       CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
+      Ops.Ty->isIntegerType()) {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
-
-    if (Ops.Ty->isIntegerType())
-      EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
+    EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
   }
 
   if (Ops.Ty->hasUnsignedIntegerRepresentation())
@@ -2592,12 +2702,15 @@
         return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
       // Fall through.
     case LangOptions::SOB_Trapping:
+      if (CanElideOverflowCheck(CGF.getContext(), op))
+        return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
       return EmitOverflowCheckedBinOp(op);
     }
   }
 
   if (op.Ty->isUnsignedIntegerType() &&
-      CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow))
+      CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
+      !CanElideOverflowCheck(CGF.getContext(), op))
     return EmitOverflowCheckedBinOp(op);
 
   if (op.LHS->getType()->isFPOrFPVectorTy()) {
@@ -2623,12 +2736,15 @@
           return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
         // Fall through.
       case LangOptions::SOB_Trapping:
+        if (CanElideOverflowCheck(CGF.getContext(), op))
+          return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
         return EmitOverflowCheckedBinOp(op);
       }
     }
 
     if (op.Ty->isUnsignedIntegerType() &&
-        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow))
+        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
+        !CanElideOverflowCheck(CGF.getContext(), op))
       return EmitOverflowCheckedBinOp(op);
 
     if (op.LHS->getType()->isFPOrFPVectorTy()) {
@@ -2727,8 +2843,8 @@
            isa<llvm::IntegerType>(Ops.LHS->getType())) {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks;
-    llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS);
-    llvm::Value *ValidExponent = Builder.CreateICmpULE(RHS, WidthMinusOne);
+    llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
+    llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
 
     if (SanitizeExponent) {
       Checks.push_back(
@@ -2743,12 +2859,14 @@
       llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
       llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check");
       Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
+      llvm::Value *PromotedWidthMinusOne =
+          (RHS == Ops.RHS) ? WidthMinusOne
+                           : GetWidthMinusOneValue(Ops.LHS, RHS);
       CGF.EmitBlock(CheckShiftBase);
-      llvm::Value *BitsShiftedOff =
-        Builder.CreateLShr(Ops.LHS,
-                           Builder.CreateSub(WidthMinusOne, RHS, "shl.zeros",
-                                             /*NUW*/true, /*NSW*/true),
-                           "shl.check");
+      llvm::Value *BitsShiftedOff = Builder.CreateLShr(
+          Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros",
+                                     /*NUW*/ true, /*NSW*/ true),
+          "shl.check");
       if (CGF.getLangOpts().CPlusPlus) {
         // In C99, we are not permitted to shift a 1 bit into the sign bit.
         // Under C++11's rules, shifting a 1 bit into the sign bit is
@@ -3014,10 +3132,12 @@
     // because the result is altered by the store, i.e., [C99 6.5.16p1]
     // 'An assignment expression has the value of the left operand after
     // the assignment...'.
-    if (LHS.isBitField())
+    if (LHS.isBitField()) {
       CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS);
-    else
+    } else {
+      CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc());
       CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
+    }
   }
 
   // If the result is clearly ignored, return now.
@@ -3303,9 +3423,11 @@
   // safe to evaluate the LHS and RHS unconditionally.
   if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) &&
       isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) {
-    CGF.incrementProfileCounter(E);
-
     llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
+    llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
+
+    CGF.incrementProfileCounter(E, StepV);
+
     llvm::Value *LHS = Visit(lhsExpr);
     llvm::Value *RHS = Visit(rhsExpr);
     if (!LHS) {
diff --git a/lib/CodeGen/CGGPUBuiltin.cpp b/lib/CodeGen/CGGPUBuiltin.cpp
new file mode 100644
index 0000000..48156b1
--- /dev/null
+++ b/lib/CodeGen/CGGPUBuiltin.cpp
@@ -0,0 +1,122 @@
+//===------ CGGPUBuiltin.cpp - Codegen for GPU builtins -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Generates code for built-in GPU calls which are not runtime-specific.
+// (Runtime-specific codegen lives in programming model specific files.)
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "clang/Basic/Builtins.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+static llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
+  llvm::Type *ArgTypes[] = {llvm::Type::getInt8PtrTy(M.getContext()),
+                            llvm::Type::getInt8PtrTy(M.getContext())};
+  llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get(
+      llvm::Type::getInt32Ty(M.getContext()), ArgTypes, false);
+
+  if (auto* F = M.getFunction("vprintf")) {
+    // Our CUDA system header declares vprintf with the right signature, so
+    // nobody else should have been able to declare vprintf with a bogus
+    // signature.
+    assert(F->getFunctionType() == VprintfFuncType);
+    return F;
+  }
+
+  // vprintf doesn't already exist; create a declaration and insert it into the
+  // module.
+  return llvm::Function::Create(
+      VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, "vprintf", &M);
+}
+
+// Transforms a call to printf into a call to the NVPTX vprintf syscall (which
+// isn't particularly special; it's invoked just like a regular function).
+// vprintf takes two args: A format string, and a pointer to a buffer containing
+// the varargs.
+//
+// For example, the call
+//
+//   printf("format string", arg1, arg2, arg3);
+//
+// is converted into something resembling
+//
+//   struct Tmp {
+//     Arg1 a1;
+//     Arg2 a2;
+//     Arg3 a3;
+//   };
+//   char* buf = alloca(sizeof(Tmp));
+//   *(Tmp*)buf = {a1, a2, a3};
+//   vprintf("format string", buf);
+//
+// buf is aligned to the max of {alignof(Arg1), ...}.  Furthermore, each of the
+// args is itself aligned to its preferred alignment.
+//
+// Note that by the time this function runs, E's args have already undergone the
+// standard C vararg promotion (short -> int, float -> double, etc.).
+RValue
+CodeGenFunction::EmitNVPTXDevicePrintfCallExpr(const CallExpr *E,
+                                               ReturnValueSlot ReturnValue) {
+  assert(getTarget().getTriple().isNVPTX());
+  assert(E->getBuiltinCallee() == Builtin::BIprintf);
+  assert(E->getNumArgs() >= 1); // printf always has at least one arg.
+
+  const llvm::DataLayout &DL = CGM.getDataLayout();
+  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
+
+  CallArgList Args;
+  EmitCallArgs(Args,
+               E->getDirectCallee()->getType()->getAs<FunctionProtoType>(),
+               E->arguments(), E->getDirectCallee(),
+               /* ParamsToSkip = */ 0);
+
+  // We don't know how to emit non-scalar varargs.
+  if (std::any_of(Args.begin() + 1, Args.end(),
+                  [](const CallArg &A) { return !A.RV.isScalar(); })) {
+    CGM.ErrorUnsupported(E, "non-scalar arg to printf");
+    return RValue::get(llvm::ConstantInt::get(IntTy, 0));
+  }
+
+  // Construct and fill the args buffer that we'll pass to vprintf.
+  llvm::Value *BufferPtr;
+  if (Args.size() <= 1) {
+    // If there are no args, pass a null pointer to vprintf.
+    BufferPtr = llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(Ctx));
+  } else {
+    llvm::SmallVector<llvm::Type *, 8> ArgTypes;
+    for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I)
+      ArgTypes.push_back(Args[I].RV.getScalarVal()->getType());
+
+    // Using llvm::StructType is correct only because printf doesn't accept
+    // aggregates.  If we had to handle aggregates here, we'd have to manually
+    // compute the offsets within the alloca -- we wouldn't be able to assume
+    // that the alignment of the llvm type was the same as the alignment of the
+    // clang type.
+    llvm::Type *AllocaTy = llvm::StructType::create(ArgTypes, "printf_args");
+    llvm::Value *Alloca = CreateTempAlloca(AllocaTy);
+
+    for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I) {
+      llvm::Value *P = Builder.CreateStructGEP(AllocaTy, Alloca, I - 1);
+      llvm::Value *Arg = Args[I].RV.getScalarVal();
+      Builder.CreateAlignedStore(Arg, P, DL.getPrefTypeAlignment(Arg->getType()));
+    }
+    BufferPtr = Builder.CreatePointerCast(Alloca, llvm::Type::getInt8PtrTy(Ctx));
+  }
+
+  // Invoke vprintf and return.
+  llvm::Function* VprintfFunc = GetVprintfDeclaration(CGM.getModule());
+  return RValue::get(
+      Builder.CreateCall(VprintfFunc, {Args[0].RV.getScalarVal(), BufferPtr}));
+}
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 9aa952d..a67131a 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -1,4 +1,4 @@
-//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
+//===---- CGObjC.cpp - Emit LLVM Code for Objective-C ---------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -427,7 +427,7 @@
   QualType ResultType = method ? method->getReturnType() : E->getType();
 
   CallArgList Args;
-  EmitCallArgs(Args, method, E->arguments());
+  EmitCallArgs(Args, method, E->arguments(), /*AC*/AbstractCallee(method));
 
   // For delegate init calls in ARC, do an unsafe store of null into
   // self.  This represents the call taking direct ownership of that
@@ -1802,25 +1802,49 @@
 }
 
 
-static llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
-                                                llvm::FunctionType *type,
-                                                StringRef fnName) {
-  llvm::Constant *fn = CGM.CreateRuntimeFunction(type, fnName);
+static bool IsForwarding(StringRef Name) {
+  return llvm::StringSwitch<bool>(Name)
+      .Cases("objc_autoreleaseReturnValue",             // ARCInstKind::AutoreleaseRV
+             "objc_autorelease",                        // ARCInstKind::Autorelease
+             "objc_retainAutoreleaseReturnValue",       // ARCInstKind::FusedRetainAutoreleaseRV
+             "objc_retainAutoreleasedReturnValue",      // ARCInstKind::RetainRV
+             "objc_retainAutorelease",                  // ARCInstKind::FusedRetainAutorelease
+             "objc_retainedObject",                     // ARCInstKind::NoopCast
+             "objc_retain",                             // ARCInstKind::Retain
+             "objc_unretainedObject",                   // ARCInstKind::NoopCast
+             "objc_unretainedPointer",                  // ARCInstKind::NoopCast
+             "objc_unsafeClaimAutoreleasedReturnValue", // ARCInstKind::ClaimRV
+             true)
+      .Default(false);
+}
 
-  if (llvm::Function *f = dyn_cast<llvm::Function>(fn)) {
+static llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
+                                                llvm::FunctionType *FTy,
+                                                StringRef Name) {
+  llvm::Constant *RTF = CGM.CreateRuntimeFunction(FTy, Name);
+
+  if (auto *F = dyn_cast<llvm::Function>(RTF)) {
     // If the target runtime doesn't naturally support ARC, emit weak
     // references to the runtime support library.  We don't really
     // permit this to fail, but we need a particular relocation style.
-    if (!CGM.getLangOpts().ObjCRuntime.hasNativeARC()) {
-      f->setLinkage(llvm::Function::ExternalWeakLinkage);
-    } else if (fnName == "objc_retain" || fnName  == "objc_release") {
+    if (!CGM.getLangOpts().ObjCRuntime.hasNativeARC() &&
+        !CGM.getTriple().isOSBinFormatCOFF()) {
+      F->setLinkage(llvm::Function::ExternalWeakLinkage);
+    } else if (Name == "objc_retain" || Name  == "objc_release") {
       // If we have Native ARC, set nonlazybind attribute for these APIs for
       // performance.
-      f->addFnAttr(llvm::Attribute::NonLazyBind);
+      F->addFnAttr(llvm::Attribute::NonLazyBind);
+    }
+
+    if (IsForwarding(Name)) {
+      llvm::AttrBuilder B;
+      B.addAttribute(llvm::Attribute::Returned);
+
+      F->arg_begin()->addAttr(llvm::AttributeSet::get(F->getContext(), 1, B));
     }
   }
 
-  return fn;
+  return RTF;
 }
 
 /// Perform an operation having the signature
@@ -1831,7 +1855,8 @@
                                           llvm::Constant *&fn,
                                           StringRef fnName,
                                           bool isTailCall = false) {
-  if (isa<llvm::ConstantPointerNull>(value)) return value;
+  if (isa<llvm::ConstantPointerNull>(value))
+    return value;
 
   if (!fn) {
     llvm::FunctionType *fnType =
@@ -3374,5 +3399,21 @@
   return Val;
 }
 
+llvm::Value *
+CodeGenFunction::EmitBuiltinAvailable(ArrayRef<llvm::Value *> Args) {
+  assert(Args.size() == 3 && "Expected 3 argument here!");
+
+  if (!CGM.IsOSVersionAtLeastFn) {
+    llvm::FunctionType *FTy =
+        llvm::FunctionType::get(Int32Ty, {Int32Ty, Int32Ty, Int32Ty}, false);
+    CGM.IsOSVersionAtLeastFn =
+        CGM.CreateRuntimeFunction(FTy, "__isOSVersionAtLeast");
+  }
+
+  llvm::Value *CallRes =
+      EmitNounwindRuntimeCall(CGM.IsOSVersionAtLeastFn, Args);
+
+  return Builder.CreateICmpNE(CallRes, llvm::Constant::getNullValue(Int32Ty));
+}
 
 CGObjCRuntime::~CGObjCRuntime() {}
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index fa2b3d8..9f6ccb4 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -18,7 +18,7 @@
 #include "CGCleanup.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
@@ -2207,7 +2207,7 @@
       IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
       // Get the type encoding for this ivar
       std::string TypeStr;
-      Context.getObjCEncodingForType(IVD->getType(), TypeStr);
+      Context.getObjCEncodingForType(IVD->getType(), TypeStr, IVD);
       IvarTypes.push_back(MakeConstantString(TypeStr));
       // Get the offset
       uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 7219592..29b45e3 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -17,7 +17,7 @@
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
diff --git a/lib/CodeGen/CGOpenCLRuntime.cpp b/lib/CodeGen/CGOpenCLRuntime.cpp
index 9062936..db02c63 100644
--- a/lib/CodeGen/CGOpenCLRuntime.cpp
+++ b/lib/CodeGen/CGOpenCLRuntime.cpp
@@ -58,9 +58,6 @@
   case BuiltinType::OCLQueue:
     return llvm::PointerType::get(
         llvm::StructType::create(Ctx, "opencl.queue_t"), 0);
-  case BuiltinType::OCLNDRange:
-    return llvm::PointerType::get(
-        llvm::StructType::create(Ctx, "opencl.ndrange_t"), 0);
   case BuiltinType::OCLReserveID:
     return llvm::PointerType::get(
         llvm::StructType::create(Ctx, "opencl.reserve_id_t"), 0);
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index c03e449..ae9cf9d 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -15,7 +15,7 @@
 #include "CGCleanup.h"
 #include "CGOpenMPRuntime.h"
 #include "CodeGenFunction.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/StmtOpenMP.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -99,10 +99,11 @@
 public:
   CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
                              const RegionCodeGenTy &CodeGen,
-                             OpenMPDirectiveKind Kind, bool HasCancel)
+                             OpenMPDirectiveKind Kind, bool HasCancel,
+                             StringRef HelperName)
       : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
                            HasCancel),
-        ThreadIDVar(ThreadIDVar) {
+        ThreadIDVar(ThreadIDVar), HelperName(HelperName) {
     assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
   }
 
@@ -111,7 +112,7 @@
   const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
 
   /// \brief Get the name of the capture helper.
-  StringRef getHelperName() const override { return ".omp_outlined."; }
+  StringRef getHelperName() const override { return HelperName; }
 
   static bool classof(const CGCapturedStmtInfo *Info) {
     return CGOpenMPRegionInfo::classof(Info) &&
@@ -123,6 +124,7 @@
   /// \brief A variable or parameter storing global thread id for OpenMP
   /// constructs.
   const VarDecl *ThreadIDVar;
+  StringRef HelperName;
 };
 
 /// \brief API for captured statement code generation in OpenMP constructs.
@@ -490,7 +492,7 @@
   OMP_sch_runtime = 37,
   OMP_sch_auto = 38,
   /// static with chunk adjustment (e.g., simd)
-  OMP_sch_static_balanced_chunked   = 45,
+  OMP_sch_static_balanced_chunked = 45,
   /// \brief Lower bound for 'ordered' versions.
   OMP_ord_lower = 64,
   OMP_ord_static_chunked = 65,
@@ -757,6 +759,7 @@
       FnTy, llvm::GlobalValue::InternalLinkage,
       IsCombiner ? ".omp_combiner." : ".omp_initializer.", &CGM.getModule());
   CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo);
+  Fn->removeFnAttr(llvm::Attribute::NoInline);
   Fn->addFnAttr(llvm::Attribute::AlwaysInline);
   CodeGenFunction CGF(CGM);
   // Map "T omp_in;" variable to "*omp_in_parm" value in all expressions.
@@ -839,12 +842,12 @@
   return CGF.Builder.CreateStructGEP(Addr, Field, Offset, Name);
 }
 
-llvm::Value *CGOpenMPRuntime::emitParallelOrTeamsOutlinedFunction(
-    const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
-    OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
+static llvm::Value *emitParallelOrTeamsOutlinedFunction(
+    CodeGenModule &CGM, const OMPExecutableDirective &D, const CapturedStmt *CS,
+    const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind,
+    const StringRef OutlinedHelperName, const RegionCodeGenTy &CodeGen) {
   assert(ThreadIDVar->getType()->isPointerType() &&
          "thread id variable must be of type kmp_int32 *");
-  const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt());
   CodeGenFunction CGF(CGM, true);
   bool HasCancel = false;
   if (auto *OPD = dyn_cast<OMPParallelDirective>(&D))
@@ -854,11 +857,27 @@
   else if (auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
     HasCancel = OPFD->hasCancel();
   CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
-                                    HasCancel);
+                                    HasCancel, OutlinedHelperName);
   CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
   return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
 }
 
+llvm::Value *CGOpenMPRuntime::emitParallelOutlinedFunction(
+    const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
+    OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
+  const CapturedStmt *CS = D.getCapturedStmt(OMPD_parallel);
+  return emitParallelOrTeamsOutlinedFunction(
+      CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
+}
+
+llvm::Value *CGOpenMPRuntime::emitTeamsOutlinedFunction(
+    const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
+    OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
+  const CapturedStmt *CS = D.getCapturedStmt(OMPD_teams);
+  return emitParallelOrTeamsOutlinedFunction(
+      CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
+}
+
 llvm::Value *CGOpenMPRuntime::emitTaskOutlinedFunction(
     const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
     const VarDecl *PartIDVar, const VarDecl *TaskTVar,
@@ -1891,9 +1910,9 @@
 /// } else {
 ///   ElseGen();
 /// }
-static void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
-                            const RegionCodeGenTy &ThenGen,
-                            const RegionCodeGenTy &ElseGen) {
+void CGOpenMPRuntime::emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
+                                      const RegionCodeGenTy &ThenGen,
+                                      const RegionCodeGenTy &ElseGen) {
   CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
 
   // If the condition constant folds and can be elided, try to avoid emitting
@@ -2700,14 +2719,16 @@
                                              "only required for the device "
                                              "code generation.");
   OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
-      OffloadEntryInfoTargetRegion(Order, /*Addr=*/nullptr, /*ID=*/nullptr);
+      OffloadEntryInfoTargetRegion(Order, /*Addr=*/nullptr, /*ID=*/nullptr,
+                                   /*Flags=*/0);
   ++OffloadingEntriesNum;
 }
 
 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
     registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
                                   StringRef ParentName, unsigned LineNum,
-                                  llvm::Constant *Addr, llvm::Constant *ID) {
+                                  llvm::Constant *Addr, llvm::Constant *ID,
+                                  int32_t Flags) {
   // If we are emitting code for a target, the entry is already initialized,
   // only has to be registered.
   if (CGM.getLangOpts().OpenMPIsDevice) {
@@ -2718,9 +2739,10 @@
     assert(Entry.isValid() && "Entry not initialized!");
     Entry.setAddress(Addr);
     Entry.setID(ID);
+    Entry.setFlags(Flags);
     return;
   } else {
-    OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum++, Addr, ID);
+    OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum++, Addr, ID, Flags);
     OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
   }
 }
@@ -2769,7 +2791,6 @@
   Args.push_back(&DummyPtr);
 
   CodeGenFunction CGF(CGM);
-  GlobalDecl();
   auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
   auto FTy = CGM.getTypes().GetFunctionType(FI);
   auto *Fn =
@@ -2888,7 +2909,8 @@
 }
 
 void CGOpenMPRuntime::createOffloadEntry(llvm::Constant *ID,
-                                         llvm::Constant *Addr, uint64_t Size) {
+                                         llvm::Constant *Addr, uint64_t Size,
+                                         int32_t Flags) {
   StringRef Name = Addr->getName();
   auto *TgtOffloadEntryType = cast<llvm::StructType>(
       CGM.getTypes().ConvertTypeForMem(getTgtOffloadEntryQTy()));
@@ -2918,6 +2940,8 @@
   EntryInit.add(AddrPtr);
   EntryInit.add(StrPtr);
   EntryInit.addInt(CGM.SizeTy, Size);
+  EntryInit.addInt(CGM.Int32Ty, Flags);
+  EntryInit.addInt(CGM.Int32Ty, 0);
   llvm::GlobalVariable *Entry =
     EntryInit.finishAndCreateGlobal(".omp_offloading.entry",
                                     Align,
@@ -2930,8 +2954,8 @@
 
 void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
   // Emit the offloading entries and metadata so that the device codegen side
-  // can
-  // easily figure out what to emit. The produced metadata looks like this:
+  // can easily figure out what to emit. The produced metadata looks like
+  // this:
   //
   // !omp_offload.info = !{!1, ...}
   //
@@ -3090,6 +3114,8 @@
   //                          // (function or global)
   //   char      *name;       // Name of the function or global.
   //   size_t     size;       // Size of the entry info (0 if it a function).
+  //   int32_t    flags;      // Flags associated with the entry, e.g. 'link'.
+  //   int32_t    reserved;   // Reserved, to use by the runtime library.
   // };
   if (TgtOffloadEntryQTy.isNull()) {
     ASTContext &C = CGM.getContext();
@@ -3098,6 +3124,10 @@
     addFieldToRecordDecl(C, RD, C.VoidPtrTy);
     addFieldToRecordDecl(C, RD, C.getPointerType(C.CharTy));
     addFieldToRecordDecl(C, RD, C.getSizeType());
+    addFieldToRecordDecl(
+        C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
+    addFieldToRecordDecl(
+        C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
     RD->completeDefinition();
     TgtOffloadEntryQTy = C.getRecordType(RD);
   }
@@ -3473,6 +3503,7 @@
       ".omp_task_privates_map.", &CGM.getModule());
   CGM.SetInternalFunctionAttributes(/*D=*/nullptr, TaskPrivatesMap,
                                     TaskPrivatesMapFnInfo);
+  TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline);
   TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
   CodeGenFunction CGF(CGM);
   CGF.disableDebugInfo();
@@ -3991,8 +4022,8 @@
     DepTaskArgs[5] = CGF.Builder.getInt32(0);
     DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
   }
-  auto &&ThenCodeGen = [this, Loc, &Data, TDBase, KmpTaskTQTyRD,
-                        NumDependencies, &TaskArgs,
+  auto &&ThenCodeGen = [this, &Data, TDBase, KmpTaskTQTyRD, NumDependencies,
+                        &TaskArgs,
                         &DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) {
     if (!Data.Tied) {
       auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
@@ -4226,12 +4257,10 @@
   CGF.EmitIgnoredExpr(ReductionOp);
 }
 
-static llvm::Value *emitReductionFunction(CodeGenModule &CGM,
-                                          llvm::Type *ArgsType,
-                                          ArrayRef<const Expr *> Privates,
-                                          ArrayRef<const Expr *> LHSExprs,
-                                          ArrayRef<const Expr *> RHSExprs,
-                                          ArrayRef<const Expr *> ReductionOps) {
+llvm::Value *CGOpenMPRuntime::emitReductionFunction(
+    CodeGenModule &CGM, llvm::Type *ArgsType, ArrayRef<const Expr *> Privates,
+    ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
+    ArrayRef<const Expr *> ReductionOps) {
   auto &C = CGM.getContext();
 
   // void reduction_func(void *LHSArg, void *RHSArg);
@@ -4314,11 +4343,11 @@
   return Fn;
 }
 
-static void emitSingleReductionCombiner(CodeGenFunction &CGF,
-                                        const Expr *ReductionOp,
-                                        const Expr *PrivateRef,
-                                        const DeclRefExpr *LHS,
-                                        const DeclRefExpr *RHS) {
+void CGOpenMPRuntime::emitSingleReductionCombiner(CodeGenFunction &CGF,
+                                                  const Expr *ReductionOp,
+                                                  const Expr *PrivateRef,
+                                                  const DeclRefExpr *LHS,
+                                                  const DeclRefExpr *RHS) {
   if (PrivateRef->getType()->isArrayType()) {
     // Emit reduction for array section.
     auto *LHSVar = cast<VarDecl>(LHS->getDecl());
@@ -4338,9 +4367,13 @@
                                     ArrayRef<const Expr *> LHSExprs,
                                     ArrayRef<const Expr *> RHSExprs,
                                     ArrayRef<const Expr *> ReductionOps,
-                                    bool WithNowait, bool SimpleReduction) {
+                                    ReductionOptionsTy Options) {
   if (!CGF.HaveInsertPoint())
     return;
+
+  bool WithNowait = Options.WithNowait;
+  bool SimpleReduction = Options.SimpleReduction;
+
   // Next code should be emitted for reduction:
   //
   // static kmp_critical_name lock = { 0 };
@@ -4444,9 +4477,8 @@
   auto *IdentTLoc = emitUpdateLocation(CGF, Loc, OMP_ATOMIC_REDUCE);
   auto *ThreadId = getThreadID(CGF, Loc);
   auto *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy);
-  auto *RL =
-    CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(ReductionList.getPointer(),
-                                                    CGF.VoidPtrTy);
+  auto *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+      ReductionList.getPointer(), CGF.VoidPtrTy);
   llvm::Value *Args[] = {
       IdentTLoc,                             // ident_t *<loc>
       ThreadId,                              // i32 <gtid>
@@ -4483,12 +4515,13 @@
   };
   auto &&CodeGen = [&Privates, &LHSExprs, &RHSExprs, &ReductionOps](
       CodeGenFunction &CGF, PrePostActionTy &Action) {
+    auto &RT = CGF.CGM.getOpenMPRuntime();
     auto IPriv = Privates.begin();
     auto ILHS = LHSExprs.begin();
     auto IRHS = RHSExprs.begin();
     for (auto *E : ReductionOps) {
-      emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
-                                  cast<DeclRefExpr>(*IRHS));
+      RT.emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
+                                     cast<DeclRefExpr>(*IRHS));
       ++IPriv;
       ++ILHS;
       ++IRHS;
@@ -4548,7 +4581,7 @@
       }
       if (XExpr) {
         auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
-        auto &&AtomicRedGen = [BO, VD, IPriv,
+        auto &&AtomicRedGen = [BO, VD,
                                Loc](CodeGenFunction &CGF, const Expr *XExpr,
                                     const Expr *EExpr, const Expr *UpExpr) {
           LValue X = CGF.EmitLValue(XExpr);
@@ -4558,7 +4591,7 @@
           CGF.EmitOMPAtomicSimpleUpdateExpr(
               X, E, BO, /*IsXLHSInRHSPart=*/true,
               llvm::AtomicOrdering::Monotonic, Loc,
-              [&CGF, UpExpr, VD, IPriv, Loc](RValue XRValue) {
+              [&CGF, UpExpr, VD, Loc](RValue XRValue) {
                 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
                 PrivateScope.addPrivate(
                     VD, [&CGF, VD, XRValue, Loc]() -> Address {
@@ -4683,7 +4716,9 @@
   // global_tid, kmp_int32 cncl_kind);
   if (auto *OMPRegionInfo =
           dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
-    if (OMPRegionInfo->hasCancel()) {
+    // For 'cancellation point taskgroup', the task region info may not have a
+    // cancel. This may instead happen in another adjacent task.
+    if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) {
       llvm::Value *Args[] = {
           emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
           CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
@@ -4691,7 +4726,6 @@
       auto *Result = CGF.EmitRuntimeCall(
           createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args);
       // if (__kmpc_cancellationpoint()) {
-      //  __kmpc_cancel_barrier();
       //   exit from construct;
       // }
       auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
@@ -4699,8 +4733,6 @@
       auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
       CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
       CGF.EmitBlock(ExitBB);
-      // __kmpc_cancel_barrier();
-      emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
       // exit from construct;
       auto CancelDest =
           CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
@@ -4729,7 +4761,6 @@
       auto *Result = CGF.EmitRuntimeCall(
           RT.createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
       // if (__kmpc_cancel()) {
-      //  __kmpc_cancel_barrier();
       //   exit from construct;
       // }
       auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
@@ -4737,8 +4768,6 @@
       auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
       CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
       CGF.EmitBlock(ExitBB);
-      // __kmpc_cancel_barrier();
-      RT.emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
       // exit from construct;
       auto CancelDest =
           CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
@@ -4852,7 +4881,8 @@
 
   // Register the information for the entry associated with this target region.
   OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
-      DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID);
+      DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID,
+      /*Flags=*/0);
 }
 
 /// discard all CompoundStmts intervening between two constructs
@@ -4863,25 +4893,45 @@
   return Body;
 }
 
-/// \brief Emit the num_teams clause of an enclosed teams directive at the
-/// target region scope. If there is no teams directive associated with the
-/// target directive, or if there is no num_teams clause associated with the
-/// enclosed teams directive, return nullptr.
+/// Emit the number of teams for a target directive.  Inspect the num_teams
+/// clause associated with a teams construct combined or closely nested
+/// with the target directive.
+///
+/// Emit a team of size one for directives such as 'target parallel' that
+/// have no associated teams construct.
+///
+/// Otherwise, return nullptr.
 static llvm::Value *
-emitNumTeamsClauseForTargetDirective(CGOpenMPRuntime &OMPRuntime,
-                                     CodeGenFunction &CGF,
-                                     const OMPExecutableDirective &D) {
+emitNumTeamsForTargetDirective(CGOpenMPRuntime &OMPRuntime,
+                               CodeGenFunction &CGF,
+                               const OMPExecutableDirective &D) {
 
   assert(!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the "
                                               "teams directive expected to be "
                                               "emitted only for the host!");
 
-  // FIXME: For the moment we do not support combined directives with target and
-  // teams, so we do not expect to get any num_teams clause in the provided
-  // directive. Once we support that, this assertion can be replaced by the
-  // actual emission of the clause expression.
-  assert(D.getSingleClause<OMPNumTeamsClause>() == nullptr &&
-         "Not expecting clause in directive.");
+  auto &Bld = CGF.Builder;
+
+  // If the target directive is combined with a teams directive:
+  //   Return the value in the num_teams clause, if any.
+  //   Otherwise, return 0 to denote the runtime default.
+  if (isOpenMPTeamsDirective(D.getDirectiveKind())) {
+    if (const auto *NumTeamsClause = D.getSingleClause<OMPNumTeamsClause>()) {
+      CodeGenFunction::RunCleanupsScope NumTeamsScope(CGF);
+      auto NumTeams = CGF.EmitScalarExpr(NumTeamsClause->getNumTeams(),
+                                         /*IgnoreResultAssign*/ true);
+      return Bld.CreateIntCast(NumTeams, CGF.Int32Ty,
+                               /*IsSigned=*/true);
+    }
+
+    // The default value is 0.
+    return Bld.getInt32(0);
+  }
+
+  // If the target directive is combined with a parallel directive but not a
+  // teams directive, start one team.
+  if (isOpenMPParallelDirective(D.getDirectiveKind()))
+    return Bld.getInt32(1);
 
   // If the current target region has a teams region enclosed, we need to get
   // the number of teams to pass to the runtime function call. This is done
@@ -4899,38 +4949,92 @@
       CGOpenMPInnerExprInfo CGInfo(CGF, CS);
       CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
       llvm::Value *NumTeams = CGF.EmitScalarExpr(NTE->getNumTeams());
-      return CGF.Builder.CreateIntCast(NumTeams, CGF.Int32Ty,
-                                       /*IsSigned=*/true);
+      return Bld.CreateIntCast(NumTeams, CGF.Int32Ty,
+                               /*IsSigned=*/true);
     }
 
     // If we have an enclosed teams directive but no num_teams clause we use
     // the default value 0.
-    return CGF.Builder.getInt32(0);
+    return Bld.getInt32(0);
   }
 
   // No teams associated with the directive.
   return nullptr;
 }
 
-/// \brief Emit the thread_limit clause of an enclosed teams directive at the
-/// target region scope. If there is no teams directive associated with the
-/// target directive, or if there is no thread_limit clause associated with the
-/// enclosed teams directive, return nullptr.
+/// Emit the number of threads for a target directive.  Inspect the
+/// thread_limit clause associated with a teams construct combined or closely
+/// nested with the target directive.
+///
+/// Emit the num_threads clause for directives such as 'target parallel' that
+/// have no associated teams construct.
+///
+/// Otherwise, return nullptr.
 static llvm::Value *
-emitThreadLimitClauseForTargetDirective(CGOpenMPRuntime &OMPRuntime,
-                                        CodeGenFunction &CGF,
-                                        const OMPExecutableDirective &D) {
+emitNumThreadsForTargetDirective(CGOpenMPRuntime &OMPRuntime,
+                                 CodeGenFunction &CGF,
+                                 const OMPExecutableDirective &D) {
 
   assert(!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the "
                                               "teams directive expected to be "
                                               "emitted only for the host!");
 
-  // FIXME: For the moment we do not support combined directives with target and
-  // teams, so we do not expect to get any thread_limit clause in the provided
-  // directive. Once we support that, this assertion can be replaced by the
-  // actual emission of the clause expression.
-  assert(D.getSingleClause<OMPThreadLimitClause>() == nullptr &&
-         "Not expecting clause in directive.");
+  auto &Bld = CGF.Builder;
+
+  //
+  // If the target directive is combined with a teams directive:
+  //   Return the value in the thread_limit clause, if any.
+  //
+  // If the target directive is combined with a parallel directive:
+  //   Return the value in the num_threads clause, if any.
+  //
+  // If both clauses are set, select the minimum of the two.
+  //
+  // If neither teams or parallel combined directives set the number of threads
+  // in a team, return 0 to denote the runtime default.
+  //
+  // If this is not a teams directive return nullptr.
+
+  if (isOpenMPTeamsDirective(D.getDirectiveKind()) ||
+      isOpenMPParallelDirective(D.getDirectiveKind())) {
+    llvm::Value *DefaultThreadLimitVal = Bld.getInt32(0);
+    llvm::Value *NumThreadsVal = nullptr;
+    llvm::Value *ThreadLimitVal = nullptr;
+
+    if (const auto *ThreadLimitClause =
+            D.getSingleClause<OMPThreadLimitClause>()) {
+      CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
+      auto ThreadLimit = CGF.EmitScalarExpr(ThreadLimitClause->getThreadLimit(),
+                                            /*IgnoreResultAssign*/ true);
+      ThreadLimitVal = Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty,
+                                         /*IsSigned=*/true);
+    }
+
+    if (const auto *NumThreadsClause =
+            D.getSingleClause<OMPNumThreadsClause>()) {
+      CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
+      llvm::Value *NumThreads =
+          CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
+                             /*IgnoreResultAssign*/ true);
+      NumThreadsVal =
+          Bld.CreateIntCast(NumThreads, CGF.Int32Ty, /*IsSigned=*/true);
+    }
+
+    // Select the lesser of thread_limit and num_threads.
+    if (NumThreadsVal)
+      ThreadLimitVal = ThreadLimitVal
+                           ? Bld.CreateSelect(Bld.CreateICmpSLT(NumThreadsVal,
+                                                                ThreadLimitVal),
+                                              NumThreadsVal, ThreadLimitVal)
+                           : NumThreadsVal;
+
+    // Set default value passed to the runtime if either teams or a target
+    // parallel type directive is found but no clause is specified.
+    if (!ThreadLimitVal)
+      ThreadLimitVal = DefaultThreadLimitVal;
+
+    return ThreadLimitVal;
+  }
 
   // If the current target region has a teams region enclosed, we need to get
   // the thread limit to pass to the runtime function call. This is done
@@ -5973,8 +6077,8 @@
                         OffloadError);
 
   // Fill up the pointer arrays and transfer execution to the device.
-  auto &&ThenGen = [&Ctx, &BasePointers, &Pointers, &Sizes, &MapTypes, Device,
-                    OutlinedFnID, OffloadError, OffloadErrorQType,
+  auto &&ThenGen = [&BasePointers, &Pointers, &Sizes, &MapTypes, Device,
+                    OutlinedFnID, OffloadError,
                     &D](CodeGenFunction &CGF, PrePostActionTy &) {
     auto &RT = CGF.CGM.getOpenMPRuntime();
     // Emit the offloading arrays.
@@ -6010,24 +6114,50 @@
     // Return value of the runtime offloading call.
     llvm::Value *Return;
 
-    auto *NumTeams = emitNumTeamsClauseForTargetDirective(RT, CGF, D);
-    auto *ThreadLimit = emitThreadLimitClauseForTargetDirective(RT, CGF, D);
+    auto *NumTeams = emitNumTeamsForTargetDirective(RT, CGF, D);
+    auto *NumThreads = emitNumThreadsForTargetDirective(RT, CGF, D);
 
-    // If we have NumTeams defined this means that we have an enclosed teams
-    // region. Therefore we also expect to have ThreadLimit defined. These two
-    // values should be defined in the presence of a teams directive, regardless
-    // of having any clauses associated. If the user is using teams but no
-    // clauses, these two values will be the default that should be passed to
-    // the runtime library - a 32-bit integer with the value zero.
+    // The target region is an outlined function launched by the runtime
+    // via calls __tgt_target() or __tgt_target_teams().
+    //
+    // __tgt_target() launches a target region with one team and one thread,
+    // executing a serial region.  This master thread may in turn launch
+    // more threads within its team upon encountering a parallel region,
+    // however, no additional teams can be launched on the device.
+    //
+    // __tgt_target_teams() launches a target region with one or more teams,
+    // each with one or more threads.  This call is required for target
+    // constructs such as:
+    //  'target teams'
+    //  'target' / 'teams'
+    //  'target teams distribute parallel for'
+    //  'target parallel'
+    // and so on.
+    //
+    // Note that on the host and CPU targets, the runtime implementation of
+    // these calls simply call the outlined function without forking threads.
+    // The outlined functions themselves have runtime calls to
+    // __kmpc_fork_teams() and __kmpc_fork() for this purpose, codegen'd by
+    // the compiler in emitTeamsCall() and emitParallelCall().
+    //
+    // In contrast, on the NVPTX target, the implementation of
+    // __tgt_target_teams() launches a GPU kernel with the requested number
+    // of teams and threads so no additional calls to the runtime are required.
     if (NumTeams) {
-      assert(ThreadLimit && "Thread limit expression should be available along "
-                            "with number of teams.");
+      // If we have NumTeams defined this means that we have an enclosed teams
+      // region. Therefore we also expect to have NumThreads defined. These two
+      // values should be defined in the presence of a teams directive,
+      // regardless of having any clauses associated. If the user is using teams
+      // but no clauses, these two values will be the default that should be
+      // passed to the runtime library - a 32-bit integer with the value zero.
+      assert(NumThreads && "Thread limit expression should be available along "
+                           "with number of teams.");
       llvm::Value *OffloadingArgs[] = {
           DeviceID,           OutlinedFnID,
           PointerNum,         Info.BasePointersArray,
           Info.PointersArray, Info.SizesArray,
           Info.MapTypesArray, NumTeams,
-          ThreadLimit};
+          NumThreads};
       Return = CGF.EmitRuntimeCall(
           RT.createRuntimeFunction(OMPRTL__tgt_target_teams), OffloadingArgs);
     } else {
@@ -6084,17 +6214,18 @@
   if (!S)
     return;
 
-  // If we find a OMP target directive, codegen the outline function and
-  // register the result.
-  // FIXME: Add other directives with target when they become supported.
-  bool isTargetDirective = isa<OMPTargetDirective>(S);
+  // Codegen OMP target directives that offload compute to the device.
+  bool requiresDeviceCodegen =
+      isa<OMPExecutableDirective>(S) &&
+      isOpenMPTargetExecutionDirective(
+          cast<OMPExecutableDirective>(S)->getDirectiveKind());
 
-  if (isTargetDirective) {
-    auto *E = cast<OMPExecutableDirective>(S);
+  if (requiresDeviceCodegen) {
+    auto &E = *cast<OMPExecutableDirective>(S);
     unsigned DeviceID;
     unsigned FileID;
     unsigned Line;
-    getTargetEntryUniqueInfo(CGM.getContext(), E->getLocStart(), DeviceID,
+    getTargetEntryUniqueInfo(CGM.getContext(), E.getLocStart(), DeviceID,
                              FileID, Line);
 
     // Is this a target region that should not be emitted as an entry point? If
@@ -6103,13 +6234,22 @@
                                                             ParentName, Line))
       return;
 
-    llvm::Function *Fn;
-    llvm::Constant *Addr;
-    std::tie(Fn, Addr) =
-        CodeGenFunction::EmitOMPTargetDirectiveOutlinedFunction(
-            CGM, cast<OMPTargetDirective>(*E), ParentName,
-            /*isOffloadEntry=*/true);
-    assert(Fn && Addr && "Target region emission failed.");
+    switch (S->getStmtClass()) {
+    case Stmt::OMPTargetDirectiveClass:
+      CodeGenFunction::EmitOMPTargetDeviceFunction(
+          CGM, ParentName, cast<OMPTargetDirective>(*S));
+      break;
+    case Stmt::OMPTargetParallelDirectiveClass:
+      CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
+          CGM, ParentName, cast<OMPTargetParallelDirective>(*S));
+      break;
+    case Stmt::OMPTargetTeamsDirectiveClass:
+      CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
+          CGM, ParentName, cast<OMPTargetTeamsDirective>(*S));
+      break;
+    default:
+      llvm_unreachable("Unknown target directive for OpenMP device codegen.");
+    }
     return;
   }
 
@@ -6143,7 +6283,7 @@
   // Try to detect target regions in the function.
   scanForTargetRegionsFunctions(FD.getBody(), CGM.getMangledName(GD));
 
-  // We should not emit any function othen that the ones created during the
+  // We should not emit any function other that the ones created during the
   // scanning. Therefore, we signal that this function is completely dealt
   // with.
   return true;
@@ -6260,8 +6400,8 @@
   // Generate the code for the opening of the data environment. Capture all the
   // arguments of the runtime call by reference because they are used in the
   // closing of the region.
-  auto &&BeginThenGen = [&D, &CGF, Device, &Info, &CodeGen, &NoPrivAction](
-      CodeGenFunction &CGF, PrePostActionTy &) {
+  auto &&BeginThenGen = [&D, Device, &Info, &CodeGen](CodeGenFunction &CGF,
+                                                      PrePostActionTy &) {
     // Fill up the arrays with all the mapped variables.
     MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
     MappableExprsHandler::MapValuesArrayTy Pointers;
@@ -6307,8 +6447,7 @@
   };
 
   // Generate code for the closing of the data region.
-  auto &&EndThenGen = [&CGF, Device, &Info](CodeGenFunction &CGF,
-                                            PrePostActionTy &) {
+  auto &&EndThenGen = [Device, &Info](CodeGenFunction &CGF, PrePostActionTy &) {
     assert(Info.isValid() && "Invalid data environment closing arguments.");
 
     llvm::Value *BasePointersArrayArg = nullptr;
@@ -6386,7 +6525,7 @@
          "Expecting either target enter, exit data, or update directives.");
 
   // Generate the code for the opening of the data environment.
-  auto &&ThenGen = [&D, &CGF, Device](CodeGenFunction &CGF, PrePostActionTy &) {
+  auto &&ThenGen = [&D, Device](CodeGenFunction &CGF, PrePostActionTy &) {
     // Fill up the arrays with all the mapped variables.
     MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
     MappableExprsHandler::MapValuesArrayTy Pointers;
diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h
index 9057e5e..dc62f2b 100644
--- a/lib/CodeGen/CGOpenMPRuntime.h
+++ b/lib/CodeGen/CGOpenMPRuntime.h
@@ -110,9 +110,9 @@
   CodeGenModule &CGM;
 
   /// \brief Creates offloading entry for the provided entry ID \a ID,
-  /// address \a Addr and size \a Size.
+  /// address \a Addr, size \a Size, and flags \a Flags.
   virtual void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr,
-                                  uint64_t Size);
+                                  uint64_t Size, int32_t Flags = 0);
 
   /// \brief Helper to emit outlined function for 'target' directive.
   /// \param D Directive to emit.
@@ -130,6 +130,35 @@
                                                 bool IsOffloadEntry,
                                                 const RegionCodeGenTy &CodeGen);
 
+  /// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
+  /// function. Here is the logic:
+  /// if (Cond) {
+  ///   ThenGen();
+  /// } else {
+  ///   ElseGen();
+  /// }
+  void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
+                       const RegionCodeGenTy &ThenGen,
+                       const RegionCodeGenTy &ElseGen);
+
+  /// \brief Emits object of ident_t type with info for source location.
+  /// \param Flags Flags for OpenMP location.
+  ///
+  llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
+                                  unsigned Flags = 0);
+
+  /// \brief Returns pointer to ident_t type.
+  llvm::Type *getIdentTyPointerTy();
+
+  /// \brief Gets thread id value for the current thread.
+  ///
+  llvm::Value *getThreadID(CodeGenFunction &CGF, SourceLocation Loc);
+
+  /// \brief Get the function name of an outlined region.
+  //  The name can be customized depending on the target.
+  //
+  virtual StringRef getOutlinedHelperName() const { return ".omp_outlined."; }
+
 private:
   /// \brief Default const ident_t object used for initialization of all other
   /// ident_t objects.
@@ -245,10 +274,10 @@
     unsigned OffloadingEntriesNum;
 
   public:
-    /// \brief Base class of the entries info.
+    /// Base class of the entries info.
     class OffloadEntryInfo {
     public:
-      /// \brief Kind of a given entry. Currently, only target regions are
+      /// Kind of a given entry. Currently, only target regions are
       /// supported.
       enum OffloadingEntryInfoKinds : unsigned {
         // Entry is a target region.
@@ -257,17 +286,24 @@
         OFFLOAD_ENTRY_INFO_INVALID = ~0u
       };
 
-      OffloadEntryInfo() : Order(~0u), Kind(OFFLOAD_ENTRY_INFO_INVALID) {}
-      explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order)
-          : Order(Order), Kind(Kind) {}
+      OffloadEntryInfo()
+          : Flags(0), Order(~0u), Kind(OFFLOAD_ENTRY_INFO_INVALID) {}
+      explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order,
+                                int32_t Flags)
+          : Flags(Flags), Order(Order), Kind(Kind) {}
 
       bool isValid() const { return Order != ~0u; }
       unsigned getOrder() const { return Order; }
       OffloadingEntryInfoKinds getKind() const { return Kind; }
+      int32_t getFlags() const { return Flags; }
+      void setFlags(int32_t NewFlags) { Flags = NewFlags; }
       static bool classof(const OffloadEntryInfo *Info) { return true; }
 
-    protected:
-      // \brief Order this entry was emitted.
+    private:
+      /// Flags associated with the device global.
+      int32_t Flags;
+
+      /// Order this entry was emitted.
       unsigned Order;
 
       OffloadingEntryInfoKinds Kind;
@@ -292,12 +328,13 @@
 
     public:
       OffloadEntryInfoTargetRegion()
-          : OffloadEntryInfo(OFFLOAD_ENTRY_INFO_TARGET_REGION, ~0u),
+          : OffloadEntryInfo(OFFLOAD_ENTRY_INFO_TARGET_REGION, ~0u,
+                             /*Flags=*/0),
             Addr(nullptr), ID(nullptr) {}
       explicit OffloadEntryInfoTargetRegion(unsigned Order,
                                             llvm::Constant *Addr,
-                                            llvm::Constant *ID)
-          : OffloadEntryInfo(OFFLOAD_ENTRY_INFO_TARGET_REGION, Order),
+                                            llvm::Constant *ID, int32_t Flags)
+          : OffloadEntryInfo(OFFLOAD_ENTRY_INFO_TARGET_REGION, Order, Flags),
             Addr(Addr), ID(ID) {}
 
       llvm::Constant *getAddress() const { return Addr; }
@@ -321,8 +358,8 @@
     /// \brief Register target region entry.
     void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
                                        StringRef ParentName, unsigned LineNum,
-                                       llvm::Constant *Addr,
-                                       llvm::Constant *ID);
+                                       llvm::Constant *Addr, llvm::Constant *ID,
+                                       int32_t Flags);
     /// \brief Return true if a target region entry with the provided
     /// information exists.
     bool hasTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
@@ -380,15 +417,6 @@
   /// \brief Build type kmp_routine_entry_t (if not built yet).
   void emitKmpRoutineEntryT(QualType KmpInt32Ty);
 
-  /// \brief Emits object of ident_t type with info for source location.
-  /// \param Flags Flags for OpenMP location.
-  ///
-  llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
-                                  unsigned Flags = 0);
-
-  /// \brief Returns pointer to ident_t type.
-  llvm::Type *getIdentTyPointerTy();
-
   /// \brief Returns pointer to kmpc_micro type.
   llvm::Type *getKmpc_MicroPointerTy();
 
@@ -424,10 +452,6 @@
   /// stored.
   virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc);
 
-  /// \brief Gets thread id value for the current thread.
-  ///
-  llvm::Value *getThreadID(CodeGenFunction &CGF, SourceLocation Loc);
-
   /// \brief Gets (if variable with the given name already exist) or creates
   /// internal global variable with the specified Name. The created variable has
   /// linkage CommonLinkage by default and is initialized by null value.
@@ -503,6 +527,7 @@
   /// Get combiner/initializer for the specified user-defined reduction, if any.
   virtual std::pair<llvm::Function *, llvm::Function *>
   getUserDefinedReduction(const OMPDeclareReductionDecl *D);
+
   /// \brief Emits outlined function for the specified OpenMP parallel directive
   /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
   /// kmp_int32 BoundID, struct context_vars*).
@@ -511,7 +536,19 @@
   /// \param InnermostKind Kind of innermost directive (for simple directives it
   /// is a directive itself, for combined - its innermost directive).
   /// \param CodeGen Code generation sequence for the \a D directive.
-  virtual llvm::Value *emitParallelOrTeamsOutlinedFunction(
+  virtual llvm::Value *emitParallelOutlinedFunction(
+      const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
+      OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
+
+  /// \brief Emits outlined function for the specified OpenMP teams directive
+  /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
+  /// kmp_int32 BoundID, struct context_vars*).
+  /// \param D OpenMP directive.
+  /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
+  /// \param InnermostKind Kind of innermost directive (for simple directives it
+  /// is a directive itself, for combined - its innermost directive).
+  /// \param CodeGen Code generation sequence for the \a D directive.
+  virtual llvm::Value *emitTeamsOutlinedFunction(
       const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
       OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
 
@@ -856,6 +893,32 @@
                                     OpenMPDirectiveKind InnermostKind,
                                     const RegionCodeGenTy &CodeGen,
                                     bool HasCancel = false);
+
+  /// Emits reduction function.
+  /// \param ArgsType Array type containing pointers to reduction variables.
+  /// \param Privates List of private copies for original reduction arguments.
+  /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
+  /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
+  /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
+  /// or 'operator binop(LHS, RHS)'.
+  llvm::Value *emitReductionFunction(CodeGenModule &CGM, llvm::Type *ArgsType,
+                                     ArrayRef<const Expr *> Privates,
+                                     ArrayRef<const Expr *> LHSExprs,
+                                     ArrayRef<const Expr *> RHSExprs,
+                                     ArrayRef<const Expr *> ReductionOps);
+
+  /// Emits single reduction combiner
+  void emitSingleReductionCombiner(CodeGenFunction &CGF,
+                                   const Expr *ReductionOp,
+                                   const Expr *PrivateRef,
+                                   const DeclRefExpr *LHS,
+                                   const DeclRefExpr *RHS);
+
+  struct ReductionOptionsTy {
+    bool WithNowait;
+    bool SimpleReduction;
+    OpenMPDirectiveKind ReductionKind;
+  };
   /// \brief Emit a code for reduction clause. Next code should be emitted for
   /// reduction:
   /// \code
@@ -892,14 +955,18 @@
   /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
   /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
   /// or 'operator binop(LHS, RHS)'.
-  /// \param WithNowait true if parent directive has also nowait clause, false
-  /// otherwise.
+  /// \param Options List of options for reduction codegen:
+  ///     WithNowait true if parent directive has also nowait clause, false
+  ///     otherwise.
+  ///     SimpleReduction Emit reduction operation only. Used for omp simd
+  ///     directive on the host.
+  ///     ReductionKind The kind of reduction to perform.
   virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
                              ArrayRef<const Expr *> Privates,
                              ArrayRef<const Expr *> LHSExprs,
                              ArrayRef<const Expr *> RHSExprs,
                              ArrayRef<const Expr *> ReductionOps,
-                             bool WithNowait, bool SimpleReduction);
+                             ReductionOptionsTy Options);
 
   /// \brief Emit code for 'taskwait' directive.
   virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc);
diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index d64f6df..c3391d0 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -20,53 +20,226 @@
 using namespace clang;
 using namespace CodeGen;
 
-/// \brief Get the GPU warp size.
-llvm::Value *CGOpenMPRuntimeNVPTX::getNVPTXWarpSize(CodeGenFunction &CGF) {
+namespace {
+enum OpenMPRTLFunctionNVPTX {
+  /// \brief Call to void __kmpc_kernel_init(kmp_int32 thread_limit);
+  OMPRTL_NVPTX__kmpc_kernel_init,
+  /// \brief Call to void __kmpc_kernel_deinit();
+  OMPRTL_NVPTX__kmpc_kernel_deinit,
+  /// \brief Call to void __kmpc_spmd_kernel_init(kmp_int32 thread_limit,
+  /// short RequiresOMPRuntime, short RequiresDataSharing);
+  OMPRTL_NVPTX__kmpc_spmd_kernel_init,
+  /// \brief Call to void __kmpc_spmd_kernel_deinit();
+  OMPRTL_NVPTX__kmpc_spmd_kernel_deinit,
+  /// \brief Call to void __kmpc_kernel_prepare_parallel(void
+  /// *outlined_function);
+  OMPRTL_NVPTX__kmpc_kernel_prepare_parallel,
+  /// \brief Call to bool __kmpc_kernel_parallel(void **outlined_function);
+  OMPRTL_NVPTX__kmpc_kernel_parallel,
+  /// \brief Call to void __kmpc_kernel_end_parallel();
+  OMPRTL_NVPTX__kmpc_kernel_end_parallel,
+  /// Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
+  /// global_tid);
+  OMPRTL_NVPTX__kmpc_serialized_parallel,
+  /// Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
+  /// global_tid);
+  OMPRTL_NVPTX__kmpc_end_serialized_parallel,
+  /// \brief Call to int32_t __kmpc_shuffle_int32(int32_t element,
+  /// int16_t lane_offset, int16_t warp_size);
+  OMPRTL_NVPTX__kmpc_shuffle_int32,
+  /// \brief Call to int64_t __kmpc_shuffle_int64(int64_t element,
+  /// int16_t lane_offset, int16_t warp_size);
+  OMPRTL_NVPTX__kmpc_shuffle_int64,
+  /// \brief Call to __kmpc_nvptx_parallel_reduce_nowait(kmp_int32
+  /// global_tid, kmp_int32 num_vars, size_t reduce_size, void* reduce_data,
+  /// void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t lane_id, int16_t
+  /// lane_offset, int16_t shortCircuit),
+  /// void (*kmp_InterWarpCopyFctPtr)(void* src, int32_t warp_num));
+  OMPRTL_NVPTX__kmpc_parallel_reduce_nowait,
+  /// \brief Call to __kmpc_nvptx_teams_reduce_nowait(int32_t global_tid,
+  /// int32_t num_vars, size_t reduce_size, void *reduce_data,
+  /// void (*kmp_ShuffleReductFctPtr)(void *rhs, int16_t lane_id, int16_t
+  /// lane_offset, int16_t shortCircuit),
+  /// void (*kmp_InterWarpCopyFctPtr)(void* src, int32_t warp_num),
+  /// void (*kmp_CopyToScratchpadFctPtr)(void *reduce_data, void * scratchpad,
+  /// int32_t index, int32_t width),
+  /// void (*kmp_LoadReduceFctPtr)(void *reduce_data, void * scratchpad, int32_t
+  /// index, int32_t width, int32_t reduce))
+  OMPRTL_NVPTX__kmpc_teams_reduce_nowait,
+  /// \brief Call to __kmpc_nvptx_end_reduce_nowait(int32_t global_tid);
+  OMPRTL_NVPTX__kmpc_end_reduce_nowait
+};
+
+/// Pre(post)-action for different OpenMP constructs specialized for NVPTX.
+class NVPTXActionTy final : public PrePostActionTy {
+  llvm::Value *EnterCallee;
+  ArrayRef<llvm::Value *> EnterArgs;
+  llvm::Value *ExitCallee;
+  ArrayRef<llvm::Value *> ExitArgs;
+  bool Conditional;
+  llvm::BasicBlock *ContBlock = nullptr;
+
+public:
+  NVPTXActionTy(llvm::Value *EnterCallee, ArrayRef<llvm::Value *> EnterArgs,
+                llvm::Value *ExitCallee, ArrayRef<llvm::Value *> ExitArgs,
+                bool Conditional = false)
+      : EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
+        ExitArgs(ExitArgs), Conditional(Conditional) {}
+  void Enter(CodeGenFunction &CGF) override {
+    llvm::Value *EnterRes = CGF.EmitRuntimeCall(EnterCallee, EnterArgs);
+    if (Conditional) {
+      llvm::Value *CallBool = CGF.Builder.CreateIsNotNull(EnterRes);
+      auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
+      ContBlock = CGF.createBasicBlock("omp_if.end");
+      // Generate the branch (If-stmt)
+      CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
+      CGF.EmitBlock(ThenBlock);
+    }
+  }
+  void Done(CodeGenFunction &CGF) {
+    // Emit the rest of blocks/branches
+    CGF.EmitBranch(ContBlock);
+    CGF.EmitBlock(ContBlock, true);
+  }
+  void Exit(CodeGenFunction &CGF) override {
+    CGF.EmitRuntimeCall(ExitCallee, ExitArgs);
+  }
+};
+
+// A class to track the execution mode when codegening directives within
+// a target region. The appropriate mode (generic/spmd) is set on entry
+// to the target region and used by containing directives such as 'parallel'
+// to emit optimized code.
+class ExecutionModeRAII {
+private:
+  CGOpenMPRuntimeNVPTX::ExecutionMode SavedMode;
+  CGOpenMPRuntimeNVPTX::ExecutionMode &Mode;
+
+public:
+  ExecutionModeRAII(CGOpenMPRuntimeNVPTX::ExecutionMode &Mode,
+                    CGOpenMPRuntimeNVPTX::ExecutionMode NewMode)
+      : Mode(Mode) {
+    SavedMode = Mode;
+    Mode = NewMode;
+  }
+  ~ExecutionModeRAII() { Mode = SavedMode; }
+};
+
+/// GPU Configuration:  This information can be derived from cuda registers,
+/// however, providing compile time constants helps generate more efficient
+/// code.  For all practical purposes this is fine because the configuration
+/// is the same for all known NVPTX architectures.
+enum MachineConfiguration : unsigned {
+  WarpSize = 32,
+  /// Number of bits required to represent a lane identifier, which is
+  /// computed as log_2(WarpSize).
+  LaneIDBits = 5,
+  LaneIDMask = WarpSize - 1,
+
+  /// Global memory alignment for performance.
+  GlobalMemoryAlignment = 256,
+};
+
+enum NamedBarrier : unsigned {
+  /// Synchronize on this barrier #ID using a named barrier primitive.
+  /// Only the subset of active threads in a parallel region arrive at the
+  /// barrier.
+  NB_Parallel = 1,
+};
+} // anonymous namespace
+
+/// Get the GPU warp size.
+static llvm::Value *getNVPTXWarpSize(CodeGenFunction &CGF) {
   CGBuilderTy &Bld = CGF.Builder;
   return Bld.CreateCall(
       llvm::Intrinsic::getDeclaration(
-          &CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_warpsize),
+          &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_warpsize),
       llvm::None, "nvptx_warp_size");
 }
 
-/// \brief Get the id of the current thread on the GPU.
-llvm::Value *CGOpenMPRuntimeNVPTX::getNVPTXThreadID(CodeGenFunction &CGF) {
+/// Get the id of the current thread on the GPU.
+static llvm::Value *getNVPTXThreadID(CodeGenFunction &CGF) {
   CGBuilderTy &Bld = CGF.Builder;
   return Bld.CreateCall(
       llvm::Intrinsic::getDeclaration(
-          &CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_tid_x),
+          &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_tid_x),
       llvm::None, "nvptx_tid");
 }
 
-// \brief Get the maximum number of threads in a block of the GPU.
-llvm::Value *CGOpenMPRuntimeNVPTX::getNVPTXNumThreads(CodeGenFunction &CGF) {
+/// Get the id of the warp in the block.
+/// We assume that the warp size is 32, which is always the case
+/// on the NVPTX device, to generate more efficient code.
+static llvm::Value *getNVPTXWarpID(CodeGenFunction &CGF) {
+  CGBuilderTy &Bld = CGF.Builder;
+  return Bld.CreateAShr(getNVPTXThreadID(CGF), LaneIDBits, "nvptx_warp_id");
+}
+
+/// Get the id of the current lane in the Warp.
+/// We assume that the warp size is 32, which is always the case
+/// on the NVPTX device, to generate more efficient code.
+static llvm::Value *getNVPTXLaneID(CodeGenFunction &CGF) {
+  CGBuilderTy &Bld = CGF.Builder;
+  return Bld.CreateAnd(getNVPTXThreadID(CGF), Bld.getInt32(LaneIDMask),
+                       "nvptx_lane_id");
+}
+
+/// Get the maximum number of threads in a block of the GPU.
+static llvm::Value *getNVPTXNumThreads(CodeGenFunction &CGF) {
   CGBuilderTy &Bld = CGF.Builder;
   return Bld.CreateCall(
       llvm::Intrinsic::getDeclaration(
-          &CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_ntid_x),
+          &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_ntid_x),
       llvm::None, "nvptx_num_threads");
 }
 
-/// \brief Get barrier to synchronize all threads in a block.
-void CGOpenMPRuntimeNVPTX::getNVPTXCTABarrier(CodeGenFunction &CGF) {
+/// Get barrier to synchronize all threads in a block.
+static void getNVPTXCTABarrier(CodeGenFunction &CGF) {
   CGBuilderTy &Bld = CGF.Builder;
   Bld.CreateCall(llvm::Intrinsic::getDeclaration(
-      &CGM.getModule(), llvm::Intrinsic::nvvm_barrier0));
+      &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_barrier0));
 }
 
-// \brief Synchronize all GPU threads in a block.
-void CGOpenMPRuntimeNVPTX::syncCTAThreads(CodeGenFunction &CGF) {
-  getNVPTXCTABarrier(CGF);
+/// Get barrier #ID to synchronize selected (multiple of warp size) threads in
+/// a CTA.
+static void getNVPTXBarrier(CodeGenFunction &CGF, int ID,
+                            llvm::Value *NumThreads) {
+  CGBuilderTy &Bld = CGF.Builder;
+  llvm::Value *Args[] = {Bld.getInt32(ID), NumThreads};
+  Bld.CreateCall(llvm::Intrinsic::getDeclaration(&CGF.CGM.getModule(),
+                                                 llvm::Intrinsic::nvvm_barrier),
+                 Args);
 }
 
-/// \brief Get the thread id of the OMP master thread.
+/// Synchronize all GPU threads in a block.
+static void syncCTAThreads(CodeGenFunction &CGF) { getNVPTXCTABarrier(CGF); }
+
+/// Synchronize worker threads in a parallel region.
+static void syncParallelThreads(CodeGenFunction &CGF, llvm::Value *NumThreads) {
+  return getNVPTXBarrier(CGF, NB_Parallel, NumThreads);
+}
+
+/// Get the value of the thread_limit clause in the teams directive.
+/// For the 'generic' execution mode, the runtime encodes thread_limit in
+/// the launch parameters, always starting thread_limit+warpSize threads per
+/// CTA. The threads in the last warp are reserved for master execution.
+/// For the 'spmd' execution mode, all threads in a CTA are part of the team.
+static llvm::Value *getThreadLimit(CodeGenFunction &CGF,
+                                   bool IsInSpmdExecutionMode = false) {
+  CGBuilderTy &Bld = CGF.Builder;
+  return IsInSpmdExecutionMode
+             ? getNVPTXNumThreads(CGF)
+             : Bld.CreateSub(getNVPTXNumThreads(CGF), getNVPTXWarpSize(CGF),
+                             "thread_limit");
+}
+
+/// Get the thread id of the OMP master thread.
 /// The master thread id is the first thread (lane) of the last warp in the
 /// GPU block.  Warp size is assumed to be some power of 2.
 /// Thread id is 0 indexed.
 /// E.g: If NumThreads is 33, master id is 32.
 ///      If NumThreads is 64, master id is 32.
 ///      If NumThreads is 1024, master id is 992.
-llvm::Value *CGOpenMPRuntimeNVPTX::getMasterThreadID(CodeGenFunction &CGF) {
+static llvm::Value *getMasterThreadID(CodeGenFunction &CGF) {
   CGBuilderTy &Bld = CGF.Builder;
   llvm::Value *NumThreads = getNVPTXNumThreads(CGF);
 
@@ -77,19 +250,6 @@
                        Bld.CreateNot(Mask), "master_tid");
 }
 
-namespace {
-enum OpenMPRTLFunctionNVPTX {
-  /// \brief Call to void __kmpc_kernel_init(kmp_int32 omp_handle,
-  /// kmp_int32 thread_limit);
-  OMPRTL_NVPTX__kmpc_kernel_init,
-};
-
-// NVPTX Address space
-enum ADDRESS_SPACE {
-  ADDRESS_SPACE_SHARED = 3,
-};
-} // namespace
-
 CGOpenMPRuntimeNVPTX::WorkerFunctionState::WorkerFunctionState(
     CodeGenModule &CGM)
     : WorkerFn(nullptr), CGFI(nullptr) {
@@ -105,35 +265,216 @@
       CGM.getTypes().GetFunctionType(*CGFI), llvm::GlobalValue::InternalLinkage,
       /* placeholder */ "_worker", &CGM.getModule());
   CGM.SetInternalFunctionAttributes(/*D=*/nullptr, WorkerFn, *CGFI);
-  WorkerFn->setLinkage(llvm::GlobalValue::InternalLinkage);
-  WorkerFn->addFnAttr(llvm::Attribute::NoInline);
 }
 
-void CGOpenMPRuntimeNVPTX::initializeEnvironment() {
-  //
-  // Initialize master-worker control state in shared memory.
-  //
+bool CGOpenMPRuntimeNVPTX::isInSpmdExecutionMode() const {
+  return CurrentExecutionMode == CGOpenMPRuntimeNVPTX::ExecutionMode::Spmd;
+}
 
-  auto DL = CGM.getDataLayout();
-  ActiveWorkers = new llvm::GlobalVariable(
-      CGM.getModule(), CGM.Int32Ty, /*isConstant=*/false,
-      llvm::GlobalValue::CommonLinkage,
-      llvm::Constant::getNullValue(CGM.Int32Ty), "__omp_num_threads", 0,
-      llvm::GlobalVariable::NotThreadLocal, ADDRESS_SPACE_SHARED);
-  ActiveWorkers->setAlignment(DL.getPrefTypeAlignment(CGM.Int32Ty));
+static CGOpenMPRuntimeNVPTX::ExecutionMode
+getExecutionModeForDirective(CodeGenModule &CGM,
+                             const OMPExecutableDirective &D) {
+  OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
+  switch (DirectiveKind) {
+  case OMPD_target:
+  case OMPD_target_teams:
+    return CGOpenMPRuntimeNVPTX::ExecutionMode::Generic;
+  case OMPD_target_parallel:
+    return CGOpenMPRuntimeNVPTX::ExecutionMode::Spmd;
+  default:
+    llvm_unreachable("Unsupported directive on NVPTX device.");
+  }
+  llvm_unreachable("Unsupported directive on NVPTX device.");
+}
 
-  WorkID = new llvm::GlobalVariable(
-      CGM.getModule(), CGM.Int64Ty, /*isConstant=*/false,
-      llvm::GlobalValue::CommonLinkage,
-      llvm::Constant::getNullValue(CGM.Int64Ty), "__tgt_work_id", 0,
-      llvm::GlobalVariable::NotThreadLocal, ADDRESS_SPACE_SHARED);
-  WorkID->setAlignment(DL.getPrefTypeAlignment(CGM.Int64Ty));
+void CGOpenMPRuntimeNVPTX::emitGenericKernel(const OMPExecutableDirective &D,
+                                             StringRef ParentName,
+                                             llvm::Function *&OutlinedFn,
+                                             llvm::Constant *&OutlinedFnID,
+                                             bool IsOffloadEntry,
+                                             const RegionCodeGenTy &CodeGen) {
+  ExecutionModeRAII ModeRAII(CurrentExecutionMode,
+                             CGOpenMPRuntimeNVPTX::ExecutionMode::Generic);
+  EntryFunctionState EST;
+  WorkerFunctionState WST(CGM);
+  Work.clear();
+
+  // Emit target region as a standalone region.
+  class NVPTXPrePostActionTy : public PrePostActionTy {
+    CGOpenMPRuntimeNVPTX &RT;
+    CGOpenMPRuntimeNVPTX::EntryFunctionState &EST;
+    CGOpenMPRuntimeNVPTX::WorkerFunctionState &WST;
+
+  public:
+    NVPTXPrePostActionTy(CGOpenMPRuntimeNVPTX &RT,
+                         CGOpenMPRuntimeNVPTX::EntryFunctionState &EST,
+                         CGOpenMPRuntimeNVPTX::WorkerFunctionState &WST)
+        : RT(RT), EST(EST), WST(WST) {}
+    void Enter(CodeGenFunction &CGF) override {
+      RT.emitGenericEntryHeader(CGF, EST, WST);
+    }
+    void Exit(CodeGenFunction &CGF) override {
+      RT.emitGenericEntryFooter(CGF, EST);
+    }
+  } Action(*this, EST, WST);
+  CodeGen.setAction(Action);
+  emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
+                                   IsOffloadEntry, CodeGen);
+
+  // Create the worker function
+  emitWorkerFunction(WST);
+
+  // Now change the name of the worker function to correspond to this target
+  // region's entry function.
+  WST.WorkerFn->setName(OutlinedFn->getName() + "_worker");
+}
+
+// Setup NVPTX threads for master-worker OpenMP scheme.
+void CGOpenMPRuntimeNVPTX::emitGenericEntryHeader(CodeGenFunction &CGF,
+                                                  EntryFunctionState &EST,
+                                                  WorkerFunctionState &WST) {
+  CGBuilderTy &Bld = CGF.Builder;
+
+  llvm::BasicBlock *WorkerBB = CGF.createBasicBlock(".worker");
+  llvm::BasicBlock *MasterCheckBB = CGF.createBasicBlock(".mastercheck");
+  llvm::BasicBlock *MasterBB = CGF.createBasicBlock(".master");
+  EST.ExitBB = CGF.createBasicBlock(".exit");
+
+  auto *IsWorker =
+      Bld.CreateICmpULT(getNVPTXThreadID(CGF), getThreadLimit(CGF));
+  Bld.CreateCondBr(IsWorker, WorkerBB, MasterCheckBB);
+
+  CGF.EmitBlock(WorkerBB);
+  CGF.EmitCallOrInvoke(WST.WorkerFn, llvm::None);
+  CGF.EmitBranch(EST.ExitBB);
+
+  CGF.EmitBlock(MasterCheckBB);
+  auto *IsMaster =
+      Bld.CreateICmpEQ(getNVPTXThreadID(CGF), getMasterThreadID(CGF));
+  Bld.CreateCondBr(IsMaster, MasterBB, EST.ExitBB);
+
+  CGF.EmitBlock(MasterBB);
+  // First action in sequential region:
+  // Initialize the state of the OpenMP runtime library on the GPU.
+  llvm::Value *Args[] = {getThreadLimit(CGF)};
+  CGF.EmitRuntimeCall(
+      createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_init), Args);
+}
+
+void CGOpenMPRuntimeNVPTX::emitGenericEntryFooter(CodeGenFunction &CGF,
+                                                  EntryFunctionState &EST) {
+  if (!EST.ExitBB)
+    EST.ExitBB = CGF.createBasicBlock(".exit");
+
+  llvm::BasicBlock *TerminateBB = CGF.createBasicBlock(".termination.notifier");
+  CGF.EmitBranch(TerminateBB);
+
+  CGF.EmitBlock(TerminateBB);
+  // Signal termination condition.
+  CGF.EmitRuntimeCall(
+      createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_deinit), None);
+  // Barrier to terminate worker threads.
+  syncCTAThreads(CGF);
+  // Master thread jumps to exit point.
+  CGF.EmitBranch(EST.ExitBB);
+
+  CGF.EmitBlock(EST.ExitBB);
+  EST.ExitBB = nullptr;
+}
+
+void CGOpenMPRuntimeNVPTX::emitSpmdKernel(const OMPExecutableDirective &D,
+                                          StringRef ParentName,
+                                          llvm::Function *&OutlinedFn,
+                                          llvm::Constant *&OutlinedFnID,
+                                          bool IsOffloadEntry,
+                                          const RegionCodeGenTy &CodeGen) {
+  ExecutionModeRAII ModeRAII(CurrentExecutionMode,
+                             CGOpenMPRuntimeNVPTX::ExecutionMode::Spmd);
+  EntryFunctionState EST;
+
+  // Emit target region as a standalone region.
+  class NVPTXPrePostActionTy : public PrePostActionTy {
+    CGOpenMPRuntimeNVPTX &RT;
+    CGOpenMPRuntimeNVPTX::EntryFunctionState &EST;
+    const OMPExecutableDirective &D;
+
+  public:
+    NVPTXPrePostActionTy(CGOpenMPRuntimeNVPTX &RT,
+                         CGOpenMPRuntimeNVPTX::EntryFunctionState &EST,
+                         const OMPExecutableDirective &D)
+        : RT(RT), EST(EST), D(D) {}
+    void Enter(CodeGenFunction &CGF) override {
+      RT.emitSpmdEntryHeader(CGF, EST, D);
+    }
+    void Exit(CodeGenFunction &CGF) override {
+      RT.emitSpmdEntryFooter(CGF, EST);
+    }
+  } Action(*this, EST, D);
+  CodeGen.setAction(Action);
+  emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
+                                   IsOffloadEntry, CodeGen);
+  return;
+}
+
+void CGOpenMPRuntimeNVPTX::emitSpmdEntryHeader(
+    CodeGenFunction &CGF, EntryFunctionState &EST,
+    const OMPExecutableDirective &D) {
+  auto &Bld = CGF.Builder;
+
+  // Setup BBs in entry function.
+  llvm::BasicBlock *ExecuteBB = CGF.createBasicBlock(".execute");
+  EST.ExitBB = CGF.createBasicBlock(".exit");
+
+  // Initialize the OMP state in the runtime; called by all active threads.
+  // TODO: Set RequiresOMPRuntime and RequiresDataSharing parameters
+  // based on code analysis of the target region.
+  llvm::Value *Args[] = {getThreadLimit(CGF, /*IsInSpmdExecutionMode=*/true),
+                         /*RequiresOMPRuntime=*/Bld.getInt16(1),
+                         /*RequiresDataSharing=*/Bld.getInt16(1)};
+  CGF.EmitRuntimeCall(
+      createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_spmd_kernel_init), Args);
+  CGF.EmitBranch(ExecuteBB);
+
+  CGF.EmitBlock(ExecuteBB);
+}
+
+void CGOpenMPRuntimeNVPTX::emitSpmdEntryFooter(CodeGenFunction &CGF,
+                                               EntryFunctionState &EST) {
+  if (!EST.ExitBB)
+    EST.ExitBB = CGF.createBasicBlock(".exit");
+
+  llvm::BasicBlock *OMPDeInitBB = CGF.createBasicBlock(".omp.deinit");
+  CGF.EmitBranch(OMPDeInitBB);
+
+  CGF.EmitBlock(OMPDeInitBB);
+  // DeInitialize the OMP state in the runtime; called by all active threads.
+  CGF.EmitRuntimeCall(
+      createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_spmd_kernel_deinit), None);
+  CGF.EmitBranch(EST.ExitBB);
+
+  CGF.EmitBlock(EST.ExitBB);
+  EST.ExitBB = nullptr;
+}
+
+// Create a unique global variable to indicate the execution mode of this target
+// region. The execution mode is either 'generic', or 'spmd' depending on the
+// target directive. This variable is picked up by the offload library to setup
+// the device appropriately before kernel launch. If the execution mode is
+// 'generic', the runtime reserves one warp for the master, otherwise, all
+// warps participate in parallel work.
+static void setPropertyExecutionMode(CodeGenModule &CGM, StringRef Name,
+                                     CGOpenMPRuntimeNVPTX::ExecutionMode Mode) {
+  (void)new llvm::GlobalVariable(
+      CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
+      llvm::GlobalValue::WeakAnyLinkage,
+      llvm::ConstantInt::get(CGM.Int8Ty, Mode), Name + Twine("_exec_mode"));
 }
 
 void CGOpenMPRuntimeNVPTX::emitWorkerFunction(WorkerFunctionState &WST) {
   auto &Ctx = CGM.getContext();
 
   CodeGenFunction CGF(CGM, /*suppressNewContext=*/true);
+  CGF.disableDebugInfo();
   CGF.StartFunction(GlobalDecl(), Ctx.VoidTy, WST.WorkerFn, *WST.CGFI, {});
   emitWorkerLoop(CGF, WST);
   CGF.FinishFunction();
@@ -165,28 +506,68 @@
   CGF.EmitBlock(AwaitBB);
   // Wait for parallel work
   syncCTAThreads(CGF);
+
+  Address WorkFn =
+      CGF.CreateDefaultAlignTempAlloca(CGF.Int8PtrTy, /*Name=*/"work_fn");
+  Address ExecStatus =
+      CGF.CreateDefaultAlignTempAlloca(CGF.Int8Ty, /*Name=*/"exec_status");
+  CGF.InitTempAlloca(ExecStatus, Bld.getInt8(/*C=*/0));
+  CGF.InitTempAlloca(WorkFn, llvm::Constant::getNullValue(CGF.Int8PtrTy));
+
+  llvm::Value *Args[] = {WorkFn.getPointer()};
+  llvm::Value *Ret = CGF.EmitRuntimeCall(
+      createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_parallel), Args);
+  Bld.CreateStore(Bld.CreateZExt(Ret, CGF.Int8Ty), ExecStatus);
+
   // On termination condition (workid == 0), exit loop.
-  llvm::Value *ShouldTerminate = Bld.CreateICmpEQ(
-      Bld.CreateAlignedLoad(WorkID, WorkID->getAlignment()),
-      llvm::Constant::getNullValue(WorkID->getType()->getElementType()),
-      "should_terminate");
+  llvm::Value *ShouldTerminate =
+      Bld.CreateIsNull(Bld.CreateLoad(WorkFn), "should_terminate");
   Bld.CreateCondBr(ShouldTerminate, ExitBB, SelectWorkersBB);
 
   // Activate requested workers.
   CGF.EmitBlock(SelectWorkersBB);
-  llvm::Value *ThreadID = getNVPTXThreadID(CGF);
-  llvm::Value *ActiveThread = Bld.CreateICmpSLT(
-      ThreadID,
-      Bld.CreateAlignedLoad(ActiveWorkers, ActiveWorkers->getAlignment()),
-      "active_thread");
-  Bld.CreateCondBr(ActiveThread, ExecuteBB, BarrierBB);
+  llvm::Value *IsActive =
+      Bld.CreateIsNotNull(Bld.CreateLoad(ExecStatus), "is_active");
+  Bld.CreateCondBr(IsActive, ExecuteBB, BarrierBB);
 
   // Signal start of parallel region.
   CGF.EmitBlock(ExecuteBB);
-  // TODO: Add parallel work.
+
+  // Process work items: outlined parallel functions.
+  for (auto *W : Work) {
+    // Try to match this outlined function.
+    auto *ID = Bld.CreatePointerBitCastOrAddrSpaceCast(W, CGM.Int8PtrTy);
+
+    llvm::Value *WorkFnMatch =
+        Bld.CreateICmpEQ(Bld.CreateLoad(WorkFn), ID, "work_match");
+
+    llvm::BasicBlock *ExecuteFNBB = CGF.createBasicBlock(".execute.fn");
+    llvm::BasicBlock *CheckNextBB = CGF.createBasicBlock(".check.next");
+    Bld.CreateCondBr(WorkFnMatch, ExecuteFNBB, CheckNextBB);
+
+    // Execute this outlined function.
+    CGF.EmitBlock(ExecuteFNBB);
+
+    // Insert call to work function.
+    // FIXME: Pass arguments to outlined function from master thread.
+    auto *Fn = cast<llvm::Function>(W);
+    Address ZeroAddr =
+        CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, /*Name=*/".zero.addr");
+    CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C=*/0));
+    llvm::Value *FnArgs[] = {ZeroAddr.getPointer(), ZeroAddr.getPointer()};
+    CGF.EmitCallOrInvoke(Fn, FnArgs);
+
+    // Go to end of parallel region.
+    CGF.EmitBranch(TerminateBB);
+
+    CGF.EmitBlock(CheckNextBB);
+  }
 
   // Signal end of parallel region.
   CGF.EmitBlock(TerminateBB);
+  CGF.EmitRuntimeCall(
+      createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_end_parallel),
+      llvm::None);
   CGF.EmitBranch(BarrierBB);
 
   // All active and inactive workers wait at a barrier after parallel region.
@@ -199,68 +580,6 @@
   CGF.EmitBlock(ExitBB);
 }
 
-// Setup NVPTX threads for master-worker OpenMP scheme.
-void CGOpenMPRuntimeNVPTX::emitEntryHeader(CodeGenFunction &CGF,
-                                           EntryFunctionState &EST,
-                                           WorkerFunctionState &WST) {
-  CGBuilderTy &Bld = CGF.Builder;
-
-  // Get the master thread id.
-  llvm::Value *MasterID = getMasterThreadID(CGF);
-  // Current thread's identifier.
-  llvm::Value *ThreadID = getNVPTXThreadID(CGF);
-
-  // Setup BBs in entry function.
-  llvm::BasicBlock *WorkerCheckBB = CGF.createBasicBlock(".check.for.worker");
-  llvm::BasicBlock *WorkerBB = CGF.createBasicBlock(".worker");
-  llvm::BasicBlock *MasterBB = CGF.createBasicBlock(".master");
-  EST.ExitBB = CGF.createBasicBlock(".exit");
-
-  // The head (master thread) marches on while its body of companion threads in
-  // the warp go to sleep.
-  llvm::Value *ShouldDie =
-      Bld.CreateICmpUGT(ThreadID, MasterID, "excess_in_master_warp");
-  Bld.CreateCondBr(ShouldDie, EST.ExitBB, WorkerCheckBB);
-
-  // Select worker threads...
-  CGF.EmitBlock(WorkerCheckBB);
-  llvm::Value *IsWorker = Bld.CreateICmpULT(ThreadID, MasterID, "is_worker");
-  Bld.CreateCondBr(IsWorker, WorkerBB, MasterBB);
-
-  // ... and send to worker loop, awaiting parallel invocation.
-  CGF.EmitBlock(WorkerBB);
-  CGF.EmitCallOrInvoke(WST.WorkerFn, llvm::None);
-  CGF.EmitBranch(EST.ExitBB);
-
-  // Only master thread executes subsequent serial code.
-  CGF.EmitBlock(MasterBB);
-
-  // First action in sequential region:
-  // Initialize the state of the OpenMP runtime library on the GPU.
-  llvm::Value *Args[] = {Bld.getInt32(/*OmpHandle=*/0), getNVPTXThreadID(CGF)};
-  CGF.EmitRuntimeCall(createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_init),
-                      Args);
-}
-
-void CGOpenMPRuntimeNVPTX::emitEntryFooter(CodeGenFunction &CGF,
-                                           EntryFunctionState &EST) {
-  CGBuilderTy &Bld = CGF.Builder;
-  llvm::BasicBlock *TerminateBB = CGF.createBasicBlock(".termination.notifier");
-  CGF.EmitBranch(TerminateBB);
-
-  CGF.EmitBlock(TerminateBB);
-  // Signal termination condition.
-  Bld.CreateAlignedStore(
-      llvm::Constant::getNullValue(WorkID->getType()->getElementType()), WorkID,
-      WorkID->getAlignment());
-  // Barrier to terminate worker threads.
-  syncCTAThreads(CGF);
-  // Master thread jumps to exit point.
-  CGF.EmitBranch(EST.ExitBB);
-
-  CGF.EmitBlock(EST.ExitBB);
-}
-
 /// \brief Returns specified OpenMP runtime function for the current OpenMP
 /// implementation.  Specialized for the NVPTX device.
 /// \param Function OpenMP runtime function.
@@ -270,21 +589,183 @@
   llvm::Constant *RTLFn = nullptr;
   switch (static_cast<OpenMPRTLFunctionNVPTX>(Function)) {
   case OMPRTL_NVPTX__kmpc_kernel_init: {
-    // Build void __kmpc_kernel_init(kmp_int32 omp_handle,
-    // kmp_int32 thread_limit);
-    llvm::Type *TypeParams[] = {CGM.Int32Ty, CGM.Int32Ty};
+    // Build void __kmpc_kernel_init(kmp_int32 thread_limit);
+    llvm::Type *TypeParams[] = {CGM.Int32Ty};
     llvm::FunctionType *FnTy =
         llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_init");
     break;
   }
+  case OMPRTL_NVPTX__kmpc_kernel_deinit: {
+    // Build void __kmpc_kernel_deinit();
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, llvm::None, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_deinit");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_spmd_kernel_init: {
+    // Build void __kmpc_spmd_kernel_init(kmp_int32 thread_limit,
+    // short RequiresOMPRuntime, short RequiresDataSharing);
+    llvm::Type *TypeParams[] = {CGM.Int32Ty, CGM.Int16Ty, CGM.Int16Ty};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_spmd_kernel_init");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_spmd_kernel_deinit: {
+    // Build void __kmpc_spmd_kernel_deinit();
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, llvm::None, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_spmd_kernel_deinit");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_kernel_prepare_parallel: {
+    /// Build void __kmpc_kernel_prepare_parallel(
+    /// void *outlined_function);
+    llvm::Type *TypeParams[] = {CGM.Int8PtrTy};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_prepare_parallel");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_kernel_parallel: {
+    /// Build bool __kmpc_kernel_parallel(void **outlined_function);
+    llvm::Type *TypeParams[] = {CGM.Int8PtrPtrTy};
+    llvm::Type *RetTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(RetTy, TypeParams, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_parallel");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_kernel_end_parallel: {
+    /// Build void __kmpc_kernel_end_parallel();
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, llvm::None, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_end_parallel");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_serialized_parallel: {
+    // Build void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
+    // global_tid);
+    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_serialized_parallel");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_end_serialized_parallel: {
+    // Build void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
+    // global_tid);
+    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_serialized_parallel");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_shuffle_int32: {
+    // Build int32_t __kmpc_shuffle_int32(int32_t element,
+    // int16_t lane_offset, int16_t warp_size);
+    llvm::Type *TypeParams[] = {CGM.Int32Ty, CGM.Int16Ty, CGM.Int16Ty};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_shuffle_int32");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_shuffle_int64: {
+    // Build int64_t __kmpc_shuffle_int64(int64_t element,
+    // int16_t lane_offset, int16_t warp_size);
+    llvm::Type *TypeParams[] = {CGM.Int64Ty, CGM.Int16Ty, CGM.Int16Ty};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.Int64Ty, TypeParams, /*isVarArg*/ false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_shuffle_int64");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_parallel_reduce_nowait: {
+    // Build int32_t kmpc_nvptx_parallel_reduce_nowait(kmp_int32 global_tid,
+    // kmp_int32 num_vars, size_t reduce_size, void* reduce_data,
+    // void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t lane_id, int16_t
+    // lane_offset, int16_t Algorithm Version),
+    // void (*kmp_InterWarpCopyFctPtr)(void* src, int warp_num));
+    llvm::Type *ShuffleReduceTypeParams[] = {CGM.VoidPtrTy, CGM.Int16Ty,
+                                             CGM.Int16Ty, CGM.Int16Ty};
+    auto *ShuffleReduceFnTy =
+        llvm::FunctionType::get(CGM.VoidTy, ShuffleReduceTypeParams,
+                                /*isVarArg=*/false);
+    llvm::Type *InterWarpCopyTypeParams[] = {CGM.VoidPtrTy, CGM.Int32Ty};
+    auto *InterWarpCopyFnTy =
+        llvm::FunctionType::get(CGM.VoidTy, InterWarpCopyTypeParams,
+                                /*isVarArg=*/false);
+    llvm::Type *TypeParams[] = {CGM.Int32Ty,
+                                CGM.Int32Ty,
+                                CGM.SizeTy,
+                                CGM.VoidPtrTy,
+                                ShuffleReduceFnTy->getPointerTo(),
+                                InterWarpCopyFnTy->getPointerTo()};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
+    RTLFn = CGM.CreateRuntimeFunction(
+        FnTy, /*Name=*/"__kmpc_nvptx_parallel_reduce_nowait");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_teams_reduce_nowait: {
+    // Build int32_t __kmpc_nvptx_teams_reduce_nowait(int32_t global_tid,
+    // int32_t num_vars, size_t reduce_size, void *reduce_data,
+    // void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t lane_id, int16_t
+    // lane_offset, int16_t shortCircuit),
+    // void (*kmp_InterWarpCopyFctPtr)(void* src, int32_t warp_num),
+    // void (*kmp_CopyToScratchpadFctPtr)(void *reduce_data, void * scratchpad,
+    // int32_t index, int32_t width),
+    // void (*kmp_LoadReduceFctPtr)(void *reduce_data, void * scratchpad,
+    // int32_t index, int32_t width, int32_t reduce))
+    llvm::Type *ShuffleReduceTypeParams[] = {CGM.VoidPtrTy, CGM.Int16Ty,
+                                             CGM.Int16Ty, CGM.Int16Ty};
+    auto *ShuffleReduceFnTy =
+        llvm::FunctionType::get(CGM.VoidTy, ShuffleReduceTypeParams,
+                                /*isVarArg=*/false);
+    llvm::Type *InterWarpCopyTypeParams[] = {CGM.VoidPtrTy, CGM.Int32Ty};
+    auto *InterWarpCopyFnTy =
+        llvm::FunctionType::get(CGM.VoidTy, InterWarpCopyTypeParams,
+                                /*isVarArg=*/false);
+    llvm::Type *CopyToScratchpadTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy,
+                                                CGM.Int32Ty, CGM.Int32Ty};
+    auto *CopyToScratchpadFnTy =
+        llvm::FunctionType::get(CGM.VoidTy, CopyToScratchpadTypeParams,
+                                /*isVarArg=*/false);
+    llvm::Type *LoadReduceTypeParams[] = {
+        CGM.VoidPtrTy, CGM.VoidPtrTy, CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty};
+    auto *LoadReduceFnTy =
+        llvm::FunctionType::get(CGM.VoidTy, LoadReduceTypeParams,
+                                /*isVarArg=*/false);
+    llvm::Type *TypeParams[] = {CGM.Int32Ty,
+                                CGM.Int32Ty,
+                                CGM.SizeTy,
+                                CGM.VoidPtrTy,
+                                ShuffleReduceFnTy->getPointerTo(),
+                                InterWarpCopyFnTy->getPointerTo(),
+                                CopyToScratchpadFnTy->getPointerTo(),
+                                LoadReduceFnTy->getPointerTo()};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
+    RTLFn = CGM.CreateRuntimeFunction(
+        FnTy, /*Name=*/"__kmpc_nvptx_teams_reduce_nowait");
+    break;
+  }
+  case OMPRTL_NVPTX__kmpc_end_reduce_nowait: {
+    // Build __kmpc_end_reduce_nowait(kmp_int32 global_tid);
+    llvm::Type *TypeParams[] = {CGM.Int32Ty};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
+    RTLFn = CGM.CreateRuntimeFunction(
+        FnTy, /*Name=*/"__kmpc_nvptx_end_reduce_nowait");
+    break;
+  }
   }
   return RTLFn;
 }
 
 void CGOpenMPRuntimeNVPTX::createOffloadEntry(llvm::Constant *ID,
                                               llvm::Constant *Addr,
-                                              uint64_t Size) {
+                                              uint64_t Size, int32_t) {
   auto *F = dyn_cast<llvm::Function>(Addr);
   // TODO: Add support for global variables on the device after declare target
   // support.
@@ -313,44 +794,51 @@
 
   assert(!ParentName.empty() && "Invalid target region parent name!");
 
-  EntryFunctionState EST;
-  WorkerFunctionState WST(CGM);
+  CGOpenMPRuntimeNVPTX::ExecutionMode Mode =
+      getExecutionModeForDirective(CGM, D);
+  switch (Mode) {
+  case CGOpenMPRuntimeNVPTX::ExecutionMode::Generic:
+    emitGenericKernel(D, ParentName, OutlinedFn, OutlinedFnID, IsOffloadEntry,
+                      CodeGen);
+    break;
+  case CGOpenMPRuntimeNVPTX::ExecutionMode::Spmd:
+    emitSpmdKernel(D, ParentName, OutlinedFn, OutlinedFnID, IsOffloadEntry,
+                   CodeGen);
+    break;
+  case CGOpenMPRuntimeNVPTX::ExecutionMode::Unknown:
+    llvm_unreachable(
+        "Unknown programming model for OpenMP directive on NVPTX target.");
+  }
 
-  // Emit target region as a standalone region.
-  class NVPTXPrePostActionTy : public PrePostActionTy {
-    CGOpenMPRuntimeNVPTX &RT;
-    CGOpenMPRuntimeNVPTX::EntryFunctionState &EST;
-    CGOpenMPRuntimeNVPTX::WorkerFunctionState &WST;
-
-  public:
-    NVPTXPrePostActionTy(CGOpenMPRuntimeNVPTX &RT,
-                         CGOpenMPRuntimeNVPTX::EntryFunctionState &EST,
-                         CGOpenMPRuntimeNVPTX::WorkerFunctionState &WST)
-        : RT(RT), EST(EST), WST(WST) {}
-    void Enter(CodeGenFunction &CGF) override {
-      RT.emitEntryHeader(CGF, EST, WST);
-    }
-    void Exit(CodeGenFunction &CGF) override { RT.emitEntryFooter(CGF, EST); }
-  } Action(*this, EST, WST);
-  CodeGen.setAction(Action);
-  emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
-                                   IsOffloadEntry, CodeGen);
-
-  // Create the worker function
-  emitWorkerFunction(WST);
-
-  // Now change the name of the worker function to correspond to this target
-  // region's entry function.
-  WST.WorkerFn->setName(OutlinedFn->getName() + "_worker");
+  setPropertyExecutionMode(CGM, OutlinedFn->getName(), Mode);
 }
 
 CGOpenMPRuntimeNVPTX::CGOpenMPRuntimeNVPTX(CodeGenModule &CGM)
-    : CGOpenMPRuntime(CGM), ActiveWorkers(nullptr), WorkID(nullptr) {
+    : CGOpenMPRuntime(CGM), CurrentExecutionMode(ExecutionMode::Unknown) {
   if (!CGM.getLangOpts().OpenMPIsDevice)
     llvm_unreachable("OpenMP NVPTX can only handle device code.");
+}
 
-  // Called once per module during initialization.
-  initializeEnvironment();
+void CGOpenMPRuntimeNVPTX::emitProcBindClause(CodeGenFunction &CGF,
+                                              OpenMPProcBindClauseKind ProcBind,
+                                              SourceLocation Loc) {
+  // Do nothing in case of Spmd mode and L0 parallel.
+  // TODO: If in Spmd mode and L1 parallel emit the clause.
+  if (isInSpmdExecutionMode())
+    return;
+
+  CGOpenMPRuntime::emitProcBindClause(CGF, ProcBind, Loc);
+}
+
+void CGOpenMPRuntimeNVPTX::emitNumThreadsClause(CodeGenFunction &CGF,
+                                                llvm::Value *NumThreads,
+                                                SourceLocation Loc) {
+  // Do nothing in case of Spmd mode and L0 parallel.
+  // TODO: If in Spmd mode and L1 parallel emit the clause.
+  if (isInSpmdExecutionMode())
+    return;
+
+  CGOpenMPRuntime::emitNumThreadsClause(CGF, NumThreads, Loc);
 }
 
 void CGOpenMPRuntimeNVPTX::emitNumTeamsClause(CodeGenFunction &CGF,
@@ -358,20 +846,22 @@
                                               const Expr *ThreadLimit,
                                               SourceLocation Loc) {}
 
-llvm::Value *CGOpenMPRuntimeNVPTX::emitParallelOrTeamsOutlinedFunction(
+llvm::Value *CGOpenMPRuntimeNVPTX::emitParallelOutlinedFunction(
+    const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
+    OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
+  return CGOpenMPRuntime::emitParallelOutlinedFunction(D, ThreadIDVar,
+                                                       InnermostKind, CodeGen);
+}
+
+llvm::Value *CGOpenMPRuntimeNVPTX::emitTeamsOutlinedFunction(
     const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
     OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
 
-  llvm::Function *OutlinedFun = nullptr;
-  if (isa<OMPTeamsDirective>(D)) {
-    llvm::Value *OutlinedFunVal =
-        CGOpenMPRuntime::emitParallelOrTeamsOutlinedFunction(
-            D, ThreadIDVar, InnermostKind, CodeGen);
-    OutlinedFun = cast<llvm::Function>(OutlinedFunVal);
-    OutlinedFun->addFnAttr(llvm::Attribute::AlwaysInline);
-  } else
-    llvm_unreachable("parallel directive is not yet supported for nvptx "
-                     "backend.");
+  llvm::Value *OutlinedFunVal = CGOpenMPRuntime::emitTeamsOutlinedFunction(
+      D, ThreadIDVar, InnermostKind, CodeGen);
+  llvm::Function *OutlinedFun = cast<llvm::Function>(OutlinedFunVal);
+  OutlinedFun->removeFnAttr(llvm::Attribute::NoInline);
+  OutlinedFun->addFnAttr(llvm::Attribute::AlwaysInline);
 
   return OutlinedFun;
 }
@@ -394,3 +884,1369 @@
   OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
   CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs);
 }
+
+void CGOpenMPRuntimeNVPTX::emitParallelCall(
+    CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+    ArrayRef<llvm::Value *> CapturedVars, const Expr *IfCond) {
+  if (!CGF.HaveInsertPoint())
+    return;
+
+  if (isInSpmdExecutionMode())
+    emitSpmdParallelCall(CGF, Loc, OutlinedFn, CapturedVars, IfCond);
+  else
+    emitGenericParallelCall(CGF, Loc, OutlinedFn, CapturedVars, IfCond);
+}
+
+void CGOpenMPRuntimeNVPTX::emitGenericParallelCall(
+    CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+    ArrayRef<llvm::Value *> CapturedVars, const Expr *IfCond) {
+  llvm::Function *Fn = cast<llvm::Function>(OutlinedFn);
+
+  auto &&L0ParallelGen = [this, Fn](CodeGenFunction &CGF, PrePostActionTy &) {
+    CGBuilderTy &Bld = CGF.Builder;
+
+    // Prepare for parallel region. Indicate the outlined function.
+    llvm::Value *Args[] = {Bld.CreateBitOrPointerCast(Fn, CGM.Int8PtrTy)};
+    CGF.EmitRuntimeCall(
+        createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_prepare_parallel),
+        Args);
+
+    // Activate workers. This barrier is used by the master to signal
+    // work for the workers.
+    syncCTAThreads(CGF);
+
+    // OpenMP [2.5, Parallel Construct, p.49]
+    // There is an implied barrier at the end of a parallel region. After the
+    // end of a parallel region, only the master thread of the team resumes
+    // execution of the enclosing task region.
+    //
+    // The master waits at this barrier until all workers are done.
+    syncCTAThreads(CGF);
+
+    // Remember for post-processing in worker loop.
+    Work.push_back(Fn);
+  };
+
+  auto *RTLoc = emitUpdateLocation(CGF, Loc);
+  auto *ThreadID = getThreadID(CGF, Loc);
+  llvm::Value *Args[] = {RTLoc, ThreadID};
+
+  auto &&SeqGen = [this, Fn, &CapturedVars, &Args](CodeGenFunction &CGF,
+                                                   PrePostActionTy &) {
+    auto &&CodeGen = [this, Fn, &CapturedVars](CodeGenFunction &CGF,
+                                               PrePostActionTy &Action) {
+      Action.Enter(CGF);
+
+      llvm::SmallVector<llvm::Value *, 16> OutlinedFnArgs;
+      OutlinedFnArgs.push_back(
+          llvm::ConstantPointerNull::get(CGM.Int32Ty->getPointerTo()));
+      OutlinedFnArgs.push_back(
+          llvm::ConstantPointerNull::get(CGM.Int32Ty->getPointerTo()));
+      OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
+      CGF.EmitCallOrInvoke(Fn, OutlinedFnArgs);
+    };
+
+    RegionCodeGenTy RCG(CodeGen);
+    NVPTXActionTy Action(
+        createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_serialized_parallel),
+        Args,
+        createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_end_serialized_parallel),
+        Args);
+    RCG.setAction(Action);
+    RCG(CGF);
+  };
+
+  if (IfCond)
+    emitOMPIfClause(CGF, IfCond, L0ParallelGen, SeqGen);
+  else {
+    CodeGenFunction::RunCleanupsScope Scope(CGF);
+    RegionCodeGenTy ThenRCG(L0ParallelGen);
+    ThenRCG(CGF);
+  }
+}
+
+void CGOpenMPRuntimeNVPTX::emitSpmdParallelCall(
+    CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+    ArrayRef<llvm::Value *> CapturedVars, const Expr *IfCond) {
+  // Just call the outlined function to execute the parallel region.
+  // OutlinedFn(&GTid, &zero, CapturedStruct);
+  //
+  // TODO: Do something with IfCond when support for the 'if' clause
+  // is added on Spmd target directives.
+  llvm::SmallVector<llvm::Value *, 16> OutlinedFnArgs;
+  OutlinedFnArgs.push_back(
+      llvm::ConstantPointerNull::get(CGM.Int32Ty->getPointerTo()));
+  OutlinedFnArgs.push_back(
+      llvm::ConstantPointerNull::get(CGM.Int32Ty->getPointerTo()));
+  OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
+  CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs);
+}
+
+/// This function creates calls to one of two shuffle functions to copy
+/// variables between lanes in a warp.
+static llvm::Value *createRuntimeShuffleFunction(CodeGenFunction &CGF,
+                                                 QualType ElemTy,
+                                                 llvm::Value *Elem,
+                                                 llvm::Value *Offset) {
+  auto &CGM = CGF.CGM;
+  auto &C = CGM.getContext();
+  auto &Bld = CGF.Builder;
+  CGOpenMPRuntimeNVPTX &RT =
+      *(static_cast<CGOpenMPRuntimeNVPTX *>(&CGM.getOpenMPRuntime()));
+
+  unsigned Size = CGM.getContext().getTypeSizeInChars(ElemTy).getQuantity();
+  assert(Size <= 8 && "Unsupported bitwidth in shuffle instruction.");
+
+  OpenMPRTLFunctionNVPTX ShuffleFn = Size <= 4
+                                         ? OMPRTL_NVPTX__kmpc_shuffle_int32
+                                         : OMPRTL_NVPTX__kmpc_shuffle_int64;
+
+  // Cast all types to 32- or 64-bit values before calling shuffle routines.
+  auto CastTy = Size <= 4 ? CGM.Int32Ty : CGM.Int64Ty;
+  auto *ElemCast = Bld.CreateSExtOrBitCast(Elem, CastTy);
+  auto *WarpSize = CGF.EmitScalarConversion(
+      getNVPTXWarpSize(CGF), C.getIntTypeForBitwidth(32, /* Signed */ true),
+      C.getIntTypeForBitwidth(16, /* Signed */ true), SourceLocation());
+
+  auto *ShuffledVal =
+      CGF.EmitRuntimeCall(RT.createNVPTXRuntimeFunction(ShuffleFn),
+                          {ElemCast, Offset, WarpSize});
+
+  return Bld.CreateTruncOrBitCast(ShuffledVal, CGF.ConvertTypeForMem(ElemTy));
+}
+
+namespace {
+enum CopyAction : unsigned {
+  // RemoteLaneToThread: Copy over a Reduce list from a remote lane in
+  // the warp using shuffle instructions.
+  RemoteLaneToThread,
+  // ThreadCopy: Make a copy of a Reduce list on the thread's stack.
+  ThreadCopy,
+  // ThreadToScratchpad: Copy a team-reduced array to the scratchpad.
+  ThreadToScratchpad,
+  // ScratchpadToThread: Copy from a scratchpad array in global memory
+  // containing team-reduced data to a thread's stack.
+  ScratchpadToThread,
+};
+} // namespace
+
+struct CopyOptionsTy {
+  llvm::Value *RemoteLaneOffset;
+  llvm::Value *ScratchpadIndex;
+  llvm::Value *ScratchpadWidth;
+};
+
+/// Emit instructions to copy a Reduce list, which contains partially
+/// aggregated values, in the specified direction.
+static void emitReductionListCopy(
+    CopyAction Action, CodeGenFunction &CGF, QualType ReductionArrayTy,
+    ArrayRef<const Expr *> Privates, Address SrcBase, Address DestBase,
+    CopyOptionsTy CopyOptions = {nullptr, nullptr, nullptr}) {
+
+  auto &CGM = CGF.CGM;
+  auto &C = CGM.getContext();
+  auto &Bld = CGF.Builder;
+
+  auto *RemoteLaneOffset = CopyOptions.RemoteLaneOffset;
+  auto *ScratchpadIndex = CopyOptions.ScratchpadIndex;
+  auto *ScratchpadWidth = CopyOptions.ScratchpadWidth;
+
+  // Iterates, element-by-element, through the source Reduce list and
+  // make a copy.
+  unsigned Idx = 0;
+  unsigned Size = Privates.size();
+  for (auto &Private : Privates) {
+    Address SrcElementAddr = Address::invalid();
+    Address DestElementAddr = Address::invalid();
+    Address DestElementPtrAddr = Address::invalid();
+    // Should we shuffle in an element from a remote lane?
+    bool ShuffleInElement = false;
+    // Set to true to update the pointer in the dest Reduce list to a
+    // newly created element.
+    bool UpdateDestListPtr = false;
+    // Increment the src or dest pointer to the scratchpad, for each
+    // new element.
+    bool IncrScratchpadSrc = false;
+    bool IncrScratchpadDest = false;
+
+    switch (Action) {
+    case RemoteLaneToThread: {
+      // Step 1.1: Get the address for the src element in the Reduce list.
+      Address SrcElementPtrAddr =
+          Bld.CreateConstArrayGEP(SrcBase, Idx, CGF.getPointerSize());
+      llvm::Value *SrcElementPtrPtr = CGF.EmitLoadOfScalar(
+          SrcElementPtrAddr, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
+      SrcElementAddr =
+          Address(SrcElementPtrPtr, C.getTypeAlignInChars(Private->getType()));
+
+      // Step 1.2: Create a temporary to store the element in the destination
+      // Reduce list.
+      DestElementPtrAddr =
+          Bld.CreateConstArrayGEP(DestBase, Idx, CGF.getPointerSize());
+      DestElementAddr =
+          CGF.CreateMemTemp(Private->getType(), ".omp.reduction.element");
+      ShuffleInElement = true;
+      UpdateDestListPtr = true;
+      break;
+    }
+    case ThreadCopy: {
+      // Step 1.1: Get the address for the src element in the Reduce list.
+      Address SrcElementPtrAddr =
+          Bld.CreateConstArrayGEP(SrcBase, Idx, CGF.getPointerSize());
+      llvm::Value *SrcElementPtrPtr = CGF.EmitLoadOfScalar(
+          SrcElementPtrAddr, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
+      SrcElementAddr =
+          Address(SrcElementPtrPtr, C.getTypeAlignInChars(Private->getType()));
+
+      // Step 1.2: Get the address for dest element.  The destination
+      // element has already been created on the thread's stack.
+      DestElementPtrAddr =
+          Bld.CreateConstArrayGEP(DestBase, Idx, CGF.getPointerSize());
+      llvm::Value *DestElementPtr =
+          CGF.EmitLoadOfScalar(DestElementPtrAddr, /*Volatile=*/false,
+                               C.VoidPtrTy, SourceLocation());
+      Address DestElemAddr =
+          Address(DestElementPtr, C.getTypeAlignInChars(Private->getType()));
+      DestElementAddr = Bld.CreateElementBitCast(
+          DestElemAddr, CGF.ConvertTypeForMem(Private->getType()));
+      break;
+    }
+    case ThreadToScratchpad: {
+      // Step 1.1: Get the address for the src element in the Reduce list.
+      Address SrcElementPtrAddr =
+          Bld.CreateConstArrayGEP(SrcBase, Idx, CGF.getPointerSize());
+      llvm::Value *SrcElementPtrPtr = CGF.EmitLoadOfScalar(
+          SrcElementPtrAddr, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
+      SrcElementAddr =
+          Address(SrcElementPtrPtr, C.getTypeAlignInChars(Private->getType()));
+
+      // Step 1.2: Get the address for dest element:
+      // address = base + index * ElementSizeInChars.
+      unsigned ElementSizeInChars =
+          C.getTypeSizeInChars(Private->getType()).getQuantity();
+      auto *CurrentOffset =
+          Bld.CreateMul(llvm::ConstantInt::get(CGM.SizeTy, ElementSizeInChars),
+                        ScratchpadIndex);
+      auto *ScratchPadElemAbsolutePtrVal =
+          Bld.CreateAdd(DestBase.getPointer(), CurrentOffset);
+      ScratchPadElemAbsolutePtrVal =
+          Bld.CreateIntToPtr(ScratchPadElemAbsolutePtrVal, CGF.VoidPtrTy);
+      Address ScratchpadPtr =
+          Address(ScratchPadElemAbsolutePtrVal,
+                  C.getTypeAlignInChars(Private->getType()));
+      DestElementAddr = Bld.CreateElementBitCast(
+          ScratchpadPtr, CGF.ConvertTypeForMem(Private->getType()));
+      IncrScratchpadDest = true;
+      break;
+    }
+    case ScratchpadToThread: {
+      // Step 1.1: Get the address for the src element in the scratchpad.
+      // address = base + index * ElementSizeInChars.
+      unsigned ElementSizeInChars =
+          C.getTypeSizeInChars(Private->getType()).getQuantity();
+      auto *CurrentOffset =
+          Bld.CreateMul(llvm::ConstantInt::get(CGM.SizeTy, ElementSizeInChars),
+                        ScratchpadIndex);
+      auto *ScratchPadElemAbsolutePtrVal =
+          Bld.CreateAdd(SrcBase.getPointer(), CurrentOffset);
+      ScratchPadElemAbsolutePtrVal =
+          Bld.CreateIntToPtr(ScratchPadElemAbsolutePtrVal, CGF.VoidPtrTy);
+      SrcElementAddr = Address(ScratchPadElemAbsolutePtrVal,
+                               C.getTypeAlignInChars(Private->getType()));
+      IncrScratchpadSrc = true;
+
+      // Step 1.2: Create a temporary to store the element in the destination
+      // Reduce list.
+      DestElementPtrAddr =
+          Bld.CreateConstArrayGEP(DestBase, Idx, CGF.getPointerSize());
+      DestElementAddr =
+          CGF.CreateMemTemp(Private->getType(), ".omp.reduction.element");
+      UpdateDestListPtr = true;
+      break;
+    }
+    }
+
+    // Regardless of src and dest of copy, we emit the load of src
+    // element as this is required in all directions
+    SrcElementAddr = Bld.CreateElementBitCast(
+        SrcElementAddr, CGF.ConvertTypeForMem(Private->getType()));
+    llvm::Value *Elem =
+        CGF.EmitLoadOfScalar(SrcElementAddr, /*Volatile=*/false,
+                             Private->getType(), SourceLocation());
+
+    // Now that all active lanes have read the element in the
+    // Reduce list, shuffle over the value from the remote lane.
+    if (ShuffleInElement) {
+      Elem = createRuntimeShuffleFunction(CGF, Private->getType(), Elem,
+                                          RemoteLaneOffset);
+    }
+
+    // Store the source element value to the dest element address.
+    CGF.EmitStoreOfScalar(Elem, DestElementAddr, /*Volatile=*/false,
+                          Private->getType());
+
+    // Step 3.1: Modify reference in dest Reduce list as needed.
+    // Modifying the reference in Reduce list to point to the newly
+    // created element.  The element is live in the current function
+    // scope and that of functions it invokes (i.e., reduce_function).
+    // RemoteReduceData[i] = (void*)&RemoteElem
+    if (UpdateDestListPtr) {
+      CGF.EmitStoreOfScalar(Bld.CreatePointerBitCastOrAddrSpaceCast(
+                                DestElementAddr.getPointer(), CGF.VoidPtrTy),
+                            DestElementPtrAddr, /*Volatile=*/false,
+                            C.VoidPtrTy);
+    }
+
+    // Step 4.1: Increment SrcBase/DestBase so that it points to the starting
+    // address of the next element in scratchpad memory, unless we're currently
+    // processing the last one.  Memory alignment is also taken care of here.
+    if ((IncrScratchpadDest || IncrScratchpadSrc) && (Idx + 1 < Size)) {
+      llvm::Value *ScratchpadBasePtr =
+          IncrScratchpadDest ? DestBase.getPointer() : SrcBase.getPointer();
+      unsigned ElementSizeInChars =
+          C.getTypeSizeInChars(Private->getType()).getQuantity();
+      ScratchpadBasePtr = Bld.CreateAdd(
+          ScratchpadBasePtr,
+          Bld.CreateMul(ScratchpadWidth, llvm::ConstantInt::get(
+                                             CGM.SizeTy, ElementSizeInChars)));
+
+      // Take care of global memory alignment for performance
+      ScratchpadBasePtr = Bld.CreateSub(ScratchpadBasePtr,
+                                        llvm::ConstantInt::get(CGM.SizeTy, 1));
+      ScratchpadBasePtr = Bld.CreateSDiv(
+          ScratchpadBasePtr,
+          llvm::ConstantInt::get(CGM.SizeTy, GlobalMemoryAlignment));
+      ScratchpadBasePtr = Bld.CreateAdd(ScratchpadBasePtr,
+                                        llvm::ConstantInt::get(CGM.SizeTy, 1));
+      ScratchpadBasePtr = Bld.CreateMul(
+          ScratchpadBasePtr,
+          llvm::ConstantInt::get(CGM.SizeTy, GlobalMemoryAlignment));
+
+      if (IncrScratchpadDest)
+        DestBase = Address(ScratchpadBasePtr, CGF.getPointerAlign());
+      else /* IncrScratchpadSrc = true */
+        SrcBase = Address(ScratchpadBasePtr, CGF.getPointerAlign());
+    }
+
+    Idx++;
+  }
+}
+
+/// This function emits a helper that loads data from the scratchpad array
+/// and (optionally) reduces it with the input operand.
+///
+///  load_and_reduce(local, scratchpad, index, width, should_reduce)
+///  reduce_data remote;
+///  for elem in remote:
+///    remote.elem = Scratchpad[elem_id][index]
+///  if (should_reduce)
+///    local = local @ remote
+///  else
+///    local = remote
+llvm::Value *emitReduceScratchpadFunction(CodeGenModule &CGM,
+                                          ArrayRef<const Expr *> Privates,
+                                          QualType ReductionArrayTy,
+                                          llvm::Value *ReduceFn) {
+  auto &C = CGM.getContext();
+  auto Int32Ty = C.getIntTypeForBitwidth(32, /* Signed */ true);
+
+  // Destination of the copy.
+  ImplicitParamDecl ReduceListArg(C, /*DC=*/nullptr, SourceLocation(),
+                                  /*Id=*/nullptr, C.VoidPtrTy);
+  // Base address of the scratchpad array, with each element storing a
+  // Reduce list per team.
+  ImplicitParamDecl ScratchPadArg(C, /*DC=*/nullptr, SourceLocation(),
+                                  /*Id=*/nullptr, C.VoidPtrTy);
+  // A source index into the scratchpad array.
+  ImplicitParamDecl IndexArg(C, /*DC=*/nullptr, SourceLocation(),
+                             /*Id=*/nullptr, Int32Ty);
+  // Row width of an element in the scratchpad array, typically
+  // the number of teams.
+  ImplicitParamDecl WidthArg(C, /*DC=*/nullptr, SourceLocation(),
+                             /*Id=*/nullptr, Int32Ty);
+  // If should_reduce == 1, then it's load AND reduce,
+  // If should_reduce == 0 (or otherwise), then it only loads (+ copy).
+  // The latter case is used for initialization.
+  ImplicitParamDecl ShouldReduceArg(C, /*DC=*/nullptr, SourceLocation(),
+                                    /*Id=*/nullptr, Int32Ty);
+
+  FunctionArgList Args;
+  Args.push_back(&ReduceListArg);
+  Args.push_back(&ScratchPadArg);
+  Args.push_back(&IndexArg);
+  Args.push_back(&WidthArg);
+  Args.push_back(&ShouldReduceArg);
+
+  auto &CGFI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+  auto *Fn = llvm::Function::Create(
+      CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
+      "_omp_reduction_load_and_reduce", &CGM.getModule());
+  CGM.SetInternalFunctionAttributes(/*DC=*/nullptr, Fn, CGFI);
+  CodeGenFunction CGF(CGM);
+  // We don't need debug information in this function as nothing here refers to
+  // user code.
+  CGF.disableDebugInfo();
+  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args);
+
+  auto &Bld = CGF.Builder;
+
+  // Get local Reduce list pointer.
+  Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg);
+  Address ReduceListAddr(
+      Bld.CreatePointerBitCastOrAddrSpaceCast(
+          CGF.EmitLoadOfScalar(AddrReduceListArg, /*Volatile=*/false,
+                               C.VoidPtrTy, SourceLocation()),
+          CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo()),
+      CGF.getPointerAlign());
+
+  Address AddrScratchPadArg = CGF.GetAddrOfLocalVar(&ScratchPadArg);
+  llvm::Value *ScratchPadBase = CGF.EmitLoadOfScalar(
+      AddrScratchPadArg, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
+
+  Address AddrIndexArg = CGF.GetAddrOfLocalVar(&IndexArg);
+  llvm::Value *IndexVal =
+      Bld.CreateIntCast(CGF.EmitLoadOfScalar(AddrIndexArg, /*Volatile=*/false,
+                                             Int32Ty, SourceLocation()),
+                        CGM.SizeTy, /*isSigned=*/true);
+
+  Address AddrWidthArg = CGF.GetAddrOfLocalVar(&WidthArg);
+  llvm::Value *WidthVal =
+      Bld.CreateIntCast(CGF.EmitLoadOfScalar(AddrWidthArg, /*Volatile=*/false,
+                                             Int32Ty, SourceLocation()),
+                        CGM.SizeTy, /*isSigned=*/true);
+
+  Address AddrShouldReduceArg = CGF.GetAddrOfLocalVar(&ShouldReduceArg);
+  llvm::Value *ShouldReduceVal = CGF.EmitLoadOfScalar(
+      AddrShouldReduceArg, /*Volatile=*/false, Int32Ty, SourceLocation());
+
+  // The absolute ptr address to the base addr of the next element to copy.
+  llvm::Value *CumulativeElemBasePtr =
+      Bld.CreatePtrToInt(ScratchPadBase, CGM.SizeTy);
+  Address SrcDataAddr(CumulativeElemBasePtr, CGF.getPointerAlign());
+
+  // Create a Remote Reduce list to store the elements read from the
+  // scratchpad array.
+  Address RemoteReduceList =
+      CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.remote_red_list");
+
+  // Assemble remote Reduce list from scratchpad array.
+  emitReductionListCopy(ScratchpadToThread, CGF, ReductionArrayTy, Privates,
+                        SrcDataAddr, RemoteReduceList,
+                        {/*RemoteLaneOffset=*/nullptr,
+                         /*ScratchpadIndex=*/IndexVal,
+                         /*ScratchpadWidth=*/WidthVal});
+
+  llvm::BasicBlock *ThenBB = CGF.createBasicBlock("then");
+  llvm::BasicBlock *ElseBB = CGF.createBasicBlock("else");
+  llvm::BasicBlock *MergeBB = CGF.createBasicBlock("ifcont");
+
+  auto CondReduce = Bld.CreateICmpEQ(ShouldReduceVal, Bld.getInt32(1));
+  Bld.CreateCondBr(CondReduce, ThenBB, ElseBB);
+
+  CGF.EmitBlock(ThenBB);
+  // We should reduce with the local Reduce list.
+  // reduce_function(LocalReduceList, RemoteReduceList)
+  llvm::Value *LocalDataPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+      ReduceListAddr.getPointer(), CGF.VoidPtrTy);
+  llvm::Value *RemoteDataPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+      RemoteReduceList.getPointer(), CGF.VoidPtrTy);
+  CGF.EmitCallOrInvoke(ReduceFn, {LocalDataPtr, RemoteDataPtr});
+  Bld.CreateBr(MergeBB);
+
+  CGF.EmitBlock(ElseBB);
+  // No reduction; just copy:
+  // Local Reduce list = Remote Reduce list.
+  emitReductionListCopy(ThreadCopy, CGF, ReductionArrayTy, Privates,
+                        RemoteReduceList, ReduceListAddr);
+  Bld.CreateBr(MergeBB);
+
+  CGF.EmitBlock(MergeBB);
+
+  CGF.FinishFunction();
+  return Fn;
+}
+
+/// This function emits a helper that stores reduced data from the team
+/// master to a scratchpad array in global memory.
+///
+///  for elem in Reduce List:
+///    scratchpad[elem_id][index] = elem
+///
+llvm::Value *emitCopyToScratchpad(CodeGenModule &CGM,
+                                  ArrayRef<const Expr *> Privates,
+                                  QualType ReductionArrayTy) {
+
+  auto &C = CGM.getContext();
+  auto Int32Ty = C.getIntTypeForBitwidth(32, /* Signed */ true);
+
+  // Source of the copy.
+  ImplicitParamDecl ReduceListArg(C, /*DC=*/nullptr, SourceLocation(),
+                                  /*Id=*/nullptr, C.VoidPtrTy);
+  // Base address of the scratchpad array, with each element storing a
+  // Reduce list per team.
+  ImplicitParamDecl ScratchPadArg(C, /*DC=*/nullptr, SourceLocation(),
+                                  /*Id=*/nullptr, C.VoidPtrTy);
+  // A destination index into the scratchpad array, typically the team
+  // identifier.
+  ImplicitParamDecl IndexArg(C, /*DC=*/nullptr, SourceLocation(),
+                             /*Id=*/nullptr, Int32Ty);
+  // Row width of an element in the scratchpad array, typically
+  // the number of teams.
+  ImplicitParamDecl WidthArg(C, /*DC=*/nullptr, SourceLocation(),
+                             /*Id=*/nullptr, Int32Ty);
+
+  FunctionArgList Args;
+  Args.push_back(&ReduceListArg);
+  Args.push_back(&ScratchPadArg);
+  Args.push_back(&IndexArg);
+  Args.push_back(&WidthArg);
+
+  auto &CGFI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+  auto *Fn = llvm::Function::Create(
+      CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
+      "_omp_reduction_copy_to_scratchpad", &CGM.getModule());
+  CGM.SetInternalFunctionAttributes(/*DC=*/nullptr, Fn, CGFI);
+  CodeGenFunction CGF(CGM);
+  // We don't need debug information in this function as nothing here refers to
+  // user code.
+  CGF.disableDebugInfo();
+  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args);
+
+  auto &Bld = CGF.Builder;
+
+  Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg);
+  Address SrcDataAddr(
+      Bld.CreatePointerBitCastOrAddrSpaceCast(
+          CGF.EmitLoadOfScalar(AddrReduceListArg, /*Volatile=*/false,
+                               C.VoidPtrTy, SourceLocation()),
+          CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo()),
+      CGF.getPointerAlign());
+
+  Address AddrScratchPadArg = CGF.GetAddrOfLocalVar(&ScratchPadArg);
+  llvm::Value *ScratchPadBase = CGF.EmitLoadOfScalar(
+      AddrScratchPadArg, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
+
+  Address AddrIndexArg = CGF.GetAddrOfLocalVar(&IndexArg);
+  llvm::Value *IndexVal =
+      Bld.CreateIntCast(CGF.EmitLoadOfScalar(AddrIndexArg, /*Volatile=*/false,
+                                             Int32Ty, SourceLocation()),
+                        CGF.SizeTy, /*isSigned=*/true);
+
+  Address AddrWidthArg = CGF.GetAddrOfLocalVar(&WidthArg);
+  llvm::Value *WidthVal =
+      Bld.CreateIntCast(CGF.EmitLoadOfScalar(AddrWidthArg, /*Volatile=*/false,
+                                             Int32Ty, SourceLocation()),
+                        CGF.SizeTy, /*isSigned=*/true);
+
+  // The absolute ptr address to the base addr of the next element to copy.
+  llvm::Value *CumulativeElemBasePtr =
+      Bld.CreatePtrToInt(ScratchPadBase, CGM.SizeTy);
+  Address DestDataAddr(CumulativeElemBasePtr, CGF.getPointerAlign());
+
+  emitReductionListCopy(ThreadToScratchpad, CGF, ReductionArrayTy, Privates,
+                        SrcDataAddr, DestDataAddr,
+                        {/*RemoteLaneOffset=*/nullptr,
+                         /*ScratchpadIndex=*/IndexVal,
+                         /*ScratchpadWidth=*/WidthVal});
+
+  CGF.FinishFunction();
+  return Fn;
+}
+
+/// This function emits a helper that gathers Reduce lists from the first
+/// lane of every active warp to lanes in the first warp.
+///
+/// void inter_warp_copy_func(void* reduce_data, num_warps)
+///   shared smem[warp_size];
+///   For all data entries D in reduce_data:
+///     If (I am the first lane in each warp)
+///       Copy my local D to smem[warp_id]
+///     sync
+///     if (I am the first warp)
+///       Copy smem[thread_id] to my local D
+///     sync
+static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM,
+                                              ArrayRef<const Expr *> Privates,
+                                              QualType ReductionArrayTy) {
+  auto &C = CGM.getContext();
+  auto &M = CGM.getModule();
+
+  // ReduceList: thread local Reduce list.
+  // At the stage of the computation when this function is called, partially
+  // aggregated values reside in the first lane of every active warp.
+  ImplicitParamDecl ReduceListArg(C, /*DC=*/nullptr, SourceLocation(),
+                                  /*Id=*/nullptr, C.VoidPtrTy);
+  // NumWarps: number of warps active in the parallel region.  This could
+  // be smaller than 32 (max warps in a CTA) for partial block reduction.
+  ImplicitParamDecl NumWarpsArg(C, /*DC=*/nullptr, SourceLocation(),
+                                /*Id=*/nullptr,
+                                C.getIntTypeForBitwidth(32, /* Signed */ true));
+  FunctionArgList Args;
+  Args.push_back(&ReduceListArg);
+  Args.push_back(&NumWarpsArg);
+
+  auto &CGFI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+  auto *Fn = llvm::Function::Create(
+      CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
+      "_omp_reduction_inter_warp_copy_func", &CGM.getModule());
+  CGM.SetInternalFunctionAttributes(/*DC=*/nullptr, Fn, CGFI);
+  CodeGenFunction CGF(CGM);
+  // We don't need debug information in this function as nothing here refers to
+  // user code.
+  CGF.disableDebugInfo();
+  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args);
+
+  auto &Bld = CGF.Builder;
+
+  // This array is used as a medium to transfer, one reduce element at a time,
+  // the data from the first lane of every warp to lanes in the first warp
+  // in order to perform the final step of a reduction in a parallel region
+  // (reduction across warps).  The array is placed in NVPTX __shared__ memory
+  // for reduced latency, as well as to have a distinct copy for concurrently
+  // executing target regions.  The array is declared with common linkage so
+  // as to be shared across compilation units.
+  const char *TransferMediumName =
+      "__openmp_nvptx_data_transfer_temporary_storage";
+  llvm::GlobalVariable *TransferMedium =
+      M.getGlobalVariable(TransferMediumName);
+  if (!TransferMedium) {
+    auto *Ty = llvm::ArrayType::get(CGM.Int64Ty, WarpSize);
+    unsigned SharedAddressSpace = C.getTargetAddressSpace(LangAS::cuda_shared);
+    TransferMedium = new llvm::GlobalVariable(
+        M, Ty,
+        /*isConstant=*/false, llvm::GlobalVariable::CommonLinkage,
+        llvm::Constant::getNullValue(Ty), TransferMediumName,
+        /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal,
+        SharedAddressSpace);
+  }
+
+  // Get the CUDA thread id of the current OpenMP thread on the GPU.
+  auto *ThreadID = getNVPTXThreadID(CGF);
+  // nvptx_lane_id = nvptx_id % warpsize
+  auto *LaneID = getNVPTXLaneID(CGF);
+  // nvptx_warp_id = nvptx_id / warpsize
+  auto *WarpID = getNVPTXWarpID(CGF);
+
+  Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg);
+  Address LocalReduceList(
+      Bld.CreatePointerBitCastOrAddrSpaceCast(
+          CGF.EmitLoadOfScalar(AddrReduceListArg, /*Volatile=*/false,
+                               C.VoidPtrTy, SourceLocation()),
+          CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo()),
+      CGF.getPointerAlign());
+
+  unsigned Idx = 0;
+  for (auto &Private : Privates) {
+    //
+    // Warp master copies reduce element to transfer medium in __shared__
+    // memory.
+    //
+    llvm::BasicBlock *ThenBB = CGF.createBasicBlock("then");
+    llvm::BasicBlock *ElseBB = CGF.createBasicBlock("else");
+    llvm::BasicBlock *MergeBB = CGF.createBasicBlock("ifcont");
+
+    // if (lane_id == 0)
+    auto IsWarpMaster =
+        Bld.CreateICmpEQ(LaneID, Bld.getInt32(0), "warp_master");
+    Bld.CreateCondBr(IsWarpMaster, ThenBB, ElseBB);
+    CGF.EmitBlock(ThenBB);
+
+    // Reduce element = LocalReduceList[i]
+    Address ElemPtrPtrAddr =
+        Bld.CreateConstArrayGEP(LocalReduceList, Idx, CGF.getPointerSize());
+    llvm::Value *ElemPtrPtr = CGF.EmitLoadOfScalar(
+        ElemPtrPtrAddr, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
+    // elemptr = (type[i]*)(elemptrptr)
+    Address ElemPtr =
+        Address(ElemPtrPtr, C.getTypeAlignInChars(Private->getType()));
+    ElemPtr = Bld.CreateElementBitCast(
+        ElemPtr, CGF.ConvertTypeForMem(Private->getType()));
+    // elem = *elemptr
+    llvm::Value *Elem = CGF.EmitLoadOfScalar(
+        ElemPtr, /*Volatile=*/false, Private->getType(), SourceLocation());
+
+    // Get pointer to location in transfer medium.
+    // MediumPtr = &medium[warp_id]
+    llvm::Value *MediumPtrVal = Bld.CreateInBoundsGEP(
+        TransferMedium, {llvm::Constant::getNullValue(CGM.Int64Ty), WarpID});
+    Address MediumPtr(MediumPtrVal, C.getTypeAlignInChars(Private->getType()));
+    // Casting to actual data type.
+    // MediumPtr = (type[i]*)MediumPtrAddr;
+    MediumPtr = Bld.CreateElementBitCast(
+        MediumPtr, CGF.ConvertTypeForMem(Private->getType()));
+
+    //*MediumPtr = elem
+    Bld.CreateStore(Elem, MediumPtr);
+
+    Bld.CreateBr(MergeBB);
+
+    CGF.EmitBlock(ElseBB);
+    Bld.CreateBr(MergeBB);
+
+    CGF.EmitBlock(MergeBB);
+
+    Address AddrNumWarpsArg = CGF.GetAddrOfLocalVar(&NumWarpsArg);
+    llvm::Value *NumWarpsVal = CGF.EmitLoadOfScalar(
+        AddrNumWarpsArg, /*Volatile=*/false, C.IntTy, SourceLocation());
+
+    auto *NumActiveThreads = Bld.CreateNSWMul(
+        NumWarpsVal, getNVPTXWarpSize(CGF), "num_active_threads");
+    // named_barrier_sync(ParallelBarrierID, num_active_threads)
+    syncParallelThreads(CGF, NumActiveThreads);
+
+    //
+    // Warp 0 copies reduce element from transfer medium.
+    //
+    llvm::BasicBlock *W0ThenBB = CGF.createBasicBlock("then");
+    llvm::BasicBlock *W0ElseBB = CGF.createBasicBlock("else");
+    llvm::BasicBlock *W0MergeBB = CGF.createBasicBlock("ifcont");
+
+    // Up to 32 threads in warp 0 are active.
+    auto IsActiveThread =
+        Bld.CreateICmpULT(ThreadID, NumWarpsVal, "is_active_thread");
+    Bld.CreateCondBr(IsActiveThread, W0ThenBB, W0ElseBB);
+
+    CGF.EmitBlock(W0ThenBB);
+
+    // SrcMediumPtr = &medium[tid]
+    llvm::Value *SrcMediumPtrVal = Bld.CreateInBoundsGEP(
+        TransferMedium, {llvm::Constant::getNullValue(CGM.Int64Ty), ThreadID});
+    Address SrcMediumPtr(SrcMediumPtrVal,
+                         C.getTypeAlignInChars(Private->getType()));
+    // SrcMediumVal = *SrcMediumPtr;
+    SrcMediumPtr = Bld.CreateElementBitCast(
+        SrcMediumPtr, CGF.ConvertTypeForMem(Private->getType()));
+    llvm::Value *SrcMediumValue = CGF.EmitLoadOfScalar(
+        SrcMediumPtr, /*Volatile=*/false, Private->getType(), SourceLocation());
+
+    // TargetElemPtr = (type[i]*)(SrcDataAddr[i])
+    Address TargetElemPtrPtr =
+        Bld.CreateConstArrayGEP(LocalReduceList, Idx, CGF.getPointerSize());
+    llvm::Value *TargetElemPtrVal = CGF.EmitLoadOfScalar(
+        TargetElemPtrPtr, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
+    Address TargetElemPtr =
+        Address(TargetElemPtrVal, C.getTypeAlignInChars(Private->getType()));
+    TargetElemPtr = Bld.CreateElementBitCast(
+        TargetElemPtr, CGF.ConvertTypeForMem(Private->getType()));
+
+    // *TargetElemPtr = SrcMediumVal;
+    CGF.EmitStoreOfScalar(SrcMediumValue, TargetElemPtr, /*Volatile=*/false,
+                          Private->getType());
+    Bld.CreateBr(W0MergeBB);
+
+    CGF.EmitBlock(W0ElseBB);
+    Bld.CreateBr(W0MergeBB);
+
+    CGF.EmitBlock(W0MergeBB);
+
+    // While warp 0 copies values from transfer medium, all other warps must
+    // wait.
+    syncParallelThreads(CGF, NumActiveThreads);
+    Idx++;
+  }
+
+  CGF.FinishFunction();
+  return Fn;
+}
+
+/// Emit a helper that reduces data across two OpenMP threads (lanes)
+/// in the same warp.  It uses shuffle instructions to copy over data from
+/// a remote lane's stack.  The reduction algorithm performed is specified
+/// by the fourth parameter.
+///
+/// Algorithm Versions.
+/// Full Warp Reduce (argument value 0):
+///   This algorithm assumes that all 32 lanes are active and gathers
+///   data from these 32 lanes, producing a single resultant value.
+/// Contiguous Partial Warp Reduce (argument value 1):
+///   This algorithm assumes that only a *contiguous* subset of lanes
+///   are active.  This happens for the last warp in a parallel region
+///   when the user specified num_threads is not an integer multiple of
+///   32.  This contiguous subset always starts with the zeroth lane.
+/// Partial Warp Reduce (argument value 2):
+///   This algorithm gathers data from any number of lanes at any position.
+/// All reduced values are stored in the lowest possible lane.  The set
+/// of problems every algorithm addresses is a super set of those
+/// addressable by algorithms with a lower version number.  Overhead
+/// increases as algorithm version increases.
+///
+/// Terminology
+/// Reduce element:
+///   Reduce element refers to the individual data field with primitive
+///   data types to be combined and reduced across threads.
+/// Reduce list:
+///   Reduce list refers to a collection of local, thread-private
+///   reduce elements.
+/// Remote Reduce list:
+///   Remote Reduce list refers to a collection of remote (relative to
+///   the current thread) reduce elements.
+///
+/// We distinguish between three states of threads that are important to
+/// the implementation of this function.
+/// Alive threads:
+///   Threads in a warp executing the SIMT instruction, as distinguished from
+///   threads that are inactive due to divergent control flow.
+/// Active threads:
+///   The minimal set of threads that has to be alive upon entry to this
+///   function.  The computation is correct iff active threads are alive.
+///   Some threads are alive but they are not active because they do not
+///   contribute to the computation in any useful manner.  Turning them off
+///   may introduce control flow overheads without any tangible benefits.
+/// Effective threads:
+///   In order to comply with the argument requirements of the shuffle
+///   function, we must keep all lanes holding data alive.  But at most
+///   half of them perform value aggregation; we refer to this half of
+///   threads as effective. The other half is simply handing off their
+///   data.
+///
+/// Procedure
+/// Value shuffle:
+///   In this step active threads transfer data from higher lane positions
+///   in the warp to lower lane positions, creating Remote Reduce list.
+/// Value aggregation:
+///   In this step, effective threads combine their thread local Reduce list
+///   with Remote Reduce list and store the result in the thread local
+///   Reduce list.
+/// Value copy:
+///   In this step, we deal with the assumption made by algorithm 2
+///   (i.e. contiguity assumption).  When we have an odd number of lanes
+///   active, say 2k+1, only k threads will be effective and therefore k
+///   new values will be produced.  However, the Reduce list owned by the
+///   (2k+1)th thread is ignored in the value aggregation.  Therefore
+///   we copy the Reduce list from the (2k+1)th lane to (k+1)th lane so
+///   that the contiguity assumption still holds.
+static llvm::Value *
+emitShuffleAndReduceFunction(CodeGenModule &CGM,
+                             ArrayRef<const Expr *> Privates,
+                             QualType ReductionArrayTy, llvm::Value *ReduceFn) {
+  auto &C = CGM.getContext();
+
+  // Thread local Reduce list used to host the values of data to be reduced.
+  ImplicitParamDecl ReduceListArg(C, /*DC=*/nullptr, SourceLocation(),
+                                  /*Id=*/nullptr, C.VoidPtrTy);
+  // Current lane id; could be logical.
+  ImplicitParamDecl LaneIDArg(C, /*DC=*/nullptr, SourceLocation(),
+                              /*Id=*/nullptr, C.ShortTy);
+  // Offset of the remote source lane relative to the current lane.
+  ImplicitParamDecl RemoteLaneOffsetArg(C, /*DC=*/nullptr, SourceLocation(),
+                                        /*Id=*/nullptr, C.ShortTy);
+  // Algorithm version.  This is expected to be known at compile time.
+  ImplicitParamDecl AlgoVerArg(C, /*DC=*/nullptr, SourceLocation(),
+                               /*Id=*/nullptr, C.ShortTy);
+  FunctionArgList Args;
+  Args.push_back(&ReduceListArg);
+  Args.push_back(&LaneIDArg);
+  Args.push_back(&RemoteLaneOffsetArg);
+  Args.push_back(&AlgoVerArg);
+
+  auto &CGFI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+  auto *Fn = llvm::Function::Create(
+      CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
+      "_omp_reduction_shuffle_and_reduce_func", &CGM.getModule());
+  CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, CGFI);
+  CodeGenFunction CGF(CGM);
+  // We don't need debug information in this function as nothing here refers to
+  // user code.
+  CGF.disableDebugInfo();
+  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args);
+
+  auto &Bld = CGF.Builder;
+
+  Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg);
+  Address LocalReduceList(
+      Bld.CreatePointerBitCastOrAddrSpaceCast(
+          CGF.EmitLoadOfScalar(AddrReduceListArg, /*Volatile=*/false,
+                               C.VoidPtrTy, SourceLocation()),
+          CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo()),
+      CGF.getPointerAlign());
+
+  Address AddrLaneIDArg = CGF.GetAddrOfLocalVar(&LaneIDArg);
+  llvm::Value *LaneIDArgVal = CGF.EmitLoadOfScalar(
+      AddrLaneIDArg, /*Volatile=*/false, C.ShortTy, SourceLocation());
+
+  Address AddrRemoteLaneOffsetArg = CGF.GetAddrOfLocalVar(&RemoteLaneOffsetArg);
+  llvm::Value *RemoteLaneOffsetArgVal = CGF.EmitLoadOfScalar(
+      AddrRemoteLaneOffsetArg, /*Volatile=*/false, C.ShortTy, SourceLocation());
+
+  Address AddrAlgoVerArg = CGF.GetAddrOfLocalVar(&AlgoVerArg);
+  llvm::Value *AlgoVerArgVal = CGF.EmitLoadOfScalar(
+      AddrAlgoVerArg, /*Volatile=*/false, C.ShortTy, SourceLocation());
+
+  // Create a local thread-private variable to host the Reduce list
+  // from a remote lane.
+  Address RemoteReduceList =
+      CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.remote_reduce_list");
+
+  // This loop iterates through the list of reduce elements and copies,
+  // element by element, from a remote lane in the warp to RemoteReduceList,
+  // hosted on the thread's stack.
+  emitReductionListCopy(RemoteLaneToThread, CGF, ReductionArrayTy, Privates,
+                        LocalReduceList, RemoteReduceList,
+                        {/*RemoteLaneOffset=*/RemoteLaneOffsetArgVal,
+                         /*ScratchpadIndex=*/nullptr,
+                         /*ScratchpadWidth=*/nullptr});
+
+  // The actions to be performed on the Remote Reduce list is dependent
+  // on the algorithm version.
+  //
+  //  if (AlgoVer==0) || (AlgoVer==1 && (LaneId < Offset)) || (AlgoVer==2 &&
+  //  LaneId % 2 == 0 && Offset > 0):
+  //    do the reduction value aggregation
+  //
+  //  The thread local variable Reduce list is mutated in place to host the
+  //  reduced data, which is the aggregated value produced from local and
+  //  remote lanes.
+  //
+  //  Note that AlgoVer is expected to be a constant integer known at compile
+  //  time.
+  //  When AlgoVer==0, the first conjunction evaluates to true, making
+  //    the entire predicate true during compile time.
+  //  When AlgoVer==1, the second conjunction has only the second part to be
+  //    evaluated during runtime.  Other conjunctions evaluates to false
+  //    during compile time.
+  //  When AlgoVer==2, the third conjunction has only the second part to be
+  //    evaluated during runtime.  Other conjunctions evaluates to false
+  //    during compile time.
+  auto CondAlgo0 = Bld.CreateICmpEQ(AlgoVerArgVal, Bld.getInt16(0));
+
+  auto Algo1 = Bld.CreateICmpEQ(AlgoVerArgVal, Bld.getInt16(1));
+  auto CondAlgo1 = Bld.CreateAnd(
+      Algo1, Bld.CreateICmpULT(LaneIDArgVal, RemoteLaneOffsetArgVal));
+
+  auto Algo2 = Bld.CreateICmpEQ(AlgoVerArgVal, Bld.getInt16(2));
+  auto CondAlgo2 = Bld.CreateAnd(
+      Algo2,
+      Bld.CreateICmpEQ(Bld.CreateAnd(LaneIDArgVal, Bld.getInt16(1)),
+                       Bld.getInt16(0)));
+  CondAlgo2 = Bld.CreateAnd(
+      CondAlgo2, Bld.CreateICmpSGT(RemoteLaneOffsetArgVal, Bld.getInt16(0)));
+
+  auto CondReduce = Bld.CreateOr(CondAlgo0, CondAlgo1);
+  CondReduce = Bld.CreateOr(CondReduce, CondAlgo2);
+
+  llvm::BasicBlock *ThenBB = CGF.createBasicBlock("then");
+  llvm::BasicBlock *ElseBB = CGF.createBasicBlock("else");
+  llvm::BasicBlock *MergeBB = CGF.createBasicBlock("ifcont");
+  Bld.CreateCondBr(CondReduce, ThenBB, ElseBB);
+
+  CGF.EmitBlock(ThenBB);
+  // reduce_function(LocalReduceList, RemoteReduceList)
+  llvm::Value *LocalReduceListPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+      LocalReduceList.getPointer(), CGF.VoidPtrTy);
+  llvm::Value *RemoteReduceListPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+      RemoteReduceList.getPointer(), CGF.VoidPtrTy);
+  CGF.EmitCallOrInvoke(ReduceFn, {LocalReduceListPtr, RemoteReduceListPtr});
+  Bld.CreateBr(MergeBB);
+
+  CGF.EmitBlock(ElseBB);
+  Bld.CreateBr(MergeBB);
+
+  CGF.EmitBlock(MergeBB);
+
+  // if (AlgoVer==1 && (LaneId >= Offset)) copy Remote Reduce list to local
+  // Reduce list.
+  Algo1 = Bld.CreateICmpEQ(AlgoVerArgVal, Bld.getInt16(1));
+  auto CondCopy = Bld.CreateAnd(
+      Algo1, Bld.CreateICmpUGE(LaneIDArgVal, RemoteLaneOffsetArgVal));
+
+  llvm::BasicBlock *CpyThenBB = CGF.createBasicBlock("then");
+  llvm::BasicBlock *CpyElseBB = CGF.createBasicBlock("else");
+  llvm::BasicBlock *CpyMergeBB = CGF.createBasicBlock("ifcont");
+  Bld.CreateCondBr(CondCopy, CpyThenBB, CpyElseBB);
+
+  CGF.EmitBlock(CpyThenBB);
+  emitReductionListCopy(ThreadCopy, CGF, ReductionArrayTy, Privates,
+                        RemoteReduceList, LocalReduceList);
+  Bld.CreateBr(CpyMergeBB);
+
+  CGF.EmitBlock(CpyElseBB);
+  Bld.CreateBr(CpyMergeBB);
+
+  CGF.EmitBlock(CpyMergeBB);
+
+  CGF.FinishFunction();
+  return Fn;
+}
+
+///
+/// Design of OpenMP reductions on the GPU
+///
+/// Consider a typical OpenMP program with one or more reduction
+/// clauses:
+///
+/// float foo;
+/// double bar;
+/// #pragma omp target teams distribute parallel for \
+///             reduction(+:foo) reduction(*:bar)
+/// for (int i = 0; i < N; i++) {
+///   foo += A[i]; bar *= B[i];
+/// }
+///
+/// where 'foo' and 'bar' are reduced across all OpenMP threads in
+/// all teams.  In our OpenMP implementation on the NVPTX device an
+/// OpenMP team is mapped to a CUDA threadblock and OpenMP threads
+/// within a team are mapped to CUDA threads within a threadblock.
+/// Our goal is to efficiently aggregate values across all OpenMP
+/// threads such that:
+///
+///   - the compiler and runtime are logically concise, and
+///   - the reduction is performed efficiently in a hierarchical
+///     manner as follows: within OpenMP threads in the same warp,
+///     across warps in a threadblock, and finally across teams on
+///     the NVPTX device.
+///
+/// Introduction to Decoupling
+///
+/// We would like to decouple the compiler and the runtime so that the
+/// latter is ignorant of the reduction variables (number, data types)
+/// and the reduction operators.  This allows a simpler interface
+/// and implementation while still attaining good performance.
+///
+/// Pseudocode for the aforementioned OpenMP program generated by the
+/// compiler is as follows:
+///
+/// 1. Create private copies of reduction variables on each OpenMP
+///    thread: 'foo_private', 'bar_private'
+/// 2. Each OpenMP thread reduces the chunk of 'A' and 'B' assigned
+///    to it and writes the result in 'foo_private' and 'bar_private'
+///    respectively.
+/// 3. Call the OpenMP runtime on the GPU to reduce within a team
+///    and store the result on the team master:
+///
+///     __kmpc_nvptx_parallel_reduce_nowait(...,
+///        reduceData, shuffleReduceFn, interWarpCpyFn)
+///
+///     where:
+///       struct ReduceData {
+///         double *foo;
+///         double *bar;
+///       } reduceData
+///       reduceData.foo = &foo_private
+///       reduceData.bar = &bar_private
+///
+///     'shuffleReduceFn' and 'interWarpCpyFn' are pointers to two
+///     auxiliary functions generated by the compiler that operate on
+///     variables of type 'ReduceData'.  They aid the runtime perform
+///     algorithmic steps in a data agnostic manner.
+///
+///     'shuffleReduceFn' is a pointer to a function that reduces data
+///     of type 'ReduceData' across two OpenMP threads (lanes) in the
+///     same warp.  It takes the following arguments as input:
+///
+///     a. variable of type 'ReduceData' on the calling lane,
+///     b. its lane_id,
+///     c. an offset relative to the current lane_id to generate a
+///        remote_lane_id.  The remote lane contains the second
+///        variable of type 'ReduceData' that is to be reduced.
+///     d. an algorithm version parameter determining which reduction
+///        algorithm to use.
+///
+///     'shuffleReduceFn' retrieves data from the remote lane using
+///     efficient GPU shuffle intrinsics and reduces, using the
+///     algorithm specified by the 4th parameter, the two operands
+///     element-wise.  The result is written to the first operand.
+///
+///     Different reduction algorithms are implemented in different
+///     runtime functions, all calling 'shuffleReduceFn' to perform
+///     the essential reduction step.  Therefore, based on the 4th
+///     parameter, this function behaves slightly differently to
+///     cooperate with the runtime to ensure correctness under
+///     different circumstances.
+///
+///     'InterWarpCpyFn' is a pointer to a function that transfers
+///     reduced variables across warps.  It tunnels, through CUDA
+///     shared memory, the thread-private data of type 'ReduceData'
+///     from lane 0 of each warp to a lane in the first warp.
+/// 4. Call the OpenMP runtime on the GPU to reduce across teams.
+///    The last team writes the global reduced value to memory.
+///
+///     ret = __kmpc_nvptx_teams_reduce_nowait(...,
+///             reduceData, shuffleReduceFn, interWarpCpyFn,
+///             scratchpadCopyFn, loadAndReduceFn)
+///
+///     'scratchpadCopyFn' is a helper that stores reduced
+///     data from the team master to a scratchpad array in
+///     global memory.
+///
+///     'loadAndReduceFn' is a helper that loads data from
+///     the scratchpad array and reduces it with the input
+///     operand.
+///
+///     These compiler generated functions hide address
+///     calculation and alignment information from the runtime.
+/// 5. if ret == 1:
+///     The team master of the last team stores the reduced
+///     result to the globals in memory.
+///     foo += reduceData.foo; bar *= reduceData.bar
+///
+///
+/// Warp Reduction Algorithms
+///
+/// On the warp level, we have three algorithms implemented in the
+/// OpenMP runtime depending on the number of active lanes:
+///
+/// Full Warp Reduction
+///
+/// The reduce algorithm within a warp where all lanes are active
+/// is implemented in the runtime as follows:
+///
+/// full_warp_reduce(void *reduce_data,
+///                  kmp_ShuffleReductFctPtr ShuffleReduceFn) {
+///   for (int offset = WARPSIZE/2; offset > 0; offset /= 2)
+///     ShuffleReduceFn(reduce_data, 0, offset, 0);
+/// }
+///
+/// The algorithm completes in log(2, WARPSIZE) steps.
+///
+/// 'ShuffleReduceFn' is used here with lane_id set to 0 because it is
+/// not used therefore we save instructions by not retrieving lane_id
+/// from the corresponding special registers.  The 4th parameter, which
+/// represents the version of the algorithm being used, is set to 0 to
+/// signify full warp reduction.
+///
+/// In this version, 'ShuffleReduceFn' behaves, per element, as follows:
+///
+/// #reduce_elem refers to an element in the local lane's data structure
+/// #remote_elem is retrieved from a remote lane
+/// remote_elem = shuffle_down(reduce_elem, offset, WARPSIZE);
+/// reduce_elem = reduce_elem REDUCE_OP remote_elem;
+///
+/// Contiguous Partial Warp Reduction
+///
+/// This reduce algorithm is used within a warp where only the first
+/// 'n' (n <= WARPSIZE) lanes are active.  It is typically used when the
+/// number of OpenMP threads in a parallel region is not a multiple of
+/// WARPSIZE.  The algorithm is implemented in the runtime as follows:
+///
+/// void
+/// contiguous_partial_reduce(void *reduce_data,
+///                           kmp_ShuffleReductFctPtr ShuffleReduceFn,
+///                           int size, int lane_id) {
+///   int curr_size;
+///   int offset;
+///   curr_size = size;
+///   mask = curr_size/2;
+///   while (offset>0) {
+///     ShuffleReduceFn(reduce_data, lane_id, offset, 1);
+///     curr_size = (curr_size+1)/2;
+///     offset = curr_size/2;
+///   }
+/// }
+///
+/// In this version, 'ShuffleReduceFn' behaves, per element, as follows:
+///
+/// remote_elem = shuffle_down(reduce_elem, offset, WARPSIZE);
+/// if (lane_id < offset)
+///     reduce_elem = reduce_elem REDUCE_OP remote_elem
+/// else
+///     reduce_elem = remote_elem
+///
+/// This algorithm assumes that the data to be reduced are located in a
+/// contiguous subset of lanes starting from the first.  When there is
+/// an odd number of active lanes, the data in the last lane is not
+/// aggregated with any other lane's dat but is instead copied over.
+///
+/// Dispersed Partial Warp Reduction
+///
+/// This algorithm is used within a warp when any discontiguous subset of
+/// lanes are active.  It is used to implement the reduction operation
+/// across lanes in an OpenMP simd region or in a nested parallel region.
+///
+/// void
+/// dispersed_partial_reduce(void *reduce_data,
+///                          kmp_ShuffleReductFctPtr ShuffleReduceFn) {
+///   int size, remote_id;
+///   int logical_lane_id = number_of_active_lanes_before_me() * 2;
+///   do {
+///       remote_id = next_active_lane_id_right_after_me();
+///       # the above function returns 0 of no active lane
+///       # is present right after the current lane.
+///       size = number_of_active_lanes_in_this_warp();
+///       logical_lane_id /= 2;
+///       ShuffleReduceFn(reduce_data, logical_lane_id,
+///                       remote_id-1-threadIdx.x, 2);
+///   } while (logical_lane_id % 2 == 0 && size > 1);
+/// }
+///
+/// There is no assumption made about the initial state of the reduction.
+/// Any number of lanes (>=1) could be active at any position.  The reduction
+/// result is returned in the first active lane.
+///
+/// In this version, 'ShuffleReduceFn' behaves, per element, as follows:
+///
+/// remote_elem = shuffle_down(reduce_elem, offset, WARPSIZE);
+/// if (lane_id % 2 == 0 && offset > 0)
+///     reduce_elem = reduce_elem REDUCE_OP remote_elem
+/// else
+///     reduce_elem = remote_elem
+///
+///
+/// Intra-Team Reduction
+///
+/// This function, as implemented in the runtime call
+/// '__kmpc_nvptx_parallel_reduce_nowait', aggregates data across OpenMP
+/// threads in a team.  It first reduces within a warp using the
+/// aforementioned algorithms.  We then proceed to gather all such
+/// reduced values at the first warp.
+///
+/// The runtime makes use of the function 'InterWarpCpyFn', which copies
+/// data from each of the "warp master" (zeroth lane of each warp, where
+/// warp-reduced data is held) to the zeroth warp.  This step reduces (in
+/// a mathematical sense) the problem of reduction across warp masters in
+/// a block to the problem of warp reduction.
+///
+///
+/// Inter-Team Reduction
+///
+/// Once a team has reduced its data to a single value, it is stored in
+/// a global scratchpad array.  Since each team has a distinct slot, this
+/// can be done without locking.
+///
+/// The last team to write to the scratchpad array proceeds to reduce the
+/// scratchpad array.  One or more workers in the last team use the helper
+/// 'loadAndReduceDataFn' to load and reduce values from the array, i.e.,
+/// the k'th worker reduces every k'th element.
+///
+/// Finally, a call is made to '__kmpc_nvptx_parallel_reduce_nowait' to
+/// reduce across workers and compute a globally reduced value.
+///
+void CGOpenMPRuntimeNVPTX::emitReduction(
+    CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> Privates,
+    ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
+    ArrayRef<const Expr *> ReductionOps, ReductionOptionsTy Options) {
+  if (!CGF.HaveInsertPoint())
+    return;
+
+  bool ParallelReduction = isOpenMPParallelDirective(Options.ReductionKind);
+  bool TeamsReduction = isOpenMPTeamsDirective(Options.ReductionKind);
+  // FIXME: Add support for simd reduction.
+  assert((TeamsReduction || ParallelReduction) &&
+         "Invalid reduction selection in emitReduction.");
+
+  auto &C = CGM.getContext();
+
+  // 1. Build a list of reduction variables.
+  // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
+  auto Size = RHSExprs.size();
+  for (auto *E : Privates) {
+    if (E->getType()->isVariablyModifiedType())
+      // Reserve place for array size.
+      ++Size;
+  }
+  llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size);
+  QualType ReductionArrayTy =
+      C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
+                             /*IndexTypeQuals=*/0);
+  Address ReductionList =
+      CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
+  auto IPriv = Privates.begin();
+  unsigned Idx = 0;
+  for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
+    Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx,
+                                                   CGF.getPointerSize());
+    CGF.Builder.CreateStore(
+        CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+            CGF.EmitLValue(RHSExprs[I]).getPointer(), CGF.VoidPtrTy),
+        Elem);
+    if ((*IPriv)->getType()->isVariablyModifiedType()) {
+      // Store array size.
+      ++Idx;
+      Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx,
+                                             CGF.getPointerSize());
+      llvm::Value *Size = CGF.Builder.CreateIntCast(
+          CGF.getVLASize(
+                 CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
+              .first,
+          CGF.SizeTy, /*isSigned=*/false);
+      CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
+                              Elem);
+    }
+  }
+
+  // 2. Emit reduce_func().
+  auto *ReductionFn = emitReductionFunction(
+      CGM, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), Privates,
+      LHSExprs, RHSExprs, ReductionOps);
+
+  // 4. Build res = __kmpc_reduce{_nowait}(<gtid>, <n>, sizeof(RedList),
+  // RedList, shuffle_reduce_func, interwarp_copy_func);
+  auto *ThreadId = getThreadID(CGF, Loc);
+  auto *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy);
+  auto *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+      ReductionList.getPointer(), CGF.VoidPtrTy);
+
+  auto *ShuffleAndReduceFn = emitShuffleAndReduceFunction(
+      CGM, Privates, ReductionArrayTy, ReductionFn);
+  auto *InterWarpCopyFn =
+      emitInterWarpCopyFunction(CGM, Privates, ReductionArrayTy);
+
+  llvm::Value *Res = nullptr;
+  if (ParallelReduction) {
+    llvm::Value *Args[] = {ThreadId,
+                           CGF.Builder.getInt32(RHSExprs.size()),
+                           ReductionArrayTySize,
+                           RL,
+                           ShuffleAndReduceFn,
+                           InterWarpCopyFn};
+
+    Res = CGF.EmitRuntimeCall(
+        createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_parallel_reduce_nowait),
+        Args);
+  }
+
+  if (TeamsReduction) {
+    auto *ScratchPadCopyFn =
+        emitCopyToScratchpad(CGM, Privates, ReductionArrayTy);
+    auto *LoadAndReduceFn = emitReduceScratchpadFunction(
+        CGM, Privates, ReductionArrayTy, ReductionFn);
+
+    llvm::Value *Args[] = {ThreadId,
+                           CGF.Builder.getInt32(RHSExprs.size()),
+                           ReductionArrayTySize,
+                           RL,
+                           ShuffleAndReduceFn,
+                           InterWarpCopyFn,
+                           ScratchPadCopyFn,
+                           LoadAndReduceFn};
+    Res = CGF.EmitRuntimeCall(
+        createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_teams_reduce_nowait),
+        Args);
+  }
+
+  // 5. Build switch(res)
+  auto *DefaultBB = CGF.createBasicBlock(".omp.reduction.default");
+  auto *SwInst = CGF.Builder.CreateSwitch(Res, DefaultBB, /*NumCases=*/1);
+
+  // 6. Build case 1: where we have reduced values in the master
+  //    thread in each team.
+  //    __kmpc_end_reduce{_nowait}(<gtid>);
+  //    break;
+  auto *Case1BB = CGF.createBasicBlock(".omp.reduction.case1");
+  SwInst->addCase(CGF.Builder.getInt32(1), Case1BB);
+  CGF.EmitBlock(Case1BB);
+
+  // Add emission of __kmpc_end_reduce{_nowait}(<gtid>);
+  llvm::Value *EndArgs[] = {ThreadId};
+  auto &&CodeGen = [&Privates, &LHSExprs, &RHSExprs, &ReductionOps,
+                    this](CodeGenFunction &CGF, PrePostActionTy &Action) {
+    auto IPriv = Privates.begin();
+    auto ILHS = LHSExprs.begin();
+    auto IRHS = RHSExprs.begin();
+    for (auto *E : ReductionOps) {
+      emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
+                                  cast<DeclRefExpr>(*IRHS));
+      ++IPriv;
+      ++ILHS;
+      ++IRHS;
+    }
+  };
+  RegionCodeGenTy RCG(CodeGen);
+  NVPTXActionTy Action(
+      nullptr, llvm::None,
+      createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_end_reduce_nowait),
+      EndArgs);
+  RCG.setAction(Action);
+  RCG(CGF);
+  CGF.EmitBranch(DefaultBB);
+  CGF.EmitBlock(DefaultBB, /*IsFinished=*/true);
+}
diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.h b/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
index a6c64b2..ae25e94 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
@@ -24,12 +24,12 @@
 namespace CodeGen {
 
 class CGOpenMPRuntimeNVPTX : public CGOpenMPRuntime {
-public:
-  class EntryFunctionState {
-  public:
-    llvm::BasicBlock *ExitBB;
+private:
+  // Parallel outlined function work for workers to execute.
+  llvm::SmallVector<llvm::Function *, 16> Work;
 
-    EntryFunctionState() : ExitBB(nullptr){};
+  struct EntryFunctionState {
+    llvm::BasicBlock *ExitBB = nullptr;
   };
 
   class WorkerFunctionState {
@@ -43,59 +43,7 @@
     void createWorkerFunction(CodeGenModule &CGM);
   };
 
-  /// \brief Helper for target entry function. Guide the master and worker
-  /// threads to their respective locations.
-  void emitEntryHeader(CodeGenFunction &CGF, EntryFunctionState &EST,
-                       WorkerFunctionState &WST);
-
-  /// \brief Signal termination of OMP execution.
-  void emitEntryFooter(CodeGenFunction &CGF, EntryFunctionState &EST);
-
-private:
-  //
-  // NVPTX calls.
-  //
-
-  /// \brief Get the GPU warp size.
-  llvm::Value *getNVPTXWarpSize(CodeGenFunction &CGF);
-
-  /// \brief Get the id of the current thread on the GPU.
-  llvm::Value *getNVPTXThreadID(CodeGenFunction &CGF);
-
-  // \brief Get the maximum number of threads in a block of the GPU.
-  llvm::Value *getNVPTXNumThreads(CodeGenFunction &CGF);
-
-  /// \brief Get barrier to synchronize all threads in a block.
-  void getNVPTXCTABarrier(CodeGenFunction &CGF);
-
-  // \brief Synchronize all GPU threads in a block.
-  void syncCTAThreads(CodeGenFunction &CGF);
-
-  //
-  // OMP calls.
-  //
-
-  /// \brief Get the thread id of the OMP master thread.
-  /// The master thread id is the first thread (lane) of the last warp in the
-  /// GPU block.  Warp size is assumed to be some power of 2.
-  /// Thread id is 0 indexed.
-  /// E.g: If NumThreads is 33, master id is 32.
-  ///      If NumThreads is 64, master id is 32.
-  ///      If NumThreads is 1024, master id is 992.
-  llvm::Value *getMasterThreadID(CodeGenFunction &CGF);
-
-  //
-  // Private state and methods.
-  //
-
-  // Master-worker control state.
-  // Number of requested OMP threads in parallel region.
-  llvm::GlobalVariable *ActiveWorkers;
-  // Outlined function for the workers to execute.
-  llvm::GlobalVariable *WorkID;
-
-  /// \brief Initialize master-worker control state.
-  void initializeEnvironment();
+  bool isInSpmdExecutionMode() const;
 
   /// \brief Emit the worker function for the current target region.
   void emitWorkerFunction(WorkerFunctionState &WST);
@@ -103,20 +51,60 @@
   /// \brief Helper for worker function. Emit body of worker loop.
   void emitWorkerLoop(CodeGenFunction &CGF, WorkerFunctionState &WST);
 
-  /// \brief Returns specified OpenMP runtime function for the current OpenMP
-  /// implementation.  Specialized for the NVPTX device.
-  /// \param Function OpenMP runtime function.
-  /// \return Specified function.
-  llvm::Constant *createNVPTXRuntimeFunction(unsigned Function);
+  /// \brief Helper for generic target entry function. Guide the master and
+  /// worker threads to their respective locations.
+  void emitGenericEntryHeader(CodeGenFunction &CGF, EntryFunctionState &EST,
+                              WorkerFunctionState &WST);
+
+  /// \brief Signal termination of OMP execution for generic target entry
+  /// function.
+  void emitGenericEntryFooter(CodeGenFunction &CGF, EntryFunctionState &EST);
+
+  /// \brief Helper for Spmd mode target directive's entry function.
+  void emitSpmdEntryHeader(CodeGenFunction &CGF, EntryFunctionState &EST,
+                           const OMPExecutableDirective &D);
+
+  /// \brief Signal termination of Spmd mode execution.
+  void emitSpmdEntryFooter(CodeGenFunction &CGF, EntryFunctionState &EST);
 
   //
   // Base class overrides.
   //
 
   /// \brief Creates offloading entry for the provided entry ID \a ID,
-  /// address \a Addr and size \a Size.
+  /// address \a Addr, size \a Size, and flags \a Flags.
   void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr,
-                          uint64_t Size) override;
+                          uint64_t Size, int32_t Flags = 0) override;
+
+  /// \brief Emit outlined function specialized for the Fork-Join
+  /// programming model for applicable target directives on the NVPTX device.
+  /// \param D Directive to emit.
+  /// \param ParentName Name of the function that encloses the target region.
+  /// \param OutlinedFn Outlined function value to be defined by this call.
+  /// \param OutlinedFnID Outlined function ID value to be defined by this call.
+  /// \param IsOffloadEntry True if the outlined function is an offload entry.
+  /// An outlined function may not be an entry if, e.g. the if clause always
+  /// evaluates to false.
+  void emitGenericKernel(const OMPExecutableDirective &D, StringRef ParentName,
+                         llvm::Function *&OutlinedFn,
+                         llvm::Constant *&OutlinedFnID, bool IsOffloadEntry,
+                         const RegionCodeGenTy &CodeGen);
+
+  /// \brief Emit outlined function specialized for the Single Program
+  /// Multiple Data programming model for applicable target directives on the
+  /// NVPTX device.
+  /// \param D Directive to emit.
+  /// \param ParentName Name of the function that encloses the target region.
+  /// \param OutlinedFn Outlined function value to be defined by this call.
+  /// \param OutlinedFnID Outlined function ID value to be defined by this call.
+  /// \param IsOffloadEntry True if the outlined function is an offload entry.
+  /// \param CodeGen Object containing the target statements.
+  /// An outlined function may not be an entry if, e.g. the if clause always
+  /// evaluates to false.
+  void emitSpmdKernel(const OMPExecutableDirective &D, StringRef ParentName,
+                      llvm::Function *&OutlinedFn,
+                      llvm::Constant *&OutlinedFnID, bool IsOffloadEntry,
+                      const RegionCodeGenTy &CodeGen);
 
   /// \brief Emit outlined function for 'target' directive on the NVPTX
   /// device.
@@ -134,9 +122,62 @@
                                   bool IsOffloadEntry,
                                   const RegionCodeGenTy &CodeGen) override;
 
+  /// \brief Emits code for parallel or serial call of the \a OutlinedFn with
+  /// variables captured in a record which address is stored in \a
+  /// CapturedStruct.
+  /// This call is for the Generic Execution Mode.
+  /// \param OutlinedFn Outlined function to be run in parallel threads. Type of
+  /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
+  /// \param CapturedVars A pointer to the record with the references to
+  /// variables used in \a OutlinedFn function.
+  /// \param IfCond Condition in the associated 'if' clause, if it was
+  /// specified, nullptr otherwise.
+  void emitGenericParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
+                               llvm::Value *OutlinedFn,
+                               ArrayRef<llvm::Value *> CapturedVars,
+                               const Expr *IfCond);
+
+  /// \brief Emits code for parallel or serial call of the \a OutlinedFn with
+  /// variables captured in a record which address is stored in \a
+  /// CapturedStruct.
+  /// This call is for a parallel directive within an SPMD target directive.
+  /// \param OutlinedFn Outlined function to be run in parallel threads. Type of
+  /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
+  /// \param CapturedVars A pointer to the record with the references to
+  /// variables used in \a OutlinedFn function.
+  /// \param IfCond Condition in the associated 'if' clause, if it was
+  /// specified, nullptr otherwise.
+  ///
+  void emitSpmdParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
+                            llvm::Value *OutlinedFn,
+                            ArrayRef<llvm::Value *> CapturedVars,
+                            const Expr *IfCond);
+
+protected:
+  /// \brief Get the function name of an outlined region.
+  //  The name can be customized depending on the target.
+  //
+  StringRef getOutlinedHelperName() const override {
+    return "__omp_outlined__";
+  }
+
 public:
   explicit CGOpenMPRuntimeNVPTX(CodeGenModule &CGM);
 
+  /// \brief Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32
+  /// global_tid, int proc_bind) to generate code for 'proc_bind' clause.
+  virtual void emitProcBindClause(CodeGenFunction &CGF,
+                                  OpenMPProcBindClauseKind ProcBind,
+                                  SourceLocation Loc) override;
+
+  /// \brief Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32
+  /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads'
+  /// clause.
+  /// \param NumThreads An integer value of threads.
+  virtual void emitNumThreadsClause(CodeGenFunction &CGF,
+                                    llvm::Value *NumThreads,
+                                    SourceLocation Loc) override;
+
   /// \brief This function ought to emit, in the general case, a call to
   // the openmp runtime kmpc_push_num_teams. In NVPTX backend it is not needed
   // as these numbers are obtained through the PTX grid and block configuration.
@@ -146,7 +187,7 @@
                           const Expr *ThreadLimit, SourceLocation Loc) override;
 
   /// \brief Emits inlined function for the specified OpenMP parallel
-  //  directive but an inlined function for teams.
+  //  directive.
   /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
   /// kmp_int32 BoundID, struct context_vars*).
   /// \param D OpenMP directive.
@@ -155,10 +196,25 @@
   /// is a directive itself, for combined - its innermost directive).
   /// \param CodeGen Code generation sequence for the \a D directive.
   llvm::Value *
-  emitParallelOrTeamsOutlinedFunction(const OMPExecutableDirective &D,
-                                      const VarDecl *ThreadIDVar,
-                                      OpenMPDirectiveKind InnermostKind,
-                                      const RegionCodeGenTy &CodeGen) override;
+  emitParallelOutlinedFunction(const OMPExecutableDirective &D,
+                               const VarDecl *ThreadIDVar,
+                               OpenMPDirectiveKind InnermostKind,
+                               const RegionCodeGenTy &CodeGen) override;
+
+  /// \brief Emits inlined function for the specified OpenMP teams
+  //  directive.
+  /// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
+  /// kmp_int32 BoundID, struct context_vars*).
+  /// \param D OpenMP directive.
+  /// \param ThreadIDVar Variable for thread id in the current OpenMP region.
+  /// \param InnermostKind Kind of innermost directive (for simple directives it
+  /// is a directive itself, for combined - its innermost directive).
+  /// \param CodeGen Code generation sequence for the \a D directive.
+  llvm::Value *
+  emitTeamsOutlinedFunction(const OMPExecutableDirective &D,
+                            const VarDecl *ThreadIDVar,
+                            OpenMPDirectiveKind InnermostKind,
+                            const RegionCodeGenTy &CodeGen) override;
 
   /// \brief Emits code for teams call of the \a OutlinedFn with
   /// variables captured in a record which address is stored in \a
@@ -171,6 +227,64 @@
   void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
                      SourceLocation Loc, llvm::Value *OutlinedFn,
                      ArrayRef<llvm::Value *> CapturedVars) override;
+
+  /// \brief Emits code for parallel or serial call of the \a OutlinedFn with
+  /// variables captured in a record which address is stored in \a
+  /// CapturedStruct.
+  /// \param OutlinedFn Outlined function to be run in parallel threads. Type of
+  /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
+  /// \param CapturedVars A pointer to the record with the references to
+  /// variables used in \a OutlinedFn function.
+  /// \param IfCond Condition in the associated 'if' clause, if it was
+  /// specified, nullptr otherwise.
+  void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
+                        llvm::Value *OutlinedFn,
+                        ArrayRef<llvm::Value *> CapturedVars,
+                        const Expr *IfCond) override;
+
+  /// Emit a code for reduction clause.
+  ///
+  /// \param Privates List of private copies for original reduction arguments.
+  /// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
+  /// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
+  /// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
+  /// or 'operator binop(LHS, RHS)'.
+  /// \param Options List of options for reduction codegen:
+  ///     WithNowait true if parent directive has also nowait clause, false
+  ///     otherwise.
+  ///     SimpleReduction Emit reduction operation only. Used for omp simd
+  ///     directive on the host.
+  ///     ReductionKind The kind of reduction to perform.
+  virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
+                             ArrayRef<const Expr *> Privates,
+                             ArrayRef<const Expr *> LHSExprs,
+                             ArrayRef<const Expr *> RHSExprs,
+                             ArrayRef<const Expr *> ReductionOps,
+                             ReductionOptionsTy Options) override;
+
+  /// Returns specified OpenMP runtime function for the current OpenMP
+  /// implementation.  Specialized for the NVPTX device.
+  /// \param Function OpenMP runtime function.
+  /// \return Specified function.
+  llvm::Constant *createNVPTXRuntimeFunction(unsigned Function);
+
+  /// Target codegen is specialized based on two programming models: the
+  /// 'generic' fork-join model of OpenMP, and a more GPU efficient 'spmd'
+  /// model for constructs like 'target parallel' that support it.
+  enum ExecutionMode {
+    /// Single Program Multiple Data.
+    Spmd,
+    /// Generic codegen to support fork-join model.
+    Generic,
+    Unknown,
+  };
+
+private:
+  // Track the execution mode when codegening directives within a target
+  // region. The appropriate mode (generic/spmd) is set on entry to the
+  // target region and used by containing directives such as 'parallel'
+  // to emit optimized code.
+  ExecutionMode CurrentExecutionMode;
 };
 
 } // CodeGen namespace.
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index ba0064f..9c92367 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -145,7 +145,7 @@
     EmitCoroutineBody(cast<CoroutineBodyStmt>(*S));
     break;
   case Stmt::CoreturnStmtClass:
-    CGM.ErrorUnsupported(S, "coroutine");
+    EmitCoreturnStmt(cast<CoreturnStmt>(*S));
     break;
   case Stmt::CapturedStmtClass: {
     const CapturedStmt *CS = cast<CapturedStmt>(S);
@@ -315,6 +315,25 @@
     EmitOMPTeamsDistributeParallelForDirective(
         cast<OMPTeamsDistributeParallelForDirective>(*S));
     break;
+  case Stmt::OMPTargetTeamsDirectiveClass:
+    EmitOMPTargetTeamsDirective(cast<OMPTargetTeamsDirective>(*S));
+    break;
+  case Stmt::OMPTargetTeamsDistributeDirectiveClass:
+    EmitOMPTargetTeamsDistributeDirective(
+        cast<OMPTargetTeamsDistributeDirective>(*S));
+    break;
+  case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
+    EmitOMPTargetTeamsDistributeParallelForDirective(
+        cast<OMPTargetTeamsDistributeParallelForDirective>(*S));
+    break;
+  case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
+    EmitOMPTargetTeamsDistributeParallelForSimdDirective(
+        cast<OMPTargetTeamsDistributeParallelForSimdDirective>(*S));
+    break;
+  case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
+    EmitOMPTargetTeamsDistributeSimdDirective(
+        cast<OMPTargetTeamsDistributeSimdDirective>(*S));
+    break;
   }
 }
 
@@ -2206,7 +2225,7 @@
       auto VAT = CurField->getCapturedVLAType();
       EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
     } else {
-      EmitInitializerForField(*CurField, LV, *I, None);
+      EmitInitializerForField(*CurField, LV, *I);
     }
   }
 
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 6cd4d11..2f64da29 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -26,7 +26,7 @@
 namespace {
 /// Lexical scope for OpenMP executable constructs, that handles correct codegen
 /// for captured expressions.
-class OMPLexicalScope final : public CodeGenFunction::LexicalScope {
+class OMPLexicalScope : public CodeGenFunction::LexicalScope {
   void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
     for (const auto *C : S.clauses()) {
       if (auto *CPI = OMPClauseWithPreInit::get(C)) {
@@ -54,10 +54,11 @@
 
 public:
   OMPLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S,
-                  bool AsInlined = false)
+                  bool AsInlined = false, bool EmitPreInitStmt = true)
       : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
         InlinedShareds(CGF) {
-    emitPreInitStmt(CGF, S);
+    if (EmitPreInitStmt)
+      emitPreInitStmt(CGF, S);
     if (AsInlined) {
       if (S.hasAssociatedStmt()) {
         auto *CS = cast<CapturedStmt>(S.getAssociatedStmt());
@@ -81,6 +82,38 @@
   }
 };
 
+/// Lexical scope for OpenMP parallel construct, that handles correct codegen
+/// for captured expressions.
+class OMPParallelScope final : public OMPLexicalScope {
+  bool EmitPreInitStmt(const OMPExecutableDirective &S) {
+    OpenMPDirectiveKind Kind = S.getDirectiveKind();
+    return !isOpenMPTargetExecutionDirective(Kind) &&
+           isOpenMPParallelDirective(Kind);
+  }
+
+public:
+  OMPParallelScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
+      : OMPLexicalScope(CGF, S,
+                        /*AsInlined=*/false,
+                        /*EmitPreInitStmt=*/EmitPreInitStmt(S)) {}
+};
+
+/// Lexical scope for OpenMP teams construct, that handles correct codegen
+/// for captured expressions.
+class OMPTeamsScope final : public OMPLexicalScope {
+  bool EmitPreInitStmt(const OMPExecutableDirective &S) {
+    OpenMPDirectiveKind Kind = S.getDirectiveKind();
+    return !isOpenMPTargetExecutionDirective(Kind) &&
+           isOpenMPTeamsDirective(Kind);
+  }
+
+public:
+  OMPTeamsScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
+      : OMPLexicalScope(CGF, S,
+                        /*AsInlined=*/false,
+                        /*EmitPreInitStmt=*/EmitPreInitStmt(S)) {}
+};
+
 /// Private scope for OpenMP loop-based directives, that supports capturing
 /// of used expression from loop statement.
 class OMPLoopScope : public CodeGenFunction::RunCleanupsScope {
@@ -986,7 +1019,7 @@
                         OriginalBaseLValue);
         // Store the address of the original variable associated with the LHS
         // implicit variable.
-        PrivateScope.addPrivate(LHSVD, [this, OASELValueLB]() -> Address {
+        PrivateScope.addPrivate(LHSVD, [OASELValueLB]() -> Address {
           return OASELValueLB.getAddress();
         });
         // Emit reduction copy.
@@ -1040,9 +1073,8 @@
             *this, OrigVD->getType(), ASELValue.getType(), OriginalBaseLValue);
         // Store the address of the original variable associated with the LHS
         // implicit variable.
-        PrivateScope.addPrivate(LHSVD, [this, ASELValue]() -> Address {
-          return ASELValue.getAddress();
-        });
+        PrivateScope.addPrivate(
+            LHSVD, [ASELValue]() -> Address { return ASELValue.getAddress(); });
         // Emit reduction copy.
         bool IsRegistered = PrivateScope.addPrivate(
             OrigVD, [this, OrigVD, PrivateVD, BaseLValue, ASELValue,
@@ -1158,7 +1190,7 @@
 }
 
 void CodeGenFunction::EmitOMPReductionClauseFinal(
-    const OMPExecutableDirective &D) {
+    const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind) {
   if (!HaveInsertPoint())
     return;
   llvm::SmallVector<const Expr *, 8> Privates;
@@ -1174,14 +1206,15 @@
     ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
   }
   if (HasAtLeastOneReduction) {
+    bool WithNowait = D.getSingleClause<OMPNowaitClause>() ||
+                      isOpenMPParallelDirective(D.getDirectiveKind()) ||
+                      D.getDirectiveKind() == OMPD_simd;
+    bool SimpleReduction = D.getDirectiveKind() == OMPD_simd;
     // Emit nowait reduction if nowait clause is present or directive is a
     // parallel directive (it always has implicit barrier).
     CGM.getOpenMPRuntime().emitReduction(
         *this, D.getLocEnd(), Privates, LHSExprs, RHSExprs, ReductionOps,
-        D.getSingleClause<OMPNowaitClause>() ||
-            isOpenMPParallelDirective(D.getDirectiveKind()) ||
-            D.getDirectiveKind() == OMPD_simd,
-        D.getDirectiveKind() == OMPD_simd);
+        {WithNowait, SimpleReduction, ReductionKind});
   }
 }
 
@@ -1214,10 +1247,9 @@
                                            const OMPExecutableDirective &S,
                                            OpenMPDirectiveKind InnermostKind,
                                            const RegionCodeGenTy &CodeGen) {
-  auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
-  auto OutlinedFn = CGF.CGM.getOpenMPRuntime().
-      emitParallelOrTeamsOutlinedFunction(S,
-          *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
+  const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
+  auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction(
+      S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
   if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) {
     CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
     auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
@@ -1239,7 +1271,7 @@
     }
   }
 
-  OMPLexicalScope Scope(CGF, S);
+  OMPParallelScope Scope(CGF, S);
   llvm::SmallVector<llvm::Value *, 16> CapturedVars;
   CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
   CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn,
@@ -1264,7 +1296,7 @@
     CGF.EmitOMPReductionClauseInit(S, PrivateScope);
     (void)PrivateScope.Privatize();
     CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
-    CGF.EmitOMPReductionClauseFinal(S);
+    CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
   };
   emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen);
   emitPostUpdateForReductionClause(
@@ -1677,7 +1709,7 @@
       // Emit final copy of the lastprivate variables at the end of loops.
       if (HasLastprivateClause)
         CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true);
-      CGF.EmitOMPReductionClauseFinal(S);
+      CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd);
       emitPostUpdateForReductionClause(
           CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
     }
@@ -2003,6 +2035,46 @@
       });
 }
 
+void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective(
+    const OMPTargetTeamsDistributeDirective &S) {
+  CGM.getOpenMPRuntime().emitInlinedDirective(
+      *this, OMPD_target_teams_distribute,
+      [&S](CodeGenFunction &CGF, PrePostActionTy &) {
+        CGF.EmitStmt(
+            cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
+      });
+}
+
+void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective(
+    const OMPTargetTeamsDistributeParallelForDirective &S) {
+  CGM.getOpenMPRuntime().emitInlinedDirective(
+      *this, OMPD_target_teams_distribute_parallel_for,
+      [&S](CodeGenFunction &CGF, PrePostActionTy &) {
+        CGF.EmitStmt(
+            cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
+      });
+}
+
+void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective(
+    const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
+  CGM.getOpenMPRuntime().emitInlinedDirective(
+      *this, OMPD_target_teams_distribute_parallel_for_simd,
+      [&S](CodeGenFunction &CGF, PrePostActionTy &) {
+        CGF.EmitStmt(
+            cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
+      });
+}
+
+void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective(
+    const OMPTargetTeamsDistributeSimdDirective &S) {
+  CGM.getOpenMPRuntime().emitInlinedDirective(
+      *this, OMPD_target_teams_distribute_simd,
+      [&S](CodeGenFunction &CGF, PrePostActionTy &) {
+        CGF.EmitStmt(
+            cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
+      });
+}
+
 /// \brief Emit a helper variable and return corresponding lvalue.
 static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
                                const DeclRefExpr *Helper) {
@@ -2173,7 +2245,10 @@
                                CGF.EmitLoadOfScalar(IL, S.getLocStart()));
                          });
       }
-      EmitOMPReductionClauseFinal(S);
+      EmitOMPReductionClauseFinal(
+          S, /*ReductionKind=*/isOpenMPSimdDirective(S.getDirectiveKind())
+                 ? /*Parallel and Simd*/ OMPD_parallel_for_simd
+                 : /*Parallel only*/ OMPD_parallel);
       // Emit post-update of the reduction variables if IsLastIter != 0.
       emitPostUpdateForReductionClause(
           *this, S, [&](CodeGenFunction &CGF) -> llvm::Value * {
@@ -2348,7 +2423,7 @@
       CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
     };
     CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
-    CGF.EmitOMPReductionClauseFinal(S);
+    CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
     // Emit post-update of the reduction variables if IsLastIter != 0.
     emitPostUpdateForReductionClause(
         CGF, S, [&](CodeGenFunction &CGF) -> llvm::Value * {
@@ -2584,7 +2659,7 @@
   for (const auto *C : S.getClausesOfKind<OMPDependClause>())
     for (auto *IRef : C->varlists())
       Data.Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef));
-  auto &&CodeGen = [PartId, &S, &Data, CS, &BodyGen, &LastprivateDstsOrigs](
+  auto &&CodeGen = [&Data, CS, &BodyGen, &LastprivateDstsOrigs](
       CodeGenFunction &CGF, PrePostActionTy &Action) {
     // Set proper addresses for generated private copies.
     OMPPrivateScope Scope(CGF);
@@ -2731,6 +2806,7 @@
 
   auto &RT = CGM.getOpenMPRuntime();
 
+  bool HasLastprivateClause = false;
   // Check pre-condition.
   {
     OMPLoopScope PreInitScope(*this, S);
@@ -2764,6 +2840,16 @@
           EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
 
       OMPPrivateScope LoopScope(*this);
+      if (EmitOMPFirstprivateClause(S, LoopScope)) {
+        // Emit implicit barrier to synchronize threads and avoid data races on
+        // initialization of firstprivate variables and post-update of
+        // lastprivate variables.
+        CGM.getOpenMPRuntime().emitBarrierCall(
+          *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
+          /*ForceSimpleCall=*/true);
+      }
+      EmitOMPPrivateClause(S, LoopScope);
+      HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
       EmitOMPPrivateLoopCounters(S, LoopScope);
       (void)LoopScope.Privatize();
 
@@ -2820,6 +2906,13 @@
                             LB.getAddress(), UB.getAddress(), ST.getAddress(),
                             IL.getAddress(), Chunk);
       }
+
+      // Emit final copy of the lastprivate variables if IsLastIter != 0.
+      if (HasLastprivateClause)
+        EmitOMPLastprivateClauseFinal(
+            S, /*NoFinals=*/false,
+            Builder.CreateIsNotNull(
+                EmitLoadOfScalar(IL, S.getLocStart())));
     }
 
     // We're now done with the loop, so jump to the continuation block.
@@ -3183,7 +3276,7 @@
     NewVValType = XRValExpr->getType();
     auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
     auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
-                  IsSeqCst, IsPostfixUpdate](RValue XRValue) -> RValue {
+                  IsPostfixUpdate](RValue XRValue) -> RValue {
       CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
       CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
       RValue Res = CGF.EmitAnyExpr(UE);
@@ -3210,7 +3303,7 @@
     NewVValType = X->getType().getNonReferenceType();
     ExprRValue = convertToType(CGF, ExprRValue, E->getType(),
                                X->getType().getNonReferenceType(), Loc);
-    auto &&Gen = [&CGF, &NewVVal, ExprRValue](RValue XRValue) -> RValue {
+    auto &&Gen = [&NewVVal, ExprRValue](RValue XRValue) -> RValue {
       NewVVal = XRValue;
       return ExprRValue;
     };
@@ -3337,41 +3430,24 @@
   CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen);
 }
 
-std::pair<llvm::Function * /*OutlinedFn*/, llvm::Constant * /*OutlinedFnID*/>
-CodeGenFunction::EmitOMPTargetDirectiveOutlinedFunction(
-    CodeGenModule &CGM, const OMPTargetDirective &S, StringRef ParentName,
-    bool IsOffloadEntry) {
-  llvm::Function *OutlinedFn = nullptr;
-  llvm::Constant *OutlinedFnID = nullptr;
-  auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
-    OMPPrivateScope PrivateScope(CGF);
-    (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
-    CGF.EmitOMPPrivateClause(S, PrivateScope);
-    (void)PrivateScope.Privatize();
-
-    Action.Enter(CGF);
-    CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
-  };
-  // Emit target region as a standalone region.
-  CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
-      S, ParentName, OutlinedFn, OutlinedFnID, IsOffloadEntry, CodeGen);
-  return std::make_pair(OutlinedFn, OutlinedFnID);
-}
-
-void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
+static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
+                                         const OMPExecutableDirective &S,
+                                         const RegionCodeGenTy &CodeGen) {
+  assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind()));
+  CodeGenModule &CGM = CGF.CGM;
   const CapturedStmt &CS = *cast<CapturedStmt>(S.getAssociatedStmt());
 
-  llvm::SmallVector<llvm::Value *, 16> CapturedVars;
-  GenerateOpenMPCapturedVars(CS, CapturedVars);
-
   llvm::Function *Fn = nullptr;
   llvm::Constant *FnID = nullptr;
 
-  // Check if we have any if clause associated with the directive.
   const Expr *IfCond = nullptr;
-
-  if (auto *C = S.getSingleClause<OMPIfClause>()) {
-    IfCond = C->getCondition();
+  // Check for the at most one if clause associated with the target region.
+  for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
+    if (C->getNameModifier() == OMPD_unknown ||
+        C->getNameModifier() == OMPD_target) {
+      IfCond = C->getCondition();
+      break;
+    }
   }
 
   // Check if we have any device clause associated with the directive.
@@ -3386,43 +3462,76 @@
   bool IsOffloadEntry = true;
   if (IfCond) {
     bool Val;
-    if (ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
+    if (CGF.ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
       IsOffloadEntry = false;
   }
   if (CGM.getLangOpts().OMPTargetTriples.empty())
     IsOffloadEntry = false;
 
-  assert(CurFuncDecl && "No parent declaration for target region!");
+  assert(CGF.CurFuncDecl && "No parent declaration for target region!");
   StringRef ParentName;
   // In case we have Ctors/Dtors we use the complete type variant to produce
   // the mangling of the device outlined kernel.
-  if (auto *D = dyn_cast<CXXConstructorDecl>(CurFuncDecl))
+  if (auto *D = dyn_cast<CXXConstructorDecl>(CGF.CurFuncDecl))
     ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete));
-  else if (auto *D = dyn_cast<CXXDestructorDecl>(CurFuncDecl))
+  else if (auto *D = dyn_cast<CXXDestructorDecl>(CGF.CurFuncDecl))
     ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete));
   else
     ParentName =
-        CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CurFuncDecl)));
+        CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CGF.CurFuncDecl)));
 
-  std::tie(Fn, FnID) = EmitOMPTargetDirectiveOutlinedFunction(
-      CGM, S, ParentName, IsOffloadEntry);
-  OMPLexicalScope Scope(*this, S);
-  CGM.getOpenMPRuntime().emitTargetCall(*this, S, Fn, FnID, IfCond, Device,
+  // Emit target region as a standalone region.
+  CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID,
+                                                    IsOffloadEntry, CodeGen);
+  OMPLexicalScope Scope(CGF, S);
+  llvm::SmallVector<llvm::Value *, 16> CapturedVars;
+  CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
+  CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device,
                                         CapturedVars);
 }
 
+static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S,
+                             PrePostActionTy &Action) {
+  CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
+  (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
+  CGF.EmitOMPPrivateClause(S, PrivateScope);
+  (void)PrivateScope.Privatize();
+
+  Action.Enter(CGF);
+  CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
+}
+
+void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
+                                                  StringRef ParentName,
+                                                  const OMPTargetDirective &S) {
+  auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
+    emitTargetRegion(CGF, S, Action);
+  };
+  llvm::Function *Fn;
+  llvm::Constant *Addr;
+  // Emit target region as a standalone region.
+  CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
+      S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
+  assert(Fn && Addr && "Target device function emission failed.");
+}
+
+void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
+  auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
+    emitTargetRegion(CGF, S, Action);
+  };
+  emitCommonOMPTargetDirective(*this, S, CodeGen);
+}
+
 static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
                                         const OMPExecutableDirective &S,
                                         OpenMPDirectiveKind InnermostKind,
                                         const RegionCodeGenTy &CodeGen) {
-  auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
-  auto OutlinedFn = CGF.CGM.getOpenMPRuntime().
-      emitParallelOrTeamsOutlinedFunction(S,
-          *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
+  const CapturedStmt *CS = S.getCapturedStmt(OMPD_teams);
+  auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitTeamsOutlinedFunction(
+      S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
 
-  const OMPTeamsDirective &TD = *dyn_cast<OMPTeamsDirective>(&S);
-  const OMPNumTeamsClause *NT = TD.getSingleClause<OMPNumTeamsClause>();
-  const OMPThreadLimitClause *TL = TD.getSingleClause<OMPThreadLimitClause>();
+  const OMPNumTeamsClause *NT = S.getSingleClause<OMPNumTeamsClause>();
+  const OMPThreadLimitClause *TL = S.getSingleClause<OMPThreadLimitClause>();
   if (NT || TL) {
     Expr *NumTeams = (NT) ? NT->getNumTeams() : nullptr;
     Expr *ThreadLimit = (TL) ? TL->getThreadLimit() : nullptr;
@@ -3431,7 +3540,7 @@
                                                   S.getLocStart());
   }
 
-  OMPLexicalScope Scope(CGF, S);
+  OMPTeamsScope Scope(CGF, S);
   llvm::SmallVector<llvm::Value *, 16> CapturedVars;
   CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
   CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getLocStart(), OutlinedFn,
@@ -3439,15 +3548,52 @@
 }
 
 void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) {
-  // Emit parallel region as a standalone region.
+  // Emit teams region as a standalone region.
   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
     OMPPrivateScope PrivateScope(CGF);
     (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
     CGF.EmitOMPPrivateClause(S, PrivateScope);
+    CGF.EmitOMPReductionClauseInit(S, PrivateScope);
     (void)PrivateScope.Privatize();
     CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
+    CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
   };
   emitCommonOMPTeamsDirective(*this, S, OMPD_teams, CodeGen);
+  emitPostUpdateForReductionClause(
+      *this, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
+}
+
+static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
+                                  const OMPTargetTeamsDirective &S) {
+  auto *CS = S.getCapturedStmt(OMPD_teams);
+  Action.Enter(CGF);
+  auto &&CodeGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
+    // TODO: Add support for clauses.
+    CGF.EmitStmt(CS->getCapturedStmt());
+  };
+  emitCommonOMPTeamsDirective(CGF, S, OMPD_teams, CodeGen);
+}
+
+void CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
+    CodeGenModule &CGM, StringRef ParentName,
+    const OMPTargetTeamsDirective &S) {
+  auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
+    emitTargetTeamsRegion(CGF, Action, S);
+  };
+  llvm::Function *Fn;
+  llvm::Constant *Addr;
+  // Emit target region as a standalone region.
+  CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
+      S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
+  assert(Fn && Addr && "Target device function emission failed.");
+}
+
+void CodeGenFunction::EmitOMPTargetTeamsDirective(
+    const OMPTargetTeamsDirective &S) {
+  auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
+    emitTargetTeamsRegion(CGF, Action, S);
+  };
+  emitCommonOMPTargetDirective(*this, S, CodeGen);
 }
 
 void CodeGenFunction::EmitOMPCancellationPointDirective(
@@ -3673,9 +3819,47 @@
   CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
 }
 
+static void emitTargetParallelRegion(CodeGenFunction &CGF,
+                                     const OMPTargetParallelDirective &S,
+                                     PrePostActionTy &Action) {
+  // Get the captured statement associated with the 'parallel' region.
+  auto *CS = S.getCapturedStmt(OMPD_parallel);
+  Action.Enter(CGF);
+  auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &) {
+    CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
+    (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
+    CGF.EmitOMPPrivateClause(S, PrivateScope);
+    CGF.EmitOMPReductionClauseInit(S, PrivateScope);
+    (void)PrivateScope.Privatize();
+    // TODO: Add support for clauses.
+    CGF.EmitStmt(CS->getCapturedStmt());
+    CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
+  };
+  emitCommonOMPParallelDirective(CGF, S, OMPD_parallel, CodeGen);
+  emitPostUpdateForReductionClause(
+      CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
+}
+
+void CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
+    CodeGenModule &CGM, StringRef ParentName,
+    const OMPTargetParallelDirective &S) {
+  auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
+    emitTargetParallelRegion(CGF, S, Action);
+  };
+  llvm::Function *Fn;
+  llvm::Constant *Addr;
+  // Emit target region as a standalone region.
+  CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
+      S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
+  assert(Fn && Addr && "Target device function emission failed.");
+}
+
 void CodeGenFunction::EmitOMPTargetParallelDirective(
     const OMPTargetParallelDirective &S) {
-  // TODO: codegen for target parallel.
+  auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
+    emitTargetParallelRegion(CGF, S, Action);
+  };
+  emitCommonOMPTargetDirective(*this, S, CodeGen);
 }
 
 void CodeGenFunction::EmitOMPTargetParallelForDirective(
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp
index 5b90ee6..92fd93b 100644
--- a/lib/CodeGen/CGVTT.cpp
+++ b/lib/CodeGen/CGVTT.cpp
@@ -23,7 +23,7 @@
                    const CXXRecordDecl *MostDerivedClass,
                    const VTTVTable &VTable,
                    llvm::GlobalVariable::LinkageTypes Linkage,
-                   llvm::DenseMap<BaseSubobject, uint64_t> &AddressPoints) {
+                   VTableLayout::AddressPointsMapTy &AddressPoints) {
   if (VTable.getBase() == MostDerivedClass) {
     assert(VTable.getBaseOffset().isZero() &&
            "Most derived class vtable must have a zero offset!");
@@ -62,25 +62,27 @@
                           *e = Builder.getVTTComponents().end(); i != e; ++i) {
     const VTTVTable &VTTVT = Builder.getVTTVTables()[i->VTableIndex];
     llvm::GlobalVariable *VTable = VTables[i->VTableIndex];
-    uint64_t AddressPoint;
+    VTableLayout::AddressPointLocation AddressPoint;
     if (VTTVT.getBase() == RD) {
       // Just get the address point for the regular vtable.
       AddressPoint =
           getItaniumVTableContext().getVTableLayout(RD).getAddressPoint(
               i->VTableBase);
-      assert(AddressPoint != 0 && "Did not find vtable address point!");
     } else {
       AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase);
-      assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
+      assert(AddressPoint.AddressPointIndex != 0 &&
+             "Did not find ctor vtable address point!");
     }
 
      llvm::Value *Idxs[] = {
        llvm::ConstantInt::get(Int32Ty, 0),
-       llvm::ConstantInt::get(Int32Ty, AddressPoint)
+       llvm::ConstantInt::get(Int32Ty, AddressPoint.VTableIndex),
+       llvm::ConstantInt::get(Int32Ty, AddressPoint.AddressPointIndex),
      };
 
-     llvm::Constant *Init = llvm::ConstantExpr::getInBoundsGetElementPtr(
-         VTable->getValueType(), VTable, Idxs);
+     llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr(
+         VTable->getValueType(), VTable, Idxs, /*InBounds=*/true,
+         /*InRangeIndex=*/1);
 
      Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
 
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index be9c311..1907b8b 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -14,7 +14,7 @@
 #include "CGCXXABI.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
@@ -284,6 +284,9 @@
   if (isa<CXXDestructorDecl>(MD))
     CGM.getCXXABI().adjustCallArgsForDestructorThunk(*this, CurGD, CallArgs);
 
+#ifndef NDEBUG
+  unsigned PrefixArgs = CallArgs.size() - 1;
+#endif
   // Add the rest of the arguments.
   for (const ParmVarDecl *PD : MD->parameters())
     EmitDelegateCallArg(CallArgs, PD, SourceLocation());
@@ -292,7 +295,7 @@
 
 #ifndef NDEBUG
   const CGFunctionInfo &CallFnInfo = CGM.getTypes().arrangeCXXMethodCall(
-      CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1, MD));
+      CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1, MD), PrefixArgs);
   assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
          CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
          CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention());
@@ -637,12 +640,27 @@
   llvm_unreachable("Unexpected vtable component kind");
 }
 
-void CodeGenVTables::createVTableInitializer(ConstantArrayBuilder &builder,
+llvm::Type *CodeGenVTables::getVTableType(const VTableLayout &layout) {
+  SmallVector<llvm::Type *, 4> tys;
+  for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i) {
+    tys.push_back(llvm::ArrayType::get(CGM.Int8PtrTy, layout.getVTableSize(i)));
+  }
+
+  return llvm::StructType::get(CGM.getLLVMContext(), tys);
+}
+
+void CodeGenVTables::createVTableInitializer(ConstantStructBuilder &builder,
                                              const VTableLayout &layout,
                                              llvm::Constant *rtti) {
   unsigned nextVTableThunkIndex = 0;
-  for (unsigned i = 0, e = layout.vtable_components().size(); i != e; ++i) {
-    addVTableComponent(builder, layout, i, rtti, nextVTableThunkIndex);
+  for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i) {
+    auto vtableElem = builder.beginArray(CGM.Int8PtrTy);
+    size_t thisIndex = layout.getVTableOffset(i);
+    size_t nextIndex = thisIndex + layout.getVTableSize(i);
+    for (unsigned i = thisIndex; i != nextIndex; ++i) {
+      addVTableComponent(vtableElem, layout, i, rtti, nextVTableThunkIndex);
+    }
+    vtableElem.finishAndAddTo(builder);
   }
 }
 
@@ -670,8 +688,7 @@
                            Base.getBase(), Out);
   StringRef Name = OutName.str();
 
-  llvm::ArrayType *ArrayType =
-      llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout->vtable_components().size());
+  llvm::Type *VTType = getVTableType(*VTLayout);
 
   // Construction vtable symbols are not part of the Itanium ABI, so we cannot
   // guarantee that they actually will be available externally. Instead, when
@@ -683,7 +700,7 @@
 
   // Create the variable that will hold the construction vtable.
   llvm::GlobalVariable *VTable =
-    CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, Linkage);
+    CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage);
   CGM.setGlobalVisibility(VTable, RD);
 
   // V-tables are always unnamed_addr.
@@ -694,7 +711,7 @@
 
   // Create and set the initializer.
   ConstantInitBuilder builder(CGM);
-  auto components = builder.beginArray(CGM.Int8PtrTy);
+  auto components = builder.beginStruct();
   createVTableInitializer(components, *VTLayout, RTTI);
   components.finishAndSetAsInitializer(VTable);
 
@@ -730,9 +747,10 @@
     switch (keyFunction->getTemplateSpecializationKind()) {
       case TSK_Undeclared:
       case TSK_ExplicitSpecialization:
-        assert((def || CodeGenOpts.OptimizationLevel > 0) &&
-               "Shouldn't query vtable linkage without key function or "
-               "optimizations");
+        assert((def || CodeGenOpts.OptimizationLevel > 0 ||
+                CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) &&
+               "Shouldn't query vtable linkage without key function, "
+               "optimizations, or debug info");
         if (!def && CodeGenOpts.OptimizationLevel > 0)
           return llvm::GlobalVariable::AvailableExternallyLinkage;
 
@@ -928,7 +946,7 @@
 
 void CodeGenModule::EmitVTableTypeMetadata(llvm::GlobalVariable *VTable,
                                            const VTableLayout &VTLayout) {
-  if (!getCodeGenOpts().PrepareForLTO)
+  if (!getCodeGenOpts().LTOUnit)
     return;
 
   CharUnits PointerWidth =
@@ -938,7 +956,10 @@
   std::vector<BSEntry> BitsetEntries;
   // Create a bit set entry for each address point.
   for (auto &&AP : VTLayout.getAddressPoints())
-    BitsetEntries.push_back(std::make_pair(AP.first.getBase(), AP.second));
+    BitsetEntries.push_back(
+        std::make_pair(AP.first.getBase(),
+                       VTLayout.getVTableOffset(AP.second.VTableIndex) +
+                           AP.second.AddressPointIndex));
 
   // Sort the bit set entries for determinism.
   std::sort(BitsetEntries.begin(), BitsetEntries.end(),
diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h
index 1d06832..b92212c 100644
--- a/lib/CodeGen/CGVTables.h
+++ b/lib/CodeGen/CGVTables.h
@@ -28,6 +28,7 @@
 namespace CodeGen {
   class CodeGenModule;
   class ConstantArrayBuilder;
+  class ConstantStructBuilder;
 
 class CodeGenVTables {
   CodeGenModule &CGM;
@@ -35,7 +36,7 @@
   VTableContextBase *VTContext;
 
   /// VTableAddressPointsMapTy - Address points for a single vtable.
-  typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
+  typedef VTableLayout::AddressPointsMapTy VTableAddressPointsMapTy;
 
   typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
   typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy;
@@ -71,7 +72,7 @@
 public:
   /// Add vtable components for the given vtable layout to the given
   /// global initializer.
-  void createVTableInitializer(ConstantArrayBuilder &builder,
+  void createVTableInitializer(ConstantStructBuilder &builder,
                                const VTableLayout &layout,
                                llvm::Constant *rtti);
 
@@ -121,6 +122,11 @@
   void GenerateClassData(const CXXRecordDecl *RD);
 
   bool isVTableExternal(const CXXRecordDecl *RD);
+
+  /// Returns the type of a vtable with the given layout. Normally a struct of
+  /// arrays of pointers, with one struct element for each vtable in the vtable
+  /// group.
+  llvm::Type *getVTableType(const VTableLayout &layout);
 };
 
 } // end namespace CodeGen
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index b013eb9..84248cc 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -14,6 +14,7 @@
   MC
   ObjCARCOpts
   Object
+  Passes
   ProfileData
   ScalarOpts
   Support
@@ -35,7 +36,6 @@
   CGAtomic.cpp
   CGBlocks.cpp
   CGBuiltin.cpp
-  CGCUDABuiltin.cpp
   CGCUDANV.cpp
   CGCUDARuntime.cpp
   CGCXX.cpp
@@ -54,6 +54,7 @@
   CGExprComplex.cpp
   CGExprConstant.cpp
   CGExprScalar.cpp
+  CGGPUBuiltin.cpp
   CGLoopInfo.cpp
   CGObjC.cpp
   CGObjCGNU.cpp
@@ -74,8 +75,10 @@
   CodeGenPGO.cpp
   CodeGenTBAA.cpp
   CodeGenTypes.cpp
+  ConstantInitBuilder.cpp
   CoverageMappingGen.cpp
   ItaniumCXXABI.cpp
+  MacroPPCallbacks.cpp
   MicrosoftCXXABI.cpp
   ModuleBuilder.cpp
   ObjectFilePCHContainerOperations.cpp
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp
index 1e17918..b864069 100644
--- a/lib/CodeGen/CodeGenAction.cpp
+++ b/lib/CodeGen/CodeGenAction.cpp
@@ -7,7 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/CodeGen/CodeGenAction.h"
+#include "CodeGenModule.h"
 #include "CoverageMappingGen.h"
+#include "MacroPPCallbacks.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
@@ -16,15 +19,16 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/CodeGen/BackendUtil.h"
-#include "clang/CodeGen/CodeGenAction.h"
 #include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IRReader/IRReader.h"
@@ -35,15 +39,20 @@
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Support/YAMLTraits.h"
+#include "llvm/Transforms/IPO/Internalize.h"
+
 #include <memory>
 using namespace clang;
 using namespace llvm;
 
 namespace clang {
   class BackendConsumer : public ASTConsumer {
+    using LinkModule = CodeGenAction::LinkModule;
+
     virtual void anchor();
     DiagnosticsEngine &Diags;
     BackendAction Action;
+    const HeaderSearchOptions &HeaderSearchOpts;
     const CodeGenOptions &CodeGenOpts;
     const TargetOptions &TargetOpts;
     const LangOptions &LangOpts;
@@ -60,43 +69,39 @@
 
     std::unique_ptr<CodeGenerator> Gen;
 
-    SmallVector<std::pair<unsigned, std::unique_ptr<llvm::Module>>, 4>
-        LinkModules;
+    SmallVector<LinkModule, 4> LinkModules;
 
     // This is here so that the diagnostic printer knows the module a diagnostic
     // refers to.
     llvm::Module *CurLinkModule = nullptr;
 
   public:
-    BackendConsumer(
-        BackendAction Action, DiagnosticsEngine &Diags,
-        const HeaderSearchOptions &HeaderSearchOpts,
-        const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts,
-        const TargetOptions &TargetOpts, const LangOptions &LangOpts,
-        bool TimePasses, const std::string &InFile,
-        const SmallVectorImpl<std::pair<unsigned, llvm::Module *>> &LinkModules,
-        std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C,
-        CoverageSourceInfo *CoverageInfo = nullptr)
-        : Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts),
-          TargetOpts(TargetOpts), LangOpts(LangOpts),
+    BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
+                    const HeaderSearchOptions &HeaderSearchOpts,
+                    const PreprocessorOptions &PPOpts,
+                    const CodeGenOptions &CodeGenOpts,
+                    const TargetOptions &TargetOpts,
+                    const LangOptions &LangOpts, bool TimePasses,
+                    const std::string &InFile,
+                    SmallVector<LinkModule, 4> LinkModules,
+                    std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C,
+                    CoverageSourceInfo *CoverageInfo = nullptr)
+        : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
+          CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
           AsmOutStream(std::move(OS)), Context(nullptr),
           LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
           LLVMIRGenerationRefCount(0),
           Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
-                                CodeGenOpts, C, CoverageInfo)) {
+                                CodeGenOpts, C, CoverageInfo)),
+          LinkModules(std::move(LinkModules)) {
       llvm::TimePassesIsEnabled = TimePasses;
-      for (auto &I : LinkModules)
-        this->LinkModules.push_back(
-            std::make_pair(I.first, std::unique_ptr<llvm::Module>(I.second)));
     }
     llvm::Module *getModule() const { return Gen->GetModule(); }
     std::unique_ptr<llvm::Module> takeModule() {
       return std::unique_ptr<llvm::Module>(Gen->ReleaseModule());
     }
-    void releaseLinkModules() {
-      for (auto &I : LinkModules)
-        I.second.release();
-    }
+
+    CodeGenerator *getCodeGenerator() { return Gen.get(); }
 
     void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
       Gen->HandleCXXStaticMemberVarInstantiation(VD);
@@ -158,6 +163,35 @@
         HandleTopLevelDecl(D);
     }
 
+    // Links each entry in LinkModules into our module.  Returns true on error.
+    bool LinkInModules() {
+      for (auto &LM : LinkModules) {
+        if (LM.PropagateAttrs)
+          for (Function &F : *LM.Module)
+            Gen->CGM().AddDefaultFnAttrs(F);
+
+        CurLinkModule = LM.Module.get();
+
+        bool Err;
+        if (LM.Internalize) {
+          Err = Linker::linkModules(
+              *getModule(), std::move(LM.Module), LM.LinkFlags,
+              [](llvm::Module &M, const llvm::StringSet<> &GVS) {
+                internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) {
+                  return !GV.hasName() || (GVS.count(GV.getName()) == 0);
+                });
+              });
+        } else {
+          Err = Linker::linkModules(*getModule(), std::move(LM.Module),
+                                    LM.LinkFlags);
+        }
+
+        if (Err)
+          return true;
+      }
+      return false; // success
+    }
+
     void HandleTranslationUnit(ASTContext &C) override {
       {
         PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
@@ -215,18 +249,14 @@
           Ctx.setDiagnosticHotnessRequested(true);
       }
 
-      // Link LinkModule into this module if present, preserving its validity.
-      for (auto &I : LinkModules) {
-        unsigned LinkFlags = I.first;
-        CurLinkModule = I.second.get();
-        if (Linker::linkModules(*getModule(), std::move(I.second), LinkFlags))
-          return;
-      }
+      // Link each LinkModule into our module.
+      if (LinkInModules())
+        return;
 
       EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef());
 
-      EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
-                        C.getTargetInfo().getDataLayout(),
+      EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
+                        LangOpts, C.getTargetInfo().getDataLayout(),
                         getModule(), Action, std::move(AsmOutStream));
 
       Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
@@ -274,7 +304,7 @@
     /// Get the best possible source location to represent a diagnostic that
     /// may have associated debug info.
     const FullSourceLoc
-    getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithDebugLocBase &D,
+    getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithLocationBase &D,
                                 bool &BadDebugInfo, StringRef &Filename,
                                 unsigned &Line, unsigned &Column) const;
 
@@ -297,9 +327,8 @@
     /// them.
     void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
                                  unsigned DiagID);
-    void OptimizationRemarkHandler(const llvm::OptimizationRemark &D);
-    void OptimizationRemarkHandler(const llvm::OptimizationRemarkMissed &D);
-    void OptimizationRemarkHandler(const llvm::OptimizationRemarkAnalysis &D);
+    void
+    OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D);
     void OptimizationRemarkHandler(
         const llvm::OptimizationRemarkAnalysisFPCommute &D);
     void OptimizationRemarkHandler(
@@ -307,7 +336,7 @@
     void OptimizationFailureHandler(
         const llvm::DiagnosticInfoOptimizationFailure &D);
   };
-  
+
   void BackendConsumer::anchor() {}
 }
 
@@ -376,7 +405,7 @@
   // code.
   if (LocCookie.isValid()) {
     Diags.Report(LocCookie, DiagID).AddString(Message);
-    
+
     if (D.getLoc().isValid()) {
       DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
       // Convert the SMDiagnostic ranges into SourceRange and attach them
@@ -389,7 +418,7 @@
     }
     return;
   }
-  
+
   // 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.
@@ -476,8 +505,8 @@
 }
 
 const FullSourceLoc BackendConsumer::getBestLocationFromDebugLoc(
-    const llvm::DiagnosticInfoWithDebugLocBase &D, bool &BadDebugInfo, StringRef &Filename,
-                                unsigned &Line, unsigned &Column) const {
+    const llvm::DiagnosticInfoWithLocationBase &D, bool &BadDebugInfo,
+    StringRef &Filename, unsigned &Line, unsigned &Column) const {
   SourceManager &SourceMgr = Context->getSourceManager();
   FileManager &FileMgr = SourceMgr.getFileManager();
   SourceLocation DILoc;
@@ -567,36 +596,34 @@
 }
 
 void BackendConsumer::OptimizationRemarkHandler(
-    const llvm::OptimizationRemark &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()))
-    EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark);
-}
+    const llvm::DiagnosticInfoOptimizationBase &D) {
+  if (D.isPassed()) {
+    // 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()))
+      EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark);
+  } else if (D.isMissed()) {
+    // 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()))
+      EmitOptimizationMessage(
+          D, diag::remark_fe_backend_optimization_remark_missed);
+  } else {
+    assert(D.isAnalysis() && "Unknown remark type");
 
-void BackendConsumer::OptimizationRemarkHandler(
-    const llvm::OptimizationRemarkMissed &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()))
-    EmitOptimizationMessage(D,
-                            diag::remark_fe_backend_optimization_remark_missed);
-}
+    bool ShouldAlwaysPrint = false;
+    if (auto *ORA = dyn_cast<llvm::OptimizationRemarkAnalysis>(&D))
+      ShouldAlwaysPrint = ORA->shouldAlwaysPrint();
 
-void BackendConsumer::OptimizationRemarkHandler(
-    const llvm::OptimizationRemarkAnalysis &D) {
-  // Optimization analysis remarks are active if the pass name is set to
-  // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a
-  // regular expression that matches the name of the pass name in \p D.
-
-  if (D.shouldAlwaysPrint() ||
-      (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
-       CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
-    EmitOptimizationMessage(
-        D, diag::remark_fe_backend_optimization_remark_analysis);
+    if (ShouldAlwaysPrint ||
+        (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
+         CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
+      EmitOptimizationMessage(
+          D, diag::remark_fe_backend_optimization_remark_analysis);
+  }
 }
 
 void BackendConsumer::OptimizationRemarkHandler(
@@ -679,6 +706,21 @@
     // handler. There is no generic way of emitting them.
     OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisAliasing>(DI));
     return;
+  case llvm::DK_MachineOptimizationRemark:
+    // Optimization remarks are always handled completely by this
+    // handler. There is no generic way of emitting them.
+    OptimizationRemarkHandler(cast<MachineOptimizationRemark>(DI));
+    return;
+  case llvm::DK_MachineOptimizationRemarkMissed:
+    // Optimization remarks are always handled completely by this
+    // handler. There is no generic way of emitting them.
+    OptimizationRemarkHandler(cast<MachineOptimizationRemarkMissed>(DI));
+    return;
+  case llvm::DK_MachineOptimizationRemarkAnalysis:
+    // Optimization remarks are always handled completely by this
+    // handler. There is no generic way of emitting them.
+    OptimizationRemarkHandler(cast<MachineOptimizationRemarkAnalysis>(DI));
+    return;
   case llvm::DK_OptimizationFailure:
     // Optimization failures are always handled completely by this
     // handler.
@@ -728,10 +770,6 @@
   if (!getCompilerInstance().hasASTConsumer())
     return;
 
-  // Take back ownership of link modules we passed to consumer.
-  if (!LinkModules.empty())
-    BEConsumer->releaseLinkModules();
-
   // Steal the module from the consumer.
   TheModule = BEConsumer->takeModule();
 }
@@ -774,13 +812,12 @@
 
   // Load bitcode modules to link with, if we need to.
   if (LinkModules.empty())
-    for (auto &I : CI.getCodeGenOpts().LinkBitcodeFiles) {
-      const std::string &LinkBCFile = I.second;
-
-      auto BCBuf = CI.getFileManager().getBufferForFile(LinkBCFile);
+    for (const CodeGenOptions::BitcodeFileToLink &F :
+         CI.getCodeGenOpts().LinkBitcodeFiles) {
+      auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename);
       if (!BCBuf) {
         CI.getDiagnostics().Report(diag::err_cannot_open_file)
-            << LinkBCFile << BCBuf.getError().message();
+            << F.Filename << BCBuf.getError().message();
         LinkModules.clear();
         return nullptr;
       }
@@ -790,12 +827,13 @@
       if (!ModuleOrErr) {
         handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
           CI.getDiagnostics().Report(diag::err_cannot_open_file)
-              << LinkBCFile << EIB.message();
+              << F.Filename << EIB.message();
         });
         LinkModules.clear();
         return nullptr;
       }
-      addLinkModule(ModuleOrErr.get().release(), I.first);
+      LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs,
+                             F.Internalize, F.LinkFlags});
     }
 
   CoverageSourceInfo *CoverageInfo = nullptr;
@@ -809,9 +847,20 @@
   std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
       BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
       CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
-      CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, LinkModules,
-      std::move(OS), *VMContext, CoverageInfo));
+      CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile,
+      std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo));
   BEConsumer = Result.get();
+
+  // Enable generating macro debug info only when debug info is not disabled and
+  // also macro debug info is enabled.
+  if (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo &&
+      CI.getCodeGenOpts().MacroDebugInfo) {
+    std::unique_ptr<PPCallbacks> Callbacks =
+        llvm::make_unique<MacroPPCallbacks>(BEConsumer->getCodeGenerator(),
+                                            CI.getPreprocessor());
+    CI.getPreprocessor().addPPCallbacks(std::move(Callbacks));
+  }
+
   return std::move(Result);
 }
 
@@ -837,6 +886,62 @@
   Diags->Report(DiagID).AddString("cannot compile inline asm");
 }
 
+std::unique_ptr<llvm::Module> CodeGenAction::loadModule(MemoryBufferRef MBRef) {
+  CompilerInstance &CI = getCompilerInstance();
+  SourceManager &SM = CI.getSourceManager();
+
+  // For ThinLTO backend invocations, ensure that the context
+  // merges types based on ODR identifiers. We also need to read
+  // the correct module out of a multi-module bitcode file.
+  if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) {
+    VMContext->enableDebugTypeODRUniquing();
+
+    auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> {
+      unsigned DiagID =
+          CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
+      handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
+        CI.getDiagnostics().Report(DiagID) << EIB.message();
+      });
+      return {};
+    };
+
+    Expected<llvm::BitcodeModule> BMOrErr = FindThinLTOModule(MBRef);
+    if (!BMOrErr)
+      return DiagErrors(BMOrErr.takeError());
+
+    Expected<std::unique_ptr<llvm::Module>> MOrErr =
+        BMOrErr->parseModule(*VMContext);
+    if (!MOrErr)
+      return DiagErrors(MOrErr.takeError());
+    return std::move(*MOrErr);
+  }
+
+  llvm::SMDiagnostic Err;
+  if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext))
+    return M;
+
+  // 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(SM.getMainFileID()),
+                                  Err.getLineNo(), Err.getColumnNo() + 1);
+  }
+
+  // Strip off a leading diagnostic code if there is one.
+  StringRef Msg = Err.getMessage();
+  if (Msg.startswith("error: "))
+    Msg = Msg.substr(7);
+
+  unsigned DiagID =
+      CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
+
+  CI.getDiagnostics().Report(Loc, DiagID) << Msg;
+  return {};
+}
+
 void CodeGenAction::ExecuteAction() {
   // If this is an IR file, we have to treat it specially.
   if (getCurrentFileKind() == IK_LLVM_IR) {
@@ -854,35 +959,10 @@
     if (Invalid)
       return;
 
-    // For ThinLTO backend invocations, ensure that the context
-    // merges types based on ODR identifiers.
-    if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty())
-      VMContext->enableDebugTypeODRUniquing();
-
-    llvm::SMDiagnostic Err;
-    TheModule = parseIR(MainFile->getMemBufferRef(), Err, *VMContext);
-    if (!TheModule) {
-      // 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();
-      if (Msg.startswith("error: "))
-        Msg = Msg.substr(7);
-
-      unsigned DiagID =
-          CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
-
-      CI.getDiagnostics().Report(Loc, DiagID) << Msg;
+    TheModule = loadModule(*MainFile);
+    if (!TheModule)
       return;
-    }
+
     const TargetOptions &TargetOpts = CI.getTargetOpts();
     if (TheModule->getTargetTriple() != TargetOpts.Triple) {
       CI.getDiagnostics().Report(SourceLocation(),
@@ -898,9 +978,10 @@
     Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler,
                                       &CI.getDiagnostics());
 
-    EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts,
-                      CI.getLangOpts(), CI.getTarget().getDataLayout(),
-                      TheModule.get(), BA, std::move(OS));
+    EmitBackendOutput(CI.getDiagnostics(), CI.getHeaderSearchOpts(),
+                      CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(),
+                      CI.getTarget().getDataLayout(), TheModule.get(), BA,
+                      std::move(OS));
     return;
   }
 
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 1507e8e..11660b4 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -42,6 +42,9 @@
 /// markers.
 static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts,
                                       const LangOptions &LangOpts) {
+  if (CGOpts.DisableLifetimeMarkers)
+    return false;
+
   // Asan uses markers for use-after-scope checks.
   if (CGOpts.SanitizeAddressUseAfterScope)
     return true;
@@ -109,9 +112,8 @@
   if (FirstBlockInfo)
     destroyBlockInfos(FirstBlockInfo);
 
-  if (getLangOpts().OpenMP) {
+  if (getLangOpts().OpenMP && CurFn)
     CGM.getOpenMPRuntime().functionFinished(*this);
-  }
 }
 
 CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T,
@@ -147,6 +149,8 @@
       Alignment = CGM.getClassPointerAlignment(RD);
     } else {
       Alignment = getContext().getTypeAlignInChars(T);
+      if (T.getQualifiers().hasUnaligned())
+        Alignment = CharUnits::One();
     }
 
     // Cap to the global maximum type alignment unless the alignment
@@ -198,7 +202,8 @@
       llvm_unreachable("non-canonical or dependent type in IR-generation");
 
     case Type::Auto:
-      llvm_unreachable("undeduced auto type in IR-generation");
+    case Type::DeducedTemplateSpecialization:
+      llvm_unreachable("undeduced type in IR-generation");
 
     // Various scalar types.
     case Type::Builtin:
@@ -705,6 +710,11 @@
   return false;
 }
 
+static void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) {
+  Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
+  Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
+}
+
 void CodeGenFunction::StartFunction(GlobalDecl GD,
                                     QualType RetTy,
                                     llvm::Function *Fn,
@@ -748,16 +758,19 @@
     Fn->addFnAttr(llvm::Attribute::SafeStack);
 
   // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize,
-  // .cxx_destruct and all of their calees at run time.
+  // .cxx_destruct, __destroy_helper_block_ and all of their calees at run time.
   if (SanOpts.has(SanitizerKind::Thread)) {
     if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
       IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
       if (OMD->getMethodFamily() == OMF_dealloc ||
           OMD->getMethodFamily() == OMF_initialize ||
           (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) {
-        Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
-        Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
+        markAsIgnoreThreadCheckingAtRuntime(Fn);
       }
+    } else if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+      IdentifierInfo *II = FD->getIdentifier();
+      if (II && II->isStr("__destroy_helper_block_"))
+        markAsIgnoreThreadCheckingAtRuntime(Fn);
     }
   }
 
@@ -768,6 +781,10 @@
         Fn->addFnAttr("function-instrument", "xray-always");
       if (XRayAttr->neverXRayInstrument())
         Fn->addFnAttr("function-instrument", "xray-never");
+      if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>()) {
+        Fn->addFnAttr("xray-log-args",
+                      llvm::utostr(LogArgs->getArgumentCount()));
+      }
     } else {
       Fn->addFnAttr(
           "xray-instruction-threshold",
@@ -775,27 +792,9 @@
     }
   }
 
-  // Pass inline keyword to optimizer if it appears explicitly on any
-  // declaration. Also, in the case of -fno-inline attach NoInline
-  // attribute to all functions that are not marked AlwaysInline, or
-  // to all functions that are not marked inline or implicitly inline
-  // in the case of -finline-hint-functions.
-  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
-    const CodeGenOptions& CodeGenOpts = CGM.getCodeGenOpts();
-    if (!CodeGenOpts.NoInline) {
-      for (auto RI : FD->redecls())
-        if (RI->isInlineSpecified()) {
-          Fn->addFnAttr(llvm::Attribute::InlineHint);
-          break;
-        }
-      if (CodeGenOpts.getInlining() == CodeGenOptions::OnlyHintInlining &&
-          !FD->isInlined() && !Fn->hasFnAttribute(llvm::Attribute::InlineHint))
-        Fn->addFnAttr(llvm::Attribute::NoInline);
-    } else if (!FD->hasAttr<AlwaysInlineAttr>())
-      Fn->addFnAttr(llvm::Attribute::NoInline);
+  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
     if (CGM.getLangOpts().OpenMP && FD->hasAttr<OMPDeclareSimdDeclAttr>())
       CGM.getOpenMPRuntime().emitDeclareSimdFunction(FD, Fn);
-  }
 
   // Add no-jump-tables value.
   Fn->addFnAttr("no-jump-tables",
@@ -823,6 +822,18 @@
     }
   }
 
+  // If we're checking nullability, we need to know whether we can check the
+  // return value. Initialize the flag to 'true' and refine it in EmitParmDecl.
+  if (SanOpts.has(SanitizerKind::NullabilityReturn)) {
+    auto Nullability = FnRetTy->getNullability(getContext());
+    if (Nullability && *Nullability == NullabilityKind::NonNull) {
+      if (!(SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&
+            CurCodeDecl && CurCodeDecl->getAttr<ReturnsNonNullAttr>()))
+        RetValNullabilityPrecondition =
+            llvm::ConstantInt::getTrue(getLLVMContext());
+    }
+  }
+
   // If we're in C++ mode and the function name is "main", it is guaranteed
   // to be norecurse by the standard (3.6.1.3 "The function main shall not be
   // used within a program").
@@ -867,8 +878,12 @@
   // inlining, we just add an attribute to insert a mcount call in backend.
   // The attribute "counting-function" is set to mcount function name which is
   // architecture dependent.
-  if (CGM.getCodeGenOpts().InstrumentForProfiling)
-    Fn->addFnAttr("counting-function", getTarget().getMCountName());
+  if (CGM.getCodeGenOpts().InstrumentForProfiling) {
+    if (CGM.getCodeGenOpts().CallFEntry)
+      Fn->addFnAttr("fentry-call", "true");
+    else
+      Fn->addFnAttr("counting-function", getTarget().getMCountName());
+  }
 
   if (RetTy->isVoidType()) {
     // Void type; nothing to return.
@@ -951,6 +966,15 @@
       // fast register allocator would be happier...
       CXXThisValue = CXXABIThisValue;
     }
+
+    // Null-check the 'this' pointer once per function, if it's available.
+    if (CXXThisValue) {
+      SanitizerSet SkippedChecks;
+      SkippedChecks.set(SanitizerKind::Alignment, true);
+      SkippedChecks.set(SanitizerKind::ObjectSize, true);
+      EmitTypeCheck(TCK_Load, Loc, CXXThisValue, MD->getThisType(getContext()),
+                    /*Alignment=*/CharUnits::Zero(), SkippedChecks);
+    }
   }
 
   // If any of the arguments have a variably modified type, make sure to
@@ -1067,6 +1091,19 @@
   return ResTy;
 }
 
+static bool
+shouldUseUndefinedBehaviorReturnOptimization(const FunctionDecl *FD,
+                                             const ASTContext &Context) {
+  QualType T = FD->getReturnType();
+  // Avoid the optimization for functions that return a record type with a
+  // trivial destructor or another trivially copyable type.
+  if (const RecordType *RT = T.getCanonicalType()->getAs<RecordType>()) {
+    if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+      return !ClassDecl->hasTrivialDestructor();
+  }
+  return !T.isTriviallyCopyableType(Context);
+}
+
 void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
                                    const CGFunctionInfo &FnInfo) {
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
@@ -1079,8 +1116,13 @@
   if (FD->hasAttr<NoDebugAttr>())
     DebugInfo = nullptr; // disable debug info indefinitely for this function
 
+  // The function might not have a body if we're generating thunks for a
+  // function declaration.
   SourceRange BodyRange;
-  if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();
+  if (Stmt *Body = FD->getBody())
+    BodyRange = Body->getSourceRange();
+  else
+    BodyRange = FD->getLocation();
   CurEHLocation = BodyRange.getEnd();
 
   // Use the location of the start of the function to determine where
@@ -1145,17 +1187,23 @@
   //   function call is used by the caller, the behavior is undefined.
   if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() && !SawAsmBlock &&
       !FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) {
+    bool ShouldEmitUnreachable =
+        CGM.getCodeGenOpts().StrictReturn ||
+        shouldUseUndefinedBehaviorReturnOptimization(FD, getContext());
     if (SanOpts.has(SanitizerKind::Return)) {
       SanitizerScope SanScope(this);
       llvm::Value *IsFalse = Builder.getFalse();
       EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
-                "missing_return", EmitCheckSourceLocation(FD->getLocation()),
-                None);
-    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
-      EmitTrapCall(llvm::Intrinsic::trap);
+                SanitizerHandler::MissingReturn,
+                EmitCheckSourceLocation(FD->getLocation()), None);
+    } else if (ShouldEmitUnreachable) {
+      if (CGM.getCodeGenOpts().OptimizationLevel == 0)
+        EmitTrapCall(llvm::Intrinsic::trap);
     }
-    Builder.CreateUnreachable();
-    Builder.ClearInsertionPoint();
+    if (SanOpts.has(SanitizerKind::Return) || ShouldEmitUnreachable) {
+      Builder.CreateUnreachable();
+      Builder.ClearInsertionPoint();
+    }
   }
 
   // Emit the standard function epilogue.
@@ -1858,7 +1906,7 @@
             };
             EmitCheck(std::make_pair(Builder.CreateICmpSGT(Size, Zero),
                                      SanitizerKind::VLABound),
-                      "vla_bound_not_positive", StaticArgs, Size);
+                      SanitizerHandler::VLABoundNotPositive, StaticArgs, Size);
           }
 
           // Always zexting here would be wrong if it weren't
@@ -1888,6 +1936,7 @@
     case Type::Typedef:
     case Type::Decltype:
     case Type::Auto:
+    case Type::DeducedTemplateSpecialization:
       // Stop walking: nothing to do.
       return;
 
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 071bcb8..2db8a18 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -103,6 +103,32 @@
   TEK_Aggregate
 };
 
+#define LIST_SANITIZER_CHECKS                                                  \
+  SANITIZER_CHECK(AddOverflow, add_overflow, 0)                                \
+  SANITIZER_CHECK(BuiltinUnreachable, builtin_unreachable, 0)                  \
+  SANITIZER_CHECK(CFICheckFail, cfi_check_fail, 0)                             \
+  SANITIZER_CHECK(DivremOverflow, divrem_overflow, 0)                          \
+  SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0)            \
+  SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0)                   \
+  SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0)             \
+  SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0)                     \
+  SANITIZER_CHECK(MissingReturn, missing_return, 0)                            \
+  SANITIZER_CHECK(MulOverflow, mul_overflow, 0)                                \
+  SANITIZER_CHECK(NegateOverflow, negate_overflow, 0)                          \
+  SANITIZER_CHECK(NonnullArg, nonnull_arg, 0)                                  \
+  SANITIZER_CHECK(NonnullReturn, nonnull_return, 0)                            \
+  SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0)                               \
+  SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0)                    \
+  SANITIZER_CHECK(SubOverflow, sub_overflow, 0)                                \
+  SANITIZER_CHECK(TypeMismatch, type_mismatch, 1)                              \
+  SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0)
+
+enum SanitizerHandler {
+#define SANITIZER_CHECK(Enum, Name, Version) Enum,
+  LIST_SANITIZER_CHECKS
+#undef SANITIZER_CHECK
+};
+
 /// CodeGenFunction - This class organizes the per-function state that is used
 /// while generating LLVM code.
 class CodeGenFunction : public CodeGenTypeCache {
@@ -186,6 +212,13 @@
   /// value. This is invalid iff the function has no return value.
   Address ReturnValue;
 
+  /// Return true if a label was seen in the current scope.
+  bool hasLabelBeenSeenInCurrentScope() const {
+    if (CurLexicalScope)
+      return CurLexicalScope->hasLabels();
+    return !LabelMap.empty();
+  }
+
   /// AllocaInsertPoint - This is an instruction in the entry block before which
   /// we prefer to insert allocas.
   llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
@@ -272,6 +305,31 @@
     ~CGCapturedStmtRAII() { CGF.CapturedStmtInfo = PrevCapturedStmtInfo; }
   };
 
+  /// An abstract representation of regular/ObjC call/message targets.
+  class AbstractCallee {
+    /// The function declaration of the callee.
+    const Decl *CalleeDecl;
+
+  public:
+    AbstractCallee() : CalleeDecl(nullptr) {}
+    AbstractCallee(const FunctionDecl *FD) : CalleeDecl(FD) {}
+    AbstractCallee(const ObjCMethodDecl *OMD) : CalleeDecl(OMD) {}
+    bool hasFunctionDecl() const {
+      return dyn_cast_or_null<FunctionDecl>(CalleeDecl);
+    }
+    const Decl *getDecl() const { return CalleeDecl; }
+    unsigned getNumParams() const {
+      if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
+        return FD->getNumParams();
+      return cast<ObjCMethodDecl>(CalleeDecl)->param_size();
+    }
+    const ParmVarDecl *getParamDecl(unsigned I) const {
+      if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
+        return FD->getParamDecl(I);
+      return *(cast<ObjCMethodDecl>(CalleeDecl)->param_begin() + I);
+    }
+  };
+
   /// \brief Sanitizers enabled for this function.
   SanitizerSet SanOpts;
 
@@ -522,14 +580,10 @@
       CGF.DidCallStackSave = false;
     }
 
-    /// \brief Exit this cleanup scope, emitting any accumulated
-    /// cleanups.
+    /// \brief Exit this cleanup scope, emitting any accumulated cleanups.
     ~RunCleanupsScope() {
-      if (PerformCleanup) {
-        CGF.DidCallStackSave = OldDidCallStackSave;
-        CGF.PopCleanupBlocks(CleanupStackDepth,
-                             LifetimeExtendedCleanupStackSize);
-      }
+      if (PerformCleanup)
+        ForceCleanup();
     }
 
     /// \brief Determine whether this scope requires any cleanups.
@@ -539,11 +593,15 @@
 
     /// \brief Force the emission of cleanups now, instead of waiting
     /// until this object is destroyed.
-    void ForceCleanup() {
+    /// \param ValuesToReload - A list of values that need to be available at
+    /// the insertion point after cleanup emission. If cleanup emission created
+    /// a shared cleanup block, these value pointers will be rewritten.
+    /// Otherwise, they not will be modified.
+    void ForceCleanup(std::initializer_list<llvm::Value**> ValuesToReload = {}) {
       assert(PerformCleanup && "Already forced cleanup");
       CGF.DidCallStackSave = OldDidCallStackSave;
-      CGF.PopCleanupBlocks(CleanupStackDepth,
-                           LifetimeExtendedCleanupStackSize);
+      CGF.PopCleanupBlocks(CleanupStackDepth, LifetimeExtendedCleanupStackSize,
+                           ValuesToReload);
       PerformCleanup = false;
     }
   };
@@ -594,6 +652,10 @@
         rescopeLabels();
     }
 
+    bool hasLabels() const {
+      return !Labels.empty();
+    }
+
     void rescopeLabels();
   };
 
@@ -701,13 +763,17 @@
 
   /// \brief Takes the old cleanup stack size and emits the cleanup blocks
   /// that have been added.
-  void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize);
+  void
+  PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize,
+                   std::initializer_list<llvm::Value **> ValuesToReload = {});
 
   /// \brief Takes the old cleanup stack size and emits the cleanup blocks
   /// that have been added, then adds all lifetime-extended cleanups from
   /// the given position to the stack.
-  void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize,
-                        size_t OldLifetimeExtendedStackSize);
+  void
+  PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize,
+                   size_t OldLifetimeExtendedStackSize,
+                   std::initializer_list<llvm::Value **> ValuesToReload = {});
 
   void ResolveBranchFixups(llvm::BasicBlock *Target);
 
@@ -918,6 +984,17 @@
                                           e->getCommon());
     }
 
+    /// Build the opaque value mapping for an OpaqueValueExpr whose source
+    /// expression is set to the expression the OVE represents.
+    OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *OV)
+        : CGF(CGF) {
+      if (OV) {
+        assert(OV->getSourceExpr() && "wrong form of OpaqueValueMapping used "
+                                      "for OVE with no source expression");
+        Data = OpaqueValueMappingData::bind(CGF, OV, OV->getSourceExpr());
+      }
+    }
+
     OpaqueValueMapping(CodeGenFunction &CGF,
                        const OpaqueValueExpr *opaqueValue,
                        LValue lvalue)
@@ -1079,10 +1156,11 @@
                                             uint64_t LoopCount);
 
 public:
-  /// Increment the profiler's counter for the given statement.
-  void incrementProfileCounter(const Stmt *S) {
+  /// Increment the profiler's counter for the given statement by \p StepV.
+  /// If \p StepV is null, the default increment is 1.
+  void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) {
     if (CGM.getCodeGenOpts().hasProfileClangInstr())
-      PGO.emitCounterIncrement(Builder, S);
+      PGO.emitCounterIncrement(Builder, S, StepV);
     PGO.setCurrentStmt(S);
   }
 
@@ -1183,6 +1261,23 @@
     CharUnits OldCXXThisAlignment;
   };
 
+  /// The scope of an ArrayInitLoopExpr. Within this scope, the value of the
+  /// current loop index is overridden.
+  class ArrayInitLoopExprScope {
+  public:
+    ArrayInitLoopExprScope(CodeGenFunction &CGF, llvm::Value *Index)
+      : CGF(CGF), OldArrayInitIndex(CGF.ArrayInitIndex) {
+      CGF.ArrayInitIndex = Index;
+    }
+    ~ArrayInitLoopExprScope() {
+      CGF.ArrayInitIndex = OldArrayInitIndex;
+    }
+
+  private:
+    CodeGenFunction &CGF;
+    llvm::Value *OldArrayInitIndex;
+  };
+
   class InlinedInheritingConstructorScope {
   public:
     InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD)
@@ -1251,6 +1346,10 @@
   /// this expression.
   Address CXXDefaultInitExprThis = Address::invalid();
 
+  /// The current array initialization index when evaluating an
+  /// ArrayInitIndexExpr within an ArrayInitLoopExpr.
+  llvm::Value *ArrayInitIndex = nullptr;
+
   /// The values of function arguments to use when evaluating
   /// CXXInheritedCtorInitExprs within this context.
   CallArgList CXXInheritedCtorInitExprArgs;
@@ -1276,6 +1375,16 @@
   /// information about the layout of the variable.
   llvm::DenseMap<const ValueDecl *, BlockByrefInfo> BlockByrefInfos;
 
+  /// Used by -fsanitize=nullability-return to determine whether the return
+  /// value can be checked.
+  llvm::Value *RetValNullabilityPrecondition = nullptr;
+
+  /// Check if -fsanitize=nullability-return instrumentation is required for
+  /// this function.
+  bool requiresReturnValueNullabilityCheck() const {
+    return RetValNullabilityPrecondition;
+  }
+
   llvm::BasicBlock *TerminateLandingPad;
   llvm::BasicBlock *TerminateHandler;
   llvm::BasicBlock *TrapBB;
@@ -1441,7 +1550,6 @@
   //===--------------------------------------------------------------------===//
 
   llvm::Value *EmitBlockLiteral(const BlockExpr *);
-  llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info);
   static void destroyBlockInfos(CGBlockInfo *info);
 
   llvm::Function *GenerateBlockFunction(GlobalDecl GD,
@@ -1496,6 +1604,8 @@
                      SourceLocation Loc = SourceLocation(),
                      SourceLocation StartLoc = SourceLocation());
 
+  static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor);
+
   void EmitConstructorBody(FunctionArgList &Args);
   void EmitDestructorBody(FunctionArgList &Args);
   void emitImplicitAssignmentOperatorBody(FunctionArgList &Args);
@@ -1543,8 +1653,7 @@
   void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type,
                         FunctionArgList &Args);
 
-  void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init,
-                               ArrayRef<VarDecl *> ArrayIndexes);
+  void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init);
 
   /// Struct with all informations about dynamic [sub]class needed to set vptr.
   struct VPtr {
@@ -1654,6 +1763,9 @@
   void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc,
                           SourceLocation EndLoc);
 
+  /// Emit a test that checks if the return value \p RV is nonnull.
+  void EmitReturnValueCheck(llvm::Value *RV, SourceLocation EndLoc);
+
   /// EmitStartEHSpec - Emit the start of the exception spec.
   void EmitStartEHSpec(const Decl *D);
 
@@ -1953,6 +2065,9 @@
     return it->second;
   }
 
+  /// Get the index of the current ArrayInitLoopExpr, if any.
+  llvm::Value *getArrayInitIndex() { return ArrayInitIndex; }
+
   /// getAccessedFieldNo - Given an encoded value and a result number, return
   /// the input field number being accessed.
   static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
@@ -1960,6 +2075,10 @@
   llvm::BlockAddress *GetAddrOfLabel(const LabelDecl *L);
   llvm::BasicBlock *GetIndirectGotoBlock();
 
+  /// Check if \p E is a reference, or a C++ "this" pointer wrapped in value-
+  /// preserving casts.
+  static bool IsDeclRefOrWrappedCXXThis(const Expr *E);
+
   /// EmitNullInitialization - Generate code to set a value of the given type to
   /// null, If the type contains data member pointers, they will be initialized
   /// to -1 in accordance with the Itanium C++ ABI.
@@ -2182,7 +2301,7 @@
   /// appropriate size and alignment for an object of type \p Type.
   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V,
                      QualType Type, CharUnits Alignment = CharUnits::Zero(),
-                     bool SkipNullCheck = false);
+                     SanitizerSet SkippedChecks = SanitizerSet());
 
   /// \brief Emit a check that \p Base points into an array object, which
   /// we can access at index \p Index. \p Accessed should be \c false if we
@@ -2404,6 +2523,7 @@
   void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S);
 
   void EmitCoroutineBody(const CoroutineBodyStmt &S);
+  void EmitCoreturnStmt(const CoreturnStmt &S);
   RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID);
 
   void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
@@ -2568,7 +2688,9 @@
   /// the end of the directive.
   ///
   /// \param D Directive that has at least one 'reduction' directives.
-  void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D);
+  /// \param ReductionKind The kind of reduction to perform.
+  void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D,
+                                   const OpenMPDirectiveKind ReductionKind);
   /// \brief Emit initial code for linear variables. Creates private copies
   /// and initializes them with the values according to OpenMP standard.
   ///
@@ -2635,14 +2757,26 @@
       const OMPTeamsDistributeParallelForSimdDirective &S);
   void EmitOMPTeamsDistributeParallelForDirective(
       const OMPTeamsDistributeParallelForDirective &S);
+  void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S);
+  void EmitOMPTargetTeamsDistributeDirective(
+      const OMPTargetTeamsDistributeDirective &S);
+  void EmitOMPTargetTeamsDistributeParallelForDirective(
+      const OMPTargetTeamsDistributeParallelForDirective &S);
+  void EmitOMPTargetTeamsDistributeParallelForSimdDirective(
+      const OMPTargetTeamsDistributeParallelForSimdDirective &S);
+  void EmitOMPTargetTeamsDistributeSimdDirective(
+      const OMPTargetTeamsDistributeSimdDirective &S);
 
-  /// Emit outlined function for the target directive.
-  static std::pair<llvm::Function * /*OutlinedFn*/,
-                   llvm::Constant * /*OutlinedFnID*/>
-  EmitOMPTargetDirectiveOutlinedFunction(CodeGenModule &CGM,
-                                         const OMPTargetDirective &S,
-                                         StringRef ParentName,
-                                         bool IsOffloadEntry);
+  /// Emit device code for the target directive.
+  static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
+                                          StringRef ParentName,
+                                          const OMPTargetDirective &S);
+  static void
+  EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName,
+                                      const OMPTargetParallelDirective &S);
+  static void
+  EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName,
+                                   const OMPTargetTeamsDirective &S);
   /// \brief Emit inner loop of the worksharing/simd construct.
   ///
   /// \param S Directive, for which the inner loop must be emitted.
@@ -2665,6 +2799,9 @@
                                   OMPPrivateScope &LoopScope);
 
 private:
+  /// Helpers for blocks
+  llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info);
+
   /// Helpers for the OpenMP loop directives.
   void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit);
   void EmitOMPSimdInit(const OMPLoopDirective &D, bool IsMonotonic = false);
@@ -2772,6 +2909,13 @@
   /// representation to its value representation.
   llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty);
 
+  /// Check if the scalar \p Value is within the valid range for the given
+  /// type \p Ty.
+  ///
+  /// Returns true if a check is needed (even if the range is unknown).
+  bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
+                            SourceLocation Loc);
+
   /// EmitLoadOfScalar - Load a scalar value from an address, taking
   /// care to appropriately convert from the memory representation to
   /// the LLVM value representation.
@@ -2812,7 +2956,7 @@
   /// rvalue, returning the rvalue.
   RValue EmitLoadOfLValue(LValue V, SourceLocation Loc);
   RValue EmitLoadOfExtVectorElementLValue(LValue V);
-  RValue EmitLoadOfBitfieldLValue(LValue LV);
+  RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc);
   RValue EmitLoadOfGlobalRegLValue(LValue LV);
 
   /// EmitStoreThroughLValue - Store the specified rvalue into the specified
@@ -3021,8 +3165,8 @@
   RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E,
                                 ReturnValueSlot ReturnValue);
 
-  RValue EmitCUDADevicePrintfCallExpr(const CallExpr *E,
-                                      ReturnValueSlot ReturnValue);
+  RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E,
+                                       ReturnValueSlot ReturnValue);
 
   RValue EmitBuiltinExpr(const FunctionDecl *FD,
                          unsigned BuiltinID, const CallExpr *E,
@@ -3078,6 +3222,8 @@
 public:
   llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E);
 
+  llvm::Value *EmitBuiltinAvailable(ArrayRef<llvm::Value *> Args);
+
   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
   llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E);
@@ -3325,6 +3471,10 @@
   void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
                             llvm::BasicBlock *FalseBlock, uint64_t TrueCount);
 
+  /// Given an assignment `*LHS = RHS`, emit a test that checks if \p RHS is
+  /// nonnull, if \p LHS is marked _Nonnull.
+  void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc);
+
   /// \brief Emit a description of a type in a format suitable for passing to
   /// a runtime sanitizer handler.
   llvm::Constant *EmitCheckTypeDescriptor(QualType T);
@@ -3341,7 +3491,7 @@
   /// sanitizer runtime with the provided arguments, and create a conditional
   /// branch to it.
   void EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked,
-                 StringRef CheckName, ArrayRef<llvm::Constant *> StaticArgs,
+                 SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs,
                  ArrayRef<llvm::Value *> DynamicArgs);
 
   /// \brief Emit a slow path cross-DSO CFI check which calls __cfi_slowpath
@@ -3364,7 +3514,7 @@
   /// \brief Create a check for a function parameter that may potentially be
   /// declared as non-null.
   void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc,
-                           const FunctionDecl *FD, unsigned ParmNum);
+                           AbstractCallee AC, unsigned ParmNum);
 
   /// EmitCallArg - Emit a single call argument.
   void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
@@ -3419,14 +3569,18 @@
   /// \brief Attempts to statically evaluate the object size of E. If that
   /// fails, emits code to figure the size of E out for us. This is
   /// pass_object_size aware.
+  ///
+  /// If EmittedExpr is non-null, this will use that instead of re-emitting E.
   llvm::Value *evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
-                                               llvm::IntegerType *ResType);
+                                               llvm::IntegerType *ResType,
+                                               llvm::Value *EmittedE);
 
   /// \brief Emits the size of E, as required by __builtin_object_size. This
   /// function is aware of pass_object_size parameters, and will act accordingly
   /// if E is a parameter with the pass_object_size attribute.
   llvm::Value *emitBuiltinObjectSize(const Expr *E, unsigned Type,
-                                     llvm::IntegerType *ResType);
+                                     llvm::IntegerType *ResType,
+                                     llvm::Value *EmittedE);
 
 public:
 #ifndef NDEBUG
@@ -3462,7 +3616,7 @@
   template <typename T>
   void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo,
                     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
-                    const FunctionDecl *CalleeDecl = nullptr,
+                    AbstractCallee AC = AbstractCallee(),
                     unsigned ParamsToSkip = 0,
                     EvaluationOrder Order = EvaluationOrder::Default) {
     SmallVector<QualType, 16> ArgTypes;
@@ -3502,14 +3656,14 @@
 
     // If we still have any arguments, emit them using the type of the argument.
     for (auto *A : llvm::make_range(Arg, ArgRange.end()))
-      ArgTypes.push_back(getVarArgType(A));
+      ArgTypes.push_back(CallArgTypeInfo ? getVarArgType(A) : A->getType());
 
-    EmitCallArgs(Args, ArgTypes, ArgRange, CalleeDecl, ParamsToSkip, Order);
+    EmitCallArgs(Args, ArgTypes, ArgRange, AC, ParamsToSkip, Order);
   }
 
   void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes,
                     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
-                    const FunctionDecl *CalleeDecl = nullptr,
+                    AbstractCallee AC = AbstractCallee(),
                     unsigned ParamsToSkip = 0,
                     EvaluationOrder Order = EvaluationOrder::Default);
 
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 78f43bd..a3920e1 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -24,7 +24,6 @@
 #include "CodeGenFunction.h"
 #include "CodeGenPGO.h"
 #include "CodeGenTBAA.h"
-#include "ConstantBuilder.h"
 #include "CoverageMappingGen.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
@@ -42,6 +41,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Version.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/ADT/Triple.h"
@@ -875,6 +875,13 @@
     B.addAttribute(llvm::Attribute::StackProtectReq);
 
   if (!D) {
+    // If we don't have a declaration to control inlining, the function isn't
+    // explicitly marked as alwaysinline for semantic reasons, and inlining is
+    // disabled, mark the function as noinline.
+    if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline) &&
+        CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining)
+      B.addAttribute(llvm::Attribute::NoInline);
+
     F->addAttributes(llvm::AttributeSet::FunctionIndex,
                      llvm::AttributeSet::get(
                          F->getContext(),
@@ -882,7 +889,23 @@
     return;
   }
 
-  if (D->hasAttr<NakedAttr>()) {
+  if (D->hasAttr<OptimizeNoneAttr>()) {
+    B.addAttribute(llvm::Attribute::OptimizeNone);
+
+    // OptimizeNone implies noinline; we should not be inlining such functions.
+    B.addAttribute(llvm::Attribute::NoInline);
+    assert(!F->hasFnAttribute(llvm::Attribute::AlwaysInline) &&
+           "OptimizeNone and AlwaysInline on same function!");
+
+    // We still need to handle naked functions even though optnone subsumes
+    // much of their semantics.
+    if (D->hasAttr<NakedAttr>())
+      B.addAttribute(llvm::Attribute::Naked);
+
+    // OptimizeNone wins over OptimizeForSize and MinSize.
+    F->removeFnAttr(llvm::Attribute::OptimizeForSize);
+    F->removeFnAttr(llvm::Attribute::MinSize);
+  } else if (D->hasAttr<NakedAttr>()) {
     // Naked implies noinline: we should not be inlining such functions.
     B.addAttribute(llvm::Attribute::Naked);
     B.addAttribute(llvm::Attribute::NoInline);
@@ -891,41 +914,47 @@
   } else if (D->hasAttr<NoInlineAttr>()) {
     B.addAttribute(llvm::Attribute::NoInline);
   } else if (D->hasAttr<AlwaysInlineAttr>() &&
-             !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex,
-                                              llvm::Attribute::NoInline)) {
+             !F->hasFnAttribute(llvm::Attribute::NoInline)) {
     // (noinline wins over always_inline, and we can't specify both in IR)
     B.addAttribute(llvm::Attribute::AlwaysInline);
+  } else if (CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining) {
+    // If we're not inlining, then force everything that isn't always_inline to
+    // carry an explicit noinline attribute.
+    if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline))
+      B.addAttribute(llvm::Attribute::NoInline);
+  } else {
+    // Otherwise, propagate the inline hint attribute and potentially use its
+    // absence to mark things as noinline.
+    if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+      if (any_of(FD->redecls(), [&](const FunctionDecl *Redecl) {
+            return Redecl->isInlineSpecified();
+          })) {
+        B.addAttribute(llvm::Attribute::InlineHint);
+      } else if (CodeGenOpts.getInlining() ==
+                     CodeGenOptions::OnlyHintInlining &&
+                 !FD->isInlined() &&
+                 !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
+        B.addAttribute(llvm::Attribute::NoInline);
+      }
+    }
   }
 
-  if (D->hasAttr<ColdAttr>()) {
-    if (!D->hasAttr<OptimizeNoneAttr>())
+  // Add other optimization related attributes if we are optimizing this
+  // function.
+  if (!D->hasAttr<OptimizeNoneAttr>()) {
+    if (D->hasAttr<ColdAttr>()) {
       B.addAttribute(llvm::Attribute::OptimizeForSize);
-    B.addAttribute(llvm::Attribute::Cold);
-  }
+      B.addAttribute(llvm::Attribute::Cold);
+    }
 
-  if (D->hasAttr<MinSizeAttr>())
-    B.addAttribute(llvm::Attribute::MinSize);
+    if (D->hasAttr<MinSizeAttr>())
+      B.addAttribute(llvm::Attribute::MinSize);
+  }
 
   F->addAttributes(llvm::AttributeSet::FunctionIndex,
                    llvm::AttributeSet::get(
                        F->getContext(), llvm::AttributeSet::FunctionIndex, B));
 
-  if (D->hasAttr<OptimizeNoneAttr>()) {
-    // OptimizeNone implies noinline; we should not be inlining such functions.
-    F->addFnAttr(llvm::Attribute::OptimizeNone);
-    F->addFnAttr(llvm::Attribute::NoInline);
-
-    // OptimizeNone wins over OptimizeForSize, MinSize, AlwaysInline.
-    F->removeFnAttr(llvm::Attribute::OptimizeForSize);
-    F->removeFnAttr(llvm::Attribute::MinSize);
-    assert(!F->hasFnAttribute(llvm::Attribute::AlwaysInline) &&
-           "OptimizeNone and AlwaysInline on same function!");
-
-    // Attribute 'inlinehint' has no effect on 'optnone' functions.
-    // Explicitly remove it from the set of function attributes.
-    F->removeFnAttr(llvm::Attribute::InlineHint);
-  }
-
   unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
   if (alignment)
     F->setAlignment(alignment);
@@ -1214,9 +1243,15 @@
   SmallVector<clang::Module *, 16> Stack;
 
   // Seed the stack with imported modules.
-  for (Module *M : ImportedModules)
+  for (Module *M : ImportedModules) {
+    // Do not add any link flags when an implementation TU of a module imports
+    // a header of that same module.
+    if (M->getTopLevelModuleName() == getLangOpts().CurrentModule &&
+        !getLangOpts().isCompilingModule())
+      continue;
     if (Visited.insert(M).second)
       Stack.push_back(M);
+  }
 
   // Find all of the modules to import, making a little effort to prune
   // non-leaf modules.
@@ -1658,6 +1693,16 @@
   }
 }
 
+// Check if T is a class type with a destructor that's not dllimport.
+static bool HasNonDllImportDtor(QualType T) {
+  if (const auto *RT = T->getBaseElementTypeUnsafe()->getAs<RecordType>())
+    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+      if (RD->getDestructor() && !RD->getDestructor()->hasAttr<DLLImportAttr>())
+        return true;
+
+  return false;
+}
+
 namespace {
   struct FunctionIsDirectlyRecursive :
     public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
@@ -1691,6 +1736,7 @@
     }
   };
 
+  // Make sure we're not referencing non-imported vars or functions.
   struct DLLImportFunctionVisitor
       : public RecursiveASTVisitor<DLLImportFunctionVisitor> {
     bool SafeToInline = true;
@@ -1698,12 +1744,25 @@
     bool shouldVisitImplicitCode() const { return true; }
 
     bool VisitVarDecl(VarDecl *VD) {
-      // A thread-local variable cannot be imported.
-      SafeToInline = !VD->getTLSKind();
+      if (VD->getTLSKind()) {
+        // A thread-local variable cannot be imported.
+        SafeToInline = false;
+        return SafeToInline;
+      }
+
+      // A variable definition might imply a destructor call.
+      if (VD->isThisDeclarationADefinition())
+        SafeToInline = !HasNonDllImportDtor(VD->getType());
+
       return SafeToInline;
     }
 
-    // Make sure we're not referencing non-imported vars or functions.
+    bool VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+      if (const auto *D = E->getTemporary()->getDestructor())
+        SafeToInline = D->hasAttr<DLLImportAttr>();
+      return SafeToInline;
+    }
+
     bool VisitDeclRefExpr(DeclRefExpr *E) {
       ValueDecl *VD = E->getDecl();
       if (isa<FunctionDecl>(VD))
@@ -1712,14 +1771,28 @@
         SafeToInline = !V->hasGlobalStorage() || V->hasAttr<DLLImportAttr>();
       return SafeToInline;
     }
+
     bool VisitCXXConstructExpr(CXXConstructExpr *E) {
       SafeToInline = E->getConstructor()->hasAttr<DLLImportAttr>();
       return SafeToInline;
     }
+
+    bool VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
+      CXXMethodDecl *M = E->getMethodDecl();
+      if (!M) {
+        // Call through a pointer to member function. This is safe to inline.
+        SafeToInline = true;
+      } else {
+        SafeToInline = M->hasAttr<DLLImportAttr>();
+      }
+      return SafeToInline;
+    }
+
     bool VisitCXXDeleteExpr(CXXDeleteExpr *E) {
       SafeToInline = E->getOperatorDelete()->hasAttr<DLLImportAttr>();
       return SafeToInline;
     }
+
     bool VisitCXXNewExpr(CXXNewExpr *E) {
       SafeToInline = E->getOperatorNew()->hasAttr<DLLImportAttr>();
       return SafeToInline;
@@ -1748,16 +1821,6 @@
   return Walker.Result;
 }
 
-// Check if T is a class type with a destructor that's not dllimport.
-static bool HasNonDllImportDtor(QualType T) {
-  if (const RecordType *RT = dyn_cast<RecordType>(T))
-    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
-      if (RD->getDestructor() && !RD->getDestructor()->hasAttr<DLLImportAttr>())
-        return true;
-
-  return false;
-}
-
 bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
   if (getFunctionLinkage(GD) != llvm::Function::AvailableExternallyLinkage)
     return true;
@@ -1793,22 +1856,6 @@
   return !isTriviallyRecursive(F);
 }
 
-/// If the type for the method's class was generated by
-/// CGDebugInfo::createContextChain(), the cache contains only a
-/// limited DIType without any declarations. Since EmitFunctionStart()
-/// needs to find the canonical declaration for each method, we need
-/// to construct the complete type prior to emitting the method.
-void CodeGenModule::CompleteDIClassType(const CXXMethodDecl* D) {
-  if (!D->isInstance())
-    return;
-
-  if (CGDebugInfo *DI = getModuleDebugInfo())
-    if (getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo) {
-      const auto *ThisPtr = cast<PointerType>(D->getThisType(getContext()));
-      DI->getOrCreateRecordType(ThisPtr->getPointeeType(), D->getLocation());
-    }
-}
-
 void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
   const auto *D = cast<ValueDecl>(GD.getDecl());
 
@@ -1823,7 +1870,6 @@
       return;
 
     if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) {
-      CompleteDIClassType(Method);
       // Make sure to emit the definition(s) before we emit the thunks.
       // This is necessary for the generation of certain thunks.
       if (const auto *CD = dyn_cast<CXXConstructorDecl>(Method))
@@ -2038,18 +2084,70 @@
                                  IsForDefinition);
 }
 
+static const FunctionDecl *
+GetRuntimeFunctionDecl(ASTContext &C, StringRef Name) {
+  TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
+  DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
+
+  IdentifierInfo &CII = C.Idents.get(Name);
+  for (const auto &Result : DC->lookup(&CII))
+    if (const auto FD = dyn_cast<FunctionDecl>(Result))
+      return FD;
+
+  if (!C.getLangOpts().CPlusPlus)
+    return nullptr;
+
+  // Demangle the premangled name from getTerminateFn()
+  IdentifierInfo &CXXII =
+      (Name == "_ZSt9terminatev" || Name == "\01?terminate@@YAXXZ")
+          ? C.Idents.get("terminate")
+          : C.Idents.get(Name);
+
+  for (const auto &N : {"__cxxabiv1", "std"}) {
+    IdentifierInfo &NS = C.Idents.get(N);
+    for (const auto &Result : DC->lookup(&NS)) {
+      NamespaceDecl *ND = dyn_cast<NamespaceDecl>(Result);
+      if (auto LSD = dyn_cast<LinkageSpecDecl>(Result))
+        for (const auto &Result : LSD->lookup(&NS))
+          if ((ND = dyn_cast<NamespaceDecl>(Result)))
+            break;
+
+      if (ND)
+        for (const auto &Result : ND->lookup(&CXXII))
+          if (const auto *FD = dyn_cast<FunctionDecl>(Result))
+            return FD;
+    }
+  }
+
+  return nullptr;
+}
+
 /// CreateRuntimeFunction - Create a new runtime function with the specified
 /// type and name.
 llvm::Constant *
-CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy,
-                                     StringRef Name,
-                                     llvm::AttributeSet ExtraAttrs) {
+CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
+                                     llvm::AttributeSet ExtraAttrs,
+                                     bool Local) {
   llvm::Constant *C =
       GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
-                              /*DontDefer=*/false, /*IsThunk=*/false, ExtraAttrs);
-  if (auto *F = dyn_cast<llvm::Function>(C))
-    if (F->empty())
+                              /*DontDefer=*/false, /*IsThunk=*/false,
+                              ExtraAttrs);
+
+  if (auto *F = dyn_cast<llvm::Function>(C)) {
+    if (F->empty()) {
       F->setCallingConv(getRuntimeCC());
+
+      if (!Local && getTriple().isOSBinFormatCOFF() &&
+          !getCodeGenOpts().LTOVisibilityPublicStd) {
+        const FunctionDecl *FD = GetRuntimeFunctionDecl(Context, Name);
+        if (!FD || FD->hasAttr<DLLImportAttr>()) {
+          F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+          F->setLinkage(llvm::GlobalValue::ExternalLinkage);
+        }
+      }
+    }
+  }
+
   return C;
 }
 
@@ -2219,29 +2317,30 @@
 llvm::Constant *
 CodeGenModule::GetAddrOfGlobal(GlobalDecl GD,
                                ForDefinition_t IsForDefinition) {
-  if (isa<CXXConstructorDecl>(GD.getDecl()))
-    return getAddrOfCXXStructor(cast<CXXConstructorDecl>(GD.getDecl()),
+  const Decl *D = GD.getDecl();
+  if (isa<CXXConstructorDecl>(D))
+    return getAddrOfCXXStructor(cast<CXXConstructorDecl>(D),
                                 getFromCtorType(GD.getCtorType()),
                                 /*FnInfo=*/nullptr, /*FnType=*/nullptr,
                                 /*DontDefer=*/false, IsForDefinition);
-  else if (isa<CXXDestructorDecl>(GD.getDecl()))
-    return getAddrOfCXXStructor(cast<CXXDestructorDecl>(GD.getDecl()),
+  else if (isa<CXXDestructorDecl>(D))
+    return getAddrOfCXXStructor(cast<CXXDestructorDecl>(D),
                                 getFromDtorType(GD.getDtorType()),
                                 /*FnInfo=*/nullptr, /*FnType=*/nullptr,
                                 /*DontDefer=*/false, IsForDefinition);
-  else if (isa<CXXMethodDecl>(GD.getDecl())) {
+  else if (isa<CXXMethodDecl>(D)) {
     auto FInfo = &getTypes().arrangeCXXMethodDeclaration(
-        cast<CXXMethodDecl>(GD.getDecl()));
+        cast<CXXMethodDecl>(D));
     auto Ty = getTypes().GetFunctionType(*FInfo);
     return GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer=*/false,
                              IsForDefinition);
-  } else if (isa<FunctionDecl>(GD.getDecl())) {
+  } else if (isa<FunctionDecl>(D)) {
     const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD);
     llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
     return GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer=*/false,
                              IsForDefinition);
   } else
-    return GetAddrOfGlobalVar(cast<VarDecl>(GD.getDecl()), /*Ty=*/nullptr,
+    return GetAddrOfGlobalVar(cast<VarDecl>(D), /*Ty=*/nullptr,
                               IsForDefinition);
 }
 
@@ -2611,9 +2710,16 @@
   else
     GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass);
 
-  if (Linkage == llvm::GlobalVariable::CommonLinkage)
+  if (Linkage == llvm::GlobalVariable::CommonLinkage) {
     // common vars aren't constant even if declared const.
     GV->setConstant(false);
+    // Tentative definition of global variables may be initialized with
+    // non-zero null pointers. In this case they should have weak linkage
+    // since common linkage must have zero initializer and must not have
+    // explicit section therefore cannot have non-zero initial value.
+    if (!GV->getInitializer()->isNullValue())
+      GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
+  }
 
   setNonAliasAttributes(D, GV);
 
@@ -2708,7 +2814,7 @@
   // We are guaranteed to have a strong definition somewhere else,
   // so we can use available_externally linkage.
   if (Linkage == GVA_AvailableExternally)
-    return llvm::Function::AvailableExternallyLinkage;
+    return llvm::GlobalValue::AvailableExternallyLinkage;
 
   // Note that Apple's kernel linker doesn't support symbol
   // coalescing, so we need to avoid linkonce and weak linkages there.
@@ -3246,6 +3352,7 @@
     llvm_unreachable("unknown file format");
   case llvm::Triple::COFF:
   case llvm::Triple::ELF:
+  case llvm::Triple::Wasm:
     GV->setSection("cfstring");
     break;
   case llvm::Triple::MachO:
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index be45bb8..8faebe1 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -166,7 +166,7 @@
   /// void objc_release(id);
   llvm::Constant *objc_release;
 
-  /// id objc_storeStrong(id*, id);
+  /// void objc_storeStrong(id*, id);
   llvm::Constant *objc_storeStrong;
 
   /// id objc_storeWeak(id*, id);
@@ -455,6 +455,14 @@
   bool isTriviallyRecursive(const FunctionDecl *F);
   bool shouldEmitFunction(GlobalDecl GD);
 
+  /// Map used to be sure we don't emit the same CompoundLiteral twice.
+  llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *>
+      EmittedCompoundLiterals;
+
+  /// Map of the global blocks we've emitted, so that we don't have to re-emit
+  /// them if the constexpr evaluator gets aggressive.
+  llvm::DenseMap<const BlockExpr *, llvm::Constant *> EmittedGlobalBlocks;
+
   /// @name Cache for Blocks Runtime Globals
   /// @{
 
@@ -538,6 +546,10 @@
     return *ObjCData;
   }
 
+  // Version checking function, used to implement ObjC's @available:
+  // i32 @__isOSVersionAtLeast(i32, i32, i32)
+  llvm::Constant *IsOSVersionAtLeastFn = nullptr;
+
   InstrProfStats &getPGOStats() { return PGOStats; }
   llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); }
 
@@ -776,6 +788,16 @@
 
   /// Gets the address of a block which requires no captures.
   llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name);
+
+  /// Returns the address of a block which requires no caputres, or null if
+  /// we've yet to emit the block for BE.
+  llvm::Constant *getAddrOfGlobalBlockIfEmitted(const BlockExpr *BE) {
+    return EmittedGlobalBlocks.lookup(BE);
+  }
+
+  /// Notes that BE's global block is available via Addr. Asserts that BE
+  /// isn't already emitted.
+  void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr);
   
   /// Return a pointer to a constant CFString object for the given string.
   ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal);
@@ -810,6 +832,16 @@
   /// compound literal expression.
   ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E);
 
+  /// If it's been emitted already, returns the GlobalVariable corresponding to
+  /// a compound literal. Otherwise, returns null.
+  llvm::GlobalVariable *
+  getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E);
+
+  /// Notes that CLE's GlobalVariable is GV. Asserts that CLE isn't already
+  /// emitted.
+  void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE,
+                                        llvm::GlobalVariable *GV);
+
   /// \brief Returns a pointer to a global variable representing a temporary
   /// with static or thread storage duration.
   ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E,
@@ -876,10 +908,11 @@
   }
 
   /// Create a new runtime function with the specified type and name.
-  llvm::Constant *CreateRuntimeFunction(llvm::FunctionType *Ty,
-                                        StringRef Name,
-                                        llvm::AttributeSet ExtraAttrs =
-                                          llvm::AttributeSet());
+  llvm::Constant *
+  CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name,
+                        llvm::AttributeSet ExtraAttrs = llvm::AttributeSet(),
+                        bool Local = false);
+
   /// Create a new compiler builtin function with the specified type and name.
   llvm::Constant *CreateBuiltinFunction(llvm::FunctionType *Ty,
                                         StringRef Name,
@@ -993,6 +1026,25 @@
                               CGCalleeInfo CalleeInfo, AttributeListType &PAL,
                               unsigned &CallingConv, bool AttrOnCallSite);
 
+  /// Adds attributes to F according to our CodeGenOptions and LangOptions, as
+  /// though we had emitted it ourselves.  We remove any attributes on F that
+  /// conflict with the attributes we add here.
+  ///
+  /// This is useful for adding attrs to bitcode modules that you want to link
+  /// with but don't control, such as CUDA's libdevice.  When linking with such
+  /// a bitcode library, you might want to set e.g. its functions'
+  /// "unsafe-fp-math" attribute to match the attr of the functions you're
+  /// codegen'ing.  Otherwise, LLVM will interpret the bitcode module's lack of
+  /// unsafe-fp-math attrs as tantamount to unsafe-fp-math=false, and then LLVM
+  /// will propagate unsafe-fp-math=false up to every transitive caller of a
+  /// function in the bitcode library!
+  ///
+  /// With the exception of fast-math attrs, this will only make the attributes
+  /// on the function more conservative.  But it's unsafe to call this on a
+  /// function which relies on particular fast-math attributes for correctness.
+  /// It's up to you to ensure that this is safe.
+  void AddDefaultFnAttrs(llvm::Function &F);
+
   // Fills in the supplied string map with the set of target features for the
   // passed in function.
   void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
@@ -1155,6 +1207,11 @@
   llvm::Value *
   createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF);
 
+  /// Get target specific null pointer.
+  /// \param T is the LLVM type of the null pointer.
+  /// \param QT is the clang QualType of the null pointer.
+  llvm::Constant *getNullPointer(llvm::PointerType *T, QualType QT);
+
 private:
   llvm::Constant *
   GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D,
@@ -1188,7 +1245,6 @@
 
   void EmitDeclContext(const DeclContext *DC);
   void EmitLinkageSpec(const LinkageSpecDecl *D);
-  void CompleteDIClassType(const CXXMethodDecl* D);
 
   /// \brief Emit the function that initializes C++ thread_local variables.
   void EmitCXXThreadLocalInitFunc();
@@ -1270,6 +1326,12 @@
   /// Check whether we can use a "simpler", more core exceptions personality
   /// function.
   void SimplifyPersonality();
+
+  /// Helper function for ConstructAttributeList and AddDefaultFnAttrs.
+  /// Constructs an AttrList for a function with the given properties.
+  void ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
+                                  bool AttrOnCallSite,
+                                  llvm::AttrBuilder &FuncAttrs);
 };
 }  // end namespace CodeGen
 }  // end namespace clang
diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp
index c6c3fa4..90711b5 100644
--- a/lib/CodeGen/CodeGenPGO.cpp
+++ b/lib/CodeGen/CodeGenPGO.cpp
@@ -626,12 +626,14 @@
   // Constructors and destructors may be represented by several functions in IR.
   // If so, instrument only base variant, others are implemented by delegation
   // to the base one, it would be counted twice otherwise.
-  if (CGM.getTarget().getCXXABI().hasConstructorVariants() &&
-      ((isa<CXXConstructorDecl>(GD.getDecl()) &&
-        GD.getCtorType() != Ctor_Base) ||
-       (isa<CXXDestructorDecl>(GD.getDecl()) &&
-        GD.getDtorType() != Dtor_Base))) {
+  if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
+    if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
       return;
+
+    if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
+      if (GD.getCtorType() != Ctor_Base &&
+          CodeGenFunction::IsConstructorDelegationValid(CCD))
+        return;
   }
   CGM.ClearUnusedCoverageMapping(D);
   setFuncName(Fn);
@@ -737,7 +739,8 @@
   Fn->setEntryCount(FunctionCount);
 }
 
-void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S) {
+void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
+                                      llvm::Value *StepV) {
   if (!CGM.getCodeGenOpts().hasProfileClangInstr() || !RegionCounterMap)
     return;
   if (!Builder.GetInsertBlock())
@@ -745,11 +748,18 @@
 
   unsigned Counter = (*RegionCounterMap)[S];
   auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
-  Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
-                     {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
-                      Builder.getInt64(FunctionHash),
-                      Builder.getInt32(NumRegionCounters),
-                      Builder.getInt32(Counter)});
+
+  llvm::Value *Args[] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
+                         Builder.getInt64(FunctionHash),
+                         Builder.getInt32(NumRegionCounters),
+                         Builder.getInt32(Counter), StepV};
+  if (!StepV)
+    Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
+                       makeArrayRef(Args, 4));
+  else
+    Builder.CreateCall(
+        CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
+        makeArrayRef(Args));
 }
 
 // This method either inserts a call to the profile run-time during
diff --git a/lib/CodeGen/CodeGenPGO.h b/lib/CodeGen/CodeGenPGO.h
index 4f229cd..0026df5 100644
--- a/lib/CodeGen/CodeGenPGO.h
+++ b/lib/CodeGen/CodeGenPGO.h
@@ -105,7 +105,8 @@
   void emitCounterRegionMapping(const Decl *D);
 
 public:
-  void emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S);
+  void emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
+                            llvm::Value *StepV);
 
   /// Return the region count for the counter at the given index.
   uint64_t getRegionCount(const Stmt *S) {
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index ebe55c7..dc24b20 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -286,21 +286,21 @@
 static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext,
                                     const llvm::fltSemantics &format,
                                     bool UseNativeHalf = false) {
-  if (&format == &llvm::APFloat::IEEEhalf) {
+  if (&format == &llvm::APFloat::IEEEhalf()) {
     if (UseNativeHalf)
       return llvm::Type::getHalfTy(VMContext);
     else
       return llvm::Type::getInt16Ty(VMContext);
   }
-  if (&format == &llvm::APFloat::IEEEsingle)
+  if (&format == &llvm::APFloat::IEEEsingle())
     return llvm::Type::getFloatTy(VMContext);
-  if (&format == &llvm::APFloat::IEEEdouble)
+  if (&format == &llvm::APFloat::IEEEdouble())
     return llvm::Type::getDoubleTy(VMContext);
-  if (&format == &llvm::APFloat::IEEEquad)
+  if (&format == &llvm::APFloat::IEEEquad())
     return llvm::Type::getFP128Ty(VMContext);
-  if (&format == &llvm::APFloat::PPCDoubleDouble)
+  if (&format == &llvm::APFloat::PPCDoubleDouble())
     return llvm::Type::getPPC_FP128Ty(VMContext);
-  if (&format == &llvm::APFloat::x87DoubleExtended)
+  if (&format == &llvm::APFloat::x87DoubleExtended())
     return llvm::Type::getX86_FP80Ty(VMContext);
   llvm_unreachable("Unknown float format!");
 }
@@ -472,7 +472,6 @@
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
-    case BuiltinType::OCLNDRange:
     case BuiltinType::OCLReserveID:
       ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty);
       break;
@@ -487,7 +486,8 @@
     break;
   }
   case Type::Auto:
-    llvm_unreachable("Unexpected undeduced auto type!");
+  case Type::DeducedTemplateSpecialization:
+    llvm_unreachable("Unexpected undeduced type!");
   case Type::Complex: {
     llvm::Type *EltTy = ConvertType(cast<ComplexType>(Ty)->getElementType());
     ResultType = llvm::StructType::get(EltTy, EltTy, nullptr);
@@ -736,10 +736,14 @@
   return *Layout;
 }
 
+bool CodeGenTypes::isPointerZeroInitializable(QualType T) {
+  assert((T->isAnyPointerType() || T->isBlockPointerType()) && "Invalid type");
+  return isZeroInitializable(T);
+}
+
 bool CodeGenTypes::isZeroInitializable(QualType T) {
-  // No need to check for member pointers when not compiling C++.
-  if (!Context.getLangOpts().CPlusPlus)
-    return true;
+  if (T->getAs<PointerType>())
+    return Context.getTargetNullPointerValue(T) == 0;
 
   if (const auto *AT = Context.getAsArrayType(T)) {
     if (isa<IncompleteArrayType>(AT))
@@ -753,7 +757,7 @@
   // Records are non-zero-initializable if they contain any
   // non-zero-initializable subobjects.
   if (const RecordType *RT = T->getAs<RecordType>()) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    auto RD = cast<RecordDecl>(RT->getDecl());
     return isZeroInitializable(RD);
   }
 
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 00df10d..f0b97eb 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -303,11 +303,14 @@
   const CGFunctionInfo &arrangeCXXConstructorCall(const CallArgList &Args,
                                                   const CXXConstructorDecl *D,
                                                   CXXCtorType CtorKind,
-                                                  unsigned ExtraArgs);
+                                                  unsigned ExtraPrefixArgs,
+                                                  unsigned ExtraSuffixArgs,
+                                                  bool PassProtoArgs = true);
 
   const CGFunctionInfo &arrangeCXXMethodCall(const CallArgList &args,
                                              const FunctionProtoType *type,
-                                             RequiredArgs required);
+                                             RequiredArgs required,
+                                             unsigned numPrefixArgs);
   const CGFunctionInfo &arrangeMSMemberPointerThunk(const CXXMethodDecl *MD);
   const CGFunctionInfo &arrangeMSCtorClosure(const CXXConstructorDecl *CD,
                                                  CXXCtorType CT);
@@ -352,6 +355,10 @@
   /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
   bool isZeroInitializable(QualType T);
 
+  /// Check if the pointer type can be zero-initialized (in the C++ sense)
+  /// with an LLVM zeroinitializer.
+  bool isPointerZeroInitializable(QualType T);
+
   /// IsZeroInitializable - Return whether a record type can be
   /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
   bool isZeroInitializable(const RecordDecl *RD);
diff --git a/lib/CodeGen/ConstantBuilder.h b/lib/CodeGen/ConstantBuilder.h
deleted file mode 100644
index 40b34a9..0000000
--- a/lib/CodeGen/ConstantBuilder.h
+++ /dev/null
@@ -1,444 +0,0 @@
-//===----- ConstantBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class provides a convenient interface for building complex
-// global initializers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H
-#define LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/Constants.h"
-
-#include "CodeGenModule.h"
-
-#include <vector>
-
-namespace clang {
-namespace CodeGen {
-
-class ConstantStructBuilder;
-class ConstantArrayBuilder;
-
-/// A convenience builder class for complex constant initializers,
-/// especially for anonymous global structures used by various language
-/// runtimes.
-///
-/// The basic usage pattern is expected to be something like:
-///    ConstantInitBuilder builder(CGM);
-///    auto toplevel = builder.beginStruct();
-///    toplevel.addInt(CGM.SizeTy, widgets.size());
-///    auto widgetArray = builder.beginArray();
-///    for (auto &widget : widgets) {
-///      auto widgetDesc = widgetArray.beginStruct();
-///      widgetDesc.addInt(CGM.SizeTy, widget.getPower());
-///      widgetDesc.add(CGM.GetAddrOfConstantString(widget.getName()));
-///      widgetDesc.add(CGM.GetAddrOfGlobal(widget.getInitializerDecl()));
-///      widgetArray.add(widgetDesc.finish());
-///    }
-///    toplevel.add(widgetArray.finish());
-///    auto global = toplevel.finishAndCreateGlobal("WIDGET_LIST", Align,
-///                                                 /*constant*/ true);
-class ConstantInitBuilder {
-  struct SelfReference {
-    llvm::GlobalVariable *Dummy;
-    llvm::SmallVector<llvm::Constant*, 4> Indices;
-
-    SelfReference(llvm::GlobalVariable *dummy) : Dummy(dummy) {}
-  };
-  CodeGenModule &CGM;
-  llvm::SmallVector<llvm::Constant*, 16> Buffer;
-  std::vector<SelfReference> SelfReferences;
-  bool Frozen = false;
-
-public:
-  explicit ConstantInitBuilder(CodeGenModule &CGM) : CGM(CGM) {}
-
-  ~ConstantInitBuilder() {
-    assert(Buffer.empty() && "didn't claim all values out of buffer");
-  }
-
-  class AggregateBuilderBase {
-  protected:
-    ConstantInitBuilder &Builder;
-    AggregateBuilderBase *Parent;
-    size_t Begin;
-    bool Finished = false;
-    bool Frozen = false;
-
-    llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() {
-      return Builder.Buffer;
-    }
-
-    const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const {
-      return Builder.Buffer;
-    }
-
-    AggregateBuilderBase(ConstantInitBuilder &builder,
-                         AggregateBuilderBase *parent)
-        : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {
-      if (parent) {
-        assert(!parent->Frozen && "parent already has child builder active");
-        parent->Frozen = true;
-      } else {
-        assert(!builder.Frozen && "builder already has child builder active");
-        builder.Frozen = true;
-      }
-    }
-
-    ~AggregateBuilderBase() {
-      assert(Finished && "didn't finish aggregate builder");
-    }
-
-    void markFinished() {
-      assert(!Frozen && "child builder still active");
-      assert(!Finished && "builder already finished");
-      Finished = true;
-      if (Parent) {
-        assert(Parent->Frozen &&
-               "parent not frozen while child builder active");
-        Parent->Frozen = false;
-      } else {
-        assert(Builder.Frozen &&
-               "builder not frozen while child builder active");
-        Builder.Frozen = false;
-      }
-    }
-
-  public:
-    // Not copyable.
-    AggregateBuilderBase(const AggregateBuilderBase &) = delete;
-    AggregateBuilderBase &operator=(const AggregateBuilderBase &) = delete;
-
-    // Movable, mostly to allow returning.  But we have to write this out
-    // properly to satisfy the assert in the destructor.
-    AggregateBuilderBase(AggregateBuilderBase &&other)
-      : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),
-        Finished(other.Finished), Frozen(other.Frozen) {
-      other.Finished = false;
-    }
-    AggregateBuilderBase &operator=(AggregateBuilderBase &&other) = delete;
-
-    /// Abandon this builder completely.
-    void abandon() {
-      markFinished();
-      auto &buffer = Builder.Buffer;
-      buffer.erase(buffer.begin() + Begin, buffer.end());
-    }
-
-    /// Add a new value to this initializer.
-    void add(llvm::Constant *value) {
-      assert(value && "adding null value to constant initializer");
-      assert(!Finished && "cannot add more values after finishing builder");
-      assert(!Frozen && "cannot add values while subbuilder is active");
-      Builder.Buffer.push_back(value);
-    }
-
-    /// Add an integer value of type size_t.
-    void addSize(CharUnits size) {
-      add(Builder.CGM.getSize(size));
-    }
-
-    /// Add an integer value of a specific type.
-    void addInt(llvm::IntegerType *intTy, uint64_t value,
-                bool isSigned = false) {
-      add(llvm::ConstantInt::get(intTy, value, isSigned));
-    }
-
-    /// Add a null pointer of a specific type.
-    void addNullPointer(llvm::PointerType *ptrTy) {
-      add(llvm::ConstantPointerNull::get(ptrTy));
-    }
-
-    /// Add a bitcast of a value to a specific type.
-    void addBitCast(llvm::Constant *value, llvm::Type *type) {
-      add(llvm::ConstantExpr::getBitCast(value, type));
-    }
-
-    /// Add a bunch of new values to this initializer.
-    void addAll(ArrayRef<llvm::Constant *> values) {
-      assert(!Finished && "cannot add more values after finishing builder");
-      assert(!Frozen && "cannot add values while subbuilder is active");
-      Builder.Buffer.append(values.begin(), values.end());
-    }
-
-    /// An opaque class to hold the abstract position of a placeholder.
-    class PlaceholderPosition {
-      size_t Index;
-      friend class AggregateBuilderBase;
-      PlaceholderPosition(size_t index) : Index(index) {}
-    };
-
-    /// Add a placeholder value to the structure.  The returned position
-    /// can be used to set the value later; it will not be invalidated by
-    /// any intermediate operations except (1) filling the same position or
-    /// (2) finishing the entire builder.
-    ///
-    /// This is useful for emitting certain kinds of structure which
-    /// contain some sort of summary field, generaly a count, before any
-    /// of the data.  By emitting a placeholder first, the structure can
-    /// be emitted eagerly.
-    PlaceholderPosition addPlaceholder() {
-      assert(!Finished && "cannot add more values after finishing builder");
-      assert(!Frozen && "cannot add values while subbuilder is active");
-      Builder.Buffer.push_back(nullptr);
-      return Builder.Buffer.size() - 1;
-    }
-
-    /// Fill a previously-added placeholder.
-    void fillPlaceholderWithInt(PlaceholderPosition position,
-                                llvm::IntegerType *type, uint64_t value,
-                                bool isSigned = false) {
-      fillPlaceholder(position, llvm::ConstantInt::get(type, value, isSigned));
-    }
-
-    /// Fill a previously-added placeholder.
-    void fillPlaceholder(PlaceholderPosition position, llvm::Constant *value) {
-      assert(!Finished && "cannot change values after finishing builder");
-      assert(!Frozen && "cannot add values while subbuilder is active");
-      llvm::Constant *&slot = Builder.Buffer[position.Index];
-      assert(slot == nullptr && "placeholder already filled");
-      slot = value;
-    }
-
-    /// Produce an address which will eventually point to the the next
-    /// position to be filled.  This is computed with an indexed
-    /// getelementptr rather than by computing offsets.
-    ///
-    /// The returned pointer will have type T*, where T is the given
-    /// position.
-    llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type) {
-      // Make a global variable.  We will replace this with a GEP to this
-      // position after installing the initializer.
-      auto dummy =
-        new llvm::GlobalVariable(Builder.CGM.getModule(), type, true,
-                                 llvm::GlobalVariable::PrivateLinkage,
-                                 nullptr, "");
-      Builder.SelfReferences.emplace_back(dummy);
-      auto &entry = Builder.SelfReferences.back();
-      (void) getGEPIndicesToCurrentPosition(entry.Indices);
-      return dummy;
-    }
-
-    ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
-                             llvm::SmallVectorImpl<llvm::Constant*> &indices) {
-      getGEPIndicesTo(indices, Builder.Buffer.size());
-      return indices;
-    }
-
-    ConstantArrayBuilder beginArray(llvm::Type *eltTy = nullptr);
-    ConstantStructBuilder beginStruct(llvm::StructType *structTy = nullptr);
-
-  private:
-    void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
-                         size_t position) const {
-      // Recurse on the parent builder if present.
-      if (Parent) {
-        Parent->getGEPIndicesTo(indices, Begin);
-
-      // Otherwise, add an index to drill into the first level of pointer. 
-      } else {
-        assert(indices.empty());
-        indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, 0));
-      }
-
-      assert(position >= Begin);
-      // We have to use i32 here because struct GEPs demand i32 indices.
-      // It's rather unlikely to matter in practice.
-      indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty,
-                                               position - Begin));
-    }
-  };
-
-  template <class Impl>
-  class AggregateBuilder : public AggregateBuilderBase {
-  protected:
-    AggregateBuilder(ConstantInitBuilder &builder,
-                     AggregateBuilderBase *parent)
-      : AggregateBuilderBase(builder, parent) {}
-
-    Impl &asImpl() { return *static_cast<Impl*>(this); }
-
-  public:
-    /// Given that this builder was created by beginning an array or struct
-    /// component on the given parent builder, finish the array/struct
-    /// component and add it to the parent.
-    ///
-    /// It is an intentional choice that the parent is passed in explicitly
-    /// despite it being redundant with information already kept in the
-    /// builder.  This aids in readability by making it easier to find the
-    /// places that add components to a builder, as well as "bookending"
-    /// the sub-builder more explicitly.
-    void finishAndAddTo(AggregateBuilderBase &parent) {
-      assert(Parent == &parent && "adding to non-parent builder");
-      parent.add(asImpl().finishImpl());
-    }
-
-    /// Given that this builder was created by beginning an array or struct
-    /// directly on a ConstantInitBuilder, finish the array/struct and
-    /// create a global variable with it as the initializer.
-    template <class... As>
-    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
-      assert(!Parent && "finishing non-root builder");
-      return Builder.createGlobal(asImpl().finishImpl(),
-                                  std::forward<As>(args)...);
-    }
-
-    /// Given that this builder was created by beginning an array or struct
-    /// directly on a ConstantInitBuilder, finish the array/struct and
-    /// set it as the initializer of the given global variable.
-    void finishAndSetAsInitializer(llvm::GlobalVariable *global) {
-      assert(!Parent && "finishing non-root builder");
-      return Builder.setGlobalInitializer(global, asImpl().finishImpl());
-    }
-  };
-
-  ConstantArrayBuilder beginArray(llvm::Type *eltTy = nullptr);
-
-  ConstantStructBuilder beginStruct(llvm::StructType *structTy = nullptr);
-
-private:
-  llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,
-                                     const llvm::Twine &name,
-                                     CharUnits alignment,
-                                     bool constant = false,
-                                     llvm::GlobalValue::LinkageTypes linkage
-                                       = llvm::GlobalValue::InternalLinkage,
-                                     unsigned addressSpace = 0) {
-    auto GV = new llvm::GlobalVariable(CGM.getModule(),
-                                       initializer->getType(),
-                                       constant,
-                                       linkage,
-                                       initializer,
-                                       name,
-                                       /*insert before*/ nullptr,
-                                       llvm::GlobalValue::NotThreadLocal,
-                                       addressSpace);
-    GV->setAlignment(alignment.getQuantity());
-    resolveSelfReferences(GV);
-    return GV;
-  }
-
-  void setGlobalInitializer(llvm::GlobalVariable *GV,
-                            llvm::Constant *initializer) {
-    GV->setInitializer(initializer);
-    resolveSelfReferences(GV);
-  }
-
-  void resolveSelfReferences(llvm::GlobalVariable *GV) {
-    for (auto &entry : SelfReferences) {
-      llvm::Constant *resolvedReference =
-        llvm::ConstantExpr::getInBoundsGetElementPtr(
-          GV->getValueType(), GV, entry.Indices);
-      entry.Dummy->replaceAllUsesWith(resolvedReference);
-      entry.Dummy->eraseFromParent();
-    }
-  }
-};
-
-/// A helper class of ConstantInitBuilder, used for building constant
-/// array initializers.
-class ConstantArrayBuilder
-    : public ConstantInitBuilder::AggregateBuilder<ConstantArrayBuilder> {
-  llvm::Type *EltTy;
-  friend class ConstantInitBuilder;
-  template <class Impl> friend class ConstantInitBuilder::AggregateBuilder;
-  ConstantArrayBuilder(ConstantInitBuilder &builder,
-                       AggregateBuilderBase *parent, llvm::Type *eltTy)
-    : AggregateBuilder(builder, parent), EltTy(eltTy) {}
-public:
-  size_t size() const {
-    assert(!Finished);
-    assert(!Frozen);
-    assert(Begin <= getBuffer().size());
-    return getBuffer().size() - Begin;
-  }
-
-  bool empty() const {
-    return size() == 0;
-  }
-
-private:
-  /// Form an array constant from the values that have been added to this
-  /// builder.
-  llvm::Constant *finishImpl() {
-    markFinished();
-
-    auto &buffer = getBuffer();
-    assert((Begin < buffer.size() ||
-            (Begin == buffer.size() && EltTy))
-           && "didn't add any array elements without element type");
-    auto elts = llvm::makeArrayRef(buffer).slice(Begin);
-    auto eltTy = EltTy ? EltTy : elts[0]->getType();
-    auto type = llvm::ArrayType::get(eltTy, elts.size());
-    auto constant = llvm::ConstantArray::get(type, elts);
-    buffer.erase(buffer.begin() + Begin, buffer.end());
-    return constant;
-  }
-};
-
-inline ConstantArrayBuilder
-ConstantInitBuilder::beginArray(llvm::Type *eltTy) {
-  return ConstantArrayBuilder(*this, nullptr, eltTy);
-}
-
-inline ConstantArrayBuilder
-ConstantInitBuilder::AggregateBuilderBase::beginArray(llvm::Type *eltTy) {
-  return ConstantArrayBuilder(Builder, this, eltTy);
-}
-
-/// A helper class of ConstantInitBuilder, used for building constant
-/// struct initializers.
-class ConstantStructBuilder
-    : public ConstantInitBuilder::AggregateBuilder<ConstantStructBuilder> {
-  llvm::StructType *Ty;
-  friend class ConstantInitBuilder;
-  template <class Impl> friend class ConstantInitBuilder::AggregateBuilder;
-  ConstantStructBuilder(ConstantInitBuilder &builder,
-                        AggregateBuilderBase *parent, llvm::StructType *ty)
-    : AggregateBuilder(builder, parent), Ty(ty) {}
-
-  /// Finish the struct.
-  llvm::Constant *finishImpl() {
-    markFinished();
-
-    auto &buffer = getBuffer();
-    assert(Begin < buffer.size() && "didn't add any struct elements?");
-    auto elts = llvm::makeArrayRef(buffer).slice(Begin);
-
-    llvm::Constant *constant;
-    if (Ty) {
-      constant = llvm::ConstantStruct::get(Ty, elts);
-    } else {
-      constant = llvm::ConstantStruct::getAnon(elts, /*packed*/ false);
-    }
-
-    buffer.erase(buffer.begin() + Begin, buffer.end());
-    return constant;
-  }
-};
-
-inline ConstantStructBuilder
-ConstantInitBuilder::beginStruct(llvm::StructType *structTy) {
-  return ConstantStructBuilder(*this, nullptr, structTy);
-}
-
-inline ConstantStructBuilder
-ConstantInitBuilder::AggregateBuilderBase::beginStruct(
-                                                  llvm::StructType *structTy) {
-  return ConstantStructBuilder(Builder, this, structTy);
-}
-
-}  // end namespace CodeGen
-}  // end namespace clang
-
-#endif
diff --git a/lib/CodeGen/ConstantInitBuilder.cpp b/lib/CodeGen/ConstantInitBuilder.cpp
new file mode 100644
index 0000000..7f8d809
--- /dev/null
+++ b/lib/CodeGen/ConstantInitBuilder.cpp
@@ -0,0 +1,280 @@
+//===--- ConstantInitBuilder.cpp - Global initializer builder -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines out-of-line routines for building initializers for
+// global variables, in particular the kind of globals that are implicitly
+// introduced by various language ABIs.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGen/ConstantInitBuilder.h"
+#include "CodeGenModule.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+llvm::Type *ConstantInitFuture::getType() const {
+  assert(Data && "dereferencing null future");
+  if (Data.is<llvm::Constant*>()) {
+    return Data.get<llvm::Constant*>()->getType();
+  } else {
+    return Data.get<ConstantInitBuilderBase*>()->Buffer[0]->getType();
+  }
+}
+
+void ConstantInitFuture::abandon() {
+  assert(Data && "abandoning null future");
+  if (auto builder = Data.dyn_cast<ConstantInitBuilderBase*>()) {
+    builder->abandon(0);
+  }
+  Data = nullptr;
+}
+
+void ConstantInitFuture::installInGlobal(llvm::GlobalVariable *GV) {
+  assert(Data && "installing null future");
+  if (Data.is<llvm::Constant*>()) {
+    GV->setInitializer(Data.get<llvm::Constant*>());
+  } else {
+    auto &builder = *Data.get<ConstantInitBuilderBase*>();
+    assert(builder.Buffer.size() == 1);
+    builder.setGlobalInitializer(GV, builder.Buffer[0]);
+    builder.Buffer.clear();
+    Data = nullptr;
+  }
+}
+
+ConstantInitFuture
+ConstantInitBuilderBase::createFuture(llvm::Constant *initializer) {
+  assert(Buffer.empty() && "buffer not current empty");
+  Buffer.push_back(initializer);
+  return ConstantInitFuture(this);
+}
+
+// Only used in this file.
+inline ConstantInitFuture::ConstantInitFuture(ConstantInitBuilderBase *builder)
+    : Data(builder) {
+  assert(!builder->Frozen);
+  assert(builder->Buffer.size() == 1);
+  assert(builder->Buffer[0] != nullptr);
+}
+
+llvm::GlobalVariable *
+ConstantInitBuilderBase::createGlobal(llvm::Constant *initializer,
+                                      const llvm::Twine &name,
+                                      CharUnits alignment,
+                                      bool constant,
+                                      llvm::GlobalValue::LinkageTypes linkage,
+                                      unsigned addressSpace) {
+  auto GV = new llvm::GlobalVariable(CGM.getModule(),
+                                     initializer->getType(),
+                                     constant,
+                                     linkage,
+                                     initializer,
+                                     name,
+                                     /*insert before*/ nullptr,
+                                     llvm::GlobalValue::NotThreadLocal,
+                                     addressSpace);
+  GV->setAlignment(alignment.getQuantity());
+  resolveSelfReferences(GV);
+  return GV;
+}
+
+void ConstantInitBuilderBase::setGlobalInitializer(llvm::GlobalVariable *GV,
+                                                   llvm::Constant *initializer){
+  GV->setInitializer(initializer);
+
+  if (!SelfReferences.empty())
+    resolveSelfReferences(GV);
+}
+
+void ConstantInitBuilderBase::resolveSelfReferences(llvm::GlobalVariable *GV) {
+  for (auto &entry : SelfReferences) {
+    llvm::Constant *resolvedReference =
+      llvm::ConstantExpr::getInBoundsGetElementPtr(
+        GV->getValueType(), GV, entry.Indices);
+    auto dummy = entry.Dummy;
+    dummy->replaceAllUsesWith(resolvedReference);
+    dummy->eraseFromParent();
+  }
+  SelfReferences.clear();
+}
+
+void ConstantInitBuilderBase::abandon(size_t newEnd) {
+  // Remove all the entries we've added.
+  Buffer.erase(Buffer.begin() + newEnd, Buffer.end());
+
+  // If we're abandoning all the way to the beginning, destroy
+  // all the self-references, because we might not get another
+  // opportunity.
+  if (newEnd == 0) {
+    for (auto &entry : SelfReferences) {
+      auto dummy = entry.Dummy;
+      dummy->replaceAllUsesWith(llvm::UndefValue::get(dummy->getType()));
+      dummy->eraseFromParent();
+    }
+    SelfReferences.clear();
+  }
+}
+
+void ConstantAggregateBuilderBase::addSize(CharUnits size) {
+  add(Builder.CGM.getSize(size));
+}
+
+llvm::Constant *
+ConstantAggregateBuilderBase::getRelativeOffset(llvm::IntegerType *offsetType,
+                                                llvm::Constant *target) {
+  // Compute the address of the relative-address slot.
+  auto base = getAddrOfCurrentPosition(offsetType);
+
+  // Subtract.
+  base = llvm::ConstantExpr::getPtrToInt(base, Builder.CGM.IntPtrTy);
+  target = llvm::ConstantExpr::getPtrToInt(target, Builder.CGM.IntPtrTy);
+  llvm::Constant *offset = llvm::ConstantExpr::getSub(target, base);
+
+  // Truncate to the relative-address type if necessary.
+  if (Builder.CGM.IntPtrTy != offsetType) {
+    offset = llvm::ConstantExpr::getTrunc(offset, offsetType);
+  }
+
+  return offset;
+}
+
+llvm::Constant *
+ConstantAggregateBuilderBase::getAddrOfCurrentPosition(llvm::Type *type) {
+  // Make a global variable.  We will replace this with a GEP to this
+  // position after installing the initializer.
+  auto dummy =
+    new llvm::GlobalVariable(Builder.CGM.getModule(), type, true,
+                             llvm::GlobalVariable::PrivateLinkage,
+                             nullptr, "");
+  Builder.SelfReferences.emplace_back(dummy);
+  auto &entry = Builder.SelfReferences.back();
+  (void) getGEPIndicesToCurrentPosition(entry.Indices);
+  return dummy;
+}
+
+void ConstantAggregateBuilderBase::getGEPIndicesTo(
+                               llvm::SmallVectorImpl<llvm::Constant*> &indices,
+                               size_t position) const {
+  // Recurse on the parent builder if present.
+  if (Parent) {
+    Parent->getGEPIndicesTo(indices, Begin);
+
+  // Otherwise, add an index to drill into the first level of pointer. 
+  } else {
+    assert(indices.empty());
+    indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, 0));
+  }
+
+  assert(position >= Begin);
+  // We have to use i32 here because struct GEPs demand i32 indices.
+  // It's rather unlikely to matter in practice.
+  indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty,
+                                           position - Begin));
+}
+
+ConstantAggregateBuilderBase::PlaceholderPosition
+ConstantAggregateBuilderBase::addPlaceholderWithSize(llvm::Type *type) {
+  // Bring the offset up to the last field.
+  CharUnits offset = getNextOffsetFromGlobal();
+
+  // Create the placeholder.
+  auto position = addPlaceholder();
+
+  // Advance the offset past that field.
+  auto &layout = Builder.CGM.getDataLayout();
+  if (!Packed)
+    offset = offset.alignTo(CharUnits::fromQuantity(
+                                layout.getABITypeAlignment(type)));
+  offset += CharUnits::fromQuantity(layout.getTypeStoreSize(type));
+
+  CachedOffsetEnd = Builder.Buffer.size();
+  CachedOffsetFromGlobal = offset;
+
+  return position;
+}
+
+CharUnits ConstantAggregateBuilderBase::getOffsetFromGlobalTo(size_t end) const{
+  size_t cacheEnd = CachedOffsetEnd;
+  assert(cacheEnd <= end);
+
+  // Fast path: if the cache is valid, just use it.
+  if (cacheEnd == end) {
+    return CachedOffsetFromGlobal;
+  }
+
+  // If the cached range ends before the index at which the current
+  // aggregate starts, recurse for the parent.
+  CharUnits offset;
+  if (cacheEnd < Begin) {
+    assert(cacheEnd == 0);
+    assert(Parent && "Begin != 0 for root builder");
+    cacheEnd = Begin;
+    offset = Parent->getOffsetFromGlobalTo(Begin);
+  } else {
+    offset = CachedOffsetFromGlobal;
+  }
+
+  // Perform simple layout on the elements in cacheEnd..<end.
+  if (cacheEnd != end) {
+    auto &layout = Builder.CGM.getDataLayout();
+    do {
+      llvm::Constant *element = Builder.Buffer[cacheEnd];
+      assert(element != nullptr &&
+             "cannot compute offset when a placeholder is present");
+      llvm::Type *elementType = element->getType();
+      if (!Packed)
+        offset = offset.alignTo(CharUnits::fromQuantity(
+                                  layout.getABITypeAlignment(elementType)));
+      offset += CharUnits::fromQuantity(layout.getTypeStoreSize(elementType));
+    } while (++cacheEnd != end);
+  }
+
+  // Cache and return.
+  CachedOffsetEnd = cacheEnd;
+  CachedOffsetFromGlobal = offset;
+  return offset;
+}
+
+llvm::Constant *ConstantAggregateBuilderBase::finishArray(llvm::Type *eltTy) {
+  markFinished();
+
+  auto &buffer = getBuffer();
+  assert((Begin < buffer.size() ||
+          (Begin == buffer.size() && eltTy))
+         && "didn't add any array elements without element type");
+  auto elts = llvm::makeArrayRef(buffer).slice(Begin);
+  if (!eltTy) eltTy = elts[0]->getType();
+  auto type = llvm::ArrayType::get(eltTy, elts.size());
+  auto constant = llvm::ConstantArray::get(type, elts);
+  buffer.erase(buffer.begin() + Begin, buffer.end());
+  return constant;
+}
+
+llvm::Constant *
+ConstantAggregateBuilderBase::finishStruct(llvm::StructType *ty) {
+  markFinished();
+
+  auto &buffer = getBuffer();
+  auto elts = llvm::makeArrayRef(buffer).slice(Begin);
+
+  if (ty == nullptr && elts.empty())
+    ty = llvm::StructType::get(Builder.CGM.getLLVMContext(), {}, Packed);
+
+  llvm::Constant *constant;
+  if (ty) {
+    assert(ty->isPacked() == Packed);
+    constant = llvm::ConstantStruct::get(ty, elts);
+  } else {
+    constant = llvm::ConstantStruct::getAnon(elts, Packed);
+  }
+
+  buffer.erase(buffer.begin() + Begin, buffer.end());
+  return constant;
+}
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index db648f2..3b2183e 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -24,8 +24,8 @@
 #include "CGVTables.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
 #include "TargetInfo.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/StmtCXX.h"
@@ -207,8 +207,9 @@
 
   void EmitCXXConstructors(const CXXConstructorDecl *D) override;
 
-  void buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
-                              SmallVectorImpl<CanQualType> &ArgTys) override;
+  AddedStructorArgs
+  buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
+                         SmallVectorImpl<CanQualType> &ArgTys) override;
 
   bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
                               CXXDtorType DT) const override {
@@ -225,11 +226,10 @@
 
   void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
 
-  unsigned addImplicitConstructorArgs(CodeGenFunction &CGF,
-                                      const CXXConstructorDecl *D,
-                                      CXXCtorType Type, bool ForVirtualBase,
-                                      bool Delegating,
-                                      CallArgList &Args) override;
+  AddedStructorArgs
+  addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
+                             CXXCtorType Type, bool ForVirtualBase,
+                             bool Delegating, CallArgList &Args) override;
 
   void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
                           CXXDtorType Type, bool ForVirtualBase,
@@ -366,11 +366,12 @@
   void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
 
  private:
-   bool hasAnyUsedVirtualInlineFunction(const CXXRecordDecl *RD) const {
+   bool hasAnyVirtualInlineFunction(const CXXRecordDecl *RD) const {
     const auto &VtableLayout =
         CGM.getItaniumVTableContext().getVTableLayout(RD);
 
     for (const auto &VtableComponent : VtableLayout.vtable_components()) {
+      // Skip empty slot.
       if (!VtableComponent.isUsedFunctionPointerKind())
         continue;
 
@@ -1352,7 +1353,7 @@
   }
 }
 
-void
+CGCXXABI::AddedStructorArgs
 ItaniumCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
                                       SmallVectorImpl<CanQualType> &ArgTys) {
   ASTContext &Context = getContext();
@@ -1361,9 +1362,12 @@
   // These are Clang types, so we don't need to worry about sret yet.
 
   // Check if we need to add a VTT parameter (which has type void **).
-  if (T == StructorType::Base && MD->getParent()->getNumVBases() != 0)
+  if (T == StructorType::Base && MD->getParent()->getNumVBases() != 0) {
     ArgTys.insert(ArgTys.begin() + 1,
                   Context.getPointerType(Context.VoidPtrTy));
+    return AddedStructorArgs::prefix(1);
+  }
+  return AddedStructorArgs{};
 }
 
 void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
@@ -1428,11 +1432,11 @@
     CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
 }
 
-unsigned ItaniumCXXABI::addImplicitConstructorArgs(
+CGCXXABI::AddedStructorArgs ItaniumCXXABI::addImplicitConstructorArgs(
     CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
     bool ForVirtualBase, bool Delegating, CallArgList &Args) {
   if (!NeedsVTTParameter(GlobalDecl(D, Type)))
-    return 0;
+    return AddedStructorArgs{};
 
   // Insert the implicit 'vtt' argument as the second argument.
   llvm::Value *VTT =
@@ -1440,7 +1444,7 @@
   QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
   Args.insert(Args.begin() + 1,
               CallArg(RValue::get(VTT), VTTTy, /*needscopy=*/false));
-  return 1;  // Added one arg.
+  return AddedStructorArgs::prefix(1);  // Added one arg.
 }
 
 void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
@@ -1479,7 +1483,7 @@
 
   // Create and set the initializer.
   ConstantInitBuilder Builder(CGM);
-  auto Components = Builder.beginArray(CGM.Int8PtrTy);
+  auto Components = Builder.beginStruct();
   CGVT.createVTableInitializer(Components, VTLayout, RTTI);
   Components.finishAndSetAsInitializer(VTable);
 
@@ -1537,17 +1541,21 @@
                                      const CXXRecordDecl *VTableClass) {
   llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());
 
-  // Find the appropriate vtable within the vtable group.
-  uint64_t AddressPoint = CGM.getItaniumVTableContext()
-                              .getVTableLayout(VTableClass)
-                              .getAddressPoint(Base);
+  // Find the appropriate vtable within the vtable group, and the address point
+  // within that vtable.
+  VTableLayout::AddressPointLocation AddressPoint =
+      CGM.getItaniumVTableContext()
+          .getVTableLayout(VTableClass)
+          .getAddressPoint(Base);
   llvm::Value *Indices[] = {
     llvm::ConstantInt::get(CGM.Int32Ty, 0),
-    llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint)
+    llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.VTableIndex),
+    llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.AddressPointIndex),
   };
 
-  return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable->getValueType(),
-                                                      VTable, Indices);
+  return llvm::ConstantExpr::getGetElementPtr(VTable->getValueType(), VTable,
+                                              Indices, /*InBounds=*/true,
+                                              /*InRangeIndex=*/1);
 }
 
 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
@@ -1589,12 +1597,12 @@
   llvm::raw_svector_ostream Out(Name);
   getMangleContext().mangleCXXVTable(RD, Out);
 
-  ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
-  llvm::ArrayType *ArrayType = llvm::ArrayType::get(
-      CGM.Int8PtrTy, VTContext.getVTableLayout(RD).vtable_components().size());
+  const VTableLayout &VTLayout =
+      CGM.getItaniumVTableContext().getVTableLayout(RD);
+  llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
 
   VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
-      Name, ArrayType, llvm::GlobalValue::ExternalLinkage);
+      Name, VTableType, llvm::GlobalValue::ExternalLinkage);
   VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
   if (RD->hasAttr<DLLImportAttr>())
@@ -1683,7 +1691,7 @@
   // then we are safe to emit available_externally copy of vtable.
   // FIXME we can still emit a copy of the vtable if we
   // can emit definition of the inline functions.
-  return !hasAnyUsedVirtualInlineFunction(RD) && !isVTableHidden(RD);
+  return !hasAnyVirtualInlineFunction(RD) && !isVTableHidden(RD);
 }
 static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF,
                                           Address InitialPtr,
@@ -2010,10 +2018,11 @@
 
     // The ABI says: "It is suggested that it be emitted in the same COMDAT
     // group as the associated data object." In practice, this doesn't work for
-    // non-ELF object formats, so only do it for ELF.
+    // non-ELF and non-Wasm object formats, so only do it for ELF and Wasm.
     llvm::Comdat *C = var->getComdat();
     if (!D.isLocalVarDecl() && C &&
-        CGM.getTarget().getTriple().isOSBinFormatELF()) {
+        (CGM.getTarget().getTriple().isOSBinFormatELF() ||
+         CGM.getTarget().getTriple().isOSBinFormatWasm())) {
       guard->setComdat(C);
       // An inline variable's guard function is run from the per-TU
       // initialization function, not via a dedicated global ctor function, so
@@ -2156,7 +2165,9 @@
 
   // Create a variable that binds the atexit to this shared object.
   llvm::Constant *handle =
-    CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
+      CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
+  auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
+  GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
 
   llvm::Value *args[] = {
     llvm::ConstantExpr::getBitCast(dtor, dtorTy),
@@ -2267,7 +2278,21 @@
     ArrayRef<llvm::Function *> CXXThreadLocalInits,
     ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
   llvm::Function *InitFunc = nullptr;
-  if (!CXXThreadLocalInits.empty()) {
+
+  // Separate initializers into those with ordered (or partially-ordered)
+  // initialization and those with unordered initialization.
+  llvm::SmallVector<llvm::Function *, 8> OrderedInits;
+  llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
+  for (unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
+    if (isTemplateInstantiation(
+            CXXThreadLocalInitVars[I]->getTemplateSpecializationKind()))
+      UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
+          CXXThreadLocalInits[I];
+    else
+      OrderedInits.push_back(CXXThreadLocalInits[I]);
+  }
+
+  if (!OrderedInits.empty()) {
     // Generate a guarded initialization function.
     llvm::FunctionType *FTy =
         llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
@@ -2284,24 +2309,28 @@
     CharUnits GuardAlign = CharUnits::One();
     Guard->setAlignment(GuardAlign.getQuantity());
 
-    CodeGenFunction(CGM)
-        .GenerateCXXGlobalInitFunc(InitFunc, CXXThreadLocalInits,
-                                   Address(Guard, GuardAlign));
+    CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(InitFunc, OrderedInits,
+                                                   Address(Guard, GuardAlign));
     // On Darwin platforms, use CXX_FAST_TLS calling convention.
     if (CGM.getTarget().getTriple().isOSDarwin()) {
       InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
       InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
     }
   }
+
+  // Emit thread wrappers.
   for (const VarDecl *VD : CXXThreadLocals) {
     llvm::GlobalVariable *Var =
         cast<llvm::GlobalVariable>(CGM.GetGlobalValue(CGM.getMangledName(VD)));
+    llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
 
     // Some targets require that all access to thread local variables go through
     // the thread wrapper.  This means that we cannot attempt to create a thread
     // wrapper or a thread helper.
-    if (isThreadWrapperReplaceable(VD, CGM) && !VD->hasDefinition())
+    if (isThreadWrapperReplaceable(VD, CGM) && !VD->hasDefinition()) {
+      Wrapper->setLinkage(llvm::Function::ExternalLinkage);
       continue;
+    }
 
     // Mangle the name for the thread_local initialization function.
     SmallString<256> InitFnName;
@@ -2317,18 +2346,21 @@
     bool InitIsInitFunc = false;
     if (VD->hasDefinition()) {
       InitIsInitFunc = true;
-      if (InitFunc)
+      llvm::Function *InitFuncToUse = InitFunc;
+      if (isTemplateInstantiation(VD->getTemplateSpecializationKind()))
+        InitFuncToUse = UnorderedInits.lookup(VD->getCanonicalDecl());
+      if (InitFuncToUse)
         Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
-                                         InitFunc);
+                                         InitFuncToUse);
     } else {
       // Emit a weak global function referring to the initialization function.
       // This function will not exist if the TU defining the thread_local
       // variable in question does not need any dynamic initialization for
       // its thread_local variables.
       llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.VoidTy, false);
-      Init = llvm::Function::Create(
-          FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(),
-          &CGM.getModule());
+      Init = llvm::Function::Create(FnTy,
+                                    llvm::GlobalVariable::ExternalWeakLinkage,
+                                    InitFnName.str(), &CGM.getModule());
       const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
       CGM.SetLLVMFunctionAttributes(nullptr, FI, cast<llvm::Function>(Init));
     }
@@ -2336,7 +2368,6 @@
     if (Init)
       Init->setVisibility(Var->getVisibility());
 
-    llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
     llvm::LLVMContext &Context = CGM.getModule().getContext();
     llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Wrapper);
     CGBuilderTy Builder(CGM, Entry);
@@ -2609,7 +2640,6 @@
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
-    case BuiltinType::OCLNDRange:
     case BuiltinType::OCLReserveID:
       return false;
 
@@ -2789,7 +2819,8 @@
     llvm_unreachable("References shouldn't get here");
 
   case Type::Auto:
-    llvm_unreachable("Undeduced auto type shouldn't get here");
+  case Type::DeducedTemplateSpecialization:
+    llvm_unreachable("Undeduced type shouldn't get here");
 
   case Type::Pipe:
     llvm_unreachable("Pipe types shouldn't get here");
@@ -3019,7 +3050,8 @@
     llvm_unreachable("References shouldn't get here");
 
   case Type::Auto:
-    llvm_unreachable("Undeduced auto type shouldn't get here");
+  case Type::DeducedTemplateSpecialization:
+    llvm_unreachable("Undeduced type shouldn't get here");
 
   case Type::Pipe:
     llvm_unreachable("Pipe type shouldn't get here");
@@ -3509,8 +3541,9 @@
     return StructorCodegen::RAUW;
 
   if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
-    // Only ELF supports COMDATs with arbitrary names (C5/D5).
-    if (CGM.getTarget().getTriple().isOSBinFormatELF())
+    // Only ELF and wasm support COMDATs with arbitrary names (C5/D5).
+    if (CGM.getTarget().getTriple().isOSBinFormatELF() ||
+        CGM.getTarget().getTriple().isOSBinFormatWasm())
       return StructorCodegen::COMDAT;
     return StructorCodegen::Emit;
   }
@@ -3895,7 +3928,8 @@
   llvm::FunctionType *fnTy =
     llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
   llvm::Constant *fnRef =
-    CGM.CreateRuntimeFunction(fnTy, "__clang_call_terminate");
+      CGM.CreateRuntimeFunction(fnTy, "__clang_call_terminate",
+                                llvm::AttributeSet(), /*Local=*/true);
 
   llvm::Function *fn = dyn_cast<llvm::Function>(fnRef);
   if (fn && fn->empty()) {
diff --git a/lib/CodeGen/MacroPPCallbacks.cpp b/lib/CodeGen/MacroPPCallbacks.cpp
new file mode 100644
index 0000000..acea5c1
--- /dev/null
+++ b/lib/CodeGen/MacroPPCallbacks.cpp
@@ -0,0 +1,207 @@
+//===--- MacroPPCallbacks.cpp ---------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file contains implementation for the macro preprocessors callbacks.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MacroPPCallbacks.h"
+#include "CGDebugInfo.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Parse/Parser.h"
+
+using namespace clang;
+
+void MacroPPCallbacks::writeMacroDefinition(const IdentifierInfo &II,
+                                            const MacroInfo &MI,
+                                            Preprocessor &PP, raw_ostream &Name,
+                                            raw_ostream &Value) {
+  Name << II.getName();
+
+  if (MI.isFunctionLike()) {
+    Name << '(';
+    if (!MI.arg_empty()) {
+      MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
+      for (; AI + 1 != E; ++AI) {
+        Name << (*AI)->getName();
+        Name << ',';
+      }
+
+      // Last argument.
+      if ((*AI)->getName() == "__VA_ARGS__")
+        Name << "...";
+      else
+        Name << (*AI)->getName();
+    }
+
+    if (MI.isGNUVarargs())
+      // #define foo(x...)
+      Name << "...";
+
+    Name << ')';
+  }
+
+  SmallString<128> SpellingBuffer;
+  bool First = true;
+  for (const auto &T : MI.tokens()) {
+    if (!First && T.hasLeadingSpace())
+      Value << ' ';
+
+    Value << PP.getSpelling(T, SpellingBuffer);
+    First = false;
+  }
+}
+
+MacroPPCallbacks::MacroPPCallbacks(CodeGenerator *Gen, Preprocessor &PP)
+    : Gen(Gen), PP(PP), Status(NoScope) {}
+
+// This is the expected flow of enter/exit compiler and user files:
+// - Main File Enter
+//   - <built-in> file enter
+//     {Compiler macro definitions} - (Line=0, no scope)
+//     - (Optional) <command line> file enter
+//     {Command line macro definitions} - (Line=0, no scope)
+//     - (Optional) <command line> file exit
+//     {Command line file includes} - (Line=0, Main file scope)
+//       {macro definitions and file includes} - (Line!=0, Parent scope)
+//   - <built-in> file exit
+//   {User code macro definitions and file includes} - (Line!=0, Parent scope)
+
+llvm::DIMacroFile *MacroPPCallbacks::getCurrentScope() {
+  if (Status == MainFileScope || Status == CommandLineIncludeScope)
+    return Scopes.back();
+  return nullptr;
+}
+
+SourceLocation MacroPPCallbacks::getCorrectLocation(SourceLocation Loc) {
+  if (Status == MainFileScope || EnteredCommandLineIncludeFiles)
+    return Loc;
+
+  // While parsing skipped files, location of macros is invalid.
+  // Invalid location represents line zero.
+  return SourceLocation();
+}
+
+static bool isBuiltinFile(SourceManager &SM, SourceLocation Loc) {
+  StringRef Filename(SM.getPresumedLoc(Loc).getFilename());
+  return Filename.equals("<built-in>");
+}
+
+static bool isCommandLineFile(SourceManager &SM, SourceLocation Loc) {
+  StringRef Filename(SM.getPresumedLoc(Loc).getFilename());
+  return Filename.equals("<command line>");
+}
+
+void MacroPPCallbacks::updateStatusToNextScope() {
+  switch (Status) {
+  case NoScope:
+    Status = InitializedScope;
+    break;
+  case InitializedScope:
+    Status = BuiltinScope;
+    break;
+  case BuiltinScope:
+    Status = CommandLineIncludeScope;
+    break;
+  case CommandLineIncludeScope:
+    Status = MainFileScope;
+    break;
+  case MainFileScope:
+    llvm_unreachable("There is no next scope, already in the final scope");
+  }
+}
+
+void MacroPPCallbacks::FileEntered(SourceLocation Loc) {
+  SourceLocation LineLoc = getCorrectLocation(LastHashLoc);
+  switch (Status) {
+  case NoScope:
+    updateStatusToNextScope();
+    break;
+  case InitializedScope:
+    updateStatusToNextScope();
+    return;
+  case BuiltinScope:
+    if (isCommandLineFile(PP.getSourceManager(), Loc))
+      return;
+    updateStatusToNextScope();
+    LLVM_FALLTHROUGH;
+  case CommandLineIncludeScope:
+    EnteredCommandLineIncludeFiles++;
+    break;
+  case MainFileScope:
+    break;
+  }
+
+  Scopes.push_back(Gen->getCGDebugInfo()->CreateTempMacroFile(getCurrentScope(),
+                                                              LineLoc, Loc));
+}
+
+void MacroPPCallbacks::FileExited(SourceLocation Loc) {
+  switch (Status) {
+  default:
+    llvm_unreachable("Do not expect to exit a file from current scope");
+  case BuiltinScope:
+    if (!isBuiltinFile(PP.getSourceManager(), Loc))
+      // Skip next scope and change status to MainFileScope.
+      Status = MainFileScope;
+    return;
+  case CommandLineIncludeScope:
+    if (!EnteredCommandLineIncludeFiles) {
+      updateStatusToNextScope();
+      return;
+    }
+    EnteredCommandLineIncludeFiles--;
+    break;
+  case MainFileScope:
+    break;
+  }
+
+  Scopes.pop_back();
+}
+
+void MacroPPCallbacks::FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                                   SrcMgr::CharacteristicKind FileType,
+                                   FileID PrevFID) {
+  // Only care about enter file or exit file changes.
+  if (Reason == EnterFile)
+    FileEntered(Loc);
+  else if (Reason == ExitFile)
+    FileExited(Loc);
+}
+
+void MacroPPCallbacks::InclusionDirective(
+    SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
+    bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
+    StringRef SearchPath, StringRef RelativePath, const Module *Imported) {
+
+  // Record the line location of the current included file.
+  LastHashLoc = HashLoc;
+}
+
+void MacroPPCallbacks::MacroDefined(const Token &MacroNameTok,
+                                    const MacroDirective *MD) {
+  IdentifierInfo *Id = MacroNameTok.getIdentifierInfo();
+  SourceLocation location = getCorrectLocation(MacroNameTok.getLocation());
+  std::string NameBuffer, ValueBuffer;
+  llvm::raw_string_ostream Name(NameBuffer);
+  llvm::raw_string_ostream Value(ValueBuffer);
+  writeMacroDefinition(*Id, *MD->getMacroInfo(), PP, Name, Value);
+  Gen->getCGDebugInfo()->CreateMacro(getCurrentScope(),
+                                     llvm::dwarf::DW_MACINFO_define, location,
+                                     Name.str(), Value.str());
+}
+
+void MacroPPCallbacks::MacroUndefined(const Token &MacroNameTok,
+                                      const MacroDefinition &MD) {
+  IdentifierInfo *Id = MacroNameTok.getIdentifierInfo();
+  SourceLocation location = getCorrectLocation(MacroNameTok.getLocation());
+  Gen->getCGDebugInfo()->CreateMacro(getCurrentScope(),
+                                     llvm::dwarf::DW_MACINFO_undef, location,
+                                     Id->getName(), "");
+}
diff --git a/lib/CodeGen/MacroPPCallbacks.h b/lib/CodeGen/MacroPPCallbacks.h
new file mode 100644
index 0000000..06217f9
--- /dev/null
+++ b/lib/CodeGen/MacroPPCallbacks.h
@@ -0,0 +1,117 @@
+//===--- MacroPPCallbacks.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines implementation for the macro preprocessors callbacks.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/PPCallbacks.h"
+
+namespace llvm {
+class DIMacroFile;
+class DIMacroNode;
+}
+namespace clang {
+class Preprocessor;
+class MacroInfo;
+class CodeGenerator;
+
+class MacroPPCallbacks : public PPCallbacks {
+  /// A pointer to code generator, where debug info generator can be found.
+  CodeGenerator *Gen;
+
+  /// Preprocessor.
+  Preprocessor &PP;
+
+  /// Location of recent included file, used for line number.
+  SourceLocation LastHashLoc;
+
+  /// Counts current number of command line included files, which were entered
+  /// and were not exited yet.
+  int EnteredCommandLineIncludeFiles = 0;
+
+  enum FileScopeStatus {
+    NoScope = 0,              // Scope is not initialized yet.
+    InitializedScope,         // Main file scope is initialized but not set yet.
+    BuiltinScope,             // <built-in> and <command line> file scopes.
+    CommandLineIncludeScope,  // Included file, from <command line> file, scope.
+    MainFileScope             // Main file scope.
+  };
+  FileScopeStatus Status;
+
+  /// Parent contains all entered files that were not exited yet according to
+  /// the inclusion order.
+  llvm::SmallVector<llvm::DIMacroFile *, 4> Scopes;
+
+  /// Get current DIMacroFile scope.
+  /// \return current DIMacroFile scope or nullptr if there is no such scope.
+  llvm::DIMacroFile *getCurrentScope();
+
+  /// Get current line location or invalid location.
+  /// \param Loc current line location.
+  /// \return current line location \p `Loc`, or invalid location if it's in a
+  ///         skipped file scope.
+  SourceLocation getCorrectLocation(SourceLocation Loc);
+
+  /// Use the passed preprocessor to write the macro name and value from the
+  /// given macro info and identifier info into the given \p `Name` and \p
+  /// `Value` output streams.
+  ///
+  /// \param II Identifier info, used to get the Macro name.
+  /// \param MI Macro info, used to get the Macro argumets and values.
+  /// \param PP Preprocessor.
+  /// \param [out] Name Place holder for returned macro name and arguments.
+  /// \param [out] Value Place holder for returned macro value.
+  static void writeMacroDefinition(const IdentifierInfo &II,
+                                   const MacroInfo &MI, Preprocessor &PP,
+                                   raw_ostream &Name, raw_ostream &Value);
+
+  /// Update current file scope status to next file scope.
+  void updateStatusToNextScope();
+
+  /// Handle the case when entering a file.
+  ///
+  /// \param Loc Indicates the new location.
+  void FileEntered(SourceLocation Loc);
+
+  /// Handle the case when exiting a file.
+  ///
+  /// \param Loc Indicates the new location.
+  void FileExited(SourceLocation Loc);
+
+public:
+  MacroPPCallbacks(CodeGenerator *Gen, Preprocessor &PP);
+
+  /// Callback invoked whenever a source file is entered or exited.
+  ///
+  /// \param Loc Indicates the new location.
+  /// \param PrevFID the file that was exited if \p Reason is ExitFile.
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID = FileID()) override;
+
+  /// Callback invoked whenever a directive (#xxx) is processed.
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override;
+
+  /// Hook called whenever a macro definition is seen.
+  void MacroDefined(const Token &MacroNameTok,
+                    const MacroDirective *MD) override;
+
+  /// Hook called whenever a macro \#undef is seen.
+  ///
+  /// MD is released immediately following this callback.
+  void MacroUndefined(const Token &MacroNameTok,
+                      const MacroDefinition &MD) override;
+};
+
+} // end namespace clang
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 08921b9..ddfdefa 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -19,8 +19,8 @@
 #include "CGVTables.h"
 #include "CodeGenModule.h"
 #include "CodeGenTypes.h"
-#include "ConstantBuilder.h"
 #include "TargetInfo.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/StmtCXX.h"
@@ -206,8 +206,9 @@
   // lacks a definition for the destructor, non-base destructors must always
   // delegate to or alias the base destructor.
 
-  void buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
-                              SmallVectorImpl<CanQualType> &ArgTys) override;
+  AddedStructorArgs
+  buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
+                         SmallVectorImpl<CanQualType> &ArgTys) override;
 
   /// Non-base dtors should be emitted as delegating thunks in this ABI.
   bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
@@ -248,11 +249,10 @@
 
   void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
 
-  unsigned addImplicitConstructorArgs(CodeGenFunction &CGF,
-                                      const CXXConstructorDecl *D,
-                                      CXXCtorType Type, bool ForVirtualBase,
-                                      bool Delegating,
-                                      CallArgList &Args) override;
+  AddedStructorArgs
+  addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
+                             CXXCtorType Type, bool ForVirtualBase,
+                             bool Delegating, CallArgList &Args) override;
 
   void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
                           CXXDtorType Type, bool ForVirtualBase,
@@ -1261,17 +1261,19 @@
   }
 }
 
-void
+CGCXXABI::AddedStructorArgs
 MicrosoftCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
                                         SmallVectorImpl<CanQualType> &ArgTys) {
+  AddedStructorArgs Added;
   // TODO: 'for base' flag
   if (T == StructorType::Deleting) {
     // The scalar deleting destructor takes an implicit int parameter.
     ArgTys.push_back(getContext().IntTy);
+    ++Added.Suffix;
   }
   auto *CD = dyn_cast<CXXConstructorDecl>(MD);
   if (!CD)
-    return;
+    return Added;
 
   // All parameters are already in place except is_most_derived, which goes
   // after 'this' if it's variadic and last if it's not.
@@ -1279,11 +1281,16 @@
   const CXXRecordDecl *Class = CD->getParent();
   const FunctionProtoType *FPT = CD->getType()->castAs<FunctionProtoType>();
   if (Class->getNumVBases()) {
-    if (FPT->isVariadic())
+    if (FPT->isVariadic()) {
       ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
-    else
+      ++Added.Prefix;
+    } else {
       ArgTys.push_back(getContext().IntTy);
+      ++Added.Suffix;
+    }
   }
+
+  return Added;
 }
 
 void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
@@ -1493,14 +1500,14 @@
   }
 }
 
-unsigned MicrosoftCXXABI::addImplicitConstructorArgs(
+CGCXXABI::AddedStructorArgs MicrosoftCXXABI::addImplicitConstructorArgs(
     CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
     bool ForVirtualBase, bool Delegating, CallArgList &Args) {
   assert(Type == Ctor_Complete || Type == Ctor_Base);
 
   // Check if we need a 'most_derived' parameter.
   if (!D->getParent()->getNumVBases())
-    return 0;
+    return AddedStructorArgs{};
 
   // Add the 'most_derived' argument second if we are variadic or last if not.
   const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
@@ -1511,13 +1518,13 @@
     MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
   }
   RValue RV = RValue::get(MostDerivedArg);
-  if (FPT->isVariadic())
+  if (FPT->isVariadic()) {
     Args.insert(Args.begin() + 1,
                 CallArg(RV, getContext().IntTy, /*needscopy=*/false));
-  else
-    Args.add(RV, getContext().IntTy);
-
-  return 1;  // Added one arg.
+    return AddedStructorArgs::prefix(1);
+  }
+  Args.add(RV, getContext().IntTy);
+  return AddedStructorArgs::suffix(1);
 }
 
 void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
@@ -1554,7 +1561,7 @@
 void MicrosoftCXXABI::emitVTableTypeMetadata(const VPtrInfo &Info,
                                              const CXXRecordDecl *RD,
                                              llvm::GlobalVariable *VTable) {
-  if (!CGM.getCodeGenOpts().PrepareForLTO)
+  if (!CGM.getCodeGenOpts().LTOUnit)
     return;
 
   // The location of the first virtual function pointer in the virtual table,
@@ -1618,7 +1625,7 @@
       RTTI = getMSCompleteObjectLocator(RD, *Info);
 
     ConstantInitBuilder Builder(CGM);
-    auto Components = Builder.beginArray(CGM.Int8PtrTy);
+    auto Components = Builder.beginStruct();
     CGVT.createVTableInitializer(Components, VTLayout, RTTI);
     Components.finishAndSetAsInitializer(VTable);
 
@@ -1739,17 +1746,14 @@
     return VTable;
   }
 
-  uint64_t NumVTableSlots =
-      VTContext.getVFTableLayout(RD, VFPtr->FullOffsetInMDC)
-          .vtable_components()
-          .size();
+  const VTableLayout &VTLayout =
+      VTContext.getVFTableLayout(RD, VFPtr->FullOffsetInMDC);
   llvm::GlobalValue::LinkageTypes VTableLinkage =
       VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
 
   StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
 
-  llvm::ArrayType *VTableType =
-      llvm::ArrayType::get(CGM.Int8PtrTy, NumVTableSlots);
+  llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
 
   // Create a backing variable for the contents of VTable.  The VTable may
   // or may not include space for a pointer to RTTI data.
@@ -1770,8 +1774,9 @@
   // importing it.  We never reference the RTTI data directly so there is no
   // need to make room for it.
   if (VTableAliasIsRequred) {
-    llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
-                                 llvm::ConstantInt::get(CGM.IntTy, 1)};
+    llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.Int32Ty, 0),
+                                 llvm::ConstantInt::get(CGM.Int32Ty, 0),
+                                 llvm::ConstantInt::get(CGM.Int32Ty, 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(
@@ -2206,7 +2211,8 @@
       CGF.IntTy, DtorStub->getType(), /*IsVarArg=*/false);
 
   llvm::Constant *TLRegDtor =
-      CGF.CGM.CreateRuntimeFunction(TLRegDtorTy, "__tlregdtor");
+      CGF.CGM.CreateRuntimeFunction(TLRegDtorTy, "__tlregdtor",
+                                    llvm::AttributeSet(), /*Local=*/true);
   if (llvm::Function *TLRegDtorFn = dyn_cast<llvm::Function>(TLRegDtor))
     TLRegDtorFn->setDoesNotThrow();
 
@@ -2304,7 +2310,8 @@
       FTy, "_Init_thread_header",
       llvm::AttributeSet::get(CGM.getLLVMContext(),
                               llvm::AttributeSet::FunctionIndex,
-                              llvm::Attribute::NoUnwind));
+                              llvm::Attribute::NoUnwind),
+      /*Local=*/true);
 }
 
 static llvm::Constant *getInitThreadFooterFn(CodeGenModule &CGM) {
@@ -2315,7 +2322,8 @@
       FTy, "_Init_thread_footer",
       llvm::AttributeSet::get(CGM.getLLVMContext(),
                               llvm::AttributeSet::FunctionIndex,
-                              llvm::Attribute::NoUnwind));
+                              llvm::Attribute::NoUnwind),
+      /*Local=*/true);
 }
 
 static llvm::Constant *getInitThreadAbortFn(CodeGenModule &CGM) {
@@ -2326,7 +2334,8 @@
       FTy, "_Init_thread_abort",
       llvm::AttributeSet::get(CGM.getLLVMContext(),
                               llvm::AttributeSet::FunctionIndex,
-                              llvm::Attribute::NoUnwind));
+                              llvm::Attribute::NoUnwind),
+      /*Local=*/true);
 }
 
 namespace {
@@ -3534,7 +3543,7 @@
 
   // Initialize the base class ClassHierarchyDescriptor.
   llvm::Constant *Fields[] = {
-      llvm::ConstantInt::get(CGM.IntTy, 0), // Unknown
+      llvm::ConstantInt::get(CGM.IntTy, 0), // reserved by the runtime
       llvm::ConstantInt::get(CGM.IntTy, Flags),
       llvm::ConstantInt::get(CGM.IntTy, Classes.size()),
       ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
@@ -3916,16 +3925,16 @@
   CGF.EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
 
   // Insert any ABI-specific implicit constructor arguments.
-  unsigned ExtraArgs = addImplicitConstructorArgs(CGF, CD, Ctor_Complete,
-                                                  /*ForVirtualBase=*/false,
-                                                  /*Delegating=*/false, Args);
-
+  AddedStructorArgs ExtraArgs =
+      addImplicitConstructorArgs(CGF, CD, Ctor_Complete,
+                                 /*ForVirtualBase=*/false,
+                                 /*Delegating=*/false, Args);
   // Call the destructor with our arguments.
   llvm::Constant *CalleePtr =
     CGM.getAddrOfCXXStructor(CD, StructorType::Complete);
   CGCallee Callee = CGCallee::forDirect(CalleePtr, CD);
   const CGFunctionInfo &CalleeInfo = CGM.getTypes().arrangeCXXConstructorCall(
-      Args, CD, Ctor_Complete, ExtraArgs);
+      Args, CD, Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
   CGF.EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args);
 
   Cleanups.ForceCleanup();
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index f925c25..89090c8 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -92,6 +92,10 @@
       return M.get();
     }
 
+    CGDebugInfo *getCGDebugInfo() {
+      return Builder->getModuleDebugInfo();
+    }
+
     llvm::Module *ReleaseModule() {
       return M.release();
     }
@@ -299,6 +303,10 @@
   return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
 }
 
+CGDebugInfo *CodeGenerator::getCGDebugInfo() {
+  return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo();
+}
+
 const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) {
   return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
 }
diff --git a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
index baf7811..37ecc05a 100644
--- a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -171,7 +171,8 @@
     // Prepare CGDebugInfo to emit debug info for a clang module.
     auto *DI = Builder->getModuleDebugInfo();
     StringRef ModuleName = llvm::sys::path::filename(MainFileName);
-    DI->setPCHDescriptor({ModuleName, "", OutputFileName, ~1ULL});
+    DI->setPCHDescriptor({ModuleName, "", OutputFileName,
+                          ASTFileSignature{{{~0U, ~0U, ~0U, ~0U, ~1U}}}});
     DI->setModuleMap(MMap);
   }
 
@@ -241,7 +242,11 @@
 
     // PCH files don't have a signature field in the control block,
     // but LLVM detects DWO CUs by looking for a non-zero DWO id.
-    uint64_t Signature = Buffer->Signature ? Buffer->Signature : ~1ULL;
+    // We use the lower 64 bits for debug info.
+    uint64_t Signature =
+        Buffer->Signature
+            ? (uint64_t)Buffer->Signature[1] << 32 | Buffer->Signature[0]
+            : ~1ULL;
     Builder->getModuleDebugInfo()->setDwoId(Signature);
 
     // Finalize the Builder.
@@ -282,7 +287,7 @@
       // Print the IR for the PCH container to the debug output.
       llvm::SmallString<0> Buffer;
       clang::EmitBackendOutput(
-          Diags, CodeGenOpts, TargetOpts, LangOpts,
+          Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts,
           Ctx.getTargetInfo().getDataLayout(), M.get(),
           BackendAction::Backend_EmitLL,
           llvm::make_unique<llvm::raw_svector_ostream>(Buffer));
@@ -290,9 +295,10 @@
     });
 
     // Use the LLVM backend to emit the pch container.
-    clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
-                             Ctx.getTargetInfo().getDataLayout(), M.get(),
-                             BackendAction::Backend_EmitObj, std::move(OS));
+    clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
+                             LangOpts, Ctx.getTargetInfo().getDataLayout(),
+                             M.get(), BackendAction::Backend_EmitObj,
+                             std::move(OS));
 
     // Free the memory for the temporary buffer.
     llvm::SmallVector<char, 0> Empty;
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 79d4815..82f412f 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -401,6 +401,20 @@
   return llvm::CallingConv::C;
 }
 
+llvm::Constant *TargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM,
+    llvm::PointerType *T, QualType QT) const {
+  return llvm::ConstantPointerNull::get(T);
+}
+
+llvm::Value *TargetCodeGenInfo::performAddrSpaceCast(
+    CodeGen::CodeGenFunction &CGF, llvm::Value *Src, QualType SrcTy,
+    QualType DestTy) const {
+  // Since target may map different address spaces in AST to the same address
+  // space, an address space conversion may end up as a bitcast.
+  return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Src,
+             CGF.ConvertType(DestTy));
+}
+
 static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);
 
 /// isEmptyField - Return true iff a the field is "empty", that is it
@@ -857,6 +871,14 @@
   return NumMembers <= 4;
 }
 
+/// Returns a Homogeneous Vector Aggregate ABIArgInfo, used in X86.
+static ABIArgInfo getDirectX86Hva(llvm::Type* T = nullptr) {
+  auto AI = ABIArgInfo::getDirect(T);
+  AI.setInReg(true);
+  AI.setCanBeFlattened(false);
+  return AI;
+}
+
 //===----------------------------------------------------------------------===//
 // X86-32 ABI Implementation
 //===----------------------------------------------------------------------===//
@@ -870,6 +892,11 @@
   unsigned FreeSSERegs;
 };
 
+enum {
+  // Vectorcall only allows the first 6 parameters to be passed in registers.
+  VectorcallMaxParamNumAsReg = 6
+};
+
 /// X86_32ABIInfo - The X86-32 ABI information.
 class X86_32ABIInfo : public SwiftABIInfo {
   enum Class {
@@ -915,6 +942,8 @@
   Class classify(QualType Ty) const;
   ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
   ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
+  ABIArgInfo reclassifyHvaArgType(QualType RetTy, CCState &State, 
+                                  const ABIArgInfo& current) const;
   /// \brief Updates the number of available free registers, returns 
   /// true if any registers were allocated.
   bool updateFreeRegs(QualType Ty, CCState &State) const;
@@ -932,6 +961,8 @@
   void addFieldToArgStruct(SmallVector<llvm::Type *, 6> &FrameFields,
                            CharUnits &StackOffset, ABIArgInfo &Info,
                            QualType Type) const;
+  void computeVectorCallArgs(CGFunctionInfo &FI, CCState &State,
+                             bool &UsedInAlloca) const;
 
 public:
 
@@ -1166,6 +1197,39 @@
   return Size == 32 || Size == 64;
 }
 
+static bool addFieldSizes(ASTContext &Context, const RecordDecl *RD,
+                          uint64_t &Size) {
+  for (const auto *FD : RD->fields()) {
+    // Scalar arguments on the stack get 4 byte alignment on x86. If the
+    // argument is smaller than 32-bits, expanding the struct will create
+    // alignment padding.
+    if (!is32Or64BitBasicType(FD->getType(), Context))
+      return false;
+
+    // FIXME: Reject bit-fields wholesale; there are two problems, we don't know
+    // how to expand them yet, and the predicate for telling if a bitfield still
+    // counts as "basic" is more complicated than what we were doing previously.
+    if (FD->isBitField())
+      return false;
+
+    Size += Context.getTypeSize(FD->getType());
+  }
+  return true;
+}
+
+static bool addBaseAndFieldSizes(ASTContext &Context, const CXXRecordDecl *RD,
+                                 uint64_t &Size) {
+  // Don't do this if there are any non-empty bases.
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    if (!addBaseAndFieldSizes(Context, Base.getType()->getAsCXXRecordDecl(),
+                              Size))
+      return false;
+  }
+  if (!addFieldSizes(Context, RD, Size))
+    return false;
+  return true;
+}
+
 /// Test whether an argument type which is to be passed indirectly (on the
 /// stack) would have the equivalent layout if it was expanded into separate
 /// arguments. If so, we prefer to do the latter to avoid inhibiting
@@ -1176,8 +1240,9 @@
   if (!RT)
     return false;
   const RecordDecl *RD = RT->getDecl();
+  uint64_t Size = 0;
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
-    if (!IsWin32StructABI ) {
+    if (!IsWin32StructABI) {
       // On non-Windows, we have to conservatively match our old bitcode
       // prototypes in order to be ABI-compatible at the bitcode level.
       if (!CXXRD->isCLike())
@@ -1186,30 +1251,12 @@
       // Don't do this for dynamic classes.
       if (CXXRD->isDynamicClass())
         return false;
-      // Don't do this if there are any non-empty bases.
-      for (const CXXBaseSpecifier &Base : CXXRD->bases()) {
-        if (!isEmptyRecord(getContext(), Base.getType(), /*AllowArrays=*/true))
-          return false;
-      }
     }
-  }
-
-  uint64_t Size = 0;
-
-  for (const auto *FD : RD->fields()) {
-    // Scalar arguments on the stack get 4 byte alignment on x86. If the
-    // argument is smaller than 32-bits, expanding the struct will create
-    // alignment padding.
-    if (!is32Or64BitBasicType(FD->getType(), getContext()))
+    if (!addBaseAndFieldSizes(getContext(), CXXRD, Size))
       return false;
-
-    // FIXME: Reject bit-fields wholesale; there are two problems, we don't know
-    // how to expand them yet, and the predicate for telling if a bitfield still
-    // counts as "basic" is more complicated than what we were doing previously.
-    if (FD->isBitField())
+  } else {
+    if (!addFieldSizes(getContext(), RD, Size))
       return false;
-
-    Size += getContext().getTypeSize(FD->getType());
   }
 
   // We can do this if there was no alignment padding.
@@ -1480,6 +1527,27 @@
   return true;
 }
 
+ABIArgInfo
+X86_32ABIInfo::reclassifyHvaArgType(QualType Ty, CCState &State,
+                                    const ABIArgInfo &current) const {
+  // Assumes vectorCall calling convention.
+  const Type *Base = nullptr;
+  uint64_t NumElts = 0;
+
+  if (!Ty->isBuiltinType() && !Ty->isVectorType() &&
+      isHomogeneousAggregate(Ty, Base, NumElts)) {
+    if (State.FreeSSERegs >= NumElts) {
+      // HVA types get passed directly in registers if there is room.
+      State.FreeSSERegs -= NumElts;
+      return getDirectX86Hva();
+    }
+    // If there's no room, the HVA gets passed as normal indirect
+    // structure.
+    return getIndirectResult(Ty, /*ByVal=*/false, State);
+  } 
+  return current;
+}
+
 ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
                                                CCState &State) const {
   // FIXME: Set alignment on indirect arguments.
@@ -1499,19 +1567,34 @@
   }
 
   // vectorcall adds the concept of a homogenous vector aggregate, similar
-  // to other targets.
+  // to other targets, regcall uses some of the HVA rules.
   const Type *Base = nullptr;
   uint64_t NumElts = 0;
   if ((State.CC == llvm::CallingConv::X86_VectorCall ||
        State.CC == llvm::CallingConv::X86_RegCall) &&
       isHomogeneousAggregate(Ty, Base, NumElts)) {
-    if (State.FreeSSERegs >= NumElts) {
-      State.FreeSSERegs -= NumElts;
-      if (Ty->isBuiltinType() || Ty->isVectorType())
+
+    if (State.CC == llvm::CallingConv::X86_RegCall) {
+      if (State.FreeSSERegs >= NumElts) {
+        State.FreeSSERegs -= NumElts;
+        if (Ty->isBuiltinType() || Ty->isVectorType())
+          return ABIArgInfo::getDirect();
+        return ABIArgInfo::getExpand();
+
+      }
+      return getIndirectResult(Ty, /*ByVal=*/false, State);
+    } else if (State.CC == llvm::CallingConv::X86_VectorCall) {
+      if (State.FreeSSERegs >= NumElts && (Ty->isBuiltinType() || Ty->isVectorType())) {
+        // Actual floating-point types get registers first time through if
+        // there is registers available
+        State.FreeSSERegs -= NumElts;
         return ABIArgInfo::getDirect();
-      return ABIArgInfo::getExpand();
+      }  else if (!Ty->isBuiltinType() && !Ty->isVectorType()) {
+        // HVA Types only get registers after everything else has been
+        // set, so it gets set as indirect for now.
+        return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty));
+      }
     }
-    return getIndirectResult(Ty, /*ByVal=*/false, State);
   }
 
   if (isAggregateTypeForABI(Ty)) {
@@ -1590,6 +1673,36 @@
   return ABIArgInfo::getDirect();
 }
 
+void X86_32ABIInfo::computeVectorCallArgs(CGFunctionInfo &FI, CCState &State,
+                                          bool &UsedInAlloca) const {
+  // Vectorcall only allows the first 6 parameters to be passed in registers,
+  // and homogeneous vector aggregates are only put into registers as a second
+  // priority.
+  unsigned Count = 0;
+  CCState ZeroState = State;
+  ZeroState.FreeRegs = ZeroState.FreeSSERegs = 0;
+  // HVAs must be done as a second priority for registers, so the deferred
+  // items are dealt with by going through the pattern a second time.
+  for (auto &I : FI.arguments()) {
+    if (Count < VectorcallMaxParamNumAsReg)
+      I.info = classifyArgumentType(I.type, State);
+    else
+      // Parameters after the 6th cannot be passed in registers,
+      // so pretend there are no registers left for them.
+      I.info = classifyArgumentType(I.type, ZeroState);
+    UsedInAlloca |= (I.info.getKind() == ABIArgInfo::InAlloca);
+    ++Count;
+  }
+  Count = 0;
+  // Go through the arguments a second time to get HVAs registers if there
+  // are still some available.
+  for (auto &I : FI.arguments()) {
+    if (Count < VectorcallMaxParamNumAsReg)
+      I.info = reclassifyHvaArgType(I.type, State, I.info);
+    ++Count;
+  }
+}
+
 void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
   CCState State(FI.getCallingConvention());
   if (IsMCUABI)
@@ -1624,9 +1737,14 @@
     ++State.FreeRegs;
 
   bool UsedInAlloca = false;
-  for (auto &I : FI.arguments()) {
-    I.info = classifyArgumentType(I.type, State);
-    UsedInAlloca |= (I.info.getKind() == ABIArgInfo::InAlloca);
+  if (State.CC == llvm::CallingConv::X86_VectorCall) {
+    computeVectorCallArgs(FI, State, UsedInAlloca);
+  } else {
+    // If not vectorcall, revert to normal behavior.
+    for (auto &I : FI.arguments()) {
+      I.info = classifyArgumentType(I.type, State);
+      UsedInAlloca |= (I.info.getKind() == ABIArgInfo::InAlloca);
+    }
   }
 
   // If we needed to use inalloca for any argument, do a second pass and rewrite
@@ -2056,10 +2174,14 @@
   }
 
 private:
-  ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs,
-                      bool IsReturnType) const;
+  ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs, bool IsReturnType,
+                      bool IsVectorCall, bool IsRegCall) const;
+  ABIArgInfo reclassifyHvaArgType(QualType Ty, unsigned &FreeSSERegs,
+                                      const ABIArgInfo &current) const;
+  void computeVectorCallArgs(CGFunctionInfo &FI, unsigned FreeSSERegs,
+                             bool IsVectorCall, bool IsRegCall) const;
 
-  bool IsMingw64;
+    bool IsMingw64;
 };
 
 class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {
@@ -2371,13 +2493,13 @@
       Current = SSE;
     } else if (k == BuiltinType::LongDouble) {
       const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat();
-      if (LDF == &llvm::APFloat::IEEEquad) {
+      if (LDF == &llvm::APFloat::IEEEquad()) {
         Lo = SSE;
         Hi = SSEUp;
-      } else if (LDF == &llvm::APFloat::x87DoubleExtended) {
+      } else if (LDF == &llvm::APFloat::x87DoubleExtended()) {
         Lo = X87;
         Hi = X87Up;
-      } else if (LDF == &llvm::APFloat::IEEEdouble) {
+      } else if (LDF == &llvm::APFloat::IEEEdouble()) {
         Current = SSE;
       } else
         llvm_unreachable("unexpected long double representation!");
@@ -2496,11 +2618,11 @@
       Lo = Hi = SSE;
     } else if (ET == getContext().LongDoubleTy) {
       const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat();
-      if (LDF == &llvm::APFloat::IEEEquad)
+      if (LDF == &llvm::APFloat::IEEEquad())
         Current = Memory;
-      else if (LDF == &llvm::APFloat::x87DoubleExtended)
+      else if (LDF == &llvm::APFloat::x87DoubleExtended())
         Current = ComplexX87;
-      else if (LDF == &llvm::APFloat::IEEEdouble)
+      else if (LDF == &llvm::APFloat::IEEEdouble())
         Lo = Hi = SSE;
       else
         llvm_unreachable("unexpected long double representation!");
@@ -3665,8 +3787,24 @@
                           /*allowHigherAlign*/ false);
 }
 
+ABIArgInfo
+WinX86_64ABIInfo::reclassifyHvaArgType(QualType Ty, unsigned &FreeSSERegs,
+                                    const ABIArgInfo &current) const {
+  // Assumes vectorCall calling convention.
+  const Type *Base = nullptr;
+  uint64_t NumElts = 0;
+
+  if (!Ty->isBuiltinType() && !Ty->isVectorType() &&
+      isHomogeneousAggregate(Ty, Base, NumElts) && FreeSSERegs >= NumElts) {
+    FreeSSERegs -= NumElts;
+    return getDirectX86Hva();
+  }
+  return current;
+}
+
 ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs,
-                                      bool IsReturnType) const {
+                                      bool IsReturnType, bool IsVectorCall,
+                                      bool IsRegCall) const {
 
   if (Ty->isVoidType())
     return ABIArgInfo::getIgnore();
@@ -3690,21 +3828,34 @@
 
   }
 
-  // vectorcall adds the concept of a homogenous vector aggregate, similar to
-  // other targets.
   const Type *Base = nullptr;
   uint64_t NumElts = 0;
-  if (FreeSSERegs && isHomogeneousAggregate(Ty, Base, NumElts)) {
-    if (FreeSSERegs >= NumElts) {
-      FreeSSERegs -= NumElts;
-      if (IsReturnType || Ty->isBuiltinType() || Ty->isVectorType())
+  // vectorcall adds the concept of a homogenous vector aggregate, similar to
+  // other targets.
+  if ((IsVectorCall || IsRegCall) &&
+      isHomogeneousAggregate(Ty, Base, NumElts)) {
+    if (IsRegCall) {
+      if (FreeSSERegs >= NumElts) {
+        FreeSSERegs -= NumElts;
+        if (IsReturnType || Ty->isBuiltinType() || Ty->isVectorType())
+          return ABIArgInfo::getDirect();
+        return ABIArgInfo::getExpand();
+      }
+      return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
+    } else if (IsVectorCall) {
+      if (FreeSSERegs >= NumElts &&
+          (IsReturnType || Ty->isBuiltinType() || Ty->isVectorType())) {
+        FreeSSERegs -= NumElts;
         return ABIArgInfo::getDirect();
-      return ABIArgInfo::getExpand();
+      } else if (IsReturnType) {
+        return ABIArgInfo::getExpand();
+      } else if (!Ty->isBuiltinType() && !Ty->isVectorType()) {
+        // HVAs are delayed and reclassified in the 2nd step.
+        return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
+      }
     }
-    return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
   }
 
-
   if (Ty->isMemberPointerType()) {
     // If the member pointer is represented by an LLVM int or ptr, pass it
     // directly.
@@ -3733,13 +3884,39 @@
   // passes them indirectly through memory.
   if (IsMingw64 && BT && BT->getKind() == BuiltinType::LongDouble) {
     const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat();
-    if (LDF == &llvm::APFloat::x87DoubleExtended)
+    if (LDF == &llvm::APFloat::x87DoubleExtended())
       return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
   }
 
   return ABIArgInfo::getDirect();
 }
 
+void WinX86_64ABIInfo::computeVectorCallArgs(CGFunctionInfo &FI,
+                                             unsigned FreeSSERegs,
+                                             bool IsVectorCall,
+                                             bool IsRegCall) const {
+  unsigned Count = 0;
+  for (auto &I : FI.arguments()) {
+    if (Count < VectorcallMaxParamNumAsReg)
+      I.info = classify(I.type, FreeSSERegs, false, IsVectorCall, IsRegCall);
+    else {
+      // Since these cannot be passed in registers, pretend no registers
+      // are left.
+      unsigned ZeroSSERegsAvail = 0;
+      I.info = classify(I.type, /*FreeSSERegs=*/ZeroSSERegsAvail, false,
+                        IsVectorCall, IsRegCall);
+    }
+    ++Count;
+  }
+
+  Count = 0;
+  for (auto &I : FI.arguments()) {
+    if (Count < VectorcallMaxParamNumAsReg)
+      I.info = reclassifyHvaArgType(I.type, FreeSSERegs, I.info);
+    ++Count;
+  }
+}
+
 void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
   bool IsVectorCall =
       FI.getCallingConvention() == llvm::CallingConv::X86_VectorCall;
@@ -3755,17 +3932,24 @@
   }
 
   if (!getCXXABI().classifyReturnType(FI))
-    FI.getReturnInfo() = classify(FI.getReturnType(), FreeSSERegs, true);
+    FI.getReturnInfo() = classify(FI.getReturnType(), FreeSSERegs, true,
+                                  IsVectorCall, IsRegCall);
 
   if (IsVectorCall) {
     // We can use up to 6 SSE register parameters with vectorcall.
     FreeSSERegs = 6;
   } else if (IsRegCall) {
+    // RegCall gives us 16 SSE registers, we can reuse the return registers.
     FreeSSERegs = 16;
   }
 
-  for (auto &I : FI.arguments())
-    I.info = classify(I.type, FreeSSERegs, false);
+  if (IsVectorCall) {
+    computeVectorCallArgs(FI, FreeSSERegs, IsVectorCall, IsRegCall);
+  } else {
+    for (auto &I : FI.arguments())
+      I.info = classify(I.type, FreeSSERegs, false, IsVectorCall, IsRegCall);
+  }
+
 }
 
 Address WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
@@ -4651,7 +4835,7 @@
       : TargetCodeGenInfo(new AArch64ABIInfo(CGT, Kind)) {}
 
   StringRef getARCRetainAutoreleasedReturnValueMarker() const override {
-    return "mov\tfp, fp\t\t; marker for objc_retainAutoreleaseReturnValue";
+    return "mov\tfp, fp\t\t# marker for objc_retainAutoreleaseReturnValue";
   }
 
   int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
@@ -6716,6 +6900,31 @@
 }
 
 //===----------------------------------------------------------------------===//
+// AVR ABI Implementation.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class AVRTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  AVRTargetCodeGenInfo(CodeGenTypes &CGT)
+    : TargetCodeGenInfo(new DefaultABIInfo(CGT)) { }
+
+  void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                           CodeGen::CodeGenModule &CGM) const override {
+    const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
+    if (!FD) return;
+    auto *Fn = cast<llvm::Function>(GV);
+
+    if (FD->getAttr<AVRInterruptAttr>())
+      Fn->addFnAttr("interrupt");
+
+    if (FD->getAttr<AVRSignalAttr>())
+      Fn->addFnAttr("signal");
+  }
+};
+}
+
+//===----------------------------------------------------------------------===//
 // TCE ABI Implementation (see http://tce.cs.tut.fi). Uses mostly the defaults.
 // Currently subclassed only to implement custom OpenCL C function attribute
 // handling.
@@ -7075,8 +7284,10 @@
   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                            CodeGen::CodeGenModule &M) const override;
   unsigned getOpenCLKernelCallingConv() const override;
-};
 
+  llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
+      llvm::PointerType *T, QualType QT) const override;
+};
 }
 
 static void appendOpenCLVersionMD (CodeGen::CodeGenModule &CGM);
@@ -7140,6 +7351,24 @@
   return llvm::CallingConv::AMDGPU_KERNEL;
 }
 
+// Currently LLVM assumes null pointers always have value 0,
+// which results in incorrectly transformed IR. Therefore, instead of
+// emitting null pointers in private and local address spaces, a null
+// pointer in generic address space is emitted which is casted to a
+// pointer in local or private address space.
+llvm::Constant *AMDGPUTargetCodeGenInfo::getNullPointer(
+    const CodeGen::CodeGenModule &CGM, llvm::PointerType *PT,
+    QualType QT) const {
+  if (CGM.getContext().getTargetNullPointerValue(QT) == 0)
+    return llvm::ConstantPointerNull::get(PT);
+
+  auto &Ctx = CGM.getContext();
+  auto NPT = llvm::PointerType::get(PT->getElementType(),
+      Ctx.getTargetAddressSpace(LangAS::opencl_generic));
+  return llvm::ConstantExpr::getAddrSpaceCast(
+      llvm::ConstantPointerNull::get(NPT), PT);
+}
+
 //===----------------------------------------------------------------------===//
 // SPARC v8 ABI Implementation.
 // Based on the SPARC Compliance Definition version 2.4.1.
@@ -8198,6 +8427,9 @@
   case llvm::Triple::mips64el:
     return SetCGInfo(new MIPSTargetCodeGenInfo(Types, false));
 
+  case llvm::Triple::avr:
+    return SetCGInfo(new AVRTargetCodeGenInfo(Types));
+
   case llvm::Triple::aarch64:
   case llvm::Triple::aarch64_be: {
     AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS;
diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h
index e463825..223d6d0 100644
--- a/lib/CodeGen/TargetInfo.h
+++ b/lib/CodeGen/TargetInfo.h
@@ -220,6 +220,22 @@
 
   /// Get LLVM calling convention for OpenCL kernel.
   virtual unsigned getOpenCLKernelCallingConv() const;
+
+  /// Get target specific null pointer.
+  /// \param T is the LLVM type of the null pointer.
+  /// \param QT is the clang QualType of the null pointer.
+  /// \return ConstantPointerNull with the given type \p T.
+  /// Each target can override it to return its own desired constant value.
+  virtual llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
+      llvm::PointerType *T, QualType QT) const;
+
+  /// Perform address space cast of an expression of pointer type.
+  /// \param V is the LLVM value to be casted to another address space.
+  /// \param SrcTy is the QualType of \p V.
+  /// \param DestTy is the destination QualType.
+  virtual llvm::Value *performAddrSpaceCast(CodeGen::CodeGenFunction &CGF,
+      llvm::Value *V, QualType SrcTy, QualType DestTy) const;
+
 };
 
 } // namespace CodeGen
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index 3ebd1c4..0d7a997 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -11,20 +11,52 @@
 add_clang_library(clangDriver
   Action.cpp
   Compilation.cpp
-  CrossWindowsToolChain.cpp
   Distro.cpp
   Driver.cpp
   DriverOptions.cpp
   Job.cpp
-  MinGWToolChain.cpp
   Multilib.cpp
-  MSVCToolChain.cpp
   Phases.cpp
   SanitizerArgs.cpp
   Tool.cpp
   ToolChain.cpp
-  ToolChains.cpp
-  Tools.cpp
+  ToolChains/Arch/AArch64.cpp
+  ToolChains/Arch/ARM.cpp
+  ToolChains/Arch/Mips.cpp
+  ToolChains/Arch/PPC.cpp
+  ToolChains/Arch/Sparc.cpp
+  ToolChains/Arch/SystemZ.cpp
+  ToolChains/Arch/X86.cpp
+  ToolChains/AMDGPU.cpp
+  ToolChains/AVR.cpp
+  ToolChains/Bitrig.cpp
+  ToolChains/Clang.cpp
+  ToolChains/CloudABI.cpp
+  ToolChains/CommonArgs.cpp
+  ToolChains/Contiki.cpp
+  ToolChains/CrossWindows.cpp
+  ToolChains/Cuda.cpp
+  ToolChains/Darwin.cpp
+  ToolChains/DragonFly.cpp
+  ToolChains/FreeBSD.cpp
+  ToolChains/Fuchsia.cpp
+  ToolChains/Gnu.cpp
+  ToolChains/Haiku.cpp
+  ToolChains/Hexagon.cpp
+  ToolChains/Linux.cpp
+  ToolChains/MipsLinux.cpp
+  ToolChains/MinGW.cpp
+  ToolChains/Minix.cpp
+  ToolChains/MSVC.cpp
+  ToolChains/Myriad.cpp
+  ToolChains/NaCl.cpp
+  ToolChains/NetBSD.cpp
+  ToolChains/OpenBSD.cpp
+  ToolChains/PS4CPU.cpp
+  ToolChains/Solaris.cpp
+  ToolChains/TCE.cpp
+  ToolChains/WebAssembly.cpp
+  ToolChains/XCore.cpp
   Types.cpp
 
   DEPENDS
diff --git a/lib/Driver/CrossWindowsToolChain.cpp b/lib/Driver/CrossWindowsToolChain.cpp
deleted file mode 100644
index 28036ea..0000000
--- a/lib/Driver/CrossWindowsToolChain.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//===--- CrossWindowsToolChain.cpp - Cross Windows Tool Chain -------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ToolChains.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Driver/Options.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Support/Path.h"
-
-using namespace clang::driver;
-using namespace clang::driver::toolchains;
-
-CrossWindowsToolChain::CrossWindowsToolChain(const Driver &D,
-                                             const llvm::Triple &T,
-                                             const llvm::opt::ArgList &Args)
-    : Generic_GCC(D, T, Args) {
-  if (GetCXXStdlibType(Args) == ToolChain::CST_Libstdcxx) {
-    const std::string &SysRoot = D.SysRoot;
-
-    // libstdc++ resides in /usr/lib, but depends on libgcc which is placed in
-    // /usr/lib/gcc.
-    getFilePaths().push_back(SysRoot + "/usr/lib");
-    getFilePaths().push_back(SysRoot + "/usr/lib/gcc");
-  }
-}
-
-bool CrossWindowsToolChain::IsUnwindTablesDefault() const {
-  // FIXME: all non-x86 targets need unwind tables, however, LLVM currently does
-  // not know how to emit them.
-  return getArch() == llvm::Triple::x86_64;
-}
-
-bool CrossWindowsToolChain::isPICDefault() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-bool CrossWindowsToolChain::isPIEDefault() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-bool CrossWindowsToolChain::isPICDefaultForced() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-void CrossWindowsToolChain::
-AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                          llvm::opt::ArgStringList &CC1Args) const {
-  const Driver &D = getDriver();
-  const std::string &SysRoot = D.SysRoot;
-
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
-    return;
-
-  addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
-  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
-    SmallString<128> ResourceDir(D.ResourceDir);
-    llvm::sys::path::append(ResourceDir, "include");
-    addSystemInclude(DriverArgs, CC1Args, ResourceDir);
-  }
-  for (const auto &P : DriverArgs.getAllArgValues(options::OPT_isystem_after))
-    addSystemInclude(DriverArgs, CC1Args, P);
-  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
-}
-
-void CrossWindowsToolChain::
-AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                             llvm::opt::ArgStringList &CC1Args) const {
-  const llvm::Triple &Triple = getTriple();
-  const std::string &SysRoot = getDriver().SysRoot;
-
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
-      DriverArgs.hasArg(options::OPT_nostdincxx))
-    return;
-
-  switch (GetCXXStdlibType(DriverArgs)) {
-  case ToolChain::CST_Libcxx:
-    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/c++/v1");
-    break;
-
-  case ToolChain::CST_Libstdcxx:
-    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/c++");
-    addSystemInclude(DriverArgs, CC1Args,
-                     SysRoot + "/usr/include/c++/" + Triple.str());
-    addSystemInclude(DriverArgs, CC1Args,
-                     SysRoot + "/usr/include/c++/backwards");
-  }
-}
-
-void CrossWindowsToolChain::
-AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs,
-                    llvm::opt::ArgStringList &CC1Args) const {
-  switch (GetCXXStdlibType(DriverArgs)) {
-  case ToolChain::CST_Libcxx:
-    CC1Args.push_back("-lc++");
-    break;
-  case ToolChain::CST_Libstdcxx:
-    CC1Args.push_back("-lstdc++");
-    CC1Args.push_back("-lmingw32");
-    CC1Args.push_back("-lmingwex");
-    CC1Args.push_back("-lgcc");
-    CC1Args.push_back("-lmoldname");
-    CC1Args.push_back("-lmingw32");
-    break;
-  }
-}
-
-clang::SanitizerMask CrossWindowsToolChain::getSupportedSanitizers() const {
-  SanitizerMask Res = ToolChain::getSupportedSanitizers();
-  Res |= SanitizerKind::Address;
-  return Res;
-}
-
-Tool *CrossWindowsToolChain::buildLinker() const {
-  return new tools::CrossWindows::Linker(*this);
-}
-
-Tool *CrossWindowsToolChain::buildAssembler() const {
-  return new tools::CrossWindows::Assembler(*this);
-}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index e6e508d..1633082 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -9,7 +9,36 @@
 
 #include "clang/Driver/Driver.h"
 #include "InputInfo.h"
-#include "ToolChains.h"
+#include "ToolChains/AMDGPU.h"
+#include "ToolChains/AVR.h"
+#include "ToolChains/Bitrig.h"
+#include "ToolChains/Clang.h"
+#include "ToolChains/CloudABI.h"
+#include "ToolChains/Contiki.h"
+#include "ToolChains/CrossWindows.h"
+#include "ToolChains/Cuda.h"
+#include "ToolChains/Darwin.h"
+#include "ToolChains/DragonFly.h"
+#include "ToolChains/FreeBSD.h"
+#include "ToolChains/Fuchsia.h"
+#include "ToolChains/Gnu.h"
+#include "ToolChains/Haiku.h"
+#include "ToolChains/Hexagon.h"
+#include "ToolChains/Lanai.h"
+#include "ToolChains/Linux.h"
+#include "ToolChains/MinGW.h"
+#include "ToolChains/Minix.h"
+#include "ToolChains/MipsLinux.h"
+#include "ToolChains/MSVC.h"
+#include "ToolChains/Myriad.h"
+#include "ToolChains/NaCl.h"
+#include "ToolChains/NetBSD.h"
+#include "ToolChains/OpenBSD.h"
+#include "ToolChains/PS4CPU.h"
+#include "ToolChains/Solaris.h"
+#include "ToolChains/TCE.h"
+#include "ToolChains/WebAssembly.h"
+#include "ToolChains/XCore.h"
 #include "clang/Basic/Version.h"
 #include "clang/Basic/VirtualFileSystem.h"
 #include "clang/Config/config.h"
@@ -79,18 +108,13 @@
     llvm::sys::path::append(P, ClangResourceDir);
   } else {
     StringRef ClangLibdirSuffix(CLANG_LIBDIR_SUFFIX);
-    llvm::sys::path::append(P, "..", Twine("lib") + ClangLibdirSuffix, "clang",
+    P = llvm::sys::path::parent_path(Dir);
+    llvm::sys::path::append(P, Twine("lib") + ClangLibdirSuffix, "clang",
                             CLANG_VERSION_STRING);
   }
   ResourceDir = P.str();
 }
 
-Driver::~Driver() {
-  delete Opts;
-
-  llvm::DeleteContainerSeconds(ToolChains);
-}
-
 void Driver::ParseDriverMode(StringRef ProgramName,
                              ArrayRef<const char *> Args) {
   auto Default = ToolChain::getTargetAndModeFromProgramName(ProgramName);
@@ -214,9 +238,9 @@
   return FinalPhase;
 }
 
-static Arg *MakeInputArg(DerivedArgList &Args, OptTable *Opts,
+static Arg *MakeInputArg(DerivedArgList &Args, OptTable &Opts,
                          StringRef Value) {
-  Arg *A = new Arg(Opts->getOption(options::OPT_INPUT), Value,
+  Arg *A = new Arg(Opts.getOption(options::OPT_INPUT), Value,
                    Args.getBaseArgs().MakeIndex(Value), Value.data());
   Args.AddSynthesizedArg(A);
   A->claim();
@@ -287,7 +311,7 @@
     if (A->getOption().matches(options::OPT__DASH_DASH)) {
       A->claim();
       for (StringRef Val : A->getValues())
-        DAL->append(MakeInputArg(*DAL, Opts, Val));
+        DAL->append(MakeInputArg(*DAL, *Opts, Val));
       continue;
     }
 
@@ -479,12 +503,12 @@
                                                      : "nvptx-nvidia-cuda");
     // Use the CUDA and host triples as the key into the ToolChains map, because
     // the device toolchain we create depends on both.
-    ToolChain *&CudaTC = ToolChains[CudaTriple.str() + "/" + HostTriple.str()];
+    auto &CudaTC = ToolChains[CudaTriple.str() + "/" + HostTriple.str()];
     if (!CudaTC) {
-      CudaTC = new toolchains::CudaToolChain(*this, CudaTriple, *HostTC,
-                                             C.getInputArgs());
+      CudaTC = llvm::make_unique<toolchains::CudaToolChain>(
+          *this, CudaTriple, *HostTC, C.getInputArgs());
     }
-    C.addOffloadDeviceToolChain(CudaTC, Action::OFK_Cuda);
+    C.addOffloadDeviceToolChain(CudaTC.get(), Action::OFK_Cuda);
   }
 
   //
@@ -1462,16 +1486,15 @@
                     ? types::TY_C
                     : types::TY_CXX;
 
-    arg_iterator it =
-        Args.filtered_begin(options::OPT__SLASH_TC, options::OPT__SLASH_TP);
-    const arg_iterator ie = Args.filtered_end();
-    Arg *Previous = *it++;
+    Arg *Previous = nullptr;
     bool ShowNote = false;
-    while (it != ie) {
-      Diag(clang::diag::warn_drv_overriding_flag_option)
-          << Previous->getSpelling() << (*it)->getSpelling();
-      Previous = *it++;
-      ShowNote = true;
+    for (Arg *A : Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
+      if (Previous) {
+        Diag(clang::diag::warn_drv_overriding_flag_option)
+          << Previous->getSpelling() << A->getSpelling();
+        ShowNote = true;
+      }
+      Previous = A;
     }
     if (ShowNote)
       Diag(clang::diag::note_drv_t_option_is_global);
@@ -1561,14 +1584,14 @@
     } else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
       StringRef Value = A->getValue();
       if (DiagnoseInputExistence(*this, Args, Value, types::TY_C)) {
-        Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
+        Arg *InputArg = MakeInputArg(Args, *Opts, A->getValue());
         Inputs.push_back(std::make_pair(types::TY_C, InputArg));
       }
       A->claim();
     } else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
       StringRef Value = A->getValue();
       if (DiagnoseInputExistence(*this, Args, Value, types::TY_CXX)) {
-        Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
+        Arg *InputArg = MakeInputArg(Args, *Opts, A->getValue());
         Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
       }
       A->claim();
@@ -1589,12 +1612,20 @@
         Diag(clang::diag::err_drv_unknown_language) << A->getValue();
         InputType = types::TY_Object;
       }
+    } else if (A->getOption().getID() == options::OPT__SLASH_U) {
+      assert(A->getNumValues() == 1 && "The /U option has one value.");
+      StringRef Val = A->getValue(0);
+      if (Val.find_first_of("/\\") != StringRef::npos) {
+        // Warn about e.g. "/Users/me/myfile.c".
+        Diag(diag::warn_slash_u_filename) << Val;
+        Diag(diag::note_use_dashdash);
+      }
     }
   }
   if (CCCIsCPP() && Inputs.empty()) {
     // If called as standalone preprocessor, stdin is processed
     // if no other input is present.
-    Arg *A = MakeInputArg(Args, Opts, "-");
+    Arg *A = MakeInputArg(Args, *Opts, "-");
     Inputs.push_back(std::make_pair(types::TY_C, A));
   }
 }
@@ -1919,25 +1950,39 @@
                               options::OPT_cuda_device_only);
 
       // Collect all cuda_gpu_arch parameters, removing duplicates.
-      llvm::SmallSet<CudaArch, 4> GpuArchs;
+      std::set<CudaArch> GpuArchs;
       bool Error = false;
       for (Arg *A : Args) {
-        if (!A->getOption().matches(options::OPT_cuda_gpu_arch_EQ))
+        if (!(A->getOption().matches(options::OPT_cuda_gpu_arch_EQ) ||
+              A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ)))
           continue;
         A->claim();
 
-        const auto &ArchStr = A->getValue();
+        const StringRef ArchStr = A->getValue();
+        if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ) &&
+            ArchStr == "all") {
+          GpuArchs.clear();
+          continue;
+        }
         CudaArch Arch = StringToCudaArch(ArchStr);
         if (Arch == CudaArch::UNKNOWN) {
           C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
           Error = true;
-        } else if (GpuArchs.insert(Arch).second)
-          GpuArchList.push_back(Arch);
+        } else if (A->getOption().matches(options::OPT_cuda_gpu_arch_EQ))
+          GpuArchs.insert(Arch);
+        else if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ))
+          GpuArchs.erase(Arch);
+        else
+          llvm_unreachable("Unexpected option.");
       }
 
-      // Default to sm_20 which is the lowest common denominator for supported
-      // GPUs.
-      // sm_20 code should work correctly, if suboptimally, on all newer GPUs.
+      // Collect list of GPUs remaining in the set.
+      for (CudaArch Arch : GpuArchs)
+        GpuArchList.push_back(Arch);
+
+      // Default to sm_20 which is the lowest common denominator for
+      // supported GPUs.  sm_20 code should work correctly, if
+      // suboptimally, on all newer GPUs.
       if (GpuArchList.empty())
         GpuArchList.push_back(CudaArch::SM_20);
 
@@ -2337,8 +2382,12 @@
   Arg *FinalPhaseArg;
   phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
 
-  if (FinalPhase == phases::Link && Args.hasArg(options::OPT_emit_llvm)) {
-    Diag(clang::diag::err_drv_emit_llvm_link);
+  if (FinalPhase == phases::Link) {
+    if (Args.hasArg(options::OPT_emit_llvm))
+      Diag(clang::diag::err_drv_emit_llvm_link);
+    if (IsCLMode() && LTOMode != LTOK_None &&
+        !Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower("lld"))
+      Diag(clang::diag::err_drv_lto_without_lld);
   }
 
   // Reject -Z* at the top level, these options should never have been exposed
@@ -2483,7 +2532,7 @@
         const types::ID HeaderType = lookupHeaderTypeForSourceType(InputType);
         llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PCHPL;
         types::getCompilationPhases(HeaderType, PCHPL);
-        Arg *PchInputArg = MakeInputArg(Args, Opts, YcArg->getValue());
+        Arg *PchInputArg = MakeInputArg(Args, *Opts, YcArg->getValue());
 
         // Build the pipeline for the pch file.
         Action *ClangClPch =
@@ -3172,7 +3221,8 @@
   const JobAction *JA = cast<JobAction>(A);
   ActionList CollapsedOffloadActions;
 
-  ToolSelector TS(JA, *TC, C, isSaveTempsEnabled(), embedBitcodeInObject());
+  ToolSelector TS(JA, *TC, C, isSaveTempsEnabled(),
+                  embedBitcodeInObject() && !isUsingLTO());
   const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
 
   if (!T)
@@ -3643,122 +3693,130 @@
 const ToolChain &Driver::getToolChain(const ArgList &Args,
                                       const llvm::Triple &Target) const {
 
-  ToolChain *&TC = ToolChains[Target.str()];
+  auto &TC = ToolChains[Target.str()];
   if (!TC) {
     switch (Target.getOS()) {
     case llvm::Triple::Haiku:
-      TC = new toolchains::Haiku(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::Haiku>(*this, Target, Args);
       break;
     case llvm::Triple::CloudABI:
-      TC = new toolchains::CloudABI(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::CloudABI>(*this, Target, Args);
       break;
     case llvm::Triple::Darwin:
     case llvm::Triple::MacOSX:
     case llvm::Triple::IOS:
     case llvm::Triple::TvOS:
     case llvm::Triple::WatchOS:
-      TC = new toolchains::DarwinClang(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::DarwinClang>(*this, Target, Args);
       break;
     case llvm::Triple::DragonFly:
-      TC = new toolchains::DragonFly(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::DragonFly>(*this, Target, Args);
       break;
     case llvm::Triple::OpenBSD:
-      TC = new toolchains::OpenBSD(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::OpenBSD>(*this, Target, Args);
       break;
     case llvm::Triple::Bitrig:
-      TC = new toolchains::Bitrig(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::Bitrig>(*this, Target, Args);
       break;
     case llvm::Triple::NetBSD:
-      TC = new toolchains::NetBSD(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::NetBSD>(*this, Target, Args);
       break;
     case llvm::Triple::FreeBSD:
-      TC = new toolchains::FreeBSD(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::FreeBSD>(*this, Target, Args);
       break;
     case llvm::Triple::Minix:
-      TC = new toolchains::Minix(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::Minix>(*this, Target, Args);
       break;
     case llvm::Triple::Linux:
     case llvm::Triple::ELFIAMCU:
       if (Target.getArch() == llvm::Triple::hexagon)
-        TC = new toolchains::HexagonToolChain(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::HexagonToolChain>(*this, Target,
+                                                             Args);
       else if ((Target.getVendor() == llvm::Triple::MipsTechnologies) &&
                !Target.hasEnvironment())
-        TC = new toolchains::MipsLLVMToolChain(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::MipsLLVMToolChain>(*this, Target,
+                                                              Args);
       else
-        TC = new toolchains::Linux(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::Linux>(*this, Target, Args);
       break;
     case llvm::Triple::NaCl:
-      TC = new toolchains::NaClToolChain(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::NaClToolChain>(*this, Target, Args);
       break;
     case llvm::Triple::Fuchsia:
-      TC = new toolchains::Fuchsia(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::Fuchsia>(*this, Target, Args);
       break;
     case llvm::Triple::Solaris:
-      TC = new toolchains::Solaris(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::Solaris>(*this, Target, Args);
       break;
     case llvm::Triple::AMDHSA:
-      TC = new toolchains::AMDGPUToolChain(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args);
       break;
     case llvm::Triple::Win32:
       switch (Target.getEnvironment()) {
       default:
         if (Target.isOSBinFormatELF())
-          TC = new toolchains::Generic_ELF(*this, Target, Args);
+          TC = llvm::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
         else if (Target.isOSBinFormatMachO())
-          TC = new toolchains::MachO(*this, Target, Args);
+          TC = llvm::make_unique<toolchains::MachO>(*this, Target, Args);
         else
-          TC = new toolchains::Generic_GCC(*this, Target, Args);
+          TC = llvm::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
         break;
       case llvm::Triple::GNU:
-        TC = new toolchains::MinGW(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::MinGW>(*this, Target, Args);
         break;
       case llvm::Triple::Itanium:
-        TC = new toolchains::CrossWindowsToolChain(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::CrossWindowsToolChain>(*this, Target,
+                                                                  Args);
         break;
       case llvm::Triple::MSVC:
       case llvm::Triple::UnknownEnvironment:
-        TC = new toolchains::MSVCToolChain(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::MSVCToolChain>(*this, Target, Args);
         break;
       }
       break;
     case llvm::Triple::PS4:
-      TC = new toolchains::PS4CPU(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::PS4CPU>(*this, Target, Args);
       break;
     case llvm::Triple::Contiki:
-      TC = new toolchains::Contiki(*this, Target, Args);
+      TC = llvm::make_unique<toolchains::Contiki>(*this, Target, Args);
       break;
     default:
       // Of these targets, Hexagon is the only one that might have
       // an OS of Linux, in which case it got handled above already.
       switch (Target.getArch()) {
       case llvm::Triple::tce:
-        TC = new toolchains::TCEToolChain(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::TCEToolChain>(*this, Target, Args);
         break;
       case llvm::Triple::tcele:
-        TC = new toolchains::TCELEToolChain(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::TCELEToolChain>(*this, Target, Args);
         break;
       case llvm::Triple::hexagon:
-        TC = new toolchains::HexagonToolChain(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::HexagonToolChain>(*this, Target,
+                                                             Args);
         break;
       case llvm::Triple::lanai:
-        TC = new toolchains::LanaiToolChain(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::LanaiToolChain>(*this, Target, Args);
         break;
       case llvm::Triple::xcore:
-        TC = new toolchains::XCoreToolChain(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::XCoreToolChain>(*this, Target, Args);
         break;
       case llvm::Triple::wasm32:
       case llvm::Triple::wasm64:
-        TC = new toolchains::WebAssembly(*this, Target, Args);
+        TC = llvm::make_unique<toolchains::WebAssembly>(*this, Target, Args);
+        break;
+      case llvm::Triple::avr:
+        TC = llvm::make_unique<toolchains::AVRToolChain>(*this, Target, Args);
         break;
       default:
         if (Target.getVendor() == llvm::Triple::Myriad)
-          TC = new toolchains::MyriadToolChain(*this, Target, Args);
+          TC = llvm::make_unique<toolchains::MyriadToolChain>(*this, Target,
+                                                              Args);
         else if (Target.isOSBinFormatELF())
-          TC = new toolchains::Generic_ELF(*this, Target, Args);
+          TC = llvm::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
         else if (Target.isOSBinFormatMachO())
-          TC = new toolchains::MachO(*this, Target, Args);
+          TC = llvm::make_unique<toolchains::MachO>(*this, Target, Args);
         else
-          TC = new toolchains::Generic_GCC(*this, Target, Args);
+          TC = llvm::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
       }
     }
   }
diff --git a/lib/Driver/DriverOptions.cpp b/lib/Driver/DriverOptions.cpp
index 8d5332b..6a74109 100644
--- a/lib/Driver/DriverOptions.cpp
+++ b/lib/Driver/DriverOptions.cpp
@@ -39,6 +39,6 @@
 
 }
 
-OptTable *clang::driver::createDriverOptTable() {
-  return new DriverOptTable();
+std::unique_ptr<OptTable> clang::driver::createDriverOptTable() {
+  return llvm::make_unique<DriverOptTable>();
 }
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 68bb4ab..9fd8808 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -50,9 +50,8 @@
   bool ShouldSkip = llvm::StringSwitch<bool>(Flag)
     .Cases("-MF", "-MT", "-MQ", "-serialize-diagnostic-file", true)
     .Cases("-o", "-coverage-file", "-dependency-file", true)
-    .Cases("-fdebug-compilation-dir", "-include-pch", true)
+    .Cases("-fdebug-compilation-dir", "-diagnostic-log-file", true)
     .Cases("-dwarf-debug-flags", "-ivfsoverlay", true)
-    .Case("-diagnostic-log-file", true)
     .Default(false);
   if (ShouldSkip)
     return true;
@@ -64,7 +63,7 @@
     .Cases("-internal-externc-isystem", "-iprefix", true)
     .Cases("-iwithprefixbefore", "-isystem", "-iquote", true)
     .Cases("-isysroot", "-I", "-F", "-resource-dir", true)
-    .Case("-iframework", true)
+    .Cases("-iframework", "-include-pch", true)
     .Default(false);
   if (IsInclude)
     return HaveCrashVFS ? false : true;
diff --git a/lib/Driver/MSVCToolChain.cpp b/lib/Driver/MSVCToolChain.cpp
deleted file mode 100644
index 95cf056..0000000
--- a/lib/Driver/MSVCToolChain.cpp
+++ /dev/null
@@ -1,883 +0,0 @@
-//===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ToolChains.h"
-#include "Tools.h"
-#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/Version.h"
-#include "clang/Driver/Compilation.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/Options.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Config/llvm-config.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-#include <cstdio>
-
-// Include the necessary headers to interface with the Windows registry and
-// environment.
-#if defined(LLVM_ON_WIN32)
-#define USE_WIN32
-#endif
-
-#ifdef USE_WIN32
-  #define WIN32_LEAN_AND_MEAN
-  #define NOGDI
-  #ifndef NOMINMAX
-    #define NOMINMAX
-  #endif
-  #include <windows.h>
-#endif
-
-using namespace clang::driver;
-using namespace clang::driver::toolchains;
-using namespace clang;
-using namespace llvm::opt;
-
-MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple,
-                             const ArgList &Args)
-  : ToolChain(D, Triple, Args) {
-  getProgramPaths().push_back(getDriver().getInstalledDir());
-  if (getDriver().getInstalledDir() != getDriver().Dir)
-    getProgramPaths().push_back(getDriver().Dir);
-}
-
-Tool *MSVCToolChain::buildLinker() const {
-  return new tools::visualstudio::Linker(*this);
-}
-
-Tool *MSVCToolChain::buildAssembler() const {
-  if (getTriple().isOSBinFormatMachO())
-    return new tools::darwin::Assembler(*this);
-  getDriver().Diag(clang::diag::err_no_external_assembler);
-  return nullptr;
-}
-
-bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
-  return true;
-}
-
-bool MSVCToolChain::IsUnwindTablesDefault() const {
-  // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
-  // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
-  // how to generate them yet.
-
-  // Don't emit unwind tables by default for MachO targets.
-  if (getTriple().isOSBinFormatMachO())
-    return false;
-
-  return getArch() == llvm::Triple::x86_64;
-}
-
-bool MSVCToolChain::isPICDefault() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-bool MSVCToolChain::isPIEDefault() const {
-  return false;
-}
-
-bool MSVCToolChain::isPICDefaultForced() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-#ifdef USE_WIN32
-static bool readFullStringValue(HKEY hkey, const char *valueName,
-                                std::string &value) {
-  std::wstring WideValueName;
-  if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
-    return false;
-
-  DWORD result = 0;
-  DWORD valueSize = 0;
-  DWORD type = 0;
-  // First just query for the required size.
-  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
-                            &valueSize);
-  if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
-    return false;
-  std::vector<BYTE> buffer(valueSize);
-  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
-                            &valueSize);
-  if (result == ERROR_SUCCESS) {
-    std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
-                           valueSize / sizeof(wchar_t));
-    if (valueSize && WideValue.back() == L'\0') {
-      WideValue.pop_back();
-    }
-    // The destination buffer must be empty as an invariant of the conversion
-    // function; but this function is sometimes called in a loop that passes in
-    // the same buffer, however. Simply clear it out so we can overwrite it.
-    value.clear();
-    return llvm::convertWideToUTF8(WideValue, value);
-  }
-  return false;
-}
-#endif
-
-/// \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.
-/// $VERSION in the key path is a placeholder for the version number,
-/// causing the highest value path to be searched for and used.
-/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
-/// There can be additional characters in the component.  Only the numeric
-/// characters are compared.  This function only searches HKLM.
-static bool getSystemRegistryString(const char *keyPath, const char *valueName,
-                                    std::string &value, std::string *phValue) {
-#ifndef USE_WIN32
-  return false;
-#else
-  HKEY hRootKey = HKEY_LOCAL_MACHINE;
-  HKEY hKey = NULL;
-  long lResult;
-  bool returnValue = false;
-
-  const char *placeHolder = strstr(keyPath, "$VERSION");
-  std::string bestName;
-  // If we have a $VERSION placeholder, do the highest-version search.
-  if (placeHolder) {
-    const char *keyEnd = placeHolder - 1;
-    const char *nextKey = placeHolder;
-    // Find end of previous key.
-    while ((keyEnd > keyPath) && (*keyEnd != '\\'))
-      keyEnd--;
-    // Find end of key containing $VERSION.
-    while (*nextKey && (*nextKey != '\\'))
-      nextKey++;
-    size_t partialKeyLength = keyEnd - keyPath;
-    char partialKey[256];
-    if (partialKeyLength >= sizeof(partialKey))
-      partialKeyLength = sizeof(partialKey) - 1;
-    strncpy(partialKey, keyPath, partialKeyLength);
-    partialKey[partialKeyLength] = '\0';
-    HKEY hTopKey = NULL;
-    lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
-                            &hTopKey);
-    if (lResult == ERROR_SUCCESS) {
-      char keyName[256];
-      double bestValue = 0.0;
-      DWORD index, size = sizeof(keyName) - 1;
-      for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
-                                    NULL, NULL) == ERROR_SUCCESS;
-           index++) {
-        const char *sp = keyName;
-        while (*sp && !isDigit(*sp))
-          sp++;
-        if (!*sp)
-          continue;
-        const char *ep = sp + 1;
-        while (*ep && (isDigit(*ep) || (*ep == '.')))
-          ep++;
-        char numBuf[32];
-        strncpy(numBuf, sp, sizeof(numBuf) - 1);
-        numBuf[sizeof(numBuf) - 1] = '\0';
-        double dvalue = strtod(numBuf, NULL);
-        if (dvalue > bestValue) {
-          // Test that InstallDir is indeed there before keeping this index.
-          // Open the chosen key path remainder.
-          bestName = keyName;
-          // Append rest of key.
-          bestName.append(nextKey);
-          lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
-                                  KEY_READ | KEY_WOW64_32KEY, &hKey);
-          if (lResult == ERROR_SUCCESS) {
-            if (readFullStringValue(hKey, valueName, value)) {
-              bestValue = dvalue;
-              if (phValue)
-                *phValue = bestName;
-              returnValue = true;
-            }
-            RegCloseKey(hKey);
-          }
-        }
-        size = sizeof(keyName) - 1;
-      }
-      RegCloseKey(hTopKey);
-    }
-  } else {
-    lResult =
-        RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
-    if (lResult == ERROR_SUCCESS) {
-      if (readFullStringValue(hKey, valueName, value))
-        returnValue = true;
-      if (phValue)
-        phValue->clear();
-      RegCloseKey(hKey);
-    }
-  }
-  return returnValue;
-#endif // USE_WIN32
-}
-
-// Convert LLVM's ArchType
-// to the corresponding name of Windows SDK libraries subfolder
-static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
-  switch (Arch) {
-  case llvm::Triple::x86:
-    return "x86";
-  case llvm::Triple::x86_64:
-    return "x64";
-  case llvm::Triple::arm:
-    return "arm";
-  default:
-    return "";
-  }
-}
-
-// Find the most recent version of Universal CRT or Windows 10 SDK.
-// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
-// directory by name and uses the last one of the list.
-// So we compare entry names lexicographically to find the greatest one.
-static bool getWindows10SDKVersion(const std::string &SDKPath,
-                                   std::string &SDKVersion) {
-  SDKVersion.clear();
-
-  std::error_code EC;
-  llvm::SmallString<128> IncludePath(SDKPath);
-  llvm::sys::path::append(IncludePath, "Include");
-  for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
-       DirIt != DirEnd && !EC; DirIt.increment(EC)) {
-    if (!llvm::sys::fs::is_directory(DirIt->path()))
-      continue;
-    StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
-    // If WDK is installed, there could be subfolders like "wdf" in the
-    // "Include" directory.
-    // Allow only directories which names start with "10.".
-    if (!CandidateName.startswith("10."))
-      continue;
-    if (CandidateName > SDKVersion)
-      SDKVersion = CandidateName;
-  }
-
-  return !SDKVersion.empty();
-}
-
-/// \brief Get Windows SDK installation directory.
-bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
-                                     std::string &WindowsSDKIncludeVersion,
-                                     std::string &WindowsSDKLibVersion) const {
-  std::string RegistrySDKVersion;
-  // Try the Windows registry.
-  if (!getSystemRegistryString(
-          "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
-          "InstallationFolder", Path, &RegistrySDKVersion))
-    return false;
-  if (Path.empty() || RegistrySDKVersion.empty())
-    return false;
-
-  WindowsSDKIncludeVersion.clear();
-  WindowsSDKLibVersion.clear();
-  Major = 0;
-  std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
-  if (Major <= 7)
-    return true;
-  if (Major == 8) {
-    // Windows SDK 8.x installs libraries in a folder whose names depend on the
-    // version of the OS you're targeting.  By default choose the newest, which
-    // usually corresponds to the version of the OS you've installed the SDK on.
-    const char *Tests[] = {"winv6.3", "win8", "win7"};
-    for (const char *Test : Tests) {
-      llvm::SmallString<128> TestPath(Path);
-      llvm::sys::path::append(TestPath, "Lib", Test);
-      if (llvm::sys::fs::exists(TestPath.c_str())) {
-        WindowsSDKLibVersion = Test;
-        break;
-      }
-    }
-    return !WindowsSDKLibVersion.empty();
-  }
-  if (Major == 10) {
-    if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
-      return false;
-    WindowsSDKLibVersion = WindowsSDKIncludeVersion;
-    return true;
-  }
-  // Unsupported SDK version
-  return false;
-}
-
-// Gets the library path required to link against the Windows SDK.
-bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
-  std::string sdkPath;
-  int sdkMajor = 0;
-  std::string windowsSDKIncludeVersion;
-  std::string windowsSDKLibVersion;
-
-  path.clear();
-  if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
-                        windowsSDKLibVersion))
-    return false;
-
-  llvm::SmallString<128> libPath(sdkPath);
-  llvm::sys::path::append(libPath, "Lib");
-  if (sdkMajor <= 7) {
-    switch (getArch()) {
-    // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
-    case llvm::Triple::x86:
-      break;
-    case llvm::Triple::x86_64:
-      llvm::sys::path::append(libPath, "x64");
-      break;
-    case llvm::Triple::arm:
-      // It is not necessary to link against Windows SDK 7.x when targeting ARM.
-      return false;
-    default:
-      return false;
-    }
-  } else {
-    const StringRef archName = getWindowsSDKArch(getArch());
-    if (archName.empty())
-      return false;
-    llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
-  }
-
-  path = libPath.str();
-  return true;
-}
-
-// Check if the Include path of a specified version of Visual Studio contains
-// specific header files. If not, they are probably shipped with Universal CRT.
-bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
-    std::string &VisualStudioDir) const {
-  llvm::SmallString<128> TestPath(VisualStudioDir);
-  llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
-
-  return !llvm::sys::fs::exists(TestPath);
-}
-
-bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
-                                          std::string &UCRTVersion) const {
-  // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
-  // for the specific key "KitsRoot10". So do we.
-  if (!getSystemRegistryString(
-          "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
-          Path, nullptr))
-    return false;
-
-  return getWindows10SDKVersion(Path, UCRTVersion);
-}
-
-bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
-  std::string UniversalCRTSdkPath;
-  std::string UCRTVersion;
-
-  Path.clear();
-  if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
-    return false;
-
-  StringRef ArchName = getWindowsSDKArch(getArch());
-  if (ArchName.empty())
-    return false;
-
-  llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
-  llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
-
-  Path = LibPath.str();
-  return true;
-}
-
-// Get the location to use for Visual Studio binaries.  The location priority
-// is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
-// system (as reported by the registry).
-bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
-                                                  std::string &path) const {
-  path.clear();
-
-  SmallString<128> BinDir;
-
-  // First check the environment variables that vsvars32.bat sets.
-  llvm::Optional<std::string> VcInstallDir =
-      llvm::sys::Process::GetEnv("VCINSTALLDIR");
-  if (VcInstallDir.hasValue()) {
-    BinDir = VcInstallDir.getValue();
-    llvm::sys::path::append(BinDir, "bin");
-  } else {
-    // Next walk the PATH, trying to find a cl.exe in the path.  If we find one,
-    // use that.  However, make sure it's not clang's cl.exe.
-    llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
-    if (OptPath.hasValue()) {
-      const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
-      SmallVector<StringRef, 8> PathSegments;
-      llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
-
-      for (StringRef PathSegment : PathSegments) {
-        if (PathSegment.empty())
-          continue;
-
-        SmallString<128> FilePath(PathSegment);
-        llvm::sys::path::append(FilePath, "cl.exe");
-        // Checking if cl.exe exists is a small optimization over calling
-        // can_execute, which really only checks for existence but will also do
-        // extra checks for cl.exe.exe.  These add up when walking a long path.
-        if (llvm::sys::fs::exists(FilePath.c_str()) &&
-            !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
-          // If we found it on the PATH, use it exactly as is with no
-          // modifications.
-          path = PathSegment;
-          return true;
-        }
-      }
-    }
-
-    std::string installDir;
-    // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
-    // registry then we have no choice but to fail.
-    if (!getVisualStudioInstallDir(installDir))
-      return false;
-
-    // Regardless of what binary we're ultimately trying to find, we make sure
-    // that this is a Visual Studio directory by checking for cl.exe.  We use
-    // cl.exe instead of other binaries like link.exe because programs such as
-    // GnuWin32 also have a utility called link.exe, so cl.exe is the least
-    // ambiguous.
-    BinDir = installDir;
-    llvm::sys::path::append(BinDir, "VC", "bin");
-    SmallString<128> ClPath(BinDir);
-    llvm::sys::path::append(ClPath, "cl.exe");
-
-    if (!llvm::sys::fs::can_execute(ClPath.c_str()))
-      return false;
-  }
-
-  if (BinDir.empty())
-    return false;
-
-  switch (getArch()) {
-  case llvm::Triple::x86:
-    break;
-  case llvm::Triple::x86_64:
-    llvm::sys::path::append(BinDir, "amd64");
-    break;
-  case llvm::Triple::arm:
-    llvm::sys::path::append(BinDir, "arm");
-    break;
-  default:
-    // Whatever this is, Visual Studio doesn't have a toolchain for it.
-    return false;
-  }
-  path = BinDir.str();
-  return true;
-}
-
-VersionTuple MSVCToolChain::getMSVCVersionFromTriple() const {
-  unsigned Major, Minor, Micro;
-  getTriple().getEnvironmentVersion(Major, Minor, Micro);
-  if (Major || Minor || Micro)
-    return VersionTuple(Major, Minor, Micro);
-  return VersionTuple();
-}
-
-VersionTuple MSVCToolChain::getMSVCVersionFromExe() const {
-  VersionTuple Version;
-#ifdef USE_WIN32
-  std::string BinPath;
-  if (!getVisualStudioBinariesFolder("", BinPath))
-    return Version;
-  SmallString<128> ClExe(BinPath);
-  llvm::sys::path::append(ClExe, "cl.exe");
-
-  std::wstring ClExeWide;
-  if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
-    return Version;
-
-  const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
-                                                      nullptr);
-  if (VersionSize == 0)
-    return Version;
-
-  SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
-  if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
-                             VersionBlock.data()))
-    return Version;
-
-  VS_FIXEDFILEINFO *FileInfo = nullptr;
-  UINT FileInfoSize = 0;
-  if (!::VerQueryValueW(VersionBlock.data(), L"\\",
-                        reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
-      FileInfoSize < sizeof(*FileInfo))
-    return Version;
-
-  const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
-  const unsigned Minor = (FileInfo->dwFileVersionMS      ) & 0xFFFF;
-  const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
-
-  Version = VersionTuple(Major, Minor, Micro);
-#endif
-  return Version;
-}
-
-// Get Visual Studio installation directory.
-bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
-  // First check the environment variables that vsvars32.bat sets.
-  if (llvm::Optional<std::string> VcInstallDir =
-          llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
-    path = std::move(*VcInstallDir);
-    path = path.substr(0, path.find("\\VC"));
-    return true;
-  }
-
-  std::string vsIDEInstallDir;
-  std::string vsExpressIDEInstallDir;
-  // Then try the windows registry.
-  bool hasVCDir =
-      getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
-                              "InstallDir", vsIDEInstallDir, nullptr);
-  if (hasVCDir && !vsIDEInstallDir.empty()) {
-    path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
-    return true;
-  }
-
-  bool hasVCExpressDir =
-      getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
-                              "InstallDir", vsExpressIDEInstallDir, nullptr);
-  if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
-    path = vsExpressIDEInstallDir.substr(
-        0, vsIDEInstallDir.find("\\Common7\\IDE"));
-    return true;
-  }
-
-  // Try the environment.
-  std::string vcomntools;
-  if (llvm::Optional<std::string> vs120comntools =
-          llvm::sys::Process::GetEnv("VS120COMNTOOLS"))
-    vcomntools = std::move(*vs120comntools);
-  else if (llvm::Optional<std::string> vs100comntools =
-               llvm::sys::Process::GetEnv("VS100COMNTOOLS"))
-    vcomntools = std::move(*vs100comntools);
-  else if (llvm::Optional<std::string> vs90comntools =
-               llvm::sys::Process::GetEnv("VS90COMNTOOLS"))
-    vcomntools = std::move(*vs90comntools);
-  else if (llvm::Optional<std::string> vs80comntools =
-               llvm::sys::Process::GetEnv("VS80COMNTOOLS"))
-    vcomntools = std::move(*vs80comntools);
-
-  // Find any version we can.
-  if (!vcomntools.empty()) {
-    size_t p = vcomntools.find("\\Common7\\Tools");
-    if (p != std::string::npos)
-      vcomntools.resize(p);
-    path = std::move(vcomntools);
-    return true;
-  }
-  return false;
-}
-
-void MSVCToolChain::AddSystemIncludeWithSubfolder(
-    const ArgList &DriverArgs, ArgStringList &CC1Args,
-    const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
-    const Twine &subfolder3) const {
-  llvm::SmallString<128> path(folder);
-  llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
-  addSystemInclude(DriverArgs, CC1Args, path);
-}
-
-void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                              ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdinc))
-    return;
-
-  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
-    AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
-                                  "include");
-  }
-
-  // Add %INCLUDE%-like directories from the -imsvc flag.
-  for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
-    addSystemInclude(DriverArgs, CC1Args, Path);
-
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
-    return;
-
-  // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
-  if (llvm::Optional<std::string> cl_include_dir =
-          llvm::sys::Process::GetEnv("INCLUDE")) {
-    SmallVector<StringRef, 8> Dirs;
-    StringRef(*cl_include_dir)
-        .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
-    for (StringRef Dir : Dirs)
-      addSystemInclude(DriverArgs, CC1Args, Dir);
-    if (!Dirs.empty())
-      return;
-  }
-
-  std::string VSDir;
-
-  // When built with access to the proper Windows APIs, try to actually find
-  // the correct include paths first.
-  if (getVisualStudioInstallDir(VSDir)) {
-    AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
-
-    if (useUniversalCRT(VSDir)) {
-      std::string UniversalCRTSdkPath;
-      std::string UCRTVersion;
-      if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
-        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
-                                      "Include", UCRTVersion, "ucrt");
-      }
-    }
-
-    std::string WindowsSDKDir;
-    int major;
-    std::string windowsSDKIncludeVersion;
-    std::string windowsSDKLibVersion;
-    if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
-                         windowsSDKLibVersion)) {
-      if (major >= 8) {
-        // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
-        // Anyway, llvm::sys::path::append is able to manage it.
-        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
-                                      "include", windowsSDKIncludeVersion,
-                                      "shared");
-        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
-                                      "include", windowsSDKIncludeVersion,
-                                      "um");
-        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
-                                      "include", windowsSDKIncludeVersion,
-                                      "winrt");
-      } else {
-        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
-                                      "include");
-      }
-    } else {
-      addSystemInclude(DriverArgs, CC1Args, VSDir);
-    }
-    return;
-  }
-
-#if defined(LLVM_ON_WIN32)
-  // 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",
-    "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
-    "C:/Program Files/Microsoft Visual Studio 8/VC/include",
-    "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
-  };
-  addSystemIncludes(DriverArgs, CC1Args, Paths);
-#endif
-}
-
-void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
-                                                 ArgStringList &CC1Args) const {
-  // FIXME: There should probably be logic here to find libc++ on Windows.
-}
-
-VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
-                                               const ArgList &Args) const {
-  bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
-  VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
-  if (MSVT.empty()) MSVT = getMSVCVersionFromTriple();
-  if (MSVT.empty() && IsWindowsMSVC) MSVT = getMSVCVersionFromExe();
-  if (MSVT.empty() &&
-      Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
-                   IsWindowsMSVC)) {
-    // -fms-compatibility-version=18.00 is default.
-    // FIXME: Consider bumping this to 19 (MSVC2015) soon.
-    MSVT = VersionTuple(18);
-  }
-  return MSVT;
-}
-
-std::string
-MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
-                                           types::ID InputType) const {
-  // The MSVC version doesn't care about the architecture, even though it
-  // may look at the triple internally.
-  VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
-  MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
-                      MSVT.getSubminor().getValueOr(0));
-
-  // For the rest of the triple, however, a computed architecture name may
-  // be needed.
-  llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
-  if (Triple.getEnvironment() == llvm::Triple::MSVC) {
-    StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
-    if (ObjFmt.empty())
-      Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
-    else
-      Triple.setEnvironmentName(
-          (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
-  }
-  return Triple.getTriple();
-}
-
-SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
-  SanitizerMask Res = ToolChain::getSupportedSanitizers();
-  Res |= SanitizerKind::Address;
-  return Res;
-}
-
-static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
-                            bool SupportsForcingFramePointer,
-                            const char *ExpandChar, const OptTable &Opts) {
-  assert(A->getOption().matches(options::OPT__SLASH_O));
-
-  StringRef OptStr = A->getValue();
-  for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
-    const char &OptChar = *(OptStr.data() + I);
-    switch (OptChar) {
-    default:
-      break;
-    case '1':
-    case '2':
-    case 'x':
-    case 'd':
-      if (&OptChar == ExpandChar) {
-        if (OptChar == 'd') {
-          DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
-        } else {
-          if (OptChar == '1') {
-            DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
-          } else if (OptChar == '2' || OptChar == 'x') {
-            DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
-            DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
-          }
-          if (SupportsForcingFramePointer &&
-              !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
-            DAL.AddFlagArg(A,
-                           Opts.getOption(options::OPT_fomit_frame_pointer));
-          if (OptChar == '1' || OptChar == '2')
-            DAL.AddFlagArg(A,
-                           Opts.getOption(options::OPT_ffunction_sections));
-        }
-      }
-      break;
-    case 'b':
-      if (I + 1 != E && isdigit(OptStr[I + 1])) {
-        switch (OptStr[I + 1]) {
-        case '0':
-          DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
-          break;
-        case '1':
-          DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
-          break;
-        case '2':
-          DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
-          break;
-        }
-        ++I;
-      }
-      break;
-    case 'g':
-      break;
-    case 'i':
-      if (I + 1 != E && OptStr[I + 1] == '-') {
-        ++I;
-        DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
-      } else {
-        DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
-      }
-      break;
-    case 's':
-      DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
-      break;
-    case 't':
-      DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
-      break;
-    case 'y': {
-      bool OmitFramePointer = true;
-      if (I + 1 != E && OptStr[I + 1] == '-') {
-        OmitFramePointer = false;
-        ++I;
-      }
-      if (SupportsForcingFramePointer) {
-        if (OmitFramePointer)
-          DAL.AddFlagArg(A,
-                         Opts.getOption(options::OPT_fomit_frame_pointer));
-        else
-          DAL.AddFlagArg(
-              A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
-      } else {
-        // Don't warn about /Oy- in 64-bit builds (where
-        // SupportsForcingFramePointer is false).  The flag having no effect
-        // there is a compiler-internal optimization, and people shouldn't have
-        // to special-case their build files for 64-bit clang-cl.
-        A->claim();
-      }
-      break;
-    }
-    }
-  }
-}
-
-static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
-                          const OptTable &Opts) {
-  assert(A->getOption().matches(options::OPT_D));
-
-  StringRef Val = A->getValue();
-  size_t Hash = Val.find('#');
-  if (Hash == StringRef::npos || Hash > Val.find('=')) {
-    DAL.append(A);
-    return;
-  }
-
-  std::string NewVal = Val;
-  NewVal[Hash] = '=';
-  DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
-}
-
-llvm::opt::DerivedArgList *
-MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
-                             StringRef BoundArch, Action::OffloadKind) const {
-  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
-  const OptTable &Opts = getDriver().getOpts();
-
-  // /Oy and /Oy- only has an effect under X86-32.
-  bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
-
-  // The -O[12xd] flag actually expands to several flags.  We must desugar the
-  // flags so that options embedded can be negated.  For example, the '-O2' flag
-  // enables '-Oy'.  Expanding '-O2' into its constituent flags allows us to
-  // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
-  // aspect of '-O2'.
-  //
-  // Note that this expansion logic only applies to the *last* of '[12xd]'.
-
-  // First step is to search for the character we'd like to expand.
-  const char *ExpandChar = nullptr;
-  for (Arg *A : Args) {
-    if (!A->getOption().matches(options::OPT__SLASH_O))
-      continue;
-    StringRef OptStr = A->getValue();
-    for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
-      char OptChar = OptStr[I];
-      char PrevChar = I > 0 ? OptStr[I - 1] : '0';
-      if (PrevChar == 'b') {
-        // OptChar does not expand; it's an argument to the previous char.
-        continue;
-      }
-      if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
-        ExpandChar = OptStr.data() + I;
-    }
-  }
-
-  for (Arg *A : Args) {
-    if (A->getOption().matches(options::OPT__SLASH_O)) {
-      // The -O flag actually takes an amalgam of other options.  For example,
-      // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
-      TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
-    } else if (A->getOption().matches(options::OPT_D)) {
-      // Translate -Dfoo#bar into -Dfoo=bar.
-      TranslateDArg(A, *DAL, Opts);
-    } else {
-      DAL->append(A);
-    }
-  }
-
-  return DAL;
-}
diff --git a/lib/Driver/MinGWToolChain.cpp b/lib/Driver/MinGWToolChain.cpp
deleted file mode 100644
index 938440b..0000000
--- a/lib/Driver/MinGWToolChain.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-//===--- MinGWToolChain.cpp - MinGWToolChain Implementation ---------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ToolChains.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Driver/Options.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-
-using namespace clang::diag;
-using namespace clang::driver;
-using namespace clang::driver::toolchains;
-using namespace clang;
-using namespace llvm::opt;
-
-namespace {
-// Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple.
-bool findGccVersion(StringRef LibDir, std::string &GccLibDir,
-                    std::string &Ver) {
-  Generic_GCC::GCCVersion Version = Generic_GCC::GCCVersion::Parse("0.0.0");
-  std::error_code EC;
-  for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
-       LI = LI.increment(EC)) {
-    StringRef VersionText = llvm::sys::path::filename(LI->path());
-    Generic_GCC::GCCVersion CandidateVersion =
-        Generic_GCC::GCCVersion::Parse(VersionText);
-    if (CandidateVersion.Major == -1)
-      continue;
-    if (CandidateVersion <= Version)
-      continue;
-    Ver = VersionText;
-    GccLibDir = LI->path();
-  }
-  return Ver.size();
-}
-}
-
-void MinGW::findGccLibDir() {
-  llvm::SmallVector<llvm::SmallString<32>, 2> Archs;
-  Archs.emplace_back(getTriple().getArchName());
-  Archs[0] += "-w64-mingw32";
-  Archs.emplace_back("mingw32");
-  Arch = Archs[0].str();
-  // lib: Arch Linux, Ubuntu, Windows
-  // lib64: openSUSE Linux
-  for (StringRef CandidateLib : {"lib", "lib64"}) {
-    for (StringRef CandidateArch : Archs) {
-      llvm::SmallString<1024> LibDir(Base);
-      llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateArch);
-      if (findGccVersion(LibDir, GccLibDir, Ver)) {
-        Arch = CandidateArch;
-        return;
-      }
-    }
-  }
-}
-
-MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
-    : ToolChain(D, Triple, Args) {
-  getProgramPaths().push_back(getDriver().getInstalledDir());
-
-// In Windows there aren't any standard install locations, we search
-// for gcc on the PATH. In Linux the base is always /usr.
-#ifdef LLVM_ON_WIN32
-  if (getDriver().SysRoot.size())
-    Base = getDriver().SysRoot;
-  else if (llvm::ErrorOr<std::string> GPPName =
-               llvm::sys::findProgramByName("gcc"))
-    Base = llvm::sys::path::parent_path(
-        llvm::sys::path::parent_path(GPPName.get()));
-  else
-    Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
-#else
-  if (getDriver().SysRoot.size())
-    Base = getDriver().SysRoot;
-  else
-    Base = "/usr";
-#endif
-
-  Base += llvm::sys::path::get_separator();
-  findGccLibDir();
-  // GccLibDir must precede Base/lib so that the
-  // correct crtbegin.o ,cetend.o would be found.
-  getFilePaths().push_back(GccLibDir);
-  getFilePaths().push_back(
-      (Base + Arch + llvm::sys::path::get_separator() + "lib").str());
-  getFilePaths().push_back(Base + "lib");
-  // openSUSE
-  getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib");
-}
-
-bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
-
-Tool *MinGW::getTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::PreprocessJobClass:
-    if (!Preprocessor)
-      Preprocessor.reset(new tools::gcc::Preprocessor(*this));
-    return Preprocessor.get();
-  case Action::CompileJobClass:
-    if (!Compiler)
-      Compiler.reset(new tools::gcc::Compiler(*this));
-    return Compiler.get();
-  default:
-    return ToolChain::getTool(AC);
-  }
-}
-
-Tool *MinGW::buildAssembler() const {
-  return new tools::MinGW::Assembler(*this);
-}
-
-Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
-
-bool MinGW::IsUnwindTablesDefault() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
-
-bool MinGW::isPIEDefault() const { return false; }
-
-bool MinGW::isPICDefaultForced() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-bool MinGW::UseSEHExceptions() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-// Include directories for various hosts:
-
-// Windows, mingw.org
-// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
-// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
-// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
-// c:\mingw\lib\gcc\mingw32\4.8.1\include
-// c:\mingw\include
-// c:\mingw\lib\gcc\mingw32\4.8.1\include-fixed
-// c:\mingw\mingw32\include
-
-// Windows, mingw-w64 mingw-builds
-// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include
-// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include-fixed
-// c:\mingw32\i686-w64-mingw32\include
-// c:\mingw32\i686-w64-mingw32\include\c++
-// c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
-// c:\mingw32\i686-w64-mingw32\include\c++\backward
-
-// Windows, mingw-w64 msys2
-// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include
-// c:\msys64\mingw32\include
-// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include-fixed
-// c:\msys64\mingw32\i686-w64-mingw32\include
-// c:\msys64\mingw32\include\c++\4.9.2
-// c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
-// c:\msys64\mingw32\include\c++\4.9.2\backward
-
-// openSUSE
-// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
-// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
-// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
-// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include
-// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include-fixed
-// /usr/x86_64-w64-mingw32/sys-root/mingw/include
-
-// Arch Linux
-// /usr/i686-w64-mingw32/include/c++/5.1.0
-// /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
-// /usr/i686-w64-mingw32/include/c++/5.1.0/backward
-// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include
-// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include-fixed
-// /usr/i686-w64-mingw32/include
-
-// Ubuntu
-// /usr/include/c++/4.8
-// /usr/include/c++/4.8/x86_64-w64-mingw32
-// /usr/include/c++/4.8/backward
-// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include
-// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include-fixed
-// /usr/x86_64-w64-mingw32/include
-
-void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                      ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdinc))
-    return;
-
-  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
-    SmallString<1024> P(getDriver().ResourceDir);
-    llvm::sys::path::append(P, "include");
-    addSystemInclude(DriverArgs, CC1Args, P.str());
-  }
-
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
-    return;
-
-  if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) {
-    llvm::SmallString<1024> IncludeDir(GccLibDir);
-    llvm::sys::path::append(IncludeDir, "include");
-    addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
-    IncludeDir += "-fixed";
-    // openSUSE
-    addSystemInclude(DriverArgs, CC1Args,
-                     Base + Arch + "/sys-root/mingw/include");
-    addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
-  }
-  addSystemInclude(DriverArgs, CC1Args,
-                   Base + Arch + llvm::sys::path::get_separator() + "include");
-  addSystemInclude(DriverArgs, CC1Args, Base + "include");
-}
-
-void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
-                                         ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
-      DriverArgs.hasArg(options::OPT_nostdincxx))
-    return;
-
-  switch (GetCXXStdlibType(DriverArgs)) {
-  case ToolChain::CST_Libcxx:
-    addSystemInclude(DriverArgs, CC1Args,
-                     Base + "include" + llvm::sys::path::get_separator() +
-                         "c++" + llvm::sys::path::get_separator() + "v1");
-    break;
-
-  case ToolChain::CST_Libstdcxx:
-    llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases;
-    CppIncludeBases.emplace_back(Base);
-    llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
-    CppIncludeBases.emplace_back(Base);
-    llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver);
-    CppIncludeBases.emplace_back(Base);
-    llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
-    CppIncludeBases.emplace_back(GccLibDir);
-    llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
-    for (auto &CppIncludeBase : CppIncludeBases) {
-      addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
-      CppIncludeBase += llvm::sys::path::get_separator();
-      addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
-      addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
-    }
-    break;
-  }
-}
diff --git a/lib/Driver/Multilib.cpp b/lib/Driver/Multilib.cpp
index a88edf7..43b62f7 100644
--- a/lib/Driver/Multilib.cpp
+++ b/lib/Driver/Multilib.cpp
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Driver/Multilib.h"
-#include "Tools.h"
+#include "ToolChains/CommonArgs.h"
 #include "clang/Driver/Options.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index f4f6dad..b05596a 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 #include "clang/Driver/SanitizerArgs.h"
-#include "Tools.h"
+#include "ToolChains/CommonArgs.h"
 #include "clang/Basic/Sanitizers.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
@@ -26,18 +26,19 @@
 using namespace llvm::opt;
 
 enum : SanitizerMask {
-  NeedsUbsanRt = Undefined | Integer | CFI,
+  NeedsUbsanRt = Undefined | Integer | Nullability | CFI,
   NeedsUbsanCxxRt = Vptr | CFI,
   NotAllowedWithTrap = Vptr,
   RequiresPIE = DataFlow,
   NeedsUnwindTables = Address | Thread | Memory | DataFlow,
-  SupportsCoverage = Address | Memory | Leak | Undefined | Integer | DataFlow,
-  RecoverableByDefault = Undefined | Integer,
+  SupportsCoverage =
+      Address | Memory | Leak | Undefined | Integer | Nullability | DataFlow,
+  RecoverableByDefault = Undefined | Integer | Nullability,
   Unrecoverable = Unreachable | Return,
   LegacyFsanitizeRecoverMask = Undefined | Integer,
   NeedsLTO = CFI,
-  TrappingSupported =
-      (Undefined & ~Vptr) | UnsignedIntegerOverflow | LocalBounds | CFI,
+  TrappingSupported = (Undefined & ~Vptr) | UnsignedIntegerOverflow |
+                      Nullability | LocalBounds | CFI,
   TrappingDefault = CFI,
   CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
 };
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index 5c6d062..f9dafb5 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -8,8 +8,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Driver/ToolChain.h"
-#include "Tools.h"
+#include "ToolChains/CommonArgs.h"
+#include "ToolChains/Arch/ARM.h"
+#include "ToolChains/Clang.h"
 #include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/VirtualFileSystem.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/Action.h"
 #include "clang/Driver/Driver.h"
@@ -74,6 +77,10 @@
     if (!isThreadModelSupported(A->getValue()))
       D.Diag(diag::err_drv_invalid_thread_model_for_target)
           << A->getValue() << A->getAsString(Args);
+
+  std::string CandidateLibPath = getArchSpecificLibPath();
+  if (getVFS().exists(CandidateLibPath))
+    getFilePaths().push_back(CandidateLibPath);
 }
 
 ToolChain::~ToolChain() {
@@ -320,6 +327,14 @@
   return Args.MakeArgString(getCompilerRT(Args, Component, Shared));
 }
 
+std::string ToolChain::getArchSpecificLibPath() const {
+  SmallString<128> Path(getDriver().ResourceDir);
+  StringRef OSLibName = getTriple().isOSFreeBSD() ? "freebsd" : getOS();
+  llvm::sys::path::append(Path, "lib", OSLibName,
+                          llvm::Triple::getArchTypeName(getArch()));
+  return Path.str();
+}
+
 bool ToolChain::needsProfileRT(const ArgList &Args) {
   if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
                    false) ||
@@ -351,33 +366,31 @@
 }
 
 std::string ToolChain::GetLinkerPath() const {
-  if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
-    StringRef UseLinker = A->getValue();
+  const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
+  StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
 
-    if (llvm::sys::path::is_absolute(UseLinker)) {
-      // If we're passed -fuse-ld= with what looks like an absolute path,
-      // don't attempt to second-guess that.
-      if (llvm::sys::fs::exists(UseLinker))
-        return UseLinker;
-    } else {
-      // If we're passed -fuse-ld= with no argument, or with the argument ld,
-      // then use whatever the default system linker is.
-      if (UseLinker.empty() || UseLinker == "ld")
-        return GetProgramPath("ld");
+  if (llvm::sys::path::is_absolute(UseLinker)) {
+    // If we're passed what looks like an absolute path, don't attempt to
+    // second-guess that.
+    if (llvm::sys::fs::exists(UseLinker))
+      return UseLinker;
+  } else if (UseLinker.empty() || UseLinker == "ld") {
+    // If we're passed -fuse-ld= with no argument, or with the argument ld,
+    // then use whatever the default system linker is.
+    return GetProgramPath(getDefaultLinker());
+  } else {
+    llvm::SmallString<8> LinkerName("ld.");
+    LinkerName.append(UseLinker);
 
-      llvm::SmallString<8> LinkerName("ld.");
-      LinkerName.append(UseLinker);
-
-      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 "";
+    std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
+    if (llvm::sys::fs::exists(LinkerPath))
+      return LinkerPath;
   }
 
-  return GetProgramPath(DefaultLinker);
+  if (A)
+    getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
+
+  return GetProgramPath(getDefaultLinker());
 }
 
 types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const {
@@ -542,7 +555,7 @@
   const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
   StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
 
-  // "platform" is only used in tests to override CLANG_DEFAULT_RTLIB
+  // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB!
   if (LibName == "compiler-rt")
     return ToolChain::RLT_CompilerRT;
   else if (LibName == "libgcc")
@@ -556,43 +569,22 @@
   return GetDefaultRuntimeLibType();
 }
 
-static bool ParseCXXStdlibType(const StringRef& Name,
-                               ToolChain::CXXStdlibType& Type) {
-  if (Name == "libc++")
-    Type = ToolChain::CST_Libcxx;
-  else if (Name == "libstdc++")
-    Type = ToolChain::CST_Libstdcxx;
-  else
-    return false;
-
-  return true;
-}
-
 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
-  ToolChain::CXXStdlibType Type;
-  bool HasValidType = false;
-  bool ForcePlatformDefault = false;
-
   const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
-  if (A) {
-    StringRef Value = A->getValue();
-    HasValidType = ParseCXXStdlibType(Value, Type);
+  StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
 
-    // Only use in tests to override CLANG_DEFAULT_CXX_STDLIB!
-    if (Value == "platform")
-      ForcePlatformDefault = true;
-    else if (!HasValidType)
-      getDriver().Diag(diag::err_drv_invalid_stdlib_name)
-        << A->getAsString(Args);
-  }
+  // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB!
+  if (LibName == "libc++")
+    return ToolChain::CST_Libcxx;
+  else if (LibName == "libstdc++")
+    return ToolChain::CST_Libstdcxx;
+  else if (LibName == "platform")
+    return GetDefaultCXXStdlibType();
 
-  // If no argument was provided or its value was invalid, look for the
-  // default unless forced or configured to take the platform default.
-  if (!HasValidType && (ForcePlatformDefault ||
-      !ParseCXXStdlibType(CLANG_DEFAULT_CXX_STDLIB, Type)))
-    Type = GetDefaultCXXStdlibType();
+  if (A)
+    getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
 
-  return Type;
+  return GetDefaultCXXStdlibType();
 }
 
 /// \brief Utility function to add a system include directory to CC1 arguments.
@@ -705,7 +697,8 @@
   // platform dependent.
   using namespace SanitizerKind;
   SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) |
-                      CFICastStrict | UnsignedIntegerOverflow | LocalBounds;
+                      CFICastStrict | UnsignedIntegerOverflow | Nullability |
+                      LocalBounds;
   if (getTriple().getArch() == llvm::Triple::x86 ||
       getTriple().getArch() == llvm::Triple::x86_64 ||
       getTriple().getArch() == llvm::Triple::arm ||
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
deleted file mode 100644
index be7fb7f..0000000
--- a/lib/Driver/ToolChains.cpp
+++ /dev/null
@@ -1,5288 +0,0 @@
-//===--- ToolChains.cpp - ToolChain Implementations -------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ToolChains.h"
-#include "clang/Basic/Cuda.h"
-#include "clang/Basic/ObjCRuntime.h"
-#include "clang/Basic/Version.h"
-#include "clang/Basic/VirtualFileSystem.h"
-#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
-#include "clang/Driver/Compilation.h"
-#include "clang/Driver/Distro.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/Options.h"
-#include "clang/Driver/SanitizerArgs.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Option/OptTable.h"
-#include "llvm/Option/Option.h"
-#include "llvm/ProfileData/InstrProf.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Program.h"
-#include "llvm/Support/TargetParser.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdlib> // ::getenv
-#include <system_error>
-
-using namespace clang::driver;
-using namespace clang::driver::toolchains;
-using namespace clang;
-using namespace llvm::opt;
-
-MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
-    : ToolChain(D, Triple, Args) {
-  // We expect 'as', 'ld', etc. to be adjacent to our install dir.
-  getProgramPaths().push_back(getDriver().getInstalledDir());
-  if (getDriver().getInstalledDir() != getDriver().Dir)
-    getProgramPaths().push_back(getDriver().Dir);
-}
-
-/// Darwin - Darwin tool chain for i386 and x86_64.
-Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
-    : MachO(D, Triple, Args), TargetInitialized(false),
-      CudaInstallation(D, Triple, Args) {}
-
-types::ID MachO::LookupTypeForExtension(StringRef Ext) const {
-  types::ID Ty = types::lookupTypeForExtension(Ext);
-
-  // Darwin always preprocesses assembly files (unless -x is used explicitly).
-  if (Ty == types::TY_PP_Asm)
-    return types::TY_Asm;
-
-  return Ty;
-}
-
-bool MachO::HasNativeLLVMSupport() const { return true; }
-
-ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const {
-  // Default to use libc++ on OS X 10.9+ and iOS 7+.
-  if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
-       (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) ||
-       isTargetWatchOSBased())
-    return ToolChain::CST_Libcxx;
-
-  return ToolChain::CST_Libstdcxx;
-}
-
-/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
-ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
-  if (isTargetWatchOSBased())
-    return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion);
-  if (isTargetIOSBased())
-    return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
-  if (isNonFragile)
-    return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
-  return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
-}
-
-/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
-bool Darwin::hasBlocksRuntime() const {
-  if (isTargetWatchOSBased())
-    return true;
-  else if (isTargetIOSBased())
-    return !isIPhoneOSVersionLT(3, 2);
-  else {
-    assert(isTargetMacOS() && "unexpected darwin target");
-    return !isMacosxVersionLT(10, 6);
-  }
-}
-
-void Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs,
-                                ArgStringList &CC1Args) const {
-  CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
-}
-
-// This is just a MachO name translation routine and there's no
-// way to join this into ARMTargetParser without breaking all
-// other assumptions. Maybe MachO should consider standardising
-// their nomenclature.
-static const char *ArmMachOArchName(StringRef Arch) {
-  return llvm::StringSwitch<const char *>(Arch)
-      .Case("armv6k", "armv6")
-      .Case("armv6m", "armv6m")
-      .Case("armv5tej", "armv5")
-      .Case("xscale", "xscale")
-      .Case("armv4t", "armv4t")
-      .Case("armv7", "armv7")
-      .Cases("armv7a", "armv7-a", "armv7")
-      .Cases("armv7r", "armv7-r", "armv7")
-      .Cases("armv7em", "armv7e-m", "armv7em")
-      .Cases("armv7k", "armv7-k", "armv7k")
-      .Cases("armv7m", "armv7-m", "armv7m")
-      .Cases("armv7s", "armv7-s", "armv7s")
-      .Default(nullptr);
-}
-
-static const char *ArmMachOArchNameCPU(StringRef CPU) {
-  unsigned ArchKind = llvm::ARM::parseCPUArch(CPU);
-  if (ArchKind == llvm::ARM::AK_INVALID)
-    return nullptr;
-  StringRef Arch = llvm::ARM::getArchName(ArchKind);
-
-  // FIXME: Make sure this MachO triple mangling is really necessary.
-  // ARMv5* normalises to ARMv5.
-  if (Arch.startswith("armv5"))
-    Arch = Arch.substr(0, 5);
-  // ARMv6*, except ARMv6M, normalises to ARMv6.
-  else if (Arch.startswith("armv6") && !Arch.endswith("6m"))
-    Arch = Arch.substr(0, 5);
-  // ARMv7A normalises to ARMv7.
-  else if (Arch.endswith("v7a"))
-    Arch = Arch.substr(0, 5);
-  return Arch.data();
-}
-
-static bool isSoftFloatABI(const ArgList &Args) {
-  Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
-                           options::OPT_mfloat_abi_EQ);
-  if (!A)
-    return false;
-
-  return A->getOption().matches(options::OPT_msoft_float) ||
-         (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
-          A->getValue() == StringRef("soft"));
-}
-
-StringRef MachO::getMachOArchName(const ArgList &Args) const {
-  switch (getTriple().getArch()) {
-  default:
-    return getDefaultUniversalArchName();
-
-  case llvm::Triple::aarch64:
-    return "arm64";
-
-  case llvm::Triple::thumb:
-  case llvm::Triple::arm:
-    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
-      if (const char *Arch = ArmMachOArchName(A->getValue()))
-        return Arch;
-
-    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
-      if (const char *Arch = ArmMachOArchNameCPU(A->getValue()))
-        return Arch;
-
-    return "arm";
-  }
-}
-
-Darwin::~Darwin() {}
-
-MachO::~MachO() {}
-
-std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
-                                                types::ID InputType) const {
-  llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
-
-  // If the target isn't initialized (e.g., an unknown Darwin platform, return
-  // the default triple).
-  if (!isTargetInitialized())
-    return Triple.getTriple();
-
-  SmallString<16> Str;
-  if (isTargetWatchOSBased())
-    Str += "watchos";
-  else if (isTargetTvOSBased())
-    Str += "tvos";
-  else if (isTargetIOSBased())
-    Str += "ios";
-  else
-    Str += "macosx";
-  Str += getTargetVersion().getAsString();
-  Triple.setOSName(Str);
-
-  return Triple.getTriple();
-}
-
-void Generic_ELF::anchor() {}
-
-Tool *MachO::getTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::LipoJobClass:
-    if (!Lipo)
-      Lipo.reset(new tools::darwin::Lipo(*this));
-    return Lipo.get();
-  case Action::DsymutilJobClass:
-    if (!Dsymutil)
-      Dsymutil.reset(new tools::darwin::Dsymutil(*this));
-    return Dsymutil.get();
-  case Action::VerifyDebugInfoJobClass:
-    if (!VerifyDebug)
-      VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
-    return VerifyDebug.get();
-  default:
-    return ToolChain::getTool(AC);
-  }
-}
-
-Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
-
-Tool *MachO::buildAssembler() const {
-  return new tools::darwin::Assembler(*this);
-}
-
-DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple,
-                         const ArgList &Args)
-    : Darwin(D, Triple, Args) {}
-
-void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
-  // For modern targets, promote certain warnings to errors.
-  if (isTargetWatchOSBased() || getTriple().isArch64Bit()) {
-    // Always enable -Wdeprecated-objc-isa-usage and promote it
-    // to an error.
-    CC1Args.push_back("-Wdeprecated-objc-isa-usage");
-    CC1Args.push_back("-Werror=deprecated-objc-isa-usage");
-
-    // For iOS and watchOS, also error about implicit function declarations,
-    // as that can impact calling conventions.
-    if (!isTargetMacOS())
-      CC1Args.push_back("-Werror=implicit-function-declaration");
-  }
-}
-
-/// \brief Determine whether Objective-C automated reference counting is
-/// enabled.
-static bool isObjCAutoRefCount(const ArgList &Args) {
-  return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
-}
-
-void DarwinClang::AddLinkARCArgs(const ArgList &Args,
-                                 ArgStringList &CmdArgs) const {
-  // Avoid linking compatibility stubs on i386 mac.
-  if (isTargetMacOS() && getArch() == llvm::Triple::x86)
-    return;
-
-  ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);
-
-  if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) &&
-      runtime.hasSubscripting())
-    return;
-
-  CmdArgs.push_back("-force_load");
-  SmallString<128> P(getDriver().ClangExecutable);
-  llvm::sys::path::remove_filename(P); // 'clang'
-  llvm::sys::path::remove_filename(P); // 'bin'
-  llvm::sys::path::append(P, "lib", "arc", "libarclite_");
-  // Mash in the platform.
-  if (isTargetWatchOSSimulator())
-    P += "watchsimulator";
-  else if (isTargetWatchOS())
-    P += "watchos";
-  else if (isTargetTvOSSimulator())
-    P += "appletvsimulator";
-  else if (isTargetTvOS())
-    P += "appletvos";
-  else if (isTargetIOSSimulator())
-    P += "iphonesimulator";
-  else if (isTargetIPhoneOS())
-    P += "iphoneos";
-  else
-    P += "macosx";
-  P += ".a";
-
-  CmdArgs.push_back(Args.MakeArgString(P));
-}
-
-unsigned DarwinClang::GetDefaultDwarfVersion() const {
-  // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower.
-  if ((isTargetMacOS() && isMacosxVersionLT(10, 11)) ||
-      (isTargetIOSBased() && isIPhoneOSVersionLT(9)))
-    return 2;
-  return 4;
-}
-
-void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
-                              StringRef DarwinLibName, bool AlwaysLink,
-                              bool IsEmbedded, bool AddRPath) const {
-  SmallString<128> Dir(getDriver().ResourceDir);
-  llvm::sys::path::append(Dir, "lib", IsEmbedded ? "macho_embedded" : "darwin");
-
-  SmallString<128> P(Dir);
-  llvm::sys::path::append(P, DarwinLibName);
-
-  // For now, allow missing resource libraries to support developers who may
-  // not have compiler-rt checked out or integrated into their build (unless
-  // we explicitly force linking with this library).
-  if (AlwaysLink || getVFS().exists(P))
-    CmdArgs.push_back(Args.MakeArgString(P));
-
-  // Adding the rpaths might negatively interact when other rpaths are involved,
-  // so we should make sure we add the rpaths last, after all user-specified
-  // rpaths. This is currently true from this place, but we need to be
-  // careful if this function is ever called before user's rpaths are emitted.
-  if (AddRPath) {
-    assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library");
-
-    // Add @executable_path to rpath to support having the dylib copied with
-    // the executable.
-    CmdArgs.push_back("-rpath");
-    CmdArgs.push_back("@executable_path");
-
-    // Add the path to the resource dir to rpath to support using the dylib
-    // from the default location without copying.
-    CmdArgs.push_back("-rpath");
-    CmdArgs.push_back(Args.MakeArgString(Dir));
-  }
-}
-
-StringRef Darwin::getPlatformFamily() const {
-  switch (TargetPlatform) {
-    case DarwinPlatformKind::MacOS:
-      return "MacOSX";
-    case DarwinPlatformKind::IPhoneOS:
-    case DarwinPlatformKind::IPhoneOSSimulator:
-      return "iPhone";
-    case DarwinPlatformKind::TvOS:
-    case DarwinPlatformKind::TvOSSimulator:
-      return "AppleTV";
-    case DarwinPlatformKind::WatchOS:
-    case DarwinPlatformKind::WatchOSSimulator:
-      return "Watch";
-  }
-  llvm_unreachable("Unsupported platform");
-}
-
-StringRef Darwin::getSDKName(StringRef isysroot) {
-  // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
-  llvm::sys::path::const_iterator SDKDir;
-  auto BeginSDK = llvm::sys::path::begin(isysroot);
-  auto EndSDK = llvm::sys::path::end(isysroot);
-  for (auto IT = BeginSDK; IT != EndSDK; ++IT) {
-    StringRef SDK = *IT;
-    if (SDK.endswith(".sdk"))
-      return SDK.slice(0, SDK.size() - 4);
-  }
-  return "";
-}
-
-StringRef Darwin::getOSLibraryNameSuffix() const {
-  switch(TargetPlatform) {
-  case DarwinPlatformKind::MacOS:
-    return "osx";
-  case DarwinPlatformKind::IPhoneOS:
-    return "ios";
-  case DarwinPlatformKind::IPhoneOSSimulator:
-    return "iossim";
-  case DarwinPlatformKind::TvOS:
-    return "tvos";
-  case DarwinPlatformKind::TvOSSimulator:
-    return "tvossim";
-  case DarwinPlatformKind::WatchOS:
-    return "watchos";
-  case DarwinPlatformKind::WatchOSSimulator:
-    return "watchossim";
-  }
-  llvm_unreachable("Unsupported platform");
-}
-
-void Darwin::addProfileRTLibs(const ArgList &Args,
-                              ArgStringList &CmdArgs) const {
-  if (!needsProfileRT(Args)) return;
-
-  AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.profile_") +
-       getOSLibraryNameSuffix() + ".a").str(),
-                    /*AlwaysLink*/ true);
-}
-
-void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,
-                                          ArgStringList &CmdArgs,
-                                          StringRef Sanitizer) const {
-  AddLinkRuntimeLib(
-      Args, CmdArgs,
-      (Twine("libclang_rt.") + Sanitizer + "_" +
-       getOSLibraryNameSuffix() + "_dynamic.dylib").str(),
-      /*AlwaysLink*/ true, /*IsEmbedded*/ false,
-      /*AddRPath*/ true);
-}
-
-ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType(
-    const ArgList &Args) const {
-  if (Arg* A = Args.getLastArg(options::OPT_rtlib_EQ)) {
-    StringRef Value = A->getValue();
-    if (Value != "compiler-rt")
-      getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
-          << Value << "darwin";
-  }
-
-  return ToolChain::RLT_CompilerRT;
-}
-
-void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
-                                        ArgStringList &CmdArgs) const {
-  // Call once to ensure diagnostic is printed if wrong value was specified
-  GetRuntimeLibType(Args);
-
-  // Darwin doesn't support real static executables, don't link any runtime
-  // libraries with -static.
-  if (Args.hasArg(options::OPT_static) ||
-      Args.hasArg(options::OPT_fapple_kext) ||
-      Args.hasArg(options::OPT_mkernel))
-    return;
-
-  // Reject -static-libgcc for now, we can deal with this when and if someone
-  // cares. This is useful in situations where someone wants to statically link
-  // something like libstdc++, and needs its runtime support routines.
-  if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
-    getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
-    return;
-  }
-
-  const SanitizerArgs &Sanitize = getSanitizerArgs();
-  if (Sanitize.needsAsanRt())
-    AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
-  if (Sanitize.needsUbsanRt())
-    AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan");
-  if (Sanitize.needsTsanRt())
-    AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
-  if (Sanitize.needsStatsRt()) {
-    StringRef OS = isTargetMacOS() ? "osx" : "iossim";
-    AddLinkRuntimeLib(Args, CmdArgs,
-                      (Twine("libclang_rt.stats_client_") + OS + ".a").str(),
-                      /*AlwaysLink=*/true);
-    AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
-  }
-  if (Sanitize.needsEsanRt())
-    AddLinkSanitizerLibArgs(Args, CmdArgs, "esan");
-
-  // Otherwise link libSystem, then the dynamic runtime library, and finally any
-  // target specific static runtime library.
-  CmdArgs.push_back("-lSystem");
-
-  // Select the dynamic runtime library and the target specific static library.
-  if (isTargetWatchOSBased()) {
-    // We currently always need a static runtime library for watchOS.
-    AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.watchos.a");
-  } else if (isTargetTvOSBased()) {
-    // We currently always need a static runtime library for tvOS.
-    AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.tvos.a");
-  } else if (isTargetIOSBased()) {
-    // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
-    // it never went into the SDK.
-    // Linking against libgcc_s.1 isn't needed for iOS 5.0+
-    if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
-        getTriple().getArch() != llvm::Triple::aarch64)
-      CmdArgs.push_back("-lgcc_s.1");
-
-    // We currently always need a static runtime library for iOS.
-    AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
-  } else {
-    assert(isTargetMacOS() && "unexpected non MacOS platform");
-    // The dynamic runtime library was merged with libSystem for 10.6 and
-    // beyond; only 10.4 and 10.5 need an additional runtime library.
-    if (isMacosxVersionLT(10, 5))
-      CmdArgs.push_back("-lgcc_s.10.4");
-    else if (isMacosxVersionLT(10, 6))
-      CmdArgs.push_back("-lgcc_s.10.5");
-
-    // Originally for OS X, we thought we would only need a static runtime
-    // library when targeting 10.4, to provide versions of the static functions
-    // which were omitted from 10.4.dylib. This led to the creation of the 10.4
-    // builtins library.
-    //
-    // Unfortunately, that turned out to not be true, because Darwin system
-    // headers can still use eprintf on i386, and it is not exported from
-    // libSystem. Therefore, we still must provide a runtime library just for
-    // the tiny tiny handful of projects that *might* use that symbol.
-    //
-    // Then over time, we figured out it was useful to add more things to the
-    // runtime so we created libclang_rt.osx.a to provide new functions when
-    // deploying to old OS builds, and for a long time we had both eprintf and
-    // osx builtin libraries. Which just seems excessive. So with PR 28855, we
-    // are removing the eprintf library and expecting eprintf to be provided by
-    // the OS X builtins library.
-    if (isMacosxVersionLT(10, 5))
-      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
-    else
-      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
-  }
-}
-
-void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
-  const OptTable &Opts = getDriver().getOpts();
-
-  // Support allowing the SDKROOT environment variable used by xcrun and other
-  // Xcode tools to define the default sysroot, by making it the default for
-  // isysroot.
-  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
-    // Warn if the path does not exist.
-    if (!getVFS().exists(A->getValue()))
-      getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
-  } else {
-    if (char *env = ::getenv("SDKROOT")) {
-      // We only use this value as the default if it is an absolute path,
-      // exists, and it is not the root path.
-      if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
-          StringRef(env) != "/") {
-        Args.append(Args.MakeSeparateArg(
-            nullptr, Opts.getOption(options::OPT_isysroot), env));
-      }
-    }
-  }
-
-  Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
-  Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
-  Arg *TvOSVersion = Args.getLastArg(options::OPT_mtvos_version_min_EQ);
-  Arg *WatchOSVersion = Args.getLastArg(options::OPT_mwatchos_version_min_EQ);
-
-  if (OSXVersion && (iOSVersion || TvOSVersion || WatchOSVersion)) {
-    getDriver().Diag(diag::err_drv_argument_not_allowed_with)
-        << OSXVersion->getAsString(Args)
-        << (iOSVersion ? iOSVersion :
-            TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
-    iOSVersion = TvOSVersion = WatchOSVersion = nullptr;
-  } else if (iOSVersion && (TvOSVersion || WatchOSVersion)) {
-    getDriver().Diag(diag::err_drv_argument_not_allowed_with)
-        << iOSVersion->getAsString(Args)
-        << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
-    TvOSVersion = WatchOSVersion = nullptr;
-  } else if (TvOSVersion && WatchOSVersion) {
-     getDriver().Diag(diag::err_drv_argument_not_allowed_with)
-        << TvOSVersion->getAsString(Args)
-        << WatchOSVersion->getAsString(Args);
-    WatchOSVersion = nullptr;
-  } else if (!OSXVersion && !iOSVersion && !TvOSVersion && !WatchOSVersion) {
-    // If no deployment target was specified on the command line, check for
-    // environment defines.
-    std::string OSXTarget;
-    std::string iOSTarget;
-    std::string TvOSTarget;
-    std::string WatchOSTarget;
-
-    if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
-      OSXTarget = env;
-    if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
-      iOSTarget = env;
-    if (char *env = ::getenv("TVOS_DEPLOYMENT_TARGET"))
-      TvOSTarget = env;
-    if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET"))
-      WatchOSTarget = env;
-
-    // If there is no command-line argument to specify the Target version and
-    // no environment variable defined, see if we can set the default based
-    // on -isysroot.
-    if (OSXTarget.empty() && iOSTarget.empty() && WatchOSTarget.empty() &&
-        TvOSTarget.empty() && Args.hasArg(options::OPT_isysroot)) {
-      if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
-        StringRef isysroot = A->getValue();
-        StringRef SDK = getSDKName(isysroot);
-        if (SDK.size() > 0) {
-          // Slice the version number out.
-          // Version number is between the first and the last number.
-          size_t StartVer = SDK.find_first_of("0123456789");
-          size_t EndVer = SDK.find_last_of("0123456789");
-          if (StartVer != StringRef::npos && EndVer > StartVer) {
-            StringRef Version = SDK.slice(StartVer, EndVer + 1);
-            if (SDK.startswith("iPhoneOS") ||
-                SDK.startswith("iPhoneSimulator"))
-              iOSTarget = Version;
-            else if (SDK.startswith("MacOSX"))
-              OSXTarget = Version;
-            else if (SDK.startswith("WatchOS") ||
-                     SDK.startswith("WatchSimulator"))
-              WatchOSTarget = Version;
-            else if (SDK.startswith("AppleTVOS") ||
-                     SDK.startswith("AppleTVSimulator"))
-              TvOSTarget = Version;
-          }
-        }
-      }
-    }
-
-    // If no OSX or iOS target has been specified, try to guess platform
-    // from arch name and compute the version from the triple.
-    if (OSXTarget.empty() && iOSTarget.empty() && TvOSTarget.empty() &&
-        WatchOSTarget.empty()) {
-      StringRef MachOArchName = getMachOArchName(Args);
-      unsigned Major, Minor, Micro;
-      if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
-          MachOArchName == "arm64") {
-        getTriple().getiOSVersion(Major, Minor, Micro);
-        llvm::raw_string_ostream(iOSTarget) << Major << '.' << Minor << '.'
-                                            << Micro;
-      } else if (MachOArchName == "armv7k") {
-        getTriple().getWatchOSVersion(Major, Minor, Micro);
-        llvm::raw_string_ostream(WatchOSTarget) << Major << '.' << Minor << '.'
-                                                << Micro;
-      } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
-                 MachOArchName != "armv7em") {
-        if (!getTriple().getMacOSXVersion(Major, Minor, Micro)) {
-          getDriver().Diag(diag::err_drv_invalid_darwin_version)
-              << getTriple().getOSName();
-        }
-        llvm::raw_string_ostream(OSXTarget) << Major << '.' << Minor << '.'
-                                            << Micro;
-      }
-    }
-
-    // Do not allow conflicts with the watchOS target.
-    if (!WatchOSTarget.empty() && (!iOSTarget.empty() || !TvOSTarget.empty())) {
-      getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
-        << "WATCHOS_DEPLOYMENT_TARGET"
-        << (!iOSTarget.empty() ? "IPHONEOS_DEPLOYMENT_TARGET" :
-            "TVOS_DEPLOYMENT_TARGET");
-    }
-
-    // Do not allow conflicts with the tvOS target.
-    if (!TvOSTarget.empty() && !iOSTarget.empty()) {
-      getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
-        << "TVOS_DEPLOYMENT_TARGET"
-        << "IPHONEOS_DEPLOYMENT_TARGET";
-    }
-
-    // Allow conflicts among OSX and iOS for historical reasons, but choose the
-    // default platform.
-    if (!OSXTarget.empty() && (!iOSTarget.empty() ||
-                               !WatchOSTarget.empty() ||
-                               !TvOSTarget.empty())) {
-      if (getTriple().getArch() == llvm::Triple::arm ||
-          getTriple().getArch() == llvm::Triple::aarch64 ||
-          getTriple().getArch() == llvm::Triple::thumb)
-        OSXTarget = "";
-      else
-        iOSTarget = WatchOSTarget = TvOSTarget = "";
-    }
-
-    if (!OSXTarget.empty()) {
-      const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
-      OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget);
-      Args.append(OSXVersion);
-    } else if (!iOSTarget.empty()) {
-      const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
-      iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget);
-      Args.append(iOSVersion);
-    } else if (!TvOSTarget.empty()) {
-      const Option O = Opts.getOption(options::OPT_mtvos_version_min_EQ);
-      TvOSVersion = Args.MakeJoinedArg(nullptr, O, TvOSTarget);
-      Args.append(TvOSVersion);
-    } else if (!WatchOSTarget.empty()) {
-      const Option O = Opts.getOption(options::OPT_mwatchos_version_min_EQ);
-      WatchOSVersion = Args.MakeJoinedArg(nullptr, O, WatchOSTarget);
-      Args.append(WatchOSVersion);
-    }
-  }
-
-  DarwinPlatformKind Platform;
-  if (OSXVersion)
-    Platform = MacOS;
-  else if (iOSVersion)
-    Platform = IPhoneOS;
-  else if (TvOSVersion)
-    Platform = TvOS;
-  else if (WatchOSVersion)
-    Platform = WatchOS;
-  else
-    llvm_unreachable("Unable to infer Darwin variant");
-
-  // Set the tool chain target information.
-  unsigned Major, Minor, Micro;
-  bool HadExtra;
-  if (Platform == MacOS) {
-    assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) &&
-           "Unknown target platform!");
-    if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro,
-                                   HadExtra) ||
-        HadExtra || Major != 10 || Minor >= 100 || Micro >= 100)
-      getDriver().Diag(diag::err_drv_invalid_version_number)
-          << OSXVersion->getAsString(Args);
-  } else if (Platform == IPhoneOS) {
-    assert(iOSVersion && "Unknown target platform!");
-    if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
-                                   HadExtra) ||
-        HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
-      getDriver().Diag(diag::err_drv_invalid_version_number)
-          << iOSVersion->getAsString(Args);
-  } else if (Platform == TvOS) {
-    if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
-                                   Micro, HadExtra) || HadExtra ||
-        Major >= 100 || Minor >= 100 || Micro >= 100)
-      getDriver().Diag(diag::err_drv_invalid_version_number)
-          << TvOSVersion->getAsString(Args);
-  } else if (Platform == WatchOS) {
-    if (!Driver::GetReleaseVersion(WatchOSVersion->getValue(), Major, Minor,
-                                   Micro, HadExtra) || HadExtra ||
-        Major >= 10 || Minor >= 100 || Micro >= 100)
-      getDriver().Diag(diag::err_drv_invalid_version_number)
-          << WatchOSVersion->getAsString(Args);
-  } else
-    llvm_unreachable("unknown kind of Darwin platform");
-
-  // Recognize iOS targets with an x86 architecture as the iOS simulator.
-  if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
-                     getTriple().getArch() == llvm::Triple::x86_64))
-    Platform = IPhoneOSSimulator;
-  if (TvOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
-                      getTriple().getArch() == llvm::Triple::x86_64))
-    Platform = TvOSSimulator;
-  if (WatchOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
-                         getTriple().getArch() == llvm::Triple::x86_64))
-    Platform = WatchOSSimulator;
-
-  setTarget(Platform, Major, Minor, Micro);
-
-  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
-    StringRef SDK = getSDKName(A->getValue());
-    if (SDK.size() > 0) {
-      size_t StartVer = SDK.find_first_of("0123456789");
-      StringRef SDKName = SDK.slice(0, StartVer);
-      if (!SDKName.startswith(getPlatformFamily()))
-        getDriver().Diag(diag::warn_incompatible_sysroot)
-            << SDKName << getPlatformFamily();
-    }
-  }
-}
-
-void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
-                                      ArgStringList &CmdArgs) const {
-  CXXStdlibType Type = GetCXXStdlibType(Args);
-
-  switch (Type) {
-  case ToolChain::CST_Libcxx:
-    CmdArgs.push_back("-lc++");
-    break;
-
-  case ToolChain::CST_Libstdcxx:
-    // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
-    // it was previously found in the gcc lib dir. However, for all the Darwin
-    // platforms we care about it was -lstdc++.6, so we search for that
-    // explicitly if we can't see an obvious -lstdc++ candidate.
-
-    // Check in the sysroot first.
-    if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
-      SmallString<128> P(A->getValue());
-      llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
-
-      if (!getVFS().exists(P)) {
-        llvm::sys::path::remove_filename(P);
-        llvm::sys::path::append(P, "libstdc++.6.dylib");
-        if (getVFS().exists(P)) {
-          CmdArgs.push_back(Args.MakeArgString(P));
-          return;
-        }
-      }
-    }
-
-    // Otherwise, look in the root.
-    // FIXME: This should be removed someday when we don't have to care about
-    // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
-    if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
-        getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
-      CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
-      return;
-    }
-
-    // Otherwise, let the linker search.
-    CmdArgs.push_back("-lstdc++");
-    break;
-  }
-}
-
-void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
-                                   ArgStringList &CmdArgs) const {
-  // For Darwin platforms, use the compiler-rt-based support library
-  // instead of the gcc-provided one (which is also incidentally
-  // only present in the gcc lib dir, which makes it hard to find).
-
-  SmallString<128> P(getDriver().ResourceDir);
-  llvm::sys::path::append(P, "lib", "darwin");
-
-  // Use the newer cc_kext for iOS ARM after 6.0.
-  if (isTargetWatchOS()) {
-    llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
-  } else if (isTargetTvOS()) {
-    llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
-  } else if (isTargetIPhoneOS()) {
-    llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
-  } else {
-    llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
-  }
-
-  // For now, allow missing resource libraries to support developers who may
-  // not have compiler-rt checked out or integrated into their build.
-  if (getVFS().exists(P))
-    CmdArgs.push_back(Args.MakeArgString(P));
-}
-
-DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
-                                     StringRef BoundArch,
-                                     Action::OffloadKind) const {
-  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
-  const OptTable &Opts = getDriver().getOpts();
-
-  // FIXME: We really want to get out of the tool chain level argument
-  // translation business, as it makes the driver functionality much
-  // more opaque. For now, we follow gcc closely solely for the
-  // purpose of easily achieving feature parity & testability. Once we
-  // have something that works, we should reevaluate each translation
-  // and try to push it down into tool specific logic.
-
-  for (Arg *A : Args) {
-    if (A->getOption().matches(options::OPT_Xarch__)) {
-      // Skip this argument unless the architecture matches either the toolchain
-      // triple arch, or the arch being bound.
-      llvm::Triple::ArchType XarchArch =
-          tools::darwin::getArchTypeForMachOArchName(A->getValue(0));
-      if (!(XarchArch == getArch() ||
-            (!BoundArch.empty() &&
-             XarchArch ==
-                 tools::darwin::getArchTypeForMachOArchName(BoundArch))))
-        continue;
-
-      Arg *OriginalArg = A;
-      unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
-      unsigned Prev = Index;
-      std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
-
-      // If the argument parsing failed or more than one argument was
-      // consumed, the -Xarch_ argument's parameter tried to consume
-      // extra arguments. Emit an error and ignore.
-      //
-      // We also want to disallow any options which would alter the
-      // driver behavior; that isn't going to work in our model. We
-      // use isDriverOption() as an approximation, although things
-      // like -O4 are going to slip through.
-      if (!XarchArg || Index > Prev + 1) {
-        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
-            << A->getAsString(Args);
-        continue;
-      } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
-        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
-            << A->getAsString(Args);
-        continue;
-      }
-
-      XarchArg->setBaseArg(A);
-
-      A = XarchArg.release();
-      DAL->AddSynthesizedArg(A);
-
-      // Linker input arguments require custom handling. The problem is that we
-      // have already constructed the phase actions, so we can not treat them as
-      // "input arguments".
-      if (A->getOption().hasFlag(options::LinkerInput)) {
-        // Convert the argument into individual Zlinker_input_args.
-        for (const char *Value : A->getValues()) {
-          DAL->AddSeparateArg(
-              OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value);
-        }
-        continue;
-      }
-    }
-
-    // Sob. These is strictly gcc compatible for the time being. Apple
-    // gcc translates options twice, which means that self-expanding
-    // options add duplicates.
-    switch ((options::ID)A->getOption().getID()) {
-    default:
-      DAL->append(A);
-      break;
-
-    case options::OPT_mkernel:
-    case options::OPT_fapple_kext:
-      DAL->append(A);
-      DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
-      break;
-
-    case options::OPT_dependency_file:
-      DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
-      break;
-
-    case options::OPT_gfull:
-      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
-      DAL->AddFlagArg(
-          A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
-      break;
-
-    case options::OPT_gused:
-      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
-      DAL->AddFlagArg(
-          A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
-      break;
-
-    case options::OPT_shared:
-      DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
-      break;
-
-    case options::OPT_fconstant_cfstrings:
-      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
-      break;
-
-    case options::OPT_fno_constant_cfstrings:
-      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
-      break;
-
-    case options::OPT_Wnonportable_cfstrings:
-      DAL->AddFlagArg(A,
-                      Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
-      break;
-
-    case options::OPT_Wno_nonportable_cfstrings:
-      DAL->AddFlagArg(
-          A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
-      break;
-
-    case options::OPT_fpascal_strings:
-      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
-      break;
-
-    case options::OPT_fno_pascal_strings:
-      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
-      break;
-    }
-  }
-
-  if (getTriple().getArch() == llvm::Triple::x86 ||
-      getTriple().getArch() == llvm::Triple::x86_64)
-    if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
-      DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ),
-                        "core2");
-
-  // Add the arch options based on the particular spelling of -arch, to match
-  // how the driver driver works.
-  if (!BoundArch.empty()) {
-    StringRef Name = BoundArch;
-    const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
-    const Option MArch = Opts.getOption(options::OPT_march_EQ);
-
-    // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
-    // which defines the list of which architectures we accept.
-    if (Name == "ppc")
-      ;
-    else if (Name == "ppc601")
-      DAL->AddJoinedArg(nullptr, MCpu, "601");
-    else if (Name == "ppc603")
-      DAL->AddJoinedArg(nullptr, MCpu, "603");
-    else if (Name == "ppc604")
-      DAL->AddJoinedArg(nullptr, MCpu, "604");
-    else if (Name == "ppc604e")
-      DAL->AddJoinedArg(nullptr, MCpu, "604e");
-    else if (Name == "ppc750")
-      DAL->AddJoinedArg(nullptr, MCpu, "750");
-    else if (Name == "ppc7400")
-      DAL->AddJoinedArg(nullptr, MCpu, "7400");
-    else if (Name == "ppc7450")
-      DAL->AddJoinedArg(nullptr, MCpu, "7450");
-    else if (Name == "ppc970")
-      DAL->AddJoinedArg(nullptr, MCpu, "970");
-
-    else if (Name == "ppc64" || Name == "ppc64le")
-      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
-
-    else if (Name == "i386")
-      ;
-    else if (Name == "i486")
-      DAL->AddJoinedArg(nullptr, MArch, "i486");
-    else if (Name == "i586")
-      DAL->AddJoinedArg(nullptr, MArch, "i586");
-    else if (Name == "i686")
-      DAL->AddJoinedArg(nullptr, MArch, "i686");
-    else if (Name == "pentium")
-      DAL->AddJoinedArg(nullptr, MArch, "pentium");
-    else if (Name == "pentium2")
-      DAL->AddJoinedArg(nullptr, MArch, "pentium2");
-    else if (Name == "pentpro")
-      DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
-    else if (Name == "pentIIm3")
-      DAL->AddJoinedArg(nullptr, MArch, "pentium2");
-
-    else if (Name == "x86_64")
-      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
-    else if (Name == "x86_64h") {
-      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
-      DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
-    }
-
-    else if (Name == "arm")
-      DAL->AddJoinedArg(nullptr, MArch, "armv4t");
-    else if (Name == "armv4t")
-      DAL->AddJoinedArg(nullptr, MArch, "armv4t");
-    else if (Name == "armv5")
-      DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
-    else if (Name == "xscale")
-      DAL->AddJoinedArg(nullptr, MArch, "xscale");
-    else if (Name == "armv6")
-      DAL->AddJoinedArg(nullptr, MArch, "armv6k");
-    else if (Name == "armv6m")
-      DAL->AddJoinedArg(nullptr, MArch, "armv6m");
-    else if (Name == "armv7")
-      DAL->AddJoinedArg(nullptr, MArch, "armv7a");
-    else if (Name == "armv7em")
-      DAL->AddJoinedArg(nullptr, MArch, "armv7em");
-    else if (Name == "armv7k")
-      DAL->AddJoinedArg(nullptr, MArch, "armv7k");
-    else if (Name == "armv7m")
-      DAL->AddJoinedArg(nullptr, MArch, "armv7m");
-    else if (Name == "armv7s")
-      DAL->AddJoinedArg(nullptr, MArch, "armv7s");
-  }
-
-  return DAL;
-}
-
-void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
-                                  ArgStringList &CmdArgs) const {
-  // Embedded targets are simple at the moment, not supporting sanitizers and
-  // with different libraries for each member of the product { static, PIC } x
-  // { hard-float, soft-float }
-  llvm::SmallString<32> CompilerRT = StringRef("libclang_rt.");
-  CompilerRT +=
-      (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)
-          ? "hard"
-          : "soft";
-  CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a";
-
-  AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true);
-}
-
-DerivedArgList *
-Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
-                      Action::OffloadKind DeviceOffloadKind) const {
-  // First get the generic Apple args, before moving onto Darwin-specific ones.
-  DerivedArgList *DAL =
-      MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind);
-  const OptTable &Opts = getDriver().getOpts();
-
-  // If no architecture is bound, none of the translations here are relevant.
-  if (BoundArch.empty())
-    return DAL;
-
-  // Add an explicit version min argument for the deployment target. We do this
-  // after argument translation because -Xarch_ arguments may add a version min
-  // argument.
-  AddDeploymentTarget(*DAL);
-
-  // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
-  // FIXME: It would be far better to avoid inserting those -static arguments,
-  // but we can't check the deployment target in the translation code until
-  // it is set here.
-  if (isTargetWatchOSBased() ||
-      (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
-    for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
-      Arg *A = *it;
-      ++it;
-      if (A->getOption().getID() != options::OPT_mkernel &&
-          A->getOption().getID() != options::OPT_fapple_kext)
-        continue;
-      assert(it != ie && "unexpected argument translation");
-      A = *it;
-      assert(A->getOption().getID() == options::OPT_static &&
-             "missing expected -static argument");
-      it = DAL->getArgs().erase(it);
-    }
-  }
-
-  if (!Args.getLastArg(options::OPT_stdlib_EQ) &&
-      GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
-    DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ),
-                      "libc++");
-
-  // Validate the C++ standard library choice.
-  CXXStdlibType Type = GetCXXStdlibType(*DAL);
-  if (Type == ToolChain::CST_Libcxx) {
-    // Check whether the target provides libc++.
-    StringRef where;
-
-    // Complain about targeting iOS < 5.0 in any way.
-    if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0))
-      where = "iOS 5.0";
-
-    if (where != StringRef()) {
-      getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where;
-    }
-  }
-
-  auto Arch = tools::darwin::getArchTypeForMachOArchName(BoundArch);
-  if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) {
-    if (Args.hasFlag(options::OPT_fomit_frame_pointer,
-                     options::OPT_fno_omit_frame_pointer, false))
-      getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
-          << "-fomit-frame-pointer" << BoundArch;
-    if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
-                     options::OPT_mno_omit_leaf_frame_pointer, false))
-      getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
-          << "-momit-leaf-frame-pointer" << BoundArch;
-  }
-
-  return DAL;
-}
-
-bool MachO::IsUnwindTablesDefault() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-bool MachO::UseDwarfDebugFlags() const {
-  if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
-    return S[0] != '\0';
-  return false;
-}
-
-bool Darwin::UseSjLjExceptions(const ArgList &Args) const {
-  // Darwin uses SjLj exceptions on ARM.
-  if (getTriple().getArch() != llvm::Triple::arm &&
-      getTriple().getArch() != llvm::Triple::thumb)
-    return false;
-
-  // Only watchOS uses the new DWARF/Compact unwinding method.
-  llvm::Triple Triple(ComputeLLVMTriple(Args));
-  return !Triple.isWatchABI();
-}
-
-bool Darwin::SupportsEmbeddedBitcode() const {
-  assert(TargetInitialized && "Target not initialized!");
-  if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
-    return false;
-  return true;
-}
-
-bool MachO::isPICDefault() const { return true; }
-
-bool MachO::isPIEDefault() const { return false; }
-
-bool MachO::isPICDefaultForced() const {
-  return (getArch() == llvm::Triple::x86_64 ||
-          getArch() == llvm::Triple::aarch64);
-}
-
-bool MachO::SupportsProfiling() const {
-  // Profiling instrumentation is only supported on x86.
-  return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
-}
-
-void Darwin::addMinVersionArgs(const ArgList &Args,
-                               ArgStringList &CmdArgs) const {
-  VersionTuple TargetVersion = getTargetVersion();
-
-  if (isTargetWatchOS())
-    CmdArgs.push_back("-watchos_version_min");
-  else if (isTargetWatchOSSimulator())
-    CmdArgs.push_back("-watchos_simulator_version_min");
-  else if (isTargetTvOS())
-    CmdArgs.push_back("-tvos_version_min");
-  else if (isTargetTvOSSimulator())
-    CmdArgs.push_back("-tvos_simulator_version_min");
-  else if (isTargetIOSSimulator())
-    CmdArgs.push_back("-ios_simulator_version_min");
-  else if (isTargetIOSBased())
-    CmdArgs.push_back("-iphoneos_version_min");
-  else {
-    assert(isTargetMacOS() && "unexpected target");
-    CmdArgs.push_back("-macosx_version_min");
-  }
-
-  CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
-}
-
-void Darwin::addStartObjectFileArgs(const ArgList &Args,
-                                    ArgStringList &CmdArgs) const {
-  // Derived from startfile spec.
-  if (Args.hasArg(options::OPT_dynamiclib)) {
-    // Derived from darwin_dylib1 spec.
-    if (isTargetWatchOSBased()) {
-      ; // watchOS does not need dylib1.o.
-    } else if (isTargetIOSSimulator()) {
-      ; // iOS simulator does not need dylib1.o.
-    } else if (isTargetIPhoneOS()) {
-      if (isIPhoneOSVersionLT(3, 1))
-        CmdArgs.push_back("-ldylib1.o");
-    } else {
-      if (isMacosxVersionLT(10, 5))
-        CmdArgs.push_back("-ldylib1.o");
-      else if (isMacosxVersionLT(10, 6))
-        CmdArgs.push_back("-ldylib1.10.5.o");
-    }
-  } else {
-    if (Args.hasArg(options::OPT_bundle)) {
-      if (!Args.hasArg(options::OPT_static)) {
-        // Derived from darwin_bundle1 spec.
-        if (isTargetWatchOSBased()) {
-          ; // watchOS does not need bundle1.o.
-        } else if (isTargetIOSSimulator()) {
-          ; // iOS simulator does not need bundle1.o.
-        } else if (isTargetIPhoneOS()) {
-          if (isIPhoneOSVersionLT(3, 1))
-            CmdArgs.push_back("-lbundle1.o");
-        } else {
-          if (isMacosxVersionLT(10, 6))
-            CmdArgs.push_back("-lbundle1.o");
-        }
-      }
-    } else {
-      if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) {
-        if (Args.hasArg(options::OPT_static) ||
-            Args.hasArg(options::OPT_object) ||
-            Args.hasArg(options::OPT_preload)) {
-          CmdArgs.push_back("-lgcrt0.o");
-        } else {
-          CmdArgs.push_back("-lgcrt1.o");
-
-          // darwin_crt2 spec is empty.
-        }
-        // By default on OS X 10.8 and later, we don't link with a crt1.o
-        // file and the linker knows to use _main as the entry point.  But,
-        // when compiling with -pg, we need to link with the gcrt1.o file,
-        // so pass the -no_new_main option to tell the linker to use the
-        // "start" symbol as the entry point.
-        if (isTargetMacOS() && !isMacosxVersionLT(10, 8))
-          CmdArgs.push_back("-no_new_main");
-      } else {
-        if (Args.hasArg(options::OPT_static) ||
-            Args.hasArg(options::OPT_object) ||
-            Args.hasArg(options::OPT_preload)) {
-          CmdArgs.push_back("-lcrt0.o");
-        } else {
-          // Derived from darwin_crt1 spec.
-          if (isTargetWatchOSBased()) {
-            ; // watchOS does not need crt1.o.
-          } else if (isTargetIOSSimulator()) {
-            ; // iOS simulator does not need crt1.o.
-          } else if (isTargetIPhoneOS()) {
-            if (getArch() == llvm::Triple::aarch64)
-              ; // iOS does not need any crt1 files for arm64
-            else if (isIPhoneOSVersionLT(3, 1))
-              CmdArgs.push_back("-lcrt1.o");
-            else if (isIPhoneOSVersionLT(6, 0))
-              CmdArgs.push_back("-lcrt1.3.1.o");
-          } else {
-            if (isMacosxVersionLT(10, 5))
-              CmdArgs.push_back("-lcrt1.o");
-            else if (isMacosxVersionLT(10, 6))
-              CmdArgs.push_back("-lcrt1.10.5.o");
-            else if (isMacosxVersionLT(10, 8))
-              CmdArgs.push_back("-lcrt1.10.6.o");
-
-            // darwin_crt2 spec is empty.
-          }
-        }
-      }
-    }
-  }
-
-  if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) &&
-      !isTargetWatchOS() &&
-      isMacosxVersionLT(10, 5)) {
-    const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
-    CmdArgs.push_back(Str);
-  }
-}
-
-bool Darwin::SupportsObjCGC() const { return isTargetMacOS(); }
-
-void Darwin::CheckObjCARC() const {
-  if (isTargetIOSBased() || isTargetWatchOSBased() ||
-      (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
-    return;
-  getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
-}
-
-SanitizerMask Darwin::getSupportedSanitizers() const {
-  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
-  SanitizerMask Res = ToolChain::getSupportedSanitizers();
-  Res |= SanitizerKind::Address;
-  if (isTargetMacOS()) {
-    if (!isMacosxVersionLT(10, 9))
-      Res |= SanitizerKind::Vptr;
-    Res |= SanitizerKind::SafeStack;
-    if (IsX86_64)
-      Res |= SanitizerKind::Thread;
-  } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) {
-    if (IsX86_64)
-      Res |= SanitizerKind::Thread;
-  }
-  return Res;
-}
-
-void Darwin::printVerboseInfo(raw_ostream &OS) const {
-  CudaInstallation.print(OS);
-}
-
-/// Generic_GCC - A tool chain using the 'gcc' command to perform
-/// all subcommands; this relies on gcc translating the majority of
-/// command line options.
-
-/// \brief Parse a GCCVersion object out of a string of text.
-///
-/// This is the primary means of forming GCCVersion objects.
-/*static*/
-Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
-  const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
-  std::pair<StringRef, StringRef> First = VersionText.split('.');
-  std::pair<StringRef, StringRef> Second = First.second.split('.');
-
-  GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
-  if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 0)
-    return BadVersion;
-  GoodVersion.MajorStr = First.first.str();
-  if (First.second.empty())
-    return GoodVersion;
-  if (Second.first.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0)
-    return BadVersion;
-  GoodVersion.MinorStr = Second.first.str();
-
-  // First look for a number prefix and parse that if present. Otherwise just
-  // stash the entire patch string in the suffix, and leave the number
-  // unspecified. This covers versions strings such as:
-  //   5        (handled above)
-  //   4.4
-  //   4.4.0
-  //   4.4.x
-  //   4.4.2-rc4
-  //   4.4.x-patched
-  // And retains any patch number it finds.
-  StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str();
-  if (!PatchText.empty()) {
-    if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
-      // Try to parse the number and any suffix.
-      if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
-          GoodVersion.Patch < 0)
-        return BadVersion;
-      GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
-    }
-  }
-
-  return GoodVersion;
-}
-
-/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
-bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
-                                          int RHSPatch,
-                                          StringRef RHSPatchSuffix) const {
-  if (Major != RHSMajor)
-    return Major < RHSMajor;
-  if (Minor != RHSMinor)
-    return Minor < RHSMinor;
-  if (Patch != RHSPatch) {
-    // Note that versions without a specified patch sort higher than those with
-    // a patch.
-    if (RHSPatch == -1)
-      return true;
-    if (Patch == -1)
-      return false;
-
-    // Otherwise just sort on the patch itself.
-    return Patch < RHSPatch;
-  }
-  if (PatchSuffix != RHSPatchSuffix) {
-    // Sort empty suffixes higher.
-    if (RHSPatchSuffix.empty())
-      return true;
-    if (PatchSuffix.empty())
-      return false;
-
-    // Provide a lexicographic sort to make this a total ordering.
-    return PatchSuffix < RHSPatchSuffix;
-  }
-
-  // The versions are equal.
-  return false;
-}
-
-static llvm::StringRef getGCCToolchainDir(const ArgList &Args) {
-  const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
-  if (A)
-    return A->getValue();
-  return GCC_INSTALL_PREFIX;
-}
-
-/// \brief Initialize a GCCInstallationDetector from the driver.
-///
-/// This performs all of the autodetection and sets up the various paths.
-/// Once constructed, a GCCInstallationDetector is essentially immutable.
-///
-/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
-/// should instead pull the target out of the driver. This is currently
-/// necessary because the driver doesn't store the final version of the target
-/// triple.
-void Generic_GCC::GCCInstallationDetector::init(
-    const llvm::Triple &TargetTriple, const ArgList &Args,
-    ArrayRef<std::string> ExtraTripleAliases) {
-  llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()
-                                         ? TargetTriple.get64BitArchVariant()
-                                         : TargetTriple.get32BitArchVariant();
-  // The library directories which may contain GCC installations.
-  SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
-  // The compatible GCC triples for this particular architecture.
-  SmallVector<StringRef, 16> CandidateTripleAliases;
-  SmallVector<StringRef, 16> CandidateBiarchTripleAliases;
-  CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
-                           CandidateTripleAliases, CandidateBiarchLibDirs,
-                           CandidateBiarchTripleAliases);
-
-  // Compute the set of prefixes for our search.
-  SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
-                                       D.PrefixDirs.end());
-
-  StringRef GCCToolchainDir = getGCCToolchainDir(Args);
-  if (GCCToolchainDir != "") {
-    if (GCCToolchainDir.back() == '/')
-      GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
-
-    Prefixes.push_back(GCCToolchainDir);
-  } else {
-    // If we have a SysRoot, try that first.
-    if (!D.SysRoot.empty()) {
-      Prefixes.push_back(D.SysRoot);
-      Prefixes.push_back(D.SysRoot + "/usr");
-    }
-
-    // Then look for gcc installed alongside clang.
-    Prefixes.push_back(D.InstalledDir + "/..");
-
-    // Then look for distribution supplied gcc installations.
-    if (D.SysRoot.empty()) {
-      // Look for RHEL devtoolsets.
-      Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
-      Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");
-      Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
-      Prefixes.push_back("/opt/rh/devtoolset-1.1/root/usr");
-      Prefixes.push_back("/opt/rh/devtoolset-1.0/root/usr");
-      // And finally in /usr.
-      Prefixes.push_back("/usr");
-    }
-  }
-
-  // Try to respect gcc-config on Gentoo. However, do that only
-  // if --gcc-toolchain is not provided or equal to the Gentoo install
-  // in /usr. This avoids accidentally enforcing the system GCC version
-  // when using a custom toolchain.
-  if (GCCToolchainDir == "" || GCCToolchainDir == D.SysRoot + "/usr") {
-    for (StringRef CandidateTriple : CandidateTripleAliases) {
-      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
-          D.getVFS().getBufferForFile(D.SysRoot + "/etc/env.d/gcc/config-" +
-                                      CandidateTriple.str());
-      if (File) {
-        SmallVector<StringRef, 2> Lines;
-        File.get()->getBuffer().split(Lines, "\n");
-        for (StringRef Line : Lines) {
-          // CURRENT=triple-version
-          if (Line.consume_front("CURRENT=")) {
-            const std::pair<StringRef, StringRef> ActiveVersion =
-              Line.rsplit('-');
-            // Note: Strictly speaking, we should be reading
-            // /etc/env.d/gcc/${CURRENT} now. However, the file doesn't
-            // contain anything new or especially useful to us.
-            const std::string GentooPath = D.SysRoot + "/usr/lib/gcc/" +
-                                           ActiveVersion.first.str() + "/" +
-                                           ActiveVersion.second.str();
-            if (D.getVFS().exists(GentooPath + "/crtbegin.o")) {
-              Version = GCCVersion::Parse(ActiveVersion.second);
-              GCCInstallPath = GentooPath;
-              GCCParentLibPath = GentooPath + "/../../..";
-              GCCTriple.setTriple(ActiveVersion.first);
-              IsValid = true;
-              return;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  // Loop over the various components which exist and select the best GCC
-  // installation available. GCC installs are ranked by version number.
-  Version = GCCVersion::Parse("0.0.0");
-  for (const std::string &Prefix : Prefixes) {
-    if (!D.getVFS().exists(Prefix))
-      continue;
-    for (StringRef Suffix : CandidateLibDirs) {
-      const std::string LibDir = Prefix + Suffix.str();
-      if (!D.getVFS().exists(LibDir))
-        continue;
-      for (StringRef Candidate : ExtraTripleAliases) // Try these first.
-        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
-      for (StringRef Candidate : CandidateTripleAliases)
-        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
-    }
-    for (StringRef Suffix : CandidateBiarchLibDirs) {
-      const std::string LibDir = Prefix + Suffix.str();
-      if (!D.getVFS().exists(LibDir))
-        continue;
-      for (StringRef Candidate : CandidateBiarchTripleAliases)
-        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate,
-                               /*NeedsBiarchSuffix=*/ true);
-    }
-  }
-}
-
-void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
-  for (const auto &InstallPath : CandidateGCCInstallPaths)
-    OS << "Found candidate GCC installation: " << InstallPath << "\n";
-
-  if (!GCCInstallPath.empty())
-    OS << "Selected GCC installation: " << GCCInstallPath << "\n";
-
-  for (const auto &Multilib : Multilibs)
-    OS << "Candidate multilib: " << Multilib << "\n";
-
-  if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())
-    OS << "Selected multilib: " << SelectedMultilib << "\n";
-}
-
-bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
-  if (BiarchSibling.hasValue()) {
-    M = BiarchSibling.getValue();
-    return true;
-  }
-  return false;
-}
-
-/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
-    const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
-    SmallVectorImpl<StringRef> &LibDirs,
-    SmallVectorImpl<StringRef> &TripleAliases,
-    SmallVectorImpl<StringRef> &BiarchLibDirs,
-    SmallVectorImpl<StringRef> &BiarchTripleAliases) {
-  // Declare a bunch of static data sets that we'll select between below. These
-  // are specifically designed to always refer to string literals to avoid any
-  // lifetime or initialization issues.
-  static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};
-  static const char *const AArch64Triples[] = {
-      "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-linux-android",
-      "aarch64-redhat-linux"};
-  static const char *const AArch64beLibDirs[] = {"/lib"};
-  static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu",
-                                                 "aarch64_be-linux-gnu"};
-
-  static const char *const ARMLibDirs[] = {"/lib"};
-  static const char *const ARMTriples[] = {"arm-linux-gnueabi",
-                                           "arm-linux-androideabi"};
-  static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",
-                                             "armv7hl-redhat-linux-gnueabi"};
-  static const char *const ARMebLibDirs[] = {"/lib"};
-  static const char *const ARMebTriples[] = {"armeb-linux-gnueabi",
-                                             "armeb-linux-androideabi"};
-  static const char *const ARMebHFTriples[] = {
-      "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};
-
-  static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};
-  static const char *const X86_64Triples[] = {
-      "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-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",       "i386-redhat-linux6E",   "i686-redhat-linux",
-      "i586-redhat-linux",    "i386-redhat-linux",     "i586-suse-linux",
-      "i486-slackware-linux", "i686-montavista-linux", "i686-linux-android",
-      "i586-linux-gnu"};
-
-  static const char *const MIPSLibDirs[] = {"/lib"};
-  static const char *const MIPSTriples[] = {"mips-linux-gnu", "mips-mti-linux",
-                                            "mips-mti-linux-gnu",
-                                            "mips-img-linux-gnu"};
-  static const char *const MIPSELLibDirs[] = {"/lib"};
-  static const char *const MIPSELTriples[] = {"mipsel-linux-gnu",
-                                              "mips-img-linux-gnu"};
-
-  static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};
-  static const char *const MIPS64Triples[] = {
-      "mips64-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", "mips-img-linux-gnu",
-      "mips64el-linux-gnuabi64"};
-
-  static const char *const MIPSELAndroidLibDirs[] = {"/lib", "/libr2",
-                                                     "/libr6"};
-  static const char *const MIPSELAndroidTriples[] = {"mipsel-linux-android"};
-  static const char *const MIPS64ELAndroidLibDirs[] = {"/lib64", "/lib",
-                                                       "/libr2", "/libr6"};
-  static const char *const MIPS64ELAndroidTriples[] = {
-      "mips64el-linux-android"};
-
-  static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
-  static const char *const PPCTriples[] = {
-      "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
-      "powerpc-suse-linux", "powerpc-montavista-linuxspe"};
-  static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
-  static const char *const PPC64Triples[] = {
-      "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
-      "powerpc64-suse-linux", "ppc64-redhat-linux"};
-  static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};
-  static const char *const PPC64LETriples[] = {
-      "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
-      "powerpc64le-suse-linux", "ppc64le-redhat-linux"};
-
-  static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
-  static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
-                                               "sparcv8-linux-gnu"};
-  static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};
-  static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",
-                                               "sparcv9-linux-gnu"};
-
-  static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};
-  static const char *const SystemZTriples[] = {
-      "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
-      "s390x-suse-linux", "s390x-redhat-linux"};
-
-  // Solaris.
-  static const char *const SolarisSPARCLibDirs[] = {"/gcc"};
-  static const char *const SolarisSPARCTriples[] = {"sparc-sun-solaris2.11",
-                                                    "i386-pc-solaris2.11"};
-
-  using std::begin;
-  using std::end;
-
-  if (TargetTriple.getOS() == llvm::Triple::Solaris) {
-    LibDirs.append(begin(SolarisSPARCLibDirs), end(SolarisSPARCLibDirs));
-    TripleAliases.append(begin(SolarisSPARCTriples), end(SolarisSPARCTriples));
-    return;
-  }
-
-  switch (TargetTriple.getArch()) {
-  case llvm::Triple::aarch64:
-    LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
-    TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
-    BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
-    BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
-    break;
-  case llvm::Triple::aarch64_be:
-    LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
-    TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
-    BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
-    BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
-    break;
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-    LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));
-    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
-      TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));
-    } else {
-      TripleAliases.append(begin(ARMTriples), end(ARMTriples));
-    }
-    break;
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumbeb:
-    LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));
-    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
-      TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));
-    } else {
-      TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));
-    }
-    break;
-  case llvm::Triple::x86_64:
-    LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
-    TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
-    // 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(begin(X32LibDirs), end(X32LibDirs));
-      BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
-    } else {
-      BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));
-      BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));
-    }
-    break;
-  case llvm::Triple::x86:
-    LibDirs.append(begin(X86LibDirs), end(X86LibDirs));
-    // MCU toolchain is 32 bit only and its triple alias is TargetTriple
-    // itself, which will be appended below.
-    if (!TargetTriple.isOSIAMCU()) {
-      TripleAliases.append(begin(X86Triples), end(X86Triples));
-      BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
-      BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
-    }
-    break;
-  case llvm::Triple::mips:
-    LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
-    TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
-    BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
-    BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
-    break;
-  case llvm::Triple::mipsel:
-    if (TargetTriple.isAndroid()) {
-      LibDirs.append(begin(MIPSELAndroidLibDirs), end(MIPSELAndroidLibDirs));
-      TripleAliases.append(begin(MIPSELAndroidTriples),
-                           end(MIPSELAndroidTriples));
-      BiarchLibDirs.append(begin(MIPS64ELAndroidLibDirs),
-                           end(MIPS64ELAndroidLibDirs));
-      BiarchTripleAliases.append(begin(MIPS64ELAndroidTriples),
-                                 end(MIPS64ELAndroidTriples));
-
-    } else {
-      LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
-      TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
-      TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
-      BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
-      BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
-    }
-    break;
-  case llvm::Triple::mips64:
-    LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
-    TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
-    BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
-    BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
-    break;
-  case llvm::Triple::mips64el:
-    if (TargetTriple.isAndroid()) {
-      LibDirs.append(begin(MIPS64ELAndroidLibDirs),
-                     end(MIPS64ELAndroidLibDirs));
-      TripleAliases.append(begin(MIPS64ELAndroidTriples),
-                           end(MIPS64ELAndroidTriples));
-      BiarchLibDirs.append(begin(MIPSELAndroidLibDirs),
-                           end(MIPSELAndroidLibDirs));
-      BiarchTripleAliases.append(begin(MIPSELAndroidTriples),
-                                 end(MIPSELAndroidTriples));
-
-    } else {
-      LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
-      TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
-      BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
-      BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
-      BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
-    }
-    break;
-  case llvm::Triple::ppc:
-    LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
-    TripleAliases.append(begin(PPCTriples), end(PPCTriples));
-    BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
-    BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
-    break;
-  case llvm::Triple::ppc64:
-    LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
-    TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
-    BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
-    BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));
-    break;
-  case llvm::Triple::ppc64le:
-    LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
-    TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
-    break;
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel:
-    LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
-    TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
-    BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
-    BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
-    break;
-  case llvm::Triple::sparcv9:
-    LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
-    TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
-    BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
-    BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
-    break;
-  case llvm::Triple::systemz:
-    LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));
-    TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));
-    break;
-  default:
-    // By default, just rely on the standard lib directories and the original
-    // triple.
-    break;
-  }
-
-  // Always append the drivers target triple to the end, in case it doesn't
-  // match any of our aliases.
-  TripleAliases.push_back(TargetTriple.str());
-
-  // Also include the multiarch variant if it's different.
-  if (TargetTriple.str() != BiarchTriple.str())
-    BiarchTripleAliases.push_back(BiarchTriple.str());
-}
-
-// Parses the contents of version.txt in an CUDA installation.  It should
-// contain one line of the from e.g. "CUDA Version 7.5.2".
-static CudaVersion ParseCudaVersionFile(llvm::StringRef V) {
-  if (!V.startswith("CUDA Version "))
-    return CudaVersion::UNKNOWN;
-  V = V.substr(strlen("CUDA Version "));
-  int Major = -1, Minor = -1;
-  auto First = V.split('.');
-  auto Second = First.second.split('.');
-  if (First.first.getAsInteger(10, Major) ||
-      Second.first.getAsInteger(10, Minor))
-    return CudaVersion::UNKNOWN;
-
-  if (Major == 7 && Minor == 0) {
-    // This doesn't appear to ever happen -- version.txt doesn't exist in the
-    // CUDA 7 installs I've seen.  But no harm in checking.
-    return CudaVersion::CUDA_70;
-  }
-  if (Major == 7 && Minor == 5)
-    return CudaVersion::CUDA_75;
-  if (Major == 8 && Minor == 0)
-    return CudaVersion::CUDA_80;
-  return CudaVersion::UNKNOWN;
-}
-
-CudaInstallationDetector::CudaInstallationDetector(
-    const Driver &D, const llvm::Triple &TargetTriple,
-    const llvm::opt::ArgList &Args)
-    : D(D) {
-  SmallVector<std::string, 4> CudaPathCandidates;
-
-  if (Args.hasArg(options::OPT_cuda_path_EQ))
-    CudaPathCandidates.push_back(
-        Args.getLastArgValue(options::OPT_cuda_path_EQ));
-  else {
-    CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda");
-    CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-8.0");
-    CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.5");
-    CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.0");
-  }
-
-  for (const auto &CudaPath : CudaPathCandidates) {
-    if (CudaPath.empty() || !D.getVFS().exists(CudaPath))
-      continue;
-
-    InstallPath = CudaPath;
-    BinPath = CudaPath + "/bin";
-    IncludePath = InstallPath + "/include";
-    LibDevicePath = InstallPath + "/nvvm/libdevice";
-
-    auto &FS = D.getVFS();
-    if (!(FS.exists(IncludePath) && FS.exists(BinPath) &&
-          FS.exists(LibDevicePath)))
-      continue;
-
-    // On Linux, we have both lib and lib64 directories, and we need to choose
-    // based on our triple.  On MacOS, we have only a lib directory.
-    //
-    // It's sufficient for our purposes to be flexible: If both lib and lib64
-    // exist, we choose whichever one matches our triple.  Otherwise, if only
-    // lib exists, we use it.
-    if (TargetTriple.isArch64Bit() && FS.exists(InstallPath + "/lib64"))
-      LibPath = InstallPath + "/lib64";
-    else if (FS.exists(InstallPath + "/lib"))
-      LibPath = InstallPath + "/lib";
-    else
-      continue;
-
-    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile =
-        FS.getBufferForFile(InstallPath + "/version.txt");
-    if (!VersionFile) {
-      // CUDA 7.0 doesn't have a version.txt, so guess that's our version if
-      // version.txt isn't present.
-      Version = CudaVersion::CUDA_70;
-    } else {
-      Version = ParseCudaVersionFile((*VersionFile)->getBuffer());
-    }
-
-    std::error_code EC;
-    for (llvm::sys::fs::directory_iterator LI(LibDevicePath, EC), LE;
-         !EC && LI != LE; LI = LI.increment(EC)) {
-      StringRef FilePath = LI->path();
-      StringRef FileName = llvm::sys::path::filename(FilePath);
-      // Process all bitcode filenames that look like libdevice.compute_XX.YY.bc
-      const StringRef LibDeviceName = "libdevice.";
-      if (!(FileName.startswith(LibDeviceName) && FileName.endswith(".bc")))
-        continue;
-      StringRef GpuArch = FileName.slice(
-          LibDeviceName.size(), FileName.find('.', LibDeviceName.size()));
-      LibDeviceMap[GpuArch] = FilePath.str();
-      // Insert map entries for specifc devices with this compute
-      // capability. NVCC's choice of the libdevice library version is
-      // rather peculiar and depends on the CUDA version.
-      if (GpuArch == "compute_20") {
-        LibDeviceMap["sm_20"] = FilePath;
-        LibDeviceMap["sm_21"] = FilePath;
-        LibDeviceMap["sm_32"] = FilePath;
-      } else if (GpuArch == "compute_30") {
-        LibDeviceMap["sm_30"] = FilePath;
-        if (Version < CudaVersion::CUDA_80) {
-          LibDeviceMap["sm_50"] = FilePath;
-          LibDeviceMap["sm_52"] = FilePath;
-          LibDeviceMap["sm_53"] = FilePath;
-        }
-        LibDeviceMap["sm_60"] = FilePath;
-        LibDeviceMap["sm_61"] = FilePath;
-        LibDeviceMap["sm_62"] = FilePath;
-      } else if (GpuArch == "compute_35") {
-        LibDeviceMap["sm_35"] = FilePath;
-        LibDeviceMap["sm_37"] = FilePath;
-      } else if (GpuArch == "compute_50") {
-        if (Version >= CudaVersion::CUDA_80) {
-          LibDeviceMap["sm_50"] = FilePath;
-          LibDeviceMap["sm_52"] = FilePath;
-          LibDeviceMap["sm_53"] = FilePath;
-        }
-      }
-    }
-
-    IsValid = true;
-    break;
-  }
-}
-
-void CudaInstallationDetector::AddCudaIncludeArgs(
-    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
-  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
-    // Add cuda_wrappers/* to our system include path.  This lets us wrap
-    // standard library headers.
-    SmallString<128> P(D.ResourceDir);
-    llvm::sys::path::append(P, "include");
-    llvm::sys::path::append(P, "cuda_wrappers");
-    CC1Args.push_back("-internal-isystem");
-    CC1Args.push_back(DriverArgs.MakeArgString(P));
-  }
-
-  if (DriverArgs.hasArg(options::OPT_nocudainc))
-    return;
-
-  if (!isValid()) {
-    D.Diag(diag::err_drv_no_cuda_installation);
-    return;
-  }
-
-  CC1Args.push_back("-internal-isystem");
-  CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath()));
-  CC1Args.push_back("-include");
-  CC1Args.push_back("__clang_cuda_runtime_wrapper.h");
-}
-
-void CudaInstallationDetector::CheckCudaVersionSupportsArch(
-    CudaArch Arch) const {
-  if (Arch == CudaArch::UNKNOWN || Version == CudaVersion::UNKNOWN ||
-      ArchsWithVersionTooLowErrors.count(Arch) > 0)
-    return;
-
-  auto RequiredVersion = MinVersionForCudaArch(Arch);
-  if (Version < RequiredVersion) {
-    ArchsWithVersionTooLowErrors.insert(Arch);
-    D.Diag(diag::err_drv_cuda_version_too_low)
-        << InstallPath << CudaArchToString(Arch) << CudaVersionToString(Version)
-        << CudaVersionToString(RequiredVersion);
-  }
-}
-
-void CudaInstallationDetector::print(raw_ostream &OS) const {
-  if (isValid())
-    OS << "Found CUDA installation: " << InstallPath << ", version "
-       << CudaVersionToString(Version) << "\n";
-}
-
-namespace {
-// Filter to remove Multilibs that don't exist as a suffix to Path
-class FilterNonExistent {
-  StringRef Base, File;
-  vfs::FileSystem &VFS;
-
-public:
-  FilterNonExistent(StringRef Base, StringRef File, vfs::FileSystem &VFS)
-      : Base(Base), File(File), VFS(VFS) {}
-  bool operator()(const Multilib &M) {
-    return !VFS.exists(Base + M.gccSuffix() + File);
-  }
-};
-} // end anonymous namespace
-
-static void addMultilibFlag(bool Enabled, const char *const Flag,
-                            std::vector<std::string> &Flags) {
-  if (Enabled)
-    Flags.push_back(std::string("+") + Flag);
-  else
-    Flags.push_back(std::string("-") + Flag);
-}
-
-static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
-  return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
-}
-
-static bool isMipsArch(llvm::Triple::ArchType Arch) {
-  return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel ||
-         Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
-}
-
-static bool isMips32(llvm::Triple::ArchType Arch) {
-  return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel;
-}
-
-static bool isMips64(llvm::Triple::ArchType Arch) {
-  return Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
-}
-
-static bool isMipsEL(llvm::Triple::ArchType Arch) {
-  return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;
-}
-
-static bool isMips16(const ArgList &Args) {
-  Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
-  return A && A->getOption().matches(options::OPT_mips16);
-}
-
-static bool isMicroMips(const ArgList &Args) {
-  Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
-  return A && A->getOption().matches(options::OPT_mmicromips);
-}
-
-namespace {
-struct DetectedMultilibs {
-  /// The set of multilibs that the detected installation supports.
-  MultilibSet Multilibs;
-
-  /// The primary multilib appropriate for the given flags.
-  Multilib SelectedMultilib;
-
-  /// On Biarch systems, this corresponds to the default multilib when
-  /// targeting the non-default multilib. Otherwise, it is empty.
-  llvm::Optional<Multilib> BiarchSibling;
-};
-} // end anonymous namespace
-
-static Multilib makeMultilib(StringRef commonSuffix) {
-  return Multilib(commonSuffix, commonSuffix, commonSuffix);
-}
-
-static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
-                                FilterNonExistent &NonExistent,
-                                DetectedMultilibs &Result) {
-  // Check for Code Sourcery toolchain multilibs
-  MultilibSet CSMipsMultilibs;
-  {
-    auto MArchMips16 = makeMultilib("/mips16").flag("+m32").flag("+mips16");
-
-    auto MArchMicroMips =
-        makeMultilib("/micromips").flag("+m32").flag("+mmicromips");
-
-    auto MArchDefault = makeMultilib("").flag("-mips16").flag("-mmicromips");
-
-    auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
-
-    auto SoftFloat = makeMultilib("/soft-float").flag("+msoft-float");
-
-    auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
-
-    auto DefaultFloat =
-        makeMultilib("").flag("-msoft-float").flag("-mnan=2008");
-
-    auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
-
-    auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
-
-    // Note that this one's osSuffix is ""
-    auto MAbi64 = makeMultilib("")
-                      .gccSuffix("/64")
-                      .includeSuffix("/64")
-                      .flag("+mabi=n64")
-                      .flag("-mabi=n32")
-                      .flag("-m32");
-
-    CSMipsMultilibs =
-        MultilibSet()
-            .Either(MArchMips16, MArchMicroMips, MArchDefault)
-            .Maybe(UCLibc)
-            .Either(SoftFloat, Nan2008, DefaultFloat)
-            .FilterOut("/micromips/nan2008")
-            .FilterOut("/mips16/nan2008")
-            .Either(BigEndian, LittleEndian)
-            .Maybe(MAbi64)
-            .FilterOut("/mips16.*/64")
-            .FilterOut("/micromips.*/64")
-            .FilterOut(NonExistent)
-            .setIncludeDirsCallback([](const Multilib &M) {
-              std::vector<std::string> Dirs({"/include"});
-              if (StringRef(M.includeSuffix()).startswith("/uclibc"))
-                Dirs.push_back(
-                    "/../../../../mips-linux-gnu/libc/uclibc/usr/include");
-              else
-                Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include");
-              return Dirs;
-            });
-  }
-
-  MultilibSet DebianMipsMultilibs;
-  {
-    Multilib MAbiN32 =
-        Multilib().gccSuffix("/n32").includeSuffix("/n32").flag("+mabi=n32");
-
-    Multilib M64 = Multilib()
-                       .gccSuffix("/64")
-                       .includeSuffix("/64")
-                       .flag("+m64")
-                       .flag("-m32")
-                       .flag("-mabi=n32");
-
-    Multilib M32 = Multilib().flag("-m64").flag("+m32").flag("-mabi=n32");
-
-    DebianMipsMultilibs =
-        MultilibSet().Either(M32, M64, MAbiN32).FilterOut(NonExistent);
-  }
-
-  // Sort candidates. Toolchain that best meets the directories tree goes first.
-  // Then select the first toolchains matches command line flags.
-  MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs};
-  if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())
-    std::iter_swap(Candidates, Candidates + 1);
-  for (const MultilibSet *Candidate : Candidates) {
-    if (Candidate->select(Flags, Result.SelectedMultilib)) {
-      if (Candidate == &DebianMipsMultilibs)
-        Result.BiarchSibling = Multilib();
-      Result.Multilibs = *Candidate;
-      return true;
-    }
-  }
-  return false;
-}
-
-static bool findMipsAndroidMultilibs(vfs::FileSystem &VFS, StringRef Path,
-                                     const Multilib::flags_list &Flags,
-                                     FilterNonExistent &NonExistent,
-                                     DetectedMultilibs &Result) {
-
-  MultilibSet AndroidMipsMultilibs =
-      MultilibSet()
-          .Maybe(Multilib("/mips-r2").flag("+march=mips32r2"))
-          .Maybe(Multilib("/mips-r6").flag("+march=mips32r6"))
-          .FilterOut(NonExistent);
-
-  MultilibSet AndroidMipselMultilibs =
-      MultilibSet()
-          .Either(Multilib().flag("+march=mips32"),
-                  Multilib("/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
-                  Multilib("/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
-          .FilterOut(NonExistent);
-
-  MultilibSet AndroidMips64elMultilibs =
-      MultilibSet()
-          .Either(
-              Multilib().flag("+march=mips64r6"),
-              Multilib("/32/mips-r1", "", "/mips-r1").flag("+march=mips32"),
-              Multilib("/32/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
-              Multilib("/32/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
-          .FilterOut(NonExistent);
-
-  MultilibSet *MS = &AndroidMipsMultilibs;
-  if (VFS.exists(Path + "/mips-r6"))
-    MS = &AndroidMipselMultilibs;
-  else if (VFS.exists(Path + "/32"))
-    MS = &AndroidMips64elMultilibs;
-  if (MS->select(Flags, Result.SelectedMultilib)) {
-    Result.Multilibs = *MS;
-    return true;
-  }
-  return false;
-}
-
-static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
-                                  FilterNonExistent &NonExistent,
-                                  DetectedMultilibs &Result) {
-  // Musl toolchain multilibs
-  MultilibSet MuslMipsMultilibs;
-  {
-    auto MArchMipsR2 = makeMultilib("")
-                           .osSuffix("/mips-r2-hard-musl")
-                           .flag("+EB")
-                           .flag("-EL")
-                           .flag("+march=mips32r2");
-
-    auto MArchMipselR2 = makeMultilib("/mipsel-r2-hard-musl")
-                             .flag("-EB")
-                             .flag("+EL")
-                             .flag("+march=mips32r2");
-
-    MuslMipsMultilibs = MultilibSet().Either(MArchMipsR2, MArchMipselR2);
-
-    // Specify the callback that computes the include directories.
-    MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) {
-      return std::vector<std::string>(
-          {"/../sysroot" + M.osSuffix() + "/usr/include"});
-    });
-  }
-  if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)) {
-    Result.Multilibs = MuslMipsMultilibs;
-    return true;
-  }
-  return false;
-}
-
-static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
-                                 FilterNonExistent &NonExistent,
-                                 DetectedMultilibs &Result) {
-  // CodeScape MTI toolchain v1.2 and early.
-  MultilibSet MtiMipsMultilibsV1;
-  {
-    auto MArchMips32 = makeMultilib("/mips32")
-                           .flag("+m32")
-                           .flag("-m64")
-                           .flag("-mmicromips")
-                           .flag("+march=mips32");
-
-    auto MArchMicroMips = makeMultilib("/micromips")
-                              .flag("+m32")
-                              .flag("-m64")
-                              .flag("+mmicromips");
-
-    auto MArchMips64r2 = makeMultilib("/mips64r2")
-                             .flag("-m32")
-                             .flag("+m64")
-                             .flag("+march=mips64r2");
-
-    auto MArchMips64 = makeMultilib("/mips64").flag("-m32").flag("+m64").flag(
-        "-march=mips64r2");
-
-    auto MArchDefault = makeMultilib("")
-                            .flag("+m32")
-                            .flag("-m64")
-                            .flag("-mmicromips")
-                            .flag("+march=mips32r2");
-
-    auto Mips16 = makeMultilib("/mips16").flag("+mips16");
-
-    auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
-
-    auto MAbi64 =
-        makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
-
-    auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
-
-    auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
-
-    auto SoftFloat = makeMultilib("/sof").flag("+msoft-float");
-
-    auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
-
-    MtiMipsMultilibsV1 =
-        MultilibSet()
-            .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64,
-                    MArchDefault)
-            .Maybe(UCLibc)
-            .Maybe(Mips16)
-            .FilterOut("/mips64/mips16")
-            .FilterOut("/mips64r2/mips16")
-            .FilterOut("/micromips/mips16")
-            .Maybe(MAbi64)
-            .FilterOut("/micromips/64")
-            .FilterOut("/mips32/64")
-            .FilterOut("^/64")
-            .FilterOut("/mips16/64")
-            .Either(BigEndian, LittleEndian)
-            .Maybe(SoftFloat)
-            .Maybe(Nan2008)
-            .FilterOut(".*sof/nan2008")
-            .FilterOut(NonExistent)
-            .setIncludeDirsCallback([](const Multilib &M) {
-              std::vector<std::string> Dirs({"/include"});
-              if (StringRef(M.includeSuffix()).startswith("/uclibc"))
-                Dirs.push_back("/../../../../sysroot/uclibc/usr/include");
-              else
-                Dirs.push_back("/../../../../sysroot/usr/include");
-              return Dirs;
-            });
-  }
-
-  // CodeScape IMG toolchain starting from v1.3.
-  MultilibSet MtiMipsMultilibsV2;
-  {
-    auto BeHard = makeMultilib("/mips-r2-hard")
-                      .flag("+EB")
-                      .flag("-msoft-float")
-                      .flag("-mnan=2008")
-                      .flag("-muclibc");
-    auto BeSoft = makeMultilib("/mips-r2-soft")
-                      .flag("+EB")
-                      .flag("+msoft-float")
-                      .flag("-mnan=2008");
-    auto ElHard = makeMultilib("/mipsel-r2-hard")
-                      .flag("+EL")
-                      .flag("-msoft-float")
-                      .flag("-mnan=2008")
-                      .flag("-muclibc");
-    auto ElSoft = makeMultilib("/mipsel-r2-soft")
-                      .flag("+EL")
-                      .flag("+msoft-float")
-                      .flag("-mnan=2008")
-                      .flag("-mmicromips");
-    auto BeHardNan = makeMultilib("/mips-r2-hard-nan2008")
-                         .flag("+EB")
-                         .flag("-msoft-float")
-                         .flag("+mnan=2008")
-                         .flag("-muclibc");
-    auto ElHardNan = makeMultilib("/mipsel-r2-hard-nan2008")
-                         .flag("+EL")
-                         .flag("-msoft-float")
-                         .flag("+mnan=2008")
-                         .flag("-muclibc")
-                         .flag("-mmicromips");
-    auto BeHardNanUclibc = makeMultilib("/mips-r2-hard-nan2008-uclibc")
-                               .flag("+EB")
-                               .flag("-msoft-float")
-                               .flag("+mnan=2008")
-                               .flag("+muclibc");
-    auto ElHardNanUclibc = makeMultilib("/mipsel-r2-hard-nan2008-uclibc")
-                               .flag("+EL")
-                               .flag("-msoft-float")
-                               .flag("+mnan=2008")
-                               .flag("+muclibc");
-    auto BeHardUclibc = makeMultilib("/mips-r2-hard-uclibc")
-                            .flag("+EB")
-                            .flag("-msoft-float")
-                            .flag("-mnan=2008")
-                            .flag("+muclibc");
-    auto ElHardUclibc = makeMultilib("/mipsel-r2-hard-uclibc")
-                            .flag("+EL")
-                            .flag("-msoft-float")
-                            .flag("-mnan=2008")
-                            .flag("+muclibc");
-    auto ElMicroHardNan = makeMultilib("/micromipsel-r2-hard-nan2008")
-                              .flag("+EL")
-                              .flag("-msoft-float")
-                              .flag("+mnan=2008")
-                              .flag("+mmicromips");
-    auto ElMicroSoft = makeMultilib("/micromipsel-r2-soft")
-                           .flag("+EL")
-                           .flag("+msoft-float")
-                           .flag("-mnan=2008")
-                           .flag("+mmicromips");
-
-    auto O32 =
-        makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
-    auto N32 =
-        makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
-    auto N64 =
-        makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
-
-    MtiMipsMultilibsV2 =
-        MultilibSet()
-            .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,
-                     BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,
-                     ElHardUclibc, ElMicroHardNan, ElMicroSoft})
-            .Either(O32, N32, N64)
-            .FilterOut(NonExistent)
-            .setIncludeDirsCallback([](const Multilib &M) {
-              return std::vector<std::string>({"/../../../../sysroot" +
-                                               M.includeSuffix() +
-                                               "/../usr/include"});
-            })
-            .setFilePathsCallback([](const Multilib &M) {
-              return std::vector<std::string>(
-                  {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});
-            });
-  }
-  for (auto Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {
-    if (Candidate->select(Flags, Result.SelectedMultilib)) {
-      Result.Multilibs = *Candidate;
-      return true;
-    }
-  }
-  return false;
-}
-
-static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
-                                 FilterNonExistent &NonExistent,
-                                 DetectedMultilibs &Result) {
-  // CodeScape IMG toolchain v1.2 and early.
-  MultilibSet ImgMultilibsV1;
-  {
-    auto Mips64r6 = makeMultilib("/mips64r6").flag("+m64").flag("-m32");
-
-    auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
-
-    auto MAbi64 =
-        makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
-
-    ImgMultilibsV1 =
-        MultilibSet()
-            .Maybe(Mips64r6)
-            .Maybe(MAbi64)
-            .Maybe(LittleEndian)
-            .FilterOut(NonExistent)
-            .setIncludeDirsCallback([](const Multilib &M) {
-              return std::vector<std::string>(
-                  {"/include", "/../../../../sysroot/usr/include"});
-            });
-  }
-
-  // CodeScape IMG toolchain starting from v1.3.
-  MultilibSet ImgMultilibsV2;
-  {
-    auto BeHard = makeMultilib("/mips-r6-hard")
-                      .flag("+EB")
-                      .flag("-msoft-float")
-                      .flag("-mmicromips");
-    auto BeSoft = makeMultilib("/mips-r6-soft")
-                      .flag("+EB")
-                      .flag("+msoft-float")
-                      .flag("-mmicromips");
-    auto ElHard = makeMultilib("/mipsel-r6-hard")
-                      .flag("+EL")
-                      .flag("-msoft-float")
-                      .flag("-mmicromips");
-    auto ElSoft = makeMultilib("/mipsel-r6-soft")
-                      .flag("+EL")
-                      .flag("+msoft-float")
-                      .flag("-mmicromips");
-    auto BeMicroHard = makeMultilib("/micromips-r6-hard")
-                           .flag("+EB")
-                           .flag("-msoft-float")
-                           .flag("+mmicromips");
-    auto BeMicroSoft = makeMultilib("/micromips-r6-soft")
-                           .flag("+EB")
-                           .flag("+msoft-float")
-                           .flag("+mmicromips");
-    auto ElMicroHard = makeMultilib("/micromipsel-r6-hard")
-                           .flag("+EL")
-                           .flag("-msoft-float")
-                           .flag("+mmicromips");
-    auto ElMicroSoft = makeMultilib("/micromipsel-r6-soft")
-                           .flag("+EL")
-                           .flag("+msoft-float")
-                           .flag("+mmicromips");
-
-    auto O32 =
-        makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
-    auto N32 =
-        makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
-    auto N64 =
-        makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
-
-    ImgMultilibsV2 =
-        MultilibSet()
-            .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,
-                     ElMicroHard, ElMicroSoft})
-            .Either(O32, N32, N64)
-            .FilterOut(NonExistent)
-            .setIncludeDirsCallback([](const Multilib &M) {
-              return std::vector<std::string>({"/../../../../sysroot" +
-                                               M.includeSuffix() +
-                                               "/../usr/include"});
-            })
-            .setFilePathsCallback([](const Multilib &M) {
-              return std::vector<std::string>(
-                  {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});
-            });
-  }
-  for (auto Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {
-    if (Candidate->select(Flags, Result.SelectedMultilib)) {
-      Result.Multilibs = *Candidate;
-      return true;
-    }
-  }
-  return false;
-}
-
-static bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
-                              StringRef Path, const ArgList &Args,
-                              DetectedMultilibs &Result) {
-  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
-
-  StringRef CPUName;
-  StringRef ABIName;
-  tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName);
-
-  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
-
-  Multilib::flags_list Flags;
-  addMultilibFlag(isMips32(TargetArch), "m32", Flags);
-  addMultilibFlag(isMips64(TargetArch), "m64", Flags);
-  addMultilibFlag(isMips16(Args), "mips16", Flags);
-  addMultilibFlag(CPUName == "mips32", "march=mips32", Flags);
-  addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||
-                      CPUName == "mips32r5" || CPUName == "p5600",
-                  "march=mips32r2", Flags);
-  addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags);
-  addMultilibFlag(CPUName == "mips64", "march=mips64", Flags);
-  addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||
-                      CPUName == "mips64r5" || CPUName == "octeon",
-                  "march=mips64r2", Flags);
-  addMultilibFlag(CPUName == "mips64r6", "march=mips64r6", Flags);
-  addMultilibFlag(isMicroMips(Args), "mmicromips", Flags);
-  addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags);
-  addMultilibFlag(tools::mips::isNaN2008(Args, TargetTriple), "mnan=2008",
-                  Flags);
-  addMultilibFlag(ABIName == "n32", "mabi=n32", Flags);
-  addMultilibFlag(ABIName == "n64", "mabi=n64", Flags);
-  addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags);
-  addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags);
-  addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
-  addMultilibFlag(!isMipsEL(TargetArch), "EB", Flags);
-
-  if (TargetTriple.isAndroid())
-    return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent,
-                                    Result);
-
-  if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
-      TargetTriple.getOS() == llvm::Triple::Linux &&
-      TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
-    return findMipsMuslMultilibs(Flags, NonExistent, Result);
-
-  if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
-      TargetTriple.getOS() == llvm::Triple::Linux &&
-      TargetTriple.getEnvironment() == llvm::Triple::GNU)
-    return findMipsMtiMultilibs(Flags, NonExistent, Result);
-
-  if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
-      TargetTriple.getOS() == llvm::Triple::Linux &&
-      TargetTriple.getEnvironment() == llvm::Triple::GNU)
-    return findMipsImgMultilibs(Flags, NonExistent, Result);
-
-  if (findMipsCsMultilibs(Flags, NonExistent, Result))
-    return true;
-
-  // 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;
-}
-
-static void findAndroidArmMultilibs(const Driver &D,
-                                    const llvm::Triple &TargetTriple,
-                                    StringRef Path, const ArgList &Args,
-                                    DetectedMultilibs &Result) {
-  // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.
-  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
-  Multilib ArmV7Multilib = makeMultilib("/armv7-a")
-                               .flag("+armv7")
-                               .flag("-thumb");
-  Multilib ThumbMultilib = makeMultilib("/thumb")
-                               .flag("-armv7")
-                               .flag("+thumb");
-  Multilib ArmV7ThumbMultilib = makeMultilib("/armv7-a/thumb")
-                               .flag("+armv7")
-                               .flag("+thumb");
-  Multilib DefaultMultilib = makeMultilib("")
-                               .flag("-armv7")
-                               .flag("-thumb");
-  MultilibSet AndroidArmMultilibs =
-      MultilibSet()
-          .Either(ThumbMultilib, ArmV7Multilib,
-                  ArmV7ThumbMultilib, DefaultMultilib)
-          .FilterOut(NonExistent);
-
-  Multilib::flags_list Flags;
-  llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);
-  bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;
-  bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;
-  bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;
-  bool IsThumbMode = IsThumbArch ||
-      Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||
-      (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::IK_THUMB);
-  bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&
-      (llvm::ARM::parseArchVersion(Arch) == 7 ||
-       (IsArmArch && Arch == "" && IsV7SubArch));
-  addMultilibFlag(IsArmV7Mode, "armv7", Flags);
-  addMultilibFlag(IsThumbMode, "thumb", Flags);
-
-  if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib))
-    Result.Multilibs = AndroidArmMultilibs;
-}
-
-static bool findBiarchMultilibs(const Driver &D,
-                                const llvm::Triple &TargetTriple,
-                                StringRef Path, const ArgList &Args,
-                                bool NeedsBiarchSuffix,
-                                DetectedMultilibs &Result) {
-  // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
-  // in what would normally be GCCInstallPath and put the 64-bit
-  // libs in a subdirectory named 64. The simple logic we follow is that
-  // *if* there is a subdirectory of the right name with crtbegin.o in it,
-  // we use that. If not, and if not a biarch triple alias, we look for
-  // crtbegin.o without the subdirectory.
-
-  Multilib Default;
-  Multilib Alt64 = Multilib()
-                       .gccSuffix("/64")
-                       .includeSuffix("/64")
-                       .flag("-m32")
-                       .flag("+m64")
-                       .flag("-mx32");
-  Multilib Alt32 = Multilib()
-                       .gccSuffix("/32")
-                       .includeSuffix("/32")
-                       .flag("+m32")
-                       .flag("-m64")
-                       .flag("-mx32");
-  Multilib Altx32 = Multilib()
-                        .gccSuffix("/x32")
-                        .includeSuffix("/x32")
-                        .flag("-m32")
-                        .flag("-m64")
-                        .flag("+mx32");
-
-  // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.
-  FilterNonExistent NonExistent(
-      Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());
-
-  // 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))
-    Want = WANT64;
-  else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
-    Want = WANT64;
-  else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
-    Want = WANT32;
-  else {
-    if (TargetTriple.isArch32Bit())
-      Want = NeedsBiarchSuffix ? WANT64 : WANT32;
-    else if (IsX32)
-      Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
-    else
-      Want = NeedsBiarchSuffix ? WANT32 : WANT64;
-  }
-
-  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
-    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() && !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 ||
-      Result.SelectedMultilib == Altx32)
-    Result.BiarchSibling = Default;
-
-  return true;
-}
-
-void Generic_GCC::GCCInstallationDetector::scanLibDirForGCCTripleSolaris(
-    const llvm::Triple &TargetArch, const llvm::opt::ArgList &Args,
-    const std::string &LibDir, StringRef CandidateTriple,
-    bool NeedsBiarchSuffix) {
-  // Solaris is a special case. The GCC installation is under
-  // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/, so we
-  // need to iterate twice.
-  std::error_code EC;
-  for (vfs::directory_iterator LI = D.getVFS().dir_begin(LibDir, EC), LE;
-       !EC && LI != LE; LI = LI.increment(EC)) {
-    StringRef VersionText = llvm::sys::path::filename(LI->getName());
-    GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
-
-    if (CandidateVersion.Major != -1) // Filter obviously bad entries.
-      if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
-        continue; // Saw this path before; no need to look at it again.
-    if (CandidateVersion.isOlderThan(4, 1, 1))
-      continue;
-    if (CandidateVersion <= Version)
-      continue;
-
-    GCCInstallPath =
-        LibDir + "/" + VersionText.str() + "/lib/gcc/" + CandidateTriple.str();
-    if (!D.getVFS().exists(GCCInstallPath))
-      continue;
-
-    // If we make it here there has to be at least one GCC version, let's just
-    // use the latest one.
-    std::error_code EEC;
-    for (vfs::directory_iterator
-             LLI = D.getVFS().dir_begin(GCCInstallPath, EEC),
-             LLE;
-         !EEC && LLI != LLE; LLI = LLI.increment(EEC)) {
-
-      StringRef SubVersionText = llvm::sys::path::filename(LLI->getName());
-      GCCVersion CandidateSubVersion = GCCVersion::Parse(SubVersionText);
-
-      if (CandidateSubVersion > Version)
-        Version = CandidateSubVersion;
-    }
-
-    GCCTriple.setTriple(CandidateTriple);
-
-    GCCInstallPath += "/" + Version.Text;
-    GCCParentLibPath = GCCInstallPath + "/../../../../";
-
-    IsValid = true;
-  }
-}
-
-void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
-    const llvm::Triple &TargetTriple, const ArgList &Args,
-    const std::string &LibDir, StringRef CandidateTriple,
-    bool NeedsBiarchSuffix) {
-  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
-  // There are various different suffixes involving the triple we
-  // check for. We also record what is necessary to walk from each back
-  // up to the lib directory. Specifically, the number of "up" steps
-  // in the second half of each row is 1 + the number of path separators
-  // in the first half.
-  const std::string LibAndInstallSuffixes[][2] = {
-      {"/gcc/" + CandidateTriple.str(), "/../../.."},
-
-      // Debian puts cross-compilers in gcc-cross
-      {"/gcc-cross/" + CandidateTriple.str(), "/../../.."},
-
-      {"/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
-       "/../../../.."},
-
-      // The Freescale PPC SDK has the gcc libraries in
-      // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well.
-      {"/" + CandidateTriple.str(), "/../.."},
-
-      // Ubuntu has a strange mis-matched pair of triples that this happens to
-      // match.
-      // FIXME: It may be worthwhile to generalize this and look for a second
-      // triple.
-      {"/i386-linux-gnu/gcc/" + CandidateTriple.str(), "/../../../.."}};
-
-  if (TargetTriple.getOS() == llvm::Triple::Solaris) {
-    scanLibDirForGCCTripleSolaris(TargetTriple, Args, LibDir, CandidateTriple,
-                                  NeedsBiarchSuffix);
-    return;
-  }
-
-  // Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
-  const unsigned NumLibSuffixes = (llvm::array_lengthof(LibAndInstallSuffixes) -
-                                   (TargetArch != llvm::Triple::x86));
-  for (unsigned i = 0; i < NumLibSuffixes; ++i) {
-    StringRef LibSuffix = LibAndInstallSuffixes[i][0];
-    std::error_code EC;
-    for (vfs::directory_iterator
-             LI = D.getVFS().dir_begin(LibDir + LibSuffix, EC),
-             LE;
-         !EC && LI != LE; LI = LI.increment(EC)) {
-      StringRef VersionText = llvm::sys::path::filename(LI->getName());
-      GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
-      if (CandidateVersion.Major != -1) // Filter obviously bad entries.
-        if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
-          continue; // Saw this path before; no need to look at it again.
-      if (CandidateVersion.isOlderThan(4, 1, 1))
-        continue;
-      if (CandidateVersion <= Version)
-        continue;
-
-      DetectedMultilibs Detected;
-
-      // Android standalone toolchain could have multilibs for ARM and Thumb.
-      // Debian mips multilibs behave more like the rest of the biarch ones,
-      // so handle them there
-      if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {
-        // It should also work without multilibs in a simplified toolchain.
-        findAndroidArmMultilibs(D, TargetTriple, LI->getName(), Args, Detected);
-      } else if (isMipsArch(TargetArch)) {
-        if (!findMIPSMultilibs(D, TargetTriple, LI->getName(), Args, Detected))
-          continue;
-      } else if (!findBiarchMultilibs(D, TargetTriple, LI->getName(), Args,
-                                      NeedsBiarchSuffix, Detected)) {
-        continue;
-      }
-
-      Multilibs = Detected.Multilibs;
-      SelectedMultilib = Detected.SelectedMultilib;
-      BiarchSibling = Detected.BiarchSibling;
-      Version = CandidateVersion;
-      GCCTriple.setTriple(CandidateTriple);
-      // FIXME: We hack together the directory name here instead of
-      // using LI to ensure stable path separators across Windows and
-      // Linux.
-      GCCInstallPath =
-          LibDir + LibAndInstallSuffixes[i][0] + "/" + VersionText.str();
-      GCCParentLibPath = GCCInstallPath + LibAndInstallSuffixes[i][1];
-      IsValid = true;
-    }
-  }
-}
-
-Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,
-                         const ArgList &Args)
-    : ToolChain(D, Triple, Args), GCCInstallation(D),
-      CudaInstallation(D, Triple, Args) {
-  getProgramPaths().push_back(getDriver().getInstalledDir());
-  if (getDriver().getInstalledDir() != getDriver().Dir)
-    getProgramPaths().push_back(getDriver().Dir);
-}
-
-Generic_GCC::~Generic_GCC() {}
-
-Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::PreprocessJobClass:
-    if (!Preprocess)
-      Preprocess.reset(new tools::gcc::Preprocessor(*this));
-    return Preprocess.get();
-  case Action::CompileJobClass:
-    if (!Compile)
-      Compile.reset(new tools::gcc::Compiler(*this));
-    return Compile.get();
-  default:
-    return ToolChain::getTool(AC);
-  }
-}
-
-Tool *Generic_GCC::buildAssembler() const {
-  return new tools::gnutools::Assembler(*this);
-}
-
-Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); }
-
-void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
-  // Print the information about how we detected the GCC installation.
-  GCCInstallation.print(OS);
-  CudaInstallation.print(OS);
-}
-
-bool Generic_GCC::IsUnwindTablesDefault() const {
-  return getArch() == llvm::Triple::x86_64;
-}
-
-bool Generic_GCC::isPICDefault() const {
-  return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
-}
-
-bool Generic_GCC::isPIEDefault() const { return false; }
-
-bool Generic_GCC::isPICDefaultForced() const {
-  return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
-}
-
-bool Generic_GCC::IsIntegratedAssemblerDefault() const {
-  switch (getTriple().getArch()) {
-  case llvm::Triple::x86:
-  case llvm::Triple::x86_64:
-  case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_be:
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::bpfel:
-  case llvm::Triple::bpfeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb:
-  case llvm::Triple::ppc:
-  case llvm::Triple::ppc64:
-  case llvm::Triple::ppc64le:
-  case llvm::Triple::systemz:
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-    return true;
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el:
-    // Enabled for Debian mips64/mips64el only. Other targets are unable to
-    // distinguish N32 from N64.
-    if (getTriple().getEnvironment() == llvm::Triple::GNUABI64)
-      return true;
-    return false;
-  default:
-    return false;
-  }
-}
-
-void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
-                                               ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
-      DriverArgs.hasArg(options::OPT_nostdincxx))
-    return;
-
-  switch (GetCXXStdlibType(DriverArgs)) {
-  case ToolChain::CST_Libcxx: {
-    std::string Path = findLibCxxIncludePath();
-    if (!Path.empty())
-      addSystemInclude(DriverArgs, CC1Args, Path);
-    break;
-  }
-
-  case ToolChain::CST_Libstdcxx:
-    addLibStdCxxIncludePaths(DriverArgs, CC1Args);
-    break;
-  }
-}
-
-std::string Generic_GCC::findLibCxxIncludePath() const {
-  // FIXME: The Linux behavior would probaby be a better approach here.
-  return getDriver().SysRoot + "/usr/include/c++/v1";
-}
-
-void
-Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
-                                      llvm::opt::ArgStringList &CC1Args) const {
-  // By default, we don't assume we know where libstdc++ might be installed.
-  // FIXME: If we have a valid GCCInstallation, use it.
-}
-
-/// \brief Helper to add the variant paths of a libstdc++ installation.
-bool Generic_GCC::addLibStdCXXIncludePaths(
-    Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple,
-    StringRef TargetMultiarchTriple, Twine IncludeSuffix,
-    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
-  if (!getVFS().exists(Base + Suffix))
-    return false;
-
-  addSystemInclude(DriverArgs, CC1Args, Base + Suffix);
-
-  // The vanilla GCC layout of libstdc++ headers uses a triple subdirectory. If
-  // that path exists or we have neither a GCC nor target multiarch triple, use
-  // this vanilla search path.
-  if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) ||
-      getVFS().exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) {
-    addSystemInclude(DriverArgs, CC1Args,
-                     Base + Suffix + "/" + GCCTriple + IncludeSuffix);
-  } else {
-    // Otherwise try to use multiarch naming schemes which have normalized the
-    // triples and put the triple before the suffix.
-    //
-    // GCC surprisingly uses *both* the GCC triple with a multilib suffix and
-    // the target triple, so we support that here.
-    addSystemInclude(DriverArgs, CC1Args,
-                     Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix);
-    addSystemInclude(DriverArgs, CC1Args,
-                     Base + "/" + TargetMultiarchTriple + Suffix);
-  }
-
-  addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward");
-  return true;
-}
-
-llvm::opt::DerivedArgList *
-Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef,
-                           Action::OffloadKind DeviceOffloadKind) const {
-
-  // If this tool chain is used for an OpenMP offloading device we have to make
-  // sure we always generate a shared library regardless of the commands the
-  // user passed to the host. This is required because the runtime library
-  // is required to load the device image dynamically at run time.
-  if (DeviceOffloadKind == Action::OFK_OpenMP) {
-    DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
-    const OptTable &Opts = getDriver().getOpts();
-
-    // Request the shared library. Given that these options are decided
-    // implicitly, they do not refer to any base argument.
-    DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_shared));
-    DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_fPIC));
-
-    // Filter all the arguments we don't care passing to the offloading
-    // toolchain as they can mess up with the creation of a shared library.
-    for (auto *A : Args) {
-      switch ((options::ID)A->getOption().getID()) {
-      default:
-        DAL->append(A);
-        break;
-      case options::OPT_shared:
-      case options::OPT_dynamic:
-      case options::OPT_static:
-      case options::OPT_fPIC:
-      case options::OPT_fno_PIC:
-      case options::OPT_fpic:
-      case options::OPT_fno_pic:
-      case options::OPT_fPIE:
-      case options::OPT_fno_PIE:
-      case options::OPT_fpie:
-      case options::OPT_fno_pie:
-        break;
-      }
-    }
-    return DAL;
-  }
-  return nullptr;
-}
-
-void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
-                                        ArgStringList &CC1Args) const {
-  const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
-  bool UseInitArrayDefault =
-      getTriple().getArch() == llvm::Triple::aarch64 ||
-      getTriple().getArch() == llvm::Triple::aarch64_be ||
-      (getTriple().getOS() == llvm::Triple::Linux &&
-       (!V.isOlderThan(4, 7, 0) || getTriple().isAndroid())) ||
-      getTriple().getOS() == llvm::Triple::NaCl ||
-      (getTriple().getVendor() == llvm::Triple::MipsTechnologies &&
-       !getTriple().hasEnvironment());
-
-  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
-                         options::OPT_fno_use_init_array, UseInitArrayDefault))
-    CC1Args.push_back("-fuse-init-array");
-}
-
-/// Mips Toolchain
-MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D,
-                                     const llvm::Triple &Triple,
-                                     const ArgList &Args)
-    : Linux(D, Triple, Args) {
-  // Select the correct multilib according to the given arguments.
-  DetectedMultilibs Result;
-  findMIPSMultilibs(D, Triple, "", Args, Result);
-  Multilibs = Result.Multilibs;
-  SelectedMultilib = Result.SelectedMultilib;
-
-  // Find out the library suffix based on the ABI.
-  LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple);
-  getFilePaths().clear();
-  getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix);
-
-  // Use LLD by default.
-  DefaultLinker = "lld";
-}
-
-void MipsLLVMToolChain::AddClangSystemIncludeArgs(
-    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdinc))
-    return;
-
-  const Driver &D = getDriver();
-
-  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
-    SmallString<128> P(D.ResourceDir);
-    llvm::sys::path::append(P, "include");
-    addSystemInclude(DriverArgs, CC1Args, P);
-  }
-
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
-    return;
-
-  const auto &Callback = Multilibs.includeDirsCallback();
-  if (Callback) {
-    for (const auto &Path : Callback(SelectedMultilib))
-      addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
-                                      D.getInstalledDir() + Path);
-  }
-}
-
-Tool *MipsLLVMToolChain::buildLinker() const {
-  return new tools::gnutools::Linker(*this);
-}
-
-std::string MipsLLVMToolChain::computeSysRoot() const {
-  if (!getDriver().SysRoot.empty())
-    return getDriver().SysRoot + SelectedMultilib.osSuffix();
-
-  const std::string InstalledDir(getDriver().getInstalledDir());
-  std::string SysRootPath =
-      InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix();
-  if (llvm::sys::fs::exists(SysRootPath))
-    return SysRootPath;
-
-  return std::string();
-}
-
-ToolChain::CXXStdlibType
-MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const {
-  Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
-  if (A) {
-    StringRef Value = A->getValue();
-    if (Value != "libc++")
-      getDriver().Diag(diag::err_drv_invalid_stdlib_name)
-          << A->getAsString(Args);
-  }
-
-  return ToolChain::CST_Libcxx;
-}
-
-std::string MipsLLVMToolChain::findLibCxxIncludePath() const {
-  if (const auto &Callback = Multilibs.includeDirsCallback()) {
-    for (std::string Path : Callback(SelectedMultilib)) {
-      Path = getDriver().getInstalledDir() + Path + "/c++/v1";
-      if (llvm::sys::fs::exists(Path)) {
-        return Path;
-      }
-    }
-  }
-  return "";
-}
-
-void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
-                                            ArgStringList &CmdArgs) const {
-  assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) &&
-         "Only -lc++ (aka libxx) is suported in this toolchain.");
-
-  CmdArgs.push_back("-lc++");
-  CmdArgs.push_back("-lc++abi");
-  CmdArgs.push_back("-lunwind");
-}
-
-std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args,
-                                             StringRef Component,
-                                             bool Shared) const {
-  SmallString<128> Path(getDriver().ResourceDir);
-  llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix,
-                          getOS());
-  llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" +
-                                      "mips" + (Shared ? ".so" : ".a")));
-  return Path.str();
-}
-
-/// Hexagon Toolchain
-
-std::string HexagonToolChain::getHexagonTargetDir(
-      const std::string &InstalledDir,
-      const SmallVectorImpl<std::string> &PrefixDirs) const {
-  std::string InstallRelDir;
-  const Driver &D = getDriver();
-
-  // Locate the rest of the toolchain ...
-  for (auto &I : PrefixDirs)
-    if (D.getVFS().exists(I))
-      return I;
-
-  if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
-    return InstallRelDir;
-
-  return InstalledDir;
-}
-
-Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
-      const ArgList &Args) {
-  StringRef Gn = "";
-  if (Arg *A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ,
-                               options::OPT_msmall_data_threshold_EQ)) {
-    Gn = A->getValue();
-  } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
-                             options::OPT_fPIC)) {
-    Gn = "0";
-  }
-
-  unsigned G;
-  if (!Gn.getAsInteger(10, G))
-    return G;
-
-  return None;
-}
-
-void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
-      ToolChain::path_list &LibPaths) const {
-  const Driver &D = getDriver();
-
-  //----------------------------------------------------------------------------
-  // -L Args
-  //----------------------------------------------------------------------------
-  for (Arg *A : Args.filtered(options::OPT_L))
-    for (const char *Value : A->getValues())
-      LibPaths.push_back(Value);
-
-  //----------------------------------------------------------------------------
-  // Other standard paths
-  //----------------------------------------------------------------------------
-  std::vector<std::string> RootDirs;
-  std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
-            std::back_inserter(RootDirs));
-
-  std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
-                                              D.PrefixDirs);
-  if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
-    RootDirs.push_back(TargetDir);
-
-  bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
-  // Assume G0 with -shared.
-  bool HasG0 = Args.hasArg(options::OPT_shared);
-  if (auto G = getSmallDataThreshold(Args))
-    HasG0 = G.getValue() == 0;
-
-  const std::string CpuVer = GetTargetCPUVersion(Args).str();
-  for (auto &Dir : RootDirs) {
-    std::string LibDir = Dir + "/hexagon/lib";
-    std::string LibDirCpu = LibDir + '/' + CpuVer;
-    if (HasG0) {
-      if (HasPIC)
-        LibPaths.push_back(LibDirCpu + "/G0/pic");
-      LibPaths.push_back(LibDirCpu + "/G0");
-    }
-    LibPaths.push_back(LibDirCpu);
-    LibPaths.push_back(LibDir);
-  }
-}
-
-HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
-                                   const llvm::opt::ArgList &Args)
-    : Linux(D, Triple, Args) {
-  const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
-                                                    D.PrefixDirs);
-
-  // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
-  // program paths
-  const std::string BinDir(TargetDir + "/bin");
-  if (D.getVFS().exists(BinDir))
-    getProgramPaths().push_back(BinDir);
-
-  ToolChain::path_list &LibPaths = getFilePaths();
-
-  // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
-  // 'elf' OS type, so the Linux paths are not appropriate. When we actually
-  // support 'linux' we'll need to fix this up
-  LibPaths.clear();
-  getHexagonLibraryPaths(Args, LibPaths);
-}
-
-HexagonToolChain::~HexagonToolChain() {}
-
-Tool *HexagonToolChain::buildAssembler() const {
-  return new tools::hexagon::Assembler(*this);
-}
-
-Tool *HexagonToolChain::buildLinker() const {
-  return new tools::hexagon::Linker(*this);
-}
-
-void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                                 ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
-      DriverArgs.hasArg(options::OPT_nostdlibinc))
-    return;
-
-  const Driver &D = getDriver();
-  std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
-                                              D.PrefixDirs);
-  addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
-}
-
-
-void HexagonToolChain::addLibStdCxxIncludePaths(
-    const llvm::opt::ArgList &DriverArgs,
-    llvm::opt::ArgStringList &CC1Args) const {
-  const Driver &D = getDriver();
-  std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
-  addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++", "", "", "", "",
-                           DriverArgs, CC1Args);
-}
-
-ToolChain::CXXStdlibType
-HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
-  Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
-  if (!A)
-    return ToolChain::CST_Libstdcxx;
-
-  StringRef Value = A->getValue();
-  if (Value != "libstdc++")
-    getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
-
-  return ToolChain::CST_Libstdcxx;
-}
-
-//
-// Returns the default CPU for Hexagon. This is the default compilation target
-// if no Hexagon processor is selected at the command-line.
-//
-const StringRef HexagonToolChain::GetDefaultCPU() {
-  return "hexagonv60";
-}
-
-const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
-  Arg *CpuArg = nullptr;
-  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
-    CpuArg = A;
-
-  StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
-  if (CPU.startswith("hexagon"))
-    return CPU.substr(sizeof("hexagon") - 1);
-  return CPU;
-}
-// End Hexagon
-
-/// AMDGPU Toolchain
-AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
-                                 const ArgList &Args)
-  : Generic_ELF(D, Triple, Args) { }
-
-Tool *AMDGPUToolChain::buildLinker() const {
-  return new tools::amdgpu::Linker(*this);
-}
-// End AMDGPU
-
-/// NaCl Toolchain
-NaClToolChain::NaClToolChain(const Driver &D, const llvm::Triple &Triple,
-                             const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-
-  // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the
-  // default paths, and must instead only use the paths provided
-  // with this toolchain based on architecture.
-  path_list &file_paths = getFilePaths();
-  path_list &prog_paths = getProgramPaths();
-
-  file_paths.clear();
-  prog_paths.clear();
-
-  // Path for library files (libc.a, ...)
-  std::string FilePath(getDriver().Dir + "/../");
-
-  // Path for tools (clang, ld, etc..)
-  std::string ProgPath(getDriver().Dir + "/../");
-
-  // Path for toolchain libraries (libgcc.a, ...)
-  std::string ToolPath(getDriver().ResourceDir + "/lib/");
-
-  switch (Triple.getArch()) {
-  case llvm::Triple::x86:
-    file_paths.push_back(FilePath + "x86_64-nacl/lib32");
-    file_paths.push_back(FilePath + "i686-nacl/usr/lib");
-    prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
-    file_paths.push_back(ToolPath + "i686-nacl");
-    break;
-  case llvm::Triple::x86_64:
-    file_paths.push_back(FilePath + "x86_64-nacl/lib");
-    file_paths.push_back(FilePath + "x86_64-nacl/usr/lib");
-    prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
-    file_paths.push_back(ToolPath + "x86_64-nacl");
-    break;
-  case llvm::Triple::arm:
-    file_paths.push_back(FilePath + "arm-nacl/lib");
-    file_paths.push_back(FilePath + "arm-nacl/usr/lib");
-    prog_paths.push_back(ProgPath + "arm-nacl/bin");
-    file_paths.push_back(ToolPath + "arm-nacl");
-    break;
-  case llvm::Triple::mipsel:
-    file_paths.push_back(FilePath + "mipsel-nacl/lib");
-    file_paths.push_back(FilePath + "mipsel-nacl/usr/lib");
-    prog_paths.push_back(ProgPath + "bin");
-    file_paths.push_back(ToolPath + "mipsel-nacl");
-    break;
-  default:
-    break;
-  }
-
-  NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s");
-}
-
-void NaClToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                              ArgStringList &CC1Args) const {
-  const Driver &D = getDriver();
-  if (DriverArgs.hasArg(options::OPT_nostdinc))
-    return;
-
-  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
-    SmallString<128> P(D.ResourceDir);
-    llvm::sys::path::append(P, "include");
-    addSystemInclude(DriverArgs, CC1Args, P.str());
-  }
-
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
-    return;
-
-  SmallString<128> P(D.Dir + "/../");
-  switch (getTriple().getArch()) {
-  case llvm::Triple::x86:
-    // x86 is special because multilib style uses x86_64-nacl/include for libc
-    // headers but the SDK wants i686-nacl/usr/include. The other architectures
-    // have the same substring.
-    llvm::sys::path::append(P, "i686-nacl/usr/include");
-    addSystemInclude(DriverArgs, CC1Args, P.str());
-    llvm::sys::path::remove_filename(P);
-    llvm::sys::path::remove_filename(P);
-    llvm::sys::path::remove_filename(P);
-    llvm::sys::path::append(P, "x86_64-nacl/include");
-    addSystemInclude(DriverArgs, CC1Args, P.str());
-    return;
-  case llvm::Triple::arm:
-    llvm::sys::path::append(P, "arm-nacl/usr/include");
-    break;
-  case llvm::Triple::x86_64:
-    llvm::sys::path::append(P, "x86_64-nacl/usr/include");
-    break;
-  case llvm::Triple::mipsel:
-    llvm::sys::path::append(P, "mipsel-nacl/usr/include");
-    break;
-  default:
-    return;
-  }
-
-  addSystemInclude(DriverArgs, CC1Args, P.str());
-  llvm::sys::path::remove_filename(P);
-  llvm::sys::path::remove_filename(P);
-  llvm::sys::path::append(P, "include");
-  addSystemInclude(DriverArgs, CC1Args, P.str());
-}
-
-void NaClToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
-                                        ArgStringList &CmdArgs) const {
-  // Check for -stdlib= flags. We only support libc++ but this consumes the arg
-  // if the value is libc++, and emits an error for other values.
-  GetCXXStdlibType(Args);
-  CmdArgs.push_back("-lc++");
-}
-
-std::string NaClToolChain::findLibCxxIncludePath() const {
-  const Driver &D = getDriver();
-
-  SmallString<128> P(D.Dir + "/../");
-  switch (getTriple().getArch()) {
-  case llvm::Triple::arm:
-    llvm::sys::path::append(P, "arm-nacl/include/c++/v1");
-    return P.str();
-  case llvm::Triple::x86:
-    llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
-    return P.str();
-  case llvm::Triple::x86_64:
-    llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
-    return P.str();
-  case llvm::Triple::mipsel:
-    llvm::sys::path::append(P, "mipsel-nacl/include/c++/v1");
-    return P.str();
-  default:
-    return "";
-  }
-}
-
-ToolChain::CXXStdlibType
-NaClToolChain::GetCXXStdlibType(const ArgList &Args) const {
-  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
-    StringRef Value = A->getValue();
-    if (Value == "libc++")
-      return ToolChain::CST_Libcxx;
-    getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
-  }
-
-  return ToolChain::CST_Libcxx;
-}
-
-std::string
-NaClToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
-                                           types::ID InputType) const {
-  llvm::Triple TheTriple(ComputeLLVMTriple(Args, InputType));
-  if (TheTriple.getArch() == llvm::Triple::arm &&
-      TheTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
-    TheTriple.setEnvironment(llvm::Triple::GNUEABIHF);
-  return TheTriple.getTriple();
-}
-
-Tool *NaClToolChain::buildLinker() const {
-  return new tools::nacltools::Linker(*this);
-}
-
-Tool *NaClToolChain::buildAssembler() const {
-  if (getTriple().getArch() == llvm::Triple::arm)
-    return new tools::nacltools::AssemblerARM(*this);
-  return new tools::gnutools::Assembler(*this);
-}
-// End NaCl
-
-/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
-/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
-/// Currently does not support anything else but compilation.
-
-TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple &Triple,
-                           const ArgList &Args)
-    : ToolChain(D, Triple, Args) {
-  // Path mangling to find libexec
-  std::string Path(getDriver().Dir);
-
-  Path += "/../libexec";
-  getProgramPaths().push_back(Path);
-}
-
-TCEToolChain::~TCEToolChain() {}
-
-bool TCEToolChain::IsMathErrnoDefault() const { return true; }
-
-bool TCEToolChain::isPICDefault() const { return false; }
-
-bool TCEToolChain::isPIEDefault() const { return false; }
-
-bool TCEToolChain::isPICDefaultForced() const { return false; }
-
-TCELEToolChain::TCELEToolChain(const Driver &D, const llvm::Triple& Triple,
-                               const ArgList &Args)
-  : TCEToolChain(D, Triple, Args) {
-}
-
-TCELEToolChain::~TCELEToolChain() {}
-
-// CloudABI - CloudABI tool chain which can call ld(1) directly.
-
-CloudABI::CloudABI(const Driver &D, const llvm::Triple &Triple,
-                   const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-  SmallString<128> P(getDriver().Dir);
-  llvm::sys::path::append(P, "..", getTriple().str(), "lib");
-  getFilePaths().push_back(P.str());
-}
-
-std::string CloudABI::findLibCxxIncludePath() const {
-  SmallString<128> P(getDriver().Dir);
-  llvm::sys::path::append(P, "..", getTriple().str(), "include/c++/v1");
-  return P.str();
-}
-
-void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args,
-                                   ArgStringList &CmdArgs) const {
-  CmdArgs.push_back("-lc++");
-  CmdArgs.push_back("-lc++abi");
-  CmdArgs.push_back("-lunwind");
-}
-
-Tool *CloudABI::buildLinker() const {
-  return new tools::cloudabi::Linker(*this);
-}
-
-bool CloudABI::isPIEDefault() const {
-  // Only enable PIE on architectures that support PC-relative
-  // addressing. PC-relative addressing is required, as the process
-  // startup code must be able to relocate itself.
-  switch (getTriple().getArch()) {
-  case llvm::Triple::aarch64:
-  case llvm::Triple::x86_64:
-    return true;
-  default:
-    return false;
-  }
-}
-
-SanitizerMask CloudABI::getSupportedSanitizers() const {
-  SanitizerMask Res = ToolChain::getSupportedSanitizers();
-  Res |= SanitizerKind::SafeStack;
-  return Res;
-}
-
-SanitizerMask CloudABI::getDefaultSanitizers() const {
-  return SanitizerKind::SafeStack;
-}
-
-/// Haiku - Haiku tool chain which can call as(1) and ld(1) directly.
-
-Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
-  : Generic_ELF(D, Triple, Args) {
-
-}
-
-std::string Haiku::findLibCxxIncludePath() const {
-  return getDriver().SysRoot + "/system/develop/headers/c++/v1";
-}
-
-void Haiku::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
-                                     llvm::opt::ArgStringList &CC1Args) const {
-  addLibStdCXXIncludePaths(getDriver().SysRoot, "/system/develop/headers/c++",
-                           getTriple().str(), "", "", "", DriverArgs, CC1Args);
-}
-
-/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
-
-OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
-                 const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-  getFilePaths().push_back(getDriver().Dir + "/../lib");
-  getFilePaths().push_back("/usr/lib");
-}
-
-Tool *OpenBSD::buildAssembler() const {
-  return new tools::openbsd::Assembler(*this);
-}
-
-Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
-
-/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
-
-Bitrig::Bitrig(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-  getFilePaths().push_back(getDriver().Dir + "/../lib");
-  getFilePaths().push_back("/usr/lib");
-}
-
-Tool *Bitrig::buildAssembler() const {
-  return new tools::bitrig::Assembler(*this);
-}
-
-Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); }
-
-ToolChain::CXXStdlibType Bitrig::GetDefaultCXXStdlibType() const {
-  return ToolChain::CST_Libcxx;
-}
-
-void Bitrig::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
-                                      llvm::opt::ArgStringList &CC1Args) const {
-  std::string Triple = getTriple().str();
-  if (StringRef(Triple).startswith("amd64"))
-    Triple = "x86_64" + Triple.substr(5);
-  addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/c++/stdc++",
-                           Triple, "", "", "", DriverArgs, CC1Args);
-}
-
-void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
-                                 ArgStringList &CmdArgs) const {
-  switch (GetCXXStdlibType(Args)) {
-  case ToolChain::CST_Libcxx:
-    CmdArgs.push_back("-lc++");
-    CmdArgs.push_back("-lc++abi");
-    CmdArgs.push_back("-lpthread");
-    break;
-  case ToolChain::CST_Libstdcxx:
-    CmdArgs.push_back("-lstdc++");
-    break;
-  }
-}
-
-/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
-
-FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple,
-                 const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-
-  // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
-  // back to '/usr/lib' if it doesn't exist.
-  if ((Triple.getArch() == llvm::Triple::x86 ||
-       Triple.getArch() == llvm::Triple::ppc) &&
-      D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
-    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
-  else
-    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
-}
-
-ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const {
-  if (getTriple().getOSMajorVersion() >= 10)
-    return ToolChain::CST_Libcxx;
-  return ToolChain::CST_Libstdcxx;
-}
-
-void FreeBSD::addLibStdCxxIncludePaths(
-    const llvm::opt::ArgList &DriverArgs,
-    llvm::opt::ArgStringList &CC1Args) const {
-  addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/c++/4.2", "", "",
-                           "", "", DriverArgs, CC1Args);
-}
-
-void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
-                                  ArgStringList &CmdArgs) const {
-  CXXStdlibType Type = GetCXXStdlibType(Args);
-  bool Profiling = Args.hasArg(options::OPT_pg);
-
-  switch (Type) {
-  case ToolChain::CST_Libcxx:
-    CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
-    break;
-
-  case ToolChain::CST_Libstdcxx:
-    CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++");
-    break;
-  }
-}
-
-Tool *FreeBSD::buildAssembler() const {
-  return new tools::freebsd::Assembler(*this);
-}
-
-Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); }
-
-bool FreeBSD::UseSjLjExceptions(const ArgList &Args) const {
-  // FreeBSD uses SjLj exceptions on ARM oabi.
-  switch (getTriple().getEnvironment()) {
-  case llvm::Triple::GNUEABIHF:
-  case llvm::Triple::GNUEABI:
-  case llvm::Triple::EABI:
-    return false;
-
-  default:
-    return (getTriple().getArch() == llvm::Triple::arm ||
-            getTriple().getArch() == llvm::Triple::thumb);
-  }
-}
-
-bool FreeBSD::HasNativeLLVMSupport() const { return true; }
-
-bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
-
-SanitizerMask FreeBSD::getSupportedSanitizers() const {
-  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
-  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
-  const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
-                        getTriple().getArch() == llvm::Triple::mips64el;
-  SanitizerMask Res = ToolChain::getSupportedSanitizers();
-  Res |= SanitizerKind::Address;
-  Res |= SanitizerKind::Vptr;
-  if (IsX86_64 || IsMIPS64) {
-    Res |= SanitizerKind::Leak;
-    Res |= SanitizerKind::Thread;
-  }
-  if (IsX86 || IsX86_64) {
-    Res |= SanitizerKind::SafeStack;
-  }
-  return Res;
-}
-
-/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
-
-NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-  if (getDriver().UseStdLib) {
-    // When targeting a 32-bit platform, try the special directory used on
-    // 64-bit hosts, and only fall back to the main library directory if that
-    // doesn't work.
-    // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
-    // what all logic is needed to emulate the '=' prefix here.
-    switch (Triple.getArch()) {
-    case llvm::Triple::x86:
-      getFilePaths().push_back("=/usr/lib/i386");
-      break;
-    case llvm::Triple::arm:
-    case llvm::Triple::armeb:
-    case llvm::Triple::thumb:
-    case llvm::Triple::thumbeb:
-      switch (Triple.getEnvironment()) {
-      case llvm::Triple::EABI:
-      case llvm::Triple::GNUEABI:
-        getFilePaths().push_back("=/usr/lib/eabi");
-        break;
-      case llvm::Triple::EABIHF:
-      case llvm::Triple::GNUEABIHF:
-        getFilePaths().push_back("=/usr/lib/eabihf");
-        break;
-      default:
-        getFilePaths().push_back("=/usr/lib/oabi");
-        break;
-      }
-      break;
-    case llvm::Triple::mips64:
-    case llvm::Triple::mips64el:
-      if (tools::mips::hasMipsAbiArg(Args, "o32"))
-        getFilePaths().push_back("=/usr/lib/o32");
-      else if (tools::mips::hasMipsAbiArg(Args, "64"))
-        getFilePaths().push_back("=/usr/lib/64");
-      break;
-    case llvm::Triple::ppc:
-      getFilePaths().push_back("=/usr/lib/powerpc");
-      break;
-    case llvm::Triple::sparc:
-      getFilePaths().push_back("=/usr/lib/sparc");
-      break;
-    default:
-      break;
-    }
-
-    getFilePaths().push_back("=/usr/lib");
-  }
-}
-
-Tool *NetBSD::buildAssembler() const {
-  return new tools::netbsd::Assembler(*this);
-}
-
-Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
-
-ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
-  unsigned Major, Minor, Micro;
-  getTriple().getOSVersion(Major, Minor, Micro);
-  if (Major >= 7 || Major == 0) {
-    switch (getArch()) {
-    case llvm::Triple::aarch64:
-    case llvm::Triple::arm:
-    case llvm::Triple::armeb:
-    case llvm::Triple::thumb:
-    case llvm::Triple::thumbeb:
-    case llvm::Triple::ppc:
-    case llvm::Triple::ppc64:
-    case llvm::Triple::ppc64le:
-    case llvm::Triple::sparc:
-    case llvm::Triple::sparcv9:
-    case llvm::Triple::x86:
-    case llvm::Triple::x86_64:
-      return ToolChain::CST_Libcxx;
-    default:
-      break;
-    }
-  }
-  return ToolChain::CST_Libstdcxx;
-}
-
-std::string NetBSD::findLibCxxIncludePath() const {
-  return getDriver().SysRoot + "/usr/include/c++/";
-}
-
-void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
-                                      llvm::opt::ArgStringList &CC1Args) const {
-  addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/g++", "", "", "",
-                           "", DriverArgs, CC1Args);
-}
-
-/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
-
-Minix::Minix(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-  getFilePaths().push_back(getDriver().Dir + "/../lib");
-  getFilePaths().push_back("/usr/lib");
-}
-
-Tool *Minix::buildAssembler() const {
-  return new tools::minix::Assembler(*this);
-}
-
-Tool *Minix::buildLinker() const { return new tools::minix::Linker(*this); }
-
-static void addPathIfExists(const Driver &D, const Twine &Path,
-                            ToolChain::path_list &Paths) {
-  if (D.getVFS().exists(Path))
-    Paths.push_back(Path.str());
-}
-
-/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
-
-Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
-                 const ArgList &Args)
-    : Generic_GCC(D, Triple, Args) {
-
-  GCCInstallation.init(Triple, Args);
-
-  path_list &Paths = getFilePaths();
-  if (GCCInstallation.isValid())
-    addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);
-
-  addPathIfExists(D, getDriver().getInstalledDir(), Paths);
-  if (getDriver().getInstalledDir() != getDriver().Dir)
-    addPathIfExists(D, getDriver().Dir, Paths);
-
-  addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);
-
-  std::string LibPath = "/usr/lib/";
-  switch (Triple.getArch()) {
-  case llvm::Triple::x86:
-  case llvm::Triple::sparc:
-    break;
-  case llvm::Triple::x86_64:
-    LibPath += "amd64/";
-    break;
-  case llvm::Triple::sparcv9:
-    LibPath += "sparcv9/";
-    break;
-  default:
-    llvm_unreachable("Unsupported architecture");
-  }
-
-  addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);
-}
-
-Tool *Solaris::buildAssembler() const {
-  return new tools::solaris::Assembler(*this);
-}
-
-Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
-
-void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
-                                           ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
-      DriverArgs.hasArg(options::OPT_nostdincxx))
-    return;
-
-  // Include the support directory for things like xlocale and fudged system
-  // headers.
-  // FIXME: This is a weird mix of libc++ and libstdc++. We should also be
-  // checking the value of -stdlib= here and adding the includes for libc++
-  // rather than libstdc++ if it's requested.
-  addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris");
-
-  if (GCCInstallation.isValid()) {
-    GCCVersion Version = GCCInstallation.getVersion();
-    addSystemInclude(DriverArgs, CC1Args,
-                     getDriver().SysRoot + "/usr/gcc/" +
-                     Version.MajorStr + "." +
-                     Version.MinorStr +
-                     "/include/c++/" + Version.Text);
-    addSystemInclude(DriverArgs, CC1Args,
-                     getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr +
-                     "." + Version.MinorStr + "/include/c++/" +
-                     Version.Text + "/" +
-                     GCCInstallation.getTriple().str());
-  }
-}
-
-/// \brief Get our best guess at the multiarch triple for a target.
-///
-/// Debian-based systems are starting to use a multiarch setup where they use
-/// a target-triple directory in the library and header search paths.
-/// Unfortunately, this triple does not align with the vanilla target triple,
-/// so we provide a rough mapping here.
-static std::string getMultiarchTriple(const Driver &D,
-                                      const llvm::Triple &TargetTriple,
-                                      StringRef SysRoot) {
-  llvm::Triple::EnvironmentType TargetEnvironment =
-      TargetTriple.getEnvironment();
-
-  // For most architectures, just use whatever we have rather than trying to be
-  // clever.
-  switch (TargetTriple.getArch()) {
-  default:
-    break;
-
-  // We use the existence of '/lib/<triple>' as a directory to detect some
-  // common linux triples that don't quite match the Clang triple for both
-  // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
-  // regardless of what the actual target triple is.
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-    if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
-      if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf"))
-        return "arm-linux-gnueabihf";
-    } else {
-      if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi"))
-        return "arm-linux-gnueabi";
-    }
-    break;
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumbeb:
-    if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
-      if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
-        return "armeb-linux-gnueabihf";
-    } else {
-      if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi"))
-        return "armeb-linux-gnueabi";
-    }
-    break;
-  case llvm::Triple::x86:
-    if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu"))
-      return "i386-linux-gnu";
-    break;
-  case llvm::Triple::x86_64:
-    // We don't want this for x32, otherwise it will match x86_64 libs
-    if (TargetEnvironment != llvm::Triple::GNUX32 &&
-        D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu"))
-      return "x86_64-linux-gnu";
-    break;
-  case llvm::Triple::aarch64:
-    if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu"))
-      return "aarch64-linux-gnu";
-    break;
-  case llvm::Triple::aarch64_be:
-    if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
-      return "aarch64_be-linux-gnu";
-    break;
-  case llvm::Triple::mips:
-    if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))
-      return "mips-linux-gnu";
-    break;
-  case llvm::Triple::mipsel:
-    if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))
-      return "mipsel-linux-gnu";
-    break;
-  case llvm::Triple::mips64:
-    if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
-      return "mips64-linux-gnu";
-    if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
-      return "mips64-linux-gnuabi64";
-    break;
-  case llvm::Triple::mips64el:
-    if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))
-      return "mips64el-linux-gnu";
-    if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
-      return "mips64el-linux-gnuabi64";
-    break;
-  case llvm::Triple::ppc:
-    if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
-      return "powerpc-linux-gnuspe";
-    if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
-      return "powerpc-linux-gnu";
-    break;
-  case llvm::Triple::ppc64:
-    if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))
-      return "powerpc64-linux-gnu";
-    break;
-  case llvm::Triple::ppc64le:
-    if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
-      return "powerpc64le-linux-gnu";
-    break;
-  case llvm::Triple::sparc:
-    if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu"))
-      return "sparc-linux-gnu";
-    break;
-  case llvm::Triple::sparcv9:
-    if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu"))
-      return "sparc64-linux-gnu";
-    break;
-  case llvm::Triple::systemz:
-    if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu"))
-      return "s390x-linux-gnu";
-    break;
-  }
-  return TargetTriple.str();
-}
-
-static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
-  if (isMipsArch(Triple.getArch())) {
-    if (Triple.isAndroid()) {
-      StringRef CPUName;
-      StringRef ABIName;
-      tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
-      if (CPUName == "mips32r6")
-        return "libr6";
-      if (CPUName == "mips32r2")
-        return "libr2";
-    }
-    // lib32 directory has a special meaning on MIPS targets.
-    // It contains N32 ABI binaries. Use this folder if produce
-    // code for N32 ABI only.
-    if (tools::mips::hasMipsAbiArg(Args, "n32"))
-      return "lib32";
-    return Triple.isArch32Bit() ? "lib" : "lib64";
-  }
-
-  // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and
-  // using that variant while targeting other architectures causes problems
-  // because the libraries are laid out in shared system roots that can't cope
-  // with a 'lib32' library search path being considered. So we only enable
-  // them when we know we may need it.
-  //
-  // FIXME: This is a bit of a hack. We should really unify this code for
-  // reasoning about oslibdir spellings with the lib dir spellings in the
-  // GCCInstallationDetector, but that is a more significant refactoring.
-  if (Triple.getArch() == llvm::Triple::x86 ||
-      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";
-}
-
-static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
-                                  const Multilib &Multilib,
-                                  StringRef InstallPath,
-                                  ToolChain::path_list &Paths) {
-  if (const auto &PathsCallback = Multilibs.filePathsCallback())
-    for (const auto &Path : PathsCallback(Multilib))
-      addPathIfExists(D, InstallPath + Path, Paths);
-}
-
-Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-  GCCInstallation.init(Triple, Args);
-  Multilibs = GCCInstallation.getMultilibs();
-  llvm::Triple::ArchType Arch = Triple.getArch();
-  std::string SysRoot = computeSysRoot();
-
-  // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
-  // least) put various tools in a triple-prefixed directory off of the parent
-  // of the GCC installation. We use the GCC triple here to ensure that we end
-  // up with tools that support the same amount of cross compiling as the
-  // detected GCC installation. For example, if we find a GCC installation
-  // targeting x86_64, but it is a bi-arch GCC installation, it can also be
-  // used to target i386.
-  // FIXME: This seems unlikely to be Linux-specific.
-  ToolChain::path_list &PPaths = getProgramPaths();
-  PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
-                         GCCInstallation.getTriple().str() + "/bin")
-                       .str());
-
-  Distro Distro(D.getVFS());
-
-  if (Distro.IsOpenSUSE() || Distro.IsUbuntu()) {
-    ExtraOpts.push_back("-z");
-    ExtraOpts.push_back("relro");
-  }
-
-  if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
-    ExtraOpts.push_back("-X");
-
-  const bool IsAndroid = Triple.isAndroid();
-  const bool IsMips = isMipsArch(Arch);
-
-  if (IsMips && !SysRoot.empty())
-    ExtraOpts.push_back("--sysroot=" + SysRoot);
-
-  // Do not use 'gnu' hash style for Mips targets because .gnu.hash
-  // and the MIPS ABI require .dynsym to be sorted in different ways.
-  // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
-  // ABI requires a mapping between the GOT and the symbol table.
-  // Android loader does not support .gnu.hash.
-  if (!IsMips && !IsAndroid) {
-    if (Distro.IsRedhat() || Distro.IsOpenSUSE() ||
-        (Distro.IsUbuntu() && Distro >= Distro::UbuntuMaverick))
-      ExtraOpts.push_back("--hash-style=gnu");
-
-    if (Distro.IsDebian() || Distro.IsOpenSUSE() || Distro == Distro::UbuntuLucid ||
-        Distro == Distro::UbuntuJaunty || Distro == Distro::UbuntuKarmic)
-      ExtraOpts.push_back("--hash-style=both");
-  }
-
-  if (Distro.IsRedhat() && Distro != Distro::RHEL5 && Distro != Distro::RHEL6)
-    ExtraOpts.push_back("--no-add-needed");
-
-#ifdef ENABLE_LINKER_BUILD_ID
-  ExtraOpts.push_back("--build-id");
-#endif
-
-  if (Distro.IsOpenSUSE())
-    ExtraOpts.push_back("--enable-new-dtags");
-
-  // The selection of paths to try here is designed to match the patterns which
-  // the GCC driver itself uses, as this is part of the GCC-compatible driver.
-  // This was determined by running GCC in a fake filesystem, creating all
-  // possible permutations of these directories, and seeing which ones it added
-  // to the link paths.
-  path_list &Paths = getFilePaths();
-
-  const std::string OSLibDir = getOSLibDir(Triple, Args);
-  const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
-
-  // Add the multilib suffixed paths where they are available.
-  if (GCCInstallation.isValid()) {
-    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
-    const std::string &LibPath = GCCInstallation.getParentLibPath();
-    const Multilib &Multilib = GCCInstallation.getMultilib();
-    const MultilibSet &Multilibs = GCCInstallation.getMultilibs();
-
-    // Add toolchain / multilib specific file paths.
-    addMultilibsFilePaths(D, Multilibs, Multilib,
-                          GCCInstallation.getInstallPath(), Paths);
-
-    // Sourcery CodeBench MIPS toolchain holds some libraries under
-    // a biarch-like suffix of the GCC installation.
-    addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(),
-                    Paths);
-
-    // GCC cross compiling toolchains will install target libraries which ship
-    // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
-    // any part of the GCC installation in
-    // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
-    // debatable, but is the reality today. We need to search this tree even
-    // when we have a sysroot somewhere else. It is the responsibility of
-    // whomever is doing the cross build targeting a sysroot using a GCC
-    // installation that is *not* within the system root to ensure two things:
-    //
-    //  1) Any DSOs that are linked in from this tree or from the install path
-    //     above must be present on the system root and found via an
-    //     appropriate rpath.
-    //  2) There must not be libraries installed into
-    //     <prefix>/<triple>/<libdir> unless they should be preferred over
-    //     those within the system root.
-    //
-    // Note that this matches the GCC behavior. See the below comment for where
-    // Clang diverges from GCC's behavior.
-    addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" +
-                           OSLibDir + Multilib.osSuffix(),
-                    Paths);
-
-    // If the GCC installation we found is inside of the sysroot, we want to
-    // prefer libraries installed in the parent prefix of the GCC installation.
-    // It is important to *not* use these paths when the GCC installation is
-    // outside of the system root as that can pick up unintended libraries.
-    // This usually happens when there is an external cross compiler on the
-    // host system, and a more minimal sysroot available that is the target of
-    // the cross. Note that GCC does include some of these directories in some
-    // configurations but this seems somewhere between questionable and simply
-    // a bug.
-    if (StringRef(LibPath).startswith(SysRoot)) {
-      addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
-      addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
-    }
-  }
-
-  // Similar to the logic for GCC above, if we currently running Clang inside
-  // of the requested system root, add its parent library paths to
-  // those searched.
-  // FIXME: It's not clear whether we should use the driver's installed
-  // directory ('Dir' below) or the ResourceDir.
-  if (StringRef(D.Dir).startswith(SysRoot)) {
-    addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths);
-    addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
-  }
-
-  addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
-  addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
-  addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
-  addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
-
-  // Try walking via the GCC triple path in case of biarch or multiarch GCC
-  // installations with strange symlinks.
-  if (GCCInstallation.isValid()) {
-    addPathIfExists(D,
-                    SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
-                        "/../../" + OSLibDir,
-                    Paths);
-
-    // Add the 'other' biarch variant path
-    Multilib BiarchSibling;
-    if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
-      addPathIfExists(D, GCCInstallation.getInstallPath() +
-                             BiarchSibling.gccSuffix(),
-                      Paths);
-    }
-
-    // See comments above on the multilib variant for details of why this is
-    // included even from outside the sysroot.
-    const std::string &LibPath = GCCInstallation.getParentLibPath();
-    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
-    const Multilib &Multilib = GCCInstallation.getMultilib();
-    addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" +
-                           Multilib.osSuffix(),
-                    Paths);
-
-    // See comments above on the multilib variant for details of why this is
-    // only included from within the sysroot.
-    if (StringRef(LibPath).startswith(SysRoot))
-      addPathIfExists(D, LibPath, Paths);
-  }
-
-  // Similar to the logic for GCC above, if we are currently running Clang
-  // inside of the requested system root, add its parent library path to those
-  // searched.
-  // FIXME: It's not clear whether we should use the driver's installed
-  // directory ('Dir' below) or the ResourceDir.
-  if (StringRef(D.Dir).startswith(SysRoot))
-    addPathIfExists(D, D.Dir + "/../lib", Paths);
-
-  addPathIfExists(D, SysRoot + "/lib", Paths);
-  addPathIfExists(D, SysRoot + "/usr/lib", Paths);
-}
-
-bool Linux::HasNativeLLVMSupport() const { return true; }
-
-Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); }
-
-Tool *Linux::buildAssembler() const {
-  return new tools::gnutools::Assembler(*this);
-}
-
-std::string Linux::computeSysRoot() const {
-  if (!getDriver().SysRoot.empty())
-    return getDriver().SysRoot;
-
-  if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
-    return std::string();
-
-  // Standalone MIPS toolchains use different names for sysroot folder
-  // and put it into different places. Here we try to check some known
-  // variants.
-
-  const StringRef InstallDir = GCCInstallation.getInstallPath();
-  const StringRef TripleStr = GCCInstallation.getTriple().str();
-  const Multilib &Multilib = GCCInstallation.getMultilib();
-
-  std::string Path =
-      (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
-          .str();
-
-  if (getVFS().exists(Path))
-    return Path;
-
-  Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
-
-  if (getVFS().exists(Path))
-    return Path;
-
-  return std::string();
-}
-
-std::string Linux::getDynamicLinker(const ArgList &Args) const {
-  const llvm::Triple::ArchType Arch = getArch();
-  const llvm::Triple &Triple = getTriple();
-
-  const Distro Distro(getDriver().getVFS());
-
-  if (Triple.isAndroid())
-    return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
-
-  if (Triple.isMusl()) {
-    std::string ArchName;
-    bool IsArm = false;
-
-    switch (Arch) {
-    case llvm::Triple::arm:
-    case llvm::Triple::thumb:
-      ArchName = "arm";
-      IsArm = true;
-      break;
-    case llvm::Triple::armeb:
-    case llvm::Triple::thumbeb:
-      ArchName = "armeb";
-      IsArm = true;
-      break;
-    default:
-      ArchName = Triple.getArchName().str();
-    }
-    if (IsArm &&
-        (Triple.getEnvironment() == llvm::Triple::MuslEABIHF ||
-         tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard))
-      ArchName += "hf";
-
-    return "/lib/ld-musl-" + ArchName + ".so.1";
-  }
-
-  std::string LibDir;
-  std::string Loader;
-
-  switch (Arch) {
-  default:
-    llvm_unreachable("unsupported architecture");
-
-  case llvm::Triple::aarch64:
-    LibDir = "lib";
-    Loader = "ld-linux-aarch64.so.1";
-    break;
-  case llvm::Triple::aarch64_be:
-    LibDir = "lib";
-    Loader = "ld-linux-aarch64_be.so.1";
-    break;
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumbeb: {
-    const bool HF =
-        Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
-        tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard;
-
-    LibDir = "lib";
-    Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3";
-    break;
-  }
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el: {
-    bool LE = (Triple.getArch() == llvm::Triple::mipsel) ||
-              (Triple.getArch() == llvm::Triple::mips64el);
-    bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple);
-
-    LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple);
-
-    if (tools::mips::isUCLibc(Args))
-      Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
-    else if (!Triple.hasEnvironment() &&
-             Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies)
-      Loader = LE ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1";
-    else
-      Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
-
-    break;
-  }
-  case llvm::Triple::ppc:
-    LibDir = "lib";
-    Loader = "ld.so.1";
-    break;
-  case llvm::Triple::ppc64:
-    LibDir = "lib64";
-    Loader =
-        (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1";
-    break;
-  case llvm::Triple::ppc64le:
-    LibDir = "lib64";
-    Loader =
-        (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2";
-    break;
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel:
-    LibDir = "lib";
-    Loader = "ld-linux.so.2";
-    break;
-  case llvm::Triple::sparcv9:
-    LibDir = "lib64";
-    Loader = "ld-linux.so.2";
-    break;
-  case llvm::Triple::systemz:
-    LibDir = "lib";
-    Loader = "ld64.so.1";
-    break;
-  case llvm::Triple::x86:
-    LibDir = "lib";
-    Loader = "ld-linux.so.2";
-    break;
-  case llvm::Triple::x86_64: {
-    bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32;
-
-    LibDir = X32 ? "libx32" : "lib64";
-    Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
-    break;
-  }
-  }
-
-  if (Distro == Distro::Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor ||
-                                    Triple.getVendor() == llvm::Triple::PC))
-    return "/usr/" + Triple.str() + "/lib/" + Loader;
-  return "/" + LibDir + "/" + Loader;
-}
-
-void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                      ArgStringList &CC1Args) const {
-  const Driver &D = getDriver();
-  std::string SysRoot = computeSysRoot();
-
-  if (DriverArgs.hasArg(options::OPT_nostdinc))
-    return;
-
-  if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
-    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
-
-  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
-    SmallString<128> P(D.ResourceDir);
-    llvm::sys::path::append(P, "include");
-    addSystemInclude(DriverArgs, CC1Args, P);
-  }
-
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
-    return;
-
-  // Check for configure-time C include directories.
-  StringRef CIncludeDirs(C_INCLUDE_DIRS);
-  if (CIncludeDirs != "") {
-    SmallVector<StringRef, 5> dirs;
-    CIncludeDirs.split(dirs, ":");
-    for (StringRef dir : dirs) {
-      StringRef Prefix =
-          llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
-      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
-    }
-    return;
-  }
-
-  // Lacking those, try to detect the correct set of system includes for the
-  // target triple.
-
-  // Add include directories specific to the selected multilib set and multilib.
-  if (GCCInstallation.isValid()) {
-    const auto &Callback = Multilibs.includeDirsCallback();
-    if (Callback) {
-      for (const auto &Path : Callback(GCCInstallation.getMultilib()))
-        addExternCSystemIncludeIfExists(
-            DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path);
-    }
-  }
-
-  // Implement generic Debian multiarch support.
-  const StringRef X86_64MultiarchIncludeDirs[] = {
-      "/usr/include/x86_64-linux-gnu",
-
-      // FIXME: These are older forms of multiarch. It's not clear that they're
-      // in use in any released version of Debian, so we should consider
-      // removing them.
-      "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"};
-  const StringRef X86MultiarchIncludeDirs[] = {
-      "/usr/include/i386-linux-gnu",
-
-      // FIXME: These are older forms of multiarch. It's not clear that they're
-      // in use in any released version of Debian, so we should consider
-      // removing them.
-      "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
-      "/usr/include/i486-linux-gnu"};
-  const StringRef AArch64MultiarchIncludeDirs[] = {
-      "/usr/include/aarch64-linux-gnu"};
-  const StringRef ARMMultiarchIncludeDirs[] = {
-      "/usr/include/arm-linux-gnueabi"};
-  const StringRef ARMHFMultiarchIncludeDirs[] = {
-      "/usr/include/arm-linux-gnueabihf"};
-  const StringRef ARMEBMultiarchIncludeDirs[] = {
-      "/usr/include/armeb-linux-gnueabi"};
-  const StringRef ARMEBHFMultiarchIncludeDirs[] = {
-      "/usr/include/armeb-linux-gnueabihf"};
-  const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"};
-  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"};
-  const StringRef SparcMultiarchIncludeDirs[] = {
-      "/usr/include/sparc-linux-gnu"};
-  const StringRef Sparc64MultiarchIncludeDirs[] = {
-      "/usr/include/sparc64-linux-gnu"};
-  const StringRef SYSTEMZMultiarchIncludeDirs[] = {
-      "/usr/include/s390x-linux-gnu"};
-  ArrayRef<StringRef> MultiarchIncludeDirs;
-  switch (getTriple().getArch()) {
-  case llvm::Triple::x86_64:
-    MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
-    break;
-  case llvm::Triple::x86:
-    MultiarchIncludeDirs = X86MultiarchIncludeDirs;
-    break;
-  case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_be:
-    MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
-    break;
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-    if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
-      MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
-    else
-      MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
-    break;
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumbeb:
-    if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
-      MultiarchIncludeDirs = ARMEBHFMultiarchIncludeDirs;
-    else
-      MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs;
-    break;
-  case llvm::Triple::mips:
-    MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
-    break;
-  case llvm::Triple::mipsel:
-    MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
-    break;
-  case llvm::Triple::mips64:
-    MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
-    break;
-  case llvm::Triple::mips64el:
-    MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
-    break;
-  case llvm::Triple::ppc:
-    MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
-    break;
-  case llvm::Triple::ppc64:
-    MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
-    break;
-  case llvm::Triple::ppc64le:
-    MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
-    break;
-  case llvm::Triple::sparc:
-    MultiarchIncludeDirs = SparcMultiarchIncludeDirs;
-    break;
-  case llvm::Triple::sparcv9:
-    MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs;
-    break;
-  case llvm::Triple::systemz:
-    MultiarchIncludeDirs = SYSTEMZMultiarchIncludeDirs;
-    break;
-  default:
-    break;
-  }
-  for (StringRef Dir : MultiarchIncludeDirs) {
-    if (D.getVFS().exists(SysRoot + Dir)) {
-      addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);
-      break;
-    }
-  }
-
-  if (getTriple().getOS() == llvm::Triple::RTEMS)
-    return;
-
-  // Add an include of '/include' directly. This isn't provided by default by
-  // system GCCs, but is often used with cross-compiling GCCs, and harmless to
-  // add even when Clang is acting as-if it were a system compiler.
-  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
-
-  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
-}
-
-static std::string DetectLibcxxIncludePath(StringRef base) {
-  std::error_code EC;
-  int MaxVersion = 0;
-  std::string MaxVersionString = "";
-  for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE;
-       LI = LI.increment(EC)) {
-    StringRef VersionText = llvm::sys::path::filename(LI->path());
-    int Version;
-    if (VersionText[0] == 'v' &&
-        !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
-      if (Version > MaxVersion) {
-        MaxVersion = Version;
-        MaxVersionString = VersionText;
-      }
-    }
-  }
-  return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
-}
-
-std::string Linux::findLibCxxIncludePath() const {
-  const std::string LibCXXIncludePathCandidates[] = {
-      DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"),
-      // If this is a development, non-installed, clang, libcxx will
-      // not be found at ../include/c++ but it likely to be found at
-      // one of the following two locations:
-      DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/local/include/c++"),
-      DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/include/c++") };
-  for (const auto &IncludePath : LibCXXIncludePathCandidates) {
-    if (IncludePath.empty() || !getVFS().exists(IncludePath))
-      continue;
-    // Use the first candidate that exists.
-    return IncludePath;
-  }
-  return "";
-}
-
-void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
-                                     llvm::opt::ArgStringList &CC1Args) const {
-  // We need a detected GCC installation on Linux to provide libstdc++'s
-  // headers.
-  if (!GCCInstallation.isValid())
-    return;
-
-  // By default, look for the C++ headers in an include directory adjacent to
-  // the lib directory of the GCC installation. Note that this is expect to be
-  // equivalent to '/usr/include/c++/X.Y' in almost all cases.
-  StringRef LibDir = GCCInstallation.getParentLibPath();
-  StringRef InstallDir = GCCInstallation.getInstallPath();
-  StringRef TripleStr = GCCInstallation.getTriple().str();
-  const Multilib &Multilib = GCCInstallation.getMultilib();
-  const std::string GCCMultiarchTriple = getMultiarchTriple(
-      getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
-  const std::string TargetMultiarchTriple =
-      getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
-  const GCCVersion &Version = GCCInstallation.getVersion();
-
-  // The primary search for libstdc++ supports multiarch variants.
-  if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
-                               "/c++/" + Version.Text, TripleStr,
-                               GCCMultiarchTriple, TargetMultiarchTriple,
-                               Multilib.includeSuffix(), DriverArgs, CC1Args))
-    return;
-
-  // Otherwise, fall back on a bunch of options which don't use multiarch
-  // layouts for simplicity.
-  const std::string LibStdCXXIncludePathCandidates[] = {
-      // Gentoo is weird and places its headers inside the GCC install,
-      // so if the first attempt to find the headers fails, try these patterns.
-      InstallDir.str() + "/include/g++-v" + Version.Text,
-      InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
-          Version.MinorStr,
-      InstallDir.str() + "/include/g++-v" + Version.MajorStr,
-      // Android standalone toolchain has C++ headers in yet another place.
-      LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
-      // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
-      // without a subdirectory corresponding to the gcc version.
-      LibDir.str() + "/../include/c++",
-  };
-
-  for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
-    if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
-                                 /*GCCMultiarchTriple*/ "",
-                                 /*TargetMultiarchTriple*/ "",
-                                 Multilib.includeSuffix(), DriverArgs, CC1Args))
-      break;
-  }
-}
-
-void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs,
-                               ArgStringList &CC1Args) const {
-  CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
-}
-
-void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
-                                ArgStringList &CC1Args) const {
-  if (GCCInstallation.isValid()) {
-    CC1Args.push_back("-isystem");
-    CC1Args.push_back(DriverArgs.MakeArgString(
-        GCCInstallation.getParentLibPath() + "/../" +
-        GCCInstallation.getTriple().str() + "/include"));
-  }
-}
-
-bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
-
-SanitizerMask Linux::getSupportedSanitizers() const {
-  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
-  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
-  const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
-                        getTriple().getArch() == llvm::Triple::mips64el;
-  const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 ||
-                           getTriple().getArch() == llvm::Triple::ppc64le;
-  const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
-                         getTriple().getArch() == llvm::Triple::aarch64_be;
-  SanitizerMask Res = ToolChain::getSupportedSanitizers();
-  Res |= SanitizerKind::Address;
-  Res |= SanitizerKind::KernelAddress;
-  Res |= SanitizerKind::Vptr;
-  Res |= SanitizerKind::SafeStack;
-  if (IsX86_64 || IsMIPS64 || IsAArch64)
-    Res |= SanitizerKind::DataFlow;
-  if (IsX86_64 || IsMIPS64 || IsAArch64)
-    Res |= SanitizerKind::Leak;
-  if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64)
-    Res |= SanitizerKind::Thread;
-  if (IsX86_64 || IsMIPS64 || IsPowerPC64 || IsAArch64)
-    Res |= SanitizerKind::Memory;
-  if (IsX86_64 || IsMIPS64)
-    Res |= SanitizerKind::Efficiency;
-  if (IsX86 || IsX86_64) {
-    Res |= SanitizerKind::Function;
-  }
-  return Res;
-}
-
-void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
-                             llvm::opt::ArgStringList &CmdArgs) const {
-  if (!needsProfileRT(Args)) return;
-
-  // Add linker option -u__llvm_runtime_variable to cause runtime
-  // initialization module to be linked in.
-  if (!Args.hasArg(options::OPT_coverage))
-    CmdArgs.push_back(Args.MakeArgString(
-        Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
-  ToolChain::addProfileRTLibs(Args, CmdArgs);
-}
-
-/// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly.
-
-Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
-                 const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-
-  getFilePaths().push_back(D.SysRoot + "/lib");
-  getFilePaths().push_back(D.ResourceDir + "/lib/fuchsia");
-
-  // Use LLD by default.
-  DefaultLinker = "lld";
-}
-
-Tool *Fuchsia::buildAssembler() const {
-  return new tools::gnutools::Assembler(*this);
-}
-
-Tool *Fuchsia::buildLinker() const {
-  return new tools::fuchsia::Linker(*this);
-}
-
-ToolChain::RuntimeLibType Fuchsia::GetRuntimeLibType(
-    const ArgList &Args) const {
-  if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
-    StringRef Value = A->getValue();
-    if (Value != "compiler-rt")
-      getDriver().Diag(diag::err_drv_invalid_rtlib_name)
-        << A->getAsString(Args);
-  }
-
-  return ToolChain::RLT_CompilerRT;
-}
-
-ToolChain::CXXStdlibType
-Fuchsia::GetCXXStdlibType(const ArgList &Args) const {
-  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
-    StringRef Value = A->getValue();
-    if (Value != "libc++")
-      getDriver().Diag(diag::err_drv_invalid_stdlib_name)
-        << A->getAsString(Args);
-  }
-
-  return ToolChain::CST_Libcxx;
-}
-
-void Fuchsia::addClangTargetOptions(const ArgList &DriverArgs,
-                                    ArgStringList &CC1Args) const {
-  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
-                         options::OPT_fno_use_init_array, true))
-    CC1Args.push_back("-fuse-init-array");
-}
-
-void Fuchsia::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                        ArgStringList &CC1Args) const {
-  const Driver &D = getDriver();
-
-  if (DriverArgs.hasArg(options::OPT_nostdinc))
-    return;
-
-  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
-    SmallString<128> P(D.ResourceDir);
-    llvm::sys::path::append(P, "include");
-    addSystemInclude(DriverArgs, CC1Args, P);
-  }
-
-  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
-    return;
-
-  // Check for configure-time C include directories.
-  StringRef CIncludeDirs(C_INCLUDE_DIRS);
-  if (CIncludeDirs != "") {
-    SmallVector<StringRef, 5> dirs;
-    CIncludeDirs.split(dirs, ":");
-    for (StringRef dir : dirs) {
-      StringRef Prefix =
-          llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : "";
-      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
-    }
-    return;
-  }
-
-  addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include");
-}
-
-std::string Fuchsia::findLibCxxIncludePath() const {
-  return getDriver().SysRoot + "/include/c++/v1";
-}
-
-void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args,
-                                  ArgStringList &CmdArgs) const {
-  (void) GetCXXStdlibType(Args);
-  CmdArgs.push_back("-lc++");
-  CmdArgs.push_back("-lc++abi");
-  CmdArgs.push_back("-lunwind");
-}
-
-/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
-
-DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
-                     const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-
-  // Path mangling to find libexec
-  getProgramPaths().push_back(getDriver().getInstalledDir());
-  if (getDriver().getInstalledDir() != getDriver().Dir)
-    getProgramPaths().push_back(getDriver().Dir);
-
-  getFilePaths().push_back(getDriver().Dir + "/../lib");
-  getFilePaths().push_back("/usr/lib");
-  getFilePaths().push_back("/usr/lib/gcc50");
-}
-
-Tool *DragonFly::buildAssembler() const {
-  return new tools::dragonfly::Assembler(*this);
-}
-
-Tool *DragonFly::buildLinker() const {
-  return new tools::dragonfly::Linker(*this);
-}
-
-/// CUDA toolchain.  Our assembler is ptxas, and our "linker" is fatbinary,
-/// which isn't properly a linker but nonetheless performs the step of stitching
-/// together object files from the assembler into a single blob.
-
-CudaToolChain::CudaToolChain(const Driver &D, const llvm::Triple &Triple,
-                             const ToolChain &HostTC, const ArgList &Args)
-    : ToolChain(D, Triple, Args), HostTC(HostTC),
-      CudaInstallation(D, Triple, Args) {
-  if (CudaInstallation.isValid())
-    getProgramPaths().push_back(CudaInstallation.getBinPath());
-}
-
-void CudaToolChain::addClangTargetOptions(
-    const llvm::opt::ArgList &DriverArgs,
-    llvm::opt::ArgStringList &CC1Args) const {
-  HostTC.addClangTargetOptions(DriverArgs, CC1Args);
-
-  CC1Args.push_back("-fcuda-is-device");
-
-  if (DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,
-                         options::OPT_fno_cuda_flush_denormals_to_zero, false))
-    CC1Args.push_back("-fcuda-flush-denormals-to-zero");
-
-  if (DriverArgs.hasFlag(options::OPT_fcuda_approx_transcendentals,
-                         options::OPT_fno_cuda_approx_transcendentals, false))
-    CC1Args.push_back("-fcuda-approx-transcendentals");
-
-  if (DriverArgs.hasArg(options::OPT_nocudalib))
-    return;
-
-  StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
-  assert(!GpuArch.empty() && "Must have an explicit GPU arch.");
-  std::string LibDeviceFile = CudaInstallation.getLibDeviceFile(GpuArch);
-
-  if (LibDeviceFile.empty()) {
-    getDriver().Diag(diag::err_drv_no_cuda_libdevice) << GpuArch;
-    return;
-  }
-
-  CC1Args.push_back("-mlink-cuda-bitcode");
-  CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
-
-  // Libdevice in CUDA-7.0 requires PTX version that's more recent
-  // than LLVM defaults to. Use PTX4.2 which is the PTX version that
-  // came with CUDA-7.0.
-  CC1Args.push_back("-target-feature");
-  CC1Args.push_back("+ptx42");
-}
-
-void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
-                                       ArgStringList &CC1Args) const {
-  // Check our CUDA version if we're going to include the CUDA headers.
-  if (!DriverArgs.hasArg(options::OPT_nocudainc) &&
-      !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) {
-    StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
-    assert(!Arch.empty() && "Must have an explicit GPU arch.");
-    CudaInstallation.CheckCudaVersionSupportsArch(StringToCudaArch(Arch));
-  }
-  CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
-}
-
-llvm::opt::DerivedArgList *
-CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
-                             StringRef BoundArch,
-                             Action::OffloadKind DeviceOffloadKind) const {
-  DerivedArgList *DAL =
-      HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind);
-  if (!DAL)
-    DAL = new DerivedArgList(Args.getBaseArgs());
-
-  const OptTable &Opts = getDriver().getOpts();
-
-  for (Arg *A : Args) {
-    if (A->getOption().matches(options::OPT_Xarch__)) {
-      // Skip this argument unless the architecture matches BoundArch
-      if (BoundArch.empty() || A->getValue(0) != BoundArch)
-        continue;
-
-      unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
-      unsigned Prev = Index;
-      std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
-
-      // If the argument parsing failed or more than one argument was
-      // consumed, the -Xarch_ argument's parameter tried to consume
-      // extra arguments. Emit an error and ignore.
-      //
-      // We also want to disallow any options which would alter the
-      // driver behavior; that isn't going to work in our model. We
-      // use isDriverOption() as an approximation, although things
-      // like -O4 are going to slip through.
-      if (!XarchArg || Index > Prev + 1) {
-        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
-            << A->getAsString(Args);
-        continue;
-      } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
-        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
-            << A->getAsString(Args);
-        continue;
-      }
-      XarchArg->setBaseArg(A);
-      A = XarchArg.release();
-      DAL->AddSynthesizedArg(A);
-    }
-    DAL->append(A);
-  }
-
-  if (!BoundArch.empty()) {
-    DAL->eraseArg(options::OPT_march_EQ);
-    DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), BoundArch);
-  }
-  return DAL;
-}
-
-Tool *CudaToolChain::buildAssembler() const {
-  return new tools::NVPTX::Assembler(*this);
-}
-
-Tool *CudaToolChain::buildLinker() const {
-  return new tools::NVPTX::Linker(*this);
-}
-
-void CudaToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {
-  HostTC.addClangWarningOptions(CC1Args);
-}
-
-ToolChain::CXXStdlibType
-CudaToolChain::GetCXXStdlibType(const ArgList &Args) const {
-  return HostTC.GetCXXStdlibType(Args);
-}
-
-void CudaToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                              ArgStringList &CC1Args) const {
-  HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
-}
-
-void CudaToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args,
-                                                 ArgStringList &CC1Args) const {
-  HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
-}
-
-void CudaToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
-                                        ArgStringList &CC1Args) const {
-  HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
-}
-
-SanitizerMask CudaToolChain::getSupportedSanitizers() const {
-  // The CudaToolChain only supports sanitizers in the sense that it allows
-  // sanitizer arguments on the command line if they are supported by the host
-  // toolchain. The CudaToolChain will actually ignore any command line
-  // arguments for any of these "supported" sanitizers. That means that no
-  // sanitization of device code is actually supported at this time.
-  //
-  // This behavior is necessary because the host and device toolchains
-  // invocations often share the command line, so the device toolchain must
-  // tolerate flags meant only for the host toolchain.
-  return HostTC.getSupportedSanitizers();
-}
-
-/// XCore tool chain
-XCoreToolChain::XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
-                               const ArgList &Args)
-    : ToolChain(D, Triple, Args) {
-  // ProgramPaths are found via 'PATH' environment variable.
-}
-
-Tool *XCoreToolChain::buildAssembler() const {
-  return new tools::XCore::Assembler(*this);
-}
-
-Tool *XCoreToolChain::buildLinker() const {
-  return new tools::XCore::Linker(*this);
-}
-
-bool XCoreToolChain::isPICDefault() const { return false; }
-
-bool XCoreToolChain::isPIEDefault() const { return false; }
-
-bool XCoreToolChain::isPICDefaultForced() const { return false; }
-
-bool XCoreToolChain::SupportsProfiling() const { return false; }
-
-bool XCoreToolChain::hasBlocksRuntime() const { return false; }
-
-void XCoreToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                               ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
-      DriverArgs.hasArg(options::OPT_nostdlibinc))
-    return;
-  if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
-    SmallVector<StringRef, 4> Dirs;
-    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
-    StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
-    ArrayRef<StringRef> DirVec(Dirs);
-    addSystemIncludes(DriverArgs, CC1Args, DirVec);
-  }
-}
-
-void XCoreToolChain::addClangTargetOptions(const ArgList &DriverArgs,
-                                           ArgStringList &CC1Args) const {
-  CC1Args.push_back("-nostdsysteminc");
-}
-
-void XCoreToolChain::AddClangCXXStdlibIncludeArgs(
-    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
-      DriverArgs.hasArg(options::OPT_nostdlibinc) ||
-      DriverArgs.hasArg(options::OPT_nostdincxx))
-    return;
-  if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
-    SmallVector<StringRef, 4> Dirs;
-    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
-    StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
-    ArrayRef<StringRef> DirVec(Dirs);
-    addSystemIncludes(DriverArgs, CC1Args, DirVec);
-  }
-}
-
-void XCoreToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
-                                         ArgStringList &CmdArgs) const {
-  // We don't output any lib args. This is handled by xcc.
-}
-
-MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
-                                 const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-  // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use
-  // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple.
-  // This won't work to find gcc. Instead we give the installation detector an
-  // extra triple, which is preferable to further hacks of the logic that at
-  // present is based solely on getArch(). In particular, it would be wrong to
-  // choose the myriad installation when targeting a non-myriad sparc install.
-  switch (Triple.getArch()) {
-  default:
-    D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
-                                              << "myriad";
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel:
-  case llvm::Triple::shave:
-    GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"});
-  }
-
-  if (GCCInstallation.isValid()) {
-    // This directory contains crt{i,n,begin,end}.o as well as libgcc.
-    // These files are tied to a particular version of gcc.
-    SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath());
-    addPathIfExists(D, CompilerSupportDir, getFilePaths());
-  }
-  // libstd++ and libc++ must both be found in this one place.
-  addPathIfExists(D, D.Dir + "/../sparc-myriad-elf/lib", getFilePaths());
-}
-
-MyriadToolChain::~MyriadToolChain() {}
-
-void MyriadToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                                ArgStringList &CC1Args) const {
-  if (!DriverArgs.hasArg(options::OPT_nostdinc))
-    addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
-}
-
-std::string MyriadToolChain::findLibCxxIncludePath() const {
-  std::string Path(getDriver().getInstalledDir());
-  return Path + "/../include/c++/v1";
-}
-
-void MyriadToolChain::addLibStdCxxIncludePaths(
-    const llvm::opt::ArgList &DriverArgs,
-    llvm::opt::ArgStringList &CC1Args) const {
-  StringRef LibDir = GCCInstallation.getParentLibPath();
-  const GCCVersion &Version = GCCInstallation.getVersion();
-  StringRef TripleStr = GCCInstallation.getTriple().str();
-  const Multilib &Multilib = GCCInstallation.getMultilib();
-  addLibStdCXXIncludePaths(
-      LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
-      "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args);
-}
-
-// MyriadToolChain handles several triples:
-//  {shave,sparc{,el}}-myriad-{rtems,unknown}-elf
-Tool *MyriadToolChain::SelectTool(const JobAction &JA) const {
-  // The inherited method works fine if not targeting the SHAVE.
-  if (!isShaveCompilation(getTriple()))
-    return ToolChain::SelectTool(JA);
-  switch (JA.getKind()) {
-  case Action::PreprocessJobClass:
-  case Action::CompileJobClass:
-    if (!Compiler)
-      Compiler.reset(new tools::SHAVE::Compiler(*this));
-    return Compiler.get();
-  case Action::AssembleJobClass:
-    if (!Assembler)
-      Assembler.reset(new tools::SHAVE::Assembler(*this));
-    return Assembler.get();
-  default:
-    return ToolChain::getTool(JA.getKind());
-  }
-}
-
-Tool *MyriadToolChain::buildLinker() const {
-  return new tools::Myriad::Linker(*this);
-}
-
-SanitizerMask MyriadToolChain::getSupportedSanitizers() const {
-  return SanitizerKind::Address;
-}
-
-WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
-                         const llvm::opt::ArgList &Args)
-  : ToolChain(D, Triple, Args) {
-
-  assert(Triple.isArch32Bit() != Triple.isArch64Bit());
-  getFilePaths().push_back(
-      getDriver().SysRoot + "/lib" + (Triple.isArch32Bit() ? "32" : "64"));
-
-  // Use LLD by default.
-  DefaultLinker = "lld";
-}
-
-bool WebAssembly::IsMathErrnoDefault() const { return false; }
-
-bool WebAssembly::IsObjCNonFragileABIDefault() const { return true; }
-
-bool WebAssembly::UseObjCMixedDispatch() const { return true; }
-
-bool WebAssembly::isPICDefault() const { return false; }
-
-bool WebAssembly::isPIEDefault() const { return false; }
-
-bool WebAssembly::isPICDefaultForced() const { return false; }
-
-bool WebAssembly::IsIntegratedAssemblerDefault() const { return true; }
-
-// TODO: Support Objective C stuff.
-bool WebAssembly::SupportsObjCGC() const { return false; }
-
-bool WebAssembly::hasBlocksRuntime() const { return false; }
-
-// TODO: Support profiling.
-bool WebAssembly::SupportsProfiling() const { return false; }
-
-bool WebAssembly::HasNativeLLVMSupport() const { return true; }
-
-void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
-                                        ArgStringList &CC1Args) const {
-  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
-                         options::OPT_fno_use_init_array, true))
-    CC1Args.push_back("-fuse-init-array");
-}
-
-ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
-  return ToolChain::RLT_CompilerRT;
-}
-
-ToolChain::CXXStdlibType WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
-  return ToolChain::CST_Libcxx;
-}
-
-void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
-                                            ArgStringList &CC1Args) const {
-  if (!DriverArgs.hasArg(options::OPT_nostdinc))
-    addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
-}
-
-void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
-                                               ArgStringList &CC1Args) const {
-  if (!DriverArgs.hasArg(options::OPT_nostdlibinc) &&
-      !DriverArgs.hasArg(options::OPT_nostdincxx))
-    addSystemInclude(DriverArgs, CC1Args,
-                     getDriver().SysRoot + "/include/c++/v1");
-}
-
-Tool *WebAssembly::buildLinker() const {
-  return new tools::wasm::Linker(*this);
-}
-
-PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {
-  if (Args.hasArg(options::OPT_static))
-    D.Diag(diag::err_drv_unsupported_opt_for_target) << "-static" << "PS4";
-
-  // Determine where to find the PS4 libraries. We use SCE_ORBIS_SDK_DIR
-  // if it exists; otherwise use the driver's installation path, which
-  // should be <SDK_DIR>/host_tools/bin.
-
-  SmallString<512> PS4SDKDir;
-  if (const char *EnvValue = getenv("SCE_ORBIS_SDK_DIR")) {
-    if (!llvm::sys::fs::exists(EnvValue))
-      getDriver().Diag(clang::diag::warn_drv_ps4_sdk_dir) << EnvValue;
-    PS4SDKDir = EnvValue;
-  } else {
-    PS4SDKDir = getDriver().Dir;
-    llvm::sys::path::append(PS4SDKDir, "/../../");
-  }
-
-  // By default, the driver won't report a warning if it can't find
-  // PS4's include or lib directories. This behavior could be changed if
-  // -Weverything or -Winvalid-or-nonexistent-directory options are passed.
-  // If -isysroot was passed, use that as the SDK base path.
-  std::string PrefixDir;
-  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
-    PrefixDir = A->getValue();
-    if (!llvm::sys::fs::exists(PrefixDir))
-      getDriver().Diag(clang::diag::warn_missing_sysroot) << PrefixDir;
-  } else
-    PrefixDir = PS4SDKDir.str();
-
-  SmallString<512> PS4SDKIncludeDir(PrefixDir);
-  llvm::sys::path::append(PS4SDKIncludeDir, "target/include");
-  if (!Args.hasArg(options::OPT_nostdinc) &&
-      !Args.hasArg(options::OPT_nostdlibinc) &&
-      !Args.hasArg(options::OPT_isysroot) &&
-      !Args.hasArg(options::OPT__sysroot_EQ) &&
-      !llvm::sys::fs::exists(PS4SDKIncludeDir)) {
-    getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
-        << "PS4 system headers" << PS4SDKIncludeDir;
-  }
-
-  SmallString<512> PS4SDKLibDir(PS4SDKDir);
-  llvm::sys::path::append(PS4SDKLibDir, "target/lib");
-  if (!Args.hasArg(options::OPT_nostdlib) &&
-      !Args.hasArg(options::OPT_nodefaultlibs) &&
-      !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) &&
-      !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) &&
-      !Args.hasArg(options::OPT_emit_ast) &&
-      !llvm::sys::fs::exists(PS4SDKLibDir)) {
-    getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
-        << "PS4 system libraries" << PS4SDKLibDir;
-    return;
-  }
-  getFilePaths().push_back(PS4SDKLibDir.str());
-}
-
-Tool *PS4CPU::buildAssembler() const {
-  return new tools::PS4cpu::Assemble(*this);
-}
-
-Tool *PS4CPU::buildLinker() const { return new tools::PS4cpu::Link(*this); }
-
-bool PS4CPU::isPICDefault() const { return true; }
-
-bool PS4CPU::HasNativeLLVMSupport() const { return true; }
-
-SanitizerMask PS4CPU::getSupportedSanitizers() const {
-  SanitizerMask Res = ToolChain::getSupportedSanitizers();
-  Res |= SanitizerKind::Address;
-  Res |= SanitizerKind::Vptr;
-  return Res;
-}
-
-Contiki::Contiki(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
-    : Generic_ELF(D, Triple, Args) {}
-
-SanitizerMask Contiki::getSupportedSanitizers() const {
-  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
-  SanitizerMask Res = ToolChain::getSupportedSanitizers();
-  if (IsX86)
-    Res |= SanitizerKind::SafeStack;
-  return Res;
-}
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
deleted file mode 100644
index 2abbd03..0000000
--- a/lib/Driver/ToolChains.h
+++ /dev/null
@@ -1,1334 +0,0 @@
-//===--- ToolChains.h - ToolChain Implementations ---------------*- 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_LIB_DRIVER_TOOLCHAINS_H
-#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_H
-
-#include "Tools.h"
-#include "clang/Basic/Cuda.h"
-#include "clang/Basic/VersionTuple.h"
-#include "clang/Driver/Action.h"
-#include "clang/Driver/Multilib.h"
-#include "clang/Driver/ToolChain.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/Support/Compiler.h"
-#include <set>
-#include <vector>
-
-namespace clang {
-namespace driver {
-
-/// A class to find a viable CUDA installation
-class CudaInstallationDetector {
-private:
-  const Driver &D;
-  bool IsValid = false;
-  CudaVersion Version = CudaVersion::UNKNOWN;
-  std::string InstallPath;
-  std::string BinPath;
-  std::string LibPath;
-  std::string LibDevicePath;
-  std::string IncludePath;
-  llvm::StringMap<std::string> LibDeviceMap;
-
-  // CUDA architectures for which we have raised an error in
-  // CheckCudaVersionSupportsArch.
-  mutable llvm::SmallSet<CudaArch, 4> ArchsWithVersionTooLowErrors;
-
-public:
-  CudaInstallationDetector(const Driver &D, const llvm::Triple &Triple,
-                           const llvm::opt::ArgList &Args);
-
-  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                          llvm::opt::ArgStringList &CC1Args) const;
-
-  /// \brief Emit an error if Version does not support the given Arch.
-  ///
-  /// If either Version or Arch is unknown, does not emit an error.  Emits at
-  /// most one error per Arch.
-  void CheckCudaVersionSupportsArch(CudaArch Arch) const;
-
-  /// \brief Check whether we detected a valid Cuda install.
-  bool isValid() const { return IsValid; }
-  /// \brief Print information about the detected CUDA installation.
-  void print(raw_ostream &OS) const;
-
-  /// \brief Get the detected Cuda install's version.
-  CudaVersion version() const { return Version; }
-  /// \brief Get the detected Cuda installation path.
-  StringRef getInstallPath() const { return InstallPath; }
-  /// \brief Get the detected path to Cuda's bin directory.
-  StringRef getBinPath() const { return BinPath; }
-  /// \brief Get the detected Cuda Include path.
-  StringRef getIncludePath() const { return IncludePath; }
-  /// \brief Get the detected Cuda library path.
-  StringRef getLibPath() const { return LibPath; }
-  /// \brief Get the detected Cuda device library path.
-  StringRef getLibDevicePath() const { return LibDevicePath; }
-  /// \brief Get libdevice file for given architecture
-  std::string getLibDeviceFile(StringRef Gpu) const {
-    return LibDeviceMap.lookup(Gpu);
-  }
-};
-
-namespace toolchains {
-
-/// Generic_GCC - A tool chain using the 'gcc' command to perform
-/// all subcommands; this relies on gcc translating the majority of
-/// command line options.
-class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
-public:
-  /// \brief Struct to store and manipulate GCC versions.
-  ///
-  /// We rely on assumptions about the form and structure of GCC version
-  /// numbers: they consist of at most three '.'-separated components, and each
-  /// component is a non-negative integer except for the last component. For
-  /// the last component we are very flexible in order to tolerate release
-  /// candidates or 'x' wildcards.
-  ///
-  /// Note that the ordering established among GCCVersions is based on the
-  /// preferred version string to use. For example we prefer versions without
-  /// a hard-coded patch number to those with a hard coded patch number.
-  ///
-  /// Currently this doesn't provide any logic for textual suffixes to patches
-  /// in the way that (for example) Debian's version format does. If that ever
-  /// becomes necessary, it can be added.
-  struct GCCVersion {
-    /// \brief The unparsed text of the version.
-    std::string Text;
-
-    /// \brief The parsed major, minor, and patch numbers.
-    int Major, Minor, Patch;
-
-    /// \brief The text of the parsed major, and major+minor versions.
-    std::string MajorStr, MinorStr;
-
-    /// \brief Any textual suffix on the patch number.
-    std::string PatchSuffix;
-
-    static GCCVersion Parse(StringRef VersionText);
-    bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch,
-                     StringRef RHSPatchSuffix = StringRef()) const;
-    bool operator<(const GCCVersion &RHS) const {
-      return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix);
-    }
-    bool operator>(const GCCVersion &RHS) const { return RHS < *this; }
-    bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }
-    bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
-  };
-
-  /// \brief This is a class to find a viable GCC installation for Clang to
-  /// use.
-  ///
-  /// This class tries to find a GCC installation on the system, and report
-  /// information about it. It starts from the host information provided to the
-  /// Driver, and has logic for fuzzing that where appropriate.
-  class GCCInstallationDetector {
-    bool IsValid;
-    llvm::Triple GCCTriple;
-    const Driver &D;
-
-    // FIXME: These might be better as path objects.
-    std::string GCCInstallPath;
-    std::string GCCParentLibPath;
-
-    /// The primary multilib appropriate for the given flags.
-    Multilib SelectedMultilib;
-    /// On Biarch systems, this corresponds to the default multilib when
-    /// targeting the non-default multilib. Otherwise, it is empty.
-    llvm::Optional<Multilib> BiarchSibling;
-
-    GCCVersion Version;
-
-    // We retain the list of install paths that were considered and rejected in
-    // order to print out detailed information in verbose mode.
-    std::set<std::string> CandidateGCCInstallPaths;
-
-    /// The set of multilibs that the detected installation supports.
-    MultilibSet Multilibs;
-
-  public:
-    explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
-    void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args,
-              ArrayRef<std::string> ExtraTripleAliases = None);
-
-    /// \brief Check whether we detected a valid GCC install.
-    bool isValid() const { return IsValid; }
-
-    /// \brief Get the GCC triple for the detected install.
-    const llvm::Triple &getTriple() const { return GCCTriple; }
-
-    /// \brief Get the detected GCC installation path.
-    StringRef getInstallPath() const { return GCCInstallPath; }
-
-    /// \brief Get the detected GCC parent lib path.
-    StringRef getParentLibPath() const { return GCCParentLibPath; }
-
-    /// \brief Get the detected Multilib
-    const Multilib &getMultilib() const { return SelectedMultilib; }
-
-    /// \brief Get the whole MultilibSet
-    const MultilibSet &getMultilibs() const { return Multilibs; }
-
-    /// Get the biarch sibling multilib (if it exists).
-    /// \return true iff such a sibling exists
-    bool getBiarchSibling(Multilib &M) const;
-
-    /// \brief Get the detected GCC version string.
-    const GCCVersion &getVersion() const { return Version; }
-
-    /// \brief Print information about the detected GCC installation.
-    void print(raw_ostream &OS) const;
-
-  private:
-    static void
-    CollectLibDirsAndTriples(const llvm::Triple &TargetTriple,
-                             const llvm::Triple &BiarchTriple,
-                             SmallVectorImpl<StringRef> &LibDirs,
-                             SmallVectorImpl<StringRef> &TripleAliases,
-                             SmallVectorImpl<StringRef> &BiarchLibDirs,
-                             SmallVectorImpl<StringRef> &BiarchTripleAliases);
-
-    void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch,
-                                const llvm::opt::ArgList &Args,
-                                const std::string &LibDir,
-                                StringRef CandidateTriple,
-                                bool NeedsBiarchSuffix = false);
-
-    void scanLibDirForGCCTripleSolaris(const llvm::Triple &TargetArch,
-                                       const llvm::opt::ArgList &Args,
-                                       const std::string &LibDir,
-                                       StringRef CandidateTriple,
-                                       bool NeedsBiarchSuffix = false);
-  };
-
-protected:
-  GCCInstallationDetector GCCInstallation;
-  CudaInstallationDetector CudaInstallation;
-
-public:
-  Generic_GCC(const Driver &D, const llvm::Triple &Triple,
-              const llvm::opt::ArgList &Args);
-  ~Generic_GCC() override;
-
-  void printVerboseInfo(raw_ostream &OS) const override;
-
-  bool IsUnwindTablesDefault() const override;
-  bool isPICDefault() const override;
-  bool isPIEDefault() const override;
-  bool isPICDefaultForced() const override;
-  bool IsIntegratedAssemblerDefault() const override;
-  llvm::opt::DerivedArgList *
-  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
-                Action::OffloadKind DeviceOffloadKind) const override;
-
-protected:
-  Tool *getTool(Action::ActionClass AC) const override;
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-
-  /// \name ToolChain Implementation Helper Functions
-  /// @{
-
-  /// \brief Check whether the target triple's architecture is 64-bits.
-  bool isTarget64Bit() const { return getTriple().isArch64Bit(); }
-
-  /// \brief Check whether the target triple's architecture is 32-bits.
-  bool isTarget32Bit() const { return getTriple().isArch32Bit(); }
-
-  // FIXME: This should be final, but the Solaris tool chain does weird
-  // things we can't easily represent.
-  void AddClangCXXStdlibIncludeArgs(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-
-  virtual std::string findLibCxxIncludePath() const;
-  virtual void
-  addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
-                           llvm::opt::ArgStringList &CC1Args) const;
-
-  bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple,
-                                StringRef GCCMultiarchTriple,
-                                StringRef TargetMultiarchTriple,
-                                Twine IncludeSuffix,
-                                const llvm::opt::ArgList &DriverArgs,
-                                llvm::opt::ArgStringList &CC1Args) const;
-
-  /// @}
-
-private:
-  mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess;
-  mutable std::unique_ptr<tools::gcc::Compiler> Compile;
-};
-
-class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-  Tool *getTool(Action::ActionClass AC) const override;
-
-private:
-  mutable std::unique_ptr<tools::darwin::Lipo> Lipo;
-  mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil;
-  mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug;
-
-public:
-  MachO(const Driver &D, const llvm::Triple &Triple,
-        const llvm::opt::ArgList &Args);
-  ~MachO() override;
-
-  /// @name MachO specific toolchain API
-  /// {
-
-  /// Get the "MachO" arch name for a particular compiler invocation. For
-  /// example, Apple treats different ARM variations as distinct architectures.
-  StringRef getMachOArchName(const llvm::opt::ArgList &Args) const;
-
-  /// Add the linker arguments to link the ARC runtime library.
-  virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args,
-                              llvm::opt::ArgStringList &CmdArgs) const {}
-
-  /// Add the linker arguments to link the compiler runtime library.
-  virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
-                                     llvm::opt::ArgStringList &CmdArgs) const;
-
-  virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
-                                      llvm::opt::ArgStringList &CmdArgs) const {
-  }
-
-  virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
-                                 llvm::opt::ArgStringList &CmdArgs) const {}
-
-  /// On some iOS platforms, kernel and kernel modules were built statically. Is
-  /// this such a target?
-  virtual bool isKernelStatic() const { return false; }
-
-  /// Is the target either iOS or an iOS simulator?
-  bool isTargetIOSBased() const { return false; }
-
-  void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
-                         llvm::opt::ArgStringList &CmdArgs,
-                         StringRef DarwinLibName, bool AlwaysLink = false,
-                         bool IsEmbedded = false, bool AddRPath = false) const;
-
-  /// Add any profiling runtime libraries that are needed. This is essentially a
-  /// MachO specific version of addProfileRT in Tools.cpp.
-  void addProfileRTLibs(const llvm::opt::ArgList &Args,
-                        llvm::opt::ArgStringList &CmdArgs) const override {
-    // There aren't any profiling libs for embedded targets currently.
-  }
-
-  /// }
-  /// @name ToolChain Implementation
-  /// {
-
-  types::ID LookupTypeForExtension(StringRef Ext) const override;
-
-  bool HasNativeLLVMSupport() const override;
-
-  llvm::opt::DerivedArgList *
-  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
-                Action::OffloadKind DeviceOffloadKind) const override;
-
-  bool IsBlocksDefault() const override {
-    // Always allow blocks on Apple; users interested in versioning are
-    // expected to use /usr/include/Block.h.
-    return true;
-  }
-  bool IsIntegratedAssemblerDefault() const override {
-    // Default integrated assembler to on for Apple's MachO targets.
-    return true;
-  }
-
-  bool IsMathErrnoDefault() const override { return false; }
-
-  bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
-
-  bool IsObjCNonFragileABIDefault() const override {
-    // Non-fragile ABI is default for everything but i386.
-    return getTriple().getArch() != llvm::Triple::x86;
-  }
-
-  bool UseObjCMixedDispatch() const override { return true; }
-
-  bool IsUnwindTablesDefault() const override;
-
-  RuntimeLibType GetDefaultRuntimeLibType() const override {
-    return ToolChain::RLT_CompilerRT;
-  }
-
-  bool isPICDefault() const override;
-  bool isPIEDefault() const override;
-  bool isPICDefaultForced() const override;
-
-  bool SupportsProfiling() const override;
-
-  bool SupportsObjCGC() const override { return false; }
-
-  bool UseDwarfDebugFlags() const override;
-
-  bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override {
-    return false;
-  }
-
-  /// }
-};
-
-/// Darwin - The base Darwin tool chain.
-class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
-public:
-  /// Whether the information on the target has been initialized.
-  //
-  // FIXME: This should be eliminated. What we want to do is make this part of
-  // the "default target for arguments" selection process, once we get out of
-  // the argument translation business.
-  mutable bool TargetInitialized;
-
-  enum DarwinPlatformKind {
-    MacOS,
-    IPhoneOS,
-    IPhoneOSSimulator,
-    TvOS,
-    TvOSSimulator,
-    WatchOS,
-    WatchOSSimulator
-  };
-
-  mutable DarwinPlatformKind TargetPlatform;
-
-  /// The OS version we are targeting.
-  mutable VersionTuple TargetVersion;
-
-  CudaInstallationDetector CudaInstallation;
-
-private:
-  void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
-
-public:
-  Darwin(const Driver &D, const llvm::Triple &Triple,
-         const llvm::opt::ArgList &Args);
-  ~Darwin() override;
-
-  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
-                                          types::ID InputType) const override;
-
-  /// @name Apple Specific Toolchain Implementation
-  /// {
-
-  void addMinVersionArgs(const llvm::opt::ArgList &Args,
-                         llvm::opt::ArgStringList &CmdArgs) const override;
-
-  void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
-                              llvm::opt::ArgStringList &CmdArgs) const override;
-
-  bool isKernelStatic() const override {
-    return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) &&
-            !isTargetWatchOS());
-  }
-
-  void addProfileRTLibs(const llvm::opt::ArgList &Args,
-                        llvm::opt::ArgStringList &CmdArgs) const override;
-
-protected:
-  /// }
-  /// @name Darwin specific Toolchain functions
-  /// {
-
-  // FIXME: Eliminate these ...Target functions and derive separate tool chains
-  // for these targets and put version in constructor.
-  void setTarget(DarwinPlatformKind Platform, unsigned Major, unsigned Minor,
-                 unsigned Micro) const {
-    // FIXME: For now, allow reinitialization as long as values don't
-    // change. This will go away when we move away from argument translation.
-    if (TargetInitialized && TargetPlatform == Platform &&
-        TargetVersion == VersionTuple(Major, Minor, Micro))
-      return;
-
-    assert(!TargetInitialized && "Target already initialized!");
-    TargetInitialized = true;
-    TargetPlatform = Platform;
-    TargetVersion = VersionTuple(Major, Minor, Micro);
-  }
-
-  bool isTargetIPhoneOS() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetPlatform == IPhoneOS || TargetPlatform == TvOS;
-  }
-
-  bool isTargetIOSSimulator() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetPlatform == IPhoneOSSimulator ||
-           TargetPlatform == TvOSSimulator;
-  }
-
-  bool isTargetIOSBased() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return isTargetIPhoneOS() || isTargetIOSSimulator();
-  }
-
-  bool isTargetTvOS() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetPlatform == TvOS;
-  }
-
-  bool isTargetTvOSSimulator() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetPlatform == TvOSSimulator;
-  }
-
-  bool isTargetTvOSBased() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetPlatform == TvOS || TargetPlatform == TvOSSimulator;
-  }
-
-  bool isTargetWatchOS() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetPlatform == WatchOS;
-  }
-
-  bool isTargetWatchOSSimulator() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetPlatform == WatchOSSimulator;
-  }
-
-  bool isTargetWatchOSBased() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetPlatform == WatchOS || TargetPlatform == WatchOSSimulator;
-  }
-
-  bool isTargetMacOS() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetPlatform == MacOS;
-  }
-
-  bool isTargetInitialized() const { return TargetInitialized; }
-
-  VersionTuple getTargetVersion() const {
-    assert(TargetInitialized && "Target not initialized!");
-    return TargetVersion;
-  }
-
-  bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
-                           unsigned V2 = 0) const {
-    assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
-    return TargetVersion < VersionTuple(V0, V1, V2);
-  }
-
-  bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
-    assert(isTargetMacOS() && "Unexpected call for non OS X target!");
-    return TargetVersion < VersionTuple(V0, V1, V2);
-  }
-
-  StringRef getPlatformFamily() const;
-  static StringRef getSDKName(StringRef isysroot);
-  StringRef getOSLibraryNameSuffix() const;
-
-public:
-  /// }
-  /// @name ToolChain Implementation
-  /// {
-
-  // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
-  // most development is done against SDKs, so compiling for a different
-  // architecture should not get any special treatment.
-  bool isCrossCompiling() const override { return false; }
-
-  llvm::opt::DerivedArgList *
-  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
-                Action::OffloadKind DeviceOffloadKind) const override;
-
-  CXXStdlibType GetDefaultCXXStdlibType() const override;
-  ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
-  bool hasBlocksRuntime() const override;
-
-  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                          llvm::opt::ArgStringList &CC1Args) const override;
-
-  bool UseObjCMixedDispatch() const override {
-    // This is only used with the non-fragile ABI and non-legacy dispatch.
-
-    // Mixed dispatch is used everywhere except OS X before 10.6.
-    return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
-  }
-
-  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
-    // Stack protectors default to on for user code on 10.5,
-    // and for everything in 10.6 and beyond
-    if (isTargetIOSBased() || isTargetWatchOSBased())
-      return 1;
-    else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
-      return 1;
-    else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
-      return 1;
-
-    return 0;
-  }
-
-  bool SupportsObjCGC() const override;
-
-  void CheckObjCARC() const override;
-
-  bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
-
-  bool SupportsEmbeddedBitcode() const override;
-
-  SanitizerMask getSupportedSanitizers() const override;
-
-  void printVerboseInfo(raw_ostream &OS) const override;
-};
-
-/// DarwinClang - The Darwin toolchain used by Clang.
-class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
-public:
-  DarwinClang(const Driver &D, const llvm::Triple &Triple,
-              const llvm::opt::ArgList &Args);
-
-  /// @name Apple ToolChain Implementation
-  /// {
-
-  RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
-
-  void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
-                             llvm::opt::ArgStringList &CmdArgs) const override;
-
-  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-
-  void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
-                        llvm::opt::ArgStringList &CmdArgs) const override;
-
-  void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
-
-  void AddLinkARCArgs(const llvm::opt::ArgList &Args,
-                      llvm::opt::ArgStringList &CmdArgs) const override;
-
-  unsigned GetDefaultDwarfVersion() const override;
-  // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
-  // Darwin defaults to standalone/full debug info.
-  bool GetDefaultStandaloneDebug() const override { return true; }
-  llvm::DebuggerKind getDefaultDebuggerTuning() const override {
-    return llvm::DebuggerKind::LLDB;
-  }
-
-  /// }
-
-private:
-  void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
-                               llvm::opt::ArgStringList &CmdArgs,
-                               StringRef Sanitizer) const;
-};
-
-class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
-  virtual void anchor();
-
-public:
-  Generic_ELF(const Driver &D, const llvm::Triple &Triple,
-              const llvm::opt::ArgList &Args)
-      : Generic_GCC(D, Triple, Args) {}
-
-  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-                             llvm::opt::ArgStringList &CC1Args) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY CloudABI : public Generic_ELF {
-public:
-  CloudABI(const Driver &D, const llvm::Triple &Triple,
-           const llvm::opt::ArgList &Args);
-  bool HasNativeLLVMSupport() const override { return true; }
-
-  bool IsMathErrnoDefault() const override { return false; }
-  bool IsObjCNonFragileABIDefault() const override { return true; }
-
-  CXXStdlibType
-  GetCXXStdlibType(const llvm::opt::ArgList &Args) const override {
-    return ToolChain::CST_Libcxx;
-  }
-  std::string findLibCxxIncludePath() const override;
-  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-
-  bool isPIEDefault() const override;
-  SanitizerMask getSupportedSanitizers() const override;
-  SanitizerMask getDefaultSanitizers() const override;
-
-protected:
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC {
-public:
-  Solaris(const Driver &D, const llvm::Triple &Triple,
-          const llvm::opt::ArgList &Args);
-
-  bool IsIntegratedAssemblerDefault() const override { return true; }
-
-  void AddClangCXXStdlibIncludeArgs(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-
-  unsigned GetDefaultDwarfVersion() const override { return 2; }
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain {
-public:
-  MinGW(const Driver &D, const llvm::Triple &Triple,
-        const llvm::opt::ArgList &Args);
-
-  bool IsIntegratedAssemblerDefault() const override;
-  bool IsUnwindTablesDefault() const override;
-  bool isPICDefault() const override;
-  bool isPIEDefault() const override;
-  bool isPICDefaultForced() const override;
-  bool UseSEHExceptions() const;
-
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  void AddClangCXXStdlibIncludeArgs(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-
-protected:
-  Tool *getTool(Action::ActionClass AC) const override;
-  Tool *buildLinker() const override;
-  Tool *buildAssembler() const override;
-
-private:
-  std::string Base;
-  std::string GccLibDir;
-  std::string Ver;
-  std::string Arch;
-  mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocessor;
-  mutable std::unique_ptr<tools::gcc::Compiler> Compiler;
-  void findGccLibDir();
-};
-
-class LLVM_LIBRARY_VISIBILITY Haiku : public Generic_ELF {
-public:
-  Haiku(const Driver &D, const llvm::Triple &Triple,
-          const llvm::opt::ArgList &Args);
-
-  bool isPIEDefault() const override {
-    return getTriple().getArch() == llvm::Triple::x86_64;
-  }
-
-  std::string findLibCxxIncludePath() const override;
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF {
-public:
-  OpenBSD(const Driver &D, const llvm::Triple &Triple,
-          const llvm::opt::ArgList &Args);
-
-  bool IsMathErrnoDefault() const override { return false; }
-  bool IsObjCNonFragileABIDefault() const override { return true; }
-  bool isPIEDefault() const override { return true; }
-
-  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
-    return 2;
-  }
-  unsigned GetDefaultDwarfVersion() const override { return 2; }
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Bitrig : public Generic_ELF {
-public:
-  Bitrig(const Driver &D, const llvm::Triple &Triple,
-         const llvm::opt::ArgList &Args);
-
-  bool IsMathErrnoDefault() const override { return false; }
-  bool IsObjCNonFragileABIDefault() const override { return true; }
-
-  CXXStdlibType GetDefaultCXXStdlibType() const override;
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
-    return 1;
-  }
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
-public:
-  FreeBSD(const Driver &D, const llvm::Triple &Triple,
-          const llvm::opt::ArgList &Args);
-  bool HasNativeLLVMSupport() const override;
-
-  bool IsMathErrnoDefault() const override { return false; }
-  bool IsObjCNonFragileABIDefault() const override { return true; }
-
-  CXXStdlibType GetDefaultCXXStdlibType() const override;
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-
-  bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
-  bool isPIEDefault() const override;
-  SanitizerMask getSupportedSanitizers() const override;
-  unsigned GetDefaultDwarfVersion() const override { return 2; }
-  // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
-  // FreeBSD defaults to standalone/full debug info.
-  bool GetDefaultStandaloneDebug() const override { return true; }
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
-public:
-  NetBSD(const Driver &D, const llvm::Triple &Triple,
-         const llvm::opt::ArgList &Args);
-
-  bool IsMathErrnoDefault() const override { return false; }
-  bool IsObjCNonFragileABIDefault() const override { return true; }
-
-  CXXStdlibType GetDefaultCXXStdlibType() const override;
-
-  std::string findLibCxxIncludePath() const override;
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-
-  bool IsUnwindTablesDefault() const override { return true; }
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF {
-public:
-  Minix(const Driver &D, const llvm::Triple &Triple,
-        const llvm::opt::ArgList &Args);
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
-public:
-  DragonFly(const Driver &D, const llvm::Triple &Triple,
-            const llvm::opt::ArgList &Args);
-
-  bool IsMathErrnoDefault() const override { return false; }
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
-public:
-  Linux(const Driver &D, const llvm::Triple &Triple,
-        const llvm::opt::ArgList &Args);
-
-  bool HasNativeLLVMSupport() const override;
-
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  std::string findLibCxxIncludePath() const override;
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                          llvm::opt::ArgStringList &CC1Args) const override;
-  void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                           llvm::opt::ArgStringList &CC1Args) const override;
-  bool isPIEDefault() const override;
-  SanitizerMask getSupportedSanitizers() const override;
-  void addProfileRTLibs(const llvm::opt::ArgList &Args,
-                        llvm::opt::ArgStringList &CmdArgs) const override;
-  virtual std::string computeSysRoot() const;
-
-  virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const;
-
-  std::vector<std::string> ExtraOpts;
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain {
-public:
-  CudaToolChain(const Driver &D, const llvm::Triple &Triple,
-                const ToolChain &HostTC, const llvm::opt::ArgList &Args);
-
-  llvm::opt::DerivedArgList *
-  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
-                Action::OffloadKind DeviceOffloadKind) const override;
-  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-                             llvm::opt::ArgStringList &CC1Args) const override;
-
-  // Never try to use the integrated assembler with CUDA; always fork out to
-  // ptxas.
-  bool useIntegratedAs() const override { return false; }
-  bool isCrossCompiling() const override { return true; }
-  bool isPICDefault() const override { return false; }
-  bool isPIEDefault() const override { return false; }
-  bool isPICDefaultForced() const override { return false; }
-  bool SupportsProfiling() const override { return false; }
-  bool SupportsObjCGC() const override { return false; }
-
-  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                          llvm::opt::ArgStringList &CC1Args) const override;
-
-  void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
-  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  void AddClangCXXStdlibIncludeArgs(
-      const llvm::opt::ArgList &Args,
-      llvm::opt::ArgStringList &CC1Args) const override;
-  void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                           llvm::opt::ArgStringList &CC1Args) const override;
-
-  SanitizerMask getSupportedSanitizers() const override;
-
-  const ToolChain &HostTC;
-  CudaInstallationDetector CudaInstallation;
-
-protected:
-  Tool *buildAssembler() const override;  // ptxas
-  Tool *buildLinker() const override;     // fatbinary (ok, not really a linker)
-};
-
-class LLVM_LIBRARY_VISIBILITY MipsLLVMToolChain : public Linux {
-protected:
-  Tool *buildLinker() const override;
-
-public:
-  MipsLLVMToolChain(const Driver &D, const llvm::Triple &Triple,
-                    const llvm::opt::ArgList &Args);
-
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-
-  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
-
-  std::string findLibCxxIncludePath() const override;
-
-  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-
-  std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
-                            bool Shared = false) const override;
-
-  std::string computeSysRoot() const override;
-
-  RuntimeLibType GetDefaultRuntimeLibType() const override {
-    return GCCInstallation.isValid() ? RuntimeLibType::RLT_Libgcc
-                                     : RuntimeLibType::RLT_CompilerRT;
-  }
-
-private:
-  Multilib SelectedMultilib;
-  std::string LibSuffix;
-};
-
-class LLVM_LIBRARY_VISIBILITY LanaiToolChain : public Generic_ELF {
-public:
-  LanaiToolChain(const Driver &D, const llvm::Triple &Triple,
-                 const llvm::opt::ArgList &Args)
-      : Generic_ELF(D, Triple, Args) {}
-
-  // No support for finding a C++ standard library yet.
-  std::string findLibCxxIncludePath() const override { return ""; }
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override {}
-
-  bool IsIntegratedAssemblerDefault() const override { return true; }
-};
-
-class LLVM_LIBRARY_VISIBILITY HexagonToolChain : public Linux {
-protected:
-  GCCVersion GCCLibAndIncVersion;
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-
-public:
-  HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
-                   const llvm::opt::ArgList &Args);
-  ~HexagonToolChain() override;
-
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
-
-  StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; }
-  bool IsIntegratedAssemblerDefault() const override {
-    return true;
-  }
-
-  std::string getHexagonTargetDir(
-      const std::string &InstalledDir,
-      const SmallVectorImpl<std::string> &PrefixDirs) const;
-  void getHexagonLibraryPaths(const llvm::opt::ArgList &Args,
-      ToolChain::path_list &LibPaths) const;
-
-  static const StringRef GetDefaultCPU();
-  static const StringRef GetTargetCPUVersion(const llvm::opt::ArgList &Args);
-
-  static Optional<unsigned> getSmallDataThreshold(
-      const llvm::opt::ArgList &Args);
-};
-
-class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
-protected:
-  Tool *buildLinker() const override;
-
-public:
-  AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
-            const llvm::opt::ArgList &Args);
-  unsigned GetDefaultDwarfVersion() const override { return 2; }
-  bool IsIntegratedAssemblerDefault() const override { return true; }
-};
-
-class LLVM_LIBRARY_VISIBILITY NaClToolChain : public Generic_ELF {
-public:
-  NaClToolChain(const Driver &D, const llvm::Triple &Triple,
-                const llvm::opt::ArgList &Args);
-
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  std::string findLibCxxIncludePath() const override;
-
-  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
-
-  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-
-  bool IsIntegratedAssemblerDefault() const override {
-    return getTriple().getArch() == llvm::Triple::mipsel;
-  }
-
-  // Get the path to the file containing NaCl's ARM macros.
-  // It lives in NaClToolChain because the ARMAssembler tool needs a
-  // const char * that it can pass around,
-  const char *GetNaClArmMacrosPath() const { return NaClArmMacrosPath.c_str(); }
-
-  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
-                                          types::ID InputType) const override;
-
-protected:
-  Tool *buildLinker() const override;
-  Tool *buildAssembler() const override;
-
-private:
-  std::string NaClArmMacrosPath;
-};
-
-class LLVM_LIBRARY_VISIBILITY Fuchsia : public Generic_ELF {
-public:
-  Fuchsia(const Driver &D, const llvm::Triple &Triple,
-          const llvm::opt::ArgList &Args);
-
-  bool isPIEDefault() const override { return true; }
-  bool HasNativeLLVMSupport() const override { return true; }
-  bool IsIntegratedAssemblerDefault() const override { return true; }
-  llvm::DebuggerKind getDefaultDebuggerTuning() const override {
-    return llvm::DebuggerKind::GDB;
-  }
-
-  RuntimeLibType
-  GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
-  CXXStdlibType
-  GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
-
-  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-                             llvm::opt::ArgStringList &CC1Args) const override;
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  std::string findLibCxxIncludePath() const override;
-  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
-/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
-class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain {
-public:
-  TCEToolChain(const Driver &D, const llvm::Triple &Triple,
-               const llvm::opt::ArgList &Args);
-  ~TCEToolChain() override;
-
-  bool IsMathErrnoDefault() const override;
-  bool isPICDefault() const override;
-  bool isPIEDefault() const override;
-  bool isPICDefaultForced() const override;
-};
-
-/// Toolchain for little endian TCE cores.
-class LLVM_LIBRARY_VISIBILITY TCELEToolChain : public TCEToolChain {
-public:
-  TCELEToolChain(const Driver &D, const llvm::Triple &Triple,
-                 const llvm::opt::ArgList &Args);
-  ~TCELEToolChain() override;
-};
-
-class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
-public:
-  MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
-                const llvm::opt::ArgList &Args);
-
-  llvm::opt::DerivedArgList *
-  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
-                Action::OffloadKind DeviceOffloadKind) const override;
-
-  bool IsIntegratedAssemblerDefault() const override;
-  bool IsUnwindTablesDefault() const override;
-  bool isPICDefault() const override;
-  bool isPIEDefault() const override;
-  bool isPICDefaultForced() const override;
-
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  void AddClangCXXStdlibIncludeArgs(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-
-  bool getWindowsSDKDir(std::string &path, int &major,
-                        std::string &windowsSDKIncludeVersion,
-                        std::string &windowsSDKLibVersion) const;
-  bool getWindowsSDKLibraryPath(std::string &path) const;
-  /// \brief Check if Universal CRT should be used if available
-  bool useUniversalCRT(std::string &visualStudioDir) const;
-  bool getUniversalCRTSdkDir(std::string &path, std::string &ucrtVersion) const;
-  bool getUniversalCRTLibraryPath(std::string &path) const;
-  bool getVisualStudioInstallDir(std::string &path) const;
-  bool getVisualStudioBinariesFolder(const char *clangProgramPath,
-                                     std::string &path) const;
-  VersionTuple
-  computeMSVCVersion(const Driver *D,
-                     const llvm::opt::ArgList &Args) const override;
-
-  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
-                                          types::ID InputType) const override;
-  SanitizerMask getSupportedSanitizers() const override;
-
-protected:
-  void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs,
-                                     llvm::opt::ArgStringList &CC1Args,
-                                     const std::string &folder,
-                                     const Twine &subfolder1,
-                                     const Twine &subfolder2 = "",
-                                     const Twine &subfolder3 = "") const;
-
-  Tool *buildLinker() const override;
-  Tool *buildAssembler() const override;
-private:
-  VersionTuple getMSVCVersionFromTriple() const;
-  VersionTuple getMSVCVersionFromExe() const;
-};
-
-class LLVM_LIBRARY_VISIBILITY CrossWindowsToolChain : public Generic_GCC {
-public:
-  CrossWindowsToolChain(const Driver &D, const llvm::Triple &T,
-                        const llvm::opt::ArgList &Args);
-
-  bool IsIntegratedAssemblerDefault() const override { return true; }
-  bool IsUnwindTablesDefault() const override;
-  bool isPICDefault() const override;
-  bool isPIEDefault() const override;
-  bool isPICDefaultForced() const override;
-
-  unsigned int GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
-    return 0;
-  }
-
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  void AddClangCXXStdlibIncludeArgs(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-
-  SanitizerMask getSupportedSanitizers() const override;
-
-protected:
-  Tool *buildLinker() const override;
-  Tool *buildAssembler() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY XCoreToolChain : public ToolChain {
-public:
-  XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
-                 const llvm::opt::ArgList &Args);
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-
-public:
-  bool isPICDefault() const override;
-  bool isPIEDefault() const override;
-  bool isPICDefaultForced() const override;
-  bool SupportsProfiling() const override;
-  bool hasBlocksRuntime() const override;
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-                             llvm::opt::ArgStringList &CC1Args) const override;
-  void AddClangCXXStdlibIncludeArgs(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-};
-
-/// MyriadToolChain - A tool chain using either clang or the external compiler
-/// installed by the Movidius SDK to perform all subcommands.
-class LLVM_LIBRARY_VISIBILITY MyriadToolChain : public Generic_ELF {
-public:
-  MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
-                  const llvm::opt::ArgList &Args);
-  ~MyriadToolChain() override;
-
-  void
-  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const override;
-  std::string findLibCxxIncludePath() const override;
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-  Tool *SelectTool(const JobAction &JA) const override;
-  unsigned GetDefaultDwarfVersion() const override { return 2; }
-  SanitizerMask getSupportedSanitizers() const override;
-
-protected:
-  Tool *buildLinker() const override;
-  bool isShaveCompilation(const llvm::Triple &T) const {
-    return T.getArch() == llvm::Triple::shave;
-  }
-
-private:
-  mutable std::unique_ptr<Tool> Compiler;
-  mutable std::unique_ptr<Tool> Assembler;
-};
-
-class LLVM_LIBRARY_VISIBILITY WebAssembly final : public ToolChain {
-public:
-  WebAssembly(const Driver &D, const llvm::Triple &Triple,
-              const llvm::opt::ArgList &Args);
-
-private:
-  bool IsMathErrnoDefault() const override;
-  bool IsObjCNonFragileABIDefault() const override;
-  bool UseObjCMixedDispatch() const override;
-  bool isPICDefault() const override;
-  bool isPIEDefault() const override;
-  bool isPICDefaultForced() const override;
-  bool IsIntegratedAssemblerDefault() const override;
-  bool hasBlocksRuntime() const override;
-  bool SupportsObjCGC() const override;
-  bool SupportsProfiling() const override;
-  bool HasNativeLLVMSupport() const override;
-  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-                             llvm::opt::ArgStringList &CC1Args) const override;
-  RuntimeLibType GetDefaultRuntimeLibType() const override;
-  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
-  void AddClangSystemIncludeArgs(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-  void AddClangCXXStdlibIncludeArgs(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override;
-
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY PS4CPU : public Generic_ELF {
-public:
-  PS4CPU(const Driver &D, const llvm::Triple &Triple,
-         const llvm::opt::ArgList &Args);
-
-  // No support for finding a C++ standard library yet.
-  std::string findLibCxxIncludePath() const override { return ""; }
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override {}
-
-  bool IsMathErrnoDefault() const override { return false; }
-  bool IsObjCNonFragileABIDefault() const override { return true; }
-  bool HasNativeLLVMSupport() const override;
-  bool isPICDefault() const override;
-
-  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
-    return 2; // SSPStrong
-  }
-
-  llvm::DebuggerKind getDefaultDebuggerTuning() const override {
-    return llvm::DebuggerKind::SCE;
-  }
-
-  SanitizerMask getSupportedSanitizers() const override;
-
-protected:
-  Tool *buildAssembler() const override;
-  Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Contiki : public Generic_ELF {
-public:
-  Contiki(const Driver &D, const llvm::Triple &Triple,
-          const llvm::opt::ArgList &Args);
-
-  // No support for finding a C++ standard library yet.
-  std::string findLibCxxIncludePath() const override { return ""; }
-  void addLibStdCxxIncludePaths(
-      const llvm::opt::ArgList &DriverArgs,
-      llvm::opt::ArgStringList &CC1Args) const override {}
-
-  SanitizerMask getSupportedSanitizers() const override;
-};
-
-} // end namespace toolchains
-} // end namespace driver
-} // end namespace clang
-
-#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_H
diff --git a/lib/Driver/ToolChains/AMDGPU.cpp b/lib/Driver/ToolChains/AMDGPU.cpp
new file mode 100644
index 0000000..63e1749
--- /dev/null
+++ b/lib/Driver/ToolChains/AMDGPU.cpp
@@ -0,0 +1,45 @@
+//===--- AMDGPU.cpp - AMDGPU ToolChain Implementations ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPU.h"
+#include "InputInfo.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                  const InputInfo &Output,
+                                  const InputInfoList &Inputs,
+                                  const ArgList &Args,
+                                  const char *LinkingOutput) const {
+
+  std::string Linker = getToolChain().GetProgramPath(getShortName());
+  ArgStringList CmdArgs;
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+  CmdArgs.push_back("-shared");
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
+                                          CmdArgs, Inputs));
+}
+
+/// AMDGPU Toolchain
+AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
+                                 const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) { }
+
+Tool *AMDGPUToolChain::buildLinker() const {
+  return new tools::amdgpu::Linker(*this);
+}
diff --git a/lib/Driver/ToolChains/AMDGPU.h b/lib/Driver/ToolChains/AMDGPU.h
new file mode 100644
index 0000000..9af1e96
--- /dev/null
+++ b/lib/Driver/ToolChains/AMDGPU.h
@@ -0,0 +1,54 @@
+//===--- AMDGPU.h - AMDGPU ToolChain Implementations ----------*- 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_LIB_DRIVER_TOOLCHAINS_AMDGPU_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+namespace amdgpu {
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("amdgpu::Linker", "ld.lld", TC) {}
+  bool isLinkJob() const override { return true; }
+  bool hasIntegratedCPP() const override { return false; }
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+} // end namespace amdgpu
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
+protected:
+  Tool *buildLinker() const override;
+
+public:
+  AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
+            const llvm::opt::ArgList &Args);
+  unsigned GetDefaultDwarfVersion() const override { return 2; }
+  bool IsIntegratedAssemblerDefault() const override { return true; }
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H
diff --git a/lib/Driver/ToolChains/AVR.cpp b/lib/Driver/ToolChains/AVR.cpp
new file mode 100644
index 0000000..877009a
--- /dev/null
+++ b/lib/Driver/ToolChains/AVR.cpp
@@ -0,0 +1,44 @@
+//===--- AVR.cpp - AVR ToolChain Implementations ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AVR.h"
+#include "CommonArgs.h"
+#include "InputInfo.h"
+#include "clang/Driver/Compilation.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+/// AVR Toolchain
+AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple,
+                           const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) { }
+Tool *AVRToolChain::buildLinker() const {
+  return new tools::AVR::Linker(*this);
+}
+
+void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                               const InputInfo &Output,
+                               const InputInfoList &Inputs,
+                               const ArgList &Args,
+                               const char *LinkingOutput) const {
+
+  std::string Linker = getToolChain().GetProgramPath(getShortName());
+  ArgStringList CmdArgs;
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
+                                          CmdArgs, Inputs));
+}
+// AVR tools end.
diff --git a/lib/Driver/ToolChains/AVR.h b/lib/Driver/ToolChains/AVR.h
new file mode 100644
index 0000000..a7479a7
--- /dev/null
+++ b/lib/Driver/ToolChains/AVR.h
@@ -0,0 +1,49 @@
+//===--- AVR.h - AVR Tool and ToolChain Implementations ---------*- 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_LIB_DRIVER_TOOLCHAINS_AVR_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AVR_H
+
+#include "Gnu.h"
+#include "InputInfo.h"
+#include "clang/Driver/ToolChain.h"
+#include "clang/Driver/Tool.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY AVRToolChain : public Generic_ELF {
+protected:
+  Tool *buildLinker() const override;
+public:
+  AVRToolChain(const Driver &D, const llvm::Triple &Triple,
+               const llvm::opt::ArgList &Args);
+};
+
+} // end namespace toolchains
+
+namespace tools {
+namespace AVR {
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("AVR::Linker", "avr-ld", TC) {}
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace AVR
+} // end namespace tools
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AVR_H
diff --git a/lib/Driver/ToolChains/Arch/AArch64.cpp b/lib/Driver/ToolChains/Arch/AArch64.cpp
new file mode 100644
index 0000000..7dc2f57
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -0,0 +1,196 @@
+//===--- AArch64.cpp - AArch64 (not ARM) Helpers for Tools ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AArch64.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/TargetParser.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
+/// targeting. Set \p A to the Arg corresponding to the -mcpu or -mtune
+/// arguments if they are provided, or to nullptr otherwise.
+std::string aarch64::getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
+  std::string CPU;
+  // If we have -mtune or -mcpu, use that.
+  if ((A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))) {
+    CPU = StringRef(A->getValue()).lower();
+  } else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
+    StringRef Mcpu = A->getValue();
+    CPU = Mcpu.split("+").first.lower();
+  }
+
+  // Handle CPU name is 'native'.
+  if (CPU == "native")
+    return llvm::sys::getHostCPUName();
+  else if (CPU.size())
+    return CPU;
+
+  // Make sure we pick "cyclone" if -arch is used.
+  // FIXME: Should this be picked by checking the target triple instead?
+  if (Args.getLastArg(options::OPT_arch))
+    return "cyclone";
+
+  return "generic";
+}
+
+// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
+static bool DecodeAArch64Features(const Driver &D, StringRef text,
+                                  std::vector<StringRef> &Features) {
+  SmallVector<StringRef, 8> Split;
+  text.split(Split, StringRef("+"), -1, false);
+
+  for (StringRef Feature : Split) {
+    StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
+    if (!FeatureName.empty())
+      Features.push_back(FeatureName);
+    else if (Feature == "neon" || Feature == "noneon")
+      D.Diag(clang::diag::err_drv_no_neon_modifier);
+    else
+      return false;
+  }
+  return true;
+}
+
+// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
+// decode CPU and feature.
+static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
+                              std::vector<StringRef> &Features) {
+  std::pair<StringRef, StringRef> Split = Mcpu.split("+");
+  CPU = Split.first;
+
+  if (CPU == "generic") {
+    Features.push_back("+neon");
+  } else {
+    unsigned ArchKind = llvm::AArch64::parseCPUArch(CPU);
+    if (!llvm::AArch64::getArchFeatures(ArchKind, Features))
+      return false;
+
+    unsigned Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind);
+    if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
+      return false;
+   }
+
+  if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
+    return false;
+
+  return true;
+}
+
+static bool
+getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
+                                const ArgList &Args,
+                                std::vector<StringRef> &Features) {
+  std::string MarchLowerCase = March.lower();
+  std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
+
+  unsigned ArchKind = llvm::AArch64::parseArch(Split.first);
+  if (ArchKind == static_cast<unsigned>(llvm::AArch64::ArchKind::AK_INVALID) ||
+      !llvm::AArch64::getArchFeatures(ArchKind, Features) ||
+      (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features)))
+    return false;
+
+  return true;
+}
+
+static bool
+getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
+                               const ArgList &Args,
+                               std::vector<StringRef> &Features) {
+  StringRef CPU;
+  std::string McpuLowerCase = Mcpu.lower();
+  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
+    return false;
+
+  return true;
+}
+
+static bool
+getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
+                                     const ArgList &Args,
+                                     std::vector<StringRef> &Features) {
+  std::string MtuneLowerCase = Mtune.lower();
+  // Handle CPU name is 'native'.
+  if (MtuneLowerCase == "native")
+    MtuneLowerCase = llvm::sys::getHostCPUName();
+  if (MtuneLowerCase == "cyclone") {
+    Features.push_back("+zcm");
+    Features.push_back("+zcz");
+  }
+  return true;
+}
+
+static bool
+getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
+                                    const ArgList &Args,
+                                    std::vector<StringRef> &Features) {
+  StringRef CPU;
+  std::vector<StringRef> DecodedFeature;
+  std::string McpuLowerCase = Mcpu.lower();
+  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
+    return false;
+
+  return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
+}
+
+void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
+                                       std::vector<StringRef> &Features) {
+  Arg *A;
+  bool success = true;
+  // Enable NEON by default.
+  Features.push_back("+neon");
+  if ((A = Args.getLastArg(options::OPT_march_EQ)))
+    success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
+  else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
+    success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
+  else if (Args.hasArg(options::OPT_arch))
+    success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args, A),
+                                             Args, Features);
+
+  if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
+    success =
+        getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
+  else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
+    success =
+        getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
+  else if (success && Args.hasArg(options::OPT_arch))
+    success = getAArch64MicroArchFeaturesFromMcpu(
+        D, getAArch64TargetCPU(Args, A), Args, Features);
+
+  if (!success)
+    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
+
+  if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
+    Features.push_back("-fp-armv8");
+    Features.push_back("-crypto");
+    Features.push_back("-neon");
+  }
+
+  // En/disable crc
+  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
+    if (A->getOption().matches(options::OPT_mcrc))
+      Features.push_back("+crc");
+    else
+      Features.push_back("-crc");
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
+                               options::OPT_munaligned_access))
+    if (A->getOption().matches(options::OPT_mno_unaligned_access))
+      Features.push_back("+strict-align");
+
+  if (Args.hasArg(options::OPT_ffixed_x18))
+    Features.push_back("+reserve-x18");
+}
diff --git a/lib/Driver/ToolChains/Arch/AArch64.h b/lib/Driver/ToolChains/Arch/AArch64.h
new file mode 100644
index 0000000..62e419c
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/AArch64.h
@@ -0,0 +1,35 @@
+//===--- AArch64.h - AArch64-specific (not ARM) Tool Helpers ----*- 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_LIB_DRIVER_TOOLCHAINS_ARCH_AARCH64_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_AARCH64_H
+
+#include "clang/Driver/Driver.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace aarch64 {
+
+void getAArch64TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
+                              std::vector<llvm::StringRef> &Features);
+
+std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args,
+                                llvm::opt::Arg *&A);
+
+} // end namespace aarch64
+} // end namespace target
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_AARCH64_H
diff --git a/lib/Driver/ToolChains/Arch/ARM.cpp b/lib/Driver/ToolChains/Arch/ARM.cpp
new file mode 100644
index 0000000..15f224b
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -0,0 +1,544 @@
+//===--- ARM.cpp - ARM (not AArch64) Helpers for Tools ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARM.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/TargetParser.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+// Get SubArch (vN).
+int arm::getARMSubArchVersionNumber(const llvm::Triple &Triple) {
+  llvm::StringRef Arch = Triple.getArchName();
+  return llvm::ARM::parseArchVersion(Arch);
+}
+
+// True if M-profile.
+bool arm::isARMMProfile(const llvm::Triple &Triple) {
+  llvm::StringRef Arch = Triple.getArchName();
+  unsigned Profile = llvm::ARM::parseArchProfile(Arch);
+  return Profile == llvm::ARM::PK_M;
+}
+
+// Get Arch/CPU from args.
+void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
+                                llvm::StringRef &CPU, bool FromAs) {
+  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
+    CPU = A->getValue();
+  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+    Arch = A->getValue();
+  if (!FromAs)
+    return;
+
+  for (const Arg *A :
+       Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
+    StringRef Value = A->getValue();
+    if (Value.startswith("-mcpu="))
+      CPU = Value.substr(6);
+    if (Value.startswith("-march="))
+      Arch = Value.substr(7);
+  }
+}
+
+// Handle -mhwdiv=.
+// FIXME: Use ARMTargetParser.
+static void getARMHWDivFeatures(const Driver &D, const Arg *A,
+                                const ArgList &Args, StringRef HWDiv,
+                                std::vector<StringRef> &Features) {
+  unsigned HWDivID = llvm::ARM::parseHWDiv(HWDiv);
+  if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
+    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+}
+
+// Handle -mfpu=.
+static void getARMFPUFeatures(const Driver &D, const Arg *A,
+                              const ArgList &Args, StringRef FPU,
+                              std::vector<StringRef> &Features) {
+  unsigned FPUID = llvm::ARM::parseFPU(FPU);
+  if (!llvm::ARM::getFPUFeatures(FPUID, Features))
+    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+}
+
+// Decode ARM features from string like +[no]featureA+[no]featureB+...
+static bool DecodeARMFeatures(const Driver &D, StringRef text,
+                              std::vector<StringRef> &Features) {
+  SmallVector<StringRef, 8> Split;
+  text.split(Split, StringRef("+"), -1, false);
+
+  for (StringRef Feature : Split) {
+    StringRef FeatureName = llvm::ARM::getArchExtFeature(Feature);
+    if (!FeatureName.empty())
+      Features.push_back(FeatureName);
+    else
+      return false;
+  }
+  return true;
+}
+
+// Check if -march is valid by checking if it can be canonicalised and parsed.
+// getARMArch is used here instead of just checking the -march value in order
+// to handle -march=native correctly.
+static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
+                             llvm::StringRef ArchName,
+                             std::vector<StringRef> &Features,
+                             const llvm::Triple &Triple) {
+  std::pair<StringRef, StringRef> Split = ArchName.split("+");
+
+  std::string MArch = arm::getARMArch(ArchName, Triple);
+  if (llvm::ARM::parseArch(MArch) == llvm::ARM::AK_INVALID ||
+      (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
+    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+}
+
+// Check -mcpu=. Needs ArchName to handle -mcpu=generic.
+static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args,
+                            llvm::StringRef CPUName, llvm::StringRef ArchName,
+                            std::vector<StringRef> &Features,
+                            const llvm::Triple &Triple) {
+  std::pair<StringRef, StringRef> Split = CPUName.split("+");
+
+  std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
+  if (arm::getLLVMArchSuffixForARM(CPU, ArchName, Triple).empty() ||
+      (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
+    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+}
+
+bool arm::useAAPCSForMachO(const llvm::Triple &T) {
+  // The backend is hardwired to assume AAPCS for M-class processors, ensure
+  // the frontend matches that.
+  return T.getEnvironment() == llvm::Triple::EABI ||
+         T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
+}
+
+// Select the float ABI as determined by -msoft-float, -mhard-float, and
+// -mfloat-abi=.
+arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
+  const Driver &D = TC.getDriver();
+  const llvm::Triple &Triple = TC.getEffectiveTriple();
+  auto SubArch = getARMSubArchVersionNumber(Triple);
+  arm::FloatABI ABI = FloatABI::Invalid;
+  if (Arg *A =
+          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
+                          options::OPT_mfloat_abi_EQ)) {
+    if (A->getOption().matches(options::OPT_msoft_float)) {
+      ABI = FloatABI::Soft;
+    } else if (A->getOption().matches(options::OPT_mhard_float)) {
+      ABI = FloatABI::Hard;
+    } else {
+      ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
+                .Case("soft", FloatABI::Soft)
+                .Case("softfp", FloatABI::SoftFP)
+                .Case("hard", FloatABI::Hard)
+                .Default(FloatABI::Invalid);
+      if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
+        D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
+        ABI = FloatABI::Soft;
+      }
+    }
+
+    // It is incorrect to select hard float ABI on MachO platforms if the ABI is
+    // "apcs-gnu".
+    if (Triple.isOSBinFormatMachO() && !useAAPCSForMachO(Triple) &&
+        ABI == FloatABI::Hard) {
+      D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args)
+                                                       << Triple.getArchName();
+    }
+  }
+
+  // If unspecified, choose the default based on the platform.
+  if (ABI == FloatABI::Invalid) {
+    switch (Triple.getOS()) {
+    case llvm::Triple::Darwin:
+    case llvm::Triple::MacOSX:
+    case llvm::Triple::IOS:
+    case llvm::Triple::TvOS: {
+      // Darwin defaults to "softfp" for v6 and v7.
+      ABI = (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
+      ABI = Triple.isWatchABI() ? FloatABI::Hard : ABI;
+      break;
+    }
+    case llvm::Triple::WatchOS:
+      ABI = FloatABI::Hard;
+      break;
+
+    // FIXME: this is invalid for WindowsCE
+    case llvm::Triple::Win32:
+      ABI = FloatABI::Hard;
+      break;
+
+    case llvm::Triple::FreeBSD:
+      switch (Triple.getEnvironment()) {
+      case llvm::Triple::GNUEABIHF:
+        ABI = FloatABI::Hard;
+        break;
+      default:
+        // FreeBSD defaults to soft float
+        ABI = FloatABI::Soft;
+        break;
+      }
+      break;
+
+    case llvm::Triple::OpenBSD:
+      ABI = FloatABI::Soft;
+      break;
+
+    default:
+      switch (Triple.getEnvironment()) {
+      case llvm::Triple::GNUEABIHF:
+      case llvm::Triple::MuslEABIHF:
+      case llvm::Triple::EABIHF:
+        ABI = FloatABI::Hard;
+        break;
+      case llvm::Triple::GNUEABI:
+      case llvm::Triple::MuslEABI:
+      case llvm::Triple::EABI:
+        // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
+        ABI = FloatABI::SoftFP;
+        break;
+      case llvm::Triple::Android:
+        ABI = (SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
+        break;
+      default:
+        // Assume "soft", but warn the user we are guessing.
+        if (Triple.isOSBinFormatMachO() &&
+            Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
+          ABI = FloatABI::Hard;
+        else
+          ABI = FloatABI::Soft;
+
+        if (Triple.getOS() != llvm::Triple::UnknownOS ||
+            !Triple.isOSBinFormatMachO())
+          D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
+        break;
+      }
+    }
+  }
+
+  assert(ABI != FloatABI::Invalid && "must select an ABI");
+  return ABI;
+}
+
+void arm::getARMTargetFeatures(const ToolChain &TC,
+                               const llvm::Triple &Triple,
+                               const ArgList &Args,
+                               ArgStringList &CmdArgs,
+                               std::vector<StringRef> &Features,
+                               bool ForAS) {
+  const Driver &D = TC.getDriver();
+
+  bool KernelOrKext =
+      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
+  arm::FloatABI ABI = arm::getARMFloatABI(TC, Args);
+  const Arg *WaCPU = nullptr, *WaFPU = nullptr;
+  const Arg *WaHDiv = nullptr, *WaArch = nullptr;
+
+  if (!ForAS) {
+    // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
+    // yet (it uses the -mfloat-abi and -msoft-float options), and it is
+    // stripped out by the ARM target. We should probably pass this a new
+    // -target-option, which is handled by the -cc1/-cc1as invocation.
+    //
+    // FIXME2:  For consistency, it would be ideal if we set up the target
+    // machine state the same when using the frontend or the assembler. We don't
+    // currently do that for the assembler, we pass the options directly to the
+    // backend and never even instantiate the frontend TargetInfo. If we did,
+    // and used its handleTargetFeatures hook, then we could ensure the
+    // assembler and the frontend behave the same.
+
+    // Use software floating point operations?
+    if (ABI == arm::FloatABI::Soft)
+      Features.push_back("+soft-float");
+
+    // Use software floating point argument passing?
+    if (ABI != arm::FloatABI::Hard)
+      Features.push_back("+soft-float-abi");
+  } else {
+    // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down
+    // to the assembler correctly.
+    for (const Arg *A :
+         Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
+      StringRef Value = A->getValue();
+      if (Value.startswith("-mfpu=")) {
+        WaFPU = A;
+      } else if (Value.startswith("-mcpu=")) {
+        WaCPU = A;
+      } else if (Value.startswith("-mhwdiv=")) {
+        WaHDiv = A;
+      } else if (Value.startswith("-march=")) {
+        WaArch = A;
+      }
+    }
+  }
+
+  // Check -march. ClangAs gives preference to -Wa,-march=.
+  const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
+  StringRef ArchName;
+  if (WaArch) {
+    if (ArchArg)
+      D.Diag(clang::diag::warn_drv_unused_argument)
+          << ArchArg->getAsString(Args);
+    ArchName = StringRef(WaArch->getValue()).substr(7);
+    checkARMArchName(D, WaArch, Args, ArchName, Features, Triple);
+    // FIXME: Set Arch.
+    D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args);
+  } else if (ArchArg) {
+    ArchName = ArchArg->getValue();
+    checkARMArchName(D, ArchArg, Args, ArchName, Features, Triple);
+  }
+
+  // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
+  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
+  StringRef CPUName;
+  if (WaCPU) {
+    if (CPUArg)
+      D.Diag(clang::diag::warn_drv_unused_argument)
+          << CPUArg->getAsString(Args);
+    CPUName = StringRef(WaCPU->getValue()).substr(6);
+    checkARMCPUName(D, WaCPU, Args, CPUName, ArchName, Features, Triple);
+  } else if (CPUArg) {
+    CPUName = CPUArg->getValue();
+    checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, Features, Triple);
+  }
+
+  // Add CPU features for generic CPUs
+  if (CPUName == "native") {
+    llvm::StringMap<bool> HostFeatures;
+    if (llvm::sys::getHostCPUFeatures(HostFeatures))
+      for (auto &F : HostFeatures)
+        Features.push_back(
+            Args.MakeArgString((F.second ? "+" : "-") + F.first()));
+  }
+
+  // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
+  const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
+  if (WaFPU) {
+    if (FPUArg)
+      D.Diag(clang::diag::warn_drv_unused_argument)
+          << FPUArg->getAsString(Args);
+    getARMFPUFeatures(D, WaFPU, Args, StringRef(WaFPU->getValue()).substr(6),
+                      Features);
+  } else if (FPUArg) {
+    getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
+  }
+
+  // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=.
+  const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
+  if (WaHDiv) {
+    if (HDivArg)
+      D.Diag(clang::diag::warn_drv_unused_argument)
+          << HDivArg->getAsString(Args);
+    getARMHWDivFeatures(D, WaHDiv, Args,
+                        StringRef(WaHDiv->getValue()).substr(8), Features);
+  } else if (HDivArg)
+    getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features);
+
+  // Setting -msoft-float effectively disables NEON because of the GCC
+  // implementation, although the same isn't true of VFP or VFP3.
+  if (ABI == arm::FloatABI::Soft) {
+    Features.push_back("-neon");
+    // Also need to explicitly disable features which imply NEON.
+    Features.push_back("-crypto");
+  }
+
+  // En/disable crc code generation.
+  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
+    if (A->getOption().matches(options::OPT_mcrc))
+      Features.push_back("+crc");
+    else
+      Features.push_back("-crc");
+  }
+
+  // Look for the last occurrence of -mlong-calls or -mno-long-calls. If
+  // neither options are specified, see if we are compiling for kernel/kext and
+  // decide whether to pass "+long-calls" based on the OS and its version.
+  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
+                               options::OPT_mno_long_calls)) {
+    if (A->getOption().matches(options::OPT_mlong_calls))
+      Features.push_back("+long-calls");
+  } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
+             !Triple.isWatchOS()) {
+      Features.push_back("+long-calls");
+  }
+
+  // Generate execute-only output (no data access to code sections).
+  // This only makes sense for the compiler, not for the assembler.
+  if (!ForAS) {
+    // Supported only on ARMv6T2 and ARMv7 and above.
+    // Cannot be combined with -mno-movt or -mlong-calls
+    if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
+      if (A->getOption().matches(options::OPT_mexecute_only)) {
+        if (getARMSubArchVersionNumber(Triple) < 7 &&
+            llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::AK_ARMV6T2)
+              D.Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
+        else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
+          D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
+        // Long calls create constant pool entries and have not yet been fixed up
+        // to play nicely with execute-only. Hence, they cannot be used in
+        // execute-only code for now
+        else if (Arg *B = Args.getLastArg(options::OPT_mlong_calls, options::OPT_mno_long_calls)) {
+          if (B->getOption().matches(options::OPT_mlong_calls))
+            D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
+        }
+
+        CmdArgs.push_back("-backend-option");
+        CmdArgs.push_back("-arm-execute-only");
+      }
+    }
+  }
+
+  // Kernel code has more strict alignment requirements.
+  if (KernelOrKext)
+    Features.push_back("+strict-align");
+  else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
+                                    options::OPT_munaligned_access)) {
+    if (A->getOption().matches(options::OPT_munaligned_access)) {
+      // No v6M core supports unaligned memory access (v6M ARM ARM A3.2).
+      if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
+        D.Diag(diag::err_target_unsupported_unaligned) << "v6m";
+      // v8M Baseline follows on from v6M, so doesn't support unaligned memory
+      // access either.
+      else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
+        D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base";
+    } else
+      Features.push_back("+strict-align");
+  } else {
+    // Assume pre-ARMv6 doesn't support unaligned accesses.
+    //
+    // ARMv6 may or may not support unaligned accesses depending on the
+    // SCTLR.U bit, which is architecture-specific. We assume ARMv6
+    // Darwin and NetBSD targets support unaligned accesses, and others don't.
+    //
+    // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
+    // which raises an alignment fault on unaligned accesses. Linux
+    // defaults this bit to 0 and handles it as a system-wide (not
+    // per-process) setting. It is therefore safe to assume that ARMv7+
+    // Linux targets support unaligned accesses. The same goes for NaCl.
+    //
+    // The above behavior is consistent with GCC.
+    int VersionNum = getARMSubArchVersionNumber(Triple);
+    if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
+      if (VersionNum < 6 ||
+          Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
+        Features.push_back("+strict-align");
+    } else if (Triple.isOSLinux() || Triple.isOSNaCl()) {
+      if (VersionNum < 7)
+        Features.push_back("+strict-align");
+    } else
+      Features.push_back("+strict-align");
+  }
+
+  // llvm does not support reserving registers in general. There is support
+  // for reserving r9 on ARM though (defined as a platform-specific register
+  // in ARM EABI).
+  if (Args.hasArg(options::OPT_ffixed_r9))
+    Features.push_back("+reserve-r9");
+
+  // The kext linker doesn't know how to deal with movw/movt.
+  if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
+    Features.push_back("+no-movt");
+}
+
+const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
+  std::string MArch;
+  if (!Arch.empty())
+    MArch = Arch;
+  else
+    MArch = Triple.getArchName();
+  MArch = StringRef(MArch).split("+").first.lower();
+
+  // Handle -march=native.
+  if (MArch == "native") {
+    std::string CPU = llvm::sys::getHostCPUName();
+    if (CPU != "generic") {
+      // Translate the native cpu into the architecture suffix for that CPU.
+      StringRef Suffix = arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
+      // If there is no valid architecture suffix for this CPU we don't know how
+      // to handle it, so return no architecture.
+      if (Suffix.empty())
+        MArch = "";
+      else
+        MArch = std::string("arm") + Suffix.str();
+    }
+  }
+
+  return MArch;
+}
+
+/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
+StringRef arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) {
+  std::string MArch = getARMArch(Arch, Triple);
+  // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch
+  // here means an -march=native that we can't handle, so instead return no CPU.
+  if (MArch.empty())
+    return StringRef();
+
+  // We need to return an empty string here on invalid MArch values as the
+  // various places that call this function can't cope with a null result.
+  return Triple.getARMCPUForArch(MArch);
+}
+
+/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
+std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,
+                                 const llvm::Triple &Triple) {
+  // FIXME: Warn on inconsistent use of -mcpu and -march.
+  // If we have -mcpu=, use that.
+  if (!CPU.empty()) {
+    std::string MCPU = StringRef(CPU).split("+").first.lower();
+    // Handle -mcpu=native.
+    if (MCPU == "native")
+      return llvm::sys::getHostCPUName();
+    else
+      return MCPU;
+  }
+
+  return getARMCPUForMArch(Arch, Triple);
+}
+
+/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
+/// CPU  (or Arch, if CPU is generic).
+// FIXME: This is redundant with -mcpu, why does LLVM use this.
+StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
+                                       const llvm::Triple &Triple) {
+  unsigned ArchKind;
+  if (CPU == "generic") {
+    std::string ARMArch = tools::arm::getARMArch(Arch, Triple);
+    ArchKind = llvm::ARM::parseArch(ARMArch);
+    if (ArchKind == llvm::ARM::AK_INVALID)
+      // In case of generic Arch, i.e. "arm",
+      // extract arch from default cpu of the Triple
+      ArchKind = llvm::ARM::parseCPUArch(Triple.getARMCPUForArch(ARMArch));
+  } else {
+    // FIXME: horrible hack to get around the fact that Cortex-A7 is only an
+    // armv7k triple if it's actually been specified via "-arch armv7k".
+    ArchKind = (Arch == "armv7k" || Arch == "thumbv7k")
+                          ? (unsigned)llvm::ARM::AK_ARMV7K
+                          : llvm::ARM::parseCPUArch(CPU);
+  }
+  if (ArchKind == llvm::ARM::AK_INVALID)
+    return "";
+  return llvm::ARM::getSubArch(ArchKind);
+}
+
+void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs,
+                            const llvm::Triple &Triple) {
+  if (Args.hasArg(options::OPT_r))
+    return;
+
+  // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker
+  // to generate BE-8 executables.
+  if (arm::getARMSubArchVersionNumber(Triple) >= 7 || arm::isARMMProfile(Triple))
+    CmdArgs.push_back("--be8");
+}
diff --git a/lib/Driver/ToolChains/Arch/ARM.h b/lib/Driver/ToolChains/Arch/ARM.h
new file mode 100644
index 0000000..5601799
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/ARM.h
@@ -0,0 +1,60 @@
+//===--- ARM.h - ARM-specific (not AArch64) Tool Helpers --------*- 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_LIB_DRIVER_TOOLCHAINS_ARCH_ARM_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_ARM_H
+
+#include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace arm {
+
+std::string getARMTargetCPU(StringRef CPU, llvm::StringRef Arch,
+                            const llvm::Triple &Triple);
+const std::string getARMArch(llvm::StringRef Arch, const llvm::Triple &Triple);
+StringRef getARMCPUForMArch(llvm::StringRef Arch, const llvm::Triple &Triple);
+StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch,
+                                  const llvm::Triple &Triple);
+
+void appendEBLinkFlags(const llvm::opt::ArgList &Args,
+                       llvm::opt::ArgStringList &CmdArgs,
+                       const llvm::Triple &Triple);
+enum class FloatABI {
+  Invalid,
+  Soft,
+  SoftFP,
+  Hard,
+};
+
+FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args);
+
+bool useAAPCSForMachO(const llvm::Triple &T);
+void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args,
+                           llvm::StringRef &Arch, llvm::StringRef &CPU,
+                           bool FromAs = false);
+void getARMTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
+                          const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs,
+                          std::vector<llvm::StringRef> &Features, bool ForAS);
+int getARMSubArchVersionNumber(const llvm::Triple &Triple);
+bool isARMMProfile(const llvm::Triple &Triple);
+
+} // end namespace arm
+} // end namespace target
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_ARM_H
diff --git a/lib/Driver/ToolChains/Arch/Mips.cpp b/lib/Driver/ToolChains/Arch/Mips.cpp
new file mode 100644
index 0000000..cd791af
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/Mips.cpp
@@ -0,0 +1,403 @@
+//===--- Mips.cpp - Tools Implementations -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Mips.h"
+#include "ToolChains/CommonArgs.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+bool tools::isMipsArch(llvm::Triple::ArchType Arch) {
+  return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel ||
+         Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
+}
+
+// Get CPU and ABI names. They are not independent
+// so we have to calculate them together.
+void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
+                            StringRef &CPUName, StringRef &ABIName) {
+  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";
+  }
+
+  // MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android).
+  if (Triple.isAndroid()) {
+    DefMips32CPU = "mips32";
+    DefMips64CPU = "mips64r6";
+  }
+
+  // MIPS3 is the default for mips64*-unknown-openbsd.
+  if (Triple.getOS() == llvm::Triple::OpenBSD)
+    DefMips64CPU = "mips3";
+
+  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ,
+                               options::OPT_mcpu_EQ))
+    CPUName = A->getValue();
+
+  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
+    ABIName = A->getValue();
+    // Convert a GNU style Mips ABI name to the name
+    // accepted by LLVM Mips backend.
+    ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
+                  .Case("32", "o32")
+                  .Case("64", "n64")
+                  .Default(ABIName);
+  }
+
+  // Setup default CPU and ABI names.
+  if (CPUName.empty() && ABIName.empty()) {
+    switch (Triple.getArch()) {
+    default:
+      llvm_unreachable("Unexpected triple arch name");
+    case llvm::Triple::mips:
+    case llvm::Triple::mipsel:
+      CPUName = DefMips32CPU;
+      break;
+    case llvm::Triple::mips64:
+    case llvm::Triple::mips64el:
+      CPUName = DefMips64CPU;
+      break;
+    }
+  }
+
+  if (ABIName.empty() &&
+      (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
+       Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
+    ABIName = llvm::StringSwitch<const char *>(CPUName)
+                  .Case("mips1", "o32")
+                  .Case("mips2", "o32")
+                  .Case("mips3", "n64")
+                  .Case("mips4", "n64")
+                  .Case("mips5", "n64")
+                  .Case("mips32", "o32")
+                  .Case("mips32r2", "o32")
+                  .Case("mips32r3", "o32")
+                  .Case("mips32r5", "o32")
+                  .Case("mips32r6", "o32")
+                  .Case("mips64", "n64")
+                  .Case("mips64r2", "n64")
+                  .Case("mips64r3", "n64")
+                  .Case("mips64r5", "n64")
+                  .Case("mips64r6", "n64")
+                  .Case("octeon", "n64")
+                  .Case("p5600", "o32")
+                  .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";
+  }
+
+  if (CPUName.empty()) {
+    // Deduce CPU name from ABI name.
+    CPUName = llvm::StringSwitch<const char *>(ABIName)
+                  .Case("o32", DefMips32CPU)
+                  .Cases("n32", "n64", DefMips64CPU)
+                  .Default("");
+  }
+
+  // FIXME: Warn on inconsistent use of -march and -mabi.
+}
+
+std::string mips::getMipsABILibSuffix(const ArgList &Args,
+                                      const llvm::Triple &Triple) {
+  StringRef CPUName, ABIName;
+  tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+  return llvm::StringSwitch<std::string>(ABIName)
+      .Case("o32", "")
+      .Case("n32", "32")
+      .Case("n64", "64");
+}
+
+// Convert ABI name to the GNU tools acceptable variant.
+StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) {
+  return llvm::StringSwitch<llvm::StringRef>(ABI)
+      .Case("o32", "32")
+      .Case("n64", "64")
+      .Default(ABI);
+}
+
+// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
+// and -mfloat-abi=.
+mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args) {
+  mips::FloatABI ABI = mips::FloatABI::Invalid;
+  if (Arg *A =
+          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
+                          options::OPT_mfloat_abi_EQ)) {
+    if (A->getOption().matches(options::OPT_msoft_float))
+      ABI = mips::FloatABI::Soft;
+    else if (A->getOption().matches(options::OPT_mhard_float))
+      ABI = mips::FloatABI::Hard;
+    else {
+      ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
+                .Case("soft", mips::FloatABI::Soft)
+                .Case("hard", mips::FloatABI::Hard)
+                .Default(mips::FloatABI::Invalid);
+      if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
+        D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
+        ABI = mips::FloatABI::Hard;
+      }
+    }
+  }
+
+  // If unspecified, choose the default based on the platform.
+  if (ABI == mips::FloatABI::Invalid) {
+    // Assume "hard", because it's a default value used by gcc.
+    // When we start to recognize specific target MIPS processors,
+    // we will be able to select the default more correctly.
+    ABI = mips::FloatABI::Hard;
+  }
+
+  assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
+  return ABI;
+}
+
+void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                                 const ArgList &Args,
+                                 std::vector<StringRef> &Features) {
+  StringRef CPUName;
+  StringRef ABIName;
+  getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+  ABIName = getGnuCompatibleMipsABIName(ABIName);
+
+  // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a
+  // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI
+  // extension was developed by Richard Sandiford & Code Sourcery to support
+  // static code calling PIC code (CPIC). For O32 and N32 this means we have
+  // several combinations of PIC/static and abicalls. Pure static, static
+  // with the CPIC extension, and pure PIC code.
+
+  // At final link time, O32 and N32 with CPIC will have another section
+  // added to the binary which contains the stub functions to perform
+  // any fixups required for PIC code.
+
+  // For N64, the situation is more regular: code can either be static
+  // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code
+  // code for N64. Since Clang has already built the relocation model portion
+  // of the commandline, we pick add +noabicalls feature in the N64 static
+  // case.
+
+  // The is another case to be accounted for: -msym32, which enforces that all
+  // symbols have 32 bits in size. In this case, N64 can in theory use CPIC
+  // but it is unsupported.
+
+  // The combinations for N64 are:
+  // a) Static without abicalls and 64bit symbols.
+  // b) Static with abicalls and 32bit symbols.
+  // c) PIC with abicalls and 64bit symbols.
+
+  // For case (a) we need to add +noabicalls for N64.
+
+  bool IsN64 = ABIName == "64";
+  bool NonPIC = false;
+
+  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
+                                    options::OPT_fpic, options::OPT_fno_pic,
+                                    options::OPT_fPIE, options::OPT_fno_PIE,
+                                    options::OPT_fpie, options::OPT_fno_pie);
+  if (LastPICArg) {
+    Option O = LastPICArg->getOption();
+    NonPIC =
+        (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
+         O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
+  }
+
+  if (IsN64 && NonPIC) {
+    Features.push_back("+noabicalls");
+  } else {
+    AddTargetFeature(Args, Features, options::OPT_mno_abicalls,
+                     options::OPT_mabicalls, "noabicalls");
+  }
+
+  mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args);
+  if (FloatABI == mips::FloatABI::Soft) {
+    // FIXME: Note, this is a hack. We need to pass the selected float
+    // mode to the MipsTargetInfoBase to define appropriate macros there.
+    // Now it is the only method.
+    Features.push_back("+soft-float");
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
+    StringRef Val = StringRef(A->getValue());
+    if (Val == "2008") {
+      if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008)
+        Features.push_back("+nan2008");
+      else {
+        Features.push_back("-nan2008");
+        D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
+      }
+    } else if (Val == "legacy") {
+      if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy)
+        Features.push_back("-nan2008");
+      else {
+        Features.push_back("+nan2008");
+        D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
+      }
+    } else
+      D.Diag(diag::err_drv_unsupported_option_argument)
+          << A->getOption().getName() << Val;
+  }
+
+  AddTargetFeature(Args, Features, options::OPT_msingle_float,
+                   options::OPT_mdouble_float, "single-float");
+  AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
+                   "mips16");
+  AddTargetFeature(Args, Features, options::OPT_mmicromips,
+                   options::OPT_mno_micromips, "micromips");
+  AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
+                   "dsp");
+  AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
+                   "dspr2");
+  AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
+                   "msa");
+
+  // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
+  // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
+  // nooddspreg.
+  if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
+                               options::OPT_mfp64)) {
+    if (A->getOption().matches(options::OPT_mfp32))
+      Features.push_back(Args.MakeArgString("-fp64"));
+    else if (A->getOption().matches(options::OPT_mfpxx)) {
+      Features.push_back(Args.MakeArgString("+fpxx"));
+      Features.push_back(Args.MakeArgString("+nooddspreg"));
+    } else
+      Features.push_back(Args.MakeArgString("+fp64"));
+  } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
+    Features.push_back(Args.MakeArgString("+fpxx"));
+    Features.push_back(Args.MakeArgString("+nooddspreg"));
+  } else if (mips::isFP64ADefault(Triple, CPUName)) {
+    Features.push_back(Args.MakeArgString("+fp64"));
+    Features.push_back(Args.MakeArgString("+nooddspreg"));
+  }
+
+  AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
+                   options::OPT_modd_spreg, "nooddspreg");
+}
+
+mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
+  // Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008
+  // was first introduced in Release 3. However, other compilers have
+  // traditionally allowed it for Release 2 so we should do the same.
+  return (NanEncoding)llvm::StringSwitch<int>(CPU)
+      .Case("mips1", NanLegacy)
+      .Case("mips2", NanLegacy)
+      .Case("mips3", NanLegacy)
+      .Case("mips4", NanLegacy)
+      .Case("mips5", NanLegacy)
+      .Case("mips32", NanLegacy)
+      .Case("mips32r2", NanLegacy | Nan2008)
+      .Case("mips32r3", NanLegacy | Nan2008)
+      .Case("mips32r5", NanLegacy | Nan2008)
+      .Case("mips32r6", Nan2008)
+      .Case("mips64", NanLegacy)
+      .Case("mips64r2", NanLegacy | Nan2008)
+      .Case("mips64r3", NanLegacy | Nan2008)
+      .Case("mips64r5", NanLegacy | Nan2008)
+      .Case("mips64r6", Nan2008)
+      .Default(NanLegacy);
+}
+
+bool mips::hasCompactBranches(StringRef &CPU) {
+  // mips32r6 and mips64r6 have compact branches.
+  return llvm::StringSwitch<bool>(CPU)
+      .Case("mips32r6", true)
+      .Case("mips64r6", true)
+      .Default(false);
+}
+
+bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
+  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
+  return A && (A->getValue() == StringRef(Value));
+}
+
+bool mips::isUCLibc(const ArgList &Args) {
+  Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
+  return A && A->getOption().matches(options::OPT_muclibc);
+}
+
+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;
+}
+
+bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
+  if (!Triple.isAndroid())
+    return false;
+
+  // Android MIPS32R6 defaults to FP64A.
+  return llvm::StringSwitch<bool>(CPUName)
+      .Case("mips32r6", true)
+      .Default(false);
+}
+
+bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
+                         StringRef ABIName, mips::FloatABI FloatABI) {
+  if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
+      Triple.getVendor() != llvm::Triple::MipsTechnologies &&
+      !Triple.isAndroid())
+    return false;
+
+  if (ABIName != "32")
+    return false;
+
+  // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
+  // present.
+  if (FloatABI == mips::FloatABI::Soft)
+    return false;
+
+  return llvm::StringSwitch<bool>(CPUName)
+      .Cases("mips2", "mips3", "mips4", "mips5", true)
+      .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
+      .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
+      .Default(false);
+}
+
+bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
+                         StringRef CPUName, StringRef ABIName,
+                         mips::FloatABI FloatABI) {
+  bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
+
+  // FPXX shouldn't be used if -msingle-float is present.
+  if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
+                               options::OPT_mdouble_float))
+    if (A->getOption().matches(options::OPT_msingle_float))
+      UseFPXX = false;
+
+  return UseFPXX;
+}
diff --git a/lib/Driver/ToolChains/Arch/Mips.h b/lib/Driver/ToolChains/Arch/Mips.h
new file mode 100644
index 0000000..0b78866
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/Mips.h
@@ -0,0 +1,62 @@
+//===--- Mips.h - Mips-specific Tool Helpers ----------------------*- 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_LIB_DRIVER_TOOLCHAINS_ARCH_MIPS_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_MIPS_H
+
+#include "clang/Driver/Driver.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+bool isMipsArch(llvm::Triple::ArchType Arch);
+
+namespace mips {
+typedef enum { NanLegacy = 1, Nan2008 = 2 } NanEncoding;
+
+enum class FloatABI {
+  Invalid,
+  Soft,
+  Hard,
+};
+
+NanEncoding getSupportedNanEncoding(StringRef &CPU);
+bool hasCompactBranches(StringRef &CPU);
+void getMipsCPUAndABI(const llvm::opt::ArgList &Args,
+                      const llvm::Triple &Triple, StringRef &CPUName,
+                      StringRef &ABIName);
+void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                           const llvm::opt::ArgList &Args,
+                           std::vector<StringRef> &Features);
+StringRef getGnuCompatibleMipsABIName(StringRef ABI);
+mips::FloatABI getMipsFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
+std::string getMipsABILibSuffix(const llvm::opt::ArgList &Args,
+                                const llvm::Triple &Triple);
+bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value);
+bool isUCLibc(const llvm::opt::ArgList &Args);
+bool isNaN2008(const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
+bool isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName);
+bool isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
+                   StringRef ABIName, mips::FloatABI FloatABI);
+bool shouldUseFPXX(const llvm::opt::ArgList &Args, const llvm::Triple &Triple,
+                   StringRef CPUName, StringRef ABIName,
+                   mips::FloatABI FloatABI);
+
+} // end namespace mips
+} // end namespace target
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_MIPS_H
diff --git a/lib/Driver/ToolChains/Arch/PPC.cpp b/lib/Driver/ToolChains/Arch/PPC.cpp
new file mode 100644
index 0000000..e83b4fe
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/PPC.cpp
@@ -0,0 +1,135 @@
+//===--- PPC.cpp - PPC Helpers for Tools ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PPC.h"
+#include "ToolChains/CommonArgs.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
+std::string ppc::getPPCTargetCPU(const ArgList &Args) {
+  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
+    StringRef CPUName = A->getValue();
+
+    if (CPUName == "native") {
+      std::string CPU = llvm::sys::getHostCPUName();
+      if (!CPU.empty() && CPU != "generic")
+        return CPU;
+      else
+        return "";
+    }
+
+    return llvm::StringSwitch<const char *>(CPUName)
+        .Case("common", "generic")
+        .Case("440", "440")
+        .Case("440fp", "440")
+        .Case("450", "450")
+        .Case("601", "601")
+        .Case("602", "602")
+        .Case("603", "603")
+        .Case("603e", "603e")
+        .Case("603ev", "603ev")
+        .Case("604", "604")
+        .Case("604e", "604e")
+        .Case("620", "620")
+        .Case("630", "pwr3")
+        .Case("G3", "g3")
+        .Case("7400", "7400")
+        .Case("G4", "g4")
+        .Case("7450", "7450")
+        .Case("G4+", "g4+")
+        .Case("750", "750")
+        .Case("970", "970")
+        .Case("G5", "g5")
+        .Case("a2", "a2")
+        .Case("a2q", "a2q")
+        .Case("e500mc", "e500mc")
+        .Case("e5500", "e5500")
+        .Case("power3", "pwr3")
+        .Case("power4", "pwr4")
+        .Case("power5", "pwr5")
+        .Case("power5x", "pwr5x")
+        .Case("power6", "pwr6")
+        .Case("power6x", "pwr6x")
+        .Case("power7", "pwr7")
+        .Case("power8", "pwr8")
+        .Case("power9", "pwr9")
+        .Case("pwr3", "pwr3")
+        .Case("pwr4", "pwr4")
+        .Case("pwr5", "pwr5")
+        .Case("pwr5x", "pwr5x")
+        .Case("pwr6", "pwr6")
+        .Case("pwr6x", "pwr6x")
+        .Case("pwr7", "pwr7")
+        .Case("pwr8", "pwr8")
+        .Case("pwr9", "pwr9")
+        .Case("powerpc", "ppc")
+        .Case("powerpc64", "ppc64")
+        .Case("powerpc64le", "ppc64le")
+        .Default("");
+  }
+
+  return "";
+}
+
+void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                               const ArgList &Args,
+                               std::vector<StringRef> &Features) {
+  handleTargetFeaturesGroup(Args, Features, options::OPT_m_ppc_Features_Group);
+
+  ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
+  if (FloatABI == ppc::FloatABI::Soft)
+    Features.push_back("-hard-float");
+
+  // Altivec is a bit weird, allow overriding of the Altivec feature here.
+  AddTargetFeature(Args, Features, options::OPT_faltivec,
+                   options::OPT_fno_altivec, "altivec");
+}
+
+ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {
+  ppc::FloatABI ABI = ppc::FloatABI::Invalid;
+  if (Arg *A =
+          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
+                          options::OPT_mfloat_abi_EQ)) {
+    if (A->getOption().matches(options::OPT_msoft_float))
+      ABI = ppc::FloatABI::Soft;
+    else if (A->getOption().matches(options::OPT_mhard_float))
+      ABI = ppc::FloatABI::Hard;
+    else {
+      ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())
+                .Case("soft", ppc::FloatABI::Soft)
+                .Case("hard", ppc::FloatABI::Hard)
+                .Default(ppc::FloatABI::Invalid);
+      if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
+        D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
+        ABI = ppc::FloatABI::Hard;
+      }
+    }
+  }
+
+  // If unspecified, choose the default based on the platform.
+  if (ABI == ppc::FloatABI::Invalid) {
+    ABI = ppc::FloatABI::Hard;
+  }
+
+  return ABI;
+}
+
+bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
+  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
+  return A && (A->getValue() == StringRef(Value));
+}
diff --git a/lib/Driver/ToolChains/Arch/PPC.h b/lib/Driver/ToolChains/Arch/PPC.h
new file mode 100644
index 0000000..892eb2c
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/PPC.h
@@ -0,0 +1,45 @@
+//===--- PPC.h - PPC-specific Tool Helpers ----------------------*- 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_LIB_DRIVER_TOOLCHAINS_ARCH_PPC_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_PPC_H
+
+#include "clang/Driver/Driver.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace ppc {
+
+bool hasPPCAbiArg(const llvm::opt::ArgList &Args, const char *Value);
+
+enum class FloatABI {
+  Invalid,
+  Soft,
+  Hard,
+};
+
+FloatABI getPPCFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
+
+std::string getPPCTargetCPU(const llvm::opt::ArgList &Args);
+
+void getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                          const llvm::opt::ArgList &Args,
+                          std::vector<llvm::StringRef> &Features);
+
+} // end namespace ppc
+} // end namespace target
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_PPC_H
diff --git a/lib/Driver/ToolChains/Arch/Sparc.cpp b/lib/Driver/ToolChains/Arch/Sparc.cpp
new file mode 100644
index 0000000..594ec99
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/Sparc.cpp
@@ -0,0 +1,100 @@
+//===--- Sparc.cpp - Tools Implementations ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sparc.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+const char *sparc::getSparcAsmModeForCPU(StringRef Name,
+                                         const llvm::Triple &Triple) {
+  if (Triple.getArch() == llvm::Triple::sparcv9) {
+    return llvm::StringSwitch<const char *>(Name)
+        .Case("niagara", "-Av9b")
+        .Case("niagara2", "-Av9b")
+        .Case("niagara3", "-Av9d")
+        .Case("niagara4", "-Av9d")
+        .Default("-Av9");
+  } else {
+    return llvm::StringSwitch<const char *>(Name)
+        .Case("v8", "-Av8")
+        .Case("supersparc", "-Av8")
+        .Case("sparclite", "-Asparclite")
+        .Case("f934", "-Asparclite")
+        .Case("hypersparc", "-Av8")
+        .Case("sparclite86x", "-Asparclite")
+        .Case("sparclet", "-Asparclet")
+        .Case("tsc701", "-Asparclet")
+        .Case("v9", "-Av8plus")
+        .Case("ultrasparc", "-Av8plus")
+        .Case("ultrasparc3", "-Av8plus")
+        .Case("niagara", "-Av8plusb")
+        .Case("niagara2", "-Av8plusb")
+        .Case("niagara3", "-Av8plusd")
+        .Case("niagara4", "-Av8plusd")
+        .Case("leon2", "-Av8")
+        .Case("at697e", "-Av8")
+        .Case("at697f", "-Av8")
+        .Case("leon3", "-Av8")
+        .Case("ut699", "-Av8")
+        .Case("gr712rc", "-Av8")
+        .Case("leon4", "-Av8")
+        .Case("gr740", "-Av8")
+        .Default("-Av8");
+  }
+}
+
+sparc::FloatABI sparc::getSparcFloatABI(const Driver &D,
+                                        const ArgList &Args) {
+  sparc::FloatABI ABI = sparc::FloatABI::Invalid;
+  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_msoft_float,
+                               options::OPT_mhard_float,
+                               options::OPT_mfloat_abi_EQ)) {
+    if (A->getOption().matches(clang::driver::options::OPT_msoft_float))
+      ABI = sparc::FloatABI::Soft;
+    else if (A->getOption().matches(options::OPT_mhard_float))
+      ABI = sparc::FloatABI::Hard;
+    else {
+      ABI = llvm::StringSwitch<sparc::FloatABI>(A->getValue())
+                .Case("soft", sparc::FloatABI::Soft)
+                .Case("hard", sparc::FloatABI::Hard)
+                .Default(sparc::FloatABI::Invalid);
+      if (ABI == sparc::FloatABI::Invalid &&
+          !StringRef(A->getValue()).empty()) {
+        D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
+        ABI = sparc::FloatABI::Hard;
+      }
+    }
+  }
+
+  // If unspecified, choose the default based on the platform.
+  // Only the hard-float ABI on Sparc is standardized, and it is the
+  // default. GCC also supports a nonstandard soft-float ABI mode, also
+  // implemented in LLVM. However as this is not standard we set the default
+  // to be hard-float.
+  if (ABI == sparc::FloatABI::Invalid) {
+    ABI = sparc::FloatABI::Hard;
+  }
+
+  return ABI;
+}
+
+void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args,
+                                   std::vector<StringRef> &Features) {
+  sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args);
+  if (FloatABI == sparc::FloatABI::Soft)
+    Features.push_back("+soft-float");
+}
diff --git a/lib/Driver/ToolChains/Arch/Sparc.h b/lib/Driver/ToolChains/Arch/Sparc.h
new file mode 100644
index 0000000..082b280
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/Sparc.h
@@ -0,0 +1,42 @@
+//===--- Sparc.h - Sparc-specific Tool Helpers ----------------------*- 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_LIB_DRIVER_TOOLCHAINS_ARCH_SPARC_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SPARC_H
+
+#include "clang/Driver/Driver.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace sparc {
+
+enum class FloatABI {
+  Invalid,
+  Soft,
+  Hard,
+};
+
+FloatABI getSparcFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
+
+void getSparcTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
+                            std::vector<llvm::StringRef> &Features);
+const char *getSparcAsmModeForCPU(llvm::StringRef Name,
+                                  const llvm::Triple &Triple);
+
+} // end namespace sparc
+} // end namespace target
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SPARC_H
diff --git a/lib/Driver/ToolChains/Arch/SystemZ.cpp b/lib/Driver/ToolChains/Arch/SystemZ.cpp
new file mode 100644
index 0000000..6ee724d
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/SystemZ.cpp
@@ -0,0 +1,41 @@
+//===--- SystemZ.cpp - SystemZ Helpers for Tools ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SystemZ.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+const char *systemz::getSystemZTargetCPU(const ArgList &Args) {
+  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ))
+    return A->getValue();
+  return "z10";
+}
+
+void systemz::getSystemZTargetFeatures(const ArgList &Args,
+                                       std::vector<llvm::StringRef> &Features) {
+  // -m(no-)htm overrides use of the transactional-execution facility.
+  if (Arg *A = Args.getLastArg(options::OPT_mhtm, options::OPT_mno_htm)) {
+    if (A->getOption().matches(options::OPT_mhtm))
+      Features.push_back("+transactional-execution");
+    else
+      Features.push_back("-transactional-execution");
+  }
+  // -m(no-)vx overrides use of the vector facility.
+  if (Arg *A = Args.getLastArg(options::OPT_mvx, options::OPT_mno_vx)) {
+    if (A->getOption().matches(options::OPT_mvx))
+      Features.push_back("+vector");
+    else
+      Features.push_back("-vector");
+  }
+}
diff --git a/lib/Driver/ToolChains/Arch/SystemZ.h b/lib/Driver/ToolChains/Arch/SystemZ.h
new file mode 100644
index 0000000..521f8c2
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/SystemZ.h
@@ -0,0 +1,32 @@
+//===--- SystemZ.h - SystemZ-specific Tool Helpers --------------*- 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_LIB_DRIVER_TOOLCHAINS_ARCH_SYSTEMZ_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SYSTEMZ_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace systemz {
+
+const char *getSystemZTargetCPU(const llvm::opt::ArgList &Args);
+
+void getSystemZTargetFeatures(const llvm::opt::ArgList &Args,
+                              std::vector<llvm::StringRef> &Features);
+
+} // end namespace systemz
+} // end namespace target
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SYSTEMZ_H
diff --git a/lib/Driver/ToolChains/Arch/X86.cpp b/lib/Driver/ToolChains/Arch/X86.cpp
new file mode 100644
index 0000000..fde4476
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/X86.cpp
@@ -0,0 +1,174 @@
+//===--- X86.cpp - X86 Helpers for Tools ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include "ToolChains/CommonArgs.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+const char *x86::getX86TargetCPU(const ArgList &Args,
+                                 const llvm::Triple &Triple) {
+  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
+    if (StringRef(A->getValue()) != "native") {
+      if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
+        return "core-avx2";
+
+      return A->getValue();
+    }
+
+    // FIXME: Reject attempts to use -march=native unless the target matches
+    // the host.
+    //
+    // FIXME: We should also incorporate the detected target features for use
+    // with -native.
+    std::string CPU = llvm::sys::getHostCPUName();
+    if (!CPU.empty() && CPU != "generic")
+      return Args.MakeArgString(CPU);
+  }
+
+  if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
+    // Mapping built by referring to X86TargetInfo::getDefaultFeatures().
+    StringRef Arch = A->getValue();
+    const char *CPU;
+    if (Triple.getArch() == llvm::Triple::x86) {
+      CPU = llvm::StringSwitch<const char *>(Arch)
+                .Case("IA32", "i386")
+                .Case("SSE", "pentium3")
+                .Case("SSE2", "pentium4")
+                .Case("AVX", "sandybridge")
+                .Case("AVX2", "haswell")
+                .Default(nullptr);
+    } else {
+      CPU = llvm::StringSwitch<const char *>(Arch)
+                .Case("AVX", "sandybridge")
+                .Case("AVX2", "haswell")
+                .Default(nullptr);
+    }
+    if (CPU)
+      return CPU;
+  }
+
+  // Select the default CPU if none was given (or detection failed).
+
+  if (Triple.getArch() != llvm::Triple::x86_64 &&
+      Triple.getArch() != llvm::Triple::x86)
+    return nullptr; // This routine is only handling x86 targets.
+
+  bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
+
+  // FIXME: Need target hooks.
+  if (Triple.isOSDarwin()) {
+    if (Triple.getArchName() == "x86_64h")
+      return "core-avx2";
+    // macosx10.12 drops support for all pre-Penryn Macs.
+    // Simulators can still run on 10.11 though, like Xcode.
+    if (Triple.isMacOSX() && !Triple.isOSVersionLT(10, 12))
+      return "penryn";
+    // The oldest x86_64 Macs have core2/Merom; the oldest x86 Macs have Yonah.
+    return Is64Bit ? "core2" : "yonah";
+  }
+
+  // Set up default CPU name for PS4 compilers.
+  if (Triple.isPS4CPU())
+    return "btver2";
+
+  // On Android use targets compatible with gcc
+  if (Triple.isAndroid())
+    return Is64Bit ? "x86-64" : "i686";
+
+  // Everything else goes to x86-64 in 64-bit mode.
+  if (Is64Bit)
+    return "x86-64";
+
+  switch (Triple.getOS()) {
+  case llvm::Triple::FreeBSD:
+  case llvm::Triple::NetBSD:
+  case llvm::Triple::OpenBSD:
+    return "i486";
+  case llvm::Triple::Haiku:
+    return "i586";
+  case llvm::Triple::Bitrig:
+    return "i686";
+  default:
+    // Fallback to p4.
+    return "pentium4";
+  }
+}
+
+void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                               const ArgList &Args,
+                               std::vector<StringRef> &Features) {
+  // If -march=native, autodetect the feature list.
+  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
+    if (StringRef(A->getValue()) == "native") {
+      llvm::StringMap<bool> HostFeatures;
+      if (llvm::sys::getHostCPUFeatures(HostFeatures))
+        for (auto &F : HostFeatures)
+          Features.push_back(
+              Args.MakeArgString((F.second ? "+" : "-") + F.first()));
+    }
+  }
+
+  if (Triple.getArchName() == "x86_64h") {
+    // x86_64h implies quite a few of the more modern subtarget features
+    // for Haswell class CPUs, but not all of them. Opt-out of a few.
+    Features.push_back("-rdrnd");
+    Features.push_back("-aes");
+    Features.push_back("-pclmul");
+    Features.push_back("-rtm");
+    Features.push_back("-hle");
+    Features.push_back("-fsgsbase");
+  }
+
+  const llvm::Triple::ArchType ArchType = Triple.getArch();
+  // Add features to be compatible with gcc for Android.
+  if (Triple.isAndroid()) {
+    if (ArchType == llvm::Triple::x86_64) {
+      Features.push_back("+sse4.2");
+      Features.push_back("+popcnt");
+    } else
+      Features.push_back("+ssse3");
+  }
+
+  // Set features according to the -arch flag on MSVC.
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
+    StringRef Arch = A->getValue();
+    bool ArchUsed = false;
+    // First, look for flags that are shared in x86 and x86-64.
+    if (ArchType == llvm::Triple::x86_64 || ArchType == llvm::Triple::x86) {
+      if (Arch == "AVX" || Arch == "AVX2") {
+        ArchUsed = true;
+        Features.push_back(Args.MakeArgString("+" + Arch.lower()));
+      }
+    }
+    // Then, look for x86-specific flags.
+    if (ArchType == llvm::Triple::x86) {
+      if (Arch == "IA32") {
+        ArchUsed = true;
+      } else if (Arch == "SSE" || Arch == "SSE2") {
+        ArchUsed = true;
+        Features.push_back(Args.MakeArgString("+" + Arch.lower()));
+      }
+    }
+    if (!ArchUsed)
+      D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args);
+  }
+
+  // Now add any that the user explicitly requested on the command line,
+  // which may override the defaults.
+  handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group);
+}
diff --git a/lib/Driver/ToolChains/Arch/X86.h b/lib/Driver/ToolChains/Arch/X86.h
new file mode 100644
index 0000000..20bf27a
--- /dev/null
+++ b/lib/Driver/ToolChains/Arch/X86.h
@@ -0,0 +1,37 @@
+//===--- X86.h - X86-specific Tool Helpers ----------------------*- 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_LIB_DRIVER_TOOLCHAINS_ARCH_X86_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_X86_H
+
+#include "clang/Driver/Driver.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace x86 {
+
+const char *getX86TargetCPU(const llvm::opt::ArgList &Args,
+                            const llvm::Triple &Triple);
+
+void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                          const llvm::opt::ArgList &Args,
+                          std::vector<llvm::StringRef> &Features);
+
+} // end namespace x86
+} // end namespace target
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_X86_H
diff --git a/lib/Driver/ToolChains/Bitrig.cpp b/lib/Driver/ToolChains/Bitrig.cpp
new file mode 100644
index 0000000..d8f541d
--- /dev/null
+++ b/lib/Driver/ToolChains/Bitrig.cpp
@@ -0,0 +1,190 @@
+//===--- Bitrig.cpp - Bitrig ToolChain Implementations ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Bitrig.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+void bitrig::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                     const InputInfo &Output,
+                                     const InputInfoList &Inputs,
+                                     const ArgList &Args,
+                                     const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void bitrig::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                  const InputInfo &Output,
+                                  const InputInfoList &Inputs,
+                                  const ArgList &Args,
+                                  const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
+    CmdArgs.push_back("-e");
+    CmdArgs.push_back("__start");
+  }
+
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    if (Args.hasArg(options::OPT_rdynamic))
+      CmdArgs.push_back("-export-dynamic");
+    CmdArgs.push_back("--eh-frame-hdr");
+    CmdArgs.push_back("-Bdynamic");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-shared");
+    } else {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/usr/libexec/ld.so");
+    }
+  }
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
+      else
+        CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
+    } else {
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
+    }
+  }
+
+  Args.AddAllArgs(CmdArgs,
+                  {options::OPT_L, options::OPT_T_Group, options::OPT_e});
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    if (D.CCCIsCXX()) {
+      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lm_p");
+      else
+        CmdArgs.push_back("-lm");
+    }
+
+    if (Args.hasArg(options::OPT_pthread)) {
+      if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lpthread_p");
+      else
+        CmdArgs.push_back("-lpthread");
+    }
+
+    if (!Args.hasArg(options::OPT_shared)) {
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lc_p");
+      else
+        CmdArgs.push_back("-lc");
+    }
+
+    StringRef MyArch;
+    switch (getToolChain().getArch()) {
+    case llvm::Triple::arm:
+      MyArch = "arm";
+      break;
+    case llvm::Triple::x86:
+      MyArch = "i386";
+      break;
+    case llvm::Triple::x86_64:
+      MyArch = "amd64";
+      break;
+    default:
+      llvm_unreachable("Unsupported architecture");
+    }
+    CmdArgs.push_back(Args.MakeArgString("-lclang_rt." + MyArch));
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+    else
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
+  }
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
+
+Bitrig::Bitrig(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+}
+
+Tool *Bitrig::buildAssembler() const {
+  return new tools::bitrig::Assembler(*this);
+}
+
+Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); }
+
+ToolChain::CXXStdlibType Bitrig::GetDefaultCXXStdlibType() const {
+  return ToolChain::CST_Libcxx;
+}
+
+void Bitrig::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+                                      llvm::opt::ArgStringList &CC1Args) const {
+  std::string Triple = getTriple().str();
+  if (StringRef(Triple).startswith("amd64"))
+    Triple = "x86_64" + Triple.substr(5);
+  addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/c++/stdc++",
+                           Triple, "", "", "", DriverArgs, CC1Args);
+}
+
+void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
+                                 ArgStringList &CmdArgs) const {
+  switch (GetCXXStdlibType(Args)) {
+  case ToolChain::CST_Libcxx:
+    CmdArgs.push_back("-lc++");
+    CmdArgs.push_back("-lc++abi");
+    CmdArgs.push_back("-lpthread");
+    break;
+  case ToolChain::CST_Libstdcxx:
+    CmdArgs.push_back("-lstdc++");
+    break;
+  }
+}
diff --git a/lib/Driver/ToolChains/Bitrig.h b/lib/Driver/ToolChains/Bitrig.h
new file mode 100644
index 0000000..6edb2e8
--- /dev/null
+++ b/lib/Driver/ToolChains/Bitrig.h
@@ -0,0 +1,79 @@
+//===--- Bitrig.h - Bitrig ToolChain Implementations ------------*- 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_LIB_DRIVER_TOOLCHAINS_BITRIG_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_BITRIG_H
+
+#include "Gnu.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+/// bitrig -- Directly call GNU Binutils assembler and linker
+namespace bitrig {
+class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+public:
+  Assembler(const ToolChain &TC)
+      : GnuTool("bitrig::Assembler", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("bitrig::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace bitrig
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY Bitrig : public Generic_ELF {
+public:
+  Bitrig(const Driver &D, const llvm::Triple &Triple,
+         const llvm::opt::ArgList &Args);
+
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
+
+  CXXStdlibType GetDefaultCXXStdlibType() const override;
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
+    return 1;
+  }
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_BITRIG_H
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
new file mode 100644
index 0000000..fcb8c3e
--- /dev/null
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -0,0 +1,5172 @@
+//===--- LLVM.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Clang.h"
+#include "Arch/AArch64.h"
+#include "Arch/ARM.h"
+#include "Arch/Mips.h"
+#include "Arch/PPC.h"
+#include "Arch/Sparc.h"
+#include "Arch/SystemZ.h"
+#include "Arch/X86.h"
+#include "CommonArgs.h"
+#include "Hexagon.h"
+#include "InputInfo.h"
+#include "PS4CPU.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Compression.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/YAMLParser.h"
+
+#ifdef LLVM_ON_UNIX
+#include <unistd.h> // For getuid().
+#endif
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
+  if (Arg *A =
+          Args.getLastArg(clang::driver::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(clang::diag::err_drv_argument_only_allowed_with)
+          << A->getBaseArg().getAsString(Args)
+          << (D.IsCLMode() ? "/E, /P or /EP" : "-E");
+    }
+  }
+}
+
+static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
+  // In gcc, only ARM checks this, but it seems reasonable to check universally.
+  if (Args.hasArg(options::OPT_static))
+    if (const Arg *A =
+            Args.getLastArg(options::OPT_dynamic, options::OPT_mdynamic_no_pic))
+      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
+                                                      << "-static";
+}
+
+// Add backslashes to escape spaces and other backslashes.
+// This is used for the space-separated argument list specified with
+// the -dwarf-debug-flags option.
+static void EscapeSpacesAndBackslashes(const char *Arg,
+                                       SmallVectorImpl<char> &Res) {
+  for (; *Arg; ++Arg) {
+    switch (*Arg) {
+    default:
+      break;
+    case ' ':
+    case '\\':
+      Res.push_back('\\');
+      break;
+    }
+    Res.push_back(*Arg);
+  }
+}
+
+// Quote target names for inclusion in GNU Make dependency files.
+// Only the characters '$', '#', ' ', '\t' are quoted.
+static void QuoteTarget(StringRef Target, SmallVectorImpl<char> &Res) {
+  for (unsigned i = 0, e = Target.size(); i != e; ++i) {
+    switch (Target[i]) {
+    case ' ':
+    case '\t':
+      // Escape the preceding backslashes
+      for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
+        Res.push_back('\\');
+
+      // Escape the space/tab
+      Res.push_back('\\');
+      break;
+    case '$':
+      Res.push_back('$');
+      break;
+    case '#':
+      Res.push_back('\\');
+      break;
+    default:
+      break;
+    }
+
+    Res.push_back(Target[i]);
+  }
+}
+
+/// Apply \a Work on the current tool chain \a RegularToolChain and any other
+/// offloading tool chain that is associated with the current action \a JA.
+static void
+forAllAssociatedToolChains(Compilation &C, const JobAction &JA,
+                           const ToolChain &RegularToolChain,
+                           llvm::function_ref<void(const ToolChain &)> Work) {
+  // Apply Work on the current/regular tool chain.
+  Work(RegularToolChain);
+
+  // Apply Work on all the offloading tool chains associated with the current
+  // action.
+  if (JA.isHostOffloading(Action::OFK_Cuda))
+    Work(*C.getSingleOffloadToolChain<Action::OFK_Cuda>());
+  else if (JA.isDeviceOffloading(Action::OFK_Cuda))
+    Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
+
+  //
+  // TODO: Add support for other offloading programming models here.
+  //
+}
+
+/// This is a helper function for validating the optional refinement step
+/// parameter in reciprocal argument strings. Return false if there is an error
+/// parsing the refinement step. Otherwise, return true and set the Position
+/// of the refinement step in the input string.
+static bool getRefinementStep(StringRef In, const Driver &D,
+                              const Arg &A, size_t &Position) {
+  const char RefinementStepToken = ':';
+  Position = In.find(RefinementStepToken);
+  if (Position != StringRef::npos) {
+    StringRef Option = A.getOption().getName();
+    StringRef RefStep = In.substr(Position + 1);
+    // Allow exactly one numeric character for the additional refinement
+    // step parameter. This is reasonable for all currently-supported
+    // operations and architectures because we would expect that a larger value
+    // of refinement steps would cause the estimate "optimization" to
+    // under-perform the native operation. Also, if the estimate does not
+    // converge quickly, it probably will not ever converge, so further
+    // refinement steps will not produce a better answer.
+    if (RefStep.size() != 1) {
+      D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
+      return false;
+    }
+    char RefStepChar = RefStep[0];
+    if (RefStepChar < '0' || RefStepChar > '9') {
+      D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
+      return false;
+    }
+  }
+  return true;
+}
+
+/// The -mrecip flag requires processing of many optional parameters.
+static void ParseMRecip(const Driver &D, const ArgList &Args,
+                        ArgStringList &OutStrings) {
+  StringRef DisabledPrefixIn = "!";
+  StringRef DisabledPrefixOut = "!";
+  StringRef EnabledPrefixOut = "";
+  StringRef Out = "-mrecip=";
+
+  Arg *A = Args.getLastArg(options::OPT_mrecip, options::OPT_mrecip_EQ);
+  if (!A)
+    return;
+
+  unsigned NumOptions = A->getNumValues();
+  if (NumOptions == 0) {
+    // No option is the same as "all".
+    OutStrings.push_back(Args.MakeArgString(Out + "all"));
+    return;
+  }
+
+  // Pass through "all", "none", or "default" with an optional refinement step.
+  if (NumOptions == 1) {
+    StringRef Val = A->getValue(0);
+    size_t RefStepLoc;
+    if (!getRefinementStep(Val, D, *A, RefStepLoc))
+      return;
+    StringRef ValBase = Val.slice(0, RefStepLoc);
+    if (ValBase == "all" || ValBase == "none" || ValBase == "default") {
+      OutStrings.push_back(Args.MakeArgString(Out + Val));
+      return;
+    }
+  }
+
+  // Each reciprocal type may be enabled or disabled individually.
+  // Check each input value for validity, concatenate them all back together,
+  // and pass through.
+
+  llvm::StringMap<bool> OptionStrings;
+  OptionStrings.insert(std::make_pair("divd", false));
+  OptionStrings.insert(std::make_pair("divf", false));
+  OptionStrings.insert(std::make_pair("vec-divd", false));
+  OptionStrings.insert(std::make_pair("vec-divf", false));
+  OptionStrings.insert(std::make_pair("sqrtd", false));
+  OptionStrings.insert(std::make_pair("sqrtf", false));
+  OptionStrings.insert(std::make_pair("vec-sqrtd", false));
+  OptionStrings.insert(std::make_pair("vec-sqrtf", false));
+
+  for (unsigned i = 0; i != NumOptions; ++i) {
+    StringRef Val = A->getValue(i);
+
+    bool IsDisabled = Val.startswith(DisabledPrefixIn);
+    // Ignore the disablement token for string matching.
+    if (IsDisabled)
+      Val = Val.substr(1);
+
+    size_t RefStep;
+    if (!getRefinementStep(Val, D, *A, RefStep))
+      return;
+
+    StringRef ValBase = Val.slice(0, RefStep);
+    llvm::StringMap<bool>::iterator OptionIter = OptionStrings.find(ValBase);
+    if (OptionIter == OptionStrings.end()) {
+      // Try again specifying float suffix.
+      OptionIter = OptionStrings.find(ValBase.str() + 'f');
+      if (OptionIter == OptionStrings.end()) {
+        // The input name did not match any known option string.
+        D.Diag(diag::err_drv_unknown_argument) << Val;
+        return;
+      }
+      // The option was specified without a float or double suffix.
+      // Make sure that the double entry was not already specified.
+      // The float entry will be checked below.
+      if (OptionStrings[ValBase.str() + 'd']) {
+        D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
+        return;
+      }
+    }
+
+    if (OptionIter->second == true) {
+      // Duplicate option specified.
+      D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
+      return;
+    }
+
+    // Mark the matched option as found. Do not allow duplicate specifiers.
+    OptionIter->second = true;
+
+    // If the precision was not specified, also mark the double entry as found.
+    if (ValBase.back() != 'f' && ValBase.back() != 'd')
+      OptionStrings[ValBase.str() + 'd'] = true;
+
+    // Build the output string.
+    StringRef Prefix = IsDisabled ? DisabledPrefixOut : EnabledPrefixOut;
+    Out = Args.MakeArgString(Out + Prefix + Val);
+    if (i != NumOptions - 1)
+      Out = Args.MakeArgString(Out + ",");
+  }
+
+  OutStrings.push_back(Args.MakeArgString(Out));
+}
+
+static void getHexagonTargetFeatures(const ArgList &Args,
+                                     std::vector<StringRef> &Features) {
+  handleTargetFeaturesGroup(Args, Features,
+                            options::OPT_m_hexagon_Features_Group);
+
+  bool UseLongCalls = false;
+  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
+                               options::OPT_mno_long_calls)) {
+    if (A->getOption().matches(options::OPT_mlong_calls))
+      UseLongCalls = true;
+  }
+
+  Features.push_back(UseLongCalls ? "+long-calls" : "-long-calls");
+}
+
+static void getWebAssemblyTargetFeatures(const ArgList &Args,
+                                         std::vector<StringRef> &Features) {
+  handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group);
+}
+
+static void getAMDGPUTargetFeatures(const Driver &D, const ArgList &Args,
+                                    std::vector<StringRef> &Features) {
+  if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi)) {
+    StringRef value = dAbi->getValue();
+    if (value == "1.0") {
+      Features.push_back("+amdgpu-debugger-insert-nops");
+      Features.push_back("+amdgpu-debugger-reserve-regs");
+      Features.push_back("+amdgpu-debugger-emit-prologue");
+    } else {
+      D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args);
+    }
+  }
+
+  handleTargetFeaturesGroup(
+    Args, Features, options::OPT_m_amdgpu_Features_Group);
+}
+
+static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
+                              const ArgList &Args, ArgStringList &CmdArgs,
+                              bool ForAS) {
+  const Driver &D = TC.getDriver();
+  std::vector<StringRef> Features;
+  switch (Triple.getArch()) {
+  default:
+    break;
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el:
+    mips::getMIPSTargetFeatures(D, Triple, Args, Features);
+    break;
+
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
+    arm::getARMTargetFeatures(TC, Triple, Args, CmdArgs, Features, ForAS);
+    break;
+
+  case llvm::Triple::ppc:
+  case llvm::Triple::ppc64:
+  case llvm::Triple::ppc64le:
+    ppc::getPPCTargetFeatures(D, Triple, Args, Features);
+    break;
+  case llvm::Triple::systemz:
+    systemz::getSystemZTargetFeatures(Args, Features);
+    break;
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+    aarch64::getAArch64TargetFeatures(D, Args, Features);
+    break;
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    x86::getX86TargetFeatures(D, Triple, Args, Features);
+    break;
+  case llvm::Triple::hexagon:
+    getHexagonTargetFeatures(Args, Features);
+    break;
+  case llvm::Triple::wasm32:
+  case llvm::Triple::wasm64:
+    getWebAssemblyTargetFeatures(Args, Features);
+    break;
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+  case llvm::Triple::sparcv9:
+    sparc::getSparcTargetFeatures(D, Args, Features);
+    break;
+  case llvm::Triple::r600:
+  case llvm::Triple::amdgcn:
+    getAMDGPUTargetFeatures(D, Args, Features);
+    break;
+  }
+
+  // Find the last of each feature.
+  llvm::StringMap<unsigned> LastOpt;
+  for (unsigned I = 0, N = Features.size(); I < N; ++I) {
+    StringRef Name = Features[I];
+    assert(Name[0] == '-' || Name[0] == '+');
+    LastOpt[Name.drop_front(1)] = I;
+  }
+
+  for (unsigned I = 0, N = Features.size(); I < N; ++I) {
+    // If this feature was overridden, ignore it.
+    StringRef Name = Features[I];
+    llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name.drop_front(1));
+    assert(LastI != LastOpt.end());
+    unsigned Last = LastI->second;
+    if (Last != I)
+      continue;
+
+    CmdArgs.push_back("-target-feature");
+    CmdArgs.push_back(Name.data());
+  }
+}
+
+static bool
+shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
+                                          const llvm::Triple &Triple) {
+  // We use the zero-cost exception tables for Objective-C if the non-fragile
+  // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
+  // later.
+  if (runtime.isNonFragile())
+    return true;
+
+  if (!Triple.isMacOSX())
+    return false;
+
+  return (!Triple.isMacOSXVersionLT(10, 5) &&
+          (Triple.getArch() == llvm::Triple::x86_64 ||
+           Triple.getArch() == llvm::Triple::arm));
+}
+
+/// Adds exception related arguments to the driver command arguments. There's a
+/// master flag, -fexceptions and also language specific flags to enable/disable
+/// C++ and Objective-C exceptions. This makes it possible to for example
+/// disable C++ exceptions but enable Objective-C exceptions.
+static void addExceptionArgs(const ArgList &Args, types::ID InputType,
+                             const ToolChain &TC, bool KernelOrKext,
+                             const ObjCRuntime &objcRuntime,
+                             ArgStringList &CmdArgs) {
+  const Driver &D = TC.getDriver();
+  const llvm::Triple &Triple = TC.getTriple();
+
+  if (KernelOrKext) {
+    // -mkernel and -fapple-kext imply no exceptions, so claim exception related
+    // arguments now to avoid warnings about unused arguments.
+    Args.ClaimAllArgs(options::OPT_fexceptions);
+    Args.ClaimAllArgs(options::OPT_fno_exceptions);
+    Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
+    Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
+    Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
+    Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
+    return;
+  }
+
+  // See if the user explicitly enabled exceptions.
+  bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
+                         false);
+
+  // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
+  // is not necessarily sensible, but follows GCC.
+  if (types::isObjC(InputType) &&
+      Args.hasFlag(options::OPT_fobjc_exceptions,
+                   options::OPT_fno_objc_exceptions, true)) {
+    CmdArgs.push_back("-fobjc-exceptions");
+
+    EH |= shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
+  }
+
+  if (types::isCXX(InputType)) {
+    // Disable C++ EH by default on XCore and PS4.
+    bool CXXExceptionsEnabled =
+        Triple.getArch() != llvm::Triple::xcore && !Triple.isPS4CPU();
+    Arg *ExceptionArg = Args.getLastArg(
+        options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
+        options::OPT_fexceptions, options::OPT_fno_exceptions);
+    if (ExceptionArg)
+      CXXExceptionsEnabled =
+          ExceptionArg->getOption().matches(options::OPT_fcxx_exceptions) ||
+          ExceptionArg->getOption().matches(options::OPT_fexceptions);
+
+    if (CXXExceptionsEnabled) {
+      if (Triple.isPS4CPU()) {
+        ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
+        assert(ExceptionArg &&
+               "On the PS4 exceptions should only be enabled if passing "
+               "an argument");
+        if (RTTIMode == ToolChain::RM_DisabledExplicitly) {
+          const Arg *RTTIArg = TC.getRTTIArg();
+          assert(RTTIArg && "RTTI disabled explicitly but no RTTIArg!");
+          D.Diag(diag::err_drv_argument_not_allowed_with)
+              << RTTIArg->getAsString(Args) << ExceptionArg->getAsString(Args);
+        } else if (RTTIMode == ToolChain::RM_EnabledImplicitly)
+          D.Diag(diag::warn_drv_enabling_rtti_with_exceptions);
+      } else
+        assert(TC.getRTTIMode() != ToolChain::RM_DisabledImplicitly);
+
+      CmdArgs.push_back("-fcxx-exceptions");
+
+      EH = true;
+    }
+  }
+
+  if (EH)
+    CmdArgs.push_back("-fexceptions");
+}
+
+static bool ShouldDisableAutolink(const ArgList &Args, const ToolChain &TC) {
+  bool Default = true;
+  if (TC.getTriple().isOSDarwin()) {
+    // The native darwin assembler doesn't support the linker_option directives,
+    // so we disable them if we think the .s file will be passed to it.
+    Default = TC.useIntegratedAs();
+  }
+  return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
+                       Default);
+}
+
+static bool ShouldDisableDwarfDirectory(const ArgList &Args,
+                                        const ToolChain &TC) {
+  bool UseDwarfDirectory =
+      Args.hasFlag(options::OPT_fdwarf_directory_asm,
+                   options::OPT_fno_dwarf_directory_asm, TC.useIntegratedAs());
+  return !UseDwarfDirectory;
+}
+
+// Convert an arg of the form "-gN" or "-ggdbN" or one of their aliases
+// to the corresponding DebugInfoKind.
+static codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) {
+  assert(A.getOption().matches(options::OPT_gN_Group) &&
+         "Not a -g option that specifies a debug-info level");
+  if (A.getOption().matches(options::OPT_g0) ||
+      A.getOption().matches(options::OPT_ggdb0))
+    return codegenoptions::NoDebugInfo;
+  if (A.getOption().matches(options::OPT_gline_tables_only) ||
+      A.getOption().matches(options::OPT_ggdb1))
+    return codegenoptions::DebugLineTablesOnly;
+  return codegenoptions::LimitedDebugInfo;
+}
+
+static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
+  switch (Triple.getArch()){
+  default:
+    return false;
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    // ARM Darwin targets require a frame pointer to be always present to aid
+    // offline debugging via backtraces.
+    return Triple.isOSDarwin();
+  }
+}
+
+static bool useFramePointerForTargetByDefault(const ArgList &Args,
+                                              const llvm::Triple &Triple) {
+  switch (Triple.getArch()) {
+  case llvm::Triple::xcore:
+  case llvm::Triple::wasm32:
+  case llvm::Triple::wasm64:
+    // XCore never wants frame pointers, regardless of OS.
+    // WebAssembly never wants frame pointers.
+    return false;
+  default:
+    break;
+  }
+
+  if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI) {
+    switch (Triple.getArch()) {
+    // Don't use a frame pointer on linux if optimizing for certain targets.
+    case llvm::Triple::mips64:
+    case llvm::Triple::mips64el:
+    case llvm::Triple::mips:
+    case llvm::Triple::mipsel:
+    case llvm::Triple::ppc:
+    case llvm::Triple::ppc64:
+    case llvm::Triple::ppc64le:
+    case llvm::Triple::systemz:
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+      return !areOptimizationsEnabled(Args);
+    default:
+      return true;
+    }
+  }
+
+  if (Triple.isOSWindows()) {
+    switch (Triple.getArch()) {
+    case llvm::Triple::x86:
+      return !areOptimizationsEnabled(Args);
+    case llvm::Triple::x86_64:
+      return Triple.isOSBinFormatMachO();
+    case llvm::Triple::arm:
+    case llvm::Triple::thumb:
+      // Windows on ARM builds with FPO disabled to aid fast stack walking
+      return true;
+    default:
+      // All other supported Windows ISAs use xdata unwind information, so frame
+      // pointers are not generally useful.
+      return false;
+    }
+  }
+
+  return true;
+}
+
+static bool shouldUseFramePointer(const ArgList &Args,
+                                  const llvm::Triple &Triple) {
+  if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
+                               options::OPT_fomit_frame_pointer))
+    return A->getOption().matches(options::OPT_fno_omit_frame_pointer) ||
+           mustUseNonLeafFramePointerForTarget(Triple);
+
+  if (Args.hasArg(options::OPT_pg))
+    return true;
+
+  return useFramePointerForTargetByDefault(Args, Triple);
+}
+
+static bool shouldUseLeafFramePointer(const ArgList &Args,
+                                      const llvm::Triple &Triple) {
+  if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
+                               options::OPT_momit_leaf_frame_pointer))
+    return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
+
+  if (Args.hasArg(options::OPT_pg))
+    return true;
+
+  if (Triple.isPS4CPU())
+    return false;
+
+  return useFramePointerForTargetByDefault(Args, Triple);
+}
+
+/// Add a CC1 option to specify the debug compilation directory.
+static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
+  SmallString<128> cwd;
+  if (!llvm::sys::fs::current_path(cwd)) {
+    CmdArgs.push_back("-fdebug-compilation-dir");
+    CmdArgs.push_back(Args.MakeArgString(cwd));
+  }
+}
+
+/// \brief Vectorize at all optimization levels greater than 1 except for -Oz.
+/// For -Oz the loop vectorizer is disable, while the slp vectorizer is enabled.
+static bool shouldEnableVectorizerAtOLevel(const ArgList &Args, bool isSlpVec) {
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O4) ||
+        A->getOption().matches(options::OPT_Ofast))
+      return true;
+
+    if (A->getOption().matches(options::OPT_O0))
+      return false;
+
+    assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
+
+    // Vectorize -Os.
+    StringRef S(A->getValue());
+    if (S == "s")
+      return true;
+
+    // Don't vectorize -Oz, unless it's the slp vectorizer.
+    if (S == "z")
+      return isSlpVec;
+
+    unsigned OptLevel = 0;
+    if (S.getAsInteger(10, OptLevel))
+      return false;
+
+    return OptLevel > 1;
+  }
+
+  return false;
+}
+
+/// Add -x lang to \p CmdArgs for \p Input.
+static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
+                             ArgStringList &CmdArgs) {
+  // When using -verify-pch, we don't want to provide the type
+  // 'precompiled-header' if it was inferred from the file extension
+  if (Args.hasArg(options::OPT_verify_pch) && Input.getType() == types::TY_PCH)
+    return;
+
+  CmdArgs.push_back("-x");
+  if (Args.hasArg(options::OPT_rewrite_objc))
+    CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
+  else
+    CmdArgs.push_back(types::getTypeName(Input.getType()));
+}
+
+static void appendUserToPath(SmallVectorImpl<char> &Result) {
+#ifdef LLVM_ON_UNIX
+  const char *Username = getenv("LOGNAME");
+#else
+  const char *Username = getenv("USERNAME");
+#endif
+  if (Username) {
+    // Validate that LoginName can be used in a path, and get its length.
+    size_t Len = 0;
+    for (const char *P = Username; *P; ++P, ++Len) {
+      if (!clang::isAlphanumeric(*P) && *P != '_') {
+        Username = nullptr;
+        break;
+      }
+    }
+
+    if (Username && Len > 0) {
+      Result.append(Username, Username + Len);
+      return;
+    }
+  }
+
+// Fallback to user id.
+#ifdef LLVM_ON_UNIX
+  std::string UID = llvm::utostr(getuid());
+#else
+  // FIXME: Windows seems to have an 'SID' that might work.
+  std::string UID = "9999";
+#endif
+  Result.append(UID.begin(), UID.end());
+}
+
+static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
+                                   const InputInfo &Output, const ArgList &Args,
+                                   ArgStringList &CmdArgs) {
+
+  auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate,
+                                         options::OPT_fprofile_generate_EQ,
+                                         options::OPT_fno_profile_generate);
+  if (PGOGenerateArg &&
+      PGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
+    PGOGenerateArg = nullptr;
+
+  auto *ProfileGenerateArg = Args.getLastArg(
+      options::OPT_fprofile_instr_generate,
+      options::OPT_fprofile_instr_generate_EQ,
+      options::OPT_fno_profile_instr_generate);
+  if (ProfileGenerateArg &&
+      ProfileGenerateArg->getOption().matches(
+          options::OPT_fno_profile_instr_generate))
+    ProfileGenerateArg = nullptr;
+
+  if (PGOGenerateArg && ProfileGenerateArg)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+        << PGOGenerateArg->getSpelling() << ProfileGenerateArg->getSpelling();
+
+  auto *ProfileUseArg = getLastProfileUseArg(Args);
+
+  if (PGOGenerateArg && ProfileUseArg)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+        << ProfileUseArg->getSpelling() << PGOGenerateArg->getSpelling();
+
+  if (ProfileGenerateArg && ProfileUseArg)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+        << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();
+
+  if (ProfileGenerateArg) {
+    if (ProfileGenerateArg->getOption().matches(
+            options::OPT_fprofile_instr_generate_EQ))
+      CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-instrument-path=") +
+                                           ProfileGenerateArg->getValue()));
+    // The default is to use Clang Instrumentation.
+    CmdArgs.push_back("-fprofile-instrument=clang");
+  }
+
+  if (PGOGenerateArg) {
+    CmdArgs.push_back("-fprofile-instrument=llvm");
+    if (PGOGenerateArg->getOption().matches(
+            options::OPT_fprofile_generate_EQ)) {
+      SmallString<128> Path(PGOGenerateArg->getValue());
+      llvm::sys::path::append(Path, "default_%m.profraw");
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-fprofile-instrument-path=") + Path));
+    }
+  }
+
+  if (ProfileUseArg) {
+    if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
+      CmdArgs.push_back(Args.MakeArgString(
+          Twine("-fprofile-instrument-use-path=") + ProfileUseArg->getValue()));
+    else if ((ProfileUseArg->getOption().matches(
+                  options::OPT_fprofile_use_EQ) ||
+              ProfileUseArg->getOption().matches(
+                  options::OPT_fprofile_instr_use))) {
+      SmallString<128> Path(
+          ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
+      if (Path.empty() || llvm::sys::fs::is_directory(Path))
+        llvm::sys::path::append(Path, "default.profdata");
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-fprofile-instrument-use-path=") + Path));
+    }
+  }
+
+  if (Args.hasArg(options::OPT_ftest_coverage) ||
+      Args.hasArg(options::OPT_coverage))
+    CmdArgs.push_back("-femit-coverage-notes");
+  if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
+                   false) ||
+      Args.hasArg(options::OPT_coverage))
+    CmdArgs.push_back("-femit-coverage-data");
+
+  if (Args.hasFlag(options::OPT_fcoverage_mapping,
+                   options::OPT_fno_coverage_mapping, false) &&
+      !ProfileGenerateArg)
+    D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+        << "-fcoverage-mapping"
+        << "-fprofile-instr-generate";
+
+  if (Args.hasFlag(options::OPT_fcoverage_mapping,
+                   options::OPT_fno_coverage_mapping, false))
+    CmdArgs.push_back("-fcoverage-mapping");
+
+  if (C.getArgs().hasArg(options::OPT_c) ||
+      C.getArgs().hasArg(options::OPT_S)) {
+    if (Output.isFilename()) {
+      CmdArgs.push_back("-coverage-notes-file");
+      SmallString<128> OutputFilename;
+      if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
+        OutputFilename = FinalOutput->getValue();
+      else
+        OutputFilename = llvm::sys::path::filename(Output.getBaseInput());
+      SmallString<128> CoverageFilename = OutputFilename;
+      if (llvm::sys::path::is_relative(CoverageFilename)) {
+        SmallString<128> Pwd;
+        if (!llvm::sys::fs::current_path(Pwd)) {
+          llvm::sys::path::append(Pwd, CoverageFilename);
+          CoverageFilename.swap(Pwd);
+        }
+      }
+      llvm::sys::path::replace_extension(CoverageFilename, "gcno");
+      CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
+
+      // Leave -fprofile-dir= an unused argument unless .gcda emission is
+      // enabled. To be polite, with '-fprofile-arcs -fno-profile-arcs' consider
+      // the flag used. There is no -fno-profile-dir, so the user has no
+      // targeted way to suppress the warning.
+      if (Args.hasArg(options::OPT_fprofile_arcs) ||
+          Args.hasArg(options::OPT_coverage)) {
+        CmdArgs.push_back("-coverage-data-file");
+        if (Arg *FProfileDir = Args.getLastArg(options::OPT_fprofile_dir)) {
+          CoverageFilename = FProfileDir->getValue();
+          llvm::sys::path::append(CoverageFilename, OutputFilename);
+        }
+        llvm::sys::path::replace_extension(CoverageFilename, "gcda");
+        CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
+      }
+    }
+  }
+}
+
+/// \brief Check whether the given input tree contains any compilation actions.
+static bool ContainsCompileAction(const Action *A) {
+  if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A))
+    return true;
+
+  for (const auto &AI : A->inputs())
+    if (ContainsCompileAction(AI))
+      return true;
+
+  return false;
+}
+
+/// \brief Check if -relax-all should be passed to the internal assembler.
+/// This is done by default when compiling non-assembler source with -O0.
+static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
+  bool RelaxDefault = true;
+
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
+    RelaxDefault = A->getOption().matches(options::OPT_O0);
+
+  if (RelaxDefault) {
+    RelaxDefault = false;
+    for (const auto &Act : C.getActions()) {
+      if (ContainsCompileAction(Act)) {
+        RelaxDefault = true;
+        break;
+      }
+    }
+  }
+
+  return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
+                      RelaxDefault);
+}
+
+// Extract the integer N from a string spelled "-dwarf-N", returning 0
+// on mismatch. The StringRef input (rather than an Arg) allows
+// for use by the "-Xassembler" option parser.
+static unsigned DwarfVersionNum(StringRef ArgValue) {
+  return llvm::StringSwitch<unsigned>(ArgValue)
+      .Case("-gdwarf-2", 2)
+      .Case("-gdwarf-3", 3)
+      .Case("-gdwarf-4", 4)
+      .Case("-gdwarf-5", 5)
+      .Default(0);
+}
+
+static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
+                                    codegenoptions::DebugInfoKind DebugInfoKind,
+                                    unsigned DwarfVersion,
+                                    llvm::DebuggerKind DebuggerTuning) {
+  switch (DebugInfoKind) {
+  case codegenoptions::DebugLineTablesOnly:
+    CmdArgs.push_back("-debug-info-kind=line-tables-only");
+    break;
+  case codegenoptions::LimitedDebugInfo:
+    CmdArgs.push_back("-debug-info-kind=limited");
+    break;
+  case codegenoptions::FullDebugInfo:
+    CmdArgs.push_back("-debug-info-kind=standalone");
+    break;
+  default:
+    break;
+  }
+  if (DwarfVersion > 0)
+    CmdArgs.push_back(
+        Args.MakeArgString("-dwarf-version=" + Twine(DwarfVersion)));
+  switch (DebuggerTuning) {
+  case llvm::DebuggerKind::GDB:
+    CmdArgs.push_back("-debugger-tuning=gdb");
+    break;
+  case llvm::DebuggerKind::LLDB:
+    CmdArgs.push_back("-debugger-tuning=lldb");
+    break;
+  case llvm::DebuggerKind::SCE:
+    CmdArgs.push_back("-debugger-tuning=sce");
+    break;
+  default:
+    break;
+  }
+}
+
+static const char *RelocationModelName(llvm::Reloc::Model Model) {
+  switch (Model) {
+  case llvm::Reloc::Static:
+    return "static";
+  case llvm::Reloc::PIC_:
+    return "pic";
+  case llvm::Reloc::DynamicNoPIC:
+    return "dynamic-no-pic";
+  case llvm::Reloc::ROPI:
+    return "ropi";
+  case llvm::Reloc::RWPI:
+    return "rwpi";
+  case llvm::Reloc::ROPI_RWPI:
+    return "ropi-rwpi";
+  }
+  llvm_unreachable("Unknown Reloc::Model kind");
+}
+
+void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
+                                    const Driver &D, const ArgList &Args,
+                                    ArgStringList &CmdArgs,
+                                    const InputInfo &Output,
+                                    const InputInfoList &Inputs) const {
+  Arg *A;
+  const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
+
+  CheckPreprocessingOptions(D, Args);
+
+  Args.AddLastArg(CmdArgs, options::OPT_C);
+  Args.AddLastArg(CmdArgs, options::OPT_CC);
+
+  // Handle dependency file generation.
+  if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) ||
+      (A = Args.getLastArg(options::OPT_MD)) ||
+      (A = Args.getLastArg(options::OPT_MMD))) {
+    // Determine the output location.
+    const char *DepFile;
+    if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
+      DepFile = MF->getValue();
+      C.addFailureResultFile(DepFile, &JA);
+    } else if (Output.getType() == types::TY_Dependencies) {
+      DepFile = Output.getFilename();
+    } else if (A->getOption().matches(options::OPT_M) ||
+               A->getOption().matches(options::OPT_MM)) {
+      DepFile = "-";
+    } else {
+      DepFile = getDependencyFileName(Args, Inputs);
+      C.addFailureResultFile(DepFile, &JA);
+    }
+    CmdArgs.push_back("-dependency-file");
+    CmdArgs.push_back(DepFile);
+
+    // Add a default target if one wasn't specified.
+    if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
+      const char *DepTarget;
+
+      // If user provided -o, that is the dependency target, except
+      // when we are only generating a dependency file.
+      Arg *OutputOpt = Args.getLastArg(options::OPT_o);
+      if (OutputOpt && Output.getType() != types::TY_Dependencies) {
+        DepTarget = OutputOpt->getValue();
+      } else {
+        // Otherwise derive from the base input.
+        //
+        // FIXME: This should use the computed output file location.
+        SmallString<128> P(Inputs[0].getBaseInput());
+        llvm::sys::path::replace_extension(P, "o");
+        DepTarget = Args.MakeArgString(llvm::sys::path::filename(P));
+      }
+
+      CmdArgs.push_back("-MT");
+      SmallString<128> Quoted;
+      QuoteTarget(DepTarget, Quoted);
+      CmdArgs.push_back(Args.MakeArgString(Quoted));
+    }
+
+    if (A->getOption().matches(options::OPT_M) ||
+        A->getOption().matches(options::OPT_MD))
+      CmdArgs.push_back("-sys-header-deps");
+    if ((isa<PrecompileJobAction>(JA) &&
+         !Args.hasArg(options::OPT_fno_module_file_deps)) ||
+        Args.hasArg(options::OPT_fmodule_file_deps))
+      CmdArgs.push_back("-module-file-deps");
+  }
+
+  if (Args.hasArg(options::OPT_MG)) {
+    if (!A || A->getOption().matches(options::OPT_MD) ||
+        A->getOption().matches(options::OPT_MMD))
+      D.Diag(diag::err_drv_mg_requires_m_or_mm);
+    CmdArgs.push_back("-MG");
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_MP);
+  Args.AddLastArg(CmdArgs, options::OPT_MV);
+
+  // Convert all -MQ <target> args to -MT <quoted target>
+  for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) {
+    A->claim();
+
+    if (A->getOption().matches(options::OPT_MQ)) {
+      CmdArgs.push_back("-MT");
+      SmallString<128> Quoted;
+      QuoteTarget(A->getValue(), Quoted);
+      CmdArgs.push_back(Args.MakeArgString(Quoted));
+
+      // -MT flag - no change
+    } else {
+      A->render(Args, CmdArgs);
+    }
+  }
+
+  // Add offload include arguments specific for CUDA.  This must happen before
+  // we -I or -include anything else, because we must pick up the CUDA headers
+  // from the particular CUDA installation, rather than from e.g.
+  // /usr/local/include.
+  if (JA.isOffloading(Action::OFK_Cuda))
+    getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
+
+  // Add -i* options, and automatically translate to
+  // -include-pch/-include-pth for transparent PCH support. It's
+  // wonky, but we include looking for .gch so we can support seamless
+  // replacement into a build system already set up to be generating
+  // .gch files.
+  int YcIndex = -1, YuIndex = -1;
+  {
+    int AI = -1;
+    const Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
+    const Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
+    for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) {
+      // Walk the whole i_Group and skip non "-include" flags so that the index
+      // here matches the index in the next loop below.
+      ++AI;
+      if (!A->getOption().matches(options::OPT_include))
+        continue;
+      if (YcArg && strcmp(A->getValue(), YcArg->getValue()) == 0)
+        YcIndex = AI;
+      if (YuArg && strcmp(A->getValue(), YuArg->getValue()) == 0)
+        YuIndex = AI;
+    }
+  }
+  if (isa<PrecompileJobAction>(JA) && YcIndex != -1) {
+    Driver::InputList Inputs;
+    D.BuildInputs(getToolChain(), C.getArgs(), Inputs);
+    assert(Inputs.size() == 1 && "Need one input when building pch");
+    CmdArgs.push_back(Args.MakeArgString(Twine("-find-pch-source=") +
+                                         Inputs[0].second->getValue()));
+  }
+
+  bool RenderedImplicitInclude = false;
+  int AI = -1;
+  for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) {
+    ++AI;
+
+    if (getToolChain().getDriver().IsCLMode() &&
+        A->getOption().matches(options::OPT_include)) {
+      // In clang-cl mode, /Ycfoo.h means that all code up to a foo.h
+      // include is compiled into foo.h, and everything after goes into
+      // the .obj file. /Yufoo.h means that all includes prior to and including
+      // foo.h are completely skipped and replaced with a use of the pch file
+      // for foo.h.  (Each flag can have at most one value, multiple /Yc flags
+      // just mean that the last one wins.)  If /Yc and /Yu are both present
+      // and refer to the same file, /Yc wins.
+      // Note that OPT__SLASH_FI gets mapped to OPT_include.
+      // FIXME: The code here assumes that /Yc and /Yu refer to the same file.
+      // cl.exe seems to support both flags with different values, but that
+      // seems strange (which flag does /Fp now refer to?), so don't implement
+      // that until someone needs it.
+      int PchIndex = YcIndex != -1 ? YcIndex : YuIndex;
+      if (PchIndex != -1) {
+        if (isa<PrecompileJobAction>(JA)) {
+          // When building the pch, skip all includes after the pch.
+          assert(YcIndex != -1 && PchIndex == YcIndex);
+          if (AI >= YcIndex)
+            continue;
+        } else {
+          // When using the pch, skip all includes prior to the pch.
+          if (AI < PchIndex) {
+            A->claim();
+            continue;
+          }
+          if (AI == PchIndex) {
+            A->claim();
+            CmdArgs.push_back("-include-pch");
+            CmdArgs.push_back(
+                Args.MakeArgString(D.GetClPchPath(C, A->getValue())));
+            continue;
+          }
+        }
+      }
+    } else if (A->getOption().matches(options::OPT_include)) {
+      // Handling of gcc-style gch precompiled headers.
+      bool IsFirstImplicitInclude = !RenderedImplicitInclude;
+      RenderedImplicitInclude = true;
+
+      // Use PCH if the user requested it.
+      bool UsePCH = D.CCCUsePCH;
+
+      bool FoundPTH = false;
+      bool FoundPCH = false;
+      SmallString<128> P(A->getValue());
+      // We want the files to have a name like foo.h.pch. Add a dummy extension
+      // so that replace_extension does the right thing.
+      P += ".dummy";
+      if (UsePCH) {
+        llvm::sys::path::replace_extension(P, "pch");
+        if (llvm::sys::fs::exists(P))
+          FoundPCH = true;
+      }
+
+      if (!FoundPCH) {
+        llvm::sys::path::replace_extension(P, "pth");
+        if (llvm::sys::fs::exists(P))
+          FoundPTH = true;
+      }
+
+      if (!FoundPCH && !FoundPTH) {
+        llvm::sys::path::replace_extension(P, "gch");
+        if (llvm::sys::fs::exists(P)) {
+          FoundPCH = UsePCH;
+          FoundPTH = !UsePCH;
+        }
+      }
+
+      if (FoundPCH || FoundPTH) {
+        if (IsFirstImplicitInclude) {
+          A->claim();
+          if (UsePCH)
+            CmdArgs.push_back("-include-pch");
+          else
+            CmdArgs.push_back("-include-pth");
+          CmdArgs.push_back(Args.MakeArgString(P));
+          continue;
+        } else {
+          // Ignore the PCH if not first on command line and emit warning.
+          D.Diag(diag::warn_drv_pch_not_first_include) << P
+                                                       << A->getAsString(Args);
+        }
+      }
+    } else if (A->getOption().matches(options::OPT_isystem_after)) {
+      // Handling of paths which must come late.  These entries are handled by
+      // the toolchain itself after the resource dir is inserted in the right
+      // search order.
+      // Do not claim the argument so that the use of the argument does not
+      // silently go unnoticed on toolchains which do not honour the option.
+      continue;
+    }
+
+    // Not translated, render as usual.
+    A->claim();
+    A->render(Args, CmdArgs);
+  }
+
+  Args.AddAllArgs(CmdArgs,
+                  {options::OPT_D, options::OPT_U, options::OPT_I_Group,
+                   options::OPT_F, options::OPT_index_header_map});
+
+  // Add -Wp, and -Xpreprocessor if using the preprocessor.
+
+  // FIXME: There is a very unfortunate problem here, some troubled
+  // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
+  // really support that we would have to parse and then translate
+  // those options. :(
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
+                       options::OPT_Xpreprocessor);
+
+  // -I- is a deprecated GCC feature, reject it.
+  if (Arg *A = Args.getLastArg(options::OPT_I_))
+    D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
+
+  // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
+  // -isysroot to the CC1 invocation.
+  StringRef sysroot = C.getSysRoot();
+  if (sysroot != "") {
+    if (!Args.hasArg(options::OPT_isysroot)) {
+      CmdArgs.push_back("-isysroot");
+      CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
+    }
+  }
+
+  // Parse additional include paths from environment variables.
+  // FIXME: We should probably sink the logic for handling these from the
+  // frontend into the driver. It will allow deleting 4 otherwise unused flags.
+  // CPATH - included following the user specified includes (but prior to
+  // builtin and standard includes).
+  addDirectoryList(Args, CmdArgs, "-I", "CPATH");
+  // C_INCLUDE_PATH - system includes enabled when compiling C.
+  addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH");
+  // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
+  addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
+  // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
+  addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH");
+  // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
+  addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
+
+  // While adding the include arguments, we also attempt to retrieve the
+  // arguments of related offloading toolchains or arguments that are specific
+  // of an offloading programming model.
+
+  // Add C++ include arguments, if needed.
+  if (types::isCXX(Inputs[0].getType()))
+    forAllAssociatedToolChains(C, JA, getToolChain(),
+                               [&Args, &CmdArgs](const ToolChain &TC) {
+                                 TC.AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
+                               });
+
+  // Add system include arguments for all targets but IAMCU.
+  if (!IsIAMCU)
+    forAllAssociatedToolChains(C, JA, getToolChain(),
+                               [&Args, &CmdArgs](const ToolChain &TC) {
+                                 TC.AddClangSystemIncludeArgs(Args, CmdArgs);
+                               });
+  else {
+    // For IAMCU add special include arguments.
+    getToolChain().AddIAMCUIncludeArgs(Args, CmdArgs);
+  }
+}
+
+// FIXME: Move to target hook.
+static bool isSignedCharDefault(const llvm::Triple &Triple) {
+  switch (Triple.getArch()) {
+  default:
+    return true;
+
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
+    if (Triple.isOSDarwin() || Triple.isOSWindows())
+      return true;
+    return false;
+
+  case llvm::Triple::ppc:
+  case llvm::Triple::ppc64:
+    if (Triple.isOSDarwin())
+      return true;
+    return false;
+
+  case llvm::Triple::hexagon:
+  case llvm::Triple::ppc64le:
+  case llvm::Triple::systemz:
+  case llvm::Triple::xcore:
+    return false;
+  }
+}
+
+static bool isNoCommonDefault(const llvm::Triple &Triple) {
+  switch (Triple.getArch()) {
+  default:
+    return false;
+
+  case llvm::Triple::xcore:
+  case llvm::Triple::wasm32:
+  case llvm::Triple::wasm64:
+    return true;
+  }
+}
+
+void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
+                             ArgStringList &CmdArgs, bool KernelOrKext) const {
+  // Select the ABI to use.
+  // FIXME: Support -meabi.
+  // FIXME: Parts of this are duplicated in the backend, unify this somehow.
+  const char *ABIName = nullptr;
+  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
+    ABIName = A->getValue();
+  } else if (Triple.isOSBinFormatMachO()) {
+    if (arm::useAAPCSForMachO(Triple)) {
+      ABIName = "aapcs";
+    } else if (Triple.isWatchABI()) {
+      ABIName = "aapcs16";
+    } else {
+      ABIName = "apcs-gnu";
+    }
+  } else if (Triple.isOSWindows()) {
+    // FIXME: this is invalid for WindowsCE
+    ABIName = "aapcs";
+  } else {
+    // Select the default based on the platform.
+    switch (Triple.getEnvironment()) {
+    case llvm::Triple::Android:
+    case llvm::Triple::GNUEABI:
+    case llvm::Triple::GNUEABIHF:
+    case llvm::Triple::MuslEABI:
+    case llvm::Triple::MuslEABIHF:
+      ABIName = "aapcs-linux";
+      break;
+    case llvm::Triple::EABIHF:
+    case llvm::Triple::EABI:
+      ABIName = "aapcs";
+      break;
+    default:
+      if (Triple.getOS() == llvm::Triple::NetBSD)
+        ABIName = "apcs-gnu";
+      else if (Triple.getOS() == llvm::Triple::OpenBSD)
+        ABIName = "aapcs-linux";
+      else
+        ABIName = "aapcs";
+      break;
+    }
+  }
+  CmdArgs.push_back("-target-abi");
+  CmdArgs.push_back(ABIName);
+
+  // Determine floating point ABI from the options & target defaults.
+  arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
+  if (ABI == arm::FloatABI::Soft) {
+    // Floating point operations and argument passing are soft.
+    // FIXME: This changes CPP defines, we need -target-soft-float.
+    CmdArgs.push_back("-msoft-float");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("soft");
+  } else if (ABI == arm::FloatABI::SoftFP) {
+    // Floating point operations are hard, but argument passing is soft.
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("soft");
+  } else {
+    // Floating point operations and argument passing are hard.
+    assert(ABI == arm::FloatABI::Hard && "Invalid float abi!");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("hard");
+  }
+
+  // Forward the -mglobal-merge option for explicit control over the pass.
+  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
+                               options::OPT_mno_global_merge)) {
+    CmdArgs.push_back("-backend-option");
+    if (A->getOption().matches(options::OPT_mno_global_merge))
+      CmdArgs.push_back("-arm-global-merge=false");
+    else
+      CmdArgs.push_back("-arm-global-merge=true");
+  }
+
+  if (!Args.hasFlag(options::OPT_mimplicit_float,
+                    options::OPT_mno_implicit_float, true))
+    CmdArgs.push_back("-no-implicit-float");
+}
+
+void Clang::AddAArch64TargetArgs(const ArgList &Args,
+                                 ArgStringList &CmdArgs) const {
+  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+
+  if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
+      Args.hasArg(options::OPT_mkernel) ||
+      Args.hasArg(options::OPT_fapple_kext))
+    CmdArgs.push_back("-disable-red-zone");
+
+  if (!Args.hasFlag(options::OPT_mimplicit_float,
+                    options::OPT_mno_implicit_float, true))
+    CmdArgs.push_back("-no-implicit-float");
+
+  const char *ABIName = nullptr;
+  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
+    ABIName = A->getValue();
+  else if (Triple.isOSDarwin())
+    ABIName = "darwinpcs";
+  else
+    ABIName = "aapcs";
+
+  CmdArgs.push_back("-target-abi");
+  CmdArgs.push_back(ABIName);
+
+  if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
+                               options::OPT_mno_fix_cortex_a53_835769)) {
+    CmdArgs.push_back("-backend-option");
+    if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
+      CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
+    else
+      CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=0");
+  } else if (Triple.isAndroid()) {
+    // Enabled A53 errata (835769) workaround by default on android
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
+  }
+
+  // Forward the -mglobal-merge option for explicit control over the pass.
+  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
+                               options::OPT_mno_global_merge)) {
+    CmdArgs.push_back("-backend-option");
+    if (A->getOption().matches(options::OPT_mno_global_merge))
+      CmdArgs.push_back("-aarch64-enable-global-merge=false");
+    else
+      CmdArgs.push_back("-aarch64-enable-global-merge=true");
+  }
+}
+
+void Clang::AddMIPSTargetArgs(const ArgList &Args,
+                              ArgStringList &CmdArgs) const {
+  const Driver &D = getToolChain().getDriver();
+  StringRef CPUName;
+  StringRef ABIName;
+  const llvm::Triple &Triple = getToolChain().getTriple();
+  mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+
+  CmdArgs.push_back("-target-abi");
+  CmdArgs.push_back(ABIName.data());
+
+  mips::FloatABI ABI = mips::getMipsFloatABI(D, Args);
+  if (ABI == mips::FloatABI::Soft) {
+    // Floating point operations and argument passing are soft.
+    CmdArgs.push_back("-msoft-float");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("soft");
+  } else {
+    // Floating point operations and argument passing are hard.
+    assert(ABI == mips::FloatABI::Hard && "Invalid float abi!");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("hard");
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
+    if (A->getOption().matches(options::OPT_mxgot)) {
+      CmdArgs.push_back("-mllvm");
+      CmdArgs.push_back("-mxgot");
+    }
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1,
+                               options::OPT_mno_ldc1_sdc1)) {
+    if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) {
+      CmdArgs.push_back("-mllvm");
+      CmdArgs.push_back("-mno-ldc1-sdc1");
+    }
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division,
+                               options::OPT_mno_check_zero_division)) {
+    if (A->getOption().matches(options::OPT_mno_check_zero_division)) {
+      CmdArgs.push_back("-mllvm");
+      CmdArgs.push_back("-mno-check-zero-division");
+    }
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_G)) {
+    StringRef v = A->getValue();
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
+    A->claim();
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mcompact_branches_EQ)) {
+    StringRef Val = StringRef(A->getValue());
+    if (mips::hasCompactBranches(CPUName)) {
+      if (Val == "never" || Val == "always" || Val == "optimal") {
+        CmdArgs.push_back("-mllvm");
+        CmdArgs.push_back(Args.MakeArgString("-mips-compact-branches=" + Val));
+      } else
+        D.Diag(diag::err_drv_unsupported_option_argument)
+            << A->getOption().getName() << Val;
+    } else
+      D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName;
+  }
+}
+
+void Clang::AddPPCTargetArgs(const ArgList &Args,
+                             ArgStringList &CmdArgs) const {
+  // Select the ABI to use.
+  const char *ABIName = nullptr;
+  if (getToolChain().getTriple().isOSLinux())
+    switch (getToolChain().getArch()) {
+    case llvm::Triple::ppc64: {
+      // When targeting a processor that supports QPX, or if QPX is
+      // specifically enabled, default to using the ABI that supports QPX (so
+      // long as it is not specifically disabled).
+      bool HasQPX = false;
+      if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+        HasQPX = A->getValue() == StringRef("a2q");
+      HasQPX = Args.hasFlag(options::OPT_mqpx, options::OPT_mno_qpx, HasQPX);
+      if (HasQPX) {
+        ABIName = "elfv1-qpx";
+        break;
+      }
+
+      ABIName = "elfv1";
+      break;
+    }
+    case llvm::Triple::ppc64le:
+      ABIName = "elfv2";
+      break;
+    default:
+      break;
+    }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
+    // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
+    // the option if given as we don't have backend support for any targets
+    // that don't use the altivec abi.
+    if (StringRef(A->getValue()) != "altivec")
+      ABIName = A->getValue();
+
+  ppc::FloatABI FloatABI =
+      ppc::getPPCFloatABI(getToolChain().getDriver(), Args);
+
+  if (FloatABI == ppc::FloatABI::Soft) {
+    // Floating point operations and argument passing are soft.
+    CmdArgs.push_back("-msoft-float");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("soft");
+  } else {
+    // Floating point operations and argument passing are hard.
+    assert(FloatABI == ppc::FloatABI::Hard && "Invalid float abi!");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("hard");
+  }
+
+  if (ABIName) {
+    CmdArgs.push_back("-target-abi");
+    CmdArgs.push_back(ABIName);
+  }
+}
+
+void Clang::AddSparcTargetArgs(const ArgList &Args,
+                               ArgStringList &CmdArgs) const {
+  sparc::FloatABI FloatABI =
+      sparc::getSparcFloatABI(getToolChain().getDriver(), Args);
+
+  if (FloatABI == sparc::FloatABI::Soft) {
+    // Floating point operations and argument passing are soft.
+    CmdArgs.push_back("-msoft-float");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("soft");
+  } else {
+    // Floating point operations and argument passing are hard.
+    assert(FloatABI == sparc::FloatABI::Hard && "Invalid float abi!");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("hard");
+  }
+}
+
+void Clang::AddSystemZTargetArgs(const ArgList &Args,
+                                 ArgStringList &CmdArgs) const {
+  if (Args.hasFlag(options::OPT_mbackchain, options::OPT_mno_backchain, false))
+    CmdArgs.push_back("-mbackchain");
+}
+
+void Clang::AddX86TargetArgs(const ArgList &Args,
+                             ArgStringList &CmdArgs) const {
+  if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
+      Args.hasArg(options::OPT_mkernel) ||
+      Args.hasArg(options::OPT_fapple_kext))
+    CmdArgs.push_back("-disable-red-zone");
+
+  // Default to avoid implicit floating-point for kernel/kext code, but allow
+  // that to be overridden with -mno-soft-float.
+  bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
+                          Args.hasArg(options::OPT_fapple_kext));
+  if (Arg *A = Args.getLastArg(
+          options::OPT_msoft_float, options::OPT_mno_soft_float,
+          options::OPT_mimplicit_float, options::OPT_mno_implicit_float)) {
+    const Option &O = A->getOption();
+    NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
+                       O.matches(options::OPT_msoft_float));
+  }
+  if (NoImplicitFloat)
+    CmdArgs.push_back("-no-implicit-float");
+
+  if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
+    StringRef Value = A->getValue();
+    if (Value == "intel" || Value == "att") {
+      CmdArgs.push_back("-mllvm");
+      CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));
+    } else {
+      getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
+          << A->getOption().getName() << Value;
+    }
+  }
+
+  // Set flags to support MCU ABI.
+  if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) {
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("soft");
+    CmdArgs.push_back("-mstack-alignment=4");
+  }
+}
+
+void Clang::AddHexagonTargetArgs(const ArgList &Args,
+                                 ArgStringList &CmdArgs) const {
+  CmdArgs.push_back("-mqdsp6-compat");
+  CmdArgs.push_back("-Wreturn-type");
+
+  if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
+    std::string N = llvm::utostr(G.getValue());
+    std::string Opt = std::string("-hexagon-small-data-threshold=") + N;
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back(Args.MakeArgString(Opt));
+  }
+
+  if (!Args.hasArg(options::OPT_fno_short_enums))
+    CmdArgs.push_back("-fshort-enums");
+  if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back("-enable-hexagon-ieee-rnd-near");
+  }
+  CmdArgs.push_back("-mllvm");
+  CmdArgs.push_back("-machine-sink-split=0");
+}
+
+void Clang::AddLanaiTargetArgs(const ArgList &Args,
+                               ArgStringList &CmdArgs) const {
+  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+    StringRef CPUName = A->getValue();
+
+    CmdArgs.push_back("-target-cpu");
+    CmdArgs.push_back(Args.MakeArgString(CPUName));
+  }
+  if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
+    StringRef Value = A->getValue();
+    // Only support mregparm=4 to support old usage. Report error for all other
+    // cases.
+    int Mregparm;
+    if (Value.getAsInteger(10, Mregparm)) {
+      if (Mregparm != 4) {
+        getToolChain().getDriver().Diag(
+            diag::err_drv_unsupported_option_argument)
+            << A->getOption().getName() << Value;
+      }
+    }
+  }
+}
+
+void Clang::AddWebAssemblyTargetArgs(const ArgList &Args,
+                                     ArgStringList &CmdArgs) const {
+  // Default to "hidden" visibility.
+  if (!Args.hasArg(options::OPT_fvisibility_EQ,
+                   options::OPT_fvisibility_ms_compat)) {
+    CmdArgs.push_back("-fvisibility");
+    CmdArgs.push_back("hidden");
+  }
+}
+
+void Clang::DumpCompilationDatabase(Compilation &C, StringRef Filename,
+                                    StringRef Target, const InputInfo &Output,
+                                    const InputInfo &Input, const ArgList &Args) const {
+  // If this is a dry run, do not create the compilation database file.
+  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
+    return;
+
+  using llvm::yaml::escape;
+  const Driver &D = getToolChain().getDriver();
+
+  if (!CompilationDatabase) {
+    std::error_code EC;
+    auto File = llvm::make_unique<llvm::raw_fd_ostream>(Filename, EC, llvm::sys::fs::F_Text);
+    if (EC) {
+      D.Diag(clang::diag::err_drv_compilationdatabase) << Filename
+                                                       << EC.message();
+      return;
+    }
+    CompilationDatabase = std::move(File);
+  }
+  auto &CDB = *CompilationDatabase;
+  SmallString<128> Buf;
+  if (llvm::sys::fs::current_path(Buf))
+    Buf = ".";
+  CDB << "{ \"directory\": \"" << escape(Buf) << "\"";
+  CDB << ", \"file\": \"" << escape(Input.getFilename()) << "\"";
+  CDB << ", \"output\": \"" << escape(Output.getFilename()) << "\"";
+  CDB << ", \"arguments\": [\"" << escape(D.ClangExecutable) << "\"";
+  Buf = "-x";
+  Buf += types::getTypeName(Input.getType());
+  CDB << ", \"" << escape(Buf) << "\"";
+  if (!D.SysRoot.empty() && !Args.hasArg(options::OPT__sysroot_EQ)) {
+    Buf = "--sysroot=";
+    Buf += D.SysRoot;
+    CDB << ", \"" << escape(Buf) << "\"";
+  }
+  CDB << ", \"" << escape(Input.getFilename()) << "\"";
+  for (auto &A: Args) {
+    auto &O = A->getOption();
+    // Skip language selection, which is positional.
+    if (O.getID() == options::OPT_x)
+      continue;
+    // Skip writing dependency output and the compilation database itself.
+    if (O.getGroup().isValid() && O.getGroup().getID() == options::OPT_M_Group)
+      continue;
+    // Skip inputs.
+    if (O.getKind() == Option::InputClass)
+      continue;
+    // All other arguments are quoted and appended.
+    ArgStringList ASL;
+    A->render(Args, ASL);
+    for (auto &it: ASL)
+      CDB << ", \"" << escape(it) << "\"";
+  }
+  Buf = "--target=";
+  Buf += Target;
+  CDB << ", \"" << escape(Buf) << "\"]},\n";
+}
+
+static void CollectArgsForIntegratedAssembler(Compilation &C,
+                                              const ArgList &Args,
+                                              ArgStringList &CmdArgs,
+                                              const Driver &D) {
+  if (UseRelaxAll(C, Args))
+    CmdArgs.push_back("-mrelax-all");
+
+  // Only default to -mincremental-linker-compatible if we think we are
+  // targeting the MSVC linker.
+  bool DefaultIncrementalLinkerCompatible =
+      C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
+  if (Args.hasFlag(options::OPT_mincremental_linker_compatible,
+                   options::OPT_mno_incremental_linker_compatible,
+                   DefaultIncrementalLinkerCompatible))
+    CmdArgs.push_back("-mincremental-linker-compatible");
+
+  switch (C.getDefaultToolChain().getArch()) {
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
+    if (Arg *A = Args.getLastArg(options::OPT_mimplicit_it_EQ)) {
+      StringRef Value = A->getValue();
+      if (Value == "always" || Value == "never" || Value == "arm" ||
+          Value == "thumb") {
+        CmdArgs.push_back("-mllvm");
+        CmdArgs.push_back(Args.MakeArgString("-arm-implicit-it=" + Value));
+      } else {
+        D.Diag(diag::err_drv_unsupported_option_argument)
+            << A->getOption().getName() << Value;
+      }
+    }
+    break;
+  default:
+    break;
+  }
+
+  // When passing -I arguments to the assembler we sometimes need to
+  // unconditionally take the next argument.  For example, when parsing
+  // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
+  // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
+  // arg after parsing the '-I' arg.
+  bool TakeNextArg = false;
+
+  // When using an integrated assembler, translate -Wa, and -Xassembler
+  // options.
+  bool CompressDebugSections = false;
+
+  bool UseRelaxRelocations = ENABLE_X86_RELAX_RELOCATIONS;
+  const char *MipsTargetFeature = nullptr;
+  for (const Arg *A :
+       Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
+    A->claim();
+
+    for (StringRef Value : A->getValues()) {
+      if (TakeNextArg) {
+        CmdArgs.push_back(Value.data());
+        TakeNextArg = false;
+        continue;
+      }
+
+      if (C.getDefaultToolChain().getTriple().isOSBinFormatCOFF() &&
+          Value == "-mbig-obj")
+        continue; // LLVM handles bigobj automatically
+
+      switch (C.getDefaultToolChain().getArch()) {
+      default:
+        break;
+      case llvm::Triple::mips:
+      case llvm::Triple::mipsel:
+      case llvm::Triple::mips64:
+      case llvm::Triple::mips64el:
+        if (Value == "--trap") {
+          CmdArgs.push_back("-target-feature");
+          CmdArgs.push_back("+use-tcc-in-div");
+          continue;
+        }
+        if (Value == "--break") {
+          CmdArgs.push_back("-target-feature");
+          CmdArgs.push_back("-use-tcc-in-div");
+          continue;
+        }
+        if (Value.startswith("-msoft-float")) {
+          CmdArgs.push_back("-target-feature");
+          CmdArgs.push_back("+soft-float");
+          continue;
+        }
+        if (Value.startswith("-mhard-float")) {
+          CmdArgs.push_back("-target-feature");
+          CmdArgs.push_back("-soft-float");
+          continue;
+        }
+
+        MipsTargetFeature = llvm::StringSwitch<const char *>(Value)
+                                .Case("-mips1", "+mips1")
+                                .Case("-mips2", "+mips2")
+                                .Case("-mips3", "+mips3")
+                                .Case("-mips4", "+mips4")
+                                .Case("-mips5", "+mips5")
+                                .Case("-mips32", "+mips32")
+                                .Case("-mips32r2", "+mips32r2")
+                                .Case("-mips32r3", "+mips32r3")
+                                .Case("-mips32r5", "+mips32r5")
+                                .Case("-mips32r6", "+mips32r6")
+                                .Case("-mips64", "+mips64")
+                                .Case("-mips64r2", "+mips64r2")
+                                .Case("-mips64r3", "+mips64r3")
+                                .Case("-mips64r5", "+mips64r5")
+                                .Case("-mips64r6", "+mips64r6")
+                                .Default(nullptr);
+        if (MipsTargetFeature)
+          continue;
+      }
+
+      if (Value == "-force_cpusubtype_ALL") {
+        // Do nothing, this is the default and we don't support anything else.
+      } else if (Value == "-L") {
+        CmdArgs.push_back("-msave-temp-labels");
+      } else if (Value == "--fatal-warnings") {
+        CmdArgs.push_back("-massembler-fatal-warnings");
+      } else if (Value == "--noexecstack") {
+        CmdArgs.push_back("-mnoexecstack");
+      } else if (Value == "-compress-debug-sections" ||
+                 Value == "--compress-debug-sections") {
+        CompressDebugSections = true;
+      } else if (Value == "-nocompress-debug-sections" ||
+                 Value == "--nocompress-debug-sections") {
+        CompressDebugSections = false;
+      } else if (Value == "-mrelax-relocations=yes" ||
+                 Value == "--mrelax-relocations=yes") {
+        UseRelaxRelocations = true;
+      } else if (Value == "-mrelax-relocations=no" ||
+                 Value == "--mrelax-relocations=no") {
+        UseRelaxRelocations = false;
+      } else if (Value.startswith("-I")) {
+        CmdArgs.push_back(Value.data());
+        // We need to consume the next argument if the current arg is a plain
+        // -I. The next arg will be the include directory.
+        if (Value == "-I")
+          TakeNextArg = true;
+      } else if (Value.startswith("-gdwarf-")) {
+        // "-gdwarf-N" options are not cc1as options.
+        unsigned DwarfVersion = DwarfVersionNum(Value);
+        if (DwarfVersion == 0) { // Send it onward, and let cc1as complain.
+          CmdArgs.push_back(Value.data());
+        } else {
+          RenderDebugEnablingArgs(Args, CmdArgs,
+                                  codegenoptions::LimitedDebugInfo,
+                                  DwarfVersion, llvm::DebuggerKind::Default);
+        }
+      } else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") ||
+                 Value.startswith("-mhwdiv") || Value.startswith("-march")) {
+        // Do nothing, we'll validate it later.
+      } else if (Value == "-defsym") {
+          if (A->getNumValues() != 2) {
+            D.Diag(diag::err_drv_defsym_invalid_format) << Value;
+            break;
+          }
+          const char *S = A->getValue(1);
+          auto Pair = StringRef(S).split('=');
+          auto Sym = Pair.first;
+          auto SVal = Pair.second;
+
+          if (Sym.empty() || SVal.empty()) {
+            D.Diag(diag::err_drv_defsym_invalid_format) << S;
+            break;
+          }
+          int64_t IVal;
+          if (SVal.getAsInteger(0, IVal)) {
+            D.Diag(diag::err_drv_defsym_invalid_symval) << SVal;
+            break;
+          }
+          CmdArgs.push_back(Value.data());
+          TakeNextArg = true;
+      } else {
+        D.Diag(diag::err_drv_unsupported_option_argument)
+            << A->getOption().getName() << Value;
+      }
+    }
+  }
+  if (CompressDebugSections) {
+    if (llvm::zlib::isAvailable())
+      CmdArgs.push_back("-compress-debug-sections");
+    else
+      D.Diag(diag::warn_debug_compression_unavailable);
+  }
+  if (UseRelaxRelocations)
+    CmdArgs.push_back("--mrelax-relocations");
+  if (MipsTargetFeature != nullptr) {
+    CmdArgs.push_back("-target-feature");
+    CmdArgs.push_back(MipsTargetFeature);
+  }
+}
+
+void Clang::ConstructJob(Compilation &C, const JobAction &JA,
+                         const InputInfo &Output, const InputInfoList &Inputs,
+                         const ArgList &Args, const char *LinkingOutput) const {
+  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+  const std::string &TripleStr = Triple.getTriple();
+
+  bool KernelOrKext =
+      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  // Check number of inputs for sanity. We need at least one input.
+  assert(Inputs.size() >= 1 && "Must have at least one input.");
+  const InputInfo &Input = Inputs[0];
+  // CUDA compilation may have multiple inputs (source file + results of
+  // device-side compilations). OpenMP device jobs also take the host IR as a
+  // second input. All other jobs are expected to have exactly one
+  // input.
+  bool IsCuda = JA.isOffloading(Action::OFK_Cuda);
+  bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
+  assert((IsCuda || (IsOpenMPDevice && Inputs.size() == 2) ||
+          Inputs.size() == 1) &&
+         "Unable to handle multiple inputs.");
+
+  bool IsWindowsGNU = getToolChain().getTriple().isWindowsGNUEnvironment();
+  bool IsWindowsCygnus =
+      getToolChain().getTriple().isWindowsCygwinEnvironment();
+  bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
+  bool IsPS4CPU = getToolChain().getTriple().isPS4CPU();
+  bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
+
+  // Adjust IsWindowsXYZ for CUDA compilations.  Even when compiling in device
+  // mode (i.e., getToolchain().getTriple() is NVPTX, not Windows), we need to
+  // pass Windows-specific flags to cc1.
+  if (IsCuda) {
+    const llvm::Triple *AuxTriple = getToolChain().getAuxTriple();
+    IsWindowsMSVC |= AuxTriple && AuxTriple->isWindowsMSVCEnvironment();
+    IsWindowsGNU |= AuxTriple && AuxTriple->isWindowsGNUEnvironment();
+    IsWindowsCygnus |= AuxTriple && AuxTriple->isWindowsCygwinEnvironment();
+  }
+
+  // C++ is not supported for IAMCU.
+  if (IsIAMCU && types::isCXX(Input.getType()))
+    D.Diag(diag::err_drv_clang_unsupported) << "C++ for IAMCU";
+
+  // Invoke ourselves in -cc1 mode.
+  //
+  // FIXME: Implement custom jobs for internal actions.
+  CmdArgs.push_back("-cc1");
+
+  // Add the "effective" target triple.
+  CmdArgs.push_back("-triple");
+  CmdArgs.push_back(Args.MakeArgString(TripleStr));
+
+  if (const Arg *MJ = Args.getLastArg(options::OPT_MJ)) {
+    DumpCompilationDatabase(C, MJ->getValue(), TripleStr, Output, Input, Args);
+    Args.ClaimAllArgs(options::OPT_MJ);
+  }
+
+  if (IsCuda) {
+    // We have to pass the triple of the host if compiling for a CUDA device and
+    // vice-versa.
+    std::string NormalizedTriple;
+    if (JA.isDeviceOffloading(Action::OFK_Cuda))
+      NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>()
+                             ->getTriple()
+                             .normalize();
+    else
+      NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Cuda>()
+                             ->getTriple()
+                             .normalize();
+
+    CmdArgs.push_back("-aux-triple");
+    CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
+  }
+
+  if (Triple.isOSWindows() && (Triple.getArch() == llvm::Triple::arm ||
+                               Triple.getArch() == llvm::Triple::thumb)) {
+    unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
+    unsigned Version;
+    Triple.getArchName().substr(Offset).getAsInteger(10, Version);
+    if (Version < 7)
+      D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
+                                                << TripleStr;
+  }
+
+  // Push all default warning arguments that are specific to
+  // the given target.  These come before user provided warning options
+  // are provided.
+  getToolChain().addClangWarningOptions(CmdArgs);
+
+  // Select the appropriate action.
+  RewriteKind rewriteKind = RK_None;
+
+  if (isa<AnalyzeJobAction>(JA)) {
+    assert(JA.getType() == types::TY_Plist && "Invalid output type.");
+    CmdArgs.push_back("-analyze");
+  } else if (isa<MigrateJobAction>(JA)) {
+    CmdArgs.push_back("-migrate");
+  } else if (isa<PreprocessJobAction>(JA)) {
+    if (Output.getType() == types::TY_Dependencies)
+      CmdArgs.push_back("-Eonly");
+    else {
+      CmdArgs.push_back("-E");
+      if (Args.hasArg(options::OPT_rewrite_objc) &&
+          !Args.hasArg(options::OPT_g_Group))
+        CmdArgs.push_back("-P");
+    }
+  } else if (isa<AssembleJobAction>(JA)) {
+    CmdArgs.push_back("-emit-obj");
+
+    CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
+
+    // Also ignore explicit -force_cpusubtype_ALL option.
+    (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
+  } else if (isa<PrecompileJobAction>(JA)) {
+    // Use PCH if the user requested it.
+    bool UsePCH = D.CCCUsePCH;
+
+    if (JA.getType() == types::TY_Nothing)
+      CmdArgs.push_back("-fsyntax-only");
+    else if (JA.getType() == types::TY_ModuleFile)
+      CmdArgs.push_back("-emit-module-interface");
+    else if (UsePCH)
+      CmdArgs.push_back("-emit-pch");
+    else
+      CmdArgs.push_back("-emit-pth");
+  } else if (isa<VerifyPCHJobAction>(JA)) {
+    CmdArgs.push_back("-verify-pch");
+  } else {
+    assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
+           "Invalid action for clang tool.");
+    if (JA.getType() == types::TY_Nothing) {
+      CmdArgs.push_back("-fsyntax-only");
+    } else if (JA.getType() == types::TY_LLVM_IR ||
+               JA.getType() == types::TY_LTO_IR) {
+      CmdArgs.push_back("-emit-llvm");
+    } else if (JA.getType() == types::TY_LLVM_BC ||
+               JA.getType() == types::TY_LTO_BC) {
+      CmdArgs.push_back("-emit-llvm-bc");
+    } else if (JA.getType() == types::TY_PP_Asm) {
+      CmdArgs.push_back("-S");
+    } else if (JA.getType() == types::TY_AST) {
+      CmdArgs.push_back("-emit-pch");
+    } else if (JA.getType() == types::TY_ModuleFile) {
+      CmdArgs.push_back("-module-file-info");
+    } else if (JA.getType() == types::TY_RewrittenObjC) {
+      CmdArgs.push_back("-rewrite-objc");
+      rewriteKind = RK_NonFragile;
+    } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
+      CmdArgs.push_back("-rewrite-objc");
+      rewriteKind = RK_Fragile;
+    } else {
+      assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
+    }
+
+    // Preserve use-list order by default when emitting bitcode, so that
+    // loading the bitcode up in 'opt' or 'llc' and running passes gives the
+    // same result as running passes here.  For LTO, we don't need to preserve
+    // the use-list order, since serialization to bitcode is part of the flow.
+    if (JA.getType() == types::TY_LLVM_BC)
+      CmdArgs.push_back("-emit-llvm-uselists");
+
+    if (D.isUsingLTO()) {
+      Args.AddLastArg(CmdArgs, options::OPT_flto, options::OPT_flto_EQ);
+
+      // The Darwin linker currently uses the legacy LTO API, which does not
+      // support LTO unit features (CFI, whole program vtable opt) under
+      // ThinLTO.
+      if (!getToolChain().getTriple().isOSDarwin() ||
+          D.getLTOMode() == LTOK_Full)
+        CmdArgs.push_back("-flto-unit");
+    }
+  }
+
+  if (const Arg *A = Args.getLastArg(options::OPT_fthinlto_index_EQ)) {
+    if (!types::isLLVMIR(Input.getType()))
+      D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
+                                                       << "-x ir";
+    Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
+  }
+
+  // Embed-bitcode option.
+  if (C.getDriver().embedBitcodeInObject() && !C.getDriver().isUsingLTO() &&
+      (isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
+    // Add flags implied by -fembed-bitcode.
+    Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
+    // Disable all llvm IR level optimizations.
+    CmdArgs.push_back("-disable-llvm-passes");
+  }
+  if (C.getDriver().embedBitcodeMarkerOnly() && !C.getDriver().isUsingLTO())
+    CmdArgs.push_back("-fembed-bitcode=marker");
+
+  // 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
+  CmdArgs.push_back("-disable-llvm-verifier");
+  // Discard LLVM value names in -asserts builds.
+  CmdArgs.push_back("-discard-value-names");
+#endif
+
+  // Set the main file name, so that debug info works even with
+  // -save-temps.
+  CmdArgs.push_back("-main-file-name");
+  CmdArgs.push_back(getBaseInputName(Args, Input));
+
+  // Some flags which affect the language (via preprocessor
+  // defines).
+  if (Args.hasArg(options::OPT_static))
+    CmdArgs.push_back("-static-define");
+
+  if (isa<AnalyzeJobAction>(JA)) {
+    // Enable region store model by default.
+    CmdArgs.push_back("-analyzer-store=region");
+
+    // Treat blocks as analysis entry points.
+    CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
+
+    CmdArgs.push_back("-analyzer-eagerly-assume");
+
+    // Add default argument set.
+    if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
+      CmdArgs.push_back("-analyzer-checker=core");
+      CmdArgs.push_back("-analyzer-checker=apiModeling");
+
+    if (!IsWindowsMSVC) {
+      CmdArgs.push_back("-analyzer-checker=unix");
+    } else {
+      // Enable "unix" checkers that also work on Windows.
+      CmdArgs.push_back("-analyzer-checker=unix.API");
+      CmdArgs.push_back("-analyzer-checker=unix.Malloc");
+      CmdArgs.push_back("-analyzer-checker=unix.MallocSizeof");
+      CmdArgs.push_back("-analyzer-checker=unix.MismatchedDeallocator");
+      CmdArgs.push_back("-analyzer-checker=unix.cstring.BadSizeArg");
+      CmdArgs.push_back("-analyzer-checker=unix.cstring.NullArg");
+    }
+
+      // Disable some unix checkers for PS4.
+      if (IsPS4CPU) {
+        CmdArgs.push_back("-analyzer-disable-checker=unix.API");
+        CmdArgs.push_back("-analyzer-disable-checker=unix.Vfork");
+      }
+
+      if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
+        CmdArgs.push_back("-analyzer-checker=osx");
+
+      CmdArgs.push_back("-analyzer-checker=deadcode");
+
+      if (types::isCXX(Input.getType()))
+        CmdArgs.push_back("-analyzer-checker=cplusplus");
+
+      if (!IsPS4CPU) {
+        CmdArgs.push_back(
+            "-analyzer-checker=security.insecureAPI.UncheckedReturn");
+        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
+        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets");
+        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp");
+        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
+        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
+      }
+
+      // Default nullability checks.
+      CmdArgs.push_back("-analyzer-checker=nullability.NullPassedToNonnull");
+      CmdArgs.push_back(
+          "-analyzer-checker=nullability.NullReturnedFromNonnull");
+    }
+
+    // Set the output format. The default is plist, for (lame) historical
+    // reasons.
+    CmdArgs.push_back("-analyzer-output");
+    if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
+      CmdArgs.push_back(A->getValue());
+    else
+      CmdArgs.push_back("plist");
+
+    // Disable the presentation of standard compiler warnings when
+    // using --analyze.  We only want to show static analyzer diagnostics
+    // or frontend errors.
+    CmdArgs.push_back("-w");
+
+    // Add -Xanalyzer arguments when running as analyzer.
+    Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
+  }
+
+  CheckCodeGenerationOptions(D, Args);
+
+  llvm::Reloc::Model RelocationModel;
+  unsigned PICLevel;
+  bool IsPIE;
+  std::tie(RelocationModel, PICLevel, IsPIE) =
+      ParsePICArgs(getToolChain(), Args);
+
+  const char *RMName = RelocationModelName(RelocationModel);
+
+  if ((RelocationModel == llvm::Reloc::ROPI ||
+       RelocationModel == llvm::Reloc::ROPI_RWPI) &&
+      types::isCXX(Input.getType()) &&
+      !Args.hasArg(options::OPT_fallow_unsupported))
+    D.Diag(diag::err_drv_ropi_incompatible_with_cxx);
+
+  if (RMName) {
+    CmdArgs.push_back("-mrelocation-model");
+    CmdArgs.push_back(RMName);
+  }
+  if (PICLevel > 0) {
+    CmdArgs.push_back("-pic-level");
+    CmdArgs.push_back(PICLevel == 1 ? "1" : "2");
+    if (IsPIE)
+      CmdArgs.push_back("-pic-is-pie");
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_meabi)) {
+    CmdArgs.push_back("-meabi");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  CmdArgs.push_back("-mthread-model");
+  if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
+    CmdArgs.push_back(A->getValue());
+  else
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().getThreadModel()));
+
+  Args.AddLastArg(CmdArgs, options::OPT_fveclib);
+
+  if (!Args.hasFlag(options::OPT_fmerge_all_constants,
+                    options::OPT_fno_merge_all_constants))
+    CmdArgs.push_back("-fno-merge-all-constants");
+
+  // LLVM Code Generator Options.
+
+  if (Args.hasArg(options::OPT_frewrite_map_file) ||
+      Args.hasArg(options::OPT_frewrite_map_file_EQ)) {
+    for (const Arg *A : Args.filtered(options::OPT_frewrite_map_file,
+                                      options::OPT_frewrite_map_file_EQ)) {
+      StringRef Map = A->getValue();
+      if (!llvm::sys::fs::exists(Map)) {
+        D.Diag(diag::err_drv_no_such_file) << Map;
+      } else {
+        CmdArgs.push_back("-frewrite-map-file");
+        CmdArgs.push_back(A->getValue());
+        A->claim();
+      }
+    }
+  }
+
+  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 (!Args.hasFlag(options::OPT_fjump_tables, options::OPT_fno_jump_tables,
+                    true))
+    CmdArgs.push_back("-fno-jump-tables");
+
+  if (!Args.hasFlag(options::OPT_fpreserve_as_comments,
+                    options::OPT_fno_preserve_as_comments, true))
+    CmdArgs.push_back("-fno-preserve-as-comments");
+
+  if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
+    CmdArgs.push_back("-mregparm");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
+                               options::OPT_freg_struct_return)) {
+    if (getToolChain().getArch() != llvm::Triple::x86) {
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getSpelling() << getToolChain().getTriple().str();
+    } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
+      CmdArgs.push_back("-fpcc-struct-return");
+    } else {
+      assert(A->getOption().matches(options::OPT_freg_struct_return));
+      CmdArgs.push_back("-freg-struct-return");
+    }
+  }
+
+  if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
+    CmdArgs.push_back("-fdefault-calling-conv=stdcall");
+
+  if (shouldUseFramePointer(Args, getToolChain().getTriple()))
+    CmdArgs.push_back("-mdisable-fp-elim");
+  if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
+                    options::OPT_fno_zero_initialized_in_bss))
+    CmdArgs.push_back("-mno-zero-initialized-in-bss");
+
+  bool OFastEnabled = isOptimizationLevelFast(Args);
+  // If -Ofast is the optimization level, then -fstrict-aliasing should be
+  // enabled.  This alias option is being used to simplify the hasFlag logic.
+  OptSpecifier StrictAliasingAliasOption =
+      OFastEnabled ? options::OPT_Ofast : options::OPT_fstrict_aliasing;
+  // We turn strict aliasing off by default if we're in CL mode, since MSVC
+  // doesn't do any TBAA.
+  bool TBAAOnByDefault = !getToolChain().getDriver().IsCLMode();
+  if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
+                    options::OPT_fno_strict_aliasing, TBAAOnByDefault))
+    CmdArgs.push_back("-relaxed-aliasing");
+  if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
+                    options::OPT_fno_struct_path_tbaa))
+    CmdArgs.push_back("-no-struct-path-tbaa");
+  if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
+                   false))
+    CmdArgs.push_back("-fstrict-enums");
+  if (!Args.hasFlag(options::OPT_fstrict_return, options::OPT_fno_strict_return,
+                    true))
+    CmdArgs.push_back("-fno-strict-return");
+  if (Args.hasFlag(options::OPT_fstrict_vtable_pointers,
+                   options::OPT_fno_strict_vtable_pointers,
+                   false))
+    CmdArgs.push_back("-fstrict-vtable-pointers");
+  if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
+                    options::OPT_fno_optimize_sibling_calls))
+    CmdArgs.push_back("-mdisable-tail-calls");
+
+  // Handle segmented stacks.
+  if (Args.hasArg(options::OPT_fsplit_stack))
+    CmdArgs.push_back("-split-stacks");
+
+  // If -Ofast is the optimization level, then -ffast-math should be enabled.
+  // This alias option is being used to simplify the getLastArg logic.
+  OptSpecifier FastMathAliasOption =
+      OFastEnabled ? options::OPT_Ofast : options::OPT_ffast_math;
+
+  // Handle various floating point optimization flags, mapping them to the
+  // appropriate LLVM code generation flags. The pattern for all of these is to
+  // default off the codegen optimizations, and if any flag enables them and no
+  // flag disables them after the flag enabling them, enable the codegen
+  // optimization. This is complicated by several "umbrella" flags.
+  if (Arg *A = Args.getLastArg(
+          options::OPT_ffast_math, FastMathAliasOption,
+          options::OPT_fno_fast_math, options::OPT_ffinite_math_only,
+          options::OPT_fno_finite_math_only, options::OPT_fhonor_infinities,
+          options::OPT_fno_honor_infinities))
+    if (A->getOption().getID() != options::OPT_fno_fast_math &&
+        A->getOption().getID() != options::OPT_fno_finite_math_only &&
+        A->getOption().getID() != options::OPT_fhonor_infinities)
+      CmdArgs.push_back("-menable-no-infs");
+  if (Arg *A = Args.getLastArg(
+          options::OPT_ffast_math, FastMathAliasOption,
+          options::OPT_fno_fast_math, options::OPT_ffinite_math_only,
+          options::OPT_fno_finite_math_only, options::OPT_fhonor_nans,
+          options::OPT_fno_honor_nans))
+    if (A->getOption().getID() != options::OPT_fno_fast_math &&
+        A->getOption().getID() != options::OPT_fno_finite_math_only &&
+        A->getOption().getID() != options::OPT_fhonor_nans)
+      CmdArgs.push_back("-menable-no-nans");
+
+  // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
+  bool MathErrno = getToolChain().IsMathErrnoDefault();
+  if (Arg *A =
+          Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
+                          options::OPT_fno_fast_math, options::OPT_fmath_errno,
+                          options::OPT_fno_math_errno)) {
+    // Turning on -ffast_math (with either flag) removes the need for MathErrno.
+    // However, turning *off* -ffast_math merely restores the toolchain default
+    // (which may be false).
+    if (A->getOption().getID() == options::OPT_fno_math_errno ||
+        A->getOption().getID() == options::OPT_ffast_math ||
+        A->getOption().getID() == options::OPT_Ofast)
+      MathErrno = false;
+    else if (A->getOption().getID() == options::OPT_fmath_errno)
+      MathErrno = true;
+  }
+  if (MathErrno)
+    CmdArgs.push_back("-fmath-errno");
+
+  // There are several flags which require disabling very specific
+  // optimizations. Any of these being disabled forces us to turn off the
+  // entire set of LLVM optimizations, so collect them through all the flag
+  // madness.
+  bool AssociativeMath = false;
+  if (Arg *A = Args.getLastArg(
+          options::OPT_ffast_math, FastMathAliasOption,
+          options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
+          options::OPT_fno_unsafe_math_optimizations,
+          options::OPT_fassociative_math, options::OPT_fno_associative_math))
+    if (A->getOption().getID() != options::OPT_fno_fast_math &&
+        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+        A->getOption().getID() != options::OPT_fno_associative_math)
+      AssociativeMath = true;
+  bool ReciprocalMath = false;
+  if (Arg *A = Args.getLastArg(
+          options::OPT_ffast_math, FastMathAliasOption,
+          options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
+          options::OPT_fno_unsafe_math_optimizations,
+          options::OPT_freciprocal_math, options::OPT_fno_reciprocal_math))
+    if (A->getOption().getID() != options::OPT_fno_fast_math &&
+        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+        A->getOption().getID() != options::OPT_fno_reciprocal_math)
+      ReciprocalMath = true;
+  bool SignedZeros = true;
+  if (Arg *A = Args.getLastArg(
+          options::OPT_ffast_math, FastMathAliasOption,
+          options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
+          options::OPT_fno_unsafe_math_optimizations,
+          options::OPT_fsigned_zeros, options::OPT_fno_signed_zeros))
+    if (A->getOption().getID() != options::OPT_fno_fast_math &&
+        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+        A->getOption().getID() != options::OPT_fsigned_zeros)
+      SignedZeros = false;
+  bool TrappingMath = true;
+  if (Arg *A = Args.getLastArg(
+          options::OPT_ffast_math, FastMathAliasOption,
+          options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
+          options::OPT_fno_unsafe_math_optimizations,
+          options::OPT_ftrapping_math, options::OPT_fno_trapping_math))
+    if (A->getOption().getID() != options::OPT_fno_fast_math &&
+        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+        A->getOption().getID() != options::OPT_ftrapping_math)
+      TrappingMath = false;
+  if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
+      !TrappingMath)
+    CmdArgs.push_back("-menable-unsafe-fp-math");
+
+  if (!SignedZeros)
+    CmdArgs.push_back("-fno-signed-zeros");
+
+  if (ReciprocalMath)
+    CmdArgs.push_back("-freciprocal-math");
+
+  if (!TrappingMath)
+    CmdArgs.push_back("-fno-trapping-math");
+
+
+  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
+                               options::OPT_fno_fast_math,
+                               options::OPT_funsafe_math_optimizations,
+                               options::OPT_fno_unsafe_math_optimizations,
+                               options::OPT_fdenormal_fp_math_EQ))
+    if (A->getOption().getID() != options::OPT_fno_fast_math &&
+        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations)
+      Args.AddLastArg(CmdArgs, options::OPT_fdenormal_fp_math_EQ);
+
+  // Validate and pass through -fp-contract option.
+  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
+                               options::OPT_fno_fast_math,
+                               options::OPT_ffp_contract)) {
+    if (A->getOption().getID() == options::OPT_ffp_contract) {
+      StringRef Val = A->getValue();
+      if (Val == "fast" || Val == "on" || Val == "off") {
+        CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val));
+      } else {
+        D.Diag(diag::err_drv_unsupported_option_argument)
+            << A->getOption().getName() << Val;
+      }
+    } else if (A->getOption().matches(options::OPT_ffast_math) ||
+               (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) {
+      // If fast-math is set then set the fp-contract mode to fast.
+      CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
+    }
+  }
+
+  ParseMRecip(getToolChain().getDriver(), Args, CmdArgs);
+
+  // We separately look for the '-ffast-math' and '-ffinite-math-only' flags,
+  // and if we find them, tell the frontend to provide the appropriate
+  // preprocessor macros. This is distinct from enabling any optimizations as
+  // these options induce language changes which must survive serialization
+  // and deserialization, etc.
+  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
+                               options::OPT_fno_fast_math))
+    if (!A->getOption().matches(options::OPT_fno_fast_math))
+      CmdArgs.push_back("-ffast-math");
+  if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only,
+                               options::OPT_fno_fast_math))
+    if (A->getOption().matches(options::OPT_ffinite_math_only))
+      CmdArgs.push_back("-ffinite-math-only");
+
+  // Decide whether to use verbose asm. Verbose assembly is the default on
+  // toolchains which have the integrated assembler on by default.
+  bool IsIntegratedAssemblerDefault =
+      getToolChain().IsIntegratedAssemblerDefault();
+  if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
+                   IsIntegratedAssemblerDefault) ||
+      Args.hasArg(options::OPT_dA))
+    CmdArgs.push_back("-masm-verbose");
+
+  if (!Args.hasFlag(options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
+                    IsIntegratedAssemblerDefault))
+    CmdArgs.push_back("-no-integrated-as");
+
+  if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
+    CmdArgs.push_back("-mdebug-pass");
+    CmdArgs.push_back("Structure");
+  }
+  if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
+    CmdArgs.push_back("-mdebug-pass");
+    CmdArgs.push_back("Arguments");
+  }
+
+  // Enable -mconstructor-aliases except on darwin, where we have to work around
+  // a linker bug (see <rdar://problem/7651567>), and CUDA device code, where
+  // aliases aren't supported.
+  if (!getToolChain().getTriple().isOSDarwin() &&
+      !getToolChain().getTriple().isNVPTX())
+    CmdArgs.push_back("-mconstructor-aliases");
+
+  // Darwin's kernel doesn't support guard variables; just die if we
+  // try to use them.
+  if (KernelOrKext && getToolChain().getTriple().isOSDarwin())
+    CmdArgs.push_back("-fforbid-guard-variables");
+
+  if (Args.hasFlag(options::OPT_mms_bitfields, options::OPT_mno_ms_bitfields,
+                   false)) {
+    CmdArgs.push_back("-mms-bitfields");
+  }
+
+  if (Args.hasFlag(options::OPT_mpie_copy_relocations,
+                   options::OPT_mno_pie_copy_relocations,
+                   false)) {
+    CmdArgs.push_back("-mpie-copy-relocations");
+  }
+
+  // This is a coarse approximation of what llvm-gcc actually does, both
+  // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
+  // complicated ways.
+  bool AsynchronousUnwindTables =
+      Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
+                   options::OPT_fno_asynchronous_unwind_tables,
+                   (getToolChain().IsUnwindTablesDefault() ||
+                    getToolChain().getSanitizerArgs().needsUnwindTables()) &&
+                       !KernelOrKext);
+  if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
+                   AsynchronousUnwindTables))
+    CmdArgs.push_back("-munwind-tables");
+
+  getToolChain().addClangTargetOptions(Args, CmdArgs);
+
+  if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
+    CmdArgs.push_back("-mlimit-float-precision");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  // FIXME: Handle -mtune=.
+  (void)Args.hasArg(options::OPT_mtune_EQ);
+
+  if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
+    CmdArgs.push_back("-mcode-model");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  // Add the target cpu
+  std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);
+  if (!CPU.empty()) {
+    CmdArgs.push_back("-target-cpu");
+    CmdArgs.push_back(Args.MakeArgString(CPU));
+  }
+
+  if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
+    CmdArgs.push_back("-mfpmath");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  // Add the target features
+  getTargetFeatures(getToolChain(), Triple, Args, CmdArgs, false);
+
+  // Add target specific flags.
+  switch (getToolChain().getArch()) {
+  default:
+    break;
+
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
+    // Use the effective triple, which takes into account the deployment target.
+    AddARMTargetArgs(Triple, Args, CmdArgs, KernelOrKext);
+    break;
+
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+    AddAArch64TargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el:
+    AddMIPSTargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::ppc:
+  case llvm::Triple::ppc64:
+  case llvm::Triple::ppc64le:
+    AddPPCTargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+  case llvm::Triple::sparcv9:
+    AddSparcTargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::systemz:
+    AddSystemZTargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    AddX86TargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::lanai:
+    AddLanaiTargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::hexagon:
+    AddHexagonTargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::wasm32:
+  case llvm::Triple::wasm64:
+    AddWebAssemblyTargetArgs(Args, CmdArgs);
+    break;
+  }
+
+  // The 'g' groups options involve a somewhat intricate sequence of decisions
+  // about what to pass from the driver to the frontend, but by the time they
+  // reach cc1 they've been factored into three well-defined orthogonal choices:
+  //  * what level of debug info to generate
+  //  * what dwarf version to write
+  //  * what debugger tuning to use
+  // This avoids having to monkey around further in cc1 other than to disable
+  // codeview if not running in a Windows environment. Perhaps even that
+  // decision should be made in the driver as well though.
+  unsigned DwarfVersion = 0;
+  llvm::DebuggerKind DebuggerTuning = getToolChain().getDefaultDebuggerTuning();
+  // These two are potentially updated by AddClangCLArgs.
+  codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
+  bool EmitCodeView = false;
+
+  // Add clang-cl arguments.
+  types::ID InputType = Input.getType();
+  if (getToolChain().getDriver().IsCLMode())
+    AddClangCLArgs(Args, InputType, CmdArgs, &DebugInfoKind, &EmitCodeView);
+
+  // Pass the linker version in use.
+  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
+    CmdArgs.push_back("-target-linker-version");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (!shouldUseLeafFramePointer(Args, getToolChain().getTriple()))
+    CmdArgs.push_back("-momit-leaf-frame-pointer");
+
+  // Explicitly error on some things we know we don't support and can't just
+  // ignore.
+  if (!Args.hasArg(options::OPT_fallow_unsupported)) {
+    Arg *Unsupported;
+    if (types::isCXX(InputType) && getToolChain().getTriple().isOSDarwin() &&
+        getToolChain().getArch() == llvm::Triple::x86) {
+      if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
+          (Unsupported = Args.getLastArg(options::OPT_mkernel)))
+        D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
+            << Unsupported->getOption().getName();
+    }
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_v);
+  Args.AddLastArg(CmdArgs, options::OPT_H);
+  if (D.CCPrintHeaders && !D.CCGenDiagnostics) {
+    CmdArgs.push_back("-header-include-file");
+    CmdArgs.push_back(D.CCPrintHeadersFilename ? D.CCPrintHeadersFilename
+                                               : "-");
+  }
+  Args.AddLastArg(CmdArgs, options::OPT_P);
+  Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
+
+  if (D.CCLogDiagnostics && !D.CCGenDiagnostics) {
+    CmdArgs.push_back("-diagnostic-log-file");
+    CmdArgs.push_back(D.CCLogDiagnosticsFilename ? D.CCLogDiagnosticsFilename
+                                                 : "-");
+  }
+
+  bool splitDwarfInlining =
+      Args.hasFlag(options::OPT_fsplit_dwarf_inlining,
+                   options::OPT_fno_split_dwarf_inlining, true);
+
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  Arg *SplitDwarfArg = Args.getLastArg(options::OPT_gsplit_dwarf);
+  if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
+    // If the last option explicitly specified a debug-info level, use it.
+    if (A->getOption().matches(options::OPT_gN_Group)) {
+      DebugInfoKind = DebugLevelToInfoKind(*A);
+      // If you say "-gsplit-dwarf -gline-tables-only", -gsplit-dwarf loses.
+      // But -gsplit-dwarf is not a g_group option, hence we have to check the
+      // order explicitly. (If -gsplit-dwarf wins, we fix DebugInfoKind later.)
+      // This gets a bit more complicated if you've disabled inline info in the
+      // skeleton CUs (splitDwarfInlining) - then there's value in composing
+      // split-dwarf and line-tables-only, so let those compose naturally in
+      // that case.
+      // And if you just turned off debug info, (-gsplit-dwarf -g0) - do that.
+      if (SplitDwarfArg) {
+        if (A->getIndex() > SplitDwarfArg->getIndex()) {
+          if (DebugInfoKind == codegenoptions::NoDebugInfo ||
+              (DebugInfoKind == codegenoptions::DebugLineTablesOnly &&
+               splitDwarfInlining))
+            SplitDwarfArg = nullptr;
+        } else if (splitDwarfInlining)
+          DebugInfoKind = codegenoptions::NoDebugInfo;
+      }
+    } else
+      // For any other 'g' option, use Limited.
+      DebugInfoKind = codegenoptions::LimitedDebugInfo;
+  }
+
+  // If a debugger tuning argument appeared, remember it.
+  if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
+                               options::OPT_ggdbN_Group)) {
+    if (A->getOption().matches(options::OPT_glldb))
+      DebuggerTuning = llvm::DebuggerKind::LLDB;
+    else if (A->getOption().matches(options::OPT_gsce))
+      DebuggerTuning = llvm::DebuggerKind::SCE;
+    else
+      DebuggerTuning = llvm::DebuggerKind::GDB;
+  }
+
+  // If a -gdwarf argument appeared, remember it.
+  if (Arg *A = Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
+                               options::OPT_gdwarf_4, options::OPT_gdwarf_5))
+    DwarfVersion = DwarfVersionNum(A->getSpelling());
+
+  // Forward -gcodeview. EmitCodeView might have been set by CL-compatibility
+  // argument parsing.
+  if (Args.hasArg(options::OPT_gcodeview) || EmitCodeView) {
+    // DwarfVersion remains at 0 if no explicit choice was made.
+    CmdArgs.push_back("-gcodeview");
+  } else if (DwarfVersion == 0 &&
+             DebugInfoKind != codegenoptions::NoDebugInfo) {
+    DwarfVersion = getToolChain().GetDefaultDwarfVersion();
+  }
+
+  // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
+  Args.ClaimAllArgs(options::OPT_g_flags_Group);
+
+  // Column info is included by default for everything except PS4 and CodeView.
+  // Clang doesn't track end columns, just starting columns, which, in theory,
+  // is fine for CodeView (and PDB).  In practice, however, the Microsoft
+  // debuggers don't handle missing end columns well, so it's better not to
+  // include any column info.
+  if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
+                   /*Default=*/ !IsPS4CPU && !(IsWindowsMSVC && EmitCodeView)))
+    CmdArgs.push_back("-dwarf-column-info");
+
+  // FIXME: Move backend command line options to the module.
+  // If -gline-tables-only is the last option it wins.
+  if (DebugInfoKind != codegenoptions::DebugLineTablesOnly &&
+      Args.hasArg(options::OPT_gmodules)) {
+    DebugInfoKind = codegenoptions::LimitedDebugInfo;
+    CmdArgs.push_back("-dwarf-ext-refs");
+    CmdArgs.push_back("-fmodule-format=obj");
+  }
+
+  // -gsplit-dwarf should turn on -g and enable the backend dwarf
+  // splitting and extraction.
+  // FIXME: Currently only works on Linux.
+  if (getToolChain().getTriple().isOSLinux() && SplitDwarfArg) {
+    if (!splitDwarfInlining)
+      CmdArgs.push_back("-fno-split-dwarf-inlining");
+    if (DebugInfoKind == codegenoptions::NoDebugInfo)
+      DebugInfoKind = codegenoptions::LimitedDebugInfo;
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-split-dwarf=Enable");
+  }
+
+  // After we've dealt with all combinations of things that could
+  // make DebugInfoKind be other than None or DebugLineTablesOnly,
+  // figure out if we need to "upgrade" it to standalone debug info.
+  // We parse these two '-f' options whether or not they will be used,
+  // to claim them even if you wrote "-fstandalone-debug -gline-tables-only"
+  bool NeedFullDebug = Args.hasFlag(options::OPT_fstandalone_debug,
+                                    options::OPT_fno_standalone_debug,
+                                    getToolChain().GetDefaultStandaloneDebug());
+  if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug)
+    DebugInfoKind = codegenoptions::FullDebugInfo;
+  RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
+                          DebuggerTuning);
+
+  // -fdebug-macro turns on macro debug info generation.
+  if (Args.hasFlag(options::OPT_fdebug_macro, options::OPT_fno_debug_macro,
+                   false))
+    CmdArgs.push_back("-debug-info-macro");
+
+  // -ggnu-pubnames turns on gnu style pubnames in the backend.
+  if (Args.hasArg(options::OPT_ggnu_pubnames)) {
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-generate-gnu-dwarf-pub-sections");
+  }
+
+  // -gdwarf-aranges turns on the emission of the aranges section in the
+  // backend.
+  // Always enabled on the PS4.
+  if (Args.hasArg(options::OPT_gdwarf_aranges) || IsPS4CPU) {
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-generate-arange-section");
+  }
+
+  if (Args.hasFlag(options::OPT_fdebug_types_section,
+                   options::OPT_fno_debug_types_section, false)) {
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-generate-type-units");
+  }
+
+  bool UseSeparateSections = isUseSeparateSections(Triple);
+
+  if (Args.hasFlag(options::OPT_ffunction_sections,
+                   options::OPT_fno_function_sections, UseSeparateSections)) {
+    CmdArgs.push_back("-ffunction-sections");
+  }
+
+  if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
+                   UseSeparateSections)) {
+    CmdArgs.push_back("-fdata-sections");
+  }
+
+  if (!Args.hasFlag(options::OPT_funique_section_names,
+                    options::OPT_fno_unique_section_names, true))
+    CmdArgs.push_back("-fno-unique-section-names");
+
+  Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
+
+  if (Args.hasFlag(options::OPT_fxray_instrument,
+                   options::OPT_fnoxray_instrument, false)) {
+    const char *const XRayInstrumentOption = "-fxray-instrument";
+    if (Triple.getOS() == llvm::Triple::Linux)
+      switch (Triple.getArch()) {
+      case llvm::Triple::x86_64:
+      case llvm::Triple::arm:
+      case llvm::Triple::aarch64:
+      case llvm::Triple::ppc64le:
+      case llvm::Triple::mips:
+      case llvm::Triple::mipsel:
+      case llvm::Triple::mips64:
+      case llvm::Triple::mips64el:
+        // Supported.
+        break;
+      default:
+        D.Diag(diag::err_drv_clang_unsupported)
+            << (std::string(XRayInstrumentOption) + " on " + Triple.str());
+      }
+    else
+      D.Diag(diag::err_drv_clang_unsupported)
+          << (std::string(XRayInstrumentOption) + " on non-Linux target OS");
+    CmdArgs.push_back(XRayInstrumentOption);
+    if (const Arg *A =
+            Args.getLastArg(options::OPT_fxray_instruction_threshold_,
+                            options::OPT_fxray_instruction_threshold_EQ)) {
+      CmdArgs.push_back("-fxray-instruction-threshold");
+      CmdArgs.push_back(A->getValue());
+    }
+  }
+
+  addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
+
+  // Add runtime flag for PS4 when PGO or Coverage are enabled.
+  if (getToolChain().getTriple().isPS4CPU())
+    PS4cpu::addProfileRTArgs(getToolChain(), Args, CmdArgs);
+
+  // Pass options for controlling the default header search paths.
+  if (Args.hasArg(options::OPT_nostdinc)) {
+    CmdArgs.push_back("-nostdsysteminc");
+    CmdArgs.push_back("-nobuiltininc");
+  } else {
+    if (Args.hasArg(options::OPT_nostdlibinc))
+      CmdArgs.push_back("-nostdsysteminc");
+    Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
+    Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
+  }
+
+  // Pass the path to compiler resource files.
+  CmdArgs.push_back("-resource-dir");
+  CmdArgs.push_back(D.ResourceDir.c_str());
+
+  Args.AddLastArg(CmdArgs, options::OPT_working_directory);
+
+  bool ARCMTEnabled = false;
+  if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) {
+    if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
+                                       options::OPT_ccc_arcmt_modify,
+                                       options::OPT_ccc_arcmt_migrate)) {
+      ARCMTEnabled = true;
+      switch (A->getOption().getID()) {
+      default:
+        llvm_unreachable("missed a case");
+      case options::OPT_ccc_arcmt_check:
+        CmdArgs.push_back("-arcmt-check");
+        break;
+      case options::OPT_ccc_arcmt_modify:
+        CmdArgs.push_back("-arcmt-modify");
+        break;
+      case options::OPT_ccc_arcmt_migrate:
+        CmdArgs.push_back("-arcmt-migrate");
+        CmdArgs.push_back("-mt-migrate-directory");
+        CmdArgs.push_back(A->getValue());
+
+        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
+        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
+        break;
+      }
+    }
+  } else {
+    Args.ClaimAllArgs(options::OPT_ccc_arcmt_check);
+    Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify);
+    Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate);
+  }
+
+  if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
+    if (ARCMTEnabled) {
+      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
+                                                      << "-ccc-arcmt-migrate";
+    }
+    CmdArgs.push_back("-mt-migrate-directory");
+    CmdArgs.push_back(A->getValue());
+
+    if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
+                     options::OPT_objcmt_migrate_subscripting,
+                     options::OPT_objcmt_migrate_property)) {
+      // None specified, means enable them all.
+      CmdArgs.push_back("-objcmt-migrate-literals");
+      CmdArgs.push_back("-objcmt-migrate-subscripting");
+      CmdArgs.push_back("-objcmt-migrate-property");
+    } else {
+      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
+      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
+      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
+    }
+  } else {
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property_dot_syntax);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_designated_init);
+    Args.AddLastArg(CmdArgs, options::OPT_objcmt_whitelist_dir_path);
+  }
+
+  // Add preprocessing options like -I, -D, etc. if we are using the
+  // preprocessor.
+  //
+  // FIXME: Support -fpreprocessed
+  if (types::getPreprocessedType(InputType) != types::TY_INVALID)
+    AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
+
+  // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
+  // that "The compiler can only warn and ignore the option if not recognized".
+  // When building with ccache, it will pass -D options to clang even on
+  // preprocessed inputs and configure concludes that -fPIC is not supported.
+  Args.ClaimAllArgs(options::OPT_D);
+
+  // Manually translate -O4 to -O3; let clang reject others.
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O4)) {
+      CmdArgs.push_back("-O3");
+      D.Diag(diag::warn_O4_is_O3);
+    } else {
+      A->render(Args, CmdArgs);
+    }
+  }
+
+  // Warn about ignored options to clang.
+  for (const Arg *A :
+       Args.filtered(options::OPT_clang_ignored_gcc_optimization_f_Group)) {
+    D.Diag(diag::warn_ignored_gcc_optimization) << A->getAsString(Args);
+    A->claim();
+  }
+
+  claimNoWarnArgs(Args);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_R_Group);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
+  if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
+    CmdArgs.push_back("-pedantic");
+  Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
+  Args.AddLastArg(CmdArgs, options::OPT_w);
+
+  // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
+  // (-ansi is equivalent to -std=c89 or -std=c++98).
+  //
+  // If a std is supplied, only add -trigraphs if it follows the
+  // option.
+  bool ImplyVCPPCXXVer = false;
+  if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
+    if (Std->getOption().matches(options::OPT_ansi))
+      if (types::isCXX(InputType))
+        CmdArgs.push_back("-std=c++98");
+      else
+        CmdArgs.push_back("-std=c89");
+    else
+      Std->render(Args, CmdArgs);
+
+    // If -f(no-)trigraphs appears after the language standard flag, honor it.
+    if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
+                                 options::OPT_ftrigraphs,
+                                 options::OPT_fno_trigraphs))
+      if (A != Std)
+        A->render(Args, CmdArgs);
+  } else {
+    // Honor -std-default.
+    //
+    // FIXME: Clang doesn't correctly handle -std= when the input language
+    // doesn't match. For the time being just ignore this for C++ inputs;
+    // eventually we want to do all the standard defaulting here instead of
+    // splitting it between the driver and clang -cc1.
+    if (!types::isCXX(InputType))
+      Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, "-std=",
+                                /*Joined=*/true);
+    else if (IsWindowsMSVC)
+      ImplyVCPPCXXVer = true;
+
+    Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs,
+                    options::OPT_fno_trigraphs);
+  }
+
+  // GCC's behavior for -Wwrite-strings is a bit strange:
+  //  * In C, this "warning flag" changes the types of string literals from
+  //    'char[N]' to 'const char[N]', and thus triggers an unrelated warning
+  //    for the discarded qualifier.
+  //  * In C++, this is just a normal warning flag.
+  //
+  // Implementing this warning correctly in C is hard, so we follow GCC's
+  // behavior for now. FIXME: Directly diagnose uses of a string literal as
+  // a non-const char* in C, rather than using this crude hack.
+  if (!types::isCXX(InputType)) {
+    // FIXME: This should behave just like a warning flag, and thus should also
+    // respect -Weverything, -Wno-everything, -Werror=write-strings, and so on.
+    Arg *WriteStrings =
+        Args.getLastArg(options::OPT_Wwrite_strings,
+                        options::OPT_Wno_write_strings, options::OPT_w);
+    if (WriteStrings &&
+        WriteStrings->getOption().matches(options::OPT_Wwrite_strings))
+      CmdArgs.push_back("-fconst-strings");
+  }
+
+  // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
+  // during C++ compilation, which it is by default. GCC keeps this define even
+  // in the presence of '-w', match this behavior bug-for-bug.
+  if (types::isCXX(InputType) &&
+      Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
+                   true)) {
+    CmdArgs.push_back("-fdeprecated-macro");
+  }
+
+  // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
+  if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
+    if (Asm->getOption().matches(options::OPT_fasm))
+      CmdArgs.push_back("-fgnu-keywords");
+    else
+      CmdArgs.push_back("-fno-gnu-keywords");
+  }
+
+  if (ShouldDisableDwarfDirectory(Args, getToolChain()))
+    CmdArgs.push_back("-fno-dwarf-directory-asm");
+
+  if (ShouldDisableAutolink(Args, getToolChain()))
+    CmdArgs.push_back("-fno-autolink");
+
+  // Add in -fdebug-compilation-dir if necessary.
+  addDebugCompDirArg(Args, CmdArgs);
+
+  for (const Arg *A : Args.filtered(options::OPT_fdebug_prefix_map_EQ)) {
+    StringRef Map = A->getValue();
+    if (Map.find('=') == StringRef::npos)
+      D.Diag(diag::err_drv_invalid_argument_to_fdebug_prefix_map) << Map;
+    else
+      CmdArgs.push_back(Args.MakeArgString("-fdebug-prefix-map=" + Map));
+    A->claim();
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
+                               options::OPT_ftemplate_depth_EQ)) {
+    CmdArgs.push_back("-ftemplate-depth");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) {
+    CmdArgs.push_back("-foperator-arrow-depth");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
+    CmdArgs.push_back("-fconstexpr-depth");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_steps_EQ)) {
+    CmdArgs.push_back("-fconstexpr-steps");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
+    CmdArgs.push_back("-fbracket-depth");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
+                               options::OPT_Wlarge_by_value_copy_def)) {
+    if (A->getNumValues()) {
+      StringRef bytes = A->getValue();
+      CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
+    } else
+      CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
+  }
+
+  if (Args.hasArg(options::OPT_relocatable_pch))
+    CmdArgs.push_back("-relocatable-pch");
+
+  if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
+    CmdArgs.push_back("-fconstant-string-class");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
+    CmdArgs.push_back("-ftabstop");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  CmdArgs.push_back("-ferror-limit");
+  if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
+    CmdArgs.push_back(A->getValue());
+  else
+    CmdArgs.push_back("19");
+
+  if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
+    CmdArgs.push_back("-fmacro-backtrace-limit");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
+    CmdArgs.push_back("-ftemplate-backtrace-limit");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
+    CmdArgs.push_back("-fconstexpr-backtrace-limit");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_fspell_checking_limit_EQ)) {
+    CmdArgs.push_back("-fspell-checking-limit");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  // Pass -fmessage-length=.
+  CmdArgs.push_back("-fmessage-length");
+  if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
+    CmdArgs.push_back(A->getValue());
+  } else {
+    // If -fmessage-length=N was not specified, determine whether this is a
+    // terminal and, if so, implicitly define -fmessage-length appropriately.
+    unsigned N = llvm::sys::Process::StandardErrColumns();
+    CmdArgs.push_back(Args.MakeArgString(Twine(N)));
+  }
+
+  // -fvisibility= and -fvisibility-ms-compat are of a piece.
+  if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
+                                     options::OPT_fvisibility_ms_compat)) {
+    if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
+      CmdArgs.push_back("-fvisibility");
+      CmdArgs.push_back(A->getValue());
+    } else {
+      assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
+      CmdArgs.push_back("-fvisibility");
+      CmdArgs.push_back("hidden");
+      CmdArgs.push_back("-ftype-visibility");
+      CmdArgs.push_back("default");
+    }
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
+
+  Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
+
+  // -fhosted is default.
+  bool IsHosted = true;
+  if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
+      KernelOrKext) {
+    CmdArgs.push_back("-ffreestanding");
+    IsHosted = false;
+  }
+
+  // Forward -f (flag) options which we can pass directly.
+  Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
+  Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
+  Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
+  // Emulated TLS is enabled by default on Android, and can be enabled manually
+  // with -femulated-tls.
+  bool EmulatedTLSDefault = Triple.isAndroid() || Triple.isWindowsCygwinEnvironment();
+  if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
+                   EmulatedTLSDefault))
+    CmdArgs.push_back("-femulated-tls");
+  // AltiVec-like language extensions aren't relevant for assembling.
+  if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm) {
+    Args.AddLastArg(CmdArgs, options::OPT_faltivec);
+    Args.AddLastArg(CmdArgs, options::OPT_fzvector);
+  }
+  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
+  Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
+
+  // Forward flags for OpenMP. We don't do this if the current action is an
+  // device offloading action other than OpenMP.
+  if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
+                   options::OPT_fno_openmp, false) &&
+      (JA.isDeviceOffloading(Action::OFK_None) ||
+       JA.isDeviceOffloading(Action::OFK_OpenMP))) {
+    switch (getToolChain().getDriver().getOpenMPRuntime(Args)) {
+    case Driver::OMPRT_OMP:
+    case Driver::OMPRT_IOMP5:
+      // Clang can generate useful OpenMP code for these two runtime libraries.
+      CmdArgs.push_back("-fopenmp");
+
+      // If no option regarding the use of TLS in OpenMP codegeneration is
+      // given, decide a default based on the target. Otherwise rely on the
+      // options and pass the right information to the frontend.
+      if (!Args.hasFlag(options::OPT_fopenmp_use_tls,
+                        options::OPT_fnoopenmp_use_tls, /*Default=*/true))
+        CmdArgs.push_back("-fnoopenmp-use-tls");
+      Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
+      break;
+    default:
+      // By default, if Clang doesn't know how to generate useful OpenMP code
+      // for a specific runtime library, we just don't pass the '-fopenmp' flag
+      // down to the actual compilation.
+      // FIXME: It would be better to have a mode which *only* omits IR
+      // generation based on the OpenMP support so that we get consistent
+      // semantic analysis, etc.
+      break;
+    }
+  }
+
+  const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
+  Sanitize.addArgs(getToolChain(), Args, CmdArgs, InputType);
+
+  // Report an error for -faltivec on anything other than PowerPC.
+  if (const Arg *A = Args.getLastArg(options::OPT_faltivec)) {
+    const llvm::Triple::ArchType Arch = getToolChain().getArch();
+    if (!(Arch == llvm::Triple::ppc || Arch == llvm::Triple::ppc64 ||
+          Arch == llvm::Triple::ppc64le))
+      D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
+                                                       << "ppc/ppc64/ppc64le";
+  }
+
+  // -fzvector is incompatible with -faltivec.
+  if (Arg *A = Args.getLastArg(options::OPT_fzvector))
+    if (Args.hasArg(options::OPT_faltivec))
+      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
+                                                      << "-faltivec";
+
+  if (getToolChain().SupportsProfiling())
+    Args.AddLastArg(CmdArgs, options::OPT_pg);
+
+  if (getToolChain().SupportsProfiling())
+    Args.AddLastArg(CmdArgs, options::OPT_mfentry);
+
+  // -flax-vector-conversions is default.
+  if (!Args.hasFlag(options::OPT_flax_vector_conversions,
+                    options::OPT_fno_lax_vector_conversions))
+    CmdArgs.push_back("-fno-lax-vector-conversions");
+
+  if (Args.getLastArg(options::OPT_fapple_kext) ||
+      (Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType)))
+    CmdArgs.push_back("-fapple-kext");
+
+  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);
+  Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
+  Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
+
+  if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
+    CmdArgs.push_back("-ftrapv-handler");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
+
+  // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
+  // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
+  if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
+    if (A->getOption().matches(options::OPT_fwrapv))
+      CmdArgs.push_back("-fwrapv");
+  } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
+                                      options::OPT_fno_strict_overflow)) {
+    if (A->getOption().matches(options::OPT_fno_strict_overflow))
+      CmdArgs.push_back("-fwrapv");
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
+                               options::OPT_fno_reroll_loops))
+    if (A->getOption().matches(options::OPT_freroll_loops))
+      CmdArgs.push_back("-freroll-loops");
+
+  Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
+  Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
+                  options::OPT_fno_unroll_loops);
+
+  Args.AddLastArg(CmdArgs, options::OPT_pthread);
+
+  // -stack-protector=0 is default.
+  unsigned StackProtectorLevel = 0;
+  // NVPTX doesn't support stack protectors; from the compiler's perspective, it
+  // doesn't even have a stack!
+  if (!Triple.isNVPTX()) {
+    if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
+                                 options::OPT_fstack_protector_all,
+                                 options::OPT_fstack_protector_strong,
+                                 options::OPT_fstack_protector)) {
+      if (A->getOption().matches(options::OPT_fstack_protector)) {
+        StackProtectorLevel = std::max<unsigned>(
+            LangOptions::SSPOn,
+            getToolChain().GetDefaultStackProtectorLevel(KernelOrKext));
+      } else if (A->getOption().matches(options::OPT_fstack_protector_strong))
+        StackProtectorLevel = LangOptions::SSPStrong;
+      else if (A->getOption().matches(options::OPT_fstack_protector_all))
+        StackProtectorLevel = LangOptions::SSPReq;
+    } else {
+      StackProtectorLevel =
+          getToolChain().GetDefaultStackProtectorLevel(KernelOrKext);
+      // Only use a default stack protector on Darwin in case -ffreestanding
+      // is not specified.
+      if (Triple.isOSDarwin() && !IsHosted)
+        StackProtectorLevel = 0;
+    }
+  }
+  if (StackProtectorLevel) {
+    CmdArgs.push_back("-stack-protector");
+    CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
+  }
+
+  // --param ssp-buffer-size=
+  for (const Arg *A : Args.filtered(options::OPT__param)) {
+    StringRef Str(A->getValue());
+    if (Str.startswith("ssp-buffer-size=")) {
+      if (StackProtectorLevel) {
+        CmdArgs.push_back("-stack-protector-buffer-size");
+        // FIXME: Verify the argument is a valid integer.
+        CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
+      }
+      A->claim();
+    }
+  }
+
+  // Translate -mstackrealign
+  if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
+                   false))
+    CmdArgs.push_back(Args.MakeArgString("-mstackrealign"));
+
+  if (Args.hasArg(options::OPT_mstack_alignment)) {
+    StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
+    CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
+  }
+
+  if (Args.hasArg(options::OPT_mstack_probe_size)) {
+    StringRef Size = Args.getLastArgValue(options::OPT_mstack_probe_size);
+
+    if (!Size.empty())
+      CmdArgs.push_back(Args.MakeArgString("-mstack-probe-size=" + Size));
+    else
+      CmdArgs.push_back("-mstack-probe-size=0");
+  }
+
+  switch (getToolChain().getArch()) {
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
+    CmdArgs.push_back("-fallow-half-arguments-and-returns");
+    break;
+
+  default:
+    break;
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,
+                               options::OPT_mno_restrict_it)) {
+    if (A->getOption().matches(options::OPT_mrestrict_it)) {
+      CmdArgs.push_back("-backend-option");
+      CmdArgs.push_back("-arm-restrict-it");
+    } else {
+      CmdArgs.push_back("-backend-option");
+      CmdArgs.push_back("-arm-no-restrict-it");
+    }
+  } else if (Triple.isOSWindows() &&
+             (Triple.getArch() == llvm::Triple::arm ||
+              Triple.getArch() == llvm::Triple::thumb)) {
+    // Windows on ARM expects restricted IT blocks
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-arm-restrict-it");
+  }
+
+  // Forward -cl options to -cc1
+  if (Args.getLastArg(options::OPT_cl_opt_disable)) {
+    CmdArgs.push_back("-cl-opt-disable");
+  }
+  if (Args.getLastArg(options::OPT_cl_strict_aliasing)) {
+    CmdArgs.push_back("-cl-strict-aliasing");
+  }
+  if (Args.getLastArg(options::OPT_cl_single_precision_constant)) {
+    CmdArgs.push_back("-cl-single-precision-constant");
+  }
+  if (Args.getLastArg(options::OPT_cl_finite_math_only)) {
+    CmdArgs.push_back("-cl-finite-math-only");
+  }
+  if (Args.getLastArg(options::OPT_cl_kernel_arg_info)) {
+    CmdArgs.push_back("-cl-kernel-arg-info");
+  }
+  if (Args.getLastArg(options::OPT_cl_unsafe_math_optimizations)) {
+    CmdArgs.push_back("-cl-unsafe-math-optimizations");
+  }
+  if (Args.getLastArg(options::OPT_cl_fast_relaxed_math)) {
+    CmdArgs.push_back("-cl-fast-relaxed-math");
+  }
+  if (Args.getLastArg(options::OPT_cl_mad_enable)) {
+    CmdArgs.push_back("-cl-mad-enable");
+  }
+  if (Args.getLastArg(options::OPT_cl_no_signed_zeros)) {
+    CmdArgs.push_back("-cl-no-signed-zeros");
+  }
+  if (Arg *A = Args.getLastArg(options::OPT_cl_std_EQ)) {
+    std::string CLStdStr = "-cl-std=";
+    CLStdStr += A->getValue();
+    CmdArgs.push_back(Args.MakeArgString(CLStdStr));
+  }
+  if (Args.getLastArg(options::OPT_cl_denorms_are_zero)) {
+    CmdArgs.push_back("-cl-denorms-are-zero");
+  }
+  if (Args.getLastArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt)) {
+    CmdArgs.push_back("-cl-fp32-correctly-rounded-divide-sqrt");
+  }
+
+  // Forward -f options with positive and negative forms; we translate
+  // these by hand.
+  if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
+    StringRef fname = A->getValue();
+    if (!llvm::sys::fs::exists(fname))
+      D.Diag(diag::err_drv_no_such_file) << fname;
+    else
+      A->render(Args, CmdArgs);
+  }
+
+  if (Args.hasFlag(options::OPT_fdebug_info_for_profiling,
+                   options::OPT_fno_debug_info_for_profiling, false))
+    CmdArgs.push_back("-fdebug-info-for-profiling");
+
+  // -fbuiltin is default unless -mkernel is used.
+  bool UseBuiltins =
+      Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin,
+                   !Args.hasArg(options::OPT_mkernel));
+  if (!UseBuiltins)
+    CmdArgs.push_back("-fno-builtin");
+
+  // -ffreestanding implies -fno-builtin.
+  if (Args.hasArg(options::OPT_ffreestanding))
+    UseBuiltins = false;
+
+  // Process the -fno-builtin-* options.
+  for (const auto &Arg : Args) {
+    const Option &O = Arg->getOption();
+    if (!O.matches(options::OPT_fno_builtin_))
+      continue;
+
+    Arg->claim();
+    // If -fno-builtin is specified, then there's no need to pass the option to
+    // the frontend.
+    if (!UseBuiltins)
+      continue;
+
+    StringRef FuncName = Arg->getValue();
+    CmdArgs.push_back(Args.MakeArgString("-fno-builtin-" + FuncName));
+  }
+
+  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
+                    options::OPT_fno_assume_sane_operator_new))
+    CmdArgs.push_back("-fno-assume-sane-operator-new");
+
+  // -fblocks=0 is default.
+  if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
+                   getToolChain().IsBlocksDefault()) ||
+      (Args.hasArg(options::OPT_fgnu_runtime) &&
+       Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
+       !Args.hasArg(options::OPT_fno_blocks))) {
+    CmdArgs.push_back("-fblocks");
+
+    if (!Args.hasArg(options::OPT_fgnu_runtime) &&
+        !getToolChain().hasBlocksRuntime())
+      CmdArgs.push_back("-fblocks-runtime-optional");
+  }
+
+  if (Args.hasFlag(options::OPT_fcoroutines_ts, options::OPT_fno_coroutines_ts,
+                   false) &&
+      types::isCXX(InputType)) {
+    CmdArgs.push_back("-fcoroutines-ts");
+  }
+
+  // -fmodules enables the use of precompiled modules (off by default).
+  // Users can pass -fno-cxx-modules to turn off modules support for
+  // C++/Objective-C++ programs.
+  bool HaveClangModules = false;
+  if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
+    bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
+                                     options::OPT_fno_cxx_modules, true);
+    if (AllowedInCXX || !types::isCXX(InputType)) {
+      CmdArgs.push_back("-fmodules");
+      HaveClangModules = true;
+    }
+  }
+
+  bool HaveAnyModules = HaveClangModules;
+  if (Args.hasArg(options::OPT_fmodules_ts)) {
+    CmdArgs.push_back("-fmodules-ts");
+    HaveAnyModules = true;
+  }
+
+  // -fmodule-maps enables implicit reading of module map files. By default,
+  // this is enabled if we are using Clang's flavor of precompiled modules.
+  if (Args.hasFlag(options::OPT_fimplicit_module_maps,
+                   options::OPT_fno_implicit_module_maps, HaveClangModules)) {
+    CmdArgs.push_back("-fimplicit-module-maps");
+  }
+
+  // -fmodules-decluse checks that modules used are declared so (off by
+  // default).
+  if (Args.hasFlag(options::OPT_fmodules_decluse,
+                   options::OPT_fno_modules_decluse, false)) {
+    CmdArgs.push_back("-fmodules-decluse");
+  }
+
+  // -fmodules-strict-decluse is like -fmodule-decluse, but also checks that
+  // all #included headers are part of modules.
+  if (Args.hasFlag(options::OPT_fmodules_strict_decluse,
+                   options::OPT_fno_modules_strict_decluse, false)) {
+    CmdArgs.push_back("-fmodules-strict-decluse");
+  }
+
+  // -fno-implicit-modules turns off implicitly compiling modules on demand.
+  if (!Args.hasFlag(options::OPT_fimplicit_modules,
+                    options::OPT_fno_implicit_modules, HaveClangModules)) {
+    if (HaveAnyModules)
+      CmdArgs.push_back("-fno-implicit-modules");
+  } else if (HaveAnyModules) {
+    // -fmodule-cache-path specifies where our implicitly-built module files
+    // should be written.
+    SmallString<128> Path;
+    if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
+      Path = A->getValue();
+    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.
+      Path = Output.getFilename();
+      llvm::sys::path::replace_extension(Path, ".cache");
+      llvm::sys::path::append(Path, "modules");
+    } else if (Path.empty()) {
+      // No module path was provided: use the default.
+      llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);
+      llvm::sys::path::append(Path, "org.llvm.clang.");
+      appendUserToPath(Path);
+      llvm::sys::path::append(Path, "ModuleCache");
+    }
+    const char Arg[] = "-fmodules-cache-path=";
+    Path.insert(Path.begin(), Arg, Arg + strlen(Arg));
+    CmdArgs.push_back(Args.MakeArgString(Path));
+  }
+
+  if (HaveAnyModules) {
+    // -fprebuilt-module-path specifies where to load the prebuilt module files.
+    for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path))
+      CmdArgs.push_back(Args.MakeArgString(
+          std::string("-fprebuilt-module-path=") + A->getValue()));
+  }
+
+  // -fmodule-name specifies the module that is currently being built (or
+  // used for header checking by -fmodule-maps).
+  Args.AddLastArg(CmdArgs, options::OPT_fmodule_name_EQ);
+
+  // -fmodule-map-file can be used to specify files containing module
+  // definitions.
+  Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
+
+  // -fbuiltin-module-map can be used to load the clang
+  // builtin headers modulemap file.
+  if (Args.hasArg(options::OPT_fbuiltin_module_map)) {
+    SmallString<128> BuiltinModuleMap(getToolChain().getDriver().ResourceDir);
+    llvm::sys::path::append(BuiltinModuleMap, "include");
+    llvm::sys::path::append(BuiltinModuleMap, "module.modulemap");
+    if (llvm::sys::fs::exists(BuiltinModuleMap)) {
+      CmdArgs.push_back(Args.MakeArgString("-fmodule-map-file=" +
+                                           BuiltinModuleMap));
+    }
+  }
+
+  // -fmodule-file can be used to specify files containing precompiled modules.
+  if (HaveAnyModules)
+    Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
+  else
+    Args.ClaimAllArgs(options::OPT_fmodule_file);
+
+  // When building modules and generating crashdumps, we need to dump a module
+  // dependency VFS alongside the output.
+  if (HaveClangModules && C.isForDiagnostics()) {
+    SmallString<128> VFSDir(Output.getFilename());
+    llvm::sys::path::replace_extension(VFSDir, ".cache");
+    // Add the cache directory as a temp so the crash diagnostics pick it up.
+    C.addTempFile(Args.MakeArgString(VFSDir));
+
+    llvm::sys::path::append(VFSDir, "vfs");
+    CmdArgs.push_back("-module-dependency-dir");
+    CmdArgs.push_back(Args.MakeArgString(VFSDir));
+  }
+
+  if (HaveClangModules)
+    Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
+
+  // Pass through all -fmodules-ignore-macro arguments.
+  Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
+  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
+  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
+
+  Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
+
+  if (Arg *A = Args.getLastArg(options::OPT_fbuild_session_file)) {
+    if (Args.hasArg(options::OPT_fbuild_session_timestamp))
+      D.Diag(diag::err_drv_argument_not_allowed_with)
+          << A->getAsString(Args) << "-fbuild-session-timestamp";
+
+    llvm::sys::fs::file_status Status;
+    if (llvm::sys::fs::status(A->getValue(), Status))
+      D.Diag(diag::err_drv_no_such_file) << A->getValue();
+    CmdArgs.push_back(
+        Args.MakeArgString("-fbuild-session-timestamp=" +
+                           Twine((uint64_t)Status.getLastModificationTime()
+                                     .time_since_epoch()
+                                     .count())));
+  }
+
+  if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {
+    if (!Args.getLastArg(options::OPT_fbuild_session_timestamp,
+                         options::OPT_fbuild_session_file))
+      D.Diag(diag::err_drv_modules_validate_once_requires_timestamp);
+
+    Args.AddLastArg(CmdArgs,
+                    options::OPT_fmodules_validate_once_per_build_session);
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_fmodules_validate_system_headers);
+  Args.AddLastArg(CmdArgs, options::OPT_fmodules_disable_diagnostic_validation);
+
+  // -faccess-control is default.
+  if (Args.hasFlag(options::OPT_fno_access_control,
+                   options::OPT_faccess_control, false))
+    CmdArgs.push_back("-fno-access-control");
+
+  // -felide-constructors is the default.
+  if (Args.hasFlag(options::OPT_fno_elide_constructors,
+                   options::OPT_felide_constructors, false))
+    CmdArgs.push_back("-fno-elide-constructors");
+
+  ToolChain::RTTIMode RTTIMode = getToolChain().getRTTIMode();
+
+  if (KernelOrKext || (types::isCXX(InputType) &&
+                       (RTTIMode == ToolChain::RM_DisabledExplicitly ||
+                        RTTIMode == ToolChain::RM_DisabledImplicitly)))
+    CmdArgs.push_back("-fno-rtti");
+
+  // -fshort-enums=0 is default for all architectures except Hexagon.
+  if (Args.hasFlag(options::OPT_fshort_enums, options::OPT_fno_short_enums,
+                   getToolChain().getArch() == llvm::Triple::hexagon))
+    CmdArgs.push_back("-fshort-enums");
+
+  // -fsigned-char is default.
+  if (Arg *A = Args.getLastArg(
+          options::OPT_fsigned_char, options::OPT_fno_signed_char,
+          options::OPT_funsigned_char, options::OPT_fno_unsigned_char)) {
+    if (A->getOption().matches(options::OPT_funsigned_char) ||
+        A->getOption().matches(options::OPT_fno_signed_char)) {
+      CmdArgs.push_back("-fno-signed-char");
+    }
+  } else if (!isSignedCharDefault(getToolChain().getTriple())) {
+    CmdArgs.push_back("-fno-signed-char");
+  }
+
+  // -fuse-cxa-atexit is default.
+  if (!Args.hasFlag(
+          options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
+          !IsWindowsCygnus && !IsWindowsGNU &&
+              getToolChain().getTriple().getOS() != llvm::Triple::Solaris &&
+              getToolChain().getArch() != llvm::Triple::hexagon &&
+              getToolChain().getArch() != llvm::Triple::xcore &&
+              ((getToolChain().getTriple().getVendor() !=
+                llvm::Triple::MipsTechnologies) ||
+               getToolChain().getTriple().hasEnvironment())) ||
+      KernelOrKext)
+    CmdArgs.push_back("-fno-use-cxa-atexit");
+
+  // -fms-extensions=0 is default.
+  if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
+                   IsWindowsMSVC))
+    CmdArgs.push_back("-fms-extensions");
+
+  // -fno-use-line-directives is default.
+  if (Args.hasFlag(options::OPT_fuse_line_directives,
+                   options::OPT_fno_use_line_directives, false))
+    CmdArgs.push_back("-fuse-line-directives");
+
+  // -fms-compatibility=0 is default.
+  if (Args.hasFlag(options::OPT_fms_compatibility,
+                   options::OPT_fno_ms_compatibility,
+                   (IsWindowsMSVC &&
+                    Args.hasFlag(options::OPT_fms_extensions,
+                                 options::OPT_fno_ms_extensions, true))))
+    CmdArgs.push_back("-fms-compatibility");
+
+  VersionTuple MSVT =
+      getToolChain().computeMSVCVersion(&getToolChain().getDriver(), Args);
+  if (!MSVT.empty())
+    CmdArgs.push_back(
+        Args.MakeArgString("-fms-compatibility-version=" + MSVT.getAsString()));
+
+  bool IsMSVC2015Compatible = MSVT.getMajor() >= 19;
+  if (ImplyVCPPCXXVer) {
+    StringRef LanguageStandard;
+    if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) {
+      LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue())
+                             .Case("c++14", "-std=c++14")
+                             .Case("c++latest", "-std=c++1z")
+                             .Default("");
+      if (LanguageStandard.empty())
+        D.Diag(clang::diag::warn_drv_unused_argument)
+            << StdArg->getAsString(Args);
+    }
+
+    if (LanguageStandard.empty()) {
+      if (IsMSVC2015Compatible)
+        LanguageStandard = "-std=c++14";
+      else
+        LanguageStandard = "-std=c++11";
+    }
+
+    CmdArgs.push_back(LanguageStandard.data());
+  }
+
+  // -fno-borland-extensions is default.
+  if (Args.hasFlag(options::OPT_fborland_extensions,
+                   options::OPT_fno_borland_extensions, false))
+    CmdArgs.push_back("-fborland-extensions");
+
+  // -fno-declspec is default, except for PS4.
+  if (Args.hasFlag(options::OPT_fdeclspec, options::OPT_fno_declspec,
+                   getToolChain().getTriple().isPS4()))
+    CmdArgs.push_back("-fdeclspec");
+  else if (Args.hasArg(options::OPT_fno_declspec))
+    CmdArgs.push_back("-fno-declspec"); // Explicitly disabling __declspec.
+
+  // -fthreadsafe-static is default, except for MSVC compatibility versions less
+  // than 19.
+  if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
+                    options::OPT_fno_threadsafe_statics,
+                    !IsWindowsMSVC || IsMSVC2015Compatible))
+    CmdArgs.push_back("-fno-threadsafe-statics");
+
+  // -fno-delayed-template-parsing is default, except for Windows where MSVC STL
+  // needs it.
+  if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
+                   options::OPT_fno_delayed_template_parsing, IsWindowsMSVC))
+    CmdArgs.push_back("-fdelayed-template-parsing");
+
+  // -fgnu-keywords default varies depending on language; only pass if
+  // specified.
+  if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
+                               options::OPT_fno_gnu_keywords))
+    A->render(Args, CmdArgs);
+
+  if (Args.hasFlag(options::OPT_fgnu89_inline, options::OPT_fno_gnu89_inline,
+                   false))
+    CmdArgs.push_back("-fgnu89-inline");
+
+  if (Args.hasArg(options::OPT_fno_inline))
+    CmdArgs.push_back("-fno-inline");
+
+  if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions,
+                                       options::OPT_finline_hint_functions,
+                                       options::OPT_fno_inline_functions))
+    InlineArg->render(Args, CmdArgs);
+
+  Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager,
+                  options::OPT_fno_experimental_new_pass_manager);
+
+  ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
+
+  // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
+  // legacy is the default. Except for deployment target of 10.5,
+  // next runtime is always legacy dispatch and -fno-objc-legacy-dispatch
+  // gets ignored silently.
+  if (objcRuntime.isNonFragile()) {
+    if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
+                      options::OPT_fno_objc_legacy_dispatch,
+                      objcRuntime.isLegacyDispatchDefaultForArch(
+                          getToolChain().getArch()))) {
+      if (getToolChain().UseObjCMixedDispatch())
+        CmdArgs.push_back("-fobjc-dispatch-method=mixed");
+      else
+        CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
+    }
+  }
+
+  // When ObjectiveC legacy runtime is in effect on MacOSX,
+  // turn on the option to do Array/Dictionary subscripting
+  // by default.
+  if (getToolChain().getArch() == llvm::Triple::x86 &&
+      getToolChain().getTriple().isMacOSX() &&
+      !getToolChain().getTriple().isMacOSXVersionLT(10, 7) &&
+      objcRuntime.getKind() == ObjCRuntime::FragileMacOSX &&
+      objcRuntime.isNeXTFamily())
+    CmdArgs.push_back("-fobjc-subscripting-legacy-runtime");
+
+  // -fencode-extended-block-signature=1 is default.
+  if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) {
+    CmdArgs.push_back("-fencode-extended-block-signature");
+  }
+
+  // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
+  // NOTE: This logic is duplicated in ToolChains.cpp.
+  bool ARC = isObjCAutoRefCount(Args);
+  if (ARC) {
+    getToolChain().CheckObjCARC();
+
+    CmdArgs.push_back("-fobjc-arc");
+
+    // FIXME: It seems like this entire block, and several around it should be
+    // wrapped in isObjC, but for now we just use it here as this is where it
+    // was being used previously.
+    if (types::isCXX(InputType) && types::isObjC(InputType)) {
+      if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
+        CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
+      else
+        CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
+    }
+
+    // Allow the user to enable full exceptions code emission.
+    // We define off for Objective-CC, on for Objective-C++.
+    if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
+                     options::OPT_fno_objc_arc_exceptions,
+                     /*default*/ types::isCXX(InputType)))
+      CmdArgs.push_back("-fobjc-arc-exceptions");
+  }
+
+  // Silence warning for full exception code emission options when explicitly
+  // set to use no ARC.
+  if (Args.hasArg(options::OPT_fno_objc_arc)) {
+    Args.ClaimAllArgs(options::OPT_fobjc_arc_exceptions);
+    Args.ClaimAllArgs(options::OPT_fno_objc_arc_exceptions);
+  }
+
+  // -fobjc-infer-related-result-type is the default, except in the Objective-C
+  // rewriter.
+  if (rewriteKind != RK_None)
+    CmdArgs.push_back("-fno-objc-infer-related-result-type");
+
+  // Pass down -fobjc-weak or -fno-objc-weak if present.
+  if (types::isObjC(InputType)) {
+    auto WeakArg = Args.getLastArg(options::OPT_fobjc_weak,
+                                   options::OPT_fno_objc_weak);
+    if (!WeakArg) {
+      // nothing to do
+    } else if (!objcRuntime.allowsWeak()) {
+      if (WeakArg->getOption().matches(options::OPT_fobjc_weak))
+        D.Diag(diag::err_objc_weak_unsupported);
+    } else {
+      WeakArg->render(Args, CmdArgs);
+    }
+  }
+
+  if (Args.hasFlag(options::OPT_fapplication_extension,
+                   options::OPT_fno_application_extension, false))
+    CmdArgs.push_back("-fapplication-extension");
+
+  // Handle GCC-style exception args.
+  if (!C.getDriver().IsCLMode())
+    addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext, objcRuntime,
+                     CmdArgs);
+
+  if (Args.hasArg(options::OPT_fsjlj_exceptions) ||
+      getToolChain().UseSjLjExceptions(Args))
+    CmdArgs.push_back("-fsjlj-exceptions");
+
+  // C++ "sane" operator new.
+  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
+                    options::OPT_fno_assume_sane_operator_new))
+    CmdArgs.push_back("-fno-assume-sane-operator-new");
+
+  // -frelaxed-template-template-args is off by default, as it is a severe
+  // breaking change until a corresponding change to template partial ordering
+  // is provided.
+  if (Args.hasFlag(options::OPT_frelaxed_template_template_args,
+                   options::OPT_fno_relaxed_template_template_args, false))
+    CmdArgs.push_back("-frelaxed-template-template-args");
+
+  // -fsized-deallocation is off by default, as it is an ABI-breaking change for
+  // most platforms.
+  if (Args.hasFlag(options::OPT_fsized_deallocation,
+                   options::OPT_fno_sized_deallocation, false))
+    CmdArgs.push_back("-fsized-deallocation");
+
+  // -faligned-allocation is on by default in C++17 onwards and otherwise off
+  // by default.
+  if (Arg *A = Args.getLastArg(options::OPT_faligned_allocation,
+                               options::OPT_fno_aligned_allocation,
+                               options::OPT_faligned_new_EQ)) {
+    if (A->getOption().matches(options::OPT_fno_aligned_allocation))
+      CmdArgs.push_back("-fno-aligned-allocation");
+    else
+      CmdArgs.push_back("-faligned-allocation");
+  }
+
+  // The default new alignment can be specified using a dedicated option or via
+  // a GCC-compatible option that also turns on aligned allocation.
+  if (Arg *A = Args.getLastArg(options::OPT_fnew_alignment_EQ,
+                               options::OPT_faligned_new_EQ))
+    CmdArgs.push_back(
+        Args.MakeArgString(Twine("-fnew-alignment=") + A->getValue()));
+
+  // -fconstant-cfstrings is default, and may be subject to argument translation
+  // on Darwin.
+  if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
+                    options::OPT_fno_constant_cfstrings) ||
+      !Args.hasFlag(options::OPT_mconstant_cfstrings,
+                    options::OPT_mno_constant_cfstrings))
+    CmdArgs.push_back("-fno-constant-cfstrings");
+
+  // -fshort-wchar default varies depending on platform; only
+  // pass if specified.
+  if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
+                               options::OPT_fno_short_wchar))
+    A->render(Args, CmdArgs);
+
+  // -fno-pascal-strings is default, only pass non-default.
+  if (Args.hasFlag(options::OPT_fpascal_strings,
+                   options::OPT_fno_pascal_strings, false))
+    CmdArgs.push_back("-fpascal-strings");
+
+  // Honor -fpack-struct= and -fpack-struct, if given. Note that
+  // -fno-pack-struct doesn't apply to -fpack-struct=.
+  if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
+    std::string PackStructStr = "-fpack-struct=";
+    PackStructStr += A->getValue();
+    CmdArgs.push_back(Args.MakeArgString(PackStructStr));
+  } else if (Args.hasFlag(options::OPT_fpack_struct,
+                          options::OPT_fno_pack_struct, false)) {
+    CmdArgs.push_back("-fpack-struct=1");
+  }
+
+  // Handle -fmax-type-align=N and -fno-type-align
+  bool SkipMaxTypeAlign = Args.hasArg(options::OPT_fno_max_type_align);
+  if (Arg *A = Args.getLastArg(options::OPT_fmax_type_align_EQ)) {
+    if (!SkipMaxTypeAlign) {
+      std::string MaxTypeAlignStr = "-fmax-type-align=";
+      MaxTypeAlignStr += A->getValue();
+      CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
+    }
+  } else if (getToolChain().getTriple().isOSDarwin()) {
+    if (!SkipMaxTypeAlign) {
+      std::string MaxTypeAlignStr = "-fmax-type-align=16";
+      CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
+    }
+  }
+
+  // -fcommon is the default unless compiling kernel code or the target says so
+  bool NoCommonDefault =
+      KernelOrKext || isNoCommonDefault(getToolChain().getTriple());
+  if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common,
+                    !NoCommonDefault))
+    CmdArgs.push_back("-fno-common");
+
+  // -fsigned-bitfields is default, and clang doesn't yet support
+  // -funsigned-bitfields.
+  if (!Args.hasFlag(options::OPT_fsigned_bitfields,
+                    options::OPT_funsigned_bitfields))
+    D.Diag(diag::warn_drv_clang_unsupported)
+        << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
+
+  // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
+  if (!Args.hasFlag(options::OPT_ffor_scope, options::OPT_fno_for_scope))
+    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.equals_lower("utf-8"))
+      D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args)
+                                          << value;
+  }
+
+  // -fexec_charset=UTF-8 is default. Reject others
+  if (Arg *execCharset = Args.getLastArg(options::OPT_fexec_charset_EQ)) {
+    StringRef value = execCharset->getValue();
+    if (!value.equals_lower("utf-8"))
+      D.Diag(diag::err_drv_invalid_value) << execCharset->getAsString(Args)
+                                          << value;
+  }
+
+  // -fcaret-diagnostics is default.
+  if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
+                    options::OPT_fno_caret_diagnostics, true))
+    CmdArgs.push_back("-fno-caret-diagnostics");
+
+  // -fdiagnostics-fixit-info is default, only pass non-default.
+  if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
+                    options::OPT_fno_diagnostics_fixit_info))
+    CmdArgs.push_back("-fno-diagnostics-fixit-info");
+
+  // Enable -fdiagnostics-show-option by default.
+  if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
+                   options::OPT_fno_diagnostics_show_option))
+    CmdArgs.push_back("-fdiagnostics-show-option");
+
+  if (const Arg *A =
+          Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
+    CmdArgs.push_back("-fdiagnostics-show-category");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness,
+                   options::OPT_fno_diagnostics_show_hotness, false))
+    CmdArgs.push_back("-fdiagnostics-show-hotness");
+
+  if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
+    CmdArgs.push_back("-fdiagnostics-format");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  if (Arg *A = Args.getLastArg(
+          options::OPT_fdiagnostics_show_note_include_stack,
+          options::OPT_fno_diagnostics_show_note_include_stack)) {
+    if (A->getOption().matches(
+            options::OPT_fdiagnostics_show_note_include_stack))
+      CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
+    else
+      CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
+  }
+
+  // Color diagnostics are parsed by the driver directly from argv
+  // and later re-parsed to construct this job; claim any possible
+  // color diagnostic here to avoid warn_drv_unused_argument and
+  // diagnose bad OPT_fdiagnostics_color_EQ values.
+  for (Arg *A : Args) {
+    const Option &O = A->getOption();
+    if (!O.matches(options::OPT_fcolor_diagnostics) &&
+        !O.matches(options::OPT_fdiagnostics_color) &&
+        !O.matches(options::OPT_fno_color_diagnostics) &&
+        !O.matches(options::OPT_fno_diagnostics_color) &&
+        !O.matches(options::OPT_fdiagnostics_color_EQ))
+      continue;
+    if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
+      StringRef Value(A->getValue());
+      if (Value != "always" && Value != "never" && Value != "auto")
+        getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
+              << ("-fdiagnostics-color=" + Value).str();
+    }
+    A->claim();
+  }
+  if (D.getDiags().getDiagnosticOptions().ShowColors)
+    CmdArgs.push_back("-fcolor-diagnostics");
+
+  if (Args.hasArg(options::OPT_fansi_escape_codes))
+    CmdArgs.push_back("-fansi-escape-codes");
+
+  if (!Args.hasFlag(options::OPT_fshow_source_location,
+                    options::OPT_fno_show_source_location))
+    CmdArgs.push_back("-fno-show-source-location");
+
+  if (Args.hasArg(options::OPT_fdiagnostics_absolute_paths))
+    CmdArgs.push_back("-fdiagnostics-absolute-paths");
+
+  if (!Args.hasFlag(options::OPT_fshow_column, options::OPT_fno_show_column,
+                    true))
+    CmdArgs.push_back("-fno-show-column");
+
+  if (!Args.hasFlag(options::OPT_fspell_checking,
+                    options::OPT_fno_spell_checking))
+    CmdArgs.push_back("-fno-spell-checking");
+
+  // -fno-asm-blocks is default.
+  if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
+                   false))
+    CmdArgs.push_back("-fasm-blocks");
+
+  // -fgnu-inline-asm is default.
+  if (!Args.hasFlag(options::OPT_fgnu_inline_asm,
+                    options::OPT_fno_gnu_inline_asm, true))
+    CmdArgs.push_back("-fno-gnu-inline-asm");
+
+  // Enable vectorization per default according to the optimization level
+  // selected. For optimization levels that want vectorization we use the alias
+  // option to simplify the hasFlag logic.
+  bool EnableVec = shouldEnableVectorizerAtOLevel(Args, false);
+  OptSpecifier VectorizeAliasOption =
+      EnableVec ? options::OPT_O_Group : options::OPT_fvectorize;
+  if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption,
+                   options::OPT_fno_vectorize, EnableVec))
+    CmdArgs.push_back("-vectorize-loops");
+
+  // -fslp-vectorize is enabled based on the optimization level selected.
+  bool EnableSLPVec = shouldEnableVectorizerAtOLevel(Args, true);
+  OptSpecifier SLPVectAliasOption =
+      EnableSLPVec ? options::OPT_O_Group : options::OPT_fslp_vectorize;
+  if (Args.hasFlag(options::OPT_fslp_vectorize, SLPVectAliasOption,
+                   options::OPT_fno_slp_vectorize, EnableSLPVec))
+    CmdArgs.push_back("-vectorize-slp");
+
+  // -fno-slp-vectorize-aggressive is default.
+  if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive,
+                   options::OPT_fno_slp_vectorize_aggressive, false))
+    CmdArgs.push_back("-vectorize-slp-aggressive");
+
+  if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
+    A->render(Args, CmdArgs);
+
+  if (Arg *A = Args.getLastArg(
+          options::OPT_fsanitize_undefined_strip_path_components_EQ))
+    A->render(Args, CmdArgs);
+
+  // -fdollars-in-identifiers default varies depending on platform and
+  // language; only pass if specified.
+  if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
+                               options::OPT_fno_dollars_in_identifiers)) {
+    if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
+      CmdArgs.push_back("-fdollars-in-identifiers");
+    else
+      CmdArgs.push_back("-fno-dollars-in-identifiers");
+  }
+
+  // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
+  // practical purposes.
+  if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
+                               options::OPT_fno_unit_at_a_time)) {
+    if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
+      D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args);
+  }
+
+  if (Args.hasFlag(options::OPT_fapple_pragma_pack,
+                   options::OPT_fno_apple_pragma_pack, false))
+    CmdArgs.push_back("-fapple-pragma-pack");
+
+  // le32-specific flags:
+  //  -fno-math-builtin: clang should not convert math builtins to intrinsics
+  //                     by default.
+  if (getToolChain().getArch() == llvm::Triple::le32) {
+    CmdArgs.push_back("-fno-math-builtin");
+  }
+
+  if (Args.hasFlag(options::OPT_fsave_optimization_record,
+                   options::OPT_fno_save_optimization_record, false)) {
+    CmdArgs.push_back("-opt-record-file");
+
+    const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
+    if (A) {
+      CmdArgs.push_back(A->getValue());
+    } else {
+      SmallString<128> F;
+      if (Output.isFilename() && (Args.hasArg(options::OPT_c) ||
+                                  Args.hasArg(options::OPT_S))) {
+        F = Output.getFilename();
+      } else {
+        // Use the input filename.
+        F = llvm::sys::path::stem(Input.getBaseInput());
+
+        // If we're compiling for an offload architecture (i.e. a CUDA device),
+        // we need to make the file name for the device compilation different
+        // from the host compilation.
+        if (!JA.isDeviceOffloading(Action::OFK_None) &&
+            !JA.isDeviceOffloading(Action::OFK_Host)) {
+          llvm::sys::path::replace_extension(F, "");
+          F += Action::GetOffloadingFileNamePrefix(JA.getOffloadingDeviceKind(),
+                                                   Triple.normalize());
+          F += "-";
+          F += JA.getOffloadingArch();
+        }
+      }
+
+      llvm::sys::path::replace_extension(F, "opt.yaml");
+      CmdArgs.push_back(Args.MakeArgString(F));
+    }
+  }
+
+// Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
+//
+// FIXME: Now that PR4941 has been fixed this can be enabled.
+#if 0
+  if (getToolChain().getTriple().isOSDarwin() &&
+      (getToolChain().getArch() == llvm::Triple::arm ||
+       getToolChain().getArch() == llvm::Triple::thumb)) {
+    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
+      CmdArgs.push_back("-fno-builtin-strcat");
+    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
+      CmdArgs.push_back("-fno-builtin-strcpy");
+  }
+#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() && !HaveAnyModules))
+    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)) {
+    if (isa<PreprocessJobAction>(JA))
+      CmdArgs.push_back("-traditional-cpp");
+    else
+      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_dM);
+  Args.AddLastArg(CmdArgs, options::OPT_dD);
+
+  // Handle serialized diagnostics.
+  if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
+    CmdArgs.push_back("-serialize-diagnostic-file");
+    CmdArgs.push_back(Args.MakeArgString(A->getValue()));
+  }
+
+  if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
+    CmdArgs.push_back("-fretain-comments-from-system-headers");
+
+  // Forward -fcomment-block-commands to -cc1.
+  Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
+  // Forward -fparse-all-comments to -cc1.
+  Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments);
+
+  // Turn -fplugin=name.so into -load name.so
+  for (const Arg *A : Args.filtered(options::OPT_fplugin_EQ)) {
+    CmdArgs.push_back("-load");
+    CmdArgs.push_back(A->getValue());
+    A->claim();
+  }
+
+  // Setup statistics file output.
+  if (const Arg *A = Args.getLastArg(options::OPT_save_stats_EQ)) {
+    StringRef SaveStats = A->getValue();
+
+    SmallString<128> StatsFile;
+    bool DoSaveStats = false;
+    if (SaveStats == "obj") {
+      if (Output.isFilename()) {
+        StatsFile.assign(Output.getFilename());
+        llvm::sys::path::remove_filename(StatsFile);
+      }
+      DoSaveStats = true;
+    } else if (SaveStats == "cwd") {
+      DoSaveStats = true;
+    } else {
+      D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << SaveStats;
+    }
+
+    if (DoSaveStats) {
+      StringRef BaseName = llvm::sys::path::filename(Input.getBaseInput());
+      llvm::sys::path::append(StatsFile, BaseName);
+      llvm::sys::path::replace_extension(StatsFile, "stats");
+      CmdArgs.push_back(Args.MakeArgString(Twine("-stats-file=") +
+                                           StatsFile));
+    }
+  }
+
+  // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
+  // parser.
+  Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
+  for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
+    A->claim();
+
+    // We translate this by hand to the -cc1 argument, since nightly test uses
+    // it and developers have been trained to spell it with -mllvm. Both
+    // spellings are now deprecated and should be removed.
+    if (StringRef(A->getValue(0)) == "-disable-llvm-optzns") {
+      CmdArgs.push_back("-disable-llvm-optzns");
+    } else {
+      A->render(Args, CmdArgs);
+    }
+  }
+
+  // With -save-temps, we want to save the unoptimized bitcode output from the
+  // CompileJobAction, use -disable-llvm-passes to get pristine IR generated
+  // by the frontend.
+  // When -fembed-bitcode is enabled, optimized bitcode is emitted because it
+  // has slightly different breakdown between stages.
+  // FIXME: -fembed-bitcode -save-temps will save optimized bitcode instead of
+  // pristine IR generated by the frontend. Ideally, a new compile action should
+  // be added so both IR can be captured.
+  if (C.getDriver().isSaveTempsEnabled() &&
+      !(C.getDriver().embedBitcodeInObject() && !C.getDriver().isUsingLTO()) &&
+      isa<CompileJobAction>(JA))
+    CmdArgs.push_back("-disable-llvm-passes");
+
+  if (Output.getType() == types::TY_Dependencies) {
+    // Handled with other dependency code.
+  } else if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  addDashXForInput(Args, Input, CmdArgs);
+
+  if (Input.isFilename())
+    CmdArgs.push_back(Input.getFilename());
+  else
+    Input.getInputArg().renderAsInput(Args, CmdArgs);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_undef);
+
+  const char *Exec = getToolChain().getDriver().getClangProgramPath();
+
+  // Optionally embed the -cc1 level arguments into the debug info, for build
+  // analysis.
+  if (getToolChain().UseDwarfDebugFlags()) {
+    ArgStringList OriginalArgs;
+    for (const auto &Arg : Args)
+      Arg->render(Args, OriginalArgs);
+
+    SmallString<256> Flags;
+    Flags += Exec;
+    for (const char *OriginalArg : OriginalArgs) {
+      SmallString<128> EscapedArg;
+      EscapeSpacesAndBackslashes(OriginalArg, EscapedArg);
+      Flags += " ";
+      Flags += EscapedArg;
+    }
+    CmdArgs.push_back("-dwarf-debug-flags");
+    CmdArgs.push_back(Args.MakeArgString(Flags));
+  }
+
+  // Add the split debug info name to the command lines here so we
+  // can propagate it to the backend.
+  bool SplitDwarf = SplitDwarfArg && getToolChain().getTriple().isOSLinux() &&
+                    (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
+                     isa<BackendJobAction>(JA));
+  const char *SplitDwarfOut;
+  if (SplitDwarf) {
+    CmdArgs.push_back("-split-dwarf-file");
+    SplitDwarfOut = SplitDebugName(Args, Input);
+    CmdArgs.push_back(SplitDwarfOut);
+  }
+
+  // Host-side cuda compilation receives device-side outputs as Inputs[1...].
+  // Include them with -fcuda-include-gpubinary.
+  if (IsCuda && Inputs.size() > 1)
+    for (auto I = std::next(Inputs.begin()), E = Inputs.end(); I != E; ++I) {
+      CmdArgs.push_back("-fcuda-include-gpubinary");
+      CmdArgs.push_back(I->getFilename());
+    }
+
+  // OpenMP offloading device jobs take the argument -fopenmp-host-ir-file-path
+  // to specify the result of the compile phase on the host, so the meaningful
+  // device declarations can be identified. Also, -fopenmp-is-device is passed
+  // along to tell the frontend that it is generating code for a device, so that
+  // only the relevant declarations are emitted.
+  if (IsOpenMPDevice && Inputs.size() == 2) {
+    CmdArgs.push_back("-fopenmp-is-device");
+    CmdArgs.push_back("-fopenmp-host-ir-file-path");
+    CmdArgs.push_back(Args.MakeArgString(Inputs.back().getFilename()));
+  }
+
+  // For all the host OpenMP offloading compile jobs we need to pass the targets
+  // information using -fopenmp-targets= option.
+  if (isa<CompileJobAction>(JA) && JA.isHostOffloading(Action::OFK_OpenMP)) {
+    SmallString<128> TargetInfo("-fopenmp-targets=");
+
+    Arg *Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ);
+    assert(Tgts && Tgts->getNumValues() &&
+           "OpenMP offloading has to have targets specified.");
+    for (unsigned i = 0; i < Tgts->getNumValues(); ++i) {
+      if (i)
+        TargetInfo += ',';
+      // We need to get the string from the triple because it may be not exactly
+      // the same as the one we get directly from the arguments.
+      llvm::Triple T(Tgts->getValue(i));
+      TargetInfo += T.getTriple();
+    }
+    CmdArgs.push_back(Args.MakeArgString(TargetInfo.str()));
+  }
+
+  bool WholeProgramVTables =
+      Args.hasFlag(options::OPT_fwhole_program_vtables,
+                   options::OPT_fno_whole_program_vtables, false);
+  if (WholeProgramVTables) {
+    if (!D.isUsingLTO())
+      D.Diag(diag::err_drv_argument_only_allowed_with)
+          << "-fwhole-program-vtables"
+          << "-flto";
+    CmdArgs.push_back("-fwhole-program-vtables");
+  }
+
+  // Finally add the compile command to the compilation.
+  if (Args.hasArg(options::OPT__SLASH_fallback) &&
+      Output.getType() == types::TY_Object &&
+      (InputType == types::TY_C || InputType == types::TY_CXX)) {
+    auto CLCommand =
+        getCLFallback()->GetCommand(C, JA, Output, Inputs, Args, LinkingOutput);
+    C.addCommand(llvm::make_unique<FallbackCommand>(
+        JA, *this, Exec, CmdArgs, Inputs, std::move(CLCommand)));
+  } else if (Args.hasArg(options::OPT__SLASH_fallback) &&
+             isa<PrecompileJobAction>(JA)) {
+    // In /fallback builds, run the main compilation even if the pch generation
+    // fails, so that the main compilation's fallback to cl.exe runs.
+    C.addCommand(llvm::make_unique<ForceSuccessCommand>(JA, *this, Exec,
+                                                        CmdArgs, Inputs));
+  } else {
+    C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+  }
+
+  // Handle the debug info splitting at object creation time if we're
+  // creating an object.
+  // TODO: Currently only works on linux with newer objcopy.
+  if (SplitDwarf && Output.getType() == types::TY_Object)
+    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut);
+
+  if (Arg *A = Args.getLastArg(options::OPT_pg))
+    if (Args.hasArg(options::OPT_fomit_frame_pointer))
+      D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer"
+                                                      << A->getAsString(Args);
+
+  // Claim some arguments which clang supports automatically.
+
+  // -fpch-preprocess is used with gcc to add a special marker in the output to
+  // include the PCH file. Clang's PTH solution is completely transparent, so we
+  // do not need to deal with it at all.
+  Args.ClaimAllArgs(options::OPT_fpch_preprocess);
+
+  // Claim some arguments which clang doesn't support, but we don't
+  // care to warn the user about.
+  Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
+  Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
+
+  // Disable warnings for clang -E -emit-llvm foo.c
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+}
+
+Clang::Clang(const ToolChain &TC)
+    // CAUTION! The first constructor argument ("clang") is not arbitrary,
+    // as it is for other tools. Some operations on a Tool actually test
+    // whether that tool is Clang based on the Tool's Name as a string.
+    : Tool("clang", "clang frontend", TC, RF_Full) {}
+
+Clang::~Clang() {}
+
+/// Add options related to the Objective-C runtime/ABI.
+///
+/// Returns true if the runtime is non-fragile.
+ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
+                                      ArgStringList &cmdArgs,
+                                      RewriteKind rewriteKind) const {
+  // Look for the controlling runtime option.
+  Arg *runtimeArg =
+      args.getLastArg(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
+                      options::OPT_fobjc_runtime_EQ);
+
+  // Just forward -fobjc-runtime= to the frontend.  This supercedes
+  // options about fragility.
+  if (runtimeArg &&
+      runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
+    ObjCRuntime runtime;
+    StringRef value = runtimeArg->getValue();
+    if (runtime.tryParse(value)) {
+      getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
+          << value;
+    }
+
+    runtimeArg->render(args, cmdArgs);
+    return runtime;
+  }
+
+  // Otherwise, we'll need the ABI "version".  Version numbers are
+  // slightly confusing for historical reasons:
+  //   1 - Traditional "fragile" ABI
+  //   2 - Non-fragile ABI, version 1
+  //   3 - Non-fragile ABI, version 2
+  unsigned objcABIVersion = 1;
+  // If -fobjc-abi-version= is present, use that to set the version.
+  if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
+    StringRef value = abiArg->getValue();
+    if (value == "1")
+      objcABIVersion = 1;
+    else if (value == "2")
+      objcABIVersion = 2;
+    else if (value == "3")
+      objcABIVersion = 3;
+    else
+      getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) << value;
+  } else {
+    // Otherwise, determine if we are using the non-fragile ABI.
+    bool nonFragileABIIsDefault =
+        (rewriteKind == RK_NonFragile ||
+         (rewriteKind == RK_None &&
+          getToolChain().IsObjCNonFragileABIDefault()));
+    if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
+                     options::OPT_fno_objc_nonfragile_abi,
+                     nonFragileABIIsDefault)) {
+// Determine the non-fragile ABI version to use.
+#ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
+      unsigned nonFragileABIVersion = 1;
+#else
+      unsigned nonFragileABIVersion = 2;
+#endif
+
+      if (Arg *abiArg =
+              args.getLastArg(options::OPT_fobjc_nonfragile_abi_version_EQ)) {
+        StringRef value = abiArg->getValue();
+        if (value == "1")
+          nonFragileABIVersion = 1;
+        else if (value == "2")
+          nonFragileABIVersion = 2;
+        else
+          getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
+              << value;
+      }
+
+      objcABIVersion = 1 + nonFragileABIVersion;
+    } else {
+      objcABIVersion = 1;
+    }
+  }
+
+  // We don't actually care about the ABI version other than whether
+  // it's non-fragile.
+  bool isNonFragile = objcABIVersion != 1;
+
+  // If we have no runtime argument, ask the toolchain for its default runtime.
+  // However, the rewriter only really supports the Mac runtime, so assume that.
+  ObjCRuntime runtime;
+  if (!runtimeArg) {
+    switch (rewriteKind) {
+    case RK_None:
+      runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
+      break;
+    case RK_Fragile:
+      runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
+      break;
+    case RK_NonFragile:
+      runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
+      break;
+    }
+
+    // -fnext-runtime
+  } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
+    // On Darwin, make this use the default behavior for the toolchain.
+    if (getToolChain().getTriple().isOSDarwin()) {
+      runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
+
+      // Otherwise, build for a generic macosx port.
+    } else {
+      runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
+    }
+
+    // -fgnu-runtime
+  } else {
+    assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
+    // Legacy behaviour is to target the gnustep runtime if we are in
+    // non-fragile mode or the GCC runtime in fragile mode.
+    if (isNonFragile)
+      runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1, 6));
+    else
+      runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
+  }
+
+  cmdArgs.push_back(
+      args.MakeArgString("-fobjc-runtime=" + runtime.getAsString()));
+  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;
+}
+
+namespace {
+struct EHFlags {
+  bool Synch = false;
+  bool Asynch = false;
+  bool NoUnwindC = false;
+};
+} // end anonymous namespace
+
+/// /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 nounwind.
+/// 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);
+        if (EH.Asynch)
+          EH.Synch = false;
+        continue;
+      case 'c':
+        EH.NoUnwindC = maybeConsumeDash(EHVal, I);
+        continue;
+      case 's':
+        EH.Synch = maybeConsumeDash(EHVal, I);
+        if (EH.Synch)
+          EH.Asynch = false;
+        continue;
+      default:
+        break;
+      }
+      D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal;
+      break;
+    }
+  }
+  // The /GX, /GX- flags are only processed if there are not /EH flags.
+  // The default is that /GX is not specified.
+  if (EHArgs.empty() &&
+      Args.hasFlag(options::OPT__SLASH_GX, options::OPT__SLASH_GX_,
+                   /*default=*/false)) {
+    EH.Synch = true;
+    EH.NoUnwindC = true;
+  }
+
+  return EH;
+}
+
+void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
+                           ArgStringList &CmdArgs,
+                           codegenoptions::DebugInfoKind *DebugInfoKind,
+                           bool *EmitCodeView) const {
+  unsigned RTOptionID = options::OPT__SLASH_MT;
+
+  if (Args.hasArg(options::OPT__SLASH_LDd))
+    // The /LDd option implies /MTd. The dependent lib part can be overridden,
+    // but defining _DEBUG is sticky.
+    RTOptionID = options::OPT__SLASH_MTd;
+
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group))
+    RTOptionID = A->getOption().getID();
+
+  StringRef FlagForCRT;
+  switch (RTOptionID) {
+  case options::OPT__SLASH_MD:
+    if (Args.hasArg(options::OPT__SLASH_LDd))
+      CmdArgs.push_back("-D_DEBUG");
+    CmdArgs.push_back("-D_MT");
+    CmdArgs.push_back("-D_DLL");
+    FlagForCRT = "--dependent-lib=msvcrt";
+    break;
+  case options::OPT__SLASH_MDd:
+    CmdArgs.push_back("-D_DEBUG");
+    CmdArgs.push_back("-D_MT");
+    CmdArgs.push_back("-D_DLL");
+    FlagForCRT = "--dependent-lib=msvcrtd";
+    break;
+  case options::OPT__SLASH_MT:
+    if (Args.hasArg(options::OPT__SLASH_LDd))
+      CmdArgs.push_back("-D_DEBUG");
+    CmdArgs.push_back("-D_MT");
+    CmdArgs.push_back("-flto-visibility-public-std");
+    FlagForCRT = "--dependent-lib=libcmt";
+    break;
+  case options::OPT__SLASH_MTd:
+    CmdArgs.push_back("-D_DEBUG");
+    CmdArgs.push_back("-D_MT");
+    CmdArgs.push_back("-flto-visibility-public-std");
+    FlagForCRT = "--dependent-lib=libcmtd";
+    break;
+  default:
+    llvm_unreachable("Unexpected option ID.");
+  }
+
+  if (Args.hasArg(options::OPT__SLASH_Zl)) {
+    CmdArgs.push_back("-D_VC_NODEFAULTLIB");
+  } else {
+    CmdArgs.push_back(FlagForCRT.data());
+
+    // This provides POSIX compatibility (maps 'open' to '_open'), which most
+    // users want.  The /Za flag to cl.exe turns this off, but it's not
+    // implemented in clang.
+    CmdArgs.push_back("--dependent-lib=oldnames");
+  }
+
+  // Both /showIncludes and /E (and /EP) write to stdout. Allowing both
+  // would produce interleaved output, so ignore /showIncludes in such cases.
+  if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_EP))
+    if (Arg *A = Args.getLastArg(options::OPT_show_includes))
+      A->render(Args, CmdArgs);
+
+  // 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");
+
+  // This controls whether or not we emit stack-protector instrumentation.
+  // In MSVC, Buffer Security Check (/GS) is on by default.
+  if (Args.hasFlag(options::OPT__SLASH_GS, options::OPT__SLASH_GS_,
+                   /*default=*/true)) {
+    CmdArgs.push_back("-stack-protector");
+    CmdArgs.push_back(Args.MakeArgString(Twine(LangOptions::SSPStrong)));
+  }
+
+  // Emit CodeView if -Z7, -Zd, or -gline-tables-only are present.
+  if (Arg *DebugInfoArg =
+          Args.getLastArg(options::OPT__SLASH_Z7, options::OPT__SLASH_Zd,
+                          options::OPT_gline_tables_only)) {
+    *EmitCodeView = true;
+    if (DebugInfoArg->getOption().matches(options::OPT__SLASH_Z7))
+      *DebugInfoKind = codegenoptions::LimitedDebugInfo;
+    else
+      *DebugInfoKind = codegenoptions::DebugLineTablesOnly;
+    CmdArgs.push_back("-gcodeview");
+  } else {
+    *EmitCodeView = false;
+  }
+
+  const Driver &D = getToolChain().getDriver();
+  EHFlags EH = parseClangCLEHFlags(D, Args);
+  if (EH.Synch || EH.Asynch) {
+    if (types::isCXX(InputType))
+      CmdArgs.push_back("-fcxx-exceptions");
+    CmdArgs.push_back("-fexceptions");
+  }
+  if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
+    CmdArgs.push_back("-fexternc-nounwind");
+
+  // /EP should expand to -E -P.
+  if (Args.hasArg(options::OPT__SLASH_EP)) {
+    CmdArgs.push_back("-E");
+    CmdArgs.push_back("-P");
+  }
+
+  unsigned VolatileOptionID;
+  if (getToolChain().getArch() == llvm::Triple::x86_64 ||
+      getToolChain().getArch() == llvm::Triple::x86)
+    VolatileOptionID = options::OPT__SLASH_volatile_ms;
+  else
+    VolatileOptionID = options::OPT__SLASH_volatile_iso;
+
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_volatile_Group))
+    VolatileOptionID = A->getOption().getID();
+
+  if (VolatileOptionID == options::OPT__SLASH_volatile_ms)
+    CmdArgs.push_back("-fms-volatile");
+
+  Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
+  Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
+  if (MostGeneralArg && BestCaseArg)
+    D.Diag(clang::diag::err_drv_argument_not_allowed_with)
+        << MostGeneralArg->getAsString(Args) << BestCaseArg->getAsString(Args);
+
+  if (MostGeneralArg) {
+    Arg *SingleArg = Args.getLastArg(options::OPT__SLASH_vms);
+    Arg *MultipleArg = Args.getLastArg(options::OPT__SLASH_vmm);
+    Arg *VirtualArg = Args.getLastArg(options::OPT__SLASH_vmv);
+
+    Arg *FirstConflict = SingleArg ? SingleArg : MultipleArg;
+    Arg *SecondConflict = VirtualArg ? VirtualArg : MultipleArg;
+    if (FirstConflict && SecondConflict && FirstConflict != SecondConflict)
+      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
+          << FirstConflict->getAsString(Args)
+          << SecondConflict->getAsString(Args);
+
+    if (SingleArg)
+      CmdArgs.push_back("-fms-memptr-rep=single");
+    else if (MultipleArg)
+      CmdArgs.push_back("-fms-memptr-rep=multiple");
+    else
+      CmdArgs.push_back("-fms-memptr-rep=virtual");
+  }
+
+  if (Args.getLastArg(options::OPT__SLASH_Gd))
+     CmdArgs.push_back("-fdefault-calling-conv=cdecl");
+  else if (Args.getLastArg(options::OPT__SLASH_Gr))
+     CmdArgs.push_back("-fdefault-calling-conv=fastcall");
+  else if (Args.getLastArg(options::OPT__SLASH_Gz))
+     CmdArgs.push_back("-fdefault-calling-conv=stdcall");
+  else if (Args.getLastArg(options::OPT__SLASH_Gv))
+     CmdArgs.push_back("-fdefault-calling-conv=vectorcall");
+
+  if (Arg *A = Args.getLastArg(options::OPT_vtordisp_mode_EQ))
+    A->render(Args, CmdArgs);
+
+  if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
+    CmdArgs.push_back("-fdiagnostics-format");
+    if (Args.hasArg(options::OPT__SLASH_fallback))
+      CmdArgs.push_back("msvc-fallback");
+    else
+      CmdArgs.push_back("msvc");
+  }
+}
+
+visualstudio::Compiler *Clang::getCLFallback() const {
+  if (!CLFallback)
+    CLFallback.reset(new visualstudio::Compiler(getToolChain()));
+  return CLFallback.get();
+}
+
+
+const char *Clang::getBaseInputName(const ArgList &Args,
+                                    const InputInfo &Input) {
+  return Args.MakeArgString(llvm::sys::path::filename(Input.getBaseInput()));
+}
+
+const char *Clang::getBaseInputStem(const ArgList &Args,
+                                    const InputInfoList &Inputs) {
+  const char *Str = getBaseInputName(Args, Inputs[0]);
+
+  if (const char *End = strrchr(Str, '.'))
+    return Args.MakeArgString(std::string(Str, End));
+
+  return Str;
+}
+
+const char *Clang::getDependencyFileName(const ArgList &Args,
+                                         const InputInfoList &Inputs) {
+  // FIXME: Think about this more.
+  std::string Res;
+
+  if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
+    std::string Str(OutputOpt->getValue());
+    Res = Str.substr(0, Str.rfind('.'));
+  } else {
+    Res = getBaseInputStem(Args, Inputs);
+  }
+  return Args.MakeArgString(Res + ".d");
+}
+
+// Begin ClangAs
+
+void ClangAs::AddMIPSTargetArgs(const ArgList &Args,
+                                ArgStringList &CmdArgs) const {
+  StringRef CPUName;
+  StringRef ABIName;
+  const llvm::Triple &Triple = getToolChain().getTriple();
+  mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+
+  CmdArgs.push_back("-target-abi");
+  CmdArgs.push_back(ABIName.data());
+}
+
+void ClangAs::AddX86TargetArgs(const ArgList &Args,
+                               ArgStringList &CmdArgs) const {
+  if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
+    StringRef Value = A->getValue();
+    if (Value == "intel" || Value == "att") {
+      CmdArgs.push_back("-mllvm");
+      CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));
+    } else {
+      getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
+          << A->getOption().getName() << Value;
+    }
+  }
+}
+
+void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
+                           const InputInfo &Output, const InputInfoList &Inputs,
+                           const ArgList &Args,
+                           const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
+  const InputInfo &Input = Inputs[0];
+
+  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+  const std::string &TripleStr = Triple.getTriple();
+
+  // Don't warn about "clang -w -c foo.s"
+  Args.ClaimAllArgs(options::OPT_w);
+  // and "clang -emit-llvm -c foo.s"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+
+  claimNoWarnArgs(Args);
+
+  // Invoke ourselves in -cc1as mode.
+  //
+  // FIXME: Implement custom jobs for internal actions.
+  CmdArgs.push_back("-cc1as");
+
+  // Add the "effective" target triple.
+  CmdArgs.push_back("-triple");
+  CmdArgs.push_back(Args.MakeArgString(TripleStr));
+
+  // Set the output mode, we currently only expect to be used as a real
+  // assembler.
+  CmdArgs.push_back("-filetype");
+  CmdArgs.push_back("obj");
+
+  // Set the main file name, so that debug info works even with
+  // -save-temps or preprocessed assembly.
+  CmdArgs.push_back("-main-file-name");
+  CmdArgs.push_back(Clang::getBaseInputName(Args, Input));
+
+  // Add the target cpu
+  std::string CPU = getCPUName(Args, Triple, /*FromAs*/ true);
+  if (!CPU.empty()) {
+    CmdArgs.push_back("-target-cpu");
+    CmdArgs.push_back(Args.MakeArgString(CPU));
+  }
+
+  // Add the target features
+  getTargetFeatures(getToolChain(), Triple, Args, CmdArgs, true);
+
+  // Ignore explicit -force_cpusubtype_ALL option.
+  (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
+
+  // Pass along any -I options so we get proper .include search paths.
+  Args.AddAllArgs(CmdArgs, options::OPT_I_Group);
+
+  // Determine the original source input.
+  const Action *SourceAction = &JA;
+  while (SourceAction->getKind() != Action::InputClass) {
+    assert(!SourceAction->getInputs().empty() && "unexpected root action!");
+    SourceAction = SourceAction->getInputs()[0];
+  }
+
+  // Forward -g and handle debug info related flags, assuming we are dealing
+  // with an actual assembly file.
+  bool WantDebug = false;
+  unsigned DwarfVersion = 0;
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
+    WantDebug = !A->getOption().matches(options::OPT_g0) &&
+                !A->getOption().matches(options::OPT_ggdb0);
+    if (WantDebug)
+      DwarfVersion = DwarfVersionNum(A->getSpelling());
+  }
+  if (DwarfVersion == 0)
+    DwarfVersion = getToolChain().GetDefaultDwarfVersion();
+
+  codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
+
+  if (SourceAction->getType() == types::TY_Asm ||
+      SourceAction->getType() == types::TY_PP_Asm) {
+    // You might think that it would be ok to set DebugInfoKind outside of
+    // the guard for source type, however there is a test which asserts
+    // that some assembler invocation receives no -debug-info-kind,
+    // and it's not clear whether that test is just overly restrictive.
+    DebugInfoKind = (WantDebug ? codegenoptions::LimitedDebugInfo
+                               : codegenoptions::NoDebugInfo);
+    // Add the -fdebug-compilation-dir flag if needed.
+    addDebugCompDirArg(Args, CmdArgs);
+
+    // Set the AT_producer to the clang version when using the integrated
+    // assembler on assembly source files.
+    CmdArgs.push_back("-dwarf-debug-producer");
+    CmdArgs.push_back(Args.MakeArgString(getClangFullVersion()));
+
+    // And pass along -I options
+    Args.AddAllArgs(CmdArgs, options::OPT_I);
+  }
+  RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
+                          llvm::DebuggerKind::Default);
+
+  // Handle -fPIC et al -- the relocation-model affects the assembler
+  // for some targets.
+  llvm::Reloc::Model RelocationModel;
+  unsigned PICLevel;
+  bool IsPIE;
+  std::tie(RelocationModel, PICLevel, IsPIE) =
+      ParsePICArgs(getToolChain(), Args);
+
+  const char *RMName = RelocationModelName(RelocationModel);
+  if (RMName) {
+    CmdArgs.push_back("-mrelocation-model");
+    CmdArgs.push_back(RMName);
+  }
+
+  // Optionally embed the -cc1as level arguments into the debug info, for build
+  // analysis.
+  if (getToolChain().UseDwarfDebugFlags()) {
+    ArgStringList OriginalArgs;
+    for (const auto &Arg : Args)
+      Arg->render(Args, OriginalArgs);
+
+    SmallString<256> Flags;
+    const char *Exec = getToolChain().getDriver().getClangProgramPath();
+    Flags += Exec;
+    for (const char *OriginalArg : OriginalArgs) {
+      SmallString<128> EscapedArg;
+      EscapeSpacesAndBackslashes(OriginalArg, EscapedArg);
+      Flags += " ";
+      Flags += EscapedArg;
+    }
+    CmdArgs.push_back("-dwarf-debug-flags");
+    CmdArgs.push_back(Args.MakeArgString(Flags));
+  }
+
+  // FIXME: Add -static support, once we have it.
+
+  // Add target specific flags.
+  switch (getToolChain().getArch()) {
+  default:
+    break;
+
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el:
+    AddMIPSTargetArgs(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    AddX86TargetArgs(Args, CmdArgs);
+    break;
+  }
+
+  // Consume all the warning flags. Usually this would be handled more
+  // gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as
+  // doesn't handle that so rather than warning about unused flags that are
+  // actually used, we'll lie by omission instead.
+  // FIXME: Stop lying and consume only the appropriate driver flags
+  Args.ClaimAllArgs(options::OPT_W_Group);
+
+  CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
+                                    getToolChain().getDriver());
+
+  Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
+
+  assert(Output.isFilename() && "Unexpected lipo output.");
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  assert(Input.isFilename() && "Invalid input.");
+  CmdArgs.push_back(Input.getFilename());
+
+  const char *Exec = getToolChain().getDriver().getClangProgramPath();
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+
+  // Handle the debug info splitting at object creation time if we're
+  // creating an object.
+  // TODO: Currently only works on linux with newer objcopy.
+  if (Args.hasArg(options::OPT_gsplit_dwarf) &&
+      getToolChain().getTriple().isOSLinux())
+    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
+                   SplitDebugName(Args, Input));
+}
+
+// Begin OffloadBundler
+
+void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA,
+                                  const InputInfo &Output,
+                                  const InputInfoList &Inputs,
+                                  const llvm::opt::ArgList &TCArgs,
+                                  const char *LinkingOutput) const {
+  // The version with only one output is expected to refer to a bundling job.
+  assert(isa<OffloadBundlingJobAction>(JA) && "Expecting bundling job!");
+
+  // The bundling command looks like this:
+  // clang-offload-bundler -type=bc
+  //   -targets=host-triple,openmp-triple1,openmp-triple2
+  //   -outputs=input_file
+  //   -inputs=unbundle_file_host,unbundle_file_tgt1,unbundle_file_tgt2"
+
+  ArgStringList CmdArgs;
+
+  // Get the type.
+  CmdArgs.push_back(TCArgs.MakeArgString(
+      Twine("-type=") + types::getTypeTempSuffix(Output.getType())));
+
+  assert(JA.getInputs().size() == Inputs.size() &&
+         "Not have inputs for all dependence actions??");
+
+  // Get the targets.
+  SmallString<128> Triples;
+  Triples += "-targets=";
+  for (unsigned I = 0; I < Inputs.size(); ++I) {
+    if (I)
+      Triples += ',';
+
+    Action::OffloadKind CurKind = Action::OFK_Host;
+    const ToolChain *CurTC = &getToolChain();
+    const Action *CurDep = JA.getInputs()[I];
+
+    if (const auto *OA = dyn_cast<OffloadAction>(CurDep)) {
+      OA->doOnEachDependence([&](Action *A, const ToolChain *TC, const char *) {
+        CurKind = A->getOffloadingDeviceKind();
+        CurTC = TC;
+      });
+    }
+    Triples += Action::GetOffloadKindName(CurKind);
+    Triples += '-';
+    Triples += CurTC->getTriple().normalize();
+  }
+  CmdArgs.push_back(TCArgs.MakeArgString(Triples));
+
+  // Get bundled file command.
+  CmdArgs.push_back(
+      TCArgs.MakeArgString(Twine("-outputs=") + Output.getFilename()));
+
+  // Get unbundled files command.
+  SmallString<128> UB;
+  UB += "-inputs=";
+  for (unsigned I = 0; I < Inputs.size(); ++I) {
+    if (I)
+      UB += ',';
+    UB += Inputs[I].getFilename();
+  }
+  CmdArgs.push_back(TCArgs.MakeArgString(UB));
+
+  // All the inputs are encoded as commands.
+  C.addCommand(llvm::make_unique<Command>(
+      JA, *this,
+      TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
+      CmdArgs, None));
+}
+
+void OffloadBundler::ConstructJobMultipleOutputs(
+    Compilation &C, const JobAction &JA, const InputInfoList &Outputs,
+    const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs,
+    const char *LinkingOutput) const {
+  // The version with multiple outputs is expected to refer to a unbundling job.
+  auto &UA = cast<OffloadUnbundlingJobAction>(JA);
+
+  // The unbundling command looks like this:
+  // clang-offload-bundler -type=bc
+  //   -targets=host-triple,openmp-triple1,openmp-triple2
+  //   -inputs=input_file
+  //   -outputs=unbundle_file_host,unbundle_file_tgt1,unbundle_file_tgt2"
+  //   -unbundle
+
+  ArgStringList CmdArgs;
+
+  assert(Inputs.size() == 1 && "Expecting to unbundle a single file!");
+  InputInfo Input = Inputs.front();
+
+  // Get the type.
+  CmdArgs.push_back(TCArgs.MakeArgString(
+      Twine("-type=") + types::getTypeTempSuffix(Input.getType())));
+
+  // Get the targets.
+  SmallString<128> Triples;
+  Triples += "-targets=";
+  auto DepInfo = UA.getDependentActionsInfo();
+  for (unsigned I = 0; I < DepInfo.size(); ++I) {
+    if (I)
+      Triples += ',';
+
+    auto &Dep = DepInfo[I];
+    Triples += Action::GetOffloadKindName(Dep.DependentOffloadKind);
+    Triples += '-';
+    Triples += Dep.DependentToolChain->getTriple().normalize();
+  }
+
+  CmdArgs.push_back(TCArgs.MakeArgString(Triples));
+
+  // Get bundled file command.
+  CmdArgs.push_back(
+      TCArgs.MakeArgString(Twine("-inputs=") + Input.getFilename()));
+
+  // Get unbundled files command.
+  SmallString<128> UB;
+  UB += "-outputs=";
+  for (unsigned I = 0; I < Outputs.size(); ++I) {
+    if (I)
+      UB += ',';
+    UB += Outputs[I].getFilename();
+  }
+  CmdArgs.push_back(TCArgs.MakeArgString(UB));
+  CmdArgs.push_back("-unbundle");
+
+  // All the inputs are encoded as commands.
+  C.addCommand(llvm::make_unique<Command>(
+      JA, *this,
+      TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
+      CmdArgs, None));
+}
diff --git a/lib/Driver/ToolChains/Clang.h b/lib/Driver/ToolChains/Clang.h
new file mode 100644
index 0000000..d53c3b4
--- /dev/null
+++ b/lib/Driver/ToolChains/Clang.h
@@ -0,0 +1,149 @@
+//===--- Clang.h - Clang Tool and ToolChain Implementations ====-*- 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_LIB_DRIVER_TOOLCHAINS_Clang_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_Clang_H
+
+#include "MSVC.h"
+#include "clang/Basic/DebugInfoOptions.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/Types.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+class ObjCRuntime;
+namespace driver {
+
+namespace tools {
+
+/// \brief Clang compiler tool.
+class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
+public:
+  static const char *getBaseInputName(const llvm::opt::ArgList &Args,
+                                      const InputInfo &Input);
+  static const char *getBaseInputStem(const llvm::opt::ArgList &Args,
+                                      const InputInfoList &Inputs);
+  static const char *getDependencyFileName(const llvm::opt::ArgList &Args,
+                                           const InputInfoList &Inputs);
+
+private:
+  void AddPreprocessingOptions(Compilation &C, const JobAction &JA,
+                               const Driver &D, const llvm::opt::ArgList &Args,
+                               llvm::opt::ArgStringList &CmdArgs,
+                               const InputInfo &Output,
+                               const InputInfoList &Inputs) const;
+
+  void AddAArch64TargetArgs(const llvm::opt::ArgList &Args,
+                            llvm::opt::ArgStringList &CmdArgs) const;
+  void AddARMTargetArgs(const llvm::Triple &Triple,
+                        const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs,
+                        bool KernelOrKext) const;
+  void AddARM64TargetArgs(const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs) const;
+  void AddMIPSTargetArgs(const llvm::opt::ArgList &Args,
+                         llvm::opt::ArgStringList &CmdArgs) const;
+  void AddPPCTargetArgs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const;
+  void AddR600TargetArgs(const llvm::opt::ArgList &Args,
+                         llvm::opt::ArgStringList &CmdArgs) const;
+  void AddSparcTargetArgs(const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs) const;
+  void AddSystemZTargetArgs(const llvm::opt::ArgList &Args,
+                            llvm::opt::ArgStringList &CmdArgs) const;
+  void AddX86TargetArgs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const;
+  void AddHexagonTargetArgs(const llvm::opt::ArgList &Args,
+                            llvm::opt::ArgStringList &CmdArgs) const;
+  void AddLanaiTargetArgs(const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs) const;
+  void AddWebAssemblyTargetArgs(const llvm::opt::ArgList &Args,
+                                llvm::opt::ArgStringList &CmdArgs) const;
+
+  enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile };
+
+  ObjCRuntime AddObjCRuntimeArgs(const llvm::opt::ArgList &args,
+                                 llvm::opt::ArgStringList &cmdArgs,
+                                 RewriteKind rewrite) const;
+
+  void AddClangCLArgs(const llvm::opt::ArgList &Args, types::ID InputType,
+                      llvm::opt::ArgStringList &CmdArgs,
+                      codegenoptions::DebugInfoKind *DebugInfoKind,
+                      bool *EmitCodeView) const;
+
+  visualstudio::Compiler *getCLFallback() const;
+
+  mutable std::unique_ptr<visualstudio::Compiler> CLFallback;
+
+  mutable std::unique_ptr<llvm::raw_fd_ostream> CompilationDatabase = nullptr;
+  void DumpCompilationDatabase(Compilation &C, StringRef Filename,
+                               StringRef Target,
+                               const InputInfo &Output, const InputInfo &Input,
+                               const llvm::opt::ArgList &Args) const;
+
+public:
+  Clang(const ToolChain &TC);
+  ~Clang() override;
+
+  bool hasGoodDiagnostics() const override { return true; }
+  bool hasIntegratedAssembler() const override { return true; }
+  bool hasIntegratedCPP() const override { return true; }
+  bool canEmitIR() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+/// \brief Clang integrated assembler tool.
+class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
+public:
+  ClangAs(const ToolChain &TC)
+      : Tool("clang::as", "clang integrated assembler", TC, RF_Full) {}
+  void AddMIPSTargetArgs(const llvm::opt::ArgList &Args,
+                         llvm::opt::ArgStringList &CmdArgs) const;
+  void AddX86TargetArgs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const;
+  bool hasGoodDiagnostics() const override { return true; }
+  bool hasIntegratedAssembler() const override { return false; }
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+/// Offload bundler tool.
+class LLVM_LIBRARY_VISIBILITY OffloadBundler final : public Tool {
+public:
+  OffloadBundler(const ToolChain &TC)
+      : Tool("offload bundler", "clang-offload-bundler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+  void ConstructJobMultipleOutputs(Compilation &C, const JobAction &JA,
+                                   const InputInfoList &Outputs,
+                                   const InputInfoList &Inputs,
+                                   const llvm::opt::ArgList &TCArgs,
+                                   const char *LinkingOutput) const override;
+};
+} // end namespace tools
+
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CLANG_H
diff --git a/lib/Driver/ToolChains/CloudABI.cpp b/lib/Driver/ToolChains/CloudABI.cpp
new file mode 100644
index 0000000..0f6c712
--- /dev/null
+++ b/lib/Driver/ToolChains/CloudABI.cpp
@@ -0,0 +1,145 @@
+//===--- CloudABI.cpp - CloudABI ToolChain Implementations ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CloudABI.h"
+#include "InputInfo.h"
+#include "CommonArgs.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                    const InputInfo &Output,
+                                    const InputInfoList &Inputs,
+                                    const ArgList &Args,
+                                    const char *LinkingOutput) const {
+  const ToolChain &ToolChain = getToolChain();
+  const Driver &D = ToolChain.getDriver();
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  // CloudABI only supports static linkage.
+  CmdArgs.push_back("-Bstatic");
+  CmdArgs.push_back("--no-dynamic-linker");
+
+  // Provide PIE linker flags in case PIE is default for the architecture.
+  if (ToolChain.isPIEDefault()) {
+    CmdArgs.push_back("-pie");
+    CmdArgs.push_back("-zrelro");
+  }
+
+  CmdArgs.push_back("--eh-frame-hdr");
+  CmdArgs.push_back("--gc-sections");
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+  Args.AddAllArgs(CmdArgs,
+                  {options::OPT_T_Group, options::OPT_e, options::OPT_s,
+                   options::OPT_t, options::OPT_Z_Flag, options::OPT_r});
+
+  if (D.isUsingLTO())
+    AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin, D);
+
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    if (D.CCCIsCXX())
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+    CmdArgs.push_back("-lc");
+    CmdArgs.push_back("-lcompiler_rt");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
+
+  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+// CloudABI - CloudABI tool chain which can call ld(1) directly.
+
+CloudABI::CloudABI(const Driver &D, const llvm::Triple &Triple,
+                   const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  SmallString<128> P(getDriver().Dir);
+  llvm::sys::path::append(P, "..", getTriple().str(), "lib");
+  getFilePaths().push_back(P.str());
+}
+
+std::string CloudABI::findLibCxxIncludePath() const {
+  SmallString<128> P(getDriver().Dir);
+  llvm::sys::path::append(P, "..", getTriple().str(), "include/c++/v1");
+  return P.str();
+}
+
+void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args,
+                                   ArgStringList &CmdArgs) const {
+  CmdArgs.push_back("-lc++");
+  CmdArgs.push_back("-lc++abi");
+  CmdArgs.push_back("-lunwind");
+}
+
+Tool *CloudABI::buildLinker() const {
+  return new tools::cloudabi::Linker(*this);
+}
+
+bool CloudABI::isPIEDefault() const {
+  // Only enable PIE on architectures that support PC-relative
+  // addressing. PC-relative addressing is required, as the process
+  // startup code must be able to relocate itself.
+  switch (getTriple().getArch()) {
+  case llvm::Triple::aarch64:
+  case llvm::Triple::x86_64:
+    return true;
+  default:
+    return false;
+  }
+}
+
+SanitizerMask CloudABI::getSupportedSanitizers() const {
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::SafeStack;
+  return Res;
+}
+
+SanitizerMask CloudABI::getDefaultSanitizers() const {
+  return SanitizerKind::SafeStack;
+}
diff --git a/lib/Driver/ToolChains/CloudABI.h b/lib/Driver/ToolChains/CloudABI.h
new file mode 100644
index 0000000..a284eb3
--- /dev/null
+++ b/lib/Driver/ToolChains/CloudABI.h
@@ -0,0 +1,69 @@
+//===--- CloudABI.h - CloudABI ToolChain Implementations --------*- 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_LIB_DRIVER_TOOLCHAINS_CLOUDABI_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CLOUDABI_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+/// cloudabi -- Directly call GNU Binutils linker
+namespace cloudabi {
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("cloudabi::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace cloudabi
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY CloudABI : public Generic_ELF {
+public:
+  CloudABI(const Driver &D, const llvm::Triple &Triple,
+           const llvm::opt::ArgList &Args);
+  bool HasNativeLLVMSupport() const override { return true; }
+
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
+
+  CXXStdlibType
+  GetCXXStdlibType(const llvm::opt::ArgList &Args) const override {
+    return ToolChain::CST_Libcxx;
+  }
+  std::string findLibCxxIncludePath() const override;
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+
+  bool isPIEDefault() const override;
+  SanitizerMask getSupportedSanitizers() const override;
+  SanitizerMask getDefaultSanitizers() const override;
+
+protected:
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CLOUDABI_H
diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
new file mode 100644
index 0000000..5afe135
--- /dev/null
+++ b/lib/Driver/ToolChains/CommonArgs.cpp
@@ -0,0 +1,959 @@
+//===--- CommonArgs.cpp - Args handling for multiple toolchains -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommonArgs.h"
+#include "InputInfo.h"
+#include "Hexagon.h"
+#include "Arch/AArch64.h"
+#include "Arch/ARM.h"
+#include "Arch/Mips.h"
+#include "Arch/PPC.h"
+#include "Arch/SystemZ.h"
+#include "Arch/X86.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/Version.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Action.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Job.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "clang/Driver/ToolChain.h"
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Compression.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/TargetParser.h"
+#include "llvm/Support/YAMLParser.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+void tools::addPathIfExists(const Driver &D, const Twine &Path,
+                            ToolChain::path_list &Paths) {
+  if (D.getVFS().exists(Path))
+    Paths.push_back(Path.str());
+}
+
+void tools::handleTargetFeaturesGroup(const ArgList &Args,
+                                      std::vector<StringRef> &Features,
+                                      OptSpecifier Group) {
+  for (const Arg *A : Args.filtered(Group)) {
+    StringRef Name = A->getOption().getName();
+    A->claim();
+
+    // Skip over "-m".
+    assert(Name.startswith("m") && "Invalid feature name.");
+    Name = Name.substr(1);
+
+    bool IsNegative = Name.startswith("no-");
+    if (IsNegative)
+      Name = Name.substr(3);
+    Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
+  }
+}
+
+void tools::addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs,
+                             const char *ArgName, const char *EnvVar) {
+  const char *DirList = ::getenv(EnvVar);
+  bool CombinedArg = false;
+
+  if (!DirList)
+    return; // Nothing to do.
+
+  StringRef Name(ArgName);
+  if (Name.equals("-I") || Name.equals("-L"))
+    CombinedArg = true;
+
+  StringRef Dirs(DirList);
+  if (Dirs.empty()) // Empty string should not add '.'.
+    return;
+
+  StringRef::size_type Delim;
+  while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) {
+    if (Delim == 0) { // Leading colon.
+      if (CombinedArg) {
+        CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
+      } else {
+        CmdArgs.push_back(ArgName);
+        CmdArgs.push_back(".");
+      }
+    } else {
+      if (CombinedArg) {
+        CmdArgs.push_back(
+            Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
+      } else {
+        CmdArgs.push_back(ArgName);
+        CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
+      }
+    }
+    Dirs = Dirs.substr(Delim + 1);
+  }
+
+  if (Dirs.empty()) { // Trailing colon.
+    if (CombinedArg) {
+      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
+    } else {
+      CmdArgs.push_back(ArgName);
+      CmdArgs.push_back(".");
+    }
+  } else { // Add the last path.
+    if (CombinedArg) {
+      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
+    } else {
+      CmdArgs.push_back(ArgName);
+      CmdArgs.push_back(Args.MakeArgString(Dirs));
+    }
+  }
+}
+
+void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
+                            const ArgList &Args, ArgStringList &CmdArgs,
+                            const JobAction &JA) {
+  const Driver &D = TC.getDriver();
+
+  // Add extra linker input arguments which are not treated as inputs
+  // (constructed via -Xarch_).
+  Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
+
+  for (const auto &II : Inputs) {
+    // If the current tool chain refers to an OpenMP offloading host, we should
+    // ignore inputs that refer to OpenMP offloading devices - they will be
+    // embedded according to a proper linker script.
+    if (auto *IA = II.getAction())
+      if (JA.isHostOffloading(Action::OFK_OpenMP) &&
+          IA->isDeviceOffloading(Action::OFK_OpenMP))
+        continue;
+
+    if (!TC.HasNativeLLVMSupport() && types::isLLVMIR(II.getType()))
+      // Don't try to pass LLVM inputs unless we have native support.
+      D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString();
+
+    // Add filenames immediately.
+    if (II.isFilename()) {
+      CmdArgs.push_back(II.getFilename());
+      continue;
+    }
+
+    // Otherwise, this is a linker input argument.
+    const Arg &A = II.getInputArg();
+
+    // Handle reserved library options.
+    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))
+      TC.AddCCKextLibArgs(Args, CmdArgs);
+    else if (A.getOption().matches(options::OPT_z)) {
+      // Pass -z prefix for gcc linker compatibility.
+      A.claim();
+      A.render(Args, CmdArgs);
+    } else {
+      A.renderAsInput(Args, CmdArgs);
+    }
+  }
+
+  // LIBRARY_PATH - included following the user specified library paths.
+  //                and only supported on native toolchains.
+  if (!TC.isCrossCompiling()) {
+    addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
+  }
+}
+
+void tools::AddTargetFeature(const ArgList &Args,
+                             std::vector<StringRef> &Features,
+                             OptSpecifier OnOpt, OptSpecifier OffOpt,
+                             StringRef FeatureName) {
+  if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
+    if (A->getOption().matches(OnOpt))
+      Features.push_back(Args.MakeArgString("+" + FeatureName));
+    else
+      Features.push_back(Args.MakeArgString("-" + FeatureName));
+  }
+}
+
+/// Get the (LLVM) name of the R600 gpu we are targeting.
+static std::string getR600TargetGPU(const ArgList &Args) {
+  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+    const char *GPUName = A->getValue();
+    return llvm::StringSwitch<const char *>(GPUName)
+        .Cases("rv630", "rv635", "r600")
+        .Cases("rv610", "rv620", "rs780", "rs880")
+        .Case("rv740", "rv770")
+        .Case("palm", "cedar")
+        .Cases("sumo", "sumo2", "sumo")
+        .Case("hemlock", "cypress")
+        .Case("aruba", "cayman")
+        .Default(GPUName);
+  }
+  return "";
+}
+
+static std::string getLanaiTargetCPU(const ArgList &Args) {
+  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+    return A->getValue();
+  }
+  return "";
+}
+
+/// Get the (LLVM) name of the WebAssembly cpu we are targeting.
+static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
+  // If we have -mcpu=, use that.
+  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+    StringRef CPU = A->getValue();
+
+#ifdef __wasm__
+    // Handle "native" by examining the host. "native" isn't meaningful when
+    // cross compiling, so only support this when the host is also WebAssembly.
+    if (CPU == "native")
+      return llvm::sys::getHostCPUName();
+#endif
+
+    return CPU;
+  }
+
+  return "generic";
+}
+
+std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
+                              bool FromAs) {
+  Arg *A;
+
+  switch (T.getArch()) {
+  default:
+    return "";
+
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+    return aarch64::getAArch64TargetCPU(Args, A);
+
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb: {
+    StringRef MArch, MCPU;
+    arm::getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
+    return arm::getARMTargetCPU(MCPU, MArch, T);
+  }
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el: {
+    StringRef CPUName;
+    StringRef ABIName;
+    mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
+    return CPUName;
+  }
+
+  case llvm::Triple::nvptx:
+  case llvm::Triple::nvptx64:
+    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+      return A->getValue();
+    return "";
+
+  case llvm::Triple::ppc:
+  case llvm::Triple::ppc64:
+  case llvm::Triple::ppc64le: {
+    std::string TargetCPUName = ppc::getPPCTargetCPU(Args);
+    // LLVM may default to generating code for the native CPU,
+    // but, like gcc, we default to a more generic option for
+    // each architecture. (except on Darwin)
+    if (TargetCPUName.empty() && !T.isOSDarwin()) {
+      if (T.getArch() == llvm::Triple::ppc64)
+        TargetCPUName = "ppc64";
+      else if (T.getArch() == llvm::Triple::ppc64le)
+        TargetCPUName = "ppc64le";
+      else
+        TargetCPUName = "ppc";
+    }
+    return TargetCPUName;
+  }
+
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+  case llvm::Triple::sparcv9:
+    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+      return A->getValue();
+    return "";
+
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    return x86::getX86TargetCPU(Args, T);
+
+  case llvm::Triple::hexagon:
+    return "hexagon" +
+           toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
+
+  case llvm::Triple::lanai:
+    return getLanaiTargetCPU(Args);
+
+  case llvm::Triple::systemz:
+    return systemz::getSystemZTargetCPU(Args);
+
+  case llvm::Triple::r600:
+  case llvm::Triple::amdgcn:
+    return getR600TargetGPU(Args);
+
+  case llvm::Triple::wasm32:
+  case llvm::Triple::wasm64:
+    return getWebAssemblyTargetCPU(Args);
+  }
+}
+
+unsigned tools::getLTOParallelism(const ArgList &Args, const Driver &D) {
+  unsigned Parallelism = 0;
+  Arg *LtoJobsArg = Args.getLastArg(options::OPT_flto_jobs_EQ);
+  if (LtoJobsArg &&
+      StringRef(LtoJobsArg->getValue()).getAsInteger(10, Parallelism))
+    D.Diag(diag::err_drv_invalid_int_value) << LtoJobsArg->getAsString(Args)
+                                            << LtoJobsArg->getValue();
+  return Parallelism;
+}
+
+// CloudABI and WebAssembly use -ffunction-sections and -fdata-sections by
+// default.
+bool tools::isUseSeparateSections(const llvm::Triple &Triple) {
+  return Triple.getOS() == llvm::Triple::CloudABI ||
+         Triple.getArch() == llvm::Triple::wasm32 ||
+         Triple.getArch() == llvm::Triple::wasm64;
+}
+
+void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args,
+                          ArgStringList &CmdArgs, bool IsThinLTO,
+                          const Driver &D) {
+  // Tell the linker to load the plugin. This has to come before AddLinkerInputs
+  // as gold requires -plugin to come before any -plugin-opt that -Wl might
+  // forward.
+  CmdArgs.push_back("-plugin");
+  std::string Plugin =
+      ToolChain.getDriver().Dir + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold.so";
+  CmdArgs.push_back(Args.MakeArgString(Plugin));
+
+  // Try to pass driver level flags relevant to LTO code generation down to
+  // the plugin.
+
+  // Handle flags for selecting CPU variants.
+  std::string CPU = getCPUName(Args, ToolChain.getTriple());
+  if (!CPU.empty())
+    CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU));
+
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    StringRef OOpt;
+    if (A->getOption().matches(options::OPT_O4) ||
+        A->getOption().matches(options::OPT_Ofast))
+      OOpt = "3";
+    else if (A->getOption().matches(options::OPT_O))
+      OOpt = A->getValue();
+    else if (A->getOption().matches(options::OPT_O0))
+      OOpt = "0";
+    if (!OOpt.empty())
+      CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=O") + OOpt));
+  }
+
+  if (IsThinLTO)
+    CmdArgs.push_back("-plugin-opt=thinlto");
+
+  if (unsigned Parallelism = getLTOParallelism(Args, D))
+    CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=jobs=") +
+                                         llvm::to_string(Parallelism)));
+
+  // If an explicit debugger tuning argument appeared, pass it along.
+  if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
+                               options::OPT_ggdbN_Group)) {
+    if (A->getOption().matches(options::OPT_glldb))
+      CmdArgs.push_back("-plugin-opt=-debugger-tune=lldb");
+    else if (A->getOption().matches(options::OPT_gsce))
+      CmdArgs.push_back("-plugin-opt=-debugger-tune=sce");
+    else
+      CmdArgs.push_back("-plugin-opt=-debugger-tune=gdb");
+  }
+
+  bool UseSeparateSections =
+      isUseSeparateSections(ToolChain.getEffectiveTriple());
+
+  if (Args.hasFlag(options::OPT_ffunction_sections,
+                   options::OPT_fno_function_sections, UseSeparateSections)) {
+    CmdArgs.push_back("-plugin-opt=-function-sections");
+  }
+
+  if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
+                   UseSeparateSections)) {
+    CmdArgs.push_back("-plugin-opt=-data-sections");
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
+    StringRef FName = A->getValue();
+    if (!llvm::sys::fs::exists(FName))
+      D.Diag(diag::err_drv_no_such_file) << FName;
+    else
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-plugin-opt=sample-profile=") + FName));
+  }
+}
+
+void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
+                                 ArgStringList &CmdArgs) {
+  // In the cross-compilation case, arch-specific library path is likely
+  // unavailable at runtime.
+  if (TC.isCrossCompiling()) return;
+
+  std::string CandidateRPath = TC.getArchSpecificLibPath();
+  if (TC.getVFS().exists(CandidateRPath)) {
+    CmdArgs.push_back("-rpath");
+    CmdArgs.push_back(Args.MakeArgString(CandidateRPath.c_str()));
+  }
+}
+
+void tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
+                             const ArgList &Args) {
+  if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
+                    options::OPT_fno_openmp, false))
+    return;
+
+  switch (TC.getDriver().getOpenMPRuntime(Args)) {
+  case Driver::OMPRT_OMP:
+    CmdArgs.push_back("-lomp");
+    break;
+  case Driver::OMPRT_GOMP:
+    CmdArgs.push_back("-lgomp");
+    break;
+  case Driver::OMPRT_IOMP5:
+    CmdArgs.push_back("-liomp5");
+    break;
+  case Driver::OMPRT_Unknown:
+    // Already diagnosed.
+    break;
+  }
+
+  addArchSpecificRPath(TC, Args, CmdArgs);
+}
+
+static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
+                                ArgStringList &CmdArgs, StringRef Sanitizer,
+                                bool IsShared, bool IsWhole) {
+  // Wrap any static runtimes that must be forced into executable in
+  // whole-archive.
+  if (IsWhole) CmdArgs.push_back("-whole-archive");
+  CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared));
+  if (IsWhole) CmdArgs.push_back("-no-whole-archive");
+
+  if (IsShared) {
+    addArchSpecificRPath(TC, Args, CmdArgs);
+  }
+}
+
+// Tries to use a file with the list of dynamic symbols that need to be exported
+// from the runtime library. Returns true if the file was found.
+static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
+                                    ArgStringList &CmdArgs,
+                                    StringRef Sanitizer) {
+  SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer));
+  if (llvm::sys::fs::exists(SanRT + ".syms")) {
+    CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
+    return true;
+  }
+  return false;
+}
+
+void tools::linkSanitizerRuntimeDeps(const ToolChain &TC,
+                                     ArgStringList &CmdArgs) {
+  // Force linking against the system libraries sanitizers depends on
+  // (see PR15823 why this is necessary).
+  CmdArgs.push_back("--no-as-needed");
+  // There's no libpthread or librt on RTEMS.
+  if (TC.getTriple().getOS() != llvm::Triple::RTEMS) {
+    CmdArgs.push_back("-lpthread");
+    CmdArgs.push_back("-lrt");
+  }
+  CmdArgs.push_back("-lm");
+  // There's no libdl on FreeBSD or RTEMS.
+  if (TC.getTriple().getOS() != llvm::Triple::FreeBSD &&
+      TC.getTriple().getOS() != llvm::Triple::RTEMS)
+    CmdArgs.push_back("-ldl");
+}
+
+static void
+collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
+                         SmallVectorImpl<StringRef> &SharedRuntimes,
+                         SmallVectorImpl<StringRef> &StaticRuntimes,
+                         SmallVectorImpl<StringRef> &NonWholeStaticRuntimes,
+                         SmallVectorImpl<StringRef> &HelperStaticRuntimes,
+                         SmallVectorImpl<StringRef> &RequiredSymbols) {
+  const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
+  // Collect shared runtimes.
+  if (SanArgs.needsAsanRt() && SanArgs.needsSharedAsanRt()) {
+    SharedRuntimes.push_back("asan");
+  }
+  // The stats_client library is also statically linked into DSOs.
+  if (SanArgs.needsStatsRt())
+    StaticRuntimes.push_back("stats_client");
+
+  // Collect static runtimes.
+  if (Args.hasArg(options::OPT_shared) || TC.getTriple().isAndroid()) {
+    // Don't link static runtimes into DSOs or if compiling for Android.
+    return;
+  }
+  if (SanArgs.needsAsanRt()) {
+    if (SanArgs.needsSharedAsanRt()) {
+      HelperStaticRuntimes.push_back("asan-preinit");
+    } else {
+      StaticRuntimes.push_back("asan");
+      if (SanArgs.linkCXXRuntimes())
+        StaticRuntimes.push_back("asan_cxx");
+    }
+  }
+  if (SanArgs.needsDfsanRt())
+    StaticRuntimes.push_back("dfsan");
+  if (SanArgs.needsLsanRt())
+    StaticRuntimes.push_back("lsan");
+  if (SanArgs.needsMsanRt()) {
+    StaticRuntimes.push_back("msan");
+    if (SanArgs.linkCXXRuntimes())
+      StaticRuntimes.push_back("msan_cxx");
+  }
+  if (SanArgs.needsTsanRt()) {
+    StaticRuntimes.push_back("tsan");
+    if (SanArgs.linkCXXRuntimes())
+      StaticRuntimes.push_back("tsan_cxx");
+  }
+  if (SanArgs.needsUbsanRt()) {
+    StaticRuntimes.push_back("ubsan_standalone");
+    if (SanArgs.linkCXXRuntimes())
+      StaticRuntimes.push_back("ubsan_standalone_cxx");
+  }
+  if (SanArgs.needsSafeStackRt()) {
+    NonWholeStaticRuntimes.push_back("safestack");
+    RequiredSymbols.push_back("__safestack_init");
+  }
+  if (SanArgs.needsCfiRt())
+    StaticRuntimes.push_back("cfi");
+  if (SanArgs.needsCfiDiagRt()) {
+    StaticRuntimes.push_back("cfi_diag");
+    if (SanArgs.linkCXXRuntimes())
+      StaticRuntimes.push_back("ubsan_standalone_cxx");
+  }
+  if (SanArgs.needsStatsRt()) {
+    NonWholeStaticRuntimes.push_back("stats");
+    RequiredSymbols.push_back("__sanitizer_stats_register");
+  }
+  if (SanArgs.needsEsanRt())
+    StaticRuntimes.push_back("esan");
+}
+
+// Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
+// C runtime, etc). Returns true if sanitizer system deps need to be linked in.
+bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
+                                 ArgStringList &CmdArgs) {
+  SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
+      NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols;
+  collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
+                           NonWholeStaticRuntimes, HelperStaticRuntimes,
+                           RequiredSymbols);
+  for (auto RT : SharedRuntimes)
+    addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false);
+  for (auto RT : HelperStaticRuntimes)
+    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
+  bool AddExportDynamic = false;
+  for (auto RT : StaticRuntimes) {
+    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
+    AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
+  }
+  for (auto RT : NonWholeStaticRuntimes) {
+    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, false);
+    AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
+  }
+  for (auto S : RequiredSymbols) {
+    CmdArgs.push_back("-u");
+    CmdArgs.push_back(Args.MakeArgString(S));
+  }
+  // If there is a static runtime with no dynamic list, force all the symbols
+  // to be dynamic to be sure we export sanitizer interface functions.
+  if (AddExportDynamic)
+    CmdArgs.push_back("-export-dynamic");
+
+  const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
+  if (SanArgs.hasCrossDsoCfi() && !AddExportDynamic)
+    CmdArgs.push_back("-export-dynamic-symbol=__cfi_check");
+
+  return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty();
+}
+
+bool tools::areOptimizationsEnabled(const ArgList &Args) {
+  // Find the last -O arg and see if it is non-zero.
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
+    return !A->getOption().matches(options::OPT_O0);
+  // Defaults to -O0.
+  return false;
+}
+
+const char *tools::SplitDebugName(const ArgList &Args, const InputInfo &Input) {
+  Arg *FinalOutput = Args.getLastArg(options::OPT_o);
+  if (FinalOutput && Args.hasArg(options::OPT_c)) {
+    SmallString<128> T(FinalOutput->getValue());
+    llvm::sys::path::replace_extension(T, "dwo");
+    return Args.MakeArgString(T);
+  } else {
+    // Use the compilation dir.
+    SmallString<128> T(
+        Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
+    SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput()));
+    llvm::sys::path::replace_extension(F, "dwo");
+    T += F;
+    return Args.MakeArgString(F);
+  }
+}
+
+void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
+                           const JobAction &JA, const ArgList &Args,
+                           const InputInfo &Output, const char *OutFile) {
+  ArgStringList ExtractArgs;
+  ExtractArgs.push_back("--extract-dwo");
+
+  ArgStringList StripArgs;
+  StripArgs.push_back("--strip-dwo");
+
+  // Grabbing the output of the earlier compile step.
+  StripArgs.push_back(Output.getFilename());
+  ExtractArgs.push_back(Output.getFilename());
+  ExtractArgs.push_back(OutFile);
+
+  const char *Exec = Args.MakeArgString(TC.GetProgramPath("objcopy"));
+  InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename());
+
+  // First extract the dwo sections.
+  C.addCommand(llvm::make_unique<Command>(JA, T, Exec, ExtractArgs, II));
+
+  // Then remove them from the original .o file.
+  C.addCommand(llvm::make_unique<Command>(JA, T, Exec, StripArgs, II));
+}
+
+// Claim options we don't want to warn if they are unused. We do this for
+// options that build systems might add but are unused when assembling or only
+// running the preprocessor for example.
+void tools::claimNoWarnArgs(const ArgList &Args) {
+  // Don't warn about unused -f(no-)?lto.  This can happen when we're
+  // preprocessing, precompiling or assembling.
+  Args.ClaimAllArgs(options::OPT_flto_EQ);
+  Args.ClaimAllArgs(options::OPT_flto);
+  Args.ClaimAllArgs(options::OPT_fno_lto);
+}
+
+Arg *tools::getLastProfileUseArg(const ArgList &Args) {
+  auto *ProfileUseArg = Args.getLastArg(
+      options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ,
+      options::OPT_fprofile_use, options::OPT_fprofile_use_EQ,
+      options::OPT_fno_profile_instr_use);
+
+  if (ProfileUseArg &&
+      ProfileUseArg->getOption().matches(options::OPT_fno_profile_instr_use))
+    ProfileUseArg = nullptr;
+
+  return ProfileUseArg;
+}
+
+/// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments.  Then,
+/// smooshes them together with platform defaults, to decide whether
+/// this compile should be using PIC mode or not. Returns a tuple of
+/// (RelocationModel, PICLevel, IsPIE).
+std::tuple<llvm::Reloc::Model, unsigned, bool>
+tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) {
+  const llvm::Triple &EffectiveTriple = ToolChain.getEffectiveTriple();
+  const llvm::Triple &Triple = ToolChain.getTriple();
+
+  bool PIE = ToolChain.isPIEDefault();
+  bool PIC = PIE || ToolChain.isPICDefault();
+  // The Darwin/MachO default to use PIC does not apply when using -static.
+  if (Triple.isOSBinFormatMachO() && Args.hasArg(options::OPT_static))
+    PIE = PIC = false;
+  bool IsPICLevelTwo = PIC;
+
+  bool KernelOrKext =
+      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
+
+  // Android-specific defaults for PIC/PIE
+  if (Triple.isAndroid()) {
+    switch (Triple.getArch()) {
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+    case llvm::Triple::aarch64:
+    case llvm::Triple::mips:
+    case llvm::Triple::mipsel:
+    case llvm::Triple::mips64:
+    case llvm::Triple::mips64el:
+      PIC = true; // "-fpic"
+      break;
+
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+      PIC = true; // "-fPIC"
+      IsPICLevelTwo = true;
+      break;
+
+    default:
+      break;
+    }
+  }
+
+  // OpenBSD-specific defaults for PIE
+  if (Triple.getOS() == llvm::Triple::OpenBSD) {
+    switch (ToolChain.getArch()) {
+    case llvm::Triple::mips64:
+    case llvm::Triple::mips64el:
+    case llvm::Triple::sparcel:
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+      IsPICLevelTwo = false; // "-fpie"
+      break;
+
+    case llvm::Triple::ppc:
+    case llvm::Triple::sparc:
+    case llvm::Triple::sparcv9:
+      IsPICLevelTwo = true; // "-fPIE"
+      break;
+
+    default:
+      break;
+    }
+  }
+
+  // The last argument relating to either PIC or PIE wins, and no
+  // other argument is used. If the last argument is any flavor of the
+  // '-fno-...' arguments, both PIC and PIE are disabled. Any PIE
+  // option implicitly enables PIC at the same level.
+  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
+                                    options::OPT_fpic, options::OPT_fno_pic,
+                                    options::OPT_fPIE, options::OPT_fno_PIE,
+                                    options::OPT_fpie, options::OPT_fno_pie);
+  if (Triple.isOSWindows() && LastPICArg &&
+      LastPICArg ==
+          Args.getLastArg(options::OPT_fPIC, options::OPT_fpic,
+                          options::OPT_fPIE, options::OPT_fpie)) {
+    ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
+        << LastPICArg->getSpelling() << Triple.str();
+    if (Triple.getArch() == llvm::Triple::x86_64)
+      return std::make_tuple(llvm::Reloc::PIC_, 2U, false);
+    return std::make_tuple(llvm::Reloc::Static, 0U, false);
+  }
+
+  // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
+  // is forced, then neither PIC nor PIE flags will have no effect.
+  if (!ToolChain.isPICDefaultForced()) {
+    if (LastPICArg) {
+      Option O = LastPICArg->getOption();
+      if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
+          O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
+        PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
+        PIC =
+            PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
+        IsPICLevelTwo =
+            O.matches(options::OPT_fPIE) || O.matches(options::OPT_fPIC);
+      } else {
+        PIE = PIC = false;
+        if (EffectiveTriple.isPS4CPU()) {
+          Arg *ModelArg = Args.getLastArg(options::OPT_mcmodel_EQ);
+          StringRef Model = ModelArg ? ModelArg->getValue() : "";
+          if (Model != "kernel") {
+            PIC = true;
+            ToolChain.getDriver().Diag(diag::warn_drv_ps4_force_pic)
+                << LastPICArg->getSpelling();
+          }
+        }
+      }
+    }
+  }
+
+  // Introduce a Darwin and PS4-specific hack. If the default is PIC, but the
+  // PIC level would've been set to level 1, force it back to level 2 PIC
+  // instead.
+  if (PIC && (Triple.isOSDarwin() || EffectiveTriple.isPS4CPU()))
+    IsPICLevelTwo |= ToolChain.isPICDefault();
+
+  // This kernel flags are a trump-card: they will disable PIC/PIE
+  // generation, independent of the argument order.
+  if (KernelOrKext &&
+      ((!EffectiveTriple.isiOS() || EffectiveTriple.isOSVersionLT(6)) &&
+       !EffectiveTriple.isWatchOS()))
+    PIC = PIE = false;
+
+  if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
+    // This is a very special mode. It trumps the other modes, almost no one
+    // uses it, and it isn't even valid on any OS but Darwin.
+    if (!Triple.isOSDarwin())
+      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getSpelling() << Triple.str();
+
+    // FIXME: Warn when this flag trumps some other PIC or PIE flag.
+
+    // Only a forced PIC mode can cause the actual compile to have PIC defines
+    // etc., no flags are sufficient. This behavior was selected to closely
+    // match that of llvm-gcc and Apple GCC before that.
+    PIC = ToolChain.isPICDefault() && ToolChain.isPICDefaultForced();
+
+    return std::make_tuple(llvm::Reloc::DynamicNoPIC, PIC ? 2U : 0U, false);
+  }
+
+  bool EmbeddedPISupported;
+  switch (Triple.getArch()) {
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+      EmbeddedPISupported = true;
+      break;
+    default:
+      EmbeddedPISupported = false;
+      break;
+  }
+
+  bool ROPI = false, RWPI = false;
+  Arg* LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi);
+  if (LastROPIArg && LastROPIArg->getOption().matches(options::OPT_fropi)) {
+    if (!EmbeddedPISupported)
+      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
+          << LastROPIArg->getSpelling() << Triple.str();
+    ROPI = true;
+  }
+  Arg *LastRWPIArg = Args.getLastArg(options::OPT_frwpi, options::OPT_fno_rwpi);
+  if (LastRWPIArg && LastRWPIArg->getOption().matches(options::OPT_frwpi)) {
+    if (!EmbeddedPISupported)
+      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
+          << LastRWPIArg->getSpelling() << Triple.str();
+    RWPI = true;
+  }
+
+  // ROPI and RWPI are not comaptible with PIC or PIE.
+  if ((ROPI || RWPI) && (PIC || PIE))
+    ToolChain.getDriver().Diag(diag::err_drv_ropi_rwpi_incompatible_with_pic);
+
+  // When targettng MIPS64 with N64, the default is PIC, unless -mno-abicalls is
+  // used.
+  if ((Triple.getArch() == llvm::Triple::mips64 ||
+       Triple.getArch() == llvm::Triple::mips64el) &&
+      Args.hasArg(options::OPT_mno_abicalls))
+    return std::make_tuple(llvm::Reloc::Static, 0U, false);
+
+  if (PIC)
+    return std::make_tuple(llvm::Reloc::PIC_, IsPICLevelTwo ? 2U : 1U, PIE);
+
+  llvm::Reloc::Model RelocM = llvm::Reloc::Static;
+  if (ROPI && RWPI)
+    RelocM = llvm::Reloc::ROPI_RWPI;
+  else if (ROPI)
+    RelocM = llvm::Reloc::ROPI;
+  else if (RWPI)
+    RelocM = llvm::Reloc::RWPI;
+
+  return std::make_tuple(RelocM, 0U, false);
+}
+
+void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
+                             ArgStringList &CmdArgs) {
+  llvm::Reloc::Model RelocationModel;
+  unsigned PICLevel;
+  bool IsPIE;
+  std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(ToolChain, Args);
+
+  if (RelocationModel != llvm::Reloc::Static)
+    CmdArgs.push_back("-KPIC");
+}
+
+/// \brief Determine whether Objective-C automated reference counting is
+/// enabled.
+bool tools::isObjCAutoRefCount(const ArgList &Args) {
+  return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
+}
+
+static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
+                      ArgStringList &CmdArgs, const ArgList &Args) {
+  bool isAndroid = Triple.isAndroid();
+  bool isCygMing = Triple.isOSCygMing();
+  bool IsIAMCU = Triple.isOSIAMCU();
+  bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
+                      Args.hasArg(options::OPT_static);
+  if (!D.CCCIsCXX())
+    CmdArgs.push_back("-lgcc");
+
+  if (StaticLibgcc || isAndroid) {
+    if (D.CCCIsCXX())
+      CmdArgs.push_back("-lgcc");
+  } else {
+    if (!D.CCCIsCXX() && !isCygMing)
+      CmdArgs.push_back("--as-needed");
+    CmdArgs.push_back("-lgcc_s");
+    if (!D.CCCIsCXX() && !isCygMing)
+      CmdArgs.push_back("--no-as-needed");
+  }
+
+  if (StaticLibgcc && !isAndroid && !IsIAMCU)
+    CmdArgs.push_back("-lgcc_eh");
+  else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
+    CmdArgs.push_back("-lgcc");
+
+  // According to Android ABI, we have to link with libdl if we are
+  // linking with non-static libgcc.
+  //
+  // NOTE: This fixes a link error on Android MIPS as well.  The non-static
+  // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
+  if (isAndroid && !StaticLibgcc)
+    CmdArgs.push_back("-ldl");
+}
+
+void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
+                           ArgStringList &CmdArgs, const ArgList &Args) {
+  // Make use of compiler-rt if --rtlib option is used
+  ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
+
+  switch (RLT) {
+  case ToolChain::RLT_CompilerRT:
+    switch (TC.getTriple().getOS()) {
+    default:
+      llvm_unreachable("unsupported OS");
+    case llvm::Triple::Win32:
+    case llvm::Triple::Linux:
+    case llvm::Triple::Fuchsia:
+      CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
+      break;
+    }
+    break;
+  case ToolChain::RLT_Libgcc:
+    // Make sure libgcc is not used under MSVC environment by default
+    if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
+      // Issue error diagnostic if libgcc is explicitly specified
+      // through command line as --rtlib option argument.
+      if (Args.hasArg(options::OPT_rtlib_EQ)) {
+        TC.getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
+            << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
+      }
+    } else
+      AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
+    break;
+  }
+}
diff --git a/lib/Driver/ToolChains/CommonArgs.h b/lib/Driver/ToolChains/CommonArgs.h
new file mode 100644
index 0000000..252dbf5
--- /dev/null
+++ b/lib/Driver/ToolChains/CommonArgs.h
@@ -0,0 +1,95 @@
+//===--- CommonArgs.h - Args handling for multiple toolchains ---*- 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_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
+
+#include "InputInfo.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+#include "llvm/Support/CodeGen.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+void addPathIfExists(const Driver &D, const Twine &Path,
+                     ToolChain::path_list &Paths);
+
+void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
+                     const llvm::opt::ArgList &Args,
+                     llvm::opt::ArgStringList &CmdArgs, const JobAction &JA);
+
+void claimNoWarnArgs(const llvm::opt::ArgList &Args);
+
+bool addSanitizerRuntimes(const ToolChain &TC, const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs);
+
+void linkSanitizerRuntimeDeps(const ToolChain &TC,
+                              llvm::opt::ArgStringList &CmdArgs);
+
+void AddRunTimeLibs(const ToolChain &TC, const Driver &D,
+                    llvm::opt::ArgStringList &CmdArgs,
+                    const llvm::opt::ArgList &Args);
+
+const char *SplitDebugName(const llvm::opt::ArgList &Args,
+                           const InputInfo &Input);
+
+void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
+                    const JobAction &JA, const llvm::opt::ArgList &Args,
+                    const InputInfo &Output, const char *OutFile);
+
+void AddGoldPlugin(const ToolChain &ToolChain, const llvm::opt::ArgList &Args,
+                   llvm::opt::ArgStringList &CmdArgs, bool IsThinLTO,
+                   const Driver &D);
+
+std::tuple<llvm::Reloc::Model, unsigned, bool>
+ParsePICArgs(const ToolChain &ToolChain, const llvm::opt::ArgList &Args);
+
+void AddAssemblerKPIC(const ToolChain &ToolChain,
+                      const llvm::opt::ArgList &Args,
+                      llvm::opt::ArgStringList &CmdArgs);
+
+void addArchSpecificRPath(const ToolChain &TC, const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs);
+void addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC,
+                      const llvm::opt::ArgList &Args);
+
+llvm::opt::Arg *getLastProfileUseArg(const llvm::opt::ArgList &Args);
+
+bool isObjCAutoRefCount(const llvm::opt::ArgList &Args);
+
+unsigned getLTOParallelism(const llvm::opt::ArgList &Args, const Driver &D);
+
+bool areOptimizationsEnabled(const llvm::opt::ArgList &Args);
+
+bool isUseSeparateSections(const llvm::Triple &Triple);
+
+void addDirectoryList(const llvm::opt::ArgList &Args,
+                      llvm::opt::ArgStringList &CmdArgs, const char *ArgName,
+                      const char *EnvVar);
+
+void AddTargetFeature(const llvm::opt::ArgList &Args,
+                      std::vector<StringRef> &Features,
+                      llvm::opt::OptSpecifier OnOpt,
+                      llvm::opt::OptSpecifier OffOpt, StringRef FeatureName);
+
+std::string getCPUName(const llvm::opt::ArgList &Args, const llvm::Triple &T,
+                       bool FromAs = false);
+
+void handleTargetFeaturesGroup(const llvm::opt::ArgList &Args,
+                               std::vector<StringRef> &Features,
+                               llvm::opt::OptSpecifier Group);
+
+} // end namespace tools
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
diff --git a/lib/Driver/ToolChains/Contiki.cpp b/lib/Driver/ToolChains/Contiki.cpp
new file mode 100644
index 0000000..7f74bfc
--- /dev/null
+++ b/lib/Driver/ToolChains/Contiki.cpp
@@ -0,0 +1,28 @@
+//===--- Contiki.cpp - Contiki ToolChain Implementations --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Contiki.h"
+#include "CommonArgs.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+Contiki::Contiki(const Driver &D, const llvm::Triple &Triple,
+                 const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {}
+
+SanitizerMask Contiki::getSupportedSanitizers() const {
+  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  if (IsX86)
+    Res |= SanitizerKind::SafeStack;
+  return Res;
+}
diff --git a/lib/Driver/ToolChains/Contiki.h b/lib/Driver/ToolChains/Contiki.h
new file mode 100644
index 0000000..f6e1507
--- /dev/null
+++ b/lib/Driver/ToolChains/Contiki.h
@@ -0,0 +1,38 @@
+//===--- Contiki.h - Contiki ToolChain Implementations ----------*- 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_LIB_DRIVER_TOOLCHAINS_CONTIKI_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CONTIKI_H
+
+#include "Gnu.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY Contiki : public Generic_ELF {
+public:
+  Contiki(const Driver &D, const llvm::Triple &Triple,
+          const llvm::opt::ArgList &Args);
+
+  // No support for finding a C++ standard library yet.
+  std::string findLibCxxIncludePath() const override { return ""; }
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override {}
+
+  SanitizerMask getSupportedSanitizers() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CONTIKI_H
diff --git a/lib/Driver/ToolChains/CrossWindows.cpp b/lib/Driver/ToolChains/CrossWindows.cpp
new file mode 100644
index 0000000..dcf085a
--- /dev/null
+++ b/lib/Driver/ToolChains/CrossWindows.cpp
@@ -0,0 +1,318 @@
+//===--- CrossWindowsToolChain.cpp - Cross Windows Tool Chain -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CrossWindows.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+
+using llvm::opt::ArgList;
+
+void tools::CrossWindows::Assembler::ConstructJob(
+    Compilation &C, const JobAction &JA, const InputInfo &Output,
+    const InputInfoList &Inputs, const ArgList &Args,
+    const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  const auto &TC =
+      static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
+  ArgStringList CmdArgs;
+  const char *Exec;
+
+  switch (TC.getArch()) {
+  default:
+    llvm_unreachable("unsupported architecture");
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    break;
+  case llvm::Triple::x86:
+    CmdArgs.push_back("--32");
+    break;
+  case llvm::Triple::x86_64:
+    CmdArgs.push_back("--64");
+    break;
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &Input : Inputs)
+    CmdArgs.push_back(Input.getFilename());
+
+  const std::string Assembler = TC.GetProgramPath("as");
+  Exec = Args.MakeArgString(Assembler);
+
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void tools::CrossWindows::Linker::ConstructJob(
+    Compilation &C, const JobAction &JA, const InputInfo &Output,
+    const InputInfoList &Inputs, const ArgList &Args,
+    const char *LinkingOutput) const {
+  const auto &TC =
+      static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
+  const llvm::Triple &T = TC.getTriple();
+  const Driver &D = TC.getDriver();
+  SmallString<128> EntryPoint;
+  ArgStringList CmdArgs;
+  const char *Exec;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_w);
+  // Other warning options are already handled somewhere else.
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (Args.hasArg(options::OPT_pie))
+    CmdArgs.push_back("-pie");
+  if (Args.hasArg(options::OPT_rdynamic))
+    CmdArgs.push_back("-export-dynamic");
+  if (Args.hasArg(options::OPT_s))
+    CmdArgs.push_back("--strip-all");
+
+  CmdArgs.push_back("-m");
+  switch (TC.getArch()) {
+  default:
+    llvm_unreachable("unsupported architecture");
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    // FIXME: this is incorrect for WinCE
+    CmdArgs.push_back("thumb2pe");
+    break;
+  case llvm::Triple::x86:
+    CmdArgs.push_back("i386pe");
+    EntryPoint.append("_");
+    break;
+  case llvm::Triple::x86_64:
+    CmdArgs.push_back("i386pep");
+    break;
+  }
+
+  if (Args.hasArg(options::OPT_shared)) {
+    switch (T.getArch()) {
+    default:
+      llvm_unreachable("unsupported architecture");
+    case llvm::Triple::arm:
+    case llvm::Triple::thumb:
+    case llvm::Triple::x86_64:
+      EntryPoint.append("_DllMainCRTStartup");
+      break;
+    case llvm::Triple::x86:
+      EntryPoint.append("_DllMainCRTStartup@12");
+      break;
+    }
+
+    CmdArgs.push_back("-shared");
+    CmdArgs.push_back("-Bdynamic");
+
+    CmdArgs.push_back("--enable-auto-image-base");
+
+    CmdArgs.push_back("--entry");
+    CmdArgs.push_back(Args.MakeArgString(EntryPoint));
+  } else {
+    EntryPoint.append("mainCRTStartup");
+
+    CmdArgs.push_back(Args.hasArg(options::OPT_static) ? "-Bstatic"
+                                                       : "-Bdynamic");
+
+    if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+      CmdArgs.push_back("--entry");
+      CmdArgs.push_back(Args.MakeArgString(EntryPoint));
+    }
+
+    // FIXME: handle subsystem
+  }
+
+  // NOTE: deal with multiple definitions on Windows (e.g. COMDAT)
+  CmdArgs.push_back("--allow-multiple-definition");
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_rdynamic)) {
+    SmallString<261> ImpLib(Output.getFilename());
+    llvm::sys::path::replace_extension(ImpLib, ".lib");
+
+    CmdArgs.push_back("--out-implib");
+    CmdArgs.push_back(Args.MakeArgString(ImpLib));
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    const std::string CRTPath(D.SysRoot + "/usr/lib/");
+    const char *CRTBegin;
+
+    CRTBegin =
+        Args.hasArg(options::OPT_shared) ? "crtbeginS.obj" : "crtbegin.obj";
+    CmdArgs.push_back(Args.MakeArgString(CRTPath + CRTBegin));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  TC.AddFilePathLibArgs(Args, CmdArgs);
+  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
+
+  if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
+                     !Args.hasArg(options::OPT_static);
+    if (StaticCXX)
+      CmdArgs.push_back("-Bstatic");
+    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
+    if (StaticCXX)
+      CmdArgs.push_back("-Bdynamic");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
+      // TODO handle /MT[d] /MD[d]
+      CmdArgs.push_back("-lmsvcrt");
+      AddRunTimeLibs(TC, D, CmdArgs, Args);
+    }
+  }
+
+  if (TC.getSanitizerArgs().needsAsanRt()) {
+    // TODO handle /MT[d] /MD[d]
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
+    } else {
+      for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
+        CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
+      // Make sure the dynamic runtime thunk is not optimized out at link time
+      // to ensure proper SEH handling.
+      CmdArgs.push_back(Args.MakeArgString("--undefined"));
+      CmdArgs.push_back(Args.MakeArgString(TC.getArch() == llvm::Triple::x86
+                                               ? "___asan_seh_interceptor"
+                                               : "__asan_seh_interceptor"));
+    }
+  }
+
+  Exec = Args.MakeArgString(TC.GetLinkerPath());
+
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+CrossWindowsToolChain::CrossWindowsToolChain(const Driver &D,
+                                             const llvm::Triple &T,
+                                             const llvm::opt::ArgList &Args)
+    : Generic_GCC(D, T, Args) {
+  if (GetCXXStdlibType(Args) == ToolChain::CST_Libstdcxx) {
+    const std::string &SysRoot = D.SysRoot;
+
+    // libstdc++ resides in /usr/lib, but depends on libgcc which is placed in
+    // /usr/lib/gcc.
+    getFilePaths().push_back(SysRoot + "/usr/lib");
+    getFilePaths().push_back(SysRoot + "/usr/lib/gcc");
+  }
+}
+
+bool CrossWindowsToolChain::IsUnwindTablesDefault() const {
+  // FIXME: all non-x86 targets need unwind tables, however, LLVM currently does
+  // not know how to emit them.
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool CrossWindowsToolChain::isPICDefault() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool CrossWindowsToolChain::isPIEDefault() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool CrossWindowsToolChain::isPICDefaultForced() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+void CrossWindowsToolChain::
+AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const {
+  const Driver &D = getDriver();
+  const std::string &SysRoot = D.SysRoot;
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
+  addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    SmallString<128> ResourceDir(D.ResourceDir);
+    llvm::sys::path::append(ResourceDir, "include");
+    addSystemInclude(DriverArgs, CC1Args, ResourceDir);
+  }
+  for (const auto &P : DriverArgs.getAllArgValues(options::OPT_isystem_after))
+    addSystemInclude(DriverArgs, CC1Args, P);
+  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
+}
+
+void CrossWindowsToolChain::
+AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                             llvm::opt::ArgStringList &CC1Args) const {
+  const llvm::Triple &Triple = getTriple();
+  const std::string &SysRoot = getDriver().SysRoot;
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+      DriverArgs.hasArg(options::OPT_nostdincxx))
+    return;
+
+  switch (GetCXXStdlibType(DriverArgs)) {
+  case ToolChain::CST_Libcxx:
+    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/c++/v1");
+    break;
+
+  case ToolChain::CST_Libstdcxx:
+    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/c++");
+    addSystemInclude(DriverArgs, CC1Args,
+                     SysRoot + "/usr/include/c++/" + Triple.str());
+    addSystemInclude(DriverArgs, CC1Args,
+                     SysRoot + "/usr/include/c++/backwards");
+  }
+}
+
+void CrossWindowsToolChain::
+AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs,
+                    llvm::opt::ArgStringList &CC1Args) const {
+  switch (GetCXXStdlibType(DriverArgs)) {
+  case ToolChain::CST_Libcxx:
+    CC1Args.push_back("-lc++");
+    break;
+  case ToolChain::CST_Libstdcxx:
+    CC1Args.push_back("-lstdc++");
+    CC1Args.push_back("-lmingw32");
+    CC1Args.push_back("-lmingwex");
+    CC1Args.push_back("-lgcc");
+    CC1Args.push_back("-lmoldname");
+    CC1Args.push_back("-lmingw32");
+    break;
+  }
+}
+
+clang::SanitizerMask CrossWindowsToolChain::getSupportedSanitizers() const {
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::Address;
+  return Res;
+}
+
+Tool *CrossWindowsToolChain::buildLinker() const {
+  return new tools::CrossWindows::Linker(*this);
+}
+
+Tool *CrossWindowsToolChain::buildAssembler() const {
+  return new tools::CrossWindows::Assembler(*this);
+}
diff --git a/lib/Driver/ToolChains/CrossWindows.h b/lib/Driver/ToolChains/CrossWindows.h
new file mode 100644
index 0000000..5375a63
--- /dev/null
+++ b/lib/Driver/ToolChains/CrossWindows.h
@@ -0,0 +1,88 @@
+//===--- CrossWindows.h - CrossWindows ToolChain Implementation -*- 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_LIB_DRIVER_TOOLCHAINS_CROSSWINDOWS_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CROSSWINDOWS_H
+
+#include "Cuda.h"
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+namespace CrossWindows {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
+public:
+  Assembler(const ToolChain &TC) : Tool("CrossWindows::Assembler", "as", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+public:
+  Linker(const ToolChain &TC)
+      : Tool("CrossWindows::Linker", "ld", TC, RF_Full) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace CrossWindows
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY CrossWindowsToolChain : public Generic_GCC {
+public:
+  CrossWindowsToolChain(const Driver &D, const llvm::Triple &T,
+                        const llvm::opt::ArgList &Args);
+
+  bool IsIntegratedAssemblerDefault() const override { return true; }
+  bool IsUnwindTablesDefault() const override;
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+
+  unsigned int GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
+    return 0;
+  }
+
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void AddClangCXXStdlibIncludeArgs(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+
+  SanitizerMask getSupportedSanitizers() const override;
+
+protected:
+  Tool *buildLinker() const override;
+  Tool *buildAssembler() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CROSSWINDOWS_H
diff --git a/lib/Driver/ToolChains/Cuda.cpp b/lib/Driver/ToolChains/Cuda.cpp
new file mode 100644
index 0000000..42bf164
--- /dev/null
+++ b/lib/Driver/ToolChains/Cuda.cpp
@@ -0,0 +1,488 @@
+//===--- Cuda.cpp - Cuda Tool and ToolChain Implementations -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Cuda.h"
+#include "InputInfo.h"
+#include "clang/Basic/Cuda.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Path.h"
+#include <system_error>
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+// Parses the contents of version.txt in an CUDA installation.  It should
+// contain one line of the from e.g. "CUDA Version 7.5.2".
+static CudaVersion ParseCudaVersionFile(llvm::StringRef V) {
+  if (!V.startswith("CUDA Version "))
+    return CudaVersion::UNKNOWN;
+  V = V.substr(strlen("CUDA Version "));
+  int Major = -1, Minor = -1;
+  auto First = V.split('.');
+  auto Second = First.second.split('.');
+  if (First.first.getAsInteger(10, Major) ||
+      Second.first.getAsInteger(10, Minor))
+    return CudaVersion::UNKNOWN;
+
+  if (Major == 7 && Minor == 0) {
+    // This doesn't appear to ever happen -- version.txt doesn't exist in the
+    // CUDA 7 installs I've seen.  But no harm in checking.
+    return CudaVersion::CUDA_70;
+  }
+  if (Major == 7 && Minor == 5)
+    return CudaVersion::CUDA_75;
+  if (Major == 8 && Minor == 0)
+    return CudaVersion::CUDA_80;
+  return CudaVersion::UNKNOWN;
+}
+
+CudaInstallationDetector::CudaInstallationDetector(
+    const Driver &D, const llvm::Triple &HostTriple,
+    const llvm::opt::ArgList &Args)
+    : D(D) {
+  SmallVector<std::string, 4> CudaPathCandidates;
+
+  // In decreasing order so we prefer newer versions to older versions.
+  std::initializer_list<const char *> Versions = {"8.0", "7.5", "7.0"};
+
+  if (Args.hasArg(clang::driver::options::OPT_cuda_path_EQ)) {
+    CudaPathCandidates.push_back(
+        Args.getLastArgValue(clang::driver::options::OPT_cuda_path_EQ));
+  } else if (HostTriple.isOSWindows()) {
+    for (const char *Ver : Versions)
+      CudaPathCandidates.push_back(
+          D.SysRoot + "/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" +
+          Ver);
+  } else {
+    CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda");
+    for (const char *Ver : Versions)
+      CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-" + Ver);
+  }
+
+  for (const auto &CudaPath : CudaPathCandidates) {
+    if (CudaPath.empty() || !D.getVFS().exists(CudaPath))
+      continue;
+
+    InstallPath = CudaPath;
+    BinPath = CudaPath + "/bin";
+    IncludePath = InstallPath + "/include";
+    LibDevicePath = InstallPath + "/nvvm/libdevice";
+
+    auto &FS = D.getVFS();
+    if (!(FS.exists(IncludePath) && FS.exists(BinPath) &&
+          FS.exists(LibDevicePath)))
+      continue;
+
+    // On Linux, we have both lib and lib64 directories, and we need to choose
+    // based on our triple.  On MacOS, we have only a lib directory.
+    //
+    // It's sufficient for our purposes to be flexible: If both lib and lib64
+    // exist, we choose whichever one matches our triple.  Otherwise, if only
+    // lib exists, we use it.
+    if (HostTriple.isArch64Bit() && FS.exists(InstallPath + "/lib64"))
+      LibPath = InstallPath + "/lib64";
+    else if (FS.exists(InstallPath + "/lib"))
+      LibPath = InstallPath + "/lib";
+    else
+      continue;
+
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile =
+        FS.getBufferForFile(InstallPath + "/version.txt");
+    if (!VersionFile) {
+      // CUDA 7.0 doesn't have a version.txt, so guess that's our version if
+      // version.txt isn't present.
+      Version = CudaVersion::CUDA_70;
+    } else {
+      Version = ParseCudaVersionFile((*VersionFile)->getBuffer());
+    }
+
+    std::error_code EC;
+    for (llvm::sys::fs::directory_iterator LI(LibDevicePath, EC), LE;
+         !EC && LI != LE; LI = LI.increment(EC)) {
+      StringRef FilePath = LI->path();
+      StringRef FileName = llvm::sys::path::filename(FilePath);
+      // Process all bitcode filenames that look like libdevice.compute_XX.YY.bc
+      const StringRef LibDeviceName = "libdevice.";
+      if (!(FileName.startswith(LibDeviceName) && FileName.endswith(".bc")))
+        continue;
+      StringRef GpuArch = FileName.slice(
+          LibDeviceName.size(), FileName.find('.', LibDeviceName.size()));
+      LibDeviceMap[GpuArch] = FilePath.str();
+      // Insert map entries for specifc devices with this compute
+      // capability. NVCC's choice of the libdevice library version is
+      // rather peculiar and depends on the CUDA version.
+      if (GpuArch == "compute_20") {
+        LibDeviceMap["sm_20"] = FilePath;
+        LibDeviceMap["sm_21"] = FilePath;
+        LibDeviceMap["sm_32"] = FilePath;
+      } else if (GpuArch == "compute_30") {
+        LibDeviceMap["sm_30"] = FilePath;
+        if (Version < CudaVersion::CUDA_80) {
+          LibDeviceMap["sm_50"] = FilePath;
+          LibDeviceMap["sm_52"] = FilePath;
+          LibDeviceMap["sm_53"] = FilePath;
+        }
+        LibDeviceMap["sm_60"] = FilePath;
+        LibDeviceMap["sm_61"] = FilePath;
+        LibDeviceMap["sm_62"] = FilePath;
+      } else if (GpuArch == "compute_35") {
+        LibDeviceMap["sm_35"] = FilePath;
+        LibDeviceMap["sm_37"] = FilePath;
+      } else if (GpuArch == "compute_50") {
+        if (Version >= CudaVersion::CUDA_80) {
+          LibDeviceMap["sm_50"] = FilePath;
+          LibDeviceMap["sm_52"] = FilePath;
+          LibDeviceMap["sm_53"] = FilePath;
+        }
+      }
+    }
+
+    IsValid = true;
+    break;
+  }
+}
+
+void CudaInstallationDetector::AddCudaIncludeArgs(
+    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    // Add cuda_wrappers/* to our system include path.  This lets us wrap
+    // standard library headers.
+    SmallString<128> P(D.ResourceDir);
+    llvm::sys::path::append(P, "include");
+    llvm::sys::path::append(P, "cuda_wrappers");
+    CC1Args.push_back("-internal-isystem");
+    CC1Args.push_back(DriverArgs.MakeArgString(P));
+  }
+
+  if (DriverArgs.hasArg(options::OPT_nocudainc))
+    return;
+
+  if (!isValid()) {
+    D.Diag(diag::err_drv_no_cuda_installation);
+    return;
+  }
+
+  CC1Args.push_back("-internal-isystem");
+  CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath()));
+  CC1Args.push_back("-include");
+  CC1Args.push_back("__clang_cuda_runtime_wrapper.h");
+}
+
+void CudaInstallationDetector::CheckCudaVersionSupportsArch(
+    CudaArch Arch) const {
+  if (Arch == CudaArch::UNKNOWN || Version == CudaVersion::UNKNOWN ||
+      ArchsWithVersionTooLowErrors.count(Arch) > 0)
+    return;
+
+  auto RequiredVersion = MinVersionForCudaArch(Arch);
+  if (Version < RequiredVersion) {
+    ArchsWithVersionTooLowErrors.insert(Arch);
+    D.Diag(diag::err_drv_cuda_version_too_low)
+        << InstallPath << CudaArchToString(Arch) << CudaVersionToString(Version)
+        << CudaVersionToString(RequiredVersion);
+  }
+}
+
+void CudaInstallationDetector::print(raw_ostream &OS) const {
+  if (isValid())
+    OS << "Found CUDA installation: " << InstallPath << ", version "
+       << CudaVersionToString(Version) << "\n";
+}
+
+void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                    const InputInfo &Output,
+                                    const InputInfoList &Inputs,
+                                    const ArgList &Args,
+                                    const char *LinkingOutput) const {
+  const auto &TC =
+      static_cast<const toolchains::CudaToolChain &>(getToolChain());
+  assert(TC.getTriple().isNVPTX() && "Wrong platform");
+
+  // Obtain architecture from the action.
+  CudaArch gpu_arch = StringToCudaArch(JA.getOffloadingArch());
+  assert(gpu_arch != CudaArch::UNKNOWN &&
+         "Device action expected to have an architecture.");
+
+  // Check that our installation's ptxas supports gpu_arch.
+  if (!Args.hasArg(options::OPT_no_cuda_version_check)) {
+    TC.CudaInstallation.CheckCudaVersionSupportsArch(gpu_arch);
+  }
+
+  ArgStringList CmdArgs;
+  CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-m64" : "-m32");
+  if (Args.hasFlag(options::OPT_cuda_noopt_device_debug,
+                   options::OPT_no_cuda_noopt_device_debug, false)) {
+    // ptxas does not accept -g option if optimization is enabled, so
+    // we ignore the compiler's -O* options if we want debug info.
+    CmdArgs.push_back("-g");
+    CmdArgs.push_back("--dont-merge-basicblocks");
+    CmdArgs.push_back("--return-at-end");
+  } else if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    // Map the -O we received to -O{0,1,2,3}.
+    //
+    // TODO: Perhaps we should map host -O2 to ptxas -O3. -O3 is ptxas's
+    // default, so it may correspond more closely to the spirit of clang -O2.
+
+    // -O3 seems like the least-bad option when -Osomething is specified to
+    // clang but it isn't handled below.
+    StringRef OOpt = "3";
+    if (A->getOption().matches(options::OPT_O4) ||
+        A->getOption().matches(options::OPT_Ofast))
+      OOpt = "3";
+    else if (A->getOption().matches(options::OPT_O0))
+      OOpt = "0";
+    else if (A->getOption().matches(options::OPT_O)) {
+      // -Os, -Oz, and -O(anything else) map to -O2, for lack of better options.
+      OOpt = llvm::StringSwitch<const char *>(A->getValue())
+                 .Case("1", "1")
+                 .Case("2", "2")
+                 .Case("3", "3")
+                 .Case("s", "2")
+                 .Case("z", "2")
+                 .Default("2");
+    }
+    CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt));
+  } else {
+    // If no -O was passed, pass -O0 to ptxas -- no opt flag should correspond
+    // to no optimizations, but ptxas's default is -O3.
+    CmdArgs.push_back("-O0");
+  }
+
+  CmdArgs.push_back("--gpu-name");
+  CmdArgs.push_back(Args.MakeArgString(CudaArchToString(gpu_arch)));
+  CmdArgs.push_back("--output-file");
+  CmdArgs.push_back(Args.MakeArgString(Output.getFilename()));
+  for (const auto& II : Inputs)
+    CmdArgs.push_back(Args.MakeArgString(II.getFilename()));
+
+  for (const auto& A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
+    CmdArgs.push_back(Args.MakeArgString(A));
+
+  const char *Exec;
+  if (Arg *A = Args.getLastArg(options::OPT_ptxas_path_EQ))
+    Exec = A->getValue();
+  else
+    Exec = Args.MakeArgString(TC.GetProgramPath("ptxas"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+// All inputs to this linker must be from CudaDeviceActions, as we need to look
+// at the Inputs' Actions in order to figure out which GPU architecture they
+// correspond to.
+void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                 const InputInfo &Output,
+                                 const InputInfoList &Inputs,
+                                 const ArgList &Args,
+                                 const char *LinkingOutput) const {
+  const auto &TC =
+      static_cast<const toolchains::CudaToolChain &>(getToolChain());
+  assert(TC.getTriple().isNVPTX() && "Wrong platform");
+
+  ArgStringList CmdArgs;
+  CmdArgs.push_back("--cuda");
+  CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-64" : "-32");
+  CmdArgs.push_back(Args.MakeArgString("--create"));
+  CmdArgs.push_back(Args.MakeArgString(Output.getFilename()));
+
+  for (const auto& II : Inputs) {
+    auto *A = II.getAction();
+    assert(A->getInputs().size() == 1 &&
+           "Device offload action is expected to have a single input");
+    const char *gpu_arch_str = A->getOffloadingArch();
+    assert(gpu_arch_str &&
+           "Device action expected to have associated a GPU architecture!");
+    CudaArch gpu_arch = StringToCudaArch(gpu_arch_str);
+
+    // We need to pass an Arch of the form "sm_XX" for cubin files and
+    // "compute_XX" for ptx.
+    const char *Arch =
+        (II.getType() == types::TY_PP_Asm)
+            ? CudaVirtualArchToString(VirtualArchForCudaArch(gpu_arch))
+            : gpu_arch_str;
+    CmdArgs.push_back(Args.MakeArgString(llvm::Twine("--image=profile=") +
+                                         Arch + ",file=" + II.getFilename()));
+  }
+
+  for (const auto& A : Args.getAllArgValues(options::OPT_Xcuda_fatbinary))
+    CmdArgs.push_back(Args.MakeArgString(A));
+
+  const char *Exec = Args.MakeArgString(TC.GetProgramPath("fatbinary"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// CUDA toolchain.  Our assembler is ptxas, and our "linker" is fatbinary,
+/// which isn't properly a linker but nonetheless performs the step of stitching
+/// together object files from the assembler into a single blob.
+
+CudaToolChain::CudaToolChain(const Driver &D, const llvm::Triple &Triple,
+                             const ToolChain &HostTC, const ArgList &Args)
+    : ToolChain(D, Triple, Args), HostTC(HostTC),
+      CudaInstallation(D, HostTC.getTriple(), Args) {
+  if (CudaInstallation.isValid())
+    getProgramPaths().push_back(CudaInstallation.getBinPath());
+}
+
+void CudaToolChain::addClangTargetOptions(
+    const llvm::opt::ArgList &DriverArgs,
+    llvm::opt::ArgStringList &CC1Args) const {
+  HostTC.addClangTargetOptions(DriverArgs, CC1Args);
+
+  CC1Args.push_back("-fcuda-is-device");
+
+  if (DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,
+                         options::OPT_fno_cuda_flush_denormals_to_zero, false))
+    CC1Args.push_back("-fcuda-flush-denormals-to-zero");
+
+  if (DriverArgs.hasFlag(options::OPT_fcuda_approx_transcendentals,
+                         options::OPT_fno_cuda_approx_transcendentals, false))
+    CC1Args.push_back("-fcuda-approx-transcendentals");
+
+  if (DriverArgs.hasArg(options::OPT_nocudalib))
+    return;
+
+  StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
+  assert(!GpuArch.empty() && "Must have an explicit GPU arch.");
+  std::string LibDeviceFile = CudaInstallation.getLibDeviceFile(GpuArch);
+
+  if (LibDeviceFile.empty()) {
+    getDriver().Diag(diag::err_drv_no_cuda_libdevice) << GpuArch;
+    return;
+  }
+
+  CC1Args.push_back("-mlink-cuda-bitcode");
+  CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
+
+  // Libdevice in CUDA-7.0 requires PTX version that's more recent
+  // than LLVM defaults to. Use PTX4.2 which is the PTX version that
+  // came with CUDA-7.0.
+  CC1Args.push_back("-target-feature");
+  CC1Args.push_back("+ptx42");
+}
+
+void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
+                                       ArgStringList &CC1Args) const {
+  // Check our CUDA version if we're going to include the CUDA headers.
+  if (!DriverArgs.hasArg(options::OPT_nocudainc) &&
+      !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) {
+    StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
+    assert(!Arch.empty() && "Must have an explicit GPU arch.");
+    CudaInstallation.CheckCudaVersionSupportsArch(StringToCudaArch(Arch));
+  }
+  CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
+}
+
+llvm::opt::DerivedArgList *
+CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
+                             StringRef BoundArch,
+                             Action::OffloadKind DeviceOffloadKind) const {
+  DerivedArgList *DAL =
+      HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind);
+  if (!DAL)
+    DAL = new DerivedArgList(Args.getBaseArgs());
+
+  const OptTable &Opts = getDriver().getOpts();
+
+  for (Arg *A : Args) {
+    if (A->getOption().matches(options::OPT_Xarch__)) {
+      // Skip this argument unless the architecture matches BoundArch
+      if (BoundArch.empty() || A->getValue(0) != BoundArch)
+        continue;
+
+      unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
+      unsigned Prev = Index;
+      std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
+
+      // If the argument parsing failed or more than one argument was
+      // consumed, the -Xarch_ argument's parameter tried to consume
+      // extra arguments. Emit an error and ignore.
+      //
+      // We also want to disallow any options which would alter the
+      // driver behavior; that isn't going to work in our model. We
+      // use isDriverOption() as an approximation, although things
+      // like -O4 are going to slip through.
+      if (!XarchArg || Index > Prev + 1) {
+        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
+            << A->getAsString(Args);
+        continue;
+      } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
+        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
+            << A->getAsString(Args);
+        continue;
+      }
+      XarchArg->setBaseArg(A);
+      A = XarchArg.release();
+      DAL->AddSynthesizedArg(A);
+    }
+    DAL->append(A);
+  }
+
+  if (!BoundArch.empty()) {
+    DAL->eraseArg(options::OPT_march_EQ);
+    DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), BoundArch);
+  }
+  return DAL;
+}
+
+Tool *CudaToolChain::buildAssembler() const {
+  return new tools::NVPTX::Assembler(*this);
+}
+
+Tool *CudaToolChain::buildLinker() const {
+  return new tools::NVPTX::Linker(*this);
+}
+
+void CudaToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {
+  HostTC.addClangWarningOptions(CC1Args);
+}
+
+ToolChain::CXXStdlibType
+CudaToolChain::GetCXXStdlibType(const ArgList &Args) const {
+  return HostTC.GetCXXStdlibType(Args);
+}
+
+void CudaToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                              ArgStringList &CC1Args) const {
+  HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
+}
+
+void CudaToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args,
+                                                 ArgStringList &CC1Args) const {
+  HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
+}
+
+void CudaToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
+                                        ArgStringList &CC1Args) const {
+  HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
+}
+
+SanitizerMask CudaToolChain::getSupportedSanitizers() const {
+  // The CudaToolChain only supports sanitizers in the sense that it allows
+  // sanitizer arguments on the command line if they are supported by the host
+  // toolchain. The CudaToolChain will actually ignore any command line
+  // arguments for any of these "supported" sanitizers. That means that no
+  // sanitization of device code is actually supported at this time.
+  //
+  // This behavior is necessary because the host and device toolchains
+  // invocations often share the command line, so the device toolchain must
+  // tolerate flags meant only for the host toolchain.
+  return HostTC.getSupportedSanitizers();
+}
+
+VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D,
+                                               const ArgList &Args) const {
+  return HostTC.computeMSVCVersion(D, Args);
+}
diff --git a/lib/Driver/ToolChains/Cuda.h b/lib/Driver/ToolChains/Cuda.h
new file mode 100644
index 0000000..acdb4c4
--- /dev/null
+++ b/lib/Driver/ToolChains/Cuda.h
@@ -0,0 +1,177 @@
+//===--- Cuda.h - Cuda ToolChain Implementations ----------------*- 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_LIB_DRIVER_TOOLCHAINS_CUDA_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H
+
+#include "clang/Basic/Cuda.h"
+#include "clang/Basic/VersionTuple.h"
+#include "clang/Driver/Action.h"
+#include "clang/Driver/Multilib.h"
+#include "clang/Driver/ToolChain.h"
+#include "clang/Driver/Tool.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/Compiler.h"
+#include <set>
+#include <vector>
+
+namespace clang {
+namespace driver {
+
+/// A class to find a viable CUDA installation
+class CudaInstallationDetector {
+private:
+  const Driver &D;
+  bool IsValid = false;
+  CudaVersion Version = CudaVersion::UNKNOWN;
+  std::string InstallPath;
+  std::string BinPath;
+  std::string LibPath;
+  std::string LibDevicePath;
+  std::string IncludePath;
+  llvm::StringMap<std::string> LibDeviceMap;
+
+  // CUDA architectures for which we have raised an error in
+  // CheckCudaVersionSupportsArch.
+  mutable llvm::SmallSet<CudaArch, 4> ArchsWithVersionTooLowErrors;
+
+public:
+  CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
+                           const llvm::opt::ArgList &Args);
+
+  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const;
+
+  /// \brief Emit an error if Version does not support the given Arch.
+  ///
+  /// If either Version or Arch is unknown, does not emit an error.  Emits at
+  /// most one error per Arch.
+  void CheckCudaVersionSupportsArch(CudaArch Arch) const;
+
+  /// \brief Check whether we detected a valid Cuda install.
+  bool isValid() const { return IsValid; }
+  /// \brief Print information about the detected CUDA installation.
+  void print(raw_ostream &OS) const;
+
+  /// \brief Get the detected Cuda install's version.
+  CudaVersion version() const { return Version; }
+  /// \brief Get the detected Cuda installation path.
+  StringRef getInstallPath() const { return InstallPath; }
+  /// \brief Get the detected path to Cuda's bin directory.
+  StringRef getBinPath() const { return BinPath; }
+  /// \brief Get the detected Cuda Include path.
+  StringRef getIncludePath() const { return IncludePath; }
+  /// \brief Get the detected Cuda library path.
+  StringRef getLibPath() const { return LibPath; }
+  /// \brief Get the detected Cuda device library path.
+  StringRef getLibDevicePath() const { return LibDevicePath; }
+  /// \brief Get libdevice file for given architecture
+  std::string getLibDeviceFile(StringRef Gpu) const {
+    return LibDeviceMap.lookup(Gpu);
+  }
+};
+
+namespace tools {
+namespace NVPTX {
+
+// Run ptxas, the NVPTX assembler.
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
+ public:
+   Assembler(const ToolChain &TC)
+       : Tool("NVPTX::Assembler", "ptxas", TC, RF_Full, llvm::sys::WEM_UTF8,
+              "--options-file") {}
+
+   bool hasIntegratedCPP() const override { return false; }
+
+   void ConstructJob(Compilation &C, const JobAction &JA,
+                     const InputInfo &Output, const InputInfoList &Inputs,
+                     const llvm::opt::ArgList &TCArgs,
+                     const char *LinkingOutput) const override;
+};
+
+// Runs fatbinary, which combines GPU object files ("cubin" files) and/or PTX
+// assembly into a single output file.
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+ public:
+   Linker(const ToolChain &TC)
+       : Tool("NVPTX::Linker", "fatbinary", TC, RF_Full, llvm::sys::WEM_UTF8,
+              "--options-file") {}
+
+   bool hasIntegratedCPP() const override { return false; }
+
+   void ConstructJob(Compilation &C, const JobAction &JA,
+                     const InputInfo &Output, const InputInfoList &Inputs,
+                     const llvm::opt::ArgList &TCArgs,
+                     const char *LinkingOutput) const override;
+};
+
+} // end namespace NVPTX
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain {
+public:
+  CudaToolChain(const Driver &D, const llvm::Triple &Triple,
+                const ToolChain &HostTC, const llvm::opt::ArgList &Args);
+
+  virtual const llvm::Triple *getAuxTriple() const override {
+    return &HostTC.getTriple();
+  }
+
+  llvm::opt::DerivedArgList *
+  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
+                Action::OffloadKind DeviceOffloadKind) const override;
+  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                             llvm::opt::ArgStringList &CC1Args) const override;
+
+  // Never try to use the integrated assembler with CUDA; always fork out to
+  // ptxas.
+  bool useIntegratedAs() const override { return false; }
+  bool isCrossCompiling() const override { return true; }
+  bool isPICDefault() const override { return false; }
+  bool isPIEDefault() const override { return false; }
+  bool isPICDefaultForced() const override { return false; }
+  bool SupportsProfiling() const override { return false; }
+  bool SupportsObjCGC() const override { return false; }
+
+  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const override;
+
+  void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
+  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void AddClangCXXStdlibIncludeArgs(
+      const llvm::opt::ArgList &Args,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                           llvm::opt::ArgStringList &CC1Args) const override;
+
+  SanitizerMask getSupportedSanitizers() const override;
+
+  VersionTuple
+  computeMSVCVersion(const Driver *D,
+                     const llvm::opt::ArgList &Args) const override;
+
+  const ToolChain &HostTC;
+  CudaInstallationDetector CudaInstallation;
+
+protected:
+  Tool *buildAssembler() const override;  // ptxas
+  Tool *buildLinker() const override;     // fatbinary (ok, not really a linker)
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H
diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp
new file mode 100644
index 0000000..4cddf65
--- /dev/null
+++ b/lib/Driver/ToolChains/Darwin.cpp
@@ -0,0 +1,1896 @@
+//===--- Darwin.cpp - Darwin Tool and ToolChain Implementations -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Darwin.h"
+#include "Arch/ARM.h"
+#include "CommonArgs.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/TargetParser.h"
+#include <cstdlib> // ::getenv
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+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.
+
+  // The matching this routine does is fairly pointless, since it is neither the
+  // complete architecture list, nor a reasonable subset. The problem is that
+  // historically the driver driver accepts this and also ties its -march=
+  // handling to the architecture name, so we need to be careful before removing
+  // support for it.
+
+  // This code must be kept in sync with Clang's Darwin specific argument
+  // translation.
+
+  return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
+      .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
+      .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
+      .Case("ppc64", llvm::Triple::ppc64)
+      .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
+      .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
+             llvm::Triple::x86)
+      .Cases("x86_64", "x86_64h", llvm::Triple::x86_64)
+      // This is derived from the driver driver.
+      .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
+      .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm)
+      .Cases("armv7s", "xscale", llvm::Triple::arm)
+      .Case("arm64", llvm::Triple::aarch64)
+      .Case("r600", llvm::Triple::r600)
+      .Case("amdgcn", llvm::Triple::amdgcn)
+      .Case("nvptx", llvm::Triple::nvptx)
+      .Case("nvptx64", llvm::Triple::nvptx64)
+      .Case("amdil", llvm::Triple::amdil)
+      .Case("spir", llvm::Triple::spir)
+      .Default(llvm::Triple::UnknownArch);
+}
+
+void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) {
+  const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str);
+  unsigned ArchKind = llvm::ARM::parseArch(Str);
+  T.setArch(Arch);
+
+  if (Str == "x86_64h")
+    T.setArchName(Str);
+  else if (ArchKind == llvm::ARM::AK_ARMV6M ||
+           ArchKind == llvm::ARM::AK_ARMV7M ||
+           ArchKind == llvm::ARM::AK_ARMV7EM) {
+    T.setOS(llvm::Triple::UnknownOS);
+    T.setObjectFormat(llvm::Triple::MachO);
+  }
+}
+
+void darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                     const InputInfo &Output,
+                                     const InputInfoList &Inputs,
+                                     const ArgList &Args,
+                                     const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
+  const InputInfo &Input = Inputs[0];
+
+  // Determine the original source input.
+  const Action *SourceAction = &JA;
+  while (SourceAction->getKind() != Action::InputClass) {
+    assert(!SourceAction->getInputs().empty() && "unexpected root action!");
+    SourceAction = SourceAction->getInputs()[0];
+  }
+
+  // If -fno-integrated-as is used add -Q to the darwin assember driver to make
+  // sure it runs its system assembler not clang's integrated assembler.
+  // Applicable to darwin11+ and Xcode 4+.  darwin<10 lacked integrated-as.
+  // FIXME: at run-time detect assembler capabilities or rely on version
+  // information forwarded by -target-assembler-version.
+  if (Args.hasArg(options::OPT_fno_integrated_as)) {
+    const llvm::Triple &T(getToolChain().getTriple());
+    if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7)))
+      CmdArgs.push_back("-Q");
+  }
+
+  // Forward -g, assuming we are dealing with an actual assembly file.
+  if (SourceAction->getType() == types::TY_Asm ||
+      SourceAction->getType() == types::TY_PP_Asm) {
+    if (Args.hasArg(options::OPT_gstabs))
+      CmdArgs.push_back("--gstabs");
+    else if (Args.hasArg(options::OPT_g_Group))
+      CmdArgs.push_back("-g");
+  }
+
+  // Derived from asm spec.
+  AddMachOArch(Args, CmdArgs);
+
+  // Use -force_cpusubtype_ALL on x86 by default.
+  if (getToolChain().getArch() == llvm::Triple::x86 ||
+      getToolChain().getArch() == llvm::Triple::x86_64 ||
+      Args.hasArg(options::OPT_force__cpusubtype__ALL))
+    CmdArgs.push_back("-force_cpusubtype_ALL");
+
+  if (getToolChain().getArch() != llvm::Triple::x86_64 &&
+      (((Args.hasArg(options::OPT_mkernel) ||
+         Args.hasArg(options::OPT_fapple_kext)) &&
+        getMachOToolChain().isKernelStatic()) ||
+       Args.hasArg(options::OPT_static)))
+    CmdArgs.push_back("-static");
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  assert(Output.isFilename() && "Unexpected lipo output.");
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  assert(Input.isFilename() && "Invalid input.");
+  CmdArgs.push_back(Input.getFilename());
+
+  // asm_final spec is empty.
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void darwin::MachOTool::anchor() {}
+
+void darwin::MachOTool::AddMachOArch(const ArgList &Args,
+                                     ArgStringList &CmdArgs) const {
+  StringRef ArchName = getMachOToolChain().getMachOArchName(Args);
+
+  // Derived from darwin_arch spec.
+  CmdArgs.push_back("-arch");
+  CmdArgs.push_back(Args.MakeArgString(ArchName));
+
+  // FIXME: Is this needed anymore?
+  if (ArchName == "arm")
+    CmdArgs.push_back("-force_cpusubtype_ALL");
+}
+
+bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const {
+  // 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 (const auto &Input : Inputs)
+    if (Input.getType() != types::TY_Object)
+      return true;
+
+  return false;
+}
+
+/// \brief Pass -no_deduplicate to ld64 under certain conditions:
+///
+/// - Either -O0 or -O1 is explicitly specified
+/// - No -O option is specified *and* this is a compile+link (implicit -O0)
+///
+/// Also do *not* add -no_deduplicate when no -O option is specified and this
+/// is just a link (we can't imply -O0)
+static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) {
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O0))
+      return true;
+    if (A->getOption().matches(options::OPT_O))
+      return llvm::StringSwitch<bool>(A->getValue())
+                    .Case("1", true)
+                    .Default(false);
+    return false; // OPT_Ofast & OPT_O4
+  }
+
+  if (!IsLinkerOnlyAction) // Implicit -O0 for compile+linker only.
+    return true;
+  return false;
+}
+
+void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
+                                 ArgStringList &CmdArgs,
+                                 const InputInfoList &Inputs) const {
+  const Driver &D = getToolChain().getDriver();
+  const toolchains::MachO &MachOTC = getMachOToolChain();
+
+  unsigned Version[5] = {0, 0, 0, 0, 0};
+  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
+    if (!Driver::GetReleaseVersion(A->getValue(), Version))
+      D.Diag(diag::err_drv_invalid_version_number) << A->getAsString(Args);
+  }
+
+  // Newer linkers support -demangle. Pass it if supported and not disabled by
+  // the user.
+  if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+    CmdArgs.push_back("-demangle");
+
+  if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137)
+    CmdArgs.push_back("-export_dynamic");
+
+  // If we are using App Extension restrictions, pass a flag to the linker
+  // telling it that the compiled code has been audited.
+  if (Args.hasFlag(options::OPT_fapplication_extension,
+                   options::OPT_fno_application_extension, false))
+    CmdArgs.push_back("-application_extension");
+
+  if (D.isUsingLTO()) {
+    // If we are using LTO, then automatically create a temporary file path for
+    // the linker to use, so that it's lifetime will extend past a possible
+    // dsymutil step.
+    if (Version[0] >= 116 && NeedsTempPath(Inputs)) {
+      const char *TmpPath = C.getArgs().MakeArgString(
+          D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
+      C.addTempFile(TmpPath);
+      CmdArgs.push_back("-object_path_lto");
+      CmdArgs.push_back(TmpPath);
+    }
+  }
+
+  // Use -lto_library option to specify the libLTO.dylib path. Try to find
+  // it in clang installed libraries. ld64 will only look at this argument
+  // when it actually uses LTO, so libLTO.dylib only needs to exist at link
+  // time if ld64 decides that it needs to use LTO.
+  // Since this is passed unconditionally, ld64 will never look for libLTO.dylib
+  // next to it. That's ok since ld64 using a libLTO.dylib not matching the
+  // clang version won't work anyways.
+  if (Version[0] >= 133) {
+    // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
+    StringRef P = llvm::sys::path::parent_path(D.Dir);
+    SmallString<128> LibLTOPath(P);
+    llvm::sys::path::append(LibLTOPath, "lib");
+    llvm::sys::path::append(LibLTOPath, "libLTO.dylib");
+    CmdArgs.push_back("-lto_library");
+    CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));
+  }
+
+  // ld64 version 262 and above run the deduplicate pass by default.
+  if (Version[0] >= 262 && shouldLinkerNotDedup(C.getJobs().empty(), Args))
+    CmdArgs.push_back("-no_deduplicate");
+
+  // Derived from the "link" spec.
+  Args.AddAllArgs(CmdArgs, options::OPT_static);
+  if (!Args.hasArg(options::OPT_static))
+    CmdArgs.push_back("-dynamic");
+  if (Args.hasArg(options::OPT_fgnu_runtime)) {
+    // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
+    // here. How do we wish to handle such things?
+  }
+
+  if (!Args.hasArg(options::OPT_dynamiclib)) {
+    AddMachOArch(Args, CmdArgs);
+    // FIXME: Why do this only on this path?
+    Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
+
+    Args.AddLastArg(CmdArgs, options::OPT_bundle);
+    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
+    Args.AddAllArgs(CmdArgs, options::OPT_client__name);
+
+    Arg *A;
+    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
+        (A = Args.getLastArg(options::OPT_current__version)) ||
+        (A = Args.getLastArg(options::OPT_install__name)))
+      D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
+                                                       << "-dynamiclib";
+
+    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
+    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
+    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
+  } else {
+    CmdArgs.push_back("-dylib");
+
+    Arg *A;
+    if ((A = Args.getLastArg(options::OPT_bundle)) ||
+        (A = Args.getLastArg(options::OPT_bundle__loader)) ||
+        (A = Args.getLastArg(options::OPT_client__name)) ||
+        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
+        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
+        (A = Args.getLastArg(options::OPT_private__bundle)))
+      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
+                                                      << "-dynamiclib";
+
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
+                              "-dylib_compatibility_version");
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
+                              "-dylib_current_version");
+
+    AddMachOArch(Args, CmdArgs);
+
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
+                              "-dylib_install_name");
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_all__load);
+  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
+  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
+  if (MachOTC.isTargetIOSBased())
+    Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
+  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
+  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
+  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
+  Args.AddLastArg(CmdArgs, options::OPT_dynamic);
+  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
+  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
+  Args.AddAllArgs(CmdArgs, options::OPT_force__load);
+  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
+  Args.AddAllArgs(CmdArgs, options::OPT_image__base);
+  Args.AddAllArgs(CmdArgs, options::OPT_init);
+
+  // Add the deployment target.
+  MachOTC.addMinVersionArgs(Args, CmdArgs);
+
+  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
+  Args.AddLastArg(CmdArgs, options::OPT_multi__module);
+  Args.AddLastArg(CmdArgs, options::OPT_single__module);
+  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
+  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
+
+  if (const Arg *A =
+          Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
+                          options::OPT_fno_pie, options::OPT_fno_PIE)) {
+    if (A->getOption().matches(options::OPT_fpie) ||
+        A->getOption().matches(options::OPT_fPIE))
+      CmdArgs.push_back("-pie");
+    else
+      CmdArgs.push_back("-no_pie");
+  }
+
+  // for embed-bitcode, use -bitcode_bundle in linker command
+  if (C.getDriver().embedBitcodeEnabled()) {
+    // Check if the toolchain supports bitcode build flow.
+    if (MachOTC.SupportsEmbeddedBitcode()) {
+      CmdArgs.push_back("-bitcode_bundle");
+      if (C.getDriver().embedBitcodeMarkerOnly() && Version[0] >= 278) {
+        CmdArgs.push_back("-bitcode_process_mode");
+        CmdArgs.push_back("marker");
+      }
+    } else
+      D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_prebind);
+  Args.AddLastArg(CmdArgs, options::OPT_noprebind);
+  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
+  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
+  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
+  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
+  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
+  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
+  Args.AddAllArgs(CmdArgs, options::OPT_segprot);
+  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
+  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
+  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
+  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
+  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
+  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
+  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
+
+  // Give --sysroot= preference, over the Apple specific behavior to also use
+  // --isysroot as the syslibroot.
+  StringRef sysroot = C.getSysRoot();
+  if (sysroot != "") {
+    CmdArgs.push_back("-syslibroot");
+    CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
+  } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+    CmdArgs.push_back("-syslibroot");
+    CmdArgs.push_back(A->getValue());
+  }
+
+  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
+  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
+  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
+  Args.AddAllArgs(CmdArgs, options::OPT_undefined);
+  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
+  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
+  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
+  Args.AddAllArgs(CmdArgs, options::OPT_y);
+  Args.AddLastArg(CmdArgs, options::OPT_w);
+  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
+  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
+  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
+  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
+  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
+  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
+  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
+  Args.AddLastArg(CmdArgs, options::OPT_whyload);
+  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
+  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
+  Args.AddLastArg(CmdArgs, options::OPT_dylinker);
+  Args.AddLastArg(CmdArgs, options::OPT_Mach);
+}
+
+/// \brief Determine whether we are linking the ObjC runtime.
+static bool isObjCRuntimeLinked(const ArgList &Args) {
+  if (isObjCAutoRefCount(Args)) {
+    Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
+    return true;
+  }
+  return Args.hasArg(options::OPT_fobjc_link_runtime);
+}
+
+void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                  const InputInfo &Output,
+                                  const InputInfoList &Inputs,
+                                  const ArgList &Args,
+                                  const char *LinkingOutput) const {
+  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
+
+  // If the number of arguments surpasses the system limits, we will encode the
+  // input files in a separate file, shortening the command line. To this end,
+  // build a list of input file names that can be passed via a file with the
+  // -filelist linker option.
+  llvm::opt::ArgStringList InputFileList;
+
+  // The logic here is derived from gcc's behavior; most of which
+  // comes from specs (starting with link_command). Consult gcc for
+  // more information.
+  ArgStringList CmdArgs;
+
+  /// 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 (const auto &Arg : Args)
+      Arg->claim();
+    const char *Exec =
+        Args.MakeArgString(getToolChain().GetProgramPath("touch"));
+    CmdArgs.push_back(Output.getFilename());
+    C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, None));
+    return;
+  }
+
+  // I'm not sure why this particular decomposition exists in gcc, but
+  // we follow suite for ease of comparison.
+  AddLinkArgs(C, Args, CmdArgs, Inputs);
+
+  // For LTO, pass the name of the optimization record file.
+  if (Args.hasFlag(options::OPT_fsave_optimization_record,
+                   options::OPT_fno_save_optimization_record, false)) {
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back("-lto-pass-remarks-output");
+    CmdArgs.push_back("-mllvm");
+
+    SmallString<128> F;
+    F = Output.getFilename();
+    F += ".opt.yaml";
+    CmdArgs.push_back(Args.MakeArgString(F));
+
+    if (getLastProfileUseArg(Args)) {
+      CmdArgs.push_back("-mllvm");
+      CmdArgs.push_back("-lto-pass-remarks-with-hotness");
+    }
+  }
+
+  // It seems that the 'e' option is completely ignored for dynamic executables
+  // (the default), and with static executables, the last one wins, as expected.
+  Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t,
+                            options::OPT_Z_Flag, options::OPT_u_Group,
+                            options::OPT_e, options::OPT_r});
+
+  // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
+  // members of static archive libraries which implement Objective-C classes or
+  // categories.
+  if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
+    CmdArgs.push_back("-ObjC");
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
+    getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs);
+
+  // SafeStack requires its own runtime libraries
+  // These libraries should be linked first, to make sure the
+  // __safestack_init constructor executes before everything else
+  if (getToolChain().getSanitizerArgs().needsSafeStackRt()) {
+    getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs,
+                                          "libclang_rt.safestack_osx.a",
+                                          /*AlwaysLink=*/true);
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+  // Build the input file for -filelist (list of linker input files) in case we
+  // need it later
+  for (const auto &II : Inputs) {
+    if (!II.isFilename()) {
+      // This is a linker input argument.
+      // We cannot mix input arguments and file names in a -filelist input, thus
+      // we prematurely stop our list (remaining files shall be passed as
+      // arguments).
+      if (InputFileList.size() > 0)
+        break;
+
+      continue;
+    }
+
+    InputFileList.push_back(II.getFilename());
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
+    addOpenMPRuntime(CmdArgs, getToolChain(), Args);
+
+  if (isObjCRuntimeLinked(Args) &&
+      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    // We use arclite library for both ARC and subscripting support.
+    getMachOToolChain().AddLinkARCArgs(Args, CmdArgs);
+
+    CmdArgs.push_back("-framework");
+    CmdArgs.push_back("Foundation");
+    // Link libobj.
+    CmdArgs.push_back("-lobjc");
+  }
+
+  if (LinkingOutput) {
+    CmdArgs.push_back("-arch_multiple");
+    CmdArgs.push_back("-final_output");
+    CmdArgs.push_back(LinkingOutput);
+  }
+
+  if (Args.hasArg(options::OPT_fnested_functions))
+    CmdArgs.push_back("-allow_stack_execute");
+
+  getMachOToolChain().addProfileRTLibs(Args, CmdArgs);
+
+  if (unsigned Parallelism =
+          getLTOParallelism(Args, getToolChain().getDriver())) {
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back(
+        Args.MakeArgString(Twine("-threads=") + llvm::to_string(Parallelism)));
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    if (getToolChain().getDriver().CCCIsCXX())
+      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+
+    // link_ssp spec is empty.
+
+    // Let the tool chain choose which runtime library to link.
+    getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
+
+    // No need to do anything for pthreads. Claim argument to avoid warning.
+    Args.ClaimAllArgs(options::OPT_pthread);
+    Args.ClaimAllArgs(options::OPT_pthreads);
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    // endfile_spec is empty.
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_F);
+
+  // -iframework should be forwarded as -F.
+  for (const Arg *A : Args.filtered(options::OPT_iframework))
+    CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue()));
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    if (Arg *A = Args.getLastArg(options::OPT_fveclib)) {
+      if (A->getValue() == StringRef("Accelerate")) {
+        CmdArgs.push_back("-framework");
+        CmdArgs.push_back("Accelerate");
+      }
+    }
+  }
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+  std::unique_ptr<Command> Cmd =
+      llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs);
+  Cmd->setInputFileList(std::move(InputFileList));
+  C.addCommand(std::move(Cmd));
+}
+
+void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
+                                const InputInfo &Output,
+                                const InputInfoList &Inputs,
+                                const ArgList &Args,
+                                const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  CmdArgs.push_back("-create");
+  assert(Output.isFilename() && "Unexpected lipo output.");
+
+  CmdArgs.push_back("-output");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs) {
+    assert(II.isFilename() && "Unexpected lipo input.");
+    CmdArgs.push_back(II.getFilename());
+  }
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
+                                    const InputInfo &Output,
+                                    const InputInfoList &Inputs,
+                                    const ArgList &Args,
+                                    const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
+  const InputInfo &Input = Inputs[0];
+  assert(Input.isFilename() && "Unexpected dsymutil input.");
+  CmdArgs.push_back(Input.getFilename());
+
+  const char *Exec =
+      Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
+                                       const InputInfo &Output,
+                                       const InputInfoList &Inputs,
+                                       const ArgList &Args,
+                                       const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+  CmdArgs.push_back("--verify");
+  CmdArgs.push_back("--debug-info");
+  CmdArgs.push_back("--eh-frame");
+  CmdArgs.push_back("--quiet");
+
+  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
+  const InputInfo &Input = Inputs[0];
+  assert(Input.isFilename() && "Unexpected verify input");
+
+  // Grabbing the output of the earlier dsymutil run.
+  CmdArgs.push_back(Input.getFilename());
+
+  const char *Exec =
+      Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+    : ToolChain(D, Triple, Args) {
+  // We expect 'as', 'ld', etc. to be adjacent to our install dir.
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
+}
+
+/// Darwin - Darwin tool chain for i386 and x86_64.
+Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+    : MachO(D, Triple, Args), TargetInitialized(false),
+      CudaInstallation(D, Triple, Args) {}
+
+types::ID MachO::LookupTypeForExtension(StringRef Ext) const {
+  types::ID Ty = types::lookupTypeForExtension(Ext);
+
+  // Darwin always preprocesses assembly files (unless -x is used explicitly).
+  if (Ty == types::TY_PP_Asm)
+    return types::TY_Asm;
+
+  return Ty;
+}
+
+bool MachO::HasNativeLLVMSupport() const { return true; }
+
+ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const {
+  // Default to use libc++ on OS X 10.9+ and iOS 7+.
+  if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
+       (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) ||
+       isTargetWatchOSBased())
+    return ToolChain::CST_Libcxx;
+
+  return ToolChain::CST_Libstdcxx;
+}
+
+/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
+ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
+  if (isTargetWatchOSBased())
+    return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion);
+  if (isTargetIOSBased())
+    return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
+  if (isNonFragile)
+    return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
+  return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
+}
+
+/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
+bool Darwin::hasBlocksRuntime() const {
+  if (isTargetWatchOSBased())
+    return true;
+  else if (isTargetIOSBased())
+    return !isIPhoneOSVersionLT(3, 2);
+  else {
+    assert(isTargetMacOS() && "unexpected darwin target");
+    return !isMacosxVersionLT(10, 6);
+  }
+}
+
+void Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs,
+                                ArgStringList &CC1Args) const {
+  CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
+}
+
+// This is just a MachO name translation routine and there's no
+// way to join this into ARMTargetParser without breaking all
+// other assumptions. Maybe MachO should consider standardising
+// their nomenclature.
+static const char *ArmMachOArchName(StringRef Arch) {
+  return llvm::StringSwitch<const char *>(Arch)
+      .Case("armv6k", "armv6")
+      .Case("armv6m", "armv6m")
+      .Case("armv5tej", "armv5")
+      .Case("xscale", "xscale")
+      .Case("armv4t", "armv4t")
+      .Case("armv7", "armv7")
+      .Cases("armv7a", "armv7-a", "armv7")
+      .Cases("armv7r", "armv7-r", "armv7")
+      .Cases("armv7em", "armv7e-m", "armv7em")
+      .Cases("armv7k", "armv7-k", "armv7k")
+      .Cases("armv7m", "armv7-m", "armv7m")
+      .Cases("armv7s", "armv7-s", "armv7s")
+      .Default(nullptr);
+}
+
+static const char *ArmMachOArchNameCPU(StringRef CPU) {
+  unsigned ArchKind = llvm::ARM::parseCPUArch(CPU);
+  if (ArchKind == llvm::ARM::AK_INVALID)
+    return nullptr;
+  StringRef Arch = llvm::ARM::getArchName(ArchKind);
+
+  // FIXME: Make sure this MachO triple mangling is really necessary.
+  // ARMv5* normalises to ARMv5.
+  if (Arch.startswith("armv5"))
+    Arch = Arch.substr(0, 5);
+  // ARMv6*, except ARMv6M, normalises to ARMv6.
+  else if (Arch.startswith("armv6") && !Arch.endswith("6m"))
+    Arch = Arch.substr(0, 5);
+  // ARMv7A normalises to ARMv7.
+  else if (Arch.endswith("v7a"))
+    Arch = Arch.substr(0, 5);
+  return Arch.data();
+}
+
+StringRef MachO::getMachOArchName(const ArgList &Args) const {
+  switch (getTriple().getArch()) {
+  default:
+    return getDefaultUniversalArchName();
+
+  case llvm::Triple::aarch64:
+    return "arm64";
+
+  case llvm::Triple::thumb:
+  case llvm::Triple::arm:
+    if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ))
+      if (const char *Arch = ArmMachOArchName(A->getValue()))
+        return Arch;
+
+    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+      if (const char *Arch = ArmMachOArchNameCPU(A->getValue()))
+        return Arch;
+
+    return "arm";
+  }
+}
+
+Darwin::~Darwin() {}
+
+MachO::~MachO() {}
+
+std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
+                                                types::ID InputType) const {
+  llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
+
+  // If the target isn't initialized (e.g., an unknown Darwin platform, return
+  // the default triple).
+  if (!isTargetInitialized())
+    return Triple.getTriple();
+
+  SmallString<16> Str;
+  if (isTargetWatchOSBased())
+    Str += "watchos";
+  else if (isTargetTvOSBased())
+    Str += "tvos";
+  else if (isTargetIOSBased())
+    Str += "ios";
+  else
+    Str += "macosx";
+  Str += getTargetVersion().getAsString();
+  Triple.setOSName(Str);
+
+  return Triple.getTriple();
+}
+
+Tool *MachO::getTool(Action::ActionClass AC) const {
+  switch (AC) {
+  case Action::LipoJobClass:
+    if (!Lipo)
+      Lipo.reset(new tools::darwin::Lipo(*this));
+    return Lipo.get();
+  case Action::DsymutilJobClass:
+    if (!Dsymutil)
+      Dsymutil.reset(new tools::darwin::Dsymutil(*this));
+    return Dsymutil.get();
+  case Action::VerifyDebugInfoJobClass:
+    if (!VerifyDebug)
+      VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
+    return VerifyDebug.get();
+  default:
+    return ToolChain::getTool(AC);
+  }
+}
+
+Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
+
+Tool *MachO::buildAssembler() const {
+  return new tools::darwin::Assembler(*this);
+}
+
+DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple,
+                         const ArgList &Args)
+    : Darwin(D, Triple, Args) {}
+
+void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
+  // For modern targets, promote certain warnings to errors.
+  if (isTargetWatchOSBased() || getTriple().isArch64Bit()) {
+    // Always enable -Wdeprecated-objc-isa-usage and promote it
+    // to an error.
+    CC1Args.push_back("-Wdeprecated-objc-isa-usage");
+    CC1Args.push_back("-Werror=deprecated-objc-isa-usage");
+
+    // For iOS and watchOS, also error about implicit function declarations,
+    // as that can impact calling conventions.
+    if (!isTargetMacOS())
+      CC1Args.push_back("-Werror=implicit-function-declaration");
+  }
+}
+
+void DarwinClang::AddLinkARCArgs(const ArgList &Args,
+                                 ArgStringList &CmdArgs) const {
+  // Avoid linking compatibility stubs on i386 mac.
+  if (isTargetMacOS() && getArch() == llvm::Triple::x86)
+    return;
+
+  ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);
+
+  if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) &&
+      runtime.hasSubscripting())
+    return;
+
+  CmdArgs.push_back("-force_load");
+  SmallString<128> P(getDriver().ClangExecutable);
+  llvm::sys::path::remove_filename(P); // 'clang'
+  llvm::sys::path::remove_filename(P); // 'bin'
+  llvm::sys::path::append(P, "lib", "arc", "libarclite_");
+  // Mash in the platform.
+  if (isTargetWatchOSSimulator())
+    P += "watchsimulator";
+  else if (isTargetWatchOS())
+    P += "watchos";
+  else if (isTargetTvOSSimulator())
+    P += "appletvsimulator";
+  else if (isTargetTvOS())
+    P += "appletvos";
+  else if (isTargetIOSSimulator())
+    P += "iphonesimulator";
+  else if (isTargetIPhoneOS())
+    P += "iphoneos";
+  else
+    P += "macosx";
+  P += ".a";
+
+  CmdArgs.push_back(Args.MakeArgString(P));
+}
+
+unsigned DarwinClang::GetDefaultDwarfVersion() const {
+  // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower.
+  if ((isTargetMacOS() && isMacosxVersionLT(10, 11)) ||
+      (isTargetIOSBased() && isIPhoneOSVersionLT(9)))
+    return 2;
+  return 4;
+}
+
+void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
+                              StringRef DarwinLibName, bool AlwaysLink,
+                              bool IsEmbedded, bool AddRPath) const {
+  SmallString<128> Dir(getDriver().ResourceDir);
+  llvm::sys::path::append(Dir, "lib", IsEmbedded ? "macho_embedded" : "darwin");
+
+  SmallString<128> P(Dir);
+  llvm::sys::path::append(P, DarwinLibName);
+
+  // For now, allow missing resource libraries to support developers who may
+  // not have compiler-rt checked out or integrated into their build (unless
+  // we explicitly force linking with this library).
+  if (AlwaysLink || getVFS().exists(P))
+    CmdArgs.push_back(Args.MakeArgString(P));
+
+  // Adding the rpaths might negatively interact when other rpaths are involved,
+  // so we should make sure we add the rpaths last, after all user-specified
+  // rpaths. This is currently true from this place, but we need to be
+  // careful if this function is ever called before user's rpaths are emitted.
+  if (AddRPath) {
+    assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library");
+
+    // Add @executable_path to rpath to support having the dylib copied with
+    // the executable.
+    CmdArgs.push_back("-rpath");
+    CmdArgs.push_back("@executable_path");
+
+    // Add the path to the resource dir to rpath to support using the dylib
+    // from the default location without copying.
+    CmdArgs.push_back("-rpath");
+    CmdArgs.push_back(Args.MakeArgString(Dir));
+  }
+}
+
+StringRef Darwin::getPlatformFamily() const {
+  switch (TargetPlatform) {
+    case DarwinPlatformKind::MacOS:
+      return "MacOSX";
+    case DarwinPlatformKind::IPhoneOS:
+    case DarwinPlatformKind::IPhoneOSSimulator:
+      return "iPhone";
+    case DarwinPlatformKind::TvOS:
+    case DarwinPlatformKind::TvOSSimulator:
+      return "AppleTV";
+    case DarwinPlatformKind::WatchOS:
+    case DarwinPlatformKind::WatchOSSimulator:
+      return "Watch";
+  }
+  llvm_unreachable("Unsupported platform");
+}
+
+StringRef Darwin::getSDKName(StringRef isysroot) {
+  // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
+  llvm::sys::path::const_iterator SDKDir;
+  auto BeginSDK = llvm::sys::path::begin(isysroot);
+  auto EndSDK = llvm::sys::path::end(isysroot);
+  for (auto IT = BeginSDK; IT != EndSDK; ++IT) {
+    StringRef SDK = *IT;
+    if (SDK.endswith(".sdk"))
+      return SDK.slice(0, SDK.size() - 4);
+  }
+  return "";
+}
+
+StringRef Darwin::getOSLibraryNameSuffix() const {
+  switch(TargetPlatform) {
+  case DarwinPlatformKind::MacOS:
+    return "osx";
+  case DarwinPlatformKind::IPhoneOS:
+    return "ios";
+  case DarwinPlatformKind::IPhoneOSSimulator:
+    return "iossim";
+  case DarwinPlatformKind::TvOS:
+    return "tvos";
+  case DarwinPlatformKind::TvOSSimulator:
+    return "tvossim";
+  case DarwinPlatformKind::WatchOS:
+    return "watchos";
+  case DarwinPlatformKind::WatchOSSimulator:
+    return "watchossim";
+  }
+  llvm_unreachable("Unsupported platform");
+}
+
+void Darwin::addProfileRTLibs(const ArgList &Args,
+                              ArgStringList &CmdArgs) const {
+  if (!needsProfileRT(Args)) return;
+
+  AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.profile_") +
+       getOSLibraryNameSuffix() + ".a").str(),
+                    /*AlwaysLink*/ true);
+}
+
+void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,
+                                          ArgStringList &CmdArgs,
+                                          StringRef Sanitizer) const {
+  AddLinkRuntimeLib(
+      Args, CmdArgs,
+      (Twine("libclang_rt.") + Sanitizer + "_" +
+       getOSLibraryNameSuffix() + "_dynamic.dylib").str(),
+      /*AlwaysLink*/ true, /*IsEmbedded*/ false,
+      /*AddRPath*/ true);
+}
+
+ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType(
+    const ArgList &Args) const {
+  if (Arg* A = Args.getLastArg(options::OPT_rtlib_EQ)) {
+    StringRef Value = A->getValue();
+    if (Value != "compiler-rt")
+      getDriver().Diag(clang::diag::err_drv_unsupported_rtlib_for_platform)
+          << Value << "darwin";
+  }
+
+  return ToolChain::RLT_CompilerRT;
+}
+
+void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
+                                        ArgStringList &CmdArgs) const {
+  // Call once to ensure diagnostic is printed if wrong value was specified
+  GetRuntimeLibType(Args);
+
+  // Darwin doesn't support real static executables, don't link any runtime
+  // libraries with -static.
+  if (Args.hasArg(options::OPT_static) ||
+      Args.hasArg(options::OPT_fapple_kext) ||
+      Args.hasArg(options::OPT_mkernel))
+    return;
+
+  // Reject -static-libgcc for now, we can deal with this when and if someone
+  // cares. This is useful in situations where someone wants to statically link
+  // something like libstdc++, and needs its runtime support routines.
+  if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
+    getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
+    return;
+  }
+
+  const SanitizerArgs &Sanitize = getSanitizerArgs();
+  if (Sanitize.needsAsanRt())
+    AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
+  if (Sanitize.needsUbsanRt())
+    AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan");
+  if (Sanitize.needsTsanRt())
+    AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
+  if (Sanitize.needsStatsRt()) {
+    StringRef OS = isTargetMacOS() ? "osx" : "iossim";
+    AddLinkRuntimeLib(Args, CmdArgs,
+                      (Twine("libclang_rt.stats_client_") + OS + ".a").str(),
+                      /*AlwaysLink=*/true);
+    AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
+  }
+  if (Sanitize.needsEsanRt())
+    AddLinkSanitizerLibArgs(Args, CmdArgs, "esan");
+
+  // Otherwise link libSystem, then the dynamic runtime library, and finally any
+  // target specific static runtime library.
+  CmdArgs.push_back("-lSystem");
+
+  // Select the dynamic runtime library and the target specific static library.
+  if (isTargetWatchOSBased()) {
+    // We currently always need a static runtime library for watchOS.
+    AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.watchos.a");
+  } else if (isTargetTvOSBased()) {
+    // We currently always need a static runtime library for tvOS.
+    AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.tvos.a");
+  } else if (isTargetIOSBased()) {
+    // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
+    // it never went into the SDK.
+    // Linking against libgcc_s.1 isn't needed for iOS 5.0+
+    if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
+        getTriple().getArch() != llvm::Triple::aarch64)
+      CmdArgs.push_back("-lgcc_s.1");
+
+    // We currently always need a static runtime library for iOS.
+    AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
+  } else {
+    assert(isTargetMacOS() && "unexpected non MacOS platform");
+    // The dynamic runtime library was merged with libSystem for 10.6 and
+    // beyond; only 10.4 and 10.5 need an additional runtime library.
+    if (isMacosxVersionLT(10, 5))
+      CmdArgs.push_back("-lgcc_s.10.4");
+    else if (isMacosxVersionLT(10, 6))
+      CmdArgs.push_back("-lgcc_s.10.5");
+
+    // Originally for OS X, we thought we would only need a static runtime
+    // library when targeting 10.4, to provide versions of the static functions
+    // which were omitted from 10.4.dylib. This led to the creation of the 10.4
+    // builtins library.
+    //
+    // Unfortunately, that turned out to not be true, because Darwin system
+    // headers can still use eprintf on i386, and it is not exported from
+    // libSystem. Therefore, we still must provide a runtime library just for
+    // the tiny tiny handful of projects that *might* use that symbol.
+    //
+    // Then over time, we figured out it was useful to add more things to the
+    // runtime so we created libclang_rt.osx.a to provide new functions when
+    // deploying to old OS builds, and for a long time we had both eprintf and
+    // osx builtin libraries. Which just seems excessive. So with PR 28855, we
+    // are removing the eprintf library and expecting eprintf to be provided by
+    // the OS X builtins library.
+    if (isMacosxVersionLT(10, 5))
+      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
+    else
+      AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
+  }
+}
+
+void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
+  const OptTable &Opts = getDriver().getOpts();
+
+  // Support allowing the SDKROOT environment variable used by xcrun and other
+  // Xcode tools to define the default sysroot, by making it the default for
+  // isysroot.
+  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+    // Warn if the path does not exist.
+    if (!getVFS().exists(A->getValue()))
+      getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
+  } else {
+    if (char *env = ::getenv("SDKROOT")) {
+      // We only use this value as the default if it is an absolute path,
+      // exists, and it is not the root path.
+      if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
+          StringRef(env) != "/") {
+        Args.append(Args.MakeSeparateArg(
+            nullptr, Opts.getOption(options::OPT_isysroot), env));
+      }
+    }
+  }
+
+  Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
+  Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
+  Arg *TvOSVersion = Args.getLastArg(options::OPT_mtvos_version_min_EQ);
+  Arg *WatchOSVersion = Args.getLastArg(options::OPT_mwatchos_version_min_EQ);
+
+  if (OSXVersion && (iOSVersion || TvOSVersion || WatchOSVersion)) {
+    getDriver().Diag(diag::err_drv_argument_not_allowed_with)
+        << OSXVersion->getAsString(Args)
+        << (iOSVersion ? iOSVersion :
+            TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
+    iOSVersion = TvOSVersion = WatchOSVersion = nullptr;
+  } else if (iOSVersion && (TvOSVersion || WatchOSVersion)) {
+    getDriver().Diag(diag::err_drv_argument_not_allowed_with)
+        << iOSVersion->getAsString(Args)
+        << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
+    TvOSVersion = WatchOSVersion = nullptr;
+  } else if (TvOSVersion && WatchOSVersion) {
+     getDriver().Diag(diag::err_drv_argument_not_allowed_with)
+        << TvOSVersion->getAsString(Args)
+        << WatchOSVersion->getAsString(Args);
+    WatchOSVersion = nullptr;
+  } else if (!OSXVersion && !iOSVersion && !TvOSVersion && !WatchOSVersion) {
+    // If no deployment target was specified on the command line, check for
+    // environment defines.
+    std::string OSXTarget;
+    std::string iOSTarget;
+    std::string TvOSTarget;
+    std::string WatchOSTarget;
+
+    if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
+      OSXTarget = env;
+    if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
+      iOSTarget = env;
+    if (char *env = ::getenv("TVOS_DEPLOYMENT_TARGET"))
+      TvOSTarget = env;
+    if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET"))
+      WatchOSTarget = env;
+
+    // If there is no command-line argument to specify the Target version and
+    // no environment variable defined, see if we can set the default based
+    // on -isysroot.
+    if (OSXTarget.empty() && iOSTarget.empty() && WatchOSTarget.empty() &&
+        TvOSTarget.empty() && Args.hasArg(options::OPT_isysroot)) {
+      if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+        StringRef isysroot = A->getValue();
+        StringRef SDK = getSDKName(isysroot);
+        if (SDK.size() > 0) {
+          // Slice the version number out.
+          // Version number is between the first and the last number.
+          size_t StartVer = SDK.find_first_of("0123456789");
+          size_t EndVer = SDK.find_last_of("0123456789");
+          if (StartVer != StringRef::npos && EndVer > StartVer) {
+            StringRef Version = SDK.slice(StartVer, EndVer + 1);
+            if (SDK.startswith("iPhoneOS") ||
+                SDK.startswith("iPhoneSimulator"))
+              iOSTarget = Version;
+            else if (SDK.startswith("MacOSX"))
+              OSXTarget = Version;
+            else if (SDK.startswith("WatchOS") ||
+                     SDK.startswith("WatchSimulator"))
+              WatchOSTarget = Version;
+            else if (SDK.startswith("AppleTVOS") ||
+                     SDK.startswith("AppleTVSimulator"))
+              TvOSTarget = Version;
+          }
+        }
+      }
+    }
+
+    // If no OSX or iOS target has been specified, try to guess platform
+    // from arch name and compute the version from the triple.
+    if (OSXTarget.empty() && iOSTarget.empty() && TvOSTarget.empty() &&
+        WatchOSTarget.empty()) {
+      StringRef MachOArchName = getMachOArchName(Args);
+      unsigned Major, Minor, Micro;
+      if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
+          MachOArchName == "arm64") {
+        getTriple().getiOSVersion(Major, Minor, Micro);
+        llvm::raw_string_ostream(iOSTarget) << Major << '.' << Minor << '.'
+                                            << Micro;
+      } else if (MachOArchName == "armv7k") {
+        getTriple().getWatchOSVersion(Major, Minor, Micro);
+        llvm::raw_string_ostream(WatchOSTarget) << Major << '.' << Minor << '.'
+                                                << Micro;
+      } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
+                 MachOArchName != "armv7em") {
+        if (!getTriple().getMacOSXVersion(Major, Minor, Micro)) {
+          getDriver().Diag(diag::err_drv_invalid_darwin_version)
+              << getTriple().getOSName();
+        }
+        llvm::raw_string_ostream(OSXTarget) << Major << '.' << Minor << '.'
+                                            << Micro;
+      }
+    }
+
+    // Do not allow conflicts with the watchOS target.
+    if (!WatchOSTarget.empty() && (!iOSTarget.empty() || !TvOSTarget.empty())) {
+      getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
+        << "WATCHOS_DEPLOYMENT_TARGET"
+        << (!iOSTarget.empty() ? "IPHONEOS_DEPLOYMENT_TARGET" :
+            "TVOS_DEPLOYMENT_TARGET");
+    }
+
+    // Do not allow conflicts with the tvOS target.
+    if (!TvOSTarget.empty() && !iOSTarget.empty()) {
+      getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
+        << "TVOS_DEPLOYMENT_TARGET"
+        << "IPHONEOS_DEPLOYMENT_TARGET";
+    }
+
+    // Allow conflicts among OSX and iOS for historical reasons, but choose the
+    // default platform.
+    if (!OSXTarget.empty() && (!iOSTarget.empty() ||
+                               !WatchOSTarget.empty() ||
+                               !TvOSTarget.empty())) {
+      if (getTriple().getArch() == llvm::Triple::arm ||
+          getTriple().getArch() == llvm::Triple::aarch64 ||
+          getTriple().getArch() == llvm::Triple::thumb)
+        OSXTarget = "";
+      else
+        iOSTarget = WatchOSTarget = TvOSTarget = "";
+    }
+
+    if (!OSXTarget.empty()) {
+      const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+      OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget);
+      Args.append(OSXVersion);
+    } else if (!iOSTarget.empty()) {
+      const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
+      iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget);
+      Args.append(iOSVersion);
+    } else if (!TvOSTarget.empty()) {
+      const Option O = Opts.getOption(options::OPT_mtvos_version_min_EQ);
+      TvOSVersion = Args.MakeJoinedArg(nullptr, O, TvOSTarget);
+      Args.append(TvOSVersion);
+    } else if (!WatchOSTarget.empty()) {
+      const Option O = Opts.getOption(options::OPT_mwatchos_version_min_EQ);
+      WatchOSVersion = Args.MakeJoinedArg(nullptr, O, WatchOSTarget);
+      Args.append(WatchOSVersion);
+    }
+  }
+
+  DarwinPlatformKind Platform;
+  if (OSXVersion)
+    Platform = MacOS;
+  else if (iOSVersion)
+    Platform = IPhoneOS;
+  else if (TvOSVersion)
+    Platform = TvOS;
+  else if (WatchOSVersion)
+    Platform = WatchOS;
+  else
+    llvm_unreachable("Unable to infer Darwin variant");
+
+  // Set the tool chain target information.
+  unsigned Major, Minor, Micro;
+  bool HadExtra;
+  if (Platform == MacOS) {
+    assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) &&
+           "Unknown target platform!");
+    if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro,
+                                   HadExtra) ||
+        HadExtra || Major != 10 || Minor >= 100 || Micro >= 100)
+      getDriver().Diag(diag::err_drv_invalid_version_number)
+          << OSXVersion->getAsString(Args);
+  } else if (Platform == IPhoneOS) {
+    assert(iOSVersion && "Unknown target platform!");
+    if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
+                                   HadExtra) ||
+        HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
+      getDriver().Diag(diag::err_drv_invalid_version_number)
+          << iOSVersion->getAsString(Args);
+  } else if (Platform == TvOS) {
+    if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
+                                   Micro, HadExtra) || HadExtra ||
+        Major >= 100 || Minor >= 100 || Micro >= 100)
+      getDriver().Diag(diag::err_drv_invalid_version_number)
+          << TvOSVersion->getAsString(Args);
+  } else if (Platform == WatchOS) {
+    if (!Driver::GetReleaseVersion(WatchOSVersion->getValue(), Major, Minor,
+                                   Micro, HadExtra) || HadExtra ||
+        Major >= 10 || Minor >= 100 || Micro >= 100)
+      getDriver().Diag(diag::err_drv_invalid_version_number)
+          << WatchOSVersion->getAsString(Args);
+  } else
+    llvm_unreachable("unknown kind of Darwin platform");
+
+  // Recognize iOS targets with an x86 architecture as the iOS simulator.
+  if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
+                     getTriple().getArch() == llvm::Triple::x86_64))
+    Platform = IPhoneOSSimulator;
+  if (TvOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
+                      getTriple().getArch() == llvm::Triple::x86_64))
+    Platform = TvOSSimulator;
+  if (WatchOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
+                         getTriple().getArch() == llvm::Triple::x86_64))
+    Platform = WatchOSSimulator;
+
+  setTarget(Platform, Major, Minor, Micro);
+
+  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+    StringRef SDK = getSDKName(A->getValue());
+    if (SDK.size() > 0) {
+      size_t StartVer = SDK.find_first_of("0123456789");
+      StringRef SDKName = SDK.slice(0, StartVer);
+      if (!SDKName.startswith(getPlatformFamily()))
+        getDriver().Diag(diag::warn_incompatible_sysroot)
+            << SDKName << getPlatformFamily();
+    }
+  }
+}
+
+void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
+                                      ArgStringList &CmdArgs) const {
+  CXXStdlibType Type = GetCXXStdlibType(Args);
+
+  switch (Type) {
+  case ToolChain::CST_Libcxx:
+    CmdArgs.push_back("-lc++");
+    break;
+
+  case ToolChain::CST_Libstdcxx:
+    // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
+    // it was previously found in the gcc lib dir. However, for all the Darwin
+    // platforms we care about it was -lstdc++.6, so we search for that
+    // explicitly if we can't see an obvious -lstdc++ candidate.
+
+    // Check in the sysroot first.
+    if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+      SmallString<128> P(A->getValue());
+      llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
+
+      if (!getVFS().exists(P)) {
+        llvm::sys::path::remove_filename(P);
+        llvm::sys::path::append(P, "libstdc++.6.dylib");
+        if (getVFS().exists(P)) {
+          CmdArgs.push_back(Args.MakeArgString(P));
+          return;
+        }
+      }
+    }
+
+    // Otherwise, look in the root.
+    // FIXME: This should be removed someday when we don't have to care about
+    // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
+    if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
+        getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
+      CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
+      return;
+    }
+
+    // Otherwise, let the linker search.
+    CmdArgs.push_back("-lstdc++");
+    break;
+  }
+}
+
+void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
+                                   ArgStringList &CmdArgs) const {
+  // For Darwin platforms, use the compiler-rt-based support library
+  // instead of the gcc-provided one (which is also incidentally
+  // only present in the gcc lib dir, which makes it hard to find).
+
+  SmallString<128> P(getDriver().ResourceDir);
+  llvm::sys::path::append(P, "lib", "darwin");
+
+  // Use the newer cc_kext for iOS ARM after 6.0.
+  if (isTargetWatchOS()) {
+    llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
+  } else if (isTargetTvOS()) {
+    llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
+  } else if (isTargetIPhoneOS()) {
+    llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
+  } else {
+    llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
+  }
+
+  // For now, allow missing resource libraries to support developers who may
+  // not have compiler-rt checked out or integrated into their build.
+  if (getVFS().exists(P))
+    CmdArgs.push_back(Args.MakeArgString(P));
+}
+
+DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
+                                     StringRef BoundArch,
+                                     Action::OffloadKind) const {
+  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
+  const OptTable &Opts = getDriver().getOpts();
+
+  // FIXME: We really want to get out of the tool chain level argument
+  // translation business, as it makes the driver functionality much
+  // more opaque. For now, we follow gcc closely solely for the
+  // purpose of easily achieving feature parity & testability. Once we
+  // have something that works, we should reevaluate each translation
+  // and try to push it down into tool specific logic.
+
+  for (Arg *A : Args) {
+    if (A->getOption().matches(options::OPT_Xarch__)) {
+      // Skip this argument unless the architecture matches either the toolchain
+      // triple arch, or the arch being bound.
+      llvm::Triple::ArchType XarchArch =
+          tools::darwin::getArchTypeForMachOArchName(A->getValue(0));
+      if (!(XarchArch == getArch() ||
+            (!BoundArch.empty() &&
+             XarchArch ==
+                 tools::darwin::getArchTypeForMachOArchName(BoundArch))))
+        continue;
+
+      Arg *OriginalArg = A;
+      unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
+      unsigned Prev = Index;
+      std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
+
+      // If the argument parsing failed or more than one argument was
+      // consumed, the -Xarch_ argument's parameter tried to consume
+      // extra arguments. Emit an error and ignore.
+      //
+      // We also want to disallow any options which would alter the
+      // driver behavior; that isn't going to work in our model. We
+      // use isDriverOption() as an approximation, although things
+      // like -O4 are going to slip through.
+      if (!XarchArg || Index > Prev + 1) {
+        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
+            << A->getAsString(Args);
+        continue;
+      } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
+        getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
+            << A->getAsString(Args);
+        continue;
+      }
+
+      XarchArg->setBaseArg(A);
+
+      A = XarchArg.release();
+      DAL->AddSynthesizedArg(A);
+
+      // Linker input arguments require custom handling. The problem is that we
+      // have already constructed the phase actions, so we can not treat them as
+      // "input arguments".
+      if (A->getOption().hasFlag(options::LinkerInput)) {
+        // Convert the argument into individual Zlinker_input_args.
+        for (const char *Value : A->getValues()) {
+          DAL->AddSeparateArg(
+              OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value);
+        }
+        continue;
+      }
+    }
+
+    // Sob. These is strictly gcc compatible for the time being. Apple
+    // gcc translates options twice, which means that self-expanding
+    // options add duplicates.
+    switch ((options::ID)A->getOption().getID()) {
+    default:
+      DAL->append(A);
+      break;
+
+    case options::OPT_mkernel:
+    case options::OPT_fapple_kext:
+      DAL->append(A);
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
+      break;
+
+    case options::OPT_dependency_file:
+      DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
+      break;
+
+    case options::OPT_gfull:
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
+      DAL->AddFlagArg(
+          A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
+      break;
+
+    case options::OPT_gused:
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
+      DAL->AddFlagArg(
+          A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
+      break;
+
+    case options::OPT_shared:
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
+      break;
+
+    case options::OPT_fconstant_cfstrings:
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
+      break;
+
+    case options::OPT_fno_constant_cfstrings:
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
+      break;
+
+    case options::OPT_Wnonportable_cfstrings:
+      DAL->AddFlagArg(A,
+                      Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
+      break;
+
+    case options::OPT_Wno_nonportable_cfstrings:
+      DAL->AddFlagArg(
+          A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
+      break;
+
+    case options::OPT_fpascal_strings:
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
+      break;
+
+    case options::OPT_fno_pascal_strings:
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
+      break;
+    }
+  }
+
+  if (getTriple().getArch() == llvm::Triple::x86 ||
+      getTriple().getArch() == llvm::Triple::x86_64)
+    if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
+      DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ),
+                        "core2");
+
+  // Add the arch options based on the particular spelling of -arch, to match
+  // how the driver driver works.
+  if (!BoundArch.empty()) {
+    StringRef Name = BoundArch;
+    const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
+    const Option MArch = Opts.getOption(clang::driver::options::OPT_march_EQ);
+
+    // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
+    // which defines the list of which architectures we accept.
+    if (Name == "ppc")
+      ;
+    else if (Name == "ppc601")
+      DAL->AddJoinedArg(nullptr, MCpu, "601");
+    else if (Name == "ppc603")
+      DAL->AddJoinedArg(nullptr, MCpu, "603");
+    else if (Name == "ppc604")
+      DAL->AddJoinedArg(nullptr, MCpu, "604");
+    else if (Name == "ppc604e")
+      DAL->AddJoinedArg(nullptr, MCpu, "604e");
+    else if (Name == "ppc750")
+      DAL->AddJoinedArg(nullptr, MCpu, "750");
+    else if (Name == "ppc7400")
+      DAL->AddJoinedArg(nullptr, MCpu, "7400");
+    else if (Name == "ppc7450")
+      DAL->AddJoinedArg(nullptr, MCpu, "7450");
+    else if (Name == "ppc970")
+      DAL->AddJoinedArg(nullptr, MCpu, "970");
+
+    else if (Name == "ppc64" || Name == "ppc64le")
+      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
+
+    else if (Name == "i386")
+      ;
+    else if (Name == "i486")
+      DAL->AddJoinedArg(nullptr, MArch, "i486");
+    else if (Name == "i586")
+      DAL->AddJoinedArg(nullptr, MArch, "i586");
+    else if (Name == "i686")
+      DAL->AddJoinedArg(nullptr, MArch, "i686");
+    else if (Name == "pentium")
+      DAL->AddJoinedArg(nullptr, MArch, "pentium");
+    else if (Name == "pentium2")
+      DAL->AddJoinedArg(nullptr, MArch, "pentium2");
+    else if (Name == "pentpro")
+      DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
+    else if (Name == "pentIIm3")
+      DAL->AddJoinedArg(nullptr, MArch, "pentium2");
+
+    else if (Name == "x86_64")
+      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
+    else if (Name == "x86_64h") {
+      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
+      DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
+    }
+
+    else if (Name == "arm")
+      DAL->AddJoinedArg(nullptr, MArch, "armv4t");
+    else if (Name == "armv4t")
+      DAL->AddJoinedArg(nullptr, MArch, "armv4t");
+    else if (Name == "armv5")
+      DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
+    else if (Name == "xscale")
+      DAL->AddJoinedArg(nullptr, MArch, "xscale");
+    else if (Name == "armv6")
+      DAL->AddJoinedArg(nullptr, MArch, "armv6k");
+    else if (Name == "armv6m")
+      DAL->AddJoinedArg(nullptr, MArch, "armv6m");
+    else if (Name == "armv7")
+      DAL->AddJoinedArg(nullptr, MArch, "armv7a");
+    else if (Name == "armv7em")
+      DAL->AddJoinedArg(nullptr, MArch, "armv7em");
+    else if (Name == "armv7k")
+      DAL->AddJoinedArg(nullptr, MArch, "armv7k");
+    else if (Name == "armv7m")
+      DAL->AddJoinedArg(nullptr, MArch, "armv7m");
+    else if (Name == "armv7s")
+      DAL->AddJoinedArg(nullptr, MArch, "armv7s");
+  }
+
+  return DAL;
+}
+
+void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
+                                  ArgStringList &CmdArgs) const {
+  // Embedded targets are simple at the moment, not supporting sanitizers and
+  // with different libraries for each member of the product { static, PIC } x
+  // { hard-float, soft-float }
+  llvm::SmallString<32> CompilerRT = StringRef("libclang_rt.");
+  CompilerRT +=
+      (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)
+          ? "hard"
+          : "soft";
+  CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a";
+
+  AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true);
+}
+
+DerivedArgList *
+Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
+                      Action::OffloadKind DeviceOffloadKind) const {
+  // First get the generic Apple args, before moving onto Darwin-specific ones.
+  DerivedArgList *DAL =
+      MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind);
+  const OptTable &Opts = getDriver().getOpts();
+
+  // If no architecture is bound, none of the translations here are relevant.
+  if (BoundArch.empty())
+    return DAL;
+
+  // Add an explicit version min argument for the deployment target. We do this
+  // after argument translation because -Xarch_ arguments may add a version min
+  // argument.
+  AddDeploymentTarget(*DAL);
+
+  // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
+  // FIXME: It would be far better to avoid inserting those -static arguments,
+  // but we can't check the deployment target in the translation code until
+  // it is set here.
+  if (isTargetWatchOSBased() ||
+      (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
+    for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
+      Arg *A = *it;
+      ++it;
+      if (A->getOption().getID() != options::OPT_mkernel &&
+          A->getOption().getID() != options::OPT_fapple_kext)
+        continue;
+      assert(it != ie && "unexpected argument translation");
+      A = *it;
+      assert(A->getOption().getID() == options::OPT_static &&
+             "missing expected -static argument");
+      it = DAL->getArgs().erase(it);
+    }
+  }
+
+  if (!Args.getLastArg(options::OPT_stdlib_EQ) &&
+      GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
+    DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ),
+                      "libc++");
+
+  // Validate the C++ standard library choice.
+  CXXStdlibType Type = GetCXXStdlibType(*DAL);
+  if (Type == ToolChain::CST_Libcxx) {
+    // Check whether the target provides libc++.
+    StringRef where;
+
+    // Complain about targeting iOS < 5.0 in any way.
+    if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0))
+      where = "iOS 5.0";
+
+    if (where != StringRef()) {
+      getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where;
+    }
+  }
+
+  auto Arch = tools::darwin::getArchTypeForMachOArchName(BoundArch);
+  if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) {
+    if (Args.hasFlag(options::OPT_fomit_frame_pointer,
+                     options::OPT_fno_omit_frame_pointer, false))
+      getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
+          << "-fomit-frame-pointer" << BoundArch;
+  }
+
+  return DAL;
+}
+
+bool MachO::IsUnwindTablesDefault() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool MachO::UseDwarfDebugFlags() const {
+  if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
+    return S[0] != '\0';
+  return false;
+}
+
+bool Darwin::UseSjLjExceptions(const ArgList &Args) const {
+  // Darwin uses SjLj exceptions on ARM.
+  if (getTriple().getArch() != llvm::Triple::arm &&
+      getTriple().getArch() != llvm::Triple::thumb)
+    return false;
+
+  // Only watchOS uses the new DWARF/Compact unwinding method.
+  llvm::Triple Triple(ComputeLLVMTriple(Args));
+  return !Triple.isWatchABI();
+}
+
+bool Darwin::SupportsEmbeddedBitcode() const {
+  assert(TargetInitialized && "Target not initialized!");
+  if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
+    return false;
+  return true;
+}
+
+bool MachO::isPICDefault() const { return true; }
+
+bool MachO::isPIEDefault() const { return false; }
+
+bool MachO::isPICDefaultForced() const {
+  return (getArch() == llvm::Triple::x86_64 ||
+          getArch() == llvm::Triple::aarch64);
+}
+
+bool MachO::SupportsProfiling() const {
+  // Profiling instrumentation is only supported on x86.
+  return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
+}
+
+void Darwin::addMinVersionArgs(const ArgList &Args,
+                               ArgStringList &CmdArgs) const {
+  VersionTuple TargetVersion = getTargetVersion();
+
+  if (isTargetWatchOS())
+    CmdArgs.push_back("-watchos_version_min");
+  else if (isTargetWatchOSSimulator())
+    CmdArgs.push_back("-watchos_simulator_version_min");
+  else if (isTargetTvOS())
+    CmdArgs.push_back("-tvos_version_min");
+  else if (isTargetTvOSSimulator())
+    CmdArgs.push_back("-tvos_simulator_version_min");
+  else if (isTargetIOSSimulator())
+    CmdArgs.push_back("-ios_simulator_version_min");
+  else if (isTargetIOSBased())
+    CmdArgs.push_back("-iphoneos_version_min");
+  else {
+    assert(isTargetMacOS() && "unexpected target");
+    CmdArgs.push_back("-macosx_version_min");
+  }
+
+  CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
+}
+
+void Darwin::addStartObjectFileArgs(const ArgList &Args,
+                                    ArgStringList &CmdArgs) const {
+  // Derived from startfile spec.
+  if (Args.hasArg(options::OPT_dynamiclib)) {
+    // Derived from darwin_dylib1 spec.
+    if (isTargetWatchOSBased()) {
+      ; // watchOS does not need dylib1.o.
+    } else if (isTargetIOSSimulator()) {
+      ; // iOS simulator does not need dylib1.o.
+    } else if (isTargetIPhoneOS()) {
+      if (isIPhoneOSVersionLT(3, 1))
+        CmdArgs.push_back("-ldylib1.o");
+    } else {
+      if (isMacosxVersionLT(10, 5))
+        CmdArgs.push_back("-ldylib1.o");
+      else if (isMacosxVersionLT(10, 6))
+        CmdArgs.push_back("-ldylib1.10.5.o");
+    }
+  } else {
+    if (Args.hasArg(options::OPT_bundle)) {
+      if (!Args.hasArg(options::OPT_static)) {
+        // Derived from darwin_bundle1 spec.
+        if (isTargetWatchOSBased()) {
+          ; // watchOS does not need bundle1.o.
+        } else if (isTargetIOSSimulator()) {
+          ; // iOS simulator does not need bundle1.o.
+        } else if (isTargetIPhoneOS()) {
+          if (isIPhoneOSVersionLT(3, 1))
+            CmdArgs.push_back("-lbundle1.o");
+        } else {
+          if (isMacosxVersionLT(10, 6))
+            CmdArgs.push_back("-lbundle1.o");
+        }
+      }
+    } else {
+      if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) {
+        if (Args.hasArg(options::OPT_static) ||
+            Args.hasArg(options::OPT_object) ||
+            Args.hasArg(options::OPT_preload)) {
+          CmdArgs.push_back("-lgcrt0.o");
+        } else {
+          CmdArgs.push_back("-lgcrt1.o");
+
+          // darwin_crt2 spec is empty.
+        }
+        // By default on OS X 10.8 and later, we don't link with a crt1.o
+        // file and the linker knows to use _main as the entry point.  But,
+        // when compiling with -pg, we need to link with the gcrt1.o file,
+        // so pass the -no_new_main option to tell the linker to use the
+        // "start" symbol as the entry point.
+        if (isTargetMacOS() && !isMacosxVersionLT(10, 8))
+          CmdArgs.push_back("-no_new_main");
+      } else {
+        if (Args.hasArg(options::OPT_static) ||
+            Args.hasArg(options::OPT_object) ||
+            Args.hasArg(options::OPT_preload)) {
+          CmdArgs.push_back("-lcrt0.o");
+        } else {
+          // Derived from darwin_crt1 spec.
+          if (isTargetWatchOSBased()) {
+            ; // watchOS does not need crt1.o.
+          } else if (isTargetIOSSimulator()) {
+            ; // iOS simulator does not need crt1.o.
+          } else if (isTargetIPhoneOS()) {
+            if (getArch() == llvm::Triple::aarch64)
+              ; // iOS does not need any crt1 files for arm64
+            else if (isIPhoneOSVersionLT(3, 1))
+              CmdArgs.push_back("-lcrt1.o");
+            else if (isIPhoneOSVersionLT(6, 0))
+              CmdArgs.push_back("-lcrt1.3.1.o");
+          } else {
+            if (isMacosxVersionLT(10, 5))
+              CmdArgs.push_back("-lcrt1.o");
+            else if (isMacosxVersionLT(10, 6))
+              CmdArgs.push_back("-lcrt1.10.5.o");
+            else if (isMacosxVersionLT(10, 8))
+              CmdArgs.push_back("-lcrt1.10.6.o");
+
+            // darwin_crt2 spec is empty.
+          }
+        }
+      }
+    }
+  }
+
+  if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) &&
+      !isTargetWatchOS() &&
+      isMacosxVersionLT(10, 5)) {
+    const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
+    CmdArgs.push_back(Str);
+  }
+}
+
+bool Darwin::SupportsObjCGC() const { return isTargetMacOS(); }
+
+void Darwin::CheckObjCARC() const {
+  if (isTargetIOSBased() || isTargetWatchOSBased() ||
+      (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
+    return;
+  getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
+}
+
+SanitizerMask Darwin::getSupportedSanitizers() const {
+  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::Address;
+  if (isTargetMacOS()) {
+    if (!isMacosxVersionLT(10, 9))
+      Res |= SanitizerKind::Vptr;
+    Res |= SanitizerKind::SafeStack;
+    if (IsX86_64)
+      Res |= SanitizerKind::Thread;
+  } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) {
+    if (IsX86_64)
+      Res |= SanitizerKind::Thread;
+  }
+  return Res;
+}
+
+void Darwin::printVerboseInfo(raw_ostream &OS) const {
+  CudaInstallation.print(OS);
+}
diff --git a/lib/Driver/ToolChains/Darwin.h b/lib/Driver/ToolChains/Darwin.h
new file mode 100644
index 0000000..984f8ef
--- /dev/null
+++ b/lib/Driver/ToolChains/Darwin.h
@@ -0,0 +1,488 @@
+//===--- Darwin.h - Darwin ToolChain Implementations ------------*- 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_LIB_DRIVER_TOOLCHAINS_DARWIN_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
+
+#include "Cuda.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+
+namespace toolchains {
+class MachO;
+} // end namespace toolchains
+
+namespace tools {
+
+namespace darwin {
+llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str);
+void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str);
+
+class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool {
+  virtual void anchor();
+
+protected:
+  void AddMachOArch(const llvm::opt::ArgList &Args,
+                    llvm::opt::ArgStringList &CmdArgs) const;
+
+  const toolchains::MachO &getMachOToolChain() const {
+    return reinterpret_cast<const toolchains::MachO &>(getToolChain());
+  }
+
+public:
+  MachOTool(
+      const char *Name, const char *ShortName, const ToolChain &TC,
+      ResponseFileSupport ResponseSupport = RF_None,
+      llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8,
+      const char *ResponseFlag = "@")
+      : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding,
+             ResponseFlag) {}
+};
+
+class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool {
+public:
+  Assembler(const ToolChain &TC)
+      : MachOTool("darwin::Assembler", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool {
+  bool NeedsTempPath(const InputInfoList &Inputs) const;
+  void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args,
+                   llvm::opt::ArgStringList &CmdArgs,
+                   const InputInfoList &Inputs) const;
+
+public:
+  Linker(const ToolChain &TC)
+      : MachOTool("darwin::Linker", "linker", TC, RF_FileList,
+                  llvm::sys::WEM_UTF8, "-filelist") {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool {
+public:
+  Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool {
+public:
+  Dsymutil(const ToolChain &TC)
+      : MachOTool("darwin::Dsymutil", "dsymutil", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isDsymutilJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool {
+public:
+  VerifyDebug(const ToolChain &TC)
+      : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace darwin
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+  Tool *getTool(Action::ActionClass AC) const override;
+
+private:
+  mutable std::unique_ptr<tools::darwin::Lipo> Lipo;
+  mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil;
+  mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug;
+
+public:
+  MachO(const Driver &D, const llvm::Triple &Triple,
+        const llvm::opt::ArgList &Args);
+  ~MachO() override;
+
+  /// @name MachO specific toolchain API
+  /// {
+
+  /// Get the "MachO" arch name for a particular compiler invocation. For
+  /// example, Apple treats different ARM variations as distinct architectures.
+  StringRef getMachOArchName(const llvm::opt::ArgList &Args) const;
+
+  /// Add the linker arguments to link the ARC runtime library.
+  virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args,
+                              llvm::opt::ArgStringList &CmdArgs) const {}
+
+  /// Add the linker arguments to link the compiler runtime library.
+  virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
+                                     llvm::opt::ArgStringList &CmdArgs) const;
+
+  virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
+                                      llvm::opt::ArgStringList &CmdArgs) const {
+  }
+
+  virtual void addMinVersionArgs(const llvm::opt::ArgList &Args,
+                                 llvm::opt::ArgStringList &CmdArgs) const {}
+
+  /// On some iOS platforms, kernel and kernel modules were built statically. Is
+  /// this such a target?
+  virtual bool isKernelStatic() const { return false; }
+
+  /// Is the target either iOS or an iOS simulator?
+  bool isTargetIOSBased() const { return false; }
+
+  void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
+                         llvm::opt::ArgStringList &CmdArgs,
+                         StringRef DarwinLibName, bool AlwaysLink = false,
+                         bool IsEmbedded = false, bool AddRPath = false) const;
+
+  /// Add any profiling runtime libraries that are needed. This is essentially a
+  /// MachO specific version of addProfileRT in Tools.cpp.
+  void addProfileRTLibs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const override {
+    // There aren't any profiling libs for embedded targets currently.
+  }
+
+  /// }
+  /// @name ToolChain Implementation
+  /// {
+
+  types::ID LookupTypeForExtension(StringRef Ext) const override;
+
+  bool HasNativeLLVMSupport() const override;
+
+  llvm::opt::DerivedArgList *
+  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
+                Action::OffloadKind DeviceOffloadKind) const override;
+
+  bool IsBlocksDefault() const override {
+    // Always allow blocks on Apple; users interested in versioning are
+    // expected to use /usr/include/Block.h.
+    return true;
+  }
+  bool IsIntegratedAssemblerDefault() const override {
+    // Default integrated assembler to on for Apple's MachO targets.
+    return true;
+  }
+
+  bool IsMathErrnoDefault() const override { return false; }
+
+  bool IsEncodeExtendedBlockSignatureDefault() const override { return true; }
+
+  bool IsObjCNonFragileABIDefault() const override {
+    // Non-fragile ABI is default for everything but i386.
+    return getTriple().getArch() != llvm::Triple::x86;
+  }
+
+  bool UseObjCMixedDispatch() const override { return true; }
+
+  bool IsUnwindTablesDefault() const override;
+
+  RuntimeLibType GetDefaultRuntimeLibType() const override {
+    return ToolChain::RLT_CompilerRT;
+  }
+
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+
+  bool SupportsProfiling() const override;
+
+  bool SupportsObjCGC() const override { return false; }
+
+  bool UseDwarfDebugFlags() const override;
+
+  bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override {
+    return false;
+  }
+
+  /// }
+};
+
+/// Darwin - The base Darwin tool chain.
+class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
+public:
+  /// Whether the information on the target has been initialized.
+  //
+  // FIXME: This should be eliminated. What we want to do is make this part of
+  // the "default target for arguments" selection process, once we get out of
+  // the argument translation business.
+  mutable bool TargetInitialized;
+
+  enum DarwinPlatformKind {
+    MacOS,
+    IPhoneOS,
+    IPhoneOSSimulator,
+    TvOS,
+    TvOSSimulator,
+    WatchOS,
+    WatchOSSimulator
+  };
+
+  mutable DarwinPlatformKind TargetPlatform;
+
+  /// The OS version we are targeting.
+  mutable VersionTuple TargetVersion;
+
+  CudaInstallationDetector CudaInstallation;
+
+private:
+  void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;
+
+public:
+  Darwin(const Driver &D, const llvm::Triple &Triple,
+         const llvm::opt::ArgList &Args);
+  ~Darwin() override;
+
+  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
+                                          types::ID InputType) const override;
+
+  /// @name Apple Specific Toolchain Implementation
+  /// {
+
+  void addMinVersionArgs(const llvm::opt::ArgList &Args,
+                         llvm::opt::ArgStringList &CmdArgs) const override;
+
+  void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
+                              llvm::opt::ArgStringList &CmdArgs) const override;
+
+  bool isKernelStatic() const override {
+    return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) &&
+            !isTargetWatchOS());
+  }
+
+  void addProfileRTLibs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const override;
+
+protected:
+  /// }
+  /// @name Darwin specific Toolchain functions
+  /// {
+
+  // FIXME: Eliminate these ...Target functions and derive separate tool chains
+  // for these targets and put version in constructor.
+  void setTarget(DarwinPlatformKind Platform, unsigned Major, unsigned Minor,
+                 unsigned Micro) const {
+    // FIXME: For now, allow reinitialization as long as values don't
+    // change. This will go away when we move away from argument translation.
+    if (TargetInitialized && TargetPlatform == Platform &&
+        TargetVersion == VersionTuple(Major, Minor, Micro))
+      return;
+
+    assert(!TargetInitialized && "Target already initialized!");
+    TargetInitialized = true;
+    TargetPlatform = Platform;
+    TargetVersion = VersionTuple(Major, Minor, Micro);
+  }
+
+  bool isTargetIPhoneOS() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetPlatform == IPhoneOS || TargetPlatform == TvOS;
+  }
+
+  bool isTargetIOSSimulator() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetPlatform == IPhoneOSSimulator ||
+           TargetPlatform == TvOSSimulator;
+  }
+
+  bool isTargetIOSBased() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return isTargetIPhoneOS() || isTargetIOSSimulator();
+  }
+
+  bool isTargetTvOS() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetPlatform == TvOS;
+  }
+
+  bool isTargetTvOSSimulator() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetPlatform == TvOSSimulator;
+  }
+
+  bool isTargetTvOSBased() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetPlatform == TvOS || TargetPlatform == TvOSSimulator;
+  }
+
+  bool isTargetWatchOS() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetPlatform == WatchOS;
+  }
+
+  bool isTargetWatchOSSimulator() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetPlatform == WatchOSSimulator;
+  }
+
+  bool isTargetWatchOSBased() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetPlatform == WatchOS || TargetPlatform == WatchOSSimulator;
+  }
+
+  bool isTargetMacOS() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetPlatform == MacOS;
+  }
+
+  bool isTargetInitialized() const { return TargetInitialized; }
+
+  VersionTuple getTargetVersion() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetVersion;
+  }
+
+  bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
+                           unsigned V2 = 0) const {
+    assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
+    return TargetVersion < VersionTuple(V0, V1, V2);
+  }
+
+  bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
+    assert(isTargetMacOS() && "Unexpected call for non OS X target!");
+    return TargetVersion < VersionTuple(V0, V1, V2);
+  }
+
+  StringRef getPlatformFamily() const;
+  static StringRef getSDKName(StringRef isysroot);
+  StringRef getOSLibraryNameSuffix() const;
+
+public:
+  /// }
+  /// @name ToolChain Implementation
+  /// {
+
+  // Darwin tools support multiple architecture (e.g., i386 and x86_64) and
+  // most development is done against SDKs, so compiling for a different
+  // architecture should not get any special treatment.
+  bool isCrossCompiling() const override { return false; }
+
+  llvm::opt::DerivedArgList *
+  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
+                Action::OffloadKind DeviceOffloadKind) const override;
+
+  CXXStdlibType GetDefaultCXXStdlibType() const override;
+  ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
+  bool hasBlocksRuntime() const override;
+
+  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const override;
+
+  bool UseObjCMixedDispatch() const override {
+    // This is only used with the non-fragile ABI and non-legacy dispatch.
+
+    // Mixed dispatch is used everywhere except OS X before 10.6.
+    return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
+  }
+
+  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
+    // Stack protectors default to on for user code on 10.5,
+    // and for everything in 10.6 and beyond
+    if (isTargetIOSBased() || isTargetWatchOSBased())
+      return 1;
+    else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
+      return 1;
+    else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
+      return 1;
+
+    return 0;
+  }
+
+  bool SupportsObjCGC() const override;
+
+  void CheckObjCARC() const override;
+
+  bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
+
+  bool SupportsEmbeddedBitcode() const override;
+
+  SanitizerMask getSupportedSanitizers() const override;
+
+  void printVerboseInfo(raw_ostream &OS) const override;
+};
+
+/// DarwinClang - The Darwin toolchain used by Clang.
+class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
+public:
+  DarwinClang(const Driver &D, const llvm::Triple &Triple,
+              const llvm::opt::ArgList &Args);
+
+  /// @name Apple ToolChain Implementation
+  /// {
+
+  RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
+
+  void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
+                             llvm::opt::ArgStringList &CmdArgs) const override;
+
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+
+  void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const override;
+
+  void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
+
+  void AddLinkARCArgs(const llvm::opt::ArgList &Args,
+                      llvm::opt::ArgStringList &CmdArgs) const override;
+
+  unsigned GetDefaultDwarfVersion() const override;
+  // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
+  // Darwin defaults to standalone/full debug info.
+  bool GetDefaultStandaloneDebug() const override { return true; }
+  llvm::DebuggerKind getDefaultDebuggerTuning() const override {
+    return llvm::DebuggerKind::LLDB;
+  }
+
+  /// }
+
+private:
+  void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
+                               llvm::opt::ArgStringList &CmdArgs,
+                               StringRef Sanitizer) const;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
diff --git a/lib/Driver/ToolChains/DragonFly.cpp b/lib/Driver/ToolChains/DragonFly.cpp
new file mode 100644
index 0000000..bd2c7fc
--- /dev/null
+++ b/lib/Driver/ToolChains/DragonFly.cpp
@@ -0,0 +1,197 @@
+//===--- DragonFly.cpp - DragonFly ToolChain Implementations ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DragonFly.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+/// DragonFly Tools
+
+// For now, DragonFly Assemble does just about the same as for
+// FreeBSD, but this may change soon.
+void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                        const InputInfo &Output,
+                                        const InputInfoList &Inputs,
+                                        const ArgList &Args,
+                                        const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  // When building 32-bit code on DragonFly/pc64, we have to explicitly
+  // instruct as in the base system to assemble 32-bit code.
+  if (getToolChain().getArch() == llvm::Triple::x86)
+    CmdArgs.push_back("--32");
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                     const InputInfo &Output,
+                                     const InputInfoList &Inputs,
+                                     const ArgList &Args,
+                                     const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  CmdArgs.push_back("--eh-frame-hdr");
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    if (Args.hasArg(options::OPT_rdynamic))
+      CmdArgs.push_back("-export-dynamic");
+    if (Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back("-Bshareable");
+    else {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
+    }
+    CmdArgs.push_back("--hash-style=gnu");
+    CmdArgs.push_back("--enable-new-dtags");
+  }
+
+  // When building 32-bit code on DragonFly/pc64, we have to explicitly
+  // instruct ld in the base system to link 32-bit code.
+  if (getToolChain().getArch() == llvm::Triple::x86) {
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf_i386");
+  }
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("gcrt1.o")));
+      else {
+        if (Args.hasArg(options::OPT_pie))
+          CmdArgs.push_back(
+              Args.MakeArgString(getToolChain().GetFilePath("Scrt1.o")));
+        else
+          CmdArgs.push_back(
+              Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
+      }
+    }
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
+    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
+    else
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
+  }
+
+  Args.AddAllArgs(CmdArgs,
+                  {options::OPT_L, options::OPT_T_Group, options::OPT_e});
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    CmdArgs.push_back("-L/usr/lib/gcc50");
+
+    if (!Args.hasArg(options::OPT_static)) {
+      CmdArgs.push_back("-rpath");
+      CmdArgs.push_back("/usr/lib/gcc50");
+    }
+
+    if (D.CCCIsCXX()) {
+      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      CmdArgs.push_back("-lm");
+    }
+
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-lpthread");
+
+    if (!Args.hasArg(options::OPT_nolibc)) {
+      CmdArgs.push_back("-lc");
+    }
+
+    if (Args.hasArg(options::OPT_static) ||
+        Args.hasArg(options::OPT_static_libgcc)) {
+        CmdArgs.push_back("-lgcc");
+        CmdArgs.push_back("-lgcc_eh");
+    } else {
+      if (Args.hasArg(options::OPT_shared_libgcc)) {
+          CmdArgs.push_back("-lgcc_pic");
+          if (!Args.hasArg(options::OPT_shared))
+            CmdArgs.push_back("-lgcc");
+      } else {
+          CmdArgs.push_back("-lgcc");
+          CmdArgs.push_back("--as-needed");
+          CmdArgs.push_back("-lgcc_pic");
+          CmdArgs.push_back("--no-as-needed");
+      }
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
+    else
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
+  }
+
+  getToolChain().addProfileRTLibs(Args, CmdArgs);
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
+
+DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
+                     const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+
+  // Path mangling to find libexec
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
+
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+  getFilePaths().push_back("/usr/lib/gcc50");
+}
+
+Tool *DragonFly::buildAssembler() const {
+  return new tools::dragonfly::Assembler(*this);
+}
+
+Tool *DragonFly::buildLinker() const {
+  return new tools::dragonfly::Linker(*this);
+}
diff --git a/lib/Driver/ToolChains/DragonFly.h b/lib/Driver/ToolChains/DragonFly.h
new file mode 100644
index 0000000..9a06fbd
--- /dev/null
+++ b/lib/Driver/ToolChains/DragonFly.h
@@ -0,0 +1,68 @@
+//===--- DragonFly.h - DragonFly ToolChain Implementations ------*- 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_LIB_DRIVER_TOOLCHAINS_DRAGONFLY_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DRAGONFLY_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+/// dragonfly -- Directly call GNU Binutils assembler and linker
+namespace dragonfly {
+class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+public:
+  Assembler(const ToolChain &TC)
+      : GnuTool("dragonfly::Assembler", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("dragonfly::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace dragonfly
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
+public:
+  DragonFly(const Driver &D, const llvm::Triple &Triple,
+            const llvm::opt::ArgList &Args);
+
+  bool IsMathErrnoDefault() const override { return false; }
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DRAGONFLY_H
diff --git a/lib/Driver/ToolChains/FreeBSD.cpp b/lib/Driver/ToolChains/FreeBSD.cpp
new file mode 100644
index 0000000..c6626e9
--- /dev/null
+++ b/lib/Driver/ToolChains/FreeBSD.cpp
@@ -0,0 +1,395 @@
+//===--- FreeBSD.cpp - FreeBSD ToolChain Implementations --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "FreeBSD.h"
+#include "Arch/ARM.h"
+#include "Arch/Mips.h"
+#include "Arch/Sparc.h"
+#include "CommonArgs.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                      const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const ArgList &Args,
+                                      const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
+  // instruct as in the base system to assemble 32-bit code.
+  switch (getToolChain().getArch()) {
+  default:
+    break;
+  case llvm::Triple::x86:
+    CmdArgs.push_back("--32");
+    break;
+  case llvm::Triple::ppc:
+    CmdArgs.push_back("-a32");
+    break;
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el: {
+    StringRef CPUName;
+    StringRef ABIName;
+    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+
+    CmdArgs.push_back("-march");
+    CmdArgs.push_back(CPUName.data());
+
+    CmdArgs.push_back("-mabi");
+    CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
+
+    if (getToolChain().getArch() == llvm::Triple::mips ||
+        getToolChain().getArch() == llvm::Triple::mips64)
+      CmdArgs.push_back("-EB");
+    else
+      CmdArgs.push_back("-EL");
+
+    if (Arg *A = Args.getLastArg(options::OPT_G)) {
+      StringRef v = A->getValue();
+      CmdArgs.push_back(Args.MakeArgString("-G" + v));
+      A->claim();
+    }
+
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb: {
+    arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
+
+    if (ABI == arm::FloatABI::Hard)
+      CmdArgs.push_back("-mfpu=vfp");
+    else
+      CmdArgs.push_back("-mfpu=softvfp");
+
+    switch (getToolChain().getTriple().getEnvironment()) {
+    case llvm::Triple::GNUEABIHF:
+    case llvm::Triple::GNUEABI:
+    case llvm::Triple::EABI:
+      CmdArgs.push_back("-meabi=5");
+      break;
+
+    default:
+      CmdArgs.push_back("-matpcs");
+    }
+    break;
+  }
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+  case llvm::Triple::sparcv9: {
+    std::string CPU = getCPUName(Args, getToolChain().getTriple());
+    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                   const InputInfo &Output,
+                                   const InputInfoList &Inputs,
+                                   const ArgList &Args,
+                                   const char *LinkingOutput) const {
+  const toolchains::FreeBSD &ToolChain =
+      static_cast<const toolchains::FreeBSD &>(getToolChain());
+  const Driver &D = ToolChain.getDriver();
+  const llvm::Triple::ArchType Arch = ToolChain.getArch();
+  const bool IsPIE =
+      !Args.hasArg(options::OPT_shared) &&
+      (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault());
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (IsPIE)
+    CmdArgs.push_back("-pie");
+
+  CmdArgs.push_back("--eh-frame-hdr");
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    if (Args.hasArg(options::OPT_rdynamic))
+      CmdArgs.push_back("-export-dynamic");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-Bshareable");
+    } else {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/libexec/ld-elf.so.1");
+    }
+    if (ToolChain.getTriple().getOSMajorVersion() >= 9) {
+      if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
+          Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
+        CmdArgs.push_back("--hash-style=both");
+      }
+    }
+    CmdArgs.push_back("--enable-new-dtags");
+  }
+
+  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
+  // instruct ld in the base system to link 32-bit code.
+  if (Arch == llvm::Triple::x86) {
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf_i386_fbsd");
+  }
+
+  if (Arch == llvm::Triple::ppc) {
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf32ppc_fbsd");
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_G)) {
+    if (ToolChain.getArch() == llvm::Triple::mips ||
+      ToolChain.getArch() == llvm::Triple::mipsel ||
+      ToolChain.getArch() == llvm::Triple::mips64 ||
+      ToolChain.getArch() == llvm::Triple::mips64el) {
+      StringRef v = A->getValue();
+      CmdArgs.push_back(Args.MakeArgString("-G" + v));
+      A->claim();
+    }
+  }
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    const char *crt1 = nullptr;
+    if (!Args.hasArg(options::OPT_shared)) {
+      if (Args.hasArg(options::OPT_pg))
+        crt1 = "gcrt1.o";
+      else if (IsPIE)
+        crt1 = "Scrt1.o";
+      else
+        crt1 = "crt1.o";
+    }
+    if (crt1)
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
+
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
+
+    const char *crtbegin = nullptr;
+    if (Args.hasArg(options::OPT_static))
+      crtbegin = "crtbeginT.o";
+    else if (Args.hasArg(options::OPT_shared) || IsPIE)
+      crtbegin = "crtbeginS.o";
+    else
+      crtbegin = "crtbegin.o";
+
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+  Args.AddAllArgs(CmdArgs, options::OPT_s);
+  Args.AddAllArgs(CmdArgs, options::OPT_t);
+  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
+  Args.AddAllArgs(CmdArgs, options::OPT_r);
+
+  if (D.isUsingLTO())
+    AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin, D);
+
+  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    addOpenMPRuntime(CmdArgs, ToolChain, Args);
+    if (D.CCCIsCXX()) {
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lm_p");
+      else
+        CmdArgs.push_back("-lm");
+    }
+    if (NeedsSanitizerDeps)
+      linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
+    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
+    // the default system libraries. Just mimic this for now.
+    if (Args.hasArg(options::OPT_pg))
+      CmdArgs.push_back("-lgcc_p");
+    else
+      CmdArgs.push_back("-lgcc");
+    if (Args.hasArg(options::OPT_static)) {
+      CmdArgs.push_back("-lgcc_eh");
+    } else if (Args.hasArg(options::OPT_pg)) {
+      CmdArgs.push_back("-lgcc_eh_p");
+    } else {
+      CmdArgs.push_back("--as-needed");
+      CmdArgs.push_back("-lgcc_s");
+      CmdArgs.push_back("--no-as-needed");
+    }
+
+    if (Args.hasArg(options::OPT_pthread)) {
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lpthread_p");
+      else
+        CmdArgs.push_back("-lpthread");
+    }
+
+    if (Args.hasArg(options::OPT_pg)) {
+      if (Args.hasArg(options::OPT_shared))
+        CmdArgs.push_back("-lc");
+      else
+        CmdArgs.push_back("-lc_p");
+      CmdArgs.push_back("-lgcc_p");
+    } else {
+      CmdArgs.push_back("-lc");
+      CmdArgs.push_back("-lgcc");
+    }
+
+    if (Args.hasArg(options::OPT_static)) {
+      CmdArgs.push_back("-lgcc_eh");
+    } else if (Args.hasArg(options::OPT_pg)) {
+      CmdArgs.push_back("-lgcc_eh_p");
+    } else {
+      CmdArgs.push_back("--as-needed");
+      CmdArgs.push_back("-lgcc_s");
+      CmdArgs.push_back("--no-as-needed");
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (Args.hasArg(options::OPT_shared) || IsPIE)
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
+    else
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+  }
+
+  ToolChain.addProfileRTLibs(Args, CmdArgs);
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
+
+FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple,
+                 const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+
+  // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
+  // back to '/usr/lib' if it doesn't exist.
+  if ((Triple.getArch() == llvm::Triple::x86 ||
+       Triple.getArch() == llvm::Triple::ppc) &&
+      D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
+    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
+  else
+    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
+}
+
+ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const {
+  if (getTriple().getOSMajorVersion() >= 10)
+    return ToolChain::CST_Libcxx;
+  return ToolChain::CST_Libstdcxx;
+}
+
+void FreeBSD::addLibStdCxxIncludePaths(
+    const llvm::opt::ArgList &DriverArgs,
+    llvm::opt::ArgStringList &CC1Args) const {
+  addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/c++/4.2", "", "",
+                           "", "", DriverArgs, CC1Args);
+}
+
+void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
+                                  ArgStringList &CmdArgs) const {
+  CXXStdlibType Type = GetCXXStdlibType(Args);
+  bool Profiling = Args.hasArg(options::OPT_pg);
+
+  switch (Type) {
+  case ToolChain::CST_Libcxx:
+    CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
+    break;
+
+  case ToolChain::CST_Libstdcxx:
+    CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++");
+    break;
+  }
+}
+
+Tool *FreeBSD::buildAssembler() const {
+  return new tools::freebsd::Assembler(*this);
+}
+
+Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); }
+
+bool FreeBSD::UseSjLjExceptions(const ArgList &Args) const {
+  // FreeBSD uses SjLj exceptions on ARM oabi.
+  switch (getTriple().getEnvironment()) {
+  case llvm::Triple::GNUEABIHF:
+  case llvm::Triple::GNUEABI:
+  case llvm::Triple::EABI:
+    return false;
+
+  default:
+    return (getTriple().getArch() == llvm::Triple::arm ||
+            getTriple().getArch() == llvm::Triple::thumb);
+  }
+}
+
+bool FreeBSD::HasNativeLLVMSupport() const { return true; }
+
+bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
+
+SanitizerMask FreeBSD::getSupportedSanitizers() const {
+  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
+  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
+  const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
+                        getTriple().getArch() == llvm::Triple::mips64el;
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::Address;
+  Res |= SanitizerKind::Vptr;
+  if (IsX86_64 || IsMIPS64) {
+    Res |= SanitizerKind::Leak;
+    Res |= SanitizerKind::Thread;
+  }
+  if (IsX86 || IsX86_64) {
+    Res |= SanitizerKind::SafeStack;
+  }
+  return Res;
+}
diff --git a/lib/Driver/ToolChains/FreeBSD.h b/lib/Driver/ToolChains/FreeBSD.h
new file mode 100644
index 0000000..25e9df7
--- /dev/null
+++ b/lib/Driver/ToolChains/FreeBSD.h
@@ -0,0 +1,86 @@
+//===--- FreeBSD.h - FreeBSD ToolChain Implementations ----------*- 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_LIB_DRIVER_TOOLCHAINS_FREEBSD_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FREEBSD_H
+
+#include "Gnu.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+/// freebsd -- Directly call GNU Binutils assembler and linker
+namespace freebsd {
+class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+public:
+  Assembler(const ToolChain &TC)
+      : GnuTool("freebsd::Assembler", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("freebsd::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace freebsd
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
+public:
+  FreeBSD(const Driver &D, const llvm::Triple &Triple,
+          const llvm::opt::ArgList &Args);
+  bool HasNativeLLVMSupport() const override;
+
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
+
+  CXXStdlibType GetDefaultCXXStdlibType() const override;
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+
+  bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
+  bool isPIEDefault() const override;
+  SanitizerMask getSupportedSanitizers() const override;
+  unsigned GetDefaultDwarfVersion() const override { return 2; }
+  // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
+  // FreeBSD defaults to standalone/full debug info.
+  bool GetDefaultStandaloneDebug() const override { return true; }
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FREEBSD_H
diff --git a/lib/Driver/ToolChains/Fuchsia.cpp b/lib/Driver/ToolChains/Fuchsia.cpp
new file mode 100644
index 0000000..b8757cf
--- /dev/null
+++ b/lib/Driver/ToolChains/Fuchsia.cpp
@@ -0,0 +1,229 @@
+//===--- Fuchsia.cpp - Fuchsia ToolChain Implementations --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Fuchsia.h"
+#include "CommonArgs.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                   const InputInfo &Output,
+                                   const InputInfoList &Inputs,
+                                   const ArgList &Args,
+                                   const char *LinkingOutput) const {
+  const toolchains::Fuchsia &ToolChain =
+      static_cast<const toolchains::Fuchsia &>(getToolChain());
+  const Driver &D = ToolChain.getDriver();
+
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
+  if (llvm::sys::path::stem(Exec).equals_lower("lld")) {
+    CmdArgs.push_back("-flavor");
+    CmdArgs.push_back("gnu");
+  }
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r))
+    CmdArgs.push_back("-pie");
+
+  if (Args.hasArg(options::OPT_rdynamic))
+    CmdArgs.push_back("-export-dynamic");
+
+  if (Args.hasArg(options::OPT_s))
+    CmdArgs.push_back("-s");
+
+  if (Args.hasArg(options::OPT_r))
+    CmdArgs.push_back("-r");
+  else
+    CmdArgs.push_back("--build-id");
+
+  if (!Args.hasArg(options::OPT_static))
+    CmdArgs.push_back("--eh-frame-hdr");
+
+  if (Args.hasArg(options::OPT_static))
+    CmdArgs.push_back("-Bstatic");
+  else if (Args.hasArg(options::OPT_shared))
+    CmdArgs.push_back("-shared");
+
+  if (!Args.hasArg(options::OPT_static)) {
+    if (Args.hasArg(options::OPT_rdynamic))
+      CmdArgs.push_back("-export-dynamic");
+
+    if (!Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back(Args.MakeArgString(D.DyldPrefix + "ld.so.1"));
+    }
+  }
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o")));
+    }
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_u);
+
+  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    if (Args.hasArg(options::OPT_static))
+      CmdArgs.push_back("-Bdynamic");
+
+    if (D.CCCIsCXX()) {
+      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+                                 !Args.hasArg(options::OPT_static);
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bstatic");
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bdynamic");
+      CmdArgs.push_back("-lm");
+    }
+
+    AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
+
+    if (Args.hasArg(options::OPT_pthread) ||
+        Args.hasArg(options::OPT_pthreads))
+      CmdArgs.push_back("-lpthread");
+
+    if (Args.hasArg(options::OPT_fsplit_stack))
+      CmdArgs.push_back("--wrap=pthread_create");
+
+    CmdArgs.push_back("-lc");
+  }
+
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly.
+
+Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
+                 const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+
+  getFilePaths().push_back(D.SysRoot + "/lib");
+  getFilePaths().push_back(D.ResourceDir + "/lib/fuchsia");
+}
+
+Tool *Fuchsia::buildAssembler() const {
+  return new tools::gnutools::Assembler(*this);
+}
+
+Tool *Fuchsia::buildLinker() const {
+  return new tools::fuchsia::Linker(*this);
+}
+
+ToolChain::RuntimeLibType Fuchsia::GetRuntimeLibType(
+    const ArgList &Args) const {
+  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) {
+    StringRef Value = A->getValue();
+    if (Value != "compiler-rt")
+      getDriver().Diag(clang::diag::err_drv_invalid_rtlib_name)
+          << A->getAsString(Args);
+  }
+
+  return ToolChain::RLT_CompilerRT;
+}
+
+ToolChain::CXXStdlibType
+Fuchsia::GetCXXStdlibType(const ArgList &Args) const {
+  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
+    StringRef Value = A->getValue();
+    if (Value != "libc++")
+      getDriver().Diag(diag::err_drv_invalid_stdlib_name)
+        << A->getAsString(Args);
+  }
+
+  return ToolChain::CST_Libcxx;
+}
+
+void Fuchsia::addClangTargetOptions(const ArgList &DriverArgs,
+                                    ArgStringList &CC1Args) const {
+  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
+                         options::OPT_fno_use_init_array, true))
+    CC1Args.push_back("-fuse-init-array");
+}
+
+void Fuchsia::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                        ArgStringList &CC1Args) const {
+  const Driver &D = getDriver();
+
+  if (DriverArgs.hasArg(options::OPT_nostdinc))
+    return;
+
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    SmallString<128> P(D.ResourceDir);
+    llvm::sys::path::append(P, "include");
+    addSystemInclude(DriverArgs, CC1Args, P);
+  }
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
+  // Check for configure-time C include directories.
+  StringRef CIncludeDirs(C_INCLUDE_DIRS);
+  if (CIncludeDirs != "") {
+    SmallVector<StringRef, 5> dirs;
+    CIncludeDirs.split(dirs, ":");
+    for (StringRef dir : dirs) {
+      StringRef Prefix =
+          llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : "";
+      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
+    }
+    return;
+  }
+
+  addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include");
+}
+
+std::string Fuchsia::findLibCxxIncludePath() const {
+  return getDriver().SysRoot + "/include/c++/v1";
+}
+
+void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args,
+                                  ArgStringList &CmdArgs) const {
+  (void) GetCXXStdlibType(Args);
+  CmdArgs.push_back("-lc++");
+  CmdArgs.push_back("-lc++abi");
+  CmdArgs.push_back("-lunwind");
+}
+
+SanitizerMask Fuchsia::getSupportedSanitizers() const {
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::SafeStack;
+  return Res;
+}
diff --git a/lib/Driver/ToolChains/Fuchsia.h b/lib/Driver/ToolChains/Fuchsia.h
new file mode 100644
index 0000000..1a8c990
--- /dev/null
+++ b/lib/Driver/ToolChains/Fuchsia.h
@@ -0,0 +1,79 @@
+//===--- Fuchsia.h - Fuchsia ToolChain Implementations ----------*- 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_LIB_DRIVER_TOOLCHAINS_FUCHSIA_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FUCHSIA_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace fuchsia {
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("fuchsia::Linker", "ld.lld", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace fuchsia
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY Fuchsia : public Generic_ELF {
+public:
+  Fuchsia(const Driver &D, const llvm::Triple &Triple,
+          const llvm::opt::ArgList &Args);
+
+  bool isPIEDefault() const override { return true; }
+  bool HasNativeLLVMSupport() const override { return true; }
+  bool IsIntegratedAssemblerDefault() const override { return true; }
+  llvm::DebuggerKind getDefaultDebuggerTuning() const override {
+    return llvm::DebuggerKind::GDB;
+  }
+
+  SanitizerMask getSupportedSanitizers() const override;
+
+  RuntimeLibType
+  GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
+  CXXStdlibType
+  GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+
+  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                             llvm::opt::ArgStringList &CC1Args) const override;
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  std::string findLibCxxIncludePath() const override;
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+
+  const char *getDefaultLinker() const override {
+    return "lld";
+  }
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FUCHSIA_H
diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp
new file mode 100644
index 0000000..fe3c019
--- /dev/null
+++ b/lib/Driver/ToolChains/Gnu.cpp
@@ -0,0 +1,2428 @@
+//===--- Gnu.cpp - Gnu Tool and ToolChain Implementations -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Gnu.h"
+#include "Linux.h"
+#include "Arch/ARM.h"
+#include "Arch/Mips.h"
+#include "Arch/Sparc.h"
+#include "Arch/SystemZ.h"
+#include "CommonArgs.h"
+#include "clang/Basic/VirtualFileSystem.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"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/Tool.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/TargetParser.h"
+#include <system_error>
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+void tools::GnuTool::anchor() {}
+
+static bool forwardToGCC(const Option &O) {
+  // Don't forward inputs from the original command line.  They are added from
+  // InputInfoList.
+  return O.getKind() != Option::InputClass &&
+         !O.hasFlag(options::DriverOption) && !O.hasFlag(options::LinkerInput);
+}
+
+void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
+                                      const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const ArgList &Args,
+                                      const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  for (const auto &A : Args) {
+    if (forwardToGCC(A->getOption())) {
+      // It is unfortunate that we have to claim here, as this means
+      // we will basically never report anything interesting for
+      // platforms using a generic gcc, even if we are just using gcc
+      // to get to the assembler.
+      A->claim();
+
+      // Don't forward any -g arguments to assembly steps.
+      if (isa<AssembleJobAction>(JA) &&
+          A->getOption().matches(options::OPT_g_Group))
+        continue;
+
+      // Don't forward any -W arguments to assembly and link steps.
+      if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) &&
+          A->getOption().matches(options::OPT_W_Group))
+        continue;
+
+      A->render(Args, CmdArgs);
+    }
+  }
+
+  RenderExtraToolArgs(JA, CmdArgs);
+
+  // If using a driver driver, force the arch.
+  if (getToolChain().getTriple().isOSDarwin()) {
+    CmdArgs.push_back("-arch");
+    CmdArgs.push_back(
+        Args.MakeArgString(getToolChain().getDefaultUniversalArchName()));
+  }
+
+  // Try to force gcc to match the tool chain we want, if we recognize
+  // the arch.
+  //
+  // FIXME: The triple class should directly provide the information we want
+  // here.
+  switch (getToolChain().getArch()) {
+  default:
+    break;
+  case llvm::Triple::x86:
+  case llvm::Triple::ppc:
+    CmdArgs.push_back("-m32");
+    break;
+  case llvm::Triple::x86_64:
+  case llvm::Triple::ppc64:
+  case llvm::Triple::ppc64le:
+    CmdArgs.push_back("-m64");
+    break;
+  case llvm::Triple::sparcel:
+    CmdArgs.push_back("-EL");
+    break;
+  }
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Unexpected output");
+    CmdArgs.push_back("-fsyntax-only");
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  // Only pass -x if gcc will understand it; otherwise hope gcc
+  // understands the suffix correctly. The main use case this would go
+  // wrong in is for linker inputs if they happened to have an odd
+  // suffix; really the only way to get this to happen is a command
+  // like '-x foobar a.c' which will treat a.c like a linker input.
+  //
+  // FIXME: For the linker case specifically, can we safely convert
+  // inputs into '-Wl,' options?
+  for (const auto &II : Inputs) {
+    // Don't try to pass LLVM or AST inputs to a generic gcc.
+    if (types::isLLVMIR(II.getType()))
+      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+          << getToolChain().getTripleString();
+    else if (II.getType() == types::TY_AST)
+      D.Diag(diag::err_drv_no_ast_support) << getToolChain().getTripleString();
+    else if (II.getType() == types::TY_ModuleFile)
+      D.Diag(diag::err_drv_no_module_support)
+          << getToolChain().getTripleString();
+
+    if (types::canTypeBeUserSpecified(II.getType())) {
+      CmdArgs.push_back("-x");
+      CmdArgs.push_back(types::getTypeName(II.getType()));
+    }
+
+    if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else {
+      const Arg &A = II.getInputArg();
+
+      // Reverse translate some rewritten options.
+      if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
+        CmdArgs.push_back("-lstdc++");
+        continue;
+      }
+
+      // Don't render as input, we need gcc to do the translations.
+      A.render(Args, CmdArgs);
+    }
+  }
+
+  const std::string &customGCCName = D.getCCCGenericGCCName();
+  const char *GCCName;
+  if (!customGCCName.empty())
+    GCCName = customGCCName.c_str();
+  else if (D.CCCIsCXX()) {
+    GCCName = "g++";
+  } else
+    GCCName = "gcc";
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void tools::gcc::Preprocessor::RenderExtraToolArgs(
+    const JobAction &JA, ArgStringList &CmdArgs) const {
+  CmdArgs.push_back("-E");
+}
+
+void tools::gcc::Compiler::RenderExtraToolArgs(const JobAction &JA,
+                                               ArgStringList &CmdArgs) const {
+  const Driver &D = getToolChain().getDriver();
+
+  switch (JA.getType()) {
+  // If -flto, etc. are present then make sure not to force assembly output.
+  case types::TY_LLVM_IR:
+  case types::TY_LTO_IR:
+  case types::TY_LLVM_BC:
+  case types::TY_LTO_BC:
+    CmdArgs.push_back("-c");
+    break;
+  // We assume we've got an "integrated" assembler in that gcc will produce an
+  // object file itself.
+  case types::TY_Object:
+    CmdArgs.push_back("-c");
+    break;
+  case types::TY_PP_Asm:
+    CmdArgs.push_back("-S");
+    break;
+  case types::TY_Nothing:
+    CmdArgs.push_back("-fsyntax-only");
+    break;
+  default:
+    D.Diag(diag::err_drv_invalid_gcc_output_type) << getTypeName(JA.getType());
+  }
+}
+
+void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA,
+                                             ArgStringList &CmdArgs) const {
+  // The types are (hopefully) good enough.
+}
+
+/// Add OpenMP linker script arguments at the end of the argument list so that
+/// the fat binary is built by embedding each of the device images into the
+/// host. The linker script also defines a few symbols required by the code
+/// generation so that the images can be easily retrieved at runtime by the
+/// offloading library. This should be used only in tool chains that support
+/// linker scripts.
+static void AddOpenMPLinkerScript(const ToolChain &TC, Compilation &C,
+                                  const InputInfo &Output,
+                                  const InputInfoList &Inputs,
+                                  const ArgList &Args, ArgStringList &CmdArgs,
+                                  const JobAction &JA) {
+
+  // If this is not an OpenMP host toolchain, we don't need to do anything.
+  if (!JA.isHostOffloading(Action::OFK_OpenMP))
+    return;
+
+  // Create temporary linker script. Keep it if save-temps is enabled.
+  const char *LKS;
+  SmallString<256> Name = llvm::sys::path::filename(Output.getFilename());
+  if (C.getDriver().isSaveTempsEnabled()) {
+    llvm::sys::path::replace_extension(Name, "lk");
+    LKS = C.getArgs().MakeArgString(Name.c_str());
+  } else {
+    llvm::sys::path::replace_extension(Name, "");
+    Name = C.getDriver().GetTemporaryPath(Name, "lk");
+    LKS = C.addTempFile(C.getArgs().MakeArgString(Name.c_str()));
+  }
+
+  // Add linker script option to the command.
+  CmdArgs.push_back("-T");
+  CmdArgs.push_back(LKS);
+
+  // Create a buffer to write the contents of the linker script.
+  std::string LksBuffer;
+  llvm::raw_string_ostream LksStream(LksBuffer);
+
+  // Get the OpenMP offload tool chains so that we can extract the triple
+  // associated with each device input.
+  auto OpenMPToolChains = C.getOffloadToolChains<Action::OFK_OpenMP>();
+  assert(OpenMPToolChains.first != OpenMPToolChains.second &&
+         "No OpenMP toolchains??");
+
+  // Track the input file name and device triple in order to build the script,
+  // inserting binaries in the designated sections.
+  SmallVector<std::pair<std::string, const char *>, 8> InputBinaryInfo;
+
+  // Add commands to embed target binaries. We ensure that each section and
+  // image is 16-byte aligned. This is not mandatory, but increases the
+  // likelihood of data to be aligned with a cache block in several main host
+  // machines.
+  LksStream << "/*\n";
+  LksStream << "       OpenMP Offload Linker Script\n";
+  LksStream << " *** Automatically generated by Clang ***\n";
+  LksStream << "*/\n";
+  LksStream << "TARGET(binary)\n";
+  auto DTC = OpenMPToolChains.first;
+  for (auto &II : Inputs) {
+    const Action *A = II.getAction();
+    // Is this a device linking action?
+    if (A && isa<LinkJobAction>(A) &&
+        A->isDeviceOffloading(Action::OFK_OpenMP)) {
+      assert(DTC != OpenMPToolChains.second &&
+             "More device inputs than device toolchains??");
+      InputBinaryInfo.push_back(std::make_pair(
+          DTC->second->getTriple().normalize(), II.getFilename()));
+      ++DTC;
+      LksStream << "INPUT(" << II.getFilename() << ")\n";
+    }
+  }
+
+  assert(DTC == OpenMPToolChains.second &&
+         "Less device inputs than device toolchains??");
+
+  LksStream << "SECTIONS\n";
+  LksStream << "{\n";
+  LksStream << "  .omp_offloading :\n";
+  LksStream << "  ALIGN(0x10)\n";
+  LksStream << "  {\n";
+
+  for (auto &BI : InputBinaryInfo) {
+    LksStream << "    . = ALIGN(0x10);\n";
+    LksStream << "    PROVIDE_HIDDEN(.omp_offloading.img_start." << BI.first
+              << " = .);\n";
+    LksStream << "    " << BI.second << "\n";
+    LksStream << "    PROVIDE_HIDDEN(.omp_offloading.img_end." << BI.first
+              << " = .);\n";
+  }
+
+  LksStream << "  }\n";
+  // Add commands to define host entries begin and end. We use 1-byte subalign
+  // so that the linker does not add any padding and the elements in this
+  // section form an array.
+  LksStream << "  .omp_offloading.entries :\n";
+  LksStream << "  ALIGN(0x10)\n";
+  LksStream << "  SUBALIGN(0x01)\n";
+  LksStream << "  {\n";
+  LksStream << "    PROVIDE_HIDDEN(.omp_offloading.entries_begin = .);\n";
+  LksStream << "    *(.omp_offloading.entries)\n";
+  LksStream << "    PROVIDE_HIDDEN(.omp_offloading.entries_end = .);\n";
+  LksStream << "  }\n";
+  LksStream << "}\n";
+  LksStream << "INSERT BEFORE .data\n";
+  LksStream.flush();
+
+  // Dump the contents of the linker script if the user requested that. We
+  // support this option to enable testing of behavior with -###.
+  if (C.getArgs().hasArg(options::OPT_fopenmp_dump_offload_linker_script))
+    llvm::errs() << LksBuffer;
+
+  // If this is a dry run, do not create the linker script file.
+  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
+    return;
+
+  // Open script file and write the contents.
+  std::error_code EC;
+  llvm::raw_fd_ostream Lksf(LKS, EC, llvm::sys::fs::F_None);
+
+  if (EC) {
+    C.getDriver().Diag(clang::diag::err_unable_to_make_temp) << EC.message();
+    return;
+  }
+
+  Lksf << LksBuffer;
+}
+
+static bool addXRayRuntime(const ToolChain &TC, const ArgList &Args,
+                           ArgStringList &CmdArgs) {
+  if (Args.hasFlag(options::OPT_fxray_instrument,
+                   options::OPT_fnoxray_instrument, false)) {
+    CmdArgs.push_back("-whole-archive");
+    CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray", false));
+    CmdArgs.push_back("-no-whole-archive");
+    return true;
+  }
+  return false;
+}
+
+static void linkXRayRuntimeDeps(const ToolChain &TC, const ArgList &Args,
+                                ArgStringList &CmdArgs) {
+  CmdArgs.push_back("--no-as-needed");
+  CmdArgs.push_back("-lpthread");
+  CmdArgs.push_back("-lrt");
+  CmdArgs.push_back("-lm");
+  CmdArgs.push_back("-latomic");
+
+  TC.AddCXXStdlibLibArgs(Args, CmdArgs);
+
+  if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
+    CmdArgs.push_back("-ldl");
+}
+
+static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
+  switch (T.getArch()) {
+  case llvm::Triple::x86:
+    if (T.isOSIAMCU())
+      return "elf_iamcu";
+    return "elf_i386";
+  case llvm::Triple::aarch64:
+    return "aarch64linux";
+  case llvm::Triple::aarch64_be:
+    return "aarch64_be_linux";
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    return "armelf_linux_eabi";
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumbeb:
+    return "armelfb_linux_eabi";
+  case llvm::Triple::ppc:
+    return "elf32ppclinux";
+  case llvm::Triple::ppc64:
+    return "elf64ppc";
+  case llvm::Triple::ppc64le:
+    return "elf64lppc";
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+    return "elf32_sparc";
+  case llvm::Triple::sparcv9:
+    return "elf64_sparc";
+  case llvm::Triple::mips:
+    return "elf32btsmip";
+  case llvm::Triple::mipsel:
+    return "elf32ltsmip";
+  case llvm::Triple::mips64:
+    if (tools::mips::hasMipsAbiArg(Args, "n32"))
+      return "elf32btsmipn32";
+    return "elf64btsmip";
+  case llvm::Triple::mips64el:
+    if (tools::mips::hasMipsAbiArg(Args, "n32"))
+      return "elf32ltsmipn32";
+    return "elf64ltsmip";
+  case llvm::Triple::systemz:
+    return "elf64_s390";
+  case llvm::Triple::x86_64:
+    if (T.getEnvironment() == llvm::Triple::GNUX32)
+      return "elf32_x86_64";
+    return "elf_x86_64";
+  default:
+    return nullptr;
+  }
+}
+
+void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                           const InputInfo &Output,
+                                           const InputInfoList &Inputs,
+                                           const ArgList &Args,
+                                           const char *LinkingOutput) const {
+  const toolchains::Linux &ToolChain =
+      static_cast<const toolchains::Linux &>(getToolChain());
+  const Driver &D = ToolChain.getDriver();
+
+  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+
+  const llvm::Triple::ArchType Arch = ToolChain.getArch();
+  const bool isAndroid = ToolChain.getTriple().isAndroid();
+  const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
+  const bool IsPIE =
+      !Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_static) &&
+      (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault());
+  const bool HasCRTBeginEndFiles =
+      ToolChain.getTriple().hasEnvironment() ||
+      (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);
+
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
+  if (llvm::sys::path::stem(Exec) == "lld") {
+    CmdArgs.push_back("-flavor");
+    CmdArgs.push_back("old-gnu");
+    CmdArgs.push_back("-target");
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().getTripleString()));
+  }
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (IsPIE)
+    CmdArgs.push_back("-pie");
+
+  if (Args.hasArg(options::OPT_rdynamic))
+    CmdArgs.push_back("-export-dynamic");
+
+  if (Args.hasArg(options::OPT_s))
+    CmdArgs.push_back("-s");
+
+  if (Arch == llvm::Triple::armeb || Arch == llvm::Triple::thumbeb)
+    arm::appendEBLinkFlags(Args, CmdArgs, Triple);
+
+  // Most Android ARM64 targets should enable the linker fix for erratum
+  // 843419. Only non-Cortex-A53 devices are allowed to skip this flag.
+  if (Arch == llvm::Triple::aarch64 && isAndroid) {
+    std::string CPU = getCPUName(Args, Triple);
+    if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")
+      CmdArgs.push_back("--fix-cortex-a53-843419");
+  }
+
+  for (const auto &Opt : ToolChain.ExtraOpts)
+    CmdArgs.push_back(Opt.c_str());
+
+  if (!Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("--eh-frame-hdr");
+  }
+
+  if (const char *LDMOption = getLDMOption(ToolChain.getTriple(), Args)) {
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back(LDMOption);
+  } else {
+    D.Diag(diag::err_target_unknown_triple) << Triple.str();
+    return;
+  }
+
+  if (Args.hasArg(options::OPT_static)) {
+    if (Arch == llvm::Triple::arm || Arch == llvm::Triple::armeb ||
+        Arch == llvm::Triple::thumb || Arch == llvm::Triple::thumbeb)
+      CmdArgs.push_back("-Bstatic");
+    else
+      CmdArgs.push_back("-static");
+  } else if (Args.hasArg(options::OPT_shared)) {
+    CmdArgs.push_back("-shared");
+  }
+
+  if (!Args.hasArg(options::OPT_static)) {
+    if (Args.hasArg(options::OPT_rdynamic))
+      CmdArgs.push_back("-export-dynamic");
+
+    if (!Args.hasArg(options::OPT_shared)) {
+      const std::string Loader =
+          D.DyldPrefix + ToolChain.getDynamicLinker(Args);
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back(Args.MakeArgString(Loader));
+    }
+  }
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!isAndroid && !IsIAMCU) {
+      const char *crt1 = nullptr;
+      if (!Args.hasArg(options::OPT_shared)) {
+        if (Args.hasArg(options::OPT_pg))
+          crt1 = "gcrt1.o";
+        else if (IsPIE)
+          crt1 = "Scrt1.o";
+        else
+          crt1 = "crt1.o";
+      }
+      if (crt1)
+        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
+
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
+    }
+
+    if (IsIAMCU)
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
+    else {
+      const char *crtbegin;
+      if (Args.hasArg(options::OPT_static))
+        crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
+      else if (Args.hasArg(options::OPT_shared))
+        crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
+      else if (IsPIE)
+        crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
+      else
+        crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
+
+      if (HasCRTBeginEndFiles)
+        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
+    }
+
+    // Add crtfastmath.o if available and fast math is enabled.
+    ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_u);
+
+  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+
+  if (D.isUsingLTO())
+    AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin, D);
+
+  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+    CmdArgs.push_back("--no-demangle");
+
+  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
+  bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+  // The profile runtime also needs access to system libraries.
+  getToolChain().addProfileRTLibs(Args, CmdArgs);
+
+  if (D.CCCIsCXX() &&
+      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+                               !Args.hasArg(options::OPT_static);
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bstatic");
+    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bdynamic");
+    CmdArgs.push_back("-lm");
+  }
+  // Silence warnings when linking C code with a C++ '-stdlib' argument.
+  Args.ClaimAllArgs(options::OPT_stdlib_EQ);
+
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
+      if (Args.hasArg(options::OPT_static))
+        CmdArgs.push_back("--start-group");
+
+      if (NeedsSanitizerDeps)
+        linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
+
+      if (NeedsXRayDeps)
+        linkXRayRuntimeDeps(ToolChain, Args, CmdArgs);
+
+      bool WantPthread = Args.hasArg(options::OPT_pthread) ||
+                         Args.hasArg(options::OPT_pthreads);
+
+      if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
+                       options::OPT_fno_openmp, false)) {
+        // OpenMP runtimes implies pthreads when using the GNU toolchain.
+        // FIXME: Does this really make sense for all GNU toolchains?
+        WantPthread = true;
+
+        // Also link the particular OpenMP runtimes.
+        switch (ToolChain.getDriver().getOpenMPRuntime(Args)) {
+        case Driver::OMPRT_OMP:
+          CmdArgs.push_back("-lomp");
+          break;
+        case Driver::OMPRT_GOMP:
+          CmdArgs.push_back("-lgomp");
+
+          // FIXME: Exclude this for platforms with libgomp that don't require
+          // librt. Most modern Linux platforms require it, but some may not.
+          CmdArgs.push_back("-lrt");
+          break;
+        case Driver::OMPRT_IOMP5:
+          CmdArgs.push_back("-liomp5");
+          break;
+        case Driver::OMPRT_Unknown:
+          // Already diagnosed.
+          break;
+        }
+        if (JA.isHostOffloading(Action::OFK_OpenMP))
+          CmdArgs.push_back("-lomptarget");
+
+        addArchSpecificRPath(ToolChain, Args, CmdArgs);
+      }
+
+      AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
+
+      if (WantPthread && !isAndroid)
+        CmdArgs.push_back("-lpthread");
+
+      if (Args.hasArg(options::OPT_fsplit_stack))
+        CmdArgs.push_back("--wrap=pthread_create");
+
+      CmdArgs.push_back("-lc");
+
+      // Add IAMCU specific libs, if needed.
+      if (IsIAMCU)
+        CmdArgs.push_back("-lgloss");
+
+      if (Args.hasArg(options::OPT_static))
+        CmdArgs.push_back("--end-group");
+      else
+        AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
+
+      // Add IAMCU specific libs (outside the group), if needed.
+      if (IsIAMCU) {
+        CmdArgs.push_back("--as-needed");
+        CmdArgs.push_back("-lsoftfp");
+        CmdArgs.push_back("--no-as-needed");
+      }
+    }
+
+    if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) {
+      const char *crtend;
+      if (Args.hasArg(options::OPT_shared))
+        crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
+      else if (IsPIE)
+        crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
+      else
+        crtend = isAndroid ? "crtend_android.o" : "crtend.o";
+
+      if (HasCRTBeginEndFiles)
+        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
+      if (!isAndroid)
+        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+    }
+  }
+
+  // Add OpenMP offloading linker script args if required.
+  AddOpenMPLinkerScript(getToolChain(), C, Output, Inputs, Args, CmdArgs, JA);
+
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void tools::gnutools::Assembler::ConstructJob(Compilation &C,
+                                              const JobAction &JA,
+                                              const InputInfo &Output,
+                                              const InputInfoList &Inputs,
+                                              const ArgList &Args,
+                                              const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+
+  ArgStringList CmdArgs;
+
+  llvm::Reloc::Model RelocationModel;
+  unsigned PICLevel;
+  bool IsPIE;
+  std::tie(RelocationModel, PICLevel, IsPIE) =
+      ParsePICArgs(getToolChain(), Args);
+
+  switch (getToolChain().getArch()) {
+  default:
+    break;
+  // Add --32/--64 to make sure we get the format we want.
+  // This is incomplete
+  case llvm::Triple::x86:
+    CmdArgs.push_back("--32");
+    break;
+  case llvm::Triple::x86_64:
+    if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32)
+      CmdArgs.push_back("--x32");
+    else
+      CmdArgs.push_back("--64");
+    break;
+  case llvm::Triple::ppc:
+    CmdArgs.push_back("-a32");
+    CmdArgs.push_back("-mppc");
+    CmdArgs.push_back("-many");
+    break;
+  case llvm::Triple::ppc64:
+    CmdArgs.push_back("-a64");
+    CmdArgs.push_back("-mppc64");
+    CmdArgs.push_back("-many");
+    break;
+  case llvm::Triple::ppc64le:
+    CmdArgs.push_back("-a64");
+    CmdArgs.push_back("-mppc64");
+    CmdArgs.push_back("-many");
+    CmdArgs.push_back("-mlittle-endian");
+    break;
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel: {
+    CmdArgs.push_back("-32");
+    std::string CPU = getCPUName(Args, getToolChain().getTriple());
+    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+  case llvm::Triple::sparcv9: {
+    CmdArgs.push_back("-64");
+    std::string CPU = getCPUName(Args, getToolChain().getTriple());
+    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb: {
+    const llvm::Triple &Triple2 = getToolChain().getTriple();
+    switch (Triple2.getSubArch()) {
+    case llvm::Triple::ARMSubArch_v7:
+      CmdArgs.push_back("-mfpu=neon");
+      break;
+    case llvm::Triple::ARMSubArch_v8:
+      CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");
+      break;
+    default:
+      break;
+    }
+
+    switch (arm::getARMFloatABI(getToolChain(), Args)) {
+    case arm::FloatABI::Invalid: llvm_unreachable("must have an ABI!");
+    case arm::FloatABI::Soft:
+      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft"));
+      break;
+    case arm::FloatABI::SoftFP:
+      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp"));
+      break;
+    case arm::FloatABI::Hard:
+      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard"));
+      break;
+    }
+
+    Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
+
+    // FIXME: remove krait check when GNU tools support krait cpu
+    // for now replace it with -mcpu=cortex-a15 to avoid a lower
+    // march from being picked in the absence of a cpu flag.
+    Arg *A;
+    if ((A = Args.getLastArg(options::OPT_mcpu_EQ)) &&
+        StringRef(A->getValue()).equals_lower("krait"))
+      CmdArgs.push_back("-mcpu=cortex-a15");
+    else
+      Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
+    Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
+    break;
+  }
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el: {
+    StringRef CPUName;
+    StringRef ABIName;
+    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+    ABIName = mips::getGnuCompatibleMipsABIName(ABIName);
+
+    CmdArgs.push_back("-march");
+    CmdArgs.push_back(CPUName.data());
+
+    CmdArgs.push_back("-mabi");
+    CmdArgs.push_back(ABIName.data());
+
+    // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE,
+    // or -mshared (not implemented) is in effect.
+    if (RelocationModel == llvm::Reloc::Static)
+      CmdArgs.push_back("-mno-shared");
+
+    // LLVM doesn't support -mplt yet and acts as if it is always given.
+    // However, -mplt has no effect with the N64 ABI.
+    if (ABIName != "64" && !Args.hasArg(options::OPT_mno_abicalls))
+      CmdArgs.push_back("-call_nonpic");
+
+    if (getToolChain().getArch() == llvm::Triple::mips ||
+        getToolChain().getArch() == llvm::Triple::mips64)
+      CmdArgs.push_back("-EB");
+    else
+      CmdArgs.push_back("-EL");
+
+    if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
+      if (StringRef(A->getValue()) == "2008")
+        CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
+    }
+
+    // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default.
+    if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
+                                 options::OPT_mfp64)) {
+      A->claim();
+      A->render(Args, CmdArgs);
+    } else if (mips::shouldUseFPXX(
+                   Args, getToolChain().getTriple(), CPUName, ABIName,
+                   mips::getMipsFloatABI(getToolChain().getDriver(), Args)))
+      CmdArgs.push_back("-mfpxx");
+
+    // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of
+    // -mno-mips16 is actually -no-mips16.
+    if (Arg *A =
+            Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) {
+      if (A->getOption().matches(options::OPT_mips16)) {
+        A->claim();
+        A->render(Args, CmdArgs);
+      } else {
+        A->claim();
+        CmdArgs.push_back("-no-mips16");
+      }
+    }
+
+    Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
+                    options::OPT_mno_micromips);
+    Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
+    Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);
+
+    if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {
+      // Do not use AddLastArg because not all versions of MIPS assembler
+      // support -mmsa / -mno-msa options.
+      if (A->getOption().matches(options::OPT_mmsa))
+        CmdArgs.push_back(Args.MakeArgString("-mmsa"));
+    }
+
+    Args.AddLastArg(CmdArgs, options::OPT_mhard_float,
+                    options::OPT_msoft_float);
+
+    Args.AddLastArg(CmdArgs, options::OPT_mdouble_float,
+                    options::OPT_msingle_float);
+
+    Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,
+                    options::OPT_mno_odd_spreg);
+
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+  case llvm::Triple::systemz: {
+    // Always pass an -march option, since our default of z10 is later
+    // than the GNU assembler's default.
+    StringRef CPUName = systemz::getSystemZTargetCPU(Args);
+    CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
+    break;
+  }
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_I);
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+
+  // Handle the debug info splitting at object creation time if we're
+  // creating an object.
+  // TODO: Currently only works on linux with newer objcopy.
+  if (Args.hasArg(options::OPT_gsplit_dwarf) &&
+      getToolChain().getTriple().isOSLinux())
+    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
+                   SplitDebugName(Args, Inputs[0]));
+}
+
+namespace {
+// Filter to remove Multilibs that don't exist as a suffix to Path
+class FilterNonExistent {
+  StringRef Base, File;
+  vfs::FileSystem &VFS;
+
+public:
+  FilterNonExistent(StringRef Base, StringRef File, vfs::FileSystem &VFS)
+      : Base(Base), File(File), VFS(VFS) {}
+  bool operator()(const Multilib &M) {
+    return !VFS.exists(Base + M.gccSuffix() + File);
+  }
+};
+} // end anonymous namespace
+
+static bool isSoftFloatABI(const ArgList &Args) {
+  Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
+                           options::OPT_mfloat_abi_EQ);
+  if (!A)
+    return false;
+
+  return A->getOption().matches(options::OPT_msoft_float) ||
+         (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
+          A->getValue() == StringRef("soft"));
+}
+
+static void addMultilibFlag(bool Enabled, const char *const Flag,
+                            std::vector<std::string> &Flags) {
+  if (Enabled)
+    Flags.push_back(std::string("+") + Flag);
+  else
+    Flags.push_back(std::string("-") + Flag);
+}
+
+static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
+  return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
+}
+
+static bool isMips32(llvm::Triple::ArchType Arch) {
+  return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel;
+}
+
+static bool isMips64(llvm::Triple::ArchType Arch) {
+  return Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
+}
+
+static bool isMipsEL(llvm::Triple::ArchType Arch) {
+  return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;
+}
+
+static bool isMips16(const ArgList &Args) {
+  Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
+  return A && A->getOption().matches(options::OPT_mips16);
+}
+
+static bool isMicroMips(const ArgList &Args) {
+  Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
+  return A && A->getOption().matches(options::OPT_mmicromips);
+}
+
+static Multilib makeMultilib(StringRef commonSuffix) {
+  return Multilib(commonSuffix, commonSuffix, commonSuffix);
+}
+
+static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
+                                FilterNonExistent &NonExistent,
+                                DetectedMultilibs &Result) {
+  // Check for Code Sourcery toolchain multilibs
+  MultilibSet CSMipsMultilibs;
+  {
+    auto MArchMips16 = makeMultilib("/mips16").flag("+m32").flag("+mips16");
+
+    auto MArchMicroMips =
+        makeMultilib("/micromips").flag("+m32").flag("+mmicromips");
+
+    auto MArchDefault = makeMultilib("").flag("-mips16").flag("-mmicromips");
+
+    auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
+
+    auto SoftFloat = makeMultilib("/soft-float").flag("+msoft-float");
+
+    auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
+
+    auto DefaultFloat =
+        makeMultilib("").flag("-msoft-float").flag("-mnan=2008");
+
+    auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
+
+    auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
+
+    // Note that this one's osSuffix is ""
+    auto MAbi64 = makeMultilib("")
+                      .gccSuffix("/64")
+                      .includeSuffix("/64")
+                      .flag("+mabi=n64")
+                      .flag("-mabi=n32")
+                      .flag("-m32");
+
+    CSMipsMultilibs =
+        MultilibSet()
+            .Either(MArchMips16, MArchMicroMips, MArchDefault)
+            .Maybe(UCLibc)
+            .Either(SoftFloat, Nan2008, DefaultFloat)
+            .FilterOut("/micromips/nan2008")
+            .FilterOut("/mips16/nan2008")
+            .Either(BigEndian, LittleEndian)
+            .Maybe(MAbi64)
+            .FilterOut("/mips16.*/64")
+            .FilterOut("/micromips.*/64")
+            .FilterOut(NonExistent)
+            .setIncludeDirsCallback([](const Multilib &M) {
+              std::vector<std::string> Dirs({"/include"});
+              if (StringRef(M.includeSuffix()).startswith("/uclibc"))
+                Dirs.push_back(
+                    "/../../../../mips-linux-gnu/libc/uclibc/usr/include");
+              else
+                Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include");
+              return Dirs;
+            });
+  }
+
+  MultilibSet DebianMipsMultilibs;
+  {
+    Multilib MAbiN32 =
+        Multilib().gccSuffix("/n32").includeSuffix("/n32").flag("+mabi=n32");
+
+    Multilib M64 = Multilib()
+                       .gccSuffix("/64")
+                       .includeSuffix("/64")
+                       .flag("+m64")
+                       .flag("-m32")
+                       .flag("-mabi=n32");
+
+    Multilib M32 = Multilib().flag("-m64").flag("+m32").flag("-mabi=n32");
+
+    DebianMipsMultilibs =
+        MultilibSet().Either(M32, M64, MAbiN32).FilterOut(NonExistent);
+  }
+
+  // Sort candidates. Toolchain that best meets the directories tree goes first.
+  // Then select the first toolchains matches command line flags.
+  MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs};
+  if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())
+    std::iter_swap(Candidates, Candidates + 1);
+  for (const MultilibSet *Candidate : Candidates) {
+    if (Candidate->select(Flags, Result.SelectedMultilib)) {
+      if (Candidate == &DebianMipsMultilibs)
+        Result.BiarchSibling = Multilib();
+      Result.Multilibs = *Candidate;
+      return true;
+    }
+  }
+  return false;
+}
+
+static bool findMipsAndroidMultilibs(vfs::FileSystem &VFS, StringRef Path,
+                                     const Multilib::flags_list &Flags,
+                                     FilterNonExistent &NonExistent,
+                                     DetectedMultilibs &Result) {
+
+  MultilibSet AndroidMipsMultilibs =
+      MultilibSet()
+          .Maybe(Multilib("/mips-r2").flag("+march=mips32r2"))
+          .Maybe(Multilib("/mips-r6").flag("+march=mips32r6"))
+          .FilterOut(NonExistent);
+
+  MultilibSet AndroidMipselMultilibs =
+      MultilibSet()
+          .Either(Multilib().flag("+march=mips32"),
+                  Multilib("/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
+                  Multilib("/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
+          .FilterOut(NonExistent);
+
+  MultilibSet AndroidMips64elMultilibs =
+      MultilibSet()
+          .Either(
+              Multilib().flag("+march=mips64r6"),
+              Multilib("/32/mips-r1", "", "/mips-r1").flag("+march=mips32"),
+              Multilib("/32/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
+              Multilib("/32/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
+          .FilterOut(NonExistent);
+
+  MultilibSet *MS = &AndroidMipsMultilibs;
+  if (VFS.exists(Path + "/mips-r6"))
+    MS = &AndroidMipselMultilibs;
+  else if (VFS.exists(Path + "/32"))
+    MS = &AndroidMips64elMultilibs;
+  if (MS->select(Flags, Result.SelectedMultilib)) {
+    Result.Multilibs = *MS;
+    return true;
+  }
+  return false;
+}
+
+static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
+                                  FilterNonExistent &NonExistent,
+                                  DetectedMultilibs &Result) {
+  // Musl toolchain multilibs
+  MultilibSet MuslMipsMultilibs;
+  {
+    auto MArchMipsR2 = makeMultilib("")
+                           .osSuffix("/mips-r2-hard-musl")
+                           .flag("+EB")
+                           .flag("-EL")
+                           .flag("+march=mips32r2");
+
+    auto MArchMipselR2 = makeMultilib("/mipsel-r2-hard-musl")
+                             .flag("-EB")
+                             .flag("+EL")
+                             .flag("+march=mips32r2");
+
+    MuslMipsMultilibs = MultilibSet().Either(MArchMipsR2, MArchMipselR2);
+
+    // Specify the callback that computes the include directories.
+    MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) {
+      return std::vector<std::string>(
+          {"/../sysroot" + M.osSuffix() + "/usr/include"});
+    });
+  }
+  if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)) {
+    Result.Multilibs = MuslMipsMultilibs;
+    return true;
+  }
+  return false;
+}
+
+static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
+                                 FilterNonExistent &NonExistent,
+                                 DetectedMultilibs &Result) {
+  // CodeScape MTI toolchain v1.2 and early.
+  MultilibSet MtiMipsMultilibsV1;
+  {
+    auto MArchMips32 = makeMultilib("/mips32")
+                           .flag("+m32")
+                           .flag("-m64")
+                           .flag("-mmicromips")
+                           .flag("+march=mips32");
+
+    auto MArchMicroMips = makeMultilib("/micromips")
+                              .flag("+m32")
+                              .flag("-m64")
+                              .flag("+mmicromips");
+
+    auto MArchMips64r2 = makeMultilib("/mips64r2")
+                             .flag("-m32")
+                             .flag("+m64")
+                             .flag("+march=mips64r2");
+
+    auto MArchMips64 = makeMultilib("/mips64").flag("-m32").flag("+m64").flag(
+        "-march=mips64r2");
+
+    auto MArchDefault = makeMultilib("")
+                            .flag("+m32")
+                            .flag("-m64")
+                            .flag("-mmicromips")
+                            .flag("+march=mips32r2");
+
+    auto Mips16 = makeMultilib("/mips16").flag("+mips16");
+
+    auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
+
+    auto MAbi64 =
+        makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
+
+    auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
+
+    auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
+
+    auto SoftFloat = makeMultilib("/sof").flag("+msoft-float");
+
+    auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
+
+    MtiMipsMultilibsV1 =
+        MultilibSet()
+            .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64,
+                    MArchDefault)
+            .Maybe(UCLibc)
+            .Maybe(Mips16)
+            .FilterOut("/mips64/mips16")
+            .FilterOut("/mips64r2/mips16")
+            .FilterOut("/micromips/mips16")
+            .Maybe(MAbi64)
+            .FilterOut("/micromips/64")
+            .FilterOut("/mips32/64")
+            .FilterOut("^/64")
+            .FilterOut("/mips16/64")
+            .Either(BigEndian, LittleEndian)
+            .Maybe(SoftFloat)
+            .Maybe(Nan2008)
+            .FilterOut(".*sof/nan2008")
+            .FilterOut(NonExistent)
+            .setIncludeDirsCallback([](const Multilib &M) {
+              std::vector<std::string> Dirs({"/include"});
+              if (StringRef(M.includeSuffix()).startswith("/uclibc"))
+                Dirs.push_back("/../../../../sysroot/uclibc/usr/include");
+              else
+                Dirs.push_back("/../../../../sysroot/usr/include");
+              return Dirs;
+            });
+  }
+
+  // CodeScape IMG toolchain starting from v1.3.
+  MultilibSet MtiMipsMultilibsV2;
+  {
+    auto BeHard = makeMultilib("/mips-r2-hard")
+                      .flag("+EB")
+                      .flag("-msoft-float")
+                      .flag("-mnan=2008")
+                      .flag("-muclibc");
+    auto BeSoft = makeMultilib("/mips-r2-soft")
+                      .flag("+EB")
+                      .flag("+msoft-float")
+                      .flag("-mnan=2008");
+    auto ElHard = makeMultilib("/mipsel-r2-hard")
+                      .flag("+EL")
+                      .flag("-msoft-float")
+                      .flag("-mnan=2008")
+                      .flag("-muclibc");
+    auto ElSoft = makeMultilib("/mipsel-r2-soft")
+                      .flag("+EL")
+                      .flag("+msoft-float")
+                      .flag("-mnan=2008")
+                      .flag("-mmicromips");
+    auto BeHardNan = makeMultilib("/mips-r2-hard-nan2008")
+                         .flag("+EB")
+                         .flag("-msoft-float")
+                         .flag("+mnan=2008")
+                         .flag("-muclibc");
+    auto ElHardNan = makeMultilib("/mipsel-r2-hard-nan2008")
+                         .flag("+EL")
+                         .flag("-msoft-float")
+                         .flag("+mnan=2008")
+                         .flag("-muclibc")
+                         .flag("-mmicromips");
+    auto BeHardNanUclibc = makeMultilib("/mips-r2-hard-nan2008-uclibc")
+                               .flag("+EB")
+                               .flag("-msoft-float")
+                               .flag("+mnan=2008")
+                               .flag("+muclibc");
+    auto ElHardNanUclibc = makeMultilib("/mipsel-r2-hard-nan2008-uclibc")
+                               .flag("+EL")
+                               .flag("-msoft-float")
+                               .flag("+mnan=2008")
+                               .flag("+muclibc");
+    auto BeHardUclibc = makeMultilib("/mips-r2-hard-uclibc")
+                            .flag("+EB")
+                            .flag("-msoft-float")
+                            .flag("-mnan=2008")
+                            .flag("+muclibc");
+    auto ElHardUclibc = makeMultilib("/mipsel-r2-hard-uclibc")
+                            .flag("+EL")
+                            .flag("-msoft-float")
+                            .flag("-mnan=2008")
+                            .flag("+muclibc");
+    auto ElMicroHardNan = makeMultilib("/micromipsel-r2-hard-nan2008")
+                              .flag("+EL")
+                              .flag("-msoft-float")
+                              .flag("+mnan=2008")
+                              .flag("+mmicromips");
+    auto ElMicroSoft = makeMultilib("/micromipsel-r2-soft")
+                           .flag("+EL")
+                           .flag("+msoft-float")
+                           .flag("-mnan=2008")
+                           .flag("+mmicromips");
+
+    auto O32 =
+        makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
+    auto N32 =
+        makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
+    auto N64 =
+        makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
+
+    MtiMipsMultilibsV2 =
+        MultilibSet()
+            .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,
+                     BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,
+                     ElHardUclibc, ElMicroHardNan, ElMicroSoft})
+            .Either(O32, N32, N64)
+            .FilterOut(NonExistent)
+            .setIncludeDirsCallback([](const Multilib &M) {
+              return std::vector<std::string>({"/../../../../sysroot" +
+                                               M.includeSuffix() +
+                                               "/../usr/include"});
+            })
+            .setFilePathsCallback([](const Multilib &M) {
+              return std::vector<std::string>(
+                  {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});
+            });
+  }
+  for (auto Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {
+    if (Candidate->select(Flags, Result.SelectedMultilib)) {
+      Result.Multilibs = *Candidate;
+      return true;
+    }
+  }
+  return false;
+}
+
+static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
+                                 FilterNonExistent &NonExistent,
+                                 DetectedMultilibs &Result) {
+  // CodeScape IMG toolchain v1.2 and early.
+  MultilibSet ImgMultilibsV1;
+  {
+    auto Mips64r6 = makeMultilib("/mips64r6").flag("+m64").flag("-m32");
+
+    auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
+
+    auto MAbi64 =
+        makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
+
+    ImgMultilibsV1 =
+        MultilibSet()
+            .Maybe(Mips64r6)
+            .Maybe(MAbi64)
+            .Maybe(LittleEndian)
+            .FilterOut(NonExistent)
+            .setIncludeDirsCallback([](const Multilib &M) {
+              return std::vector<std::string>(
+                  {"/include", "/../../../../sysroot/usr/include"});
+            });
+  }
+
+  // CodeScape IMG toolchain starting from v1.3.
+  MultilibSet ImgMultilibsV2;
+  {
+    auto BeHard = makeMultilib("/mips-r6-hard")
+                      .flag("+EB")
+                      .flag("-msoft-float")
+                      .flag("-mmicromips");
+    auto BeSoft = makeMultilib("/mips-r6-soft")
+                      .flag("+EB")
+                      .flag("+msoft-float")
+                      .flag("-mmicromips");
+    auto ElHard = makeMultilib("/mipsel-r6-hard")
+                      .flag("+EL")
+                      .flag("-msoft-float")
+                      .flag("-mmicromips");
+    auto ElSoft = makeMultilib("/mipsel-r6-soft")
+                      .flag("+EL")
+                      .flag("+msoft-float")
+                      .flag("-mmicromips");
+    auto BeMicroHard = makeMultilib("/micromips-r6-hard")
+                           .flag("+EB")
+                           .flag("-msoft-float")
+                           .flag("+mmicromips");
+    auto BeMicroSoft = makeMultilib("/micromips-r6-soft")
+                           .flag("+EB")
+                           .flag("+msoft-float")
+                           .flag("+mmicromips");
+    auto ElMicroHard = makeMultilib("/micromipsel-r6-hard")
+                           .flag("+EL")
+                           .flag("-msoft-float")
+                           .flag("+mmicromips");
+    auto ElMicroSoft = makeMultilib("/micromipsel-r6-soft")
+                           .flag("+EL")
+                           .flag("+msoft-float")
+                           .flag("+mmicromips");
+
+    auto O32 =
+        makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
+    auto N32 =
+        makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
+    auto N64 =
+        makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
+
+    ImgMultilibsV2 =
+        MultilibSet()
+            .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,
+                     ElMicroHard, ElMicroSoft})
+            .Either(O32, N32, N64)
+            .FilterOut(NonExistent)
+            .setIncludeDirsCallback([](const Multilib &M) {
+              return std::vector<std::string>({"/../../../../sysroot" +
+                                               M.includeSuffix() +
+                                               "/../usr/include"});
+            })
+            .setFilePathsCallback([](const Multilib &M) {
+              return std::vector<std::string>(
+                  {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});
+            });
+  }
+  for (auto Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {
+    if (Candidate->select(Flags, Result.SelectedMultilib)) {
+      Result.Multilibs = *Candidate;
+      return true;
+    }
+  }
+  return false;
+}
+
+bool clang::driver::findMIPSMultilibs(const Driver &D,
+                                      const llvm::Triple &TargetTriple,
+                                      StringRef Path, const ArgList &Args,
+                                      DetectedMultilibs &Result) {
+  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
+
+  StringRef CPUName;
+  StringRef ABIName;
+  tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName);
+
+  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
+
+  Multilib::flags_list Flags;
+  addMultilibFlag(isMips32(TargetArch), "m32", Flags);
+  addMultilibFlag(isMips64(TargetArch), "m64", Flags);
+  addMultilibFlag(isMips16(Args), "mips16", Flags);
+  addMultilibFlag(CPUName == "mips32", "march=mips32", Flags);
+  addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||
+                      CPUName == "mips32r5" || CPUName == "p5600",
+                  "march=mips32r2", Flags);
+  addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags);
+  addMultilibFlag(CPUName == "mips64", "march=mips64", Flags);
+  addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||
+                      CPUName == "mips64r5" || CPUName == "octeon",
+                  "march=mips64r2", Flags);
+  addMultilibFlag(CPUName == "mips64r6", "march=mips64r6", Flags);
+  addMultilibFlag(isMicroMips(Args), "mmicromips", Flags);
+  addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags);
+  addMultilibFlag(tools::mips::isNaN2008(Args, TargetTriple), "mnan=2008",
+                  Flags);
+  addMultilibFlag(ABIName == "n32", "mabi=n32", Flags);
+  addMultilibFlag(ABIName == "n64", "mabi=n64", Flags);
+  addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags);
+  addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags);
+  addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
+  addMultilibFlag(!isMipsEL(TargetArch), "EB", Flags);
+
+  if (TargetTriple.isAndroid())
+    return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent,
+                                    Result);
+
+  if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
+      TargetTriple.getOS() == llvm::Triple::Linux &&
+      TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
+    return findMipsMuslMultilibs(Flags, NonExistent, Result);
+
+  if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
+      TargetTriple.getOS() == llvm::Triple::Linux &&
+      TargetTriple.getEnvironment() == llvm::Triple::GNU)
+    return findMipsMtiMultilibs(Flags, NonExistent, Result);
+
+  if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
+      TargetTriple.getOS() == llvm::Triple::Linux &&
+      TargetTriple.getEnvironment() == llvm::Triple::GNU)
+    return findMipsImgMultilibs(Flags, NonExistent, Result);
+
+  if (findMipsCsMultilibs(Flags, NonExistent, Result))
+    return true;
+
+  // 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;
+}
+
+static void findAndroidArmMultilibs(const Driver &D,
+                                    const llvm::Triple &TargetTriple,
+                                    StringRef Path, const ArgList &Args,
+                                    DetectedMultilibs &Result) {
+  // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.
+  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
+  Multilib ArmV7Multilib = makeMultilib("/armv7-a")
+                               .flag("+armv7")
+                               .flag("-thumb");
+  Multilib ThumbMultilib = makeMultilib("/thumb")
+                               .flag("-armv7")
+                               .flag("+thumb");
+  Multilib ArmV7ThumbMultilib = makeMultilib("/armv7-a/thumb")
+                               .flag("+armv7")
+                               .flag("+thumb");
+  Multilib DefaultMultilib = makeMultilib("")
+                               .flag("-armv7")
+                               .flag("-thumb");
+  MultilibSet AndroidArmMultilibs =
+      MultilibSet()
+          .Either(ThumbMultilib, ArmV7Multilib,
+                  ArmV7ThumbMultilib, DefaultMultilib)
+          .FilterOut(NonExistent);
+
+  Multilib::flags_list Flags;
+  llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);
+  bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;
+  bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;
+  bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;
+  bool IsThumbMode = IsThumbArch ||
+      Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||
+      (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::IK_THUMB);
+  bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&
+      (llvm::ARM::parseArchVersion(Arch) == 7 ||
+       (IsArmArch && Arch == "" && IsV7SubArch));
+  addMultilibFlag(IsArmV7Mode, "armv7", Flags);
+  addMultilibFlag(IsThumbMode, "thumb", Flags);
+
+  if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib))
+    Result.Multilibs = AndroidArmMultilibs;
+}
+
+static bool findBiarchMultilibs(const Driver &D,
+                                const llvm::Triple &TargetTriple,
+                                StringRef Path, const ArgList &Args,
+                                bool NeedsBiarchSuffix,
+                                DetectedMultilibs &Result) {
+  // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
+  // in what would normally be GCCInstallPath and put the 64-bit
+  // libs in a subdirectory named 64. The simple logic we follow is that
+  // *if* there is a subdirectory of the right name with crtbegin.o in it,
+  // we use that. If not, and if not a biarch triple alias, we look for
+  // crtbegin.o without the subdirectory.
+
+  Multilib Default;
+  Multilib Alt64 = Multilib()
+                       .gccSuffix("/64")
+                       .includeSuffix("/64")
+                       .flag("-m32")
+                       .flag("+m64")
+                       .flag("-mx32");
+  Multilib Alt32 = Multilib()
+                       .gccSuffix("/32")
+                       .includeSuffix("/32")
+                       .flag("+m32")
+                       .flag("-m64")
+                       .flag("-mx32");
+  Multilib Altx32 = Multilib()
+                        .gccSuffix("/x32")
+                        .includeSuffix("/x32")
+                        .flag("-m32")
+                        .flag("-m64")
+                        .flag("+mx32");
+
+  // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.
+  FilterNonExistent NonExistent(
+      Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());
+
+  // 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))
+    Want = WANT64;
+  else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
+    Want = WANT64;
+  else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
+    Want = WANT32;
+  else {
+    if (TargetTriple.isArch32Bit())
+      Want = NeedsBiarchSuffix ? WANT64 : WANT32;
+    else if (IsX32)
+      Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
+    else
+      Want = NeedsBiarchSuffix ? WANT32 : WANT64;
+  }
+
+  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
+    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() && !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 ||
+      Result.SelectedMultilib == Altx32)
+    Result.BiarchSibling = Default;
+
+  return true;
+}
+
+/// Generic_GCC - A tool chain using the 'gcc' command to perform
+/// all subcommands; this relies on gcc translating the majority of
+/// command line options.
+
+/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
+bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
+                                          int RHSPatch,
+                                          StringRef RHSPatchSuffix) const {
+  if (Major != RHSMajor)
+    return Major < RHSMajor;
+  if (Minor != RHSMinor)
+    return Minor < RHSMinor;
+  if (Patch != RHSPatch) {
+    // Note that versions without a specified patch sort higher than those with
+    // a patch.
+    if (RHSPatch == -1)
+      return true;
+    if (Patch == -1)
+      return false;
+
+    // Otherwise just sort on the patch itself.
+    return Patch < RHSPatch;
+  }
+  if (PatchSuffix != RHSPatchSuffix) {
+    // Sort empty suffixes higher.
+    if (RHSPatchSuffix.empty())
+      return true;
+    if (PatchSuffix.empty())
+      return false;
+
+    // Provide a lexicographic sort to make this a total ordering.
+    return PatchSuffix < RHSPatchSuffix;
+  }
+
+  // The versions are equal.
+  return false;
+}
+
+static llvm::StringRef getGCCToolchainDir(const ArgList &Args) {
+  const Arg *A = Args.getLastArg(clang::driver::options::OPT_gcc_toolchain);
+  if (A)
+    return A->getValue();
+  return GCC_INSTALL_PREFIX;
+}
+
+/// \brief Initialize a GCCInstallationDetector from the driver.
+///
+/// This performs all of the autodetection and sets up the various paths.
+/// Once constructed, a GCCInstallationDetector is essentially immutable.
+///
+/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
+/// should instead pull the target out of the driver. This is currently
+/// necessary because the driver doesn't store the final version of the target
+/// triple.
+void Generic_GCC::GCCInstallationDetector::init(
+    const llvm::Triple &TargetTriple, const ArgList &Args,
+    ArrayRef<std::string> ExtraTripleAliases) {
+  llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()
+                                         ? TargetTriple.get64BitArchVariant()
+                                         : TargetTriple.get32BitArchVariant();
+  // The library directories which may contain GCC installations.
+  SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
+  // The compatible GCC triples for this particular architecture.
+  SmallVector<StringRef, 16> CandidateTripleAliases;
+  SmallVector<StringRef, 16> CandidateBiarchTripleAliases;
+  CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
+                           CandidateTripleAliases, CandidateBiarchLibDirs,
+                           CandidateBiarchTripleAliases);
+
+  // Compute the set of prefixes for our search.
+  SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
+                                       D.PrefixDirs.end());
+
+  StringRef GCCToolchainDir = getGCCToolchainDir(Args);
+  if (GCCToolchainDir != "") {
+    if (GCCToolchainDir.back() == '/')
+      GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
+
+    Prefixes.push_back(GCCToolchainDir);
+  } else {
+    // If we have a SysRoot, try that first.
+    if (!D.SysRoot.empty()) {
+      Prefixes.push_back(D.SysRoot);
+      Prefixes.push_back(D.SysRoot + "/usr");
+    }
+
+    // Then look for gcc installed alongside clang.
+    Prefixes.push_back(D.InstalledDir + "/..");
+
+    // Then look for distribution supplied gcc installations.
+    if (D.SysRoot.empty()) {
+      // Look for RHEL devtoolsets.
+      Prefixes.push_back("/opt/rh/devtoolset-6/root/usr");
+      Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
+      Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");
+      Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
+      // And finally in /usr.
+      Prefixes.push_back("/usr");
+    }
+  }
+
+  // Try to respect gcc-config on Gentoo. However, do that only
+  // if --gcc-toolchain is not provided or equal to the Gentoo install
+  // in /usr. This avoids accidentally enforcing the system GCC version
+  // when using a custom toolchain.
+  if (GCCToolchainDir == "" || GCCToolchainDir == D.SysRoot + "/usr") {
+    for (StringRef CandidateTriple : ExtraTripleAliases) {
+      if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple))
+        return;
+    }
+    for (StringRef CandidateTriple : CandidateTripleAliases) {
+      if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple))
+        return;
+    }
+    for (StringRef CandidateTriple : CandidateBiarchTripleAliases) {
+      if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true))
+        return;
+    }
+  }
+
+  // Loop over the various components which exist and select the best GCC
+  // installation available. GCC installs are ranked by version number.
+  Version = GCCVersion::Parse("0.0.0");
+  for (const std::string &Prefix : Prefixes) {
+    if (!D.getVFS().exists(Prefix))
+      continue;
+    for (StringRef Suffix : CandidateLibDirs) {
+      const std::string LibDir = Prefix + Suffix.str();
+      if (!D.getVFS().exists(LibDir))
+        continue;
+      for (StringRef Candidate : ExtraTripleAliases) // Try these first.
+        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
+      for (StringRef Candidate : CandidateTripleAliases)
+        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
+    }
+    for (StringRef Suffix : CandidateBiarchLibDirs) {
+      const std::string LibDir = Prefix + Suffix.str();
+      if (!D.getVFS().exists(LibDir))
+        continue;
+      for (StringRef Candidate : CandidateBiarchTripleAliases)
+        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate,
+                               /*NeedsBiarchSuffix=*/ true);
+    }
+  }
+}
+
+void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
+  for (const auto &InstallPath : CandidateGCCInstallPaths)
+    OS << "Found candidate GCC installation: " << InstallPath << "\n";
+
+  if (!GCCInstallPath.empty())
+    OS << "Selected GCC installation: " << GCCInstallPath << "\n";
+
+  for (const auto &Multilib : Multilibs)
+    OS << "Candidate multilib: " << Multilib << "\n";
+
+  if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())
+    OS << "Selected multilib: " << SelectedMultilib << "\n";
+}
+
+bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
+  if (BiarchSibling.hasValue()) {
+    M = BiarchSibling.getValue();
+    return true;
+  }
+  return false;
+}
+
+/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
+    const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
+    SmallVectorImpl<StringRef> &LibDirs,
+    SmallVectorImpl<StringRef> &TripleAliases,
+    SmallVectorImpl<StringRef> &BiarchLibDirs,
+    SmallVectorImpl<StringRef> &BiarchTripleAliases) {
+  // Declare a bunch of static data sets that we'll select between below. These
+  // are specifically designed to always refer to string literals to avoid any
+  // lifetime or initialization issues.
+  static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};
+  static const char *const AArch64Triples[] = {
+      "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-linux-android",
+      "aarch64-redhat-linux", "aarch64-suse-linux"};
+  static const char *const AArch64beLibDirs[] = {"/lib"};
+  static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu",
+                                                 "aarch64_be-linux-gnu"};
+
+  static const char *const ARMLibDirs[] = {"/lib"};
+  static const char *const ARMTriples[] = {"arm-linux-gnueabi",
+                                           "arm-linux-androideabi"};
+  static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",
+                                             "armv7hl-redhat-linux-gnueabi"};
+  static const char *const ARMebLibDirs[] = {"/lib"};
+  static const char *const ARMebTriples[] = {"armeb-linux-gnueabi",
+                                             "armeb-linux-androideabi"};
+  static const char *const ARMebHFTriples[] = {
+      "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};
+
+  static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};
+  static const char *const X86_64Triples[] = {
+      "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-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",       "i386-redhat-linux6E",   "i686-redhat-linux",
+      "i586-redhat-linux",    "i386-redhat-linux",     "i586-suse-linux",
+      "i486-slackware-linux", "i686-montavista-linux", "i686-linux-android",
+      "i586-linux-gnu"};
+
+  static const char *const MIPSLibDirs[] = {"/lib"};
+  static const char *const MIPSTriples[] = {"mips-linux-gnu", "mips-mti-linux",
+                                            "mips-mti-linux-gnu",
+                                            "mips-img-linux-gnu"};
+  static const char *const MIPSELLibDirs[] = {"/lib"};
+  static const char *const MIPSELTriples[] = {"mipsel-linux-gnu",
+                                              "mips-img-linux-gnu"};
+
+  static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};
+  static const char *const MIPS64Triples[] = {
+      "mips64-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", "mips-img-linux-gnu",
+      "mips64el-linux-gnuabi64"};
+
+  static const char *const MIPSELAndroidLibDirs[] = {"/lib", "/libr2",
+                                                     "/libr6"};
+  static const char *const MIPSELAndroidTriples[] = {"mipsel-linux-android"};
+  static const char *const MIPS64ELAndroidLibDirs[] = {"/lib64", "/lib",
+                                                       "/libr2", "/libr6"};
+  static const char *const MIPS64ELAndroidTriples[] = {
+      "mips64el-linux-android"};
+
+  static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
+  static const char *const PPCTriples[] = {
+      "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
+      "powerpc-suse-linux", "powerpc-montavista-linuxspe"};
+  static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
+  static const char *const PPC64Triples[] = {
+      "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
+      "powerpc64-suse-linux", "ppc64-redhat-linux"};
+  static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};
+  static const char *const PPC64LETriples[] = {
+      "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
+      "powerpc64le-suse-linux", "ppc64le-redhat-linux"};
+
+  static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
+  static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
+                                               "sparcv8-linux-gnu"};
+  static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};
+  static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",
+                                               "sparcv9-linux-gnu"};
+
+  static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};
+  static const char *const SystemZTriples[] = {
+      "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
+      "s390x-suse-linux", "s390x-redhat-linux"};
+
+  // Solaris.
+  static const char *const SolarisSPARCLibDirs[] = {"/gcc"};
+  static const char *const SolarisSPARCTriples[] = {"sparc-sun-solaris2.11",
+                                                    "i386-pc-solaris2.11"};
+
+  using std::begin;
+  using std::end;
+
+  if (TargetTriple.getOS() == llvm::Triple::Solaris) {
+    LibDirs.append(begin(SolarisSPARCLibDirs), end(SolarisSPARCLibDirs));
+    TripleAliases.append(begin(SolarisSPARCTriples), end(SolarisSPARCTriples));
+    return;
+  }
+
+  switch (TargetTriple.getArch()) {
+  case llvm::Triple::aarch64:
+    LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
+    TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
+    BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
+    BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
+    break;
+  case llvm::Triple::aarch64_be:
+    LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
+    TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
+    BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
+    BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
+    break;
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));
+    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+      TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));
+    } else {
+      TripleAliases.append(begin(ARMTriples), end(ARMTriples));
+    }
+    break;
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumbeb:
+    LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));
+    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+      TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));
+    } else {
+      TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));
+    }
+    break;
+  case llvm::Triple::x86_64:
+    LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
+    TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
+    // 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(begin(X32LibDirs), end(X32LibDirs));
+      BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
+    } else {
+      BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));
+      BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));
+    }
+    break;
+  case llvm::Triple::x86:
+    LibDirs.append(begin(X86LibDirs), end(X86LibDirs));
+    // MCU toolchain is 32 bit only and its triple alias is TargetTriple
+    // itself, which will be appended below.
+    if (!TargetTriple.isOSIAMCU()) {
+      TripleAliases.append(begin(X86Triples), end(X86Triples));
+      BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
+      BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
+    }
+    break;
+  case llvm::Triple::mips:
+    LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
+    TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
+    BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
+    BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
+    break;
+  case llvm::Triple::mipsel:
+    if (TargetTriple.isAndroid()) {
+      LibDirs.append(begin(MIPSELAndroidLibDirs), end(MIPSELAndroidLibDirs));
+      TripleAliases.append(begin(MIPSELAndroidTriples),
+                           end(MIPSELAndroidTriples));
+      BiarchLibDirs.append(begin(MIPS64ELAndroidLibDirs),
+                           end(MIPS64ELAndroidLibDirs));
+      BiarchTripleAliases.append(begin(MIPS64ELAndroidTriples),
+                                 end(MIPS64ELAndroidTriples));
+
+    } else {
+      LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
+      TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
+      TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
+      BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
+      BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
+    }
+    break;
+  case llvm::Triple::mips64:
+    LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
+    TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
+    BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
+    BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
+    break;
+  case llvm::Triple::mips64el:
+    if (TargetTriple.isAndroid()) {
+      LibDirs.append(begin(MIPS64ELAndroidLibDirs),
+                     end(MIPS64ELAndroidLibDirs));
+      TripleAliases.append(begin(MIPS64ELAndroidTriples),
+                           end(MIPS64ELAndroidTriples));
+      BiarchLibDirs.append(begin(MIPSELAndroidLibDirs),
+                           end(MIPSELAndroidLibDirs));
+      BiarchTripleAliases.append(begin(MIPSELAndroidTriples),
+                                 end(MIPSELAndroidTriples));
+
+    } else {
+      LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
+      TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
+      BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
+      BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
+      BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
+    }
+    break;
+  case llvm::Triple::ppc:
+    LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
+    TripleAliases.append(begin(PPCTriples), end(PPCTriples));
+    BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
+    BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
+    break;
+  case llvm::Triple::ppc64:
+    LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
+    TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
+    BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
+    BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));
+    break;
+  case llvm::Triple::ppc64le:
+    LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
+    TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
+    break;
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+    LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
+    TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
+    BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
+    BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
+    break;
+  case llvm::Triple::sparcv9:
+    LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
+    TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
+    BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
+    BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
+    break;
+  case llvm::Triple::systemz:
+    LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));
+    TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));
+    break;
+  default:
+    // By default, just rely on the standard lib directories and the original
+    // triple.
+    break;
+  }
+
+  // Always append the drivers target triple to the end, in case it doesn't
+  // match any of our aliases.
+  TripleAliases.push_back(TargetTriple.str());
+
+  // Also include the multiarch variant if it's different.
+  if (TargetTriple.str() != BiarchTriple.str())
+    BiarchTripleAliases.push_back(BiarchTriple.str());
+}
+
+void Generic_GCC::GCCInstallationDetector::scanLibDirForGCCTripleSolaris(
+    const llvm::Triple &TargetArch, const llvm::opt::ArgList &Args,
+    const std::string &LibDir, StringRef CandidateTriple,
+    bool NeedsBiarchSuffix) {
+  // Solaris is a special case. The GCC installation is under
+  // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/, so we
+  // need to iterate twice.
+  std::error_code EC;
+  for (vfs::directory_iterator LI = D.getVFS().dir_begin(LibDir, EC), LE;
+       !EC && LI != LE; LI = LI.increment(EC)) {
+    StringRef VersionText = llvm::sys::path::filename(LI->getName());
+    GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
+
+    if (CandidateVersion.Major != -1) // Filter obviously bad entries.
+      if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
+        continue; // Saw this path before; no need to look at it again.
+    if (CandidateVersion.isOlderThan(4, 1, 1))
+      continue;
+    if (CandidateVersion <= Version)
+      continue;
+
+    GCCInstallPath =
+        LibDir + "/" + VersionText.str() + "/lib/gcc/" + CandidateTriple.str();
+    if (!D.getVFS().exists(GCCInstallPath))
+      continue;
+
+    // If we make it here there has to be at least one GCC version, let's just
+    // use the latest one.
+    std::error_code EEC;
+    for (vfs::directory_iterator
+             LLI = D.getVFS().dir_begin(GCCInstallPath, EEC),
+             LLE;
+         !EEC && LLI != LLE; LLI = LLI.increment(EEC)) {
+
+      StringRef SubVersionText = llvm::sys::path::filename(LLI->getName());
+      GCCVersion CandidateSubVersion = GCCVersion::Parse(SubVersionText);
+
+      if (CandidateSubVersion > Version)
+        Version = CandidateSubVersion;
+    }
+
+    GCCTriple.setTriple(CandidateTriple);
+
+    GCCInstallPath += "/" + Version.Text;
+    GCCParentLibPath = GCCInstallPath + "/../../../../";
+
+    IsValid = true;
+  }
+}
+
+bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(
+    const llvm::Triple &TargetTriple, const ArgList &Args,
+    StringRef Path, bool NeedsBiarchSuffix) {
+  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
+  DetectedMultilibs Detected;
+
+  // Android standalone toolchain could have multilibs for ARM and Thumb.
+  // Debian mips multilibs behave more like the rest of the biarch ones,
+  // so handle them there
+  if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {
+    // It should also work without multilibs in a simplified toolchain.
+    findAndroidArmMultilibs(D, TargetTriple, Path, Args, Detected);
+  } else if (tools::isMipsArch(TargetArch)) {
+    if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected))
+      return false;
+  } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args,
+                                  NeedsBiarchSuffix, Detected)) {
+    return false;
+  }
+
+  Multilibs = Detected.Multilibs;
+  SelectedMultilib = Detected.SelectedMultilib;
+  BiarchSibling = Detected.BiarchSibling;
+
+  return true;
+}
+
+void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
+    const llvm::Triple &TargetTriple, const ArgList &Args,
+    const std::string &LibDir, StringRef CandidateTriple,
+    bool NeedsBiarchSuffix) {
+  if (TargetTriple.getOS() == llvm::Triple::Solaris) {
+    scanLibDirForGCCTripleSolaris(TargetTriple, Args, LibDir, CandidateTriple,
+                                  NeedsBiarchSuffix);
+    return;
+  }
+
+  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
+  // Locations relative to the system lib directory where GCC's triple-specific
+  // directories might reside.
+  struct GCCLibSuffix {
+    // Path from system lib directory to GCC triple-specific directory.
+    std::string LibSuffix;
+    // Path from GCC triple-specific directory back to system lib directory.
+    // This is one '..' component per component in LibSuffix.
+    StringRef ReversePath;
+    // Whether this library suffix is relevant for the triple.
+    bool Active;
+  } Suffixes[] = {
+    // This is the normal place.
+    {"gcc/" + CandidateTriple.str(), "../..", true},
+
+    // Debian puts cross-compilers in gcc-cross.
+    {"gcc-cross/" + CandidateTriple.str(), "../..", true},
+
+    // The Freescale PPC SDK has the gcc libraries in
+    // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. Only do
+    // this on Freescale triples, though, since some systems put a *lot* of
+    // files in that location, not just GCC installation data.
+    {CandidateTriple.str(), "..",
+      TargetTriple.getVendor() == llvm::Triple::Freescale},
+
+    // Natively multiarch systems sometimes put the GCC triple-specific
+    // directory within their multiarch lib directory, resulting in the
+    // triple appearing twice.
+    {CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), "../../..", true},
+
+    // Deal with cases (on Ubuntu) where the system architecture could be i386
+    // but the GCC target architecture could be (say) i686.
+    // FIXME: It may be worthwhile to generalize this and look for a second
+    // triple.
+    {"i386-linux-gnu/gcc/" + CandidateTriple.str(), "../../..",
+      TargetArch == llvm::Triple::x86}
+  };
+
+  for (auto &Suffix : Suffixes) {
+    if (!Suffix.Active)
+      continue;
+
+    StringRef LibSuffix = Suffix.LibSuffix;
+    std::error_code EC;
+    for (vfs::directory_iterator
+             LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC),
+             LE;
+         !EC && LI != LE; LI = LI.increment(EC)) {
+      StringRef VersionText = llvm::sys::path::filename(LI->getName());
+      GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
+      if (CandidateVersion.Major != -1) // Filter obviously bad entries.
+        if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
+          continue; // Saw this path before; no need to look at it again.
+      if (CandidateVersion.isOlderThan(4, 1, 1))
+        continue;
+      if (CandidateVersion <= Version)
+        continue;
+
+      if (!ScanGCCForMultilibs(TargetTriple, Args, LI->getName(),
+                               NeedsBiarchSuffix))
+        continue;
+
+      Version = CandidateVersion;
+      GCCTriple.setTriple(CandidateTriple);
+      // FIXME: We hack together the directory name here instead of
+      // using LI to ensure stable path separators across Windows and
+      // Linux.
+      GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str();
+      GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str();
+      IsValid = true;
+    }
+  }
+}
+
+bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig(
+    const llvm::Triple &TargetTriple, const ArgList &Args,
+    StringRef CandidateTriple, bool NeedsBiarchSuffix) {
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
+      D.getVFS().getBufferForFile(D.SysRoot + "/etc/env.d/gcc/config-" +
+                                  CandidateTriple.str());
+  if (File) {
+    SmallVector<StringRef, 2> Lines;
+    File.get()->getBuffer().split(Lines, "\n");
+    for (StringRef Line : Lines) {
+      // CURRENT=triple-version
+      if (Line.consume_front("CURRENT=")) {
+        const std::pair<StringRef, StringRef> ActiveVersion =
+          Line.rsplit('-');
+        // Note: Strictly speaking, we should be reading
+        // /etc/env.d/gcc/${CURRENT} now. However, the file doesn't
+        // contain anything new or especially useful to us.
+        const std::string GentooPath = D.SysRoot + "/usr/lib/gcc/" +
+                                       ActiveVersion.first.str() + "/" +
+                                       ActiveVersion.second.str();
+        if (D.getVFS().exists(GentooPath + "/crtbegin.o")) {
+          if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath,
+                                   NeedsBiarchSuffix))
+            return false;
+
+          Version = GCCVersion::Parse(ActiveVersion.second);
+          GCCInstallPath = GentooPath;
+          GCCParentLibPath = GentooPath + "/../../..";
+          GCCTriple.setTriple(ActiveVersion.first);
+          IsValid = true;
+          return true;
+        }
+      }
+    }
+  }
+
+  return false;
+}
+
+Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,
+                         const ArgList &Args)
+    : ToolChain(D, Triple, Args), GCCInstallation(D),
+      CudaInstallation(D, Triple, Args) {
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
+}
+
+Generic_GCC::~Generic_GCC() {}
+
+Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
+  switch (AC) {
+  case Action::PreprocessJobClass:
+    if (!Preprocess)
+      Preprocess.reset(new clang::driver::tools::gcc::Preprocessor(*this));
+    return Preprocess.get();
+  case Action::CompileJobClass:
+    if (!Compile)
+      Compile.reset(new tools::gcc::Compiler(*this));
+    return Compile.get();
+  default:
+    return ToolChain::getTool(AC);
+  }
+}
+
+Tool *Generic_GCC::buildAssembler() const {
+  return new tools::gnutools::Assembler(*this);
+}
+
+Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); }
+
+void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
+  // Print the information about how we detected the GCC installation.
+  GCCInstallation.print(OS);
+  CudaInstallation.print(OS);
+}
+
+bool Generic_GCC::IsUnwindTablesDefault() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool Generic_GCC::isPICDefault() const {
+  switch (getArch()) {
+  case llvm::Triple::x86_64:
+    return getTriple().isOSWindows();
+  case llvm::Triple::ppc64:
+  case llvm::Triple::ppc64le:
+    return !getTriple().isOSBinFormatMachO() && !getTriple().isMacOSX();
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el:
+    return true;
+  default:
+    return false;
+  }
+}
+
+bool Generic_GCC::isPIEDefault() const { return false; }
+
+bool Generic_GCC::isPICDefaultForced() const {
+  return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
+}
+
+bool Generic_GCC::IsIntegratedAssemblerDefault() const {
+  switch (getTriple().getArch()) {
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::avr:
+  case llvm::Triple::bpfel:
+  case llvm::Triple::bpfeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
+  case llvm::Triple::ppc:
+  case llvm::Triple::ppc64:
+  case llvm::Triple::ppc64le:
+  case llvm::Triple::systemz:
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+    return true;
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el:
+    // Enabled for Debian mips64/mips64el only. Other targets are unable to
+    // distinguish N32 from N64.
+    if (getTriple().getEnvironment() == llvm::Triple::GNUABI64)
+      return true;
+    return false;
+  default:
+    return false;
+  }
+}
+
+void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+                                               ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+      DriverArgs.hasArg(options::OPT_nostdincxx))
+    return;
+
+  switch (GetCXXStdlibType(DriverArgs)) {
+  case ToolChain::CST_Libcxx: {
+    std::string Path = findLibCxxIncludePath();
+    if (!Path.empty())
+      addSystemInclude(DriverArgs, CC1Args, Path);
+    break;
+  }
+
+  case ToolChain::CST_Libstdcxx:
+    addLibStdCxxIncludePaths(DriverArgs, CC1Args);
+    break;
+  }
+}
+
+std::string Generic_GCC::findLibCxxIncludePath() const {
+  // FIXME: The Linux behavior would probaby be a better approach here.
+  return getDriver().SysRoot + "/usr/include/c++/v1";
+}
+
+void
+Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+                                      llvm::opt::ArgStringList &CC1Args) const {
+  // By default, we don't assume we know where libstdc++ might be installed.
+  // FIXME: If we have a valid GCCInstallation, use it.
+}
+
+/// \brief Helper to add the variant paths of a libstdc++ installation.
+bool Generic_GCC::addLibStdCXXIncludePaths(
+    Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple,
+    StringRef TargetMultiarchTriple, Twine IncludeSuffix,
+    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
+  if (!getVFS().exists(Base + Suffix))
+    return false;
+
+  addSystemInclude(DriverArgs, CC1Args, Base + Suffix);
+
+  // The vanilla GCC layout of libstdc++ headers uses a triple subdirectory. If
+  // that path exists or we have neither a GCC nor target multiarch triple, use
+  // this vanilla search path.
+  if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) ||
+      getVFS().exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) {
+    addSystemInclude(DriverArgs, CC1Args,
+                     Base + Suffix + "/" + GCCTriple + IncludeSuffix);
+  } else {
+    // Otherwise try to use multiarch naming schemes which have normalized the
+    // triples and put the triple before the suffix.
+    //
+    // GCC surprisingly uses *both* the GCC triple with a multilib suffix and
+    // the target triple, so we support that here.
+    addSystemInclude(DriverArgs, CC1Args,
+                     Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix);
+    addSystemInclude(DriverArgs, CC1Args,
+                     Base + "/" + TargetMultiarchTriple + Suffix);
+  }
+
+  addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward");
+  return true;
+}
+
+llvm::opt::DerivedArgList *
+Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef,
+                           Action::OffloadKind DeviceOffloadKind) const {
+
+  // If this tool chain is used for an OpenMP offloading device we have to make
+  // sure we always generate a shared library regardless of the commands the
+  // user passed to the host. This is required because the runtime library
+  // is required to load the device image dynamically at run time.
+  if (DeviceOffloadKind == Action::OFK_OpenMP) {
+    DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
+    const OptTable &Opts = getDriver().getOpts();
+
+    // Request the shared library. Given that these options are decided
+    // implicitly, they do not refer to any base argument.
+    DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_shared));
+    DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_fPIC));
+
+    // Filter all the arguments we don't care passing to the offloading
+    // toolchain as they can mess up with the creation of a shared library.
+    for (auto *A : Args) {
+      switch ((options::ID)A->getOption().getID()) {
+      default:
+        DAL->append(A);
+        break;
+      case options::OPT_shared:
+      case options::OPT_dynamic:
+      case options::OPT_static:
+      case options::OPT_fPIC:
+      case options::OPT_fno_PIC:
+      case options::OPT_fpic:
+      case options::OPT_fno_pic:
+      case options::OPT_fPIE:
+      case options::OPT_fno_PIE:
+      case options::OPT_fpie:
+      case options::OPT_fno_pie:
+        break;
+      }
+    }
+    return DAL;
+  }
+  return nullptr;
+}
+
+void Generic_ELF::anchor() {}
+
+void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
+                                        ArgStringList &CC1Args) const {
+  const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
+  bool UseInitArrayDefault =
+      getTriple().getArch() == llvm::Triple::aarch64 ||
+      getTriple().getArch() == llvm::Triple::aarch64_be ||
+      (getTriple().getOS() == llvm::Triple::Linux &&
+       (!V.isOlderThan(4, 7, 0) || getTriple().isAndroid())) ||
+      getTriple().getOS() == llvm::Triple::NaCl ||
+      (getTriple().getVendor() == llvm::Triple::MipsTechnologies &&
+       !getTriple().hasEnvironment());
+
+  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
+                         options::OPT_fno_use_init_array, UseInitArrayDefault))
+    CC1Args.push_back("-fuse-init-array");
+}
diff --git a/lib/Driver/ToolChains/Gnu.h b/lib/Driver/ToolChains/Gnu.h
new file mode 100644
index 0000000..1dc1ad4
--- /dev/null
+++ b/lib/Driver/ToolChains/Gnu.h
@@ -0,0 +1,351 @@
+//===--- Gnu.h - Gnu Tool and ToolChain Implementations ---------*- 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_LIB_DRIVER_TOOLCHAINS_GNU_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H
+
+#include "Cuda.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+#include <set>
+
+namespace clang {
+namespace driver {
+
+struct DetectedMultilibs {
+  /// The set of multilibs that the detected installation supports.
+  MultilibSet Multilibs;
+
+  /// The primary multilib appropriate for the given flags.
+  Multilib SelectedMultilib;
+
+  /// On Biarch systems, this corresponds to the default multilib when
+  /// targeting the non-default multilib. Otherwise, it is empty.
+  llvm::Optional<Multilib> BiarchSibling;
+};
+
+bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
+                       StringRef Path, const llvm::opt::ArgList &Args,
+                       DetectedMultilibs &Result);
+
+namespace tools {
+
+/// \brief Base class for all GNU tools that provide the same behavior when
+/// it comes to response files support
+class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool {
+  virtual void anchor();
+
+public:
+  GnuTool(const char *Name, const char *ShortName, const ToolChain &TC)
+      : Tool(Name, ShortName, TC, RF_Full, llvm::sys::WEM_CurrentCodePage) {}
+};
+
+/// Directly call GNU Binutils' assembler and linker.
+namespace gnutools {
+class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+public:
+  Assembler(const ToolChain &TC) : GnuTool("GNU::Assembler", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("GNU::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace gnutools
+
+/// gcc - Generic GCC tool implementations.
+namespace gcc {
+class LLVM_LIBRARY_VISIBILITY Common : public GnuTool {
+public:
+  Common(const char *Name, const char *ShortName, const ToolChain &TC)
+      : GnuTool(Name, ShortName, TC) {}
+
+  // A gcc tool has an "integrated" assembler that it will call to produce an
+  // object. Let it use that assembler so that we don't have to deal with
+  // assembly syntax incompatibilities.
+  bool hasIntegratedAssembler() const override { return true; }
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+
+  /// RenderExtraToolArgs - Render any arguments necessary to force
+  /// the particular tool mode.
+  virtual void RenderExtraToolArgs(const JobAction &JA,
+                                   llvm::opt::ArgStringList &CmdArgs) const = 0;
+};
+
+class LLVM_LIBRARY_VISIBILITY Preprocessor : public Common {
+public:
+  Preprocessor(const ToolChain &TC)
+      : Common("gcc::Preprocessor", "gcc preprocessor", TC) {}
+
+  bool hasGoodDiagnostics() const override { return true; }
+  bool hasIntegratedCPP() const override { return false; }
+
+  void RenderExtraToolArgs(const JobAction &JA,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Compiler : public Common {
+public:
+  Compiler(const ToolChain &TC) : Common("gcc::Compiler", "gcc frontend", TC) {}
+
+  bool hasGoodDiagnostics() const override { return true; }
+  bool hasIntegratedCPP() const override { return true; }
+
+  void RenderExtraToolArgs(const JobAction &JA,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public Common {
+public:
+  Linker(const ToolChain &TC) : Common("gcc::Linker", "linker (via gcc)", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void RenderExtraToolArgs(const JobAction &JA,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+};
+} // end namespace gcc
+} // end namespace tools
+
+namespace toolchains {
+
+/// Generic_GCC - A tool chain using the 'gcc' command to perform
+/// all subcommands; this relies on gcc translating the majority of
+/// command line options.
+class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
+public:
+  /// \brief Struct to store and manipulate GCC versions.
+  ///
+  /// We rely on assumptions about the form and structure of GCC version
+  /// numbers: they consist of at most three '.'-separated components, and each
+  /// component is a non-negative integer except for the last component. For
+  /// the last component we are very flexible in order to tolerate release
+  /// candidates or 'x' wildcards.
+  ///
+  /// Note that the ordering established among GCCVersions is based on the
+  /// preferred version string to use. For example we prefer versions without
+  /// a hard-coded patch number to those with a hard coded patch number.
+  ///
+  /// Currently this doesn't provide any logic for textual suffixes to patches
+  /// in the way that (for example) Debian's version format does. If that ever
+  /// becomes necessary, it can be added.
+  struct GCCVersion {
+    /// \brief The unparsed text of the version.
+    std::string Text;
+
+    /// \brief The parsed major, minor, and patch numbers.
+    int Major, Minor, Patch;
+
+    /// \brief The text of the parsed major, and major+minor versions.
+    std::string MajorStr, MinorStr;
+
+    /// \brief Any textual suffix on the patch number.
+    std::string PatchSuffix;
+
+    static GCCVersion Parse(StringRef VersionText);
+    bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch,
+                     StringRef RHSPatchSuffix = StringRef()) const;
+    bool operator<(const GCCVersion &RHS) const {
+      return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix);
+    }
+    bool operator>(const GCCVersion &RHS) const { return RHS < *this; }
+    bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }
+    bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
+  };
+
+  /// \brief This is a class to find a viable GCC installation for Clang to
+  /// use.
+  ///
+  /// This class tries to find a GCC installation on the system, and report
+  /// information about it. It starts from the host information provided to the
+  /// Driver, and has logic for fuzzing that where appropriate.
+  class GCCInstallationDetector {
+    bool IsValid;
+    llvm::Triple GCCTriple;
+    const Driver &D;
+
+    // FIXME: These might be better as path objects.
+    std::string GCCInstallPath;
+    std::string GCCParentLibPath;
+
+    /// The primary multilib appropriate for the given flags.
+    Multilib SelectedMultilib;
+    /// On Biarch systems, this corresponds to the default multilib when
+    /// targeting the non-default multilib. Otherwise, it is empty.
+    llvm::Optional<Multilib> BiarchSibling;
+
+    GCCVersion Version;
+
+    // We retain the list of install paths that were considered and rejected in
+    // order to print out detailed information in verbose mode.
+    std::set<std::string> CandidateGCCInstallPaths;
+
+    /// The set of multilibs that the detected installation supports.
+    MultilibSet Multilibs;
+
+  public:
+    explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
+    void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args,
+              ArrayRef<std::string> ExtraTripleAliases = None);
+
+    /// \brief Check whether we detected a valid GCC install.
+    bool isValid() const { return IsValid; }
+
+    /// \brief Get the GCC triple for the detected install.
+    const llvm::Triple &getTriple() const { return GCCTriple; }
+
+    /// \brief Get the detected GCC installation path.
+    StringRef getInstallPath() const { return GCCInstallPath; }
+
+    /// \brief Get the detected GCC parent lib path.
+    StringRef getParentLibPath() const { return GCCParentLibPath; }
+
+    /// \brief Get the detected Multilib
+    const Multilib &getMultilib() const { return SelectedMultilib; }
+
+    /// \brief Get the whole MultilibSet
+    const MultilibSet &getMultilibs() const { return Multilibs; }
+
+    /// Get the biarch sibling multilib (if it exists).
+    /// \return true iff such a sibling exists
+    bool getBiarchSibling(Multilib &M) const;
+
+    /// \brief Get the detected GCC version string.
+    const GCCVersion &getVersion() const { return Version; }
+
+    /// \brief Print information about the detected GCC installation.
+    void print(raw_ostream &OS) const;
+
+  private:
+    static void
+    CollectLibDirsAndTriples(const llvm::Triple &TargetTriple,
+                             const llvm::Triple &BiarchTriple,
+                             SmallVectorImpl<StringRef> &LibDirs,
+                             SmallVectorImpl<StringRef> &TripleAliases,
+                             SmallVectorImpl<StringRef> &BiarchLibDirs,
+                             SmallVectorImpl<StringRef> &BiarchTripleAliases);
+
+    bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple,
+                             const llvm::opt::ArgList &Args,
+                             StringRef Path,
+                             bool NeedsBiarchSuffix = false);
+
+    void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch,
+                                const llvm::opt::ArgList &Args,
+                                const std::string &LibDir,
+                                StringRef CandidateTriple,
+                                bool NeedsBiarchSuffix = false);
+
+    void scanLibDirForGCCTripleSolaris(const llvm::Triple &TargetArch,
+                                       const llvm::opt::ArgList &Args,
+                                       const std::string &LibDir,
+                                       StringRef CandidateTriple,
+                                       bool NeedsBiarchSuffix = false);
+
+    bool ScanGentooGccConfig(const llvm::Triple &TargetTriple,
+                             const llvm::opt::ArgList &Args,
+                             StringRef CandidateTriple,
+                             bool NeedsBiarchSuffix = false);
+  };
+
+protected:
+  GCCInstallationDetector GCCInstallation;
+  CudaInstallationDetector CudaInstallation;
+
+public:
+  Generic_GCC(const Driver &D, const llvm::Triple &Triple,
+              const llvm::opt::ArgList &Args);
+  ~Generic_GCC() override;
+
+  void printVerboseInfo(raw_ostream &OS) const override;
+
+  bool IsUnwindTablesDefault() const override;
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+  bool IsIntegratedAssemblerDefault() const override;
+  llvm::opt::DerivedArgList *
+  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
+                Action::OffloadKind DeviceOffloadKind) const override;
+
+protected:
+  Tool *getTool(Action::ActionClass AC) const override;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+
+  /// \name ToolChain Implementation Helper Functions
+  /// @{
+
+  /// \brief Check whether the target triple's architecture is 64-bits.
+  bool isTarget64Bit() const { return getTriple().isArch64Bit(); }
+
+  /// \brief Check whether the target triple's architecture is 32-bits.
+  bool isTarget32Bit() const { return getTriple().isArch32Bit(); }
+
+  // FIXME: This should be final, but the Solaris tool chain does weird
+  // things we can't easily represent.
+  void AddClangCXXStdlibIncludeArgs(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+
+  virtual std::string findLibCxxIncludePath() const;
+  virtual void
+  addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+                           llvm::opt::ArgStringList &CC1Args) const;
+
+  bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple,
+                                StringRef GCCMultiarchTriple,
+                                StringRef TargetMultiarchTriple,
+                                Twine IncludeSuffix,
+                                const llvm::opt::ArgList &DriverArgs,
+                                llvm::opt::ArgStringList &CC1Args) const;
+
+  /// @}
+
+private:
+  mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess;
+  mutable std::unique_ptr<tools::gcc::Compiler> Compile;
+};
+
+class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
+  virtual void anchor();
+
+public:
+  Generic_ELF(const Driver &D, const llvm::Triple &Triple,
+              const llvm::opt::ArgList &Args)
+      : Generic_GCC(D, Triple, Args) {}
+
+  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                             llvm::opt::ArgStringList &CC1Args) const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H
diff --git a/lib/Driver/ToolChains/Haiku.cpp b/lib/Driver/ToolChains/Haiku.cpp
new file mode 100644
index 0000000..284d269
--- /dev/null
+++ b/lib/Driver/ToolChains/Haiku.cpp
@@ -0,0 +1,33 @@
+//===--- Haiku.cpp - Haiku ToolChain Implementations ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Haiku.h"
+#include "CommonArgs.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+/// Haiku - Haiku tool chain which can call as(1) and ld(1) directly.
+
+Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) {
+
+}
+
+std::string Haiku::findLibCxxIncludePath() const {
+  return getDriver().SysRoot + "/system/develop/headers/c++/v1";
+}
+
+void Haiku::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+                                     llvm::opt::ArgStringList &CC1Args) const {
+  addLibStdCXXIncludePaths(getDriver().SysRoot, "/system/develop/headers/c++",
+                           getTriple().str(), "", "", "", DriverArgs, CC1Args);
+}
diff --git a/lib/Driver/ToolChains/Haiku.h b/lib/Driver/ToolChains/Haiku.h
new file mode 100644
index 0000000..8b5b48e
--- /dev/null
+++ b/lib/Driver/ToolChains/Haiku.h
@@ -0,0 +1,40 @@
+//===--- Haiku.h - Haiku ToolChain Implementations --------------*- 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_LIB_DRIVER_TOOLCHAINS_HAIKU_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HAIKU_H
+
+#include "Gnu.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY Haiku : public Generic_ELF {
+public:
+  Haiku(const Driver &D, const llvm::Triple &Triple,
+          const llvm::opt::ArgList &Args);
+
+  bool isPIEDefault() const override {
+    return getTriple().getArch() == llvm::Triple::x86_64;
+  }
+
+  std::string findLibCxxIncludePath() const override;
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HAIKU_H
diff --git a/lib/Driver/ToolChains/Hexagon.cpp b/lib/Driver/ToolChains/Hexagon.cpp
new file mode 100644
index 0000000..c143b7f
--- /dev/null
+++ b/lib/Driver/ToolChains/Hexagon.cpp
@@ -0,0 +1,457 @@
+//===--- Hexagon.cpp - Hexagon ToolChain Implementations --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Hexagon.h"
+#include "InputInfo.h"
+#include "CommonArgs.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+// Hexagon tools start.
+void hexagon::Assembler::RenderExtraToolArgs(const JobAction &JA,
+                                             ArgStringList &CmdArgs) const {
+}
+
+void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                      const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const ArgList &Args,
+                                      const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+
+  auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
+  const Driver &D = HTC.getDriver();
+  ArgStringList CmdArgs;
+
+  std::string MArchString = "-march=hexagon";
+  CmdArgs.push_back(Args.MakeArgString(MArchString));
+
+  RenderExtraToolArgs(JA, CmdArgs);
+
+  std::string AsName = "hexagon-llvm-mc";
+  std::string MCpuString = "-mcpu=hexagon" +
+        toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
+  CmdArgs.push_back("-filetype=obj");
+  CmdArgs.push_back(Args.MakeArgString(MCpuString));
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Unexpected output");
+    CmdArgs.push_back("-fsyntax-only");
+  }
+
+  if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
+    std::string N = llvm::utostr(G.getValue());
+    CmdArgs.push_back(Args.MakeArgString(std::string("-gpsize=") + N));
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  // Only pass -x if gcc will understand it; otherwise hope gcc
+  // understands the suffix correctly. The main use case this would go
+  // wrong in is for linker inputs if they happened to have an odd
+  // suffix; really the only way to get this to happen is a command
+  // like '-x foobar a.c' which will treat a.c like a linker input.
+  //
+  // FIXME: For the linker case specifically, can we safely convert
+  // inputs into '-Wl,' options?
+  for (const auto &II : Inputs) {
+    // Don't try to pass LLVM or AST inputs to a generic gcc.
+    if (types::isLLVMIR(II.getType()))
+      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+          << HTC.getTripleString();
+    else if (II.getType() == types::TY_AST)
+      D.Diag(clang::diag::err_drv_no_ast_support)
+          << HTC.getTripleString();
+    else if (II.getType() == types::TY_ModuleFile)
+      D.Diag(diag::err_drv_no_module_support)
+          << HTC.getTripleString();
+
+    if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else
+      // Don't render as input, we need gcc to do the translations.
+      // FIXME: What is this?
+      II.getInputArg().render(Args, CmdArgs);
+  }
+
+  auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName.c_str()));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA,
+                                          ArgStringList &CmdArgs) const {
+}
+
+static void
+constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
+                         const toolchains::HexagonToolChain &HTC,
+                         const InputInfo &Output, const InputInfoList &Inputs,
+                         const ArgList &Args, ArgStringList &CmdArgs,
+                         const char *LinkingOutput) {
+
+  const Driver &D = HTC.getDriver();
+
+  //----------------------------------------------------------------------------
+  //
+  //----------------------------------------------------------------------------
+  bool IsStatic = Args.hasArg(options::OPT_static);
+  bool IsShared = Args.hasArg(options::OPT_shared);
+  bool IsPIE = Args.hasArg(options::OPT_pie);
+  bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
+  bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
+  bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
+  bool UseG0 = false;
+  bool UseShared = IsShared && !IsStatic;
+
+  //----------------------------------------------------------------------------
+  // Silence warnings for various options
+  //----------------------------------------------------------------------------
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
+                                     // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_static_libgcc);
+
+  //----------------------------------------------------------------------------
+  //
+  //----------------------------------------------------------------------------
+  if (Args.hasArg(options::OPT_s))
+    CmdArgs.push_back("-s");
+
+  if (Args.hasArg(options::OPT_r))
+    CmdArgs.push_back("-r");
+
+  for (const auto &Opt : HTC.ExtraOpts)
+    CmdArgs.push_back(Opt.c_str());
+
+  CmdArgs.push_back("-march=hexagon");
+  std::string CpuVer =
+        toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
+  std::string MCpuString = "-mcpu=hexagon" + CpuVer;
+  CmdArgs.push_back(Args.MakeArgString(MCpuString));
+
+  if (IsShared) {
+    CmdArgs.push_back("-shared");
+    // The following should be the default, but doing as hexagon-gcc does.
+    CmdArgs.push_back("-call_shared");
+  }
+
+  if (IsStatic)
+    CmdArgs.push_back("-static");
+
+  if (IsPIE && !IsShared)
+    CmdArgs.push_back("-pie");
+
+  if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
+    std::string N = llvm::utostr(G.getValue());
+    CmdArgs.push_back(Args.MakeArgString(std::string("-G") + N));
+    UseG0 = G.getValue() == 0;
+  }
+
+  //----------------------------------------------------------------------------
+  //
+  //----------------------------------------------------------------------------
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  //----------------------------------------------------------------------------
+  // moslib
+  //----------------------------------------------------------------------------
+  std::vector<std::string> OsLibs;
+  bool HasStandalone = false;
+
+  for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
+    A->claim();
+    OsLibs.emplace_back(A->getValue());
+    HasStandalone = HasStandalone || (OsLibs.back() == "standalone");
+  }
+  if (OsLibs.empty()) {
+    OsLibs.push_back("standalone");
+    HasStandalone = true;
+  }
+
+  //----------------------------------------------------------------------------
+  // Start Files
+  //----------------------------------------------------------------------------
+  const std::string MCpuSuffix = "/" + CpuVer;
+  const std::string MCpuG0Suffix = MCpuSuffix + "/G0";
+  const std::string RootDir =
+      HTC.getHexagonTargetDir(D.InstalledDir, D.PrefixDirs) + "/";
+  const std::string StartSubDir =
+      "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
+
+  auto Find = [&HTC] (const std::string &RootDir, const std::string &SubDir,
+                      const char *Name) -> std::string {
+    std::string RelName = SubDir + Name;
+    std::string P = HTC.GetFilePath(RelName.c_str());
+    if (llvm::sys::fs::exists(P))
+      return P;
+    return RootDir + RelName;
+  };
+
+  if (IncStdLib && IncStartFiles) {
+    if (!IsShared) {
+      if (HasStandalone) {
+        std::string Crt0SA = Find(RootDir, StartSubDir, "/crt0_standalone.o");
+        CmdArgs.push_back(Args.MakeArgString(Crt0SA));
+      }
+      std::string Crt0 = Find(RootDir, StartSubDir, "/crt0.o");
+      CmdArgs.push_back(Args.MakeArgString(Crt0));
+    }
+    std::string Init = UseShared
+          ? Find(RootDir, StartSubDir + "/pic", "/initS.o")
+          : Find(RootDir, StartSubDir, "/init.o");
+    CmdArgs.push_back(Args.MakeArgString(Init));
+  }
+
+  //----------------------------------------------------------------------------
+  // Library Search Paths
+  //----------------------------------------------------------------------------
+  const ToolChain::path_list &LibPaths = HTC.getFilePaths();
+  for (const auto &LibPath : LibPaths)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
+
+  //----------------------------------------------------------------------------
+  //
+  //----------------------------------------------------------------------------
+  Args.AddAllArgs(CmdArgs,
+                  {options::OPT_T_Group, options::OPT_e, options::OPT_s,
+                   options::OPT_t, options::OPT_u_Group});
+
+  AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
+
+  //----------------------------------------------------------------------------
+  // Libraries
+  //----------------------------------------------------------------------------
+  if (IncStdLib && IncDefLibs) {
+    if (D.CCCIsCXX()) {
+      HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
+      CmdArgs.push_back("-lm");
+    }
+
+    CmdArgs.push_back("--start-group");
+
+    if (!IsShared) {
+      for (const std::string &Lib : OsLibs)
+        CmdArgs.push_back(Args.MakeArgString("-l" + Lib));
+      CmdArgs.push_back("-lc");
+    }
+    CmdArgs.push_back("-lgcc");
+
+    CmdArgs.push_back("--end-group");
+  }
+
+  //----------------------------------------------------------------------------
+  // End files
+  //----------------------------------------------------------------------------
+  if (IncStdLib && IncStartFiles) {
+    std::string Fini = UseShared
+          ? Find(RootDir, StartSubDir + "/pic", "/finiS.o")
+          : Find(RootDir, StartSubDir, "/fini.o");
+    CmdArgs.push_back(Args.MakeArgString(Fini));
+  }
+}
+
+void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                   const InputInfo &Output,
+                                   const InputInfoList &Inputs,
+                                   const ArgList &Args,
+                                   const char *LinkingOutput) const {
+  auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
+
+  ArgStringList CmdArgs;
+  constructHexagonLinkArgs(C, JA, HTC, Output, Inputs, Args, CmdArgs,
+                           LinkingOutput);
+
+  std::string Linker = HTC.GetProgramPath("hexagon-link");
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
+                                          CmdArgs, Inputs));
+}
+// Hexagon tools end.
+
+/// Hexagon Toolchain
+
+std::string HexagonToolChain::getHexagonTargetDir(
+      const std::string &InstalledDir,
+      const SmallVectorImpl<std::string> &PrefixDirs) const {
+  std::string InstallRelDir;
+  const Driver &D = getDriver();
+
+  // Locate the rest of the toolchain ...
+  for (auto &I : PrefixDirs)
+    if (D.getVFS().exists(I))
+      return I;
+
+  if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
+    return InstallRelDir;
+
+  return InstalledDir;
+}
+
+Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
+      const ArgList &Args) {
+  StringRef Gn = "";
+  if (Arg *A = Args.getLastArg(options::OPT_G)) {
+    Gn = A->getValue();
+  } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
+                             options::OPT_fPIC)) {
+    Gn = "0";
+  }
+
+  unsigned G;
+  if (!Gn.getAsInteger(10, G))
+    return G;
+
+  return None;
+}
+
+void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
+      ToolChain::path_list &LibPaths) const {
+  const Driver &D = getDriver();
+
+  //----------------------------------------------------------------------------
+  // -L Args
+  //----------------------------------------------------------------------------
+  for (Arg *A : Args.filtered(options::OPT_L))
+    for (const char *Value : A->getValues())
+      LibPaths.push_back(Value);
+
+  //----------------------------------------------------------------------------
+  // Other standard paths
+  //----------------------------------------------------------------------------
+  std::vector<std::string> RootDirs;
+  std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
+            std::back_inserter(RootDirs));
+
+  std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
+                                              D.PrefixDirs);
+  if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
+    RootDirs.push_back(TargetDir);
+
+  bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
+  // Assume G0 with -shared.
+  bool HasG0 = Args.hasArg(options::OPT_shared);
+  if (auto G = getSmallDataThreshold(Args))
+    HasG0 = G.getValue() == 0;
+
+  const std::string CpuVer = GetTargetCPUVersion(Args).str();
+  for (auto &Dir : RootDirs) {
+    std::string LibDir = Dir + "/hexagon/lib";
+    std::string LibDirCpu = LibDir + '/' + CpuVer;
+    if (HasG0) {
+      if (HasPIC)
+        LibPaths.push_back(LibDirCpu + "/G0/pic");
+      LibPaths.push_back(LibDirCpu + "/G0");
+    }
+    LibPaths.push_back(LibDirCpu);
+    LibPaths.push_back(LibDir);
+  }
+}
+
+HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
+                                   const llvm::opt::ArgList &Args)
+    : Linux(D, Triple, Args) {
+  const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
+                                                    D.PrefixDirs);
+
+  // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
+  // program paths
+  const std::string BinDir(TargetDir + "/bin");
+  if (D.getVFS().exists(BinDir))
+    getProgramPaths().push_back(BinDir);
+
+  ToolChain::path_list &LibPaths = getFilePaths();
+
+  // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
+  // 'elf' OS type, so the Linux paths are not appropriate. When we actually
+  // support 'linux' we'll need to fix this up
+  LibPaths.clear();
+  getHexagonLibraryPaths(Args, LibPaths);
+}
+
+HexagonToolChain::~HexagonToolChain() {}
+
+Tool *HexagonToolChain::buildAssembler() const {
+  return new tools::hexagon::Assembler(*this);
+}
+
+Tool *HexagonToolChain::buildLinker() const {
+  return new tools::hexagon::Linker(*this);
+}
+
+void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                                 ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
+      DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
+  const Driver &D = getDriver();
+  std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
+                                              D.PrefixDirs);
+  addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
+}
+
+
+void HexagonToolChain::addLibStdCxxIncludePaths(
+    const llvm::opt::ArgList &DriverArgs,
+    llvm::opt::ArgStringList &CC1Args) const {
+  const Driver &D = getDriver();
+  std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
+  addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++", "", "", "", "",
+                           DriverArgs, CC1Args);
+}
+
+ToolChain::CXXStdlibType
+HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
+  Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
+  if (!A)
+    return ToolChain::CST_Libstdcxx;
+
+  StringRef Value = A->getValue();
+  if (Value != "libstdc++")
+    getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
+
+  return ToolChain::CST_Libstdcxx;
+}
+
+//
+// Returns the default CPU for Hexagon. This is the default compilation target
+// if no Hexagon processor is selected at the command-line.
+//
+const StringRef HexagonToolChain::GetDefaultCPU() {
+  return "hexagonv60";
+}
+
+const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
+  Arg *CpuArg = nullptr;
+  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
+    CpuArg = A;
+
+  StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
+  if (CPU.startswith("hexagon"))
+    return CPU.substr(sizeof("hexagon") - 1);
+  return CPU;
+}
diff --git a/lib/Driver/ToolChains/Hexagon.h b/lib/Driver/ToolChains/Hexagon.h
new file mode 100644
index 0000000..fb50ba3
--- /dev/null
+++ b/lib/Driver/ToolChains/Hexagon.h
@@ -0,0 +1,99 @@
+//===--- Hexagon.h - Hexagon ToolChain Implementations ----------*- 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_LIB_DRIVER_TOOLCHAINS_HEXAGON_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HEXAGON_H
+
+#include "Linux.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace hexagon {
+// For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile
+// and Compile.
+// We simply use "clang -cc1" for those actions.
+class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+public:
+  Assembler(const ToolChain &TC)
+      : GnuTool("hexagon::Assembler", "hexagon-as", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void RenderExtraToolArgs(const JobAction &JA,
+                           llvm::opt::ArgStringList &CmdArgs) const;
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("hexagon::Linker", "hexagon-ld", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  virtual void RenderExtraToolArgs(const JobAction &JA,
+                                   llvm::opt::ArgStringList &CmdArgs) const;
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace hexagon.
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY HexagonToolChain : public Linux {
+protected:
+  GCCVersion GCCLibAndIncVersion;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+
+public:
+  HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
+                   const llvm::opt::ArgList &Args);
+  ~HexagonToolChain() override;
+
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+
+  StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; }
+  bool IsIntegratedAssemblerDefault() const override {
+    return true;
+  }
+
+  std::string getHexagonTargetDir(
+      const std::string &InstalledDir,
+      const SmallVectorImpl<std::string> &PrefixDirs) const;
+  void getHexagonLibraryPaths(const llvm::opt::ArgList &Args,
+      ToolChain::path_list &LibPaths) const;
+
+  static const StringRef GetDefaultCPU();
+  static const StringRef GetTargetCPUVersion(const llvm::opt::ArgList &Args);
+
+  static Optional<unsigned> getSmallDataThreshold(
+      const llvm::opt::ArgList &Args);
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HEXAGON_H
diff --git a/lib/Driver/ToolChains/Lanai.h b/lib/Driver/ToolChains/Lanai.h
new file mode 100644
index 0000000..4ce658d
--- /dev/null
+++ b/lib/Driver/ToolChains/Lanai.h
@@ -0,0 +1,39 @@
+//===--- Lanai.h - Lanai ToolChain Implementations --------------*- 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_LIB_DRIVER_TOOLCHAINS_LANAI_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LANAI_H
+
+#include "Gnu.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY LanaiToolChain : public Generic_ELF {
+public:
+  LanaiToolChain(const Driver &D, const llvm::Triple &Triple,
+                 const llvm::opt::ArgList &Args)
+      : Generic_ELF(D, Triple, Args) {}
+
+  // No support for finding a C++ standard library yet.
+  std::string findLibCxxIncludePath() const override { return ""; }
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override {}
+
+  bool IsIntegratedAssemblerDefault() const override { return true; }
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LANAI_H
diff --git a/lib/Driver/ToolChains/Linux.cpp b/lib/Driver/ToolChains/Linux.cpp
new file mode 100644
index 0000000..e87ef08
--- /dev/null
+++ b/lib/Driver/ToolChains/Linux.cpp
@@ -0,0 +1,898 @@
+//===--- Linux.h - Linux ToolChain Implementations --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Linux.h"
+#include "Arch/ARM.h"
+#include "Arch/Mips.h"
+#include "Arch/PPC.h"
+#include "CommonArgs.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Distro.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Path.h"
+#include <system_error>
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+using tools::addPathIfExists;
+
+/// \brief Get our best guess at the multiarch triple for a target.
+///
+/// Debian-based systems are starting to use a multiarch setup where they use
+/// a target-triple directory in the library and header search paths.
+/// Unfortunately, this triple does not align with the vanilla target triple,
+/// so we provide a rough mapping here.
+static std::string getMultiarchTriple(const Driver &D,
+                                      const llvm::Triple &TargetTriple,
+                                      StringRef SysRoot) {
+  llvm::Triple::EnvironmentType TargetEnvironment =
+      TargetTriple.getEnvironment();
+
+  // For most architectures, just use whatever we have rather than trying to be
+  // clever.
+  switch (TargetTriple.getArch()) {
+  default:
+    break;
+
+  // We use the existence of '/lib/<triple>' as a directory to detect some
+  // common linux triples that don't quite match the Clang triple for both
+  // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
+  // regardless of what the actual target triple is.
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
+      if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf"))
+        return "arm-linux-gnueabihf";
+    } else {
+      if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi"))
+        return "arm-linux-gnueabi";
+    }
+    break;
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumbeb:
+    if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
+      if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
+        return "armeb-linux-gnueabihf";
+    } else {
+      if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi"))
+        return "armeb-linux-gnueabi";
+    }
+    break;
+  case llvm::Triple::x86:
+    if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu"))
+      return "i386-linux-gnu";
+    break;
+  case llvm::Triple::x86_64:
+    // We don't want this for x32, otherwise it will match x86_64 libs
+    if (TargetEnvironment != llvm::Triple::GNUX32 &&
+        D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu"))
+      return "x86_64-linux-gnu";
+    break;
+  case llvm::Triple::aarch64:
+    if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu"))
+      return "aarch64-linux-gnu";
+    break;
+  case llvm::Triple::aarch64_be:
+    if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
+      return "aarch64_be-linux-gnu";
+    break;
+  case llvm::Triple::mips:
+    if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))
+      return "mips-linux-gnu";
+    break;
+  case llvm::Triple::mipsel:
+    if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))
+      return "mipsel-linux-gnu";
+    break;
+  case llvm::Triple::mips64:
+    if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
+      return "mips64-linux-gnu";
+    if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
+      return "mips64-linux-gnuabi64";
+    break;
+  case llvm::Triple::mips64el:
+    if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))
+      return "mips64el-linux-gnu";
+    if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
+      return "mips64el-linux-gnuabi64";
+    break;
+  case llvm::Triple::ppc:
+    if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
+      return "powerpc-linux-gnuspe";
+    if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
+      return "powerpc-linux-gnu";
+    break;
+  case llvm::Triple::ppc64:
+    if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))
+      return "powerpc64-linux-gnu";
+    break;
+  case llvm::Triple::ppc64le:
+    if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
+      return "powerpc64le-linux-gnu";
+    break;
+  case llvm::Triple::sparc:
+    if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu"))
+      return "sparc-linux-gnu";
+    break;
+  case llvm::Triple::sparcv9:
+    if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu"))
+      return "sparc64-linux-gnu";
+    break;
+  case llvm::Triple::systemz:
+    if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu"))
+      return "s390x-linux-gnu";
+    break;
+  }
+  return TargetTriple.str();
+}
+
+static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
+  if (tools::isMipsArch(Triple.getArch())) {
+    if (Triple.isAndroid()) {
+      StringRef CPUName;
+      StringRef ABIName;
+      tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+      if (CPUName == "mips32r6")
+        return "libr6";
+      if (CPUName == "mips32r2")
+        return "libr2";
+    }
+    // lib32 directory has a special meaning on MIPS targets.
+    // It contains N32 ABI binaries. Use this folder if produce
+    // code for N32 ABI only.
+    if (tools::mips::hasMipsAbiArg(Args, "n32"))
+      return "lib32";
+    return Triple.isArch32Bit() ? "lib" : "lib64";
+  }
+
+  // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and
+  // using that variant while targeting other architectures causes problems
+  // because the libraries are laid out in shared system roots that can't cope
+  // with a 'lib32' library search path being considered. So we only enable
+  // them when we know we may need it.
+  //
+  // FIXME: This is a bit of a hack. We should really unify this code for
+  // reasoning about oslibdir spellings with the lib dir spellings in the
+  // GCCInstallationDetector, but that is a more significant refactoring.
+  if (Triple.getArch() == llvm::Triple::x86 ||
+      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";
+}
+
+static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
+                                  const Multilib &Multilib,
+                                  StringRef InstallPath,
+                                  ToolChain::path_list &Paths) {
+  if (const auto &PathsCallback = Multilibs.filePathsCallback())
+    for (const auto &Path : PathsCallback(Multilib))
+      addPathIfExists(D, InstallPath + Path, Paths);
+}
+
+Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  GCCInstallation.init(Triple, Args);
+  Multilibs = GCCInstallation.getMultilibs();
+  llvm::Triple::ArchType Arch = Triple.getArch();
+  std::string SysRoot = computeSysRoot();
+
+  // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
+  // least) put various tools in a triple-prefixed directory off of the parent
+  // of the GCC installation. We use the GCC triple here to ensure that we end
+  // up with tools that support the same amount of cross compiling as the
+  // detected GCC installation. For example, if we find a GCC installation
+  // targeting x86_64, but it is a bi-arch GCC installation, it can also be
+  // used to target i386.
+  // FIXME: This seems unlikely to be Linux-specific.
+  ToolChain::path_list &PPaths = getProgramPaths();
+  PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
+                         GCCInstallation.getTriple().str() + "/bin")
+                       .str());
+
+  Distro Distro(D.getVFS());
+
+  if (Distro.IsOpenSUSE() || Distro.IsUbuntu()) {
+    ExtraOpts.push_back("-z");
+    ExtraOpts.push_back("relro");
+  }
+
+  if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
+    ExtraOpts.push_back("-X");
+
+  const bool IsAndroid = Triple.isAndroid();
+  const bool IsMips = tools::isMipsArch(Arch);
+  const bool IsHexagon = Arch == llvm::Triple::hexagon;
+
+  if (IsMips && !SysRoot.empty())
+    ExtraOpts.push_back("--sysroot=" + SysRoot);
+
+  // Do not use 'gnu' hash style for Mips targets because .gnu.hash
+  // and the MIPS ABI require .dynsym to be sorted in different ways.
+  // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
+  // ABI requires a mapping between the GOT and the symbol table.
+  // Android loader does not support .gnu.hash.
+  // Hexagon linker/loader does not support .gnu.hash
+  if (!IsMips && !IsAndroid && !IsHexagon) {
+    if (Distro.IsRedhat() || Distro.IsOpenSUSE() ||
+        (Distro.IsUbuntu() && Distro >= Distro::UbuntuMaverick))
+      ExtraOpts.push_back("--hash-style=gnu");
+
+    if (Distro.IsDebian() || Distro.IsOpenSUSE() || Distro == Distro::UbuntuLucid ||
+        Distro == Distro::UbuntuJaunty || Distro == Distro::UbuntuKarmic)
+      ExtraOpts.push_back("--hash-style=both");
+  }
+
+  if (Distro.IsRedhat() && Distro != Distro::RHEL5 && Distro != Distro::RHEL6)
+    ExtraOpts.push_back("--no-add-needed");
+
+#ifdef ENABLE_LINKER_BUILD_ID
+  ExtraOpts.push_back("--build-id");
+#endif
+
+  if (Distro.IsOpenSUSE())
+    ExtraOpts.push_back("--enable-new-dtags");
+
+  // The selection of paths to try here is designed to match the patterns which
+  // the GCC driver itself uses, as this is part of the GCC-compatible driver.
+  // This was determined by running GCC in a fake filesystem, creating all
+  // possible permutations of these directories, and seeing which ones it added
+  // to the link paths.
+  path_list &Paths = getFilePaths();
+
+  const std::string OSLibDir = getOSLibDir(Triple, Args);
+  const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
+
+  // Add the multilib suffixed paths where they are available.
+  if (GCCInstallation.isValid()) {
+    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
+    const std::string &LibPath = GCCInstallation.getParentLibPath();
+    const Multilib &Multilib = GCCInstallation.getMultilib();
+    const MultilibSet &Multilibs = GCCInstallation.getMultilibs();
+
+    // Add toolchain / multilib specific file paths.
+    addMultilibsFilePaths(D, Multilibs, Multilib,
+                          GCCInstallation.getInstallPath(), Paths);
+
+    // Sourcery CodeBench MIPS toolchain holds some libraries under
+    // a biarch-like suffix of the GCC installation.
+    addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(),
+                    Paths);
+
+    // GCC cross compiling toolchains will install target libraries which ship
+    // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
+    // any part of the GCC installation in
+    // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
+    // debatable, but is the reality today. We need to search this tree even
+    // when we have a sysroot somewhere else. It is the responsibility of
+    // whomever is doing the cross build targeting a sysroot using a GCC
+    // installation that is *not* within the system root to ensure two things:
+    //
+    //  1) Any DSOs that are linked in from this tree or from the install path
+    //     above must be present on the system root and found via an
+    //     appropriate rpath.
+    //  2) There must not be libraries installed into
+    //     <prefix>/<triple>/<libdir> unless they should be preferred over
+    //     those within the system root.
+    //
+    // Note that this matches the GCC behavior. See the below comment for where
+    // Clang diverges from GCC's behavior.
+    addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" +
+                           OSLibDir + Multilib.osSuffix(),
+                    Paths);
+
+    // If the GCC installation we found is inside of the sysroot, we want to
+    // prefer libraries installed in the parent prefix of the GCC installation.
+    // It is important to *not* use these paths when the GCC installation is
+    // outside of the system root as that can pick up unintended libraries.
+    // This usually happens when there is an external cross compiler on the
+    // host system, and a more minimal sysroot available that is the target of
+    // the cross. Note that GCC does include some of these directories in some
+    // configurations but this seems somewhere between questionable and simply
+    // a bug.
+    if (StringRef(LibPath).startswith(SysRoot)) {
+      addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
+      addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
+    }
+  }
+
+  // Similar to the logic for GCC above, if we currently running Clang inside
+  // of the requested system root, add its parent library paths to
+  // those searched.
+  // FIXME: It's not clear whether we should use the driver's installed
+  // directory ('Dir' below) or the ResourceDir.
+  if (StringRef(D.Dir).startswith(SysRoot)) {
+    addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths);
+    addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
+  }
+
+  addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
+  addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
+  addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
+  addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
+
+  // Try walking via the GCC triple path in case of biarch or multiarch GCC
+  // installations with strange symlinks.
+  if (GCCInstallation.isValid()) {
+    addPathIfExists(D,
+                    SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
+                        "/../../" + OSLibDir,
+                    Paths);
+
+    // Add the 'other' biarch variant path
+    Multilib BiarchSibling;
+    if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
+      addPathIfExists(D, GCCInstallation.getInstallPath() +
+                             BiarchSibling.gccSuffix(),
+                      Paths);
+    }
+
+    // See comments above on the multilib variant for details of why this is
+    // included even from outside the sysroot.
+    const std::string &LibPath = GCCInstallation.getParentLibPath();
+    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
+    const Multilib &Multilib = GCCInstallation.getMultilib();
+    addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" +
+                           Multilib.osSuffix(),
+                    Paths);
+
+    // See comments above on the multilib variant for details of why this is
+    // only included from within the sysroot.
+    if (StringRef(LibPath).startswith(SysRoot))
+      addPathIfExists(D, LibPath, Paths);
+  }
+
+  // Similar to the logic for GCC above, if we are currently running Clang
+  // inside of the requested system root, add its parent library path to those
+  // searched.
+  // FIXME: It's not clear whether we should use the driver's installed
+  // directory ('Dir' below) or the ResourceDir.
+  if (StringRef(D.Dir).startswith(SysRoot))
+    addPathIfExists(D, D.Dir + "/../lib", Paths);
+
+  addPathIfExists(D, SysRoot + "/lib", Paths);
+  addPathIfExists(D, SysRoot + "/usr/lib", Paths);
+}
+
+/// \brief Parse a GCCVersion object out of a string of text.
+///
+/// This is the primary means of forming GCCVersion objects.
+/*static*/
+Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
+  const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
+  std::pair<StringRef, StringRef> First = VersionText.split('.');
+  std::pair<StringRef, StringRef> Second = First.second.split('.');
+
+  GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
+  if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 0)
+    return BadVersion;
+  GoodVersion.MajorStr = First.first.str();
+  if (First.second.empty())
+    return GoodVersion;
+  if (Second.first.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0)
+    return BadVersion;
+  GoodVersion.MinorStr = Second.first.str();
+
+  // First look for a number prefix and parse that if present. Otherwise just
+  // stash the entire patch string in the suffix, and leave the number
+  // unspecified. This covers versions strings such as:
+  //   5        (handled above)
+  //   4.4
+  //   4.4.0
+  //   4.4.x
+  //   4.4.2-rc4
+  //   4.4.x-patched
+  // And retains any patch number it finds.
+  StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str();
+  if (!PatchText.empty()) {
+    if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
+      // Try to parse the number and any suffix.
+      if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
+          GoodVersion.Patch < 0)
+        return BadVersion;
+      GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
+    }
+  }
+
+  return GoodVersion;
+}
+
+bool Linux::HasNativeLLVMSupport() const { return true; }
+
+Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); }
+
+Tool *Linux::buildAssembler() const {
+  return new tools::gnutools::Assembler(*this);
+}
+
+std::string Linux::computeSysRoot() const {
+  if (!getDriver().SysRoot.empty())
+    return getDriver().SysRoot;
+
+  if (!GCCInstallation.isValid() || !tools::isMipsArch(getTriple().getArch()))
+    return std::string();
+
+  // Standalone MIPS toolchains use different names for sysroot folder
+  // and put it into different places. Here we try to check some known
+  // variants.
+
+  const StringRef InstallDir = GCCInstallation.getInstallPath();
+  const StringRef TripleStr = GCCInstallation.getTriple().str();
+  const Multilib &Multilib = GCCInstallation.getMultilib();
+
+  std::string Path =
+      (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
+          .str();
+
+  if (getVFS().exists(Path))
+    return Path;
+
+  Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
+
+  if (getVFS().exists(Path))
+    return Path;
+
+  return std::string();
+}
+
+std::string Linux::getDynamicLinker(const ArgList &Args) const {
+  const llvm::Triple::ArchType Arch = getArch();
+  const llvm::Triple &Triple = getTriple();
+
+  const Distro Distro(getDriver().getVFS());
+
+  if (Triple.isAndroid())
+    return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
+
+  if (Triple.isMusl()) {
+    std::string ArchName;
+    bool IsArm = false;
+
+    switch (Arch) {
+    case llvm::Triple::arm:
+    case llvm::Triple::thumb:
+      ArchName = "arm";
+      IsArm = true;
+      break;
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumbeb:
+      ArchName = "armeb";
+      IsArm = true;
+      break;
+    default:
+      ArchName = Triple.getArchName().str();
+    }
+    if (IsArm &&
+        (Triple.getEnvironment() == llvm::Triple::MuslEABIHF ||
+         tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard))
+      ArchName += "hf";
+
+    return "/lib/ld-musl-" + ArchName + ".so.1";
+  }
+
+  std::string LibDir;
+  std::string Loader;
+
+  switch (Arch) {
+  default:
+    llvm_unreachable("unsupported architecture");
+
+  case llvm::Triple::aarch64:
+    LibDir = "lib";
+    Loader = "ld-linux-aarch64.so.1";
+    break;
+  case llvm::Triple::aarch64_be:
+    LibDir = "lib";
+    Loader = "ld-linux-aarch64_be.so.1";
+    break;
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumbeb: {
+    const bool HF =
+        Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
+        tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard;
+
+    LibDir = "lib";
+    Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3";
+    break;
+  }
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el: {
+    bool LE = (Triple.getArch() == llvm::Triple::mipsel) ||
+              (Triple.getArch() == llvm::Triple::mips64el);
+    bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple);
+
+    LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple);
+
+    if (tools::mips::isUCLibc(Args))
+      Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
+    else if (!Triple.hasEnvironment() &&
+             Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies)
+      Loader = LE ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1";
+    else
+      Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
+
+    break;
+  }
+  case llvm::Triple::ppc:
+    LibDir = "lib";
+    Loader = "ld.so.1";
+    break;
+  case llvm::Triple::ppc64:
+    LibDir = "lib64";
+    Loader =
+        (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1";
+    break;
+  case llvm::Triple::ppc64le:
+    LibDir = "lib64";
+    Loader =
+        (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2";
+    break;
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+    LibDir = "lib";
+    Loader = "ld-linux.so.2";
+    break;
+  case llvm::Triple::sparcv9:
+    LibDir = "lib64";
+    Loader = "ld-linux.so.2";
+    break;
+  case llvm::Triple::systemz:
+    LibDir = "lib";
+    Loader = "ld64.so.1";
+    break;
+  case llvm::Triple::x86:
+    LibDir = "lib";
+    Loader = "ld-linux.so.2";
+    break;
+  case llvm::Triple::x86_64: {
+    bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32;
+
+    LibDir = X32 ? "libx32" : "lib64";
+    Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
+    break;
+  }
+  }
+
+  if (Distro == Distro::Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor ||
+                                    Triple.getVendor() == llvm::Triple::PC))
+    return "/usr/" + Triple.str() + "/lib/" + Loader;
+  return "/" + LibDir + "/" + Loader;
+}
+
+void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                      ArgStringList &CC1Args) const {
+  const Driver &D = getDriver();
+  std::string SysRoot = computeSysRoot();
+
+  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
+    return;
+
+  if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
+    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
+
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    SmallString<128> P(D.ResourceDir);
+    llvm::sys::path::append(P, "include");
+    addSystemInclude(DriverArgs, CC1Args, P);
+  }
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
+  // Check for configure-time C include directories.
+  StringRef CIncludeDirs(C_INCLUDE_DIRS);
+  if (CIncludeDirs != "") {
+    SmallVector<StringRef, 5> dirs;
+    CIncludeDirs.split(dirs, ":");
+    for (StringRef dir : dirs) {
+      StringRef Prefix =
+          llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
+      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
+    }
+    return;
+  }
+
+  // Lacking those, try to detect the correct set of system includes for the
+  // target triple.
+
+  // Add include directories specific to the selected multilib set and multilib.
+  if (GCCInstallation.isValid()) {
+    const auto &Callback = Multilibs.includeDirsCallback();
+    if (Callback) {
+      for (const auto &Path : Callback(GCCInstallation.getMultilib()))
+        addExternCSystemIncludeIfExists(
+            DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path);
+    }
+  }
+
+  // Implement generic Debian multiarch support.
+  const StringRef X86_64MultiarchIncludeDirs[] = {
+      "/usr/include/x86_64-linux-gnu",
+
+      // FIXME: These are older forms of multiarch. It's not clear that they're
+      // in use in any released version of Debian, so we should consider
+      // removing them.
+      "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"};
+  const StringRef X86MultiarchIncludeDirs[] = {
+      "/usr/include/i386-linux-gnu",
+
+      // FIXME: These are older forms of multiarch. It's not clear that they're
+      // in use in any released version of Debian, so we should consider
+      // removing them.
+      "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
+      "/usr/include/i486-linux-gnu"};
+  const StringRef AArch64MultiarchIncludeDirs[] = {
+      "/usr/include/aarch64-linux-gnu"};
+  const StringRef ARMMultiarchIncludeDirs[] = {
+      "/usr/include/arm-linux-gnueabi"};
+  const StringRef ARMHFMultiarchIncludeDirs[] = {
+      "/usr/include/arm-linux-gnueabihf"};
+  const StringRef ARMEBMultiarchIncludeDirs[] = {
+      "/usr/include/armeb-linux-gnueabi"};
+  const StringRef ARMEBHFMultiarchIncludeDirs[] = {
+      "/usr/include/armeb-linux-gnueabihf"};
+  const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"};
+  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"};
+  const StringRef SparcMultiarchIncludeDirs[] = {
+      "/usr/include/sparc-linux-gnu"};
+  const StringRef Sparc64MultiarchIncludeDirs[] = {
+      "/usr/include/sparc64-linux-gnu"};
+  const StringRef SYSTEMZMultiarchIncludeDirs[] = {
+      "/usr/include/s390x-linux-gnu"};
+  ArrayRef<StringRef> MultiarchIncludeDirs;
+  switch (getTriple().getArch()) {
+  case llvm::Triple::x86_64:
+    MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
+    break;
+  case llvm::Triple::x86:
+    MultiarchIncludeDirs = X86MultiarchIncludeDirs;
+    break;
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+    MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
+    break;
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+      MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
+    else
+      MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
+    break;
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumbeb:
+    if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+      MultiarchIncludeDirs = ARMEBHFMultiarchIncludeDirs;
+    else
+      MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs;
+    break;
+  case llvm::Triple::mips:
+    MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
+    break;
+  case llvm::Triple::mipsel:
+    MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
+    break;
+  case llvm::Triple::mips64:
+    MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
+    break;
+  case llvm::Triple::mips64el:
+    MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
+    break;
+  case llvm::Triple::ppc:
+    MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
+    break;
+  case llvm::Triple::ppc64:
+    MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
+    break;
+  case llvm::Triple::ppc64le:
+    MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
+    break;
+  case llvm::Triple::sparc:
+    MultiarchIncludeDirs = SparcMultiarchIncludeDirs;
+    break;
+  case llvm::Triple::sparcv9:
+    MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs;
+    break;
+  case llvm::Triple::systemz:
+    MultiarchIncludeDirs = SYSTEMZMultiarchIncludeDirs;
+    break;
+  default:
+    break;
+  }
+  for (StringRef Dir : MultiarchIncludeDirs) {
+    if (D.getVFS().exists(SysRoot + Dir)) {
+      addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);
+      break;
+    }
+  }
+
+  if (getTriple().getOS() == llvm::Triple::RTEMS)
+    return;
+
+  // Add an include of '/include' directly. This isn't provided by default by
+  // system GCCs, but is often used with cross-compiling GCCs, and harmless to
+  // add even when Clang is acting as-if it were a system compiler.
+  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
+
+  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
+}
+
+static std::string DetectLibcxxIncludePath(StringRef base) {
+  std::error_code EC;
+  int MaxVersion = 0;
+  std::string MaxVersionString = "";
+  for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE;
+       LI = LI.increment(EC)) {
+    StringRef VersionText = llvm::sys::path::filename(LI->path());
+    int Version;
+    if (VersionText[0] == 'v' &&
+        !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
+      if (Version > MaxVersion) {
+        MaxVersion = Version;
+        MaxVersionString = VersionText;
+      }
+    }
+  }
+  return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
+}
+
+std::string Linux::findLibCxxIncludePath() const {
+  const std::string LibCXXIncludePathCandidates[] = {
+      DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"),
+      // If this is a development, non-installed, clang, libcxx will
+      // not be found at ../include/c++ but it likely to be found at
+      // one of the following two locations:
+      DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/local/include/c++"),
+      DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/include/c++") };
+  for (const auto &IncludePath : LibCXXIncludePathCandidates) {
+    if (IncludePath.empty() || !getVFS().exists(IncludePath))
+      continue;
+    // Use the first candidate that exists.
+    return IncludePath;
+  }
+  return "";
+}
+
+void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+                                     llvm::opt::ArgStringList &CC1Args) const {
+  // We need a detected GCC installation on Linux to provide libstdc++'s
+  // headers.
+  if (!GCCInstallation.isValid())
+    return;
+
+  // By default, look for the C++ headers in an include directory adjacent to
+  // the lib directory of the GCC installation. Note that this is expect to be
+  // equivalent to '/usr/include/c++/X.Y' in almost all cases.
+  StringRef LibDir = GCCInstallation.getParentLibPath();
+  StringRef InstallDir = GCCInstallation.getInstallPath();
+  StringRef TripleStr = GCCInstallation.getTriple().str();
+  const Multilib &Multilib = GCCInstallation.getMultilib();
+  const std::string GCCMultiarchTriple = getMultiarchTriple(
+      getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
+  const std::string TargetMultiarchTriple =
+      getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
+  const GCCVersion &Version = GCCInstallation.getVersion();
+
+  // The primary search for libstdc++ supports multiarch variants.
+  if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
+                               "/c++/" + Version.Text, TripleStr,
+                               GCCMultiarchTriple, TargetMultiarchTriple,
+                               Multilib.includeSuffix(), DriverArgs, CC1Args))
+    return;
+
+  // Otherwise, fall back on a bunch of options which don't use multiarch
+  // layouts for simplicity.
+  const std::string LibStdCXXIncludePathCandidates[] = {
+      // Gentoo is weird and places its headers inside the GCC install,
+      // so if the first attempt to find the headers fails, try these patterns.
+      InstallDir.str() + "/include/g++-v" + Version.Text,
+      InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
+          Version.MinorStr,
+      InstallDir.str() + "/include/g++-v" + Version.MajorStr,
+      // Android standalone toolchain has C++ headers in yet another place.
+      LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
+      // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
+      // without a subdirectory corresponding to the gcc version.
+      LibDir.str() + "/../include/c++",
+  };
+
+  for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
+    if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
+                                 /*GCCMultiarchTriple*/ "",
+                                 /*TargetMultiarchTriple*/ "",
+                                 Multilib.includeSuffix(), DriverArgs, CC1Args))
+      break;
+  }
+}
+
+void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs,
+                               ArgStringList &CC1Args) const {
+  CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
+}
+
+void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
+                                ArgStringList &CC1Args) const {
+  if (GCCInstallation.isValid()) {
+    CC1Args.push_back("-isystem");
+    CC1Args.push_back(DriverArgs.MakeArgString(
+        GCCInstallation.getParentLibPath() + "/../" +
+        GCCInstallation.getTriple().str() + "/include"));
+  }
+}
+
+bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
+
+SanitizerMask Linux::getSupportedSanitizers() const {
+  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
+  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
+  const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
+                        getTriple().getArch() == llvm::Triple::mips64el;
+  const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 ||
+                           getTriple().getArch() == llvm::Triple::ppc64le;
+  const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
+                         getTriple().getArch() == llvm::Triple::aarch64_be;
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::Address;
+  Res |= SanitizerKind::KernelAddress;
+  Res |= SanitizerKind::Vptr;
+  Res |= SanitizerKind::SafeStack;
+  if (IsX86_64 || IsMIPS64 || IsAArch64)
+    Res |= SanitizerKind::DataFlow;
+  if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86)
+    Res |= SanitizerKind::Leak;
+  if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64)
+    Res |= SanitizerKind::Thread;
+  if (IsX86_64 || IsMIPS64 || IsPowerPC64 || IsAArch64)
+    Res |= SanitizerKind::Memory;
+  if (IsX86_64 || IsMIPS64)
+    Res |= SanitizerKind::Efficiency;
+  if (IsX86 || IsX86_64) {
+    Res |= SanitizerKind::Function;
+  }
+  return Res;
+}
+
+void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
+                             llvm::opt::ArgStringList &CmdArgs) const {
+  if (!needsProfileRT(Args)) return;
+
+  // Add linker option -u__llvm_runtime_variable to cause runtime
+  // initialization module to be linked in.
+  if (!Args.hasArg(options::OPT_coverage))
+    CmdArgs.push_back(Args.MakeArgString(
+        Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
+  ToolChain::addProfileRTLibs(Args, CmdArgs);
+}
diff --git a/lib/Driver/ToolChains/Linux.h b/lib/Driver/ToolChains/Linux.h
new file mode 100644
index 0000000..9778c18
--- /dev/null
+++ b/lib/Driver/ToolChains/Linux.h
@@ -0,0 +1,57 @@
+//===--- Linux.h - Linux ToolChain Implementations --------------*- 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_LIB_DRIVER_TOOLCHAINS_LINUX_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LINUX_H
+
+#include "Gnu.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
+public:
+  Linux(const Driver &D, const llvm::Triple &Triple,
+        const llvm::opt::ArgList &Args);
+
+  bool HasNativeLLVMSupport() const override;
+
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  std::string findLibCxxIncludePath() const override;
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const override;
+  void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                           llvm::opt::ArgStringList &CC1Args) const override;
+  bool isPIEDefault() const override;
+  SanitizerMask getSupportedSanitizers() const override;
+  void addProfileRTLibs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const override;
+  virtual std::string computeSysRoot() const;
+
+  virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const;
+
+  std::vector<std::string> ExtraOpts;
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LINUX_H
diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp
new file mode 100644
index 0000000..7996627
--- /dev/null
+++ b/lib/Driver/ToolChains/MSVC.cpp
@@ -0,0 +1,1233 @@
+//===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Darwin.h"
+#include "MSVC.h"
+#include "CommonArgs.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Version.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include <cstdio>
+
+// Include the necessary headers to interface with the Windows registry and
+// environment.
+#if defined(LLVM_ON_WIN32)
+#define USE_WIN32
+#endif
+
+#ifdef USE_WIN32
+  #define WIN32_LEAN_AND_MEAN
+  #define NOGDI
+  #ifndef NOMINMAX
+    #define NOMINMAX
+  #endif
+  #include <windows.h>
+#endif
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+// Try to find Exe from a Visual Studio distribution.  This first tries to find
+// an installed copy of Visual Studio and, failing that, looks in the PATH,
+// making sure that whatever executable that's found is not a same-named exe
+// from clang itself to prevent clang from falling back to itself.
+static std::string FindVisualStudioExecutable(const ToolChain &TC,
+                                              const char *Exe,
+                                              const char *ClangProgramPath) {
+  const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
+  std::string visualStudioBinDir;
+  if (MSVC.getVisualStudioBinariesFolder(ClangProgramPath,
+                                         visualStudioBinDir)) {
+    SmallString<128> FilePath(visualStudioBinDir);
+    llvm::sys::path::append(FilePath, Exe);
+    if (llvm::sys::fs::can_execute(FilePath.c_str()))
+      return FilePath.str();
+  }
+
+  return Exe;
+}
+
+void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                        const InputInfo &Output,
+                                        const InputInfoList &Inputs,
+                                        const ArgList &Args,
+                                        const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+  const ToolChain &TC = getToolChain();
+
+  assert((Output.isFilename() || Output.isNothing()) && "invalid output");
+  if (Output.isFilename())
+    CmdArgs.push_back(
+        Args.MakeArgString(std::string("-out:") + Output.getFilename()));
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
+      !C.getDriver().IsCLMode())
+    CmdArgs.push_back("-defaultlib:libcmt");
+
+  if (!llvm::sys::Process::GetEnv("LIB")) {
+    // If the VC environment hasn't been configured (perhaps because the user
+    // did not run vcvarsall), try to build a consistent link environment.  If
+    // the environment variable is set however, assume the user knows what
+    // they're doing.
+    std::string VisualStudioDir;
+    const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
+    if (MSVC.getVisualStudioInstallDir(VisualStudioDir)) {
+      SmallString<128> LibDir(VisualStudioDir);
+      llvm::sys::path::append(LibDir, "VC", "lib");
+      switch (MSVC.getArch()) {
+      case llvm::Triple::x86:
+        // x86 just puts the libraries directly in lib
+        break;
+      case llvm::Triple::x86_64:
+        llvm::sys::path::append(LibDir, "amd64");
+        break;
+      case llvm::Triple::arm:
+        llvm::sys::path::append(LibDir, "arm");
+        break;
+      default:
+        break;
+      }
+      CmdArgs.push_back(
+          Args.MakeArgString(std::string("-libpath:") + LibDir.c_str()));
+
+      if (MSVC.useUniversalCRT(VisualStudioDir)) {
+        std::string UniversalCRTLibPath;
+        if (MSVC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
+          CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
+                                               UniversalCRTLibPath));
+      }
+    }
+
+    std::string WindowsSdkLibPath;
+    if (MSVC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
+      CmdArgs.push_back(
+          Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
+  }
+
+  if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
+    for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
+      CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
+
+  CmdArgs.push_back("-nologo");
+
+  if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
+                  options::OPT__SLASH_Zd))
+    CmdArgs.push_back("-debug");
+
+  bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
+                         options::OPT_shared);
+  if (DLL) {
+    CmdArgs.push_back(Args.MakeArgString("-dll"));
+
+    SmallString<128> ImplibName(Output.getFilename());
+    llvm::sys::path::replace_extension(ImplibName, "lib");
+    CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
+  }
+
+  if (TC.getSanitizerArgs().needsAsanRt()) {
+    CmdArgs.push_back(Args.MakeArgString("-debug"));
+    CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
+    if (TC.getSanitizerArgs().needsSharedAsanRt() ||
+        Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
+      for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
+        CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
+      // Make sure the dynamic runtime thunk is not optimized out at link time
+      // to ensure proper SEH handling.
+      CmdArgs.push_back(Args.MakeArgString(
+          TC.getArch() == llvm::Triple::x86
+              ? "-include:___asan_seh_interceptor"
+              : "-include:__asan_seh_interceptor"));
+      // Make sure the linker consider all object files from the dynamic runtime
+      // thunk.
+      CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
+          TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
+    } else if (DLL) {
+      CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
+    } else {
+      for (const auto &Lib : {"asan", "asan_cxx"}) {
+        CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
+        // Make sure the linker consider all object files from the static lib.
+        // This is necessary because instrumented dlls need access to all the
+        // interface exported by the static lib in the main executable.
+        CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
+            TC.getCompilerRT(Args, Lib)));
+      }
+    }
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
+
+  if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
+                   options::OPT_fno_openmp, false)) {
+    CmdArgs.push_back("-nodefaultlib:vcomp.lib");
+    CmdArgs.push_back("-nodefaultlib:vcompd.lib");
+    CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
+                                         TC.getDriver().Dir + "/../lib"));
+    switch (TC.getDriver().getOpenMPRuntime(Args)) {
+    case Driver::OMPRT_OMP:
+      CmdArgs.push_back("-defaultlib:libomp.lib");
+      break;
+    case Driver::OMPRT_IOMP5:
+      CmdArgs.push_back("-defaultlib:libiomp5md.lib");
+      break;
+    case Driver::OMPRT_GOMP:
+      break;
+    case Driver::OMPRT_Unknown:
+      // Already diagnosed.
+      break;
+    }
+  }
+
+  // Add compiler-rt lib in case if it was explicitly
+  // specified as an argument for --rtlib option.
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+    AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
+  }
+
+  // Add filenames, libraries, and other linker inputs.
+  for (const auto &Input : Inputs) {
+    if (Input.isFilename()) {
+      CmdArgs.push_back(Input.getFilename());
+      continue;
+    }
+
+    const Arg &A = Input.getInputArg();
+
+    // Render -l options differently for the MSVC linker.
+    if (A.getOption().matches(options::OPT_l)) {
+      StringRef Lib = A.getValue();
+      const char *LinkLibArg;
+      if (Lib.endswith(".lib"))
+        LinkLibArg = Args.MakeArgString(Lib);
+      else
+        LinkLibArg = Args.MakeArgString(Lib + ".lib");
+      CmdArgs.push_back(LinkLibArg);
+      continue;
+    }
+
+    // Otherwise, this is some other kind of linker input option like -Wl, -z,
+    // or -L. Render it, even if MSVC doesn't understand it.
+    A.renderAsInput(Args, CmdArgs);
+  }
+
+  TC.addProfileRTLibs(Args, CmdArgs);
+
+  // We need to special case some linker paths.  In the case of lld, we need to
+  // translate 'lld' into 'lld-link', and in the case of the regular msvc
+  // linker, we need to use a special search algorithm.
+  llvm::SmallString<128> linkPath;
+  StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
+  if (Linker.equals_lower("lld"))
+    Linker = "lld-link";
+
+  if (Linker.equals_lower("link")) {
+    // If we're using the MSVC linker, it's not sufficient to just use link
+    // from the program PATH, because other environments like GnuWin32 install
+    // their own link.exe which may come first.
+    linkPath = FindVisualStudioExecutable(TC, "link.exe",
+                                          C.getDriver().getClangProgramPath());
+  } else {
+    linkPath = Linker;
+    llvm::sys::path::replace_extension(linkPath, "exe");
+    linkPath = TC.GetProgramPath(linkPath.c_str());
+  }
+
+  const char *Exec = Args.MakeArgString(linkPath);
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
+                                          const InputInfo &Output,
+                                          const InputInfoList &Inputs,
+                                          const ArgList &Args,
+                                          const char *LinkingOutput) const {
+  C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
+}
+
+std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
+    Compilation &C, const JobAction &JA, const InputInfo &Output,
+    const InputInfoList &Inputs, const ArgList &Args,
+    const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+  CmdArgs.push_back("/nologo");
+  CmdArgs.push_back("/c");  // Compile only.
+  CmdArgs.push_back("/W0"); // No warnings.
+
+  // The goal is to be able to invoke this tool correctly based on
+  // any flag accepted by clang-cl.
+
+  // These are spelled the same way in clang and cl.exe,.
+  Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
+
+  // Optimization level.
+  if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
+    CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
+                                                                      : "/Oi-");
+  if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
+    if (A->getOption().getID() == options::OPT_O0) {
+      CmdArgs.push_back("/Od");
+    } else {
+      CmdArgs.push_back("/Og");
+
+      StringRef OptLevel = A->getValue();
+      if (OptLevel == "s" || OptLevel == "z")
+        CmdArgs.push_back("/Os");
+      else
+        CmdArgs.push_back("/Ot");
+
+      CmdArgs.push_back("/Ob2");
+    }
+  }
+  if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
+                               options::OPT_fno_omit_frame_pointer))
+    CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
+                          ? "/Oy"
+                          : "/Oy-");
+  if (!Args.hasArg(options::OPT_fwritable_strings))
+    CmdArgs.push_back("/GF");
+
+  // Flags for which clang-cl has an alias.
+  // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
+
+  if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
+                   /*default=*/false))
+    CmdArgs.push_back("/GR-");
+
+  if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
+                   /*default=*/false))
+    CmdArgs.push_back("/GS-");
+
+  if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
+                               options::OPT_fno_function_sections))
+    CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
+                          ? "/Gy"
+                          : "/Gy-");
+  if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
+                               options::OPT_fno_data_sections))
+    CmdArgs.push_back(
+        A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
+  if (Args.hasArg(options::OPT_fsyntax_only))
+    CmdArgs.push_back("/Zs");
+  if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
+                  options::OPT__SLASH_Z7))
+    CmdArgs.push_back("/Z7");
+
+  std::vector<std::string> Includes =
+      Args.getAllArgValues(options::OPT_include);
+  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_GX);
+  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
+  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
+  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
+
+  // 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,
+                               options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
+    A->render(Args, CmdArgs);
+
+  // Use MSVC's default threadsafe statics behaviour unless there was a flag.
+  if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
+                               options::OPT_fno_threadsafe_statics)) {
+    CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
+                          ? "/Zc:threadSafeInit"
+                          : "/Zc:threadSafeInit-");
+  }
+
+  // Pass through all unknown arguments so that the fallback command can see
+  // them too.
+  Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
+
+  // Input filename.
+  assert(Inputs.size() == 1);
+  const InputInfo &II = Inputs[0];
+  assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
+  CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
+  if (II.isFilename())
+    CmdArgs.push_back(II.getFilename());
+  else
+    II.getInputArg().renderAsInput(Args, CmdArgs);
+
+  // Output filename.
+  assert(Output.getType() == types::TY_Object);
+  const char *Fo =
+      Args.MakeArgString(std::string("/Fo") + Output.getFilename());
+  CmdArgs.push_back(Fo);
+
+  const Driver &D = getToolChain().getDriver();
+  std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe",
+                                                D.getClangProgramPath());
+  return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
+                                    CmdArgs, Inputs);
+}
+
+MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
+                             const ArgList &Args)
+    : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
+}
+
+Tool *MSVCToolChain::buildLinker() const {
+  return new tools::visualstudio::Linker(*this);
+}
+
+Tool *MSVCToolChain::buildAssembler() const {
+  if (getTriple().isOSBinFormatMachO())
+    return new tools::darwin::Assembler(*this);
+  getDriver().Diag(clang::diag::err_no_external_assembler);
+  return nullptr;
+}
+
+bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
+  return true;
+}
+
+bool MSVCToolChain::IsUnwindTablesDefault() const {
+  // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
+  // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
+  // how to generate them yet.
+
+  // Don't emit unwind tables by default for MachO targets.
+  if (getTriple().isOSBinFormatMachO())
+    return false;
+
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool MSVCToolChain::isPICDefault() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool MSVCToolChain::isPIEDefault() const {
+  return false;
+}
+
+bool MSVCToolChain::isPICDefaultForced() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
+                                       ArgStringList &CC1Args) const {
+  CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
+}
+
+void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
+  CudaInstallation.print(OS);
+}
+
+#ifdef USE_WIN32
+static bool readFullStringValue(HKEY hkey, const char *valueName,
+                                std::string &value) {
+  std::wstring WideValueName;
+  if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
+    return false;
+
+  DWORD result = 0;
+  DWORD valueSize = 0;
+  DWORD type = 0;
+  // First just query for the required size.
+  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
+                            &valueSize);
+  if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
+    return false;
+  std::vector<BYTE> buffer(valueSize);
+  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
+                            &valueSize);
+  if (result == ERROR_SUCCESS) {
+    std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
+                           valueSize / sizeof(wchar_t));
+    if (valueSize && WideValue.back() == L'\0') {
+      WideValue.pop_back();
+    }
+    // The destination buffer must be empty as an invariant of the conversion
+    // function; but this function is sometimes called in a loop that passes in
+    // the same buffer, however. Simply clear it out so we can overwrite it.
+    value.clear();
+    return llvm::convertWideToUTF8(WideValue, value);
+  }
+  return false;
+}
+#endif
+
+/// \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.
+/// $VERSION in the key path is a placeholder for the version number,
+/// causing the highest value path to be searched for and used.
+/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
+/// There can be additional characters in the component.  Only the numeric
+/// characters are compared.  This function only searches HKLM.
+static bool getSystemRegistryString(const char *keyPath, const char *valueName,
+                                    std::string &value, std::string *phValue) {
+#ifndef USE_WIN32
+  return false;
+#else
+  HKEY hRootKey = HKEY_LOCAL_MACHINE;
+  HKEY hKey = NULL;
+  long lResult;
+  bool returnValue = false;
+
+  const char *placeHolder = strstr(keyPath, "$VERSION");
+  std::string bestName;
+  // If we have a $VERSION placeholder, do the highest-version search.
+  if (placeHolder) {
+    const char *keyEnd = placeHolder - 1;
+    const char *nextKey = placeHolder;
+    // Find end of previous key.
+    while ((keyEnd > keyPath) && (*keyEnd != '\\'))
+      keyEnd--;
+    // Find end of key containing $VERSION.
+    while (*nextKey && (*nextKey != '\\'))
+      nextKey++;
+    size_t partialKeyLength = keyEnd - keyPath;
+    char partialKey[256];
+    if (partialKeyLength >= sizeof(partialKey))
+      partialKeyLength = sizeof(partialKey) - 1;
+    strncpy(partialKey, keyPath, partialKeyLength);
+    partialKey[partialKeyLength] = '\0';
+    HKEY hTopKey = NULL;
+    lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
+                            &hTopKey);
+    if (lResult == ERROR_SUCCESS) {
+      char keyName[256];
+      double bestValue = 0.0;
+      DWORD index, size = sizeof(keyName) - 1;
+      for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
+                                    NULL, NULL) == ERROR_SUCCESS;
+           index++) {
+        const char *sp = keyName;
+        while (*sp && !isDigit(*sp))
+          sp++;
+        if (!*sp)
+          continue;
+        const char *ep = sp + 1;
+        while (*ep && (isDigit(*ep) || (*ep == '.')))
+          ep++;
+        char numBuf[32];
+        strncpy(numBuf, sp, sizeof(numBuf) - 1);
+        numBuf[sizeof(numBuf) - 1] = '\0';
+        double dvalue = strtod(numBuf, NULL);
+        if (dvalue > bestValue) {
+          // Test that InstallDir is indeed there before keeping this index.
+          // Open the chosen key path remainder.
+          bestName = keyName;
+          // Append rest of key.
+          bestName.append(nextKey);
+          lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
+                                  KEY_READ | KEY_WOW64_32KEY, &hKey);
+          if (lResult == ERROR_SUCCESS) {
+            if (readFullStringValue(hKey, valueName, value)) {
+              bestValue = dvalue;
+              if (phValue)
+                *phValue = bestName;
+              returnValue = true;
+            }
+            RegCloseKey(hKey);
+          }
+        }
+        size = sizeof(keyName) - 1;
+      }
+      RegCloseKey(hTopKey);
+    }
+  } else {
+    lResult =
+        RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
+    if (lResult == ERROR_SUCCESS) {
+      if (readFullStringValue(hKey, valueName, value))
+        returnValue = true;
+      if (phValue)
+        phValue->clear();
+      RegCloseKey(hKey);
+    }
+  }
+  return returnValue;
+#endif // USE_WIN32
+}
+
+// Convert LLVM's ArchType
+// to the corresponding name of Windows SDK libraries subfolder
+static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
+  switch (Arch) {
+  case llvm::Triple::x86:
+    return "x86";
+  case llvm::Triple::x86_64:
+    return "x64";
+  case llvm::Triple::arm:
+    return "arm";
+  default:
+    return "";
+  }
+}
+
+// Find the most recent version of Universal CRT or Windows 10 SDK.
+// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
+// directory by name and uses the last one of the list.
+// So we compare entry names lexicographically to find the greatest one.
+static bool getWindows10SDKVersion(const std::string &SDKPath,
+                                   std::string &SDKVersion) {
+  SDKVersion.clear();
+
+  std::error_code EC;
+  llvm::SmallString<128> IncludePath(SDKPath);
+  llvm::sys::path::append(IncludePath, "Include");
+  for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
+       DirIt != DirEnd && !EC; DirIt.increment(EC)) {
+    if (!llvm::sys::fs::is_directory(DirIt->path()))
+      continue;
+    StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
+    // If WDK is installed, there could be subfolders like "wdf" in the
+    // "Include" directory.
+    // Allow only directories which names start with "10.".
+    if (!CandidateName.startswith("10."))
+      continue;
+    if (CandidateName > SDKVersion)
+      SDKVersion = CandidateName;
+  }
+
+  return !SDKVersion.empty();
+}
+
+/// \brief Get Windows SDK installation directory.
+bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
+                                     std::string &WindowsSDKIncludeVersion,
+                                     std::string &WindowsSDKLibVersion) const {
+  std::string RegistrySDKVersion;
+  // Try the Windows registry.
+  if (!getSystemRegistryString(
+          "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
+          "InstallationFolder", Path, &RegistrySDKVersion))
+    return false;
+  if (Path.empty() || RegistrySDKVersion.empty())
+    return false;
+
+  WindowsSDKIncludeVersion.clear();
+  WindowsSDKLibVersion.clear();
+  Major = 0;
+  std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
+  if (Major <= 7)
+    return true;
+  if (Major == 8) {
+    // Windows SDK 8.x installs libraries in a folder whose names depend on the
+    // version of the OS you're targeting.  By default choose the newest, which
+    // usually corresponds to the version of the OS you've installed the SDK on.
+    const char *Tests[] = {"winv6.3", "win8", "win7"};
+    for (const char *Test : Tests) {
+      llvm::SmallString<128> TestPath(Path);
+      llvm::sys::path::append(TestPath, "Lib", Test);
+      if (llvm::sys::fs::exists(TestPath.c_str())) {
+        WindowsSDKLibVersion = Test;
+        break;
+      }
+    }
+    return !WindowsSDKLibVersion.empty();
+  }
+  if (Major == 10) {
+    if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
+      return false;
+    WindowsSDKLibVersion = WindowsSDKIncludeVersion;
+    return true;
+  }
+  // Unsupported SDK version
+  return false;
+}
+
+// Gets the library path required to link against the Windows SDK.
+bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
+  std::string sdkPath;
+  int sdkMajor = 0;
+  std::string windowsSDKIncludeVersion;
+  std::string windowsSDKLibVersion;
+
+  path.clear();
+  if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
+                        windowsSDKLibVersion))
+    return false;
+
+  llvm::SmallString<128> libPath(sdkPath);
+  llvm::sys::path::append(libPath, "Lib");
+  if (sdkMajor <= 7) {
+    switch (getArch()) {
+    // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
+    case llvm::Triple::x86:
+      break;
+    case llvm::Triple::x86_64:
+      llvm::sys::path::append(libPath, "x64");
+      break;
+    case llvm::Triple::arm:
+      // It is not necessary to link against Windows SDK 7.x when targeting ARM.
+      return false;
+    default:
+      return false;
+    }
+  } else {
+    const StringRef archName = getWindowsSDKArch(getArch());
+    if (archName.empty())
+      return false;
+    llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
+  }
+
+  path = libPath.str();
+  return true;
+}
+
+// Check if the Include path of a specified version of Visual Studio contains
+// specific header files. If not, they are probably shipped with Universal CRT.
+bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
+    std::string &VisualStudioDir) const {
+  llvm::SmallString<128> TestPath(VisualStudioDir);
+  llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
+
+  return !llvm::sys::fs::exists(TestPath);
+}
+
+bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
+                                          std::string &UCRTVersion) const {
+  // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
+  // for the specific key "KitsRoot10". So do we.
+  if (!getSystemRegistryString(
+          "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
+          Path, nullptr))
+    return false;
+
+  return getWindows10SDKVersion(Path, UCRTVersion);
+}
+
+bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
+  std::string UniversalCRTSdkPath;
+  std::string UCRTVersion;
+
+  Path.clear();
+  if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
+    return false;
+
+  StringRef ArchName = getWindowsSDKArch(getArch());
+  if (ArchName.empty())
+    return false;
+
+  llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
+  llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
+
+  Path = LibPath.str();
+  return true;
+}
+
+// Get the location to use for Visual Studio binaries.  The location priority
+// is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
+// system (as reported by the registry).
+bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
+                                                  std::string &path) const {
+  path.clear();
+
+  SmallString<128> BinDir;
+
+  // First check the environment variables that vsvars32.bat sets.
+  llvm::Optional<std::string> VcInstallDir =
+      llvm::sys::Process::GetEnv("VCINSTALLDIR");
+  if (VcInstallDir.hasValue()) {
+    BinDir = VcInstallDir.getValue();
+    llvm::sys::path::append(BinDir, "bin");
+  } else {
+    // Next walk the PATH, trying to find a cl.exe in the path.  If we find one,
+    // use that.  However, make sure it's not clang's cl.exe.
+    llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
+    if (OptPath.hasValue()) {
+      const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
+      SmallVector<StringRef, 8> PathSegments;
+      llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
+
+      for (StringRef PathSegment : PathSegments) {
+        if (PathSegment.empty())
+          continue;
+
+        SmallString<128> FilePath(PathSegment);
+        llvm::sys::path::append(FilePath, "cl.exe");
+        // Checking if cl.exe exists is a small optimization over calling
+        // can_execute, which really only checks for existence but will also do
+        // extra checks for cl.exe.exe.  These add up when walking a long path.
+        if (llvm::sys::fs::exists(FilePath.c_str()) &&
+            !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
+          // If we found it on the PATH, use it exactly as is with no
+          // modifications.
+          path = PathSegment;
+          return true;
+        }
+      }
+    }
+
+    std::string installDir;
+    // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
+    // registry then we have no choice but to fail.
+    if (!getVisualStudioInstallDir(installDir))
+      return false;
+
+    // Regardless of what binary we're ultimately trying to find, we make sure
+    // that this is a Visual Studio directory by checking for cl.exe.  We use
+    // cl.exe instead of other binaries like link.exe because programs such as
+    // GnuWin32 also have a utility called link.exe, so cl.exe is the least
+    // ambiguous.
+    BinDir = installDir;
+    llvm::sys::path::append(BinDir, "VC", "bin");
+    SmallString<128> ClPath(BinDir);
+    llvm::sys::path::append(ClPath, "cl.exe");
+
+    if (!llvm::sys::fs::can_execute(ClPath.c_str()))
+      return false;
+  }
+
+  if (BinDir.empty())
+    return false;
+
+  switch (getArch()) {
+  case llvm::Triple::x86:
+    break;
+  case llvm::Triple::x86_64:
+    llvm::sys::path::append(BinDir, "amd64");
+    break;
+  case llvm::Triple::arm:
+    llvm::sys::path::append(BinDir, "arm");
+    break;
+  default:
+    // Whatever this is, Visual Studio doesn't have a toolchain for it.
+    return false;
+  }
+  path = BinDir.str();
+  return true;
+}
+
+VersionTuple MSVCToolChain::getMSVCVersionFromTriple() const {
+  unsigned Major, Minor, Micro;
+  getTriple().getEnvironmentVersion(Major, Minor, Micro);
+  if (Major || Minor || Micro)
+    return VersionTuple(Major, Minor, Micro);
+  return VersionTuple();
+}
+
+VersionTuple MSVCToolChain::getMSVCVersionFromExe() const {
+  VersionTuple Version;
+#ifdef USE_WIN32
+  std::string BinPath;
+  if (!getVisualStudioBinariesFolder("", BinPath))
+    return Version;
+  SmallString<128> ClExe(BinPath);
+  llvm::sys::path::append(ClExe, "cl.exe");
+
+  std::wstring ClExeWide;
+  if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
+    return Version;
+
+  const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
+                                                      nullptr);
+  if (VersionSize == 0)
+    return Version;
+
+  SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
+  if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
+                             VersionBlock.data()))
+    return Version;
+
+  VS_FIXEDFILEINFO *FileInfo = nullptr;
+  UINT FileInfoSize = 0;
+  if (!::VerQueryValueW(VersionBlock.data(), L"\\",
+                        reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
+      FileInfoSize < sizeof(*FileInfo))
+    return Version;
+
+  const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
+  const unsigned Minor = (FileInfo->dwFileVersionMS      ) & 0xFFFF;
+  const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
+
+  Version = VersionTuple(Major, Minor, Micro);
+#endif
+  return Version;
+}
+
+// Get Visual Studio installation directory.
+bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
+  // First check the environment variables that vsvars32.bat sets.
+  if (llvm::Optional<std::string> VcInstallDir =
+          llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
+    path = std::move(*VcInstallDir);
+    path = path.substr(0, path.find("\\VC"));
+    return true;
+  }
+
+  std::string vsIDEInstallDir;
+  std::string vsExpressIDEInstallDir;
+  // Then try the windows registry.
+  bool hasVCDir =
+      getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
+                              "InstallDir", vsIDEInstallDir, nullptr);
+  if (hasVCDir && !vsIDEInstallDir.empty()) {
+    path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
+    return true;
+  }
+
+  bool hasVCExpressDir =
+      getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
+                              "InstallDir", vsExpressIDEInstallDir, nullptr);
+  if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
+    path = vsExpressIDEInstallDir.substr(
+        0, vsIDEInstallDir.find("\\Common7\\IDE"));
+    return true;
+  }
+
+  // Try the environment.
+  std::string vcomntools;
+  if (llvm::Optional<std::string> vs120comntools =
+          llvm::sys::Process::GetEnv("VS120COMNTOOLS"))
+    vcomntools = std::move(*vs120comntools);
+  else if (llvm::Optional<std::string> vs100comntools =
+               llvm::sys::Process::GetEnv("VS100COMNTOOLS"))
+    vcomntools = std::move(*vs100comntools);
+  else if (llvm::Optional<std::string> vs90comntools =
+               llvm::sys::Process::GetEnv("VS90COMNTOOLS"))
+    vcomntools = std::move(*vs90comntools);
+  else if (llvm::Optional<std::string> vs80comntools =
+               llvm::sys::Process::GetEnv("VS80COMNTOOLS"))
+    vcomntools = std::move(*vs80comntools);
+
+  // Find any version we can.
+  if (!vcomntools.empty()) {
+    size_t p = vcomntools.find("\\Common7\\Tools");
+    if (p != std::string::npos)
+      vcomntools.resize(p);
+    path = std::move(vcomntools);
+    return true;
+  }
+  return false;
+}
+
+void MSVCToolChain::AddSystemIncludeWithSubfolder(
+    const ArgList &DriverArgs, ArgStringList &CC1Args,
+    const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
+    const Twine &subfolder3) const {
+  llvm::SmallString<128> path(folder);
+  llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
+  addSystemInclude(DriverArgs, CC1Args, path);
+}
+
+void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                              ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nostdinc))
+    return;
+
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
+                                  "include");
+  }
+
+  // Add %INCLUDE%-like directories from the -imsvc flag.
+  for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
+    addSystemInclude(DriverArgs, CC1Args, Path);
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
+  // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
+  if (llvm::Optional<std::string> cl_include_dir =
+          llvm::sys::Process::GetEnv("INCLUDE")) {
+    SmallVector<StringRef, 8> Dirs;
+    StringRef(*cl_include_dir)
+        .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+    for (StringRef Dir : Dirs)
+      addSystemInclude(DriverArgs, CC1Args, Dir);
+    if (!Dirs.empty())
+      return;
+  }
+
+  std::string VSDir;
+
+  // When built with access to the proper Windows APIs, try to actually find
+  // the correct include paths first.
+  if (getVisualStudioInstallDir(VSDir)) {
+    AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
+
+    if (useUniversalCRT(VSDir)) {
+      std::string UniversalCRTSdkPath;
+      std::string UCRTVersion;
+      if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
+        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
+                                      "Include", UCRTVersion, "ucrt");
+      }
+    }
+
+    std::string WindowsSDKDir;
+    int major;
+    std::string windowsSDKIncludeVersion;
+    std::string windowsSDKLibVersion;
+    if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
+                         windowsSDKLibVersion)) {
+      if (major >= 8) {
+        // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
+        // Anyway, llvm::sys::path::append is able to manage it.
+        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
+                                      "include", windowsSDKIncludeVersion,
+                                      "shared");
+        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
+                                      "include", windowsSDKIncludeVersion,
+                                      "um");
+        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
+                                      "include", windowsSDKIncludeVersion,
+                                      "winrt");
+      } else {
+        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
+                                      "include");
+      }
+    } else {
+      addSystemInclude(DriverArgs, CC1Args, VSDir);
+    }
+    return;
+  }
+
+#if defined(LLVM_ON_WIN32)
+  // 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",
+    "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
+    "C:/Program Files/Microsoft Visual Studio 8/VC/include",
+    "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
+  };
+  addSystemIncludes(DriverArgs, CC1Args, Paths);
+#endif
+}
+
+void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+                                                 ArgStringList &CC1Args) const {
+  // FIXME: There should probably be logic here to find libc++ on Windows.
+}
+
+VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
+                                               const ArgList &Args) const {
+  bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
+  VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
+  if (MSVT.empty()) MSVT = getMSVCVersionFromTriple();
+  if (MSVT.empty() && IsWindowsMSVC) MSVT = getMSVCVersionFromExe();
+  if (MSVT.empty() &&
+      Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
+                   IsWindowsMSVC)) {
+    // -fms-compatibility-version=18.00 is default.
+    // FIXME: Consider bumping this to 19 (MSVC2015) soon.
+    MSVT = VersionTuple(18);
+  }
+  return MSVT;
+}
+
+std::string
+MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
+                                           types::ID InputType) const {
+  // The MSVC version doesn't care about the architecture, even though it
+  // may look at the triple internally.
+  VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
+  MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
+                      MSVT.getSubminor().getValueOr(0));
+
+  // For the rest of the triple, however, a computed architecture name may
+  // be needed.
+  llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
+  if (Triple.getEnvironment() == llvm::Triple::MSVC) {
+    StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
+    if (ObjFmt.empty())
+      Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
+    else
+      Triple.setEnvironmentName(
+          (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
+  }
+  return Triple.getTriple();
+}
+
+SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::Address;
+  return Res;
+}
+
+static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
+                            bool SupportsForcingFramePointer,
+                            const char *ExpandChar, const OptTable &Opts) {
+  assert(A->getOption().matches(options::OPT__SLASH_O));
+
+  StringRef OptStr = A->getValue();
+  for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
+    const char &OptChar = *(OptStr.data() + I);
+    switch (OptChar) {
+    default:
+      break;
+    case '1':
+    case '2':
+    case 'x':
+    case 'd':
+      if (&OptChar == ExpandChar) {
+        if (OptChar == 'd') {
+          DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
+        } else {
+          if (OptChar == '1') {
+            DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
+          } else if (OptChar == '2' || OptChar == 'x') {
+            DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
+            DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
+          }
+          if (SupportsForcingFramePointer &&
+              !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
+            DAL.AddFlagArg(A,
+                           Opts.getOption(options::OPT_fomit_frame_pointer));
+          if (OptChar == '1' || OptChar == '2')
+            DAL.AddFlagArg(A,
+                           Opts.getOption(options::OPT_ffunction_sections));
+        }
+      }
+      break;
+    case 'b':
+      if (I + 1 != E && isdigit(OptStr[I + 1])) {
+        switch (OptStr[I + 1]) {
+        case '0':
+          DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
+          break;
+        case '1':
+          DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
+          break;
+        case '2':
+          DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
+          break;
+        }
+        ++I;
+      }
+      break;
+    case 'g':
+      break;
+    case 'i':
+      if (I + 1 != E && OptStr[I + 1] == '-') {
+        ++I;
+        DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
+      } else {
+        DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
+      }
+      break;
+    case 's':
+      DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
+      break;
+    case 't':
+      DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
+      break;
+    case 'y': {
+      bool OmitFramePointer = true;
+      if (I + 1 != E && OptStr[I + 1] == '-') {
+        OmitFramePointer = false;
+        ++I;
+      }
+      if (SupportsForcingFramePointer) {
+        if (OmitFramePointer)
+          DAL.AddFlagArg(A,
+                         Opts.getOption(options::OPT_fomit_frame_pointer));
+        else
+          DAL.AddFlagArg(
+              A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
+      } else {
+        // Don't warn about /Oy- in 64-bit builds (where
+        // SupportsForcingFramePointer is false).  The flag having no effect
+        // there is a compiler-internal optimization, and people shouldn't have
+        // to special-case their build files for 64-bit clang-cl.
+        A->claim();
+      }
+      break;
+    }
+    }
+  }
+}
+
+static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
+                          const OptTable &Opts) {
+  assert(A->getOption().matches(options::OPT_D));
+
+  StringRef Val = A->getValue();
+  size_t Hash = Val.find('#');
+  if (Hash == StringRef::npos || Hash > Val.find('=')) {
+    DAL.append(A);
+    return;
+  }
+
+  std::string NewVal = Val;
+  NewVal[Hash] = '=';
+  DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
+}
+
+llvm::opt::DerivedArgList *
+MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
+                             StringRef BoundArch, Action::OffloadKind) const {
+  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
+  const OptTable &Opts = getDriver().getOpts();
+
+  // /Oy and /Oy- only has an effect under X86-32.
+  bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
+
+  // The -O[12xd] flag actually expands to several flags.  We must desugar the
+  // flags so that options embedded can be negated.  For example, the '-O2' flag
+  // enables '-Oy'.  Expanding '-O2' into its constituent flags allows us to
+  // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
+  // aspect of '-O2'.
+  //
+  // Note that this expansion logic only applies to the *last* of '[12xd]'.
+
+  // First step is to search for the character we'd like to expand.
+  const char *ExpandChar = nullptr;
+  for (Arg *A : Args) {
+    if (!A->getOption().matches(options::OPT__SLASH_O))
+      continue;
+    StringRef OptStr = A->getValue();
+    for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
+      char OptChar = OptStr[I];
+      char PrevChar = I > 0 ? OptStr[I - 1] : '0';
+      if (PrevChar == 'b') {
+        // OptChar does not expand; it's an argument to the previous char.
+        continue;
+      }
+      if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
+        ExpandChar = OptStr.data() + I;
+    }
+  }
+
+  for (Arg *A : Args) {
+    if (A->getOption().matches(options::OPT__SLASH_O)) {
+      // The -O flag actually takes an amalgam of other options.  For example,
+      // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
+      TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
+    } else if (A->getOption().matches(options::OPT_D)) {
+      // Translate -Dfoo#bar into -Dfoo=bar.
+      TranslateDArg(A, *DAL, Opts);
+    } else {
+      DAL->append(A);
+    }
+  }
+
+  return DAL;
+}
diff --git a/lib/Driver/ToolChains/MSVC.h b/lib/Driver/ToolChains/MSVC.h
new file mode 100644
index 0000000..2b2f3e2
--- /dev/null
+++ b/lib/Driver/ToolChains/MSVC.h
@@ -0,0 +1,133 @@
+//===--- MSVC.h - MSVC ToolChain Implementations ----------------*- 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_LIB_DRIVER_TOOLCHAINS_MSVC_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H
+
+#include "Cuda.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+/// Visual studio tools.
+namespace visualstudio {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+public:
+  Linker(const ToolChain &TC)
+      : Tool("visualstudio::Linker", "linker", TC, RF_Full,
+             llvm::sys::WEM_UTF16) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Compiler : public Tool {
+public:
+  Compiler(const ToolChain &TC)
+      : Tool("visualstudio::Compiler", "compiler", TC, RF_Full,
+             llvm::sys::WEM_UTF16) {}
+
+  bool hasIntegratedAssembler() const override { return true; }
+  bool hasIntegratedCPP() const override { return true; }
+  bool isLinkJob() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+
+  std::unique_ptr<Command> GetCommand(Compilation &C, const JobAction &JA,
+                                      const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const llvm::opt::ArgList &TCArgs,
+                                      const char *LinkingOutput) const;
+};
+} // end namespace visualstudio
+
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
+public:
+  MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
+                const llvm::opt::ArgList &Args);
+
+  llvm::opt::DerivedArgList *
+  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
+                Action::OffloadKind DeviceOffloadKind) const override;
+
+  bool IsIntegratedAssemblerDefault() const override;
+  bool IsUnwindTablesDefault() const override;
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void AddClangCXXStdlibIncludeArgs(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+
+  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const override;
+
+  bool getWindowsSDKDir(std::string &path, int &major,
+                        std::string &windowsSDKIncludeVersion,
+                        std::string &windowsSDKLibVersion) const;
+  bool getWindowsSDKLibraryPath(std::string &path) const;
+  /// \brief Check if Universal CRT should be used if available
+  bool useUniversalCRT(std::string &visualStudioDir) const;
+  bool getUniversalCRTSdkDir(std::string &path, std::string &ucrtVersion) const;
+  bool getUniversalCRTLibraryPath(std::string &path) const;
+  bool getVisualStudioInstallDir(std::string &path) const;
+  bool getVisualStudioBinariesFolder(const char *clangProgramPath,
+                                     std::string &path) const;
+  VersionTuple
+  computeMSVCVersion(const Driver *D,
+                     const llvm::opt::ArgList &Args) const override;
+
+  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
+                                          types::ID InputType) const override;
+  SanitizerMask getSupportedSanitizers() const override;
+
+  void printVerboseInfo(raw_ostream &OS) const override;
+
+protected:
+  void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs,
+                                     llvm::opt::ArgStringList &CC1Args,
+                                     const std::string &folder,
+                                     const Twine &subfolder1,
+                                     const Twine &subfolder2 = "",
+                                     const Twine &subfolder3 = "") const;
+
+  Tool *buildLinker() const override;
+  Tool *buildAssembler() const override;
+private:
+  VersionTuple getMSVCVersionFromTriple() const;
+  VersionTuple getMSVCVersionFromExe() const;
+
+  CudaInstallationDetector CudaInstallation;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H
diff --git a/lib/Driver/ToolChains/MinGW.cpp b/lib/Driver/ToolChains/MinGW.cpp
new file mode 100644
index 0000000..ca5bf06
--- /dev/null
+++ b/lib/Driver/ToolChains/MinGW.cpp
@@ -0,0 +1,471 @@
+//===--- MinGW.cpp - MinGWToolChain Implementation ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MinGW.h"
+#include "InputInfo.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include <system_error>
+
+using namespace clang::diag;
+using namespace clang::driver;
+using namespace clang;
+using namespace llvm::opt;
+
+/// MinGW Tools
+void tools::MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                           const InputInfo &Output,
+                                           const InputInfoList &Inputs,
+                                           const ArgList &Args,
+                                           const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  if (getToolChain().getArch() == llvm::Triple::x86) {
+    CmdArgs.push_back("--32");
+  } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
+    CmdArgs.push_back("--64");
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+
+  if (Args.hasArg(options::OPT_gsplit_dwarf))
+    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
+                   SplitDebugName(Args, Inputs[0]));
+}
+
+void tools::MinGW::Linker::AddLibGCC(const ArgList &Args,
+                                     ArgStringList &CmdArgs) const {
+  if (Args.hasArg(options::OPT_mthreads))
+    CmdArgs.push_back("-lmingwthrd");
+  CmdArgs.push_back("-lmingw32");
+
+  // Make use of compiler-rt if --rtlib option is used
+  ToolChain::RuntimeLibType RLT = getToolChain().GetRuntimeLibType(Args);
+  if (RLT == ToolChain::RLT_Libgcc) {
+    bool Static = Args.hasArg(options::OPT_static_libgcc) ||
+                  Args.hasArg(options::OPT_static);
+    bool Shared = Args.hasArg(options::OPT_shared);
+    bool CXX = getToolChain().getDriver().CCCIsCXX();
+
+    if (Static || (!CXX && !Shared)) {
+      CmdArgs.push_back("-lgcc");
+      CmdArgs.push_back("-lgcc_eh");
+    } else {
+      CmdArgs.push_back("-lgcc_s");
+      CmdArgs.push_back("-lgcc");
+    }
+  } else {
+    AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args);
+  }
+
+  CmdArgs.push_back("-lmoldname");
+  CmdArgs.push_back("-lmingwex");
+  CmdArgs.push_back("-lmsvcrt");
+}
+
+void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                        const InputInfo &Output,
+                                        const InputInfoList &Inputs,
+                                        const ArgList &Args,
+                                        const char *LinkingOutput) const {
+  const ToolChain &TC = getToolChain();
+  const Driver &D = TC.getDriver();
+  // const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
+
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  StringRef LinkerName = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "ld");
+  if (LinkerName.equals_lower("lld")) {
+    CmdArgs.push_back("-flavor");
+    CmdArgs.push_back("gnu");
+  } else if (!LinkerName.equals_lower("ld")) {
+    D.Diag(diag::err_drv_unsupported_linker) << LinkerName;
+  }
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (Args.hasArg(options::OPT_s))
+    CmdArgs.push_back("-s");
+
+  CmdArgs.push_back("-m");
+  if (TC.getArch() == llvm::Triple::x86)
+    CmdArgs.push_back("i386pe");
+  if (TC.getArch() == llvm::Triple::x86_64)
+    CmdArgs.push_back("i386pep");
+  if (TC.getArch() == llvm::Triple::arm)
+    CmdArgs.push_back("thumb2pe");
+
+  if (Args.hasArg(options::OPT_mwindows)) {
+    CmdArgs.push_back("--subsystem");
+    CmdArgs.push_back("windows");
+  } else if (Args.hasArg(options::OPT_mconsole)) {
+    CmdArgs.push_back("--subsystem");
+    CmdArgs.push_back("console");
+  }
+
+  if (Args.hasArg(options::OPT_static))
+    CmdArgs.push_back("-Bstatic");
+  else {
+    if (Args.hasArg(options::OPT_mdll))
+      CmdArgs.push_back("--dll");
+    else if (Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back("--shared");
+    CmdArgs.push_back("-Bdynamic");
+    if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-e");
+      if (TC.getArch() == llvm::Triple::x86)
+        CmdArgs.push_back("_DllMainCRTStartup@12");
+      else
+        CmdArgs.push_back("DllMainCRTStartup");
+      CmdArgs.push_back("--enable-auto-image-base");
+    }
+  }
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+  // FIXME: add -N, -n flags
+  Args.AddLastArg(CmdArgs, options::OPT_r);
+  Args.AddLastArg(CmdArgs, options::OPT_s);
+  Args.AddLastArg(CmdArgs, options::OPT_t);
+  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
+  Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
+      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o")));
+    } else {
+      if (Args.hasArg(options::OPT_municode))
+        CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2u.o")));
+      else
+        CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2.o")));
+    }
+    if (Args.hasArg(options::OPT_pg))
+      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt2.o")));
+    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o")));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  TC.AddFilePathLibArgs(Args, CmdArgs);
+  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
+
+  // TODO: Add ASan stuff here
+
+  // TODO: Add profile stuff here
+
+  if (D.CCCIsCXX() &&
+      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+                               !Args.hasArg(options::OPT_static);
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bstatic");
+    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bdynamic");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
+      if (Args.hasArg(options::OPT_static))
+        CmdArgs.push_back("--start-group");
+
+      if (Args.hasArg(options::OPT_fstack_protector) ||
+          Args.hasArg(options::OPT_fstack_protector_strong) ||
+          Args.hasArg(options::OPT_fstack_protector_all)) {
+        CmdArgs.push_back("-lssp_nonshared");
+        CmdArgs.push_back("-lssp");
+      }
+      if (Args.hasArg(options::OPT_fopenmp))
+        CmdArgs.push_back("-lgomp");
+
+      AddLibGCC(Args, CmdArgs);
+
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lgmon");
+
+      if (Args.hasArg(options::OPT_pthread))
+        CmdArgs.push_back("-lpthread");
+
+      // add system libraries
+      if (Args.hasArg(options::OPT_mwindows)) {
+        CmdArgs.push_back("-lgdi32");
+        CmdArgs.push_back("-lcomdlg32");
+      }
+      CmdArgs.push_back("-ladvapi32");
+      CmdArgs.push_back("-lshell32");
+      CmdArgs.push_back("-luser32");
+      CmdArgs.push_back("-lkernel32");
+
+      if (Args.hasArg(options::OPT_static))
+        CmdArgs.push_back("--end-group");
+      else if (!LinkerName.equals_lower("lld"))
+        AddLibGCC(Args, CmdArgs);
+    }
+
+    if (!Args.hasArg(options::OPT_nostartfiles)) {
+      // Add crtfastmath.o if available and fast math is enabled.
+      TC.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
+
+      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
+    }
+  }
+  const char *Exec = Args.MakeArgString(TC.GetProgramPath(LinkerName.data()));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+// Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple.
+static bool findGccVersion(StringRef LibDir, std::string &GccLibDir,
+                           std::string &Ver) {
+  auto Version = toolchains::Generic_GCC::GCCVersion::Parse("0.0.0");
+  std::error_code EC;
+  for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
+       LI = LI.increment(EC)) {
+    StringRef VersionText = llvm::sys::path::filename(LI->path());
+    auto CandidateVersion =
+        toolchains::Generic_GCC::GCCVersion::Parse(VersionText);
+    if (CandidateVersion.Major == -1)
+      continue;
+    if (CandidateVersion <= Version)
+      continue;
+    Ver = VersionText;
+    GccLibDir = LI->path();
+  }
+  return Ver.size();
+}
+
+void toolchains::MinGW::findGccLibDir() {
+  llvm::SmallVector<llvm::SmallString<32>, 2> Archs;
+  Archs.emplace_back(getTriple().getArchName());
+  Archs[0] += "-w64-mingw32";
+  Archs.emplace_back("mingw32");
+  Arch = Archs[0].str();
+  // lib: Arch Linux, Ubuntu, Windows
+  // lib64: openSUSE Linux
+  for (StringRef CandidateLib : {"lib", "lib64"}) {
+    for (StringRef CandidateArch : Archs) {
+      llvm::SmallString<1024> LibDir(Base);
+      llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateArch);
+      if (findGccVersion(LibDir, GccLibDir, Ver)) {
+        Arch = CandidateArch;
+        return;
+      }
+    }
+  }
+}
+
+toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple,
+                         const ArgList &Args)
+    : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+
+// In Windows there aren't any standard install locations, we search
+// for gcc on the PATH. In Linux the base is always /usr.
+#ifdef LLVM_ON_WIN32
+  if (getDriver().SysRoot.size())
+    Base = getDriver().SysRoot;
+  else if (llvm::ErrorOr<std::string> GPPName =
+               llvm::sys::findProgramByName("gcc"))
+    Base = llvm::sys::path::parent_path(
+        llvm::sys::path::parent_path(GPPName.get()));
+  else
+    Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
+#else
+  if (getDriver().SysRoot.size())
+    Base = getDriver().SysRoot;
+  else
+    Base = "/usr";
+#endif
+
+  Base += llvm::sys::path::get_separator();
+  findGccLibDir();
+  // GccLibDir must precede Base/lib so that the
+  // correct crtbegin.o ,cetend.o would be found.
+  getFilePaths().push_back(GccLibDir);
+  getFilePaths().push_back(
+      (Base + Arch + llvm::sys::path::get_separator() + "lib").str());
+  getFilePaths().push_back(Base + "lib");
+  // openSUSE
+  getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib");
+}
+
+bool toolchains::MinGW::IsIntegratedAssemblerDefault() const { return true; }
+
+Tool *toolchains::MinGW::getTool(Action::ActionClass AC) const {
+  switch (AC) {
+  case Action::PreprocessJobClass:
+    if (!Preprocessor)
+      Preprocessor.reset(new tools::gcc::Preprocessor(*this));
+    return Preprocessor.get();
+  case Action::CompileJobClass:
+    if (!Compiler)
+      Compiler.reset(new tools::gcc::Compiler(*this));
+    return Compiler.get();
+  default:
+    return ToolChain::getTool(AC);
+  }
+}
+
+Tool *toolchains::MinGW::buildAssembler() const {
+  return new tools::MinGW::Assembler(*this);
+}
+
+Tool *toolchains::MinGW::buildLinker() const {
+  return new tools::MinGW::Linker(*this);
+}
+
+bool toolchains::MinGW::IsUnwindTablesDefault() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool toolchains::MinGW::isPICDefault() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool toolchains::MinGW::isPIEDefault() const { return false; }
+
+bool toolchains::MinGW::isPICDefaultForced() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+bool toolchains::MinGW::UseSEHExceptions() const {
+  return getArch() == llvm::Triple::x86_64;
+}
+
+void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs,
+                                           ArgStringList &CC1Args) const {
+  CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
+}
+
+void toolchains::MinGW::printVerboseInfo(raw_ostream &OS) const {
+  CudaInstallation.print(OS);
+}
+
+// Include directories for various hosts:
+
+// Windows, mingw.org
+// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
+// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
+// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
+// c:\mingw\include
+// c:\mingw\mingw32\include
+
+// Windows, mingw-w64 mingw-builds
+// c:\mingw32\i686-w64-mingw32\include
+// c:\mingw32\i686-w64-mingw32\include\c++
+// c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
+// c:\mingw32\i686-w64-mingw32\include\c++\backward
+
+// Windows, mingw-w64 msys2
+// c:\msys64\mingw32\include
+// c:\msys64\mingw32\i686-w64-mingw32\include
+// c:\msys64\mingw32\include\c++\4.9.2
+// c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
+// c:\msys64\mingw32\include\c++\4.9.2\backward
+
+// openSUSE
+// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
+// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
+// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
+// /usr/x86_64-w64-mingw32/sys-root/mingw/include
+
+// Arch Linux
+// /usr/i686-w64-mingw32/include/c++/5.1.0
+// /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
+// /usr/i686-w64-mingw32/include/c++/5.1.0/backward
+// /usr/i686-w64-mingw32/include
+
+// Ubuntu
+// /usr/include/c++/4.8
+// /usr/include/c++/4.8/x86_64-w64-mingw32
+// /usr/include/c++/4.8/backward
+// /usr/x86_64-w64-mingw32/include
+
+void toolchains::MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                                  ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nostdinc))
+    return;
+
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    SmallString<1024> P(getDriver().ResourceDir);
+    llvm::sys::path::append(P, "include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  }
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
+  if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) {
+    // openSUSE
+    addSystemInclude(DriverArgs, CC1Args,
+                     Base + Arch + "/sys-root/mingw/include");
+  }
+
+  addSystemInclude(DriverArgs, CC1Args,
+                   Base + Arch + llvm::sys::path::get_separator() + "include");
+  addSystemInclude(DriverArgs, CC1Args, Base + "include");
+}
+
+void toolchains::MinGW::AddClangCXXStdlibIncludeArgs(
+    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+      DriverArgs.hasArg(options::OPT_nostdincxx))
+    return;
+
+  switch (GetCXXStdlibType(DriverArgs)) {
+  case ToolChain::CST_Libcxx:
+    addSystemInclude(DriverArgs, CC1Args,
+                     Base + "include" + llvm::sys::path::get_separator() +
+                         "c++" + llvm::sys::path::get_separator() + "v1");
+    break;
+
+  case ToolChain::CST_Libstdcxx:
+    llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases;
+    CppIncludeBases.emplace_back(Base);
+    llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
+    CppIncludeBases.emplace_back(Base);
+    llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver);
+    CppIncludeBases.emplace_back(Base);
+    llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
+    CppIncludeBases.emplace_back(GccLibDir);
+    llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
+    for (auto &CppIncludeBase : CppIncludeBases) {
+      addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
+      CppIncludeBase += llvm::sys::path::get_separator();
+      addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
+      addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
+    }
+    break;
+  }
+}
diff --git a/lib/Driver/ToolChains/MinGW.h b/lib/Driver/ToolChains/MinGW.h
new file mode 100644
index 0000000..9d2468f
--- /dev/null
+++ b/lib/Driver/ToolChains/MinGW.h
@@ -0,0 +1,102 @@
+//===--- MinGW.h - MinGW ToolChain Implementations --------------*- 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_LIB_DRIVER_TOOLCHAINS_MINGW_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINGW_H
+
+#include "Cuda.h"
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+/// MinGW -- Directly call GNU Binutils assembler and linker
+namespace MinGW {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
+public:
+  Assembler(const ToolChain &TC) : Tool("MinGW::Assemble", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+public:
+  Linker(const ToolChain &TC) : Tool("MinGW::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+
+private:
+  void AddLibGCC(const llvm::opt::ArgList &Args,
+                 llvm::opt::ArgStringList &CmdArgs) const;
+};
+} // end namespace MinGW
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain {
+public:
+  MinGW(const Driver &D, const llvm::Triple &Triple,
+        const llvm::opt::ArgList &Args);
+
+  bool IsIntegratedAssemblerDefault() const override;
+  bool IsUnwindTablesDefault() const override;
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+  bool UseSEHExceptions() const;
+
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void AddClangCXXStdlibIncludeArgs(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+
+  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const override;
+
+  void printVerboseInfo(raw_ostream &OS) const override;
+
+protected:
+  Tool *getTool(Action::ActionClass AC) const override;
+  Tool *buildLinker() const override;
+  Tool *buildAssembler() const override;
+
+private:
+  CudaInstallationDetector CudaInstallation;
+
+  std::string Base;
+  std::string GccLibDir;
+  std::string Ver;
+  std::string Arch;
+  mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocessor;
+  mutable std::unique_ptr<tools::gcc::Compiler> Compiler;
+  void findGccLibDir();
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINGW_H
diff --git a/lib/Driver/ToolChains/Minix.cpp b/lib/Driver/ToolChains/Minix.cpp
new file mode 100644
index 0000000..2e8939c
--- /dev/null
+++ b/lib/Driver/ToolChains/Minix.cpp
@@ -0,0 +1,109 @@
+//===--- Minix.cpp - Minix ToolChain Implementations ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Minix.h"
+#include "InputInfo.h"
+#include "CommonArgs.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang;
+using namespace llvm::opt;
+
+void tools::minix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                           const InputInfo &Output,
+                                           const InputInfoList &Inputs,
+                                           const ArgList &Args,
+                                           const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void tools::minix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                 const InputInfo &Output,
+                                 const InputInfoList &Inputs,
+                                 const ArgList &Args,
+                                 const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
+    CmdArgs.push_back(
+        Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
+  }
+
+  Args.AddAllArgs(CmdArgs,
+                  {options::OPT_L, options::OPT_T_Group, options::OPT_e});
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+
+  getToolChain().addProfileRTLibs(Args, CmdArgs);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    if (D.CCCIsCXX()) {
+      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      CmdArgs.push_back("-lm");
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-lpthread");
+    CmdArgs.push_back("-lc");
+    CmdArgs.push_back("-lCompilerRT-Generic");
+    CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib");
+    CmdArgs.push_back(
+        Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+  }
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
+
+toolchains::Minix::Minix(const Driver &D, const llvm::Triple &Triple,
+                         const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+}
+
+Tool *toolchains::Minix::buildAssembler() const {
+  return new tools::minix::Assembler(*this);
+}
+
+Tool *toolchains::Minix::buildLinker() const {
+  return new tools::minix::Linker(*this);
+}
diff --git a/lib/Driver/ToolChains/Minix.h b/lib/Driver/ToolChains/Minix.h
new file mode 100644
index 0000000..6fd7185
--- /dev/null
+++ b/lib/Driver/ToolChains/Minix.h
@@ -0,0 +1,66 @@
+//===--- Minix.h - Minix ToolChain Implementations --------------*- 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_LIB_DRIVER_TOOLCHAINS_MINIX_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINIX_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+/// minix -- Directly call GNU Binutils assembler and linker
+namespace minix {
+class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+public:
+  Assembler(const ToolChain &TC)
+      : GnuTool("minix::Assembler", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("minix::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace minix
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF {
+public:
+  Minix(const Driver &D, const llvm::Triple &Triple,
+        const llvm::opt::ArgList &Args);
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MINIX_H
diff --git a/lib/Driver/ToolChains/MipsLinux.cpp b/lib/Driver/ToolChains/MipsLinux.cpp
new file mode 100644
index 0000000..709c396
--- /dev/null
+++ b/lib/Driver/ToolChains/MipsLinux.cpp
@@ -0,0 +1,128 @@
+//===--- Mips.cpp - Mips ToolChain Implementations --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsLinux.h"
+#include "Arch/Mips.h"
+#include "CommonArgs.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+/// Mips Toolchain
+MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D,
+                                     const llvm::Triple &Triple,
+                                     const ArgList &Args)
+    : Linux(D, Triple, Args) {
+  // Select the correct multilib according to the given arguments.
+  DetectedMultilibs Result;
+  findMIPSMultilibs(D, Triple, "", Args, Result);
+  Multilibs = Result.Multilibs;
+  SelectedMultilib = Result.SelectedMultilib;
+
+  // Find out the library suffix based on the ABI.
+  LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple);
+  getFilePaths().clear();
+  getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix);
+}
+
+void MipsLLVMToolChain::AddClangSystemIncludeArgs(
+    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
+    return;
+
+  const Driver &D = getDriver();
+
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    SmallString<128> P(D.ResourceDir);
+    llvm::sys::path::append(P, "include");
+    addSystemInclude(DriverArgs, CC1Args, P);
+  }
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
+  const auto &Callback = Multilibs.includeDirsCallback();
+  if (Callback) {
+    for (const auto &Path : Callback(SelectedMultilib))
+      addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
+                                      D.getInstalledDir() + Path);
+  }
+}
+
+Tool *MipsLLVMToolChain::buildLinker() const {
+  return new tools::gnutools::Linker(*this);
+}
+
+std::string MipsLLVMToolChain::computeSysRoot() const {
+  if (!getDriver().SysRoot.empty())
+    return getDriver().SysRoot + SelectedMultilib.osSuffix();
+
+  const std::string InstalledDir(getDriver().getInstalledDir());
+  std::string SysRootPath =
+      InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix();
+  if (llvm::sys::fs::exists(SysRootPath))
+    return SysRootPath;
+
+  return std::string();
+}
+
+ToolChain::CXXStdlibType
+MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const {
+  Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
+  if (A) {
+    StringRef Value = A->getValue();
+    if (Value != "libc++")
+      getDriver().Diag(clang::diag::err_drv_invalid_stdlib_name)
+          << A->getAsString(Args);
+  }
+
+  return ToolChain::CST_Libcxx;
+}
+
+std::string MipsLLVMToolChain::findLibCxxIncludePath() const {
+  if (const auto &Callback = Multilibs.includeDirsCallback()) {
+    for (std::string Path : Callback(SelectedMultilib)) {
+      Path = getDriver().getInstalledDir() + Path + "/c++/v1";
+      if (llvm::sys::fs::exists(Path)) {
+        return Path;
+      }
+    }
+  }
+  return "";
+}
+
+void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
+                                            ArgStringList &CmdArgs) const {
+  assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) &&
+         "Only -lc++ (aka libxx) is suported in this toolchain.");
+
+  CmdArgs.push_back("-lc++");
+  CmdArgs.push_back("-lc++abi");
+  CmdArgs.push_back("-lunwind");
+}
+
+std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args,
+                                             StringRef Component,
+                                             bool Shared) const {
+  SmallString<128> Path(getDriver().ResourceDir);
+  llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix,
+                          getOS());
+  llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" +
+                                      "mips" + (Shared ? ".so" : ".a")));
+  return Path.str();
+}
diff --git a/lib/Driver/ToolChains/MipsLinux.h b/lib/Driver/ToolChains/MipsLinux.h
new file mode 100644
index 0000000..fa82efb
--- /dev/null
+++ b/lib/Driver/ToolChains/MipsLinux.h
@@ -0,0 +1,62 @@
+//===--- Mips.h - Mips ToolChain Implementations ----------------*- 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_LIB_DRIVER_TOOLCHAINS_MIPS_LINUX_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MIPS_LINUX_H
+
+#include "Linux.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY MipsLLVMToolChain : public Linux {
+protected:
+  Tool *buildLinker() const override;
+
+public:
+  MipsLLVMToolChain(const Driver &D, const llvm::Triple &Triple,
+                    const llvm::opt::ArgList &Args);
+
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+
+  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+
+  std::string findLibCxxIncludePath() const override;
+
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+
+  std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
+                            bool Shared = false) const override;
+
+  std::string computeSysRoot() const override;
+
+  RuntimeLibType GetDefaultRuntimeLibType() const override {
+    return GCCInstallation.isValid() ? RuntimeLibType::RLT_Libgcc
+                                     : RuntimeLibType::RLT_CompilerRT;
+  }
+
+  const char *getDefaultLinker() const override {
+    return "lld";
+  }
+
+private:
+  Multilib SelectedMultilib;
+  std::string LibSuffix;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MIPS_LINUX_H
diff --git a/lib/Driver/ToolChains/Myriad.cpp b/lib/Driver/ToolChains/Myriad.cpp
new file mode 100644
index 0000000..2935755
--- /dev/null
+++ b/lib/Driver/ToolChains/Myriad.cpp
@@ -0,0 +1,286 @@
+//===--- Myriad.cpp - Myriad ToolChain Implementations ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Myriad.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+using tools::addPathIfExists;
+
+void tools::SHAVE::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
+                                          const InputInfo &Output,
+                                          const InputInfoList &Inputs,
+                                          const ArgList &Args,
+                                          const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+  assert(Inputs.size() == 1);
+  const InputInfo &II = Inputs[0];
+  assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX ||
+         II.getType() == types::TY_PP_CXX);
+
+  if (JA.getKind() == Action::PreprocessJobClass) {
+    Args.ClaimAllArgs();
+    CmdArgs.push_back("-E");
+  } else {
+    assert(Output.getType() == types::TY_PP_Asm); // Require preprocessed asm.
+    CmdArgs.push_back("-S");
+    CmdArgs.push_back("-fno-exceptions"); // Always do this even if unspecified.
+  }
+  CmdArgs.push_back("-DMYRIAD2");
+
+  // Append all -I, -iquote, -isystem paths, defines/undefines,
+  // 'f' flags, optimize flags, and warning options.
+  // These are spelled the same way in clang and moviCompile.
+  Args.AddAllArgsExcept(
+      CmdArgs,
+      {options::OPT_I_Group, options::OPT_clang_i_Group, options::OPT_std_EQ,
+       options::OPT_D, options::OPT_U, options::OPT_f_Group,
+       options::OPT_f_clang_Group, options::OPT_g_Group, options::OPT_M_Group,
+       options::OPT_O_Group, options::OPT_W_Group, options::OPT_mcpu_EQ},
+      {options::OPT_fno_split_dwarf_inlining});
+  Args.hasArg(options::OPT_fno_split_dwarf_inlining); // Claim it if present.
+
+  // If we're producing a dependency file, and assembly is the final action,
+  // then the name of the target in the dependency file should be the '.o'
+  // file, not the '.s' file produced by this step. For example, instead of
+  //  /tmp/mumble.s: mumble.c .../someheader.h
+  // the filename on the lefthand side should be "mumble.o"
+  if (Args.getLastArg(options::OPT_MF) && !Args.getLastArg(options::OPT_MT) &&
+      C.getActions().size() == 1 &&
+      C.getActions()[0]->getKind() == Action::AssembleJobClass) {
+    Arg *A = Args.getLastArg(options::OPT_o);
+    if (A) {
+      CmdArgs.push_back("-MT");
+      CmdArgs.push_back(Args.MakeArgString(A->getValue()));
+    }
+  }
+
+  CmdArgs.push_back(II.getFilename());
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  std::string Exec =
+      Args.MakeArgString(getToolChain().GetProgramPath("moviCompile"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
+                                          CmdArgs, Inputs));
+}
+
+void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                           const InputInfo &Output,
+                                           const InputInfoList &Inputs,
+                                           const ArgList &Args,
+                                           const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  assert(Inputs.size() == 1);
+  const InputInfo &II = Inputs[0];
+  assert(II.getType() == types::TY_PP_Asm); // Require preprocessed asm input.
+  assert(Output.getType() == types::TY_Object);
+
+  CmdArgs.push_back("-no6thSlotCompression");
+  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
+  if (CPUArg)
+    CmdArgs.push_back(
+        Args.MakeArgString("-cv:" + StringRef(CPUArg->getValue())));
+  CmdArgs.push_back("-noSPrefixing");
+  CmdArgs.push_back("-a"); // Mystery option.
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+  for (const Arg *A : Args.filtered(options::OPT_I, options::OPT_isystem)) {
+    A->claim();
+    CmdArgs.push_back(
+        Args.MakeArgString(std::string("-i:") + A->getValue(0)));
+  }
+  CmdArgs.push_back("-elf"); // Output format.
+  CmdArgs.push_back(II.getFilename());
+  CmdArgs.push_back(
+      Args.MakeArgString(std::string("-o:") + Output.getFilename()));
+
+  std::string Exec =
+      Args.MakeArgString(getToolChain().GetProgramPath("moviAsm"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
+                                          CmdArgs, Inputs));
+}
+
+void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                         const InputInfo &Output,
+                                         const InputInfoList &Inputs,
+                                         const ArgList &Args,
+                                         const char *LinkingOutput) const {
+  const auto &TC =
+      static_cast<const toolchains::MyriadToolChain &>(getToolChain());
+  const llvm::Triple &T = TC.getTriple();
+  ArgStringList CmdArgs;
+  bool UseStartfiles =
+      !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
+  bool UseDefaultLibs =
+      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs);
+  // Silence warning if the args contain both -nostdlib and -stdlib=.
+  Args.getLastArg(options::OPT_stdlib_EQ);
+
+  if (T.getArch() == llvm::Triple::sparc)
+    CmdArgs.push_back("-EB");
+  else // SHAVE assumes little-endian, and sparcel is expressly so.
+    CmdArgs.push_back("-EL");
+
+  // The remaining logic is mostly like gnutools::Linker::ConstructJob,
+  // but we never pass through a --sysroot option and various other bits.
+  // For example, there are no sanitizers (yet) nor gold linker.
+
+  // Eat some arguments that may be present but have no effect.
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  Args.ClaimAllArgs(options::OPT_w);
+  Args.ClaimAllArgs(options::OPT_static_libgcc);
+
+  if (Args.hasArg(options::OPT_s)) // Pass the 'strip' option.
+    CmdArgs.push_back("-s");
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  if (UseStartfiles) {
+    // If you want startfiles, it means you want the builtin crti and crtbegin,
+    // but not crt0. Myriad link commands provide their own crt0.o as needed.
+    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crti.o")));
+    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o")));
+  }
+
+  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
+                            options::OPT_e, options::OPT_s, options::OPT_t,
+                            options::OPT_Z_Flag, options::OPT_r});
+
+  TC.AddFilePathLibArgs(Args, CmdArgs);
+
+  bool NeedsSanitizerDeps = addSanitizerRuntimes(TC, Args, CmdArgs);
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+
+  if (UseDefaultLibs) {
+    if (NeedsSanitizerDeps)
+      linkSanitizerRuntimeDeps(TC, CmdArgs);
+    if (C.getDriver().CCCIsCXX()) {
+      if (TC.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) {
+        CmdArgs.push_back("-lc++");
+        CmdArgs.push_back("-lc++abi");
+      } else
+        CmdArgs.push_back("-lstdc++");
+    }
+    if (T.getOS() == llvm::Triple::RTEMS) {
+      CmdArgs.push_back("--start-group");
+      CmdArgs.push_back("-lc");
+      CmdArgs.push_back("-lgcc"); // circularly dependent on rtems
+      // You must provide your own "-L" option to enable finding these.
+      CmdArgs.push_back("-lrtemscpu");
+      CmdArgs.push_back("-lrtemsbsp");
+      CmdArgs.push_back("--end-group");
+    } else {
+      CmdArgs.push_back("-lc");
+      CmdArgs.push_back("-lgcc");
+    }
+  }
+  if (UseStartfiles) {
+    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
+    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtn.o")));
+  }
+
+  std::string Exec =
+      Args.MakeArgString(TC.GetProgramPath("sparc-myriad-elf-ld"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
+                                          CmdArgs, Inputs));
+}
+
+MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
+                                 const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use
+  // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple.
+  // This won't work to find gcc. Instead we give the installation detector an
+  // extra triple, which is preferable to further hacks of the logic that at
+  // present is based solely on getArch(). In particular, it would be wrong to
+  // choose the myriad installation when targeting a non-myriad sparc install.
+  switch (Triple.getArch()) {
+  default:
+    D.Diag(clang::diag::err_target_unsupported_arch)
+        << Triple.getArchName() << "myriad";
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+  case llvm::Triple::shave:
+    GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"});
+  }
+
+  if (GCCInstallation.isValid()) {
+    // This directory contains crt{i,n,begin,end}.o as well as libgcc.
+    // These files are tied to a particular version of gcc.
+    SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath());
+    addPathIfExists(D, CompilerSupportDir, getFilePaths());
+  }
+  // libstd++ and libc++ must both be found in this one place.
+  addPathIfExists(D, D.Dir + "/../sparc-myriad-elf/lib", getFilePaths());
+}
+
+MyriadToolChain::~MyriadToolChain() {}
+
+void MyriadToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                                ArgStringList &CC1Args) const {
+  if (!DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
+    addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
+}
+
+std::string MyriadToolChain::findLibCxxIncludePath() const {
+  std::string Path(getDriver().getInstalledDir());
+  return Path + "/../include/c++/v1";
+}
+
+void MyriadToolChain::addLibStdCxxIncludePaths(
+    const llvm::opt::ArgList &DriverArgs,
+    llvm::opt::ArgStringList &CC1Args) const {
+  StringRef LibDir = GCCInstallation.getParentLibPath();
+  const GCCVersion &Version = GCCInstallation.getVersion();
+  StringRef TripleStr = GCCInstallation.getTriple().str();
+  const Multilib &Multilib = GCCInstallation.getMultilib();
+  addLibStdCXXIncludePaths(
+      LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
+      "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args);
+}
+
+// MyriadToolChain handles several triples:
+//  {shave,sparc{,el}}-myriad-{rtems,unknown}-elf
+Tool *MyriadToolChain::SelectTool(const JobAction &JA) const {
+  // The inherited method works fine if not targeting the SHAVE.
+  if (!isShaveCompilation(getTriple()))
+    return ToolChain::SelectTool(JA);
+  switch (JA.getKind()) {
+  case Action::PreprocessJobClass:
+  case Action::CompileJobClass:
+    if (!Compiler)
+      Compiler.reset(new tools::SHAVE::Compiler(*this));
+    return Compiler.get();
+  case Action::AssembleJobClass:
+    if (!Assembler)
+      Assembler.reset(new tools::SHAVE::Assembler(*this));
+    return Assembler.get();
+  default:
+    return ToolChain::getTool(JA.getKind());
+  }
+}
+
+Tool *MyriadToolChain::buildLinker() const {
+  return new tools::Myriad::Linker(*this);
+}
+
+SanitizerMask MyriadToolChain::getSupportedSanitizers() const {
+  return SanitizerKind::Address;
+}
diff --git a/lib/Driver/ToolChains/Myriad.h b/lib/Driver/ToolChains/Myriad.h
new file mode 100644
index 0000000..4c213c7
--- /dev/null
+++ b/lib/Driver/ToolChains/Myriad.h
@@ -0,0 +1,102 @@
+//===--- Myriad.h - Myriad ToolChain Implementations ------------*- 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_LIB_DRIVER_TOOLCHAINS_MYRIAD_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MYRIAD_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+/// SHAVE tools -- Directly call moviCompile and moviAsm
+namespace SHAVE {
+class LLVM_LIBRARY_VISIBILITY Compiler : public Tool {
+public:
+  Compiler(const ToolChain &TC) : Tool("moviCompile", "movicompile", TC) {}
+
+  bool hasIntegratedCPP() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
+public:
+  Assembler(const ToolChain &TC) : Tool("moviAsm", "moviAsm", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; } // not sure.
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace SHAVE
+
+/// The Myriad toolchain uses tools that are in two different namespaces.
+/// The Compiler and Assembler as defined above are in the SHAVE namespace,
+/// whereas the linker, which accepts code for a mixture of Sparc and SHAVE,
+/// is in the Myriad namespace.
+namespace Myriad {
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("shave::Linker", "ld", TC) {}
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace Myriad
+} // end namespace tools
+
+namespace toolchains {
+
+/// MyriadToolChain - A tool chain using either clang or the external compiler
+/// installed by the Movidius SDK to perform all subcommands.
+class LLVM_LIBRARY_VISIBILITY MyriadToolChain : public Generic_ELF {
+public:
+  MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
+                  const llvm::opt::ArgList &Args);
+  ~MyriadToolChain() override;
+
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  std::string findLibCxxIncludePath() const override;
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  Tool *SelectTool(const JobAction &JA) const override;
+  unsigned GetDefaultDwarfVersion() const override { return 2; }
+  SanitizerMask getSupportedSanitizers() const override;
+
+protected:
+  Tool *buildLinker() const override;
+  bool isShaveCompilation(const llvm::Triple &T) const {
+    return T.getArch() == llvm::Triple::shave;
+  }
+
+private:
+  mutable std::unique_ptr<Tool> Compiler;
+  mutable std::unique_ptr<Tool> Assembler;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MYRIAD_H
diff --git a/lib/Driver/ToolChains/NaCl.cpp b/lib/Driver/ToolChains/NaCl.cpp
new file mode 100644
index 0000000..5eb5c74
--- /dev/null
+++ b/lib/Driver/ToolChains/NaCl.cpp
@@ -0,0 +1,363 @@
+//===--- NaCl.cpp - Native Client ToolChain Implementations -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NaCl.h"
+#include "InputInfo.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+// NaCl ARM assembly (inline or standalone) can be written with a set of macros
+// for the various SFI requirements like register masking. The assembly tool
+// inserts the file containing the macros as an input into all the assembly
+// jobs.
+void nacltools::AssemblerARM::ConstructJob(Compilation &C, const JobAction &JA,
+                                           const InputInfo &Output,
+                                           const InputInfoList &Inputs,
+                                           const ArgList &Args,
+                                           const char *LinkingOutput) const {
+  const toolchains::NaClToolChain &ToolChain =
+      static_cast<const toolchains::NaClToolChain &>(getToolChain());
+  InputInfo NaClMacros(types::TY_PP_Asm, ToolChain.GetNaClArmMacrosPath(),
+                       "nacl-arm-macros.s");
+  InputInfoList NewInputs;
+  NewInputs.push_back(NaClMacros);
+  NewInputs.append(Inputs.begin(), Inputs.end());
+  gnutools::Assembler::ConstructJob(C, JA, Output, NewInputs, Args,
+                                    LinkingOutput);
+}
+
+// This is quite similar to gnutools::Linker::ConstructJob with changes that
+// we use static by default, do not yet support sanitizers or LTO, and a few
+// others. Eventually we can support more of that and hopefully migrate back
+// to gnutools::Linker.
+void nacltools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                     const InputInfo &Output,
+                                     const InputInfoList &Inputs,
+                                     const ArgList &Args,
+                                     const char *LinkingOutput) const {
+
+  const toolchains::NaClToolChain &ToolChain =
+      static_cast<const toolchains::NaClToolChain &>(getToolChain());
+  const Driver &D = ToolChain.getDriver();
+  const llvm::Triple::ArchType Arch = ToolChain.getArch();
+  const bool IsStatic =
+      !Args.hasArg(options::OPT_dynamic) && !Args.hasArg(options::OPT_shared);
+
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (Args.hasArg(options::OPT_rdynamic))
+    CmdArgs.push_back("-export-dynamic");
+
+  if (Args.hasArg(options::OPT_s))
+    CmdArgs.push_back("-s");
+
+  // NaClToolChain doesn't have ExtraOpts like Linux; the only relevant flag
+  // from there is --build-id, which we do want.
+  CmdArgs.push_back("--build-id");
+
+  if (!IsStatic)
+    CmdArgs.push_back("--eh-frame-hdr");
+
+  CmdArgs.push_back("-m");
+  if (Arch == llvm::Triple::x86)
+    CmdArgs.push_back("elf_i386_nacl");
+  else if (Arch == llvm::Triple::arm)
+    CmdArgs.push_back("armelf_nacl");
+  else if (Arch == llvm::Triple::x86_64)
+    CmdArgs.push_back("elf_x86_64_nacl");
+  else if (Arch == llvm::Triple::mipsel)
+    CmdArgs.push_back("mipselelf_nacl");
+  else
+    D.Diag(diag::err_target_unsupported_arch) << ToolChain.getArchName()
+                                              << "Native Client";
+
+  if (IsStatic)
+    CmdArgs.push_back("-static");
+  else if (Args.hasArg(options::OPT_shared))
+    CmdArgs.push_back("-shared");
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt1.o")));
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
+
+    const char *crtbegin;
+    if (IsStatic)
+      crtbegin = "crtbeginT.o";
+    else if (Args.hasArg(options::OPT_shared))
+      crtbegin = "crtbeginS.o";
+    else
+      crtbegin = "crtbegin.o";
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_u);
+
+  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+
+  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+    CmdArgs.push_back("--no-demangle");
+
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+  if (D.CCCIsCXX() &&
+      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    bool OnlyLibstdcxxStatic =
+        Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bstatic");
+    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bdynamic");
+    CmdArgs.push_back("-lm");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
+      // Always use groups, since it has no effect on dynamic libraries.
+      CmdArgs.push_back("--start-group");
+      CmdArgs.push_back("-lc");
+      // NaCl's libc++ currently requires libpthread, so just always include it
+      // in the group for C++.
+      if (Args.hasArg(options::OPT_pthread) ||
+          Args.hasArg(options::OPT_pthreads) || D.CCCIsCXX()) {
+        // Gold, used by Mips, handles nested groups differently than ld, and
+        // without '-lnacl' it prefers symbols from libpthread.a over libnacl.a,
+        // which is not a desired behaviour here.
+        // See https://sourceware.org/ml/binutils/2015-03/msg00034.html
+        if (getToolChain().getArch() == llvm::Triple::mipsel)
+          CmdArgs.push_back("-lnacl");
+
+        CmdArgs.push_back("-lpthread");
+      }
+
+      CmdArgs.push_back("-lgcc");
+      CmdArgs.push_back("--as-needed");
+      if (IsStatic)
+        CmdArgs.push_back("-lgcc_eh");
+      else
+        CmdArgs.push_back("-lgcc_s");
+      CmdArgs.push_back("--no-as-needed");
+
+      // Mips needs to create and use pnacl_legacy library that contains
+      // definitions from bitcode/pnaclmm.c and definitions for
+      // __nacl_tp_tls_offset() and __nacl_tp_tdb_offset().
+      if (getToolChain().getArch() == llvm::Triple::mipsel)
+        CmdArgs.push_back("-lpnacl_legacy");
+
+      CmdArgs.push_back("--end-group");
+    }
+
+    if (!Args.hasArg(options::OPT_nostartfiles)) {
+      const char *crtend;
+      if (Args.hasArg(options::OPT_shared))
+        crtend = "crtendS.o";
+      else
+        crtend = "crtend.o";
+
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+    }
+  }
+
+  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// NaCl Toolchain
+NaClToolChain::NaClToolChain(const Driver &D, const llvm::Triple &Triple,
+                             const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+
+  // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the
+  // default paths, and must instead only use the paths provided
+  // with this toolchain based on architecture.
+  path_list &file_paths = getFilePaths();
+  path_list &prog_paths = getProgramPaths();
+
+  file_paths.clear();
+  prog_paths.clear();
+
+  // Path for library files (libc.a, ...)
+  std::string FilePath(getDriver().Dir + "/../");
+
+  // Path for tools (clang, ld, etc..)
+  std::string ProgPath(getDriver().Dir + "/../");
+
+  // Path for toolchain libraries (libgcc.a, ...)
+  std::string ToolPath(getDriver().ResourceDir + "/lib/");
+
+  switch (Triple.getArch()) {
+  case llvm::Triple::x86:
+    file_paths.push_back(FilePath + "x86_64-nacl/lib32");
+    file_paths.push_back(FilePath + "i686-nacl/usr/lib");
+    prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
+    file_paths.push_back(ToolPath + "i686-nacl");
+    break;
+  case llvm::Triple::x86_64:
+    file_paths.push_back(FilePath + "x86_64-nacl/lib");
+    file_paths.push_back(FilePath + "x86_64-nacl/usr/lib");
+    prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
+    file_paths.push_back(ToolPath + "x86_64-nacl");
+    break;
+  case llvm::Triple::arm:
+    file_paths.push_back(FilePath + "arm-nacl/lib");
+    file_paths.push_back(FilePath + "arm-nacl/usr/lib");
+    prog_paths.push_back(ProgPath + "arm-nacl/bin");
+    file_paths.push_back(ToolPath + "arm-nacl");
+    break;
+  case llvm::Triple::mipsel:
+    file_paths.push_back(FilePath + "mipsel-nacl/lib");
+    file_paths.push_back(FilePath + "mipsel-nacl/usr/lib");
+    prog_paths.push_back(ProgPath + "bin");
+    file_paths.push_back(ToolPath + "mipsel-nacl");
+    break;
+  default:
+    break;
+  }
+
+  NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s");
+}
+
+void NaClToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                              ArgStringList &CC1Args) const {
+  const Driver &D = getDriver();
+  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
+    return;
+
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    SmallString<128> P(D.ResourceDir);
+    llvm::sys::path::append(P, "include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  }
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
+  SmallString<128> P(D.Dir + "/../");
+  switch (getTriple().getArch()) {
+  case llvm::Triple::x86:
+    // x86 is special because multilib style uses x86_64-nacl/include for libc
+    // headers but the SDK wants i686-nacl/usr/include. The other architectures
+    // have the same substring.
+    llvm::sys::path::append(P, "i686-nacl/usr/include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+    llvm::sys::path::remove_filename(P);
+    llvm::sys::path::remove_filename(P);
+    llvm::sys::path::remove_filename(P);
+    llvm::sys::path::append(P, "x86_64-nacl/include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+    return;
+  case llvm::Triple::arm:
+    llvm::sys::path::append(P, "arm-nacl/usr/include");
+    break;
+  case llvm::Triple::x86_64:
+    llvm::sys::path::append(P, "x86_64-nacl/usr/include");
+    break;
+  case llvm::Triple::mipsel:
+    llvm::sys::path::append(P, "mipsel-nacl/usr/include");
+    break;
+  default:
+    return;
+  }
+
+  addSystemInclude(DriverArgs, CC1Args, P.str());
+  llvm::sys::path::remove_filename(P);
+  llvm::sys::path::remove_filename(P);
+  llvm::sys::path::append(P, "include");
+  addSystemInclude(DriverArgs, CC1Args, P.str());
+}
+
+void NaClToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
+                                        ArgStringList &CmdArgs) const {
+  // Check for -stdlib= flags. We only support libc++ but this consumes the arg
+  // if the value is libc++, and emits an error for other values.
+  GetCXXStdlibType(Args);
+  CmdArgs.push_back("-lc++");
+}
+
+std::string NaClToolChain::findLibCxxIncludePath() const {
+  const Driver &D = getDriver();
+
+  SmallString<128> P(D.Dir + "/../");
+  switch (getTriple().getArch()) {
+  case llvm::Triple::arm:
+    llvm::sys::path::append(P, "arm-nacl/include/c++/v1");
+    return P.str();
+  case llvm::Triple::x86:
+    llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
+    return P.str();
+  case llvm::Triple::x86_64:
+    llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
+    return P.str();
+  case llvm::Triple::mipsel:
+    llvm::sys::path::append(P, "mipsel-nacl/include/c++/v1");
+    return P.str();
+  default:
+    return "";
+  }
+}
+
+ToolChain::CXXStdlibType
+NaClToolChain::GetCXXStdlibType(const ArgList &Args) const {
+  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
+    StringRef Value = A->getValue();
+    if (Value == "libc++")
+      return ToolChain::CST_Libcxx;
+    getDriver().Diag(clang::diag::err_drv_invalid_stdlib_name)
+        << A->getAsString(Args);
+  }
+
+  return ToolChain::CST_Libcxx;
+}
+
+std::string
+NaClToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
+                                           types::ID InputType) const {
+  llvm::Triple TheTriple(ComputeLLVMTriple(Args, InputType));
+  if (TheTriple.getArch() == llvm::Triple::arm &&
+      TheTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
+    TheTriple.setEnvironment(llvm::Triple::GNUEABIHF);
+  return TheTriple.getTriple();
+}
+
+Tool *NaClToolChain::buildLinker() const {
+  return new tools::nacltools::Linker(*this);
+}
+
+Tool *NaClToolChain::buildAssembler() const {
+  if (getTriple().getArch() == llvm::Triple::arm)
+    return new tools::nacltools::AssemblerARM(*this);
+  return new tools::gnutools::Assembler(*this);
+}
diff --git a/lib/Driver/ToolChains/NaCl.h b/lib/Driver/ToolChains/NaCl.h
new file mode 100644
index 0000000..31af3a5
--- /dev/null
+++ b/lib/Driver/ToolChains/NaCl.h
@@ -0,0 +1,87 @@
+//===--- NaCl.h - Native Client ToolChain Implementations -------*- 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_LIB_DRIVER_TOOLCHAINS_NACL_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_NACL_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace nacltools {
+class LLVM_LIBRARY_VISIBILITY AssemblerARM : public gnutools::Assembler {
+public:
+  AssemblerARM(const ToolChain &TC) : gnutools::Assembler(TC) {}
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("NaCl::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace nacltools
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY NaClToolChain : public Generic_ELF {
+public:
+  NaClToolChain(const Driver &D, const llvm::Triple &Triple,
+                const llvm::opt::ArgList &Args);
+
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  std::string findLibCxxIncludePath() const override;
+
+  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+
+  bool IsIntegratedAssemblerDefault() const override {
+    return getTriple().getArch() == llvm::Triple::mipsel;
+  }
+
+  // Get the path to the file containing NaCl's ARM macros.
+  // It lives in NaClToolChain because the ARMAssembler tool needs a
+  // const char * that it can pass around,
+  const char *GetNaClArmMacrosPath() const { return NaClArmMacrosPath.c_str(); }
+
+  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
+                                          types::ID InputType) const override;
+
+protected:
+  Tool *buildLinker() const override;
+  Tool *buildAssembler() const override;
+
+private:
+  std::string NaClArmMacrosPath;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_NACL_H
diff --git a/lib/Driver/ToolChains/NetBSD.cpp b/lib/Driver/ToolChains/NetBSD.cpp
new file mode 100644
index 0000000..d7d3ad6
--- /dev/null
+++ b/lib/Driver/ToolChains/NetBSD.cpp
@@ -0,0 +1,412 @@
+//===--- NetBSD.cpp - NetBSD ToolChain Implementations ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NetBSD.h"
+#include "Arch/ARM.h"
+#include "Arch/Mips.h"
+#include "Arch/Sparc.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                     const InputInfo &Output,
+                                     const InputInfoList &Inputs,
+                                     const ArgList &Args,
+                                     const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  // GNU as needs different flags for creating the correct output format
+  // on architectures with different ABIs or optional feature sets.
+  switch (getToolChain().getArch()) {
+  case llvm::Triple::x86:
+    CmdArgs.push_back("--32");
+    break;
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb: {
+    StringRef MArch, MCPU;
+    arm::getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true);
+    std::string Arch =
+        arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
+    CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
+    break;
+  }
+
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el: {
+    StringRef CPUName;
+    StringRef ABIName;
+    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+
+    CmdArgs.push_back("-march");
+    CmdArgs.push_back(CPUName.data());
+
+    CmdArgs.push_back("-mabi");
+    CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
+
+    if (getToolChain().getArch() == llvm::Triple::mips ||
+        getToolChain().getArch() == llvm::Triple::mips64)
+      CmdArgs.push_back("-EB");
+    else
+      CmdArgs.push_back("-EL");
+
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel: {
+    CmdArgs.push_back("-32");
+    std::string CPU = getCPUName(Args, getToolChain().getTriple());
+    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+
+  case llvm::Triple::sparcv9: {
+    CmdArgs.push_back("-64");
+    std::string CPU = getCPUName(Args, getToolChain().getTriple());
+    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+
+  default:
+    break;
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                  const InputInfo &Output,
+                                  const InputInfoList &Inputs,
+                                  const ArgList &Args,
+                                  const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  CmdArgs.push_back("--eh-frame-hdr");
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    if (Args.hasArg(options::OPT_rdynamic))
+      CmdArgs.push_back("-export-dynamic");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-Bshareable");
+    } else {
+      Args.AddAllArgs(CmdArgs, options::OPT_pie);
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/libexec/ld.elf_so");
+    }
+  }
+
+  // Many NetBSD architectures support more than one ABI.
+  // Determine the correct emulation for ld.
+  switch (getToolChain().getArch()) {
+  case llvm::Triple::x86:
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf_i386");
+    break;
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    CmdArgs.push_back("-m");
+    switch (getToolChain().getTriple().getEnvironment()) {
+    case llvm::Triple::EABI:
+    case llvm::Triple::GNUEABI:
+      CmdArgs.push_back("armelf_nbsd_eabi");
+      break;
+    case llvm::Triple::EABIHF:
+    case llvm::Triple::GNUEABIHF:
+      CmdArgs.push_back("armelf_nbsd_eabihf");
+      break;
+    default:
+      CmdArgs.push_back("armelf_nbsd");
+      break;
+    }
+    break;
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumbeb:
+    arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getEffectiveTriple());
+    CmdArgs.push_back("-m");
+    switch (getToolChain().getTriple().getEnvironment()) {
+    case llvm::Triple::EABI:
+    case llvm::Triple::GNUEABI:
+      CmdArgs.push_back("armelfb_nbsd_eabi");
+      break;
+    case llvm::Triple::EABIHF:
+    case llvm::Triple::GNUEABIHF:
+      CmdArgs.push_back("armelfb_nbsd_eabihf");
+      break;
+    default:
+      CmdArgs.push_back("armelfb_nbsd");
+      break;
+    }
+    break;
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el:
+    if (mips::hasMipsAbiArg(Args, "32")) {
+      CmdArgs.push_back("-m");
+      if (getToolChain().getArch() == llvm::Triple::mips64)
+        CmdArgs.push_back("elf32btsmip");
+      else
+        CmdArgs.push_back("elf32ltsmip");
+    } else if (mips::hasMipsAbiArg(Args, "64")) {
+      CmdArgs.push_back("-m");
+      if (getToolChain().getArch() == llvm::Triple::mips64)
+        CmdArgs.push_back("elf64btsmip");
+      else
+        CmdArgs.push_back("elf64ltsmip");
+    }
+    break;
+  case llvm::Triple::ppc:
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf32ppc_nbsd");
+    break;
+
+  case llvm::Triple::ppc64:
+  case llvm::Triple::ppc64le:
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf64ppc");
+    break;
+
+  case llvm::Triple::sparc:
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf32_sparc");
+    break;
+
+  case llvm::Triple::sparcv9:
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf64_sparc");
+    break;
+
+  default:
+    break;
+  }
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
+    }
+    CmdArgs.push_back(
+        Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
+    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) {
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
+    } else {
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
+    }
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+  Args.AddAllArgs(CmdArgs, options::OPT_s);
+  Args.AddAllArgs(CmdArgs, options::OPT_t);
+  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
+  Args.AddAllArgs(CmdArgs, options::OPT_r);
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+
+  unsigned Major, Minor, Micro;
+  getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
+  bool useLibgcc = true;
+  if (Major >= 7 || Major == 0) {
+    switch (getToolChain().getArch()) {
+    case llvm::Triple::aarch64:
+    case llvm::Triple::aarch64_be:
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+    case llvm::Triple::ppc:
+    case llvm::Triple::ppc64:
+    case llvm::Triple::ppc64le:
+    case llvm::Triple::sparc:
+    case llvm::Triple::sparcv9:
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+      useLibgcc = false;
+      break;
+    default:
+      break;
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    addOpenMPRuntime(CmdArgs, getToolChain(), Args);
+    if (D.CCCIsCXX()) {
+      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      CmdArgs.push_back("-lm");
+    }
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-lpthread");
+    CmdArgs.push_back("-lc");
+
+    if (useLibgcc) {
+      if (Args.hasArg(options::OPT_static)) {
+        // libgcc_eh depends on libc, so resolve as much as possible,
+        // pull in any new requirements from libc and then get the rest
+        // of libgcc.
+        CmdArgs.push_back("-lgcc_eh");
+        CmdArgs.push_back("-lc");
+        CmdArgs.push_back("-lgcc");
+      } else {
+        CmdArgs.push_back("-lgcc");
+        CmdArgs.push_back("--as-needed");
+        CmdArgs.push_back("-lgcc_s");
+        CmdArgs.push_back("--no-as-needed");
+      }
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
+    else
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
+  }
+
+  getToolChain().addProfileRTLibs(Args, CmdArgs);
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
+
+NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  if (getDriver().UseStdLib) {
+    // When targeting a 32-bit platform, try the special directory used on
+    // 64-bit hosts, and only fall back to the main library directory if that
+    // doesn't work.
+    // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
+    // what all logic is needed to emulate the '=' prefix here.
+    switch (Triple.getArch()) {
+    case llvm::Triple::x86:
+      getFilePaths().push_back("=/usr/lib/i386");
+      break;
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+      switch (Triple.getEnvironment()) {
+      case llvm::Triple::EABI:
+      case llvm::Triple::GNUEABI:
+        getFilePaths().push_back("=/usr/lib/eabi");
+        break;
+      case llvm::Triple::EABIHF:
+      case llvm::Triple::GNUEABIHF:
+        getFilePaths().push_back("=/usr/lib/eabihf");
+        break;
+      default:
+        getFilePaths().push_back("=/usr/lib/oabi");
+        break;
+      }
+      break;
+    case llvm::Triple::mips64:
+    case llvm::Triple::mips64el:
+      if (tools::mips::hasMipsAbiArg(Args, "o32"))
+        getFilePaths().push_back("=/usr/lib/o32");
+      else if (tools::mips::hasMipsAbiArg(Args, "64"))
+        getFilePaths().push_back("=/usr/lib/64");
+      break;
+    case llvm::Triple::ppc:
+      getFilePaths().push_back("=/usr/lib/powerpc");
+      break;
+    case llvm::Triple::sparc:
+      getFilePaths().push_back("=/usr/lib/sparc");
+      break;
+    default:
+      break;
+    }
+
+    getFilePaths().push_back("=/usr/lib");
+  }
+}
+
+Tool *NetBSD::buildAssembler() const {
+  return new tools::netbsd::Assembler(*this);
+}
+
+Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
+
+ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
+  unsigned Major, Minor, Micro;
+  getTriple().getOSVersion(Major, Minor, Micro);
+  if (Major >= 7 || Major == 0) {
+    switch (getArch()) {
+    case llvm::Triple::aarch64:
+    case llvm::Triple::aarch64_be:
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+    case llvm::Triple::ppc:
+    case llvm::Triple::ppc64:
+    case llvm::Triple::ppc64le:
+    case llvm::Triple::sparc:
+    case llvm::Triple::sparcv9:
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+      return ToolChain::CST_Libcxx;
+    default:
+      break;
+    }
+  }
+  return ToolChain::CST_Libstdcxx;
+}
+
+std::string NetBSD::findLibCxxIncludePath() const {
+  return getDriver().SysRoot + "/usr/include/c++/";
+}
+
+void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+                                      llvm::opt::ArgStringList &CC1Args) const {
+  addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/g++", "", "", "",
+                           "", DriverArgs, CC1Args);
+}
diff --git a/lib/Driver/ToolChains/NetBSD.h b/lib/Driver/ToolChains/NetBSD.h
new file mode 100644
index 0000000..d53aa68
--- /dev/null
+++ b/lib/Driver/ToolChains/NetBSD.h
@@ -0,0 +1,79 @@
+//===--- NetBSD.h - NetBSD ToolChain Implementations ------------*- 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_LIB_DRIVER_TOOLCHAINS_NETBSD_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_NETBSD_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+/// netbsd -- Directly call GNU Binutils assembler and linker
+namespace netbsd {
+class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+public:
+  Assembler(const ToolChain &TC)
+      : GnuTool("netbsd::Assembler", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("netbsd::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace netbsd
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
+public:
+  NetBSD(const Driver &D, const llvm::Triple &Triple,
+         const llvm::opt::ArgList &Args);
+
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
+
+  CXXStdlibType GetDefaultCXXStdlibType() const override;
+
+  std::string findLibCxxIncludePath() const override;
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+
+  bool IsUnwindTablesDefault() const override { return true; }
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_NETBSD_H
diff --git a/lib/Driver/ToolChains/OpenBSD.cpp b/lib/Driver/ToolChains/OpenBSD.cpp
new file mode 100644
index 0000000..c5f266e
--- /dev/null
+++ b/lib/Driver/ToolChains/OpenBSD.cpp
@@ -0,0 +1,234 @@
+//===--- OpenBSD.cpp - OpenBSD ToolChain Implementations --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OpenBSD.h"
+#include "Arch/Mips.h"
+#include "Arch/Sparc.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                      const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const ArgList &Args,
+                                      const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  switch (getToolChain().getArch()) {
+  case llvm::Triple::x86:
+    // When building 32-bit code on OpenBSD/amd64, we have to explicitly
+    // instruct as in the base system to assemble 32-bit code.
+    CmdArgs.push_back("--32");
+    break;
+
+  case llvm::Triple::ppc:
+    CmdArgs.push_back("-mppc");
+    CmdArgs.push_back("-many");
+    break;
+
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel: {
+    CmdArgs.push_back("-32");
+    std::string CPU = getCPUName(Args, getToolChain().getTriple());
+    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+
+  case llvm::Triple::sparcv9: {
+    CmdArgs.push_back("-64");
+    std::string CPU = getCPUName(Args, getToolChain().getTriple());
+    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el: {
+    StringRef CPUName;
+    StringRef ABIName;
+    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+
+    CmdArgs.push_back("-mabi");
+    CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
+
+    if (getToolChain().getArch() == llvm::Triple::mips64)
+      CmdArgs.push_back("-EB");
+    else
+      CmdArgs.push_back("-EL");
+
+    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
+    break;
+  }
+
+  default:
+    break;
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                   const InputInfo &Output,
+                                   const InputInfoList &Inputs,
+                                   const ArgList &Args,
+                                   const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (getToolChain().getArch() == llvm::Triple::mips64)
+    CmdArgs.push_back("-EB");
+  else if (getToolChain().getArch() == llvm::Triple::mips64el)
+    CmdArgs.push_back("-EL");
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
+    CmdArgs.push_back("-e");
+    CmdArgs.push_back("__start");
+  }
+
+  CmdArgs.push_back("--eh-frame-hdr");
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    if (Args.hasArg(options::OPT_rdynamic))
+      CmdArgs.push_back("-export-dynamic");
+    CmdArgs.push_back("-Bdynamic");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-shared");
+    } else {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/usr/libexec/ld.so");
+    }
+  }
+
+  if (Args.hasArg(options::OPT_nopie))
+    CmdArgs.push_back("-nopie");
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
+      else if (Args.hasArg(options::OPT_static) &&
+               !Args.hasArg(options::OPT_nopie))
+        CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("rcrt0.o")));
+      else
+        CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
+    } else {
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
+    }
+  }
+
+  std::string Triple = getToolChain().getTripleString();
+  if (Triple.substr(0, 6) == "x86_64")
+    Triple.replace(0, 6, "amd64");
+  CmdArgs.push_back(
+      Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + "/4.2.1"));
+
+  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
+                            options::OPT_e, options::OPT_s, options::OPT_t,
+                            options::OPT_Z_Flag, options::OPT_r});
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    if (D.CCCIsCXX()) {
+      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lm_p");
+      else
+        CmdArgs.push_back("-lm");
+    }
+
+    // FIXME: For some reason GCC passes -lgcc before adding
+    // the default system libraries. Just mimic this for now.
+    CmdArgs.push_back("-lgcc");
+
+    if (Args.hasArg(options::OPT_pthread)) {
+      if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lpthread_p");
+      else
+        CmdArgs.push_back("-lpthread");
+    }
+
+    if (!Args.hasArg(options::OPT_shared)) {
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lc_p");
+      else
+        CmdArgs.push_back("-lc");
+    }
+
+    CmdArgs.push_back("-lgcc");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+    else
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
+  }
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
+
+OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
+                 const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+}
+
+Tool *OpenBSD::buildAssembler() const {
+  return new tools::openbsd::Assembler(*this);
+}
+
+Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
diff --git a/lib/Driver/ToolChains/OpenBSD.h b/lib/Driver/ToolChains/OpenBSD.h
new file mode 100644
index 0000000..1cc0ca7
--- /dev/null
+++ b/lib/Driver/ToolChains/OpenBSD.h
@@ -0,0 +1,76 @@
+//===--- OpenBSD.h - OpenBSD ToolChain Implementations ----------*- 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_LIB_DRIVER_TOOLCHAINS_OPENBSD_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OPENBSD_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+/// openbsd -- Directly call GNU Binutils assembler and linker
+namespace openbsd {
+class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
+public:
+  Assembler(const ToolChain &TC)
+      : GnuTool("openbsd::Assembler", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("openbsd::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace openbsd
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF {
+public:
+  OpenBSD(const Driver &D, const llvm::Triple &Triple,
+          const llvm::opt::ArgList &Args);
+
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
+  bool isPIEDefault() const override { return true; }
+
+  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
+    return 2;
+  }
+  unsigned GetDefaultDwarfVersion() const override { return 2; }
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OPENBSD_H
diff --git a/lib/Driver/ToolChains/PS4CPU.cpp b/lib/Driver/ToolChains/PS4CPU.cpp
new file mode 100644
index 0000000..c1b8c3d
--- /dev/null
+++ b/lib/Driver/ToolChains/PS4CPU.cpp
@@ -0,0 +1,419 @@
+//===--- PS4CPU.cpp - PS4CPU ToolChain Implementations ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PS4CPU.h"
+#include "FreeBSD.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include <cstdlib> // ::getenv
+
+using namespace clang::driver;
+using namespace clang;
+using namespace llvm::opt;
+
+using clang::driver::tools::AddLinkerInputs;
+
+void tools::PS4cpu::addProfileRTArgs(const ToolChain &TC, const ArgList &Args,
+                                     ArgStringList &CmdArgs) {
+  if ((Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
+                    false) ||
+       Args.hasFlag(options::OPT_fprofile_generate,
+                    options::OPT_fno_profile_instr_generate, false) ||
+       Args.hasFlag(options::OPT_fprofile_generate_EQ,
+                    options::OPT_fno_profile_instr_generate, false) ||
+       Args.hasFlag(options::OPT_fprofile_instr_generate,
+                    options::OPT_fno_profile_instr_generate, false) ||
+       Args.hasFlag(options::OPT_fprofile_instr_generate_EQ,
+                    options::OPT_fno_profile_instr_generate, false) ||
+       Args.hasArg(options::OPT_fcreate_profile) ||
+       Args.hasArg(options::OPT_coverage)))
+    CmdArgs.push_back("--dependent-lib=libclang_rt.profile-x86_64.a");
+}
+
+void tools::PS4cpu::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+                                           const InputInfo &Output,
+                                           const InputInfoList &Inputs,
+                                           const ArgList &Args,
+                                           const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
+  const InputInfo &Input = Inputs[0];
+  assert(Input.isFilename() && "Invalid input.");
+  CmdArgs.push_back(Input.getFilename());
+
+  const char *Exec =
+      Args.MakeArgString(getToolChain().GetProgramPath("orbis-as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+static void AddPS4SanitizerArgs(const ToolChain &TC, ArgStringList &CmdArgs) {
+  const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
+  if (SanArgs.needsUbsanRt()) {
+    CmdArgs.push_back("-lSceDbgUBSanitizer_stub_weak");
+  }
+  if (SanArgs.needsAsanRt()) {
+    CmdArgs.push_back("-lSceDbgAddressSanitizer_stub_weak");
+  }
+}
+
+static void ConstructPS4LinkJob(const Tool &T, Compilation &C,
+                                const JobAction &JA, const InputInfo &Output,
+                                const InputInfoList &Inputs,
+                                const ArgList &Args,
+                                const char *LinkingOutput) {
+  const toolchains::FreeBSD &ToolChain =
+      static_cast<const toolchains::FreeBSD &>(T.getToolChain());
+  const Driver &D = ToolChain.getDriver();
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (Args.hasArg(options::OPT_pie))
+    CmdArgs.push_back("-pie");
+
+  if (Args.hasArg(options::OPT_rdynamic))
+    CmdArgs.push_back("-export-dynamic");
+  if (Args.hasArg(options::OPT_shared))
+    CmdArgs.push_back("--oformat=so");
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  AddPS4SanitizerArgs(ToolChain, CmdArgs);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+  Args.AddAllArgs(CmdArgs, options::OPT_s);
+  Args.AddAllArgs(CmdArgs, options::OPT_t);
+  Args.AddAllArgs(CmdArgs, options::OPT_r);
+
+  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+    CmdArgs.push_back("--no-demangle");
+
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+  if (Args.hasArg(options::OPT_pthread)) {
+    CmdArgs.push_back("-lpthread");
+  }
+
+  const char *Exec = Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld"));
+
+  C.addCommand(llvm::make_unique<Command>(JA, T, Exec, CmdArgs, Inputs));
+}
+
+static void ConstructGoldLinkJob(const Tool &T, Compilation &C,
+                                 const JobAction &JA, const InputInfo &Output,
+                                 const InputInfoList &Inputs,
+                                 const ArgList &Args,
+                                 const char *LinkingOutput) {
+  const toolchains::FreeBSD &ToolChain =
+      static_cast<const toolchains::FreeBSD &>(T.getToolChain());
+  const Driver &D = ToolChain.getDriver();
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (Args.hasArg(options::OPT_pie))
+    CmdArgs.push_back("-pie");
+
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    if (Args.hasArg(options::OPT_rdynamic))
+      CmdArgs.push_back("-export-dynamic");
+    CmdArgs.push_back("--eh-frame-hdr");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-Bshareable");
+    } else {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/libexec/ld-elf.so.1");
+    }
+    CmdArgs.push_back("--enable-new-dtags");
+  }
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  AddPS4SanitizerArgs(ToolChain, CmdArgs);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    const char *crt1 = nullptr;
+    if (!Args.hasArg(options::OPT_shared)) {
+      if (Args.hasArg(options::OPT_pg))
+        crt1 = "gcrt1.o";
+      else if (Args.hasArg(options::OPT_pie))
+        crt1 = "Scrt1.o";
+      else
+        crt1 = "crt1.o";
+    }
+    if (crt1)
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
+
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
+
+    const char *crtbegin = nullptr;
+    if (Args.hasArg(options::OPT_static))
+      crtbegin = "crtbeginT.o";
+    else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+      crtbegin = "crtbeginS.o";
+    else
+      crtbegin = "crtbegin.o";
+
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+  Args.AddAllArgs(CmdArgs, options::OPT_s);
+  Args.AddAllArgs(CmdArgs, options::OPT_t);
+  Args.AddAllArgs(CmdArgs, options::OPT_r);
+
+  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+    CmdArgs.push_back("--no-demangle");
+
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    // For PS4, we always want to pass libm, libstdc++ and libkernel
+    // libraries for both C and C++ compilations.
+    CmdArgs.push_back("-lkernel");
+    if (D.CCCIsCXX()) {
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lm_p");
+      else
+        CmdArgs.push_back("-lm");
+    }
+    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
+    // the default system libraries. Just mimic this for now.
+    if (Args.hasArg(options::OPT_pg))
+      CmdArgs.push_back("-lgcc_p");
+    else
+      CmdArgs.push_back("-lcompiler_rt");
+    if (Args.hasArg(options::OPT_static)) {
+      CmdArgs.push_back("-lstdc++");
+    } else if (Args.hasArg(options::OPT_pg)) {
+      CmdArgs.push_back("-lgcc_eh_p");
+    } else {
+      CmdArgs.push_back("--as-needed");
+      CmdArgs.push_back("-lstdc++");
+      CmdArgs.push_back("--no-as-needed");
+    }
+
+    if (Args.hasArg(options::OPT_pthread)) {
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lpthread_p");
+      else
+        CmdArgs.push_back("-lpthread");
+    }
+
+    if (Args.hasArg(options::OPT_pg)) {
+      if (Args.hasArg(options::OPT_shared))
+        CmdArgs.push_back("-lc");
+      else {
+        if (Args.hasArg(options::OPT_static)) {
+          CmdArgs.push_back("--start-group");
+          CmdArgs.push_back("-lc_p");
+          CmdArgs.push_back("-lpthread_p");
+          CmdArgs.push_back("--end-group");
+        } else {
+          CmdArgs.push_back("-lc_p");
+        }
+      }
+      CmdArgs.push_back("-lgcc_p");
+    } else {
+      if (Args.hasArg(options::OPT_static)) {
+        CmdArgs.push_back("--start-group");
+        CmdArgs.push_back("-lc");
+        CmdArgs.push_back("-lpthread");
+        CmdArgs.push_back("--end-group");
+      } else {
+        CmdArgs.push_back("-lc");
+      }
+      CmdArgs.push_back("-lcompiler_rt");
+    }
+
+    if (Args.hasArg(options::OPT_static)) {
+      CmdArgs.push_back("-lstdc++");
+    } else if (Args.hasArg(options::OPT_pg)) {
+      CmdArgs.push_back("-lgcc_eh_p");
+    } else {
+      CmdArgs.push_back("--as-needed");
+      CmdArgs.push_back("-lstdc++");
+      CmdArgs.push_back("--no-as-needed");
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
+    else
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+  }
+
+  const char *Exec =
+#ifdef LLVM_ON_WIN32
+      Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld.gold"));
+#else
+      Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld"));
+#endif
+
+  C.addCommand(llvm::make_unique<Command>(JA, T, Exec, CmdArgs, Inputs));
+}
+
+void tools::PS4cpu::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                                       const InputInfo &Output,
+                                       const InputInfoList &Inputs,
+                                       const ArgList &Args,
+                                       const char *LinkingOutput) const {
+  const toolchains::FreeBSD &ToolChain =
+      static_cast<const toolchains::FreeBSD &>(getToolChain());
+  const Driver &D = ToolChain.getDriver();
+  bool PS4Linker;
+  StringRef LinkerOptName;
+  if (const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
+    LinkerOptName = A->getValue();
+    if (LinkerOptName != "ps4" && LinkerOptName != "gold")
+      D.Diag(diag::err_drv_unsupported_linker) << LinkerOptName;
+  }
+
+  if (LinkerOptName == "gold")
+    PS4Linker = false;
+  else if (LinkerOptName == "ps4")
+    PS4Linker = true;
+  else
+    PS4Linker = !Args.hasArg(options::OPT_shared);
+
+  if (PS4Linker)
+    ConstructPS4LinkJob(*this, C, JA, Output, Inputs, Args, LinkingOutput);
+  else
+    ConstructGoldLinkJob(*this, C, JA, Output, Inputs, Args, LinkingOutput);
+}
+
+toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple,
+                           const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  if (Args.hasArg(clang::driver::options::OPT_static))
+    D.Diag(clang::diag::err_drv_unsupported_opt_for_target) << "-static"
+                                                            << "PS4";
+
+  // Determine where to find the PS4 libraries. We use SCE_ORBIS_SDK_DIR
+  // if it exists; otherwise use the driver's installation path, which
+  // should be <SDK_DIR>/host_tools/bin.
+
+  SmallString<512> PS4SDKDir;
+  if (const char *EnvValue = getenv("SCE_ORBIS_SDK_DIR")) {
+    if (!llvm::sys::fs::exists(EnvValue))
+      getDriver().Diag(clang::diag::warn_drv_ps4_sdk_dir) << EnvValue;
+    PS4SDKDir = EnvValue;
+  } else {
+    PS4SDKDir = getDriver().Dir;
+    llvm::sys::path::append(PS4SDKDir, "/../../");
+  }
+
+  // By default, the driver won't report a warning if it can't find
+  // PS4's include or lib directories. This behavior could be changed if
+  // -Weverything or -Winvalid-or-nonexistent-directory options are passed.
+  // If -isysroot was passed, use that as the SDK base path.
+  std::string PrefixDir;
+  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+    PrefixDir = A->getValue();
+    if (!llvm::sys::fs::exists(PrefixDir))
+      getDriver().Diag(clang::diag::warn_missing_sysroot) << PrefixDir;
+  } else
+    PrefixDir = PS4SDKDir.str();
+
+  SmallString<512> PS4SDKIncludeDir(PrefixDir);
+  llvm::sys::path::append(PS4SDKIncludeDir, "target/include");
+  if (!Args.hasArg(options::OPT_nostdinc) &&
+      !Args.hasArg(options::OPT_nostdlibinc) &&
+      !Args.hasArg(options::OPT_isysroot) &&
+      !Args.hasArg(options::OPT__sysroot_EQ) &&
+      !llvm::sys::fs::exists(PS4SDKIncludeDir)) {
+    getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
+        << "PS4 system headers" << PS4SDKIncludeDir;
+  }
+
+  SmallString<512> PS4SDKLibDir(PS4SDKDir);
+  llvm::sys::path::append(PS4SDKLibDir, "target/lib");
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs) &&
+      !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) &&
+      !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) &&
+      !Args.hasArg(options::OPT_emit_ast) &&
+      !llvm::sys::fs::exists(PS4SDKLibDir)) {
+    getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
+        << "PS4 system libraries" << PS4SDKLibDir;
+    return;
+  }
+  getFilePaths().push_back(PS4SDKLibDir.str());
+}
+
+Tool *toolchains::PS4CPU::buildAssembler() const {
+  return new tools::PS4cpu::Assemble(*this);
+}
+
+Tool *toolchains::PS4CPU::buildLinker() const {
+  return new tools::PS4cpu::Link(*this);
+}
+
+bool toolchains::PS4CPU::isPICDefault() const { return true; }
+
+bool toolchains::PS4CPU::HasNativeLLVMSupport() const { return true; }
+
+SanitizerMask toolchains::PS4CPU::getSupportedSanitizers() const {
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::Address;
+  Res |= SanitizerKind::Vptr;
+  return Res;
+}
diff --git a/lib/Driver/ToolChains/PS4CPU.h b/lib/Driver/ToolChains/PS4CPU.h
new file mode 100644
index 0000000..e507edb
--- /dev/null
+++ b/lib/Driver/ToolChains/PS4CPU.h
@@ -0,0 +1,93 @@
+//===--- PS4CPU.h - PS4CPU ToolChain Implementations ------------*- 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_LIB_DRIVER_TOOLCHAINS_PS4CPU_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PS4CPU_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+namespace PS4cpu {
+
+void addProfileRTArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
+                      llvm::opt::ArgStringList &CmdArgs);
+
+class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
+public:
+  Assemble(const ToolChain &TC)
+      : Tool("PS4cpu::Assemble", "assembler", TC, RF_Full) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output,
+                    const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Link : public Tool {
+public:
+  Link(const ToolChain &TC) : Tool("PS4cpu::Link", "linker", TC, RF_Full) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output,
+                    const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace PS4cpu
+} // namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY PS4CPU : public Generic_ELF {
+public:
+  PS4CPU(const Driver &D, const llvm::Triple &Triple,
+         const llvm::opt::ArgList &Args);
+
+  // No support for finding a C++ standard library yet.
+  std::string findLibCxxIncludePath() const override { return ""; }
+  void addLibStdCxxIncludePaths(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override {}
+
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
+  bool HasNativeLLVMSupport() const override;
+  bool isPICDefault() const override;
+
+  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
+    return 2; // SSPStrong
+  }
+
+  llvm::DebuggerKind getDefaultDebuggerTuning() const override {
+    return llvm::DebuggerKind::SCE;
+  }
+
+  SanitizerMask getSupportedSanitizers() const override;
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PS4CPU_H
diff --git a/lib/Driver/ToolChains/Solaris.cpp b/lib/Driver/ToolChains/Solaris.cpp
new file mode 100644
index 0000000..78797c4
--- /dev/null
+++ b/lib/Driver/ToolChains/Solaris.cpp
@@ -0,0 +1,193 @@
+//===--- Solaris.cpp - Solaris ToolChain Implementations --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Solaris.h"
+#include "CommonArgs.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                      const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const ArgList &Args,
+                                      const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                   const InputInfo &Output,
+                                   const InputInfoList &Inputs,
+                                   const ArgList &Args,
+                                   const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  // Demangle C++ names in errors
+  CmdArgs.push_back("-C");
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
+    CmdArgs.push_back("-e");
+    CmdArgs.push_back("_start");
+  }
+
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+    CmdArgs.push_back("-dn");
+  } else {
+    CmdArgs.push_back("-Bdynamic");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-shared");
+    } else {
+      CmdArgs.push_back("--dynamic-linker");
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("ld.so.1")));
+    }
+  }
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(
+          Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
+
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
+    CmdArgs.push_back(
+        Args.MakeArgString(getToolChain().GetFilePath("values-Xa.o")));
+    CmdArgs.push_back(
+        Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
+  }
+
+  getToolChain().AddFilePathLibArgs(Args, CmdArgs);
+
+  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
+                            options::OPT_e, options::OPT_r});
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    if (getToolChain().getDriver().CCCIsCXX())
+      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+    CmdArgs.push_back("-lgcc_s");
+    CmdArgs.push_back("-lc");
+    if (!Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-lgcc");
+      CmdArgs.push_back("-lm");
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    CmdArgs.push_back(
+        Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+  }
+  CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
+
+  getToolChain().addProfileRTLibs(Args, CmdArgs);
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
+
+Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
+                 const ArgList &Args)
+    : Generic_GCC(D, Triple, Args) {
+
+  GCCInstallation.init(Triple, Args);
+
+  path_list &Paths = getFilePaths();
+  if (GCCInstallation.isValid())
+    addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);
+
+  addPathIfExists(D, getDriver().getInstalledDir(), Paths);
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    addPathIfExists(D, getDriver().Dir, Paths);
+
+  addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);
+
+  std::string LibPath = "/usr/lib/";
+  switch (Triple.getArch()) {
+  case llvm::Triple::x86:
+  case llvm::Triple::sparc:
+    break;
+  case llvm::Triple::x86_64:
+    LibPath += "amd64/";
+    break;
+  case llvm::Triple::sparcv9:
+    LibPath += "sparcv9/";
+    break;
+  default:
+    llvm_unreachable("Unsupported architecture");
+  }
+
+  addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);
+}
+
+Tool *Solaris::buildAssembler() const {
+  return new tools::solaris::Assembler(*this);
+}
+
+Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
+
+void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+                                           ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+      DriverArgs.hasArg(options::OPT_nostdincxx))
+    return;
+
+  // Include the support directory for things like xlocale and fudged system
+  // headers.
+  // FIXME: This is a weird mix of libc++ and libstdc++. We should also be
+  // checking the value of -stdlib= here and adding the includes for libc++
+  // rather than libstdc++ if it's requested.
+  addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris");
+
+  if (GCCInstallation.isValid()) {
+    GCCVersion Version = GCCInstallation.getVersion();
+    addSystemInclude(DriverArgs, CC1Args,
+                     getDriver().SysRoot + "/usr/gcc/" +
+                     Version.MajorStr + "." +
+                     Version.MinorStr +
+                     "/include/c++/" + Version.Text);
+    addSystemInclude(DriverArgs, CC1Args,
+                     getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr +
+                     "." + Version.MinorStr + "/include/c++/" +
+                     Version.Text + "/" +
+                     GCCInstallation.getTriple().str());
+  }
+}
diff --git a/lib/Driver/ToolChains/Solaris.h b/lib/Driver/ToolChains/Solaris.h
new file mode 100644
index 0000000..edb4437
--- /dev/null
+++ b/lib/Driver/ToolChains/Solaris.h
@@ -0,0 +1,75 @@
+//===--- Solaris.h - Solaris ToolChain Implementations ----------*- 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_LIB_DRIVER_TOOLCHAINS_SOLARIS_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SOLARIS_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+/// solaris -- Directly call Solaris assembler and linker
+namespace solaris {
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
+public:
+  Assembler(const ToolChain &TC)
+      : Tool("solaris::Assembler", "assembler", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+public:
+  Linker(const ToolChain &TC) : Tool("solaris::Linker", "linker", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace solaris
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC {
+public:
+  Solaris(const Driver &D, const llvm::Triple &Triple,
+          const llvm::opt::ArgList &Args);
+
+  bool IsIntegratedAssemblerDefault() const override { return true; }
+
+  void AddClangCXXStdlibIncludeArgs(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+
+  unsigned GetDefaultDwarfVersion() const override { return 2; }
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SOLARIS_H
diff --git a/lib/Driver/ToolChains/TCE.cpp b/lib/Driver/ToolChains/TCE.cpp
new file mode 100644
index 0000000..ae8a1c8
--- /dev/null
+++ b/lib/Driver/ToolChains/TCE.cpp
@@ -0,0 +1,47 @@
+//===--- TCE.cpp - TCE ToolChain Implementations ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TCE.h"
+#include "CommonArgs.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
+/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
+/// Currently does not support anything else but compilation.
+
+TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple &Triple,
+                           const ArgList &Args)
+    : ToolChain(D, Triple, Args) {
+  // Path mangling to find libexec
+  std::string Path(getDriver().Dir);
+
+  Path += "/../libexec";
+  getProgramPaths().push_back(Path);
+}
+
+TCEToolChain::~TCEToolChain() {}
+
+bool TCEToolChain::IsMathErrnoDefault() const { return true; }
+
+bool TCEToolChain::isPICDefault() const { return false; }
+
+bool TCEToolChain::isPIEDefault() const { return false; }
+
+bool TCEToolChain::isPICDefaultForced() const { return false; }
+
+TCELEToolChain::TCELEToolChain(const Driver &D, const llvm::Triple& Triple,
+                               const ArgList &Args)
+  : TCEToolChain(D, Triple, Args) {
+}
+
+TCELEToolChain::~TCELEToolChain() {}
diff --git a/lib/Driver/ToolChains/TCE.h b/lib/Driver/ToolChains/TCE.h
new file mode 100644
index 0000000..4644f4e
--- /dev/null
+++ b/lib/Driver/ToolChains/TCE.h
@@ -0,0 +1,47 @@
+//===--- TCE.h - TCE Tool and ToolChain Implementations ---------*- 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_LIB_DRIVER_TOOLCHAINS_TCE_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_TCE_H
+
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/ToolChain.h"
+#include <set>
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
+/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
+class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain {
+public:
+  TCEToolChain(const Driver &D, const llvm::Triple &Triple,
+               const llvm::opt::ArgList &Args);
+  ~TCEToolChain() override;
+
+  bool IsMathErrnoDefault() const override;
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+};
+
+/// Toolchain for little endian TCE cores.
+class LLVM_LIBRARY_VISIBILITY TCELEToolChain : public TCEToolChain {
+public:
+  TCELEToolChain(const Driver &D, const llvm::Triple &Triple,
+                 const llvm::opt::ArgList &Args);
+  ~TCELEToolChain() override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_TCE_H
diff --git a/lib/Driver/ToolChains/WebAssembly.cpp b/lib/Driver/ToolChains/WebAssembly.cpp
new file mode 100644
index 0000000..123a151
--- /dev/null
+++ b/lib/Driver/ToolChains/WebAssembly.cpp
@@ -0,0 +1,163 @@
+//===--- WebAssembly.cpp - WebAssembly ToolChain Implementation -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "WebAssembly.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+wasm::Linker::Linker(const ToolChain &TC)
+  : GnuTool("wasm::Linker", "lld", TC) {}
+
+bool wasm::Linker::isLinkJob() const {
+  return true;
+}
+
+bool wasm::Linker::hasIntegratedCPP() const {
+  return false;
+}
+
+void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                const InputInfo &Output,
+                                const InputInfoList &Inputs,
+                                const ArgList &Args,
+                                const char *LinkingOutput) const {
+
+  const ToolChain &ToolChain = getToolChain();
+  const Driver &D = ToolChain.getDriver();
+  const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
+  ArgStringList CmdArgs;
+  CmdArgs.push_back("-flavor");
+  CmdArgs.push_back("ld");
+
+  // Enable garbage collection of unused input sections by default, since code
+  // size is of particular importance. This is significantly facilitated by
+  // the enabling of -ffunction-sections and -fdata-sections in
+  // Clang::ConstructJob.
+  if (areOptimizationsEnabled(Args))
+    CmdArgs.push_back("--gc-sections");
+
+  if (Args.hasArg(options::OPT_rdynamic))
+    CmdArgs.push_back("-export-dynamic");
+  if (Args.hasArg(options::OPT_s))
+    CmdArgs.push_back("--strip-all");
+  if (Args.hasArg(options::OPT_shared))
+    CmdArgs.push_back("-shared");
+  if (Args.hasArg(options::OPT_static))
+    CmdArgs.push_back("-Bstatic");
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("rcrt1.o")));
+    else if (Args.hasArg(options::OPT_pie))
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o")));
+    else
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt1.o")));
+
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
+  }
+
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+    if (D.CCCIsCXX())
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-lpthread");
+
+    CmdArgs.push_back("-lc");
+    CmdArgs.push_back("-lcompiler_rt");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Linker, CmdArgs, Inputs));
+}
+
+WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
+                         const llvm::opt::ArgList &Args)
+  : ToolChain(D, Triple, Args) {
+
+  assert(Triple.isArch32Bit() != Triple.isArch64Bit());
+  getFilePaths().push_back(
+      getDriver().SysRoot + "/lib" + (Triple.isArch32Bit() ? "32" : "64"));
+}
+
+bool WebAssembly::IsMathErrnoDefault() const { return false; }
+
+bool WebAssembly::IsObjCNonFragileABIDefault() const { return true; }
+
+bool WebAssembly::UseObjCMixedDispatch() const { return true; }
+
+bool WebAssembly::isPICDefault() const { return false; }
+
+bool WebAssembly::isPIEDefault() const { return false; }
+
+bool WebAssembly::isPICDefaultForced() const { return false; }
+
+bool WebAssembly::IsIntegratedAssemblerDefault() const { return true; }
+
+// TODO: Support Objective C stuff.
+bool WebAssembly::SupportsObjCGC() const { return false; }
+
+bool WebAssembly::hasBlocksRuntime() const { return false; }
+
+// TODO: Support profiling.
+bool WebAssembly::SupportsProfiling() const { return false; }
+
+bool WebAssembly::HasNativeLLVMSupport() const { return true; }
+
+void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
+                                        ArgStringList &CC1Args) const {
+  if (DriverArgs.hasFlag(clang::driver::options::OPT_fuse_init_array,
+                         options::OPT_fno_use_init_array, true))
+    CC1Args.push_back("-fuse-init-array");
+}
+
+ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
+  return ToolChain::RLT_CompilerRT;
+}
+
+ToolChain::CXXStdlibType WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
+  return ToolChain::CST_Libcxx;
+}
+
+void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                            ArgStringList &CC1Args) const {
+  if (!DriverArgs.hasArg(options::OPT_nostdinc))
+    addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
+}
+
+void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+                                               ArgStringList &CC1Args) const {
+  if (!DriverArgs.hasArg(options::OPT_nostdlibinc) &&
+      !DriverArgs.hasArg(options::OPT_nostdincxx))
+    addSystemInclude(DriverArgs, CC1Args,
+                     getDriver().SysRoot + "/include/c++/v1");
+}
+
+Tool *WebAssembly::buildLinker() const {
+  return new tools::wasm::Linker(*this);
+}
diff --git a/lib/Driver/ToolChains/WebAssembly.h b/lib/Driver/ToolChains/WebAssembly.h
new file mode 100644
index 0000000..ca42fc6
--- /dev/null
+++ b/lib/Driver/ToolChains/WebAssembly.h
@@ -0,0 +1,77 @@
+//===--- WebAssembly.h - WebAssembly ToolChain Implementations --*- 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_LIB_DRIVER_TOOLCHAINS_WEBASSEMBLY_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_WEBASSEMBLY_H
+
+#include "Gnu.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace wasm {
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  explicit Linker(const ToolChain &TC);
+  bool isLinkJob() const override;
+  bool hasIntegratedCPP() const override;
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+} // end namespace wasm
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY WebAssembly final : public ToolChain {
+public:
+  WebAssembly(const Driver &D, const llvm::Triple &Triple,
+              const llvm::opt::ArgList &Args);
+
+private:
+  bool IsMathErrnoDefault() const override;
+  bool IsObjCNonFragileABIDefault() const override;
+  bool UseObjCMixedDispatch() const override;
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+  bool IsIntegratedAssemblerDefault() const override;
+  bool hasBlocksRuntime() const override;
+  bool SupportsObjCGC() const override;
+  bool SupportsProfiling() const override;
+  bool HasNativeLLVMSupport() const override;
+  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                             llvm::opt::ArgStringList &CC1Args) const override;
+  RuntimeLibType GetDefaultRuntimeLibType() const override;
+  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+  void AddClangSystemIncludeArgs(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  void AddClangCXXStdlibIncludeArgs(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+
+  const char *getDefaultLinker() const override {
+    return "lld";
+  }
+
+  Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_WEBASSEMBLY_H
diff --git a/lib/Driver/ToolChains/XCore.cpp b/lib/Driver/ToolChains/XCore.cpp
new file mode 100644
index 0000000..c3ae958
--- /dev/null
+++ b/lib/Driver/ToolChains/XCore.cpp
@@ -0,0 +1,149 @@
+//===--- XCore.cpp - XCore ToolChain Implementations ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "XCore.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include <cstdlib> // ::getenv
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+/// XCore Tools
+// We pass assemble and link construction to the xcc tool.
+
+void tools::XCore::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                           const InputInfo &Output,
+                                           const InputInfoList &Inputs,
+                                           const ArgList &Args,
+                                           const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  CmdArgs.push_back("-c");
+
+  if (Args.hasArg(options::OPT_v))
+    CmdArgs.push_back("-v");
+
+  if (Arg *A = Args.getLastArg(options::OPT_g_Group))
+    if (!A->getOption().matches(options::OPT_g0))
+      CmdArgs.push_back("-g");
+
+  if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
+                   false))
+    CmdArgs.push_back("-fverbose-asm");
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+void tools::XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                        const InputInfo &Output,
+                                        const InputInfoList &Inputs,
+                                        const ArgList &Args,
+                                        const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (Args.hasArg(options::OPT_v))
+    CmdArgs.push_back("-v");
+
+  // Pass -fexceptions through to the linker if it was present.
+  if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
+                   false))
+    CmdArgs.push_back("-fexceptions");
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+}
+
+/// XCore tool chain
+XCoreToolChain::XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
+                               const ArgList &Args)
+    : ToolChain(D, Triple, Args) {
+  // ProgramPaths are found via 'PATH' environment variable.
+}
+
+Tool *XCoreToolChain::buildAssembler() const {
+  return new tools::XCore::Assembler(*this);
+}
+
+Tool *XCoreToolChain::buildLinker() const {
+  return new tools::XCore::Linker(*this);
+}
+
+bool XCoreToolChain::isPICDefault() const { return false; }
+
+bool XCoreToolChain::isPIEDefault() const { return false; }
+
+bool XCoreToolChain::isPICDefaultForced() const { return false; }
+
+bool XCoreToolChain::SupportsProfiling() const { return false; }
+
+bool XCoreToolChain::hasBlocksRuntime() const { return false; }
+
+void XCoreToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                               ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) ||
+      DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+  if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
+    SmallVector<StringRef, 4> Dirs;
+    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
+    StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
+    ArrayRef<StringRef> DirVec(Dirs);
+    addSystemIncludes(DriverArgs, CC1Args, DirVec);
+  }
+}
+
+void XCoreToolChain::addClangTargetOptions(const ArgList &DriverArgs,
+                                           ArgStringList &CC1Args) const {
+  CC1Args.push_back("-nostdsysteminc");
+}
+
+void XCoreToolChain::AddClangCXXStdlibIncludeArgs(
+    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) ||
+      DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+      DriverArgs.hasArg(options::OPT_nostdincxx))
+    return;
+  if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
+    SmallVector<StringRef, 4> Dirs;
+    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
+    StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
+    ArrayRef<StringRef> DirVec(Dirs);
+    addSystemIncludes(DriverArgs, CC1Args, DirVec);
+  }
+}
+
+void XCoreToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
+                                         ArgStringList &CmdArgs) const {
+  // We don't output any lib args. This is handled by xcc.
+}
diff --git a/lib/Driver/ToolChains/XCore.h b/lib/Driver/ToolChains/XCore.h
new file mode 100644
index 0000000..4084b1c
--- /dev/null
+++ b/lib/Driver/ToolChains/XCore.h
@@ -0,0 +1,82 @@
+//===--- XCore.h - XCore ToolChain Implementations --------------*- 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_LIB_DRIVER_TOOLCHAINS_XCORE_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_XCORE_H
+
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+
+namespace XCore {
+// For XCore, we do not need to instantiate tools for PreProcess, PreCompile and
+// Compile.
+// We simply use "clang -cc1" for those actions.
+class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
+public:
+  Assembler(const ToolChain &TC) : Tool("XCore::Assembler", "XCore-as", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+public:
+  Linker(const ToolChain &TC) : Tool("XCore::Linker", "XCore-ld", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace XCore.
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY XCoreToolChain : public ToolChain {
+public:
+  XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
+                 const llvm::opt::ArgList &Args);
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+
+public:
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+  bool SupportsProfiling() const override;
+  bool hasBlocksRuntime() const override;
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                             llvm::opt::ArgStringList &CC1Args) const override;
+  void AddClangCXXStdlibIncludeArgs(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_XCORE_H
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
deleted file mode 100644
index 661e6f4..0000000
--- a/lib/Driver/Tools.cpp
+++ /dev/null
@@ -1,12124 +0,0 @@
-//===--- Tools.cpp - Tools Implementations ----------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Tools.h"
-#include "InputInfo.h"
-#include "ToolChains.h"
-#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/ObjCRuntime.h"
-#include "clang/Basic/Version.h"
-#include "clang/Config/config.h"
-#include "clang/Driver/Action.h"
-#include "clang/Driver/Compilation.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/Job.h"
-#include "clang/Driver/Options.h"
-#include "clang/Driver/SanitizerArgs.h"
-#include "clang/Driver/ToolChain.h"
-#include "clang/Driver/Util.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/CodeGen.h"
-#include "llvm/Support/Compression.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/Program.h"
-#include "llvm/Support/ScopedPrinter.h"
-#include "llvm/Support/TargetParser.h"
-#include "llvm/Support/YAMLParser.h"
-
-#ifdef LLVM_ON_UNIX
-#include <unistd.h> // For getuid().
-#endif
-
-using namespace clang::driver;
-using namespace clang::driver::tools;
-using namespace clang;
-using namespace llvm::opt;
-
-static void handleTargetFeaturesGroup(const ArgList &Args,
-                                      std::vector<StringRef> &Features,
-                                      OptSpecifier Group) {
-  for (const Arg *A : Args.filtered(Group)) {
-    StringRef Name = A->getOption().getName();
-    A->claim();
-
-    // Skip over "-m".
-    assert(Name.startswith("m") && "Invalid feature name.");
-    Name = Name.substr(1);
-
-    bool IsNegative = Name.startswith("no-");
-    if (IsNegative)
-      Name = Name.substr(3);
-    Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
-  }
-}
-
-static const char *getSparcAsmModeForCPU(StringRef Name,
-                                         const llvm::Triple &Triple) {
-  if (Triple.getArch() == llvm::Triple::sparcv9) {
-    return llvm::StringSwitch<const char *>(Name)
-          .Case("niagara", "-Av9b")
-          .Case("niagara2", "-Av9b")
-          .Case("niagara3", "-Av9d")
-          .Case("niagara4", "-Av9d")
-          .Default("-Av9");
-  } else {
-    return llvm::StringSwitch<const char *>(Name)
-          .Case("v8", "-Av8")
-          .Case("supersparc", "-Av8")
-          .Case("sparclite", "-Asparclite")
-          .Case("f934", "-Asparclite")
-          .Case("hypersparc", "-Av8")
-          .Case("sparclite86x", "-Asparclite")
-          .Case("sparclet", "-Asparclet")
-          .Case("tsc701", "-Asparclet")
-          .Case("v9", "-Av8plus")
-          .Case("ultrasparc", "-Av8plus")
-          .Case("ultrasparc3", "-Av8plus")
-          .Case("niagara", "-Av8plusb")
-          .Case("niagara2", "-Av8plusb")
-          .Case("niagara3", "-Av8plusd")
-          .Case("niagara4", "-Av8plusd")
-          .Case("leon2", "-Av8")
-          .Case("at697e", "-Av8")
-          .Case("at697f", "-Av8")
-          .Case("leon3", "-Av8")
-          .Case("ut699", "-Av8")
-          .Case("gr712rc", "-Av8")
-          .Case("leon4", "-Av8")
-          .Case("gr740", "-Av8")
-          .Default("-Av8");
-  }
-}
-
-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) && !Args.hasArg(options::OPT__SLASH_P) &&
-        !Args.hasArg(options::OPT__SLASH_EP) && !D.CCCIsCPP()) {
-      D.Diag(diag::err_drv_argument_only_allowed_with)
-          << A->getBaseArg().getAsString(Args)
-          << (D.IsCLMode() ? "/E, /P or /EP" : "-E");
-    }
-  }
-}
-
-static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
-  // In gcc, only ARM checks this, but it seems reasonable to check universally.
-  if (Args.hasArg(options::OPT_static))
-    if (const Arg *A =
-            Args.getLastArg(options::OPT_dynamic, options::OPT_mdynamic_no_pic))
-      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
-                                                      << "-static";
-}
-
-// Add backslashes to escape spaces and other backslashes.
-// This is used for the space-separated argument list specified with
-// the -dwarf-debug-flags option.
-static void EscapeSpacesAndBackslashes(const char *Arg,
-                                       SmallVectorImpl<char> &Res) {
-  for (; *Arg; ++Arg) {
-    switch (*Arg) {
-    default:
-      break;
-    case ' ':
-    case '\\':
-      Res.push_back('\\');
-      break;
-    }
-    Res.push_back(*Arg);
-  }
-}
-
-// Quote target names for inclusion in GNU Make dependency files.
-// Only the characters '$', '#', ' ', '\t' are quoted.
-static void QuoteTarget(StringRef Target, SmallVectorImpl<char> &Res) {
-  for (unsigned i = 0, e = Target.size(); i != e; ++i) {
-    switch (Target[i]) {
-    case ' ':
-    case '\t':
-      // Escape the preceding backslashes
-      for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
-        Res.push_back('\\');
-
-      // Escape the space/tab
-      Res.push_back('\\');
-      break;
-    case '$':
-      Res.push_back('$');
-      break;
-    case '#':
-      Res.push_back('\\');
-      break;
-    default:
-      break;
-    }
-
-    Res.push_back(Target[i]);
-  }
-}
-
-static void addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs,
-                             const char *ArgName, const char *EnvVar) {
-  const char *DirList = ::getenv(EnvVar);
-  bool CombinedArg = false;
-
-  if (!DirList)
-    return; // Nothing to do.
-
-  StringRef Name(ArgName);
-  if (Name.equals("-I") || Name.equals("-L"))
-    CombinedArg = true;
-
-  StringRef Dirs(DirList);
-  if (Dirs.empty()) // Empty string should not add '.'.
-    return;
-
-  StringRef::size_type Delim;
-  while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) {
-    if (Delim == 0) { // Leading colon.
-      if (CombinedArg) {
-        CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
-      } else {
-        CmdArgs.push_back(ArgName);
-        CmdArgs.push_back(".");
-      }
-    } else {
-      if (CombinedArg) {
-        CmdArgs.push_back(
-            Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
-      } else {
-        CmdArgs.push_back(ArgName);
-        CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
-      }
-    }
-    Dirs = Dirs.substr(Delim + 1);
-  }
-
-  if (Dirs.empty()) { // Trailing colon.
-    if (CombinedArg) {
-      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
-    } else {
-      CmdArgs.push_back(ArgName);
-      CmdArgs.push_back(".");
-    }
-  } else { // Add the last path.
-    if (CombinedArg) {
-      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
-    } else {
-      CmdArgs.push_back(ArgName);
-      CmdArgs.push_back(Args.MakeArgString(Dirs));
-    }
-  }
-}
-
-static void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
-                            const ArgList &Args, ArgStringList &CmdArgs,
-                            const JobAction &JA) {
-  const Driver &D = TC.getDriver();
-
-  // Add extra linker input arguments which are not treated as inputs
-  // (constructed via -Xarch_).
-  Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
-
-  for (const auto &II : Inputs) {
-    // If the current tool chain refers to an OpenMP offloading host, we should
-    // ignore inputs that refer to OpenMP offloading devices - they will be
-    // embedded according to a proper linker script.
-    if (auto *IA = II.getAction())
-      if (JA.isHostOffloading(Action::OFK_OpenMP) &&
-          IA->isDeviceOffloading(Action::OFK_OpenMP))
-        continue;
-
-    if (!TC.HasNativeLLVMSupport() && types::isLLVMIR(II.getType()))
-      // Don't try to pass LLVM inputs unless we have native support.
-      D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString();
-
-    // Add filenames immediately.
-    if (II.isFilename()) {
-      CmdArgs.push_back(II.getFilename());
-      continue;
-    }
-
-    // Otherwise, this is a linker input argument.
-    const Arg &A = II.getInputArg();
-
-    // Handle reserved library options.
-    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))
-      TC.AddCCKextLibArgs(Args, CmdArgs);
-    else if (A.getOption().matches(options::OPT_z)) {
-      // Pass -z prefix for gcc linker compatibility.
-      A.claim();
-      A.render(Args, CmdArgs);
-    } else {
-      A.renderAsInput(Args, CmdArgs);
-    }
-  }
-
-  // LIBRARY_PATH - included following the user specified library paths.
-  //                and only supported on native toolchains.
-  if (!TC.isCrossCompiling())
-    addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
-}
-
-/// Add OpenMP linker script arguments at the end of the argument list so that
-/// the fat binary is built by embedding each of the device images into the
-/// host. The linker script also defines a few symbols required by the code
-/// generation so that the images can be easily retrieved at runtime by the
-/// offloading library. This should be used only in tool chains that support
-/// linker scripts.
-static void AddOpenMPLinkerScript(const ToolChain &TC, Compilation &C,
-                                  const InputInfo &Output,
-                                  const InputInfoList &Inputs,
-                                  const ArgList &Args, ArgStringList &CmdArgs,
-                                  const JobAction &JA) {
-
-  // If this is not an OpenMP host toolchain, we don't need to do anything.
-  if (!JA.isHostOffloading(Action::OFK_OpenMP))
-    return;
-
-  // Create temporary linker script. Keep it if save-temps is enabled.
-  const char *LKS;
-  SmallString<256> Name = llvm::sys::path::filename(Output.getFilename());
-  if (C.getDriver().isSaveTempsEnabled()) {
-    llvm::sys::path::replace_extension(Name, "lk");
-    LKS = C.getArgs().MakeArgString(Name.c_str());
-  } else {
-    llvm::sys::path::replace_extension(Name, "");
-    Name = C.getDriver().GetTemporaryPath(Name, "lk");
-    LKS = C.addTempFile(C.getArgs().MakeArgString(Name.c_str()));
-  }
-
-  // Add linker script option to the command.
-  CmdArgs.push_back("-T");
-  CmdArgs.push_back(LKS);
-
-  // Create a buffer to write the contents of the linker script.
-  std::string LksBuffer;
-  llvm::raw_string_ostream LksStream(LksBuffer);
-
-  // Get the OpenMP offload tool chains so that we can extract the triple
-  // associated with each device input.
-  auto OpenMPToolChains = C.getOffloadToolChains<Action::OFK_OpenMP>();
-  assert(OpenMPToolChains.first != OpenMPToolChains.second &&
-         "No OpenMP toolchains??");
-
-  // Track the input file name and device triple in order to build the script,
-  // inserting binaries in the designated sections.
-  SmallVector<std::pair<std::string, const char *>, 8> InputBinaryInfo;
-
-  // Add commands to embed target binaries. We ensure that each section and
-  // image is 16-byte aligned. This is not mandatory, but increases the
-  // likelihood of data to be aligned with a cache block in several main host
-  // machines.
-  LksStream << "/*\n";
-  LksStream << "       OpenMP Offload Linker Script\n";
-  LksStream << " *** Automatically generated by Clang ***\n";
-  LksStream << "*/\n";
-  LksStream << "TARGET(binary)\n";
-  auto DTC = OpenMPToolChains.first;
-  for (auto &II : Inputs) {
-    const Action *A = II.getAction();
-    // Is this a device linking action?
-    if (A && isa<LinkJobAction>(A) &&
-        A->isDeviceOffloading(Action::OFK_OpenMP)) {
-      assert(DTC != OpenMPToolChains.second &&
-             "More device inputs than device toolchains??");
-      InputBinaryInfo.push_back(std::make_pair(
-          DTC->second->getTriple().normalize(), II.getFilename()));
-      ++DTC;
-      LksStream << "INPUT(" << II.getFilename() << ")\n";
-    }
-  }
-
-  assert(DTC == OpenMPToolChains.second &&
-         "Less device inputs than device toolchains??");
-
-  LksStream << "SECTIONS\n";
-  LksStream << "{\n";
-  LksStream << "  .omp_offloading :\n";
-  LksStream << "  ALIGN(0x10)\n";
-  LksStream << "  {\n";
-
-  for (auto &BI : InputBinaryInfo) {
-    LksStream << "    . = ALIGN(0x10);\n";
-    LksStream << "    PROVIDE_HIDDEN(.omp_offloading.img_start." << BI.first
-              << " = .);\n";
-    LksStream << "    " << BI.second << "\n";
-    LksStream << "    PROVIDE_HIDDEN(.omp_offloading.img_end." << BI.first
-              << " = .);\n";
-  }
-
-  LksStream << "  }\n";
-  // Add commands to define host entries begin and end. We use 1-byte subalign
-  // so that the linker does not add any padding and the elements in this
-  // section form an array.
-  LksStream << "  .omp_offloading.entries :\n";
-  LksStream << "  ALIGN(0x10)\n";
-  LksStream << "  SUBALIGN(0x01)\n";
-  LksStream << "  {\n";
-  LksStream << "    PROVIDE_HIDDEN(.omp_offloading.entries_begin = .);\n";
-  LksStream << "    *(.omp_offloading.entries)\n";
-  LksStream << "    PROVIDE_HIDDEN(.omp_offloading.entries_end = .);\n";
-  LksStream << "  }\n";
-  LksStream << "}\n";
-  LksStream << "INSERT BEFORE .data\n";
-  LksStream.flush();
-
-  // Dump the contents of the linker script if the user requested that. We
-  // support this option to enable testing of behavior with -###.
-  if (C.getArgs().hasArg(options::OPT_fopenmp_dump_offload_linker_script))
-    llvm::errs() << LksBuffer;
-
-  // If this is a dry run, do not create the linker script file.
-  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
-    return;
-
-  // Open script file and write the contents.
-  std::error_code EC;
-  llvm::raw_fd_ostream Lksf(LKS, EC, llvm::sys::fs::F_None);
-
-  if (EC) {
-    C.getDriver().Diag(clang::diag::err_unable_to_make_temp) << EC.message();
-    return;
-  }
-
-  Lksf << LksBuffer;
-}
-
-/// \brief Determine whether Objective-C automated reference counting is
-/// enabled.
-static bool isObjCAutoRefCount(const ArgList &Args) {
-  return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
-}
-
-/// \brief Determine whether we are linking the ObjC runtime.
-static bool isObjCRuntimeLinked(const ArgList &Args) {
-  if (isObjCAutoRefCount(Args)) {
-    Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
-    return true;
-  }
-  return Args.hasArg(options::OPT_fobjc_link_runtime);
-}
-
-static bool forwardToGCC(const Option &O) {
-  // Don't forward inputs from the original command line.  They are added from
-  // InputInfoList.
-  return O.getKind() != Option::InputClass &&
-         !O.hasFlag(options::DriverOption) && !O.hasFlag(options::LinkerInput);
-}
-
-/// Apply \a Work on the current tool chain \a RegularToolChain and any other
-/// offloading tool chain that is associated with the current action \a JA.
-static void
-forAllAssociatedToolChains(Compilation &C, const JobAction &JA,
-                           const ToolChain &RegularToolChain,
-                           llvm::function_ref<void(const ToolChain &)> Work) {
-  // Apply Work on the current/regular tool chain.
-  Work(RegularToolChain);
-
-  // Apply Work on all the offloading tool chains associated with the current
-  // action.
-  if (JA.isHostOffloading(Action::OFK_Cuda))
-    Work(*C.getSingleOffloadToolChain<Action::OFK_Cuda>());
-  else if (JA.isDeviceOffloading(Action::OFK_Cuda))
-    Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
-
-  //
-  // TODO: Add support for other offloading programming models here.
-  //
-}
-
-void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
-                                    const Driver &D, const ArgList &Args,
-                                    ArgStringList &CmdArgs,
-                                    const InputInfo &Output,
-                                    const InputInfoList &Inputs) const {
-  Arg *A;
-  const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
-
-  CheckPreprocessingOptions(D, Args);
-
-  Args.AddLastArg(CmdArgs, options::OPT_C);
-  Args.AddLastArg(CmdArgs, options::OPT_CC);
-
-  // Handle dependency file generation.
-  if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) ||
-      (A = Args.getLastArg(options::OPT_MD)) ||
-      (A = Args.getLastArg(options::OPT_MMD))) {
-    // Determine the output location.
-    const char *DepFile;
-    if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
-      DepFile = MF->getValue();
-      C.addFailureResultFile(DepFile, &JA);
-    } else if (Output.getType() == types::TY_Dependencies) {
-      DepFile = Output.getFilename();
-    } else if (A->getOption().matches(options::OPT_M) ||
-               A->getOption().matches(options::OPT_MM)) {
-      DepFile = "-";
-    } else {
-      DepFile = getDependencyFileName(Args, Inputs);
-      C.addFailureResultFile(DepFile, &JA);
-    }
-    CmdArgs.push_back("-dependency-file");
-    CmdArgs.push_back(DepFile);
-
-    // Add a default target if one wasn't specified.
-    if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
-      const char *DepTarget;
-
-      // If user provided -o, that is the dependency target, except
-      // when we are only generating a dependency file.
-      Arg *OutputOpt = Args.getLastArg(options::OPT_o);
-      if (OutputOpt && Output.getType() != types::TY_Dependencies) {
-        DepTarget = OutputOpt->getValue();
-      } else {
-        // Otherwise derive from the base input.
-        //
-        // FIXME: This should use the computed output file location.
-        SmallString<128> P(Inputs[0].getBaseInput());
-        llvm::sys::path::replace_extension(P, "o");
-        DepTarget = Args.MakeArgString(llvm::sys::path::filename(P));
-      }
-
-      CmdArgs.push_back("-MT");
-      SmallString<128> Quoted;
-      QuoteTarget(DepTarget, Quoted);
-      CmdArgs.push_back(Args.MakeArgString(Quoted));
-    }
-
-    if (A->getOption().matches(options::OPT_M) ||
-        A->getOption().matches(options::OPT_MD))
-      CmdArgs.push_back("-sys-header-deps");
-    if ((isa<PrecompileJobAction>(JA) &&
-         !Args.hasArg(options::OPT_fno_module_file_deps)) ||
-        Args.hasArg(options::OPT_fmodule_file_deps))
-      CmdArgs.push_back("-module-file-deps");
-  }
-
-  if (Args.hasArg(options::OPT_MG)) {
-    if (!A || A->getOption().matches(options::OPT_MD) ||
-        A->getOption().matches(options::OPT_MMD))
-      D.Diag(diag::err_drv_mg_requires_m_or_mm);
-    CmdArgs.push_back("-MG");
-  }
-
-  Args.AddLastArg(CmdArgs, options::OPT_MP);
-  Args.AddLastArg(CmdArgs, options::OPT_MV);
-
-  // Convert all -MQ <target> args to -MT <quoted target>
-  for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) {
-    A->claim();
-
-    if (A->getOption().matches(options::OPT_MQ)) {
-      CmdArgs.push_back("-MT");
-      SmallString<128> Quoted;
-      QuoteTarget(A->getValue(), Quoted);
-      CmdArgs.push_back(Args.MakeArgString(Quoted));
-
-      // -MT flag - no change
-    } else {
-      A->render(Args, CmdArgs);
-    }
-  }
-
-  // Add offload include arguments specific for CUDA.  This must happen before
-  // we -I or -include anything else, because we must pick up the CUDA headers
-  // from the particular CUDA installation, rather than from e.g.
-  // /usr/local/include.
-  if (JA.isOffloading(Action::OFK_Cuda))
-    getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
-
-  // Add -i* options, and automatically translate to
-  // -include-pch/-include-pth for transparent PCH support. It's
-  // wonky, but we include looking for .gch so we can support seamless
-  // replacement into a build system already set up to be generating
-  // .gch files.
-  int YcIndex = -1, YuIndex = -1;
-  {
-    int AI = -1;
-    const Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
-    const Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
-    for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) {
-      // Walk the whole i_Group and skip non "-include" flags so that the index
-      // here matches the index in the next loop below.
-      ++AI;
-      if (!A->getOption().matches(options::OPT_include))
-        continue;
-      if (YcArg && strcmp(A->getValue(), YcArg->getValue()) == 0)
-        YcIndex = AI;
-      if (YuArg && strcmp(A->getValue(), YuArg->getValue()) == 0)
-        YuIndex = AI;
-    }
-  }
-  if (isa<PrecompileJobAction>(JA) && YcIndex != -1) {
-    Driver::InputList Inputs;
-    D.BuildInputs(getToolChain(), C.getArgs(), Inputs);
-    assert(Inputs.size() == 1 && "Need one input when building pch");
-    CmdArgs.push_back(Args.MakeArgString(Twine("-find-pch-source=") +
-                                         Inputs[0].second->getValue()));
-  }
-
-  bool RenderedImplicitInclude = false;
-  int AI = -1;
-  for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) {
-    ++AI;
-
-    if (getToolChain().getDriver().IsCLMode() &&
-        A->getOption().matches(options::OPT_include)) {
-      // In clang-cl mode, /Ycfoo.h means that all code up to a foo.h
-      // include is compiled into foo.h, and everything after goes into
-      // the .obj file. /Yufoo.h means that all includes prior to and including
-      // foo.h are completely skipped and replaced with a use of the pch file
-      // for foo.h.  (Each flag can have at most one value, multiple /Yc flags
-      // just mean that the last one wins.)  If /Yc and /Yu are both present
-      // and refer to the same file, /Yc wins.
-      // Note that OPT__SLASH_FI gets mapped to OPT_include.
-      // FIXME: The code here assumes that /Yc and /Yu refer to the same file.
-      // cl.exe seems to support both flags with different values, but that
-      // seems strange (which flag does /Fp now refer to?), so don't implement
-      // that until someone needs it.
-      int PchIndex = YcIndex != -1 ? YcIndex : YuIndex;
-      if (PchIndex != -1) {
-        if (isa<PrecompileJobAction>(JA)) {
-          // When building the pch, skip all includes after the pch.
-          assert(YcIndex != -1 && PchIndex == YcIndex);
-          if (AI >= YcIndex)
-            continue;
-        } else {
-          // When using the pch, skip all includes prior to the pch.
-          if (AI < PchIndex) {
-            A->claim();
-            continue;
-          }
-          if (AI == PchIndex) {
-            A->claim();
-            CmdArgs.push_back("-include-pch");
-            CmdArgs.push_back(
-                Args.MakeArgString(D.GetClPchPath(C, A->getValue())));
-            continue;
-          }
-        }
-      }
-    } else if (A->getOption().matches(options::OPT_include)) {
-      // Handling of gcc-style gch precompiled headers.
-      bool IsFirstImplicitInclude = !RenderedImplicitInclude;
-      RenderedImplicitInclude = true;
-
-      // Use PCH if the user requested it.
-      bool UsePCH = D.CCCUsePCH;
-
-      bool FoundPTH = false;
-      bool FoundPCH = false;
-      SmallString<128> P(A->getValue());
-      // We want the files to have a name like foo.h.pch. Add a dummy extension
-      // so that replace_extension does the right thing.
-      P += ".dummy";
-      if (UsePCH) {
-        llvm::sys::path::replace_extension(P, "pch");
-        if (llvm::sys::fs::exists(P))
-          FoundPCH = true;
-      }
-
-      if (!FoundPCH) {
-        llvm::sys::path::replace_extension(P, "pth");
-        if (llvm::sys::fs::exists(P))
-          FoundPTH = true;
-      }
-
-      if (!FoundPCH && !FoundPTH) {
-        llvm::sys::path::replace_extension(P, "gch");
-        if (llvm::sys::fs::exists(P)) {
-          FoundPCH = UsePCH;
-          FoundPTH = !UsePCH;
-        }
-      }
-
-      if (FoundPCH || FoundPTH) {
-        if (IsFirstImplicitInclude) {
-          A->claim();
-          if (UsePCH)
-            CmdArgs.push_back("-include-pch");
-          else
-            CmdArgs.push_back("-include-pth");
-          CmdArgs.push_back(Args.MakeArgString(P));
-          continue;
-        } else {
-          // Ignore the PCH if not first on command line and emit warning.
-          D.Diag(diag::warn_drv_pch_not_first_include) << P
-                                                       << A->getAsString(Args);
-        }
-      }
-    } else if (A->getOption().matches(options::OPT_isystem_after)) {
-      // Handling of paths which must come late.  These entries are handled by
-      // the toolchain itself after the resource dir is inserted in the right
-      // search order.
-      // Do not claim the argument so that the use of the argument does not
-      // silently go unnoticed on toolchains which do not honour the option.
-      continue;
-    }
-
-    // Not translated, render as usual.
-    A->claim();
-    A->render(Args, CmdArgs);
-  }
-
-  Args.AddAllArgs(CmdArgs,
-                  {options::OPT_D, options::OPT_U, options::OPT_I_Group,
-                   options::OPT_F, options::OPT_index_header_map});
-
-  // Add -Wp, and -Xpreprocessor if using the preprocessor.
-
-  // FIXME: There is a very unfortunate problem here, some troubled
-  // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
-  // really support that we would have to parse and then translate
-  // those options. :(
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
-                       options::OPT_Xpreprocessor);
-
-  // -I- is a deprecated GCC feature, reject it.
-  if (Arg *A = Args.getLastArg(options::OPT_I_))
-    D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
-
-  // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
-  // -isysroot to the CC1 invocation.
-  StringRef sysroot = C.getSysRoot();
-  if (sysroot != "") {
-    if (!Args.hasArg(options::OPT_isysroot)) {
-      CmdArgs.push_back("-isysroot");
-      CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
-    }
-  }
-
-  // Parse additional include paths from environment variables.
-  // FIXME: We should probably sink the logic for handling these from the
-  // frontend into the driver. It will allow deleting 4 otherwise unused flags.
-  // CPATH - included following the user specified includes (but prior to
-  // builtin and standard includes).
-  addDirectoryList(Args, CmdArgs, "-I", "CPATH");
-  // C_INCLUDE_PATH - system includes enabled when compiling C.
-  addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH");
-  // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
-  addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
-  // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
-  addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH");
-  // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
-  addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
-
-  // While adding the include arguments, we also attempt to retrieve the
-  // arguments of related offloading toolchains or arguments that are specific
-  // of an offloading programming model.
-
-  // Add C++ include arguments, if needed.
-  if (types::isCXX(Inputs[0].getType()))
-    forAllAssociatedToolChains(C, JA, getToolChain(),
-                               [&Args, &CmdArgs](const ToolChain &TC) {
-                                 TC.AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
-                               });
-
-  // Add system include arguments for all targets but IAMCU.
-  if (!IsIAMCU)
-    forAllAssociatedToolChains(C, JA, getToolChain(),
-                               [&Args, &CmdArgs](const ToolChain &TC) {
-                                 TC.AddClangSystemIncludeArgs(Args, CmdArgs);
-                               });
-  else {
-    // For IAMCU add special include arguments.
-    getToolChain().AddIAMCUIncludeArgs(Args, CmdArgs);
-  }
-}
-
-// FIXME: Move to target hook.
-static bool isSignedCharDefault(const llvm::Triple &Triple) {
-  switch (Triple.getArch()) {
-  default:
-    return true;
-
-  case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_be:
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb:
-    if (Triple.isOSDarwin() || Triple.isOSWindows())
-      return true;
-    return false;
-
-  case llvm::Triple::ppc:
-  case llvm::Triple::ppc64:
-    if (Triple.isOSDarwin())
-      return true;
-    return false;
-
-  case llvm::Triple::hexagon:
-  case llvm::Triple::ppc64le:
-  case llvm::Triple::systemz:
-  case llvm::Triple::xcore:
-    return false;
-  }
-}
-
-static bool isNoCommonDefault(const llvm::Triple &Triple) {
-  switch (Triple.getArch()) {
-  default:
-    return false;
-
-  case llvm::Triple::xcore:
-  case llvm::Triple::wasm32:
-  case llvm::Triple::wasm64:
-    return true;
-  }
-}
-
-// ARM tools start.
-
-// Get SubArch (vN).
-static int getARMSubArchVersionNumber(const llvm::Triple &Triple) {
-  llvm::StringRef Arch = Triple.getArchName();
-  return llvm::ARM::parseArchVersion(Arch);
-}
-
-// True if M-profile.
-static bool isARMMProfile(const llvm::Triple &Triple) {
-  llvm::StringRef Arch = Triple.getArchName();
-  unsigned Profile = llvm::ARM::parseArchProfile(Arch);
-  return Profile == llvm::ARM::PK_M;
-}
-
-// Get Arch/CPU from args.
-static void getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
-                                  llvm::StringRef &CPU, bool FromAs = false) {
-  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
-    CPU = A->getValue();
-  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
-    Arch = A->getValue();
-  if (!FromAs)
-    return;
-
-  for (const Arg *A :
-       Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
-    StringRef Value = A->getValue();
-    if (Value.startswith("-mcpu="))
-      CPU = Value.substr(6);
-    if (Value.startswith("-march="))
-      Arch = Value.substr(7);
-  }
-}
-
-// Handle -mhwdiv=.
-// FIXME: Use ARMTargetParser.
-static void getARMHWDivFeatures(const Driver &D, const Arg *A,
-                                const ArgList &Args, StringRef HWDiv,
-                                std::vector<StringRef> &Features) {
-  unsigned HWDivID = llvm::ARM::parseHWDiv(HWDiv);
-  if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
-    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
-// Handle -mfpu=.
-static void getARMFPUFeatures(const Driver &D, const Arg *A,
-                              const ArgList &Args, StringRef FPU,
-                              std::vector<StringRef> &Features) {
-  unsigned FPUID = llvm::ARM::parseFPU(FPU);
-  if (!llvm::ARM::getFPUFeatures(FPUID, Features))
-    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
-// Decode ARM features from string like +[no]featureA+[no]featureB+...
-static bool DecodeARMFeatures(const Driver &D, StringRef text,
-                              std::vector<StringRef> &Features) {
-  SmallVector<StringRef, 8> Split;
-  text.split(Split, StringRef("+"), -1, false);
-
-  for (StringRef Feature : Split) {
-    StringRef FeatureName = llvm::ARM::getArchExtFeature(Feature);
-    if (!FeatureName.empty())
-      Features.push_back(FeatureName);
-    else
-      return false;
-  }
-  return true;
-}
-
-// Check if -march is valid by checking if it can be canonicalised and parsed.
-// getARMArch is used here instead of just checking the -march value in order
-// to handle -march=native correctly.
-static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
-                             llvm::StringRef ArchName,
-                             std::vector<StringRef> &Features,
-                             const llvm::Triple &Triple) {
-  std::pair<StringRef, StringRef> Split = ArchName.split("+");
-
-  std::string MArch = arm::getARMArch(ArchName, Triple);
-  if (llvm::ARM::parseArch(MArch) == llvm::ARM::AK_INVALID ||
-      (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
-    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
-// Check -mcpu=. Needs ArchName to handle -mcpu=generic.
-static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args,
-                            llvm::StringRef CPUName, llvm::StringRef ArchName,
-                            std::vector<StringRef> &Features,
-                            const llvm::Triple &Triple) {
-  std::pair<StringRef, StringRef> Split = CPUName.split("+");
-
-  std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
-  if (arm::getLLVMArchSuffixForARM(CPU, ArchName, Triple).empty() ||
-      (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
-    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
-static bool useAAPCSForMachO(const llvm::Triple &T) {
-  // The backend is hardwired to assume AAPCS for M-class processors, ensure
-  // the frontend matches that.
-  return T.getEnvironment() == llvm::Triple::EABI ||
-         T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
-}
-
-// Select the float ABI as determined by -msoft-float, -mhard-float, and
-// -mfloat-abi=.
-arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
-  const Driver &D = TC.getDriver();
-  const llvm::Triple &Triple = TC.getEffectiveTriple();
-  auto SubArch = getARMSubArchVersionNumber(Triple);
-  arm::FloatABI ABI = FloatABI::Invalid;
-  if (Arg *A =
-          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
-                          options::OPT_mfloat_abi_EQ)) {
-    if (A->getOption().matches(options::OPT_msoft_float)) {
-      ABI = FloatABI::Soft;
-    } else if (A->getOption().matches(options::OPT_mhard_float)) {
-      ABI = FloatABI::Hard;
-    } else {
-      ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
-                .Case("soft", FloatABI::Soft)
-                .Case("softfp", FloatABI::SoftFP)
-                .Case("hard", FloatABI::Hard)
-                .Default(FloatABI::Invalid);
-      if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
-        D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
-        ABI = FloatABI::Soft;
-      }
-    }
-
-    // It is incorrect to select hard float ABI on MachO platforms if the ABI is
-    // "apcs-gnu".
-    if (Triple.isOSBinFormatMachO() && !useAAPCSForMachO(Triple) &&
-        ABI == FloatABI::Hard) {
-      D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args)
-                                                       << Triple.getArchName();
-    }
-  }
-
-  // If unspecified, choose the default based on the platform.
-  if (ABI == FloatABI::Invalid) {
-    switch (Triple.getOS()) {
-    case llvm::Triple::Darwin:
-    case llvm::Triple::MacOSX:
-    case llvm::Triple::IOS:
-    case llvm::Triple::TvOS: {
-      // Darwin defaults to "softfp" for v6 and v7.
-      ABI = (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
-      ABI = Triple.isWatchABI() ? FloatABI::Hard : ABI;
-      break;
-    }
-    case llvm::Triple::WatchOS:
-      ABI = FloatABI::Hard;
-      break;
-
-    // FIXME: this is invalid for WindowsCE
-    case llvm::Triple::Win32:
-      ABI = FloatABI::Hard;
-      break;
-
-    case llvm::Triple::FreeBSD:
-      switch (Triple.getEnvironment()) {
-      case llvm::Triple::GNUEABIHF:
-        ABI = FloatABI::Hard;
-        break;
-      default:
-        // FreeBSD defaults to soft float
-        ABI = FloatABI::Soft;
-        break;
-      }
-      break;
-
-    default:
-      switch (Triple.getEnvironment()) {
-      case llvm::Triple::GNUEABIHF:
-      case llvm::Triple::MuslEABIHF:
-      case llvm::Triple::EABIHF:
-        ABI = FloatABI::Hard;
-        break;
-      case llvm::Triple::GNUEABI:
-      case llvm::Triple::MuslEABI:
-      case llvm::Triple::EABI:
-        // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
-        ABI = FloatABI::SoftFP;
-        break;
-      case llvm::Triple::Android:
-        ABI = (SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
-        break;
-      default:
-        // Assume "soft", but warn the user we are guessing.
-        if (Triple.isOSBinFormatMachO() &&
-            Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
-          ABI = FloatABI::Hard;
-        else
-          ABI = FloatABI::Soft;
-
-        if (Triple.getOS() != llvm::Triple::UnknownOS ||
-            !Triple.isOSBinFormatMachO())
-          D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
-        break;
-      }
-    }
-  }
-
-  assert(ABI != FloatABI::Invalid && "must select an ABI");
-  return ABI;
-}
-
-static void getARMTargetFeatures(const ToolChain &TC,
-                                 const llvm::Triple &Triple,
-                                 const ArgList &Args,
-                                 std::vector<StringRef> &Features,
-                                 bool ForAS) {
-  const Driver &D = TC.getDriver();
-
-  bool KernelOrKext =
-      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
-  arm::FloatABI ABI = arm::getARMFloatABI(TC, Args);
-  const Arg *WaCPU = nullptr, *WaFPU = nullptr;
-  const Arg *WaHDiv = nullptr, *WaArch = nullptr;
-
-  if (!ForAS) {
-    // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
-    // yet (it uses the -mfloat-abi and -msoft-float options), and it is
-    // stripped out by the ARM target. We should probably pass this a new
-    // -target-option, which is handled by the -cc1/-cc1as invocation.
-    //
-    // FIXME2:  For consistency, it would be ideal if we set up the target
-    // machine state the same when using the frontend or the assembler. We don't
-    // currently do that for the assembler, we pass the options directly to the
-    // backend and never even instantiate the frontend TargetInfo. If we did,
-    // and used its handleTargetFeatures hook, then we could ensure the
-    // assembler and the frontend behave the same.
-
-    // Use software floating point operations?
-    if (ABI == arm::FloatABI::Soft)
-      Features.push_back("+soft-float");
-
-    // Use software floating point argument passing?
-    if (ABI != arm::FloatABI::Hard)
-      Features.push_back("+soft-float-abi");
-  } else {
-    // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down
-    // to the assembler correctly.
-    for (const Arg *A :
-         Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
-      StringRef Value = A->getValue();
-      if (Value.startswith("-mfpu=")) {
-        WaFPU = A;
-      } else if (Value.startswith("-mcpu=")) {
-        WaCPU = A;
-      } else if (Value.startswith("-mhwdiv=")) {
-        WaHDiv = A;
-      } else if (Value.startswith("-march=")) {
-        WaArch = A;
-      }
-    }
-  }
-
-  // Check -march. ClangAs gives preference to -Wa,-march=.
-  const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
-  StringRef ArchName;
-  if (WaArch) {
-    if (ArchArg)
-      D.Diag(clang::diag::warn_drv_unused_argument)
-          << ArchArg->getAsString(Args);
-    ArchName = StringRef(WaArch->getValue()).substr(7);
-    checkARMArchName(D, WaArch, Args, ArchName, Features, Triple);
-    // FIXME: Set Arch.
-    D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args);
-  } else if (ArchArg) {
-    ArchName = ArchArg->getValue();
-    checkARMArchName(D, ArchArg, Args, ArchName, Features, Triple);
-  }
-
-  // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
-  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
-  StringRef CPUName;
-  if (WaCPU) {
-    if (CPUArg)
-      D.Diag(clang::diag::warn_drv_unused_argument)
-          << CPUArg->getAsString(Args);
-    CPUName = StringRef(WaCPU->getValue()).substr(6);
-    checkARMCPUName(D, WaCPU, Args, CPUName, ArchName, Features, Triple);
-  } else if (CPUArg) {
-    CPUName = CPUArg->getValue();
-    checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, Features, Triple);
-  }
-
-  // Add CPU features for generic CPUs
-  if (CPUName == "native") {
-    llvm::StringMap<bool> HostFeatures;
-    if (llvm::sys::getHostCPUFeatures(HostFeatures))
-      for (auto &F : HostFeatures)
-        Features.push_back(
-            Args.MakeArgString((F.second ? "+" : "-") + F.first()));
-  }
-
-  // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
-  const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
-  if (WaFPU) {
-    if (FPUArg)
-      D.Diag(clang::diag::warn_drv_unused_argument)
-          << FPUArg->getAsString(Args);
-    getARMFPUFeatures(D, WaFPU, Args, StringRef(WaFPU->getValue()).substr(6),
-                      Features);
-  } else if (FPUArg) {
-    getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
-  }
-
-  // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=.
-  const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
-  if (WaHDiv) {
-    if (HDivArg)
-      D.Diag(clang::diag::warn_drv_unused_argument)
-          << HDivArg->getAsString(Args);
-    getARMHWDivFeatures(D, WaHDiv, Args,
-                        StringRef(WaHDiv->getValue()).substr(8), Features);
-  } else if (HDivArg)
-    getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features);
-
-  // Setting -msoft-float effectively disables NEON because of the GCC
-  // implementation, although the same isn't true of VFP or VFP3.
-  if (ABI == arm::FloatABI::Soft) {
-    Features.push_back("-neon");
-    // Also need to explicitly disable features which imply NEON.
-    Features.push_back("-crypto");
-  }
-
-  // En/disable crc code generation.
-  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
-    if (A->getOption().matches(options::OPT_mcrc))
-      Features.push_back("+crc");
-    else
-      Features.push_back("-crc");
-  }
-
-  // Look for the last occurrence of -mlong-calls or -mno-long-calls. If
-  // neither options are specified, see if we are compiling for kernel/kext and
-  // decide whether to pass "+long-calls" based on the OS and its version.
-  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
-                               options::OPT_mno_long_calls)) {
-    if (A->getOption().matches(options::OPT_mlong_calls))
-      Features.push_back("+long-calls");
-  } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
-             !Triple.isWatchOS()) {
-      Features.push_back("+long-calls");
-  }
-
-  // Kernel code has more strict alignment requirements.
-  if (KernelOrKext)
-    Features.push_back("+strict-align");
-  else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
-                                    options::OPT_munaligned_access)) {
-    if (A->getOption().matches(options::OPT_munaligned_access)) {
-      // No v6M core supports unaligned memory access (v6M ARM ARM A3.2).
-      if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
-        D.Diag(diag::err_target_unsupported_unaligned) << "v6m";
-      // v8M Baseline follows on from v6M, so doesn't support unaligned memory
-      // access either.
-      else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
-        D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base";
-    } else
-      Features.push_back("+strict-align");
-  } else {
-    // Assume pre-ARMv6 doesn't support unaligned accesses.
-    //
-    // ARMv6 may or may not support unaligned accesses depending on the
-    // SCTLR.U bit, which is architecture-specific. We assume ARMv6
-    // Darwin and NetBSD targets support unaligned accesses, and others don't.
-    //
-    // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
-    // which raises an alignment fault on unaligned accesses. Linux
-    // defaults this bit to 0 and handles it as a system-wide (not
-    // per-process) setting. It is therefore safe to assume that ARMv7+
-    // Linux targets support unaligned accesses. The same goes for NaCl.
-    //
-    // The above behavior is consistent with GCC.
-    int VersionNum = getARMSubArchVersionNumber(Triple);
-    if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
-      if (VersionNum < 6 ||
-          Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
-        Features.push_back("+strict-align");
-    } else if (Triple.isOSLinux() || Triple.isOSNaCl()) {
-      if (VersionNum < 7)
-        Features.push_back("+strict-align");
-    } else
-      Features.push_back("+strict-align");
-  }
-
-  // llvm does not support reserving registers in general. There is support
-  // for reserving r9 on ARM though (defined as a platform-specific register
-  // in ARM EABI).
-  if (Args.hasArg(options::OPT_ffixed_r9))
-    Features.push_back("+reserve-r9");
-
-  // The kext linker doesn't know how to deal with movw/movt.
-  if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
-    Features.push_back("+no-movt");
-}
-
-void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
-                             ArgStringList &CmdArgs, bool KernelOrKext) const {
-  // Select the ABI to use.
-  // FIXME: Support -meabi.
-  // FIXME: Parts of this are duplicated in the backend, unify this somehow.
-  const char *ABIName = nullptr;
-  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
-    ABIName = A->getValue();
-  } else if (Triple.isOSBinFormatMachO()) {
-    if (useAAPCSForMachO(Triple)) {
-      ABIName = "aapcs";
-    } else if (Triple.isWatchABI()) {
-      ABIName = "aapcs16";
-    } else {
-      ABIName = "apcs-gnu";
-    }
-  } else if (Triple.isOSWindows()) {
-    // FIXME: this is invalid for WindowsCE
-    ABIName = "aapcs";
-  } else {
-    // Select the default based on the platform.
-    switch (Triple.getEnvironment()) {
-    case llvm::Triple::Android:
-    case llvm::Triple::GNUEABI:
-    case llvm::Triple::GNUEABIHF:
-    case llvm::Triple::MuslEABI:
-    case llvm::Triple::MuslEABIHF:
-      ABIName = "aapcs-linux";
-      break;
-    case llvm::Triple::EABIHF:
-    case llvm::Triple::EABI:
-      ABIName = "aapcs";
-      break;
-    default:
-      if (Triple.getOS() == llvm::Triple::NetBSD)
-        ABIName = "apcs-gnu";
-      else
-        ABIName = "aapcs";
-      break;
-    }
-  }
-  CmdArgs.push_back("-target-abi");
-  CmdArgs.push_back(ABIName);
-
-  // Determine floating point ABI from the options & target defaults.
-  arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
-  if (ABI == arm::FloatABI::Soft) {
-    // Floating point operations and argument passing are soft.
-    // FIXME: This changes CPP defines, we need -target-soft-float.
-    CmdArgs.push_back("-msoft-float");
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("soft");
-  } else if (ABI == arm::FloatABI::SoftFP) {
-    // Floating point operations are hard, but argument passing is soft.
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("soft");
-  } else {
-    // Floating point operations and argument passing are hard.
-    assert(ABI == arm::FloatABI::Hard && "Invalid float abi!");
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("hard");
-  }
-
-  // Forward the -mglobal-merge option for explicit control over the pass.
-  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
-                               options::OPT_mno_global_merge)) {
-    CmdArgs.push_back("-backend-option");
-    if (A->getOption().matches(options::OPT_mno_global_merge))
-      CmdArgs.push_back("-arm-global-merge=false");
-    else
-      CmdArgs.push_back("-arm-global-merge=true");
-  }
-
-  if (!Args.hasFlag(options::OPT_mimplicit_float,
-                    options::OPT_mno_implicit_float, true))
-    CmdArgs.push_back("-no-implicit-float");
-}
-// ARM tools end.
-
-/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
-/// targeting. Set \p A to the Arg corresponding to the -mcpu or -mtune
-/// arguments if they are provided, or to nullptr otherwise.
-static std::string getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
-  std::string CPU;
-  // If we have -mtune or -mcpu, use that.
-  if ((A = Args.getLastArg(options::OPT_mtune_EQ))) {
-    CPU = StringRef(A->getValue()).lower();
-  } else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
-    StringRef Mcpu = A->getValue();
-    CPU = Mcpu.split("+").first.lower();
-  }
-
-  // Handle CPU name is 'native'.
-  if (CPU == "native")
-    return llvm::sys::getHostCPUName();
-  else if (CPU.size())
-    return CPU;
-
-  // Make sure we pick "cyclone" if -arch is used.
-  // FIXME: Should this be picked by checking the target triple instead?
-  if (Args.getLastArg(options::OPT_arch))
-    return "cyclone";
-
-  return "generic";
-}
-
-void Clang::AddAArch64TargetArgs(const ArgList &Args,
-                                 ArgStringList &CmdArgs) const {
-  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
-
-  if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
-      Args.hasArg(options::OPT_mkernel) ||
-      Args.hasArg(options::OPT_fapple_kext))
-    CmdArgs.push_back("-disable-red-zone");
-
-  if (!Args.hasFlag(options::OPT_mimplicit_float,
-                    options::OPT_mno_implicit_float, true))
-    CmdArgs.push_back("-no-implicit-float");
-
-  const char *ABIName = nullptr;
-  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
-    ABIName = A->getValue();
-  else if (Triple.isOSDarwin())
-    ABIName = "darwinpcs";
-  else
-    ABIName = "aapcs";
-
-  CmdArgs.push_back("-target-abi");
-  CmdArgs.push_back(ABIName);
-
-  if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
-                               options::OPT_mno_fix_cortex_a53_835769)) {
-    CmdArgs.push_back("-backend-option");
-    if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
-      CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
-    else
-      CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=0");
-  } else if (Triple.isAndroid()) {
-    // Enabled A53 errata (835769) workaround by default on android
-    CmdArgs.push_back("-backend-option");
-    CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
-  }
-
-  // Forward the -mglobal-merge option for explicit control over the pass.
-  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
-                               options::OPT_mno_global_merge)) {
-    CmdArgs.push_back("-backend-option");
-    if (A->getOption().matches(options::OPT_mno_global_merge))
-      CmdArgs.push_back("-aarch64-global-merge=false");
-    else
-      CmdArgs.push_back("-aarch64-global-merge=true");
-  }
-}
-
-// Get CPU and ABI names. They are not independent
-// so we have to calculate them together.
-void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
-                            StringRef &CPUName, StringRef &ABIName) {
-  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";
-  }
-
-  // MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android).
-  if (Triple.isAndroid()) {
-    DefMips32CPU = "mips32";
-    DefMips64CPU = "mips64r6";
-  }
-
-  // MIPS3 is the default for mips64*-unknown-openbsd.
-  if (Triple.getOS() == llvm::Triple::OpenBSD)
-    DefMips64CPU = "mips3";
-
-  if (Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ))
-    CPUName = A->getValue();
-
-  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
-    ABIName = A->getValue();
-    // Convert a GNU style Mips ABI name to the name
-    // accepted by LLVM Mips backend.
-    ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
-                  .Case("32", "o32")
-                  .Case("64", "n64")
-                  .Default(ABIName);
-  }
-
-  // Setup default CPU and ABI names.
-  if (CPUName.empty() && ABIName.empty()) {
-    switch (Triple.getArch()) {
-    default:
-      llvm_unreachable("Unexpected triple arch name");
-    case llvm::Triple::mips:
-    case llvm::Triple::mipsel:
-      CPUName = DefMips32CPU;
-      break;
-    case llvm::Triple::mips64:
-    case llvm::Triple::mips64el:
-      CPUName = DefMips64CPU;
-      break;
-    }
-  }
-
-  if (ABIName.empty() &&
-      (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
-       Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
-    ABIName = llvm::StringSwitch<const char *>(CPUName)
-                  .Case("mips1", "o32")
-                  .Case("mips2", "o32")
-                  .Case("mips3", "n64")
-                  .Case("mips4", "n64")
-                  .Case("mips5", "n64")
-                  .Case("mips32", "o32")
-                  .Case("mips32r2", "o32")
-                  .Case("mips32r3", "o32")
-                  .Case("mips32r5", "o32")
-                  .Case("mips32r6", "o32")
-                  .Case("mips64", "n64")
-                  .Case("mips64r2", "n64")
-                  .Case("mips64r3", "n64")
-                  .Case("mips64r5", "n64")
-                  .Case("mips64r6", "n64")
-                  .Case("octeon", "n64")
-                  .Case("p5600", "o32")
-                  .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";
-  }
-
-  if (CPUName.empty()) {
-    // Deduce CPU name from ABI name.
-    CPUName = llvm::StringSwitch<const char *>(ABIName)
-                  .Case("o32", DefMips32CPU)
-                  .Cases("n32", "n64", DefMips64CPU)
-                  .Default("");
-  }
-
-  // FIXME: Warn on inconsistent use of -march and -mabi.
-}
-
-std::string mips::getMipsABILibSuffix(const ArgList &Args,
-                                      const llvm::Triple &Triple) {
-  StringRef CPUName, ABIName;
-  tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
-  return llvm::StringSwitch<std::string>(ABIName)
-      .Case("o32", "")
-      .Case("n32", "32")
-      .Case("n64", "64");
-}
-
-// Convert ABI name to the GNU tools acceptable variant.
-static StringRef getGnuCompatibleMipsABIName(StringRef ABI) {
-  return llvm::StringSwitch<llvm::StringRef>(ABI)
-      .Case("o32", "32")
-      .Case("n64", "64")
-      .Default(ABI);
-}
-
-// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
-// and -mfloat-abi=.
-static mips::FloatABI getMipsFloatABI(const Driver &D, const ArgList &Args) {
-  mips::FloatABI ABI = mips::FloatABI::Invalid;
-  if (Arg *A =
-          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
-                          options::OPT_mfloat_abi_EQ)) {
-    if (A->getOption().matches(options::OPT_msoft_float))
-      ABI = mips::FloatABI::Soft;
-    else if (A->getOption().matches(options::OPT_mhard_float))
-      ABI = mips::FloatABI::Hard;
-    else {
-      ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
-                .Case("soft", mips::FloatABI::Soft)
-                .Case("hard", mips::FloatABI::Hard)
-                .Default(mips::FloatABI::Invalid);
-      if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
-        D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
-        ABI = mips::FloatABI::Hard;
-      }
-    }
-  }
-
-  // If unspecified, choose the default based on the platform.
-  if (ABI == mips::FloatABI::Invalid) {
-    // Assume "hard", because it's a default value used by gcc.
-    // When we start to recognize specific target MIPS processors,
-    // we will be able to select the default more correctly.
-    ABI = mips::FloatABI::Hard;
-  }
-
-  assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
-  return ABI;
-}
-
-static void AddTargetFeature(const ArgList &Args,
-                             std::vector<StringRef> &Features,
-                             OptSpecifier OnOpt, OptSpecifier OffOpt,
-                             StringRef FeatureName) {
-  if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
-    if (A->getOption().matches(OnOpt))
-      Features.push_back(Args.MakeArgString("+" + FeatureName));
-    else
-      Features.push_back(Args.MakeArgString("-" + FeatureName));
-  }
-}
-
-static void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
-                                  const ArgList &Args,
-                                  std::vector<StringRef> &Features) {
-  StringRef CPUName;
-  StringRef ABIName;
-  mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
-  ABIName = getGnuCompatibleMipsABIName(ABIName);
-
-  AddTargetFeature(Args, Features, options::OPT_mno_abicalls,
-                   options::OPT_mabicalls, "noabicalls");
-
-  mips::FloatABI FloatABI = getMipsFloatABI(D, Args);
-  if (FloatABI == mips::FloatABI::Soft) {
-    // FIXME: Note, this is a hack. We need to pass the selected float
-    // mode to the MipsTargetInfoBase to define appropriate macros there.
-    // Now it is the only method.
-    Features.push_back("+soft-float");
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
-    StringRef Val = StringRef(A->getValue());
-    if (Val == "2008") {
-      if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008)
-        Features.push_back("+nan2008");
-      else {
-        Features.push_back("-nan2008");
-        D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
-      }
-    } else if (Val == "legacy") {
-      if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy)
-        Features.push_back("-nan2008");
-      else {
-        Features.push_back("+nan2008");
-        D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
-      }
-    } else
-      D.Diag(diag::err_drv_unsupported_option_argument)
-          << A->getOption().getName() << Val;
-  }
-
-  AddTargetFeature(Args, Features, options::OPT_msingle_float,
-                   options::OPT_mdouble_float, "single-float");
-  AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
-                   "mips16");
-  AddTargetFeature(Args, Features, options::OPT_mmicromips,
-                   options::OPT_mno_micromips, "micromips");
-  AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
-                   "dsp");
-  AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
-                   "dspr2");
-  AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
-                   "msa");
-
-  // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
-  // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
-  // nooddspreg.
-  if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
-                               options::OPT_mfp64)) {
-    if (A->getOption().matches(options::OPT_mfp32))
-      Features.push_back(Args.MakeArgString("-fp64"));
-    else if (A->getOption().matches(options::OPT_mfpxx)) {
-      Features.push_back(Args.MakeArgString("+fpxx"));
-      Features.push_back(Args.MakeArgString("+nooddspreg"));
-    } else
-      Features.push_back(Args.MakeArgString("+fp64"));
-  } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
-    Features.push_back(Args.MakeArgString("+fpxx"));
-    Features.push_back(Args.MakeArgString("+nooddspreg"));
-  } else if (mips::isFP64ADefault(Triple, CPUName)) {
-    Features.push_back(Args.MakeArgString("+fp64"));
-    Features.push_back(Args.MakeArgString("+nooddspreg"));
-  }
-
-  AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
-                   options::OPT_modd_spreg, "nooddspreg");
-}
-
-void Clang::AddMIPSTargetArgs(const ArgList &Args,
-                              ArgStringList &CmdArgs) const {
-  const Driver &D = getToolChain().getDriver();
-  StringRef CPUName;
-  StringRef ABIName;
-  const llvm::Triple &Triple = getToolChain().getTriple();
-  mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
-
-  CmdArgs.push_back("-target-abi");
-  CmdArgs.push_back(ABIName.data());
-
-  mips::FloatABI ABI = getMipsFloatABI(D, Args);
-  if (ABI == mips::FloatABI::Soft) {
-    // Floating point operations and argument passing are soft.
-    CmdArgs.push_back("-msoft-float");
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("soft");
-  } else {
-    // Floating point operations and argument passing are hard.
-    assert(ABI == mips::FloatABI::Hard && "Invalid float abi!");
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("hard");
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
-    if (A->getOption().matches(options::OPT_mxgot)) {
-      CmdArgs.push_back("-mllvm");
-      CmdArgs.push_back("-mxgot");
-    }
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1,
-                               options::OPT_mno_ldc1_sdc1)) {
-    if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) {
-      CmdArgs.push_back("-mllvm");
-      CmdArgs.push_back("-mno-ldc1-sdc1");
-    }
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division,
-                               options::OPT_mno_check_zero_division)) {
-    if (A->getOption().matches(options::OPT_mno_check_zero_division)) {
-      CmdArgs.push_back("-mllvm");
-      CmdArgs.push_back("-mno-check-zero-division");
-    }
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_G)) {
-    StringRef v = A->getValue();
-    CmdArgs.push_back("-mllvm");
-    CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
-    A->claim();
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_mcompact_branches_EQ)) {
-    StringRef Val = StringRef(A->getValue());
-    if (mips::hasCompactBranches(CPUName)) {
-      if (Val == "never" || Val == "always" || Val == "optimal") {
-        CmdArgs.push_back("-mllvm");
-        CmdArgs.push_back(Args.MakeArgString("-mips-compact-branches=" + Val));
-      } else
-        D.Diag(diag::err_drv_unsupported_option_argument)
-            << A->getOption().getName() << Val;
-    } else
-      D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName;
-  }
-}
-
-/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
-static std::string getPPCTargetCPU(const ArgList &Args) {
-  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
-    StringRef CPUName = A->getValue();
-
-    if (CPUName == "native") {
-      std::string CPU = llvm::sys::getHostCPUName();
-      if (!CPU.empty() && CPU != "generic")
-        return CPU;
-      else
-        return "";
-    }
-
-    return llvm::StringSwitch<const char *>(CPUName)
-        .Case("common", "generic")
-        .Case("440", "440")
-        .Case("440fp", "440")
-        .Case("450", "450")
-        .Case("601", "601")
-        .Case("602", "602")
-        .Case("603", "603")
-        .Case("603e", "603e")
-        .Case("603ev", "603ev")
-        .Case("604", "604")
-        .Case("604e", "604e")
-        .Case("620", "620")
-        .Case("630", "pwr3")
-        .Case("G3", "g3")
-        .Case("7400", "7400")
-        .Case("G4", "g4")
-        .Case("7450", "7450")
-        .Case("G4+", "g4+")
-        .Case("750", "750")
-        .Case("970", "970")
-        .Case("G5", "g5")
-        .Case("a2", "a2")
-        .Case("a2q", "a2q")
-        .Case("e500mc", "e500mc")
-        .Case("e5500", "e5500")
-        .Case("power3", "pwr3")
-        .Case("power4", "pwr4")
-        .Case("power5", "pwr5")
-        .Case("power5x", "pwr5x")
-        .Case("power6", "pwr6")
-        .Case("power6x", "pwr6x")
-        .Case("power7", "pwr7")
-        .Case("power8", "pwr8")
-        .Case("power9", "pwr9")
-        .Case("pwr3", "pwr3")
-        .Case("pwr4", "pwr4")
-        .Case("pwr5", "pwr5")
-        .Case("pwr5x", "pwr5x")
-        .Case("pwr6", "pwr6")
-        .Case("pwr6x", "pwr6x")
-        .Case("pwr7", "pwr7")
-        .Case("pwr8", "pwr8")
-        .Case("pwr9", "pwr9")
-        .Case("powerpc", "ppc")
-        .Case("powerpc64", "ppc64")
-        .Case("powerpc64le", "ppc64le")
-        .Default("");
-  }
-
-  return "";
-}
-
-static void getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
-                                 const ArgList &Args,
-                                 std::vector<StringRef> &Features) {
-  handleTargetFeaturesGroup(Args, Features, options::OPT_m_ppc_Features_Group);
-
-  ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
-  if (FloatABI == ppc::FloatABI::Soft)
-    Features.push_back("-hard-float");
-
-  // Altivec is a bit weird, allow overriding of the Altivec feature here.
-  AddTargetFeature(Args, Features, options::OPT_faltivec,
-                   options::OPT_fno_altivec, "altivec");
-}
-
-ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {
-  ppc::FloatABI ABI = ppc::FloatABI::Invalid;
-  if (Arg *A =
-          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
-                          options::OPT_mfloat_abi_EQ)) {
-    if (A->getOption().matches(options::OPT_msoft_float))
-      ABI = ppc::FloatABI::Soft;
-    else if (A->getOption().matches(options::OPT_mhard_float))
-      ABI = ppc::FloatABI::Hard;
-    else {
-      ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())
-                .Case("soft", ppc::FloatABI::Soft)
-                .Case("hard", ppc::FloatABI::Hard)
-                .Default(ppc::FloatABI::Invalid);
-      if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
-        D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
-        ABI = ppc::FloatABI::Hard;
-      }
-    }
-  }
-
-  // If unspecified, choose the default based on the platform.
-  if (ABI == ppc::FloatABI::Invalid) {
-    ABI = ppc::FloatABI::Hard;
-  }
-
-  return ABI;
-}
-
-void Clang::AddPPCTargetArgs(const ArgList &Args,
-                             ArgStringList &CmdArgs) const {
-  // Select the ABI to use.
-  const char *ABIName = nullptr;
-  if (getToolChain().getTriple().isOSLinux())
-    switch (getToolChain().getArch()) {
-    case llvm::Triple::ppc64: {
-      // When targeting a processor that supports QPX, or if QPX is
-      // specifically enabled, default to using the ABI that supports QPX (so
-      // long as it is not specifically disabled).
-      bool HasQPX = false;
-      if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
-        HasQPX = A->getValue() == StringRef("a2q");
-      HasQPX = Args.hasFlag(options::OPT_mqpx, options::OPT_mno_qpx, HasQPX);
-      if (HasQPX) {
-        ABIName = "elfv1-qpx";
-        break;
-      }
-
-      ABIName = "elfv1";
-      break;
-    }
-    case llvm::Triple::ppc64le:
-      ABIName = "elfv2";
-      break;
-    default:
-      break;
-    }
-
-  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
-    // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
-    // the option if given as we don't have backend support for any targets
-    // that don't use the altivec abi.
-    if (StringRef(A->getValue()) != "altivec")
-      ABIName = A->getValue();
-
-  ppc::FloatABI FloatABI =
-      ppc::getPPCFloatABI(getToolChain().getDriver(), Args);
-
-  if (FloatABI == ppc::FloatABI::Soft) {
-    // Floating point operations and argument passing are soft.
-    CmdArgs.push_back("-msoft-float");
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("soft");
-  } else {
-    // Floating point operations and argument passing are hard.
-    assert(FloatABI == ppc::FloatABI::Hard && "Invalid float abi!");
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("hard");
-  }
-
-  if (ABIName) {
-    CmdArgs.push_back("-target-abi");
-    CmdArgs.push_back(ABIName);
-  }
-}
-
-bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
-  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
-  return A && (A->getValue() == StringRef(Value));
-}
-
-/// Get the (LLVM) name of the R600 gpu we are targeting.
-static std::string getR600TargetGPU(const ArgList &Args) {
-  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
-    const char *GPUName = A->getValue();
-    return llvm::StringSwitch<const char *>(GPUName)
-        .Cases("rv630", "rv635", "r600")
-        .Cases("rv610", "rv620", "rs780", "rs880")
-        .Case("rv740", "rv770")
-        .Case("palm", "cedar")
-        .Cases("sumo", "sumo2", "sumo")
-        .Case("hemlock", "cypress")
-        .Case("aruba", "cayman")
-        .Default(GPUName);
-  }
-  return "";
-}
-
-static std::string getLanaiTargetCPU(const ArgList &Args) {
-  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
-    return A->getValue();
-  }
-  return "";
-}
-
-sparc::FloatABI sparc::getSparcFloatABI(const Driver &D,
-                                        const ArgList &Args) {
-  sparc::FloatABI ABI = sparc::FloatABI::Invalid;
-  if (Arg *A =
-          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
-                          options::OPT_mfloat_abi_EQ)) {
-    if (A->getOption().matches(options::OPT_msoft_float))
-      ABI = sparc::FloatABI::Soft;
-    else if (A->getOption().matches(options::OPT_mhard_float))
-      ABI = sparc::FloatABI::Hard;
-    else {
-      ABI = llvm::StringSwitch<sparc::FloatABI>(A->getValue())
-                .Case("soft", sparc::FloatABI::Soft)
-                .Case("hard", sparc::FloatABI::Hard)
-                .Default(sparc::FloatABI::Invalid);
-      if (ABI == sparc::FloatABI::Invalid &&
-          !StringRef(A->getValue()).empty()) {
-        D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
-        ABI = sparc::FloatABI::Hard;
-      }
-    }
-  }
-
-  // If unspecified, choose the default based on the platform.
-  // Only the hard-float ABI on Sparc is standardized, and it is the
-  // default. GCC also supports a nonstandard soft-float ABI mode, also
-  // implemented in LLVM. However as this is not standard we set the default
-  // to be hard-float.
-  if (ABI == sparc::FloatABI::Invalid) {
-    ABI = sparc::FloatABI::Hard;
-  }
-
-  return ABI;
-}
-
-static void getSparcTargetFeatures(const Driver &D, const ArgList &Args,
-                                 std::vector<StringRef> &Features) {
-  sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args);
-  if (FloatABI == sparc::FloatABI::Soft)
-    Features.push_back("+soft-float");
-}
-
-void Clang::AddSparcTargetArgs(const ArgList &Args,
-                               ArgStringList &CmdArgs) const {
-  sparc::FloatABI FloatABI =
-      sparc::getSparcFloatABI(getToolChain().getDriver(), Args);
-
-  if (FloatABI == sparc::FloatABI::Soft) {
-    // Floating point operations and argument passing are soft.
-    CmdArgs.push_back("-msoft-float");
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("soft");
-  } else {
-    // Floating point operations and argument passing are hard.
-    assert(FloatABI == sparc::FloatABI::Hard && "Invalid float abi!");
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("hard");
-  }
-}
-
-void Clang::AddSystemZTargetArgs(const ArgList &Args,
-                                 ArgStringList &CmdArgs) const {
-  if (Args.hasFlag(options::OPT_mbackchain, options::OPT_mno_backchain, false))
-    CmdArgs.push_back("-mbackchain");
-}
-
-static const char *getSystemZTargetCPU(const ArgList &Args) {
-  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
-    return A->getValue();
-  return "z10";
-}
-
-static void getSystemZTargetFeatures(const ArgList &Args,
-                                     std::vector<StringRef> &Features) {
-  // -m(no-)htm overrides use of the transactional-execution facility.
-  if (Arg *A = Args.getLastArg(options::OPT_mhtm, options::OPT_mno_htm)) {
-    if (A->getOption().matches(options::OPT_mhtm))
-      Features.push_back("+transactional-execution");
-    else
-      Features.push_back("-transactional-execution");
-  }
-  // -m(no-)vx overrides use of the vector facility.
-  if (Arg *A = Args.getLastArg(options::OPT_mvx, options::OPT_mno_vx)) {
-    if (A->getOption().matches(options::OPT_mvx))
-      Features.push_back("+vector");
-    else
-      Features.push_back("-vector");
-  }
-}
-
-static const char *getX86TargetCPU(const ArgList &Args,
-                                   const llvm::Triple &Triple) {
-  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
-    if (StringRef(A->getValue()) != "native") {
-      if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
-        return "core-avx2";
-
-      return A->getValue();
-    }
-
-    // FIXME: Reject attempts to use -march=native unless the target matches
-    // the host.
-    //
-    // FIXME: We should also incorporate the detected target features for use
-    // with -native.
-    std::string CPU = llvm::sys::getHostCPUName();
-    if (!CPU.empty() && CPU != "generic")
-      return Args.MakeArgString(CPU);
-  }
-
-  if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
-    // Mapping built by referring to X86TargetInfo::getDefaultFeatures().
-    StringRef Arch = A->getValue();
-    const char *CPU;
-    if (Triple.getArch() == llvm::Triple::x86) {
-      CPU = llvm::StringSwitch<const char *>(Arch)
-                .Case("IA32", "i386")
-                .Case("SSE", "pentium3")
-                .Case("SSE2", "pentium4")
-                .Case("AVX", "sandybridge")
-                .Case("AVX2", "haswell")
-                .Default(nullptr);
-    } else {
-      CPU = llvm::StringSwitch<const char *>(Arch)
-                .Case("AVX", "sandybridge")
-                .Case("AVX2", "haswell")
-                .Default(nullptr);
-    }
-    if (CPU)
-      return CPU;
-  }
-
-  // Select the default CPU if none was given (or detection failed).
-
-  if (Triple.getArch() != llvm::Triple::x86_64 &&
-      Triple.getArch() != llvm::Triple::x86)
-    return nullptr; // This routine is only handling x86 targets.
-
-  bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
-
-  // FIXME: Need target hooks.
-  if (Triple.isOSDarwin()) {
-    if (Triple.getArchName() == "x86_64h")
-      return "core-avx2";
-    return Is64Bit ? "core2" : "yonah";
-  }
-
-  // Set up default CPU name for PS4 compilers.
-  if (Triple.isPS4CPU())
-    return "btver2";
-
-  // On Android use targets compatible with gcc
-  if (Triple.isAndroid())
-    return Is64Bit ? "x86-64" : "i686";
-
-  // Everything else goes to x86-64 in 64-bit mode.
-  if (Is64Bit)
-    return "x86-64";
-
-  switch (Triple.getOS()) {
-  case llvm::Triple::FreeBSD:
-  case llvm::Triple::NetBSD:
-  case llvm::Triple::OpenBSD:
-    return "i486";
-  case llvm::Triple::Haiku:
-    return "i586";
-  case llvm::Triple::Bitrig:
-    return "i686";
-  default:
-    // Fallback to p4.
-    return "pentium4";
-  }
-}
-
-/// Get the (LLVM) name of the WebAssembly cpu we are targeting.
-static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
-  // If we have -mcpu=, use that.
-  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
-    StringRef CPU = A->getValue();
-
-#ifdef __wasm__
-    // Handle "native" by examining the host. "native" isn't meaningful when
-    // cross compiling, so only support this when the host is also WebAssembly.
-    if (CPU == "native")
-      return llvm::sys::getHostCPUName();
-#endif
-
-    return CPU;
-  }
-
-  return "generic";
-}
-
-static std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
-                              bool FromAs = false) {
-  Arg *A;
-
-  switch (T.getArch()) {
-  default:
-    return "";
-
-  case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_be:
-    return getAArch64TargetCPU(Args, A);
-
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb: {
-    StringRef MArch, MCPU;
-    getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
-    return arm::getARMTargetCPU(MCPU, MArch, T);
-  }
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el: {
-    StringRef CPUName;
-    StringRef ABIName;
-    mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
-    return CPUName;
-  }
-
-  case llvm::Triple::nvptx:
-  case llvm::Triple::nvptx64:
-    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
-      return A->getValue();
-    return "";
-
-  case llvm::Triple::ppc:
-  case llvm::Triple::ppc64:
-  case llvm::Triple::ppc64le: {
-    std::string TargetCPUName = getPPCTargetCPU(Args);
-    // LLVM may default to generating code for the native CPU,
-    // but, like gcc, we default to a more generic option for
-    // each architecture. (except on Darwin)
-    if (TargetCPUName.empty() && !T.isOSDarwin()) {
-      if (T.getArch() == llvm::Triple::ppc64)
-        TargetCPUName = "ppc64";
-      else if (T.getArch() == llvm::Triple::ppc64le)
-        TargetCPUName = "ppc64le";
-      else
-        TargetCPUName = "ppc";
-    }
-    return TargetCPUName;
-  }
-
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel:
-  case llvm::Triple::sparcv9:
-    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
-      return A->getValue();
-    return "";
-
-  case llvm::Triple::x86:
-  case llvm::Triple::x86_64:
-    return getX86TargetCPU(Args, T);
-
-  case llvm::Triple::hexagon:
-    return "hexagon" +
-           toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
-
-  case llvm::Triple::lanai:
-    return getLanaiTargetCPU(Args);
-
-  case llvm::Triple::systemz:
-    return getSystemZTargetCPU(Args);
-
-  case llvm::Triple::r600:
-  case llvm::Triple::amdgcn:
-    return getR600TargetGPU(Args);
-
-  case llvm::Triple::wasm32:
-  case llvm::Triple::wasm64:
-    return getWebAssemblyTargetCPU(Args);
-  }
-}
-
-static unsigned getLTOParallelism(const ArgList &Args, const Driver &D) {
-  unsigned Parallelism = 0;
-  Arg *LtoJobsArg = Args.getLastArg(options::OPT_flto_jobs_EQ);
-  if (LtoJobsArg &&
-      StringRef(LtoJobsArg->getValue()).getAsInteger(10, Parallelism))
-    D.Diag(diag::err_drv_invalid_int_value) << LtoJobsArg->getAsString(Args)
-                                            << LtoJobsArg->getValue();
-  return Parallelism;
-}
-
-// CloudABI and WebAssembly use -ffunction-sections and -fdata-sections by
-// default.
-static bool isUseSeparateSections(const llvm::Triple &Triple) {
-  return Triple.getOS() == llvm::Triple::CloudABI ||
-         Triple.getArch() == llvm::Triple::wasm32 ||
-         Triple.getArch() == llvm::Triple::wasm64;
-}
-
-static void AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args,
-                          ArgStringList &CmdArgs, bool IsThinLTO,
-                          const Driver &D) {
-  // Tell the linker to load the plugin. This has to come before AddLinkerInputs
-  // as gold requires -plugin to come before any -plugin-opt that -Wl might
-  // forward.
-  CmdArgs.push_back("-plugin");
-  std::string Plugin =
-      ToolChain.getDriver().Dir + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold.so";
-  CmdArgs.push_back(Args.MakeArgString(Plugin));
-
-  // Try to pass driver level flags relevant to LTO code generation down to
-  // the plugin.
-
-  // Handle flags for selecting CPU variants.
-  std::string CPU = getCPUName(Args, ToolChain.getTriple());
-  if (!CPU.empty())
-    CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU));
-
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    StringRef OOpt;
-    if (A->getOption().matches(options::OPT_O4) ||
-        A->getOption().matches(options::OPT_Ofast))
-      OOpt = "3";
-    else if (A->getOption().matches(options::OPT_O))
-      OOpt = A->getValue();
-    else if (A->getOption().matches(options::OPT_O0))
-      OOpt = "0";
-    if (!OOpt.empty())
-      CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=O") + OOpt));
-  }
-
-  if (IsThinLTO)
-    CmdArgs.push_back("-plugin-opt=thinlto");
-
-  if (unsigned Parallelism = getLTOParallelism(Args, D))
-    CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=jobs=") +
-                                         llvm::to_string(Parallelism)));
-
-  // If an explicit debugger tuning argument appeared, pass it along.
-  if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
-                               options::OPT_ggdbN_Group)) {
-    if (A->getOption().matches(options::OPT_glldb))
-      CmdArgs.push_back("-plugin-opt=-debugger-tune=lldb");
-    else if (A->getOption().matches(options::OPT_gsce))
-      CmdArgs.push_back("-plugin-opt=-debugger-tune=sce");
-    else
-      CmdArgs.push_back("-plugin-opt=-debugger-tune=gdb");
-  }
-
-  bool UseSeparateSections =
-      isUseSeparateSections(ToolChain.getEffectiveTriple());
-
-  if (Args.hasFlag(options::OPT_ffunction_sections,
-                   options::OPT_fno_function_sections, UseSeparateSections)) {
-    CmdArgs.push_back("-plugin-opt=-function-sections");
-  }
-
-  if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
-                   UseSeparateSections)) {
-    CmdArgs.push_back("-plugin-opt=-data-sections");
-  }
-}
-
-/// This is a helper function for validating the optional refinement step
-/// parameter in reciprocal argument strings. Return false if there is an error
-/// parsing the refinement step. Otherwise, return true and set the Position
-/// of the refinement step in the input string.
-static bool getRefinementStep(StringRef In, const Driver &D,
-                              const Arg &A, size_t &Position) {
-  const char RefinementStepToken = ':';
-  Position = In.find(RefinementStepToken);
-  if (Position != StringRef::npos) {
-    StringRef Option = A.getOption().getName();
-    StringRef RefStep = In.substr(Position + 1);
-    // Allow exactly one numeric character for the additional refinement
-    // step parameter. This is reasonable for all currently-supported
-    // operations and architectures because we would expect that a larger value
-    // of refinement steps would cause the estimate "optimization" to
-    // under-perform the native operation. Also, if the estimate does not
-    // converge quickly, it probably will not ever converge, so further
-    // refinement steps will not produce a better answer.
-    if (RefStep.size() != 1) {
-      D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
-      return false;
-    }
-    char RefStepChar = RefStep[0];
-    if (RefStepChar < '0' || RefStepChar > '9') {
-      D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
-      return false;
-    }
-  }
-  return true;
-}
-
-/// The -mrecip flag requires processing of many optional parameters.
-static void ParseMRecip(const Driver &D, const ArgList &Args,
-                        ArgStringList &OutStrings) {
-  StringRef DisabledPrefixIn = "!";
-  StringRef DisabledPrefixOut = "!";
-  StringRef EnabledPrefixOut = "";
-  StringRef Out = "-mrecip=";
-
-  Arg *A = Args.getLastArg(options::OPT_mrecip, options::OPT_mrecip_EQ);
-  if (!A)
-    return;
-
-  unsigned NumOptions = A->getNumValues();
-  if (NumOptions == 0) {
-    // No option is the same as "all".
-    OutStrings.push_back(Args.MakeArgString(Out + "all"));
-    return;
-  }
-
-  // Pass through "all", "none", or "default" with an optional refinement step.
-  if (NumOptions == 1) {
-    StringRef Val = A->getValue(0);
-    size_t RefStepLoc;
-    if (!getRefinementStep(Val, D, *A, RefStepLoc))
-      return;
-    StringRef ValBase = Val.slice(0, RefStepLoc);
-    if (ValBase == "all" || ValBase == "none" || ValBase == "default") {
-      OutStrings.push_back(Args.MakeArgString(Out + Val));
-      return;
-    }
-  }
-
-  // Each reciprocal type may be enabled or disabled individually.
-  // Check each input value for validity, concatenate them all back together,
-  // and pass through.
-
-  llvm::StringMap<bool> OptionStrings;
-  OptionStrings.insert(std::make_pair("divd", false));
-  OptionStrings.insert(std::make_pair("divf", false));
-  OptionStrings.insert(std::make_pair("vec-divd", false));
-  OptionStrings.insert(std::make_pair("vec-divf", false));
-  OptionStrings.insert(std::make_pair("sqrtd", false));
-  OptionStrings.insert(std::make_pair("sqrtf", false));
-  OptionStrings.insert(std::make_pair("vec-sqrtd", false));
-  OptionStrings.insert(std::make_pair("vec-sqrtf", false));
-
-  for (unsigned i = 0; i != NumOptions; ++i) {
-    StringRef Val = A->getValue(i);
-
-    bool IsDisabled = Val.startswith(DisabledPrefixIn);
-    // Ignore the disablement token for string matching.
-    if (IsDisabled)
-      Val = Val.substr(1);
-
-    size_t RefStep;
-    if (!getRefinementStep(Val, D, *A, RefStep))
-      return;
-
-    StringRef ValBase = Val.slice(0, RefStep);
-    llvm::StringMap<bool>::iterator OptionIter = OptionStrings.find(ValBase);
-    if (OptionIter == OptionStrings.end()) {
-      // Try again specifying float suffix.
-      OptionIter = OptionStrings.find(ValBase.str() + 'f');
-      if (OptionIter == OptionStrings.end()) {
-        // The input name did not match any known option string.
-        D.Diag(diag::err_drv_unknown_argument) << Val;
-        return;
-      }
-      // The option was specified without a float or double suffix.
-      // Make sure that the double entry was not already specified.
-      // The float entry will be checked below.
-      if (OptionStrings[ValBase.str() + 'd']) {
-        D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
-        return;
-      }
-    }
-
-    if (OptionIter->second == true) {
-      // Duplicate option specified.
-      D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
-      return;
-    }
-
-    // Mark the matched option as found. Do not allow duplicate specifiers.
-    OptionIter->second = true;
-
-    // If the precision was not specified, also mark the double entry as found.
-    if (ValBase.back() != 'f' && ValBase.back() != 'd')
-      OptionStrings[ValBase.str() + 'd'] = true;
-
-    // Build the output string.
-    StringRef Prefix = IsDisabled ? DisabledPrefixOut : EnabledPrefixOut;
-    Out = Args.MakeArgString(Out + Prefix + Val);
-    if (i != NumOptions - 1)
-      Out = Args.MakeArgString(Out + ",");
-  }
-
-  OutStrings.push_back(Args.MakeArgString(Out));
-}
-
-static void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
-                                 const ArgList &Args,
-                                 std::vector<StringRef> &Features) {
-  // If -march=native, autodetect the feature list.
-  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
-    if (StringRef(A->getValue()) == "native") {
-      llvm::StringMap<bool> HostFeatures;
-      if (llvm::sys::getHostCPUFeatures(HostFeatures))
-        for (auto &F : HostFeatures)
-          Features.push_back(
-              Args.MakeArgString((F.second ? "+" : "-") + F.first()));
-    }
-  }
-
-  if (Triple.getArchName() == "x86_64h") {
-    // x86_64h implies quite a few of the more modern subtarget features
-    // for Haswell class CPUs, but not all of them. Opt-out of a few.
-    Features.push_back("-rdrnd");
-    Features.push_back("-aes");
-    Features.push_back("-pclmul");
-    Features.push_back("-rtm");
-    Features.push_back("-hle");
-    Features.push_back("-fsgsbase");
-  }
-
-  const llvm::Triple::ArchType ArchType = Triple.getArch();
-  // Add features to be compatible with gcc for Android.
-  if (Triple.isAndroid()) {
-    if (ArchType == llvm::Triple::x86_64) {
-      Features.push_back("+sse4.2");
-      Features.push_back("+popcnt");
-    } else
-      Features.push_back("+ssse3");
-  }
-
-  // Set features according to the -arch flag on MSVC.
-  if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
-    StringRef Arch = A->getValue();
-    bool ArchUsed = false;
-    // First, look for flags that are shared in x86 and x86-64.
-    if (ArchType == llvm::Triple::x86_64 || ArchType == llvm::Triple::x86) {
-      if (Arch == "AVX" || Arch == "AVX2") {
-        ArchUsed = true;
-        Features.push_back(Args.MakeArgString("+" + Arch.lower()));
-      }
-    }
-    // Then, look for x86-specific flags.
-    if (ArchType == llvm::Triple::x86) {
-      if (Arch == "IA32") {
-        ArchUsed = true;
-      } else if (Arch == "SSE" || Arch == "SSE2") {
-        ArchUsed = true;
-        Features.push_back(Args.MakeArgString("+" + Arch.lower()));
-      }
-    }
-    if (!ArchUsed)
-      D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args);
-  }
-
-  // Now add any that the user explicitly requested on the command line,
-  // which may override the defaults.
-  handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group);
-}
-
-void Clang::AddX86TargetArgs(const ArgList &Args,
-                             ArgStringList &CmdArgs) const {
-  if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
-      Args.hasArg(options::OPT_mkernel) ||
-      Args.hasArg(options::OPT_fapple_kext))
-    CmdArgs.push_back("-disable-red-zone");
-
-  // Default to avoid implicit floating-point for kernel/kext code, but allow
-  // that to be overridden with -mno-soft-float.
-  bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
-                          Args.hasArg(options::OPT_fapple_kext));
-  if (Arg *A = Args.getLastArg(
-          options::OPT_msoft_float, options::OPT_mno_soft_float,
-          options::OPT_mimplicit_float, options::OPT_mno_implicit_float)) {
-    const Option &O = A->getOption();
-    NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
-                       O.matches(options::OPT_msoft_float));
-  }
-  if (NoImplicitFloat)
-    CmdArgs.push_back("-no-implicit-float");
-
-  if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
-    StringRef Value = A->getValue();
-    if (Value == "intel" || Value == "att") {
-      CmdArgs.push_back("-mllvm");
-      CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));
-    } else {
-      getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
-          << A->getOption().getName() << Value;
-    }
-  }
-
-  // Set flags to support MCU ABI.
-  if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) {
-    CmdArgs.push_back("-mfloat-abi");
-    CmdArgs.push_back("soft");
-    CmdArgs.push_back("-mstack-alignment=4");
-  }
-}
-
-void Clang::AddHexagonTargetArgs(const ArgList &Args,
-                                 ArgStringList &CmdArgs) const {
-  CmdArgs.push_back("-mqdsp6-compat");
-  CmdArgs.push_back("-Wreturn-type");
-
-  if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
-    std::string N = llvm::utostr(G.getValue());
-    std::string Opt = std::string("-hexagon-small-data-threshold=") + N;
-    CmdArgs.push_back("-mllvm");
-    CmdArgs.push_back(Args.MakeArgString(Opt));
-  }
-
-  if (!Args.hasArg(options::OPT_fno_short_enums))
-    CmdArgs.push_back("-fshort-enums");
-  if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
-    CmdArgs.push_back("-mllvm");
-    CmdArgs.push_back("-enable-hexagon-ieee-rnd-near");
-  }
-  CmdArgs.push_back("-mllvm");
-  CmdArgs.push_back("-machine-sink-split=0");
-}
-
-void Clang::AddLanaiTargetArgs(const ArgList &Args,
-                               ArgStringList &CmdArgs) const {
-  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
-    StringRef CPUName = A->getValue();
-
-    CmdArgs.push_back("-target-cpu");
-    CmdArgs.push_back(Args.MakeArgString(CPUName));
-  }
-  if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
-    StringRef Value = A->getValue();
-    // Only support mregparm=4 to support old usage. Report error for all other
-    // cases.
-    int Mregparm;
-    if (Value.getAsInteger(10, Mregparm)) {
-      if (Mregparm != 4) {
-        getToolChain().getDriver().Diag(
-            diag::err_drv_unsupported_option_argument)
-            << A->getOption().getName() << Value;
-      }
-    }
-  }
-}
-
-void Clang::AddWebAssemblyTargetArgs(const ArgList &Args,
-                                     ArgStringList &CmdArgs) const {
-  // Default to "hidden" visibility.
-  if (!Args.hasArg(options::OPT_fvisibility_EQ,
-                   options::OPT_fvisibility_ms_compat)) {
-    CmdArgs.push_back("-fvisibility");
-    CmdArgs.push_back("hidden");
-  }
-}
-
-// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
-static bool DecodeAArch64Features(const Driver &D, StringRef text,
-                                  std::vector<StringRef> &Features) {
-  SmallVector<StringRef, 8> Split;
-  text.split(Split, StringRef("+"), -1, false);
-
-  for (StringRef Feature : Split) {
-    StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
-    if (!FeatureName.empty())
-      Features.push_back(FeatureName);
-    else if (Feature == "neon" || Feature == "noneon")
-      D.Diag(diag::err_drv_no_neon_modifier);
-    else
-      return false;
-  }
-  return true;
-}
-
-// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
-// decode CPU and feature.
-static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
-                              std::vector<StringRef> &Features) {
-  std::pair<StringRef, StringRef> Split = Mcpu.split("+");
-  CPU = Split.first;
-
-  if (CPU == "generic") {
-    Features.push_back("+neon");
-  } else {
-    unsigned ArchKind = llvm::AArch64::parseCPUArch(CPU);
-    unsigned Extersion = llvm::AArch64::getDefaultExtensions(CPU, ArchKind);
-
-    if (!llvm::AArch64::getExtensionFeatures(Extersion, Features))
-      return false;
-   }
-
-  if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
-    return false;
-
-  return true;
-}
-
-static bool
-getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
-                                const ArgList &Args,
-                                std::vector<StringRef> &Features) {
-  std::string MarchLowerCase = March.lower();
-  std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
-
-  unsigned ArchKind = llvm::AArch64::parseArch(Split.first);
-  if (ArchKind == static_cast<unsigned>(llvm::AArch64::ArchKind::AK_INVALID) ||
-      !llvm::AArch64::getArchFeatures(ArchKind, Features) ||
-      (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features)))
-    return false;
-
-  return true;
-}
-
-static bool
-getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
-                               const ArgList &Args,
-                               std::vector<StringRef> &Features) {
-  StringRef CPU;
-  std::string McpuLowerCase = Mcpu.lower();
-  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
-    return false;
-
-  return true;
-}
-
-static bool
-getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
-                                     const ArgList &Args,
-                                     std::vector<StringRef> &Features) {
-  std::string MtuneLowerCase = Mtune.lower();
-  // Handle CPU name is 'native'.
-  if (MtuneLowerCase == "native")
-    MtuneLowerCase = llvm::sys::getHostCPUName();
-  if (MtuneLowerCase == "cyclone") {
-    Features.push_back("+zcm");
-    Features.push_back("+zcz");
-  }
-  return true;
-}
-
-static bool
-getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
-                                    const ArgList &Args,
-                                    std::vector<StringRef> &Features) {
-  StringRef CPU;
-  std::vector<StringRef> DecodedFeature;
-  std::string McpuLowerCase = Mcpu.lower();
-  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
-    return false;
-
-  return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
-}
-
-static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
-                                     std::vector<StringRef> &Features) {
-  Arg *A;
-  bool success = true;
-  // Enable NEON by default.
-  Features.push_back("+neon");
-  if ((A = Args.getLastArg(options::OPT_march_EQ)))
-    success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
-  else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
-    success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
-  else if (Args.hasArg(options::OPT_arch))
-    success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args, A),
-                                             Args, Features);
-
-  if (success && (A = Args.getLastArg(options::OPT_mtune_EQ)))
-    success =
-        getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
-  else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
-    success =
-        getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
-  else if (success && Args.hasArg(options::OPT_arch))
-    success = getAArch64MicroArchFeaturesFromMcpu(
-        D, getAArch64TargetCPU(Args, A), Args, Features);
-
-  if (!success)
-    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-
-  if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
-    Features.push_back("-fp-armv8");
-    Features.push_back("-crypto");
-    Features.push_back("-neon");
-  }
-
-  // En/disable crc
-  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
-    if (A->getOption().matches(options::OPT_mcrc))
-      Features.push_back("+crc");
-    else
-      Features.push_back("-crc");
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
-                               options::OPT_munaligned_access))
-    if (A->getOption().matches(options::OPT_mno_unaligned_access))
-      Features.push_back("+strict-align");
-
-  if (Args.hasArg(options::OPT_ffixed_x18))
-    Features.push_back("+reserve-x18");
-}
-
-static void getHexagonTargetFeatures(const ArgList &Args,
-                                     std::vector<StringRef> &Features) {
-  handleTargetFeaturesGroup(Args, Features,
-                            options::OPT_m_hexagon_Features_Group);
-
-  bool UseLongCalls = false;
-  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
-                               options::OPT_mno_long_calls)) {
-    if (A->getOption().matches(options::OPT_mlong_calls))
-      UseLongCalls = true;
-  }
-
-  Features.push_back(UseLongCalls ? "+long-calls" : "-long-calls");
-}
-
-static void getWebAssemblyTargetFeatures(const ArgList &Args,
-                                         std::vector<StringRef> &Features) {
-  handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group);
-}
-
-static void getAMDGPUTargetFeatures(const Driver &D, const ArgList &Args,
-                                    std::vector<StringRef> &Features) {
-  if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi)) {
-    StringRef value = dAbi->getValue();
-    if (value == "1.0") {
-      Features.push_back("+amdgpu-debugger-insert-nops");
-      Features.push_back("+amdgpu-debugger-reserve-regs");
-      Features.push_back("+amdgpu-debugger-emit-prologue");
-    } else {
-      D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args);
-    }
-  }
-
-  handleTargetFeaturesGroup(
-    Args, Features, options::OPT_m_amdgpu_Features_Group);
-}
-
-static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
-                              const ArgList &Args, ArgStringList &CmdArgs,
-                              bool ForAS) {
-  const Driver &D = TC.getDriver();
-  std::vector<StringRef> Features;
-  switch (Triple.getArch()) {
-  default:
-    break;
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el:
-    getMIPSTargetFeatures(D, Triple, Args, Features);
-    break;
-
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb:
-    getARMTargetFeatures(TC, Triple, Args, Features, ForAS);
-    break;
-
-  case llvm::Triple::ppc:
-  case llvm::Triple::ppc64:
-  case llvm::Triple::ppc64le:
-    getPPCTargetFeatures(D, Triple, Args, Features);
-    break;
-  case llvm::Triple::systemz:
-    getSystemZTargetFeatures(Args, Features);
-    break;
-  case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_be:
-    getAArch64TargetFeatures(D, Args, Features);
-    break;
-  case llvm::Triple::x86:
-  case llvm::Triple::x86_64:
-    getX86TargetFeatures(D, Triple, Args, Features);
-    break;
-  case llvm::Triple::hexagon:
-    getHexagonTargetFeatures(Args, Features);
-    break;
-  case llvm::Triple::wasm32:
-  case llvm::Triple::wasm64:
-    getWebAssemblyTargetFeatures(Args, Features);
-    break;
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel:
-  case llvm::Triple::sparcv9:
-    getSparcTargetFeatures(D, Args, Features);
-    break;
-  case llvm::Triple::r600:
-  case llvm::Triple::amdgcn:
-    getAMDGPUTargetFeatures(D, Args, Features);
-    break;
-  }
-
-  // Find the last of each feature.
-  llvm::StringMap<unsigned> LastOpt;
-  for (unsigned I = 0, N = Features.size(); I < N; ++I) {
-    StringRef Name = Features[I];
-    assert(Name[0] == '-' || Name[0] == '+');
-    LastOpt[Name.drop_front(1)] = I;
-  }
-
-  for (unsigned I = 0, N = Features.size(); I < N; ++I) {
-    // If this feature was overridden, ignore it.
-    StringRef Name = Features[I];
-    llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name.drop_front(1));
-    assert(LastI != LastOpt.end());
-    unsigned Last = LastI->second;
-    if (Last != I)
-      continue;
-
-    CmdArgs.push_back("-target-feature");
-    CmdArgs.push_back(Name.data());
-  }
-}
-
-static bool
-shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
-                                          const llvm::Triple &Triple) {
-  // We use the zero-cost exception tables for Objective-C if the non-fragile
-  // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
-  // later.
-  if (runtime.isNonFragile())
-    return true;
-
-  if (!Triple.isMacOSX())
-    return false;
-
-  return (!Triple.isMacOSXVersionLT(10, 5) &&
-          (Triple.getArch() == llvm::Triple::x86_64 ||
-           Triple.getArch() == llvm::Triple::arm));
-}
-
-/// Adds exception related arguments to the driver command arguments. There's a
-/// master flag, -fexceptions and also language specific flags to enable/disable
-/// C++ and Objective-C exceptions. This makes it possible to for example
-/// disable C++ exceptions but enable Objective-C exceptions.
-static void addExceptionArgs(const ArgList &Args, types::ID InputType,
-                             const ToolChain &TC, bool KernelOrKext,
-                             const ObjCRuntime &objcRuntime,
-                             ArgStringList &CmdArgs) {
-  const Driver &D = TC.getDriver();
-  const llvm::Triple &Triple = TC.getTriple();
-
-  if (KernelOrKext) {
-    // -mkernel and -fapple-kext imply no exceptions, so claim exception related
-    // arguments now to avoid warnings about unused arguments.
-    Args.ClaimAllArgs(options::OPT_fexceptions);
-    Args.ClaimAllArgs(options::OPT_fno_exceptions);
-    Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
-    Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
-    Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
-    Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
-    return;
-  }
-
-  // See if the user explicitly enabled exceptions.
-  bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
-                         false);
-
-  // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
-  // is not necessarily sensible, but follows GCC.
-  if (types::isObjC(InputType) &&
-      Args.hasFlag(options::OPT_fobjc_exceptions,
-                   options::OPT_fno_objc_exceptions, true)) {
-    CmdArgs.push_back("-fobjc-exceptions");
-
-    EH |= shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
-  }
-
-  if (types::isCXX(InputType)) {
-    // Disable C++ EH by default on XCore and PS4.
-    bool CXXExceptionsEnabled =
-        Triple.getArch() != llvm::Triple::xcore && !Triple.isPS4CPU();
-    Arg *ExceptionArg = Args.getLastArg(
-        options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
-        options::OPT_fexceptions, options::OPT_fno_exceptions);
-    if (ExceptionArg)
-      CXXExceptionsEnabled =
-          ExceptionArg->getOption().matches(options::OPT_fcxx_exceptions) ||
-          ExceptionArg->getOption().matches(options::OPT_fexceptions);
-
-    if (CXXExceptionsEnabled) {
-      if (Triple.isPS4CPU()) {
-        ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
-        assert(ExceptionArg &&
-               "On the PS4 exceptions should only be enabled if passing "
-               "an argument");
-        if (RTTIMode == ToolChain::RM_DisabledExplicitly) {
-          const Arg *RTTIArg = TC.getRTTIArg();
-          assert(RTTIArg && "RTTI disabled explicitly but no RTTIArg!");
-          D.Diag(diag::err_drv_argument_not_allowed_with)
-              << RTTIArg->getAsString(Args) << ExceptionArg->getAsString(Args);
-        } else if (RTTIMode == ToolChain::RM_EnabledImplicitly)
-          D.Diag(diag::warn_drv_enabling_rtti_with_exceptions);
-      } else
-        assert(TC.getRTTIMode() != ToolChain::RM_DisabledImplicitly);
-
-      CmdArgs.push_back("-fcxx-exceptions");
-
-      EH = true;
-    }
-  }
-
-  if (EH)
-    CmdArgs.push_back("-fexceptions");
-}
-
-static bool ShouldDisableAutolink(const ArgList &Args, const ToolChain &TC) {
-  bool Default = true;
-  if (TC.getTriple().isOSDarwin()) {
-    // The native darwin assembler doesn't support the linker_option directives,
-    // so we disable them if we think the .s file will be passed to it.
-    Default = TC.useIntegratedAs();
-  }
-  return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
-                       Default);
-}
-
-static bool ShouldDisableDwarfDirectory(const ArgList &Args,
-                                        const ToolChain &TC) {
-  bool UseDwarfDirectory =
-      Args.hasFlag(options::OPT_fdwarf_directory_asm,
-                   options::OPT_fno_dwarf_directory_asm, TC.useIntegratedAs());
-  return !UseDwarfDirectory;
-}
-
-/// \brief Check whether the given input tree contains any compilation actions.
-static bool ContainsCompileAction(const Action *A) {
-  if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A))
-    return true;
-
-  for (const auto &AI : A->inputs())
-    if (ContainsCompileAction(AI))
-      return true;
-
-  return false;
-}
-
-/// \brief Check if -relax-all should be passed to the internal assembler.
-/// This is done by default when compiling non-assembler source with -O0.
-static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
-  bool RelaxDefault = true;
-
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
-    RelaxDefault = A->getOption().matches(options::OPT_O0);
-
-  if (RelaxDefault) {
-    RelaxDefault = false;
-    for (const auto &Act : C.getActions()) {
-      if (ContainsCompileAction(Act)) {
-        RelaxDefault = true;
-        break;
-      }
-    }
-  }
-
-  return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
-                      RelaxDefault);
-}
-
-// Convert an arg of the form "-gN" or "-ggdbN" or one of their aliases
-// to the corresponding DebugInfoKind.
-static codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) {
-  assert(A.getOption().matches(options::OPT_gN_Group) &&
-         "Not a -g option that specifies a debug-info level");
-  if (A.getOption().matches(options::OPT_g0) ||
-      A.getOption().matches(options::OPT_ggdb0))
-    return codegenoptions::NoDebugInfo;
-  if (A.getOption().matches(options::OPT_gline_tables_only) ||
-      A.getOption().matches(options::OPT_ggdb1))
-    return codegenoptions::DebugLineTablesOnly;
-  return codegenoptions::LimitedDebugInfo;
-}
-
-// Extract the integer N from a string spelled "-dwarf-N", returning 0
-// on mismatch. The StringRef input (rather than an Arg) allows
-// for use by the "-Xassembler" option parser.
-static unsigned DwarfVersionNum(StringRef ArgValue) {
-  return llvm::StringSwitch<unsigned>(ArgValue)
-      .Case("-gdwarf-2", 2)
-      .Case("-gdwarf-3", 3)
-      .Case("-gdwarf-4", 4)
-      .Case("-gdwarf-5", 5)
-      .Default(0);
-}
-
-static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
-                                    codegenoptions::DebugInfoKind DebugInfoKind,
-                                    unsigned DwarfVersion,
-                                    llvm::DebuggerKind DebuggerTuning) {
-  switch (DebugInfoKind) {
-  case codegenoptions::DebugLineTablesOnly:
-    CmdArgs.push_back("-debug-info-kind=line-tables-only");
-    break;
-  case codegenoptions::LimitedDebugInfo:
-    CmdArgs.push_back("-debug-info-kind=limited");
-    break;
-  case codegenoptions::FullDebugInfo:
-    CmdArgs.push_back("-debug-info-kind=standalone");
-    break;
-  default:
-    break;
-  }
-  if (DwarfVersion > 0)
-    CmdArgs.push_back(
-        Args.MakeArgString("-dwarf-version=" + Twine(DwarfVersion)));
-  switch (DebuggerTuning) {
-  case llvm::DebuggerKind::GDB:
-    CmdArgs.push_back("-debugger-tuning=gdb");
-    break;
-  case llvm::DebuggerKind::LLDB:
-    CmdArgs.push_back("-debugger-tuning=lldb");
-    break;
-  case llvm::DebuggerKind::SCE:
-    CmdArgs.push_back("-debugger-tuning=sce");
-    break;
-  default:
-    break;
-  }
-}
-
-static void CollectArgsForIntegratedAssembler(Compilation &C,
-                                              const ArgList &Args,
-                                              ArgStringList &CmdArgs,
-                                              const Driver &D) {
-  if (UseRelaxAll(C, Args))
-    CmdArgs.push_back("-mrelax-all");
-
-  // Only default to -mincremental-linker-compatible if we think we are
-  // targeting the MSVC linker.
-  bool DefaultIncrementalLinkerCompatible =
-      C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
-  if (Args.hasFlag(options::OPT_mincremental_linker_compatible,
-                   options::OPT_mno_incremental_linker_compatible,
-                   DefaultIncrementalLinkerCompatible))
-    CmdArgs.push_back("-mincremental-linker-compatible");
-
-  switch (C.getDefaultToolChain().getArch()) {
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb:
-    if (Arg *A = Args.getLastArg(options::OPT_mimplicit_it_EQ)) {
-      StringRef Value = A->getValue();
-      if (Value == "always" || Value == "never" || Value == "arm" ||
-          Value == "thumb") {
-        CmdArgs.push_back("-mllvm");
-        CmdArgs.push_back(Args.MakeArgString("-arm-implicit-it=" + Value));
-      } else {
-        D.Diag(diag::err_drv_unsupported_option_argument)
-            << A->getOption().getName() << Value;
-      }
-    }
-    break;
-  default:
-    break;
-  }
-
-  // When passing -I arguments to the assembler we sometimes need to
-  // unconditionally take the next argument.  For example, when parsing
-  // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
-  // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
-  // arg after parsing the '-I' arg.
-  bool TakeNextArg = false;
-
-  // When using an integrated assembler, translate -Wa, and -Xassembler
-  // options.
-  bool CompressDebugSections = false;
-
-  bool UseRelaxRelocations = ENABLE_X86_RELAX_RELOCATIONS;
-  const char *MipsTargetFeature = nullptr;
-  for (const Arg *A :
-       Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
-    A->claim();
-
-    for (StringRef Value : A->getValues()) {
-      if (TakeNextArg) {
-        CmdArgs.push_back(Value.data());
-        TakeNextArg = false;
-        continue;
-      }
-
-      switch (C.getDefaultToolChain().getArch()) {
-      default:
-        break;
-      case llvm::Triple::mips:
-      case llvm::Triple::mipsel:
-      case llvm::Triple::mips64:
-      case llvm::Triple::mips64el:
-        if (Value == "--trap") {
-          CmdArgs.push_back("-target-feature");
-          CmdArgs.push_back("+use-tcc-in-div");
-          continue;
-        }
-        if (Value == "--break") {
-          CmdArgs.push_back("-target-feature");
-          CmdArgs.push_back("-use-tcc-in-div");
-          continue;
-        }
-        if (Value.startswith("-msoft-float")) {
-          CmdArgs.push_back("-target-feature");
-          CmdArgs.push_back("+soft-float");
-          continue;
-        }
-        if (Value.startswith("-mhard-float")) {
-          CmdArgs.push_back("-target-feature");
-          CmdArgs.push_back("-soft-float");
-          continue;
-        }
-
-        MipsTargetFeature = llvm::StringSwitch<const char *>(Value)
-                                .Case("-mips1", "+mips1")
-                                .Case("-mips2", "+mips2")
-                                .Case("-mips3", "+mips3")
-                                .Case("-mips4", "+mips4")
-                                .Case("-mips5", "+mips5")
-                                .Case("-mips32", "+mips32")
-                                .Case("-mips32r2", "+mips32r2")
-                                .Case("-mips32r3", "+mips32r3")
-                                .Case("-mips32r5", "+mips32r5")
-                                .Case("-mips32r6", "+mips32r6")
-                                .Case("-mips64", "+mips64")
-                                .Case("-mips64r2", "+mips64r2")
-                                .Case("-mips64r3", "+mips64r3")
-                                .Case("-mips64r5", "+mips64r5")
-                                .Case("-mips64r6", "+mips64r6")
-                                .Default(nullptr);
-        if (MipsTargetFeature)
-          continue;
-      }
-
-      if (Value == "-force_cpusubtype_ALL") {
-        // Do nothing, this is the default and we don't support anything else.
-      } else if (Value == "-L") {
-        CmdArgs.push_back("-msave-temp-labels");
-      } else if (Value == "--fatal-warnings") {
-        CmdArgs.push_back("-massembler-fatal-warnings");
-      } else if (Value == "--noexecstack") {
-        CmdArgs.push_back("-mnoexecstack");
-      } else if (Value == "-compress-debug-sections" ||
-                 Value == "--compress-debug-sections") {
-        CompressDebugSections = true;
-      } else if (Value == "-nocompress-debug-sections" ||
-                 Value == "--nocompress-debug-sections") {
-        CompressDebugSections = false;
-      } else if (Value == "-mrelax-relocations=yes" ||
-                 Value == "--mrelax-relocations=yes") {
-        UseRelaxRelocations = true;
-      } else if (Value == "-mrelax-relocations=no" ||
-                 Value == "--mrelax-relocations=no") {
-        UseRelaxRelocations = false;
-      } else if (Value.startswith("-I")) {
-        CmdArgs.push_back(Value.data());
-        // We need to consume the next argument if the current arg is a plain
-        // -I. The next arg will be the include directory.
-        if (Value == "-I")
-          TakeNextArg = true;
-      } else if (Value.startswith("-gdwarf-")) {
-        // "-gdwarf-N" options are not cc1as options.
-        unsigned DwarfVersion = DwarfVersionNum(Value);
-        if (DwarfVersion == 0) { // Send it onward, and let cc1as complain.
-          CmdArgs.push_back(Value.data());
-        } else {
-          RenderDebugEnablingArgs(Args, CmdArgs,
-                                  codegenoptions::LimitedDebugInfo,
-                                  DwarfVersion, llvm::DebuggerKind::Default);
-        }
-      } else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") ||
-                 Value.startswith("-mhwdiv") || Value.startswith("-march")) {
-        // Do nothing, we'll validate it later.
-      } else if (Value == "-defsym") {
-          if (A->getNumValues() != 2) {
-            D.Diag(diag::err_drv_defsym_invalid_format) << Value;
-            break;
-          }
-          const char *S = A->getValue(1);
-          auto Pair = StringRef(S).split('=');
-          auto Sym = Pair.first;
-          auto SVal = Pair.second;
-
-          if (Sym.empty() || SVal.empty()) {
-            D.Diag(diag::err_drv_defsym_invalid_format) << S;
-            break;
-          }
-          int64_t IVal;
-          if (SVal.getAsInteger(0, IVal)) {
-            D.Diag(diag::err_drv_defsym_invalid_symval) << SVal;
-            break;
-          }
-          CmdArgs.push_back(Value.data());
-          TakeNextArg = true;
-      } else {
-        D.Diag(diag::err_drv_unsupported_option_argument)
-            << A->getOption().getName() << Value;
-      }
-    }
-  }
-  if (CompressDebugSections) {
-    if (llvm::zlib::isAvailable())
-      CmdArgs.push_back("-compress-debug-sections");
-    else
-      D.Diag(diag::warn_debug_compression_unavailable);
-  }
-  if (UseRelaxRelocations)
-    CmdArgs.push_back("--mrelax-relocations");
-  if (MipsTargetFeature != nullptr) {
-    CmdArgs.push_back("-target-feature");
-    CmdArgs.push_back(MipsTargetFeature);
-  }
-}
-
-// This adds the static libclang_rt.builtins-arch.a directly to the command line
-// FIXME: Make sure we can also emit shared objects if they're requested
-// and available, check for possible errors, etc.
-static void addClangRT(const ToolChain &TC, const ArgList &Args,
-                       ArgStringList &CmdArgs) {
-  CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
-}
-
-static void addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
-                              const ArgList &Args) {
-  if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
-                    options::OPT_fno_openmp, false))
-    return;
-
-  switch (TC.getDriver().getOpenMPRuntime(Args)) {
-  case Driver::OMPRT_OMP:
-    CmdArgs.push_back("-lomp");
-    break;
-  case Driver::OMPRT_GOMP:
-    CmdArgs.push_back("-lgomp");
-    break;
-  case Driver::OMPRT_IOMP5:
-    CmdArgs.push_back("-liomp5");
-    break;
-  case Driver::OMPRT_Unknown:
-    // Already diagnosed.
-    break;
-  }
-}
-
-static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
-                                ArgStringList &CmdArgs, StringRef Sanitizer,
-                                bool IsShared, bool IsWhole) {
-  // Wrap any static runtimes that must be forced into executable in
-  // whole-archive.
-  if (IsWhole) CmdArgs.push_back("-whole-archive");
-  CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared));
-  if (IsWhole) CmdArgs.push_back("-no-whole-archive");
-}
-
-// Tries to use a file with the list of dynamic symbols that need to be exported
-// from the runtime library. Returns true if the file was found.
-static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
-                                    ArgStringList &CmdArgs,
-                                    StringRef Sanitizer) {
-  SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer));
-  if (llvm::sys::fs::exists(SanRT + ".syms")) {
-    CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
-    return true;
-  }
-  return false;
-}
-
-static void linkSanitizerRuntimeDeps(const ToolChain &TC,
-                                     ArgStringList &CmdArgs) {
-  // Force linking against the system libraries sanitizers depends on
-  // (see PR15823 why this is necessary).
-  CmdArgs.push_back("--no-as-needed");
-  // There's no libpthread or librt on RTEMS.
-  if (TC.getTriple().getOS() != llvm::Triple::RTEMS) {
-    CmdArgs.push_back("-lpthread");
-    CmdArgs.push_back("-lrt");
-  }
-  CmdArgs.push_back("-lm");
-  // There's no libdl on FreeBSD or RTEMS.
-  if (TC.getTriple().getOS() != llvm::Triple::FreeBSD &&
-      TC.getTriple().getOS() != llvm::Triple::RTEMS)
-    CmdArgs.push_back("-ldl");
-}
-
-static void
-collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
-                         SmallVectorImpl<StringRef> &SharedRuntimes,
-                         SmallVectorImpl<StringRef> &StaticRuntimes,
-                         SmallVectorImpl<StringRef> &NonWholeStaticRuntimes,
-                         SmallVectorImpl<StringRef> &HelperStaticRuntimes,
-                         SmallVectorImpl<StringRef> &RequiredSymbols) {
-  const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
-  // Collect shared runtimes.
-  if (SanArgs.needsAsanRt() && SanArgs.needsSharedAsanRt()) {
-    SharedRuntimes.push_back("asan");
-  }
-  // The stats_client library is also statically linked into DSOs.
-  if (SanArgs.needsStatsRt())
-    StaticRuntimes.push_back("stats_client");
-
-  // Collect static runtimes.
-  if (Args.hasArg(options::OPT_shared) || TC.getTriple().isAndroid()) {
-    // Don't link static runtimes into DSOs or if compiling for Android.
-    return;
-  }
-  if (SanArgs.needsAsanRt()) {
-    if (SanArgs.needsSharedAsanRt()) {
-      HelperStaticRuntimes.push_back("asan-preinit");
-    } else {
-      StaticRuntimes.push_back("asan");
-      if (SanArgs.linkCXXRuntimes())
-        StaticRuntimes.push_back("asan_cxx");
-    }
-  }
-  if (SanArgs.needsDfsanRt())
-    StaticRuntimes.push_back("dfsan");
-  if (SanArgs.needsLsanRt())
-    StaticRuntimes.push_back("lsan");
-  if (SanArgs.needsMsanRt()) {
-    StaticRuntimes.push_back("msan");
-    if (SanArgs.linkCXXRuntimes())
-      StaticRuntimes.push_back("msan_cxx");
-  }
-  if (SanArgs.needsTsanRt()) {
-    StaticRuntimes.push_back("tsan");
-    if (SanArgs.linkCXXRuntimes())
-      StaticRuntimes.push_back("tsan_cxx");
-  }
-  if (SanArgs.needsUbsanRt()) {
-    StaticRuntimes.push_back("ubsan_standalone");
-    if (SanArgs.linkCXXRuntimes())
-      StaticRuntimes.push_back("ubsan_standalone_cxx");
-  }
-  if (SanArgs.needsSafeStackRt())
-    StaticRuntimes.push_back("safestack");
-  if (SanArgs.needsCfiRt())
-    StaticRuntimes.push_back("cfi");
-  if (SanArgs.needsCfiDiagRt()) {
-    StaticRuntimes.push_back("cfi_diag");
-    if (SanArgs.linkCXXRuntimes())
-      StaticRuntimes.push_back("ubsan_standalone_cxx");
-  }
-  if (SanArgs.needsStatsRt()) {
-    NonWholeStaticRuntimes.push_back("stats");
-    RequiredSymbols.push_back("__sanitizer_stats_register");
-  }
-  if (SanArgs.needsEsanRt())
-    StaticRuntimes.push_back("esan");
-}
-
-// Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
-// C runtime, etc). Returns true if sanitizer system deps need to be linked in.
-static bool addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
-                                 ArgStringList &CmdArgs) {
-  SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
-      NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols;
-  collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
-                           NonWholeStaticRuntimes, HelperStaticRuntimes,
-                           RequiredSymbols);
-  for (auto RT : SharedRuntimes)
-    addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false);
-  for (auto RT : HelperStaticRuntimes)
-    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
-  bool AddExportDynamic = false;
-  for (auto RT : StaticRuntimes) {
-    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
-    AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
-  }
-  for (auto RT : NonWholeStaticRuntimes) {
-    addSanitizerRuntime(TC, Args, CmdArgs, RT, false, false);
-    AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
-  }
-  for (auto S : RequiredSymbols) {
-    CmdArgs.push_back("-u");
-    CmdArgs.push_back(Args.MakeArgString(S));
-  }
-  // If there is a static runtime with no dynamic list, force all the symbols
-  // to be dynamic to be sure we export sanitizer interface functions.
-  if (AddExportDynamic)
-    CmdArgs.push_back("-export-dynamic");
-
-  const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
-  if (SanArgs.hasCrossDsoCfi() && !AddExportDynamic)
-    CmdArgs.push_back("-export-dynamic-symbol=__cfi_check");
-
-  return !StaticRuntimes.empty();
-}
-
-static bool addXRayRuntime(const ToolChain &TC, const ArgList &Args,
-                           ArgStringList &CmdArgs) {
-  if (Args.hasFlag(options::OPT_fxray_instrument,
-                   options::OPT_fnoxray_instrument, false)) {
-    CmdArgs.push_back("-whole-archive");
-    CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray", false));
-    CmdArgs.push_back("-no-whole-archive");
-    return true;
-  }
-  return false;
-}
-
-static void linkXRayRuntimeDeps(const ToolChain &TC, const ArgList &Args,
-                                ArgStringList &CmdArgs) {
-  CmdArgs.push_back("--no-as-needed");
-  CmdArgs.push_back("-lpthread");
-  CmdArgs.push_back("-lrt");
-  CmdArgs.push_back("-lm");
-  CmdArgs.push_back("-latomic");
-  if (TC.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
-    CmdArgs.push_back("-lc++");
-  else
-    CmdArgs.push_back("-lstdc++");
-  if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
-    CmdArgs.push_back("-ldl");
-}
-
-static bool areOptimizationsEnabled(const ArgList &Args) {
-  // Find the last -O arg and see if it is non-zero.
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
-    return !A->getOption().matches(options::OPT_O0);
-  // Defaults to -O0.
-  return false;
-}
-
-static bool mustUseFramePointerForTarget(const llvm::Triple &Triple) {
-  switch (Triple.getArch()){
-  default:
-    return false;
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-    // ARM Darwin targets require a frame pointer to be always present to aid
-    // offline debugging via backtraces.
-    return Triple.isOSDarwin();
-  }
-}
-
-static bool useFramePointerForTargetByDefault(const ArgList &Args,
-                                              const llvm::Triple &Triple) {
-  switch (Triple.getArch()) {
-  case llvm::Triple::xcore:
-  case llvm::Triple::wasm32:
-  case llvm::Triple::wasm64:
-    // XCore never wants frame pointers, regardless of OS.
-    // WebAssembly never wants frame pointers.
-    return false;
-  default:
-    break;
-  }
-
-  if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI) {
-    switch (Triple.getArch()) {
-    // Don't use a frame pointer on linux if optimizing for certain targets.
-    case llvm::Triple::mips64:
-    case llvm::Triple::mips64el:
-    case llvm::Triple::mips:
-    case llvm::Triple::mipsel:
-    case llvm::Triple::systemz:
-    case llvm::Triple::x86:
-    case llvm::Triple::x86_64:
-      return !areOptimizationsEnabled(Args);
-    default:
-      return true;
-    }
-  }
-
-  if (Triple.isOSWindows()) {
-    switch (Triple.getArch()) {
-    case llvm::Triple::x86:
-      return !areOptimizationsEnabled(Args);
-    case llvm::Triple::x86_64:
-      return Triple.isOSBinFormatMachO();
-    case llvm::Triple::arm:
-    case llvm::Triple::thumb:
-      // Windows on ARM builds with FPO disabled to aid fast stack walking
-      return true;
-    default:
-      // All other supported Windows ISAs use xdata unwind information, so frame
-      // pointers are not generally useful.
-      return false;
-    }
-  }
-
-  return true;
-}
-
-static bool shouldUseFramePointer(const ArgList &Args,
-                                  const llvm::Triple &Triple) {
-  if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
-                               options::OPT_fomit_frame_pointer))
-    return A->getOption().matches(options::OPT_fno_omit_frame_pointer) ||
-           mustUseFramePointerForTarget(Triple);
-
-  if (Args.hasArg(options::OPT_pg))
-    return true;
-
-  return useFramePointerForTargetByDefault(Args, Triple);
-}
-
-static bool shouldUseLeafFramePointer(const ArgList &Args,
-                                      const llvm::Triple &Triple) {
-  if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
-                               options::OPT_momit_leaf_frame_pointer))
-    return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer) ||
-           mustUseFramePointerForTarget(Triple);
-
-  if (Args.hasArg(options::OPT_pg))
-    return true;
-
-  if (Triple.isPS4CPU())
-    return false;
-
-  return useFramePointerForTargetByDefault(Args, Triple);
-}
-
-/// Add a CC1 option to specify the debug compilation directory.
-static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
-  SmallString<128> cwd;
-  if (!llvm::sys::fs::current_path(cwd)) {
-    CmdArgs.push_back("-fdebug-compilation-dir");
-    CmdArgs.push_back(Args.MakeArgString(cwd));
-  }
-}
-
-static const char *SplitDebugName(const ArgList &Args, const InputInfo &Input) {
-  Arg *FinalOutput = Args.getLastArg(options::OPT_o);
-  if (FinalOutput && Args.hasArg(options::OPT_c)) {
-    SmallString<128> T(FinalOutput->getValue());
-    llvm::sys::path::replace_extension(T, "dwo");
-    return Args.MakeArgString(T);
-  } else {
-    // Use the compilation dir.
-    SmallString<128> T(
-        Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
-    SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput()));
-    llvm::sys::path::replace_extension(F, "dwo");
-    T += F;
-    return Args.MakeArgString(F);
-  }
-}
-
-static void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
-                           const JobAction &JA, const ArgList &Args,
-                           const InputInfo &Output, const char *OutFile) {
-  ArgStringList ExtractArgs;
-  ExtractArgs.push_back("--extract-dwo");
-
-  ArgStringList StripArgs;
-  StripArgs.push_back("--strip-dwo");
-
-  // Grabbing the output of the earlier compile step.
-  StripArgs.push_back(Output.getFilename());
-  ExtractArgs.push_back(Output.getFilename());
-  ExtractArgs.push_back(OutFile);
-
-  const char *Exec = Args.MakeArgString(TC.GetProgramPath("objcopy"));
-  InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename());
-
-  // First extract the dwo sections.
-  C.addCommand(llvm::make_unique<Command>(JA, T, Exec, ExtractArgs, II));
-
-  // Then remove them from the original .o file.
-  C.addCommand(llvm::make_unique<Command>(JA, T, Exec, StripArgs, II));
-}
-
-/// \brief Vectorize at all optimization levels greater than 1 except for -Oz.
-/// For -Oz the loop vectorizer is disable, while the slp vectorizer is enabled.
-static bool shouldEnableVectorizerAtOLevel(const ArgList &Args, bool isSlpVec) {
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    if (A->getOption().matches(options::OPT_O4) ||
-        A->getOption().matches(options::OPT_Ofast))
-      return true;
-
-    if (A->getOption().matches(options::OPT_O0))
-      return false;
-
-    assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
-
-    // Vectorize -Os.
-    StringRef S(A->getValue());
-    if (S == "s")
-      return true;
-
-    // Don't vectorize -Oz, unless it's the slp vectorizer.
-    if (S == "z")
-      return isSlpVec;
-
-    unsigned OptLevel = 0;
-    if (S.getAsInteger(10, OptLevel))
-      return false;
-
-    return OptLevel > 1;
-  }
-
-  return false;
-}
-
-/// Add -x lang to \p CmdArgs for \p Input.
-static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
-                             ArgStringList &CmdArgs) {
-  // When using -verify-pch, we don't want to provide the type
-  // 'precompiled-header' if it was inferred from the file extension
-  if (Args.hasArg(options::OPT_verify_pch) && Input.getType() == types::TY_PCH)
-    return;
-
-  CmdArgs.push_back("-x");
-  if (Args.hasArg(options::OPT_rewrite_objc))
-    CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
-  else
-    CmdArgs.push_back(types::getTypeName(Input.getType()));
-}
-
-// Claim options we don't want to warn if they are unused. We do this for
-// options that build systems might add but are unused when assembling or only
-// running the preprocessor for example.
-static void claimNoWarnArgs(const ArgList &Args) {
-  // Don't warn about unused -f(no-)?lto.  This can happen when we're
-  // preprocessing, precompiling or assembling.
-  Args.ClaimAllArgs(options::OPT_flto_EQ);
-  Args.ClaimAllArgs(options::OPT_flto);
-  Args.ClaimAllArgs(options::OPT_fno_lto);
-}
-
-static void appendUserToPath(SmallVectorImpl<char> &Result) {
-#ifdef LLVM_ON_UNIX
-  const char *Username = getenv("LOGNAME");
-#else
-  const char *Username = getenv("USERNAME");
-#endif
-  if (Username) {
-    // Validate that LoginName can be used in a path, and get its length.
-    size_t Len = 0;
-    for (const char *P = Username; *P; ++P, ++Len) {
-      if (!isAlphanumeric(*P) && *P != '_') {
-        Username = nullptr;
-        break;
-      }
-    }
-
-    if (Username && Len > 0) {
-      Result.append(Username, Username + Len);
-      return;
-    }
-  }
-
-// Fallback to user id.
-#ifdef LLVM_ON_UNIX
-  std::string UID = llvm::utostr(getuid());
-#else
-  // FIXME: Windows seems to have an 'SID' that might work.
-  std::string UID = "9999";
-#endif
-  Result.append(UID.begin(), UID.end());
-}
-
-static Arg *getLastProfileUseArg(const ArgList &Args) {
-  auto *ProfileUseArg = Args.getLastArg(
-      options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ,
-      options::OPT_fprofile_use, options::OPT_fprofile_use_EQ,
-      options::OPT_fno_profile_instr_use);
-
-  if (ProfileUseArg &&
-      ProfileUseArg->getOption().matches(options::OPT_fno_profile_instr_use))
-    ProfileUseArg = nullptr;
-
-  return ProfileUseArg;
-}
-
-static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
-                                   const InputInfo &Output, const ArgList &Args,
-                                   ArgStringList &CmdArgs) {
-
-  auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate,
-                                         options::OPT_fprofile_generate_EQ,
-                                         options::OPT_fno_profile_generate);
-  if (PGOGenerateArg &&
-      PGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
-    PGOGenerateArg = nullptr;
-
-  auto *ProfileGenerateArg = Args.getLastArg(
-      options::OPT_fprofile_instr_generate,
-      options::OPT_fprofile_instr_generate_EQ,
-      options::OPT_fno_profile_instr_generate);
-  if (ProfileGenerateArg &&
-      ProfileGenerateArg->getOption().matches(
-          options::OPT_fno_profile_instr_generate))
-    ProfileGenerateArg = nullptr;
-
-  if (PGOGenerateArg && ProfileGenerateArg)
-    D.Diag(diag::err_drv_argument_not_allowed_with)
-        << PGOGenerateArg->getSpelling() << ProfileGenerateArg->getSpelling();
-
-  auto *ProfileUseArg = getLastProfileUseArg(Args);
-
-  if (PGOGenerateArg && ProfileUseArg)
-    D.Diag(diag::err_drv_argument_not_allowed_with)
-        << ProfileUseArg->getSpelling() << PGOGenerateArg->getSpelling();
-
-  if (ProfileGenerateArg && ProfileUseArg)
-    D.Diag(diag::err_drv_argument_not_allowed_with)
-        << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();
-
-  if (ProfileGenerateArg) {
-    if (ProfileGenerateArg->getOption().matches(
-            options::OPT_fprofile_instr_generate_EQ))
-      CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-instrument-path=") +
-                                           ProfileGenerateArg->getValue()));
-    // The default is to use Clang Instrumentation.
-    CmdArgs.push_back("-fprofile-instrument=clang");
-  }
-
-  if (PGOGenerateArg) {
-    CmdArgs.push_back("-fprofile-instrument=llvm");
-    if (PGOGenerateArg->getOption().matches(
-            options::OPT_fprofile_generate_EQ)) {
-      SmallString<128> Path(PGOGenerateArg->getValue());
-      llvm::sys::path::append(Path, "default_%m.profraw");
-      CmdArgs.push_back(
-          Args.MakeArgString(Twine("-fprofile-instrument-path=") + Path));
-    }
-  }
-
-  if (ProfileUseArg) {
-    if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
-      CmdArgs.push_back(Args.MakeArgString(
-          Twine("-fprofile-instrument-use-path=") + ProfileUseArg->getValue()));
-    else if ((ProfileUseArg->getOption().matches(
-                  options::OPT_fprofile_use_EQ) ||
-              ProfileUseArg->getOption().matches(
-                  options::OPT_fprofile_instr_use))) {
-      SmallString<128> Path(
-          ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
-      if (Path.empty() || llvm::sys::fs::is_directory(Path))
-        llvm::sys::path::append(Path, "default.profdata");
-      CmdArgs.push_back(
-          Args.MakeArgString(Twine("-fprofile-instrument-use-path=") + Path));
-    }
-  }
-
-  if (Args.hasArg(options::OPT_ftest_coverage) ||
-      Args.hasArg(options::OPT_coverage))
-    CmdArgs.push_back("-femit-coverage-notes");
-  if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
-                   false) ||
-      Args.hasArg(options::OPT_coverage))
-    CmdArgs.push_back("-femit-coverage-data");
-
-  if (Args.hasFlag(options::OPT_fcoverage_mapping,
-                   options::OPT_fno_coverage_mapping, false) &&
-      !ProfileGenerateArg)
-    D.Diag(diag::err_drv_argument_only_allowed_with)
-        << "-fcoverage-mapping"
-        << "-fprofile-instr-generate";
-
-  if (Args.hasFlag(options::OPT_fcoverage_mapping,
-                   options::OPT_fno_coverage_mapping, false))
-    CmdArgs.push_back("-fcoverage-mapping");
-
-  if (C.getArgs().hasArg(options::OPT_c) ||
-      C.getArgs().hasArg(options::OPT_S)) {
-    if (Output.isFilename()) {
-      CmdArgs.push_back("-coverage-notes-file");
-      SmallString<128> OutputFilename;
-      if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
-        OutputFilename = FinalOutput->getValue();
-      else
-        OutputFilename = llvm::sys::path::filename(Output.getBaseInput());
-      SmallString<128> CoverageFilename = OutputFilename;
-      if (llvm::sys::path::is_relative(CoverageFilename)) {
-        SmallString<128> Pwd;
-        if (!llvm::sys::fs::current_path(Pwd)) {
-          llvm::sys::path::append(Pwd, CoverageFilename);
-          CoverageFilename.swap(Pwd);
-        }
-      }
-      llvm::sys::path::replace_extension(CoverageFilename, "gcno");
-      CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
-
-      // Leave -fprofile-dir= an unused argument unless .gcda emission is
-      // enabled. To be polite, with '-fprofile-arcs -fno-profile-arcs' consider
-      // the flag used. There is no -fno-profile-dir, so the user has no
-      // targeted way to suppress the warning.
-      if (Args.hasArg(options::OPT_fprofile_arcs) ||
-          Args.hasArg(options::OPT_coverage)) {
-        CmdArgs.push_back("-coverage-data-file");
-        if (Arg *FProfileDir = Args.getLastArg(options::OPT_fprofile_dir)) {
-          CoverageFilename = FProfileDir->getValue();
-          llvm::sys::path::append(CoverageFilename, OutputFilename);
-        }
-        llvm::sys::path::replace_extension(CoverageFilename, "gcda");
-        CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
-      }
-    }
-  }
-}
-
-static void addPS4ProfileRTArgs(const ToolChain &TC, const ArgList &Args,
-                                ArgStringList &CmdArgs) {
-  if ((Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
-                    false) ||
-       Args.hasFlag(options::OPT_fprofile_generate,
-                    options::OPT_fno_profile_instr_generate, false) ||
-       Args.hasFlag(options::OPT_fprofile_generate_EQ,
-                    options::OPT_fno_profile_instr_generate, false) ||
-       Args.hasFlag(options::OPT_fprofile_instr_generate,
-                    options::OPT_fno_profile_instr_generate, false) ||
-       Args.hasFlag(options::OPT_fprofile_instr_generate_EQ,
-                    options::OPT_fno_profile_instr_generate, false) ||
-       Args.hasArg(options::OPT_fcreate_profile) ||
-       Args.hasArg(options::OPT_coverage)))
-    CmdArgs.push_back("--dependent-lib=libclang_rt.profile-x86_64.a");
-}
-
-/// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments.  Then,
-/// smooshes them together with platform defaults, to decide whether
-/// this compile should be using PIC mode or not. Returns a tuple of
-/// (RelocationModel, PICLevel, IsPIE).
-static std::tuple<llvm::Reloc::Model, unsigned, bool>
-ParsePICArgs(const ToolChain &ToolChain, const llvm::Triple &Triple,
-             const ArgList &Args) {
-  // FIXME: why does this code...and so much everywhere else, use both
-  // ToolChain.getTriple() and Triple?
-  bool PIE = ToolChain.isPIEDefault();
-  bool PIC = PIE || ToolChain.isPICDefault();
-  // The Darwin/MachO default to use PIC does not apply when using -static.
-  if (ToolChain.getTriple().isOSBinFormatMachO() &&
-      Args.hasArg(options::OPT_static))
-    PIE = PIC = false;
-  bool IsPICLevelTwo = PIC;
-
-  bool KernelOrKext =
-      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
-
-  // Android-specific defaults for PIC/PIE
-  if (ToolChain.getTriple().isAndroid()) {
-    switch (ToolChain.getArch()) {
-    case llvm::Triple::arm:
-    case llvm::Triple::armeb:
-    case llvm::Triple::thumb:
-    case llvm::Triple::thumbeb:
-    case llvm::Triple::aarch64:
-    case llvm::Triple::mips:
-    case llvm::Triple::mipsel:
-    case llvm::Triple::mips64:
-    case llvm::Triple::mips64el:
-      PIC = true; // "-fpic"
-      break;
-
-    case llvm::Triple::x86:
-    case llvm::Triple::x86_64:
-      PIC = true; // "-fPIC"
-      IsPICLevelTwo = true;
-      break;
-
-    default:
-      break;
-    }
-  }
-
-  // OpenBSD-specific defaults for PIE
-  if (ToolChain.getTriple().getOS() == llvm::Triple::OpenBSD) {
-    switch (ToolChain.getArch()) {
-    case llvm::Triple::mips64:
-    case llvm::Triple::mips64el:
-    case llvm::Triple::sparcel:
-    case llvm::Triple::x86:
-    case llvm::Triple::x86_64:
-      IsPICLevelTwo = false; // "-fpie"
-      break;
-
-    case llvm::Triple::ppc:
-    case llvm::Triple::sparc:
-    case llvm::Triple::sparcv9:
-      IsPICLevelTwo = true; // "-fPIE"
-      break;
-
-    default:
-      break;
-    }
-  }
-
-  // The last argument relating to either PIC or PIE wins, and no
-  // other argument is used. If the last argument is any flavor of the
-  // '-fno-...' arguments, both PIC and PIE are disabled. Any PIE
-  // option implicitly enables PIC at the same level.
-  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
-                                    options::OPT_fpic, options::OPT_fno_pic,
-                                    options::OPT_fPIE, options::OPT_fno_PIE,
-                                    options::OPT_fpie, options::OPT_fno_pie);
-  // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
-  // is forced, then neither PIC nor PIE flags will have no effect.
-  if (!ToolChain.isPICDefaultForced()) {
-    if (LastPICArg) {
-      Option O = LastPICArg->getOption();
-      if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
-          O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
-        PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
-        PIC =
-            PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
-        IsPICLevelTwo =
-            O.matches(options::OPT_fPIE) || O.matches(options::OPT_fPIC);
-      } else {
-        PIE = PIC = false;
-        if (Triple.isPS4CPU()) {
-          Arg *ModelArg = Args.getLastArg(options::OPT_mcmodel_EQ);
-          StringRef Model = ModelArg ? ModelArg->getValue() : "";
-          if (Model != "kernel") {
-            PIC = true;
-            ToolChain.getDriver().Diag(diag::warn_drv_ps4_force_pic)
-                << LastPICArg->getSpelling();
-          }
-        }
-      }
-    }
-  }
-
-  // Introduce a Darwin and PS4-specific hack. If the default is PIC, but the
-  // PIC level would've been set to level 1, force it back to level 2 PIC
-  // instead.
-  if (PIC && (ToolChain.getTriple().isOSDarwin() || Triple.isPS4CPU()))
-    IsPICLevelTwo |= ToolChain.isPICDefault();
-
-  // This kernel flags are a trump-card: they will disable PIC/PIE
-  // generation, independent of the argument order.
-  if (KernelOrKext && ((!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
-                       !Triple.isWatchOS()))
-    PIC = PIE = false;
-
-  if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
-    // This is a very special mode. It trumps the other modes, almost no one
-    // uses it, and it isn't even valid on any OS but Darwin.
-    if (!ToolChain.getTriple().isOSDarwin())
-      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
-          << A->getSpelling() << ToolChain.getTriple().str();
-
-    // FIXME: Warn when this flag trumps some other PIC or PIE flag.
-
-    // Only a forced PIC mode can cause the actual compile to have PIC defines
-    // etc., no flags are sufficient. This behavior was selected to closely
-    // match that of llvm-gcc and Apple GCC before that.
-    PIC = ToolChain.isPICDefault() && ToolChain.isPICDefaultForced();
-
-    return std::make_tuple(llvm::Reloc::DynamicNoPIC, PIC ? 2U : 0U, false);
-  }
-
-  bool EmbeddedPISupported;
-  switch (ToolChain.getArch()) {
-    case llvm::Triple::arm:
-    case llvm::Triple::armeb:
-    case llvm::Triple::thumb:
-    case llvm::Triple::thumbeb:
-      EmbeddedPISupported = true;
-      break;
-    default:
-      EmbeddedPISupported = false;
-      break;
-  }
-
-  bool ROPI = false, RWPI = false;
-  Arg* LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi);
-  if (LastROPIArg && LastROPIArg->getOption().matches(options::OPT_fropi)) {
-    if (!EmbeddedPISupported)
-      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
-          << LastROPIArg->getSpelling() << ToolChain.getTriple().str();
-    ROPI = true;
-  }
-  Arg *LastRWPIArg = Args.getLastArg(options::OPT_frwpi, options::OPT_fno_rwpi);
-  if (LastRWPIArg && LastRWPIArg->getOption().matches(options::OPT_frwpi)) {
-    if (!EmbeddedPISupported)
-      ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
-          << LastRWPIArg->getSpelling() << ToolChain.getTriple().str();
-    RWPI = true;
-  }
-
-  // ROPI and RWPI are not comaptible with PIC or PIE.
-  if ((ROPI || RWPI) && (PIC || PIE)) {
-    ToolChain.getDriver().Diag(diag::err_drv_ropi_rwpi_incompatible_with_pic);
-  }
-
-  if (PIC)
-    return std::make_tuple(llvm::Reloc::PIC_, IsPICLevelTwo ? 2U : 1U, PIE);
-
-  llvm::Reloc::Model RelocM = llvm::Reloc::Static;
-  if (ROPI && RWPI)
-    RelocM = llvm::Reloc::ROPI_RWPI;
-  else if (ROPI)
-    RelocM = llvm::Reloc::ROPI;
-  else if (RWPI)
-    RelocM = llvm::Reloc::RWPI;
-
-  return std::make_tuple(RelocM, 0U, false);
-}
-
-static const char *RelocationModelName(llvm::Reloc::Model Model) {
-  switch (Model) {
-  case llvm::Reloc::Static:
-    return "static";
-  case llvm::Reloc::PIC_:
-    return "pic";
-  case llvm::Reloc::DynamicNoPIC:
-    return "dynamic-no-pic";
-  case llvm::Reloc::ROPI:
-    return "ropi";
-  case llvm::Reloc::RWPI:
-    return "rwpi";
-  case llvm::Reloc::ROPI_RWPI:
-    return "ropi-rwpi";
-  }
-  llvm_unreachable("Unknown Reloc::Model kind");
-}
-
-static void AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
-                             ArgStringList &CmdArgs) {
-  llvm::Reloc::Model RelocationModel;
-  unsigned PICLevel;
-  bool IsPIE;
-  std::tie(RelocationModel, PICLevel, IsPIE) =
-      ParsePICArgs(ToolChain, ToolChain.getTriple(), Args);
-
-  if (RelocationModel != llvm::Reloc::Static)
-    CmdArgs.push_back("-KPIC");
-}
-
-void Clang::DumpCompilationDatabase(Compilation &C, StringRef Filename,
-                                    StringRef Target, const InputInfo &Output,
-                                    const InputInfo &Input, const ArgList &Args) const {
-  // If this is a dry run, do not create the compilation database file.
-  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
-    return;
-
-  using llvm::yaml::escape;
-  const Driver &D = getToolChain().getDriver();
-
-  if (!CompilationDatabase) {
-    std::error_code EC;
-    auto File = llvm::make_unique<llvm::raw_fd_ostream>(Filename, EC, llvm::sys::fs::F_Text);
-    if (EC) {
-      D.Diag(clang::diag::err_drv_compilationdatabase) << Filename
-                                                       << EC.message();
-      return;
-    }
-    CompilationDatabase = std::move(File);
-  }
-  auto &CDB = *CompilationDatabase;
-  SmallString<128> Buf;
-  if (llvm::sys::fs::current_path(Buf))
-    Buf = ".";
-  CDB << "{ \"directory\": \"" << escape(Buf) << "\"";
-  CDB << ", \"file\": \"" << escape(Input.getFilename()) << "\"";
-  CDB << ", \"output\": \"" << escape(Output.getFilename()) << "\"";
-  CDB << ", \"arguments\": [\"" << escape(D.ClangExecutable) << "\"";
-  Buf = "-x";
-  Buf += types::getTypeName(Input.getType());
-  CDB << ", \"" << escape(Buf) << "\"";
-  if (!D.SysRoot.empty() && !Args.hasArg(options::OPT__sysroot_EQ)) {
-    Buf = "--sysroot=";
-    Buf += D.SysRoot;
-    CDB << ", \"" << escape(Buf) << "\"";
-  }
-  CDB << ", \"" << escape(Input.getFilename()) << "\"";
-  for (auto &A: Args) {
-    auto &O = A->getOption();
-    // Skip language selection, which is positional.
-    if (O.getID() == options::OPT_x)
-      continue;
-    // Skip writing dependency output and the compilation database itself.
-    if (O.getGroup().isValid() && O.getGroup().getID() == options::OPT_M_Group)
-      continue;
-    // Skip inputs.
-    if (O.getKind() == Option::InputClass)
-      continue;
-    // All other arguments are quoted and appended.
-    ArgStringList ASL;
-    A->render(Args, ASL);
-    for (auto &it: ASL)
-      CDB << ", \"" << escape(it) << "\"";
-  }
-  Buf = "--target=";
-  Buf += Target;
-  CDB << ", \"" << escape(Buf) << "\"]},\n";
-}
-
-void Clang::ConstructJob(Compilation &C, const JobAction &JA,
-                         const InputInfo &Output, const InputInfoList &Inputs,
-                         const ArgList &Args, const char *LinkingOutput) const {
-  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
-  const std::string &TripleStr = Triple.getTriple();
-
-  bool KernelOrKext =
-      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
-  const Driver &D = getToolChain().getDriver();
-  ArgStringList CmdArgs;
-
-  bool IsWindowsGNU = getToolChain().getTriple().isWindowsGNUEnvironment();
-  bool IsWindowsCygnus =
-      getToolChain().getTriple().isWindowsCygwinEnvironment();
-  bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
-  bool IsPS4CPU = getToolChain().getTriple().isPS4CPU();
-  bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
-
-  // Check number of inputs for sanity. We need at least one input.
-  assert(Inputs.size() >= 1 && "Must have at least one input.");
-  const InputInfo &Input = Inputs[0];
-  // CUDA compilation may have multiple inputs (source file + results of
-  // device-side compilations). OpenMP device jobs also take the host IR as a
-  // second input. All other jobs are expected to have exactly one
-  // input.
-  bool IsCuda = JA.isOffloading(Action::OFK_Cuda);
-  bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
-  assert((IsCuda || (IsOpenMPDevice && Inputs.size() == 2) ||
-          Inputs.size() == 1) &&
-         "Unable to handle multiple inputs.");
-
-  // C++ is not supported for IAMCU.
-  if (IsIAMCU && types::isCXX(Input.getType()))
-    D.Diag(diag::err_drv_clang_unsupported) << "C++ for IAMCU";
-
-  // Invoke ourselves in -cc1 mode.
-  //
-  // FIXME: Implement custom jobs for internal actions.
-  CmdArgs.push_back("-cc1");
-
-  // Add the "effective" target triple.
-  CmdArgs.push_back("-triple");
-  CmdArgs.push_back(Args.MakeArgString(TripleStr));
-
-  if (const Arg *MJ = Args.getLastArg(options::OPT_MJ)) {
-    DumpCompilationDatabase(C, MJ->getValue(), TripleStr, Output, Input, Args);
-    Args.ClaimAllArgs(options::OPT_MJ);
-  }
-
-  if (IsCuda) {
-    // We have to pass the triple of the host if compiling for a CUDA device and
-    // vice-versa.
-    std::string NormalizedTriple;
-    if (JA.isDeviceOffloading(Action::OFK_Cuda))
-      NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>()
-                             ->getTriple()
-                             .normalize();
-    else
-      NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Cuda>()
-                             ->getTriple()
-                             .normalize();
-
-    CmdArgs.push_back("-aux-triple");
-    CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
-  }
-
-  if (Triple.isOSWindows() && (Triple.getArch() == llvm::Triple::arm ||
-                               Triple.getArch() == llvm::Triple::thumb)) {
-    unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
-    unsigned Version;
-    Triple.getArchName().substr(Offset).getAsInteger(10, Version);
-    if (Version < 7)
-      D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
-                                                << TripleStr;
-  }
-
-  // Push all default warning arguments that are specific to
-  // the given target.  These come before user provided warning options
-  // are provided.
-  getToolChain().addClangWarningOptions(CmdArgs);
-
-  // Select the appropriate action.
-  RewriteKind rewriteKind = RK_None;
-
-  if (isa<AnalyzeJobAction>(JA)) {
-    assert(JA.getType() == types::TY_Plist && "Invalid output type.");
-    CmdArgs.push_back("-analyze");
-  } else if (isa<MigrateJobAction>(JA)) {
-    CmdArgs.push_back("-migrate");
-  } else if (isa<PreprocessJobAction>(JA)) {
-    if (Output.getType() == types::TY_Dependencies)
-      CmdArgs.push_back("-Eonly");
-    else {
-      CmdArgs.push_back("-E");
-      if (Args.hasArg(options::OPT_rewrite_objc) &&
-          !Args.hasArg(options::OPT_g_Group))
-        CmdArgs.push_back("-P");
-    }
-  } else if (isa<AssembleJobAction>(JA)) {
-    CmdArgs.push_back("-emit-obj");
-
-    CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
-
-    // Also ignore explicit -force_cpusubtype_ALL option.
-    (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
-  } else if (isa<PrecompileJobAction>(JA)) {
-    // Use PCH if the user requested it.
-    bool UsePCH = D.CCCUsePCH;
-
-    if (JA.getType() == types::TY_Nothing)
-      CmdArgs.push_back("-fsyntax-only");
-    else if (JA.getType() == types::TY_ModuleFile)
-      CmdArgs.push_back("-emit-module-interface");
-    else if (UsePCH)
-      CmdArgs.push_back("-emit-pch");
-    else
-      CmdArgs.push_back("-emit-pth");
-  } else if (isa<VerifyPCHJobAction>(JA)) {
-    CmdArgs.push_back("-verify-pch");
-  } else {
-    assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
-           "Invalid action for clang tool.");
-    if (JA.getType() == types::TY_Nothing) {
-      CmdArgs.push_back("-fsyntax-only");
-    } else if (JA.getType() == types::TY_LLVM_IR ||
-               JA.getType() == types::TY_LTO_IR) {
-      CmdArgs.push_back("-emit-llvm");
-    } else if (JA.getType() == types::TY_LLVM_BC ||
-               JA.getType() == types::TY_LTO_BC) {
-      CmdArgs.push_back("-emit-llvm-bc");
-    } else if (JA.getType() == types::TY_PP_Asm) {
-      CmdArgs.push_back("-S");
-    } else if (JA.getType() == types::TY_AST) {
-      CmdArgs.push_back("-emit-pch");
-    } else if (JA.getType() == types::TY_ModuleFile) {
-      CmdArgs.push_back("-module-file-info");
-    } else if (JA.getType() == types::TY_RewrittenObjC) {
-      CmdArgs.push_back("-rewrite-objc");
-      rewriteKind = RK_NonFragile;
-    } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
-      CmdArgs.push_back("-rewrite-objc");
-      rewriteKind = RK_Fragile;
-    } else {
-      assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
-    }
-
-    // Preserve use-list order by default when emitting bitcode, so that
-    // loading the bitcode up in 'opt' or 'llc' and running passes gives the
-    // same result as running passes here.  For LTO, we don't need to preserve
-    // the use-list order, since serialization to bitcode is part of the flow.
-    if (JA.getType() == types::TY_LLVM_BC)
-      CmdArgs.push_back("-emit-llvm-uselists");
-
-    if (D.isUsingLTO())
-      Args.AddLastArg(CmdArgs, options::OPT_flto, options::OPT_flto_EQ);
-  }
-
-  if (const Arg *A = Args.getLastArg(options::OPT_fthinlto_index_EQ)) {
-    if (!types::isLLVMIR(Input.getType()))
-      D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
-                                                       << "-x ir";
-    Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
-  }
-
-  // Embed-bitcode option.
-  if (C.getDriver().embedBitcodeInObject() &&
-      (isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
-    // Add flags implied by -fembed-bitcode.
-    Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
-    // Disable all llvm IR level optimizations.
-    CmdArgs.push_back("-disable-llvm-optzns");
-  }
-  if (C.getDriver().embedBitcodeMarkerOnly())
-    CmdArgs.push_back("-fembed-bitcode=marker");
-
-  // 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
-  CmdArgs.push_back("-disable-llvm-verifier");
-  // Discard LLVM value names in -asserts builds.
-  CmdArgs.push_back("-discard-value-names");
-#endif
-
-  // Set the main file name, so that debug info works even with
-  // -save-temps.
-  CmdArgs.push_back("-main-file-name");
-  CmdArgs.push_back(getBaseInputName(Args, Input));
-
-  // Some flags which affect the language (via preprocessor
-  // defines).
-  if (Args.hasArg(options::OPT_static))
-    CmdArgs.push_back("-static-define");
-
-  if (isa<AnalyzeJobAction>(JA)) {
-    // Enable region store model by default.
-    CmdArgs.push_back("-analyzer-store=region");
-
-    // Treat blocks as analysis entry points.
-    CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
-
-    CmdArgs.push_back("-analyzer-eagerly-assume");
-
-    // Add default argument set.
-    if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
-      CmdArgs.push_back("-analyzer-checker=core");
-
-    if (!IsWindowsMSVC) {
-      CmdArgs.push_back("-analyzer-checker=unix");
-    } else {
-      // Enable "unix" checkers that also work on Windows.
-      CmdArgs.push_back("-analyzer-checker=unix.API");
-      CmdArgs.push_back("-analyzer-checker=unix.Malloc");
-      CmdArgs.push_back("-analyzer-checker=unix.MallocSizeof");
-      CmdArgs.push_back("-analyzer-checker=unix.MismatchedDeallocator");
-      CmdArgs.push_back("-analyzer-checker=unix.cstring.BadSizeArg");
-      CmdArgs.push_back("-analyzer-checker=unix.cstring.NullArg");
-    }
-
-      // Disable some unix checkers for PS4.
-      if (IsPS4CPU) {
-        CmdArgs.push_back("-analyzer-disable-checker=unix.API");
-        CmdArgs.push_back("-analyzer-disable-checker=unix.Vfork");
-      }
-
-      if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
-        CmdArgs.push_back("-analyzer-checker=osx");
-
-      CmdArgs.push_back("-analyzer-checker=deadcode");
-
-      if (types::isCXX(Input.getType()))
-        CmdArgs.push_back("-analyzer-checker=cplusplus");
-
-      if (!IsPS4CPU) {
-        CmdArgs.push_back(
-            "-analyzer-checker=security.insecureAPI.UncheckedReturn");
-        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
-        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets");
-        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp");
-        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
-        CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
-      }
-
-      // Default nullability checks.
-      CmdArgs.push_back("-analyzer-checker=nullability.NullPassedToNonnull");
-      CmdArgs.push_back(
-          "-analyzer-checker=nullability.NullReturnedFromNonnull");
-    }
-
-    // Set the output format. The default is plist, for (lame) historical
-    // reasons.
-    CmdArgs.push_back("-analyzer-output");
-    if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
-      CmdArgs.push_back(A->getValue());
-    else
-      CmdArgs.push_back("plist");
-
-    // Disable the presentation of standard compiler warnings when
-    // using --analyze.  We only want to show static analyzer diagnostics
-    // or frontend errors.
-    CmdArgs.push_back("-w");
-
-    // Add -Xanalyzer arguments when running as analyzer.
-    Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
-  }
-
-  CheckCodeGenerationOptions(D, Args);
-
-  llvm::Reloc::Model RelocationModel;
-  unsigned PICLevel;
-  bool IsPIE;
-  std::tie(RelocationModel, PICLevel, IsPIE) =
-      ParsePICArgs(getToolChain(), Triple, Args);
-
-  const char *RMName = RelocationModelName(RelocationModel);
-
-  if ((RelocationModel == llvm::Reloc::ROPI ||
-       RelocationModel == llvm::Reloc::ROPI_RWPI) &&
-      types::isCXX(Input.getType()) &&
-      !Args.hasArg(options::OPT_fallow_unsupported))
-    D.Diag(diag::err_drv_ropi_incompatible_with_cxx);
-
-  if (RMName) {
-    CmdArgs.push_back("-mrelocation-model");
-    CmdArgs.push_back(RMName);
-  }
-  if (PICLevel > 0) {
-    CmdArgs.push_back("-pic-level");
-    CmdArgs.push_back(PICLevel == 1 ? "1" : "2");
-    if (IsPIE)
-      CmdArgs.push_back("-pic-is-pie");
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_meabi)) {
-    CmdArgs.push_back("-meabi");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  CmdArgs.push_back("-mthread-model");
-  if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
-    CmdArgs.push_back(A->getValue());
-  else
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().getThreadModel()));
-
-  Args.AddLastArg(CmdArgs, options::OPT_fveclib);
-
-  if (!Args.hasFlag(options::OPT_fmerge_all_constants,
-                    options::OPT_fno_merge_all_constants))
-    CmdArgs.push_back("-fno-merge-all-constants");
-
-  // LLVM Code Generator Options.
-
-  if (Args.hasArg(options::OPT_frewrite_map_file) ||
-      Args.hasArg(options::OPT_frewrite_map_file_EQ)) {
-    for (const Arg *A : Args.filtered(options::OPT_frewrite_map_file,
-                                      options::OPT_frewrite_map_file_EQ)) {
-      StringRef Map = A->getValue();
-      if (!llvm::sys::fs::exists(Map)) {
-        D.Diag(diag::err_drv_no_such_file) << Map;
-      } else {
-        CmdArgs.push_back("-frewrite-map-file");
-        CmdArgs.push_back(A->getValue());
-        A->claim();
-      }
-    }
-  }
-
-  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 (!Args.hasFlag(options::OPT_fjump_tables, options::OPT_fno_jump_tables,
-                    true))
-    CmdArgs.push_back("-fno-jump-tables");
-
-  if (!Args.hasFlag(options::OPT_fpreserve_as_comments,
-                    options::OPT_fno_preserve_as_comments, true))
-    CmdArgs.push_back("-fno-preserve-as-comments");
-
-  if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
-    CmdArgs.push_back("-mregparm");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
-                               options::OPT_freg_struct_return)) {
-    if (getToolChain().getArch() != llvm::Triple::x86) {
-      D.Diag(diag::err_drv_unsupported_opt_for_target)
-          << A->getSpelling() << getToolChain().getTriple().str();
-    } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
-      CmdArgs.push_back("-fpcc-struct-return");
-    } else {
-      assert(A->getOption().matches(options::OPT_freg_struct_return));
-      CmdArgs.push_back("-freg-struct-return");
-    }
-  }
-
-  if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
-    CmdArgs.push_back("-fdefault-calling-conv=stdcall");
-
-  if (shouldUseFramePointer(Args, getToolChain().getTriple()))
-    CmdArgs.push_back("-mdisable-fp-elim");
-  if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
-                    options::OPT_fno_zero_initialized_in_bss))
-    CmdArgs.push_back("-mno-zero-initialized-in-bss");
-
-  bool OFastEnabled = isOptimizationLevelFast(Args);
-  // If -Ofast is the optimization level, then -fstrict-aliasing should be
-  // enabled.  This alias option is being used to simplify the hasFlag logic.
-  OptSpecifier StrictAliasingAliasOption =
-      OFastEnabled ? options::OPT_Ofast : options::OPT_fstrict_aliasing;
-  // We turn strict aliasing off by default if we're in CL mode, since MSVC
-  // doesn't do any TBAA.
-  bool TBAAOnByDefault = !getToolChain().getDriver().IsCLMode();
-  if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
-                    options::OPT_fno_strict_aliasing, TBAAOnByDefault))
-    CmdArgs.push_back("-relaxed-aliasing");
-  if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
-                    options::OPT_fno_struct_path_tbaa))
-    CmdArgs.push_back("-no-struct-path-tbaa");
-  if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
-                   false))
-    CmdArgs.push_back("-fstrict-enums");
-  if (Args.hasFlag(options::OPT_fstrict_vtable_pointers,
-                   options::OPT_fno_strict_vtable_pointers,
-                   false))
-    CmdArgs.push_back("-fstrict-vtable-pointers");
-  if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
-                    options::OPT_fno_optimize_sibling_calls))
-    CmdArgs.push_back("-mdisable-tail-calls");
-
-  // Handle segmented stacks.
-  if (Args.hasArg(options::OPT_fsplit_stack))
-    CmdArgs.push_back("-split-stacks");
-
-  // If -Ofast is the optimization level, then -ffast-math should be enabled.
-  // This alias option is being used to simplify the getLastArg logic.
-  OptSpecifier FastMathAliasOption =
-      OFastEnabled ? options::OPT_Ofast : options::OPT_ffast_math;
-
-  // Handle various floating point optimization flags, mapping them to the
-  // appropriate LLVM code generation flags. The pattern for all of these is to
-  // default off the codegen optimizations, and if any flag enables them and no
-  // flag disables them after the flag enabling them, enable the codegen
-  // optimization. This is complicated by several "umbrella" flags.
-  if (Arg *A = Args.getLastArg(
-          options::OPT_ffast_math, FastMathAliasOption,
-          options::OPT_fno_fast_math, options::OPT_ffinite_math_only,
-          options::OPT_fno_finite_math_only, options::OPT_fhonor_infinities,
-          options::OPT_fno_honor_infinities))
-    if (A->getOption().getID() != options::OPT_fno_fast_math &&
-        A->getOption().getID() != options::OPT_fno_finite_math_only &&
-        A->getOption().getID() != options::OPT_fhonor_infinities)
-      CmdArgs.push_back("-menable-no-infs");
-  if (Arg *A = Args.getLastArg(
-          options::OPT_ffast_math, FastMathAliasOption,
-          options::OPT_fno_fast_math, options::OPT_ffinite_math_only,
-          options::OPT_fno_finite_math_only, options::OPT_fhonor_nans,
-          options::OPT_fno_honor_nans))
-    if (A->getOption().getID() != options::OPT_fno_fast_math &&
-        A->getOption().getID() != options::OPT_fno_finite_math_only &&
-        A->getOption().getID() != options::OPT_fhonor_nans)
-      CmdArgs.push_back("-menable-no-nans");
-
-  // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
-  bool MathErrno = getToolChain().IsMathErrnoDefault();
-  if (Arg *A =
-          Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
-                          options::OPT_fno_fast_math, options::OPT_fmath_errno,
-                          options::OPT_fno_math_errno)) {
-    // Turning on -ffast_math (with either flag) removes the need for MathErrno.
-    // However, turning *off* -ffast_math merely restores the toolchain default
-    // (which may be false).
-    if (A->getOption().getID() == options::OPT_fno_math_errno ||
-        A->getOption().getID() == options::OPT_ffast_math ||
-        A->getOption().getID() == options::OPT_Ofast)
-      MathErrno = false;
-    else if (A->getOption().getID() == options::OPT_fmath_errno)
-      MathErrno = true;
-  }
-  if (MathErrno)
-    CmdArgs.push_back("-fmath-errno");
-
-  // There are several flags which require disabling very specific
-  // optimizations. Any of these being disabled forces us to turn off the
-  // entire set of LLVM optimizations, so collect them through all the flag
-  // madness.
-  bool AssociativeMath = false;
-  if (Arg *A = Args.getLastArg(
-          options::OPT_ffast_math, FastMathAliasOption,
-          options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
-          options::OPT_fno_unsafe_math_optimizations,
-          options::OPT_fassociative_math, options::OPT_fno_associative_math))
-    if (A->getOption().getID() != options::OPT_fno_fast_math &&
-        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
-        A->getOption().getID() != options::OPT_fno_associative_math)
-      AssociativeMath = true;
-  bool ReciprocalMath = false;
-  if (Arg *A = Args.getLastArg(
-          options::OPT_ffast_math, FastMathAliasOption,
-          options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
-          options::OPT_fno_unsafe_math_optimizations,
-          options::OPT_freciprocal_math, options::OPT_fno_reciprocal_math))
-    if (A->getOption().getID() != options::OPT_fno_fast_math &&
-        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
-        A->getOption().getID() != options::OPT_fno_reciprocal_math)
-      ReciprocalMath = true;
-  bool SignedZeros = true;
-  if (Arg *A = Args.getLastArg(
-          options::OPT_ffast_math, FastMathAliasOption,
-          options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
-          options::OPT_fno_unsafe_math_optimizations,
-          options::OPT_fsigned_zeros, options::OPT_fno_signed_zeros))
-    if (A->getOption().getID() != options::OPT_fno_fast_math &&
-        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
-        A->getOption().getID() != options::OPT_fsigned_zeros)
-      SignedZeros = false;
-  bool TrappingMath = true;
-  if (Arg *A = Args.getLastArg(
-          options::OPT_ffast_math, FastMathAliasOption,
-          options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
-          options::OPT_fno_unsafe_math_optimizations,
-          options::OPT_ftrapping_math, options::OPT_fno_trapping_math))
-    if (A->getOption().getID() != options::OPT_fno_fast_math &&
-        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
-        A->getOption().getID() != options::OPT_ftrapping_math)
-      TrappingMath = false;
-  if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
-      !TrappingMath)
-    CmdArgs.push_back("-menable-unsafe-fp-math");
-
-  if (!SignedZeros)
-    CmdArgs.push_back("-fno-signed-zeros");
-
-  if (ReciprocalMath)
-    CmdArgs.push_back("-freciprocal-math");
-
-  if (!TrappingMath)
-    CmdArgs.push_back("-fno-trapping-math");
-
-
-  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
-                               options::OPT_fno_fast_math,
-                               options::OPT_funsafe_math_optimizations,
-                               options::OPT_fno_unsafe_math_optimizations,
-                               options::OPT_fdenormal_fp_math_EQ))
-    if (A->getOption().getID() != options::OPT_fno_fast_math &&
-        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations)
-      Args.AddLastArg(CmdArgs, options::OPT_fdenormal_fp_math_EQ);
-
-  // Validate and pass through -fp-contract option.
-  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
-                               options::OPT_fno_fast_math,
-                               options::OPT_ffp_contract)) {
-    if (A->getOption().getID() == options::OPT_ffp_contract) {
-      StringRef Val = A->getValue();
-      if (Val == "fast" || Val == "on" || Val == "off") {
-        CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val));
-      } else {
-        D.Diag(diag::err_drv_unsupported_option_argument)
-            << A->getOption().getName() << Val;
-      }
-    } else if (A->getOption().matches(options::OPT_ffast_math) ||
-               (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) {
-      // If fast-math is set then set the fp-contract mode to fast.
-      CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
-    }
-  }
-
-  ParseMRecip(getToolChain().getDriver(), Args, CmdArgs);
-
-  // We separately look for the '-ffast-math' and '-ffinite-math-only' flags,
-  // and if we find them, tell the frontend to provide the appropriate
-  // preprocessor macros. This is distinct from enabling any optimizations as
-  // these options induce language changes which must survive serialization
-  // and deserialization, etc.
-  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
-                               options::OPT_fno_fast_math))
-    if (!A->getOption().matches(options::OPT_fno_fast_math))
-      CmdArgs.push_back("-ffast-math");
-  if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only,
-                               options::OPT_fno_fast_math))
-    if (A->getOption().matches(options::OPT_ffinite_math_only))
-      CmdArgs.push_back("-ffinite-math-only");
-
-  // Decide whether to use verbose asm. Verbose assembly is the default on
-  // toolchains which have the integrated assembler on by default.
-  bool IsIntegratedAssemblerDefault =
-      getToolChain().IsIntegratedAssemblerDefault();
-  if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
-                   IsIntegratedAssemblerDefault) ||
-      Args.hasArg(options::OPT_dA))
-    CmdArgs.push_back("-masm-verbose");
-
-  if (!Args.hasFlag(options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
-                    IsIntegratedAssemblerDefault))
-    CmdArgs.push_back("-no-integrated-as");
-
-  if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
-    CmdArgs.push_back("-mdebug-pass");
-    CmdArgs.push_back("Structure");
-  }
-  if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
-    CmdArgs.push_back("-mdebug-pass");
-    CmdArgs.push_back("Arguments");
-  }
-
-  // Enable -mconstructor-aliases except on darwin, where we have to work around
-  // a linker bug (see <rdar://problem/7651567>), and CUDA device code, where
-  // aliases aren't supported.
-  if (!getToolChain().getTriple().isOSDarwin() &&
-      !getToolChain().getTriple().isNVPTX())
-    CmdArgs.push_back("-mconstructor-aliases");
-
-  // Darwin's kernel doesn't support guard variables; just die if we
-  // try to use them.
-  if (KernelOrKext && getToolChain().getTriple().isOSDarwin())
-    CmdArgs.push_back("-fforbid-guard-variables");
-
-  if (Args.hasFlag(options::OPT_mms_bitfields, options::OPT_mno_ms_bitfields,
-                   false)) {
-    CmdArgs.push_back("-mms-bitfields");
-  }
-
-  if (Args.hasFlag(options::OPT_mpie_copy_relocations,
-                   options::OPT_mno_pie_copy_relocations,
-                   false)) {
-    CmdArgs.push_back("-mpie-copy-relocations");
-  }
-
-  // This is a coarse approximation of what llvm-gcc actually does, both
-  // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
-  // complicated ways.
-  bool AsynchronousUnwindTables =
-      Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
-                   options::OPT_fno_asynchronous_unwind_tables,
-                   (getToolChain().IsUnwindTablesDefault() ||
-                    getToolChain().getSanitizerArgs().needsUnwindTables()) &&
-                       !KernelOrKext);
-  if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
-                   AsynchronousUnwindTables))
-    CmdArgs.push_back("-munwind-tables");
-
-  getToolChain().addClangTargetOptions(Args, CmdArgs);
-
-  if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
-    CmdArgs.push_back("-mlimit-float-precision");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  // FIXME: Handle -mtune=.
-  (void)Args.hasArg(options::OPT_mtune_EQ);
-
-  if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
-    CmdArgs.push_back("-mcode-model");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  // Add the target cpu
-  std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);
-  if (!CPU.empty()) {
-    CmdArgs.push_back("-target-cpu");
-    CmdArgs.push_back(Args.MakeArgString(CPU));
-  }
-
-  if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
-    CmdArgs.push_back("-mfpmath");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  // Add the target features
-  getTargetFeatures(getToolChain(), Triple, Args, CmdArgs, false);
-
-  // Add target specific flags.
-  switch (getToolChain().getArch()) {
-  default:
-    break;
-
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb:
-    // Use the effective triple, which takes into account the deployment target.
-    AddARMTargetArgs(Triple, Args, CmdArgs, KernelOrKext);
-    break;
-
-  case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_be:
-    AddAArch64TargetArgs(Args, CmdArgs);
-    break;
-
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el:
-    AddMIPSTargetArgs(Args, CmdArgs);
-    break;
-
-  case llvm::Triple::ppc:
-  case llvm::Triple::ppc64:
-  case llvm::Triple::ppc64le:
-    AddPPCTargetArgs(Args, CmdArgs);
-    break;
-
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel:
-  case llvm::Triple::sparcv9:
-    AddSparcTargetArgs(Args, CmdArgs);
-    break;
-
-  case llvm::Triple::systemz:
-    AddSystemZTargetArgs(Args, CmdArgs);
-    break;
-
-  case llvm::Triple::x86:
-  case llvm::Triple::x86_64:
-    AddX86TargetArgs(Args, CmdArgs);
-    break;
-
-  case llvm::Triple::lanai:
-    AddLanaiTargetArgs(Args, CmdArgs);
-    break;
-
-  case llvm::Triple::hexagon:
-    AddHexagonTargetArgs(Args, CmdArgs);
-    break;
-
-  case llvm::Triple::wasm32:
-  case llvm::Triple::wasm64:
-    AddWebAssemblyTargetArgs(Args, CmdArgs);
-    break;
-  }
-
-  // The 'g' groups options involve a somewhat intricate sequence of decisions
-  // about what to pass from the driver to the frontend, but by the time they
-  // reach cc1 they've been factored into three well-defined orthogonal choices:
-  //  * what level of debug info to generate
-  //  * what dwarf version to write
-  //  * what debugger tuning to use
-  // This avoids having to monkey around further in cc1 other than to disable
-  // codeview if not running in a Windows environment. Perhaps even that
-  // decision should be made in the driver as well though.
-  unsigned DwarfVersion = 0;
-  llvm::DebuggerKind DebuggerTuning = getToolChain().getDefaultDebuggerTuning();
-  // These two are potentially updated by AddClangCLArgs.
-  codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
-  bool EmitCodeView = false;
-
-  // Add clang-cl arguments.
-  types::ID InputType = Input.getType();
-  if (getToolChain().getDriver().IsCLMode())
-    AddClangCLArgs(Args, InputType, CmdArgs, &DebugInfoKind, &EmitCodeView);
-
-  // Pass the linker version in use.
-  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
-    CmdArgs.push_back("-target-linker-version");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (!shouldUseLeafFramePointer(Args, getToolChain().getTriple()))
-    CmdArgs.push_back("-momit-leaf-frame-pointer");
-
-  // Explicitly error on some things we know we don't support and can't just
-  // ignore.
-  if (!Args.hasArg(options::OPT_fallow_unsupported)) {
-    Arg *Unsupported;
-    if (types::isCXX(InputType) && getToolChain().getTriple().isOSDarwin() &&
-        getToolChain().getArch() == llvm::Triple::x86) {
-      if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
-          (Unsupported = Args.getLastArg(options::OPT_mkernel)))
-        D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
-            << Unsupported->getOption().getName();
-    }
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_v);
-  Args.AddLastArg(CmdArgs, options::OPT_H);
-  if (D.CCPrintHeaders && !D.CCGenDiagnostics) {
-    CmdArgs.push_back("-header-include-file");
-    CmdArgs.push_back(D.CCPrintHeadersFilename ? D.CCPrintHeadersFilename
-                                               : "-");
-  }
-  Args.AddLastArg(CmdArgs, options::OPT_P);
-  Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
-
-  if (D.CCLogDiagnostics && !D.CCGenDiagnostics) {
-    CmdArgs.push_back("-diagnostic-log-file");
-    CmdArgs.push_back(D.CCLogDiagnosticsFilename ? D.CCLogDiagnosticsFilename
-                                                 : "-");
-  }
-
-  bool splitDwarfInlining =
-      Args.hasFlag(options::OPT_fsplit_dwarf_inlining,
-                   options::OPT_fno_split_dwarf_inlining, true);
-
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  Arg *SplitDwarfArg = Args.getLastArg(options::OPT_gsplit_dwarf);
-  if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
-    // If the last option explicitly specified a debug-info level, use it.
-    if (A->getOption().matches(options::OPT_gN_Group)) {
-      DebugInfoKind = DebugLevelToInfoKind(*A);
-      // If you say "-gsplit-dwarf -gline-tables-only", -gsplit-dwarf loses.
-      // But -gsplit-dwarf is not a g_group option, hence we have to check the
-      // order explicitly. (If -gsplit-dwarf wins, we fix DebugInfoKind later.)
-      // This gets a bit more complicated if you've disabled inline info in the
-      // skeleton CUs (splitDwarfInlining) - then there's value in composing
-      // split-dwarf and line-tables-only, so let those compose naturally in
-      // that case.
-      // And if you just turned off debug info, (-gsplit-dwarf -g0) - do that.
-      if (SplitDwarfArg) {
-        if (A->getIndex() > SplitDwarfArg->getIndex()) {
-          if (DebugInfoKind == codegenoptions::NoDebugInfo ||
-              (DebugInfoKind == codegenoptions::DebugLineTablesOnly &&
-               splitDwarfInlining))
-            SplitDwarfArg = nullptr;
-        } else if (splitDwarfInlining)
-          DebugInfoKind = codegenoptions::NoDebugInfo;
-      }
-    } else
-      // For any other 'g' option, use Limited.
-      DebugInfoKind = codegenoptions::LimitedDebugInfo;
-  }
-
-  // If a debugger tuning argument appeared, remember it.
-  if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
-                               options::OPT_ggdbN_Group)) {
-    if (A->getOption().matches(options::OPT_glldb))
-      DebuggerTuning = llvm::DebuggerKind::LLDB;
-    else if (A->getOption().matches(options::OPT_gsce))
-      DebuggerTuning = llvm::DebuggerKind::SCE;
-    else
-      DebuggerTuning = llvm::DebuggerKind::GDB;
-  }
-
-  // If a -gdwarf argument appeared, remember it.
-  if (Arg *A = Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
-                               options::OPT_gdwarf_4, options::OPT_gdwarf_5))
-    DwarfVersion = DwarfVersionNum(A->getSpelling());
-
-  // Forward -gcodeview. EmitCodeView might have been set by CL-compatibility
-  // argument parsing.
-  if (Args.hasArg(options::OPT_gcodeview) || EmitCodeView) {
-    // DwarfVersion remains at 0 if no explicit choice was made.
-    CmdArgs.push_back("-gcodeview");
-  } else if (DwarfVersion == 0 &&
-             DebugInfoKind != codegenoptions::NoDebugInfo) {
-    DwarfVersion = getToolChain().GetDefaultDwarfVersion();
-  }
-
-  // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
-  Args.ClaimAllArgs(options::OPT_g_flags_Group);
-
-  // Column info is included by default for everything except PS4 and CodeView.
-  // Clang doesn't track end columns, just starting columns, which, in theory,
-  // is fine for CodeView (and PDB).  In practice, however, the Microsoft
-  // debuggers don't handle missing end columns well, so it's better not to
-  // include any column info.
-  if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
-                   /*Default=*/ !IsPS4CPU && !(IsWindowsMSVC && EmitCodeView)))
-    CmdArgs.push_back("-dwarf-column-info");
-
-  // FIXME: Move backend command line options to the module.
-  // If -gline-tables-only is the last option it wins.
-  if (DebugInfoKind != codegenoptions::DebugLineTablesOnly &&
-      Args.hasArg(options::OPT_gmodules)) {
-    DebugInfoKind = codegenoptions::LimitedDebugInfo;
-    CmdArgs.push_back("-dwarf-ext-refs");
-    CmdArgs.push_back("-fmodule-format=obj");
-  }
-
-  // -gsplit-dwarf should turn on -g and enable the backend dwarf
-  // splitting and extraction.
-  // FIXME: Currently only works on Linux.
-  if (getToolChain().getTriple().isOSLinux() && SplitDwarfArg) {
-    if (!splitDwarfInlining)
-      CmdArgs.push_back("-fno-split-dwarf-inlining");
-    if (DebugInfoKind == codegenoptions::NoDebugInfo)
-      DebugInfoKind = codegenoptions::LimitedDebugInfo;
-    CmdArgs.push_back("-backend-option");
-    CmdArgs.push_back("-split-dwarf=Enable");
-  }
-
-  // After we've dealt with all combinations of things that could
-  // make DebugInfoKind be other than None or DebugLineTablesOnly,
-  // figure out if we need to "upgrade" it to standalone debug info.
-  // We parse these two '-f' options whether or not they will be used,
-  // to claim them even if you wrote "-fstandalone-debug -gline-tables-only"
-  bool NeedFullDebug = Args.hasFlag(options::OPT_fstandalone_debug,
-                                    options::OPT_fno_standalone_debug,
-                                    getToolChain().GetDefaultStandaloneDebug());
-  if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug)
-    DebugInfoKind = codegenoptions::FullDebugInfo;
-  RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
-                          DebuggerTuning);
-
-  // -ggnu-pubnames turns on gnu style pubnames in the backend.
-  if (Args.hasArg(options::OPT_ggnu_pubnames)) {
-    CmdArgs.push_back("-backend-option");
-    CmdArgs.push_back("-generate-gnu-dwarf-pub-sections");
-  }
-
-  // -gdwarf-aranges turns on the emission of the aranges section in the
-  // backend.
-  // Always enabled on the PS4.
-  if (Args.hasArg(options::OPT_gdwarf_aranges) || IsPS4CPU) {
-    CmdArgs.push_back("-backend-option");
-    CmdArgs.push_back("-generate-arange-section");
-  }
-
-  if (Args.hasFlag(options::OPT_fdebug_types_section,
-                   options::OPT_fno_debug_types_section, false)) {
-    CmdArgs.push_back("-backend-option");
-    CmdArgs.push_back("-generate-type-units");
-  }
-
-  bool UseSeparateSections = isUseSeparateSections(Triple);
-
-  if (Args.hasFlag(options::OPT_ffunction_sections,
-                   options::OPT_fno_function_sections, UseSeparateSections)) {
-    CmdArgs.push_back("-ffunction-sections");
-  }
-
-  if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
-                   UseSeparateSections)) {
-    CmdArgs.push_back("-fdata-sections");
-  }
-
-  if (!Args.hasFlag(options::OPT_funique_section_names,
-                    options::OPT_fno_unique_section_names, true))
-    CmdArgs.push_back("-fno-unique-section-names");
-
-  Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
-
-  if (Args.hasFlag(options::OPT_fxray_instrument,
-                   options::OPT_fnoxray_instrument, false)) {
-    const char *const XRayInstrumentOption = "-fxray-instrument";
-    if (Triple.getOS() == llvm::Triple::Linux)
-      switch (Triple.getArch()) {
-      case llvm::Triple::x86_64:
-      case llvm::Triple::arm:
-      case llvm::Triple::aarch64:
-        // Supported.
-        break;
-      default:
-        D.Diag(diag::err_drv_clang_unsupported)
-            << (std::string(XRayInstrumentOption) + " on " + Triple.str());
-      }
-    else
-      D.Diag(diag::err_drv_clang_unsupported)
-          << (std::string(XRayInstrumentOption) + " on non-Linux target OS");
-    CmdArgs.push_back(XRayInstrumentOption);
-    if (const Arg *A =
-            Args.getLastArg(options::OPT_fxray_instruction_threshold_,
-                            options::OPT_fxray_instruction_threshold_EQ)) {
-      CmdArgs.push_back("-fxray-instruction-threshold");
-      CmdArgs.push_back(A->getValue());
-    }
-  }
-
-  addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
-
-  // Add runtime flag for PS4 when PGO or Coverage are enabled.
-  if (getToolChain().getTriple().isPS4CPU())
-    addPS4ProfileRTArgs(getToolChain(), Args, CmdArgs);
-
-  // Pass options for controlling the default header search paths.
-  if (Args.hasArg(options::OPT_nostdinc)) {
-    CmdArgs.push_back("-nostdsysteminc");
-    CmdArgs.push_back("-nobuiltininc");
-  } else {
-    if (Args.hasArg(options::OPT_nostdlibinc))
-      CmdArgs.push_back("-nostdsysteminc");
-    Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
-    Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
-  }
-
-  // Pass the path to compiler resource files.
-  CmdArgs.push_back("-resource-dir");
-  CmdArgs.push_back(D.ResourceDir.c_str());
-
-  Args.AddLastArg(CmdArgs, options::OPT_working_directory);
-
-  bool ARCMTEnabled = false;
-  if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) {
-    if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
-                                       options::OPT_ccc_arcmt_modify,
-                                       options::OPT_ccc_arcmt_migrate)) {
-      ARCMTEnabled = true;
-      switch (A->getOption().getID()) {
-      default:
-        llvm_unreachable("missed a case");
-      case options::OPT_ccc_arcmt_check:
-        CmdArgs.push_back("-arcmt-check");
-        break;
-      case options::OPT_ccc_arcmt_modify:
-        CmdArgs.push_back("-arcmt-modify");
-        break;
-      case options::OPT_ccc_arcmt_migrate:
-        CmdArgs.push_back("-arcmt-migrate");
-        CmdArgs.push_back("-mt-migrate-directory");
-        CmdArgs.push_back(A->getValue());
-
-        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
-        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
-        break;
-      }
-    }
-  } else {
-    Args.ClaimAllArgs(options::OPT_ccc_arcmt_check);
-    Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify);
-    Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate);
-  }
-
-  if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
-    if (ARCMTEnabled) {
-      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
-                                                      << "-ccc-arcmt-migrate";
-    }
-    CmdArgs.push_back("-mt-migrate-directory");
-    CmdArgs.push_back(A->getValue());
-
-    if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
-                     options::OPT_objcmt_migrate_subscripting,
-                     options::OPT_objcmt_migrate_property)) {
-      // None specified, means enable them all.
-      CmdArgs.push_back("-objcmt-migrate-literals");
-      CmdArgs.push_back("-objcmt-migrate-subscripting");
-      CmdArgs.push_back("-objcmt-migrate-property");
-    } else {
-      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
-      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
-      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
-    }
-  } else {
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property_dot_syntax);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_designated_init);
-    Args.AddLastArg(CmdArgs, options::OPT_objcmt_whitelist_dir_path);
-  }
-
-  // Add preprocessing options like -I, -D, etc. if we are using the
-  // preprocessor.
-  //
-  // FIXME: Support -fpreprocessed
-  if (types::getPreprocessedType(InputType) != types::TY_INVALID)
-    AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
-
-  // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
-  // that "The compiler can only warn and ignore the option if not recognized".
-  // When building with ccache, it will pass -D options to clang even on
-  // preprocessed inputs and configure concludes that -fPIC is not supported.
-  Args.ClaimAllArgs(options::OPT_D);
-
-  // Manually translate -O4 to -O3; let clang reject others.
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    if (A->getOption().matches(options::OPT_O4)) {
-      CmdArgs.push_back("-O3");
-      D.Diag(diag::warn_O4_is_O3);
-    } else {
-      A->render(Args, CmdArgs);
-    }
-  }
-
-  // Warn about ignored options to clang.
-  for (const Arg *A :
-       Args.filtered(options::OPT_clang_ignored_gcc_optimization_f_Group)) {
-    D.Diag(diag::warn_ignored_gcc_optimization) << A->getAsString(Args);
-    A->claim();
-  }
-
-  claimNoWarnArgs(Args);
-
-  Args.AddAllArgs(CmdArgs, options::OPT_R_Group);
-
-  Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
-  if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
-    CmdArgs.push_back("-pedantic");
-  Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
-  Args.AddLastArg(CmdArgs, options::OPT_w);
-
-  // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
-  // (-ansi is equivalent to -std=c89 or -std=c++98).
-  //
-  // If a std is supplied, only add -trigraphs if it follows the
-  // option.
-  bool ImplyVCPPCXXVer = false;
-  if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
-    if (Std->getOption().matches(options::OPT_ansi))
-      if (types::isCXX(InputType))
-        CmdArgs.push_back("-std=c++98");
-      else
-        CmdArgs.push_back("-std=c89");
-    else
-      Std->render(Args, CmdArgs);
-
-    // If -f(no-)trigraphs appears after the language standard flag, honor it.
-    if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
-                                 options::OPT_ftrigraphs,
-                                 options::OPT_fno_trigraphs))
-      if (A != Std)
-        A->render(Args, CmdArgs);
-  } else {
-    // Honor -std-default.
-    //
-    // FIXME: Clang doesn't correctly handle -std= when the input language
-    // doesn't match. For the time being just ignore this for C++ inputs;
-    // eventually we want to do all the standard defaulting here instead of
-    // splitting it between the driver and clang -cc1.
-    if (!types::isCXX(InputType))
-      Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, "-std=",
-                                /*Joined=*/true);
-    else if (IsWindowsMSVC)
-      ImplyVCPPCXXVer = true;
-
-    Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs,
-                    options::OPT_fno_trigraphs);
-  }
-
-  // GCC's behavior for -Wwrite-strings is a bit strange:
-  //  * In C, this "warning flag" changes the types of string literals from
-  //    'char[N]' to 'const char[N]', and thus triggers an unrelated warning
-  //    for the discarded qualifier.
-  //  * In C++, this is just a normal warning flag.
-  //
-  // Implementing this warning correctly in C is hard, so we follow GCC's
-  // behavior for now. FIXME: Directly diagnose uses of a string literal as
-  // a non-const char* in C, rather than using this crude hack.
-  if (!types::isCXX(InputType)) {
-    // FIXME: This should behave just like a warning flag, and thus should also
-    // respect -Weverything, -Wno-everything, -Werror=write-strings, and so on.
-    Arg *WriteStrings =
-        Args.getLastArg(options::OPT_Wwrite_strings,
-                        options::OPT_Wno_write_strings, options::OPT_w);
-    if (WriteStrings &&
-        WriteStrings->getOption().matches(options::OPT_Wwrite_strings))
-      CmdArgs.push_back("-fconst-strings");
-  }
-
-  // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
-  // during C++ compilation, which it is by default. GCC keeps this define even
-  // in the presence of '-w', match this behavior bug-for-bug.
-  if (types::isCXX(InputType) &&
-      Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
-                   true)) {
-    CmdArgs.push_back("-fdeprecated-macro");
-  }
-
-  // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
-  if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
-    if (Asm->getOption().matches(options::OPT_fasm))
-      CmdArgs.push_back("-fgnu-keywords");
-    else
-      CmdArgs.push_back("-fno-gnu-keywords");
-  }
-
-  if (ShouldDisableDwarfDirectory(Args, getToolChain()))
-    CmdArgs.push_back("-fno-dwarf-directory-asm");
-
-  if (ShouldDisableAutolink(Args, getToolChain()))
-    CmdArgs.push_back("-fno-autolink");
-
-  // Add in -fdebug-compilation-dir if necessary.
-  addDebugCompDirArg(Args, CmdArgs);
-
-  for (const Arg *A : Args.filtered(options::OPT_fdebug_prefix_map_EQ)) {
-    StringRef Map = A->getValue();
-    if (Map.find('=') == StringRef::npos)
-      D.Diag(diag::err_drv_invalid_argument_to_fdebug_prefix_map) << Map;
-    else
-      CmdArgs.push_back(Args.MakeArgString("-fdebug-prefix-map=" + Map));
-    A->claim();
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
-                               options::OPT_ftemplate_depth_EQ)) {
-    CmdArgs.push_back("-ftemplate-depth");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) {
-    CmdArgs.push_back("-foperator-arrow-depth");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
-    CmdArgs.push_back("-fconstexpr-depth");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_steps_EQ)) {
-    CmdArgs.push_back("-fconstexpr-steps");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
-    CmdArgs.push_back("-fbracket-depth");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
-                               options::OPT_Wlarge_by_value_copy_def)) {
-    if (A->getNumValues()) {
-      StringRef bytes = A->getValue();
-      CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
-    } else
-      CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
-  }
-
-  if (Args.hasArg(options::OPT_relocatable_pch))
-    CmdArgs.push_back("-relocatable-pch");
-
-  if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
-    CmdArgs.push_back("-fconstant-string-class");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
-    CmdArgs.push_back("-ftabstop");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  CmdArgs.push_back("-ferror-limit");
-  if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
-    CmdArgs.push_back(A->getValue());
-  else
-    CmdArgs.push_back("19");
-
-  if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
-    CmdArgs.push_back("-fmacro-backtrace-limit");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
-    CmdArgs.push_back("-ftemplate-backtrace-limit");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
-    CmdArgs.push_back("-fconstexpr-backtrace-limit");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_fspell_checking_limit_EQ)) {
-    CmdArgs.push_back("-fspell-checking-limit");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  // Pass -fmessage-length=.
-  CmdArgs.push_back("-fmessage-length");
-  if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
-    CmdArgs.push_back(A->getValue());
-  } else {
-    // If -fmessage-length=N was not specified, determine whether this is a
-    // terminal and, if so, implicitly define -fmessage-length appropriately.
-    unsigned N = llvm::sys::Process::StandardErrColumns();
-    CmdArgs.push_back(Args.MakeArgString(Twine(N)));
-  }
-
-  // -fvisibility= and -fvisibility-ms-compat are of a piece.
-  if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
-                                     options::OPT_fvisibility_ms_compat)) {
-    if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
-      CmdArgs.push_back("-fvisibility");
-      CmdArgs.push_back(A->getValue());
-    } else {
-      assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
-      CmdArgs.push_back("-fvisibility");
-      CmdArgs.push_back("hidden");
-      CmdArgs.push_back("-ftype-visibility");
-      CmdArgs.push_back("default");
-    }
-  }
-
-  Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
-
-  Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
-
-  // -fhosted is default.
-  bool IsHosted = true;
-  if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
-      KernelOrKext) {
-    CmdArgs.push_back("-ffreestanding");
-    IsHosted = false;
-  }
-
-  // Forward -f (flag) options which we can pass directly.
-  Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
-  Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
-  Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
-  // Emulated TLS is enabled by default on Android, and can be enabled manually
-  // with -femulated-tls.
-  bool EmulatedTLSDefault = Triple.isAndroid() || Triple.isWindowsCygwinEnvironment();
-  if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
-                   EmulatedTLSDefault))
-    CmdArgs.push_back("-femulated-tls");
-  // AltiVec-like language extensions aren't relevant for assembling.
-  if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm) {
-    Args.AddLastArg(CmdArgs, options::OPT_faltivec);
-    Args.AddLastArg(CmdArgs, options::OPT_fzvector);
-  }
-  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
-  Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
-
-  // Forward flags for OpenMP. We don't do this if the current action is an
-  // device offloading action other than OpenMP.
-  if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
-                   options::OPT_fno_openmp, false) &&
-      (JA.isDeviceOffloading(Action::OFK_None) ||
-       JA.isDeviceOffloading(Action::OFK_OpenMP))) {
-    switch (getToolChain().getDriver().getOpenMPRuntime(Args)) {
-    case Driver::OMPRT_OMP:
-    case Driver::OMPRT_IOMP5:
-      // Clang can generate useful OpenMP code for these two runtime libraries.
-      CmdArgs.push_back("-fopenmp");
-
-      // If no option regarding the use of TLS in OpenMP codegeneration is
-      // given, decide a default based on the target. Otherwise rely on the
-      // options and pass the right information to the frontend.
-      if (!Args.hasFlag(options::OPT_fopenmp_use_tls,
-                        options::OPT_fnoopenmp_use_tls, /*Default=*/true))
-        CmdArgs.push_back("-fnoopenmp-use-tls");
-      Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
-      break;
-    default:
-      // By default, if Clang doesn't know how to generate useful OpenMP code
-      // for a specific runtime library, we just don't pass the '-fopenmp' flag
-      // down to the actual compilation.
-      // FIXME: It would be better to have a mode which *only* omits IR
-      // generation based on the OpenMP support so that we get consistent
-      // semantic analysis, etc.
-      break;
-    }
-  }
-
-  const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
-  Sanitize.addArgs(getToolChain(), Args, CmdArgs, InputType);
-
-  // Report an error for -faltivec on anything other than PowerPC.
-  if (const Arg *A = Args.getLastArg(options::OPT_faltivec)) {
-    const llvm::Triple::ArchType Arch = getToolChain().getArch();
-    if (!(Arch == llvm::Triple::ppc || Arch == llvm::Triple::ppc64 ||
-          Arch == llvm::Triple::ppc64le))
-      D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
-                                                       << "ppc/ppc64/ppc64le";
-  }
-
-  // -fzvector is incompatible with -faltivec.
-  if (Arg *A = Args.getLastArg(options::OPT_fzvector))
-    if (Args.hasArg(options::OPT_faltivec))
-      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
-                                                      << "-faltivec";
-
-  if (getToolChain().SupportsProfiling())
-    Args.AddLastArg(CmdArgs, options::OPT_pg);
-
-  // -flax-vector-conversions is default.
-  if (!Args.hasFlag(options::OPT_flax_vector_conversions,
-                    options::OPT_fno_lax_vector_conversions))
-    CmdArgs.push_back("-fno-lax-vector-conversions");
-
-  if (Args.getLastArg(options::OPT_fapple_kext) ||
-      (Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType)))
-    CmdArgs.push_back("-fapple-kext");
-
-  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);
-  Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
-  Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
-
-  if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
-    CmdArgs.push_back("-ftrapv-handler");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
-
-  // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
-  // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
-  if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
-    if (A->getOption().matches(options::OPT_fwrapv))
-      CmdArgs.push_back("-fwrapv");
-  } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
-                                      options::OPT_fno_strict_overflow)) {
-    if (A->getOption().matches(options::OPT_fno_strict_overflow))
-      CmdArgs.push_back("-fwrapv");
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
-                               options::OPT_fno_reroll_loops))
-    if (A->getOption().matches(options::OPT_freroll_loops))
-      CmdArgs.push_back("-freroll-loops");
-
-  Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
-  Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
-                  options::OPT_fno_unroll_loops);
-
-  Args.AddLastArg(CmdArgs, options::OPT_pthread);
-
-  // -stack-protector=0 is default.
-  unsigned StackProtectorLevel = 0;
-  if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
-                               options::OPT_fstack_protector_all,
-                               options::OPT_fstack_protector_strong,
-                               options::OPT_fstack_protector)) {
-    if (A->getOption().matches(options::OPT_fstack_protector)) {
-      StackProtectorLevel = std::max<unsigned>(
-          LangOptions::SSPOn,
-          getToolChain().GetDefaultStackProtectorLevel(KernelOrKext));
-    } else if (A->getOption().matches(options::OPT_fstack_protector_strong))
-      StackProtectorLevel = LangOptions::SSPStrong;
-    else if (A->getOption().matches(options::OPT_fstack_protector_all))
-      StackProtectorLevel = LangOptions::SSPReq;
-  } else {
-    StackProtectorLevel =
-        getToolChain().GetDefaultStackProtectorLevel(KernelOrKext);
-    // Only use a default stack protector on Darwin in case -ffreestanding
-    // is not specified.
-    if (Triple.isOSDarwin() && !IsHosted)
-      StackProtectorLevel = 0;
-  }
-  if (StackProtectorLevel) {
-    CmdArgs.push_back("-stack-protector");
-    CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
-  }
-
-  // --param ssp-buffer-size=
-  for (const Arg *A : Args.filtered(options::OPT__param)) {
-    StringRef Str(A->getValue());
-    if (Str.startswith("ssp-buffer-size=")) {
-      if (StackProtectorLevel) {
-        CmdArgs.push_back("-stack-protector-buffer-size");
-        // FIXME: Verify the argument is a valid integer.
-        CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
-      }
-      A->claim();
-    }
-  }
-
-  // Translate -mstackrealign
-  if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
-                   false))
-    CmdArgs.push_back(Args.MakeArgString("-mstackrealign"));
-
-  if (Args.hasArg(options::OPT_mstack_alignment)) {
-    StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
-    CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
-  }
-
-  if (Args.hasArg(options::OPT_mstack_probe_size)) {
-    StringRef Size = Args.getLastArgValue(options::OPT_mstack_probe_size);
-
-    if (!Size.empty())
-      CmdArgs.push_back(Args.MakeArgString("-mstack-probe-size=" + Size));
-    else
-      CmdArgs.push_back("-mstack-probe-size=0");
-  }
-
-  switch (getToolChain().getArch()) {
-  case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_be:
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb:
-    CmdArgs.push_back("-fallow-half-arguments-and-returns");
-    break;
-
-  default:
-    break;
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,
-                               options::OPT_mno_restrict_it)) {
-    if (A->getOption().matches(options::OPT_mrestrict_it)) {
-      CmdArgs.push_back("-backend-option");
-      CmdArgs.push_back("-arm-restrict-it");
-    } else {
-      CmdArgs.push_back("-backend-option");
-      CmdArgs.push_back("-arm-no-restrict-it");
-    }
-  } else if (Triple.isOSWindows() &&
-             (Triple.getArch() == llvm::Triple::arm ||
-              Triple.getArch() == llvm::Triple::thumb)) {
-    // Windows on ARM expects restricted IT blocks
-    CmdArgs.push_back("-backend-option");
-    CmdArgs.push_back("-arm-restrict-it");
-  }
-
-  // Forward -cl options to -cc1
-  if (Args.getLastArg(options::OPT_cl_opt_disable)) {
-    CmdArgs.push_back("-cl-opt-disable");
-  }
-  if (Args.getLastArg(options::OPT_cl_strict_aliasing)) {
-    CmdArgs.push_back("-cl-strict-aliasing");
-  }
-  if (Args.getLastArg(options::OPT_cl_single_precision_constant)) {
-    CmdArgs.push_back("-cl-single-precision-constant");
-  }
-  if (Args.getLastArg(options::OPT_cl_finite_math_only)) {
-    CmdArgs.push_back("-cl-finite-math-only");
-  }
-  if (Args.getLastArg(options::OPT_cl_kernel_arg_info)) {
-    CmdArgs.push_back("-cl-kernel-arg-info");
-  }
-  if (Args.getLastArg(options::OPT_cl_unsafe_math_optimizations)) {
-    CmdArgs.push_back("-cl-unsafe-math-optimizations");
-  }
-  if (Args.getLastArg(options::OPT_cl_fast_relaxed_math)) {
-    CmdArgs.push_back("-cl-fast-relaxed-math");
-  }
-  if (Args.getLastArg(options::OPT_cl_mad_enable)) {
-    CmdArgs.push_back("-cl-mad-enable");
-  }
-  if (Args.getLastArg(options::OPT_cl_no_signed_zeros)) {
-    CmdArgs.push_back("-cl-no-signed-zeros");
-  }
-  if (Arg *A = Args.getLastArg(options::OPT_cl_std_EQ)) {
-    std::string CLStdStr = "-cl-std=";
-    CLStdStr += A->getValue();
-    CmdArgs.push_back(Args.MakeArgString(CLStdStr));
-  }
-  if (Args.getLastArg(options::OPT_cl_denorms_are_zero)) {
-    CmdArgs.push_back("-cl-denorms-are-zero");
-  }
-  if (Args.getLastArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt)) {
-    CmdArgs.push_back("-cl-fp32-correctly-rounded-divide-sqrt");
-  }
-
-  // Forward -f options with positive and negative forms; we translate
-  // these by hand.
-  if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
-    StringRef fname = A->getValue();
-    if (!llvm::sys::fs::exists(fname))
-      D.Diag(diag::err_drv_no_such_file) << fname;
-    else
-      A->render(Args, CmdArgs);
-  }
-
-  // -fbuiltin is default unless -mkernel is used.
-  bool UseBuiltins =
-      Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin,
-                   !Args.hasArg(options::OPT_mkernel));
-  if (!UseBuiltins)
-    CmdArgs.push_back("-fno-builtin");
-
-  // -ffreestanding implies -fno-builtin.
-  if (Args.hasArg(options::OPT_ffreestanding))
-    UseBuiltins = false;
-
-  // Process the -fno-builtin-* options.
-  for (const auto &Arg : Args) {
-    const Option &O = Arg->getOption();
-    if (!O.matches(options::OPT_fno_builtin_))
-      continue;
-
-    Arg->claim();
-    // If -fno-builtin is specified, then there's no need to pass the option to
-    // the frontend.
-    if (!UseBuiltins)
-      continue;
-
-    StringRef FuncName = Arg->getValue();
-    CmdArgs.push_back(Args.MakeArgString("-fno-builtin-" + FuncName));
-  }
-
-  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
-                    options::OPT_fno_assume_sane_operator_new))
-    CmdArgs.push_back("-fno-assume-sane-operator-new");
-
-  // -fblocks=0 is default.
-  if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
-                   getToolChain().IsBlocksDefault()) ||
-      (Args.hasArg(options::OPT_fgnu_runtime) &&
-       Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
-       !Args.hasArg(options::OPT_fno_blocks))) {
-    CmdArgs.push_back("-fblocks");
-
-    if (!Args.hasArg(options::OPT_fgnu_runtime) &&
-        !getToolChain().hasBlocksRuntime())
-      CmdArgs.push_back("-fblocks-runtime-optional");
-  }
-
-  if (Args.hasFlag(options::OPT_fcoroutines_ts, options::OPT_fno_coroutines_ts,
-                   false) &&
-      types::isCXX(InputType)) {
-    CmdArgs.push_back("-fcoroutines-ts");
-  }
-
-  // -fmodules enables the use of precompiled modules (off by default).
-  // Users can pass -fno-cxx-modules to turn off modules support for
-  // C++/Objective-C++ programs.
-  bool HaveClangModules = false;
-  if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
-    bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
-                                     options::OPT_fno_cxx_modules, true);
-    if (AllowedInCXX || !types::isCXX(InputType)) {
-      CmdArgs.push_back("-fmodules");
-      HaveClangModules = true;
-    }
-  }
-
-  bool HaveAnyModules = HaveClangModules;
-  if (Args.hasArg(options::OPT_fmodules_ts)) {
-    CmdArgs.push_back("-fmodules-ts");
-    HaveAnyModules = true;
-  }
-
-  // -fmodule-maps enables implicit reading of module map files. By default,
-  // this is enabled if we are using Clang's flavor of precompiled modules.
-  if (Args.hasFlag(options::OPT_fimplicit_module_maps,
-                   options::OPT_fno_implicit_module_maps, HaveClangModules)) {
-    CmdArgs.push_back("-fimplicit-module-maps");
-  }
-
-  // -fmodules-decluse checks that modules used are declared so (off by
-  // default).
-  if (Args.hasFlag(options::OPT_fmodules_decluse,
-                   options::OPT_fno_modules_decluse, false)) {
-    CmdArgs.push_back("-fmodules-decluse");
-  }
-
-  // -fmodules-strict-decluse is like -fmodule-decluse, but also checks that
-  // all #included headers are part of modules.
-  if (Args.hasFlag(options::OPT_fmodules_strict_decluse,
-                   options::OPT_fno_modules_strict_decluse, false)) {
-    CmdArgs.push_back("-fmodules-strict-decluse");
-  }
-
-  // -fno-implicit-modules turns off implicitly compiling modules on demand.
-  if (!Args.hasFlag(options::OPT_fimplicit_modules,
-                    options::OPT_fno_implicit_modules, HaveClangModules)) {
-    if (HaveAnyModules)
-      CmdArgs.push_back("-fno-implicit-modules");
-  } else if (HaveAnyModules) {
-    // -fmodule-cache-path specifies where our implicitly-built module files
-    // should be written.
-    SmallString<128> Path;
-    if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
-      Path = A->getValue();
-    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.
-      Path = Output.getFilename();
-      llvm::sys::path::replace_extension(Path, ".cache");
-      llvm::sys::path::append(Path, "modules");
-    } else if (Path.empty()) {
-      // No module path was provided: use the default.
-      llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);
-      llvm::sys::path::append(Path, "org.llvm.clang.");
-      appendUserToPath(Path);
-      llvm::sys::path::append(Path, "ModuleCache");
-    }
-    const char Arg[] = "-fmodules-cache-path=";
-    Path.insert(Path.begin(), Arg, Arg + strlen(Arg));
-    CmdArgs.push_back(Args.MakeArgString(Path));
-  }
-
-  if (HaveAnyModules) {
-    // -fprebuilt-module-path specifies where to load the prebuilt module files.
-    for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path))
-      CmdArgs.push_back(Args.MakeArgString(
-          std::string("-fprebuilt-module-path=") + A->getValue()));
-  }
-      
-  // -fmodule-name specifies the module that is currently being built (or
-  // used for header checking by -fmodule-maps).
-  Args.AddLastArg(CmdArgs, options::OPT_fmodule_name_EQ);
-
-  // -fmodule-map-file can be used to specify files containing module
-  // definitions.
-  Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
-
-  // -fbuiltin-module-map can be used to load the clang
-  // builtin headers modulemap file.
-  if (Args.hasArg(options::OPT_fbuiltin_module_map)) {
-    SmallString<128> BuiltinModuleMap(getToolChain().getDriver().ResourceDir);
-    llvm::sys::path::append(BuiltinModuleMap, "include");
-    llvm::sys::path::append(BuiltinModuleMap, "module.modulemap");
-    if (llvm::sys::fs::exists(BuiltinModuleMap)) {
-      CmdArgs.push_back(Args.MakeArgString("-fmodule-map-file=" +
-                                           BuiltinModuleMap));
-    }
-  }
-
-  // -fmodule-file can be used to specify files containing precompiled modules.
-  if (HaveAnyModules)
-    Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
-  else
-    Args.ClaimAllArgs(options::OPT_fmodule_file);
-
-  // When building modules and generating crashdumps, we need to dump a module
-  // dependency VFS alongside the output.
-  if (HaveClangModules && C.isForDiagnostics()) {
-    SmallString<128> VFSDir(Output.getFilename());
-    llvm::sys::path::replace_extension(VFSDir, ".cache");
-    // Add the cache directory as a temp so the crash diagnostics pick it up.
-    C.addTempFile(Args.MakeArgString(VFSDir));
-
-    llvm::sys::path::append(VFSDir, "vfs");
-    CmdArgs.push_back("-module-dependency-dir");
-    CmdArgs.push_back(Args.MakeArgString(VFSDir));
-  }
-
-  if (HaveClangModules)
-    Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
-
-  // Pass through all -fmodules-ignore-macro arguments.
-  Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
-  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
-  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
-
-  Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
-
-  if (Arg *A = Args.getLastArg(options::OPT_fbuild_session_file)) {
-    if (Args.hasArg(options::OPT_fbuild_session_timestamp))
-      D.Diag(diag::err_drv_argument_not_allowed_with)
-          << A->getAsString(Args) << "-fbuild-session-timestamp";
-
-    llvm::sys::fs::file_status Status;
-    if (llvm::sys::fs::status(A->getValue(), Status))
-      D.Diag(diag::err_drv_no_such_file) << A->getValue();
-    CmdArgs.push_back(
-        Args.MakeArgString("-fbuild-session-timestamp=" +
-                           Twine((uint64_t)Status.getLastModificationTime()
-                                     .time_since_epoch()
-                                     .count())));
-  }
-
-  if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {
-    if (!Args.getLastArg(options::OPT_fbuild_session_timestamp,
-                         options::OPT_fbuild_session_file))
-      D.Diag(diag::err_drv_modules_validate_once_requires_timestamp);
-
-    Args.AddLastArg(CmdArgs,
-                    options::OPT_fmodules_validate_once_per_build_session);
-  }
-
-  Args.AddLastArg(CmdArgs, options::OPT_fmodules_validate_system_headers);
-  Args.AddLastArg(CmdArgs, options::OPT_fmodules_disable_diagnostic_validation);
-
-  // -faccess-control is default.
-  if (Args.hasFlag(options::OPT_fno_access_control,
-                   options::OPT_faccess_control, false))
-    CmdArgs.push_back("-fno-access-control");
-
-  // -felide-constructors is the default.
-  if (Args.hasFlag(options::OPT_fno_elide_constructors,
-                   options::OPT_felide_constructors, false))
-    CmdArgs.push_back("-fno-elide-constructors");
-
-  ToolChain::RTTIMode RTTIMode = getToolChain().getRTTIMode();
-
-  if (KernelOrKext || (types::isCXX(InputType) &&
-                       (RTTIMode == ToolChain::RM_DisabledExplicitly ||
-                        RTTIMode == ToolChain::RM_DisabledImplicitly)))
-    CmdArgs.push_back("-fno-rtti");
-
-  // -fshort-enums=0 is default for all architectures except Hexagon.
-  if (Args.hasFlag(options::OPT_fshort_enums, options::OPT_fno_short_enums,
-                   getToolChain().getArch() == llvm::Triple::hexagon))
-    CmdArgs.push_back("-fshort-enums");
-
-  // -fsigned-char is default.
-  if (Arg *A = Args.getLastArg(
-          options::OPT_fsigned_char, options::OPT_fno_signed_char,
-          options::OPT_funsigned_char, options::OPT_fno_unsigned_char)) {
-    if (A->getOption().matches(options::OPT_funsigned_char) ||
-        A->getOption().matches(options::OPT_fno_signed_char)) {
-      CmdArgs.push_back("-fno-signed-char");
-    }
-  } else if (!isSignedCharDefault(getToolChain().getTriple())) {
-    CmdArgs.push_back("-fno-signed-char");
-  }
-
-  // -fuse-cxa-atexit is default.
-  if (!Args.hasFlag(
-          options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
-          !IsWindowsCygnus && !IsWindowsGNU &&
-              getToolChain().getTriple().getOS() != llvm::Triple::Solaris &&
-              getToolChain().getArch() != llvm::Triple::hexagon &&
-              getToolChain().getArch() != llvm::Triple::xcore &&
-              ((getToolChain().getTriple().getVendor() !=
-                llvm::Triple::MipsTechnologies) ||
-               getToolChain().getTriple().hasEnvironment())) ||
-      KernelOrKext)
-    CmdArgs.push_back("-fno-use-cxa-atexit");
-
-  // -fms-extensions=0 is default.
-  if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
-                   IsWindowsMSVC))
-    CmdArgs.push_back("-fms-extensions");
-
-  // -fno-use-line-directives is default.
-  if (Args.hasFlag(options::OPT_fuse_line_directives,
-                   options::OPT_fno_use_line_directives, false))
-    CmdArgs.push_back("-fuse-line-directives");
-
-  // -fms-compatibility=0 is default.
-  if (Args.hasFlag(options::OPT_fms_compatibility,
-                   options::OPT_fno_ms_compatibility,
-                   (IsWindowsMSVC &&
-                    Args.hasFlag(options::OPT_fms_extensions,
-                                 options::OPT_fno_ms_extensions, true))))
-    CmdArgs.push_back("-fms-compatibility");
-
-  VersionTuple MSVT =
-      getToolChain().computeMSVCVersion(&getToolChain().getDriver(), Args);
-  if (!MSVT.empty())
-    CmdArgs.push_back(
-        Args.MakeArgString("-fms-compatibility-version=" + MSVT.getAsString()));
-
-  bool IsMSVC2015Compatible = MSVT.getMajor() >= 19;
-  if (ImplyVCPPCXXVer) {
-    StringRef LanguageStandard;
-    if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) {
-      LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue())
-                             .Case("c++14", "-std=c++14")
-                             .Case("c++latest", "-std=c++1z")
-                             .Default("");
-      if (LanguageStandard.empty())
-        D.Diag(clang::diag::warn_drv_unused_argument)
-            << StdArg->getAsString(Args);
-    }
-
-    if (LanguageStandard.empty()) {
-      if (IsMSVC2015Compatible)
-        LanguageStandard = "-std=c++14";
-      else
-        LanguageStandard = "-std=c++11";
-    }
-
-    CmdArgs.push_back(LanguageStandard.data());
-  }
-
-  // -fno-borland-extensions is default.
-  if (Args.hasFlag(options::OPT_fborland_extensions,
-                   options::OPT_fno_borland_extensions, false))
-    CmdArgs.push_back("-fborland-extensions");
-
-  // -fno-declspec is default, except for PS4.
-  if (Args.hasFlag(options::OPT_fdeclspec, options::OPT_fno_declspec,
-                   getToolChain().getTriple().isPS4()))
-    CmdArgs.push_back("-fdeclspec");
-  else if (Args.hasArg(options::OPT_fno_declspec))
-    CmdArgs.push_back("-fno-declspec"); // Explicitly disabling __declspec.
-
-  // -fthreadsafe-static is default, except for MSVC compatibility versions less
-  // than 19.
-  if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
-                    options::OPT_fno_threadsafe_statics,
-                    !IsWindowsMSVC || IsMSVC2015Compatible))
-    CmdArgs.push_back("-fno-threadsafe-statics");
-
-  // -fno-delayed-template-parsing is default, except for Windows where MSVC STL
-  // needs it.
-  if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
-                   options::OPT_fno_delayed_template_parsing, IsWindowsMSVC))
-    CmdArgs.push_back("-fdelayed-template-parsing");
-
-  // -fgnu-keywords default varies depending on language; only pass if
-  // specified.
-  if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
-                               options::OPT_fno_gnu_keywords))
-    A->render(Args, CmdArgs);
-
-  if (Args.hasFlag(options::OPT_fgnu89_inline, options::OPT_fno_gnu89_inline,
-                   false))
-    CmdArgs.push_back("-fgnu89-inline");
-
-  if (Args.hasArg(options::OPT_fno_inline))
-    CmdArgs.push_back("-fno-inline");
-
-  if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions,
-                                       options::OPT_finline_hint_functions,
-                                       options::OPT_fno_inline_functions))
-    InlineArg->render(Args, CmdArgs);
-
-  ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
-
-  // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
-  // legacy is the default. Except for deployment target of 10.5,
-  // next runtime is always legacy dispatch and -fno-objc-legacy-dispatch
-  // gets ignored silently.
-  if (objcRuntime.isNonFragile()) {
-    if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
-                      options::OPT_fno_objc_legacy_dispatch,
-                      objcRuntime.isLegacyDispatchDefaultForArch(
-                          getToolChain().getArch()))) {
-      if (getToolChain().UseObjCMixedDispatch())
-        CmdArgs.push_back("-fobjc-dispatch-method=mixed");
-      else
-        CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
-    }
-  }
-
-  // When ObjectiveC legacy runtime is in effect on MacOSX,
-  // turn on the option to do Array/Dictionary subscripting
-  // by default.
-  if (getToolChain().getArch() == llvm::Triple::x86 &&
-      getToolChain().getTriple().isMacOSX() &&
-      !getToolChain().getTriple().isMacOSXVersionLT(10, 7) &&
-      objcRuntime.getKind() == ObjCRuntime::FragileMacOSX &&
-      objcRuntime.isNeXTFamily())
-    CmdArgs.push_back("-fobjc-subscripting-legacy-runtime");
-
-  // -fencode-extended-block-signature=1 is default.
-  if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) {
-    CmdArgs.push_back("-fencode-extended-block-signature");
-  }
-
-  // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
-  // NOTE: This logic is duplicated in ToolChains.cpp.
-  bool ARC = isObjCAutoRefCount(Args);
-  if (ARC) {
-    getToolChain().CheckObjCARC();
-
-    CmdArgs.push_back("-fobjc-arc");
-
-    // FIXME: It seems like this entire block, and several around it should be
-    // wrapped in isObjC, but for now we just use it here as this is where it
-    // was being used previously.
-    if (types::isCXX(InputType) && types::isObjC(InputType)) {
-      if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
-        CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
-      else
-        CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
-    }
-
-    // Allow the user to enable full exceptions code emission.
-    // We define off for Objective-CC, on for Objective-C++.
-    if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
-                     options::OPT_fno_objc_arc_exceptions,
-                     /*default*/ types::isCXX(InputType)))
-      CmdArgs.push_back("-fobjc-arc-exceptions");
-
-  }
-
-  // -fobjc-infer-related-result-type is the default, except in the Objective-C
-  // rewriter.
-  if (rewriteKind != RK_None)
-    CmdArgs.push_back("-fno-objc-infer-related-result-type");
-
-  // Pass down -fobjc-weak or -fno-objc-weak if present.
-  if (types::isObjC(InputType)) {
-    auto WeakArg = Args.getLastArg(options::OPT_fobjc_weak,
-                                   options::OPT_fno_objc_weak);
-    if (!WeakArg) {
-      // nothing to do
-    } else if (!objcRuntime.allowsWeak()) {
-      if (WeakArg->getOption().matches(options::OPT_fobjc_weak))
-        D.Diag(diag::err_objc_weak_unsupported);
-    } else {
-      WeakArg->render(Args, CmdArgs);
-    }
-  }
-
-  if (Args.hasFlag(options::OPT_fapplication_extension,
-                   options::OPT_fno_application_extension, false))
-    CmdArgs.push_back("-fapplication-extension");
-
-  // Handle GCC-style exception args.
-  if (!C.getDriver().IsCLMode())
-    addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext, objcRuntime,
-                     CmdArgs);
-
-  if (Args.hasArg(options::OPT_fsjlj_exceptions) ||
-      getToolChain().UseSjLjExceptions(Args))
-    CmdArgs.push_back("-fsjlj-exceptions");
-
-  // C++ "sane" operator new.
-  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
-                    options::OPT_fno_assume_sane_operator_new))
-    CmdArgs.push_back("-fno-assume-sane-operator-new");
-
-  // -fsized-deallocation is off by default, as it is an ABI-breaking change for
-  // most platforms.
-  if (Args.hasFlag(options::OPT_fsized_deallocation,
-                   options::OPT_fno_sized_deallocation, false))
-    CmdArgs.push_back("-fsized-deallocation");
-
-  // -faligned-allocation is on by default in C++17 onwards and otherwise off
-  // by default.
-  if (Arg *A = Args.getLastArg(options::OPT_faligned_allocation,
-                               options::OPT_fno_aligned_allocation,
-                               options::OPT_faligned_new_EQ)) {
-    if (A->getOption().matches(options::OPT_fno_aligned_allocation))
-      CmdArgs.push_back("-fno-aligned-allocation");
-    else
-      CmdArgs.push_back("-faligned-allocation");
-  }
-
-  // The default new alignment can be specified using a dedicated option or via
-  // a GCC-compatible option that also turns on aligned allocation.
-  if (Arg *A = Args.getLastArg(options::OPT_fnew_alignment_EQ,
-                               options::OPT_faligned_new_EQ))
-    CmdArgs.push_back(
-        Args.MakeArgString(Twine("-fnew-alignment=") + A->getValue()));
-
-  // -fconstant-cfstrings is default, and may be subject to argument translation
-  // on Darwin.
-  if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
-                    options::OPT_fno_constant_cfstrings) ||
-      !Args.hasFlag(options::OPT_mconstant_cfstrings,
-                    options::OPT_mno_constant_cfstrings))
-    CmdArgs.push_back("-fno-constant-cfstrings");
-
-  // -fshort-wchar default varies depending on platform; only
-  // pass if specified.
-  if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
-                               options::OPT_fno_short_wchar))
-    A->render(Args, CmdArgs);
-
-  // -fno-pascal-strings is default, only pass non-default.
-  if (Args.hasFlag(options::OPT_fpascal_strings,
-                   options::OPT_fno_pascal_strings, false))
-    CmdArgs.push_back("-fpascal-strings");
-
-  // Honor -fpack-struct= and -fpack-struct, if given. Note that
-  // -fno-pack-struct doesn't apply to -fpack-struct=.
-  if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
-    std::string PackStructStr = "-fpack-struct=";
-    PackStructStr += A->getValue();
-    CmdArgs.push_back(Args.MakeArgString(PackStructStr));
-  } else if (Args.hasFlag(options::OPT_fpack_struct,
-                          options::OPT_fno_pack_struct, false)) {
-    CmdArgs.push_back("-fpack-struct=1");
-  }
-
-  // Handle -fmax-type-align=N and -fno-type-align
-  bool SkipMaxTypeAlign = Args.hasArg(options::OPT_fno_max_type_align);
-  if (Arg *A = Args.getLastArg(options::OPT_fmax_type_align_EQ)) {
-    if (!SkipMaxTypeAlign) {
-      std::string MaxTypeAlignStr = "-fmax-type-align=";
-      MaxTypeAlignStr += A->getValue();
-      CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
-    }
-  } else if (getToolChain().getTriple().isOSDarwin()) {
-    if (!SkipMaxTypeAlign) {
-      std::string MaxTypeAlignStr = "-fmax-type-align=16";
-      CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
-    }
-  }
-
-  // -fcommon is the default unless compiling kernel code or the target says so
-  bool NoCommonDefault =
-      KernelOrKext || isNoCommonDefault(getToolChain().getTriple());
-  if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common,
-                    !NoCommonDefault))
-    CmdArgs.push_back("-fno-common");
-
-  // -fsigned-bitfields is default, and clang doesn't yet support
-  // -funsigned-bitfields.
-  if (!Args.hasFlag(options::OPT_fsigned_bitfields,
-                    options::OPT_funsigned_bitfields))
-    D.Diag(diag::warn_drv_clang_unsupported)
-        << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
-
-  // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
-  if (!Args.hasFlag(options::OPT_ffor_scope, options::OPT_fno_for_scope))
-    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.equals_lower("utf-8"))
-      D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args)
-                                          << value;
-  }
-
-  // -fexec_charset=UTF-8 is default. Reject others
-  if (Arg *execCharset = Args.getLastArg(options::OPT_fexec_charset_EQ)) {
-    StringRef value = execCharset->getValue();
-    if (!value.equals_lower("utf-8"))
-      D.Diag(diag::err_drv_invalid_value) << execCharset->getAsString(Args)
-                                          << value;
-  }
-
-  // -fcaret-diagnostics is default.
-  if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
-                    options::OPT_fno_caret_diagnostics, true))
-    CmdArgs.push_back("-fno-caret-diagnostics");
-
-  // -fdiagnostics-fixit-info is default, only pass non-default.
-  if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
-                    options::OPT_fno_diagnostics_fixit_info))
-    CmdArgs.push_back("-fno-diagnostics-fixit-info");
-
-  // Enable -fdiagnostics-show-option by default.
-  if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
-                   options::OPT_fno_diagnostics_show_option))
-    CmdArgs.push_back("-fdiagnostics-show-option");
-
-  if (const Arg *A =
-          Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
-    CmdArgs.push_back("-fdiagnostics-show-category");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness,
-                   options::OPT_fno_diagnostics_show_hotness, false))
-    CmdArgs.push_back("-fdiagnostics-show-hotness");
-
-  if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
-    CmdArgs.push_back("-fdiagnostics-format");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  if (Arg *A = Args.getLastArg(
-          options::OPT_fdiagnostics_show_note_include_stack,
-          options::OPT_fno_diagnostics_show_note_include_stack)) {
-    if (A->getOption().matches(
-            options::OPT_fdiagnostics_show_note_include_stack))
-      CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
-    else
-      CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
-  }
-
-  // Color diagnostics are parsed by the driver directly from argv
-  // and later re-parsed to construct this job; claim any possible
-  // color diagnostic here to avoid warn_drv_unused_argument and
-  // diagnose bad OPT_fdiagnostics_color_EQ values.
-  for (Arg *A : Args) {
-    const Option &O = A->getOption();
-    if (!O.matches(options::OPT_fcolor_diagnostics) &&
-        !O.matches(options::OPT_fdiagnostics_color) &&
-        !O.matches(options::OPT_fno_color_diagnostics) &&
-        !O.matches(options::OPT_fno_diagnostics_color) &&
-        !O.matches(options::OPT_fdiagnostics_color_EQ))
-      continue;
-    if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
-      StringRef Value(A->getValue());
-      if (Value != "always" && Value != "never" && Value != "auto")
-        getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
-              << ("-fdiagnostics-color=" + Value).str();
-    }
-    A->claim();
-  }
-  if (D.getDiags().getDiagnosticOptions().ShowColors)
-    CmdArgs.push_back("-fcolor-diagnostics");
-
-  if (Args.hasArg(options::OPT_fansi_escape_codes))
-    CmdArgs.push_back("-fansi-escape-codes");
-
-  if (!Args.hasFlag(options::OPT_fshow_source_location,
-                    options::OPT_fno_show_source_location))
-    CmdArgs.push_back("-fno-show-source-location");
-
-  if (Args.hasArg(options::OPT_fdiagnostics_absolute_paths))
-    CmdArgs.push_back("-fdiagnostics-absolute-paths");
-
-  if (!Args.hasFlag(options::OPT_fshow_column, options::OPT_fno_show_column,
-                    true))
-    CmdArgs.push_back("-fno-show-column");
-
-  if (!Args.hasFlag(options::OPT_fspell_checking,
-                    options::OPT_fno_spell_checking))
-    CmdArgs.push_back("-fno-spell-checking");
-
-  // -fno-asm-blocks is default.
-  if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
-                   false))
-    CmdArgs.push_back("-fasm-blocks");
-
-  // -fgnu-inline-asm is default.
-  if (!Args.hasFlag(options::OPT_fgnu_inline_asm,
-                    options::OPT_fno_gnu_inline_asm, true))
-    CmdArgs.push_back("-fno-gnu-inline-asm");
-
-  // Enable vectorization per default according to the optimization level
-  // selected. For optimization levels that want vectorization we use the alias
-  // option to simplify the hasFlag logic.
-  bool EnableVec = shouldEnableVectorizerAtOLevel(Args, false);
-  OptSpecifier VectorizeAliasOption =
-      EnableVec ? options::OPT_O_Group : options::OPT_fvectorize;
-  if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption,
-                   options::OPT_fno_vectorize, EnableVec))
-    CmdArgs.push_back("-vectorize-loops");
-
-  // -fslp-vectorize is enabled based on the optimization level selected.
-  bool EnableSLPVec = shouldEnableVectorizerAtOLevel(Args, true);
-  OptSpecifier SLPVectAliasOption =
-      EnableSLPVec ? options::OPT_O_Group : options::OPT_fslp_vectorize;
-  if (Args.hasFlag(options::OPT_fslp_vectorize, SLPVectAliasOption,
-                   options::OPT_fno_slp_vectorize, EnableSLPVec))
-    CmdArgs.push_back("-vectorize-slp");
-
-  // -fno-slp-vectorize-aggressive is default.
-  if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive,
-                   options::OPT_fno_slp_vectorize_aggressive, false))
-    CmdArgs.push_back("-vectorize-slp-aggressive");
-
-  if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
-    A->render(Args, CmdArgs);
-
-  if (Arg *A = Args.getLastArg(
-          options::OPT_fsanitize_undefined_strip_path_components_EQ))
-    A->render(Args, CmdArgs);
-
-  // -fdollars-in-identifiers default varies depending on platform and
-  // language; only pass if specified.
-  if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
-                               options::OPT_fno_dollars_in_identifiers)) {
-    if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
-      CmdArgs.push_back("-fdollars-in-identifiers");
-    else
-      CmdArgs.push_back("-fno-dollars-in-identifiers");
-  }
-
-  // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
-  // practical purposes.
-  if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
-                               options::OPT_fno_unit_at_a_time)) {
-    if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
-      D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args);
-  }
-
-  if (Args.hasFlag(options::OPT_fapple_pragma_pack,
-                   options::OPT_fno_apple_pragma_pack, false))
-    CmdArgs.push_back("-fapple-pragma-pack");
-
-  // le32-specific flags:
-  //  -fno-math-builtin: clang should not convert math builtins to intrinsics
-  //                     by default.
-  if (getToolChain().getArch() == llvm::Triple::le32) {
-    CmdArgs.push_back("-fno-math-builtin");
-  }
-
-  if (Args.hasFlag(options::OPT_fsave_optimization_record,
-                   options::OPT_fno_save_optimization_record, false)) {
-    CmdArgs.push_back("-opt-record-file");
-
-    const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
-    if (A) {
-      CmdArgs.push_back(A->getValue());
-    } else {
-      SmallString<128> F;
-      if (Output.isFilename() && (Args.hasArg(options::OPT_c) ||
-                                  Args.hasArg(options::OPT_S))) {
-        F = Output.getFilename();
-      } else {
-        // Use the input filename.
-        F = llvm::sys::path::stem(Input.getBaseInput());
-
-        // If we're compiling for an offload architecture (i.e. a CUDA device),
-        // we need to make the file name for the device compilation different
-        // from the host compilation.
-        if (!JA.isDeviceOffloading(Action::OFK_None) &&
-            !JA.isDeviceOffloading(Action::OFK_Host)) {
-          llvm::sys::path::replace_extension(F, "");
-          F += Action::GetOffloadingFileNamePrefix(JA.getOffloadingDeviceKind(),
-                                                   Triple.normalize());
-          F += "-";
-          F += JA.getOffloadingArch();
-        }
-      }
-
-      llvm::sys::path::replace_extension(F, "opt.yaml");
-      CmdArgs.push_back(Args.MakeArgString(F));
-    }
-  }
-
-// Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
-//
-// FIXME: Now that PR4941 has been fixed this can be enabled.
-#if 0
-  if (getToolChain().getTriple().isOSDarwin() &&
-      (getToolChain().getArch() == llvm::Triple::arm ||
-       getToolChain().getArch() == llvm::Triple::thumb)) {
-    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
-      CmdArgs.push_back("-fno-builtin-strcat");
-    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
-      CmdArgs.push_back("-fno-builtin-strcpy");
-  }
-#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() && !HaveAnyModules))
-    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)) {
-    if (isa<PreprocessJobAction>(JA))
-      CmdArgs.push_back("-traditional-cpp");
-    else
-      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-  }
-
-  Args.AddLastArg(CmdArgs, options::OPT_dM);
-  Args.AddLastArg(CmdArgs, options::OPT_dD);
-
-  // Handle serialized diagnostics.
-  if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
-    CmdArgs.push_back("-serialize-diagnostic-file");
-    CmdArgs.push_back(Args.MakeArgString(A->getValue()));
-  }
-
-  if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
-    CmdArgs.push_back("-fretain-comments-from-system-headers");
-
-  // Forward -fcomment-block-commands to -cc1.
-  Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
-  // Forward -fparse-all-comments to -cc1.
-  Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments);
-
-  // Turn -fplugin=name.so into -load name.so
-  for (const Arg *A : Args.filtered(options::OPT_fplugin_EQ)) {
-    CmdArgs.push_back("-load");
-    CmdArgs.push_back(A->getValue());
-    A->claim();
-  }
-
-  // Setup statistics file output.
-  if (const Arg *A = Args.getLastArg(options::OPT_save_stats_EQ)) {
-    StringRef SaveStats = A->getValue();
-
-    SmallString<128> StatsFile;
-    bool DoSaveStats = false;
-    if (SaveStats == "obj") {
-      if (Output.isFilename()) {
-        StatsFile.assign(Output.getFilename());
-        llvm::sys::path::remove_filename(StatsFile);
-      }
-      DoSaveStats = true;
-    } else if (SaveStats == "cwd") {
-      DoSaveStats = true;
-    } else {
-      D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << SaveStats;
-    }
-
-    if (DoSaveStats) {
-      StringRef BaseName = llvm::sys::path::filename(Input.getBaseInput());
-      llvm::sys::path::append(StatsFile, BaseName);
-      llvm::sys::path::replace_extension(StatsFile, "stats");
-      CmdArgs.push_back(Args.MakeArgString(Twine("-stats-file=") +
-                                           StatsFile));
-    }
-  }
-
-  // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
-  // parser.
-  Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
-  for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
-    A->claim();
-
-    // We translate this by hand to the -cc1 argument, since nightly test uses
-    // it and developers have been trained to spell it with -mllvm.
-    if (StringRef(A->getValue(0)) == "-disable-llvm-optzns") {
-      CmdArgs.push_back("-disable-llvm-optzns");
-    } else
-      A->render(Args, CmdArgs);
-  }
-
-  // With -save-temps, we want to save the unoptimized bitcode output from the
-  // CompileJobAction, use -disable-llvm-passes to get pristine IR generated
-  // by the frontend.
-  // When -fembed-bitcode is enabled, optimized bitcode is emitted because it
-  // has slightly different breakdown between stages.
-  // FIXME: -fembed-bitcode -save-temps will save optimized bitcode instead of
-  // pristine IR generated by the frontend. Ideally, a new compile action should
-  // be added so both IR can be captured.
-  if (C.getDriver().isSaveTempsEnabled() &&
-      !C.getDriver().embedBitcodeInObject() && isa<CompileJobAction>(JA))
-    CmdArgs.push_back("-disable-llvm-passes");
-
-  if (Output.getType() == types::TY_Dependencies) {
-    // Handled with other dependency code.
-  } else if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  addDashXForInput(Args, Input, CmdArgs);
-
-  if (Input.isFilename())
-    CmdArgs.push_back(Input.getFilename());
-  else
-    Input.getInputArg().renderAsInput(Args, CmdArgs);
-
-  Args.AddAllArgs(CmdArgs, options::OPT_undef);
-
-  const char *Exec = getToolChain().getDriver().getClangProgramPath();
-
-  // Optionally embed the -cc1 level arguments into the debug info, for build
-  // analysis.
-  if (getToolChain().UseDwarfDebugFlags()) {
-    ArgStringList OriginalArgs;
-    for (const auto &Arg : Args)
-      Arg->render(Args, OriginalArgs);
-
-    SmallString<256> Flags;
-    Flags += Exec;
-    for (const char *OriginalArg : OriginalArgs) {
-      SmallString<128> EscapedArg;
-      EscapeSpacesAndBackslashes(OriginalArg, EscapedArg);
-      Flags += " ";
-      Flags += EscapedArg;
-    }
-    CmdArgs.push_back("-dwarf-debug-flags");
-    CmdArgs.push_back(Args.MakeArgString(Flags));
-  }
-
-  // Add the split debug info name to the command lines here so we
-  // can propagate it to the backend.
-  bool SplitDwarf = SplitDwarfArg && getToolChain().getTriple().isOSLinux() &&
-                    (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
-                     isa<BackendJobAction>(JA));
-  const char *SplitDwarfOut;
-  if (SplitDwarf) {
-    CmdArgs.push_back("-split-dwarf-file");
-    SplitDwarfOut = SplitDebugName(Args, Input);
-    CmdArgs.push_back(SplitDwarfOut);
-  }
-
-  // Host-side cuda compilation receives device-side outputs as Inputs[1...].
-  // Include them with -fcuda-include-gpubinary.
-  if (IsCuda && Inputs.size() > 1)
-    for (auto I = std::next(Inputs.begin()), E = Inputs.end(); I != E; ++I) {
-      CmdArgs.push_back("-fcuda-include-gpubinary");
-      CmdArgs.push_back(I->getFilename());
-    }
-
-  // OpenMP offloading device jobs take the argument -fopenmp-host-ir-file-path
-  // to specify the result of the compile phase on the host, so the meaningful
-  // device declarations can be identified. Also, -fopenmp-is-device is passed
-  // along to tell the frontend that it is generating code for a device, so that
-  // only the relevant declarations are emitted.
-  if (IsOpenMPDevice && Inputs.size() == 2) {
-    CmdArgs.push_back("-fopenmp-is-device");
-    CmdArgs.push_back("-fopenmp-host-ir-file-path");
-    CmdArgs.push_back(Args.MakeArgString(Inputs.back().getFilename()));
-  }
-
-  // For all the host OpenMP offloading compile jobs we need to pass the targets
-  // information using -fopenmp-targets= option.
-  if (isa<CompileJobAction>(JA) && JA.isHostOffloading(Action::OFK_OpenMP)) {
-    SmallString<128> TargetInfo("-fopenmp-targets=");
-
-    Arg *Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ);
-    assert(Tgts && Tgts->getNumValues() &&
-           "OpenMP offloading has to have targets specified.");
-    for (unsigned i = 0; i < Tgts->getNumValues(); ++i) {
-      if (i)
-        TargetInfo += ',';
-      // We need to get the string from the triple because it may be not exactly
-      // the same as the one we get directly from the arguments.
-      llvm::Triple T(Tgts->getValue(i));
-      TargetInfo += T.getTriple();
-    }
-    CmdArgs.push_back(Args.MakeArgString(TargetInfo.str()));
-  }
-
-  bool WholeProgramVTables =
-      Args.hasFlag(options::OPT_fwhole_program_vtables,
-                   options::OPT_fno_whole_program_vtables, false);
-  if (WholeProgramVTables) {
-    if (!D.isUsingLTO())
-      D.Diag(diag::err_drv_argument_only_allowed_with)
-          << "-fwhole-program-vtables"
-          << "-flto";
-    CmdArgs.push_back("-fwhole-program-vtables");
-  }
-
-  // Finally add the compile command to the compilation.
-  if (Args.hasArg(options::OPT__SLASH_fallback) &&
-      Output.getType() == types::TY_Object &&
-      (InputType == types::TY_C || InputType == types::TY_CXX)) {
-    auto CLCommand =
-        getCLFallback()->GetCommand(C, JA, Output, Inputs, Args, LinkingOutput);
-    C.addCommand(llvm::make_unique<FallbackCommand>(
-        JA, *this, Exec, CmdArgs, Inputs, std::move(CLCommand)));
-  } else if (Args.hasArg(options::OPT__SLASH_fallback) &&
-             isa<PrecompileJobAction>(JA)) {
-    // In /fallback builds, run the main compilation even if the pch generation
-    // fails, so that the main compilation's fallback to cl.exe runs.
-    C.addCommand(llvm::make_unique<ForceSuccessCommand>(JA, *this, Exec,
-                                                        CmdArgs, Inputs));
-  } else {
-    C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-  }
-
-  // Handle the debug info splitting at object creation time if we're
-  // creating an object.
-  // TODO: Currently only works on linux with newer objcopy.
-  if (SplitDwarf && Output.getType() == types::TY_Object)
-    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut);
-
-  if (Arg *A = Args.getLastArg(options::OPT_pg))
-    if (Args.hasArg(options::OPT_fomit_frame_pointer))
-      D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer"
-                                                      << A->getAsString(Args);
-
-  // Claim some arguments which clang supports automatically.
-
-  // -fpch-preprocess is used with gcc to add a special marker in the output to
-  // include the PCH file. Clang's PTH solution is completely transparent, so we
-  // do not need to deal with it at all.
-  Args.ClaimAllArgs(options::OPT_fpch_preprocess);
-
-  // Claim some arguments which clang doesn't support, but we don't
-  // care to warn the user about.
-  Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
-  Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
-
-  // Disable warnings for clang -E -emit-llvm foo.c
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-}
-
-/// Add options related to the Objective-C runtime/ABI.
-///
-/// Returns true if the runtime is non-fragile.
-ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
-                                      ArgStringList &cmdArgs,
-                                      RewriteKind rewriteKind) const {
-  // Look for the controlling runtime option.
-  Arg *runtimeArg =
-      args.getLastArg(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
-                      options::OPT_fobjc_runtime_EQ);
-
-  // Just forward -fobjc-runtime= to the frontend.  This supercedes
-  // options about fragility.
-  if (runtimeArg &&
-      runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
-    ObjCRuntime runtime;
-    StringRef value = runtimeArg->getValue();
-    if (runtime.tryParse(value)) {
-      getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
-          << value;
-    }
-
-    runtimeArg->render(args, cmdArgs);
-    return runtime;
-  }
-
-  // Otherwise, we'll need the ABI "version".  Version numbers are
-  // slightly confusing for historical reasons:
-  //   1 - Traditional "fragile" ABI
-  //   2 - Non-fragile ABI, version 1
-  //   3 - Non-fragile ABI, version 2
-  unsigned objcABIVersion = 1;
-  // If -fobjc-abi-version= is present, use that to set the version.
-  if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
-    StringRef value = abiArg->getValue();
-    if (value == "1")
-      objcABIVersion = 1;
-    else if (value == "2")
-      objcABIVersion = 2;
-    else if (value == "3")
-      objcABIVersion = 3;
-    else
-      getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) << value;
-  } else {
-    // Otherwise, determine if we are using the non-fragile ABI.
-    bool nonFragileABIIsDefault =
-        (rewriteKind == RK_NonFragile ||
-         (rewriteKind == RK_None &&
-          getToolChain().IsObjCNonFragileABIDefault()));
-    if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
-                     options::OPT_fno_objc_nonfragile_abi,
-                     nonFragileABIIsDefault)) {
-// Determine the non-fragile ABI version to use.
-#ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
-      unsigned nonFragileABIVersion = 1;
-#else
-      unsigned nonFragileABIVersion = 2;
-#endif
-
-      if (Arg *abiArg =
-              args.getLastArg(options::OPT_fobjc_nonfragile_abi_version_EQ)) {
-        StringRef value = abiArg->getValue();
-        if (value == "1")
-          nonFragileABIVersion = 1;
-        else if (value == "2")
-          nonFragileABIVersion = 2;
-        else
-          getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
-              << value;
-      }
-
-      objcABIVersion = 1 + nonFragileABIVersion;
-    } else {
-      objcABIVersion = 1;
-    }
-  }
-
-  // We don't actually care about the ABI version other than whether
-  // it's non-fragile.
-  bool isNonFragile = objcABIVersion != 1;
-
-  // If we have no runtime argument, ask the toolchain for its default runtime.
-  // However, the rewriter only really supports the Mac runtime, so assume that.
-  ObjCRuntime runtime;
-  if (!runtimeArg) {
-    switch (rewriteKind) {
-    case RK_None:
-      runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
-      break;
-    case RK_Fragile:
-      runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
-      break;
-    case RK_NonFragile:
-      runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
-      break;
-    }
-
-    // -fnext-runtime
-  } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
-    // On Darwin, make this use the default behavior for the toolchain.
-    if (getToolChain().getTriple().isOSDarwin()) {
-      runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
-
-      // Otherwise, build for a generic macosx port.
-    } else {
-      runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
-    }
-
-    // -fgnu-runtime
-  } else {
-    assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
-    // Legacy behaviour is to target the gnustep runtime if we are in
-    // non-fragile mode or the GCC runtime in fragile mode.
-    if (isNonFragile)
-      runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1, 6));
-    else
-      runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
-  }
-
-  cmdArgs.push_back(
-      args.MakeArgString("-fobjc-runtime=" + runtime.getAsString()));
-  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;
-}
-
-namespace {
-struct EHFlags {
-  bool Synch = false;
-  bool Asynch = false;
-  bool NoUnwindC = false;
-};
-} // end anonymous namespace
-
-/// /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 nounwind.
-/// 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);
-        if (EH.Asynch)
-          EH.Synch = false;
-        continue;
-      case 'c':
-        EH.NoUnwindC = maybeConsumeDash(EHVal, I);
-        continue;
-      case 's':
-        EH.Synch = maybeConsumeDash(EHVal, I);
-        if (EH.Synch)
-          EH.Asynch = false;
-        continue;
-      default:
-        break;
-      }
-      D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal;
-      break;
-    }
-  }
-  // The /GX, /GX- flags are only processed if there are not /EH flags.
-  // The default is that /GX is not specified.
-  if (EHArgs.empty() &&
-      Args.hasFlag(options::OPT__SLASH_GX, options::OPT__SLASH_GX_,
-                   /*default=*/false)) {
-    EH.Synch = true;
-    EH.NoUnwindC = true;
-  }
-
-  return EH;
-}
-
-void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
-                           ArgStringList &CmdArgs,
-                           codegenoptions::DebugInfoKind *DebugInfoKind,
-                           bool *EmitCodeView) const {
-  unsigned RTOptionID = options::OPT__SLASH_MT;
-
-  if (Args.hasArg(options::OPT__SLASH_LDd))
-    // The /LDd option implies /MTd. The dependent lib part can be overridden,
-    // but defining _DEBUG is sticky.
-    RTOptionID = options::OPT__SLASH_MTd;
-
-  if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group))
-    RTOptionID = A->getOption().getID();
-
-  StringRef FlagForCRT;
-  switch (RTOptionID) {
-  case options::OPT__SLASH_MD:
-    if (Args.hasArg(options::OPT__SLASH_LDd))
-      CmdArgs.push_back("-D_DEBUG");
-    CmdArgs.push_back("-D_MT");
-    CmdArgs.push_back("-D_DLL");
-    FlagForCRT = "--dependent-lib=msvcrt";
-    break;
-  case options::OPT__SLASH_MDd:
-    CmdArgs.push_back("-D_DEBUG");
-    CmdArgs.push_back("-D_MT");
-    CmdArgs.push_back("-D_DLL");
-    FlagForCRT = "--dependent-lib=msvcrtd";
-    break;
-  case options::OPT__SLASH_MT:
-    if (Args.hasArg(options::OPT__SLASH_LDd))
-      CmdArgs.push_back("-D_DEBUG");
-    CmdArgs.push_back("-D_MT");
-    CmdArgs.push_back("-flto-visibility-public-std");
-    FlagForCRT = "--dependent-lib=libcmt";
-    break;
-  case options::OPT__SLASH_MTd:
-    CmdArgs.push_back("-D_DEBUG");
-    CmdArgs.push_back("-D_MT");
-    CmdArgs.push_back("-flto-visibility-public-std");
-    FlagForCRT = "--dependent-lib=libcmtd";
-    break;
-  default:
-    llvm_unreachable("Unexpected option ID.");
-  }
-
-  if (Args.hasArg(options::OPT__SLASH_Zl)) {
-    CmdArgs.push_back("-D_VC_NODEFAULTLIB");
-  } else {
-    CmdArgs.push_back(FlagForCRT.data());
-
-    // This provides POSIX compatibility (maps 'open' to '_open'), which most
-    // users want.  The /Za flag to cl.exe turns this off, but it's not
-    // implemented in clang.
-    CmdArgs.push_back("--dependent-lib=oldnames");
-  }
-
-  // Both /showIncludes and /E (and /EP) write to stdout. Allowing both
-  // would produce interleaved output, so ignore /showIncludes in such cases.
-  if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_EP))
-    if (Arg *A = Args.getLastArg(options::OPT_show_includes))
-      A->render(Args, CmdArgs);
-
-  // 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");
-
-  // This controls whether or not we emit stack-protector instrumentation.
-  // In MSVC, Buffer Security Check (/GS) is on by default.
-  if (Args.hasFlag(options::OPT__SLASH_GS, options::OPT__SLASH_GS_,
-                   /*default=*/true)) {
-    CmdArgs.push_back("-stack-protector");
-    CmdArgs.push_back(Args.MakeArgString(Twine(LangOptions::SSPStrong)));
-  }
-
-  // Emit CodeView if -Z7, -Zd, or -gline-tables-only are present.
-  if (Arg *DebugInfoArg =
-          Args.getLastArg(options::OPT__SLASH_Z7, options::OPT__SLASH_Zd,
-                          options::OPT_gline_tables_only)) {
-    *EmitCodeView = true;
-    if (DebugInfoArg->getOption().matches(options::OPT__SLASH_Z7))
-      *DebugInfoKind = codegenoptions::LimitedDebugInfo;
-    else
-      *DebugInfoKind = codegenoptions::DebugLineTablesOnly;
-    CmdArgs.push_back("-gcodeview");
-  } else {
-    *EmitCodeView = false;
-  }
-
-  const Driver &D = getToolChain().getDriver();
-  EHFlags EH = parseClangCLEHFlags(D, Args);
-  if (EH.Synch || EH.Asynch) {
-    if (types::isCXX(InputType))
-      CmdArgs.push_back("-fcxx-exceptions");
-    CmdArgs.push_back("-fexceptions");
-  }
-  if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
-    CmdArgs.push_back("-fexternc-nounwind");
-
-  // /EP should expand to -E -P.
-  if (Args.hasArg(options::OPT__SLASH_EP)) {
-    CmdArgs.push_back("-E");
-    CmdArgs.push_back("-P");
-  }
-
-  unsigned VolatileOptionID;
-  if (getToolChain().getArch() == llvm::Triple::x86_64 ||
-      getToolChain().getArch() == llvm::Triple::x86)
-    VolatileOptionID = options::OPT__SLASH_volatile_ms;
-  else
-    VolatileOptionID = options::OPT__SLASH_volatile_iso;
-
-  if (Arg *A = Args.getLastArg(options::OPT__SLASH_volatile_Group))
-    VolatileOptionID = A->getOption().getID();
-
-  if (VolatileOptionID == options::OPT__SLASH_volatile_ms)
-    CmdArgs.push_back("-fms-volatile");
-
-  Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
-  Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
-  if (MostGeneralArg && BestCaseArg)
-    D.Diag(clang::diag::err_drv_argument_not_allowed_with)
-        << MostGeneralArg->getAsString(Args) << BestCaseArg->getAsString(Args);
-
-  if (MostGeneralArg) {
-    Arg *SingleArg = Args.getLastArg(options::OPT__SLASH_vms);
-    Arg *MultipleArg = Args.getLastArg(options::OPT__SLASH_vmm);
-    Arg *VirtualArg = Args.getLastArg(options::OPT__SLASH_vmv);
-
-    Arg *FirstConflict = SingleArg ? SingleArg : MultipleArg;
-    Arg *SecondConflict = VirtualArg ? VirtualArg : MultipleArg;
-    if (FirstConflict && SecondConflict && FirstConflict != SecondConflict)
-      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
-          << FirstConflict->getAsString(Args)
-          << SecondConflict->getAsString(Args);
-
-    if (SingleArg)
-      CmdArgs.push_back("-fms-memptr-rep=single");
-    else if (MultipleArg)
-      CmdArgs.push_back("-fms-memptr-rep=multiple");
-    else
-      CmdArgs.push_back("-fms-memptr-rep=virtual");
-  }
-
-  if (Args.getLastArg(options::OPT__SLASH_Gd))
-     CmdArgs.push_back("-fdefault-calling-conv=cdecl");
-  else if (Args.getLastArg(options::OPT__SLASH_Gr))
-     CmdArgs.push_back("-fdefault-calling-conv=fastcall");
-  else if (Args.getLastArg(options::OPT__SLASH_Gz))
-     CmdArgs.push_back("-fdefault-calling-conv=stdcall");
-  else if (Args.getLastArg(options::OPT__SLASH_Gv))
-     CmdArgs.push_back("-fdefault-calling-conv=vectorcall");
-
-  if (Arg *A = Args.getLastArg(options::OPT_vtordisp_mode_EQ))
-    A->render(Args, CmdArgs);
-
-  if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
-    CmdArgs.push_back("-fdiagnostics-format");
-    if (Args.hasArg(options::OPT__SLASH_fallback))
-      CmdArgs.push_back("msvc-fallback");
-    else
-      CmdArgs.push_back("msvc");
-  }
-}
-
-visualstudio::Compiler *Clang::getCLFallback() const {
-  if (!CLFallback)
-    CLFallback.reset(new visualstudio::Compiler(getToolChain()));
-  return CLFallback.get();
-}
-
-void ClangAs::AddMIPSTargetArgs(const ArgList &Args,
-                                ArgStringList &CmdArgs) const {
-  StringRef CPUName;
-  StringRef ABIName;
-  const llvm::Triple &Triple = getToolChain().getTriple();
-  mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
-
-  CmdArgs.push_back("-target-abi");
-  CmdArgs.push_back(ABIName.data());
-}
-
-void ClangAs::AddX86TargetArgs(const ArgList &Args,
-                               ArgStringList &CmdArgs) const {
-  if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
-    StringRef Value = A->getValue();
-    if (Value == "intel" || Value == "att") {
-      CmdArgs.push_back("-mllvm");
-      CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));
-    } else {
-      getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
-          << A->getOption().getName() << Value;
-    }
-  }
-}
-
-void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
-                           const InputInfo &Output, const InputInfoList &Inputs,
-                           const ArgList &Args,
-                           const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-
-  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
-  const InputInfo &Input = Inputs[0];
-
-  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
-  const std::string &TripleStr = Triple.getTriple();
-
-  // Don't warn about "clang -w -c foo.s"
-  Args.ClaimAllArgs(options::OPT_w);
-  // and "clang -emit-llvm -c foo.s"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-
-  claimNoWarnArgs(Args);
-
-  // Invoke ourselves in -cc1as mode.
-  //
-  // FIXME: Implement custom jobs for internal actions.
-  CmdArgs.push_back("-cc1as");
-
-  // Add the "effective" target triple.
-  CmdArgs.push_back("-triple");
-  CmdArgs.push_back(Args.MakeArgString(TripleStr));
-
-  // Set the output mode, we currently only expect to be used as a real
-  // assembler.
-  CmdArgs.push_back("-filetype");
-  CmdArgs.push_back("obj");
-
-  // Set the main file name, so that debug info works even with
-  // -save-temps or preprocessed assembly.
-  CmdArgs.push_back("-main-file-name");
-  CmdArgs.push_back(Clang::getBaseInputName(Args, Input));
-
-  // Add the target cpu
-  std::string CPU = getCPUName(Args, Triple, /*FromAs*/ true);
-  if (!CPU.empty()) {
-    CmdArgs.push_back("-target-cpu");
-    CmdArgs.push_back(Args.MakeArgString(CPU));
-  }
-
-  // Add the target features
-  getTargetFeatures(getToolChain(), Triple, Args, CmdArgs, true);
-
-  // Ignore explicit -force_cpusubtype_ALL option.
-  (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
-
-  // Pass along any -I options so we get proper .include search paths.
-  Args.AddAllArgs(CmdArgs, options::OPT_I_Group);
-
-  // Determine the original source input.
-  const Action *SourceAction = &JA;
-  while (SourceAction->getKind() != Action::InputClass) {
-    assert(!SourceAction->getInputs().empty() && "unexpected root action!");
-    SourceAction = SourceAction->getInputs()[0];
-  }
-
-  // Forward -g and handle debug info related flags, assuming we are dealing
-  // with an actual assembly file.
-  bool WantDebug = false;
-  unsigned DwarfVersion = 0;
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
-    WantDebug = !A->getOption().matches(options::OPT_g0) &&
-                !A->getOption().matches(options::OPT_ggdb0);
-    if (WantDebug)
-      DwarfVersion = DwarfVersionNum(A->getSpelling());
-  }
-  if (DwarfVersion == 0)
-    DwarfVersion = getToolChain().GetDefaultDwarfVersion();
-
-  codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
-
-  if (SourceAction->getType() == types::TY_Asm ||
-      SourceAction->getType() == types::TY_PP_Asm) {
-    // You might think that it would be ok to set DebugInfoKind outside of
-    // the guard for source type, however there is a test which asserts
-    // that some assembler invocation receives no -debug-info-kind,
-    // and it's not clear whether that test is just overly restrictive.
-    DebugInfoKind = (WantDebug ? codegenoptions::LimitedDebugInfo
-                               : codegenoptions::NoDebugInfo);
-    // Add the -fdebug-compilation-dir flag if needed.
-    addDebugCompDirArg(Args, CmdArgs);
-
-    // Set the AT_producer to the clang version when using the integrated
-    // assembler on assembly source files.
-    CmdArgs.push_back("-dwarf-debug-producer");
-    CmdArgs.push_back(Args.MakeArgString(getClangFullVersion()));
-
-    // And pass along -I options
-    Args.AddAllArgs(CmdArgs, options::OPT_I);
-  }
-  RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
-                          llvm::DebuggerKind::Default);
-
-  // Handle -fPIC et al -- the relocation-model affects the assembler
-  // for some targets.
-  llvm::Reloc::Model RelocationModel;
-  unsigned PICLevel;
-  bool IsPIE;
-  std::tie(RelocationModel, PICLevel, IsPIE) =
-      ParsePICArgs(getToolChain(), Triple, Args);
-
-  const char *RMName = RelocationModelName(RelocationModel);
-  if (RMName) {
-    CmdArgs.push_back("-mrelocation-model");
-    CmdArgs.push_back(RMName);
-  }
-
-  // Optionally embed the -cc1as level arguments into the debug info, for build
-  // analysis.
-  if (getToolChain().UseDwarfDebugFlags()) {
-    ArgStringList OriginalArgs;
-    for (const auto &Arg : Args)
-      Arg->render(Args, OriginalArgs);
-
-    SmallString<256> Flags;
-    const char *Exec = getToolChain().getDriver().getClangProgramPath();
-    Flags += Exec;
-    for (const char *OriginalArg : OriginalArgs) {
-      SmallString<128> EscapedArg;
-      EscapeSpacesAndBackslashes(OriginalArg, EscapedArg);
-      Flags += " ";
-      Flags += EscapedArg;
-    }
-    CmdArgs.push_back("-dwarf-debug-flags");
-    CmdArgs.push_back(Args.MakeArgString(Flags));
-  }
-
-  // FIXME: Add -static support, once we have it.
-
-  // Add target specific flags.
-  switch (getToolChain().getArch()) {
-  default:
-    break;
-
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el:
-    AddMIPSTargetArgs(Args, CmdArgs);
-    break;
-
-  case llvm::Triple::x86:
-  case llvm::Triple::x86_64:
-    AddX86TargetArgs(Args, CmdArgs);
-    break;
-  }
-
-  // Consume all the warning flags. Usually this would be handled more
-  // gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as
-  // doesn't handle that so rather than warning about unused flags that are
-  // actually used, we'll lie by omission instead.
-  // FIXME: Stop lying and consume only the appropriate driver flags
-  Args.ClaimAllArgs(options::OPT_W_Group);
-
-  CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
-                                    getToolChain().getDriver());
-
-  Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
-
-  assert(Output.isFilename() && "Unexpected lipo output.");
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  assert(Input.isFilename() && "Invalid input.");
-  CmdArgs.push_back(Input.getFilename());
-
-  const char *Exec = getToolChain().getDriver().getClangProgramPath();
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-
-  // Handle the debug info splitting at object creation time if we're
-  // creating an object.
-  // TODO: Currently only works on linux with newer objcopy.
-  if (Args.hasArg(options::OPT_gsplit_dwarf) &&
-      getToolChain().getTriple().isOSLinux())
-    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
-                   SplitDebugName(Args, Input));
-}
-
-void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA,
-                                  const InputInfo &Output,
-                                  const InputInfoList &Inputs,
-                                  const llvm::opt::ArgList &TCArgs,
-                                  const char *LinkingOutput) const {
-  // The version with only one output is expected to refer to a bundling job.
-  assert(isa<OffloadBundlingJobAction>(JA) && "Expecting bundling job!");
-
-  // The bundling command looks like this:
-  // clang-offload-bundler -type=bc
-  //   -targets=host-triple,openmp-triple1,openmp-triple2
-  //   -outputs=input_file
-  //   -inputs=unbundle_file_host,unbundle_file_tgt1,unbundle_file_tgt2"
-
-  ArgStringList CmdArgs;
-
-  // Get the type.
-  CmdArgs.push_back(TCArgs.MakeArgString(
-      Twine("-type=") + types::getTypeTempSuffix(Output.getType())));
-
-  assert(JA.getInputs().size() == Inputs.size() &&
-         "Not have inputs for all dependence actions??");
-
-  // Get the targets.
-  SmallString<128> Triples;
-  Triples += "-targets=";
-  for (unsigned I = 0; I < Inputs.size(); ++I) {
-    if (I)
-      Triples += ',';
-
-    Action::OffloadKind CurKind = Action::OFK_Host;
-    const ToolChain *CurTC = &getToolChain();
-    const Action *CurDep = JA.getInputs()[I];
-
-    if (const auto *OA = dyn_cast<OffloadAction>(CurDep)) {
-      OA->doOnEachDependence([&](Action *A, const ToolChain *TC, const char *) {
-        CurKind = A->getOffloadingDeviceKind();
-        CurTC = TC;
-      });
-    }
-    Triples += Action::GetOffloadKindName(CurKind);
-    Triples += '-';
-    Triples += CurTC->getTriple().normalize();
-  }
-  CmdArgs.push_back(TCArgs.MakeArgString(Triples));
-
-  // Get bundled file command.
-  CmdArgs.push_back(
-      TCArgs.MakeArgString(Twine("-outputs=") + Output.getFilename()));
-
-  // Get unbundled files command.
-  SmallString<128> UB;
-  UB += "-inputs=";
-  for (unsigned I = 0; I < Inputs.size(); ++I) {
-    if (I)
-      UB += ',';
-    UB += Inputs[I].getFilename();
-  }
-  CmdArgs.push_back(TCArgs.MakeArgString(UB));
-
-  // All the inputs are encoded as commands.
-  C.addCommand(llvm::make_unique<Command>(
-      JA, *this,
-      TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
-      CmdArgs, None));
-}
-
-void OffloadBundler::ConstructJobMultipleOutputs(
-    Compilation &C, const JobAction &JA, const InputInfoList &Outputs,
-    const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs,
-    const char *LinkingOutput) const {
-  // The version with multiple outputs is expected to refer to a unbundling job.
-  auto &UA = cast<OffloadUnbundlingJobAction>(JA);
-
-  // The unbundling command looks like this:
-  // clang-offload-bundler -type=bc
-  //   -targets=host-triple,openmp-triple1,openmp-triple2
-  //   -inputs=input_file
-  //   -outputs=unbundle_file_host,unbundle_file_tgt1,unbundle_file_tgt2"
-  //   -unbundle
-
-  ArgStringList CmdArgs;
-
-  assert(Inputs.size() == 1 && "Expecting to unbundle a single file!");
-  InputInfo Input = Inputs.front();
-
-  // Get the type.
-  CmdArgs.push_back(TCArgs.MakeArgString(
-      Twine("-type=") + types::getTypeTempSuffix(Input.getType())));
-
-  // Get the targets.
-  SmallString<128> Triples;
-  Triples += "-targets=";
-  auto DepInfo = UA.getDependentActionsInfo();
-  for (unsigned I = 0; I < DepInfo.size(); ++I) {
-    if (I)
-      Triples += ',';
-
-    auto &Dep = DepInfo[I];
-    Triples += Action::GetOffloadKindName(Dep.DependentOffloadKind);
-    Triples += '-';
-    Triples += Dep.DependentToolChain->getTriple().normalize();
-  }
-
-  CmdArgs.push_back(TCArgs.MakeArgString(Triples));
-
-  // Get bundled file command.
-  CmdArgs.push_back(
-      TCArgs.MakeArgString(Twine("-inputs=") + Input.getFilename()));
-
-  // Get unbundled files command.
-  SmallString<128> UB;
-  UB += "-outputs=";
-  for (unsigned I = 0; I < Outputs.size(); ++I) {
-    if (I)
-      UB += ',';
-    UB += Outputs[I].getFilename();
-  }
-  CmdArgs.push_back(TCArgs.MakeArgString(UB));
-  CmdArgs.push_back("-unbundle");
-
-  // All the inputs are encoded as commands.
-  C.addCommand(llvm::make_unique<Command>(
-      JA, *this,
-      TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
-      CmdArgs, None));
-}
-
-void GnuTool::anchor() {}
-
-void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
-                               const InputInfo &Output,
-                               const InputInfoList &Inputs, const ArgList &Args,
-                               const char *LinkingOutput) const {
-  const Driver &D = getToolChain().getDriver();
-  ArgStringList CmdArgs;
-
-  for (const auto &A : Args) {
-    if (forwardToGCC(A->getOption())) {
-      // It is unfortunate that we have to claim here, as this means
-      // we will basically never report anything interesting for
-      // platforms using a generic gcc, even if we are just using gcc
-      // to get to the assembler.
-      A->claim();
-
-      // Don't forward any -g arguments to assembly steps.
-      if (isa<AssembleJobAction>(JA) &&
-          A->getOption().matches(options::OPT_g_Group))
-        continue;
-
-      // Don't forward any -W arguments to assembly and link steps.
-      if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) &&
-          A->getOption().matches(options::OPT_W_Group))
-        continue;
-
-      A->render(Args, CmdArgs);
-    }
-  }
-
-  RenderExtraToolArgs(JA, CmdArgs);
-
-  // If using a driver driver, force the arch.
-  if (getToolChain().getTriple().isOSDarwin()) {
-    CmdArgs.push_back("-arch");
-    CmdArgs.push_back(
-        Args.MakeArgString(getToolChain().getDefaultUniversalArchName()));
-  }
-
-  // Try to force gcc to match the tool chain we want, if we recognize
-  // the arch.
-  //
-  // FIXME: The triple class should directly provide the information we want
-  // here.
-  switch (getToolChain().getArch()) {
-  default:
-    break;
-  case llvm::Triple::x86:
-  case llvm::Triple::ppc:
-    CmdArgs.push_back("-m32");
-    break;
-  case llvm::Triple::x86_64:
-  case llvm::Triple::ppc64:
-  case llvm::Triple::ppc64le:
-    CmdArgs.push_back("-m64");
-    break;
-  case llvm::Triple::sparcel:
-    CmdArgs.push_back("-EL");
-    break;
-  }
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Unexpected output");
-    CmdArgs.push_back("-fsyntax-only");
-  }
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  // Only pass -x if gcc will understand it; otherwise hope gcc
-  // understands the suffix correctly. The main use case this would go
-  // wrong in is for linker inputs if they happened to have an odd
-  // suffix; really the only way to get this to happen is a command
-  // like '-x foobar a.c' which will treat a.c like a linker input.
-  //
-  // FIXME: For the linker case specifically, can we safely convert
-  // inputs into '-Wl,' options?
-  for (const auto &II : Inputs) {
-    // Don't try to pass LLVM or AST inputs to a generic gcc.
-    if (types::isLLVMIR(II.getType()))
-      D.Diag(diag::err_drv_no_linker_llvm_support)
-          << getToolChain().getTripleString();
-    else if (II.getType() == types::TY_AST)
-      D.Diag(diag::err_drv_no_ast_support) << getToolChain().getTripleString();
-    else if (II.getType() == types::TY_ModuleFile)
-      D.Diag(diag::err_drv_no_module_support)
-          << getToolChain().getTripleString();
-
-    if (types::canTypeBeUserSpecified(II.getType())) {
-      CmdArgs.push_back("-x");
-      CmdArgs.push_back(types::getTypeName(II.getType()));
-    }
-
-    if (II.isFilename())
-      CmdArgs.push_back(II.getFilename());
-    else {
-      const Arg &A = II.getInputArg();
-
-      // Reverse translate some rewritten options.
-      if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
-        CmdArgs.push_back("-lstdc++");
-        continue;
-      }
-
-      // Don't render as input, we need gcc to do the translations.
-      A.render(Args, CmdArgs);
-    }
-  }
-
-  const std::string &customGCCName = D.getCCCGenericGCCName();
-  const char *GCCName;
-  if (!customGCCName.empty())
-    GCCName = customGCCName.c_str();
-  else if (D.CCCIsCXX()) {
-    GCCName = "g++";
-  } else
-    GCCName = "gcc";
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void gcc::Preprocessor::RenderExtraToolArgs(const JobAction &JA,
-                                            ArgStringList &CmdArgs) const {
-  CmdArgs.push_back("-E");
-}
-
-void gcc::Compiler::RenderExtraToolArgs(const JobAction &JA,
-                                        ArgStringList &CmdArgs) const {
-  const Driver &D = getToolChain().getDriver();
-
-  switch (JA.getType()) {
-  // If -flto, etc. are present then make sure not to force assembly output.
-  case types::TY_LLVM_IR:
-  case types::TY_LTO_IR:
-  case types::TY_LLVM_BC:
-  case types::TY_LTO_BC:
-    CmdArgs.push_back("-c");
-    break;
-  // We assume we've got an "integrated" assembler in that gcc will produce an
-  // object file itself.
-  case types::TY_Object:
-    CmdArgs.push_back("-c");
-    break;
-  case types::TY_PP_Asm:
-    CmdArgs.push_back("-S");
-    break;
-  case types::TY_Nothing:
-    CmdArgs.push_back("-fsyntax-only");
-    break;
-  default:
-    D.Diag(diag::err_drv_invalid_gcc_output_type) << getTypeName(JA.getType());
-  }
-}
-
-void gcc::Linker::RenderExtraToolArgs(const JobAction &JA,
-                                      ArgStringList &CmdArgs) const {
-  // The types are (hopefully) good enough.
-}
-
-// Hexagon tools start.
-void hexagon::Assembler::RenderExtraToolArgs(const JobAction &JA,
-                                             ArgStringList &CmdArgs) const {
-}
-
-void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                      const InputInfo &Output,
-                                      const InputInfoList &Inputs,
-                                      const ArgList &Args,
-                                      const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-
-  auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
-  const Driver &D = HTC.getDriver();
-  ArgStringList CmdArgs;
-
-  std::string MArchString = "-march=hexagon";
-  CmdArgs.push_back(Args.MakeArgString(MArchString));
-
-  RenderExtraToolArgs(JA, CmdArgs);
-
-  std::string AsName = "hexagon-llvm-mc";
-  std::string MCpuString = "-mcpu=hexagon" +
-        toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
-  CmdArgs.push_back("-filetype=obj");
-  CmdArgs.push_back(Args.MakeArgString(MCpuString));
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Unexpected output");
-    CmdArgs.push_back("-fsyntax-only");
-  }
-
-  if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
-    std::string N = llvm::utostr(G.getValue());
-    CmdArgs.push_back(Args.MakeArgString(std::string("-gpsize=") + N));
-  }
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  // Only pass -x if gcc will understand it; otherwise hope gcc
-  // understands the suffix correctly. The main use case this would go
-  // wrong in is for linker inputs if they happened to have an odd
-  // suffix; really the only way to get this to happen is a command
-  // like '-x foobar a.c' which will treat a.c like a linker input.
-  //
-  // FIXME: For the linker case specifically, can we safely convert
-  // inputs into '-Wl,' options?
-  for (const auto &II : Inputs) {
-    // Don't try to pass LLVM or AST inputs to a generic gcc.
-    if (types::isLLVMIR(II.getType()))
-      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
-          << HTC.getTripleString();
-    else if (II.getType() == types::TY_AST)
-      D.Diag(clang::diag::err_drv_no_ast_support)
-          << HTC.getTripleString();
-    else if (II.getType() == types::TY_ModuleFile)
-      D.Diag(diag::err_drv_no_module_support)
-          << HTC.getTripleString();
-
-    if (II.isFilename())
-      CmdArgs.push_back(II.getFilename());
-    else
-      // Don't render as input, we need gcc to do the translations.
-      // FIXME: What is this?
-      II.getInputArg().render(Args, CmdArgs);
-  }
-
-  auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName.c_str()));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA,
-                                          ArgStringList &CmdArgs) const {
-}
-
-static void
-constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
-                         const toolchains::HexagonToolChain &HTC,
-                         const InputInfo &Output, const InputInfoList &Inputs,
-                         const ArgList &Args, ArgStringList &CmdArgs,
-                         const char *LinkingOutput) {
-
-  const Driver &D = HTC.getDriver();
-
-  //----------------------------------------------------------------------------
-  //
-  //----------------------------------------------------------------------------
-  bool IsStatic = Args.hasArg(options::OPT_static);
-  bool IsShared = Args.hasArg(options::OPT_shared);
-  bool IsPIE = Args.hasArg(options::OPT_pie);
-  bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
-  bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
-  bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
-  bool UseG0 = false;
-  bool UseShared = IsShared && !IsStatic;
-
-  //----------------------------------------------------------------------------
-  // Silence warnings for various options
-  //----------------------------------------------------------------------------
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
-                                     // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_static_libgcc);
-
-  //----------------------------------------------------------------------------
-  //
-  //----------------------------------------------------------------------------
-  if (Args.hasArg(options::OPT_s))
-    CmdArgs.push_back("-s");
-
-  if (Args.hasArg(options::OPT_r))
-    CmdArgs.push_back("-r");
-
-  for (const auto &Opt : HTC.ExtraOpts)
-    CmdArgs.push_back(Opt.c_str());
-
-  CmdArgs.push_back("-march=hexagon");
-  std::string CpuVer =
-        toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
-  std::string MCpuString = "-mcpu=hexagon" + CpuVer;
-  CmdArgs.push_back(Args.MakeArgString(MCpuString));
-
-  if (IsShared) {
-    CmdArgs.push_back("-shared");
-    // The following should be the default, but doing as hexagon-gcc does.
-    CmdArgs.push_back("-call_shared");
-  }
-
-  if (IsStatic)
-    CmdArgs.push_back("-static");
-
-  if (IsPIE && !IsShared)
-    CmdArgs.push_back("-pie");
-
-  if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
-    std::string N = llvm::utostr(G.getValue());
-    CmdArgs.push_back(Args.MakeArgString(std::string("-G") + N));
-    UseG0 = G.getValue() == 0;
-  }
-
-  //----------------------------------------------------------------------------
-  //
-  //----------------------------------------------------------------------------
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  //----------------------------------------------------------------------------
-  // moslib
-  //----------------------------------------------------------------------------
-  std::vector<std::string> OsLibs;
-  bool HasStandalone = false;
-
-  for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
-    A->claim();
-    OsLibs.emplace_back(A->getValue());
-    HasStandalone = HasStandalone || (OsLibs.back() == "standalone");
-  }
-  if (OsLibs.empty()) {
-    OsLibs.push_back("standalone");
-    HasStandalone = true;
-  }
-
-  //----------------------------------------------------------------------------
-  // Start Files
-  //----------------------------------------------------------------------------
-  const std::string MCpuSuffix = "/" + CpuVer;
-  const std::string MCpuG0Suffix = MCpuSuffix + "/G0";
-  const std::string RootDir =
-      HTC.getHexagonTargetDir(D.InstalledDir, D.PrefixDirs) + "/";
-  const std::string StartSubDir =
-      "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
-
-  auto Find = [&HTC] (const std::string &RootDir, const std::string &SubDir,
-                      const char *Name) -> std::string {
-    std::string RelName = SubDir + Name;
-    std::string P = HTC.GetFilePath(RelName.c_str());
-    if (llvm::sys::fs::exists(P))
-      return P;
-    return RootDir + RelName;
-  };
-
-  if (IncStdLib && IncStartFiles) {
-    if (!IsShared) {
-      if (HasStandalone) {
-        std::string Crt0SA = Find(RootDir, StartSubDir, "/crt0_standalone.o");
-        CmdArgs.push_back(Args.MakeArgString(Crt0SA));
-      }
-      std::string Crt0 = Find(RootDir, StartSubDir, "/crt0.o");
-      CmdArgs.push_back(Args.MakeArgString(Crt0));
-    }
-    std::string Init = UseShared
-          ? Find(RootDir, StartSubDir + "/pic", "/initS.o")
-          : Find(RootDir, StartSubDir, "/init.o");
-    CmdArgs.push_back(Args.MakeArgString(Init));
-  }
-
-  //----------------------------------------------------------------------------
-  // Library Search Paths
-  //----------------------------------------------------------------------------
-  const ToolChain::path_list &LibPaths = HTC.getFilePaths();
-  for (const auto &LibPath : LibPaths)
-    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
-
-  //----------------------------------------------------------------------------
-  //
-  //----------------------------------------------------------------------------
-  Args.AddAllArgs(CmdArgs,
-                  {options::OPT_T_Group, options::OPT_e, options::OPT_s,
-                   options::OPT_t, options::OPT_u_Group});
-
-  AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
-
-  //----------------------------------------------------------------------------
-  // Libraries
-  //----------------------------------------------------------------------------
-  if (IncStdLib && IncDefLibs) {
-    if (D.CCCIsCXX()) {
-      HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
-      CmdArgs.push_back("-lm");
-    }
-
-    CmdArgs.push_back("--start-group");
-
-    if (!IsShared) {
-      for (const std::string &Lib : OsLibs)
-        CmdArgs.push_back(Args.MakeArgString("-l" + Lib));
-      CmdArgs.push_back("-lc");
-    }
-    CmdArgs.push_back("-lgcc");
-
-    CmdArgs.push_back("--end-group");
-  }
-
-  //----------------------------------------------------------------------------
-  // End files
-  //----------------------------------------------------------------------------
-  if (IncStdLib && IncStartFiles) {
-    std::string Fini = UseShared
-          ? Find(RootDir, StartSubDir + "/pic", "/finiS.o")
-          : Find(RootDir, StartSubDir, "/fini.o");
-    CmdArgs.push_back(Args.MakeArgString(Fini));
-  }
-}
-
-void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                   const InputInfo &Output,
-                                   const InputInfoList &Inputs,
-                                   const ArgList &Args,
-                                   const char *LinkingOutput) const {
-  auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
-
-  ArgStringList CmdArgs;
-  constructHexagonLinkArgs(C, JA, HTC, Output, Inputs, Args, CmdArgs,
-                           LinkingOutput);
-
-  std::string Linker = HTC.GetProgramPath("hexagon-link");
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
-                                          CmdArgs, Inputs));
-}
-// Hexagon tools end.
-
-void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                  const InputInfo &Output,
-                                  const InputInfoList &Inputs,
-                                  const ArgList &Args,
-                                  const char *LinkingOutput) const {
-
-  std::string Linker = getToolChain().GetProgramPath(getShortName());
-  ArgStringList CmdArgs;
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-  CmdArgs.push_back("-shared");
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
-                                          CmdArgs, Inputs));
-}
-// AMDGPU tools end.
-
-wasm::Linker::Linker(const ToolChain &TC)
-  : GnuTool("wasm::Linker", "lld", TC) {}
-
-bool wasm::Linker::isLinkJob() const {
-  return true;
-}
-
-bool wasm::Linker::hasIntegratedCPP() const {
-  return false;
-}
-
-void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                const InputInfo &Output,
-                                const InputInfoList &Inputs,
-                                const ArgList &Args,
-                                const char *LinkingOutput) const {
-
-  const ToolChain &ToolChain = getToolChain();
-  const Driver &D = ToolChain.getDriver();
-  const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
-  ArgStringList CmdArgs;
-  CmdArgs.push_back("-flavor");
-  CmdArgs.push_back("ld");
-
-  // Enable garbage collection of unused input sections by default, since code
-  // size is of particular importance. This is significantly facilitated by
-  // the enabling of -ffunction-sections and -fdata-sections in
-  // Clang::ConstructJob.
-  if (areOptimizationsEnabled(Args))
-    CmdArgs.push_back("--gc-sections");
-
-  if (Args.hasArg(options::OPT_rdynamic))
-    CmdArgs.push_back("-export-dynamic");
-  if (Args.hasArg(options::OPT_s))
-    CmdArgs.push_back("--strip-all");
-  if (Args.hasArg(options::OPT_shared))
-    CmdArgs.push_back("-shared");
-  if (Args.hasArg(options::OPT_static))
-    CmdArgs.push_back("-Bstatic");
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (Args.hasArg(options::OPT_shared))
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("rcrt1.o")));
-    else if (Args.hasArg(options::OPT_pie))
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o")));
-    else
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt1.o")));
-
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
-  }
-
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX())
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-
-    if (Args.hasArg(options::OPT_pthread))
-      CmdArgs.push_back("-lpthread");
-
-    CmdArgs.push_back("-lc");
-    CmdArgs.push_back("-lcompiler_rt");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Linker, CmdArgs, Inputs));
-}
-
-const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
-  std::string MArch;
-  if (!Arch.empty())
-    MArch = Arch;
-  else
-    MArch = Triple.getArchName();
-  MArch = StringRef(MArch).split("+").first.lower();
-
-  // Handle -march=native.
-  if (MArch == "native") {
-    std::string CPU = llvm::sys::getHostCPUName();
-    if (CPU != "generic") {
-      // Translate the native cpu into the architecture suffix for that CPU.
-      StringRef Suffix = arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
-      // If there is no valid architecture suffix for this CPU we don't know how
-      // to handle it, so return no architecture.
-      if (Suffix.empty())
-        MArch = "";
-      else
-        MArch = std::string("arm") + Suffix.str();
-    }
-  }
-
-  return MArch;
-}
-
-/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
-StringRef arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) {
-  std::string MArch = getARMArch(Arch, Triple);
-  // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch
-  // here means an -march=native that we can't handle, so instead return no CPU.
-  if (MArch.empty())
-    return StringRef();
-
-  // We need to return an empty string here on invalid MArch values as the
-  // various places that call this function can't cope with a null result.
-  return Triple.getARMCPUForArch(MArch);
-}
-
-/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
-std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,
-                                 const llvm::Triple &Triple) {
-  // FIXME: Warn on inconsistent use of -mcpu and -march.
-  // If we have -mcpu=, use that.
-  if (!CPU.empty()) {
-    std::string MCPU = StringRef(CPU).split("+").first.lower();
-    // Handle -mcpu=native.
-    if (MCPU == "native")
-      return llvm::sys::getHostCPUName();
-    else
-      return MCPU;
-  }
-
-  return getARMCPUForMArch(Arch, Triple);
-}
-
-/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
-/// CPU  (or Arch, if CPU is generic).
-// FIXME: This is redundant with -mcpu, why does LLVM use this.
-StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
-                                       const llvm::Triple &Triple) {
-  unsigned ArchKind;
-  if (CPU == "generic") {
-    std::string ARMArch = tools::arm::getARMArch(Arch, Triple);
-    ArchKind = llvm::ARM::parseArch(ARMArch);
-    if (ArchKind == llvm::ARM::AK_INVALID)
-      // In case of generic Arch, i.e. "arm",
-      // extract arch from default cpu of the Triple
-      ArchKind = llvm::ARM::parseCPUArch(Triple.getARMCPUForArch(ARMArch));
-  } else {
-    // FIXME: horrible hack to get around the fact that Cortex-A7 is only an
-    // armv7k triple if it's actually been specified via "-arch armv7k".
-    ArchKind = (Arch == "armv7k" || Arch == "thumbv7k")
-                          ? (unsigned)llvm::ARM::AK_ARMV7K
-                          : llvm::ARM::parseCPUArch(CPU);
-  }
-  if (ArchKind == llvm::ARM::AK_INVALID)
-    return "";
-  return llvm::ARM::getSubArch(ArchKind);
-}
-
-void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs,
-                            const llvm::Triple &Triple) {
-  if (Args.hasArg(options::OPT_r))
-    return;
-
-  // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker
-  // to generate BE-8 executables.
-  if (getARMSubArchVersionNumber(Triple) >= 7 || isARMMProfile(Triple))
-    CmdArgs.push_back("--be8");
-}
-
-mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
-  // Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008
-  // was first introduced in Release 3. However, other compilers have
-  // traditionally allowed it for Release 2 so we should do the same.
-  return (NanEncoding)llvm::StringSwitch<int>(CPU)
-      .Case("mips1", NanLegacy)
-      .Case("mips2", NanLegacy)
-      .Case("mips3", NanLegacy)
-      .Case("mips4", NanLegacy)
-      .Case("mips5", NanLegacy)
-      .Case("mips32", NanLegacy)
-      .Case("mips32r2", NanLegacy | Nan2008)
-      .Case("mips32r3", NanLegacy | Nan2008)
-      .Case("mips32r5", NanLegacy | Nan2008)
-      .Case("mips32r6", Nan2008)
-      .Case("mips64", NanLegacy)
-      .Case("mips64r2", NanLegacy | Nan2008)
-      .Case("mips64r3", NanLegacy | Nan2008)
-      .Case("mips64r5", NanLegacy | Nan2008)
-      .Case("mips64r6", Nan2008)
-      .Default(NanLegacy);
-}
-
-bool mips::hasCompactBranches(StringRef &CPU) {
-  // mips32r6 and mips64r6 have compact branches.
-  return llvm::StringSwitch<bool>(CPU)
-      .Case("mips32r6", true)
-      .Case("mips64r6", true)
-      .Default(false);
-}
-
-bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
-  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
-  return A && (A->getValue() == StringRef(Value));
-}
-
-bool mips::isUCLibc(const ArgList &Args) {
-  Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
-  return A && A->getOption().matches(options::OPT_muclibc);
-}
-
-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;
-}
-
-bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
-  if (!Triple.isAndroid())
-    return false;
-
-  // Android MIPS32R6 defaults to FP64A.
-  return llvm::StringSwitch<bool>(CPUName)
-      .Case("mips32r6", true)
-      .Default(false);
-}
-
-bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
-                         StringRef ABIName, mips::FloatABI FloatABI) {
-  if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
-      Triple.getVendor() != llvm::Triple::MipsTechnologies &&
-      !Triple.isAndroid())
-    return false;
-
-  if (ABIName != "32")
-    return false;
-
-  // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
-  // present.
-  if (FloatABI == mips::FloatABI::Soft)
-    return false;
-
-  return llvm::StringSwitch<bool>(CPUName)
-      .Cases("mips2", "mips3", "mips4", "mips5", true)
-      .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
-      .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
-      .Default(false);
-}
-
-bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
-                         StringRef CPUName, StringRef ABIName,
-                         mips::FloatABI FloatABI) {
-  bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
-
-  // FPXX shouldn't be used if -msingle-float is present.
-  if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
-                               options::OPT_mdouble_float))
-    if (A->getOption().matches(options::OPT_msingle_float))
-      UseFPXX = false;
-
-  return UseFPXX;
-}
-
-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.
-
-  // The matching this routine does is fairly pointless, since it is neither the
-  // complete architecture list, nor a reasonable subset. The problem is that
-  // historically the driver driver accepts this and also ties its -march=
-  // handling to the architecture name, so we need to be careful before removing
-  // support for it.
-
-  // This code must be kept in sync with Clang's Darwin specific argument
-  // translation.
-
-  return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
-      .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
-      .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
-      .Case("ppc64", llvm::Triple::ppc64)
-      .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
-      .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
-             llvm::Triple::x86)
-      .Cases("x86_64", "x86_64h", llvm::Triple::x86_64)
-      // This is derived from the driver driver.
-      .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
-      .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm)
-      .Cases("armv7s", "xscale", llvm::Triple::arm)
-      .Case("arm64", llvm::Triple::aarch64)
-      .Case("r600", llvm::Triple::r600)
-      .Case("amdgcn", llvm::Triple::amdgcn)
-      .Case("nvptx", llvm::Triple::nvptx)
-      .Case("nvptx64", llvm::Triple::nvptx64)
-      .Case("amdil", llvm::Triple::amdil)
-      .Case("spir", llvm::Triple::spir)
-      .Default(llvm::Triple::UnknownArch);
-}
-
-void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) {
-  const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str);
-  unsigned ArchKind = llvm::ARM::parseArch(Str);
-  T.setArch(Arch);
-
-  if (Str == "x86_64h")
-    T.setArchName(Str);
-  else if (ArchKind == llvm::ARM::AK_ARMV6M ||
-           ArchKind == llvm::ARM::AK_ARMV7M ||
-           ArchKind == llvm::ARM::AK_ARMV7EM) {
-    T.setOS(llvm::Triple::UnknownOS);
-    T.setObjectFormat(llvm::Triple::MachO);
-  }
-}
-
-const char *Clang::getBaseInputName(const ArgList &Args,
-                                    const InputInfo &Input) {
-  return Args.MakeArgString(llvm::sys::path::filename(Input.getBaseInput()));
-}
-
-const char *Clang::getBaseInputStem(const ArgList &Args,
-                                    const InputInfoList &Inputs) {
-  const char *Str = getBaseInputName(Args, Inputs[0]);
-
-  if (const char *End = strrchr(Str, '.'))
-    return Args.MakeArgString(std::string(Str, End));
-
-  return Str;
-}
-
-const char *Clang::getDependencyFileName(const ArgList &Args,
-                                         const InputInfoList &Inputs) {
-  // FIXME: Think about this more.
-  std::string Res;
-
-  if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
-    std::string Str(OutputOpt->getValue());
-    Res = Str.substr(0, Str.rfind('.'));
-  } else {
-    Res = getBaseInputStem(Args, Inputs);
-  }
-  return Args.MakeArgString(Res + ".d");
-}
-
-void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                    const InputInfo &Output,
-                                    const InputInfoList &Inputs,
-                                    const ArgList &Args,
-                                    const char *LinkingOutput) const {
-  const ToolChain &ToolChain = getToolChain();
-  const Driver &D = ToolChain.getDriver();
-  ArgStringList CmdArgs;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo". Other warning options are already
-  // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_w);
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  // CloudABI only supports static linkage.
-  CmdArgs.push_back("-Bstatic");
-  CmdArgs.push_back("--no-dynamic-linker");
-
-  // Provide PIE linker flags in case PIE is default for the architecture.
-  if (ToolChain.isPIEDefault()) {
-    CmdArgs.push_back("-pie");
-    CmdArgs.push_back("-zrelro");
-  }
-
-  CmdArgs.push_back("--eh-frame-hdr");
-  CmdArgs.push_back("--gc-sections");
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")));
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
-  Args.AddAllArgs(CmdArgs,
-                  {options::OPT_T_Group, options::OPT_e, options::OPT_s,
-                   options::OPT_t, options::OPT_Z_Flag, options::OPT_r});
-
-  if (D.isUsingLTO())
-    AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin, D);
-
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX())
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-    CmdArgs.push_back("-lc");
-    CmdArgs.push_back("-lcompiler_rt");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
-
-  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                     const InputInfo &Output,
-                                     const InputInfoList &Inputs,
-                                     const ArgList &Args,
-                                     const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-
-  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
-  const InputInfo &Input = Inputs[0];
-
-  // Determine the original source input.
-  const Action *SourceAction = &JA;
-  while (SourceAction->getKind() != Action::InputClass) {
-    assert(!SourceAction->getInputs().empty() && "unexpected root action!");
-    SourceAction = SourceAction->getInputs()[0];
-  }
-
-  // If -fno-integrated-as is used add -Q to the darwin assember driver to make
-  // sure it runs its system assembler not clang's integrated assembler.
-  // Applicable to darwin11+ and Xcode 4+.  darwin<10 lacked integrated-as.
-  // FIXME: at run-time detect assembler capabilities or rely on version
-  // information forwarded by -target-assembler-version.
-  if (Args.hasArg(options::OPT_fno_integrated_as)) {
-    const llvm::Triple &T(getToolChain().getTriple());
-    if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7)))
-      CmdArgs.push_back("-Q");
-  }
-
-  // Forward -g, assuming we are dealing with an actual assembly file.
-  if (SourceAction->getType() == types::TY_Asm ||
-      SourceAction->getType() == types::TY_PP_Asm) {
-    if (Args.hasArg(options::OPT_gstabs))
-      CmdArgs.push_back("--gstabs");
-    else if (Args.hasArg(options::OPT_g_Group))
-      CmdArgs.push_back("-g");
-  }
-
-  // Derived from asm spec.
-  AddMachOArch(Args, CmdArgs);
-
-  // Use -force_cpusubtype_ALL on x86 by default.
-  if (getToolChain().getArch() == llvm::Triple::x86 ||
-      getToolChain().getArch() == llvm::Triple::x86_64 ||
-      Args.hasArg(options::OPT_force__cpusubtype__ALL))
-    CmdArgs.push_back("-force_cpusubtype_ALL");
-
-  if (getToolChain().getArch() != llvm::Triple::x86_64 &&
-      (((Args.hasArg(options::OPT_mkernel) ||
-         Args.hasArg(options::OPT_fapple_kext)) &&
-        getMachOToolChain().isKernelStatic()) ||
-       Args.hasArg(options::OPT_static)))
-    CmdArgs.push_back("-static");
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  assert(Output.isFilename() && "Unexpected lipo output.");
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  assert(Input.isFilename() && "Invalid input.");
-  CmdArgs.push_back(Input.getFilename());
-
-  // asm_final spec is empty.
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void darwin::MachOTool::anchor() {}
-
-void darwin::MachOTool::AddMachOArch(const ArgList &Args,
-                                     ArgStringList &CmdArgs) const {
-  StringRef ArchName = getMachOToolChain().getMachOArchName(Args);
-
-  // Derived from darwin_arch spec.
-  CmdArgs.push_back("-arch");
-  CmdArgs.push_back(Args.MakeArgString(ArchName));
-
-  // FIXME: Is this needed anymore?
-  if (ArchName == "arm")
-    CmdArgs.push_back("-force_cpusubtype_ALL");
-}
-
-bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const {
-  // 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 (const auto &Input : Inputs)
-    if (Input.getType() != types::TY_Object)
-      return true;
-
-  return false;
-}
-
-/// \brief Pass -no_deduplicate to ld64 under certain conditions:
-///
-/// - Either -O0 or -O1 is explicitly specified
-/// - No -O option is specified *and* this is a compile+link (implicit -O0)
-///
-/// Also do *not* add -no_deduplicate when no -O option is specified and this
-/// is just a link (we can't imply -O0)
-static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) {
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    if (A->getOption().matches(options::OPT_O0))
-      return true;
-    if (A->getOption().matches(options::OPT_O))
-      return llvm::StringSwitch<bool>(A->getValue())
-                    .Case("1", true)
-                    .Default(false);
-    return false; // OPT_Ofast & OPT_O4
-  }
-
-  if (!IsLinkerOnlyAction) // Implicit -O0 for compile+linker only.
-    return true;
-  return false;
-}
-
-void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
-                                 ArgStringList &CmdArgs,
-                                 const InputInfoList &Inputs) const {
-  const Driver &D = getToolChain().getDriver();
-  const toolchains::MachO &MachOTC = getMachOToolChain();
-
-  unsigned Version[5] = {0, 0, 0, 0, 0};
-  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
-    if (!Driver::GetReleaseVersion(A->getValue(), Version))
-      D.Diag(diag::err_drv_invalid_version_number) << A->getAsString(Args);
-  }
-
-  // Newer linkers support -demangle. Pass it if supported and not disabled by
-  // the user.
-  if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
-    CmdArgs.push_back("-demangle");
-
-  if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137)
-    CmdArgs.push_back("-export_dynamic");
-
-  // If we are using App Extension restrictions, pass a flag to the linker
-  // telling it that the compiled code has been audited.
-  if (Args.hasFlag(options::OPT_fapplication_extension,
-                   options::OPT_fno_application_extension, false))
-    CmdArgs.push_back("-application_extension");
-
-  if (D.isUsingLTO()) {
-    // If we are using LTO, then automatically create a temporary file path for
-    // the linker to use, so that it's lifetime will extend past a possible
-    // dsymutil step.
-    if (Version[0] >= 116 && NeedsTempPath(Inputs)) {
-      const char *TmpPath = C.getArgs().MakeArgString(
-          D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
-      C.addTempFile(TmpPath);
-      CmdArgs.push_back("-object_path_lto");
-      CmdArgs.push_back(TmpPath);
-    }
-  }
-
-  // Use -lto_library option to specify the libLTO.dylib path. Try to find
-  // it in clang installed libraries. ld64 will only look at this argument
-  // when it actually uses LTO, so libLTO.dylib only needs to exist at link
-  // time if ld64 decides that it needs to use LTO.
-  // Since this is passed unconditionally, ld64 will never look for libLTO.dylib
-  // next to it. That's ok since ld64 using a libLTO.dylib not matching the
-  // clang version won't work anyways.
-  if (Version[0] >= 133) {
-    // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
-    StringRef P = llvm::sys::path::parent_path(D.Dir);
-    SmallString<128> LibLTOPath(P);
-    llvm::sys::path::append(LibLTOPath, "lib");
-    llvm::sys::path::append(LibLTOPath, "libLTO.dylib");
-    CmdArgs.push_back("-lto_library");
-    CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));
-  }
-
-  // ld64 version 262 and above run the deduplicate pass by default.
-  if (Version[0] >= 262 && shouldLinkerNotDedup(C.getJobs().empty(), Args))
-    CmdArgs.push_back("-no_deduplicate");
-
-  // Derived from the "link" spec.
-  Args.AddAllArgs(CmdArgs, options::OPT_static);
-  if (!Args.hasArg(options::OPT_static))
-    CmdArgs.push_back("-dynamic");
-  if (Args.hasArg(options::OPT_fgnu_runtime)) {
-    // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
-    // here. How do we wish to handle such things?
-  }
-
-  if (!Args.hasArg(options::OPT_dynamiclib)) {
-    AddMachOArch(Args, CmdArgs);
-    // FIXME: Why do this only on this path?
-    Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
-
-    Args.AddLastArg(CmdArgs, options::OPT_bundle);
-    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
-    Args.AddAllArgs(CmdArgs, options::OPT_client__name);
-
-    Arg *A;
-    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
-        (A = Args.getLastArg(options::OPT_current__version)) ||
-        (A = Args.getLastArg(options::OPT_install__name)))
-      D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
-                                                       << "-dynamiclib";
-
-    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
-    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
-    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
-  } else {
-    CmdArgs.push_back("-dylib");
-
-    Arg *A;
-    if ((A = Args.getLastArg(options::OPT_bundle)) ||
-        (A = Args.getLastArg(options::OPT_bundle__loader)) ||
-        (A = Args.getLastArg(options::OPT_client__name)) ||
-        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
-        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
-        (A = Args.getLastArg(options::OPT_private__bundle)))
-      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
-                                                      << "-dynamiclib";
-
-    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
-                              "-dylib_compatibility_version");
-    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
-                              "-dylib_current_version");
-
-    AddMachOArch(Args, CmdArgs);
-
-    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
-                              "-dylib_install_name");
-  }
-
-  Args.AddLastArg(CmdArgs, options::OPT_all__load);
-  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
-  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
-  if (MachOTC.isTargetIOSBased())
-    Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
-  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
-  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
-  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
-  Args.AddLastArg(CmdArgs, options::OPT_dynamic);
-  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
-  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
-  Args.AddAllArgs(CmdArgs, options::OPT_force__load);
-  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
-  Args.AddAllArgs(CmdArgs, options::OPT_image__base);
-  Args.AddAllArgs(CmdArgs, options::OPT_init);
-
-  // Add the deployment target.
-  MachOTC.addMinVersionArgs(Args, CmdArgs);
-
-  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
-  Args.AddLastArg(CmdArgs, options::OPT_multi__module);
-  Args.AddLastArg(CmdArgs, options::OPT_single__module);
-  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
-  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
-
-  if (const Arg *A =
-          Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
-                          options::OPT_fno_pie, options::OPT_fno_PIE)) {
-    if (A->getOption().matches(options::OPT_fpie) ||
-        A->getOption().matches(options::OPT_fPIE))
-      CmdArgs.push_back("-pie");
-    else
-      CmdArgs.push_back("-no_pie");
-  }
-
-  // for embed-bitcode, use -bitcode_bundle in linker command
-  if (C.getDriver().embedBitcodeEnabled()) {
-    // Check if the toolchain supports bitcode build flow.
-    if (MachOTC.SupportsEmbeddedBitcode())
-      CmdArgs.push_back("-bitcode_bundle");
-    else
-      D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
-  }
-
-  Args.AddLastArg(CmdArgs, options::OPT_prebind);
-  Args.AddLastArg(CmdArgs, options::OPT_noprebind);
-  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
-  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
-  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
-  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
-  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
-  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
-  Args.AddAllArgs(CmdArgs, options::OPT_segprot);
-  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
-  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
-  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
-  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
-  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
-  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
-  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
-
-  // Give --sysroot= preference, over the Apple specific behavior to also use
-  // --isysroot as the syslibroot.
-  StringRef sysroot = C.getSysRoot();
-  if (sysroot != "") {
-    CmdArgs.push_back("-syslibroot");
-    CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
-  } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
-    CmdArgs.push_back("-syslibroot");
-    CmdArgs.push_back(A->getValue());
-  }
-
-  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
-  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
-  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
-  Args.AddAllArgs(CmdArgs, options::OPT_undefined);
-  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
-  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
-  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
-  Args.AddAllArgs(CmdArgs, options::OPT_y);
-  Args.AddLastArg(CmdArgs, options::OPT_w);
-  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
-  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
-  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
-  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
-  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
-  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
-  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
-  Args.AddLastArg(CmdArgs, options::OPT_whyload);
-  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
-  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
-  Args.AddLastArg(CmdArgs, options::OPT_dylinker);
-  Args.AddLastArg(CmdArgs, options::OPT_Mach);
-}
-
-void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                  const InputInfo &Output,
-                                  const InputInfoList &Inputs,
-                                  const ArgList &Args,
-                                  const char *LinkingOutput) const {
-  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
-
-  // If the number of arguments surpasses the system limits, we will encode the
-  // input files in a separate file, shortening the command line. To this end,
-  // build a list of input file names that can be passed via a file with the
-  // -filelist linker option.
-  llvm::opt::ArgStringList InputFileList;
-
-  // The logic here is derived from gcc's behavior; most of which
-  // comes from specs (starting with link_command). Consult gcc for
-  // more information.
-  ArgStringList CmdArgs;
-
-  /// 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 (const auto &Arg : Args)
-      Arg->claim();
-    const char *Exec =
-        Args.MakeArgString(getToolChain().GetProgramPath("touch"));
-    CmdArgs.push_back(Output.getFilename());
-    C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, None));
-    return;
-  }
-
-  // I'm not sure why this particular decomposition exists in gcc, but
-  // we follow suite for ease of comparison.
-  AddLinkArgs(C, Args, CmdArgs, Inputs);
-
-  // For LTO, pass the name of the optimization record file.
-  if (Args.hasFlag(options::OPT_fsave_optimization_record,
-                   options::OPT_fno_save_optimization_record, false)) {
-    CmdArgs.push_back("-mllvm");
-    CmdArgs.push_back("-lto-pass-remarks-output");
-    CmdArgs.push_back("-mllvm");
-
-    SmallString<128> F;
-    F = Output.getFilename();
-    F += ".opt.yaml";
-    CmdArgs.push_back(Args.MakeArgString(F));
-
-    if (getLastProfileUseArg(Args)) {
-      CmdArgs.push_back("-mllvm");
-      CmdArgs.push_back("-lto-pass-remarks-with-hotness");
-    }
-  }
-
-  // It seems that the 'e' option is completely ignored for dynamic executables
-  // (the default), and with static executables, the last one wins, as expected.
-  Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t,
-                            options::OPT_Z_Flag, options::OPT_u_Group,
-                            options::OPT_e, options::OPT_r});
-
-  // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
-  // members of static archive libraries which implement Objective-C classes or
-  // categories.
-  if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
-    CmdArgs.push_back("-ObjC");
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
-    getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs);
-
-  // SafeStack requires its own runtime libraries
-  // These libraries should be linked first, to make sure the
-  // __safestack_init constructor executes before everything else
-  if (getToolChain().getSanitizerArgs().needsSafeStackRt()) {
-    getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs,
-                                          "libclang_rt.safestack_osx.a",
-                                          /*AlwaysLink=*/true);
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-  // Build the input file for -filelist (list of linker input files) in case we
-  // need it later
-  for (const auto &II : Inputs) {
-    if (!II.isFilename()) {
-      // This is a linker input argument.
-      // We cannot mix input arguments and file names in a -filelist input, thus
-      // we prematurely stop our list (remaining files shall be passed as
-      // arguments).
-      if (InputFileList.size() > 0)
-        break;
-
-      continue;
-    }
-
-    InputFileList.push_back(II.getFilename());
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
-    addOpenMPRuntime(CmdArgs, getToolChain(), Args);
-
-  if (isObjCRuntimeLinked(Args) &&
-      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    // We use arclite library for both ARC and subscripting support.
-    getMachOToolChain().AddLinkARCArgs(Args, CmdArgs);
-
-    CmdArgs.push_back("-framework");
-    CmdArgs.push_back("Foundation");
-    // Link libobj.
-    CmdArgs.push_back("-lobjc");
-  }
-
-  if (LinkingOutput) {
-    CmdArgs.push_back("-arch_multiple");
-    CmdArgs.push_back("-final_output");
-    CmdArgs.push_back(LinkingOutput);
-  }
-
-  if (Args.hasArg(options::OPT_fnested_functions))
-    CmdArgs.push_back("-allow_stack_execute");
-
-  getMachOToolChain().addProfileRTLibs(Args, CmdArgs);
-
-  if (unsigned Parallelism =
-          getLTOParallelism(Args, getToolChain().getDriver())) {
-    CmdArgs.push_back("-mllvm");
-    CmdArgs.push_back(
-        Args.MakeArgString(Twine("-threads=") + llvm::to_string(Parallelism)));
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (getToolChain().getDriver().CCCIsCXX())
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-
-    // link_ssp spec is empty.
-
-    // Let the tool chain choose which runtime library to link.
-    getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    // endfile_spec is empty.
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
-  Args.AddAllArgs(CmdArgs, options::OPT_F);
-
-  // -iframework should be forwarded as -F.
-  for (const Arg *A : Args.filtered(options::OPT_iframework))
-    CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue()));
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (Arg *A = Args.getLastArg(options::OPT_fveclib)) {
-      if (A->getValue() == StringRef("Accelerate")) {
-        CmdArgs.push_back("-framework");
-        CmdArgs.push_back("Accelerate");
-      }
-    }
-  }
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
-  std::unique_ptr<Command> Cmd =
-      llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs);
-  Cmd->setInputFileList(std::move(InputFileList));
-  C.addCommand(std::move(Cmd));
-}
-
-void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
-                                const InputInfo &Output,
-                                const InputInfoList &Inputs,
-                                const ArgList &Args,
-                                const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-
-  CmdArgs.push_back("-create");
-  assert(Output.isFilename() && "Unexpected lipo output.");
-
-  CmdArgs.push_back("-output");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs) {
-    assert(II.isFilename() && "Unexpected lipo input.");
-    CmdArgs.push_back(II.getFilename());
-  }
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
-                                    const InputInfo &Output,
-                                    const InputInfoList &Inputs,
-                                    const ArgList &Args,
-                                    const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
-  const InputInfo &Input = Inputs[0];
-  assert(Input.isFilename() && "Unexpected dsymutil input.");
-  CmdArgs.push_back(Input.getFilename());
-
-  const char *Exec =
-      Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
-                                       const InputInfo &Output,
-                                       const InputInfoList &Inputs,
-                                       const ArgList &Args,
-                                       const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-  CmdArgs.push_back("--verify");
-  CmdArgs.push_back("--debug-info");
-  CmdArgs.push_back("--eh-frame");
-  CmdArgs.push_back("--quiet");
-
-  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
-  const InputInfo &Input = Inputs[0];
-  assert(Input.isFilename() && "Unexpected verify input");
-
-  // Grabbing the output of the earlier dsymutil run.
-  CmdArgs.push_back(Input.getFilename());
-
-  const char *Exec =
-      Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                      const InputInfo &Output,
-                                      const InputInfoList &Inputs,
-                                      const ArgList &Args,
-                                      const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                   const InputInfo &Output,
-                                   const InputInfoList &Inputs,
-                                   const ArgList &Args,
-                                   const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-
-  // Demangle C++ names in errors
-  CmdArgs.push_back("-C");
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
-    CmdArgs.push_back("-e");
-    CmdArgs.push_back("_start");
-  }
-
-  if (Args.hasArg(options::OPT_static)) {
-    CmdArgs.push_back("-Bstatic");
-    CmdArgs.push_back("-dn");
-  } else {
-    CmdArgs.push_back("-Bdynamic");
-    if (Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-shared");
-    } else {
-      CmdArgs.push_back("--dynamic-linker");
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("ld.so.1")));
-    }
-  }
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!Args.hasArg(options::OPT_shared))
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
-
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
-    CmdArgs.push_back(
-        Args.MakeArgString(getToolChain().GetFilePath("values-Xa.o")));
-    CmdArgs.push_back(
-        Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
-  }
-
-  getToolChain().AddFilePathLibArgs(Args, CmdArgs);
-
-  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
-                            options::OPT_e, options::OPT_r});
-
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (getToolChain().getDriver().CCCIsCXX())
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-    CmdArgs.push_back("-lgcc_s");
-    CmdArgs.push_back("-lc");
-    if (!Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-lgcc");
-      CmdArgs.push_back("-lm");
-    }
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    CmdArgs.push_back(
-        Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
-  }
-  CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
-
-  getToolChain().addProfileRTLibs(Args, CmdArgs);
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                      const InputInfo &Output,
-                                      const InputInfoList &Inputs,
-                                      const ArgList &Args,
-                                      const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  switch (getToolChain().getArch()) {
-  case llvm::Triple::x86:
-    // When building 32-bit code on OpenBSD/amd64, we have to explicitly
-    // instruct as in the base system to assemble 32-bit code.
-    CmdArgs.push_back("--32");
-    break;
-
-  case llvm::Triple::ppc:
-    CmdArgs.push_back("-mppc");
-    CmdArgs.push_back("-many");
-    break;
-
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel: {
-    CmdArgs.push_back("-32");
-    std::string CPU = getCPUName(Args, getToolChain().getTriple());
-    CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-
-  case llvm::Triple::sparcv9: {
-    CmdArgs.push_back("-64");
-    std::string CPU = getCPUName(Args, getToolChain().getTriple());
-    CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el: {
-    StringRef CPUName;
-    StringRef ABIName;
-    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
-
-    CmdArgs.push_back("-mabi");
-    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
-
-    if (getToolChain().getArch() == llvm::Triple::mips64)
-      CmdArgs.push_back("-EB");
-    else
-      CmdArgs.push_back("-EL");
-
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-
-  default:
-    break;
-  }
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                   const InputInfo &Output,
-                                   const InputInfoList &Inputs,
-                                   const ArgList &Args,
-                                   const char *LinkingOutput) const {
-  const Driver &D = getToolChain().getDriver();
-  ArgStringList CmdArgs;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo". Other warning options are already
-  // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_w);
-
-  if (getToolChain().getArch() == llvm::Triple::mips64)
-    CmdArgs.push_back("-EB");
-  else if (getToolChain().getArch() == llvm::Triple::mips64el)
-    CmdArgs.push_back("-EL");
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
-    CmdArgs.push_back("-e");
-    CmdArgs.push_back("__start");
-  }
-
-  if (Args.hasArg(options::OPT_static)) {
-    CmdArgs.push_back("-Bstatic");
-  } else {
-    if (Args.hasArg(options::OPT_rdynamic))
-      CmdArgs.push_back("-export-dynamic");
-    CmdArgs.push_back("--eh-frame-hdr");
-    CmdArgs.push_back("-Bdynamic");
-    if (Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-shared");
-    } else {
-      CmdArgs.push_back("-dynamic-linker");
-      CmdArgs.push_back("/usr/libexec/ld.so");
-    }
-  }
-
-  if (Args.hasArg(options::OPT_nopie))
-    CmdArgs.push_back("-nopie");
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!Args.hasArg(options::OPT_shared)) {
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back(
-            Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
-      else
-        CmdArgs.push_back(
-            Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
-    } else {
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
-    }
-  }
-
-  std::string Triple = getToolChain().getTripleString();
-  if (Triple.substr(0, 6) == "x86_64")
-    Triple.replace(0, 6, "amd64");
-  CmdArgs.push_back(
-      Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + "/4.2.1"));
-
-  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
-                            options::OPT_e, options::OPT_s, options::OPT_t,
-                            options::OPT_Z_Flag, options::OPT_r});
-
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lm_p");
-      else
-        CmdArgs.push_back("-lm");
-    }
-
-    // FIXME: For some reason GCC passes -lgcc before adding
-    // the default system libraries. Just mimic this for now.
-    CmdArgs.push_back("-lgcc");
-
-    if (Args.hasArg(options::OPT_pthread)) {
-      if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lpthread_p");
-      else
-        CmdArgs.push_back("-lpthread");
-    }
-
-    if (!Args.hasArg(options::OPT_shared)) {
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lc_p");
-      else
-        CmdArgs.push_back("-lc");
-    }
-
-    CmdArgs.push_back("-lgcc");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!Args.hasArg(options::OPT_shared))
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
-    else
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
-  }
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void bitrig::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                     const InputInfo &Output,
-                                     const InputInfoList &Inputs,
-                                     const ArgList &Args,
-                                     const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void bitrig::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                  const InputInfo &Output,
-                                  const InputInfoList &Inputs,
-                                  const ArgList &Args,
-                                  const char *LinkingOutput) const {
-  const Driver &D = getToolChain().getDriver();
-  ArgStringList CmdArgs;
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
-    CmdArgs.push_back("-e");
-    CmdArgs.push_back("__start");
-  }
-
-  if (Args.hasArg(options::OPT_static)) {
-    CmdArgs.push_back("-Bstatic");
-  } else {
-    if (Args.hasArg(options::OPT_rdynamic))
-      CmdArgs.push_back("-export-dynamic");
-    CmdArgs.push_back("--eh-frame-hdr");
-    CmdArgs.push_back("-Bdynamic");
-    if (Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-shared");
-    } else {
-      CmdArgs.push_back("-dynamic-linker");
-      CmdArgs.push_back("/usr/libexec/ld.so");
-    }
-  }
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!Args.hasArg(options::OPT_shared)) {
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back(
-            Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
-      else
-        CmdArgs.push_back(
-            Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
-    } else {
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
-    }
-  }
-
-  Args.AddAllArgs(CmdArgs,
-                  {options::OPT_L, options::OPT_T_Group, options::OPT_e});
-
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lm_p");
-      else
-        CmdArgs.push_back("-lm");
-    }
-
-    if (Args.hasArg(options::OPT_pthread)) {
-      if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lpthread_p");
-      else
-        CmdArgs.push_back("-lpthread");
-    }
-
-    if (!Args.hasArg(options::OPT_shared)) {
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lc_p");
-      else
-        CmdArgs.push_back("-lc");
-    }
-
-    StringRef MyArch;
-    switch (getToolChain().getArch()) {
-    case llvm::Triple::arm:
-      MyArch = "arm";
-      break;
-    case llvm::Triple::x86:
-      MyArch = "i386";
-      break;
-    case llvm::Triple::x86_64:
-      MyArch = "amd64";
-      break;
-    default:
-      llvm_unreachable("Unsupported architecture");
-    }
-    CmdArgs.push_back(Args.MakeArgString("-lclang_rt." + MyArch));
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!Args.hasArg(options::OPT_shared))
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
-    else
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
-  }
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                      const InputInfo &Output,
-                                      const InputInfoList &Inputs,
-                                      const ArgList &Args,
-                                      const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
-  // instruct as in the base system to assemble 32-bit code.
-  switch (getToolChain().getArch()) {
-  default:
-    break;
-  case llvm::Triple::x86:
-    CmdArgs.push_back("--32");
-    break;
-  case llvm::Triple::ppc:
-    CmdArgs.push_back("-a32");
-    break;
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el: {
-    StringRef CPUName;
-    StringRef ABIName;
-    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
-
-    CmdArgs.push_back("-march");
-    CmdArgs.push_back(CPUName.data());
-
-    CmdArgs.push_back("-mabi");
-    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
-
-    if (getToolChain().getArch() == llvm::Triple::mips ||
-        getToolChain().getArch() == llvm::Triple::mips64)
-      CmdArgs.push_back("-EB");
-    else
-      CmdArgs.push_back("-EL");
-
-    if (Arg *A = Args.getLastArg(options::OPT_G)) {
-      StringRef v = A->getValue();
-      CmdArgs.push_back(Args.MakeArgString("-G" + v));
-      A->claim();
-    }
-
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb: {
-    arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
-
-    if (ABI == arm::FloatABI::Hard)
-      CmdArgs.push_back("-mfpu=vfp");
-    else
-      CmdArgs.push_back("-mfpu=softvfp");
-
-    switch (getToolChain().getTriple().getEnvironment()) {
-    case llvm::Triple::GNUEABIHF:
-    case llvm::Triple::GNUEABI:
-    case llvm::Triple::EABI:
-      CmdArgs.push_back("-meabi=5");
-      break;
-
-    default:
-      CmdArgs.push_back("-matpcs");
-    }
-    break;
-  }
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel:
-  case llvm::Triple::sparcv9: {
-    std::string CPU = getCPUName(Args, getToolChain().getTriple());
-    CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-  }
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                   const InputInfo &Output,
-                                   const InputInfoList &Inputs,
-                                   const ArgList &Args,
-                                   const char *LinkingOutput) const {
-  const toolchains::FreeBSD &ToolChain =
-      static_cast<const toolchains::FreeBSD &>(getToolChain());
-  const Driver &D = ToolChain.getDriver();
-  const llvm::Triple::ArchType Arch = ToolChain.getArch();
-  const bool IsPIE =
-      !Args.hasArg(options::OPT_shared) &&
-      (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault());
-  ArgStringList CmdArgs;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo". Other warning options are already
-  // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_w);
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  if (IsPIE)
-    CmdArgs.push_back("-pie");
-
-  CmdArgs.push_back("--eh-frame-hdr");
-  if (Args.hasArg(options::OPT_static)) {
-    CmdArgs.push_back("-Bstatic");
-  } else {
-    if (Args.hasArg(options::OPT_rdynamic))
-      CmdArgs.push_back("-export-dynamic");
-    if (Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-Bshareable");
-    } else {
-      CmdArgs.push_back("-dynamic-linker");
-      CmdArgs.push_back("/libexec/ld-elf.so.1");
-    }
-    if (ToolChain.getTriple().getOSMajorVersion() >= 9) {
-      if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
-          Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
-        CmdArgs.push_back("--hash-style=both");
-      }
-    }
-    CmdArgs.push_back("--enable-new-dtags");
-  }
-
-  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
-  // instruct ld in the base system to link 32-bit code.
-  if (Arch == llvm::Triple::x86) {
-    CmdArgs.push_back("-m");
-    CmdArgs.push_back("elf_i386_fbsd");
-  }
-
-  if (Arch == llvm::Triple::ppc) {
-    CmdArgs.push_back("-m");
-    CmdArgs.push_back("elf32ppc_fbsd");
-  }
-
-  if (Arg *A = Args.getLastArg(options::OPT_G)) {
-    if (ToolChain.getArch() == llvm::Triple::mips ||
-      ToolChain.getArch() == llvm::Triple::mipsel ||
-      ToolChain.getArch() == llvm::Triple::mips64 ||
-      ToolChain.getArch() == llvm::Triple::mips64el) {
-      StringRef v = A->getValue();
-      CmdArgs.push_back(Args.MakeArgString("-G" + v));
-      A->claim();
-    }
-  }
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    const char *crt1 = nullptr;
-    if (!Args.hasArg(options::OPT_shared)) {
-      if (Args.hasArg(options::OPT_pg))
-        crt1 = "gcrt1.o";
-      else if (IsPIE)
-        crt1 = "Scrt1.o";
-      else
-        crt1 = "crt1.o";
-    }
-    if (crt1)
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
-
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
-
-    const char *crtbegin = nullptr;
-    if (Args.hasArg(options::OPT_static))
-      crtbegin = "crtbeginT.o";
-    else if (Args.hasArg(options::OPT_shared) || IsPIE)
-      crtbegin = "crtbeginS.o";
-    else
-      crtbegin = "crtbegin.o";
-
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
-  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
-  Args.AddAllArgs(CmdArgs, options::OPT_e);
-  Args.AddAllArgs(CmdArgs, options::OPT_s);
-  Args.AddAllArgs(CmdArgs, options::OPT_t);
-  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
-  Args.AddAllArgs(CmdArgs, options::OPT_r);
-
-  if (D.isUsingLTO())
-    AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin, D);
-
-  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    addOpenMPRuntime(CmdArgs, ToolChain, Args);
-    if (D.CCCIsCXX()) {
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lm_p");
-      else
-        CmdArgs.push_back("-lm");
-    }
-    if (NeedsSanitizerDeps)
-      linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
-    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
-    // the default system libraries. Just mimic this for now.
-    if (Args.hasArg(options::OPT_pg))
-      CmdArgs.push_back("-lgcc_p");
-    else
-      CmdArgs.push_back("-lgcc");
-    if (Args.hasArg(options::OPT_static)) {
-      CmdArgs.push_back("-lgcc_eh");
-    } else if (Args.hasArg(options::OPT_pg)) {
-      CmdArgs.push_back("-lgcc_eh_p");
-    } else {
-      CmdArgs.push_back("--as-needed");
-      CmdArgs.push_back("-lgcc_s");
-      CmdArgs.push_back("--no-as-needed");
-    }
-
-    if (Args.hasArg(options::OPT_pthread)) {
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lpthread_p");
-      else
-        CmdArgs.push_back("-lpthread");
-    }
-
-    if (Args.hasArg(options::OPT_pg)) {
-      if (Args.hasArg(options::OPT_shared))
-        CmdArgs.push_back("-lc");
-      else
-        CmdArgs.push_back("-lc_p");
-      CmdArgs.push_back("-lgcc_p");
-    } else {
-      CmdArgs.push_back("-lc");
-      CmdArgs.push_back("-lgcc");
-    }
-
-    if (Args.hasArg(options::OPT_static)) {
-      CmdArgs.push_back("-lgcc_eh");
-    } else if (Args.hasArg(options::OPT_pg)) {
-      CmdArgs.push_back("-lgcc_eh_p");
-    } else {
-      CmdArgs.push_back("--as-needed");
-      CmdArgs.push_back("-lgcc_s");
-      CmdArgs.push_back("--no-as-needed");
-    }
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (Args.hasArg(options::OPT_shared) || IsPIE)
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
-    else
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
-  }
-
-  ToolChain.addProfileRTLibs(Args, CmdArgs);
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                     const InputInfo &Output,
-                                     const InputInfoList &Inputs,
-                                     const ArgList &Args,
-                                     const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  // GNU as needs different flags for creating the correct output format
-  // on architectures with different ABIs or optional feature sets.
-  switch (getToolChain().getArch()) {
-  case llvm::Triple::x86:
-    CmdArgs.push_back("--32");
-    break;
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb: {
-    StringRef MArch, MCPU;
-    getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true);
-    std::string Arch =
-        arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
-    CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
-    break;
-  }
-
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el: {
-    StringRef CPUName;
-    StringRef ABIName;
-    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
-
-    CmdArgs.push_back("-march");
-    CmdArgs.push_back(CPUName.data());
-
-    CmdArgs.push_back("-mabi");
-    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
-
-    if (getToolChain().getArch() == llvm::Triple::mips ||
-        getToolChain().getArch() == llvm::Triple::mips64)
-      CmdArgs.push_back("-EB");
-    else
-      CmdArgs.push_back("-EL");
-
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel: {
-    CmdArgs.push_back("-32");
-    std::string CPU = getCPUName(Args, getToolChain().getTriple());
-    CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-
-  case llvm::Triple::sparcv9: {
-    CmdArgs.push_back("-64");
-    std::string CPU = getCPUName(Args, getToolChain().getTriple());
-    CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-
-  default:
-    break;
-  }
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                  const InputInfo &Output,
-                                  const InputInfoList &Inputs,
-                                  const ArgList &Args,
-                                  const char *LinkingOutput) const {
-  const Driver &D = getToolChain().getDriver();
-  ArgStringList CmdArgs;
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  CmdArgs.push_back("--eh-frame-hdr");
-  if (Args.hasArg(options::OPT_static)) {
-    CmdArgs.push_back("-Bstatic");
-  } else {
-    if (Args.hasArg(options::OPT_rdynamic))
-      CmdArgs.push_back("-export-dynamic");
-    if (Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-Bshareable");
-    } else {
-      Args.AddAllArgs(CmdArgs, options::OPT_pie);
-      CmdArgs.push_back("-dynamic-linker");
-      CmdArgs.push_back("/libexec/ld.elf_so");
-    }
-  }
-
-  // Many NetBSD architectures support more than one ABI.
-  // Determine the correct emulation for ld.
-  switch (getToolChain().getArch()) {
-  case llvm::Triple::x86:
-    CmdArgs.push_back("-m");
-    CmdArgs.push_back("elf_i386");
-    break;
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-    CmdArgs.push_back("-m");
-    switch (getToolChain().getTriple().getEnvironment()) {
-    case llvm::Triple::EABI:
-    case llvm::Triple::GNUEABI:
-      CmdArgs.push_back("armelf_nbsd_eabi");
-      break;
-    case llvm::Triple::EABIHF:
-    case llvm::Triple::GNUEABIHF:
-      CmdArgs.push_back("armelf_nbsd_eabihf");
-      break;
-    default:
-      CmdArgs.push_back("armelf_nbsd");
-      break;
-    }
-    break;
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumbeb:
-    arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getEffectiveTriple());
-    CmdArgs.push_back("-m");
-    switch (getToolChain().getTriple().getEnvironment()) {
-    case llvm::Triple::EABI:
-    case llvm::Triple::GNUEABI:
-      CmdArgs.push_back("armelfb_nbsd_eabi");
-      break;
-    case llvm::Triple::EABIHF:
-    case llvm::Triple::GNUEABIHF:
-      CmdArgs.push_back("armelfb_nbsd_eabihf");
-      break;
-    default:
-      CmdArgs.push_back("armelfb_nbsd");
-      break;
-    }
-    break;
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el:
-    if (mips::hasMipsAbiArg(Args, "32")) {
-      CmdArgs.push_back("-m");
-      if (getToolChain().getArch() == llvm::Triple::mips64)
-        CmdArgs.push_back("elf32btsmip");
-      else
-        CmdArgs.push_back("elf32ltsmip");
-    } else if (mips::hasMipsAbiArg(Args, "64")) {
-      CmdArgs.push_back("-m");
-      if (getToolChain().getArch() == llvm::Triple::mips64)
-        CmdArgs.push_back("elf64btsmip");
-      else
-        CmdArgs.push_back("elf64ltsmip");
-    }
-    break;
-  case llvm::Triple::ppc:
-    CmdArgs.push_back("-m");
-    CmdArgs.push_back("elf32ppc_nbsd");
-    break;
-
-  case llvm::Triple::ppc64:
-  case llvm::Triple::ppc64le:
-    CmdArgs.push_back("-m");
-    CmdArgs.push_back("elf64ppc");
-    break;
-
-  case llvm::Triple::sparc:
-    CmdArgs.push_back("-m");
-    CmdArgs.push_back("elf32_sparc");
-    break;
-
-  case llvm::Triple::sparcv9:
-    CmdArgs.push_back("-m");
-    CmdArgs.push_back("elf64_sparc");
-    break;
-
-  default:
-    break;
-  }
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
-    }
-    CmdArgs.push_back(
-        Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
-    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) {
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
-    } else {
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
-    }
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
-  Args.AddAllArgs(CmdArgs, options::OPT_e);
-  Args.AddAllArgs(CmdArgs, options::OPT_s);
-  Args.AddAllArgs(CmdArgs, options::OPT_t);
-  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
-  Args.AddAllArgs(CmdArgs, options::OPT_r);
-
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-
-  unsigned Major, Minor, Micro;
-  getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
-  bool useLibgcc = true;
-  if (Major >= 7 || Major == 0) {
-    switch (getToolChain().getArch()) {
-    case llvm::Triple::aarch64:
-    case llvm::Triple::arm:
-    case llvm::Triple::armeb:
-    case llvm::Triple::thumb:
-    case llvm::Triple::thumbeb:
-    case llvm::Triple::ppc:
-    case llvm::Triple::ppc64:
-    case llvm::Triple::ppc64le:
-    case llvm::Triple::sparc:
-    case llvm::Triple::sparcv9:
-    case llvm::Triple::x86:
-    case llvm::Triple::x86_64:
-      useLibgcc = false;
-      break;
-    default:
-      break;
-    }
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    addOpenMPRuntime(CmdArgs, getToolChain(), Args);
-    if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-      CmdArgs.push_back("-lm");
-    }
-    if (Args.hasArg(options::OPT_pthread))
-      CmdArgs.push_back("-lpthread");
-    CmdArgs.push_back("-lc");
-
-    if (useLibgcc) {
-      if (Args.hasArg(options::OPT_static)) {
-        // libgcc_eh depends on libc, so resolve as much as possible,
-        // pull in any new requirements from libc and then get the rest
-        // of libgcc.
-        CmdArgs.push_back("-lgcc_eh");
-        CmdArgs.push_back("-lc");
-        CmdArgs.push_back("-lgcc");
-      } else {
-        CmdArgs.push_back("-lgcc");
-        CmdArgs.push_back("--as-needed");
-        CmdArgs.push_back("-lgcc_s");
-        CmdArgs.push_back("--no-as-needed");
-      }
-    }
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
-    else
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
-  }
-
-  getToolChain().addProfileRTLibs(Args, CmdArgs);
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                       const InputInfo &Output,
-                                       const InputInfoList &Inputs,
-                                       const ArgList &Args,
-                                       const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-
-  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
-
-  ArgStringList CmdArgs;
-
-  llvm::Reloc::Model RelocationModel;
-  unsigned PICLevel;
-  bool IsPIE;
-  std::tie(RelocationModel, PICLevel, IsPIE) =
-      ParsePICArgs(getToolChain(), Triple, Args);
-
-  switch (getToolChain().getArch()) {
-  default:
-    break;
-  // Add --32/--64 to make sure we get the format we want.
-  // This is incomplete
-  case llvm::Triple::x86:
-    CmdArgs.push_back("--32");
-    break;
-  case llvm::Triple::x86_64:
-    if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32)
-      CmdArgs.push_back("--x32");
-    else
-      CmdArgs.push_back("--64");
-    break;
-  case llvm::Triple::ppc:
-    CmdArgs.push_back("-a32");
-    CmdArgs.push_back("-mppc");
-    CmdArgs.push_back("-many");
-    break;
-  case llvm::Triple::ppc64:
-    CmdArgs.push_back("-a64");
-    CmdArgs.push_back("-mppc64");
-    CmdArgs.push_back("-many");
-    break;
-  case llvm::Triple::ppc64le:
-    CmdArgs.push_back("-a64");
-    CmdArgs.push_back("-mppc64");
-    CmdArgs.push_back("-many");
-    CmdArgs.push_back("-mlittle-endian");
-    break;
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel: {
-    CmdArgs.push_back("-32");
-    std::string CPU = getCPUName(Args, getToolChain().getTriple());
-    CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-  case llvm::Triple::sparcv9: {
-    CmdArgs.push_back("-64");
-    std::string CPU = getCPUName(Args, getToolChain().getTriple());
-    CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-  case llvm::Triple::arm:
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb: {
-    const llvm::Triple &Triple2 = getToolChain().getTriple();
-    switch (Triple2.getSubArch()) {
-    case llvm::Triple::ARMSubArch_v7:
-      CmdArgs.push_back("-mfpu=neon");
-      break;
-    case llvm::Triple::ARMSubArch_v8:
-      CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");
-      break;
-    default:
-      break;
-    }
-
-    switch (arm::getARMFloatABI(getToolChain(), Args)) {
-    case arm::FloatABI::Invalid: llvm_unreachable("must have an ABI!");
-    case arm::FloatABI::Soft:
-      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft"));
-      break;
-    case arm::FloatABI::SoftFP:
-      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp"));
-      break;
-    case arm::FloatABI::Hard:
-      CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard"));
-      break;
-    }
-
-    Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
-
-    // FIXME: remove krait check when GNU tools support krait cpu
-    // for now replace it with -mcpu=cortex-a15 to avoid a lower
-    // march from being picked in the absence of a cpu flag.
-    Arg *A;
-    if ((A = Args.getLastArg(options::OPT_mcpu_EQ)) &&
-        StringRef(A->getValue()).equals_lower("krait"))
-      CmdArgs.push_back("-mcpu=cortex-a15");
-    else
-      Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
-    Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
-    break;
-  }
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el: {
-    StringRef CPUName;
-    StringRef ABIName;
-    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
-    ABIName = getGnuCompatibleMipsABIName(ABIName);
-
-    CmdArgs.push_back("-march");
-    CmdArgs.push_back(CPUName.data());
-
-    CmdArgs.push_back("-mabi");
-    CmdArgs.push_back(ABIName.data());
-
-    // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE,
-    // or -mshared (not implemented) is in effect.
-    if (RelocationModel == llvm::Reloc::Static)
-      CmdArgs.push_back("-mno-shared");
-
-    // LLVM doesn't support -mplt yet and acts as if it is always given.
-    // However, -mplt has no effect with the N64 ABI.
-    CmdArgs.push_back(ABIName == "64" ? "-KPIC" : "-call_nonpic");
-
-    if (getToolChain().getArch() == llvm::Triple::mips ||
-        getToolChain().getArch() == llvm::Triple::mips64)
-      CmdArgs.push_back("-EB");
-    else
-      CmdArgs.push_back("-EL");
-
-    if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
-      if (StringRef(A->getValue()) == "2008")
-        CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
-    }
-
-    // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default.
-    if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
-                                 options::OPT_mfp64)) {
-      A->claim();
-      A->render(Args, CmdArgs);
-    } else if (mips::shouldUseFPXX(
-                   Args, getToolChain().getTriple(), CPUName, ABIName,
-                   getMipsFloatABI(getToolChain().getDriver(), Args)))
-      CmdArgs.push_back("-mfpxx");
-
-    // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of
-    // -mno-mips16 is actually -no-mips16.
-    if (Arg *A =
-            Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) {
-      if (A->getOption().matches(options::OPT_mips16)) {
-        A->claim();
-        A->render(Args, CmdArgs);
-      } else {
-        A->claim();
-        CmdArgs.push_back("-no-mips16");
-      }
-    }
-
-    Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
-                    options::OPT_mno_micromips);
-    Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
-    Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);
-
-    if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {
-      // Do not use AddLastArg because not all versions of MIPS assembler
-      // support -mmsa / -mno-msa options.
-      if (A->getOption().matches(options::OPT_mmsa))
-        CmdArgs.push_back(Args.MakeArgString("-mmsa"));
-    }
-
-    Args.AddLastArg(CmdArgs, options::OPT_mhard_float,
-                    options::OPT_msoft_float);
-
-    Args.AddLastArg(CmdArgs, options::OPT_mdouble_float,
-                    options::OPT_msingle_float);
-
-    Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,
-                    options::OPT_mno_odd_spreg);
-
-    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
-    break;
-  }
-  case llvm::Triple::systemz: {
-    // Always pass an -march option, since our default of z10 is later
-    // than the GNU assembler's default.
-    StringRef CPUName = getSystemZTargetCPU(Args);
-    CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
-    break;
-  }
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_I);
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-
-  // Handle the debug info splitting at object creation time if we're
-  // creating an object.
-  // TODO: Currently only works on linux with newer objcopy.
-  if (Args.hasArg(options::OPT_gsplit_dwarf) &&
-      getToolChain().getTriple().isOSLinux())
-    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
-                   SplitDebugName(Args, Inputs[0]));
-}
-
-static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
-                      ArgStringList &CmdArgs, const ArgList &Args) {
-  bool isAndroid = Triple.isAndroid();
-  bool isCygMing = Triple.isOSCygMing();
-  bool IsIAMCU = Triple.isOSIAMCU();
-  bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
-                      Args.hasArg(options::OPT_static);
-  if (!D.CCCIsCXX())
-    CmdArgs.push_back("-lgcc");
-
-  if (StaticLibgcc || isAndroid) {
-    if (D.CCCIsCXX())
-      CmdArgs.push_back("-lgcc");
-  } else {
-    if (!D.CCCIsCXX() && !isCygMing)
-      CmdArgs.push_back("--as-needed");
-    CmdArgs.push_back("-lgcc_s");
-    if (!D.CCCIsCXX() && !isCygMing)
-      CmdArgs.push_back("--no-as-needed");
-  }
-
-  if (StaticLibgcc && !isAndroid && !IsIAMCU)
-    CmdArgs.push_back("-lgcc_eh");
-  else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
-    CmdArgs.push_back("-lgcc");
-
-  // According to Android ABI, we have to link with libdl if we are
-  // linking with non-static libgcc.
-  //
-  // NOTE: This fixes a link error on Android MIPS as well.  The non-static
-  // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
-  if (isAndroid && !StaticLibgcc)
-    CmdArgs.push_back("-ldl");
-}
-
-static void AddRunTimeLibs(const ToolChain &TC, const Driver &D,
-                           ArgStringList &CmdArgs, const ArgList &Args) {
-  // Make use of compiler-rt if --rtlib option is used
-  ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
-
-  switch (RLT) {
-  case ToolChain::RLT_CompilerRT:
-    switch (TC.getTriple().getOS()) {
-    default:
-      llvm_unreachable("unsupported OS");
-    case llvm::Triple::Win32:
-    case llvm::Triple::Linux:
-    case llvm::Triple::Fuchsia:
-      addClangRT(TC, Args, CmdArgs);
-      break;
-    }
-    break;
-  case ToolChain::RLT_Libgcc:
-    // Make sure libgcc is not used under MSVC environment by default
-    if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
-      // Issue error diagnostic if libgcc is explicitly specified
-      // through command line as --rtlib option argument.
-      if (Args.hasArg(options::OPT_rtlib_EQ)) {
-        TC.getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
-            << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
-      }
-    } else
-      AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
-    break;
-  }
-}
-
-static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
-  switch (T.getArch()) {
-  case llvm::Triple::x86:
-    if (T.isOSIAMCU())
-      return "elf_iamcu";
-    return "elf_i386";
-  case llvm::Triple::aarch64:
-    return "aarch64linux";
-  case llvm::Triple::aarch64_be:
-    return "aarch64_be_linux";
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-    return "armelf_linux_eabi";
-  case llvm::Triple::armeb:
-  case llvm::Triple::thumbeb:
-    return "armelfb_linux_eabi";
-  case llvm::Triple::ppc:
-    return "elf32ppclinux";
-  case llvm::Triple::ppc64:
-    return "elf64ppc";
-  case llvm::Triple::ppc64le:
-    return "elf64lppc";
-  case llvm::Triple::sparc:
-  case llvm::Triple::sparcel:
-    return "elf32_sparc";
-  case llvm::Triple::sparcv9:
-    return "elf64_sparc";
-  case llvm::Triple::mips:
-    return "elf32btsmip";
-  case llvm::Triple::mipsel:
-    return "elf32ltsmip";
-  case llvm::Triple::mips64:
-    if (mips::hasMipsAbiArg(Args, "n32"))
-      return "elf32btsmipn32";
-    return "elf64btsmip";
-  case llvm::Triple::mips64el:
-    if (mips::hasMipsAbiArg(Args, "n32"))
-      return "elf32ltsmipn32";
-    return "elf64ltsmip";
-  case llvm::Triple::systemz:
-    return "elf64_s390";
-  case llvm::Triple::x86_64:
-    if (T.getEnvironment() == llvm::Triple::GNUX32)
-      return "elf32_x86_64";
-    return "elf_x86_64";
-  default:
-    return nullptr;
-  }
-}
-
-void gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                    const InputInfo &Output,
-                                    const InputInfoList &Inputs,
-                                    const ArgList &Args,
-                                    const char *LinkingOutput) const {
-  const toolchains::Linux &ToolChain =
-      static_cast<const toolchains::Linux &>(getToolChain());
-  const Driver &D = ToolChain.getDriver();
-
-  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
-
-  const llvm::Triple::ArchType Arch = ToolChain.getArch();
-  const bool isAndroid = ToolChain.getTriple().isAndroid();
-  const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
-  const bool IsPIE =
-      !Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_static) &&
-      (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault());
-  const bool HasCRTBeginEndFiles =
-      ToolChain.getTriple().hasEnvironment() ||
-      (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);
-
-  ArgStringList CmdArgs;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo". Other warning options are already
-  // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_w);
-
-  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
-  if (llvm::sys::path::filename(Exec) == "lld") {
-    CmdArgs.push_back("-flavor");
-    CmdArgs.push_back("old-gnu");
-    CmdArgs.push_back("-target");
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().getTripleString()));
-  }
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  if (IsPIE)
-    CmdArgs.push_back("-pie");
-
-  if (Args.hasArg(options::OPT_rdynamic))
-    CmdArgs.push_back("-export-dynamic");
-
-  if (Args.hasArg(options::OPT_s))
-    CmdArgs.push_back("-s");
-
-  if (Arch == llvm::Triple::armeb || Arch == llvm::Triple::thumbeb)
-    arm::appendEBLinkFlags(Args, CmdArgs, Triple);
-
-  // Most Android ARM64 targets should enable the linker fix for erratum
-  // 843419. Only non-Cortex-A53 devices are allowed to skip this flag.
-  if (Arch == llvm::Triple::aarch64 && isAndroid) {
-    std::string CPU = getCPUName(Args, Triple);
-    if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")
-      CmdArgs.push_back("--fix-cortex-a53-843419");
-  }
-
-  for (const auto &Opt : ToolChain.ExtraOpts)
-    CmdArgs.push_back(Opt.c_str());
-
-  if (!Args.hasArg(options::OPT_static)) {
-    CmdArgs.push_back("--eh-frame-hdr");
-  }
-
-  if (const char *LDMOption = getLDMOption(ToolChain.getTriple(), Args)) {
-    CmdArgs.push_back("-m");
-    CmdArgs.push_back(LDMOption);
-  } else {
-    D.Diag(diag::err_target_unknown_triple) << Triple.str();
-    return;
-  }
-
-  if (Args.hasArg(options::OPT_static)) {
-    if (Arch == llvm::Triple::arm || Arch == llvm::Triple::armeb ||
-        Arch == llvm::Triple::thumb || Arch == llvm::Triple::thumbeb)
-      CmdArgs.push_back("-Bstatic");
-    else
-      CmdArgs.push_back("-static");
-  } else if (Args.hasArg(options::OPT_shared)) {
-    CmdArgs.push_back("-shared");
-  }
-
-  if (!Args.hasArg(options::OPT_static)) {
-    if (Args.hasArg(options::OPT_rdynamic))
-      CmdArgs.push_back("-export-dynamic");
-
-    if (!Args.hasArg(options::OPT_shared)) {
-      const std::string Loader =
-          D.DyldPrefix + ToolChain.getDynamicLinker(Args);
-      CmdArgs.push_back("-dynamic-linker");
-      CmdArgs.push_back(Args.MakeArgString(Loader));
-    }
-  }
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!isAndroid && !IsIAMCU) {
-      const char *crt1 = nullptr;
-      if (!Args.hasArg(options::OPT_shared)) {
-        if (Args.hasArg(options::OPT_pg))
-          crt1 = "gcrt1.o";
-        else if (IsPIE)
-          crt1 = "Scrt1.o";
-        else
-          crt1 = "crt1.o";
-      }
-      if (crt1)
-        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
-
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
-    }
-
-    if (IsIAMCU)
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
-    else {
-      const char *crtbegin;
-      if (Args.hasArg(options::OPT_static))
-        crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
-      else if (Args.hasArg(options::OPT_shared))
-        crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
-      else if (IsPIE)
-        crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
-      else
-        crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
-
-      if (HasCRTBeginEndFiles)
-        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
-    }
-
-    // Add crtfastmath.o if available and fast math is enabled.
-    ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  Args.AddAllArgs(CmdArgs, options::OPT_u);
-
-  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
-
-  if (D.isUsingLTO())
-    AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin, D);
-
-  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
-    CmdArgs.push_back("--no-demangle");
-
-  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
-  bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
-  // The profile runtime also needs access to system libraries.
-  getToolChain().addProfileRTLibs(Args, CmdArgs);
-
-  if (D.CCCIsCXX() &&
-      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
-                               !Args.hasArg(options::OPT_static);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
-    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
-    CmdArgs.push_back("-lm");
-  }
-  // Silence warnings when linking C code with a C++ '-stdlib' argument.
-  Args.ClaimAllArgs(options::OPT_stdlib_EQ);
-
-  if (!Args.hasArg(options::OPT_nostdlib)) {
-    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
-      if (Args.hasArg(options::OPT_static))
-        CmdArgs.push_back("--start-group");
-
-      if (NeedsSanitizerDeps)
-        linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
-
-      if (NeedsXRayDeps)
-        linkXRayRuntimeDeps(ToolChain, Args, CmdArgs);
-
-      bool WantPthread = Args.hasArg(options::OPT_pthread) ||
-                         Args.hasArg(options::OPT_pthreads);
-
-      if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
-                       options::OPT_fno_openmp, false)) {
-        // OpenMP runtimes implies pthreads when using the GNU toolchain.
-        // FIXME: Does this really make sense for all GNU toolchains?
-        WantPthread = true;
-
-        // Also link the particular OpenMP runtimes.
-        switch (ToolChain.getDriver().getOpenMPRuntime(Args)) {
-        case Driver::OMPRT_OMP:
-          CmdArgs.push_back("-lomp");
-          break;
-        case Driver::OMPRT_GOMP:
-          CmdArgs.push_back("-lgomp");
-
-          // FIXME: Exclude this for platforms with libgomp that don't require
-          // librt. Most modern Linux platforms require it, but some may not.
-          CmdArgs.push_back("-lrt");
-          break;
-        case Driver::OMPRT_IOMP5:
-          CmdArgs.push_back("-liomp5");
-          break;
-        case Driver::OMPRT_Unknown:
-          // Already diagnosed.
-          break;
-        }
-        if (JA.isHostOffloading(Action::OFK_OpenMP))
-          CmdArgs.push_back("-lomptarget");
-      }
-
-      AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
-
-      if (WantPthread && !isAndroid)
-        CmdArgs.push_back("-lpthread");
-
-      if (Args.hasArg(options::OPT_fsplit_stack))
-        CmdArgs.push_back("--wrap=pthread_create");
-
-      CmdArgs.push_back("-lc");
-
-      // Add IAMCU specific libs, if needed.
-      if (IsIAMCU)
-        CmdArgs.push_back("-lgloss");
-
-      if (Args.hasArg(options::OPT_static))
-        CmdArgs.push_back("--end-group");
-      else
-        AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
-
-      // Add IAMCU specific libs (outside the group), if needed.
-      if (IsIAMCU) {
-        CmdArgs.push_back("--as-needed");
-        CmdArgs.push_back("-lsoftfp");
-        CmdArgs.push_back("--no-as-needed");
-      }
-    }
-
-    if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) {
-      const char *crtend;
-      if (Args.hasArg(options::OPT_shared))
-        crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
-      else if (IsPIE)
-        crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
-      else
-        crtend = isAndroid ? "crtend_android.o" : "crtend.o";
-
-      if (HasCRTBeginEndFiles)
-        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
-      if (!isAndroid)
-        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
-    }
-  }
-
-  // Add OpenMP offloading linker script args if required.
-  AddOpenMPLinkerScript(getToolChain(), C, Output, Inputs, Args, CmdArgs, JA);
-
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-// NaCl ARM assembly (inline or standalone) can be written with a set of macros
-// for the various SFI requirements like register masking. The assembly tool
-// inserts the file containing the macros as an input into all the assembly
-// jobs.
-void nacltools::AssemblerARM::ConstructJob(Compilation &C, const JobAction &JA,
-                                           const InputInfo &Output,
-                                           const InputInfoList &Inputs,
-                                           const ArgList &Args,
-                                           const char *LinkingOutput) const {
-  const toolchains::NaClToolChain &ToolChain =
-      static_cast<const toolchains::NaClToolChain &>(getToolChain());
-  InputInfo NaClMacros(types::TY_PP_Asm, ToolChain.GetNaClArmMacrosPath(),
-                       "nacl-arm-macros.s");
-  InputInfoList NewInputs;
-  NewInputs.push_back(NaClMacros);
-  NewInputs.append(Inputs.begin(), Inputs.end());
-  gnutools::Assembler::ConstructJob(C, JA, Output, NewInputs, Args,
-                                    LinkingOutput);
-}
-
-// This is quite similar to gnutools::Linker::ConstructJob with changes that
-// we use static by default, do not yet support sanitizers or LTO, and a few
-// others. Eventually we can support more of that and hopefully migrate back
-// to gnutools::Linker.
-void nacltools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                     const InputInfo &Output,
-                                     const InputInfoList &Inputs,
-                                     const ArgList &Args,
-                                     const char *LinkingOutput) const {
-
-  const toolchains::NaClToolChain &ToolChain =
-      static_cast<const toolchains::NaClToolChain &>(getToolChain());
-  const Driver &D = ToolChain.getDriver();
-  const llvm::Triple::ArchType Arch = ToolChain.getArch();
-  const bool IsStatic =
-      !Args.hasArg(options::OPT_dynamic) && !Args.hasArg(options::OPT_shared);
-
-  ArgStringList CmdArgs;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo". Other warning options are already
-  // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_w);
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  if (Args.hasArg(options::OPT_rdynamic))
-    CmdArgs.push_back("-export-dynamic");
-
-  if (Args.hasArg(options::OPT_s))
-    CmdArgs.push_back("-s");
-
-  // NaClToolChain doesn't have ExtraOpts like Linux; the only relevant flag
-  // from there is --build-id, which we do want.
-  CmdArgs.push_back("--build-id");
-
-  if (!IsStatic)
-    CmdArgs.push_back("--eh-frame-hdr");
-
-  CmdArgs.push_back("-m");
-  if (Arch == llvm::Triple::x86)
-    CmdArgs.push_back("elf_i386_nacl");
-  else if (Arch == llvm::Triple::arm)
-    CmdArgs.push_back("armelf_nacl");
-  else if (Arch == llvm::Triple::x86_64)
-    CmdArgs.push_back("elf_x86_64_nacl");
-  else if (Arch == llvm::Triple::mipsel)
-    CmdArgs.push_back("mipselelf_nacl");
-  else
-    D.Diag(diag::err_target_unsupported_arch) << ToolChain.getArchName()
-                                              << "Native Client";
-
-  if (IsStatic)
-    CmdArgs.push_back("-static");
-  else if (Args.hasArg(options::OPT_shared))
-    CmdArgs.push_back("-shared");
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!Args.hasArg(options::OPT_shared))
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt1.o")));
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
-
-    const char *crtbegin;
-    if (IsStatic)
-      crtbegin = "crtbeginT.o";
-    else if (Args.hasArg(options::OPT_shared))
-      crtbegin = "crtbeginS.o";
-    else
-      crtbegin = "crtbegin.o";
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  Args.AddAllArgs(CmdArgs, options::OPT_u);
-
-  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
-
-  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
-    CmdArgs.push_back("--no-demangle");
-
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
-
-  if (D.CCCIsCXX() &&
-      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic =
-        Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
-    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
-    CmdArgs.push_back("-lm");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib)) {
-    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
-      // Always use groups, since it has no effect on dynamic libraries.
-      CmdArgs.push_back("--start-group");
-      CmdArgs.push_back("-lc");
-      // NaCl's libc++ currently requires libpthread, so just always include it
-      // in the group for C++.
-      if (Args.hasArg(options::OPT_pthread) ||
-          Args.hasArg(options::OPT_pthreads) || D.CCCIsCXX()) {
-        // Gold, used by Mips, handles nested groups differently than ld, and
-        // without '-lnacl' it prefers symbols from libpthread.a over libnacl.a,
-        // which is not a desired behaviour here.
-        // See https://sourceware.org/ml/binutils/2015-03/msg00034.html
-        if (getToolChain().getArch() == llvm::Triple::mipsel)
-          CmdArgs.push_back("-lnacl");
-
-        CmdArgs.push_back("-lpthread");
-      }
-
-      CmdArgs.push_back("-lgcc");
-      CmdArgs.push_back("--as-needed");
-      if (IsStatic)
-        CmdArgs.push_back("-lgcc_eh");
-      else
-        CmdArgs.push_back("-lgcc_s");
-      CmdArgs.push_back("--no-as-needed");
-
-      // Mips needs to create and use pnacl_legacy library that contains
-      // definitions from bitcode/pnaclmm.c and definitions for
-      // __nacl_tp_tls_offset() and __nacl_tp_tdb_offset().
-      if (getToolChain().getArch() == llvm::Triple::mipsel)
-        CmdArgs.push_back("-lpnacl_legacy");
-
-      CmdArgs.push_back("--end-group");
-    }
-
-    if (!Args.hasArg(options::OPT_nostartfiles)) {
-      const char *crtend;
-      if (Args.hasArg(options::OPT_shared))
-        crtend = "crtendS.o";
-      else
-        crtend = "crtend.o";
-
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
-    }
-  }
-
-  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                   const InputInfo &Output,
-                                   const InputInfoList &Inputs,
-                                   const ArgList &Args,
-                                   const char *LinkingOutput) const {
-  const toolchains::Fuchsia &ToolChain =
-      static_cast<const toolchains::Fuchsia &>(getToolChain());
-  const Driver &D = ToolChain.getDriver();
-
-  ArgStringList CmdArgs;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo". Other warning options are already
-  // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_w);
-
-  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
-  if (llvm::sys::path::stem(Exec).equals_lower("lld")) {
-    CmdArgs.push_back("-flavor");
-    CmdArgs.push_back("gnu");
-  }
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r))
-    CmdArgs.push_back("-pie");
-
-  if (Args.hasArg(options::OPT_rdynamic))
-    CmdArgs.push_back("-export-dynamic");
-
-  if (Args.hasArg(options::OPT_s))
-    CmdArgs.push_back("-s");
-
-  if (Args.hasArg(options::OPT_r))
-    CmdArgs.push_back("-r");
-  else
-    CmdArgs.push_back("--build-id");
-
-  if (!Args.hasArg(options::OPT_static))
-    CmdArgs.push_back("--eh-frame-hdr");
-
-  if (Args.hasArg(options::OPT_static))
-    CmdArgs.push_back("-Bstatic");
-  else if (Args.hasArg(options::OPT_shared))
-    CmdArgs.push_back("-shared");
-
-  if (!Args.hasArg(options::OPT_static)) {
-    if (Args.hasArg(options::OPT_rdynamic))
-      CmdArgs.push_back("-export-dynamic");
-
-    if (!Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-dynamic-linker");
-      CmdArgs.push_back(Args.MakeArgString(D.DyldPrefix + "ld.so.1"));
-    }
-  }
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o")));
-    }
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  Args.AddAllArgs(CmdArgs, options::OPT_u);
-
-  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
-
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (Args.hasArg(options::OPT_static))
-      CmdArgs.push_back("-Bdynamic");
-
-    if (D.CCCIsCXX()) {
-      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
-                                 !Args.hasArg(options::OPT_static);
-      if (OnlyLibstdcxxStatic)
-        CmdArgs.push_back("-Bstatic");
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (OnlyLibstdcxxStatic)
-        CmdArgs.push_back("-Bdynamic");
-      CmdArgs.push_back("-lm");
-    }
-
-    AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
-
-    if (Args.hasArg(options::OPT_pthread) ||
-        Args.hasArg(options::OPT_pthreads))
-      CmdArgs.push_back("-lpthread");
-
-    if (Args.hasArg(options::OPT_fsplit_stack))
-      CmdArgs.push_back("--wrap=pthread_create");
-
-    CmdArgs.push_back("-lc");
-  }
-
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void minix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                    const InputInfo &Output,
-                                    const InputInfoList &Inputs,
-                                    const ArgList &Args,
-                                    const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void minix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                 const InputInfo &Output,
-                                 const InputInfoList &Inputs,
-                                 const ArgList &Args,
-                                 const char *LinkingOutput) const {
-  const Driver &D = getToolChain().getDriver();
-  ArgStringList CmdArgs;
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
-    CmdArgs.push_back(
-        Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
-  }
-
-  Args.AddAllArgs(CmdArgs,
-                  {options::OPT_L, options::OPT_T_Group, options::OPT_e});
-
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-
-  getToolChain().addProfileRTLibs(Args, CmdArgs);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-      CmdArgs.push_back("-lm");
-    }
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (Args.hasArg(options::OPT_pthread))
-      CmdArgs.push_back("-lpthread");
-    CmdArgs.push_back("-lc");
-    CmdArgs.push_back("-lCompilerRT-Generic");
-    CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib");
-    CmdArgs.push_back(
-        Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
-  }
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-/// DragonFly Tools
-
-// For now, DragonFly Assemble does just about the same as for
-// FreeBSD, but this may change soon.
-void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                        const InputInfo &Output,
-                                        const InputInfoList &Inputs,
-                                        const ArgList &Args,
-                                        const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  // When building 32-bit code on DragonFly/pc64, we have to explicitly
-  // instruct as in the base system to assemble 32-bit code.
-  if (getToolChain().getArch() == llvm::Triple::x86)
-    CmdArgs.push_back("--32");
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                     const InputInfo &Output,
-                                     const InputInfoList &Inputs,
-                                     const ArgList &Args,
-                                     const char *LinkingOutput) const {
-  const Driver &D = getToolChain().getDriver();
-  ArgStringList CmdArgs;
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  CmdArgs.push_back("--eh-frame-hdr");
-  if (Args.hasArg(options::OPT_static)) {
-    CmdArgs.push_back("-Bstatic");
-  } else {
-    if (Args.hasArg(options::OPT_rdynamic))
-      CmdArgs.push_back("-export-dynamic");
-    if (Args.hasArg(options::OPT_shared))
-      CmdArgs.push_back("-Bshareable");
-    else {
-      CmdArgs.push_back("-dynamic-linker");
-      CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
-    }
-    CmdArgs.push_back("--hash-style=gnu");
-    CmdArgs.push_back("--enable-new-dtags");
-  }
-
-  // When building 32-bit code on DragonFly/pc64, we have to explicitly
-  // instruct ld in the base system to link 32-bit code.
-  if (getToolChain().getArch() == llvm::Triple::x86) {
-    CmdArgs.push_back("-m");
-    CmdArgs.push_back("elf_i386");
-  }
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (!Args.hasArg(options::OPT_shared)) {
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back(
-            Args.MakeArgString(getToolChain().GetFilePath("gcrt1.o")));
-      else {
-        if (Args.hasArg(options::OPT_pie))
-          CmdArgs.push_back(
-              Args.MakeArgString(getToolChain().GetFilePath("Scrt1.o")));
-        else
-          CmdArgs.push_back(
-              Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
-      }
-    }
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
-    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
-    else
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
-  }
-
-  Args.AddAllArgs(CmdArgs,
-                  {options::OPT_L, options::OPT_T_Group, options::OPT_e});
-
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    CmdArgs.push_back("-L/usr/lib/gcc50");
-
-    if (!Args.hasArg(options::OPT_static)) {
-      CmdArgs.push_back("-rpath");
-      CmdArgs.push_back("/usr/lib/gcc50");
-    }
-
-    if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-      CmdArgs.push_back("-lm");
-    }
-
-    if (Args.hasArg(options::OPT_pthread))
-      CmdArgs.push_back("-lpthread");
-
-    if (!Args.hasArg(options::OPT_nolibc)) {
-      CmdArgs.push_back("-lc");
-    }
-
-    if (Args.hasArg(options::OPT_static) ||
-        Args.hasArg(options::OPT_static_libgcc)) {
-        CmdArgs.push_back("-lgcc");
-        CmdArgs.push_back("-lgcc_eh");
-    } else {
-      if (Args.hasArg(options::OPT_shared_libgcc)) {
-          CmdArgs.push_back("-lgcc_pic");
-          if (!Args.hasArg(options::OPT_shared))
-            CmdArgs.push_back("-lgcc");
-      } else {
-          CmdArgs.push_back("-lgcc");
-          CmdArgs.push_back("--as-needed");
-          CmdArgs.push_back("-lgcc_pic");
-          CmdArgs.push_back("--no-as-needed");
-      }
-    }
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
-    else
-      CmdArgs.push_back(
-          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
-  }
-
-  getToolChain().addProfileRTLibs(Args, CmdArgs);
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-// Try to find Exe from a Visual Studio distribution.  This first tries to find
-// an installed copy of Visual Studio and, failing that, looks in the PATH,
-// making sure that whatever executable that's found is not a same-named exe
-// from clang itself to prevent clang from falling back to itself.
-static std::string FindVisualStudioExecutable(const ToolChain &TC,
-                                              const char *Exe,
-                                              const char *ClangProgramPath) {
-  const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
-  std::string visualStudioBinDir;
-  if (MSVC.getVisualStudioBinariesFolder(ClangProgramPath,
-                                         visualStudioBinDir)) {
-    SmallString<128> FilePath(visualStudioBinDir);
-    llvm::sys::path::append(FilePath, Exe);
-    if (llvm::sys::fs::can_execute(FilePath.c_str()))
-      return FilePath.str();
-  }
-
-  return Exe;
-}
-
-void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                        const InputInfo &Output,
-                                        const InputInfoList &Inputs,
-                                        const ArgList &Args,
-                                        const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-  const ToolChain &TC = getToolChain();
-
-  assert((Output.isFilename() || Output.isNothing()) && "invalid output");
-  if (Output.isFilename())
-    CmdArgs.push_back(
-        Args.MakeArgString(std::string("-out:") + Output.getFilename()));
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
-      !C.getDriver().IsCLMode())
-    CmdArgs.push_back("-defaultlib:libcmt");
-
-  if (!llvm::sys::Process::GetEnv("LIB")) {
-    // If the VC environment hasn't been configured (perhaps because the user
-    // did not run vcvarsall), try to build a consistent link environment.  If
-    // the environment variable is set however, assume the user knows what
-    // they're doing.
-    std::string VisualStudioDir;
-    const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
-    if (MSVC.getVisualStudioInstallDir(VisualStudioDir)) {
-      SmallString<128> LibDir(VisualStudioDir);
-      llvm::sys::path::append(LibDir, "VC", "lib");
-      switch (MSVC.getArch()) {
-      case llvm::Triple::x86:
-        // x86 just puts the libraries directly in lib
-        break;
-      case llvm::Triple::x86_64:
-        llvm::sys::path::append(LibDir, "amd64");
-        break;
-      case llvm::Triple::arm:
-        llvm::sys::path::append(LibDir, "arm");
-        break;
-      default:
-        break;
-      }
-      CmdArgs.push_back(
-          Args.MakeArgString(std::string("-libpath:") + LibDir.c_str()));
-
-      if (MSVC.useUniversalCRT(VisualStudioDir)) {
-        std::string UniversalCRTLibPath;
-        if (MSVC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
-          CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
-                                               UniversalCRTLibPath));
-      }
-    }
-
-    std::string WindowsSdkLibPath;
-    if (MSVC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
-      CmdArgs.push_back(
-          Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
-  }
-
-  if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
-    for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
-      CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
-
-  CmdArgs.push_back("-nologo");
-
-  if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
-                  options::OPT__SLASH_Zd))
-    CmdArgs.push_back("-debug");
-
-  bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
-                         options::OPT_shared);
-  if (DLL) {
-    CmdArgs.push_back(Args.MakeArgString("-dll"));
-
-    SmallString<128> ImplibName(Output.getFilename());
-    llvm::sys::path::replace_extension(ImplibName, "lib");
-    CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
-  }
-
-  if (TC.getSanitizerArgs().needsAsanRt()) {
-    CmdArgs.push_back(Args.MakeArgString("-debug"));
-    CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
-    if (TC.getSanitizerArgs().needsSharedAsanRt() ||
-        Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
-      for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
-        CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
-      // Make sure the dynamic runtime thunk is not optimized out at link time
-      // to ensure proper SEH handling.
-      CmdArgs.push_back(Args.MakeArgString(
-          TC.getArch() == llvm::Triple::x86
-              ? "-include:___asan_seh_interceptor"
-              : "-include:__asan_seh_interceptor"));
-    } else if (DLL) {
-      CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
-    } else {
-      for (const auto &Lib : {"asan", "asan_cxx"})
-        CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
-    }
-  }
-
-  Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
-
-  if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
-                   options::OPT_fno_openmp, false)) {
-    CmdArgs.push_back("-nodefaultlib:vcomp.lib");
-    CmdArgs.push_back("-nodefaultlib:vcompd.lib");
-    CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
-                                         TC.getDriver().Dir + "/../lib"));
-    switch (TC.getDriver().getOpenMPRuntime(Args)) {
-    case Driver::OMPRT_OMP:
-      CmdArgs.push_back("-defaultlib:libomp.lib");
-      break;
-    case Driver::OMPRT_IOMP5:
-      CmdArgs.push_back("-defaultlib:libiomp5md.lib");
-      break;
-    case Driver::OMPRT_GOMP:
-      break;
-    case Driver::OMPRT_Unknown:
-      // Already diagnosed.
-      break;
-    }
-  }
-
-  // Add compiler-rt lib in case if it was explicitly
-  // specified as an argument for --rtlib option.
-  if (!Args.hasArg(options::OPT_nostdlib)) {
-    AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
-  }
-
-  // Add filenames, libraries, and other linker inputs.
-  for (const auto &Input : Inputs) {
-    if (Input.isFilename()) {
-      CmdArgs.push_back(Input.getFilename());
-      continue;
-    }
-
-    const Arg &A = Input.getInputArg();
-
-    // Render -l options differently for the MSVC linker.
-    if (A.getOption().matches(options::OPT_l)) {
-      StringRef Lib = A.getValue();
-      const char *LinkLibArg;
-      if (Lib.endswith(".lib"))
-        LinkLibArg = Args.MakeArgString(Lib);
-      else
-        LinkLibArg = Args.MakeArgString(Lib + ".lib");
-      CmdArgs.push_back(LinkLibArg);
-      continue;
-    }
-
-    // Otherwise, this is some other kind of linker input option like -Wl, -z,
-    // or -L. Render it, even if MSVC doesn't understand it.
-    A.renderAsInput(Args, CmdArgs);
-  }
-
-  TC.addProfileRTLibs(Args, CmdArgs);
-
-  // We need to special case some linker paths.  In the case of lld, we need to
-  // translate 'lld' into 'lld-link', and in the case of the regular msvc
-  // linker, we need to use a special search algorithm.
-  llvm::SmallString<128> linkPath;
-  StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
-  if (Linker.equals_lower("lld"))
-    Linker = "lld-link";
-
-  if (Linker.equals_lower("link")) {
-    // If we're using the MSVC linker, it's not sufficient to just use link
-    // from the program PATH, because other environments like GnuWin32 install
-    // their own link.exe which may come first.
-    linkPath = FindVisualStudioExecutable(TC, "link.exe",
-                                          C.getDriver().getClangProgramPath());
-  } else {
-    linkPath = Linker;
-    llvm::sys::path::replace_extension(linkPath, "exe");
-    linkPath = TC.GetProgramPath(linkPath.c_str());
-  }
-
-  const char *Exec = Args.MakeArgString(linkPath);
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
-                                          const InputInfo &Output,
-                                          const InputInfoList &Inputs,
-                                          const ArgList &Args,
-                                          const char *LinkingOutput) const {
-  C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
-}
-
-std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
-    Compilation &C, const JobAction &JA, const InputInfo &Output,
-    const InputInfoList &Inputs, const ArgList &Args,
-    const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-  CmdArgs.push_back("/nologo");
-  CmdArgs.push_back("/c");  // Compile only.
-  CmdArgs.push_back("/W0"); // No warnings.
-
-  // The goal is to be able to invoke this tool correctly based on
-  // any flag accepted by clang-cl.
-
-  // These are spelled the same way in clang and cl.exe,.
-  Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
-
-  // Optimization level.
-  if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
-    CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
-                                                                      : "/Oi-");
-  if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
-    if (A->getOption().getID() == options::OPT_O0) {
-      CmdArgs.push_back("/Od");
-    } else {
-      CmdArgs.push_back("/Og");
-
-      StringRef OptLevel = A->getValue();
-      if (OptLevel == "s" || OptLevel == "z")
-        CmdArgs.push_back("/Os");
-      else
-        CmdArgs.push_back("/Ot");
-
-      CmdArgs.push_back("/Ob2");
-    }
-  }
-  if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
-                               options::OPT_fno_omit_frame_pointer))
-    CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
-                          ? "/Oy"
-                          : "/Oy-");
-  if (!Args.hasArg(options::OPT_fwritable_strings))
-    CmdArgs.push_back("/GF");
-
-  // Flags for which clang-cl has an alias.
-  // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
-
-  if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
-                   /*default=*/false))
-    CmdArgs.push_back("/GR-");
-
-  if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
-                   /*default=*/false))
-    CmdArgs.push_back("/GS-");
-
-  if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
-                               options::OPT_fno_function_sections))
-    CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
-                          ? "/Gy"
-                          : "/Gy-");
-  if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
-                               options::OPT_fno_data_sections))
-    CmdArgs.push_back(
-        A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
-  if (Args.hasArg(options::OPT_fsyntax_only))
-    CmdArgs.push_back("/Zs");
-  if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
-                  options::OPT__SLASH_Z7))
-    CmdArgs.push_back("/Z7");
-
-  std::vector<std::string> Includes =
-      Args.getAllArgValues(options::OPT_include);
-  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_GX);
-  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
-  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
-  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
-
-  // 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,
-                               options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
-    A->render(Args, CmdArgs);
-
-  // Use MSVC's default threadsafe statics behaviour unless there was a flag.
-  if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
-                               options::OPT_fno_threadsafe_statics)) {
-    CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
-                          ? "/Zc:threadSafeInit"
-                          : "/Zc:threadSafeInit-");
-  }
-
-  // Pass through all unknown arguments so that the fallback command can see
-  // them too.
-  Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
-
-  // Input filename.
-  assert(Inputs.size() == 1);
-  const InputInfo &II = Inputs[0];
-  assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
-  CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
-  if (II.isFilename())
-    CmdArgs.push_back(II.getFilename());
-  else
-    II.getInputArg().renderAsInput(Args, CmdArgs);
-
-  // Output filename.
-  assert(Output.getType() == types::TY_Object);
-  const char *Fo =
-      Args.MakeArgString(std::string("/Fo") + Output.getFilename());
-  CmdArgs.push_back(Fo);
-
-  const Driver &D = getToolChain().getDriver();
-  std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe",
-                                                D.getClangProgramPath());
-  return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
-                                    CmdArgs, Inputs);
-}
-
-/// MinGW Tools
-void MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                    const InputInfo &Output,
-                                    const InputInfoList &Inputs,
-                                    const ArgList &Args,
-                                    const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  if (getToolChain().getArch() == llvm::Triple::x86) {
-    CmdArgs.push_back("--32");
-  } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
-    CmdArgs.push_back("--64");
-  }
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-
-  if (Args.hasArg(options::OPT_gsplit_dwarf))
-    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
-                   SplitDebugName(Args, Inputs[0]));
-}
-
-void MinGW::Linker::AddLibGCC(const ArgList &Args,
-                              ArgStringList &CmdArgs) const {
-  if (Args.hasArg(options::OPT_mthreads))
-    CmdArgs.push_back("-lmingwthrd");
-  CmdArgs.push_back("-lmingw32");
-
-  // Make use of compiler-rt if --rtlib option is used
-  ToolChain::RuntimeLibType RLT = getToolChain().GetRuntimeLibType(Args);
-  if (RLT == ToolChain::RLT_Libgcc) {
-    bool Static = Args.hasArg(options::OPT_static_libgcc) ||
-                  Args.hasArg(options::OPT_static);
-    bool Shared = Args.hasArg(options::OPT_shared);
-    bool CXX = getToolChain().getDriver().CCCIsCXX();
-
-    if (Static || (!CXX && !Shared)) {
-      CmdArgs.push_back("-lgcc");
-      CmdArgs.push_back("-lgcc_eh");
-    } else {
-      CmdArgs.push_back("-lgcc_s");
-      CmdArgs.push_back("-lgcc");
-    }
-  } else {
-    AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args);
-  }
-
-  CmdArgs.push_back("-lmoldname");
-  CmdArgs.push_back("-lmingwex");
-  CmdArgs.push_back("-lmsvcrt");
-}
-
-void MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                 const InputInfo &Output,
-                                 const InputInfoList &Inputs,
-                                 const ArgList &Args,
-                                 const char *LinkingOutput) const {
-  const ToolChain &TC = getToolChain();
-  const Driver &D = TC.getDriver();
-  // const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
-
-  ArgStringList CmdArgs;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo". Other warning options are already
-  // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_w);
-
-  StringRef LinkerName = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "ld");
-  if (LinkerName.equals_lower("lld")) {
-    CmdArgs.push_back("-flavor");
-    CmdArgs.push_back("gnu");
-  } else if (!LinkerName.equals_lower("ld")) {
-    D.Diag(diag::err_drv_unsupported_linker) << LinkerName;
-  }
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  if (Args.hasArg(options::OPT_s))
-    CmdArgs.push_back("-s");
-
-  CmdArgs.push_back("-m");
-  if (TC.getArch() == llvm::Triple::x86)
-    CmdArgs.push_back("i386pe");
-  if (TC.getArch() == llvm::Triple::x86_64)
-    CmdArgs.push_back("i386pep");
-  if (TC.getArch() == llvm::Triple::arm)
-    CmdArgs.push_back("thumb2pe");
-
-  if (Args.hasArg(options::OPT_mwindows)) {
-    CmdArgs.push_back("--subsystem");
-    CmdArgs.push_back("windows");
-  } else if (Args.hasArg(options::OPT_mconsole)) {
-    CmdArgs.push_back("--subsystem");
-    CmdArgs.push_back("console");
-  }
-
-  if (Args.hasArg(options::OPT_static))
-    CmdArgs.push_back("-Bstatic");
-  else {
-    if (Args.hasArg(options::OPT_mdll))
-      CmdArgs.push_back("--dll");
-    else if (Args.hasArg(options::OPT_shared))
-      CmdArgs.push_back("--shared");
-    CmdArgs.push_back("-Bdynamic");
-    if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-e");
-      if (TC.getArch() == llvm::Triple::x86)
-        CmdArgs.push_back("_DllMainCRTStartup@12");
-      else
-        CmdArgs.push_back("DllMainCRTStartup");
-      CmdArgs.push_back("--enable-auto-image-base");
-    }
-  }
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  Args.AddAllArgs(CmdArgs, options::OPT_e);
-  // FIXME: add -N, -n flags
-  Args.AddLastArg(CmdArgs, options::OPT_r);
-  Args.AddLastArg(CmdArgs, options::OPT_s);
-  Args.AddLastArg(CmdArgs, options::OPT_t);
-  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
-  Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
-      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o")));
-    } else {
-      if (Args.hasArg(options::OPT_municode))
-        CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2u.o")));
-      else
-        CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2.o")));
-    }
-    if (Args.hasArg(options::OPT_pg))
-      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt2.o")));
-    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o")));
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  TC.AddFilePathLibArgs(Args, CmdArgs);
-  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
-
-  // TODO: Add ASan stuff here
-
-  // TODO: Add profile stuff here
-
-  if (D.CCCIsCXX() &&
-      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
-                               !Args.hasArg(options::OPT_static);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
-    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib)) {
-    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
-      if (Args.hasArg(options::OPT_static))
-        CmdArgs.push_back("--start-group");
-
-      if (Args.hasArg(options::OPT_fstack_protector) ||
-          Args.hasArg(options::OPT_fstack_protector_strong) ||
-          Args.hasArg(options::OPT_fstack_protector_all)) {
-        CmdArgs.push_back("-lssp_nonshared");
-        CmdArgs.push_back("-lssp");
-      }
-      if (Args.hasArg(options::OPT_fopenmp))
-        CmdArgs.push_back("-lgomp");
-
-      AddLibGCC(Args, CmdArgs);
-
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lgmon");
-
-      if (Args.hasArg(options::OPT_pthread))
-        CmdArgs.push_back("-lpthread");
-
-      // add system libraries
-      if (Args.hasArg(options::OPT_mwindows)) {
-        CmdArgs.push_back("-lgdi32");
-        CmdArgs.push_back("-lcomdlg32");
-      }
-      CmdArgs.push_back("-ladvapi32");
-      CmdArgs.push_back("-lshell32");
-      CmdArgs.push_back("-luser32");
-      CmdArgs.push_back("-lkernel32");
-
-      if (Args.hasArg(options::OPT_static))
-        CmdArgs.push_back("--end-group");
-      else if (!LinkerName.equals_lower("lld"))
-        AddLibGCC(Args, CmdArgs);
-    }
-
-    if (!Args.hasArg(options::OPT_nostartfiles)) {
-      // Add crtfastmath.o if available and fast math is enabled.
-      TC.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
-
-      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
-    }
-  }
-  const char *Exec = Args.MakeArgString(TC.GetProgramPath(LinkerName.data()));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-/// XCore Tools
-// We pass assemble and link construction to the xcc tool.
-
-void XCore::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                    const InputInfo &Output,
-                                    const InputInfoList &Inputs,
-                                    const ArgList &Args,
-                                    const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  CmdArgs.push_back("-c");
-
-  if (Args.hasArg(options::OPT_v))
-    CmdArgs.push_back("-v");
-
-  if (Arg *A = Args.getLastArg(options::OPT_g_Group))
-    if (!A->getOption().matches(options::OPT_g0))
-      CmdArgs.push_back("-g");
-
-  if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
-                   false))
-    CmdArgs.push_back("-fverbose-asm");
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  for (const auto &II : Inputs)
-    CmdArgs.push_back(II.getFilename());
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                 const InputInfo &Output,
-                                 const InputInfoList &Inputs,
-                                 const ArgList &Args,
-                                 const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  if (Args.hasArg(options::OPT_v))
-    CmdArgs.push_back("-v");
-
-  // Pass -fexceptions through to the linker if it was present.
-  if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
-                   false))
-    CmdArgs.push_back("-fexceptions");
-
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void CrossWindows::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                           const InputInfo &Output,
-                                           const InputInfoList &Inputs,
-                                           const ArgList &Args,
-                                           const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  const auto &TC =
-      static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
-  ArgStringList CmdArgs;
-  const char *Exec;
-
-  switch (TC.getArch()) {
-  default:
-    llvm_unreachable("unsupported architecture");
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-    break;
-  case llvm::Triple::x86:
-    CmdArgs.push_back("--32");
-    break;
-  case llvm::Triple::x86_64:
-    CmdArgs.push_back("--64");
-    break;
-  }
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  for (const auto &Input : Inputs)
-    CmdArgs.push_back(Input.getFilename());
-
-  const std::string Assembler = TC.GetProgramPath("as");
-  Exec = Args.MakeArgString(Assembler);
-
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void CrossWindows::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                        const InputInfo &Output,
-                                        const InputInfoList &Inputs,
-                                        const ArgList &Args,
-                                        const char *LinkingOutput) const {
-  const auto &TC =
-      static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
-  const llvm::Triple &T = TC.getTriple();
-  const Driver &D = TC.getDriver();
-  SmallString<128> EntryPoint;
-  ArgStringList CmdArgs;
-  const char *Exec;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_w);
-  // Other warning options are already handled somewhere else.
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  if (Args.hasArg(options::OPT_pie))
-    CmdArgs.push_back("-pie");
-  if (Args.hasArg(options::OPT_rdynamic))
-    CmdArgs.push_back("-export-dynamic");
-  if (Args.hasArg(options::OPT_s))
-    CmdArgs.push_back("--strip-all");
-
-  CmdArgs.push_back("-m");
-  switch (TC.getArch()) {
-  default:
-    llvm_unreachable("unsupported architecture");
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-    // FIXME: this is incorrect for WinCE
-    CmdArgs.push_back("thumb2pe");
-    break;
-  case llvm::Triple::x86:
-    CmdArgs.push_back("i386pe");
-    EntryPoint.append("_");
-    break;
-  case llvm::Triple::x86_64:
-    CmdArgs.push_back("i386pep");
-    break;
-  }
-
-  if (Args.hasArg(options::OPT_shared)) {
-    switch (T.getArch()) {
-    default:
-      llvm_unreachable("unsupported architecture");
-    case llvm::Triple::arm:
-    case llvm::Triple::thumb:
-    case llvm::Triple::x86_64:
-      EntryPoint.append("_DllMainCRTStartup");
-      break;
-    case llvm::Triple::x86:
-      EntryPoint.append("_DllMainCRTStartup@12");
-      break;
-    }
-
-    CmdArgs.push_back("-shared");
-    CmdArgs.push_back("-Bdynamic");
-
-    CmdArgs.push_back("--enable-auto-image-base");
-
-    CmdArgs.push_back("--entry");
-    CmdArgs.push_back(Args.MakeArgString(EntryPoint));
-  } else {
-    EntryPoint.append("mainCRTStartup");
-
-    CmdArgs.push_back(Args.hasArg(options::OPT_static) ? "-Bstatic"
-                                                       : "-Bdynamic");
-
-    if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-      CmdArgs.push_back("--entry");
-      CmdArgs.push_back(Args.MakeArgString(EntryPoint));
-    }
-
-    // FIXME: handle subsystem
-  }
-
-  // NOTE: deal with multiple definitions on Windows (e.g. COMDAT)
-  CmdArgs.push_back("--allow-multiple-definition");
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_rdynamic)) {
-    SmallString<261> ImpLib(Output.getFilename());
-    llvm::sys::path::replace_extension(ImpLib, ".lib");
-
-    CmdArgs.push_back("--out-implib");
-    CmdArgs.push_back(Args.MakeArgString(ImpLib));
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    const std::string CRTPath(D.SysRoot + "/usr/lib/");
-    const char *CRTBegin;
-
-    CRTBegin =
-        Args.hasArg(options::OPT_shared) ? "crtbeginS.obj" : "crtbegin.obj";
-    CmdArgs.push_back(Args.MakeArgString(CRTPath + CRTBegin));
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  TC.AddFilePathLibArgs(Args, CmdArgs);
-  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
-
-  if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
-      !Args.hasArg(options::OPT_nodefaultlibs)) {
-    bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
-                     !Args.hasArg(options::OPT_static);
-    if (StaticCXX)
-      CmdArgs.push_back("-Bstatic");
-    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (StaticCXX)
-      CmdArgs.push_back("-Bdynamic");
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib)) {
-    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
-      // TODO handle /MT[d] /MD[d]
-      CmdArgs.push_back("-lmsvcrt");
-      AddRunTimeLibs(TC, D, CmdArgs, Args);
-    }
-  }
-
-  if (TC.getSanitizerArgs().needsAsanRt()) {
-    // TODO handle /MT[d] /MD[d]
-    if (Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
-    } else {
-      for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
-        CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
-      // Make sure the dynamic runtime thunk is not optimized out at link time
-      // to ensure proper SEH handling.
-      CmdArgs.push_back(Args.MakeArgString("--undefined"));
-      CmdArgs.push_back(Args.MakeArgString(TC.getArch() == llvm::Triple::x86
-                                               ? "___asan_seh_interceptor"
-                                               : "__asan_seh_interceptor"));
-    }
-  }
-
-  Exec = Args.MakeArgString(TC.GetLinkerPath());
-
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-void tools::SHAVE::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
-                                          const InputInfo &Output,
-                                          const InputInfoList &Inputs,
-                                          const ArgList &Args,
-                                          const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-  assert(Inputs.size() == 1);
-  const InputInfo &II = Inputs[0];
-  assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX ||
-         II.getType() == types::TY_PP_CXX);
-
-  if (JA.getKind() == Action::PreprocessJobClass) {
-    Args.ClaimAllArgs();
-    CmdArgs.push_back("-E");
-  } else {
-    assert(Output.getType() == types::TY_PP_Asm); // Require preprocessed asm.
-    CmdArgs.push_back("-S");
-    CmdArgs.push_back("-fno-exceptions"); // Always do this even if unspecified.
-  }
-  CmdArgs.push_back("-DMYRIAD2");
-
-  // Append all -I, -iquote, -isystem paths, defines/undefines,
-  // 'f' flags, optimize flags, and warning options.
-  // These are spelled the same way in clang and moviCompile.
-  Args.AddAllArgsExcept(
-      CmdArgs,
-      {options::OPT_I_Group, options::OPT_clang_i_Group, options::OPT_std_EQ,
-       options::OPT_D, options::OPT_U, options::OPT_f_Group,
-       options::OPT_f_clang_Group, options::OPT_g_Group, options::OPT_M_Group,
-       options::OPT_O_Group, options::OPT_W_Group, options::OPT_mcpu_EQ},
-      {options::OPT_fno_split_dwarf_inlining});
-  Args.hasArg(options::OPT_fno_split_dwarf_inlining); // Claim it if present.
-
-  // If we're producing a dependency file, and assembly is the final action,
-  // then the name of the target in the dependency file should be the '.o'
-  // file, not the '.s' file produced by this step. For example, instead of
-  //  /tmp/mumble.s: mumble.c .../someheader.h
-  // the filename on the lefthand side should be "mumble.o"
-  if (Args.getLastArg(options::OPT_MF) && !Args.getLastArg(options::OPT_MT) &&
-      C.getActions().size() == 1 &&
-      C.getActions()[0]->getKind() == Action::AssembleJobClass) {
-    Arg *A = Args.getLastArg(options::OPT_o);
-    if (A) {
-      CmdArgs.push_back("-MT");
-      CmdArgs.push_back(Args.MakeArgString(A->getValue()));
-    }
-  }
-
-  CmdArgs.push_back(II.getFilename());
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  std::string Exec =
-      Args.MakeArgString(getToolChain().GetProgramPath("moviCompile"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
-                                          CmdArgs, Inputs));
-}
-
-void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                           const InputInfo &Output,
-                                           const InputInfoList &Inputs,
-                                           const ArgList &Args,
-                                           const char *LinkingOutput) const {
-  ArgStringList CmdArgs;
-
-  assert(Inputs.size() == 1);
-  const InputInfo &II = Inputs[0];
-  assert(II.getType() == types::TY_PP_Asm); // Require preprocessed asm input.
-  assert(Output.getType() == types::TY_Object);
-
-  CmdArgs.push_back("-no6thSlotCompression");
-  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
-  if (CPUArg)
-    CmdArgs.push_back(
-        Args.MakeArgString("-cv:" + StringRef(CPUArg->getValue())));
-  CmdArgs.push_back("-noSPrefixing");
-  CmdArgs.push_back("-a"); // Mystery option.
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-  for (const Arg *A : Args.filtered(options::OPT_I, options::OPT_isystem)) {
-    A->claim();
-    CmdArgs.push_back(
-        Args.MakeArgString(std::string("-i:") + A->getValue(0)));
-  }
-  CmdArgs.push_back("-elf"); // Output format.
-  CmdArgs.push_back(II.getFilename());
-  CmdArgs.push_back(
-      Args.MakeArgString(std::string("-o:") + Output.getFilename()));
-
-  std::string Exec =
-      Args.MakeArgString(getToolChain().GetProgramPath("moviAsm"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
-                                          CmdArgs, Inputs));
-}
-
-void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                         const InputInfo &Output,
-                                         const InputInfoList &Inputs,
-                                         const ArgList &Args,
-                                         const char *LinkingOutput) const {
-  const auto &TC =
-      static_cast<const toolchains::MyriadToolChain &>(getToolChain());
-  const llvm::Triple &T = TC.getTriple();
-  ArgStringList CmdArgs;
-  bool UseStartfiles =
-      !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
-  bool UseDefaultLibs =
-      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs);
-  // Silence warning if the args contain both -nostdlib and -stdlib=.
-  Args.getLastArg(options::OPT_stdlib_EQ);
-
-  if (T.getArch() == llvm::Triple::sparc)
-    CmdArgs.push_back("-EB");
-  else // SHAVE assumes little-endian, and sparcel is expressly so.
-    CmdArgs.push_back("-EL");
-
-  // The remaining logic is mostly like gnutools::Linker::ConstructJob,
-  // but we never pass through a --sysroot option and various other bits.
-  // For example, there are no sanitizers (yet) nor gold linker.
-
-  // Eat some arguments that may be present but have no effect.
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  Args.ClaimAllArgs(options::OPT_w);
-  Args.ClaimAllArgs(options::OPT_static_libgcc);
-
-  if (Args.hasArg(options::OPT_s)) // Pass the 'strip' option.
-    CmdArgs.push_back("-s");
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  if (UseStartfiles) {
-    // If you want startfiles, it means you want the builtin crti and crtbegin,
-    // but not crt0. Myriad link commands provide their own crt0.o as needed.
-    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crti.o")));
-    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o")));
-  }
-
-  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
-                            options::OPT_e, options::OPT_s, options::OPT_t,
-                            options::OPT_Z_Flag, options::OPT_r});
-
-  TC.AddFilePathLibArgs(Args, CmdArgs);
-
-  bool NeedsSanitizerDeps = addSanitizerRuntimes(TC, Args, CmdArgs);
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
-
-  if (UseDefaultLibs) {
-    if (NeedsSanitizerDeps)
-      linkSanitizerRuntimeDeps(TC, CmdArgs);
-    if (C.getDriver().CCCIsCXX()) {
-      if (TC.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) {
-        CmdArgs.push_back("-lc++");
-        CmdArgs.push_back("-lc++abi");
-      } else
-        CmdArgs.push_back("-lstdc++");
-    }
-    if (T.getOS() == llvm::Triple::RTEMS) {
-      CmdArgs.push_back("--start-group");
-      CmdArgs.push_back("-lc");
-      CmdArgs.push_back("-lgcc"); // circularly dependent on rtems
-      // You must provide your own "-L" option to enable finding these.
-      CmdArgs.push_back("-lrtemscpu");
-      CmdArgs.push_back("-lrtemsbsp");
-      CmdArgs.push_back("--end-group");
-    } else {
-      CmdArgs.push_back("-lc");
-      CmdArgs.push_back("-lgcc");
-    }
-  }
-  if (UseStartfiles) {
-    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
-    CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtn.o")));
-  }
-
-  std::string Exec =
-      Args.MakeArgString(TC.GetProgramPath("sparc-myriad-elf-ld"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
-                                          CmdArgs, Inputs));
-}
-
-void PS4cpu::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
-                                    const InputInfo &Output,
-                                    const InputInfoList &Inputs,
-                                    const ArgList &Args,
-                                    const char *LinkingOutput) const {
-  claimNoWarnArgs(Args);
-  ArgStringList CmdArgs;
-
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
-
-  CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
-
-  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
-  const InputInfo &Input = Inputs[0];
-  assert(Input.isFilename() && "Invalid input.");
-  CmdArgs.push_back(Input.getFilename());
-
-  const char *Exec =
-      Args.MakeArgString(getToolChain().GetProgramPath("orbis-as"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-static void AddPS4SanitizerArgs(const ToolChain &TC, ArgStringList &CmdArgs) {
-  const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
-  if (SanArgs.needsUbsanRt()) {
-    CmdArgs.push_back("-lSceDbgUBSanitizer_stub_weak");
-  }
-  if (SanArgs.needsAsanRt()) {
-    CmdArgs.push_back("-lSceDbgAddressSanitizer_stub_weak");
-  }
-}
-
-static void ConstructPS4LinkJob(const Tool &T, Compilation &C,
-                                const JobAction &JA, const InputInfo &Output,
-                                const InputInfoList &Inputs,
-                                const ArgList &Args,
-                                const char *LinkingOutput) {
-  const toolchains::FreeBSD &ToolChain =
-      static_cast<const toolchains::FreeBSD &>(T.getToolChain());
-  const Driver &D = ToolChain.getDriver();
-  ArgStringList CmdArgs;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo". Other warning options are already
-  // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_w);
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  if (Args.hasArg(options::OPT_pie))
-    CmdArgs.push_back("-pie");
-
-  if (Args.hasArg(options::OPT_rdynamic))
-    CmdArgs.push_back("-export-dynamic");
-  if (Args.hasArg(options::OPT_shared))
-    CmdArgs.push_back("--oformat=so");
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  AddPS4SanitizerArgs(ToolChain, CmdArgs);
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
-  Args.AddAllArgs(CmdArgs, options::OPT_e);
-  Args.AddAllArgs(CmdArgs, options::OPT_s);
-  Args.AddAllArgs(CmdArgs, options::OPT_t);
-  Args.AddAllArgs(CmdArgs, options::OPT_r);
-
-  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
-    CmdArgs.push_back("--no-demangle");
-
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
-
-  if (Args.hasArg(options::OPT_pthread)) {
-    CmdArgs.push_back("-lpthread");
-  }
-
-  const char *Exec = Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld"));
-
-  C.addCommand(llvm::make_unique<Command>(JA, T, Exec, CmdArgs, Inputs));
-}
-
-static void ConstructGoldLinkJob(const Tool &T, Compilation &C,
-                                 const JobAction &JA, const InputInfo &Output,
-                                 const InputInfoList &Inputs,
-                                 const ArgList &Args,
-                                 const char *LinkingOutput) {
-  const toolchains::FreeBSD &ToolChain =
-      static_cast<const toolchains::FreeBSD &>(T.getToolChain());
-  const Driver &D = ToolChain.getDriver();
-  ArgStringList CmdArgs;
-
-  // Silence warning for "clang -g foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  // and "clang -emit-llvm foo.o -o foo"
-  Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -w foo.o -o foo". Other warning options are already
-  // handled somewhere else.
-  Args.ClaimAllArgs(options::OPT_w);
-
-  if (!D.SysRoot.empty())
-    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
-
-  if (Args.hasArg(options::OPT_pie))
-    CmdArgs.push_back("-pie");
-
-  if (Args.hasArg(options::OPT_static)) {
-    CmdArgs.push_back("-Bstatic");
-  } else {
-    if (Args.hasArg(options::OPT_rdynamic))
-      CmdArgs.push_back("-export-dynamic");
-    CmdArgs.push_back("--eh-frame-hdr");
-    if (Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-Bshareable");
-    } else {
-      CmdArgs.push_back("-dynamic-linker");
-      CmdArgs.push_back("/libexec/ld-elf.so.1");
-    }
-    CmdArgs.push_back("--enable-new-dtags");
-  }
-
-  if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
-  } else {
-    assert(Output.isNothing() && "Invalid output.");
-  }
-
-  AddPS4SanitizerArgs(ToolChain, CmdArgs);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    const char *crt1 = nullptr;
-    if (!Args.hasArg(options::OPT_shared)) {
-      if (Args.hasArg(options::OPT_pg))
-        crt1 = "gcrt1.o";
-      else if (Args.hasArg(options::OPT_pie))
-        crt1 = "Scrt1.o";
-      else
-        crt1 = "crt1.o";
-    }
-    if (crt1)
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
-
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
-
-    const char *crtbegin = nullptr;
-    if (Args.hasArg(options::OPT_static))
-      crtbegin = "crtbeginT.o";
-    else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
-      crtbegin = "crtbeginS.o";
-    else
-      crtbegin = "crtbegin.o";
-
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
-  }
-
-  Args.AddAllArgs(CmdArgs, options::OPT_L);
-  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
-  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
-  Args.AddAllArgs(CmdArgs, options::OPT_e);
-  Args.AddAllArgs(CmdArgs, options::OPT_s);
-  Args.AddAllArgs(CmdArgs, options::OPT_t);
-  Args.AddAllArgs(CmdArgs, options::OPT_r);
-
-  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
-    CmdArgs.push_back("--no-demangle");
-
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    // For PS4, we always want to pass libm, libstdc++ and libkernel
-    // libraries for both C and C++ compilations.
-    CmdArgs.push_back("-lkernel");
-    if (D.CCCIsCXX()) {
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lm_p");
-      else
-        CmdArgs.push_back("-lm");
-    }
-    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
-    // the default system libraries. Just mimic this for now.
-    if (Args.hasArg(options::OPT_pg))
-      CmdArgs.push_back("-lgcc_p");
-    else
-      CmdArgs.push_back("-lcompiler_rt");
-    if (Args.hasArg(options::OPT_static)) {
-      CmdArgs.push_back("-lstdc++");
-    } else if (Args.hasArg(options::OPT_pg)) {
-      CmdArgs.push_back("-lgcc_eh_p");
-    } else {
-      CmdArgs.push_back("--as-needed");
-      CmdArgs.push_back("-lstdc++");
-      CmdArgs.push_back("--no-as-needed");
-    }
-
-    if (Args.hasArg(options::OPT_pthread)) {
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lpthread_p");
-      else
-        CmdArgs.push_back("-lpthread");
-    }
-
-    if (Args.hasArg(options::OPT_pg)) {
-      if (Args.hasArg(options::OPT_shared))
-        CmdArgs.push_back("-lc");
-      else {
-        if (Args.hasArg(options::OPT_static)) {
-          CmdArgs.push_back("--start-group");
-          CmdArgs.push_back("-lc_p");
-          CmdArgs.push_back("-lpthread_p");
-          CmdArgs.push_back("--end-group");
-        } else {
-          CmdArgs.push_back("-lc_p");
-        }
-      }
-      CmdArgs.push_back("-lgcc_p");
-    } else {
-      if (Args.hasArg(options::OPT_static)) {
-        CmdArgs.push_back("--start-group");
-        CmdArgs.push_back("-lc");
-        CmdArgs.push_back("-lpthread");
-        CmdArgs.push_back("--end-group");
-      } else {
-        CmdArgs.push_back("-lc");
-      }
-      CmdArgs.push_back("-lcompiler_rt");
-    }
-
-    if (Args.hasArg(options::OPT_static)) {
-      CmdArgs.push_back("-lstdc++");
-    } else if (Args.hasArg(options::OPT_pg)) {
-      CmdArgs.push_back("-lgcc_eh_p");
-    } else {
-      CmdArgs.push_back("--as-needed");
-      CmdArgs.push_back("-lstdc++");
-      CmdArgs.push_back("--no-as-needed");
-    }
-  }
-
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
-    else
-      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
-    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
-  }
-
-  const char *Exec =
-#ifdef LLVM_ON_WIN32
-      Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld.gold"));
-#else
-      Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld"));
-#endif
-
-  C.addCommand(llvm::make_unique<Command>(JA, T, Exec, CmdArgs, Inputs));
-}
-
-void PS4cpu::Link::ConstructJob(Compilation &C, const JobAction &JA,
-                                const InputInfo &Output,
-                                const InputInfoList &Inputs,
-                                const ArgList &Args,
-                                const char *LinkingOutput) const {
-  const toolchains::FreeBSD &ToolChain =
-      static_cast<const toolchains::FreeBSD &>(getToolChain());
-  const Driver &D = ToolChain.getDriver();
-  bool PS4Linker;
-  StringRef LinkerOptName;
-  if (const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
-    LinkerOptName = A->getValue();
-    if (LinkerOptName != "ps4" && LinkerOptName != "gold")
-      D.Diag(diag::err_drv_unsupported_linker) << LinkerOptName;
-  }
-
-  if (LinkerOptName == "gold")
-    PS4Linker = false;
-  else if (LinkerOptName == "ps4")
-    PS4Linker = true;
-  else
-    PS4Linker = !Args.hasArg(options::OPT_shared);
-
-  if (PS4Linker)
-    ConstructPS4LinkJob(*this, C, JA, Output, Inputs, Args, LinkingOutput);
-  else
-    ConstructGoldLinkJob(*this, C, JA, Output, Inputs, Args, LinkingOutput);
-}
-
-void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
-                                    const InputInfo &Output,
-                                    const InputInfoList &Inputs,
-                                    const ArgList &Args,
-                                    const char *LinkingOutput) const {
-  const auto &TC =
-      static_cast<const toolchains::CudaToolChain &>(getToolChain());
-  assert(TC.getTriple().isNVPTX() && "Wrong platform");
-
-  // Obtain architecture from the action.
-  CudaArch gpu_arch = StringToCudaArch(JA.getOffloadingArch());
-  assert(gpu_arch != CudaArch::UNKNOWN &&
-         "Device action expected to have an architecture.");
-
-  // Check that our installation's ptxas supports gpu_arch.
-  if (!Args.hasArg(options::OPT_no_cuda_version_check)) {
-    TC.CudaInstallation.CheckCudaVersionSupportsArch(gpu_arch);
-  }
-
-  ArgStringList CmdArgs;
-  CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-m64" : "-m32");
-  if (Args.hasFlag(options::OPT_cuda_noopt_device_debug,
-                   options::OPT_no_cuda_noopt_device_debug, false)) {
-    // ptxas does not accept -g option if optimization is enabled, so
-    // we ignore the compiler's -O* options if we want debug info.
-    CmdArgs.push_back("-g");
-    CmdArgs.push_back("--dont-merge-basicblocks");
-    CmdArgs.push_back("--return-at-end");
-  } else if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    // Map the -O we received to -O{0,1,2,3}.
-    //
-    // TODO: Perhaps we should map host -O2 to ptxas -O3. -O3 is ptxas's
-    // default, so it may correspond more closely to the spirit of clang -O2.
-
-    // -O3 seems like the least-bad option when -Osomething is specified to
-    // clang but it isn't handled below.
-    StringRef OOpt = "3";
-    if (A->getOption().matches(options::OPT_O4) ||
-        A->getOption().matches(options::OPT_Ofast))
-      OOpt = "3";
-    else if (A->getOption().matches(options::OPT_O0))
-      OOpt = "0";
-    else if (A->getOption().matches(options::OPT_O)) {
-      // -Os, -Oz, and -O(anything else) map to -O2, for lack of better options.
-      OOpt = llvm::StringSwitch<const char *>(A->getValue())
-                 .Case("1", "1")
-                 .Case("2", "2")
-                 .Case("3", "3")
-                 .Case("s", "2")
-                 .Case("z", "2")
-                 .Default("2");
-    }
-    CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt));
-  } else {
-    // If no -O was passed, pass -O0 to ptxas -- no opt flag should correspond
-    // to no optimizations, but ptxas's default is -O3.
-    CmdArgs.push_back("-O0");
-  }
-
-  CmdArgs.push_back("--gpu-name");
-  CmdArgs.push_back(Args.MakeArgString(CudaArchToString(gpu_arch)));
-  CmdArgs.push_back("--output-file");
-  CmdArgs.push_back(Args.MakeArgString(Output.getFilename()));
-  for (const auto& II : Inputs)
-    CmdArgs.push_back(Args.MakeArgString(II.getFilename()));
-
-  for (const auto& A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
-    CmdArgs.push_back(Args.MakeArgString(A));
-
-  const char *Exec = Args.MakeArgString(TC.GetProgramPath("ptxas"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
-
-// All inputs to this linker must be from CudaDeviceActions, as we need to look
-// at the Inputs' Actions in order to figure out which GPU architecture they
-// correspond to.
-void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA,
-                                 const InputInfo &Output,
-                                 const InputInfoList &Inputs,
-                                 const ArgList &Args,
-                                 const char *LinkingOutput) const {
-  const auto &TC =
-      static_cast<const toolchains::CudaToolChain &>(getToolChain());
-  assert(TC.getTriple().isNVPTX() && "Wrong platform");
-
-  ArgStringList CmdArgs;
-  CmdArgs.push_back("--cuda");
-  CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-64" : "-32");
-  CmdArgs.push_back(Args.MakeArgString("--create"));
-  CmdArgs.push_back(Args.MakeArgString(Output.getFilename()));
-
-  for (const auto& II : Inputs) {
-    auto *A = II.getAction();
-    assert(A->getInputs().size() == 1 &&
-           "Device offload action is expected to have a single input");
-    const char *gpu_arch_str = A->getOffloadingArch();
-    assert(gpu_arch_str &&
-           "Device action expected to have associated a GPU architecture!");
-    CudaArch gpu_arch = StringToCudaArch(gpu_arch_str);
-
-    // We need to pass an Arch of the form "sm_XX" for cubin files and
-    // "compute_XX" for ptx.
-    const char *Arch =
-        (II.getType() == types::TY_PP_Asm)
-            ? CudaVirtualArchToString(VirtualArchForCudaArch(gpu_arch))
-            : gpu_arch_str;
-    CmdArgs.push_back(Args.MakeArgString(llvm::Twine("--image=profile=") +
-                                         Arch + ",file=" + II.getFilename()));
-  }
-
-  for (const auto& A : Args.getAllArgValues(options::OPT_Xcuda_fatbinary))
-    CmdArgs.push_back(Args.MakeArgString(A));
-
-  const char *Exec = Args.MakeArgString(TC.GetProgramPath("fatbinary"));
-  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
-}
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
deleted file mode 100644
index 98dcf84..0000000
--- a/lib/Driver/Tools.h
+++ /dev/null
@@ -1,997 +0,0 @@
-//===--- Tools.h - Tool Implementations -------------------------*- 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_LIB_DRIVER_TOOLS_H
-#define LLVM_CLANG_LIB_DRIVER_TOOLS_H
-
-#include "clang/Basic/DebugInfoOptions.h"
-#include "clang/Basic/VersionTuple.h"
-#include "clang/Driver/Tool.h"
-#include "clang/Driver/Types.h"
-#include "clang/Driver/Util.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-class ObjCRuntime;
-
-namespace driver {
-class Command;
-class Driver;
-
-namespace toolchains {
-class MachO;
-}
-
-namespace tools {
-
-namespace visualstudio {
-class Compiler;
-}
-
-using llvm::opt::ArgStringList;
-
-SmallString<128> getCompilerRT(const ToolChain &TC,
-                               const llvm::opt::ArgList &Args,
-                               StringRef Component, bool Shared = false);
-
-/// \brief Clang compiler tool.
-class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
-public:
-  static const char *getBaseInputName(const llvm::opt::ArgList &Args,
-                                      const InputInfo &Input);
-  static const char *getBaseInputStem(const llvm::opt::ArgList &Args,
-                                      const InputInfoList &Inputs);
-  static const char *getDependencyFileName(const llvm::opt::ArgList &Args,
-                                           const InputInfoList &Inputs);
-
-private:
-  void AddPreprocessingOptions(Compilation &C, const JobAction &JA,
-                               const Driver &D, const llvm::opt::ArgList &Args,
-                               llvm::opt::ArgStringList &CmdArgs,
-                               const InputInfo &Output,
-                               const InputInfoList &Inputs) const;
-
-  void AddAArch64TargetArgs(const llvm::opt::ArgList &Args,
-                            llvm::opt::ArgStringList &CmdArgs) const;
-  void AddARMTargetArgs(const llvm::Triple &Triple,
-                        const llvm::opt::ArgList &Args,
-                        llvm::opt::ArgStringList &CmdArgs,
-                        bool KernelOrKext) const;
-  void AddARM64TargetArgs(const llvm::opt::ArgList &Args,
-                          llvm::opt::ArgStringList &CmdArgs) const;
-  void AddMIPSTargetArgs(const llvm::opt::ArgList &Args,
-                         llvm::opt::ArgStringList &CmdArgs) const;
-  void AddPPCTargetArgs(const llvm::opt::ArgList &Args,
-                        llvm::opt::ArgStringList &CmdArgs) const;
-  void AddR600TargetArgs(const llvm::opt::ArgList &Args,
-                         llvm::opt::ArgStringList &CmdArgs) const;
-  void AddSparcTargetArgs(const llvm::opt::ArgList &Args,
-                          llvm::opt::ArgStringList &CmdArgs) const;
-  void AddSystemZTargetArgs(const llvm::opt::ArgList &Args,
-                            llvm::opt::ArgStringList &CmdArgs) const;
-  void AddX86TargetArgs(const llvm::opt::ArgList &Args,
-                        llvm::opt::ArgStringList &CmdArgs) const;
-  void AddHexagonTargetArgs(const llvm::opt::ArgList &Args,
-                            llvm::opt::ArgStringList &CmdArgs) const;
-  void AddLanaiTargetArgs(const llvm::opt::ArgList &Args,
-                          llvm::opt::ArgStringList &CmdArgs) const;
-  void AddWebAssemblyTargetArgs(const llvm::opt::ArgList &Args,
-                                llvm::opt::ArgStringList &CmdArgs) const;
-
-  enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile };
-
-  ObjCRuntime AddObjCRuntimeArgs(const llvm::opt::ArgList &args,
-                                 llvm::opt::ArgStringList &cmdArgs,
-                                 RewriteKind rewrite) const;
-
-  void AddClangCLArgs(const llvm::opt::ArgList &Args, types::ID InputType,
-                      llvm::opt::ArgStringList &CmdArgs,
-                      codegenoptions::DebugInfoKind *DebugInfoKind,
-                      bool *EmitCodeView) const;
-
-  visualstudio::Compiler *getCLFallback() const;
-
-  mutable std::unique_ptr<visualstudio::Compiler> CLFallback;
-
-  mutable std::unique_ptr<llvm::raw_fd_ostream> CompilationDatabase = nullptr;
-  void DumpCompilationDatabase(Compilation &C, StringRef Filename,
-                               StringRef Target,
-                               const InputInfo &Output, const InputInfo &Input,
-                               const llvm::opt::ArgList &Args) const;
-
-public:
-  // CAUTION! The first constructor argument ("clang") is not arbitrary,
-  // as it is for other tools. Some operations on a Tool actually test
-  // whether that tool is Clang based on the Tool's Name as a string.
-  Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC, RF_Full) {}
-
-  bool hasGoodDiagnostics() const override { return true; }
-  bool hasIntegratedAssembler() const override { return true; }
-  bool hasIntegratedCPP() const override { return true; }
-  bool canEmitIR() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-/// \brief Clang integrated assembler tool.
-class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
-public:
-  ClangAs(const ToolChain &TC)
-      : Tool("clang::as", "clang integrated assembler", TC, RF_Full) {}
-  void AddMIPSTargetArgs(const llvm::opt::ArgList &Args,
-                         llvm::opt::ArgStringList &CmdArgs) const;
-  void AddX86TargetArgs(const llvm::opt::ArgList &Args,
-                        llvm::opt::ArgStringList &CmdArgs) const;
-  bool hasGoodDiagnostics() const override { return true; }
-  bool hasIntegratedAssembler() const override { return false; }
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-/// Offload bundler tool.
-class LLVM_LIBRARY_VISIBILITY OffloadBundler final : public Tool {
-public:
-  OffloadBundler(const ToolChain &TC)
-      : Tool("offload bundler", "clang-offload-bundler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-  void ConstructJobMultipleOutputs(Compilation &C, const JobAction &JA,
-                                   const InputInfoList &Outputs,
-                                   const InputInfoList &Inputs,
-                                   const llvm::opt::ArgList &TCArgs,
-                                   const char *LinkingOutput) const override;
-};
-
-/// \brief Base class for all GNU tools that provide the same behavior when
-/// it comes to response files support
-class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool {
-  virtual void anchor();
-
-public:
-  GnuTool(const char *Name, const char *ShortName, const ToolChain &TC)
-      : Tool(Name, ShortName, TC, RF_Full, llvm::sys::WEM_CurrentCodePage) {}
-};
-
-/// gcc - Generic GCC tool implementations.
-namespace gcc {
-class LLVM_LIBRARY_VISIBILITY Common : public GnuTool {
-public:
-  Common(const char *Name, const char *ShortName, const ToolChain &TC)
-      : GnuTool(Name, ShortName, TC) {}
-
-  // A gcc tool has an "integrated" assembler that it will call to produce an
-  // object. Let it use that assembler so that we don't have to deal with
-  // assembly syntax incompatibilities.
-  bool hasIntegratedAssembler() const override { return true; }
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-
-  /// RenderExtraToolArgs - Render any arguments necessary to force
-  /// the particular tool mode.
-  virtual void RenderExtraToolArgs(const JobAction &JA,
-                                   llvm::opt::ArgStringList &CmdArgs) const = 0;
-};
-
-class LLVM_LIBRARY_VISIBILITY Preprocessor : public Common {
-public:
-  Preprocessor(const ToolChain &TC)
-      : Common("gcc::Preprocessor", "gcc preprocessor", TC) {}
-
-  bool hasGoodDiagnostics() const override { return true; }
-  bool hasIntegratedCPP() const override { return false; }
-
-  void RenderExtraToolArgs(const JobAction &JA,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Compiler : public Common {
-public:
-  Compiler(const ToolChain &TC) : Common("gcc::Compiler", "gcc frontend", TC) {}
-
-  bool hasGoodDiagnostics() const override { return true; }
-  bool hasIntegratedCPP() const override { return true; }
-
-  void RenderExtraToolArgs(const JobAction &JA,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public Common {
-public:
-  Linker(const ToolChain &TC) : Common("gcc::Linker", "linker (via gcc)", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void RenderExtraToolArgs(const JobAction &JA,
-                           llvm::opt::ArgStringList &CmdArgs) const override;
-};
-} // end namespace gcc
-
-namespace hexagon {
-// For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile
-// and Compile.
-// We simply use "clang -cc1" for those actions.
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
-public:
-  Assembler(const ToolChain &TC)
-      : GnuTool("hexagon::Assembler", "hexagon-as", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void RenderExtraToolArgs(const JobAction &JA,
-                           llvm::opt::ArgStringList &CmdArgs) const;
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("hexagon::Linker", "hexagon-ld", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  virtual void RenderExtraToolArgs(const JobAction &JA,
-                                   llvm::opt::ArgStringList &CmdArgs) const;
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace hexagon.
-
-namespace amdgpu {
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("amdgpu::Linker", "ld.lld", TC) {}
-  bool isLinkJob() const override { return true; }
-  bool hasIntegratedCPP() const override { return false; }
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-} // end namespace amdgpu
-
-namespace wasm {
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  explicit Linker(const ToolChain &TC);
-  bool isLinkJob() const override;
-  bool hasIntegratedCPP() const override;
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-} // end namespace wasm
-
-namespace arm {
-std::string getARMTargetCPU(StringRef CPU, StringRef Arch,
-                            const llvm::Triple &Triple);
-const std::string getARMArch(StringRef Arch,
-                             const llvm::Triple &Triple);
-StringRef getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple);
-StringRef getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
-                                  const llvm::Triple &Triple);
-
-void appendEBLinkFlags(const llvm::opt::ArgList &Args, ArgStringList &CmdArgs,
-                       const llvm::Triple &Triple);
-} // end namespace arm
-
-namespace mips {
-typedef enum { NanLegacy = 1, Nan2008 = 2 } NanEncoding;
-
-enum class FloatABI {
-  Invalid,
-  Soft,
-  Hard,
-};
-
-NanEncoding getSupportedNanEncoding(StringRef &CPU);
-bool hasCompactBranches(StringRef &CPU);
-void getMipsCPUAndABI(const llvm::opt::ArgList &Args,
-                      const llvm::Triple &Triple, StringRef &CPUName,
-                      StringRef &ABIName);
-std::string getMipsABILibSuffix(const llvm::opt::ArgList &Args,
-                                const llvm::Triple &Triple);
-bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value);
-bool isUCLibc(const llvm::opt::ArgList &Args);
-bool isNaN2008(const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
-bool isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName);
-bool isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
-                   StringRef ABIName, mips::FloatABI FloatABI);
-bool shouldUseFPXX(const llvm::opt::ArgList &Args, const llvm::Triple &Triple,
-                   StringRef CPUName, StringRef ABIName,
-                   mips::FloatABI FloatABI);
-} // end namespace mips
-
-namespace ppc {
-bool hasPPCAbiArg(const llvm::opt::ArgList &Args, const char *Value);
-} // end namespace ppc
-
-/// cloudabi -- Directly call GNU Binutils linker
-namespace cloudabi {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("cloudabi::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace cloudabi
-
-namespace darwin {
-llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str);
-void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str);
-
-class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool {
-  virtual void anchor();
-
-protected:
-  void AddMachOArch(const llvm::opt::ArgList &Args,
-                    llvm::opt::ArgStringList &CmdArgs) const;
-
-  const toolchains::MachO &getMachOToolChain() const {
-    return reinterpret_cast<const toolchains::MachO &>(getToolChain());
-  }
-
-public:
-  MachOTool(
-      const char *Name, const char *ShortName, const ToolChain &TC,
-      ResponseFileSupport ResponseSupport = RF_None,
-      llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8,
-      const char *ResponseFlag = "@")
-      : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding,
-             ResponseFlag) {}
-};
-
-class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool {
-public:
-  Assembler(const ToolChain &TC)
-      : MachOTool("darwin::Assembler", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool {
-  bool NeedsTempPath(const InputInfoList &Inputs) const;
-  void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args,
-                   llvm::opt::ArgStringList &CmdArgs,
-                   const InputInfoList &Inputs) const;
-
-public:
-  Linker(const ToolChain &TC)
-      : MachOTool("darwin::Linker", "linker", TC, RF_FileList,
-                  llvm::sys::WEM_UTF8, "-filelist") {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool {
-public:
-  Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool {
-public:
-  Dsymutil(const ToolChain &TC)
-      : MachOTool("darwin::Dsymutil", "dsymutil", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isDsymutilJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool {
-public:
-  VerifyDebug(const ToolChain &TC)
-      : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace darwin
-
-/// openbsd -- Directly call GNU Binutils assembler and linker
-namespace openbsd {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
-public:
-  Assembler(const ToolChain &TC)
-      : GnuTool("openbsd::Assembler", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("openbsd::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace openbsd
-
-/// bitrig -- Directly call GNU Binutils assembler and linker
-namespace bitrig {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
-public:
-  Assembler(const ToolChain &TC)
-      : GnuTool("bitrig::Assembler", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("bitrig::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace bitrig
-
-/// freebsd -- Directly call GNU Binutils assembler and linker
-namespace freebsd {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
-public:
-  Assembler(const ToolChain &TC)
-      : GnuTool("freebsd::Assembler", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("freebsd::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace freebsd
-
-/// netbsd -- Directly call GNU Binutils assembler and linker
-namespace netbsd {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
-public:
-  Assembler(const ToolChain &TC)
-      : GnuTool("netbsd::Assembler", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("netbsd::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace netbsd
-
-/// Directly call GNU Binutils' assembler and linker.
-namespace gnutools {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
-public:
-  Assembler(const ToolChain &TC) : GnuTool("GNU::Assembler", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("GNU::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace gnutools
-
-namespace nacltools {
-class LLVM_LIBRARY_VISIBILITY AssemblerARM : public gnutools::Assembler {
-public:
-  AssemblerARM(const ToolChain &TC) : gnutools::Assembler(TC) {}
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("NaCl::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace nacltools
-
-namespace fuchsia {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("fuchsia::Linker", "ld.lld", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace fuchsia
-
-/// minix -- Directly call GNU Binutils assembler and linker
-namespace minix {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
-public:
-  Assembler(const ToolChain &TC)
-      : GnuTool("minix::Assembler", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("minix::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace minix
-
-/// solaris -- Directly call Solaris assembler and linker
-namespace solaris {
-class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
-public:
-  Assembler(const ToolChain &TC)
-      : Tool("solaris::Assembler", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
-public:
-  Linker(const ToolChain &TC) : Tool("solaris::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace solaris
-
-/// dragonfly -- Directly call GNU Binutils assembler and linker
-namespace dragonfly {
-class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
-public:
-  Assembler(const ToolChain &TC)
-      : GnuTool("dragonfly::Assembler", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("dragonfly::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace dragonfly
-
-/// Visual studio tools.
-namespace visualstudio {
-class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
-public:
-  Linker(const ToolChain &TC)
-      : Tool("visualstudio::Linker", "linker", TC, RF_Full,
-             llvm::sys::WEM_UTF16) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Compiler : public Tool {
-public:
-  Compiler(const ToolChain &TC)
-      : Tool("visualstudio::Compiler", "compiler", TC, RF_Full,
-             llvm::sys::WEM_UTF16) {}
-
-  bool hasIntegratedAssembler() const override { return true; }
-  bool hasIntegratedCPP() const override { return true; }
-  bool isLinkJob() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-
-  std::unique_ptr<Command> GetCommand(Compilation &C, const JobAction &JA,
-                                      const InputInfo &Output,
-                                      const InputInfoList &Inputs,
-                                      const llvm::opt::ArgList &TCArgs,
-                                      const char *LinkingOutput) const;
-};
-} // end namespace visualstudio
-
-/// MinGW -- Directly call GNU Binutils assembler and linker
-namespace MinGW {
-class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
-public:
-  Assembler(const ToolChain &TC) : Tool("MinGW::Assemble", "assembler", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
-public:
-  Linker(const ToolChain &TC) : Tool("MinGW::Linker", "linker", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-
-private:
-  void AddLibGCC(const llvm::opt::ArgList &Args, ArgStringList &CmdArgs) const;
-};
-} // end namespace MinGW
-
-namespace arm {
-enum class FloatABI {
-  Invalid,
-  Soft,
-  SoftFP,
-  Hard,
-};
-
-FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args);
-} // end namespace arm
-
-namespace ppc {
-enum class FloatABI {
-  Invalid,
-  Soft,
-  Hard,
-};
-
-FloatABI getPPCFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
-} // end namespace ppc
-
-namespace sparc {
-enum class FloatABI {
-  Invalid,
-  Soft,
-  Hard,
-};
-
-FloatABI getSparcFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
-} // end namespace sparc
-
-namespace XCore {
-// For XCore, we do not need to instantiate tools for PreProcess, PreCompile and
-// Compile.
-// We simply use "clang -cc1" for those actions.
-class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
-public:
-  Assembler(const ToolChain &TC) : Tool("XCore::Assembler", "XCore-as", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
-public:
-  Linker(const ToolChain &TC) : Tool("XCore::Linker", "XCore-ld", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace XCore.
-
-namespace CrossWindows {
-class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
-public:
-  Assembler(const ToolChain &TC) : Tool("CrossWindows::Assembler", "as", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
-public:
-  Linker(const ToolChain &TC)
-      : Tool("CrossWindows::Linker", "ld", TC, RF_Full) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace CrossWindows
-
-/// SHAVE tools -- Directly call moviCompile and moviAsm
-namespace SHAVE {
-class LLVM_LIBRARY_VISIBILITY Compiler : public Tool {
-public:
-  Compiler(const ToolChain &TC) : Tool("moviCompile", "movicompile", TC) {}
-
-  bool hasIntegratedCPP() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
-public:
-  Assembler(const ToolChain &TC) : Tool("moviAsm", "moviAsm", TC) {}
-
-  bool hasIntegratedCPP() const override { return false; } // not sure.
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace SHAVE
-
-/// The Myriad toolchain uses tools that are in two different namespaces.
-/// The Compiler and Assembler as defined above are in the SHAVE namespace,
-/// whereas the linker, which accepts code for a mixture of Sparc and SHAVE,
-/// is in the Myriad namespace.
-namespace Myriad {
-class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
-public:
-  Linker(const ToolChain &TC) : GnuTool("shave::Linker", "ld", TC) {}
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output, const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace Myriad
-
-namespace PS4cpu {
-class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
-public:
-  Assemble(const ToolChain &TC)
-      : Tool("PS4cpu::Assemble", "assembler", TC, RF_Full) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output,
-                    const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY Link : public Tool {
-public:
-  Link(const ToolChain &TC) : Tool("PS4cpu::Link", "linker", TC, RF_Full) {}
-
-  bool hasIntegratedCPP() const override { return false; }
-  bool isLinkJob() const override { return true; }
-
-  void ConstructJob(Compilation &C, const JobAction &JA,
-                    const InputInfo &Output,
-                    const InputInfoList &Inputs,
-                    const llvm::opt::ArgList &TCArgs,
-                    const char *LinkingOutput) const override;
-};
-} // end namespace PS4cpu
-
-namespace NVPTX {
-
-// Run ptxas, the NVPTX assembler.
-class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
- public:
-   Assembler(const ToolChain &TC)
-       : Tool("NVPTX::Assembler", "ptxas", TC, RF_Full, llvm::sys::WEM_UTF8,
-              "--options-file") {}
-
-   bool hasIntegratedCPP() const override { return false; }
-
-   void ConstructJob(Compilation &C, const JobAction &JA,
-                     const InputInfo &Output, const InputInfoList &Inputs,
-                     const llvm::opt::ArgList &TCArgs,
-                     const char *LinkingOutput) const override;
-};
-
-// Runs fatbinary, which combines GPU object files ("cubin" files) and/or PTX
-// assembly into a single output file.
-class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
- public:
-   Linker(const ToolChain &TC)
-       : Tool("NVPTX::Linker", "fatbinary", TC, RF_Full, llvm::sys::WEM_UTF8,
-              "--options-file") {}
-
-   bool hasIntegratedCPP() const override { return false; }
-
-   void ConstructJob(Compilation &C, const JobAction &JA,
-                     const InputInfo &Output, const InputInfoList &Inputs,
-                     const llvm::opt::ArgList &TCArgs,
-                     const char *LinkingOutput) const override;
-};
-
-}  // end namespace NVPTX
-
-} // end namespace tools
-} // end namespace driver
-} // end namespace clang
-
-#endif // LLVM_CLANG_LIB_DRIVER_TOOLS_H
diff --git a/lib/Edit/RewriteObjCFoundationAPI.cpp b/lib/Edit/RewriteObjCFoundationAPI.cpp
index 0ae1ec7..2148316 100644
--- a/lib/Edit/RewriteObjCFoundationAPI.cpp
+++ b/lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -1076,6 +1076,7 @@
     case CK_CopyAndAutoreleaseBlockObject:
     case CK_BuiltinFnToFnPtr:
     case CK_ZeroToOCLEvent:
+    case CK_ZeroToOCLQueue:
     case CK_IntToOCLSampler:
       return false;
 
diff --git a/lib/Format/BreakableToken.cpp b/lib/Format/BreakableToken.cpp
index 6363f89..b42e4ae 100644
--- a/lib/Format/BreakableToken.cpp
+++ b/lib/Format/BreakableToken.cpp
@@ -14,7 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "BreakableToken.h"
-#include "Comments.h"
+#include "ContinuationIndenter.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Format/Format.h"
 #include "llvm/ADT/STLExtras.h"
@@ -40,6 +40,21 @@
   }
 }
 
+static StringRef getLineCommentIndentPrefix(StringRef Comment) {
+  static const char *const KnownPrefixes[] = {"///", "//", "//!"};
+  StringRef LongestPrefix;
+  for (StringRef KnownPrefix : KnownPrefixes) {
+    if (Comment.startswith(KnownPrefix)) {
+      size_t PrefixLength = KnownPrefix.size();
+      while (PrefixLength < Comment.size() && Comment[PrefixLength] == ' ')
+        ++PrefixLength;
+      if (PrefixLength > LongestPrefix.size())
+        LongestPrefix = Comment.substr(0, PrefixLength);
+    }
+  }
+  return LongestPrefix;
+}
+
 static BreakableToken::Split getCommentSplit(StringRef Text,
                                              unsigned ContentStartColumn,
                                              unsigned ColumnLimit,
@@ -132,21 +147,44 @@
   return BreakableToken::Split(StringRef::npos, 0);
 }
 
+bool switchesFormatting(const FormatToken &Token) {
+  assert((Token.is(TT_BlockComment) || Token.is(TT_LineComment)) &&
+         "formatting regions are switched by comment tokens");
+  StringRef Content = Token.TokenText.substr(2).ltrim();
+  return Content.startswith("clang-format on") ||
+         Content.startswith("clang-format off");
+}
+
+unsigned
+BreakableToken::getLineLengthAfterCompression(unsigned RemainingTokenColumns,
+                                              Split Split) const {
+  // Example: consider the content
+  // lala  lala
+  // - RemainingTokenColumns is the original number of columns, 10;
+  // - Split is (4, 2), denoting the two spaces between the two words;
+  //
+  // We compute the number of columns when the split is compressed into a single
+  // space, like:
+  // lala lala
+  return RemainingTokenColumns + 1 - Split.second;
+}
+
 unsigned BreakableSingleLineToken::getLineCount() const { return 1; }
 
 unsigned BreakableSingleLineToken::getLineLengthAfterSplit(
-    unsigned LineIndex, unsigned Offset, StringRef::size_type Length) const {
+    unsigned LineIndex, unsigned TailOffset,
+    StringRef::size_type Length) const {
   return StartColumn + Prefix.size() + Postfix.size() +
-         encoding::columnWidthWithTabs(Line.substr(Offset, Length),
+         encoding::columnWidthWithTabs(Line.substr(TailOffset, Length),
                                        StartColumn + Prefix.size(),
                                        Style.TabWidth, Encoding);
 }
 
 BreakableSingleLineToken::BreakableSingleLineToken(
-    const FormatToken &Tok, unsigned IndentLevel, unsigned StartColumn,
-    StringRef Prefix, StringRef Postfix, bool InPPDirective,
-    encoding::Encoding Encoding, const FormatStyle &Style)
-    : BreakableToken(Tok, IndentLevel, InPPDirective, Encoding, Style),
+    const FormatToken &Tok, unsigned StartColumn, StringRef Prefix,
+    StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding,
+    const FormatStyle &Style)
+    : BreakableToken(Tok, InPPDirective, Encoding, Style),
       StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix) {
   assert(Tok.TokenText.endswith(Postfix));
   Line = Tok.TokenText.substr(
@@ -154,15 +192,16 @@
 }
 
 BreakableStringLiteral::BreakableStringLiteral(
-    const FormatToken &Tok, unsigned IndentLevel, unsigned StartColumn,
-    StringRef Prefix, StringRef Postfix, bool InPPDirective,
-    encoding::Encoding Encoding, const FormatStyle &Style)
-    : BreakableSingleLineToken(Tok, IndentLevel, StartColumn, Prefix, Postfix,
-                               InPPDirective, Encoding, Style) {}
+    const FormatToken &Tok, unsigned StartColumn, StringRef Prefix,
+    StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding,
+    const FormatStyle &Style)
+    : BreakableSingleLineToken(Tok, StartColumn, Prefix, Postfix, InPPDirective,
+                               Encoding, Style) {}
 
 BreakableToken::Split
 BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset,
-                                 unsigned ColumnLimit) const {
+                                 unsigned ColumnLimit,
+                                 llvm::Regex &CommentPragmasRegex) const {
   return getStringSplit(Line.substr(TailOffset),
                         StartColumn + Prefix.size() + Postfix.size(),
                         ColumnLimit, Style.TabWidth, Encoding);
@@ -180,77 +219,147 @@
     --LeadingSpaces;
   Whitespaces.replaceWhitespaceInToken(
       Tok, Prefix.size() + TailOffset + Split.first, Split.second, Postfix,
-      Prefix, InPPDirective, 1, IndentLevel, LeadingSpaces);
+      Prefix, InPPDirective, 1, LeadingSpaces);
 }
 
-BreakableLineComment::BreakableLineComment(
-    const FormatToken &Token, unsigned IndentLevel, unsigned StartColumn,
-    bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style)
-    : BreakableSingleLineToken(Token, IndentLevel, StartColumn,
-                               getLineCommentIndentPrefix(Token.TokenText), "",
-                               InPPDirective, Encoding, Style) {
-  OriginalPrefix = Prefix;
-  if (Token.TokenText.size() > Prefix.size() &&
-      isAlphanumeric(Token.TokenText[Prefix.size()])) {
-    if (Prefix == "//")
-      Prefix = "// ";
-    else if (Prefix == "///")
-      Prefix = "/// ";
-    else if (Prefix == "//!")
-      Prefix = "//! ";
-  }
-}
+BreakableComment::BreakableComment(const FormatToken &Token,
+                                   unsigned StartColumn,
+                                   bool InPPDirective,
+                                   encoding::Encoding Encoding,
+                                   const FormatStyle &Style)
+    : BreakableToken(Token, InPPDirective, Encoding, Style),
+      StartColumn(StartColumn) {}
+
+unsigned BreakableComment::getLineCount() const { return Lines.size(); }
 
 BreakableToken::Split
-BreakableLineComment::getSplit(unsigned LineIndex, unsigned TailOffset,
-                               unsigned ColumnLimit) const {
-  return getCommentSplit(Line.substr(TailOffset), StartColumn + Prefix.size(),
+BreakableComment::getSplit(unsigned LineIndex, unsigned TailOffset,
+                           unsigned ColumnLimit,
+                           llvm::Regex &CommentPragmasRegex) const {
+  // Don't break lines matching the comment pragmas regex.
+  if (CommentPragmasRegex.match(Content[LineIndex]))
+    return Split(StringRef::npos, 0);
+  return getCommentSplit(Content[LineIndex].substr(TailOffset),
+                         getContentStartColumn(LineIndex, TailOffset),
                          ColumnLimit, Style.TabWidth, Encoding);
 }
 
-void BreakableLineComment::insertBreak(unsigned LineIndex, unsigned TailOffset,
-                                       Split Split,
-                                       WhitespaceManager &Whitespaces) {
+void BreakableComment::compressWhitespace(unsigned LineIndex,
+                                          unsigned TailOffset, Split Split,
+                                          WhitespaceManager &Whitespaces) {
+  StringRef Text = Content[LineIndex].substr(TailOffset);
+  // Text is relative to the content line, but Whitespaces operates relative to
+  // the start of the corresponding token, so compute the start of the Split
+  // that needs to be compressed into a single space relative to the start of
+  // its token.
+  unsigned BreakOffsetInToken =
+      Text.data() - tokenAt(LineIndex).TokenText.data() + Split.first;
+  unsigned CharsToRemove = Split.second;
   Whitespaces.replaceWhitespaceInToken(
-      Tok, OriginalPrefix.size() + TailOffset + Split.first, Split.second,
-      Postfix, Prefix, InPPDirective, /*Newlines=*/1, IndentLevel, StartColumn);
+      tokenAt(LineIndex), BreakOffsetInToken, CharsToRemove, "", "",
+      /*InPPDirective=*/false, /*Newlines=*/0, /*Spaces=*/1);
 }
 
-void BreakableLineComment::replaceWhitespace(unsigned LineIndex,
-                                             unsigned TailOffset, Split Split,
-                                             WhitespaceManager &Whitespaces) {
-  Whitespaces.replaceWhitespaceInToken(
-      Tok, OriginalPrefix.size() + TailOffset + Split.first, Split.second, "",
-      "", /*InPPDirective=*/false, /*Newlines=*/0, /*IndentLevel=*/0,
-      /*Spaces=*/1);
-}
+BreakableToken::Split
+BreakableComment::getReflowSplit(StringRef Text, StringRef ReflowPrefix,
+                                 unsigned PreviousEndColumn,
+                                 unsigned ColumnLimit) const {
+  unsigned ReflowStartColumn = PreviousEndColumn + ReflowPrefix.size();
+  StringRef TrimmedText = Text.rtrim(Blanks);
+  // This is the width of the resulting line in case the full line of Text gets
+  // reflown up starting at ReflowStartColumn.
+  unsigned FullWidth = ReflowStartColumn + encoding::columnWidthWithTabs(
+                                               TrimmedText, ReflowStartColumn,
+                                               Style.TabWidth, Encoding);
+  // If the full line fits up, we return a reflow split after it,
+  // otherwise we compute the largest piece of text that fits after
+  // ReflowStartColumn.
+  Split ReflowSplit =
+      FullWidth <= ColumnLimit
+          ? Split(TrimmedText.size(), Text.size() - TrimmedText.size())
+          : getCommentSplit(Text, ReflowStartColumn, ColumnLimit,
+                            Style.TabWidth, Encoding);
 
-void BreakableLineComment::replaceWhitespaceBefore(
-    unsigned LineIndex, WhitespaceManager &Whitespaces) {
-  if (OriginalPrefix != Prefix) {
-    Whitespaces.replaceWhitespaceInToken(Tok, OriginalPrefix.size(), 0, "", "",
-                                         /*InPPDirective=*/false,
-                                         /*Newlines=*/0, /*IndentLevel=*/0,
-                                         /*Spaces=*/1);
+  // We need to be extra careful here, because while it's OK to keep a long line
+  // if it can't be broken into smaller pieces (like when the first word of a
+  // long line is longer than the column limit), it's not OK to reflow that long
+  // word up. So we recompute the size of the previous line after reflowing and
+  // only return the reflow split if that's under the line limit.
+  if (ReflowSplit.first != StringRef::npos &&
+      // Check if the width of the newly reflown line is under the limit.
+      PreviousEndColumn + ReflowPrefix.size() +
+              encoding::columnWidthWithTabs(Text.substr(0, ReflowSplit.first),
+                                            PreviousEndColumn +
+                                                ReflowPrefix.size(),
+                                            Style.TabWidth, Encoding) <=
+          ColumnLimit) {
+    return ReflowSplit;
   }
+  return Split(StringRef::npos, 0);
+}
+
+const FormatToken &BreakableComment::tokenAt(unsigned LineIndex) const {
+  return Tokens[LineIndex] ? *Tokens[LineIndex] : Tok;
+}
+
+static bool mayReflowContent(StringRef Content) {
+  Content = Content.trim(Blanks);
+  // Lines starting with '@' commonly have special meaning.
+  static const SmallVector<StringRef, 4> kSpecialMeaningPrefixes = {
+      "@", "TODO", "FIXME", "XXX"};
+  bool hasSpecialMeaningPrefix = false;
+  for (StringRef Prefix : kSpecialMeaningPrefixes) {
+    if (Content.startswith(Prefix)) {
+      hasSpecialMeaningPrefix = true;
+      break;
+    }
+  }
+  // Simple heuristic for what to reflow: content should contain at least two
+  // characters and either the first or second character must be
+  // non-punctuation.
+  return Content.size() >= 2 && !hasSpecialMeaningPrefix &&
+         !Content.endswith("\\") &&
+         // Note that this is UTF-8 safe, since if isPunctuation(Content[0]) is
+         // true, then the first code point must be 1 byte long.
+         (!isPunctuation(Content[0]) || !isPunctuation(Content[1]));
 }
 
 BreakableBlockComment::BreakableBlockComment(
-    const FormatToken &Token, unsigned IndentLevel, unsigned StartColumn,
+    const FormatToken &Token, unsigned StartColumn,
     unsigned OriginalStartColumn, bool FirstInLine, bool InPPDirective,
     encoding::Encoding Encoding, const FormatStyle &Style)
-    : BreakableToken(Token, IndentLevel, InPPDirective, Encoding, Style) {
-  StringRef TokenText(Token.TokenText);
+    : BreakableComment(Token, StartColumn, InPPDirective, Encoding, Style) {
+  assert(Tok.is(TT_BlockComment) &&
+         "block comment section must start with a block comment");
+
+  StringRef TokenText(Tok.TokenText);
   assert(TokenText.startswith("/*") && TokenText.endswith("*/"));
   TokenText.substr(2, TokenText.size() - 4).split(Lines, "\n");
 
   int IndentDelta = StartColumn - OriginalStartColumn;
-  LeadingWhitespace.resize(Lines.size());
-  StartOfLineColumn.resize(Lines.size());
-  StartOfLineColumn[0] = StartColumn + 2;
+  Content.resize(Lines.size());
+  Content[0] = Lines[0];
+  ContentColumn.resize(Lines.size());
+  // Account for the initial '/*'.
+  ContentColumn[0] = StartColumn + 2;
+  Tokens.resize(Lines.size());
   for (size_t i = 1; i < Lines.size(); ++i)
     adjustWhitespace(i, IndentDelta);
 
+  // Align decorations with the column of the star on the first line,
+  // that is one column after the start "/*".
+  DecorationColumn = StartColumn + 1;
+
+  // Account for comment decoration patterns like this:
+  //
+  // /*
+  // ** blah blah blah
+  // */
+  if (Lines.size() >= 2 && Content[1].startswith("**") &&
+      static_cast<unsigned>(ContentColumn[1]) == StartColumn) {
+    DecorationColumn = StartColumn;
+  }
+
   Decoration = "* ";
   if (Lines.size() == 1 && !FirstInLine) {
     // Comments for which FirstInLine is false can start on arbitrary column,
@@ -262,49 +371,60 @@
   }
   for (size_t i = 1, e = Lines.size(); i < e && !Decoration.empty(); ++i) {
     // If the last line is empty, the closing "*/" will have a star.
-    if (i + 1 == e && Lines[i].empty())
+    if (i + 1 == e && Content[i].empty())
       break;
-    if (!Lines[i].empty() && i + 1 != e && Decoration.startswith(Lines[i]))
+    if (!Content[i].empty() && i + 1 != e &&
+        Decoration.startswith(Content[i]))
       continue;
-    while (!Lines[i].startswith(Decoration))
+    while (!Content[i].startswith(Decoration))
       Decoration = Decoration.substr(0, Decoration.size() - 1);
   }
 
   LastLineNeedsDecoration = true;
-  IndentAtLineBreak = StartOfLineColumn[0] + 1;
-  for (size_t i = 1; i < Lines.size(); ++i) {
-    if (Lines[i].empty()) {
-      if (i + 1 == Lines.size()) {
+  IndentAtLineBreak = ContentColumn[0] + 1;
+  for (size_t i = 1, e = Lines.size(); i < e; ++i) {
+    if (Content[i].empty()) {
+      if (i + 1 == e) {
         // Empty last line means that we already have a star as a part of the
         // trailing */. We also need to preserve whitespace, so that */ is
         // correctly indented.
         LastLineNeedsDecoration = false;
+        // Align the star in the last '*/' with the stars on the previous lines.
+        if (e >= 2 && !Decoration.empty()) {
+          ContentColumn[i] = DecorationColumn;
+        }
       } else if (Decoration.empty()) {
         // For all other lines, set the start column to 0 if they're empty, so
         // we do not insert trailing whitespace anywhere.
-        StartOfLineColumn[i] = 0;
+        ContentColumn[i] = 0;
       }
       continue;
     }
 
     // The first line already excludes the star.
+    // The last line excludes the star if LastLineNeedsDecoration is false.
     // For all other lines, adjust the line to exclude the star and
     // (optionally) the first whitespace.
-    unsigned DecorationSize =
-        Decoration.startswith(Lines[i]) ? Lines[i].size() : Decoration.size();
-    StartOfLineColumn[i] += DecorationSize;
-    Lines[i] = Lines[i].substr(DecorationSize);
-    LeadingWhitespace[i] += DecorationSize;
-    if (!Decoration.startswith(Lines[i]))
+    unsigned DecorationSize = Decoration.startswith(Content[i])
+                                  ? Content[i].size()
+                                  : Decoration.size();
+    if (DecorationSize) {
+      ContentColumn[i] = DecorationColumn + DecorationSize;
+    }
+    Content[i] = Content[i].substr(DecorationSize);
+    if (!Decoration.startswith(Content[i]))
       IndentAtLineBreak =
-          std::min<int>(IndentAtLineBreak, std::max(0, StartOfLineColumn[i]));
+          std::min<int>(IndentAtLineBreak, std::max(0, ContentColumn[i]));
   }
-  IndentAtLineBreak = std::max<unsigned>(IndentAtLineBreak, Decoration.size());
+  IndentAtLineBreak =
+      std::max<unsigned>(IndentAtLineBreak, Decoration.size());
+
   DEBUG({
     llvm::dbgs() << "IndentAtLineBreak " << IndentAtLineBreak << "\n";
     for (size_t i = 0; i < Lines.size(); ++i) {
-      llvm::dbgs() << i << " |" << Lines[i] << "| " << LeadingWhitespace[i]
-                   << "\n";
+      llvm::dbgs() << i << " |" << Content[i] << "| "
+                   << "CC=" << ContentColumn[i] << "| "
+                   << "IN=" << (Content[i].data() - Lines[i].data()) << "\n";
     }
   });
 }
@@ -334,78 +454,162 @@
 
   StringRef Whitespace = Lines[LineIndex].substr(0, StartOfLine);
   // Adjust Lines to only contain relevant text.
-  Lines[LineIndex - 1] = Lines[LineIndex - 1].substr(0, EndOfPreviousLine);
-  Lines[LineIndex] = Lines[LineIndex].substr(StartOfLine);
-  // Adjust LeadingWhitespace to account all whitespace between the lines
-  // to the current line.
-  LeadingWhitespace[LineIndex] =
-      Lines[LineIndex].begin() - Lines[LineIndex - 1].end();
+  size_t PreviousContentOffset =
+      Content[LineIndex - 1].data() - Lines[LineIndex - 1].data();
+  Content[LineIndex - 1] = Lines[LineIndex - 1].substr(
+      PreviousContentOffset, EndOfPreviousLine - PreviousContentOffset);
+  Content[LineIndex] = Lines[LineIndex].substr(StartOfLine);
 
   // Adjust the start column uniformly across all lines.
-  StartOfLineColumn[LineIndex] =
+  ContentColumn[LineIndex] =
       encoding::columnWidthWithTabs(Whitespace, 0, Style.TabWidth, Encoding) +
       IndentDelta;
 }
 
-unsigned BreakableBlockComment::getLineCount() const { return Lines.size(); }
-
 unsigned BreakableBlockComment::getLineLengthAfterSplit(
-    unsigned LineIndex, unsigned Offset, StringRef::size_type Length) const {
-  unsigned ContentStartColumn = getContentStartColumn(LineIndex, Offset);
-  return ContentStartColumn +
-         encoding::columnWidthWithTabs(Lines[LineIndex].substr(Offset, Length),
-                                       ContentStartColumn, Style.TabWidth,
-                                       Encoding) +
-         // The last line gets a "*/" postfix.
-         (LineIndex + 1 == Lines.size() ? 2 : 0);
-}
-
-BreakableToken::Split
-BreakableBlockComment::getSplit(unsigned LineIndex, unsigned TailOffset,
-                                unsigned ColumnLimit) const {
-  return getCommentSplit(Lines[LineIndex].substr(TailOffset),
-                         getContentStartColumn(LineIndex, TailOffset),
-                         ColumnLimit, Style.TabWidth, Encoding);
+    unsigned LineIndex, unsigned TailOffset,
+    StringRef::size_type Length) const {
+  unsigned ContentStartColumn = getContentStartColumn(LineIndex, TailOffset);
+  unsigned LineLength =
+      ContentStartColumn + encoding::columnWidthWithTabs(
+                               Content[LineIndex].substr(TailOffset, Length),
+                               ContentStartColumn, Style.TabWidth, Encoding);
+  // The last line gets a "*/" postfix.
+  if (LineIndex + 1 == Lines.size()) {
+    LineLength += 2;
+    // We never need a decoration when breaking just the trailing "*/" postfix.
+    // Note that checking that Length == 0 is not enough, since Length could
+    // also be StringRef::npos.
+    if (Content[LineIndex].substr(TailOffset, Length).empty()) {
+      LineLength -= Decoration.size();
+    }
+  }
+  return LineLength;
 }
 
 void BreakableBlockComment::insertBreak(unsigned LineIndex, unsigned TailOffset,
                                         Split Split,
                                         WhitespaceManager &Whitespaces) {
-  StringRef Text = Lines[LineIndex].substr(TailOffset);
+  StringRef Text = Content[LineIndex].substr(TailOffset);
   StringRef Prefix = Decoration;
+  // We need this to account for the case when we have a decoration "* " for all
+  // the lines except for the last one, where the star in "*/" acts as a
+  // decoration.
+  unsigned LocalIndentAtLineBreak = IndentAtLineBreak;
   if (LineIndex + 1 == Lines.size() &&
       Text.size() == Split.first + Split.second) {
     // For the last line we need to break before "*/", but not to add "* ".
     Prefix = "";
+    if (LocalIndentAtLineBreak >= 2)
+      LocalIndentAtLineBreak -= 2;
+  }
+  // The split offset is from the beginning of the line. Convert it to an offset
+  // from the beginning of the token text.
+  unsigned BreakOffsetInToken =
+      Text.data() - tokenAt(LineIndex).TokenText.data() + Split.first;
+  unsigned CharsToRemove = Split.second;
+  assert(LocalIndentAtLineBreak >= Prefix.size());
+  Whitespaces.replaceWhitespaceInToken(
+      tokenAt(LineIndex), BreakOffsetInToken, CharsToRemove, "", Prefix,
+      InPPDirective, /*Newlines=*/1,
+      /*Spaces=*/LocalIndentAtLineBreak - Prefix.size());
+}
+
+BreakableToken::Split BreakableBlockComment::getSplitBefore(
+    unsigned LineIndex,
+    unsigned PreviousEndColumn,
+    unsigned ColumnLimit,
+    llvm::Regex &CommentPragmasRegex) const {
+  if (!mayReflow(LineIndex, CommentPragmasRegex))
+    return Split(StringRef::npos, 0);
+  StringRef TrimmedContent = Content[LineIndex].ltrim(Blanks);
+  return getReflowSplit(TrimmedContent, ReflowPrefix, PreviousEndColumn,
+                        ColumnLimit);
+}
+
+unsigned BreakableBlockComment::getReflownColumn(
+    StringRef Content,
+    unsigned LineIndex,
+    unsigned PreviousEndColumn) const {
+    unsigned StartColumn = PreviousEndColumn + ReflowPrefix.size();
+    // If this is the last line, it will carry around its '*/' postfix.
+    unsigned PostfixLength = (LineIndex + 1 == Lines.size() ? 2 : 0);
+    // The line is composed of previous text, reflow prefix, reflown text and
+    // postfix.
+    unsigned ReflownColumn =
+        StartColumn + encoding::columnWidthWithTabs(Content, StartColumn,
+                                                    Style.TabWidth, Encoding) +
+        PostfixLength;
+    return ReflownColumn;
+}
+
+unsigned BreakableBlockComment::getLineLengthAfterSplitBefore(
+    unsigned LineIndex, unsigned TailOffset,
+    unsigned PreviousEndColumn,
+    unsigned ColumnLimit,
+    Split SplitBefore) const {
+  if (SplitBefore.first == StringRef::npos ||
+      // Block comment line contents contain the trailing whitespace after the
+      // decoration, so the need of left trim. Note that this behavior is
+      // consistent with the breaking of block comments where the indentation of
+      // a broken line is uniform across all the lines of the block comment.
+      SplitBefore.first + SplitBefore.second <
+          Content[LineIndex].ltrim().size()) {
+    // A piece of line, not the whole, gets reflown.
+    return getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
+  } else {
+    // The whole line gets reflown, need to check if we need to insert a break
+    // for the postfix or not.
+    StringRef TrimmedContent = Content[LineIndex].ltrim(Blanks);
+    unsigned ReflownColumn =
+        getReflownColumn(TrimmedContent, LineIndex, PreviousEndColumn);
+    if (ReflownColumn <= ColumnLimit) {
+      return ReflownColumn;
+    }
+    return getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
+  }
+}
+void BreakableBlockComment::replaceWhitespaceBefore(
+    unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit,
+    Split SplitBefore, WhitespaceManager &Whitespaces) {
+  if (LineIndex == 0) return;
+  StringRef TrimmedContent = Content[LineIndex].ltrim(Blanks);
+  if (SplitBefore.first != StringRef::npos) {
+    // Here we need to reflow.
+    assert(Tokens[LineIndex - 1] == Tokens[LineIndex] &&
+           "Reflowing whitespace within a token");
+    // This is the offset of the end of the last line relative to the start of
+    // the token text in the token.
+    unsigned WhitespaceOffsetInToken = Content[LineIndex - 1].data() +
+        Content[LineIndex - 1].size() -
+        tokenAt(LineIndex).TokenText.data();
+    unsigned WhitespaceLength = TrimmedContent.data() -
+        tokenAt(LineIndex).TokenText.data() -
+        WhitespaceOffsetInToken;
+    Whitespaces.replaceWhitespaceInToken(
+        tokenAt(LineIndex), WhitespaceOffsetInToken,
+        /*ReplaceChars=*/WhitespaceLength, /*PreviousPostfix=*/"",
+        /*CurrentPrefix=*/ReflowPrefix, InPPDirective, /*Newlines=*/0,
+        /*Spaces=*/0);
+    // Check if we need to also insert a break at the whitespace range.
+    // For this we first adapt the reflow split relative to the beginning of the
+    // content.
+    // Note that we don't need a penalty for this break, since it doesn't change
+    // the total number of lines.
+    Split BreakSplit = SplitBefore;
+    BreakSplit.first += TrimmedContent.data() - Content[LineIndex].data();
+    unsigned ReflownColumn =
+        getReflownColumn(TrimmedContent, LineIndex, PreviousEndColumn);
+    if (ReflownColumn > ColumnLimit) {
+      insertBreak(LineIndex, 0, BreakSplit, Whitespaces);
+    }
+    return;
   }
 
-  unsigned BreakOffsetInToken =
-      Text.data() - Tok.TokenText.data() + Split.first;
-  unsigned CharsToRemove = Split.second;
-  assert(IndentAtLineBreak >= Decoration.size());
-  Whitespaces.replaceWhitespaceInToken(
-      Tok, BreakOffsetInToken, CharsToRemove, "", Prefix, InPPDirective, 1,
-      IndentLevel, IndentAtLineBreak - Decoration.size());
-}
-
-void BreakableBlockComment::replaceWhitespace(unsigned LineIndex,
-                                              unsigned TailOffset, Split Split,
-                                              WhitespaceManager &Whitespaces) {
-  StringRef Text = Lines[LineIndex].substr(TailOffset);
-  unsigned BreakOffsetInToken =
-      Text.data() - Tok.TokenText.data() + Split.first;
-  unsigned CharsToRemove = Split.second;
-  Whitespaces.replaceWhitespaceInToken(
-      Tok, BreakOffsetInToken, CharsToRemove, "", "", /*InPPDirective=*/false,
-      /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1);
-}
-
-void BreakableBlockComment::replaceWhitespaceBefore(
-    unsigned LineIndex, WhitespaceManager &Whitespaces) {
-  if (LineIndex == 0)
-    return;
+  // Here no reflow with the previous line will happen.
+  // Fix the decoration of the line at LineIndex.
   StringRef Prefix = Decoration;
-  if (Lines[LineIndex].empty()) {
+  if (Content[LineIndex].empty()) {
     if (LineIndex + 1 == Lines.size()) {
       if (!LastLineNeedsDecoration) {
         // If the last line was empty, we don't need a prefix, as the */ will
@@ -418,19 +622,35 @@
       Prefix = Prefix.substr(0, 1);
     }
   } else {
-    if (StartOfLineColumn[LineIndex] == 1) {
+    if (ContentColumn[LineIndex] == 1) {
       // This line starts immediately after the decorating *.
       Prefix = Prefix.substr(0, 1);
     }
   }
-
-  unsigned WhitespaceOffsetInToken = Lines[LineIndex].data() -
-                                     Tok.TokenText.data() -
-                                     LeadingWhitespace[LineIndex];
+  // This is the offset of the end of the last line relative to the start of the
+  // token text in the token.
+  unsigned WhitespaceOffsetInToken = Content[LineIndex - 1].data() +
+                                     Content[LineIndex - 1].size() -
+                                     tokenAt(LineIndex).TokenText.data();
+  unsigned WhitespaceLength = Content[LineIndex].data() -
+                              tokenAt(LineIndex).TokenText.data() -
+                              WhitespaceOffsetInToken;
   Whitespaces.replaceWhitespaceInToken(
-      Tok, WhitespaceOffsetInToken, LeadingWhitespace[LineIndex], "", Prefix,
-      InPPDirective, 1, IndentLevel,
-      StartOfLineColumn[LineIndex] - Prefix.size());
+      tokenAt(LineIndex), WhitespaceOffsetInToken, WhitespaceLength, "", Prefix,
+      InPPDirective, /*Newlines=*/1, ContentColumn[LineIndex] - Prefix.size());
+}
+
+bool BreakableBlockComment::mayReflow(unsigned LineIndex,
+                                      llvm::Regex &CommentPragmasRegex) const {
+  // Content[LineIndex] may exclude the indent after the '*' decoration. In that
+  // case, we compute the start of the comment pragma manually.
+  StringRef IndentContent = Content[LineIndex];
+  if (Lines[LineIndex].ltrim(Blanks).startswith("*")) {
+    IndentContent = Lines[LineIndex].ltrim(Blanks).substr(1);
+  }
+  return LineIndex > 0 && !CommentPragmasRegex.match(IndentContent) &&
+         mayReflowContent(Content[LineIndex]) && !Tok.Finalized &&
+         !switchesFormatting(tokenAt(LineIndex));
 }
 
 unsigned
@@ -439,7 +659,248 @@
   // If we break, we always break at the predefined indent.
   if (TailOffset != 0)
     return IndentAtLineBreak;
-  return std::max(0, StartOfLineColumn[LineIndex]);
+  return std::max(0, ContentColumn[LineIndex]);
+}
+
+BreakableLineCommentSection::BreakableLineCommentSection(
+    const FormatToken &Token, unsigned StartColumn,
+    unsigned OriginalStartColumn, bool FirstInLine, bool InPPDirective,
+    encoding::Encoding Encoding, const FormatStyle &Style)
+    : BreakableComment(Token, StartColumn, InPPDirective, Encoding, Style) {
+  assert(Tok.is(TT_LineComment) &&
+         "line comment section must start with a line comment");
+  FormatToken *LineTok = nullptr;
+  for (const FormatToken *CurrentTok = &Tok;
+       CurrentTok && CurrentTok->is(TT_LineComment);
+       CurrentTok = CurrentTok->Next) {
+    LastLineTok = LineTok;
+    StringRef TokenText(CurrentTok->TokenText);
+    assert(TokenText.startswith("//"));
+    size_t FirstLineIndex = Lines.size();
+    TokenText.split(Lines, "\n");
+    Content.resize(Lines.size());
+    ContentColumn.resize(Lines.size());
+    OriginalContentColumn.resize(Lines.size());
+    Tokens.resize(Lines.size());
+    Prefix.resize(Lines.size());
+    OriginalPrefix.resize(Lines.size());
+    for (size_t i = FirstLineIndex, e = Lines.size(); i < e; ++i) {
+      // We need to trim the blanks in case this is not the first line in a
+      // multiline comment. Then the indent is included in Lines[i].
+      StringRef IndentPrefix =
+          getLineCommentIndentPrefix(Lines[i].ltrim(Blanks));
+      assert(IndentPrefix.startswith("//"));
+      OriginalPrefix[i] = Prefix[i] = IndentPrefix;
+      if (Lines[i].size() > Prefix[i].size() &&
+          isAlphanumeric(Lines[i][Prefix[i].size()])) {
+        if (Prefix[i] == "//")
+          Prefix[i] = "// ";
+        else if (Prefix[i] == "///")
+          Prefix[i] = "/// ";
+        else if (Prefix[i] == "//!")
+          Prefix[i] = "//! ";
+      }
+
+      Tokens[i] = LineTok;
+      Content[i] = Lines[i].substr(IndentPrefix.size());
+      OriginalContentColumn[i] =
+          StartColumn +
+          encoding::columnWidthWithTabs(OriginalPrefix[i],
+                                        StartColumn,
+                                        Style.TabWidth,
+                                        Encoding);
+      ContentColumn[i] =
+          StartColumn +
+          encoding::columnWidthWithTabs(Prefix[i],
+                                        StartColumn,
+                                        Style.TabWidth,
+                                        Encoding);
+
+      // Calculate the end of the non-whitespace text in this line.
+      size_t EndOfLine = Content[i].find_last_not_of(Blanks);
+      if (EndOfLine == StringRef::npos)
+        EndOfLine = Content[i].size();
+      else
+        ++EndOfLine;
+      Content[i] = Content[i].substr(0, EndOfLine);
+    }
+    LineTok = CurrentTok->Next;
+    if (CurrentTok->Next && !CurrentTok->Next->ContinuesLineCommentSection) {
+      // A line comment section needs to broken by a line comment that is
+      // preceded by at least two newlines. Note that we put this break here
+      // instead of breaking at a previous stage during parsing, since that
+      // would split the contents of the enum into two unwrapped lines in this
+      // example, which is undesirable:
+      // enum A {
+      //   a, // comment about a
+      //
+      //   // comment about b
+      //   b
+      // };
+      //
+      // FIXME: Consider putting separate line comment sections as children to
+      // the unwrapped line instead.
+      break;
+    }
+  }
+}
+
+unsigned BreakableLineCommentSection::getLineLengthAfterSplit(
+    unsigned LineIndex, unsigned TailOffset,
+    StringRef::size_type Length) const {
+  unsigned ContentStartColumn =
+      (TailOffset == 0 ? ContentColumn[LineIndex]
+                       : OriginalContentColumn[LineIndex]);
+  return ContentStartColumn + encoding::columnWidthWithTabs(
+                                  Content[LineIndex].substr(TailOffset, Length),
+                                  ContentStartColumn, Style.TabWidth, Encoding);
+}
+
+void BreakableLineCommentSection::insertBreak(unsigned LineIndex,
+                                              unsigned TailOffset, Split Split,
+                                              WhitespaceManager &Whitespaces) {
+  StringRef Text = Content[LineIndex].substr(TailOffset);
+  // Compute the offset of the split relative to the beginning of the token
+  // text.
+  unsigned BreakOffsetInToken =
+      Text.data() - tokenAt(LineIndex).TokenText.data() + Split.first;
+  unsigned CharsToRemove = Split.second;
+  // Compute the size of the new indent, including the size of the new prefix of
+  // the newly broken line.
+  unsigned IndentAtLineBreak = OriginalContentColumn[LineIndex] +
+                               Prefix[LineIndex].size() -
+                               OriginalPrefix[LineIndex].size();
+  assert(IndentAtLineBreak >= Prefix[LineIndex].size());
+  Whitespaces.replaceWhitespaceInToken(
+      tokenAt(LineIndex), BreakOffsetInToken, CharsToRemove, "",
+      Prefix[LineIndex], InPPDirective, /*Newlines=*/1,
+      /*Spaces=*/IndentAtLineBreak - Prefix[LineIndex].size());
+}
+
+BreakableComment::Split BreakableLineCommentSection::getSplitBefore(
+    unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit,
+    llvm::Regex &CommentPragmasRegex) const {
+  if (!mayReflow(LineIndex, CommentPragmasRegex))
+    return Split(StringRef::npos, 0);
+  return getReflowSplit(Content[LineIndex], ReflowPrefix, PreviousEndColumn,
+                        ColumnLimit);
+}
+
+unsigned BreakableLineCommentSection::getLineLengthAfterSplitBefore(
+    unsigned LineIndex, unsigned TailOffset,
+    unsigned PreviousEndColumn,
+    unsigned ColumnLimit,
+    Split SplitBefore) const {
+  if (SplitBefore.first == StringRef::npos ||
+      SplitBefore.first + SplitBefore.second < Content[LineIndex].size()) {
+    // A piece of line, not the whole line, gets reflown.
+    return getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
+  } else {
+    // The whole line gets reflown.
+    unsigned StartColumn = PreviousEndColumn + ReflowPrefix.size();
+    return StartColumn + encoding::columnWidthWithTabs(Content[LineIndex],
+                                                       StartColumn,
+                                                       Style.TabWidth,
+                                                       Encoding);
+  }
+}
+
+void BreakableLineCommentSection::replaceWhitespaceBefore(
+    unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit,
+    Split SplitBefore, WhitespaceManager &Whitespaces) {
+  // If this is the first line of a token, we need to inform Whitespace Manager
+  // about it: either adapt the whitespace range preceding it, or mark it as an
+  // untouchable token.
+  // This happens for instance here:
+  // // line 1 \
+  // // line 2
+  if (LineIndex > 0 && Tokens[LineIndex] != Tokens[LineIndex - 1]) {
+    if (SplitBefore.first != StringRef::npos) {
+      // Reflow happens between tokens. Replace the whitespace between the
+      // tokens by the empty string.
+      Whitespaces.replaceWhitespace(
+          *Tokens[LineIndex], /*Newlines=*/0, /*Spaces=*/0,
+          /*StartOfTokenColumn=*/StartColumn, /*InPPDirective=*/false);
+      // Replace the indent and prefix of the token with the reflow prefix.
+      unsigned WhitespaceLength =
+          Content[LineIndex].data() - tokenAt(LineIndex).TokenText.data();
+      Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex],
+                                           /*Offset=*/0,
+                                           /*ReplaceChars=*/WhitespaceLength,
+                                           /*PreviousPostfix=*/"",
+                                           /*CurrentPrefix=*/ReflowPrefix,
+                                           /*InPPDirective=*/false,
+                                           /*Newlines=*/0,
+                                           /*Spaces=*/0);
+    } else {
+      // This is the first line for the current token, but no reflow with the
+      // previous token is necessary. However, we still may need to adjust the
+      // start column. Note that ContentColumn[LineIndex] is the expected
+      // content column after a possible update to the prefix, hence the prefix
+      // length change is included.
+      unsigned LineColumn =
+          ContentColumn[LineIndex] -
+          (Content[LineIndex].data() - Lines[LineIndex].data()) +
+          (OriginalPrefix[LineIndex].size() - Prefix[LineIndex].size());
+
+      // We always want to create a replacement instead of adding an untouchable
+      // token, even if LineColumn is the same as the original column of the
+      // token. This is because WhitespaceManager doesn't align trailing
+      // comments if they are untouchable.
+      Whitespaces.replaceWhitespace(*Tokens[LineIndex],
+                                    /*Newlines=*/1,
+                                    /*Spaces=*/LineColumn,
+                                    /*StartOfTokenColumn=*/LineColumn,
+                                    /*InPPDirective=*/false);
+    }
+  }
+  if (OriginalPrefix[LineIndex] != Prefix[LineIndex]) {
+    // Adjust the prefix if necessary.
+
+    // Take care of the space possibly introduced after a decoration.
+    assert(Prefix[LineIndex] == (OriginalPrefix[LineIndex] + " ").str() &&
+           "Expecting a line comment prefix to differ from original by at most "
+           "a space");
+    Whitespaces.replaceWhitespaceInToken(
+        tokenAt(LineIndex), OriginalPrefix[LineIndex].size(), 0, "", "",
+        /*InPPDirective=*/false, /*Newlines=*/0, /*Spaces=*/1);
+  }
+  // Add a break after a reflow split has been introduced, if necessary.
+  // Note that this break doesn't need to be penalized, since it doesn't change
+  // the number of lines.
+  if (SplitBefore.first != StringRef::npos &&
+      SplitBefore.first + SplitBefore.second < Content[LineIndex].size()) {
+    insertBreak(LineIndex, 0, SplitBefore, Whitespaces);
+  }
+}
+
+void BreakableLineCommentSection::updateNextToken(LineState& State) const {
+  if (LastLineTok) {
+    State.NextToken = LastLineTok->Next;
+  }
+}
+
+bool BreakableLineCommentSection::mayReflow(
+    unsigned LineIndex, llvm::Regex &CommentPragmasRegex) const {
+  // Line comments have the indent as part of the prefix, so we need to
+  // recompute the start of the line.
+  StringRef IndentContent = Content[LineIndex];
+  if (Lines[LineIndex].startswith("//")) {
+    IndentContent = Lines[LineIndex].substr(2);
+  }
+  return LineIndex > 0 && !CommentPragmasRegex.match(IndentContent) &&
+         mayReflowContent(Content[LineIndex]) && !Tok.Finalized &&
+         !switchesFormatting(tokenAt(LineIndex)) &&
+         OriginalPrefix[LineIndex] == OriginalPrefix[LineIndex - 1];
+}
+
+unsigned
+BreakableLineCommentSection::getContentStartColumn(unsigned LineIndex,
+                                                   unsigned TailOffset) const {
+  if (TailOffset != 0) {
+    return OriginalContentColumn[LineIndex];
+  }
+  return ContentColumn[LineIndex];
 }
 
 } // namespace format
diff --git a/lib/Format/BreakableToken.h b/lib/Format/BreakableToken.h
index eb1f9fd..e642a53 100644
--- a/lib/Format/BreakableToken.h
+++ b/lib/Format/BreakableToken.h
@@ -8,9 +8,10 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Declares BreakableToken, BreakableStringLiteral, and
-/// BreakableBlockComment classes, that contain token type-specific logic to
-/// break long lines in tokens.
+/// \brief Declares BreakableToken, BreakableStringLiteral, BreakableComment,
+/// BreakableBlockComment and BreakableLineCommentSection classes, that contain
+/// token type-specific logic to break long lines in tokens and reflow content
+/// between tokens.
 ///
 //===----------------------------------------------------------------------===//
 
@@ -20,15 +21,49 @@
 #include "Encoding.h"
 #include "TokenAnnotator.h"
 #include "WhitespaceManager.h"
+#include "llvm/Support/Regex.h"
 #include <utility>
 
 namespace clang {
 namespace format {
 
+/// \brief Checks if \p Token switches formatting, like /* clang-format off */.
+/// \p Token must be a comment.
+bool switchesFormatting(const FormatToken &Token);
+
 struct FormatStyle;
 
 /// \brief Base class for strategies on how to break tokens.
 ///
+/// This is organised around the concept of a \c Split, which is a whitespace
+/// range that signifies a position of the content of a token where a
+/// reformatting might be done. Operating with splits is divided into 3
+/// operations:
+/// - getSplit, for finding a split starting at a position,
+/// - getLineLengthAfterSplit, for calculating the size in columns of the rest
+///   of the content after a split has been used for breaking, and
+/// - insertBreak, for executing the split using a whitespace manager.
+///
+/// There is a pair of operations that are used to compress a long whitespace
+/// range with a single space if that will bring the line lenght under the
+/// column limit:
+/// - getLineLengthAfterCompression, for calculating the size in columns of the
+///   line after a whitespace range has been compressed, and
+/// - compressWhitespace, for executing the whitespace compression using a
+///   whitespace manager; note that the compressed whitespace may be in the
+///   middle of the original line and of the reformatted line.
+///
+/// For tokens where the whitespace before each line needs to be also
+/// reformatted, for example for tokens supporting reflow, there are analogous
+/// operations that might be executed before the main line breaking occurs:
+/// - getSplitBefore, for finding a split such that the content preceding it
+///   needs to be specially reflown,
+/// - getLineLengthAfterSplitBefore, for calculating the line length in columns
+///   of the remainder of the content after the beginning of the content has
+///   been reformatted, and
+/// - replaceWhitespaceBefore, for executing the reflow using a whitespace
+///   manager.
+///
 /// FIXME: The interface seems set in stone, so we might want to just pull the
 /// strategy into the class, instead of controlling it from the outside.
 class BreakableToken {
@@ -42,44 +77,85 @@
   virtual unsigned getLineCount() const = 0;
 
   /// \brief Returns the number of columns required to format the piece of line
-  /// at \p LineIndex, from byte offset \p Offset with length \p Length.
+  /// at \p LineIndex, from byte offset \p TailOffset with length \p Length.
   ///
-  /// Note that previous breaks are not taken into account. \p Offset is always
-  /// specified from the start of the (original) line.
+  /// Note that previous breaks are not taken into account. \p TailOffset is
+  /// always specified from the start of the (original) line.
   /// \p Length can be set to StringRef::npos, which means "to the end of line".
   virtual unsigned
-  getLineLengthAfterSplit(unsigned LineIndex, unsigned Offset,
+  getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
                           StringRef::size_type Length) const = 0;
 
   /// \brief Returns a range (offset, length) at which to break the line at
   /// \p LineIndex, if previously broken at \p TailOffset. If possible, do not
   /// violate \p ColumnLimit.
   virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
-                         unsigned ColumnLimit) const = 0;
+                         unsigned ColumnLimit,
+                         llvm::Regex &CommentPragmasRegex) const = 0;
 
   /// \brief Emits the previously retrieved \p Split via \p Whitespaces.
   virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
                            WhitespaceManager &Whitespaces) = 0;
 
+  /// \brief Returns the number of columns required to format the piece of line
+  /// at \p LineIndex, from byte offset \p TailOffset after the whitespace range
+  /// \p Split has been compressed into a single space.
+  unsigned getLineLengthAfterCompression(unsigned RemainingTokenColumns,
+                                         Split Split) const;
+
   /// \brief Replaces the whitespace range described by \p Split with a single
   /// space.
-  virtual void replaceWhitespace(unsigned LineIndex, unsigned TailOffset,
-                                 Split Split,
-                                 WhitespaceManager &Whitespaces) = 0;
+  virtual void compressWhitespace(unsigned LineIndex, unsigned TailOffset,
+                                  Split Split,
+                                  WhitespaceManager &Whitespaces) = 0;
+
+  /// \brief Returns a whitespace range (offset, length) of the content at
+  /// \p LineIndex such that the content preceding this range needs to be
+  /// reformatted before any breaks are made to this line.
+  ///
+  /// \p PreviousEndColumn is the end column of the previous line after
+  /// formatting.
+  ///
+  /// A result having offset == StringRef::npos means that no piece of the line
+  /// needs to be reformatted before any breaks are made.
+  virtual Split getSplitBefore(unsigned LineIndex, unsigned PreviousEndColumn,
+                               unsigned ColumnLimit,
+                               llvm::Regex &CommentPragmasRegex) const {
+    return Split(StringRef::npos, 0);
+  }
+
+  /// \brief Returns the number of columns required to format the piece of line
+  /// at \p LineIndex after the content preceding the whitespace range specified
+  /// \p SplitBefore has been reformatted, but before any breaks are made to
+  /// this line.
+  virtual unsigned getLineLengthAfterSplitBefore(unsigned LineIndex,
+                                                 unsigned TailOffset,
+                                                 unsigned PreviousEndColumn,
+                                                 unsigned ColumnLimit,
+                                                 Split SplitBefore) const {
+    return getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
+  }
 
   /// \brief Replaces the whitespace between \p LineIndex-1 and \p LineIndex.
+  /// Performs a reformatting of the content at \p LineIndex preceding the
+  /// whitespace range \p SplitBefore.
   virtual void replaceWhitespaceBefore(unsigned LineIndex,
+                                       unsigned PreviousEndColumn,
+                                       unsigned ColumnLimit, Split SplitBefore,
                                        WhitespaceManager &Whitespaces) {}
 
+  /// \brief Updates the next token of \p State to the next token after this
+  /// one. This can be used when this token manages a set of underlying tokens
+  /// as a unit and is responsible for the formatting of the them.
+  virtual void updateNextToken(LineState &State) const {}
+
 protected:
-  BreakableToken(const FormatToken &Tok, unsigned IndentLevel,
-                 bool InPPDirective, encoding::Encoding Encoding,
-                 const FormatStyle &Style)
-      : Tok(Tok), IndentLevel(IndentLevel), InPPDirective(InPPDirective),
-        Encoding(Encoding), Style(Style) {}
+  BreakableToken(const FormatToken &Tok, bool InPPDirective,
+                 encoding::Encoding Encoding, const FormatStyle &Style)
+      : Tok(Tok), InPPDirective(InPPDirective), Encoding(Encoding),
+        Style(Style) {}
 
   const FormatToken &Tok;
-  const unsigned IndentLevel;
   const bool InPPDirective;
   const encoding::Encoding Encoding;
   const FormatStyle &Style;
@@ -95,10 +171,9 @@
                                    StringRef::size_type Length) const override;
 
 protected:
-  BreakableSingleLineToken(const FormatToken &Tok, unsigned IndentLevel,
-                           unsigned StartColumn, StringRef Prefix,
-                           StringRef Postfix, bool InPPDirective,
-                           encoding::Encoding Encoding,
+  BreakableSingleLineToken(const FormatToken &Tok, unsigned StartColumn,
+                           StringRef Prefix, StringRef Postfix,
+                           bool InPPDirective, encoding::Encoding Encoding,
                            const FormatStyle &Style);
 
   // The column in which the token starts.
@@ -117,107 +192,139 @@
   ///
   /// \p StartColumn specifies the column in which the token will start
   /// after formatting.
-  BreakableStringLiteral(const FormatToken &Tok, unsigned IndentLevel,
-                         unsigned StartColumn, StringRef Prefix,
-                         StringRef Postfix, bool InPPDirective,
-                         encoding::Encoding Encoding, const FormatStyle &Style);
+  BreakableStringLiteral(const FormatToken &Tok, unsigned StartColumn,
+                         StringRef Prefix, StringRef Postfix,
+                         bool InPPDirective, encoding::Encoding Encoding,
+                         const FormatStyle &Style);
 
-  Split getSplit(unsigned LineIndex, unsigned TailOffset,
-                 unsigned ColumnLimit) const override;
+  Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit,
+                 llvm::Regex &CommentPragmasRegex) const override;
   void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
                    WhitespaceManager &Whitespaces) override;
-  void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
-                         WhitespaceManager &Whitespaces) override {}
+  void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
+                          WhitespaceManager &Whitespaces) override {}
 };
 
-class BreakableLineComment : public BreakableSingleLineToken {
-public:
-  /// \brief Creates a breakable token for a line comment.
+class BreakableComment : public BreakableToken {
+protected:
+  /// \brief Creates a breakable token for a comment.
   ///
-  /// \p StartColumn specifies the column in which the comment will start
-  /// after formatting.
-  BreakableLineComment(const FormatToken &Token, unsigned IndentLevel,
-                       unsigned StartColumn, bool InPPDirective,
-                       encoding::Encoding Encoding, const FormatStyle &Style);
+  /// \p StartColumn specifies the column in which the comment will start after
+  /// formatting.
+  BreakableComment(const FormatToken &Token, unsigned StartColumn,
+                   bool InPPDirective, encoding::Encoding Encoding,
+                   const FormatStyle &Style);
 
-  Split getSplit(unsigned LineIndex, unsigned TailOffset,
-                 unsigned ColumnLimit) const override;
-  void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
-                   WhitespaceManager &Whitespaces) override;
-  void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
-                         WhitespaceManager &Whitespaces) override;
-  void replaceWhitespaceBefore(unsigned LineIndex,
-                               WhitespaceManager &Whitespaces) override;
-
-private:
-  // The prefix without an additional space if one was added.
-  StringRef OriginalPrefix;
-};
-
-class BreakableBlockComment : public BreakableToken {
 public:
-  /// \brief Creates a breakable token for a block comment.
-  ///
-  /// \p StartColumn specifies the column in which the comment will start
-  /// after formatting, while \p OriginalStartColumn specifies in which
-  /// column the comment started before formatting.
-  /// If the comment starts a line after formatting, set \p FirstInLine to true.
-  BreakableBlockComment(const FormatToken &Token, unsigned IndentLevel,
-                        unsigned StartColumn, unsigned OriginaStartColumn,
-                        bool FirstInLine, bool InPPDirective,
-                        encoding::Encoding Encoding, const FormatStyle &Style);
-
   unsigned getLineCount() const override;
+  Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit,
+                 llvm::Regex &CommentPragmasRegex) const override;
+  void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
+                          WhitespaceManager &Whitespaces) override;
+
+protected:
+  virtual unsigned getContentStartColumn(unsigned LineIndex,
+                                         unsigned TailOffset) const = 0;
+
+  // Returns a split that divides Text into a left and right parts, such that
+  // the left part is suitable for reflowing after PreviousEndColumn.
+  Split getReflowSplit(StringRef Text, StringRef ReflowPrefix,
+                       unsigned PreviousEndColumn, unsigned ColumnLimit) const;
+
+  // Returns the token containing the line at LineIndex.
+  const FormatToken &tokenAt(unsigned LineIndex) const;
+
+  // Checks if the content of line LineIndex may be reflown with the previous
+  // line.
+  virtual bool mayReflow(unsigned LineIndex,
+                         llvm::Regex &CommentPragmasRegex) const = 0;
+
+  // Contains the original text of the lines of the block comment.
+  //
+  // In case of a block comments, excludes the leading /* in the first line and
+  // trailing */ in the last line. In case of line comments, excludes the
+  // leading // and spaces.
+  SmallVector<StringRef, 16> Lines;
+
+  // Contains the text of the lines excluding all leading and trailing
+  // whitespace between the lines. Note that the decoration (if present) is also
+  // not considered part of the text.
+  SmallVector<StringRef, 16> Content;
+
+  // Tokens[i] contains a reference to the token containing Lines[i] if the
+  // whitespace range before that token is managed by this block.
+  // Otherwise, Tokens[i] is a null pointer.
+  SmallVector<FormatToken *, 16> Tokens;
+
+  // ContentColumn[i] is the target column at which Content[i] should be.
+  // Note that this excludes a leading "* " or "*" in case of block comments
+  // where all lines have a "*" prefix, or the leading "// " or "//" in case of
+  // line comments.
+  //
+  // In block comments, the first line's target column is always positive. The
+  // remaining lines' target columns are relative to the first line to allow
+  // correct indentation of comments in \c WhitespaceManager. Thus they can be
+  // negative as well (in case the first line needs to be unindented more than
+  // there's actual whitespace in another line).
+  SmallVector<int, 16> ContentColumn;
+
+  // The intended start column of the first line of text from this section.
+  unsigned StartColumn;
+
+  // The prefix to use in front a line that has been reflown up.
+  // For example, when reflowing the second line after the first here:
+  // // comment 1
+  // // comment 2
+  // we expect:
+  // // comment 1 comment 2
+  // and not:
+  // // comment 1comment 2
+  StringRef ReflowPrefix = " ";
+};
+
+class BreakableBlockComment : public BreakableComment {
+public:
+  BreakableBlockComment(const FormatToken &Token, unsigned StartColumn,
+                        unsigned OriginalStartColumn, bool FirstInLine,
+                        bool InPPDirective, encoding::Encoding Encoding,
+                        const FormatStyle &Style);
+
   unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
                                    StringRef::size_type Length) const override;
-  Split getSplit(unsigned LineIndex, unsigned TailOffset,
-                 unsigned ColumnLimit) const override;
   void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
                    WhitespaceManager &Whitespaces) override;
-  void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
-                         WhitespaceManager &Whitespaces) override;
-  void replaceWhitespaceBefore(unsigned LineIndex,
+  Split getSplitBefore(unsigned LineIndex, unsigned PreviousEndColumn,
+                       unsigned ColumnLimit,
+                       llvm::Regex &CommentPragmasRegex) const override;
+  unsigned getLineLengthAfterSplitBefore(unsigned LineIndex,
+                                         unsigned TailOffset,
+                                         unsigned PreviousEndColumn,
+                                         unsigned ColumnLimit,
+                                         Split SplitBefore) const override;
+  void replaceWhitespaceBefore(unsigned LineIndex, unsigned PreviousEndColumn,
+                               unsigned ColumnLimit, Split SplitBefore,
                                WhitespaceManager &Whitespaces) override;
+  bool mayReflow(unsigned LineIndex,
+                 llvm::Regex &CommentPragmasRegex) const override;
 
 private:
-  // Rearranges the whitespace between Lines[LineIndex-1] and Lines[LineIndex],
-  // so that all whitespace between the lines is accounted to Lines[LineIndex]
-  // as leading whitespace:
-  // - Lines[LineIndex] points to the text after that whitespace
-  // - Lines[LineIndex-1] shrinks by its trailing whitespace
-  // - LeadingWhitespace[LineIndex] is updated with the complete whitespace
-  //   between the end of the text of Lines[LineIndex-1] and Lines[LineIndex]
+  // Rearranges the whitespace between Lines[LineIndex-1] and Lines[LineIndex].
   //
-  // Sets StartOfLineColumn to the intended column in which the text at
+  // Updates Content[LineIndex-1] and Content[LineIndex] by stripping off
+  // leading and trailing whitespace.
+  //
+  // Sets ContentColumn to the intended column in which the text at
   // Lines[LineIndex] starts (note that the decoration, if present, is not
   // considered part of the text).
   void adjustWhitespace(unsigned LineIndex, int IndentDelta);
 
-  // Returns the column at which the text in line LineIndex starts, when broken
-  // at TailOffset. Note that the decoration (if present) is not considered part
-  // of the text.
-  unsigned getContentStartColumn(unsigned LineIndex, unsigned TailOffset) const;
+  // Computes the end column if the full Content from LineIndex gets reflown
+  // after PreviousEndColumn.
+  unsigned getReflownColumn(StringRef Content, unsigned LineIndex,
+                            unsigned PreviousEndColumn) const;
 
-  // Contains the text of the lines of the block comment, excluding the leading
-  // /* in the first line and trailing */ in the last line, and excluding all
-  // trailing whitespace between the lines. Note that the decoration (if
-  // present) is also not considered part of the text.
-  SmallVector<StringRef, 16> Lines;
-
-  // LeadingWhitespace[i] is the number of characters regarded as whitespace in
-  // front of Lines[i]. Note that this can include "* " sequences, which we
-  // regard as whitespace when all lines have a "*" prefix.
-  SmallVector<unsigned, 16> LeadingWhitespace;
-
-  // StartOfLineColumn[i] is the target column at which Line[i] should be.
-  // Note that this excludes a leading "* " or "*" in case all lines have
-  // a "*" prefix.
-  // The first line's target column is always positive. The remaining lines'
-  // target columns are relative to the first line to allow correct indentation
-  // of comments in \c WhitespaceManager. Thus they can be negative as well (in
-  // case the first line needs to be unindented more than there's actual
-  // whitespace in another line).
-  SmallVector<int, 16> StartOfLineColumn;
+  unsigned getContentStartColumn(unsigned LineIndex,
+                                 unsigned TailOffset) const override;
 
   // The column at which the text of a broken line should start.
   // Note that an optional decoration would go before that column.
@@ -237,8 +344,69 @@
 
   // Either "* " if all lines begin with a "*", or empty.
   StringRef Decoration;
+
+  // If this block comment has decorations, this is the column of the start of
+  // the decorations.
+  unsigned DecorationColumn;
 };
 
+class BreakableLineCommentSection : public BreakableComment {
+public:
+  BreakableLineCommentSection(const FormatToken &Token, unsigned StartColumn,
+                              unsigned OriginalStartColumn, bool FirstInLine,
+                              bool InPPDirective, encoding::Encoding Encoding,
+                              const FormatStyle &Style);
+
+  unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
+                                   StringRef::size_type Length) const override;
+  void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
+                   WhitespaceManager &Whitespaces) override;
+  Split getSplitBefore(unsigned LineIndex, unsigned PreviousEndColumn,
+                       unsigned ColumnLimit,
+                       llvm::Regex &CommentPragmasRegex) const override;
+  unsigned getLineLengthAfterSplitBefore(unsigned LineIndex,
+                                         unsigned TailOffset,
+                                         unsigned PreviousEndColumn,
+                                         unsigned ColumnLimit,
+                                         Split SplitBefore) const override;
+  void replaceWhitespaceBefore(unsigned LineIndex, unsigned PreviousEndColumn,
+                               unsigned ColumnLimit, Split SplitBefore,
+                               WhitespaceManager &Whitespaces) override;
+  void updateNextToken(LineState &State) const override;
+  bool mayReflow(unsigned LineIndex,
+                 llvm::Regex &CommentPragmasRegex) const override;
+
+private:
+  unsigned getContentStartColumn(unsigned LineIndex,
+                                 unsigned TailOffset) const override;
+
+  // OriginalPrefix[i] contains the original prefix of line i, including
+  // trailing whitespace before the start of the content. The indentation
+  // preceding the prefix is not included.
+  // For example, if the line is:
+  // // content
+  // then the original prefix is "// ".
+  SmallVector<StringRef, 16> OriginalPrefix;
+
+  // Prefix[i] contains the intended leading "//" with trailing spaces to
+  // account for the indentation of content within the comment at line i after
+  // formatting. It can be different than the original prefix when the original
+  // line starts like this:
+  // //content
+  // Then the original prefix is "//", but the prefix is "// ".
+  SmallVector<StringRef, 16> Prefix;
+
+  SmallVector<unsigned, 16> OriginalContentColumn;
+
+  /// \brief The token to which the last line of this breakable token belongs
+  /// to; nullptr if that token is the initial token.
+  ///
+  /// The distinction is because if the token of the last line of this breakable
+  /// token is distinct from the initial token, this breakable token owns the
+  /// whitespace before the token of the last line, and the whitespace manager
+  /// must be able to modify it.
+  FormatToken *LastLineTok = nullptr;
+};
 } // namespace format
 } // namespace clang
 
diff --git a/lib/Format/CMakeLists.txt b/lib/Format/CMakeLists.txt
index c977c2d..0c7511c 100644
--- a/lib/Format/CMakeLists.txt
+++ b/lib/Format/CMakeLists.txt
@@ -3,11 +3,11 @@
 add_clang_library(clangFormat
   AffectedRangeManager.cpp
   BreakableToken.cpp
-  Comments.cpp
   ContinuationIndenter.cpp
   Format.cpp
   FormatToken.cpp
   FormatTokenLexer.cpp
+  NamespaceEndCommentsFixer.cpp
   SortJavaScriptImports.cpp
   TokenAnalyzer.cpp
   TokenAnnotator.cpp
diff --git a/lib/Format/Comments.cpp b/lib/Format/Comments.cpp
deleted file mode 100644
index 1b27f5b..0000000
--- a/lib/Format/Comments.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-//===--- Comments.cpp - Comment Manipulation  -------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Implements comment manipulation.
-///
-//===----------------------------------------------------------------------===//
-
-#include "Comments.h"
-
-namespace clang {
-namespace format {
-
-StringRef getLineCommentIndentPrefix(StringRef Comment) {
-  static const char *const KnownPrefixes[] = {"///", "//", "//!"};
-  StringRef LongestPrefix;
-  for (StringRef KnownPrefix : KnownPrefixes) {
-    if (Comment.startswith(KnownPrefix)) {
-      size_t PrefixLength = KnownPrefix.size();
-      while (PrefixLength < Comment.size() && Comment[PrefixLength] == ' ')
-        ++PrefixLength;
-      if (PrefixLength > LongestPrefix.size())
-        LongestPrefix = Comment.substr(0, PrefixLength);
-    }
-  }
-  return LongestPrefix;
-}
-
-} // namespace format
-} // namespace clang
diff --git a/lib/Format/Comments.h b/lib/Format/Comments.h
deleted file mode 100644
index 59f0596..0000000
--- a/lib/Format/Comments.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===--- Comments.cpp - Comment manipulation  -----------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Declares comment manipulation functionality.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_FORMAT_COMMENTS_H
-#define LLVM_CLANG_LIB_FORMAT_COMMENTS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace format {
-
-/// \brief Returns the comment prefix of the line comment \p Comment.
-///
-/// The comment prefix consists of a leading known prefix, like "//" or "///",
-/// together with the following whitespace.
-StringRef getLineCommentIndentPrefix(StringRef Comment);
-
-} // namespace format
-} // namespace clang
-
-#endif
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index 404e3a3..c518db8 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -20,7 +20,7 @@
 #include "clang/Format/Format.h"
 #include "llvm/Support/Debug.h"
 
-#define DEBUG_TYPE "format-formatter"
+#define DEBUG_TYPE "format-indenter"
 
 namespace clang {
 namespace format {
@@ -57,8 +57,10 @@
       Style.BreakConstructorInitializersBeforeComma)
     return true;
   return Previous.is(tok::comma) && !Current.isTrailingComment() &&
-         (Previous.isNot(TT_CtorInitializerComma) ||
-          !Style.BreakConstructorInitializersBeforeComma);
+         ((Previous.isNot(TT_CtorInitializerComma) ||
+          !Style.BreakConstructorInitializersBeforeComma) &&
+          (Previous.isNot(TT_InheritanceComma) ||
+          !Style.BreakBeforeInheritanceComma));
 }
 
 ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style,
@@ -80,7 +82,7 @@
   State.Column = FirstIndent;
   State.Line = Line;
   State.NextToken = Line->First;
-  State.Stack.push_back(ParenState(FirstIndent, Line->Level, FirstIndent,
+  State.Stack.push_back(ParenState(FirstIndent, FirstIndent,
                                    /*AvoidBinPacking=*/false,
                                    /*NoLineBreak=*/false));
   State.LineContainsContinuedForLoopSection = false;
@@ -135,6 +137,12 @@
       return false;
   }
 
+  // If binary operators are moved to the next line (including commas for some
+  // styles of constructor initializers), that's always ok.
+  if (!Current.isOneOf(TT_BinaryOperator, tok::comma) &&
+      State.Stack.back().NoLineBreakInOperand)
+    return false;
+
   return !State.Stack.back().NoLineBreak;
 }
 
@@ -150,7 +158,7 @@
     return true;
   if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) ||
        (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&
-        Style.Language == FormatStyle::LK_Cpp &&
+        Style.IsCpp() &&
         // FIXME: This is a temporary workaround for the case where clang-format
         // sets BreakBeforeParameter to avoid bin packing and this creates a
         // completely unnecessary line break after a template type that isn't
@@ -191,6 +199,18 @@
        Current.NestingLevel < State.StartOfLineLevel))
     return true;
 
+  if (startsSegmentOfBuilderTypeCall(Current) &&
+      (State.Stack.back().CallContinuation != 0 ||
+       State.Stack.back().BreakBeforeParameter) &&
+      // JavaScript is treated different here as there is a frequent pattern:
+      //   SomeFunction(function() {
+      //     ...
+      //   }.bind(...));
+      // FIXME: We should find a more generic solution to this problem.
+      !(State.Column <= NewLineColumn &&
+        Style.Language == FormatStyle::LK_JavaScript))
+    return true;
+
   if (State.Column <= NewLineColumn)
     return false;
 
@@ -255,11 +275,6 @@
       !Previous.is(tok::kw_template) && State.Stack.back().BreakBeforeParameter)
     return true;
 
-  if (startsSegmentOfBuilderTypeCall(Current) &&
-      (State.Stack.back().CallContinuation != 0 ||
-       State.Stack.back().BreakBeforeParameter))
-    return true;
-
   // The following could be precomputed as they do not depend on the state.
   // However, as they should take effect only if the UnwrappedLine does not fit
   // into the ColumnLimit, they are checked here in the ContinuationIndenter.
@@ -334,8 +349,13 @@
   unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
 
   if (!DryRun)
-    Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, /*IndentLevel=*/0,
-                                  Spaces, State.Column + Spaces);
+    Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, Spaces,
+                                  State.Column + Spaces);
+
+  // If "BreakBeforeInheritanceComma" mode, don't break within the inheritance
+  // declaration unless there is multiple inheritance.
+  if (Style.BreakBeforeInheritanceComma && Current.is(TT_InheritanceColon))
+    State.Stack.back().NoLineBreak = true;
 
   if (Current.is(TT_SelectorName) &&
       !State.Stack.back().ObjCSelectorNameFound) {
@@ -370,6 +390,8 @@
       Current.FakeLParens.size() > 0 &&
       Current.FakeLParens.back() > prec::Unknown)
     State.Stack.back().NoLineBreak = true;
+  if (Previous.is(TT_TemplateString) && Previous.opensScope())
+    State.Stack.back().NoLineBreak = true;
 
   if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign &&
       Previous.opensScope() && Previous.isNot(TT_ObjCMethodExpr) &&
@@ -385,7 +407,7 @@
     State.Stack.back().NoLineBreak = true;
   if (Current.isMemberAccess() && Previous.is(tok::r_paren) &&
       (Previous.MatchingParen &&
-       (Previous.TotalLength - Previous.MatchingParen->TotalLength > 10))) {
+       (Previous.TotalLength - Previous.MatchingParen->TotalLength > 10)))
     // If there is a function call with long parameters, break before trailing
     // calls. This prevents things like:
     //   EXPECT_CALL(SomeLongParameter).Times(
@@ -393,6 +415,31 @@
     // We don't want to do this for short parameters as they can just be
     // indexes.
     State.Stack.back().NoLineBreak = true;
+
+  // Don't allow the RHS of an operator to be split over multiple lines unless
+  // there is a line-break right after the operator.
+  // Exclude relational operators, as there, it is always more desirable to
+  // have the LHS 'left' of the RHS.
+  const FormatToken *P = Current.getPreviousNonComment();
+  if (!Current.is(tok::comment) && P &&
+      (P->isOneOf(TT_BinaryOperator, tok::comma) ||
+       (P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
+      !P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
+      P->getPrecedence() != prec::Assignment &&
+      P->getPrecedence() != prec::Relational) {
+    bool BreakBeforeOperator =
+        P->MustBreakBefore || P->is(tok::lessless) ||
+        (P->is(TT_BinaryOperator) &&
+         Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
+        (P->is(TT_ConditionalExpr) && Style.BreakBeforeTernaryOperators);
+    // Don't do this if there are only two operands. In these cases, there is
+    // always a nice vertical separation between them and the extra line break
+    // does not help.
+    bool HasTwoOperands =
+        P->OperatorIndex == 0 && !P->NextOperator && !P->is(TT_ConditionalExpr);
+    if ((!BreakBeforeOperator && !(HasTwoOperands && Style.AlignOperands)) ||
+        (!State.Stack.back().LastOperatorWrapped && BreakBeforeOperator))
+      State.Stack.back().NoLineBreakInOperand = true;
   }
 
   State.Column += Spaces;
@@ -460,7 +507,7 @@
   Penalty += State.NextToken->SplitPenalty;
 
   // Breaking before the first "<<" is generally not desirable if the LHS is
-  // short. Also always add the penalty if the LHS is split over mutliple lines
+  // short. Also always add the penalty if the LHS is split over multiple lines
   // to avoid unnecessary line breaks that just work around this penalty.
   if (NextNonComment->is(tok::lessless) &&
       State.Stack.back().FirstLessLess == 0 &&
@@ -540,9 +587,8 @@
   if (!DryRun) {
     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);
+    Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,
+                                  State.Line->InPPDirective);
   }
 
   if (!Current.isTrailingComment())
@@ -559,8 +605,7 @@
   // Any break on this level means that the parent level has been broken
   // and we need to avoid bin packing there.
   bool NestedBlockSpecialCase =
-      Style.Language != FormatStyle::LK_Cpp &&
-      Current.is(tok::r_brace) && State.Stack.size() > 1 &&
+      !Style.IsCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 &&
       State.Stack[State.Stack.size() - 2].NestedBlockInlined;
   if (!NestedBlockSpecialCase)
     for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
@@ -579,7 +624,9 @@
   // If we break after { or the [ of an array initializer, we should also break
   // before the corresponding } or ].
   if (PreviousNonComment &&
-      (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)))
+      (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
+       (PreviousNonComment->is(TT_TemplateString) &&
+        PreviousNonComment->opensScope())))
     State.Stack.back().BreakBeforeClosingBrace = true;
 
   if (State.Stack.back().AvoidBinPacking) {
@@ -627,6 +674,8 @@
       return State.Stack[State.Stack.size() - 2].LastSpace;
     return State.FirstIndent;
   }
+  if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
+    return State.Stack[State.Stack.size() - 2].LastSpace;
   if (Current.is(tok::identifier) && Current.Next &&
       Current.Next->is(TT_DictLiteral))
     return State.Stack.back().Indent;
@@ -695,10 +744,11 @@
   if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
       PreviousNonComment->isOneOf(TT_ObjCMethodExpr, TT_DictLiteral))
     return ContinuationIndent;
-  if (NextNonComment->is(TT_CtorInitializerColon))
-    return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
   if (NextNonComment->is(TT_CtorInitializerComma))
     return State.Stack.back().Indent;
+  if (NextNonComment->isOneOf(TT_CtorInitializerColon, TT_InheritanceColon,
+                              TT_InheritanceComma))
+    return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
   if (Previous.is(tok::r_paren) && !Current.isBinaryOperator() &&
       !Current.isOneOf(tok::colon, tok::comment))
     return ContinuationIndent;
@@ -715,6 +765,8 @@
   assert(State.Stack.size());
   const FormatToken &Current = *State.NextToken;
 
+  if (Current.isOneOf(tok::comma, TT_BinaryOperator))
+    State.Stack.back().NoLineBreakInOperand = false;
   if (Current.is(TT_InheritanceColon))
     State.Stack.back().AvoidBinPacking = true;
   if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator)) {
@@ -723,8 +775,10 @@
     else
       State.Stack.back().LastOperatorWrapped = Newline;
   }
-  if ((Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless)) ||
-      Current.is(TT_ConditionalExpr))
+  if (Current.is(TT_BinaryOperator) && Current.isNot(tok::lessless))
+    State.Stack.back().LastOperatorWrapped = Newline;
+  if (Current.is(TT_ConditionalExpr) && Current.Previous &&
+      !Current.Previous->is(TT_ConditionalExpr))
     State.Stack.back().LastOperatorWrapped = Newline;
   if (Current.is(TT_ArraySubscriptLSquare) &&
       State.Stack.back().StartOfArraySubscripts == 0)
@@ -764,9 +818,14 @@
       State.Stack.back().AvoidBinPacking = true;
     State.Stack.back().BreakBeforeParameter = false;
   }
+  if (Current.is(TT_InheritanceColon))
+    State.Stack.back().Indent =
+        State.FirstIndent + Style.ContinuationIndentWidth;
   if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
     State.Stack.back().NestedBlockIndent =
         State.Column + Current.ColumnWidth + 1;
+  if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
+    State.Stack.back().LastSpace = State.Column;
 
   // Insert scopes created by fake parenthesis.
   const FormatToken *Previous = Current.getPreviousNonComment();
@@ -794,8 +853,15 @@
   }
 
   moveStatePastFakeLParens(State, Newline);
-  moveStatePastScopeOpener(State, Newline);
   moveStatePastScopeCloser(State);
+  if (Current.is(TT_TemplateString) && Current.opensScope())
+    State.Stack.back().LastSpace =
+        (Current.IsMultiline ? Current.LastLineColumnWidth
+                             : State.Column + Current.ColumnWidth) -
+        strlen("${");
+  bool CanBreakProtrudingToken = !State.Stack.back().NoLineBreak &&
+                                 !State.Stack.back().NoLineBreakInOperand;
+  moveStatePastScopeOpener(State, Newline);
   moveStatePastFakeRParens(State);
 
   if (Current.isStringLiteral() && State.StartOfStringLiteral == 0)
@@ -808,7 +874,9 @@
 
   State.Column += Current.ColumnWidth;
   State.NextToken = State.NextToken->Next;
-  unsigned Penalty = breakProtrudingToken(Current, State, DryRun);
+  unsigned Penalty = 0;
+  if (CanBreakProtrudingToken)
+    Penalty = breakProtrudingToken(Current, State, DryRun);
   if (State.Column > getColumnLimit(State)) {
     unsigned ExcessCharacters = State.Column - getColumnLimit(State);
     Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
@@ -847,6 +915,8 @@
        I != E; ++I) {
     ParenState NewParenState = State.Stack.back();
     NewParenState.ContainsLineBreak = false;
+    NewParenState.NoLineBreak =
+        NewParenState.NoLineBreak || State.Stack.back().NoLineBreakInOperand;
 
     // Indent from 'LastSpace' unless these are fake parentheses encapsulating
     // a builder type call after 'return' or, if the alignment after opening
@@ -861,24 +931,6 @@
           std::max(std::max(State.Column, NewParenState.Indent),
                    State.Stack.back().LastSpace);
 
-    // Don't allow the RHS of an operator to be split over multiple lines unless
-    // there is a line-break right after the operator.
-    // Exclude relational operators, as there, it is always more desirable to
-    // have the LHS 'left' of the RHS.
-    if (Previous && Previous->getPrecedence() != prec::Assignment &&
-        Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr, tok::comma) &&
-        Previous->getPrecedence() != prec::Relational) {
-      bool BreakBeforeOperator =
-          Previous->is(tok::lessless) ||
-          (Previous->is(TT_BinaryOperator) &&
-           Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None) ||
-          (Previous->is(TT_ConditionalExpr) &&
-           Style.BreakBeforeTernaryOperators);
-      if ((!Newline && !BreakBeforeOperator) ||
-          (!State.Stack.back().LastOperatorWrapped && BreakBeforeOperator))
-        NewParenState.NoLineBreak = true;
-    }
-
     // Do not indent relative to the fake parentheses inserted for "." or "->".
     // This is a special case to make the following to statements consistent:
     //   OuterFunction(InnerFunctionCall( // break
@@ -930,7 +982,6 @@
   }
 
   unsigned NewIndent;
-  unsigned NewIndentLevel = State.Stack.back().IndentLevel;
   unsigned LastSpace = State.Stack.back().LastSpace;
   bool AvoidBinPacking;
   bool BreakBeforeParameter = false;
@@ -940,7 +991,6 @@
     if (Current.opensBlockOrBlockTypeList(Style)) {
       NewIndent = State.Stack.back().NestedBlockIndent + Style.IndentWidth;
       NewIndent = std::min(State.Column + 2, NewIndent);
-      ++NewIndentLevel;
     } else {
       NewIndent = State.Stack.back().LastSpace + Style.ContinuationIndentWidth;
     }
@@ -965,12 +1015,23 @@
     //                       int> v);
     // FIXME: We likely want to do this for more combinations of brackets.
     // Verify that it is wanted for ObjC, too.
-    if (Current.Tok.getKind() == tok::less &&
-        Current.ParentBracket == tok::l_paren) {
+    if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
       NewIndent = std::max(NewIndent, State.Stack.back().Indent);
       LastSpace = std::max(LastSpace, State.Stack.back().Indent);
     }
 
+    // JavaScript template strings are special as we always want to indent
+    // nested expressions relative to the ${}. Otherwise, this can create quite
+    // a mess.
+    if (Current.is(TT_TemplateString)) {
+      unsigned Column = Current.IsMultiline
+                            ? Current.LastLineColumnWidth
+                            : State.Column + Current.ColumnWidth;
+      NewIndent = Column;
+      LastSpace = Column;
+      NestedBlockIndent = Column;
+    }
+
     AvoidBinPacking =
         (State.Line->MustBeDeclaration && !Style.BinPackParameters) ||
         (!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
@@ -1006,10 +1067,11 @@
       Current.Children.empty() &&
       !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
       (State.Stack.back().NoLineBreak ||
+       State.Stack.back().NoLineBreakInOperand ||
        (Current.is(TT_TemplateOpener) &&
         State.Stack.back().ContainsUnwrappedBuilder));
-  State.Stack.push_back(ParenState(NewIndent, NewIndentLevel, LastSpace,
-                                   AvoidBinPacking, NoLineBreak));
+  State.Stack.push_back(
+      ParenState(NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
   State.Stack.back().NestedBlockIndent = NestedBlockIndent;
   State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
   State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
@@ -1023,7 +1085,7 @@
   // If we encounter a closing ), ], } or >, we can remove a level from our
   // stacks.
   if (State.Stack.size() > 1 &&
-      (Current.isOneOf(tok::r_paren, tok::r_square) ||
+      (Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
        (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
        State.NextToken->is(TT_TemplateCloser)))
     State.Stack.pop_back();
@@ -1043,10 +1105,9 @@
       NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
                                ? Style.ObjCBlockIndentWidth
                                : Style.IndentWidth);
-  State.Stack.push_back(ParenState(
-      NewIndent, /*NewIndentLevel=*/State.Stack.back().IndentLevel + 1,
-      State.Stack.back().LastSpace, /*AvoidBinPacking=*/true,
-      /*NoLineBreak=*/false));
+  State.Stack.push_back(ParenState(NewIndent, State.Stack.back().LastSpace,
+                                   /*AvoidBinPacking=*/true,
+                                   /*NoLineBreak=*/false));
   State.Stack.back().NestedBlockIndent = NestedBlockIndent;
   State.Stack.back().BreakBeforeParameter = true;
 }
@@ -1129,28 +1190,32 @@
           Text.startswith(Prefix = "u8\"") ||
           Text.startswith(Prefix = "L\""))) ||
         (Text.startswith(Prefix = "_T(\"") && Text.endswith(Postfix = "\")"))) {
-      Token.reset(new BreakableStringLiteral(
-          Current, State.Line->Level, StartColumn, Prefix, Postfix,
-          State.Line->InPPDirective, Encoding, Style));
+      Token.reset(new BreakableStringLiteral(Current, StartColumn, Prefix,
+                                             Postfix, State.Line->InPPDirective,
+                                             Encoding, Style));
     } else {
       return 0;
     }
   } else if (Current.is(TT_BlockComment)) {
     if (!Current.isTrailingComment() || !Style.ReflowComments ||
-        CommentPragmasRegex.match(Current.TokenText.substr(2)))
+        // If a comment token switches formatting, like
+        // /* clang-format on */, we don't want to break it further,
+        // but we may still want to adjust its indentation.
+        switchesFormatting(Current))
       return addMultilineToken(Current, State);
     Token.reset(new BreakableBlockComment(
-        Current, State.Line->Level, StartColumn, Current.OriginalColumn,
-        !Current.Previous, State.Line->InPPDirective, Encoding, Style));
+        Current, StartColumn, Current.OriginalColumn, !Current.Previous,
+        State.Line->InPPDirective, Encoding, Style));
   } else if (Current.is(TT_LineComment) &&
              (Current.Previous == nullptr ||
               Current.Previous->isNot(TT_ImplicitStringLiteral))) {
     if (!Style.ReflowComments ||
-        CommentPragmasRegex.match(Current.TokenText.substr(2)))
+        CommentPragmasRegex.match(Current.TokenText.substr(2)) ||
+        switchesFormatting(Current))
       return 0;
-    Token.reset(new BreakableLineComment(Current, State.Line->Level,
-                                         StartColumn, /*InPPDirective=*/false,
-                                         Encoding, Style));
+    Token.reset(new BreakableLineCommentSection(
+        Current, StartColumn, Current.OriginalColumn, !Current.Previous,
+        /*InPPDirective=*/false, Encoding, Style));
     // We don't insert backslashes when breaking line comments.
     ColumnLimit = Style.ColumnLimit;
   } else {
@@ -1161,18 +1226,30 @@
 
   unsigned RemainingSpace = ColumnLimit - Current.UnbreakableTailLength;
   bool BreakInserted = false;
+  // We use a conservative reflowing strategy. Reflow starts after a line is
+  // broken or the corresponding whitespace compressed. Reflow ends as soon as a
+  // line that doesn't get reflown with the previous line is reached.
+  bool ReflowInProgress = false;
   unsigned Penalty = 0;
   unsigned RemainingTokenColumns = 0;
   for (unsigned LineIndex = 0, EndIndex = Token->getLineCount();
        LineIndex != EndIndex; ++LineIndex) {
+    BreakableToken::Split SplitBefore(StringRef::npos, 0);
+    if (ReflowInProgress) {
+      SplitBefore = Token->getSplitBefore(LineIndex, RemainingTokenColumns,
+                                          RemainingSpace, CommentPragmasRegex);
+    }
+    ReflowInProgress = SplitBefore.first != StringRef::npos;
+    unsigned TailOffset =
+        ReflowInProgress ? (SplitBefore.first + SplitBefore.second) : 0;
     if (!DryRun)
-      Token->replaceWhitespaceBefore(LineIndex, Whitespaces);
-    unsigned TailOffset = 0;
-    RemainingTokenColumns =
-        Token->getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
+      Token->replaceWhitespaceBefore(LineIndex, RemainingTokenColumns,
+                                     RemainingSpace, SplitBefore, Whitespaces);
+    RemainingTokenColumns = Token->getLineLengthAfterSplitBefore(
+        LineIndex, TailOffset, RemainingTokenColumns, ColumnLimit, SplitBefore);
     while (RemainingTokenColumns > RemainingSpace) {
-      BreakableToken::Split Split =
-          Token->getSplit(LineIndex, TailOffset, ColumnLimit);
+      BreakableToken::Split Split = Token->getSplit(
+          LineIndex, TailOffset, ColumnLimit, CommentPragmasRegex);
       if (Split.first == StringRef::npos) {
         // The last line's penalty is handled in addNextStateToQueue().
         if (LineIndex < EndIndex - 1)
@@ -1181,17 +1258,23 @@
         break;
       }
       assert(Split.first != 0);
-      unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
-          LineIndex, TailOffset + Split.first + Split.second, StringRef::npos);
 
-      // We can remove extra whitespace instead of breaking the line.
-      if (RemainingTokenColumns + 1 - Split.second <= RemainingSpace) {
-        RemainingTokenColumns = 0;
+      // Check if compressing the whitespace range will bring the line length
+      // under the limit. If that is the case, we perform whitespace compression
+      // instead of inserting a line break.
+      unsigned RemainingTokenColumnsAfterCompression =
+          Token->getLineLengthAfterCompression(RemainingTokenColumns, Split);
+      if (RemainingTokenColumnsAfterCompression <= RemainingSpace) {
+        RemainingTokenColumns = RemainingTokenColumnsAfterCompression;
+        ReflowInProgress = true;
         if (!DryRun)
-          Token->replaceWhitespace(LineIndex, TailOffset, Split, Whitespaces);
+          Token->compressWhitespace(LineIndex, TailOffset, Split, Whitespaces);
         break;
       }
 
+      unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
+          LineIndex, TailOffset + Split.first + Split.second, StringRef::npos);
+
       // When breaking before a tab character, it may be moved by a few columns,
       // but will still be expanded to the next tab stop, so we don't save any
       // columns.
@@ -1209,6 +1292,7 @@
       }
       TailOffset += Split.first + Split.second;
       RemainingTokenColumns = NewRemainingTokenColumns;
+      ReflowInProgress = true;
       BreakInserted = true;
     }
   }
@@ -1229,6 +1313,9 @@
 
     State.Stack.back().LastSpace = StartColumn;
   }
+
+  Token->updateNextToken(State);
+
   return Penalty;
 }
 
diff --git a/lib/Format/ContinuationIndenter.h b/lib/Format/ContinuationIndenter.h
index 21ad653..9a06aa6 100644
--- a/lib/Format/ContinuationIndenter.h
+++ b/lib/Format/ContinuationIndenter.h
@@ -146,12 +146,12 @@
 };
 
 struct ParenState {
-  ParenState(unsigned Indent, unsigned IndentLevel, unsigned LastSpace,
-             bool AvoidBinPacking, bool NoLineBreak)
-      : Indent(Indent), IndentLevel(IndentLevel), LastSpace(LastSpace),
-        NestedBlockIndent(Indent), BreakBeforeClosingBrace(false),
-        AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
-        NoLineBreak(NoLineBreak), LastOperatorWrapped(true),
+  ParenState(unsigned Indent, unsigned LastSpace, bool AvoidBinPacking,
+             bool NoLineBreak)
+      : Indent(Indent), LastSpace(LastSpace), NestedBlockIndent(Indent),
+        BreakBeforeClosingBrace(false), AvoidBinPacking(AvoidBinPacking),
+        BreakBeforeParameter(false), NoLineBreak(NoLineBreak),
+        NoLineBreakInOperand(false), LastOperatorWrapped(true),
         ContainsLineBreak(false), ContainsUnwrappedBuilder(false),
         AlignColons(true), ObjCSelectorNameFound(false),
         HasMultipleNestedBlocks(false), NestedBlockInlined(false) {}
@@ -160,9 +160,6 @@
   /// indented.
   unsigned Indent;
 
-  /// \brief The number of indentation levels of the block.
-  unsigned IndentLevel;
-
   /// \brief The position of the last space on each level.
   ///
   /// Used e.g. to break like:
@@ -224,6 +221,10 @@
   /// \brief Line breaking in this context would break a formatting rule.
   bool NoLineBreak : 1;
 
+  /// \brief Same as \c NoLineBreak, but is restricted until the end of the
+  /// operand (including the next ",").
+  bool NoLineBreakInOperand : 1;
+
   /// \brief True if the last binary operator on this level was wrapped to the
   /// next line.
   bool LastOperatorWrapped : 1;
diff --git a/lib/Format/Encoding.h b/lib/Format/Encoding.h
index b2103cb..3339597 100644
--- a/lib/Format/Encoding.h
+++ b/lib/Format/Encoding.h
@@ -40,26 +40,6 @@
   return Encoding_Unknown;
 }
 
-inline unsigned getCodePointCountUTF8(StringRef Text) {
-  unsigned CodePoints = 0;
-  for (size_t i = 0, e = Text.size(); i < e;
-       i += llvm::getNumBytesForUTF8(Text[i])) {
-    ++CodePoints;
-  }
-  return CodePoints;
-}
-
-/// \brief Gets the number of code points in the Text using the specified
-/// Encoding.
-inline unsigned getCodePointCount(StringRef Text, Encoding Encoding) {
-  switch (Encoding) {
-  case Encoding_UTF8:
-    return getCodePointCountUTF8(Text);
-  default:
-    return Text.size();
-  }
-}
-
 /// \brief Returns the number of columns required to display the \p Text on a
 /// generic Unicode-capable terminal. Text is assumed to use the specified
 /// \p Encoding.
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index bcea5ac..9bb2a97 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -17,6 +17,7 @@
 #include "AffectedRangeManager.h"
 #include "ContinuationIndenter.h"
 #include "FormatTokenLexer.h"
+#include "NamespaceEndCommentsFixer.h"
 #include "SortJavaScriptImports.h"
 #include "TokenAnalyzer.h"
 #include "TokenAnnotator.h"
@@ -52,6 +53,7 @@
     IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
     IO.enumCase(Value, "Java", FormatStyle::LK_Java);
     IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
+    IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
     IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
     IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
   }
@@ -296,6 +298,8 @@
     IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
     IO.mapOptional("ColumnLimit", Style.ColumnLimit);
     IO.mapOptional("CommentPragmas", Style.CommentPragmas);
+    IO.mapOptional("BreakBeforeInheritanceComma",
+                   Style.BreakBeforeInheritanceComma);
     IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
                    Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
     IO.mapOptional("ConstructorInitializerIndentWidth",
@@ -306,6 +310,7 @@
     IO.mapOptional("DisableFormat", Style.DisableFormat);
     IO.mapOptional("ExperimentalAutoDetectBinPacking",
                    Style.ExperimentalAutoDetectBinPacking);
+    IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
     IO.mapOptional("ForEachMacros", Style.ForEachMacros);
     IO.mapOptional("IncludeCategories", Style.IncludeCategories);
     IO.mapOptional("IncludeIsMainRegex", Style.IncludeIsMainRegex);
@@ -420,6 +425,11 @@
   return std::error_code(static_cast<int>(e), getParseCategory());
 }
 
+inline llvm::Error make_string_error(const llvm::Twine &Message) {
+  return llvm::make_error<llvm::StringError>(Message,
+                                             llvm::inconvertibleErrorCode());
+}
+
 const char *ParseErrorCategory::name() const noexcept {
   return "clang-format.parse_error";
 }
@@ -513,6 +523,7 @@
                              false, false, false, false, false};
   LLVMStyle.BreakAfterJavaFieldAnnotations = false;
   LLVMStyle.BreakConstructorInitializersBeforeComma = false;
+  LLVMStyle.BreakBeforeInheritanceComma = false;
   LLVMStyle.BreakStringLiterals = true;
   LLVMStyle.ColumnLimit = 80;
   LLVMStyle.CommentPragmas = "^ IWYU pragma:";
@@ -522,6 +533,7 @@
   LLVMStyle.Cpp11BracedListStyle = true;
   LLVMStyle.DerivePointerAlignment = false;
   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
+  LLVMStyle.FixNamespaceComments = true;
   LLVMStyle.ForEachMacros.push_back("foreach");
   LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
   LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
@@ -545,7 +557,6 @@
   LLVMStyle.SpacesBeforeTrailingComments = 1;
   LLVMStyle.Standard = FormatStyle::LS_Cpp11;
   LLVMStyle.UseTab = FormatStyle::UT_Never;
-  LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
   LLVMStyle.ReflowComments = true;
   LLVMStyle.SpacesInParentheses = false;
   LLVMStyle.SpacesInSquareBrackets = false;
@@ -613,8 +624,9 @@
     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
     GoogleStyle.BreakBeforeTernaryOperators = false;
-    GoogleStyle.CommentPragmas =
-        "(taze:|@(export|requirecss|return|returns|see|visibility)) ";
+    // taze:, @tag followed by { for a lot of JSDoc tags, and @see, which is
+    // commonly followed by overlong URLs.
+    GoogleStyle.CommentPragmas = "(taze:|(@[A-Za-z_0-9-]+[ \\t]*{)|@see)";
     GoogleStyle.MaxEmptyLinesToKeep = 3;
     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
     GoogleStyle.SpacesInContainerLiterals = false;
@@ -623,6 +635,8 @@
   } else if (Language == FormatStyle::LK_Proto) {
     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
     GoogleStyle.SpacesInContainerLiterals = false;
+  } else if (Language == FormatStyle::LK_ObjC) {
+    GoogleStyle.ColumnLimit = 100;
   }
 
   return GoogleStyle;
@@ -635,6 +649,9 @@
     ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
     ChromiumStyle.ContinuationIndentWidth = 8;
     ChromiumStyle.IndentWidth = 4;
+  } else if (Language == FormatStyle::LK_JavaScript) {
+    ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
+    ChromiumStyle.AllowShortLoopsOnASingleLine = false;
   } else {
     ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
     ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
@@ -642,8 +659,9 @@
     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
     ChromiumStyle.BinPackParameters = false;
     ChromiumStyle.DerivePointerAlignment = false;
+    if (Language == FormatStyle::LK_ObjC)
+      ChromiumStyle.ColumnLimit = 80;
   }
-  ChromiumStyle.SortIncludes = false;
   return ChromiumStyle;
 }
 
@@ -652,15 +670,19 @@
   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
   MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
   MozillaStyle.AlwaysBreakAfterReturnType =
-      FormatStyle::RTBS_TopLevelDefinitions;
+      FormatStyle::RTBS_TopLevel;
   MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
       FormatStyle::DRTBS_TopLevel;
   MozillaStyle.AlwaysBreakTemplateDeclarations = true;
+  MozillaStyle.BinPackParameters = false;
+  MozillaStyle.BinPackArguments = false;
   MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
   MozillaStyle.BreakConstructorInitializersBeforeComma = true;
+  MozillaStyle.BreakBeforeInheritanceComma = true;
   MozillaStyle.ConstructorInitializerIndentWidth = 2;
   MozillaStyle.ContinuationIndentWidth = 2;
   MozillaStyle.Cpp11BracedListStyle = false;
+  MozillaStyle.FixNamespaceComments = false;
   MozillaStyle.IndentCaseLabels = true;
   MozillaStyle.ObjCSpaceAfterProperty = true;
   MozillaStyle.ObjCSpaceBeforeProtocolList = false;
@@ -681,6 +703,7 @@
   Style.BreakConstructorInitializersBeforeComma = true;
   Style.Cpp11BracedListStyle = false;
   Style.ColumnLimit = 0;
+  Style.FixNamespaceComments = false;
   Style.IndentWidth = 4;
   Style.NamespaceIndentation = FormatStyle::NI_Inner;
   Style.ObjCBlockIndentWidth = 4;
@@ -698,6 +721,7 @@
   Style.BreakBeforeTernaryOperators = true;
   Style.Cpp11BracedListStyle = false;
   Style.ColumnLimit = 79;
+  Style.FixNamespaceComments = false;
   Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
   Style.Standard = FormatStyle::LS_Cpp03;
   return Style;
@@ -839,9 +863,10 @@
               Env.getSourceManager(), Start, Length, ReplacementText));
           // FIXME: handle error. For now, print error message and skip the
           // replacement for release version.
-          if (Err)
+          if (Err) {
             llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-          assert(!Err);
+            assert(false);
+          }
         };
         Replace(Start, 1, IsSingle ? "'" : "\"");
         Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
@@ -1188,9 +1213,10 @@
           Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
       // FIXME: better error handling. for now just print error message and skip
       // for the release version.
-      if (Err)
+      if (Err) {
         llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-      assert(!Err && "Fixes must not conflict!");
+        assert(false && "Fixes must not conflict!");
+      }
       Idx = End + 1;
     }
 
@@ -1322,9 +1348,10 @@
       FileName, Includes.front().Offset, IncludesBlockSize, result));
   // FIXME: better error handling. For now, just skip the replacement for the
   // release version.
-  if (Err)
+  if (Err) {
     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-  assert(!Err);
+    assert(false);
+  }
 }
 
 namespace {
@@ -1446,12 +1473,22 @@
   return Replaces;
 }
 
+bool isMpegTS(StringRef Code) {
+  // MPEG transport streams use the ".ts" file extension. clang-format should
+  // not attempt to format those. MPEG TS' frame format starts with 0x47 every
+  // 189 bytes - detect that and return.
+  return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
+}
+
 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
                                    ArrayRef<tooling::Range> Ranges,
                                    StringRef FileName, unsigned *Cursor) {
   tooling::Replacements Replaces;
   if (!Style.SortIncludes)
     return Replaces;
+  if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript &&
+      isMpegTS(Code))
+    return Replaces;
   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript)
     return sortJavaScriptImports(Style, Code, Ranges, FileName);
   sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor);
@@ -1520,8 +1557,8 @@
 // tokens and returns an offset after the sequence.
 unsigned getOffsetAfterTokenSequence(
     StringRef FileName, StringRef Code, const FormatStyle &Style,
-    std::function<unsigned(const SourceManager &, Lexer &, Token &)>
-        GetOffsetAfterSequense) {
+    llvm::function_ref<unsigned(const SourceManager &, Lexer &, Token &)>
+        GetOffsetAfterSequence) {
   std::unique_ptr<Environment> Env =
       Environment::CreateVirtualEnvironment(Code, FileName, /*Ranges=*/{});
   const SourceManager &SourceMgr = Env->getSourceManager();
@@ -1530,7 +1567,7 @@
   Token Tok;
   // Get the first token.
   Lex.LexFromRawLexer(Tok);
-  return GetOffsetAfterSequense(SourceMgr, Lex, Tok);
+  return GetOffsetAfterSequence(SourceMgr, Lex, Tok);
 }
 
 // Check if a sequence of tokens is like "#<Name> <raw_identifier>". If it is,
@@ -1540,7 +1577,7 @@
   bool Matched = Tok.is(tok::hash) && !Lex.LexFromRawLexer(Tok) &&
                  Tok.is(tok::raw_identifier) &&
                  Tok.getRawIdentifier() == Name && !Lex.LexFromRawLexer(Tok) &&
-                 tok::raw_identifier;
+                 Tok.is(tok::raw_identifier);
   if (Matched)
     Lex.LexFromRawLexer(Tok);
   return Matched;
@@ -1634,7 +1671,7 @@
 tooling::Replacements
 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
                         const FormatStyle &Style) {
-  if (Style.Language != FormatStyle::LanguageKind::LK_Cpp)
+  if (!Style.IsCpp())
     return Replaces;
 
   tooling::Replacements HeaderInsertions;
@@ -1797,23 +1834,36 @@
   FormatStyle Expanded = expandPresets(Style);
   if (Expanded.DisableFormat)
     return tooling::Replacements();
-
+  if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
+    return tooling::Replacements();
   auto Env = Environment::CreateVirtualEnvironment(Code, FileName, Ranges);
 
+  auto reformatAfterApplying = [&] (TokenAnalyzer& Fixer) {
+    tooling::Replacements Fixes = Fixer.process();
+    if (!Fixes.empty()) {
+      auto NewCode = applyAllReplacements(Code, Fixes);
+      if (NewCode) {
+        auto NewEnv = Environment::CreateVirtualEnvironment(
+            *NewCode, FileName,
+            tooling::calculateRangesAfterReplacements(Fixes, Ranges));
+        Formatter Format(*NewEnv, Expanded, IncompleteFormat);
+        return Fixes.merge(Format.process());
+      }
+    }
+    Formatter Format(*Env, Expanded, IncompleteFormat);
+    return Format.process();
+  };
+
+  if (Style.Language == FormatStyle::LK_Cpp &&
+      Style.FixNamespaceComments) {
+    NamespaceEndCommentsFixer CommentsFixer(*Env, Expanded);
+    return reformatAfterApplying(CommentsFixer);
+  }
+
   if (Style.Language == FormatStyle::LK_JavaScript &&
       Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) {
     JavaScriptRequoter Requoter(*Env, Expanded);
-    tooling::Replacements Requotes = Requoter.process();
-    if (!Requotes.empty()) {
-      auto NewCode = applyAllReplacements(Code, Requotes);
-      if (NewCode) {
-        auto NewEnv = Environment::CreateVirtualEnvironment(
-            *NewCode, FileName,
-            tooling::calculateRangesAfterReplacements(Requotes, Ranges));
-        Formatter Format(*NewEnv, Expanded, IncompleteFormat);
-        return Requotes.merge(Format.process());
-      }
-    }
+    return reformatAfterApplying(Requoter);
   }
 
   Formatter Format(*Env, Expanded, IncompleteFormat);
@@ -1829,13 +1879,23 @@
   return Clean.process();
 }
 
+tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style,
+                                              StringRef Code,
+                                              ArrayRef<tooling::Range> Ranges,
+                                              StringRef FileName) {
+  std::unique_ptr<Environment> Env =
+      Environment::CreateVirtualEnvironment(Code, FileName, Ranges);
+  NamespaceEndCommentsFixer Fix(*Env, Style);
+  return Fix.process();
+}
+
 LangOptions getFormattingLangOpts(const FormatStyle &Style) {
   LangOptions LangOpts;
   LangOpts.CPlusPlus = 1;
   LangOpts.CPlusPlus11 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
   LangOpts.CPlusPlus14 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
   LangOpts.LineComment = 1;
-  bool AlternativeOperators = Style.Language == FormatStyle::LK_Cpp;
+  bool AlternativeOperators = Style.IsCpp();
   LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0;
   LangOpts.Bool = 1;
   LangOpts.ObjC1 = 1;
@@ -1861,6 +1921,8 @@
     return FormatStyle::LK_Java;
   if (FileName.endswith_lower(".js") || FileName.endswith_lower(".ts"))
     return FormatStyle::LK_JavaScript; // JavaScript or TypeScript.
+  if (FileName.endswith(".m") || FileName.endswith(".mm"))
+    return FormatStyle::LK_ObjC;
   if (FileName.endswith_lower(".proto") ||
       FileName.endswith_lower(".protodevel"))
     return FormatStyle::LK_Proto;
@@ -1869,39 +1931,45 @@
   return FormatStyle::LK_Cpp;
 }
 
-FormatStyle getStyle(StringRef StyleName, StringRef FileName,
-                     StringRef FallbackStyle, vfs::FileSystem *FS) {
+llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
+                                     StringRef FallbackStyleName,
+                                     StringRef Code, vfs::FileSystem *FS) {
   if (!FS) {
     FS = vfs::getRealFileSystem().get();
   }
   FormatStyle Style = getLLVMStyle();
   Style.Language = getLanguageByFileName(FileName);
-  if (!getPredefinedStyle(FallbackStyle, Style.Language, &Style)) {
-    llvm::errs() << "Invalid fallback style \"" << FallbackStyle
-                 << "\" using LLVM style\n";
-    return Style;
-  }
+
+  // This is a very crude detection of whether a header contains ObjC code that
+  // should be improved over time and probably be done on tokens, not one the
+  // bare content of the file.
+  if (Style.Language == FormatStyle::LK_Cpp && FileName.endswith(".h") &&
+      (Code.contains("\n- (") || Code.contains("\n+ (")))
+    Style.Language = FormatStyle::LK_ObjC;
+
+  FormatStyle FallbackStyle = getNoStyle();
+  if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
+    return make_string_error("Invalid fallback style \"" + FallbackStyleName);
 
   if (StyleName.startswith("{")) {
     // Parse YAML/JSON style from the command line.
-    if (std::error_code ec = parseConfiguration(StyleName, &Style)) {
-      llvm::errs() << "Error parsing -style: " << ec.message() << ", using "
-                   << FallbackStyle << " style\n";
-    }
+    if (std::error_code ec = parseConfiguration(StyleName, &Style))
+      return make_string_error("Error parsing -style: " + ec.message());
     return Style;
   }
 
   if (!StyleName.equals_lower("file")) {
     if (!getPredefinedStyle(StyleName, Style.Language, &Style))
-      llvm::errs() << "Invalid value for -style, using " << FallbackStyle
-                   << " style\n";
+      return make_string_error("Invalid value for -style");
     return Style;
   }
 
   // Look for .clang-format/_clang-format file in the file's parent directories.
   SmallString<128> UnsuitableConfigFiles;
   SmallString<128> Path(FileName);
-  llvm::sys::fs::make_absolute(Path);
+  if (std::error_code EC = FS->makeAbsolute(Path))
+    return make_string_error(EC.message());
+
   for (StringRef Directory = Path; !Directory.empty();
        Directory = llvm::sys::path::parent_path(Directory)) {
 
@@ -1917,25 +1985,23 @@
     DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
 
     Status = FS->status(ConfigFile.str());
-    bool IsFile =
+    bool FoundConfigFile =
         Status && (Status->getType() == llvm::sys::fs::file_type::regular_file);
-    if (!IsFile) {
+    if (!FoundConfigFile) {
       // Try _clang-format too, since dotfiles are not commonly used on Windows.
       ConfigFile = Directory;
       llvm::sys::path::append(ConfigFile, "_clang-format");
       DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
       Status = FS->status(ConfigFile.str());
-      IsFile = Status &&
-               (Status->getType() == llvm::sys::fs::file_type::regular_file);
+      FoundConfigFile = Status && (Status->getType() ==
+                                   llvm::sys::fs::file_type::regular_file);
     }
 
-    if (IsFile) {
+    if (FoundConfigFile) {
       llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
           FS->getBufferForFile(ConfigFile.str());
-      if (std::error_code EC = Text.getError()) {
-        llvm::errs() << EC.message() << "\n";
-        break;
-      }
+      if (std::error_code EC = Text.getError())
+        return make_string_error(EC.message());
       if (std::error_code ec =
               parseConfiguration(Text.get()->getBuffer(), &Style)) {
         if (ec == ParseError::Unsuitable) {
@@ -1944,20 +2010,18 @@
           UnsuitableConfigFiles.append(ConfigFile);
           continue;
         }
-        llvm::errs() << "Error reading " << ConfigFile << ": " << ec.message()
-                     << "\n";
-        break;
+        return make_string_error("Error reading " + ConfigFile + ": " +
+                                 ec.message());
       }
       DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n");
       return Style;
     }
   }
-  if (!UnsuitableConfigFiles.empty()) {
-    llvm::errs() << "Configuration file(s) do(es) not support "
-                 << getLanguageName(Style.Language) << ": "
-                 << UnsuitableConfigFiles << "\n";
-  }
-  return Style;
+  if (!UnsuitableConfigFiles.empty())
+    return make_string_error("Configuration file(s) do(es) not support " +
+                             getLanguageName(Style.Language) + ": " +
+                             UnsuitableConfigFiles);
+  return FallbackStyle;
 }
 
 } // namespace format
diff --git a/lib/Format/FormatToken.cpp b/lib/Format/FormatToken.cpp
index 180e537..ba5bf03 100644
--- a/lib/Format/FormatToken.cpp
+++ b/lib/Format/FormatToken.cpp
@@ -77,6 +77,9 @@
   if (State.NextToken == nullptr || !State.NextToken->Previous)
     return 0;
 
+  if (Formats.size() == 1)
+    return 0; // Handled by formatFromToken
+
   // Ensure that we start on the opening brace.
   const FormatToken *LBrace =
       State.NextToken->Previous->getPreviousNonComment();
@@ -92,6 +95,7 @@
 
   // Find the best ColumnFormat, i.e. the best number of columns to use.
   const ColumnFormat *Format = getColumnFormat(RemainingCodePoints);
+
   // If no ColumnFormat can be used, the braced list would generally be
   // bin-packed. Add a severe penalty to this so that column layouts are
   // preferred if possible.
@@ -129,7 +133,9 @@
 unsigned CommaSeparatedList::formatFromToken(LineState &State,
                                              ContinuationIndenter *Indenter,
                                              bool DryRun) {
-  if (HasNestedBracedList)
+  // Formatting with 1 Column isn't really a column layout, so we don't need the
+  // special logic here. We can just avoid bin packing any of the parameters.
+  if (Formats.size() == 1 || HasNestedBracedList)
     State.Stack.back().AvoidBinPacking = true;
   return 0;
 }
@@ -273,7 +279,7 @@
       continue;
 
     // Ignore layouts that are bound to violate the column limit.
-    if (Format.TotalWidth > Style.ColumnLimit)
+    if (Format.TotalWidth > Style.ColumnLimit && Columns > 1)
       continue;
 
     Formats.push_back(Format);
@@ -287,7 +293,7 @@
            I = Formats.rbegin(),
            E = Formats.rend();
        I != E; ++I) {
-    if (I->TotalWidth <= RemainingCharacters) {
+    if (I->TotalWidth <= RemainingCharacters || I->Columns == 1) {
       if (BestFormat && I->LineCount > BestFormat->LineCount)
         break;
       BestFormat = &*I;
diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h
index dd7e991..c964912 100644
--- a/lib/Format/FormatToken.h
+++ b/lib/Format/FormatToken.h
@@ -48,11 +48,13 @@
   TYPE(FunctionTypeLParen) \
   TYPE(ImplicitStringLiteral) \
   TYPE(InheritanceColon) \
+  TYPE(InheritanceComma) \
   TYPE(InlineASMBrace) \
   TYPE(InlineASMColon) \
   TYPE(JavaAnnotation) \
   TYPE(JsComputedPropertyName) \
   TYPE(JsFatArrow) \
+  TYPE(JsNonNullAssertion) \
   TYPE(JsTypeColon) \
   TYPE(JsTypeOperator) \
   TYPE(JsTypeOptionalQuestion) \
@@ -220,6 +222,9 @@
   /// [], {} or <>.
   unsigned NestingLevel = 0;
 
+  /// \brief The indent level of this token. Copied from the surrounding line.
+  unsigned IndentLevel = 0;
+
   /// \brief Penalty for inserting a line break before this token.
   unsigned SplitPenalty = 0;
 
@@ -258,6 +263,11 @@
   /// Only set if \c Type == \c TT_StartOfName.
   bool PartOfMultiVariableDeclStmt = false;
 
+  /// \brief Does this line comment continue a line comment section?
+  ///
+  /// Only set to true if \c Type == \c TT_LineComment.
+  bool ContinuesLineCommentSection = false;
+
   /// \brief If this is a bracket, this points to the matching one.
   FormatToken *MatchingParen = nullptr;
 
@@ -334,11 +344,15 @@
 
   /// \brief Returns whether \p Tok is ([{ or a template opening <.
   bool opensScope() const {
+    if (is(TT_TemplateString) && TokenText.endswith("${"))
+      return true;
     return isOneOf(tok::l_paren, tok::l_brace, tok::l_square,
                    TT_TemplateOpener);
   }
   /// \brief Returns whether \p Tok is )]} or a template closing >.
   bool closesScope() const {
+    if (is(TT_TemplateString) && TokenText.startswith("}"))
+      return true;
     return isOneOf(tok::r_paren, tok::r_brace, tok::r_square,
                    TT_TemplateCloser);
   }
@@ -396,6 +410,21 @@
     }
   }
 
+  /// \brief Returns \c true if this is a string literal that's like a label,
+  /// e.g. ends with "=" or ":".
+  bool isLabelString() const {
+    if (!is(tok::string_literal))
+      return false;
+    StringRef Content = TokenText;
+    if (Content.startswith("\"") || Content.startswith("'"))
+      Content = Content.drop_front(1);
+    if (Content.endswith("\"") || Content.endswith("'"))
+      Content = Content.drop_back(1);
+    Content = Content.trim();
+    return Content.size() > 1 &&
+           (Content.back() == ':' || Content.back() == '=');
+  }
+
   /// \brief Returns actual token start location without leading escaped
   /// newlines and whitespace.
   ///
@@ -428,6 +457,8 @@
   /// \brief Returns \c true if this tokens starts a block-type list, i.e. a
   /// list that should be indented with a block indent.
   bool opensBlockOrBlockTypeList(const FormatStyle &Style) const {
+    if (is(TT_TemplateString) && opensScope())
+      return true;
     return is(TT_ArrayInitializerLSquare) ||
            (is(tok::l_brace) &&
             (BlockKind == BK_Block || is(TT_DictLiteral) ||
@@ -436,6 +467,8 @@
 
   /// \brief Same as opensBlockOrBlockTypeList, but for the closing token.
   bool closesBlockOrBlockTypeList(const FormatStyle &Style) const {
+    if (is(TT_TemplateString) && closesScope())
+      return true;
     return MatchingParen && MatchingParen->opensBlockOrBlockTypeList(Style);
   }
 
@@ -603,6 +636,8 @@
     kw_synchronized = &IdentTable.get("synchronized");
     kw_throws = &IdentTable.get("throws");
     kw___except = &IdentTable.get("__except");
+    kw___has_include = &IdentTable.get("__has_include");
+    kw___has_include_next = &IdentTable.get("__has_include_next");
 
     kw_mark = &IdentTable.get("mark");
 
@@ -629,6 +664,8 @@
   IdentifierInfo *kw_NS_ENUM;
   IdentifierInfo *kw_NS_OPTIONS;
   IdentifierInfo *kw___except;
+  IdentifierInfo *kw___has_include;
+  IdentifierInfo *kw___has_include_next;
 
   // JavaScript keywords.
   IdentifierInfo *kw_as;
diff --git a/lib/Format/FormatTokenLexer.cpp b/lib/Format/FormatTokenLexer.cpp
index 2aa48e3..90b80a4 100644
--- a/lib/Format/FormatTokenLexer.cpp
+++ b/lib/Format/FormatTokenLexer.cpp
@@ -157,7 +157,9 @@
   // postfix unary operators. If the '++' is followed by a non-operand
   // introducing token, the slash here is the operand and not the start of a
   // regex.
-  if (Prev->isOneOf(tok::plusplus, tok::minusminus))
+  // `!` is an unary prefix operator, but also a post-fix operator that casts
+  // away nullability, so the same check applies.
+  if (Prev->isOneOf(tok::plusplus, tok::minusminus, tok::exclaim))
     return (Tokens.size() < 3 || precedesOperand(Tokens[Tokens.size() - 3]));
 
   // The previous token must introduce an operand location where regex
@@ -558,7 +560,7 @@
     Column = FormatTok->LastLineColumnWidth;
   }
 
-  if (Style.Language == FormatStyle::LK_Cpp) {
+  if (Style.IsCpp()) {
     if (!(Tokens.size() > 0 && Tokens.back()->Tok.getIdentifierInfo() &&
           Tokens.back()->Tok.getIdentifierInfo()->getPPKeywordID() ==
               tok::pp_define) &&
diff --git a/lib/Format/NamespaceEndCommentsFixer.cpp b/lib/Format/NamespaceEndCommentsFixer.cpp
new file mode 100644
index 0000000..af75110
--- /dev/null
+++ b/lib/Format/NamespaceEndCommentsFixer.cpp
@@ -0,0 +1,175 @@
+//===--- NamespaceEndCommentsFixer.cpp --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements NamespaceEndCommentsFixer, a TokenAnalyzer that
+/// fixes namespace end comments.
+///
+//===----------------------------------------------------------------------===//
+
+#include "NamespaceEndCommentsFixer.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Regex.h"
+
+#define DEBUG_TYPE "namespace-end-comments-fixer"
+
+namespace clang {
+namespace format {
+
+namespace {
+// The maximal number of unwrapped lines that a short namespace spans.
+// Short namespaces don't need an end comment.
+static const int kShortNamespaceMaxLines = 1;
+
+// Matches a valid namespace end comment.
+// Valid namespace end comments don't need to be edited.
+static llvm::Regex kNamespaceCommentPattern =
+    llvm::Regex("^/[/*] *(end (of )?)? *(anonymous|unnamed)? *"
+                "namespace( +([a-zA-Z0-9:_]+))?\\.? *(\\*/)?$",
+                llvm::Regex::IgnoreCase);
+
+// Computes the name of a namespace given the namespace token.
+// Returns "" for anonymous namespace.
+std::string computeName(const FormatToken *NamespaceTok) {
+  assert(NamespaceTok && NamespaceTok->is(tok::kw_namespace) &&
+         "expecting a namespace token");
+  std::string name = "";
+  // Collects all the non-comment tokens between 'namespace' and '{'.
+  const FormatToken *Tok = NamespaceTok->getNextNonComment();
+  while (Tok && !Tok->is(tok::l_brace)) {
+    name += Tok->TokenText;
+    Tok = Tok->getNextNonComment();
+  }
+  return name;
+}
+
+std::string computeEndCommentText(StringRef NamespaceName, bool AddNewline) {
+  std::string text = "// namespace";
+  if (!NamespaceName.empty()) {
+    text += ' ';
+    text += NamespaceName;
+  }
+  if (AddNewline)
+    text += '\n';
+  return text;
+}
+
+bool hasEndComment(const FormatToken *RBraceTok) {
+  return RBraceTok->Next && RBraceTok->Next->is(tok::comment);
+}
+
+bool validEndComment(const FormatToken *RBraceTok, StringRef NamespaceName) {
+  assert(hasEndComment(RBraceTok));
+  const FormatToken *Comment = RBraceTok->Next;
+  SmallVector<StringRef, 7> Groups;
+  if (kNamespaceCommentPattern.match(Comment->TokenText, &Groups)) {
+    StringRef NamespaceNameInComment = Groups.size() > 5 ? Groups[5] : "";
+    // Anonymous namespace comments must not mention a namespace name.
+    if (NamespaceName.empty() && !NamespaceNameInComment.empty())
+      return false;
+    StringRef AnonymousInComment = Groups.size() > 3 ? Groups[3] : "";
+    // Named namespace comments must not mention anonymous namespace.
+    if (!NamespaceName.empty() && !AnonymousInComment.empty())
+      return false;
+    return NamespaceNameInComment == NamespaceName;
+  }
+  return false;
+}
+
+void addEndComment(const FormatToken *RBraceTok, StringRef EndCommentText,
+                   const SourceManager &SourceMgr,
+                   tooling::Replacements *Fixes) {
+  auto EndLoc = RBraceTok->Tok.getEndLoc();
+  auto Range = CharSourceRange::getCharRange(EndLoc, EndLoc);
+  auto Err = Fixes->add(tooling::Replacement(SourceMgr, Range, EndCommentText));
+  if (Err) {
+    llvm::errs() << "Error while adding namespace end comment: "
+                 << llvm::toString(std::move(Err)) << "\n";
+  }
+}
+
+void updateEndComment(const FormatToken *RBraceTok, StringRef EndCommentText,
+                      const SourceManager &SourceMgr,
+                      tooling::Replacements *Fixes) {
+  assert(hasEndComment(RBraceTok));
+  const FormatToken *Comment = RBraceTok->Next;
+  auto Range = CharSourceRange::getCharRange(Comment->getStartOfNonWhitespace(),
+                                             Comment->Tok.getEndLoc());
+  auto Err = Fixes->add(tooling::Replacement(SourceMgr, Range, EndCommentText));
+  if (Err) {
+    llvm::errs() << "Error while updating namespace end comment: "
+                 << llvm::toString(std::move(Err)) << "\n";
+  }
+}
+} // namespace
+
+NamespaceEndCommentsFixer::NamespaceEndCommentsFixer(const Environment &Env,
+                                                     const FormatStyle &Style)
+    : TokenAnalyzer(Env, Style) {}
+
+tooling::Replacements NamespaceEndCommentsFixer::analyze(
+    TokenAnnotator &Annotator, SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
+    FormatTokenLexer &Tokens) {
+  const SourceManager &SourceMgr = Env.getSourceManager();
+  AffectedRangeMgr.computeAffectedLines(AnnotatedLines.begin(),
+                                        AnnotatedLines.end());
+  tooling::Replacements Fixes;
+  for (size_t I = 0, E = AnnotatedLines.size(); I != E; ++I) {
+    if (!AnnotatedLines[I]->Affected || AnnotatedLines[I]->InPPDirective ||
+        !AnnotatedLines[I]->startsWith(tok::r_brace))
+      continue;
+    const AnnotatedLine *EndLine = AnnotatedLines[I];
+    size_t StartLineIndex = EndLine->MatchingOpeningBlockLineIndex;
+    if (StartLineIndex == UnwrappedLine::kInvalidIndex)
+      continue;
+    assert(StartLineIndex < E);
+    const FormatToken *NamespaceTok = AnnotatedLines[StartLineIndex]->First;
+    // Detect "(inline)? namespace" in the beginning of a line.
+    if (NamespaceTok->is(tok::kw_inline))
+      NamespaceTok = NamespaceTok->getNextNonComment();
+    if (NamespaceTok->isNot(tok::kw_namespace))
+      continue;
+    FormatToken *RBraceTok = EndLine->First;
+    if (RBraceTok->Finalized)
+      continue;
+    RBraceTok->Finalized = true;
+    const FormatToken *EndCommentPrevTok = RBraceTok;
+    // Namespaces often end with '};'. In that case, attach namespace end
+    // comments to the semicolon tokens.
+    if (RBraceTok->Next && RBraceTok->Next->is(tok::semi)) {
+      EndCommentPrevTok = RBraceTok->Next;
+    }
+    // The next token in the token stream after the place where the end comment
+    // token must be. This is either the next token on the current line or the
+    // first token on the next line.
+    const FormatToken *EndCommentNextTok = EndCommentPrevTok->Next;
+    if (EndCommentNextTok && EndCommentNextTok->is(tok::comment))
+      EndCommentNextTok = EndCommentNextTok->Next;
+    if (!EndCommentNextTok && I + 1 < E)
+      EndCommentNextTok = AnnotatedLines[I + 1]->First;
+    bool AddNewline = EndCommentNextTok &&
+                      EndCommentNextTok->NewlinesBefore == 0 &&
+                      EndCommentNextTok->isNot(tok::eof);
+    const std::string NamespaceName = computeName(NamespaceTok);
+    const std::string EndCommentText =
+        computeEndCommentText(NamespaceName, AddNewline);
+    if (!hasEndComment(EndCommentPrevTok)) {
+      bool isShort = I - StartLineIndex <= kShortNamespaceMaxLines + 1;
+      if (!isShort)
+        addEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes);
+      continue;
+    }
+    if (!validEndComment(EndCommentPrevTok, NamespaceName))
+      updateEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes);
+  }
+  return Fixes;
+}
+
+} // namespace format
+} // namespace clang
diff --git a/lib/Format/NamespaceEndCommentsFixer.h b/lib/Format/NamespaceEndCommentsFixer.h
new file mode 100644
index 0000000..7790668
--- /dev/null
+++ b/lib/Format/NamespaceEndCommentsFixer.h
@@ -0,0 +1,37 @@
+//===--- NamespaceEndCommentsFixer.h ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file declares NamespaceEndCommentsFixer, a TokenAnalyzer that
+/// fixes namespace end comments.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_FORMAT_NAMESPACEENDCOMMENTSFIXER_H
+#define LLVM_CLANG_LIB_FORMAT_NAMESPACEENDCOMMENTSFIXER_H
+
+#include "TokenAnalyzer.h"
+
+namespace clang {
+namespace format {
+
+class NamespaceEndCommentsFixer : public TokenAnalyzer {
+public:
+  NamespaceEndCommentsFixer(const Environment &Env, const FormatStyle &Style);
+
+  tooling::Replacements
+  analyze(TokenAnnotator &Annotator,
+          SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
+          FormatTokenLexer &Tokens) override;
+};
+
+} // end namespace format
+} // end namespace clang
+
+#endif
diff --git a/lib/Format/SortJavaScriptImports.cpp b/lib/Format/SortJavaScriptImports.cpp
index d72455b..e73695c 100644
--- a/lib/Format/SortJavaScriptImports.cpp
+++ b/lib/Format/SortJavaScriptImports.cpp
@@ -197,9 +197,10 @@
         ReferencesText));
     // FIXME: better error handling. For now, just print error message and skip
     // the replacement for the release version.
-    if (Err)
+    if (Err) {
       llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-    assert(!Err);
+      assert(false);
+    }
 
     return Result;
   }
diff --git a/lib/Format/TokenAnalyzer.h b/lib/Format/TokenAnalyzer.h
index b49f3da..78a3d1b 100644
--- a/lib/Format/TokenAnalyzer.h
+++ b/lib/Format/TokenAnalyzer.h
@@ -55,15 +55,12 @@
 
   FileID getFileID() const { return ID; }
 
-  StringRef getFileName() const { return FileName; }
-
   ArrayRef<CharSourceRange> getCharRanges() const { return CharRanges; }
 
   const SourceManager &getSourceManager() const { return SM; }
 
 private:
   FileID ID;
-  StringRef FileName;
   SmallVector<CharSourceRange, 8> CharRanges;
   SourceManager &SM;
 
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 57f3027..228425b 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -311,13 +311,13 @@
     // In C++, this can happen either in array of templates (foo<int>[10])
     // or when array is a nested template type (unique_ptr<type1<type2>[]>).
     bool CppArrayTemplates =
-        Style.Language == FormatStyle::LK_Cpp && Parent &&
+        Style.IsCpp() && Parent &&
         Parent->is(TT_TemplateCloser) &&
         (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
          Contexts.back().InTemplateArgument);
 
     bool StartsObjCMethodExpr =
-        !CppArrayTemplates && Style.Language == FormatStyle::LK_Cpp &&
+        !CppArrayTemplates && Style.IsCpp() &&
         Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
         CurrentToken->isNot(tok::l_brace) &&
         (!Parent ||
@@ -336,6 +336,9 @@
                  Contexts.back().ContextKind == tok::l_brace &&
                  Parent->isOneOf(tok::l_brace, tok::comma)) {
         Left->Type = TT_JsComputedPropertyName;
+      } else if (CurrentToken->is(tok::r_square) && Parent &&
+                 Parent->is(TT_TemplateCloser)) {
+        Left->Type = TT_ArraySubscriptLSquare;
       } else if (Style.Language == FormatStyle::LK_Proto ||
                  (!CppArrayTemplates && Parent &&
                   Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
@@ -432,8 +435,7 @@
         if (CurrentToken->isOneOf(tok::colon, tok::l_brace)) {
           FormatToken *Previous = CurrentToken->getPreviousNonComment();
           if (((CurrentToken->is(tok::colon) &&
-                (!Contexts.back().ColonIsDictLiteral ||
-                 Style.Language != FormatStyle::LK_Cpp)) ||
+                (!Contexts.back().ColonIsDictLiteral || !Style.IsCpp())) ||
                Style.Language == FormatStyle::LK_Proto) &&
               (Previous->Tok.getIdentifierInfo() ||
                Previous->is(tok::string_literal)))
@@ -674,6 +676,8 @@
     case tok::comma:
       if (Contexts.back().InCtorInitializer)
         Tok->Type = TT_CtorInitializerComma;
+      else if (Contexts.back().InInheritanceList)
+        Tok->Type = TT_InheritanceComma;
       else if (Contexts.back().FirstStartOfName &&
                (Contexts.size() == 1 || Line.startsWith(tok::kw_for))) {
         Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
@@ -682,6 +686,12 @@
       if (Contexts.back().IsForEachMacro)
         Contexts.back().IsExpression = true;
       break;
+    case tok::identifier:
+      if (Tok->isOneOf(Keywords.kw___has_include,
+                       Keywords.kw___has_include_next)) {
+        parseHasInclude();
+      }
+      break;
     default:
       break;
     }
@@ -725,6 +735,14 @@
     }
   }
 
+  void parseHasInclude() {
+    if (!CurrentToken || !CurrentToken->is(tok::l_paren))
+      return;
+    next();  // '('
+    parseIncludeDirective();
+    next();  // ')'
+  }
+
   LineType parsePreprocessorDirective() {
     bool IsFirstToken = CurrentToken->IsFirst;
     LineType Type = LT_PreprocessorDirective;
@@ -775,8 +793,14 @@
     default:
       break;
     }
-    while (CurrentToken)
+    while (CurrentToken) {
+      FormatToken *Tok = CurrentToken;
       next();
+      if (Tok->isOneOf(Keywords.kw___has_include,
+                       Keywords.kw___has_include_next)) {
+        parseHasInclude();
+      }
+    }
     return Type;
   }
 
@@ -923,6 +947,7 @@
     bool CanBeExpression = true;
     bool InTemplateArgument = false;
     bool InCtorInitializer = false;
+    bool InInheritanceList = false;
     bool CaretFound = false;
     bool IsForEachMacro = false;
   };
@@ -982,6 +1007,9 @@
                Current.Previous->is(TT_CtorInitializerColon)) {
       Contexts.back().IsExpression = true;
       Contexts.back().InCtorInitializer = true;
+    } else if (Current.Previous &&
+               Current.Previous->is(TT_InheritanceColon)) {
+      Contexts.back().InInheritanceList = true;
     } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
       for (FormatToken *Previous = Current.Previous;
            Previous && Previous->isOneOf(tok::star, tok::amp);
@@ -1002,6 +1030,23 @@
       // The token type is already known.
       return;
 
+    if (Style.Language == FormatStyle::LK_JavaScript) {
+      if (Current.is(tok::exclaim)) {
+        if (Current.Previous &&
+            (Current.Previous->isOneOf(tok::identifier, tok::r_paren,
+                                       tok::r_square, tok::r_brace) ||
+             Current.Previous->Tok.isLiteral())) {
+          Current.Type = TT_JsNonNullAssertion;
+          return;
+        }
+        if (Current.Next &&
+            Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
+          Current.Type = TT_JsNonNullAssertion;
+          return;
+        }
+      }
+    }
+
     // Line.MightBeFunctionDecl can only be true after the parentheses of a
     // function declaration have been found. In this case, 'Current' is a
     // trailing token of this declaration and thus cannot be a name.
@@ -1061,7 +1106,8 @@
       if (Current.MatchingParen && Current.Next &&
           !Current.Next->isBinaryOperator() &&
           !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
-                                 tok::period, tok::arrow, tok::coloncolon))
+                                 tok::comma, tok::period, tok::arrow,
+                                 tok::coloncolon))
         if (FormatToken *AfterParen = Current.MatchingParen->Next) {
           // Make sure this isn't the return type of an Obj-C block declaration
           if (AfterParen->Tok.isNot(tok::caret)) {
@@ -1135,16 +1181,17 @@
     if (Tok.isNot(tok::identifier) || !Tok.Previous)
       return false;
 
-    if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof))
+    if (Tok.Previous->isOneOf(TT_LeadingJavaAnnotation, Keywords.kw_instanceof,
+                              Keywords.kw_as))
       return false;
     if (Style.Language == FormatStyle::LK_JavaScript &&
         Tok.Previous->is(Keywords.kw_in))
       return false;
 
     // Skip "const" as it does not have an influence on whether this is a name.
-    FormatToken *PreviousNotConst = Tok.Previous;
+    FormatToken *PreviousNotConst = Tok.getPreviousNonComment();
     while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
-      PreviousNotConst = PreviousNotConst->Previous;
+      PreviousNotConst = PreviousNotConst->getPreviousNonComment();
 
     if (!PreviousNotConst)
       return false;
@@ -1173,8 +1220,7 @@
   /// \brief Determine whether ')' is ending a cast.
   bool rParenEndsCast(const FormatToken &Tok) {
     // C-style casts are only used in C++ and Java.
-    if (Style.Language != FormatStyle::LK_Cpp &&
-        Style.Language != FormatStyle::LK_Java)
+    if (!Style.IsCpp() && Style.Language != FormatStyle::LK_Java)
       return false;
 
     // Empty parens aren't casts and there are no casts at the end of the line.
@@ -1280,8 +1326,7 @@
 
     const FormatToken *NextToken = Tok.getNextNonComment();
     if (!NextToken ||
-        NextToken->isOneOf(tok::arrow, Keywords.kw_final, tok::equal,
-                           Keywords.kw_override) ||
+        NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const) ||
         (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment()))
       return TT_PointerOrReference;
 
@@ -1444,7 +1489,9 @@
 
       // At the end of the line or when an operator with higher precedence is
       // found, insert fake parenthesis and return.
-      if (!Current || (Current->closesScope() && Current->MatchingParen) ||
+      if (!Current ||
+          (Current->closesScope() &&
+           (Current->MatchingParen || Current->is(TT_TemplateString))) ||
           (CurrentPrecedence != -1 && CurrentPrecedence < Precedence) ||
           (CurrentPrecedence == prec::Conditional &&
            Precedence == prec::Assignment && Current->is(tok::colon))) {
@@ -1453,7 +1500,9 @@
 
       // Consume scopes: (), [], <> and {}
       if (Current->opensScope()) {
-        while (Current && !Current->closesScope()) {
+        // In fragment of a JavaScript template string can look like '}..${' and
+        // thus close a scope and open a new one at the same time.
+        while (Current && (!Current->closesScope() || Current->opensScope())) {
           next();
           parse();
         }
@@ -1492,13 +1541,14 @@
         return prec::Conditional;
       if (NextNonComment && NextNonComment->is(tok::colon) &&
           NextNonComment->is(TT_DictLiteral))
-        return prec::Comma;
+        return prec::Assignment;
+      if (Current->is(TT_JsComputedPropertyName))
+        return prec::Assignment;
       if (Current->is(TT_LambdaArrow))
         return prec::Comma;
       if (Current->is(TT_JsFatArrow))
         return prec::Assignment;
-      if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName,
-                           TT_JsComputedPropertyName) ||
+      if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName) ||
           (Current->is(tok::comment) && NextNonComment &&
            NextNonComment->is(TT_SelectorName)))
         return 0;
@@ -1509,7 +1559,7 @@
           Current->is(Keywords.kw_instanceof))
         return prec::Relational;
       if (Style.Language == FormatStyle::LK_JavaScript &&
-          Current->is(Keywords.kw_in))
+          Current->isOneOf(Keywords.kw_in, Keywords.kw_as))
         return prec::Relational;
       if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
         return Current->getPrecedence();
@@ -1593,8 +1643,14 @@
   for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(),
                                                           E = Lines.rend();
        I != E; ++I) {
-    if (NextNonCommentLine && (*I)->First->is(tok::comment) &&
-        (*I)->First->Next == nullptr)
+    bool CommentLine = (*I)->First;
+    for (const FormatToken *Tok = (*I)->First; Tok; Tok = Tok->Next) {
+      if (!Tok->is(tok::comment)) {
+        CommentLine = false;
+        break;
+      }
+    }
+    if (NextNonCommentLine && CommentLine)
       (*I)->Level = NextNonCommentLine->Level;
     else
       NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
@@ -1696,7 +1752,7 @@
     }
   }
 
-  // Check whether parameter list can be long to a function declaration.
+  // Check whether parameter list can belong to a function declaration.
   if (!Next || !Next->is(tok::l_paren) || !Next->MatchingParen)
     return false;
   // If the lines ends with "{", this is likely an function definition.
@@ -1710,6 +1766,10 @@
     return true;
   for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen;
        Tok = Tok->Next) {
+    if (Tok->is(tok::l_paren) && Tok->MatchingParen) {
+      Tok = Tok->MatchingParen;
+      continue;
+    }
     if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
         Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis))
       return true;
@@ -1752,8 +1812,6 @@
 
   Line.First->TotalLength =
       Line.First->IsMultiline ? Style.ColumnLimit : Line.First->ColumnWidth;
-  if (!Line.First->Next)
-    return;
   FormatToken *Current = Line.First->Next;
   bool InFunctionDecl = Line.MightBeFunctionDecl;
   while (Current) {
@@ -1829,9 +1887,18 @@
   }
 
   calculateUnbreakableTailLengths(Line);
+  unsigned IndentLevel = Line.Level;
   for (Current = Line.First; Current != nullptr; Current = Current->Next) {
     if (Current->Role)
       Current->Role->precomputeFormattingInfos(Current);
+    if (Current->MatchingParen &&
+        Current->MatchingParen->opensBlockOrBlockTypeList(Style)) {
+      assert(IndentLevel > 0);
+      --IndentLevel;
+    }
+    Current->IndentLevel = IndentLevel;
+    if (Current->opensBlockOrBlockTypeList(Style))
+      ++IndentLevel;
   }
 
   DEBUG({ printDebugInfo(Line); });
@@ -1879,8 +1946,7 @@
       return 100;
   }
 
-  if (Left.is(tok::comma) || (Right.is(tok::identifier) && Right.Next &&
-                              Right.Next->is(TT_DictLiteral)))
+  if (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_DictLiteral))
     return 1;
   if (Right.is(tok::l_square)) {
     if (Style.Language == FormatStyle::LK_Proto)
@@ -1910,7 +1976,7 @@
   if (Right.is(TT_LambdaArrow))
     return 110;
   if (Left.is(tok::equal) && Right.is(tok::l_brace))
-    return 150;
+    return 160;
   if (Left.is(TT_CastRParen))
     return 100;
   if (Left.is(tok::coloncolon) ||
@@ -1996,20 +2062,24 @@
   if (Left.is(TT_JavaAnnotation))
     return 50;
 
+  if (Left.isOneOf(tok::plus, tok::comma) && Left.Previous &&
+      Left.Previous->isLabelString() &&
+      (Left.NextOperator || Left.OperatorIndex != 0))
+    return 45;
+  if (Right.is(tok::plus) && Left.isLabelString() &&
+      (Right.NextOperator || Right.OperatorIndex != 0))
+    return 25;
+  if (Left.is(tok::comma))
+    return 1;
+  if (Right.is(tok::lessless) && Left.isLabelString() &&
+      (Right.NextOperator || Right.OperatorIndex != 1))
+    return 25;
   if (Right.is(tok::lessless)) {
-    if (Left.is(tok::string_literal) &&
-        (Right.NextOperator || Right.OperatorIndex != 1)) {
-      StringRef Content = Left.TokenText;
-      if (Content.startswith("\""))
-        Content = Content.drop_front(1);
-      if (Content.endswith("\""))
-        Content = Content.drop_back(1);
-      Content = Content.trim();
-      if (Content.size() > 1 &&
-          (Content.back() == ':' || Content.back() == '='))
-        return 25;
-    }
-    return 1; // Breaking at a << is really cheap.
+    // Breaking at a << is really cheap.
+    if (!Left.is(tok::r_paren) || Right.OperatorIndex > 0)
+      // Slightly prefer to break before the first one in log-like statements.
+      return 2;
+    return 1;
   }
   if (Left.is(TT_ConditionalExpr))
     return prec::Conditional;
@@ -2082,9 +2152,9 @@
         !Line.IsMultiVariableDeclStmt)))
     return true;
   if (Left.is(TT_PointerOrReference))
-    return Right.Tok.isLiteral() ||
-           Right.isOneOf(TT_BlockComment, Keywords.kw_final,
-                         Keywords.kw_override) ||
+    return Right.Tok.isLiteral() || Right.is(TT_BlockComment) ||
+           (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
+            !Right.is(TT_StartOfName)) ||
            (Right.is(tok::l_brace) && Right.BlockKind == BK_Block) ||
            (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
                            tok::l_paren) &&
@@ -2163,7 +2233,7 @@
   const FormatToken &Left = *Right.Previous;
   if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo())
     return true; // Never ever merge two identifiers.
-  if (Style.Language == FormatStyle::LK_Cpp) {
+  if (Style.IsCpp()) {
     if (Left.is(tok::kw_operator))
       return Right.is(tok::coloncolon);
   } else if (Style.Language == FormatStyle::LK_Proto) {
@@ -2177,6 +2247,14 @@
   } else if (Style.Language == FormatStyle::LK_JavaScript) {
     if (Left.is(TT_JsFatArrow))
       return true;
+    if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
+        Right.MatchingParen) {
+      const FormatToken *Next = Right.MatchingParen->getNextNonComment();
+      // An async arrow function, for example: `x = async () => foo();`,
+      // as opposed to calling a function called async: `x = async();`
+      if (Next && Next->is(TT_JsFatArrow))
+        return true;
+    }
     if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) ||
         (Right.is(TT_TemplateString) && Right.TokenText.startswith("}")))
       return false;
@@ -2223,12 +2301,9 @@
       // locations that should have whitespace following are identified by the
       // above set of follower tokens.
       return false;
-    // Postfix non-null assertion operator, as in `foo!.bar()`.
-    if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren,
-                                                tok::r_square, tok::r_brace) ||
-                                   Left.Tok.isLiteral()))
+    if (Right.is(TT_JsNonNullAssertion))
       return false;
-    if (Left.is(tok::exclaim) && Right.is(Keywords.kw_as))
+    if (Left.is(TT_JsNonNullAssertion) && Right.is(Keywords.kw_as))
       return true; // "x! as string"
   } else if (Style.Language == FormatStyle::LK_Java) {
     if (Left.is(tok::r_square) && Right.is(tok::l_brace))
@@ -2298,12 +2373,16 @@
   if (!Style.SpaceBeforeAssignmentOperators &&
       Right.getPrecedence() == prec::Assignment)
     return false;
+  if (Right.is(tok::coloncolon) && Left.is(tok::identifier))
+    // Generally don't remove existing spaces between an identifier and "::".
+    // The identifier might actually be a macro name such as ALWAYS_INLINE. If
+    // this turns out to be too lenient, add analysis of the identifier itself.
+    return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd();
   if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment))
     return (Left.is(TT_TemplateOpener) &&
             Style.Standard == FormatStyle::LS_Cpp03) ||
-           !(Left.isOneOf(tok::identifier, tok::l_paren, tok::r_paren,
-                          tok::l_square) ||
-             Left.isOneOf(TT_TemplateCloser, TT_TemplateOpener));
+           !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
+                          TT_TemplateCloser, TT_TemplateOpener));
   if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
     return Style.SpacesInAngles;
   if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) ||
@@ -2371,6 +2450,12 @@
     if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next &&
         Right.Next->is(tok::string_literal))
       return true;
+  } else if (Style.Language == FormatStyle::LK_Cpp ||
+             Style.Language == FormatStyle::LK_ObjC ||
+             Style.Language == FormatStyle::LK_Proto) {
+    if (Left.isStringLiteral() &&
+        (Right.isStringLiteral() || Right.is(TT_ObjCStringLiteral)))
+      return true;
   }
 
   // If the last token before a '}' is a comma or a trailing comment, the
@@ -2394,9 +2479,6 @@
            (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
   if (Left.isTrailingComment())
     return true;
-  if (Left.isStringLiteral() &&
-      (Right.isStringLiteral() || Right.is(TT_ObjCStringLiteral)))
-    return true;
   if (Right.Previous->IsUnterminatedLiteral)
     return true;
   if (Right.is(tok::lessless) && Right.Next &&
@@ -2412,6 +2494,10 @@
       Style.BreakConstructorInitializersBeforeComma &&
       !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
     return true;
+  // Break only if we have multiple inheritance.
+  if (Style.BreakBeforeInheritanceComma &&
+      Right.is(TT_InheritanceComma))
+   return true;
   if (Right.is(tok::string_literal) && Right.TokenText.startswith("R\""))
     // Raw string literals are special wrt. line breaks. The author has made a
     // deliberate choice and might have aligned the contents of the string
@@ -2454,11 +2540,10 @@
       return true;
   } else if (Style.Language == FormatStyle::LK_JavaScript) {
     const FormatToken *NonComment = Right.getPreviousNonComment();
-    if (Left.isOneOf(tok::kw_return, tok::kw_continue, tok::kw_break,
-                     tok::kw_throw) ||
-        (NonComment &&
-         NonComment->isOneOf(tok::kw_return, tok::kw_continue, tok::kw_break,
-                             tok::kw_throw)))
+    if (NonComment &&
+        NonComment->isOneOf(tok::kw_return, tok::kw_continue, tok::kw_break,
+                            tok::kw_throw, Keywords.kw_interface,
+                            Keywords.kw_type))
       return false; // Otherwise a semicolon is inserted.
     if (Left.is(TT_JsFatArrow) && Right.is(tok::l_brace))
       return false;
@@ -2472,6 +2557,10 @@
       return Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
     if (Right.is(Keywords.kw_as))
       return false; // must not break before as in 'x as type' casts
+    if (Left.is(Keywords.kw_as))
+      return true;
+    if (Left.is(TT_JsNonNullAssertion))
+      return true;
     if (Left.is(Keywords.kw_declare) &&
         Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
                       Keywords.kw_function, tok::kw_class, tok::kw_enum,
@@ -2481,9 +2570,12 @@
       // https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#A.10
       return false;
     if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) &&
-        Right.isOneOf(tok::identifier, tok::string_literal)) {
+        Right.isOneOf(tok::identifier, tok::string_literal))
       return false; // must not break in "module foo { ...}"
-    }
+    if (Right.is(TT_TemplateString) && Right.closesScope())
+      return false;
+    if (Left.is(TT_TemplateString) && Left.opensScope())
+      return true;
   }
 
   if (Left.is(tok::at))
@@ -2586,6 +2678,10 @@
   if (Right.is(TT_CtorInitializerComma) &&
       Style.BreakConstructorInitializersBeforeComma)
     return true;
+  if (Left.is(TT_InheritanceComma) && Style.BreakBeforeInheritanceComma)
+    return false;
+  if (Right.is(TT_InheritanceComma) && Style.BreakBeforeInheritanceComma)
+    return true;
   if ((Left.is(tok::greater) && Right.is(tok::greater)) ||
       (Left.is(tok::less) && Right.is(tok::less)))
     return false;
@@ -2611,7 +2707,8 @@
                        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));
+         (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
+         (Left.is(TT_TemplateOpener) && !Right.is(TT_TemplateCloser));
 }
 
 void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) {
@@ -2623,12 +2720,14 @@
                  << " T=" << getTokenTypeName(Tok->Type)
                  << " S=" << Tok->SpacesRequiredBefore
                  << " B=" << Tok->BlockParameterCount
+                 << " BK=" << Tok->BlockKind
                  << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName()
                  << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind
                  << " FakeLParens=";
     for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
       llvm::errs() << Tok->FakeLParens[i] << "/";
-    llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n";
+    llvm::errs() << " FakeRParens=" << Tok->FakeRParens;
+    llvm::errs() << " Text='" << Tok->TokenText << "'\n";
     if (!Tok->Next)
       assert(Tok == Line.Last);
     Tok = Tok->Next;
diff --git a/lib/Format/TokenAnnotator.h b/lib/Format/TokenAnnotator.h
index 97daaf4..8055095 100644
--- a/lib/Format/TokenAnnotator.h
+++ b/lib/Format/TokenAnnotator.h
@@ -39,6 +39,7 @@
 public:
   AnnotatedLine(const UnwrappedLine &Line)
       : First(Line.Tokens.front().Tok), Level(Line.Level),
+        MatchingOpeningBlockLineIndex(Line.MatchingOpeningBlockLineIndex),
         InPPDirective(Line.InPPDirective),
         MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
         IsMultiVariableDeclStmt(false), Affected(false),
@@ -109,6 +110,7 @@
 
   LineType Type;
   unsigned Level;
+  size_t MatchingOpeningBlockLineIndex;
   bool InPPDirective;
   bool MustBeDeclaration;
   bool MightBeFunctionDecl;
@@ -122,7 +124,7 @@
   /// input ranges.
   bool LeadingEmptyLinesAffected;
 
-  /// \c True if a one of this line's children intersects with an input range.
+  /// \c True if one of this line's children intersects with an input range.
   bool ChildrenAffected;
 
 private:
diff --git a/lib/Format/UnwrappedLineFormatter.cpp b/lib/Format/UnwrappedLineFormatter.cpp
index d7f1c42..c3c154a 100644
--- a/lib/Format/UnwrappedLineFormatter.cpp
+++ b/lib/Format/UnwrappedLineFormatter.cpp
@@ -530,34 +530,33 @@
     if (Previous.Children[0]->First->MustBreakBefore)
       return false;
 
-    // Cannot merge multiple statements into a single line.
-    if (Previous.Children.size() > 1)
-      return false;
-
     // Cannot merge into one line if this line ends on a comment.
     if (Previous.is(tok::comment))
       return false;
 
+    // Cannot merge multiple statements into a single line.
+    if (Previous.Children.size() > 1)
+      return false;
+
+    const AnnotatedLine *Child = Previous.Children[0];
     // We can't put the closing "}" on a line with a trailing comment.
-    if (Previous.Children[0]->Last->isTrailingComment())
+    if (Child->Last->isTrailingComment())
       return false;
 
     // If the child line exceeds the column limit, we wouldn't want to merge it.
     // We add +2 for the trailing " }".
     if (Style.ColumnLimit > 0 &&
-        Previous.Children[0]->Last->TotalLength + State.Column + 2 >
-            Style.ColumnLimit)
+        Child->Last->TotalLength + State.Column + 2 > Style.ColumnLimit)
       return false;
 
     if (!DryRun) {
       Whitespaces->replaceWhitespace(
-          *Previous.Children[0]->First,
-          /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1,
+          *Child->First, /*Newlines=*/0, /*Spaces=*/1,
           /*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective);
     }
-    Penalty += formatLine(*Previous.Children[0], State.Column + 1, DryRun);
+    Penalty += formatLine(*Child, State.Column + 1, DryRun);
 
-    State.Column += 1 + Previous.Children[0]->Last->TotalLength;
+    State.Column += 1 + Child->Last->TotalLength;
     return true;
   }
 
@@ -841,8 +840,7 @@
 
     if (ShouldFormat && TheLine.Type != LT_Invalid) {
       if (!DryRun)
-        formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level, Indent,
-                         TheLine.InPPDirective);
+        formatFirstToken(TheLine, PreviousLine, Indent);
 
       NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
       unsigned ColumnLimit = getColumnLimit(TheLine.InPPDirective, NextLine);
@@ -882,9 +880,8 @@
                               TheLine.LeadingEmptyLinesAffected);
         // Format the first token.
         if (ReformatLeadingWhitespace)
-          formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level,
-                           TheLine.First->OriginalColumn,
-                           TheLine.InPPDirective);
+          formatFirstToken(TheLine, PreviousLine,
+                           TheLine.First->OriginalColumn);
         else
           Whitespaces->addUntouchableToken(*TheLine.First,
                                            TheLine.InPPDirective);
@@ -904,15 +901,14 @@
   return Penalty;
 }
 
-void UnwrappedLineFormatter::formatFirstToken(FormatToken &RootToken,
+void UnwrappedLineFormatter::formatFirstToken(const AnnotatedLine &Line,
                                               const AnnotatedLine *PreviousLine,
-                                              unsigned IndentLevel,
-                                              unsigned Indent,
-                                              bool InPPDirective) {
+                                              unsigned Indent) {
+  FormatToken& RootToken = *Line.First;
   if (RootToken.is(tok::eof)) {
     unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u);
-    Whitespaces->replaceWhitespace(RootToken, Newlines, /*IndentLevel=*/0,
-                                   /*Spaces=*/0, /*TargetColumn=*/0);
+    Whitespaces->replaceWhitespace(RootToken, Newlines, /*Spaces=*/0,
+                                   /*StartOfTokenColumn=*/0);
     return;
   }
   unsigned Newlines =
@@ -944,9 +940,9 @@
       (!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline))
     Newlines = std::min(1u, Newlines);
 
-  Whitespaces->replaceWhitespace(RootToken, Newlines, IndentLevel, Indent,
-                                 Indent, InPPDirective &&
-                                             !RootToken.HasUnescapedNewline);
+  Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent,
+                                 Line.InPPDirective &&
+                                     !RootToken.HasUnescapedNewline);
 }
 
 unsigned
diff --git a/lib/Format/UnwrappedLineFormatter.h b/lib/Format/UnwrappedLineFormatter.h
index 7bcead9..93247f7 100644
--- a/lib/Format/UnwrappedLineFormatter.h
+++ b/lib/Format/UnwrappedLineFormatter.h
@@ -44,9 +44,8 @@
 private:
   /// \brief Add a new line and the required indent before the first Token
   /// of the \c UnwrappedLine if there was no structural parsing error.
-  void formatFirstToken(FormatToken &RootToken,
-                        const AnnotatedLine *PreviousLine, unsigned IndentLevel,
-                        unsigned Indent, bool InPPDirective);
+  void formatFirstToken(const AnnotatedLine &Line,
+                        const AnnotatedLine *PreviousLine, unsigned Indent);
 
   /// \brief Returns the column limit for a line, taking into account whether we
   /// need an escaped newline due to a continued preprocessor directive.
@@ -57,7 +56,8 @@
   // starting from a specific additional offset. Improves performance if there
   // are many nested blocks.
   std::map<std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned>,
-           unsigned> PenaltyCache;
+           unsigned>
+      PenaltyCache;
 
   ContinuationIndenter *Indenter;
   WhitespaceManager *Whitespaces;
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 52278d1..25bc991 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -202,7 +202,8 @@
                                          ArrayRef<FormatToken *> Tokens,
                                          UnwrappedLineConsumer &Callback)
     : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
-      CurrentLines(&Lines), Style(Style), Keywords(Keywords), Tokens(nullptr),
+      CurrentLines(&Lines), Style(Style), Keywords(Keywords),
+      CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
       Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1) {}
 
 void UnwrappedLineParser::reset() {
@@ -334,8 +335,11 @@
     case tok::l_brace:
       if (Style.Language == FormatStyle::LK_JavaScript && PrevTok &&
           PrevTok->is(tok::colon))
-        // In TypeScript's TypeMemberLists, there can be semicolons between the
-        // individual members.
+        // A colon indicates this code is in a type, or a braced list following
+        // a label in an object literal ({a: {b: 1}}).
+        // The code below could be confused by semicolons between the individual
+        // members in a type member list, which would normally trigger BK_Block.
+        // In both cases, this must be parsed as an inline braced init.
         Tok->BlockKind = BK_BracedInit;
       else
         Tok->BlockKind = BK_Unknown;
@@ -360,8 +364,6 @@
           // BlockKind later if we parse a braced list (where all blocks
           // inside are by default braced lists), or when we explicitly detect
           // blocks (for example while parsing lambdas).
-          //
-          // We exclude + and - as they can be ObjC visibility modifiers.
           ProbablyBracedList =
               (Style.Language == FormatStyle::LK_JavaScript &&
                NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,
@@ -369,6 +371,8 @@
               NextTok->isOneOf(tok::comma, tok::period, tok::colon,
                                tok::r_paren, tok::r_square, tok::l_brace,
                                tok::l_square, tok::l_paren, tok::ellipsis) ||
+              (NextTok->is(tok::identifier) &&
+               !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace)) ||
               (NextTok->is(tok::semi) &&
                (!ExpectClassBody || LBraceStack.size() != 1)) ||
               (NextTok->isBinaryOperator() && !NextIsObjCMethod);
@@ -424,6 +428,8 @@
     parseParens();
 
   addUnwrappedLine();
+  size_t OpeningLineIndex =
+      Lines.empty() ? (UnwrappedLine::kInvalidIndex) : (Lines.size() - 1);
 
   ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
                                           MustBeDeclaration);
@@ -449,6 +455,7 @@
   if (MunchSemi && FormatTok->Tok.is(tok::semi))
     nextToken();
   Line->Level = InitialLevel;
+  Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
 }
 
 static bool isGoogScope(const UnwrappedLine &Line) {
@@ -582,13 +589,14 @@
 }
 
 void UnwrappedLineParser::parsePPIf(bool IfDef) {
+  bool IfNDef = FormatTok->is(tok::pp_ifndef);
   nextToken();
-  bool IsLiteralFalse = (FormatTok->Tok.isLiteral() &&
-                         FormatTok->Tok.getLiteralData() != nullptr &&
-                         StringRef(FormatTok->Tok.getLiteralData(),
-                                   FormatTok->Tok.getLength()) == "0") ||
-                        FormatTok->Tok.is(tok::kw_false);
-  conditionalCompilationStart(!IfDef && IsLiteralFalse);
+  bool Unreachable = false;
+  if (!IfDef && (FormatTok->is(tok::kw_false) || FormatTok->TokenText == "0"))
+    Unreachable = true;
+  if (IfDef && !IfNDef && FormatTok->TokenText == "SWIG")
+    Unreachable = true;
+  conditionalCompilationStart(Unreachable);
   parsePPUnknown();
 }
 
@@ -737,7 +745,7 @@
       return;
   }
   if (Next->is(tok::exclaim) && PreviousMustBeValue)
-    addUnwrappedLine();
+    return addUnwrappedLine();
   bool NextMustBeValue = mustBeJSIdentOrValue(Keywords, Next);
   bool NextEndsTemplateExpr =
       Next->is(TT_TemplateString) && Next->TokenText.startswith("}");
@@ -745,9 +753,9 @@
       (PreviousMustBeValue ||
        Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus,
                          tok::minusminus)))
-    addUnwrappedLine();
+    return addUnwrappedLine();
   if (PreviousMustBeValue && isJSDeclOrStmt(Keywords, Next))
-    addUnwrappedLine();
+    return addUnwrappedLine();
 }
 
 void UnwrappedLineParser::parseStructuralElement() {
@@ -942,7 +950,7 @@
       if (!parseEnum())
         break;
       // This only applies for C++.
-      if (Style.Language != FormatStyle::LK_Cpp) {
+      if (!Style.IsCpp()) {
         addUnwrappedLine();
         return;
       }
@@ -1123,7 +1131,7 @@
 }
 
 bool UnwrappedLineParser::tryToParseLambda() {
-  if (Style.Language != FormatStyle::LK_Cpp) {
+  if (!Style.IsCpp()) {
     nextToken();
     return false;
   }
@@ -1255,10 +1263,13 @@
     if (FormatTok->is(tok::l_brace))
       tryToParseBracedList();
     else
-      while (FormatTok->isNot(tok::l_brace) && !eof())
+      while (!FormatTok->isOneOf(tok::l_brace, tok::semi) && !eof())
         nextToken();
   }
 
+  if (FormatTok->is(tok::semi))
+    return;
+
   parseChildBlock();
 }
 
@@ -1294,6 +1305,12 @@
           continue;
         }
       }
+      if (FormatTok->is(tok::l_brace)) {
+        // Could be a method inside of a braced list `{a() { return 1; }}`.
+        if (tryToParseBracedList())
+          continue;
+        parseChildBlock();
+      }
     }
     switch (FormatTok->Tok.getKind()) {
     case tok::caret:
@@ -1305,12 +1322,6 @@
     case tok::l_square:
       tryToParseLambda();
       break;
-    case tok::l_brace:
-      // Assume there are no blocks inside a braced init list apart
-      // from the ones we explicitly parse out (like lambdas).
-      FormatTok->BlockKind = BK_BracedInit;
-      parseBracedList();
-      break;
     case tok::l_paren:
       parseParens();
       // JavaScript can just have free standing methods and getters/setters in
@@ -1321,6 +1332,12 @@
         break;
       }
       break;
+    case tok::l_brace:
+      // Assume there are no blocks inside a braced init list apart
+      // from the ones we explicitly parse out (like lambdas).
+      FormatTok->BlockKind = BK_BracedInit;
+      parseBracedList();
+      break;
     case tok::r_brace:
       nextToken();
       return !HasError;
@@ -1377,6 +1394,12 @@
       if (FormatTok->Tok.is(tok::l_brace))
         parseBracedList();
       break;
+    case tok::kw_class:
+      if (Style.Language == FormatStyle::LK_JavaScript)
+        parseRecord(/*ParseAsExpr=*/true);
+      else
+        nextToken();
+      break;
     case tok::identifier:
       if (Style.Language == FormatStyle::LK_JavaScript &&
           (FormatTok->is(Keywords.kw_function) ||
@@ -1718,8 +1741,7 @@
       nextToken();
       // If there are two identifiers in a row, this is likely an elaborate
       // return type. In Java, this can be "implements", etc.
-      if (Style.Language == FormatStyle::LK_Cpp &&
-          FormatTok->is(tok::identifier))
+      if (Style.IsCpp() && FormatTok->is(tok::identifier))
         return false;
     }
   }
@@ -1815,7 +1837,7 @@
   addUnwrappedLine();
 }
 
-void UnwrappedLineParser::parseRecord() {
+void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
   const FormatToken &InitialToken = *FormatTok;
   nextToken();
 
@@ -1859,11 +1881,15 @@
     }
   }
   if (FormatTok->Tok.is(tok::l_brace)) {
-    if (ShouldBreakBeforeBrace(Style, InitialToken))
-      addUnwrappedLine();
+    if (ParseAsExpr) {
+      parseChildBlock();
+    } else {
+      if (ShouldBreakBeforeBrace(Style, InitialToken))
+        addUnwrappedLine();
 
-    parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
-               /*MunchSemi=*/false);
+      parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
+                 /*MunchSemi=*/false);
+    }
   }
   // There is no addUnwrappedLine() here so that we fall through to parsing a
   // structural element afterwards. Thus, in "class A {} n, m;",
@@ -1971,7 +1997,14 @@
       !FormatTok->isStringLiteral())
     return;
 
-  while (!eof() && FormatTok->isNot(tok::semi)) {
+  while (!eof()) {
+    if (FormatTok->is(tok::semi))
+      return;
+    if (Line->Tokens.size() == 0) {
+      // Common issue: Automatic Semicolon Insertion wrapped the line, so the
+      // import statement should terminate.
+      return;
+    }
     if (FormatTok->is(tok::l_brace)) {
       FormatTok->BlockKind = BK_Block;
       parseBracedList();
@@ -1988,7 +2021,9 @@
   for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
                                                     E = Line.Tokens.end();
        I != E; ++I) {
-    llvm::dbgs() << I->Tok->Tok.getName() << "[" << I->Tok->Type << "] ";
+    llvm::dbgs() << I->Tok->Tok.getName() << "["
+                 << "T=" << I->Tok->Type
+                 << ", OC=" << I->Tok->OriginalColumn << "] ";
   }
   for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
                                                     E = Line.Tokens.end();
@@ -2013,6 +2048,7 @@
   });
   CurrentLines->push_back(std::move(*Line));
   Line->Tokens.clear();
+  Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;
   if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
     CurrentLines->append(
         std::make_move_iterator(PreprocessorDirectives.begin()),
@@ -2028,13 +2064,139 @@
          FormatTok.NewlinesBefore > 0;
 }
 
+static bool isLineComment(const FormatToken &FormatTok) {
+  return FormatTok.is(tok::comment) &&
+         FormatTok.TokenText.startswith("//");
+}
+
+// Checks if \p FormatTok is a line comment that continues the line comment
+// section on \p Line.
+static bool continuesLineComment(const FormatToken &FormatTok,
+                                 const UnwrappedLine &Line,
+                                 llvm::Regex &CommentPragmasRegex) {
+  if (Line.Tokens.empty())
+    return false;
+
+  StringRef IndentContent = FormatTok.TokenText;
+  if (FormatTok.TokenText.startswith("//") ||
+      FormatTok.TokenText.startswith("/*"))
+    IndentContent = FormatTok.TokenText.substr(2);
+  if (CommentPragmasRegex.match(IndentContent))
+    return false;
+
+  // If Line starts with a line comment, then FormatTok continues the comment
+  // section if its original column is greater or equal to the original start
+  // column of the line.
+  //
+  // Define the min column token of a line as follows: if a line ends in '{' or
+  // contains a '{' followed by a line comment, then the min column token is
+  // that '{'. Otherwise, the min column token of the line is the first token of
+  // the line.
+  //
+  // If Line starts with a token other than a line comment, then FormatTok
+  // continues the comment section if its original column is greater than the
+  // original start column of the min column token of the line.
+  //
+  // For example, the second line comment continues the first in these cases:
+  //
+  // // first line
+  // // second line
+  //
+  // and:
+  //
+  // // first line
+  //  // second line
+  //
+  // and:
+  //
+  // int i; // first line
+  //  // second line
+  //
+  // and:
+  //
+  // do { // first line
+  //      // second line
+  //   int i;
+  // } while (true);
+  //
+  // and:
+  //
+  // enum {
+  //   a, // first line
+  //    // second line
+  //   b
+  // };
+  //
+  // The second line comment doesn't continue the first in these cases:
+  //
+  //   // first line
+  //  // second line
+  //
+  // and:
+  //
+  // int i; // first line
+  // // second line
+  //
+  // and:
+  //
+  // do { // first line
+  //   // second line
+  //   int i;
+  // } while (true);
+  //
+  // and:
+  //
+  // enum {
+  //   a, // first line
+  //   // second line
+  // };
+  const FormatToken *MinColumnToken = Line.Tokens.front().Tok;
+
+  // Scan for '{//'. If found, use the column of '{' as a min column for line
+  // comment section continuation.
+  const FormatToken *PreviousToken = nullptr;
+  for (const UnwrappedLineNode &Node : Line.Tokens) {
+    if (PreviousToken && PreviousToken->is(tok::l_brace) &&
+        isLineComment(*Node.Tok)) {
+      MinColumnToken = PreviousToken;
+      break;
+    }
+    PreviousToken = Node.Tok;
+
+    // Grab the last newline preceding a token in this unwrapped line.
+    if (Node.Tok->NewlinesBefore > 0) {
+      MinColumnToken = Node.Tok;
+    }
+  }
+  if (PreviousToken && PreviousToken->is(tok::l_brace)) {
+    MinColumnToken = PreviousToken;
+  }
+
+  unsigned MinContinueColumn =
+      MinColumnToken->OriginalColumn +
+      (isLineComment(*MinColumnToken) ? 0 : 1);
+  return isLineComment(FormatTok) && FormatTok.NewlinesBefore == 1 &&
+         isLineComment(*(Line.Tokens.back().Tok)) &&
+         FormatTok.OriginalColumn >= MinContinueColumn;
+}
+
 void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
   bool JustComments = Line->Tokens.empty();
   for (SmallVectorImpl<FormatToken *>::const_iterator
            I = CommentsBeforeNextToken.begin(),
            E = CommentsBeforeNextToken.end();
        I != E; ++I) {
-    if (isOnNewLine(**I) && JustComments)
+    // Line comments that belong to the same line comment section are put on the
+    // same line since later we might want to reflow content between them.
+    // Additional fine-grained breaking of line comment sections is controlled
+    // by the class BreakableLineCommentSection in case it is desirable to keep
+    // several line comment sections in the same unwrapped line.
+    //
+    // FIXME: Consider putting separate line comment sections as children to the
+    // unwrapped line instead.
+    (*I)->ContinuesLineCommentSection =
+        continuesLineComment(**I, *Line, CommentPragmasRegex);
+    if (isOnNewLine(**I) && JustComments && !(*I)->ContinuesLineCommentSection)
       addUnwrappedLine();
     pushToken(*I);
   }
@@ -2062,13 +2224,71 @@
   return Line->Tokens.back().Tok;
 }
 
+void UnwrappedLineParser::distributeComments(
+    const SmallVectorImpl<FormatToken *> &Comments,
+    const FormatToken *NextTok) {
+  // Whether or not a line comment token continues a line is controlled by
+  // the method continuesLineComment, with the following caveat:
+  //
+  // Define a trail of Comments to be a nonempty proper postfix of Comments such
+  // that each comment line from the trail is aligned with the next token, if
+  // the next token exists. If a trail exists, the beginning of the maximal
+  // trail is marked as a start of a new comment section.
+  //
+  // For example in this code:
+  //
+  // int a; // line about a
+  //   // line 1 about b
+  //   // line 2 about b
+  //   int b;
+  //
+  // the two lines about b form a maximal trail, so there are two sections, the
+  // first one consisting of the single comment "// line about a" and the
+  // second one consisting of the next two comments.
+  if (Comments.empty())
+    return;
+  bool ShouldPushCommentsInCurrentLine = true;
+  bool HasTrailAlignedWithNextToken = false;
+  unsigned StartOfTrailAlignedWithNextToken = 0;
+  if (NextTok) {
+    // We are skipping the first element intentionally.
+    for (unsigned i = Comments.size() - 1; i > 0; --i) {
+      if (Comments[i]->OriginalColumn == NextTok->OriginalColumn) {
+        HasTrailAlignedWithNextToken = true;
+        StartOfTrailAlignedWithNextToken = i;
+      }
+    }
+  }
+  for (unsigned i = 0, e = Comments.size(); i < e; ++i) {
+    FormatToken *FormatTok = Comments[i];
+    if (HasTrailAlignedWithNextToken &&
+        i == StartOfTrailAlignedWithNextToken) {
+      FormatTok->ContinuesLineCommentSection = false;
+    } else {
+      FormatTok->ContinuesLineCommentSection =
+          continuesLineComment(*FormatTok, *Line, CommentPragmasRegex);
+    }
+    if (!FormatTok->ContinuesLineCommentSection &&
+        (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
+      ShouldPushCommentsInCurrentLine = false;
+    }
+    if (ShouldPushCommentsInCurrentLine) {
+      pushToken(FormatTok);
+    } else {
+      CommentsBeforeNextToken.push_back(FormatTok);
+    }
+  }
+}
+
 void UnwrappedLineParser::readToken() {
-  bool CommentsInCurrentLine = true;
+  SmallVector<FormatToken *, 1> Comments;
   do {
     FormatTok = Tokens->getNextToken();
     assert(FormatTok);
     while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) &&
            (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) {
+      distributeComments(Comments, FormatTok);
+      Comments.clear();
       // If there is an unfinished unwrapped line, we flush the preprocessor
       // directives only after that unwrapped line was finished later.
       bool SwitchToPreprocessorLines = !Line->Tokens.empty();
@@ -2098,17 +2318,17 @@
       continue;
     }
 
-    if (!FormatTok->Tok.is(tok::comment))
+    if (!FormatTok->Tok.is(tok::comment)) {
+      distributeComments(Comments, FormatTok);
+      Comments.clear();
       return;
-    if (isOnNewLine(*FormatTok) || FormatTok->IsFirst) {
-      CommentsInCurrentLine = false;
     }
-    if (CommentsInCurrentLine) {
-      pushToken(FormatTok);
-    } else {
-      CommentsBeforeNextToken.push_back(FormatTok);
-    }
+
+    Comments.push_back(FormatTok);
   } while (!eof());
+
+  distributeComments(Comments, nullptr);
+  Comments.clear();
 }
 
 void UnwrappedLineParser::pushToken(FormatToken *Tok) {
diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h
index 9c78d33..15d1d9c 100644
--- a/lib/Format/UnwrappedLineParser.h
+++ b/lib/Format/UnwrappedLineParser.h
@@ -19,6 +19,7 @@
 #include "FormatToken.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Format/Format.h"
+#include "llvm/Support/Regex.h"
 #include <list>
 #include <stack>
 
@@ -47,6 +48,14 @@
   bool InPPDirective;
 
   bool MustBeDeclaration;
+
+  /// \brief If this \c UnwrappedLine closes a block in a sequence of lines,
+  /// \c MatchingOpeningBlockLineIndex stores the index of the corresponding
+  /// opening line. Otherwise, \c MatchingOpeningBlockLineIndex must be
+  /// \c kInvalidIndex.
+  size_t MatchingOpeningBlockLineIndex;
+
+  static const size_t kInvalidIndex = -1;
 };
 
 class UnwrappedLineConsumer {
@@ -99,7 +108,10 @@
   void parseAccessSpecifier();
   bool parseEnum();
   void parseJavaEnumBody();
-  void parseRecord();
+  // Parses a record (aka class) as a top level element. If ParseAsExpr is true,
+  // parses the record as a child block, i.e. if the class declaration is an
+  // expression.
+  void parseRecord(bool ParseAsExpr = false);
   void parseObjCProtocolList();
   void parseObjCUntilAtEnd();
   void parseObjCInterfaceOrImplementation();
@@ -113,6 +125,21 @@
   void nextToken();
   const FormatToken *getPreviousToken();
   void readToken();
+
+  // Decides which comment tokens should be added to the current line and which
+  // should be added as comments before the next token.
+  //
+  // Comments specifies the sequence of comment tokens to analyze. They get
+  // either pushed to the current line or added to the comments before the next
+  // token.
+  //
+  // NextTok specifies the next token. A null pointer NextTok is supported, and
+  // signifies either the absense of a next token, or that the next token
+  // shouldn't be taken into accunt for the analysis.
+  void distributeComments(const SmallVectorImpl<FormatToken *> &Comments,
+                          const FormatToken *NextTok);
+
+  // Adds the comment preceding the next token to unwrapped lines.
   void flushComments(bool NewlineBeforeNext);
   void pushToken(FormatToken *Tok);
   void calculateBraceTypes(bool ExpectClassBody = false);
@@ -162,6 +189,8 @@
   const FormatStyle &Style;
   const AdditionalKeywords &Keywords;
 
+  llvm::Regex CommentPragmasRegex;
+
   FormatTokenSource *Tokens;
   UnwrappedLineConsumer &Callback;
 
@@ -213,8 +242,8 @@
   SmallVector<UnwrappedLine, 0> Children;
 };
 
-inline UnwrappedLine::UnwrappedLine()
-    : Level(0), InPPDirective(false), MustBeDeclaration(false) {}
+inline UnwrappedLine::UnwrappedLine() : Level(0), InPPDirective(false),
+  MustBeDeclaration(false), MatchingOpeningBlockLineIndex(kInvalidIndex) {}
 
 } // end namespace format
 } // end namespace clang
diff --git a/lib/Format/WhitespaceManager.cpp b/lib/Format/WhitespaceManager.cpp
index ebc72a9..93a2e49 100644
--- a/lib/Format/WhitespaceManager.cpp
+++ b/lib/Format/WhitespaceManager.cpp
@@ -25,69 +25,60 @@
       C2.OriginalWhitespaceRange.getBegin());
 }
 
-WhitespaceManager::Change::Change(
-    bool CreateReplacement, SourceRange OriginalWhitespaceRange,
-    unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn,
-    unsigned NewlinesBefore, StringRef PreviousLinePostfix,
-    StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective,
-    bool IsStartOfDeclName, bool IsInsideToken)
-    : CreateReplacement(CreateReplacement),
+WhitespaceManager::Change::Change(const FormatToken &Tok,
+                                  bool CreateReplacement,
+                                  SourceRange OriginalWhitespaceRange,
+                                  int Spaces, unsigned StartOfTokenColumn,
+                                  unsigned NewlinesBefore,
+                                  StringRef PreviousLinePostfix,
+                                  StringRef CurrentLinePrefix,
+                                  bool ContinuesPPDirective, bool IsInsideToken)
+    : Tok(&Tok), CreateReplacement(CreateReplacement),
       OriginalWhitespaceRange(OriginalWhitespaceRange),
       StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
       PreviousLinePostfix(PreviousLinePostfix),
-      CurrentLinePrefix(CurrentLinePrefix), Kind(Kind),
-      ContinuesPPDirective(ContinuesPPDirective),
-      IsStartOfDeclName(IsStartOfDeclName), IndentLevel(IndentLevel),
-      Spaces(Spaces), IsInsideToken(IsInsideToken), IsTrailingComment(false),
-      TokenLength(0), PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
+      CurrentLinePrefix(CurrentLinePrefix),
+      ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces),
+      IsInsideToken(IsInsideToken), IsTrailingComment(false), TokenLength(0),
+      PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
       StartOfBlockComment(nullptr), IndentationOffset(0) {}
 
-void WhitespaceManager::reset() {
-  Changes.clear();
-  Replaces.clear();
-}
-
 void WhitespaceManager::replaceWhitespace(FormatToken &Tok, unsigned Newlines,
-                                          unsigned IndentLevel, unsigned Spaces,
+                                          unsigned Spaces,
                                           unsigned StartOfTokenColumn,
                                           bool InPPDirective) {
   if (Tok.Finalized)
     return;
   Tok.Decision = (Newlines > 0) ? FD_Break : FD_Continue;
-  Changes.push_back(
-      Change(/*CreateReplacement=*/true, Tok.WhitespaceRange, IndentLevel,
-             Spaces, StartOfTokenColumn, Newlines, "", "", Tok.Tok.getKind(),
-             InPPDirective && !Tok.IsFirst,
-             Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName),
-             /*IsInsideToken=*/false));
+  Changes.push_back(Change(Tok, /*CreateReplacement=*/true,
+                           Tok.WhitespaceRange, Spaces, StartOfTokenColumn,
+                           Newlines, "", "", InPPDirective && !Tok.IsFirst,
+                           /*IsInsideToken=*/false));
 }
 
 void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
                                             bool InPPDirective) {
   if (Tok.Finalized)
     return;
-  Changes.push_back(Change(
-      /*CreateReplacement=*/false, Tok.WhitespaceRange, /*IndentLevel=*/0,
-      /*Spaces=*/0, Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
-      Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst,
-      Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName),
-      /*IsInsideToken=*/false));
+  Changes.push_back(Change(Tok, /*CreateReplacement=*/false,
+                           Tok.WhitespaceRange, /*Spaces=*/0,
+                           Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
+                           InPPDirective && !Tok.IsFirst,
+                           /*IsInsideToken=*/false));
 }
 
 void WhitespaceManager::replaceWhitespaceInToken(
     const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
     StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
-    unsigned Newlines, unsigned IndentLevel, int Spaces) {
+    unsigned Newlines, int Spaces) {
   if (Tok.Finalized)
     return;
   SourceLocation Start = Tok.getStartOfNonWhitespace().getLocWithOffset(Offset);
-  Changes.push_back(Change(
-      true, SourceRange(Start, Start.getLocWithOffset(ReplaceChars)),
-      IndentLevel, Spaces, std::max(0, Spaces), Newlines, PreviousPostfix,
-      CurrentPrefix, Tok.is(TT_LineComment) ? tok::comment : tok::unknown,
-      InPPDirective && !Tok.IsFirst,
-      Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName),
-      /*IsInsideToken=*/Newlines == 0));
+  Changes.push_back(
+      Change(Tok, /*CreateReplacement=*/true,
+             SourceRange(Start, Start.getLocWithOffset(ReplaceChars)), Spaces,
+             std::max(0, Spaces), Newlines, PreviousPostfix, CurrentPrefix,
+             InPPDirective && !Tok.IsFirst, /*IsInsideToken=*/true));
 }
 
 const tooling::Replacements &WhitespaceManager::generateReplacements() {
@@ -130,30 +121,64 @@
         Changes[i - 1].StartOfTokenColumn + Changes[i - 1].TokenLength;
 
     Changes[i - 1].IsTrailingComment =
-        (Changes[i].NewlinesBefore > 0 || Changes[i].Kind == tok::eof ||
-         (Changes[i].IsInsideToken && Changes[i].Kind == tok::comment)) &&
-        Changes[i - 1].Kind == tok::comment;
+        (Changes[i].NewlinesBefore > 0 || Changes[i].Tok->is(tok::eof) ||
+         (Changes[i].IsInsideToken && Changes[i].Tok->is(tok::comment))) &&
+        Changes[i - 1].Tok->is(tok::comment) &&
+        // FIXME: This is a dirty hack. The problem is that
+        // BreakableLineCommentSection does comment reflow changes and here is
+        // the aligning of trailing comments. Consider the case where we reflow
+        // the second line up in this example:
+        // 
+        // // line 1
+        // // line 2
+        // 
+        // That amounts to 2 changes by BreakableLineCommentSection:
+        //  - the first, delimited by (), for the whitespace between the tokens,
+        //  - and second, delimited by [], for the whitespace at the beginning
+        //  of the second token:
+        // 
+        // // line 1(
+        // )[// ]line 2
+        //
+        // So in the end we have two changes like this:
+        //
+        // // line1()[ ]line 2
+        //
+        // Note that the OriginalWhitespaceStart of the second change is the
+        // same as the PreviousOriginalWhitespaceEnd of the first change.
+        // In this case, the below check ensures that the second change doesn't
+        // get treated as a trailing comment change here, since this might
+        // trigger additional whitespace to be wrongly inserted before "line 2"
+        // by the comment aligner here.
+        //
+        // For a proper solution we need a mechanism to say to WhitespaceManager
+        // that a particular change breaks the current sequence of trailing
+        // comments.
+        OriginalWhitespaceStart != PreviousOriginalWhitespaceEnd;
   }
   // FIXME: The last token is currently not always an eof token; in those
   // cases, setting TokenLength of the last token to 0 is wrong.
   Changes.back().TokenLength = 0;
-  Changes.back().IsTrailingComment = Changes.back().Kind == tok::comment;
+  Changes.back().IsTrailingComment = Changes.back().Tok->is(tok::comment);
 
   const WhitespaceManager::Change *LastBlockComment = nullptr;
   for (auto &Change : Changes) {
     // Reset the IsTrailingComment flag for changes inside of trailing comments
-    // so they don't get realigned later.
-    if (Change.IsInsideToken)
+    // so they don't get realigned later. Comment line breaks however still need
+    // to be aligned.
+    if (Change.IsInsideToken && Change.NewlinesBefore == 0)
       Change.IsTrailingComment = false;
     Change.StartOfBlockComment = nullptr;
     Change.IndentationOffset = 0;
-    if (Change.Kind == tok::comment) {
-      LastBlockComment = &Change;
-    } else if (Change.Kind == tok::unknown) {
-      if ((Change.StartOfBlockComment = LastBlockComment))
-        Change.IndentationOffset =
-            Change.StartOfTokenColumn -
-            Change.StartOfBlockComment->StartOfTokenColumn;
+    if (Change.Tok->is(tok::comment)) {
+      if (Change.Tok->is(TT_LineComment) || !Change.IsInsideToken)
+        LastBlockComment = &Change;
+      else {
+        if ((Change.StartOfBlockComment = LastBlockComment))
+          Change.IndentationOffset =
+              Change.StartOfTokenColumn -
+              Change.StartOfBlockComment->StartOfTokenColumn;
+      }
     } else {
       LastBlockComment = nullptr;
     }
@@ -252,15 +277,13 @@
       FoundMatchOnLine = false;
     }
 
-    if (Changes[i].Kind == tok::comma) {
+    if (Changes[i].Tok->is(tok::comma)) {
       ++CommasBeforeMatch;
-    } else if (Changes[i].Kind == tok::r_brace ||
-               Changes[i].Kind == tok::r_paren ||
-               Changes[i].Kind == tok::r_square) {
+    } else if (Changes[i].Tok->isOneOf(tok::r_brace, tok::r_paren,
+                                       tok::r_square)) {
       --NestingLevel;
-    } else if (Changes[i].Kind == tok::l_brace ||
-               Changes[i].Kind == tok::l_paren ||
-               Changes[i].Kind == tok::l_square) {
+    } else if (Changes[i].Tok->isOneOf(tok::l_brace, tok::l_paren,
+                                       tok::l_square)) {
       // We want sequences to skip over child scopes if possible, but not the
       // other way around.
       NestingLevelOfLastMatch = std::min(NestingLevelOfLastMatch, NestingLevel);
@@ -319,7 +342,7 @@
                 if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
                   return false;
 
-                return C.Kind == tok::equal;
+                return C.Tok->is(tok::equal);
               },
               Changes);
 }
@@ -335,7 +358,11 @@
   //   float const* v2;
   //   SomeVeryLongType const& v3;
 
-  AlignTokens(Style, [](Change const &C) { return C.IsStartOfDeclName; },
+  AlignTokens(Style,
+              [](Change const &C) {
+                return C.Tok->isOneOf(TT_StartOfName,
+                                      TT_FunctionDeclarationName);
+              },
               Changes);
 }
 
@@ -365,17 +392,14 @@
     // If this comment follows an } in column 0, it probably documents the
     // closing of a namespace and we don't want to align it.
     bool FollowsRBraceInColumn0 = i > 0 && Changes[i].NewlinesBefore == 0 &&
-                                  Changes[i - 1].Kind == tok::r_brace &&
+                                  Changes[i - 1].Tok->is(tok::r_brace) &&
                                   Changes[i - 1].StartOfTokenColumn == 0;
     bool WasAlignedWithStartOfNextLine = false;
     if (Changes[i].NewlinesBefore == 1) { // A comment on its own line.
       unsigned CommentColumn = SourceMgr.getSpellingColumnNumber(
           Changes[i].OriginalWhitespaceRange.getEnd());
       for (unsigned j = i + 1; j != e; ++j) {
-        if (Changes[j].Kind == tok::comment ||
-            Changes[j].Kind == tok::unknown)
-          // Skip over comments and unknown tokens. "unknown tokens are used for
-          // the continuation of multiline comments.
+        if (Changes[j].Tok->is(tok::comment))
           continue;
 
         unsigned NextColumn = SourceMgr.getSpellingColumnNumber(
@@ -486,7 +510,8 @@
                           C.PreviousEndOfTokenColumn, C.EscapedNewlineColumn);
       else
         appendNewlineText(ReplacementText, C.NewlinesBefore);
-      appendIndentText(ReplacementText, C.IndentLevel, std::max(0, C.Spaces),
+      appendIndentText(ReplacementText, C.Tok->IndentLevel,
+                       std::max(0, C.Spaces),
                        C.StartOfTokenColumn - std::max(0, C.Spaces));
       ReplacementText.append(C.CurrentLinePrefix);
       storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
@@ -506,9 +531,10 @@
       SourceMgr, CharSourceRange::getCharRange(Range), Text));
   // FIXME: better error handling. For now, just print an error message in the
   // release version.
-  if (Err)
+  if (Err) {
     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-  assert(!Err);
+    assert(false);
+  }
 }
 
 void WhitespaceManager::appendNewlineText(std::string &Text,
diff --git a/lib/Format/WhitespaceManager.h b/lib/Format/WhitespaceManager.h
index 3562347..0a2a031 100644
--- a/lib/Format/WhitespaceManager.h
+++ b/lib/Format/WhitespaceManager.h
@@ -41,13 +41,9 @@
                     bool UseCRLF)
       : SourceMgr(SourceMgr), Style(Style), UseCRLF(UseCRLF) {}
 
-  /// \brief Prepares the \c WhitespaceManager for another run.
-  void reset();
-
   /// \brief Replaces the whitespace in front of \p Tok. Only call once for
   /// each \c AnnotatedToken.
-  void replaceWhitespace(FormatToken &Tok, unsigned Newlines,
-                         unsigned IndentLevel, unsigned Spaces,
+  void replaceWhitespace(FormatToken &Tok, unsigned Newlines, unsigned Spaces,
                          unsigned StartOfTokenColumn,
                          bool InPPDirective = false);
 
@@ -75,8 +71,7 @@
                                 unsigned ReplaceChars,
                                 StringRef PreviousPostfix,
                                 StringRef CurrentPrefix, bool InPPDirective,
-                                unsigned Newlines, unsigned IndentLevel,
-                                int Spaces);
+                                unsigned Newlines, int Spaces);
 
   /// \brief Returns all the \c Replacements created during formatting.
   const tooling::Replacements &generateReplacements();
@@ -94,8 +89,6 @@
       const SourceManager &SourceMgr;
     };
 
-    Change() {}
-
     /// \brief Creates a \c Change.
     ///
     /// The generated \c Change will replace the characters at
@@ -105,12 +98,17 @@
     ///
     /// \p StartOfTokenColumn and \p InPPDirective will be used to lay out
     /// trailing comments and escaped newlines.
-    Change(bool CreateReplacement, SourceRange OriginalWhitespaceRange,
-           unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn,
-           unsigned NewlinesBefore, StringRef PreviousLinePostfix,
-           StringRef CurrentLinePrefix, tok::TokenKind Kind,
-           bool ContinuesPPDirective, bool IsStartOfDeclName,
-           bool IsInsideToken);
+    Change(const FormatToken &Tok, bool CreateReplacement,
+           SourceRange OriginalWhitespaceRange, int Spaces,
+           unsigned StartOfTokenColumn, unsigned NewlinesBefore,
+           StringRef PreviousLinePostfix, StringRef CurrentLinePrefix,
+           bool ContinuesPPDirective, bool IsInsideToken);
+
+    // The kind of the token whose whitespace this change replaces, or in which
+    // this change inserts whitespace.
+    // FIXME: Currently this is not set correctly for breaks inside comments, as
+    // the \c BreakableToken is still doing its own alignment.
+    const FormatToken *Tok;
 
     bool CreateReplacement;
     // Changes might be in the middle of a token, so we cannot just keep the
@@ -120,18 +118,7 @@
     unsigned NewlinesBefore;
     std::string PreviousLinePostfix;
     std::string CurrentLinePrefix;
-    // The kind of the token whose whitespace this change replaces, or in which
-    // this change inserts whitespace.
-    // FIXME: Currently this is not set correctly for breaks inside comments, as
-    // the \c BreakableToken is still doing its own alignment.
-    tok::TokenKind Kind;
     bool ContinuesPPDirective;
-    bool IsStartOfDeclName;
-
-    // The number of nested blocks the token is in. This is used to add tabs
-    // only for the indentation, and not for alignment, when
-    // UseTab = US_ForIndentation.
-    unsigned IndentLevel;
 
     // The number of spaces in front of the token or broken part of the token.
     // This will be adapted when aligning tokens.
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index bd2ee06..720baa5 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -34,10 +34,11 @@
     typedef RecursiveASTVisitor<ASTPrinter> base;
 
   public:
-    ASTPrinter(std::unique_ptr<raw_ostream> Out = nullptr, bool Dump = false,
-               StringRef FilterString = "", bool DumpLookups = false)
-        : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)), Dump(Dump),
-          FilterString(FilterString), DumpLookups(DumpLookups) {}
+    enum Kind { DumpFull, Dump, Print, None };
+    ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K, StringRef FilterString,
+               bool DumpLookups = false)
+        : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
+          OutputKind(K), FilterString(FilterString), DumpLookups(DumpLookups) {}
 
     void HandleTranslationUnit(ASTContext &Context) override {
       TranslationUnitDecl *D = Context.getTranslationUnitDecl();
@@ -55,7 +56,7 @@
         bool ShowColors = Out.has_colors();
         if (ShowColors)
           Out.changeColor(raw_ostream::BLUE);
-        Out << ((Dump || DumpLookups) ? "Dumping " : "Printing ") << getName(D)
+        Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
             << ":\n";
         if (ShowColors)
           Out.resetColor();
@@ -80,22 +81,30 @@
       if (DumpLookups) {
         if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
           if (DC == DC->getPrimaryContext())
-            DC->dumpLookups(Out, Dump);
+            DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
           else
             Out << "Lookup map is in primary DeclContext "
                 << DC->getPrimaryContext() << "\n";
         } else
           Out << "Not a DeclContext\n";
-      } else if (Dump)
-        D->dump(Out);
-      else
+      } else if (OutputKind == Print)
         D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true);
+      else if (OutputKind != None)
+        D->dump(Out, OutputKind == DumpFull);
     }
 
     raw_ostream &Out;
     std::unique_ptr<raw_ostream> OwnedOut;
-    bool Dump;
+
+    /// How to output individual declarations.
+    Kind OutputKind;
+
+    /// Which declarations or DeclContexts to display.
     std::string FilterString;
+
+    /// Whether the primary output is lookup results or declarations. Individual
+    /// results will be output with a format determined by OutputKind. This is
+    /// incompatible with OutputKind == Print.
     bool DumpLookups;
   };
 
@@ -125,16 +134,20 @@
 std::unique_ptr<ASTConsumer>
 clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
                         StringRef FilterString) {
-  return llvm::make_unique<ASTPrinter>(std::move(Out), /*Dump=*/false,
+  return llvm::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
                                        FilterString);
 }
 
 std::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString,
                                                     bool DumpDecls,
+                                                    bool Deserialize,
                                                     bool DumpLookups) {
   assert((DumpDecls || DumpLookups) && "nothing to dump");
-  return llvm::make_unique<ASTPrinter>(nullptr, DumpDecls, FilterString,
-                                       DumpLookups);
+  return llvm::make_unique<ASTPrinter>(nullptr,
+                                       Deserialize ? ASTPrinter::DumpFull :
+                                       DumpDecls ? ASTPrinter::Dump :
+                                       ASTPrinter::None,
+                                       FilterString, DumpLookups);
 }
 
 std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
@@ -370,6 +383,26 @@
     break;
   }
 
+  case Decl::ClassTemplateSpecialization: {
+    const auto *CTSD = cast<ClassTemplateSpecializationDecl>(DC);
+    if (CTSD->isCompleteDefinition())
+      Out << "[class template specialization] ";
+    else
+      Out << "<class template specialization> ";
+    Out << *CTSD;
+    break;
+  }
+
+  case Decl::ClassTemplatePartialSpecialization: {
+    const auto *CTPSD = cast<ClassTemplatePartialSpecializationDecl>(DC);
+    if (CTPSD->isCompleteDefinition())
+      Out << "[class template partial specialization] ";
+    else
+      Out << "<class template partial specialization> ";
+    Out << *CTPSD;
+    break;
+  }
+
   default:
     llvm_unreachable("a decl that inherits DeclContext isn't handled");
   }
@@ -400,7 +433,8 @@
     case Decl::CXXConstructor:
     case Decl::CXXDestructor:
     case Decl::CXXConversion:
-    {
+    case Decl::ClassTemplateSpecialization:
+    case Decl::ClassTemplatePartialSpecialization: {
       DeclContext* DC = cast<DeclContext>(I);
       PrintDeclContext(DC, Indentation+2);
       break;
@@ -478,6 +512,37 @@
       Out << "<omp threadprivate> " << '"' << I << "\"\n";
       break;
     }
+    case Decl::Friend: {
+      Out << "<friend>";
+      if (const NamedDecl *ND = cast<FriendDecl>(I)->getFriendDecl())
+        Out << ' ' << *ND;
+      Out << "\n";
+      break;
+    }
+    case Decl::Using: {
+      Out << "<using> " << *cast<UsingDecl>(I) << "\n";
+      break;
+    }
+    case Decl::UsingShadow: {
+      Out << "<using shadow> " << *cast<UsingShadowDecl>(I) << "\n";
+      break;
+    }
+    case Decl::Empty: {
+      Out << "<empty>\n";
+      break;
+    }
+    case Decl::AccessSpec: {
+      Out << "<access specifier>\n";
+      break;
+    }
+    case Decl::VarTemplate: {
+      Out << "<var template> " << *cast<VarTemplateDecl>(I) << "\n";
+      break;
+    }
+    case Decl::StaticAssert: {
+      Out << "<static assert>\n";
+      break;
+    }
     default:
       Out << "DeclKind: " << DK << '"' << I << "\"\n";
       llvm_unreachable("decl unhandled");
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 32ce966..ac5c7ca 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -185,7 +185,7 @@
   llvm::BitstreamWriter Stream;
   ASTWriter Writer;
 
-  ASTWriterData() : Stream(Buffer), Writer(Stream, { }) { }
+  ASTWriterData() : Stream(Buffer), Writer(Stream, Buffer, {}) {}
 };
 
 void ASTUnit::clearFileLevelDecls() {
@@ -245,7 +245,7 @@
   // perform this operation here because we explicitly request that the
   // compiler instance *not* free these buffers for each invocation of the
   // parser.
-  if (Invocation.get() && OwnsRemappedFileBuffers) {
+  if (Invocation && OwnsRemappedFileBuffers) {
     PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
     for (const auto &RB : PPOpts.RemappedFileBuffers)
       delete RB.second;
@@ -257,7 +257,9 @@
     fprintf(stderr, "--- %u translation units\n", --ActiveASTUnitObjects);
 }
 
-void ASTUnit::setPreprocessor(Preprocessor *pp) { PP = pp; }
+void ASTUnit::setPreprocessor(std::shared_ptr<Preprocessor> PP) {
+  this->PP = std::move(PP);
+}
 
 /// \brief Determine the set of code-completion contexts in which this 
 /// declaration should be shown.
@@ -346,7 +348,7 @@
   // Gather the set of global code completions.
   typedef CodeCompletionResult Result;
   SmallVector<Result, 8> Results;
-  CachedCompletionAllocator = new GlobalCodeCompletionAllocator;
+  CachedCompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();
   CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator);
   TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator,
                                        CCTUInfo, Results);
@@ -617,6 +619,10 @@
     StoredDiags.emplace_back(Level, Info);
 }
 
+IntrusiveRefCntPtr<ASTReader> ASTUnit::getASTReader() const {
+  return Reader;
+}
+
 ASTMutationListener *ASTUnit::getASTMutationListener() {
   if (WriterData)
     return &WriterData->Writer;
@@ -675,7 +681,7 @@
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
                                      AST->getFileManager(),
                                      UserFilesAreVolatile);
-  AST->HSOpts = new HeaderSearchOptions();
+  AST->HSOpts = std::make_shared<HeaderSearchOptions>();
   AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat();
   AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
                                          AST->getSourceManager(),
@@ -683,7 +689,7 @@
                                          AST->ASTFileLangOpts,
                                          /*Target=*/nullptr));
 
-  PreprocessorOptions *PPOpts = new PreprocessorOptions();
+  auto PPOpts = std::make_shared<PreprocessorOptions>();
 
   for (const auto &RemappedFile : RemappedFiles)
     PPOpts->addRemappedFile(RemappedFile.first, RemappedFile.second);
@@ -693,11 +699,11 @@
   HeaderSearch &HeaderInfo = *AST->HeaderInfo;
   unsigned Counter;
 
-  AST->PP =
-      new Preprocessor(PPOpts, AST->getDiagnostics(), AST->ASTFileLangOpts,
-                       AST->getSourceManager(), HeaderInfo, *AST,
-                       /*IILookup=*/nullptr,
-                       /*OwnsHeaderSearch=*/false);
+  AST->PP = std::make_shared<Preprocessor>(
+      std::move(PPOpts), AST->getDiagnostics(), AST->ASTFileLangOpts,
+      AST->getSourceManager(), HeaderInfo, *AST,
+      /*IILookup=*/nullptr,
+      /*OwnsHeaderSearch=*/false);
   Preprocessor &PP = *AST->PP;
 
   AST->Ctx = new ASTContext(AST->ASTFileLangOpts, AST->getSourceManager(),
@@ -926,7 +932,7 @@
                              const Preprocessor &PP, StringRef isysroot,
                              std::unique_ptr<raw_ostream> Out)
       : PCHGenerator(PP, "", isysroot, std::make_shared<PCHBuffer>(),
-                     ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>>(),
+                     ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
                      /*AllowASTWithErrors=*/true),
         Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action),
         Out(std::move(Out)) {
@@ -1046,10 +1052,7 @@
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
     CICleanup(Clang.get());
 
-  IntrusiveRefCntPtr<CompilerInvocation>
-    CCInvocation(new CompilerInvocation(*Invocation));
-
-  Clang->setInvocation(CCInvocation.get());
+  Clang->setInvocation(std::make_shared<CompilerInvocation>(*Invocation));
   OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
     
   // Set up diagnostics, capturing any diagnostics that would
@@ -1342,8 +1345,8 @@
     const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild,
     unsigned MaxLines) {
 
-  IntrusiveRefCntPtr<CompilerInvocation>
-    PreambleInvocation(new CompilerInvocation(PreambleInvocationIn));
+  auto PreambleInvocation =
+      std::make_shared<CompilerInvocation>(PreambleInvocationIn);
   FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts();
   PreprocessorOptions &PreprocessorOpts
     = PreambleInvocation->getPreprocessorOpts();
@@ -1521,7 +1524,7 @@
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
     CICleanup(Clang.get());
 
-  Clang->setInvocation(&*PreambleInvocation);
+  Clang->setInvocation(std::move(PreambleInvocation));
   OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
   
   // Set up diagnostics, capturing all of the diagnostics produced.
@@ -1671,7 +1674,7 @@
   if (CI.hasASTContext())
     Ctx = &CI.getASTContext();
   if (CI.hasPreprocessor())
-    PP = &CI.getPreprocessor();
+    PP = CI.getPreprocessorPtr();
   CI.setSourceManager(nullptr);
   CI.setFileManager(nullptr);
   if (CI.hasTarget())
@@ -1707,30 +1710,29 @@
   return Mod.FileName;
 }
 
-ASTUnit *ASTUnit::create(CompilerInvocation *CI,
-                         IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-                         bool CaptureDiagnostics,
-                         bool UserFilesAreVolatile) {
-  std::unique_ptr<ASTUnit> AST;
-  AST.reset(new ASTUnit(false));
+std::unique_ptr<ASTUnit>
+ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
+                IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+                bool CaptureDiagnostics, bool UserFilesAreVolatile) {
+  std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
   ConfigureDiags(Diags, *AST, CaptureDiagnostics);
-  AST->Diagnostics = Diags;
-  AST->Invocation = CI;
-  AST->FileSystemOpts = CI->getFileSystemOpts();
   IntrusiveRefCntPtr<vfs::FileSystem> VFS =
       createVFSFromCompilerInvocation(*CI, *Diags);
   if (!VFS)
     return nullptr;
+  AST->Diagnostics = Diags;
+  AST->FileSystemOpts = CI->getFileSystemOpts();
+  AST->Invocation = std::move(CI);
   AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
                                      UserFilesAreVolatile);
 
-  return AST.release();
+  return AST;
 }
 
 ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
-    CompilerInvocation *CI,
+    std::shared_ptr<CompilerInvocation> CI,
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FrontendAction *Action,
     ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
@@ -1744,7 +1746,7 @@
   ASTUnit *AST = Unit;
   if (!AST) {
     // Create the AST unit.
-    OwnAST.reset(create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile));
+    OwnAST = create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile);
     AST = OwnAST.get();
     if (!AST)
       return nullptr;
@@ -1783,7 +1785,7 @@
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
     CICleanup(Clang.get());
 
-  Clang->setInvocation(CI);
+  Clang->setInvocation(std::move(CI));
   AST->OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
     
   // Set up diagnostics, capturing any diagnostics that would
@@ -1881,6 +1883,7 @@
   // We'll manage file buffers ourselves.
   Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;
   Invocation->getFrontendOpts().DisableFree = false;
+  getDiagnostics().Reset();
   ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
 
   std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
@@ -1888,6 +1891,8 @@
     PreambleRebuildCounter = PrecompilePreambleAfterNParses;
     OverrideMainBuffer =
         getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation);
+    getDiagnostics().Reset();
+    ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
   }
   
   SimpleTimer ParsingTimer(WantTiming);
@@ -1901,7 +1906,7 @@
 }
 
 std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
-    CompilerInvocation *CI,
+    std::shared_ptr<CompilerInvocation> CI,
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
     bool OnlyLocalDecls, bool CaptureDiagnostics,
@@ -1918,7 +1923,7 @@
   AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
   AST->IncludeBriefCommentsInCodeCompletion
     = IncludeBriefCommentsInCodeCompletion;
-  AST->Invocation = CI;
+  AST->Invocation = std::move(CI);
   AST->FileSystemOpts = FileMgr->getFileSystemOpts();
   AST->FileMgr = FileMgr;
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
@@ -1950,8 +1955,8 @@
   assert(Diags.get() && "no DiagnosticsEngine was provided");
 
   SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
-  
-  IntrusiveRefCntPtr<CompilerInvocation> CI;
+
+  std::shared_ptr<CompilerInvocation> CI;
 
   {
 
@@ -1959,8 +1964,7 @@
                                       StoredDiagnostics);
 
     CI = clang::createInvocationFromCommandLine(
-                                           llvm::makeArrayRef(ArgBegin, ArgEnd),
-                                           Diags);
+        llvm::makeArrayRef(ArgBegin, ArgEnd), Diags);
     if (!CI)
       return nullptr;
   }
@@ -2331,8 +2335,7 @@
   CompletionTimer.setOutput("Code completion @ " + File + ":" +
                             Twine(Line) + ":" + Twine(Column));
 
-  IntrusiveRefCntPtr<CompilerInvocation>
-    CCInvocation(new CompilerInvocation(*Invocation));
+  auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
 
   FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
   CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
@@ -2364,7 +2367,8 @@
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
     CICleanup(Clang.get());
 
-  Clang->setInvocation(&*CCInvocation);
+  auto &Inv = *CCInvocation;
+  Clang->setInvocation(std::move(CCInvocation));
   OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
     
   // Set up diagnostics, capturing any diagnostics produced.
@@ -2372,8 +2376,8 @@
   CaptureDroppedDiagnostics Capture(true, 
                                     Clang->getDiagnostics(), 
                                     StoredDiagnostics);
-  ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts());
-  
+  ProcessWarningOptions(Diag, Inv.getDiagnosticOpts());
+
   // Create the target instance.
   Clang->setTarget(TargetInfo::CreateTargetInfo(
       Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
@@ -2429,7 +2433,7 @@
       if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) {
         if (CompleteFileID == MainID && Line > 1)
           OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
-              PCHContainerOps, *CCInvocation, false, Line - 1);
+              PCHContainerOps, Inv, false, Line - 1);
       }
     }
   }
@@ -2519,7 +2523,7 @@
 
   SmallString<128> Buffer;
   llvm::BitstreamWriter Stream(Buffer);
-  ASTWriter Writer(Stream, { });
+  ASTWriter Writer(Stream, Buffer, {});
   return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
 }
 
@@ -2537,6 +2541,8 @@
 
   SmallVector<StoredDiagnostic, 4> Result;
   Result.reserve(Diags.size());
+  const FileEntry *PreviousFE = nullptr;
+  FileID FID;
   for (const StandaloneDiagnostic &SD : Diags) {
     // Rebuild the StoredDiagnostic.
     if (SD.Filename.empty())
@@ -2544,7 +2550,10 @@
     const FileEntry *FE = FileMgr.getFile(SD.Filename);
     if (!FE)
       continue;
-    FileID FID = SrcMgr.translateFile(FE);
+    if (FE != PreviousFE) {
+      FID = SrcMgr.translateFile(FE);
+      PreviousFE = FE;
+    }
     SourceLocation FileLoc = SrcMgr.getLocForStartOfFile(FID);
     if (FileLoc.isInvalid())
       continue;
diff --git a/lib/Frontend/ChainedIncludesSource.cpp b/lib/Frontend/ChainedIncludesSource.cpp
index c5b77ee..b984c2e 100644
--- a/lib/Frontend/ChainedIncludesSource.cpp
+++ b/lib/Frontend/ChainedIncludesSource.cpp
@@ -147,7 +147,7 @@
 
     std::unique_ptr<CompilerInstance> Clang(
         new CompilerInstance(CI.getPCHContainerOperations()));
-    Clang->setInvocation(CInvok.release());
+    Clang->setInvocation(std::move(CInvok));
     Clang->setDiagnostics(Diags.get());
     Clang->setTarget(TargetInfo::CreateTargetInfo(
         Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
@@ -159,7 +159,7 @@
     Clang->createASTContext();
 
     auto Buffer = std::make_shared<PCHBuffer>();
-    ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions;
+    ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions;
     auto consumer = llvm::make_unique<PCHGenerator>(
         Clang->getPreprocessor(), "-", /*isysroot=*/"", Buffer,
         Extensions, /*AllowASTWithErrors=*/true);
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 991e9ef..a0e81f0 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -57,17 +57,15 @@
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     bool BuildingModule)
     : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()),
-      ModuleManager(nullptr),
-      ThePCHContainerOperations(std::move(PCHContainerOps)),
-      BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false),
-      ModuleBuildFailed(false) {}
+      ThePCHContainerOperations(std::move(PCHContainerOps)) {}
 
 CompilerInstance::~CompilerInstance() {
   assert(OutputFiles.empty() && "Still output files in flight?");
 }
 
-void CompilerInstance::setInvocation(CompilerInvocation *Value) {
-  Invocation = Value;
+void CompilerInstance::setInvocation(
+    std::shared_ptr<CompilerInvocation> Value) {
+  Invocation = std::move(Value);
 }
 
 bool CompilerInstance::shouldBuildGlobalModuleIndex() const {
@@ -96,7 +94,9 @@
   SourceMgr = Value;
 }
 
-void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; }
+void CompilerInstance::setPreprocessor(std::shared_ptr<Preprocessor> Value) {
+  PP = std::move(Value);
+}
 
 void CompilerInstance::setASTContext(ASTContext *Value) {
   Context = Value;
@@ -141,6 +141,66 @@
   ModuleDepCollector = std::move(Collector);
 }
 
+static void collectHeaderMaps(const HeaderSearch &HS,
+                              std::shared_ptr<ModuleDependencyCollector> MDC) {
+  SmallVector<std::string, 4> HeaderMapFileNames;
+  HS.getHeaderMapFileNames(HeaderMapFileNames);
+  for (auto &Name : HeaderMapFileNames)
+    MDC->addFile(Name);
+}
+
+static void collectIncludePCH(CompilerInstance &CI,
+                              std::shared_ptr<ModuleDependencyCollector> MDC) {
+  const PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
+  if (PPOpts.ImplicitPCHInclude.empty())
+    return;
+
+  StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
+  FileManager &FileMgr = CI.getFileManager();
+  const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude);
+  if (!PCHDir) {
+    MDC->addFile(PCHInclude);
+    return;
+  }
+
+  std::error_code EC;
+  SmallString<128> DirNative;
+  llvm::sys::path::native(PCHDir->getName(), DirNative);
+  vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+  SimpleASTReaderListener Validator(CI.getPreprocessor());
+  for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
+       Dir != DirEnd && !EC; Dir.increment(EC)) {
+    // Check whether this is an AST file. ASTReader::isAcceptableASTFile is not
+    // used here since we're not interested in validating the PCH at this time,
+    // but only to check whether this is a file containing an AST.
+    if (!ASTReader::readASTFileControlBlock(
+            Dir->getName(), FileMgr, CI.getPCHContainerReader(),
+            /*FindModuleFileExtensions=*/false, Validator,
+            /*ValidateDiagnosticOptions=*/false))
+      MDC->addFile(Dir->getName());
+  }
+}
+
+static void collectVFSEntries(CompilerInstance &CI,
+                              std::shared_ptr<ModuleDependencyCollector> MDC) {
+  if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty())
+    return;
+
+  // Collect all VFS found.
+  SmallVector<vfs::YAMLVFSEntry, 16> VFSEntries;
+  for (const std::string &VFSFile : CI.getHeaderSearchOpts().VFSOverlayFiles) {
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
+        llvm::MemoryBuffer::getFile(VFSFile);
+    if (!Buffer)
+      return;
+    vfs::collectVFSFromYAML(std::move(Buffer.get()), /*DiagHandler*/ nullptr,
+                            VFSFile, VFSEntries);
+  }
+
+  for (auto &E : VFSEntries)
+    MDC->addFile(E.VPath, E.RPath);
+}
+
 // Diagnostics
 static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
                                const CodeGenOptions *CodeGenOpts,
@@ -305,14 +365,13 @@
     PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics());
 
   // Create the Preprocessor.
-  HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(),
-                                              getSourceManager(),
-                                              getDiagnostics(),
-                                              getLangOpts(),
-                                              &getTarget());
-  PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(),
-                        getSourceManager(), *HeaderInfo, *this, PTHMgr,
-                        /*OwnsHeaderSearch=*/true, TUKind);
+  HeaderSearch *HeaderInfo =
+      new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(),
+                       getDiagnostics(), getLangOpts(), &getTarget());
+  PP = std::make_shared<Preprocessor>(
+      Invocation->getPreprocessorOptsPtr(), getDiagnostics(), getLangOpts(),
+      getSourceManager(), *HeaderInfo, *this, PTHMgr,
+      /*OwnsHeaderSearch=*/true, TUKind);
   PP->Initialize(getTarget(), getAuxTarget());
 
   // Note that this is different then passing PTHMgr to Preprocessor's ctor.
@@ -366,8 +425,14 @@
         DepOpts.ModuleDependencyOutputDir);
   }
 
-  if (ModuleDepCollector)
+  // If there is a module dep collector, register with other dep collectors
+  // and also (a) collect header maps and (b) TODO: input vfs overlay files.
+  if (ModuleDepCollector) {
     addDependencyCollector(ModuleDepCollector);
+    collectHeaderMaps(PP->getHeaderSearchInfo(), ModuleDepCollector);
+    collectIncludePCH(*this, ModuleDepCollector);
+    collectVFSEntries(*this, ModuleDepCollector);
+  }
 
   for (auto &Listener : DependencyCollectors)
     Listener->attachToPreprocessor(*PP);
@@ -432,7 +497,7 @@
     StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
     bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
     const PCHContainerReader &PCHContainerRdr,
-    ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
+    ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
     void *DeserializationListener, bool OwnDeserializationListener,
     bool Preamble, bool UseGlobalModuleIndex) {
   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
@@ -952,8 +1017,8 @@
     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
     
   // Construct a compiler invocation for creating this module.
-  IntrusiveRefCntPtr<CompilerInvocation> Invocation
-    (new CompilerInvocation(ImportingInstance.getInvocation()));
+  auto Invocation =
+      std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation());
 
   PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
   
@@ -964,7 +1029,7 @@
 
   // Remove any macro definitions that are explicitly ignored by the module.
   // They aren't supposed to affect how the module is built anyway.
-  const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
+  HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
   PPOpts.Macros.erase(
       std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(),
                      [&HSOpts](const std::pair<std::string, bool> &def) {
@@ -983,7 +1048,8 @@
   PreprocessorOptions &ImportingPPOpts
     = ImportingInstance.getInvocation().getPreprocessorOpts();
   if (!ImportingPPOpts.FailedModules)
-    ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet;
+    ImportingPPOpts.FailedModules =
+        std::make_shared<PreprocessorOptions::FailedModulesSet>();
   PPOpts.FailedModules = ImportingPPOpts.FailedModules;
 
   // If there is a module map file, build the module using the module map.
@@ -994,6 +1060,8 @@
   FrontendOpts.DisableFree = false;
   FrontendOpts.GenerateGlobalModuleIndex = false;
   FrontendOpts.BuildingImplicitModule = true;
+  // Force implicitly-built modules to hash the content of the module file.
+  HSOpts.ModulesHashContent = true;
   FrontendOpts.Inputs.clear();
   InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
 
@@ -1008,7 +1076,8 @@
   // module.
   CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),
                             /*BuildingModule=*/true);
-  Instance.setInvocation(&*Invocation);
+  auto &Inv = *Invocation;
+  Instance.setInvocation(std::move(Invocation));
 
   Instance.createDiagnostics(new ForwardingDiagnosticConsumer(
                                    ImportingInstance.getDiagnosticClient()),
@@ -1030,7 +1099,7 @@
   // between all of the module CompilerInstances. Other than that, we don't
   // want to produce any dependency output from the module build.
   Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector());
-  Invocation->getDependencyOutputOpts() = DependencyOutputOptions();
+  Inv.getDependencyOutputOpts() = DependencyOutputOptions();
 
   // Get or create the module map that we'll use to build this module.
   std::string InferredModuleMapContent;
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index af1ab07..d5ad3df 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -60,12 +60,11 @@
     PreprocessorOpts(new PreprocessorOptions()) {}
 
 CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X)
-  : RefCountedBase<CompilerInvocation>(),
-    LangOpts(new LangOptions(*X.getLangOpts())),
-    TargetOpts(new TargetOptions(X.getTargetOpts())),
-    DiagnosticOpts(new DiagnosticOptions(X.getDiagnosticOpts())),
-    HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())),
-    PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())) {}
+    : LangOpts(new LangOptions(*X.getLangOpts())),
+      TargetOpts(new TargetOptions(X.getTargetOpts())),
+      DiagnosticOpts(new DiagnosticOptions(X.getDiagnosticOpts())),
+      HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())),
+      PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())) {}
 
 CompilerInvocationBase::~CompilerInvocationBase() {}
 
@@ -441,24 +440,31 @@
   }
   Opts.OptimizationLevel = OptimizationLevel;
 
-  // We must always run at least the always inlining pass.
-  Opts.setInlining(
-    (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
-                                 : CodeGenOptions::OnlyAlwaysInlining);
-  // -fno-inline-functions overrides OptimizationLevel > 1.
-  Opts.NoInline = Args.hasArg(OPT_fno_inline);
-  if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions,
-                                       options::OPT_finline_hint_functions,
-                                       options::OPT_fno_inline_functions)) {
-    const Option& InlineOpt = InlineArg->getOption();
-    if (InlineOpt.matches(options::OPT_finline_functions))
-      Opts.setInlining(CodeGenOptions::NormalInlining);
-    else if (InlineOpt.matches(options::OPT_finline_hint_functions))
-      Opts.setInlining(CodeGenOptions::OnlyHintInlining);
-    else
-      Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
+  // At O0 we want to fully disable inlining outside of cases marked with
+  // 'alwaysinline' that are required for correctness.
+  Opts.setInlining((Opts.OptimizationLevel == 0)
+                       ? CodeGenOptions::OnlyAlwaysInlining
+                       : CodeGenOptions::NormalInlining);
+  // Explicit inlining flags can disable some or all inlining even at
+  // optimization levels above zero.
+  if (Arg *InlineArg = Args.getLastArg(
+          options::OPT_finline_functions, options::OPT_finline_hint_functions,
+          options::OPT_fno_inline_functions, options::OPT_fno_inline)) {
+    if (Opts.OptimizationLevel > 0) {
+      const Option &InlineOpt = InlineArg->getOption();
+      if (InlineOpt.matches(options::OPT_finline_functions))
+        Opts.setInlining(CodeGenOptions::NormalInlining);
+      else if (InlineOpt.matches(options::OPT_finline_hint_functions))
+        Opts.setInlining(CodeGenOptions::OnlyHintInlining);
+      else
+        Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
+    }
   }
 
+  Opts.ExperimentalNewPassManager = Args.hasFlag(
+      OPT_fexperimental_new_pass_manager, OPT_fno_experimental_new_pass_manager,
+      /* Default */ false);
+
   if (Arg *A = Args.getLastArg(OPT_fveclib)) {
     StringRef Name = A->getValue();
     if (Name == "Accelerate")
@@ -499,6 +505,7 @@
   Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags);
   Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info);
   Opts.EmitCodeView = Args.hasArg(OPT_gcodeview);
+  Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro);
   Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables);
   Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std);
   Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
@@ -513,8 +520,8 @@
           Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists))
     Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists;
 
-  Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
   Opts.DisableLLVMPasses = Args.hasArg(OPT_disable_llvm_passes);
+  Opts.DisableLifetimeMarkers = Args.hasArg(OPT_disable_lifetimemarkers);
   Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
   Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables);
   Opts.UseRegisterSizedBitfieldAccess = Args.hasArg(
@@ -538,6 +545,8 @@
   Opts.DisableIntegratedAS = Args.hasArg(OPT_fno_integrated_as);
   Opts.Autolink = !Args.hasArg(OPT_fno_autolink);
   Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ);
+  Opts.DebugInfoForProfiling = Args.hasFlag(
+      OPT_fdebug_info_for_profiling, OPT_fno_debug_info_for_profiling, false);
 
   setPGOInstrumentor(Opts, Args, Diags);
   Opts.InstrProfileOutput =
@@ -596,6 +605,7 @@
   Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
   Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
   Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
+  Opts.StrictReturn = !Args.hasArg(OPT_fno_strict_return);
   Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers);
   Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
                       Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
@@ -624,6 +634,7 @@
   Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ);
   const Arg *A = Args.getLastArg(OPT_flto, OPT_flto_EQ);
   Opts.EmitSummaryIndex = A && A->containsValue("thin");
+  Opts.LTOUnit = Args.hasFlag(OPT_flto_unit, OPT_fno_lto_unit, false);
   if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
     if (IK != IK_LLVM_IR)
       Diags.Report(diag::err_drv_argument_only_allowed_with)
@@ -707,16 +718,22 @@
   Opts.XRayInstructionThreshold =
       getLastArgIntValue(Args, OPT_fxray_instruction_threshold_, 200, Diags);
   Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
+  Opts.CallFEntry = Args.hasArg(OPT_mfentry);
   Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
   Opts.CompressDebugSections = Args.hasArg(OPT_compress_debug_sections);
   Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations);
   Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
   for (auto A : Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_cuda_bitcode)) {
-    unsigned LinkFlags = llvm::Linker::Flags::None;
-    if (A->getOption().matches(OPT_mlink_cuda_bitcode))
-      LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded |
-                  llvm::Linker::Flags::InternalizeLinkedSymbols;
-    Opts.LinkBitcodeFiles.push_back(std::make_pair(LinkFlags, A->getValue()));
+    CodeGenOptions::BitcodeFileToLink F;
+    F.Filename = A->getValue();
+    if (A->getOption().matches(OPT_mlink_cuda_bitcode)) {
+      F.LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded;
+      // When linking CUDA bitcode, propagate function attributes so that
+      // e.g. libdevice gets fast-math attrs if we're building with fast-math.
+      F.PropagateAttrs = true;
+      F.Internalize = true;
+    }
+    Opts.LinkBitcodeFiles.push_back(F);
   }
   Opts.SanitizeCoverageType =
       getLastArgIntValue(Args, OPT_fsanitize_coverage_type, 0, Diags);
@@ -930,21 +947,13 @@
   } ShowColors = DefaultColor ? Colors_Auto : Colors_Off;
   for (Arg *A : Args) {
     const Option &O = A->getOption();
-    if (!O.matches(options::OPT_fcolor_diagnostics) &&
-        !O.matches(options::OPT_fdiagnostics_color) &&
-        !O.matches(options::OPT_fno_color_diagnostics) &&
-        !O.matches(options::OPT_fno_diagnostics_color) &&
-        !O.matches(options::OPT_fdiagnostics_color_EQ))
-      continue;
-
     if (O.matches(options::OPT_fcolor_diagnostics) ||
         O.matches(options::OPT_fdiagnostics_color)) {
       ShowColors = Colors_On;
     } else if (O.matches(options::OPT_fno_color_diagnostics) ||
                O.matches(options::OPT_fno_diagnostics_color)) {
       ShowColors = Colors_Off;
-    } else {
-      assert(O.matches(options::OPT_fdiagnostics_color_EQ));
+    } else if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
       StringRef Value(A->getValue());
       if (Value == "always")
         ShowColors = Colors_On;
@@ -954,10 +963,9 @@
         ShowColors = Colors_Auto;
     }
   }
-  if (ShowColors == Colors_On ||
-      (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors()))
-    return true;
-  return false;
+  return ShowColors == Colors_On ||
+         (ShowColors == Colors_Auto &&
+          llvm::sys::Process::StandardErrHasColors());
 }
 
 bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
@@ -1125,6 +1133,7 @@
     case OPT_ast_list:
       Opts.ProgramAction = frontend::ASTDeclList; break;
     case OPT_ast_dump:
+    case OPT_ast_dump_all:
     case OPT_ast_dump_lookups:
       Opts.ProgramAction = frontend::ASTDump; break;
     case OPT_ast_print:
@@ -1216,8 +1225,8 @@
 
     // Add the testing module file extension.
     Opts.ModuleFileExtensions.push_back(
-      new TestModuleFileExtension(BlockName, MajorVersion, MinorVersion,
-                                  Hashed, UserInfo));
+        std::make_shared<TestModuleFileExtension>(
+            BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));
   }
 
   if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
@@ -1243,6 +1252,7 @@
   Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile);
   Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp);
   Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump);
+  Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all);
   Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter);
   Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups);
   Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index);
@@ -1424,6 +1434,7 @@
   for (const Arg *A : Args.filtered(OPT_fprebuilt_module_path))
     Opts.AddPrebuiltModulePath(A->getValue());
   Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
+  Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content);
   Opts.ModulesValidateDiagnosticOptions =
       !Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
   Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
@@ -1497,6 +1508,9 @@
                  !A->getOption().matches(OPT_iwithsysroot));
   for (const Arg *A : Args.filtered(OPT_iframework))
     Opts.AddPath(A->getValue(), frontend::System, true, true);
+  for (const Arg *A : Args.filtered(OPT_iframeworkwithsysroot))
+    Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
+                 /*IgnoreSysRoot=*/false);
 
   // Add the paths for the various language specific isystem flags.
   for (const Arg *A : Args.filtered(OPT_c_isystem))
@@ -1527,13 +1541,6 @@
     Opts.AddVFSOverlayFile(A->getValue());
 }
 
-static bool isOpenCL(LangStandard::Kind LangStd) {
-  return LangStd == LangStandard::lang_opencl ||
-         LangStd == LangStandard::lang_opencl11 ||
-         LangStd == LangStandard::lang_opencl12 ||
-         LangStd == LangStandard::lang_opencl20;
-}
-
 void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
                                          const llvm::Triple &T,
                                          PreprocessorOptions &PPOpts,
@@ -1567,19 +1574,25 @@
     case IK_Asm:
     case IK_C:
     case IK_PreprocessedC:
-    case IK_ObjC:
-    case IK_PreprocessedObjC:
       // The PS4 uses C99 as the default C standard.
       if (T.isPS4())
         LangStd = LangStandard::lang_gnu99;
       else
         LangStd = LangStandard::lang_gnu11;
       break;
+    case IK_ObjC:
+    case IK_PreprocessedObjC:
+      LangStd = LangStandard::lang_gnu11;
+      break;
     case IK_CXX:
     case IK_PreprocessedCXX:
     case IK_ObjCXX:
     case IK_PreprocessedObjCXX:
-      LangStd = LangStandard::lang_gnucxx98;
+      // The PS4 uses C++11 as the default C++ standard.
+      if (T.isPS4())
+        LangStd = LangStandard::lang_gnucxx11;
+      else
+        LangStd = LangStandard::lang_gnucxx98;
       break;
     case IK_RenderScript:
       LangStd = LangStandard::lang_c99;
@@ -1602,7 +1615,7 @@
   Opts.ImplicitInt = Std.hasImplicitInt();
 
   // Set OpenCL Version.
-  Opts.OpenCL = isOpenCL(LangStd) || IK == IK_OpenCL;
+  Opts.OpenCL = Std.isOpenCL() || IK == IK_OpenCL;
   if (LangStd == LangStandard::lang_opencl)
     Opts.OpenCLVersion = 100;
   else if (LangStd == LangStandard::lang_opencl11)
@@ -1671,6 +1684,63 @@
   return DefaultVisibility;
 }
 
+/// Check if input file kind and language standard are compatible.
+static bool IsInputCompatibleWithStandard(InputKind IK,
+                                          const LangStandard &S) {
+  switch (IK) {
+  case IK_C:
+  case IK_ObjC:
+  case IK_PreprocessedC:
+  case IK_PreprocessedObjC:
+    if (S.isC89() || S.isC99())
+      return true;
+    break;
+  case IK_CXX:
+  case IK_ObjCXX:
+  case IK_PreprocessedCXX:
+  case IK_PreprocessedObjCXX:
+    if (S.isCPlusPlus())
+      return true;
+    break;
+  case IK_OpenCL:
+    if (S.isOpenCL())
+      return true;
+    break;
+  case IK_CUDA:
+  case IK_PreprocessedCuda:
+    if (S.isCPlusPlus())
+      return true;
+    break;
+  default:
+    // For other inputs, accept (and ignore) all -std= values.
+    return true;
+  }
+  return false;
+}
+
+/// Get language name for given input kind.
+static const StringRef GetInputKindName(InputKind IK) {
+  switch (IK) {
+  case IK_C:
+  case IK_ObjC:
+  case IK_PreprocessedC:
+  case IK_PreprocessedObjC:
+    return "C/ObjC";
+  case IK_CXX:
+  case IK_ObjCXX:
+  case IK_PreprocessedCXX:
+  case IK_PreprocessedObjCXX:
+    return "C++/ObjC++";
+  case IK_OpenCL:
+    return "OpenCL";
+  case IK_CUDA:
+  case IK_PreprocessedCuda:
+    return "CUDA";
+  default:
+    llvm_unreachable("Cannot decide on name for InputKind!");
+  }
+}
+
 static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
                           const TargetOptions &TargetOpts,
                           PreprocessorOptions &PPOpts,
@@ -1685,43 +1755,27 @@
       .Case(alias, LangStandard::lang_##id)
 #include "clang/Frontend/LangStandards.def"
       .Default(LangStandard::lang_unspecified);
-    if (LangStd == LangStandard::lang_unspecified)
+    if (LangStd == LangStandard::lang_unspecified) {
       Diags.Report(diag::err_drv_invalid_value)
         << A->getAsString(Args) << A->getValue();
-    else {
+      // Report supported standards with short description.
+      for (unsigned KindValue = 0;
+           KindValue != LangStandard::lang_unspecified;
+           ++KindValue) {
+        const LangStandard &Std = LangStandard::getLangStandardForKind(
+          static_cast<LangStandard::Kind>(KindValue));
+        if (IsInputCompatibleWithStandard(IK, Std)) {
+          Diags.Report(diag::note_drv_use_standard)
+            << Std.getName() << Std.getDescription();
+        }
+      }
+    } else {
       // Valid standard, check to make sure language and standard are
       // compatible.
       const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
-      switch (IK) {
-      case IK_C:
-      case IK_ObjC:
-      case IK_PreprocessedC:
-      case IK_PreprocessedObjC:
-        if (!(Std.isC89() || Std.isC99()))
-          Diags.Report(diag::err_drv_argument_not_allowed_with)
-            << A->getAsString(Args) << "C/ObjC";
-        break;
-      case IK_CXX:
-      case IK_ObjCXX:
-      case IK_PreprocessedCXX:
-      case IK_PreprocessedObjCXX:
-        if (!Std.isCPlusPlus())
-          Diags.Report(diag::err_drv_argument_not_allowed_with)
-            << A->getAsString(Args) << "C++/ObjC++";
-        break;
-      case IK_OpenCL:
-        if (!isOpenCL(LangStd))
-          Diags.Report(diag::err_drv_argument_not_allowed_with)
-            << A->getAsString(Args) << "OpenCL";
-        break;
-      case IK_CUDA:
-      case IK_PreprocessedCuda:
-        if (!Std.isCPlusPlus())
-          Diags.Report(diag::err_drv_argument_not_allowed_with)
-            << A->getAsString(Args) << "CUDA";
-        break;
-      default:
-        break;
+      if (!IsInputCompatibleWithStandard(IK, Std)) {
+        Diags.Report(diag::err_drv_argument_not_allowed_with)
+          << A->getAsString(Args) << GetInputKindName(IK);
       }
     }
   }
@@ -1730,16 +1784,16 @@
   // Override the -std option in this case.
   if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
     LangStandard::Kind OpenCLLangStd
-    = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
-    .Cases("cl", "CL", LangStandard::lang_opencl)
-    .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
-    .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
-    .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
-    .Default(LangStandard::lang_unspecified);
+      = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
+        .Cases("cl", "CL", LangStandard::lang_opencl)
+        .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
+        .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
+        .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
+        .Default(LangStandard::lang_unspecified);
 
     if (OpenCLLangStd == LangStandard::lang_unspecified) {
       Diags.Report(diag::err_drv_invalid_value)
-      << A->getAsString(Args) << A->getValue();
+        << A->getAsString(Args) << A->getValue();
     }
     else
       LangStd = OpenCLLangStd;
@@ -1840,8 +1894,8 @@
 
   if (Args.hasArg(OPT_fgnu89_inline)) {
     if (Opts.CPlusPlus)
-      Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fgnu89-inline"
-                                                            << "C++/ObjC++";
+      Diags.Report(diag::err_drv_argument_not_allowed_with)
+        << "-fgnu89-inline" << GetInputKindName(IK);
     else
       Opts.GNUInline = 1;
   }
@@ -1947,6 +2001,7 @@
       Args.hasArg(OPT_fmodules_decluse) || Opts.ModulesStrictDeclUse;
   Opts.ModulesLocalVisibility =
       Args.hasArg(OPT_fmodules_local_submodule_visibility) || Opts.ModulesTS;
+  Opts.ModularCodegen = Args.hasArg(OPT_fmodule_codegen);
   Opts.ModulesSearchAll = Opts.Modules &&
     !Args.hasArg(OPT_fno_modules_search_all) &&
     Args.hasArg(OPT_fmodules_search_all);
@@ -1961,6 +2016,8 @@
   if (!Opts.NoBuiltin)
     getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
   Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
+  Opts.RelaxedTemplateTemplateArgs =
+      Args.hasArg(OPT_frelaxed_template_template_args);
   Opts.SizedDeallocation = Args.hasArg(OPT_fsized_deallocation);
   Opts.AlignedAllocation =
       Args.hasFlag(OPT_faligned_allocation, OPT_fno_aligned_allocation,
@@ -2196,7 +2253,12 @@
   // This is the __NO_INLINE__ define, which just depends on things like the
   // optimization level and -fno-inline, not actually whether the backend has
   // inlining enabled.
-  Opts.NoInlineDefine = !Opt || Args.hasArg(OPT_fno_inline);
+  Opts.NoInlineDefine = !Opts.Optimize;
+  if (Arg *InlineArg = Args.getLastArg(
+          options::OPT_finline_functions, options::OPT_finline_hint_functions,
+          options::OPT_fno_inline_functions, options::OPT_fno_inline))
+    if (InlineArg->getOption().matches(options::OPT_fno_inline))
+      Opts.NoInlineDefine = true;
 
   Opts.FastMath = Args.hasArg(OPT_ffast_math) ||
       Args.hasArg(OPT_cl_fast_relaxed_math);
@@ -2244,6 +2306,7 @@
   Opts.UsePredefines = !Args.hasArg(OPT_undef);
   Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
   Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
+  Opts.AllowPCHWithCompilerErrors = Args.hasArg(OPT_fallow_pch_with_errors);
 
   Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
   for (const Arg *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
@@ -2398,7 +2461,7 @@
   bool Success = true;
 
   // Parse the arguments.
-  std::unique_ptr<OptTable> Opts(createDriverOptTable());
+  std::unique_ptr<OptTable> Opts = createDriverOptTable();
   const unsigned IncludedFlagsBitmask = options::CC1Option;
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args =
diff --git a/lib/Frontend/CreateInvocationFromCommandLine.cpp b/lib/Frontend/CreateInvocationFromCommandLine.cpp
index 1e9e57a..1626906 100644
--- a/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -30,9 +30,9 @@
 ///
 /// \return A CompilerInvocation, or 0 if none was built for the given
 /// argument vector.
-CompilerInvocation *
-clang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList,
-                            IntrusiveRefCntPtr<DiagnosticsEngine> Diags) {
+std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine(
+    ArrayRef<const char *> ArgList,
+    IntrusiveRefCntPtr<DiagnosticsEngine> Diags) {
   if (!Diags.get()) {
     // No diagnostics engine was provided, so create our own diagnostics object
     // with the default options.
@@ -93,12 +93,12 @@
   }
 
   const ArgStringList &CCArgs = Cmd.getArguments();
-  std::unique_ptr<CompilerInvocation> CI(new CompilerInvocation());
+  auto CI = llvm::make_unique<CompilerInvocation>();
   if (!CompilerInvocation::CreateFromArgs(*CI,
                                      const_cast<const char **>(CCArgs.data()),
                                      const_cast<const char **>(CCArgs.data()) +
                                      CCArgs.size(),
                                      *Diags))
     return nullptr;
-  return CI.release();
+  return CI;
 }
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index 059f116..bd14c53 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -447,9 +447,9 @@
   // Create phony targets if requested.
   if (PhonyTarget && !Files.empty()) {
     // Skip the first entry, this is always the input file itself.
-    for (StringRef File : Files) {
+    for (auto I = Files.begin() + 1, E = Files.end(); I != E; ++I) {
       OS << '\n';
-      PrintFilename(OS, File, OutputFormat);
+      PrintFilename(OS, *I, OutputFormat);
       OS << ":\n";
     }
   }
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 2945b89..0dd07d9 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -19,6 +19,7 @@
 #include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/LiteralSupport.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Parse/ParseAST.h"
@@ -187,6 +188,42 @@
   return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
 }
 
+// For preprocessed files, if the first line is the linemarker and specifies
+// the original source file name, use that name as the input file name.
+static bool ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile)
+{
+  bool Invalid = false;
+  auto &SourceMgr = CI.getSourceManager();
+  auto MainFileID = SourceMgr.getMainFileID();
+  const auto *MainFileBuf = SourceMgr.getBuffer(MainFileID, &Invalid);
+  if (Invalid)
+    return false;
+
+  std::unique_ptr<Lexer> RawLexer(
+      new Lexer(MainFileID, MainFileBuf, SourceMgr, CI.getLangOpts()));
+
+  // If the first line has the syntax of
+  //
+  // # NUM "FILENAME"
+  //
+  // we use FILENAME as the input file name.
+  Token T;
+  if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
+    return false;
+  if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
+      T.getKind() != tok::numeric_constant)
+    return false;
+  RawLexer->LexFromRawLexer(T);
+  if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
+    return false;
+
+  StringLiteralParser Literal(T, CI.getPreprocessor());
+  if (Literal.hadError)
+    return false;
+  InputFile = Literal.GetString().str();
+  return true;
+}
+
 bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                      const FrontendInputFile &Input) {
   assert(!Instance && "Already processing a source file!");
@@ -224,7 +261,10 @@
     // file, otherwise the CompilerInstance will happily destroy them.
     CI.setFileManager(&AST->getFileManager());
     CI.setSourceManager(&AST->getSourceManager());
-    CI.setPreprocessor(&AST->getPreprocessor());
+    CI.setPreprocessor(AST->getPreprocessorPtr());
+    Preprocessor &PP = CI.getPreprocessor();
+    PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
+                                           PP.getLangOpts());
     CI.setASTContext(&AST->getASTContext());
 
     setCurrentInput(Input, std::move(AST));
@@ -288,14 +328,15 @@
       SmallString<128> DirNative;
       llvm::sys::path::native(PCHDir->getName(), DirNative);
       bool Found = false;
-      for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd;
+      vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+      for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
            Dir != DirEnd && !EC; Dir.increment(EC)) {
         // Check whether this is an acceptable AST file.
         if (ASTReader::isAcceptableASTFile(
-                Dir->path(), FileMgr, CI.getPCHContainerReader(),
+                Dir->getName(), FileMgr, CI.getPCHContainerReader(),
                 CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(),
                 SpecificModuleCachePath)) {
-          PPOpts.ImplicitPCHInclude = Dir->path();
+          PPOpts.ImplicitPCHInclude = Dir->getName();
           Found = true;
           break;
         }
@@ -334,6 +375,13 @@
     if (!isModelParsingAction())
       CI.createASTContext();
 
+    // For preprocessed files, check if the first line specifies the original
+    // source file name with a linemarker.
+    std::string OrigFile;
+    if (Input.isPreprocessed())
+      if (ReadOriginalFileName(CI, OrigFile))
+        InputFile = OrigFile;
+
     std::unique_ptr<ASTConsumer> Consumer =
         CreateWrappedASTConsumer(CI, InputFile);
     if (!Consumer)
@@ -351,8 +399,9 @@
         goto failure;
       CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get()));
       CI.getASTContext().setExternalSource(source);
-    } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
-      // Use PCH.
+    } else if (CI.getLangOpts().Modules ||
+               !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
+      // Use PCM or PCH.
       assert(hasPCHSupport() && "This action does not have PCH support!");
       ASTDeserializationListener *DeserialListener =
           Consumer->GetASTDeserializationListener();
@@ -369,13 +418,24 @@
             DeserialListener, DeleteDeserialListener);
         DeleteDeserialListener = true;
       }
-      CI.createPCHExternalASTSource(
-          CI.getPreprocessorOpts().ImplicitPCHInclude,
-          CI.getPreprocessorOpts().DisablePCHValidation,
+      if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
+        CI.createPCHExternalASTSource(
+            CI.getPreprocessorOpts().ImplicitPCHInclude,
+            CI.getPreprocessorOpts().DisablePCHValidation,
           CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener,
-          DeleteDeserialListener);
-      if (!CI.getASTContext().getExternalSource())
-        goto failure;
+            DeleteDeserialListener);
+        if (!CI.getASTContext().getExternalSource())
+          goto failure;
+      }
+      // If modules are enabled, create the module manager before creating
+      // any builtins, so that all declarations know that they might be
+      // extended by an external source.
+      if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
+          !CI.getASTContext().getExternalSource()) {
+        CI.createModuleManager();
+        CI.getModuleManager()->setDeserializationListener(DeserialListener,
+                                                        DeleteDeserialListener);
+      }
     }
 
     CI.setASTConsumer(std::move(Consumer));
@@ -385,15 +445,9 @@
 
   // Initialize built-in info as long as we aren't using an external AST
   // source.
-  if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
+  if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
+      !CI.getASTContext().getExternalSource()) {
     Preprocessor &PP = CI.getPreprocessor();
-
-    // If modules are enabled, create the module manager before creating
-    // any builtins, so that all declarations know that they might be
-    // extended by an external source.
-    if (CI.getLangOpts().Modules)
-      CI.createModuleManager();
-
     PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
                                            PP.getLangOpts());
   } else {
@@ -420,9 +474,9 @@
 
   // If there is a layout overrides file, attach an external AST source that
   // provides the layouts from that file.
-  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 
+  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
       CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
-    IntrusiveRefCntPtr<ExternalASTSource> 
+    IntrusiveRefCntPtr<ExternalASTSource>
       Override(new LayoutOverrideSource(
                      CI.getFrontendOpts().OverrideRecordLayoutsFile));
     CI.getASTContext().setExternalSource(Override);
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index eb91940..e818038 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -57,6 +57,7 @@
 ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter,
                          CI.getFrontendOpts().ASTDumpDecls,
+                         CI.getFrontendOpts().ASTDumpAll,
                          CI.getFrontendOpts().ASTDumpLookups);
 }
 
@@ -93,7 +94,7 @@
   Consumers.push_back(llvm::make_unique<PCHGenerator>(
                         CI.getPreprocessor(), OutputFile, Sysroot,
                         Buffer, CI.getFrontendOpts().ModuleFileExtensions,
-                        /*AllowASTWithErrors*/false,
+      /*AllowASTWithErrors*/CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
                         /*IncludeTimestamps*/
                           +CI.getFrontendOpts().IncludeTimestamps));
   Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
@@ -127,6 +128,18 @@
   return OS;
 }
 
+bool GeneratePCHAction::shouldEraseOutputFiles() {
+  if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)
+    return false;
+  return ASTFrontendAction::shouldEraseOutputFiles();
+}
+
+bool GeneratePCHAction::BeginSourceFileAction(CompilerInstance &CI,
+                                              StringRef Filename) {
+  CI.getLangOpts().CompilingPCH = true;
+  return true;
+}
+
 std::unique_ptr<ASTConsumer>
 GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
                                         StringRef InFile) {
@@ -561,6 +574,7 @@
                                  bool Complain) override {
       Out.indent(2) << "Header search options:\n";
       Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
+      Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
       Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
       DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes,
                    "Use builtin include directories [-nobuiltininc]");
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index b95741b..749dd9b 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -112,15 +112,15 @@
 static T PickFP(const llvm::fltSemantics *Sem, T IEEESingleVal,
                 T IEEEDoubleVal, T X87DoubleExtendedVal, T PPCDoubleDoubleVal,
                 T IEEEQuadVal) {
-  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle)
+  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle())
     return IEEESingleVal;
-  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEdouble)
+  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEdouble())
     return IEEEDoubleVal;
-  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::x87DoubleExtended)
+  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::x87DoubleExtended())
     return X87DoubleExtendedVal;
-  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::PPCDoubleDouble)
+  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::PPCDoubleDouble())
     return PPCDoubleDoubleVal;
-  assert(Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEquad);
+  assert(Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEquad());
   return IEEEQuadVal;
 }
 
@@ -475,6 +475,7 @@
     Builder.defineMacro("__cpp_user_defined_literals", "200809");
     Builder.defineMacro("__cpp_lambdas", "200907");
     Builder.defineMacro("__cpp_constexpr",
+                        LangOpts.CPlusPlus1z ? "201603" : 
                         LangOpts.CPlusPlus14 ? "201304" : "200704");
     Builder.defineMacro("__cpp_range_based_for",
                         LangOpts.CPlusPlus1z ? "201603" : "200907");
@@ -517,9 +518,13 @@
     Builder.defineMacro("__cpp_namespace_attributes", "201411");
     Builder.defineMacro("__cpp_enumerator_attributes", "201411");
     Builder.defineMacro("__cpp_nested_namespace_definitions", "201411");
+    Builder.defineMacro("__cpp_variadic_using", "201611");
     Builder.defineMacro("__cpp_aggregate_bases", "201603");
+    Builder.defineMacro("__cpp_structured_bindings", "201606");
     Builder.defineMacro("__cpp_nontype_template_args", "201411");
     Builder.defineMacro("__cpp_fold_expressions", "201603");
+    // FIXME: This is not yet listed in SD-6.
+    Builder.defineMacro("__cpp_deduction_guides", "201611");
   }
   if (LangOpts.AlignedAllocation)
     Builder.defineMacro("__cpp_aligned_new", "201606");
@@ -591,9 +596,6 @@
         Builder.defineMacro("OBJC_ZEROCOST_EXCEPTIONS");
     }
 
-    Builder.defineMacro("__OBJC_BOOL_IS_BOOL",
-                        Twine(TI.useSignedCharForObjCBool() ? "0" : "1"));
-
     if (LangOpts.getGC() != LangOptions::NonGC)
       Builder.defineMacro("__OBJC_GC__");
 
@@ -624,6 +626,11 @@
     Builder.defineMacro("IB_DESIGNABLE", "");
   }
 
+  // Define a macro that describes the Objective-C boolean type even for C
+  // and C++ since BOOL can be used from non Objective-C code.
+  Builder.defineMacro("__OBJC_BOOL_IS_BOOL",
+                      Twine(TI.useSignedCharForObjCBool() ? "0" : "1"));
+
   if (LangOpts.CPlusPlus)
     InitializeCPlusPlusFeatureTestMacros(LangOpts, Builder);
 
@@ -988,7 +995,7 @@
   // OpenCL definitions.
   if (LangOpts.OpenCL) {
 #define OPENCLEXT(Ext) \
-    if (TI.getSupportedOpenCLOpts().is_##Ext##_supported( \
+    if (TI.getSupportedOpenCLOpts().isSupported(#Ext, \
         LangOpts.OpenCLVersion)) \
       Builder.defineMacro(#Ext);
 #include "clang/Basic/OpenCLExtensions.def"
diff --git a/lib/Frontend/ModuleDependencyCollector.cpp b/lib/Frontend/ModuleDependencyCollector.cpp
index cc655f6..9b34d42 100644
--- a/lib/Frontend/ModuleDependencyCollector.cpp
+++ b/lib/Frontend/ModuleDependencyCollector.cpp
@@ -38,6 +38,24 @@
   }
 };
 
+struct ModuleDependencyPPCallbacks : public PPCallbacks {
+  ModuleDependencyCollector &Collector;
+  SourceManager &SM;
+  ModuleDependencyPPCallbacks(ModuleDependencyCollector &Collector,
+                              SourceManager &SM)
+      : Collector(Collector), SM(SM) {}
+
+  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)
+      return;
+    Collector.addFile(File->getName());
+  }
+};
+
 struct ModuleDependencyMMCallbacks : public ModuleMapCallbacks {
   ModuleDependencyCollector &Collector;
   ModuleDependencyMMCallbacks(ModuleDependencyCollector &Collector)
@@ -102,6 +120,8 @@
 }
 
 void ModuleDependencyCollector::attachToPreprocessor(Preprocessor &PP) {
+  PP.addPPCallbacks(llvm::make_unique<ModuleDependencyPPCallbacks>(
+      *this, PP.getSourceManager()));
   PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks(
       llvm::make_unique<ModuleDependencyMMCallbacks>(*this));
 }
@@ -181,7 +201,8 @@
   return true;
 }
 
-std::error_code ModuleDependencyCollector::copyToRoot(StringRef Src) {
+std::error_code ModuleDependencyCollector::copyToRoot(StringRef Src,
+                                                      StringRef Dst) {
   using namespace llvm::sys;
 
   // We need an absolute src path to append to the root.
@@ -193,23 +214,35 @@
   AbsoluteSrc = path::remove_leading_dotslash(AbsoluteSrc);
 
   // Canonicalize the source path by removing "..", "." components.
-  SmallString<256> CanonicalPath = AbsoluteSrc;
-  path::remove_dots(CanonicalPath, /*remove_dot_dot=*/true);
+  SmallString<256> VirtualPath = AbsoluteSrc;
+  path::remove_dots(VirtualPath, /*remove_dot_dot=*/true);
 
   // If a ".." component is present after a symlink component, remove_dots may
   // lead to the wrong real destination path. Let the source be canonicalized
   // like that but make sure we always use the real path for the destination.
-  SmallString<256> RealPath;
-  if (!getRealPath(AbsoluteSrc, RealPath))
-    RealPath = CanonicalPath;
-  SmallString<256> Dest = getDest();
-  path::append(Dest, path::relative_path(RealPath));
+  SmallString<256> CopyFrom;
+  if (!getRealPath(AbsoluteSrc, CopyFrom))
+    CopyFrom = VirtualPath;
+  SmallString<256> CacheDst = getDest();
+
+  if (Dst.empty()) {
+    // The common case is to map the virtual path to the same path inside the
+    // cache.
+    path::append(CacheDst, path::relative_path(CopyFrom));
+  } else {
+    // When collecting entries from input vfsoverlays, copy the external
+    // contents into the cache but still map from the source.
+    if (!fs::exists(Dst))
+      return std::error_code();
+    path::append(CacheDst, Dst);
+    CopyFrom = Dst;
+  }
 
   // Copy the file into place.
-  if (std::error_code EC = fs::create_directories(path::parent_path(Dest),
-                                                   /*IgnoreExisting=*/true))
+  if (std::error_code EC = fs::create_directories(path::parent_path(CacheDst),
+                                                  /*IgnoreExisting=*/true))
     return EC;
-  if (std::error_code EC = fs::copy_file(RealPath, Dest))
+  if (std::error_code EC = fs::copy_file(CopyFrom, CacheDst))
     return EC;
 
   // Always map a canonical src path to its real path into the YAML, by doing
@@ -217,12 +250,12 @@
   // overlay, which is a way to emulate symlink inside the VFS; this is also
   // needed for correctness, not doing that can lead to module redifinition
   // errors.
-  addFileMapping(CanonicalPath, Dest);
+  addFileMapping(VirtualPath, CacheDst);
   return std::error_code();
 }
 
-void ModuleDependencyCollector::addFile(StringRef Filename) {
+void ModuleDependencyCollector::addFile(StringRef Filename, StringRef FileDst) {
   if (insertSeen(Filename))
-    if (copyToRoot(Filename))
+    if (copyToRoot(Filename, FileDst))
       HasErrors = true;
 }
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index e7bfced..e6469f5 100644
--- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -4454,7 +4454,7 @@
   Name += "__" + MD->getSelector().getAsString();
   // Convert colons to underscores.
   std::string::size_type loc = 0;
-  while ((loc = Name.find(":", loc)) != std::string::npos)
+  while ((loc = Name.find(':', loc)) != std::string::npos)
     Name.replace(loc, 1, "_");
 }
 
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
index e842e59..934d6aa 100644
--- a/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -3629,7 +3629,7 @@
   Name += "__" + MD->getSelector().getAsString();
   // Convert colons to underscores.
   std::string::size_type loc = 0;
-  while ((loc = Name.find(":", loc)) != std::string::npos)
+  while ((loc = Name.find(':', loc)) != std::string::npos)
     Name.replace(loc, 1, "_");
 }
 
diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp
index 1ea5a34..7f88c91 100644
--- a/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -143,7 +143,7 @@
 
   struct SharedState;
 
-  explicit SDiagsWriter(IntrusiveRefCntPtr<SharedState> State)
+  explicit SDiagsWriter(std::shared_ptr<SharedState> State)
       : LangOpts(nullptr), OriginalInstance(false), MergeChildRecords(false),
         State(std::move(State)) {}
 
@@ -151,7 +151,7 @@
   SDiagsWriter(StringRef File, DiagnosticOptions *Diags, bool MergeChildRecords)
       : LangOpts(nullptr), OriginalInstance(true),
         MergeChildRecords(MergeChildRecords),
-        State(new SharedState(File, Diags)) {
+        State(std::make_shared<SharedState>(File, Diags)) {
     if (MergeChildRecords)
       RemoveOldDiagnostics();
     EmitPreamble();
@@ -251,7 +251,7 @@
 
   /// \brief State that is shared among the various clones of this diagnostic
   /// consumer.
-  struct SharedState : RefCountedBase<SharedState> {
+  struct SharedState {
     SharedState(StringRef File, DiagnosticOptions *Diags)
         : DiagOpts(Diags), Stream(Buffer), OutputFile(File.str()),
           EmittedAnyDiagBlocks(false) {}
@@ -299,7 +299,7 @@
   };
 
   /// \brief State shared among the various clones of this diagnostic consumer.
-  IntrusiveRefCntPtr<SharedState> State;
+  std::shared_ptr<SharedState> State;
 };
 } // end anonymous namespace
 
@@ -422,15 +422,15 @@
   EmitMetaBlock();
 }
 
-static void AddSourceLocationAbbrev(llvm::BitCodeAbbrev *Abbrev) {
+static void AddSourceLocationAbbrev(llvm::BitCodeAbbrev &Abbrev) {
   using namespace llvm;
-  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // File ID.
-  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line.
-  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column.
-  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Offset;
+  Abbrev.Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // File ID.
+  Abbrev.Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line.
+  Abbrev.Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Column.
+  Abbrev.Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Offset;
 }
 
-static void AddRangeLocationAbbrev(llvm::BitCodeAbbrev *Abbrev) {
+static void AddRangeLocationAbbrev(llvm::BitCodeAbbrev &Abbrev) {
   AddSourceLocationAbbrev(Abbrev);
   AddSourceLocationAbbrev(Abbrev);  
 }
@@ -449,7 +449,7 @@
 
   EmitBlockID(BLOCK_META, "Meta", Stream, Record);
   EmitRecordID(RECORD_VERSION, "Version", Stream, Record);
-  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_VERSION));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
   Abbrevs.set(RECORD_VERSION, Stream.EmitBlockInfoAbbrev(BLOCK_META, Abbrev));
@@ -467,10 +467,10 @@
   EmitRecordID(RECORD_FIXIT, "FixIt", Stream, Record);
 
   // Emit abbreviation for RECORD_DIAG.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_DIAG));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));  // Diag level.
-  AddSourceLocationAbbrev(Abbrev);
+  AddSourceLocationAbbrev(*Abbrev);
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Category.  
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Mapped Diag ID.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // Text size.
@@ -478,7 +478,7 @@
   Abbrevs.set(RECORD_DIAG, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
   
   // Emit abbrevation for RECORD_CATEGORY.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_CATEGORY));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Category ID.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));  // Text size.
@@ -486,14 +486,14 @@
   Abbrevs.set(RECORD_CATEGORY, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
 
   // Emit abbrevation for RECORD_SOURCE_RANGE.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_SOURCE_RANGE));
-  AddRangeLocationAbbrev(Abbrev);
+  AddRangeLocationAbbrev(*Abbrev);
   Abbrevs.set(RECORD_SOURCE_RANGE,
               Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
   
   // Emit the abbreviation for RECORD_DIAG_FLAG.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_DIAG_FLAG));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Mapped Diag ID.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Text size.
@@ -502,7 +502,7 @@
                                                            Abbrev));
   
   // Emit the abbreviation for RECORD_FILENAME.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_FILENAME));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Mapped file ID.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Size.
@@ -513,9 +513,9 @@
                                                           Abbrev));
   
   // Emit the abbreviation for RECORD_FIXIT.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_FIXIT));
-  AddRangeLocationAbbrev(Abbrev);
+  AddRangeLocationAbbrev(*Abbrev);
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Text size.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));      // FixIt text.
   Abbrevs.set(RECORD_FIXIT, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG,
diff --git a/lib/Frontend/TestModuleFileExtension.cpp b/lib/Frontend/TestModuleFileExtension.cpp
index b43d45f..294f7e4 100644
--- a/lib/Frontend/TestModuleFileExtension.cpp
+++ b/lib/Frontend/TestModuleFileExtension.cpp
@@ -24,11 +24,11 @@
   using namespace llvm;
 
   // Write an abbreviation for this record.
-  BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
+  auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(FIRST_EXTENSION_RECORD_ID));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of characters
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));   // message
-  auto Abbrev = Stream.EmitAbbrev(Abv);
+  auto Abbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Write a message into the extension block.
   SmallString<64> Message;
diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 187a6e7..1f7493c 100644
--- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -174,7 +174,7 @@
 bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
   // Honor -help.
   if (Clang->getFrontendOpts().ShowHelp) {
-    std::unique_ptr<OptTable> Opts(driver::createDriverOptTable());
+    std::unique_ptr<OptTable> Opts = driver::createDriverOptTable();
     Opts->PrintHelp(llvm::outs(), "clang -cc1",
                     "LLVM 'Clang' Compiler: http://clang.llvm.org",
                     /*Include=*/ driver::options::CC1Option, /*Exclude=*/ 0);
diff --git a/lib/Headers/CMakeLists.txt b/lib/Headers/CMakeLists.txt
index efc4dd0..35aff40 100644
--- a/lib/Headers/CMakeLists.txt
+++ b/lib/Headers/CMakeLists.txt
@@ -28,6 +28,7 @@
   __clang_cuda_intrinsics.h
   __clang_cuda_math_forward_declares.h
   __clang_cuda_runtime_wrapper.h
+  clzerointrin.h
   cpuid.h
   clflushoptintrin.h
   emmintrin.h
diff --git a/lib/Headers/__clang_cuda_cmath.h b/lib/Headers/__clang_cuda_cmath.h
index 0eaa08b..9bef826 100644
--- a/lib/Headers/__clang_cuda_cmath.h
+++ b/lib/Headers/__clang_cuda_cmath.h
@@ -72,6 +72,10 @@
 __DEVICE__ float frexp(float __arg, int *__exp) {
   return ::frexpf(__arg, __exp);
 }
+
+// For inscrutable reasons, the CUDA headers define these functions for us on
+// Windows.
+#ifndef _MSC_VER
 __DEVICE__ bool isinf(float __x) { return ::__isinff(__x); }
 __DEVICE__ bool isinf(double __x) { return ::__isinf(__x); }
 __DEVICE__ bool isfinite(float __x) { return ::__finitef(__x); }
@@ -79,6 +83,10 @@
 // __finitef, does not exist when compiling for MacOS.  __isfinited is available
 // everywhere and is just as good.
 __DEVICE__ bool isfinite(double __x) { return ::__isfinited(__x); }
+__DEVICE__ bool isnan(float __x) { return ::__isnanf(__x); }
+__DEVICE__ bool isnan(double __x) { return ::__isnan(__x); }
+#endif
+
 __DEVICE__ bool isgreater(float __x, float __y) {
   return __builtin_isgreater(__x, __y);
 }
@@ -109,8 +117,6 @@
 __DEVICE__ bool islessgreater(double __x, double __y) {
   return __builtin_islessgreater(__x, __y);
 }
-__DEVICE__ bool isnan(float __x) { return ::__isnanf(__x); }
-__DEVICE__ bool isnan(double __x) { return ::__isnan(__x); }
 __DEVICE__ bool isnormal(float __x) { return __builtin_isnormal(__x); }
 __DEVICE__ bool isnormal(double __x) { return __builtin_isnormal(__x); }
 __DEVICE__ bool isunordered(float __x, float __y) {
diff --git a/lib/Headers/__clang_cuda_intrinsics.h b/lib/Headers/__clang_cuda_intrinsics.h
index 3df41fa..b43ce21 100644
--- a/lib/Headers/__clang_cuda_intrinsics.h
+++ b/lib/Headers/__clang_cuda_intrinsics.h
@@ -35,50 +35,50 @@
 
 #pragma push_macro("__MAKE_SHUFFLES")
 #define __MAKE_SHUFFLES(__FnName, __IntIntrinsic, __FloatIntrinsic, __Mask)    \
-  inline __device__ int __FnName(int __in, int __offset,                       \
+  inline __device__ int __FnName(int __val, int __offset,                      \
                                  int __width = warpSize) {                     \
-    return __IntIntrinsic(__in, __offset,                                      \
+    return __IntIntrinsic(__val, __offset,                                     \
                           ((warpSize - __width) << 8) | (__Mask));             \
   }                                                                            \
-  inline __device__ float __FnName(float __in, int __offset,                   \
+  inline __device__ float __FnName(float __val, int __offset,                  \
                                    int __width = warpSize) {                   \
-    return __FloatIntrinsic(__in, __offset,                                    \
+    return __FloatIntrinsic(__val, __offset,                                   \
                             ((warpSize - __width) << 8) | (__Mask));           \
   }                                                                            \
-  inline __device__ unsigned int __FnName(unsigned int __in, int __offset,     \
+  inline __device__ unsigned int __FnName(unsigned int __val, int __offset,    \
                                           int __width = warpSize) {            \
     return static_cast<unsigned int>(                                          \
-        ::__FnName(static_cast<int>(__in), __offset, __width));                \
+        ::__FnName(static_cast<int>(__val), __offset, __width));               \
   }                                                                            \
-  inline __device__ long long __FnName(long long __in, int __offset,           \
+  inline __device__ long long __FnName(long long __val, int __offset,          \
                                        int __width = warpSize) {               \
     struct __Bits {                                                            \
       int __a, __b;                                                            \
     };                                                                         \
-    _Static_assert(sizeof(__in) == sizeof(__Bits));                            \
+    _Static_assert(sizeof(__val) == sizeof(__Bits));                           \
     _Static_assert(sizeof(__Bits) == 2 * sizeof(int));                         \
     __Bits __tmp;                                                              \
-    memcpy(&__in, &__tmp, sizeof(__in));                                       \
+    memcpy(&__val, &__tmp, sizeof(__val));                                     \
     __tmp.__a = ::__FnName(__tmp.__a, __offset, __width);                      \
     __tmp.__b = ::__FnName(__tmp.__b, __offset, __width);                      \
-    long long __out;                                                           \
-    memcpy(&__out, &__tmp, sizeof(__tmp));                                     \
-    return __out;                                                              \
+    long long __ret;                                                           \
+    memcpy(&__ret, &__tmp, sizeof(__tmp));                                     \
+    return __ret;                                                              \
   }                                                                            \
   inline __device__ unsigned long long __FnName(                               \
-      unsigned long long __in, int __offset, int __width = warpSize) {         \
-    return static_cast<unsigned long long>(                                    \
-        ::__FnName(static_cast<unsigned long long>(__in), __offset, __width)); \
+      unsigned long long __val, int __offset, int __width = warpSize) {        \
+    return static_cast<unsigned long long>(::__FnName(                         \
+        static_cast<unsigned long long>(__val), __offset, __width));           \
   }                                                                            \
-  inline __device__ double __FnName(double __in, int __offset,                 \
+  inline __device__ double __FnName(double __val, int __offset,                \
                                     int __width = warpSize) {                  \
     long long __tmp;                                                           \
-    _Static_assert(sizeof(__tmp) == sizeof(__in));                             \
-    memcpy(&__tmp, &__in, sizeof(__in));                                       \
+    _Static_assert(sizeof(__tmp) == sizeof(__val));                            \
+    memcpy(&__tmp, &__val, sizeof(__val));                                     \
     __tmp = ::__FnName(__tmp, __offset, __width);                              \
-    double __out;                                                              \
-    memcpy(&__out, &__tmp, sizeof(__out));                                     \
-    return __out;                                                              \
+    double __ret;                                                              \
+    memcpy(&__ret, &__tmp, sizeof(__ret));                                     \
+    return __ret;                                                              \
   }
 
 __MAKE_SHUFFLES(__shfl, __nvvm_shfl_idx_i32, __nvvm_shfl_idx_f32, 0x1f);
diff --git a/lib/Headers/__clang_cuda_runtime_wrapper.h b/lib/Headers/__clang_cuda_runtime_wrapper.h
index 205e15b..931d44b 100644
--- a/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -232,6 +232,11 @@
 // hardware, seems to generate faster machine code because ptxas can more easily
 // reason about our code.
 
+#if CUDA_VERSION >= 8000
+#include "sm_60_atomic_functions.hpp"
+#include "sm_61_intrinsics.hpp"
+#endif
+
 #undef __MATH_FUNCTIONS_HPP__
 
 // math_functions.hpp defines ::signbit as a __host__ __device__ function.  This
diff --git a/lib/Headers/__wmmintrin_aes.h b/lib/Headers/__wmmintrin_aes.h
index 211518e..3a2ee1b 100644
--- a/lib/Headers/__wmmintrin_aes.h
+++ b/lib/Headers/__wmmintrin_aes.h
@@ -35,7 +35,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VAESENC instruction.
+/// This intrinsic corresponds to the <c> VAESENC </c> instruction.
 ///
 /// \param __V
 ///    A 128-bit integer vector containing the state value.
@@ -55,7 +55,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VAESENCLAST instruction.
+/// This intrinsic corresponds to the <c> VAESENCLAST </c> instruction.
 ///
 /// \param __V
 ///    A 128-bit integer vector containing the state value.
@@ -75,7 +75,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VAESDEC instruction.
+/// This intrinsic corresponds to the <c> VAESDEC </c> instruction.
 ///
 /// \param __V
 ///    A 128-bit integer vector containing the state value.
@@ -95,7 +95,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VAESDECLAST instruction.
+/// This intrinsic corresponds to the <c> VAESDECLAST </c> instruction.
 ///
 /// \param __V
 ///    A 128-bit integer vector containing the state value.
@@ -114,7 +114,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VAESIMC instruction.
+/// This intrinsic corresponds to the <c> VAESIMC </c> instruction.
 ///
 /// \param __V
 ///    A 128-bit integer vector containing the expanded key.
@@ -136,7 +136,7 @@
 /// __m128i _mm_aeskeygenassist_si128(__m128i C, const int R);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c AESKEYGENASSIST instruction.
+/// This intrinsic corresponds to the <c> AESKEYGENASSIST </c> instruction.
 ///
 /// \param C
 ///    A 128-bit integer vector that is used to generate the AES encryption key.
diff --git a/lib/Headers/__wmmintrin_pclmul.h b/lib/Headers/__wmmintrin_pclmul.h
index 235f978..e9c6a9f 100644
--- a/lib/Headers/__wmmintrin_pclmul.h
+++ b/lib/Headers/__wmmintrin_pclmul.h
@@ -34,7 +34,7 @@
 /// __m128i _mm_clmulepi64_si128(__m128i __X, __m128i __Y, const int __I);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPCLMULQDQ instruction.
+/// This intrinsic corresponds to the <c> VPCLMULQDQ </c> instruction.
 ///
 /// \param __X
 ///    A 128-bit vector of [2 x i64] containing one of the source operands.
@@ -42,12 +42,11 @@
 ///    A 128-bit vector of [2 x i64] containing one of the source operands.
 /// \param __I
 ///    An immediate value specifying which 64-bit values to select from the
-///    operands.
-///    Bit 0 is used to select a value from operand \a __X, and bit 4 is used
-///    to select a value from operand \a __Y:
-///    Bit[0]=0 indicates that bits[63:0] of operand \a __X are used.
-///    Bit[0]=1 indicates that bits[127:64] of operand \a __X are used.
-///    Bit[4]=0 indicates that bits[63:0] of operand \a __Y are used.
+///    operands. Bit 0 is used to select a value from operand \a __X, and bit
+///    4 is used to select a value from operand \a __Y: \n
+///    Bit[0]=0 indicates that bits[63:0] of operand \a __X are used. \n
+///    Bit[0]=1 indicates that bits[127:64] of operand \a __X are used. \n
+///    Bit[4]=0 indicates that bits[63:0] of operand \a __Y are used. \n
 ///    Bit[4]=1 indicates that bits[127:64] of operand \a __Y are used.
 /// \returns The 128-bit integer vector containing the result of the carry-less
 ///    multiplication of the selected 64-bit values.
diff --git a/lib/Headers/altivec.h b/lib/Headers/altivec.h
index d1d1d80..421e2a7 100644
--- a/lib/Headers/altivec.h
+++ b/lib/Headers/altivec.h
@@ -7664,13 +7664,15 @@
 static __inline__ vector unsigned int __ATTRS_o_ai
 vec_rlnm(vector unsigned int __a, vector unsigned int __b,
          vector unsigned int __c) {
-  return __builtin_altivec_vrlwnm(__a, __b) & __c;
+  vector unsigned int OneByte = { 0x8, 0x8, 0x8, 0x8 };
+  return __builtin_altivec_vrlwnm(__a, ((__c << OneByte) | __b));
 }
 
 static __inline__ vector unsigned long long __ATTRS_o_ai
 vec_rlnm(vector unsigned long long __a, vector unsigned long long __b,
          vector unsigned long long __c) {
-  return __builtin_altivec_vrldnm(__a, __b) & __c;
+  vector unsigned long long OneByte = { 0x8, 0x8 };
+  return __builtin_altivec_vrldnm(__a, ((__c << OneByte) | __b));
 }
 #endif
 
@@ -8043,45 +8045,51 @@
 
 /* vec_sl */
 
-static __inline__ vector signed char __ATTRS_o_ai
-vec_sl(vector signed char __a, vector unsigned char __b) {
-  return __a << (vector signed char)__b;
-}
-
+// vec_sl does modulo arithmetic on __b first, so __b is allowed to be more
+// than the length of __a.
 static __inline__ vector unsigned char __ATTRS_o_ai
 vec_sl(vector unsigned char __a, vector unsigned char __b) {
-  return __a << __b;
+  return __a << (__b %
+                 (vector unsigned char)(sizeof(unsigned char) * __CHAR_BIT__));
 }
 
-static __inline__ vector short __ATTRS_o_ai vec_sl(vector short __a,
-                                                   vector unsigned short __b) {
-  return __a << (vector short)__b;
+static __inline__ vector signed char __ATTRS_o_ai
+vec_sl(vector signed char __a, vector unsigned char __b) {
+  return (vector signed char)vec_sl((vector unsigned char)__a, __b);
 }
 
 static __inline__ vector unsigned short __ATTRS_o_ai
 vec_sl(vector unsigned short __a, vector unsigned short __b) {
-  return __a << __b;
+  return __a << (__b % (vector unsigned short)(sizeof(unsigned short) *
+                                               __CHAR_BIT__));
 }
 
-static __inline__ vector int __ATTRS_o_ai vec_sl(vector int __a,
-                                                 vector unsigned int __b) {
-  return __a << (vector int)__b;
+static __inline__ vector short __ATTRS_o_ai vec_sl(vector short __a,
+                                                   vector unsigned short __b) {
+  return (vector short)vec_sl((vector unsigned short)__a, __b);
 }
 
 static __inline__ vector unsigned int __ATTRS_o_ai
 vec_sl(vector unsigned int __a, vector unsigned int __b) {
-  return __a << __b;
+  return __a << (__b %
+                 (vector unsigned int)(sizeof(unsigned int) * __CHAR_BIT__));
+}
+
+static __inline__ vector int __ATTRS_o_ai vec_sl(vector int __a,
+                                                 vector unsigned int __b) {
+  return (vector int)vec_sl((vector unsigned int)__a, __b);
 }
 
 #ifdef __POWER8_VECTOR__
-static __inline__ vector signed long long __ATTRS_o_ai
-vec_sl(vector signed long long __a, vector unsigned long long __b) {
-  return __a << (vector long long)__b;
-}
-
 static __inline__ vector unsigned long long __ATTRS_o_ai
 vec_sl(vector unsigned long long __a, vector unsigned long long __b) {
-  return __a << __b;
+  return __a << (__b % (vector unsigned long long)(sizeof(unsigned long long) *
+                                                   __CHAR_BIT__));
+}
+
+static __inline__ vector long long __ATTRS_o_ai
+vec_sl(vector long long __a, vector unsigned long long __b) {
+  return (vector long long)vec_sl((vector unsigned long long)__a, __b);
 }
 #endif
 
@@ -12574,6 +12582,9 @@
 
 #ifdef __POWER9_VECTOR__
 
+#define vec_insert4b __builtin_vsx_insertword
+#define vec_extract4b __builtin_vsx_extractuword
+
 /* vec_extract_exp */
 
 static __inline__ vector unsigned int __ATTRS_o_ai
diff --git a/lib/Headers/ammintrin.h b/lib/Headers/ammintrin.h
index 24deb86..2843a7a 100644
--- a/lib/Headers/ammintrin.h
+++ b/lib/Headers/ammintrin.h
@@ -38,7 +38,7 @@
 /// __m128i _mm_extracti_si64(__m128i x, const int len, const int idx);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c EXTRQ instruction.
+/// This intrinsic corresponds to the <c> EXTRQ </c> instruction.
 ///
 /// \param x
 ///    The value from which bits are extracted.
@@ -63,7 +63,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c EXTRQ instruction.
+/// This intrinsic corresponds to the <c> EXTRQ </c> instruction.
 ///
 /// \param __x
 ///    The value from which bits are extracted.
@@ -93,7 +93,7 @@
 /// const int idx);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c INSERTQ instruction.
+/// This intrinsic corresponds to the <c> INSERTQ </c> instruction.
 ///
 /// \param x
 ///    The destination operand where bits will be inserted. The inserted bits
@@ -126,7 +126,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c INSERTQ instruction.
+/// This intrinsic corresponds to the <c> INSERTQ </c> instruction.
 ///
 /// \param __x
 ///    The destination operand where bits will be inserted. The inserted bits
@@ -158,7 +158,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c MOVNTSD instruction.
+/// This intrinsic corresponds to the <c> MOVNTSD </c> instruction.
 ///
 /// \param __p
 ///    The 64-bit memory location used to store the register value.
@@ -176,7 +176,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c MOVNTSS instruction.
+/// This intrinsic corresponds to the <c> MOVNTSS </c> instruction.
 ///
 /// \param __p
 ///    The 32-bit memory location used to store the register value.
diff --git a/lib/Headers/avx512bwintrin.h b/lib/Headers/avx512bwintrin.h
index 62f0731..41958b7 100644
--- a/lib/Headers/avx512bwintrin.h
+++ b/lib/Headers/avx512bwintrin.h
@@ -504,115 +504,91 @@
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_packs_epi32 (__m512i __A, __m512i __B)
+_mm512_packs_epi32(__m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packssdw512_mask ((__v16si) __A,
-              (__v16si) __B,
-              (__v32hi) _mm512_setzero_hi(),
-              (__mmask32) -1);
+  return (__m512i)__builtin_ia32_packssdw512((__v16si)__A, (__v16si)__B);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_packs_epi32 (__mmask32 __M, __m512i __A, __m512i __B)
+_mm512_maskz_packs_epi32(__mmask32 __M, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packssdw512_mask ((__v16si) __A,
-              (__v16si) __B,
-              (__v32hi) _mm512_setzero_hi(),
-              __M);
+  return (__m512i)__builtin_ia32_selectw_512((__mmask32)__M,
+                                       (__v32hi)_mm512_packs_epi32(__A, __B),
+                                       (__v32hi)_mm512_setzero_hi());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_packs_epi32 (__m512i __W, __mmask32 __M, __m512i __A,
-       __m512i __B)
+_mm512_mask_packs_epi32(__m512i __W, __mmask32 __M, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packssdw512_mask ((__v16si) __A,
-              (__v16si) __B,
-              (__v32hi) __W,
-              __M);
+  return (__m512i)__builtin_ia32_selectw_512((__mmask32)__M,
+                                       (__v32hi)_mm512_packs_epi32(__A, __B),
+                                       (__v32hi)__W);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_packs_epi16 (__m512i __A, __m512i __B)
+_mm512_packs_epi16(__m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packsswb512_mask ((__v32hi) __A,
-              (__v32hi) __B,
-              (__v64qi) _mm512_setzero_qi(),
-              (__mmask64) -1);
+  return (__m512i)__builtin_ia32_packsswb512((__v32hi)__A, (__v32hi) __B);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_packs_epi16 (__m512i __W, __mmask64 __M, __m512i __A,
-       __m512i __B)
+_mm512_mask_packs_epi16(__m512i __W, __mmask64 __M, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packsswb512_mask ((__v32hi) __A,
-              (__v32hi) __B,
-              (__v64qi) __W,
-              (__mmask64) __M);
+  return (__m512i)__builtin_ia32_selectb_512((__mmask64)__M,
+                                        (__v64qi)_mm512_packs_epi16(__A, __B),
+                                        (__v64qi)__W);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_packs_epi16 (__mmask64 __M, __m512i __A, __m512i __B)
+_mm512_maskz_packs_epi16(__mmask64 __M, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packsswb512_mask ((__v32hi) __A,
-              (__v32hi) __B,
-              (__v64qi) _mm512_setzero_qi(),
-              __M);
+  return (__m512i)__builtin_ia32_selectb_512((__mmask64)__M,
+                                        (__v64qi)_mm512_packs_epi16(__A, __B),
+                                        (__v64qi)_mm512_setzero_qi());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_packus_epi32 (__m512i __A, __m512i __B)
+_mm512_packus_epi32(__m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packusdw512_mask ((__v16si) __A,
-              (__v16si) __B,
-              (__v32hi) _mm512_setzero_hi(),
-              (__mmask32) -1);
+  return (__m512i)__builtin_ia32_packusdw512((__v16si) __A, (__v16si) __B);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_packus_epi32 (__mmask32 __M, __m512i __A, __m512i __B)
+_mm512_maskz_packus_epi32(__mmask32 __M, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packusdw512_mask ((__v16si) __A,
-              (__v16si) __B,
-              (__v32hi) _mm512_setzero_hi(),
-              __M);
+  return (__m512i)__builtin_ia32_selectw_512((__mmask32)__M,
+                                       (__v32hi)_mm512_packus_epi32(__A, __B),
+                                       (__v32hi)_mm512_setzero_hi());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_packus_epi32 (__m512i __W, __mmask32 __M, __m512i __A,
-        __m512i __B)
+_mm512_mask_packus_epi32(__m512i __W, __mmask32 __M, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packusdw512_mask ((__v16si) __A,
-              (__v16si) __B,
-              (__v32hi) __W,
-              __M);
+  return (__m512i)__builtin_ia32_selectw_512((__mmask32)__M,
+                                       (__v32hi)_mm512_packus_epi32(__A, __B),
+                                       (__v32hi)__W);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_packus_epi16 (__m512i __A, __m512i __B)
+_mm512_packus_epi16(__m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packuswb512_mask ((__v32hi) __A,
-              (__v32hi) __B,
-              (__v64qi) _mm512_setzero_qi(),
-              (__mmask64) -1);
+  return (__m512i)__builtin_ia32_packuswb512((__v32hi) __A, (__v32hi) __B);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_packus_epi16 (__m512i __W, __mmask64 __M, __m512i __A,
-        __m512i __B)
+_mm512_mask_packus_epi16(__m512i __W, __mmask64 __M, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packuswb512_mask ((__v32hi) __A,
-              (__v32hi) __B,
-              (__v64qi) __W,
-              (__mmask64) __M);
+  return (__m512i)__builtin_ia32_selectb_512((__mmask64)__M,
+                                        (__v64qi)_mm512_packus_epi16(__A, __B),
+                                        (__v64qi)__W);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_packus_epi16 (__mmask64 __M, __m512i __A, __m512i __B)
+_mm512_maskz_packus_epi16(__mmask64 __M, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_packuswb512_mask ((__v32hi) __A,
-              (__v32hi) __B,
-              (__v64qi) _mm512_setzero_qi(),
-              (__mmask64) __M);
+  return (__m512i)__builtin_ia32_selectb_512((__mmask64)__M,
+                                        (__v64qi)_mm512_packus_epi16(__A, __B),
+                                        (__v64qi)_mm512_setzero_qi());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
@@ -1008,31 +984,25 @@
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_shuffle_epi8 (__m512i __A, __m512i __B)
+_mm512_shuffle_epi8(__m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_pshufb512_mask ((__v64qi) __A,
-              (__v64qi) __B,
-              (__v64qi) _mm512_setzero_qi(),
-              (__mmask64) -1);
+  return (__m512i)__builtin_ia32_pshufb512((__v64qi)__A,(__v64qi)__B);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_shuffle_epi8 (__m512i __W, __mmask64 __U, __m512i __A,
-        __m512i __B)
+_mm512_mask_shuffle_epi8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_pshufb512_mask ((__v64qi) __A,
-              (__v64qi) __B,
-              (__v64qi) __W,
-              (__mmask64) __U);
+  return (__m512i)__builtin_ia32_selectb_512((__mmask64)__U,
+                                         (__v64qi)_mm512_shuffle_epi8(__A, __B),
+                                         (__v64qi)__W);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_shuffle_epi8 (__mmask64 __U, __m512i __A, __m512i __B)
+_mm512_maskz_shuffle_epi8(__mmask64 __U, __m512i __A, __m512i __B)
 {
-  return (__m512i) __builtin_ia32_pshufb512_mask ((__v64qi) __A,
-              (__v64qi) __B,
-              (__v64qi) _mm512_setzero_qi(),
-              (__mmask64) __U);
+  return (__m512i)__builtin_ia32_selectb_512((__mmask64)__U,
+                                         (__v64qi)_mm512_shuffle_epi8(__A, __B),
+                                         (__v64qi)_mm512_setzero_qi());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
diff --git a/lib/Headers/avx512dqintrin.h b/lib/Headers/avx512dqintrin.h
index ae44b98..4fd1add 100644
--- a/lib/Headers/avx512dqintrin.h
+++ b/lib/Headers/avx512dqintrin.h
@@ -995,51 +995,50 @@
 }
 
 static __inline__ __m512 __DEFAULT_FN_ATTRS
-_mm512_broadcast_f32x8 (__m256 __A)
+_mm512_broadcast_f32x8(__m256 __A)
 {
-  return (__m512) __builtin_ia32_broadcastf32x8_512_mask ((__v8sf) __A,
-                _mm512_undefined_ps(),
-                (__mmask16) -1);
+  return (__m512)__builtin_shufflevector((__v8sf)__A, (__v8sf)__A,
+                                         0, 1, 2, 3, 4, 5, 6, 7,
+                                         0, 1, 2, 3, 4, 5, 6, 7);
 }
 
 static __inline__ __m512 __DEFAULT_FN_ATTRS
-_mm512_mask_broadcast_f32x8 (__m512 __O, __mmask16 __M, __m256 __A)
+_mm512_mask_broadcast_f32x8(__m512 __O, __mmask16 __M, __m256 __A)
 {
-  return (__m512) __builtin_ia32_broadcastf32x8_512_mask ((__v8sf) __A,
-                (__v16sf)__O,
-                __M);
+  return (__m512)__builtin_ia32_selectps_512((__mmask8)__M,
+                                           (__v16sf)_mm512_broadcast_f32x8(__A),
+                                           (__v16sf)__O);
 }
 
 static __inline__ __m512 __DEFAULT_FN_ATTRS
-_mm512_maskz_broadcast_f32x8 (__mmask16 __M, __m256 __A)
+_mm512_maskz_broadcast_f32x8(__mmask16 __M, __m256 __A)
 {
-  return (__m512) __builtin_ia32_broadcastf32x8_512_mask ((__v8sf) __A,
-                (__v16sf)_mm512_setzero_ps (),
-                __M);
+  return (__m512)__builtin_ia32_selectps_512((__mmask8)__M,
+                                           (__v16sf)_mm512_broadcast_f32x8(__A),
+                                           (__v16sf)_mm512_setzero_ps());
 }
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
-_mm512_broadcast_f64x2 (__m128d __A)
+_mm512_broadcast_f64x2(__m128d __A)
 {
-  return (__m512d) __builtin_ia32_broadcastf64x2_512_mask ((__v2df) __A,
-                 (__v8df)_mm512_undefined_pd(),
-                 (__mmask8) -1);
+  return (__m512d)__builtin_shufflevector((__v2df)__A, (__v2df)__A,
+                                          0, 1, 0, 1, 0, 1, 0, 1);
 }
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
-_mm512_mask_broadcast_f64x2 (__m512d __O, __mmask8 __M, __m128d __A)
+_mm512_mask_broadcast_f64x2(__m512d __O, __mmask8 __M, __m128d __A)
 {
-  return (__m512d) __builtin_ia32_broadcastf64x2_512_mask ((__v2df) __A,
-                 (__v8df)
-                 __O, __M);
+  return (__m512d)__builtin_ia32_selectpd_512((__mmask8)__M,
+                                            (__v8df)_mm512_broadcast_f64x2(__A),
+                                            (__v8df)__O);
 }
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
-_mm512_maskz_broadcast_f64x2 (__mmask8 __M, __m128d __A)
+_mm512_maskz_broadcast_f64x2(__mmask8 __M, __m128d __A)
 {
-  return (__m512d) __builtin_ia32_broadcastf64x2_512_mask ((__v2df) __A,
-                 (__v8df)_mm512_setzero_ps (),
-                 __M);
+  return (__m512d)__builtin_ia32_selectpd_512((__mmask8)__M,
+                                            (__v8df)_mm512_broadcast_f64x2(__A),
+                                            (__v8df)_mm512_setzero_pd());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
@@ -1067,52 +1066,50 @@
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_broadcast_i32x8 (__m256i __A)
+_mm512_broadcast_i32x8(__m256i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti32x8_512_mask ((__v8si) __A,
-                 (__v16si)_mm512_setzero_si512(),
-                 (__mmask16) -1);
+  return (__m512i)__builtin_shufflevector((__v8si)__A, (__v8si)__A,
+                                          0, 1, 2, 3, 4, 5, 6, 7,
+                                          0, 1, 2, 3, 4, 5, 6, 7);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_broadcast_i32x8 (__m512i __O, __mmask16 __M, __m256i __A)
+_mm512_mask_broadcast_i32x8(__m512i __O, __mmask16 __M, __m256i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti32x8_512_mask ((__v8si) __A,
-                 (__v16si)__O,
-                 __M);
+  return (__m512i)__builtin_ia32_selectd_512((__mmask8)__M,
+                                           (__v16si)_mm512_broadcast_i32x8(__A),
+                                           (__v16si)__O);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_broadcast_i32x8 (__mmask16 __M, __m256i __A)
+_mm512_maskz_broadcast_i32x8(__mmask16 __M, __m256i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti32x8_512_mask ((__v8si) __A,
-                 (__v16si)
-                 _mm512_setzero_si512 (),
-                 __M);
+  return (__m512i)__builtin_ia32_selectd_512((__mmask8)__M,
+                                           (__v16si)_mm512_broadcast_i32x8(__A),
+                                           (__v16si)_mm512_setzero_si512());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_broadcast_i64x2 (__m128i __A)
+_mm512_broadcast_i64x2(__m128i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti64x2_512_mask ((__v2di) __A,
-                 (__v8di)_mm512_setzero_si512(),
-                 (__mmask8) -1);
+  return (__m512i)__builtin_shufflevector((__v2di)__A, (__v2di)__A,
+                                          0, 1, 0, 1, 0, 1, 0, 1);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_broadcast_i64x2 (__m512i __O, __mmask8 __M, __m128i __A)
+_mm512_mask_broadcast_i64x2(__m512i __O, __mmask8 __M, __m128i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti64x2_512_mask ((__v2di) __A,
-                 (__v8di)
-                 __O, __M);
+  return (__m512i)__builtin_ia32_selectq_512((__mmask8)__M,
+                                            (__v8di)_mm512_broadcast_i64x2(__A),
+                                            (__v8di)__O);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_broadcast_i64x2 (__mmask8 __M, __m128i __A)
+_mm512_maskz_broadcast_i64x2(__mmask8 __M, __m128i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti64x2_512_mask ((__v2di) __A,
-                 (__v8di)_mm512_setzero_si512 (),
-                 __M);
+  return (__m512i)__builtin_ia32_selectq_512((__mmask8)__M,
+                                            (__v8di)_mm512_broadcast_i64x2(__A),
+                                            (__v8di)_mm512_setzero_si512());
 }
 
 #define _mm512_extractf32x8_ps(A, imm) __extension__ ({ \
diff --git a/lib/Headers/avx512fintrin.h b/lib/Headers/avx512fintrin.h
index 8699957..7d9a52f 100644
--- a/lib/Headers/avx512fintrin.h
+++ b/lib/Headers/avx512fintrin.h
@@ -1416,57 +1416,45 @@
 static __inline __m512i __DEFAULT_FN_ATTRS
 _mm512_mul_epi32(__m512i __X, __m512i __Y)
 {
-  return (__m512i) __builtin_ia32_pmuldq512_mask ((__v16si) __X,
-              (__v16si) __Y,
-              (__v8di)
-              _mm512_setzero_si512 (),
-              (__mmask8) -1);
+  return (__m512i)__builtin_ia32_pmuldq512((__v16si)__X, (__v16si) __Y);
 }
 
 static __inline __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_mul_epi32 (__m512i __W, __mmask8 __M, __m512i __X, __m512i __Y)
+_mm512_mask_mul_epi32(__m512i __W, __mmask8 __M, __m512i __X, __m512i __Y)
 {
-  return (__m512i) __builtin_ia32_pmuldq512_mask ((__v16si) __X,
-              (__v16si) __Y,
-              (__v8di) __W, __M);
+  return (__m512i)__builtin_ia32_selectq_512((__mmask8)__M,
+                                             (__v8di)_mm512_mul_epi32(__X, __Y),
+                                             (__v8di)__W);
 }
 
 static __inline __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_mul_epi32 (__mmask8 __M, __m512i __X, __m512i __Y)
+_mm512_maskz_mul_epi32(__mmask8 __M, __m512i __X, __m512i __Y)
 {
-  return (__m512i) __builtin_ia32_pmuldq512_mask ((__v16si) __X,
-              (__v16si) __Y,
-              (__v8di)
-              _mm512_setzero_si512 (),
-              __M);
+  return (__m512i)__builtin_ia32_selectq_512((__mmask8)__M,
+                                             (__v8di)_mm512_mul_epi32(__X, __Y),
+                                             (__v8di)_mm512_setzero_si512 ());
 }
 
 static __inline __m512i __DEFAULT_FN_ATTRS
 _mm512_mul_epu32(__m512i __X, __m512i __Y)
 {
-  return (__m512i) __builtin_ia32_pmuludq512_mask ((__v16si) __X,
-               (__v16si) __Y,
-               (__v8di)
-               _mm512_setzero_si512 (),
-               (__mmask8) -1);
+  return (__m512i)__builtin_ia32_pmuludq512((__v16si)__X, (__v16si)__Y);
 }
 
 static __inline __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_mul_epu32 (__m512i __W, __mmask8 __M, __m512i __X, __m512i __Y)
+_mm512_mask_mul_epu32(__m512i __W, __mmask8 __M, __m512i __X, __m512i __Y)
 {
-  return (__m512i) __builtin_ia32_pmuludq512_mask ((__v16si) __X,
-               (__v16si) __Y,
-               (__v8di) __W, __M);
+  return (__m512i)__builtin_ia32_selectq_512((__mmask8)__M,
+                                             (__v8di)_mm512_mul_epu32(__X, __Y),
+                                             (__v8di)__W);
 }
 
 static __inline __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_mul_epu32 (__mmask8 __M, __m512i __X, __m512i __Y)
+_mm512_maskz_mul_epu32(__mmask8 __M, __m512i __X, __m512i __Y)
 {
-  return (__m512i) __builtin_ia32_pmuludq512_mask ((__v16si) __X,
-               (__v16si) __Y,
-               (__v8di)
-               _mm512_setzero_si512 (),
-               __M);
+  return (__m512i)__builtin_ia32_selectq_512((__mmask8)__M,
+                                             (__v8di)_mm512_mul_epu32(__X, __Y),
+                                             (__v8di)_mm512_setzero_si512 ());
 }
 
 static __inline __m512i __DEFAULT_FN_ATTRS
@@ -6588,61 +6576,47 @@
                                       (__v16sf)_mm512_setzero_ps()); })
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
-_mm512_permutevar_pd (__m512d __A, __m512i __C)
+_mm512_permutevar_pd(__m512d __A, __m512i __C)
 {
-  return (__m512d) __builtin_ia32_vpermilvarpd512_mask ((__v8df) __A,
-              (__v8di) __C,
-              (__v8df)
-              _mm512_undefined_pd (),
-              (__mmask8) -1);
+  return (__m512d)__builtin_ia32_vpermilvarpd512((__v8df)__A, (__v8di)__C);
 }
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
-_mm512_mask_permutevar_pd (__m512d __W, __mmask8 __U, __m512d __A, __m512i __C)
+_mm512_mask_permutevar_pd(__m512d __W, __mmask8 __U, __m512d __A, __m512i __C)
 {
-  return (__m512d) __builtin_ia32_vpermilvarpd512_mask ((__v8df) __A,
-              (__v8di) __C,
-              (__v8df) __W,
-              (__mmask8) __U);
+  return (__m512d)__builtin_ia32_selectpd_512((__mmask8)__U,
+                                         (__v8df)_mm512_permutevar_pd(__A, __C),
+                                         (__v8df)__W);
 }
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
-_mm512_maskz_permutevar_pd (__mmask8 __U, __m512d __A, __m512i __C)
+_mm512_maskz_permutevar_pd(__mmask8 __U, __m512d __A, __m512i __C)
 {
-  return (__m512d) __builtin_ia32_vpermilvarpd512_mask ((__v8df) __A,
-              (__v8di) __C,
-              (__v8df)
-              _mm512_setzero_pd (),
-              (__mmask8) __U);
+  return (__m512d)__builtin_ia32_selectpd_512((__mmask8)__U,
+                                         (__v8df)_mm512_permutevar_pd(__A, __C),
+                                         (__v8df)_mm512_setzero_pd());
 }
 
 static __inline__ __m512 __DEFAULT_FN_ATTRS
-_mm512_permutevar_ps (__m512 __A, __m512i __C)
+_mm512_permutevar_ps(__m512 __A, __m512i __C)
 {
-  return (__m512) __builtin_ia32_vpermilvarps512_mask ((__v16sf) __A,
-                   (__v16si) __C,
-                   (__v16sf)
-                   _mm512_undefined_ps (),
-                   (__mmask16) -1);
+  return (__m512)__builtin_ia32_vpermilvarps512((__v16sf)__A, (__v16si)__C);
 }
 
 static __inline__ __m512 __DEFAULT_FN_ATTRS
-_mm512_mask_permutevar_ps (__m512 __W, __mmask16 __U, __m512 __A, __m512i __C)
+_mm512_mask_permutevar_ps(__m512 __W, __mmask16 __U, __m512 __A, __m512i __C)
 {
-  return (__m512) __builtin_ia32_vpermilvarps512_mask ((__v16sf) __A,
-                   (__v16si) __C,
-                   (__v16sf) __W,
-                   (__mmask16) __U);
+  return (__m512)__builtin_ia32_selectps_512((__mmask16)__U,
+                                        (__v16sf)_mm512_permutevar_ps(__A, __C),
+                                        (__v16sf)__W);
 }
 
 static __inline__ __m512 __DEFAULT_FN_ATTRS
-_mm512_maskz_permutevar_ps (__mmask16 __U, __m512 __A, __m512i __C)
+_mm512_maskz_permutevar_ps(__mmask16 __U, __m512 __A, __m512i __C)
 {
-  return (__m512) __builtin_ia32_vpermilvarps512_mask ((__v16sf) __A,
-                   (__v16si) __C,
-                   (__v16sf)
-                   _mm512_setzero_ps (),
-                   (__mmask16) __U);
+  return (__m512)__builtin_ia32_selectps_512((__mmask16)__U,
+                                        (__v16sf)_mm512_permutevar_ps(__A, __C),
+                                        (__v16sf)_mm512_setzero_ps());
 }
 
 static __inline __m512d __DEFAULT_FN_ATTRS
@@ -7304,107 +7278,97 @@
                                            (__mmask8)(U), (int)(R)); })
 
 static __inline__ __m512 __DEFAULT_FN_ATTRS
-_mm512_broadcast_f32x4 (__m128 __A)
+_mm512_broadcast_f32x4(__m128 __A)
 {
-  return (__m512) __builtin_ia32_broadcastf32x4_512 ((__v4sf) __A,
-                 (__v16sf)
-                 _mm512_undefined_ps (),
-                 (__mmask16) -1);
+  return (__m512)__builtin_shufflevector((__v4sf)__A, (__v4sf)__A,
+                                         0, 1, 2, 3, 0, 1, 2, 3,
+                                         0, 1, 2, 3, 0, 1, 2, 3);
 }
 
 static __inline__ __m512 __DEFAULT_FN_ATTRS
-_mm512_mask_broadcast_f32x4 (__m512 __O, __mmask16 __M, __m128 __A)
+_mm512_mask_broadcast_f32x4(__m512 __O, __mmask16 __M, __m128 __A)
 {
-  return (__m512) __builtin_ia32_broadcastf32x4_512 ((__v4sf) __A,
-                 (__v16sf) __O,
-                 __M);
+  return (__m512)__builtin_ia32_selectps_512((__mmask16)__M,
+                                           (__v16sf)_mm512_broadcast_f32x4(__A),
+                                           (__v16sf)__O);
 }
 
 static __inline__ __m512 __DEFAULT_FN_ATTRS
-_mm512_maskz_broadcast_f32x4 (__mmask16 __M, __m128 __A)
+_mm512_maskz_broadcast_f32x4(__mmask16 __M, __m128 __A)
 {
-  return (__m512) __builtin_ia32_broadcastf32x4_512 ((__v4sf) __A,
-                 (__v16sf)
-                 _mm512_setzero_ps (),
-                 __M);
+  return (__m512)__builtin_ia32_selectps_512((__mmask16)__M,
+                                           (__v16sf)_mm512_broadcast_f32x4(__A),
+                                           (__v16sf)_mm512_setzero_ps());
 }
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
-_mm512_broadcast_f64x4 (__m256d __A)
+_mm512_broadcast_f64x4(__m256d __A)
 {
-  return (__m512d) __builtin_ia32_broadcastf64x4_512 ((__v4df) __A,
-                  (__v8df)
-                  _mm512_undefined_pd (),
-                  (__mmask8) -1);
+  return (__m512d)__builtin_shufflevector((__v4df)__A, (__v4df)__A,
+                                          0, 1, 2, 3, 0, 1, 2, 3);
 }
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
-_mm512_mask_broadcast_f64x4 (__m512d __O, __mmask8 __M, __m256d __A)
+_mm512_mask_broadcast_f64x4(__m512d __O, __mmask8 __M, __m256d __A)
 {
-  return (__m512d) __builtin_ia32_broadcastf64x4_512 ((__v4df) __A,
-                  (__v8df) __O,
-                  __M);
+  return (__m512d)__builtin_ia32_selectpd_512((__mmask8)__M,
+                                            (__v8df)_mm512_broadcast_f64x4(__A),
+                                            (__v8df)__O);
 }
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
-_mm512_maskz_broadcast_f64x4 (__mmask8 __M, __m256d __A)
+_mm512_maskz_broadcast_f64x4(__mmask8 __M, __m256d __A)
 {
-  return (__m512d) __builtin_ia32_broadcastf64x4_512 ((__v4df) __A,
-                  (__v8df)
-                  _mm512_setzero_pd (),
-                  __M);
+  return (__m512d)__builtin_ia32_selectpd_512((__mmask8)__M,
+                                            (__v8df)_mm512_broadcast_f64x4(__A),
+                                            (__v8df)_mm512_setzero_pd());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_broadcast_i32x4 (__m128i __A)
+_mm512_broadcast_i32x4(__m128i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti32x4_512 ((__v4si) __A,
-                  (__v16si)
-                  _mm512_undefined_epi32 (),
-                  (__mmask16) -1);
+  return (__m512i)__builtin_shufflevector((__v4si)__A, (__v4si)__A,
+                                          0, 1, 2, 3, 0, 1, 2, 3,
+                                          0, 1, 2, 3, 0, 1, 2, 3);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_broadcast_i32x4 (__m512i __O, __mmask16 __M, __m128i __A)
+_mm512_mask_broadcast_i32x4(__m512i __O, __mmask16 __M, __m128i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti32x4_512 ((__v4si) __A,
-                  (__v16si) __O,
-                  __M);
+  return (__m512i)__builtin_ia32_selectd_512((__mmask16)__M,
+                                           (__v16si)_mm512_broadcast_i32x4(__A),
+                                           (__v16si)__O);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_broadcast_i32x4 (__mmask16 __M, __m128i __A)
+_mm512_maskz_broadcast_i32x4(__mmask16 __M, __m128i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti32x4_512 ((__v4si) __A,
-                  (__v16si)
-                  _mm512_setzero_si512 (),
-                  __M);
+  return (__m512i)__builtin_ia32_selectd_512((__mmask16)__M,
+                                           (__v16si)_mm512_broadcast_i32x4(__A),
+                                           (__v16si)_mm512_setzero_si512());
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_broadcast_i64x4 (__m256i __A)
+_mm512_broadcast_i64x4(__m256i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti64x4_512 ((__v4di) __A,
-                  (__v8di)
-                  _mm512_undefined_epi32 (),
-                  (__mmask8) -1);
+  return (__m512i)__builtin_shufflevector((__v4di)__A, (__v4di)__A,
+                                          0, 1, 2, 3, 0, 1, 2, 3);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_broadcast_i64x4 (__m512i __O, __mmask8 __M, __m256i __A)
+_mm512_mask_broadcast_i64x4(__m512i __O, __mmask8 __M, __m256i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti64x4_512 ((__v4di) __A,
-                  (__v8di) __O,
-                  __M);
+  return (__m512i)__builtin_ia32_selectq_512((__mmask8)__M,
+                                            (__v8di)_mm512_broadcast_i64x4(__A),
+                                            (__v8di)__O);
 }
 
 static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_broadcast_i64x4 (__mmask8 __M, __m256i __A)
+_mm512_maskz_broadcast_i64x4(__mmask8 __M, __m256i __A)
 {
-  return (__m512i) __builtin_ia32_broadcasti64x4_512 ((__v4di) __A,
-                  (__v8di)
-                  _mm512_setzero_si512 (),
-                  __M);
+  return (__m512i)__builtin_ia32_selectq_512((__mmask8)__M,
+                                            (__v8di)_mm512_broadcast_i64x4(__A),
+                                            (__v8di)_mm512_setzero_si512());
 }
 
 static __inline__ __m512d __DEFAULT_FN_ATTRS
diff --git a/lib/Headers/avx512vldqintrin.h b/lib/Headers/avx512vldqintrin.h
index cd9da43..aecd7df 100644
--- a/lib/Headers/avx512vldqintrin.h
+++ b/lib/Headers/avx512vldqintrin.h
@@ -1000,27 +1000,26 @@
 }
 
 static __inline__ __m256d __DEFAULT_FN_ATTRS
-_mm256_broadcast_f64x2 (__m128d __A)
+_mm256_broadcast_f64x2(__m128d __A)
 {
-  return (__m256d) __builtin_ia32_broadcastf64x2_256_mask ((__v2df) __A,
-                 (__v4df)_mm256_undefined_pd(),
-                 (__mmask8) -1);
+  return (__m256d)__builtin_shufflevector((__v2df)__A, (__v2df)__A,
+                                          0, 1, 0, 1);
 }
 
 static __inline__ __m256d __DEFAULT_FN_ATTRS
-_mm256_mask_broadcast_f64x2 (__m256d __O, __mmask8 __M, __m128d __A)
+_mm256_mask_broadcast_f64x2(__m256d __O, __mmask8 __M, __m128d __A)
 {
-  return (__m256d) __builtin_ia32_broadcastf64x2_256_mask ((__v2df) __A,
-                 (__v4df) __O,
-                 __M);
+  return (__m256d)__builtin_ia32_selectpd_256((__mmask8)__M,
+                                            (__v4df)_mm256_broadcast_f64x2(__A),
+                                            (__v4df)__O);
 }
 
 static __inline__ __m256d __DEFAULT_FN_ATTRS
 _mm256_maskz_broadcast_f64x2 (__mmask8 __M, __m128d __A)
 {
-  return (__m256d) __builtin_ia32_broadcastf64x2_256_mask ((__v2df) __A,
-                 (__v4df) _mm256_setzero_ps (),
-                 __M);
+  return (__m256d)__builtin_ia32_selectpd_256((__mmask8)__M,
+                                            (__v4df)_mm256_broadcast_f64x2(__A),
+                                            (__v4df)_mm256_setzero_pd());
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS
@@ -1072,27 +1071,26 @@
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS
-_mm256_broadcast_i64x2 (__m128i __A)
+_mm256_broadcast_i64x2(__m128i __A)
 {
-  return (__m256i) __builtin_ia32_broadcasti64x2_256_mask ((__v2di) __A,
-                 (__v4di)_mm256_undefined_si256(),
-                 (__mmask8) -1);
+  return (__m256i)__builtin_shufflevector((__v2di)__A, (__v2di)__A,
+                                          0, 1, 0, 1);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS
-_mm256_mask_broadcast_i64x2 (__m256i __O, __mmask8 __M, __m128i __A)
+_mm256_mask_broadcast_i64x2(__m256i __O, __mmask8 __M, __m128i __A)
 {
-  return (__m256i) __builtin_ia32_broadcasti64x2_256_mask ((__v2di) __A,
-                 (__v4di) __O,
-                 __M);
+  return (__m256i)__builtin_ia32_selectq_256((__mmask8)__M,
+                                            (__v4di)_mm256_broadcast_i64x2(__A),
+                                            (__v4di)__O);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS
 _mm256_maskz_broadcast_i64x2 (__mmask8 __M, __m128i __A)
 {
-  return (__m256i) __builtin_ia32_broadcasti64x2_256_mask ((__v2di) __A,
-                 (__v4di) _mm256_setzero_si256 (),
-                 __M);
+  return (__m256i)__builtin_ia32_selectq_256((__mmask8)__M,
+                                            (__v4di)_mm256_broadcast_i64x2(__A),
+                                            (__v4di)_mm256_setzero_si256());
 }
 
 #define _mm256_extractf64x2_pd(A, imm) __extension__ ({ \
diff --git a/lib/Headers/avx512vlintrin.h b/lib/Headers/avx512vlintrin.h
index 0974fc8..99bb050 100644
--- a/lib/Headers/avx512vlintrin.h
+++ b/lib/Headers/avx512vlintrin.h
@@ -6424,85 +6424,67 @@
                                       (__v8sf)_mm256_setzero_ps()); })
 
 static __inline__ __m128d __DEFAULT_FN_ATTRS
-_mm_mask_permutevar_pd (__m128d __W, __mmask8 __U, __m128d __A,
-      __m128i __C)
+_mm_mask_permutevar_pd(__m128d __W, __mmask8 __U, __m128d __A, __m128i __C)
 {
-  return (__m128d) __builtin_ia32_vpermilvarpd_mask ((__v2df) __A,
-                 (__v2di) __C,
-                 (__v2df) __W,
-                 (__mmask8) __U);
+  return (__m128d)__builtin_ia32_selectpd_128((__mmask8)__U,
+                                            (__v2df)_mm_permutevar_pd(__A, __C),
+                                            (__v2df)__W);
 }
 
 static __inline__ __m128d __DEFAULT_FN_ATTRS
-_mm_maskz_permutevar_pd (__mmask8 __U, __m128d __A, __m128i __C)
+_mm_maskz_permutevar_pd(__mmask8 __U, __m128d __A, __m128i __C)
 {
-  return (__m128d) __builtin_ia32_vpermilvarpd_mask ((__v2df) __A,
-                 (__v2di) __C,
-                 (__v2df)
-                 _mm_setzero_pd (),
-                 (__mmask8) __U);
+  return (__m128d)__builtin_ia32_selectpd_128((__mmask8)__U,
+                                            (__v2df)_mm_permutevar_pd(__A, __C),
+                                            (__v2df)_mm_setzero_pd());
 }
 
 static __inline__ __m256d __DEFAULT_FN_ATTRS
-_mm256_mask_permutevar_pd (__m256d __W, __mmask8 __U, __m256d __A,
-         __m256i __C)
+_mm256_mask_permutevar_pd(__m256d __W, __mmask8 __U, __m256d __A, __m256i __C)
 {
-  return (__m256d) __builtin_ia32_vpermilvarpd256_mask ((__v4df) __A,
-              (__v4di) __C,
-              (__v4df) __W,
-              (__mmask8)
-              __U);
+  return (__m256d)__builtin_ia32_selectpd_256((__mmask8)__U,
+                                         (__v4df)_mm256_permutevar_pd(__A, __C),
+                                         (__v4df)__W);
 }
 
 static __inline__ __m256d __DEFAULT_FN_ATTRS
-_mm256_maskz_permutevar_pd (__mmask8 __U, __m256d __A, __m256i __C)
+_mm256_maskz_permutevar_pd(__mmask8 __U, __m256d __A, __m256i __C)
 {
-  return (__m256d) __builtin_ia32_vpermilvarpd256_mask ((__v4df) __A,
-              (__v4di) __C,
-              (__v4df)
-              _mm256_setzero_pd (),
-              (__mmask8)
-              __U);
+  return (__m256d)__builtin_ia32_selectpd_256((__mmask8)__U,
+                                         (__v4df)_mm256_permutevar_pd(__A, __C),
+                                         (__v4df)_mm256_setzero_pd());
 }
 
 static __inline__ __m128 __DEFAULT_FN_ATTRS
-_mm_mask_permutevar_ps (__m128 __W, __mmask8 __U, __m128 __A,
-      __m128i __C)
+_mm_mask_permutevar_ps(__m128 __W, __mmask8 __U, __m128 __A, __m128i __C)
 {
-  return (__m128) __builtin_ia32_vpermilvarps_mask ((__v4sf) __A,
-                (__v4si) __C,
-                (__v4sf) __W,
-                (__mmask8) __U);
+  return (__m128)__builtin_ia32_selectps_128((__mmask8)__U,
+                                            (__v4sf)_mm_permutevar_ps(__A, __C),
+                                            (__v4sf)__W);
 }
 
 static __inline__ __m128 __DEFAULT_FN_ATTRS
-_mm_maskz_permutevar_ps (__mmask8 __U, __m128 __A, __m128i __C)
+_mm_maskz_permutevar_ps(__mmask8 __U, __m128 __A, __m128i __C)
 {
-  return (__m128) __builtin_ia32_vpermilvarps_mask ((__v4sf) __A,
-                (__v4si) __C,
-                (__v4sf)
-                _mm_setzero_ps (),
-                (__mmask8) __U);
+  return (__m128)__builtin_ia32_selectps_128((__mmask8)__U,
+                                            (__v4sf)_mm_permutevar_ps(__A, __C),
+                                            (__v4sf)_mm_setzero_ps());
 }
 
 static __inline__ __m256 __DEFAULT_FN_ATTRS
-_mm256_mask_permutevar_ps (__m256 __W, __mmask8 __U, __m256 __A,
-         __m256i __C)
+_mm256_mask_permutevar_ps(__m256 __W, __mmask8 __U, __m256 __A, __m256i __C)
 {
-  return (__m256) __builtin_ia32_vpermilvarps256_mask ((__v8sf) __A,
-                   (__v8si) __C,
-                   (__v8sf) __W,
-                   (__mmask8) __U);
+  return (__m256)__builtin_ia32_selectps_256((__mmask8)__U,
+                                          (__v8sf)_mm256_permutevar_ps(__A, __C),
+                                          (__v8sf)__W);
 }
 
 static __inline__ __m256 __DEFAULT_FN_ATTRS
-_mm256_maskz_permutevar_ps (__mmask8 __U, __m256 __A, __m256i __C)
+_mm256_maskz_permutevar_ps(__mmask8 __U, __m256 __A, __m256i __C)
 {
-  return (__m256) __builtin_ia32_vpermilvarps256_mask ((__v8sf) __A,
-                   (__v8si) __C,
-                   (__v8sf)
-                   _mm256_setzero_ps (),
-                   (__mmask8) __U);
+  return (__m256)__builtin_ia32_selectps_256((__mmask8)__U,
+                                          (__v8sf)_mm256_permutevar_ps(__A, __C),
+                                          (__v8sf)_mm256_setzero_ps());
 }
 
 static __inline__ __mmask8 __DEFAULT_FN_ATTRS
@@ -7207,52 +7189,49 @@
 }
 
 static __inline__ __m256 __DEFAULT_FN_ATTRS
-_mm256_broadcast_f32x4 (__m128 __A)
+_mm256_broadcast_f32x4(__m128 __A)
 {
-  return (__m256) __builtin_ia32_broadcastf32x4_256_mask ((__v4sf) __A,
-                (__v8sf)_mm256_undefined_pd (),
-                (__mmask8) -1);
+  return (__m256)__builtin_shufflevector((__v4sf)__A, (__v4sf)__A,
+                                         0, 1, 2, 3, 0, 1, 2, 3);
 }
 
 static __inline__ __m256 __DEFAULT_FN_ATTRS
-_mm256_mask_broadcast_f32x4 (__m256 __O, __mmask8 __M, __m128 __A)
+_mm256_mask_broadcast_f32x4(__m256 __O, __mmask8 __M, __m128 __A)
 {
-  return (__m256) __builtin_ia32_broadcastf32x4_256_mask ((__v4sf) __A,
-                (__v8sf) __O,
-                __M);
+  return (__m256)__builtin_ia32_selectps_256((__mmask8)__M,
+                                            (__v8sf)_mm256_broadcast_f32x4(__A),
+                                            (__v8sf)__O);
 }
 
 static __inline__ __m256 __DEFAULT_FN_ATTRS
 _mm256_maskz_broadcast_f32x4 (__mmask8 __M, __m128 __A)
 {
-  return (__m256) __builtin_ia32_broadcastf32x4_256_mask ((__v4sf) __A,
-                (__v8sf) _mm256_setzero_ps (),
-                __M);
+  return (__m256)__builtin_ia32_selectps_256((__mmask8)__M,
+                                            (__v8sf)_mm256_broadcast_f32x4(__A),
+                                            (__v8sf)_mm256_setzero_ps());
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS
-_mm256_broadcast_i32x4 (__m128i __A)
+_mm256_broadcast_i32x4(__m128i __A)
 {
-  return (__m256i) __builtin_ia32_broadcasti32x4_256_mask ((__v4si) __A,
-                 (__v8si)_mm256_undefined_si256 (),
-                 (__mmask8) -1);
+  return (__m256i)__builtin_shufflevector((__v4si)__A, (__v4si)__A,
+                                          0, 1, 2, 3, 0, 1, 2, 3);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS
-_mm256_mask_broadcast_i32x4 (__m256i __O, __mmask8 __M, __m128i __A)
+_mm256_mask_broadcast_i32x4(__m256i __O, __mmask8 __M, __m128i __A)
 {
-  return (__m256i) __builtin_ia32_broadcasti32x4_256_mask ((__v4si) __A,
-                 (__v8si)
-                 __O, __M);
+  return (__m256i)__builtin_ia32_selectd_256((__mmask8)__M,
+                                            (__v8si)_mm256_broadcast_i32x4(__A),
+                                            (__v8si)__O);
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS
-_mm256_maskz_broadcast_i32x4 (__mmask8 __M, __m128i __A)
+_mm256_maskz_broadcast_i32x4(__mmask8 __M, __m128i __A)
 {
-  return (__m256i) __builtin_ia32_broadcasti32x4_256_mask ((__v4si)
-                 __A,
-                 (__v8si) _mm256_setzero_si256 (),
-                 __M);
+  return (__m256i)__builtin_ia32_selectd_256((__mmask8)__M,
+                                            (__v8si)_mm256_broadcast_i32x4(__A),
+                                            (__v8si)_mm256_setzero_si256());
 }
 
 static __inline__ __m256d __DEFAULT_FN_ATTRS
diff --git a/lib/Headers/avxintrin.h b/lib/Headers/avxintrin.h
index fb5816a..eafb32d 100644
--- a/lib/Headers/avxintrin.h
+++ b/lib/Headers/avxintrin.h
@@ -57,7 +57,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDPD instruction.
+/// This intrinsic corresponds to the <c> VADDPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing one of the source operands.
@@ -75,7 +75,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDPS instruction.
+/// This intrinsic corresponds to the <c> VADDPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing one of the source operands.
@@ -93,7 +93,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSUBPD instruction.
+/// This intrinsic corresponds to the <c> VSUBPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing the minuend.
@@ -111,7 +111,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSUBPS instruction.
+/// This intrinsic corresponds to the <c> VSUBPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing the minuend.
@@ -130,7 +130,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDSUBPD instruction.
+/// This intrinsic corresponds to the <c> VADDSUBPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing the left source operand.
@@ -149,7 +149,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDSUBPS instruction.
+/// This intrinsic corresponds to the <c> VADDSUBPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing the left source operand.
@@ -167,7 +167,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VDIVPD instruction.
+/// This intrinsic corresponds to the <c> VDIVPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing the dividend.
@@ -185,7 +185,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VDIVPS instruction.
+/// This intrinsic corresponds to the <c> VDIVPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing the dividend.
@@ -204,7 +204,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMAXPD instruction.
+/// This intrinsic corresponds to the <c> VMAXPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing one of the operands.
@@ -223,7 +223,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMAXPS instruction.
+/// This intrinsic corresponds to the <c> VMAXPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing one of the operands.
@@ -242,7 +242,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMINPD instruction.
+/// This intrinsic corresponds to the <c> VMINPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing one of the operands.
@@ -261,7 +261,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMINPS instruction.
+/// This intrinsic corresponds to the <c> VMINPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing one of the operands.
@@ -279,7 +279,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMULPD instruction.
+/// This intrinsic corresponds to the <c> VMULPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing one of the operands.
@@ -297,7 +297,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMULPS instruction.
+/// This intrinsic corresponds to the <c> VMULPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing one of the operands.
@@ -316,7 +316,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSQRTPD instruction.
+/// This intrinsic corresponds to the <c> VSQRTPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double].
@@ -333,7 +333,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSQRTPS instruction.
+/// This intrinsic corresponds to the <c> VSQRTPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
@@ -350,7 +350,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VRSQRTPS instruction.
+/// This intrinsic corresponds to the <c> VRSQRTPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
@@ -367,7 +367,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VRCPPS instruction.
+/// This intrinsic corresponds to the <c> VRCPPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
@@ -389,7 +389,7 @@
 /// __m256d _mm256_round_pd(__m256d V, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VROUNDPD instruction.
+/// This intrinsic corresponds to the <c> VROUNDPD </c> instruction.
 ///
 /// \param V
 ///    A 256-bit vector of [4 x double].
@@ -397,16 +397,16 @@
 ///    An integer value that specifies the rounding operation. \n
 ///    Bits [7:4] are reserved. \n
 ///    Bit [3] is a precision exception value: \n
-///    0: A normal PE exception is used. \n
-///    1: The PE field is not updated. \n
+///      0: A normal PE exception is used. \n
+///      1: The PE field is not updated. \n
 ///    Bit [2] is the rounding control source: \n
-///    0: Use bits [1:0] of \a M. \n
-///    1: Use the current MXCSR setting. \n
+///      0: Use bits [1:0] of \a M. \n
+///      1: Use the current MXCSR setting. \n
 ///    Bits [1:0] contain the rounding control definition: \n
-///    00: Nearest. \n
-///    01: Downward (toward negative infinity). \n
-///    10: Upward (toward positive infinity). \n
-///    11: Truncated. 
+///      00: Nearest. \n
+///      01: Downward (toward negative infinity). \n
+///      10: Upward (toward positive infinity). \n
+///      11: Truncated.
 /// \returns A 256-bit vector of [4 x double] containing the rounded values.
 #define _mm256_round_pd(V, M) __extension__ ({ \
     (__m256d)__builtin_ia32_roundpd256((__v4df)(__m256d)(V), (M)); })
@@ -421,7 +421,7 @@
 /// __m256 _mm256_round_ps(__m256 V, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VROUNDPS instruction.
+/// This intrinsic corresponds to the <c> VROUNDPS </c> instruction.
 ///
 /// \param V
 ///    A 256-bit vector of [8 x float].
@@ -438,7 +438,7 @@
 ///      00: Nearest. \n
 ///      01: Downward (toward negative infinity). \n
 ///      10: Upward (toward positive infinity). \n
-///      11: Truncated. \n
+///      11: Truncated.
 /// \returns A 256-bit vector of [8 x float] containing the rounded values.
 #define _mm256_round_ps(V, M) __extension__ ({ \
   (__m256)__builtin_ia32_roundps256((__v8sf)(__m256)(V), (M)); })
@@ -453,7 +453,7 @@
 /// __m256d _mm256_ceil_pd(__m256d V);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VROUNDPD instruction.
+/// This intrinsic corresponds to the <c> VROUNDPD </c> instruction.
 ///
 /// \param V
 ///    A 256-bit vector of [4 x double].
@@ -470,7 +470,7 @@
 /// __m256d _mm256_floor_pd(__m256d V);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VROUNDPD instruction.
+/// This intrinsic corresponds to the <c> VROUNDPD </c> instruction.
 ///
 /// \param V
 ///    A 256-bit vector of [4 x double].
@@ -488,7 +488,7 @@
 /// __m256 _mm256_ceil_ps(__m256 V);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VROUNDPS instruction.
+/// This intrinsic corresponds to the <c> VROUNDPS </c> instruction.
 ///
 /// \param V
 ///    A 256-bit vector of [8 x float].
@@ -505,7 +505,7 @@
 /// __m256 _mm256_floor_ps(__m256 V);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VROUNDPS instruction.
+/// This intrinsic corresponds to the <c> VROUNDPS </c> instruction.
 ///
 /// \param V
 ///    A 256-bit vector of [8 x float].
@@ -517,7 +517,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VANDPD instruction.
+/// This intrinsic corresponds to the <c> VANDPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing one of the source operands.
@@ -535,7 +535,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VANDPS instruction.
+/// This intrinsic corresponds to the <c> VANDPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing one of the source operands.
@@ -554,7 +554,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VANDNPD instruction.
+/// This intrinsic corresponds to the <c> VANDNPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing the left source operand. The
@@ -575,7 +575,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VANDNPS instruction.
+/// This intrinsic corresponds to the <c> VANDNPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing the left source operand. The
@@ -595,7 +595,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VORPD instruction.
+/// This intrinsic corresponds to the <c> VORPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing one of the source operands.
@@ -613,7 +613,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VORPS instruction.
+/// This intrinsic corresponds to the <c> VORPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing one of the source operands.
@@ -631,7 +631,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VXORPD instruction.
+/// This intrinsic corresponds to the <c> VXORPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing one of the source operands.
@@ -649,7 +649,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VXORPS instruction.
+/// This intrinsic corresponds to the <c> VXORPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing one of the source operands.
@@ -669,7 +669,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VHADDPD instruction.
+/// This intrinsic corresponds to the <c> VHADDPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing one of the source operands.
@@ -692,7 +692,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VHADDPS instruction.
+/// This intrinsic corresponds to the <c> VHADDPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing one of the source operands.
@@ -715,7 +715,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VHSUBPD instruction.
+/// This intrinsic corresponds to the <c> VHSUBPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing one of the source operands.
@@ -738,7 +738,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VHSUBPS instruction.
+/// This intrinsic corresponds to the <c> VHSUBPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing one of the source operands.
@@ -762,23 +762,23 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPERMILPD instruction.
+/// This intrinsic corresponds to the <c> VPERMILPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
 /// \param __c
-///    \li A 128-bit integer vector operand specifying how the values are to be
-///    copied.
-///    \li Bit [1]:
-///    \li 0: Bits [63:0] of the source are copied to bits [63:0] of the
-///    returned vector.
-///    \li 1: Bits [127:64] of the source are copied to bits [63:0] of the
-///    returned vector.
-///    \li Bit [65]:
-///    \li 0: Bits [63:0] of the source are copied to bits [127:64] of the
-///    returned vector.
-///    \li 1: Bits [127:64] of the source are copied to bits [127:64] of the
-///    returned vector.
+///    A 128-bit integer vector operand specifying how the values are to be
+///    copied. \n
+///    Bit [1]: \n
+///      0: Bits [63:0] of the source are copied to bits [63:0] of the returned
+///         vector. \n
+///      1: Bits [127:64] of the source are copied to bits [63:0] of the
+///         returned vector. \n
+///    Bit [65]: \n
+///      0: Bits [63:0] of the source are copied to bits [127:64] of the
+///         returned vector. \n
+///      1: Bits [127:64] of the source are copied to bits [127:64] of the
+///         returned vector.
 /// \returns A 128-bit vector of [2 x double] containing the copied values.
 static __inline __m128d __DEFAULT_FN_ATTRS
 _mm_permutevar_pd(__m128d __a, __m128i __c)
@@ -786,12 +786,12 @@
   return (__m128d)__builtin_ia32_vpermilvarpd((__v2df)__a, (__v2di)__c);
 }
 
-/// \brief Copies the values in a 256-bit vector of [4 x double] as
-///    specified by the 256-bit integer vector operand.
+/// \brief Copies the values in a 256-bit vector of [4 x double] as specified
+///    by the 256-bit integer vector operand.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPERMILPD instruction.
+/// This intrinsic corresponds to the <c> VPERMILPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double].
@@ -799,24 +799,24 @@
 ///    A 256-bit integer vector operand specifying how the values are to be
 ///    copied. \n
 ///    Bit [1]: \n
-///    \li 0: Bits [63:0] of the source are copied to bits [63:0] of the
-///    returned vector.
-///    \li 1: Bits [127:64] of the source are copied to bits [63:0] of the
-///    returned vector.
+///      0: Bits [63:0] of the source are copied to bits [63:0] of the returned
+///         vector. \n
+///      1: Bits [127:64] of the source are copied to bits [63:0] of the
+///         returned vector. \n
 ///    Bit [65]: \n
-///    \li 0: Bits [63:0] of the source are copied to bits [127:64] of the
-///    returned vector.
-///    \li 1: Bits [127:64] of the source are copied to bits [127:64] of the
-///    returned vector.
-///    Bit [129]: \n 
-///    \li 0: Bits [191:128] of the source are copied to bits [191:128] of the
-///    returned vector.
-///    \li 1: Bits [255:192] of the source are copied to bits [191:128] of the
-///    returned vector.
-///    Bit [193]: \n 
-///    \li 0: Bits [191:128] of the source are copied to bits [255:192] of the
-///    returned vector.
-///    \li 1: Bits [255:192] of the source are copied to bits [255:192] of the
+///      0: Bits [63:0] of the source are copied to bits [127:64] of the
+///         returned vector. \n
+///      1: Bits [127:64] of the source are copied to bits [127:64] of the
+///         returned vector. \n
+///    Bit [129]: \n
+///      0: Bits [191:128] of the source are copied to bits [191:128] of the
+///         returned vector. \n
+///      1: Bits [255:192] of the source are copied to bits [191:128] of the
+///         returned vector. \n
+///    Bit [193]: \n
+///      0: Bits [191:128] of the source are copied to bits [255:192] of the
+///         returned vector. \n
+///      1: Bits [255:192] of the source are copied to bits [255:192] of the
 ///    returned vector.
 /// \returns A 256-bit vector of [4 x double] containing the copied values.
 static __inline __m256d __DEFAULT_FN_ATTRS
@@ -827,69 +827,51 @@
 
 /// \brief Copies the values stored in a 128-bit vector of [4 x float] as
 ///    specified by the 128-bit integer vector operand.
-///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPERMILPS instruction.
+/// This intrinsic corresponds to the <c> VPERMILPS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
 /// \param __c
-///    <ul>
-///    <li> A 128-bit integer vector operand specifying how the values are to be
-///         copied. 
-///    </li>
-///    <li> Bits [1:0]:
-///      <ul> 
-///      <li> 00: Bits [31:0] of the source are copied to bits [31:0] of the
-///           returned vector. </li>
-///      <li> 01: Bits [63:32] of the source are copied to bits [31:0] of the
-///           returned vector. </li>
-///      <li> 10: Bits [95:64] of the source are copied to bits [31:0] of the
-///           returned vector. </li>
-///      <li> 11: Bits [127:96] of the source are copied to bits [31:0] of the
-///           returned vector. </li>
-///      </ul>
-///    </li>
-///    <li> Bits [33:32]:
-///      <ul>
-///      <li> 00: Bits [31:0] of the source are copied to bits [63:32] of the
-///           returned vector. </li>
-///      <li> 01: Bits [63:32] of the source are copied to bits [63:32] of the
-///           returned vector. </li>
-///      <li> 10: Bits [95:64] of the source are copied to bits [63:32] of the
-///           returned vector. </li>
-///      <li> 11: Bits [127:96] of the source are copied to bits [63:32] of the
-///           returned vector. </li>
-///      </ul>
-///    </li> 
-///    <li> Bits [65:64]:
-///      <ul>
-///      <li> 00: Bits [31:0] of the source are copied to bits [95:64] of the
-///           returned vector. </li>
-///      <li> 01: Bits [63:32] of the source are copied to bits [95:64] of the
-///           returned vector. </li>
-///      <li> 10: Bits [95:64] of the source are copied to bits [95:64] of the
-///           returned vector. </li>
-///      <li> 11: Bits [127:96] of the source are copied to bits [95:64] of the
-///           returned vector. </li>
-///      </ul>
-///    </li>
-///    <li> Bits [97:96]:
-///      <ul>
-///      <li> 00: Bits [31:0] of the source are copied to bits [127:96] of the
-///           returned vector. </li>
-///      <li> 01: Bits [63:32] of the source are copied to bits [127:96] of the
-///           returned vector. </li>
-///      <li> 10: Bits [95:64] of the source are copied to bits [127:96] of the
-///           returned vector. </li>
-///      <li> 11: Bits [127:96] of the source are copied to bits [127:96] of the
-///           returned vector. </li>
-///      <li> 11: Bits [127:96] of the source are copied to bits [95:64] of the
-///           returned vector. </li>
-///      </ul>
-///    </li>
-///    </ul> 
+///    A 128-bit integer vector operand specifying how the values are to be
+///    copied. \n
+///    Bits [1:0]: \n
+///      00: Bits [31:0] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///    Bits [33:32]: \n
+///      00: Bits [31:0] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///    Bits [65:64]: \n
+///      00: Bits [31:0] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///    Bits [97:96]: \n
+///      00: Bits [31:0] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [127:96] of the
+///          returned vector.
 /// \returns A 128-bit vector of [4 x float] containing the copied values.
 static __inline __m128 __DEFAULT_FN_ATTRS
 _mm_permutevar_ps(__m128 __a, __m128i __c)
@@ -902,85 +884,85 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPERMILPS instruction.
+/// This intrinsic corresponds to the <c> VPERMILPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
 /// \param __c
 ///    A 256-bit integer vector operand specifying how the values are to be
-///    copied.
-///    Bits [1:0]:
-///    00: Bits [31:0] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    Bits [33:32]:
-///    00: Bits [31:0] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    Bits [65:64]:
-///    00: Bits [31:0] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    Bits [97:96]:
-///    00: Bits [31:0] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    Bits [129:128]:
-///    00: Bits [159:128] of the source are copied to bits [159:128] of the
-///    returned vector.
-///    01: Bits [191:160] of the source are copied to bits [159:128] of the
-///    returned vector.
-///    10: Bits [223:192] of the source are copied to bits [159:128] of the
-///    returned vector.
-///    11: Bits [255:224] of the source are copied to bits [159:128] of the
-///    returned vector.
-///    Bits [161:160]:
-///    00: Bits [159:128] of the source are copied to bits [191:160] of the
-///    returned vector.
-///    01: Bits [191:160] of the source are copied to bits [191:160] of the
-///    returned vector.
-///    10: Bits [223:192] of the source are copied to bits [191:160] of the
-///    returned vector.
-///    11: Bits [255:224] of the source are copied to bits [191:160] of the
-///    returned vector.
-///    Bits [193:192]:
-///    00: Bits [159:128] of the source are copied to bits [223:192] of the
-///    returned vector.
-///    01: Bits [191:160] of the source are copied to bits [223:192] of the
-///    returned vector.
-///    10: Bits [223:192] of the source are copied to bits [223:192] of the
-///    returned vector.
-///    11: Bits [255:224] of the source are copied to bits [223:192] of the
-///    returned vector.
-///    Bits [225:224]:
-///    00: Bits [159:128] of the source are copied to bits [255:224] of the
-///    returned vector.
-///    01: Bits [191:160] of the source are copied to bits [255:224] of the
-///    returned vector.
-///    10: Bits [223:192] of the source are copied to bits [255:224] of the
-///    returned vector.
-///    11: Bits [255:224] of the source are copied to bits [255:224] of the
-///    returned vector.
+///    copied. \n
+///    Bits [1:0]: \n
+///      00: Bits [31:0] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///    Bits [33:32]: \n
+///      00: Bits [31:0] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///    Bits [65:64]: \n
+///      00: Bits [31:0] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///    Bits [97:96]: \n
+///      00: Bits [31:0] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///    Bits [129:128]: \n
+///      00: Bits [159:128] of the source are copied to bits [159:128] of the
+///          returned vector. \n
+///      01: Bits [191:160] of the source are copied to bits [159:128] of the
+///          returned vector. \n
+///      10: Bits [223:192] of the source are copied to bits [159:128] of the
+///          returned vector. \n
+///      11: Bits [255:224] of the source are copied to bits [159:128] of the
+///          returned vector. \n
+///    Bits [161:160]: \n
+///      00: Bits [159:128] of the source are copied to bits [191:160] of the
+///          returned vector. \n
+///      01: Bits [191:160] of the source are copied to bits [191:160] of the
+///          returned vector. \n
+///      10: Bits [223:192] of the source are copied to bits [191:160] of the
+///          returned vector. \n
+///      11: Bits [255:224] of the source are copied to bits [191:160] of the
+///          returned vector. \n
+///    Bits [193:192]: \n
+///      00: Bits [159:128] of the source are copied to bits [223:192] of the
+///          returned vector. \n
+///      01: Bits [191:160] of the source are copied to bits [223:192] of the
+///          returned vector. \n
+///      10: Bits [223:192] of the source are copied to bits [223:192] of the
+///          returned vector. \n
+///      11: Bits [255:224] of the source are copied to bits [223:192] of the
+///          returned vector. \n
+///    Bits [225:224]: \n
+///      00: Bits [159:128] of the source are copied to bits [255:224] of the
+///          returned vector. \n
+///      01: Bits [191:160] of the source are copied to bits [255:224] of the
+///          returned vector. \n
+///      10: Bits [223:192] of the source are copied to bits [255:224] of the
+///          returned vector. \n
+///      11: Bits [255:224] of the source are copied to bits [255:224] of the
+///          returned vector.
 /// \returns A 256-bit vector of [8 x float] containing the copied values.
 static __inline __m256 __DEFAULT_FN_ATTRS
 _mm256_permutevar_ps(__m256 __a, __m256i __c)
@@ -988,8 +970,8 @@
   return (__m256)__builtin_ia32_vpermilvarps256((__v8sf)__a, (__v8si)__c);
 }
 
-/// \brief Copies the values in a 128-bit vector of [2 x double] as
-///    specified by the immediate integer operand.
+/// \brief Copies the values in a 128-bit vector of [2 x double] as specified
+///    by the immediate integer operand.
 ///
 /// \headerfile <x86intrin.h>
 ///
@@ -997,32 +979,31 @@
 /// __m128d _mm_permute_pd(__m128d A, const int C);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPERMILPD instruction.
+/// This intrinsic corresponds to the <c> VPERMILPD </c> instruction.
 ///
 /// \param A
 ///    A 128-bit vector of [2 x double].
 /// \param C
-/// \parblock
-///    An immediate integer operand specifying how the values are to be copied.
-///    Bit [0]:
-///    0: Bits [63:0] of the source are copied to bits [63:0] of the
-///    returned vector.
-///    1: Bits [127:64] of the source are copied to bits [63:0] of the
-///    returned vector.
-///    Bit [1]:
-///    0: Bits [63:0] of the source are copied to bits [127:64] of the
-///    returned vector.
-///    1: Bits [127:64] of the source are copied to bits [127:64] of the
-///    returned vector.
-/// \endparblock
+///    An immediate integer operand specifying how the values are to be
+///    copied. \n
+///    Bit [0]: \n
+///      0: Bits [63:0] of the source are copied to bits [63:0] of the returned
+///         vector. \n
+///      1: Bits [127:64] of the source are copied to bits [63:0] of the
+///         returned vector. \n
+///    Bit [1]: \n
+///      0: Bits [63:0] of the source are copied to bits [127:64] of the
+///         returned vector. \n
+///      1: Bits [127:64] of the source are copied to bits [127:64] of the
+///         returned vector.
 /// \returns A 128-bit vector of [2 x double] containing the copied values.
 #define _mm_permute_pd(A, C) __extension__ ({ \
   (__m128d)__builtin_shufflevector((__v2df)(__m128d)(A), \
                                    (__v2df)_mm_undefined_pd(), \
                                    ((C) >> 0) & 0x1, ((C) >> 1) & 0x1); })
 
-/// \brief Copies the values in a 256-bit vector of [4 x double] as
-///    specified by the immediate integer operand.
+/// \brief Copies the values in a 256-bit vector of [4 x double] as specified by
+///    the immediate integer operand.
 ///
 /// \headerfile <x86intrin.h>
 ///
@@ -1030,32 +1011,33 @@
 /// __m256d _mm256_permute_pd(__m256d A, const int C);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPERMILPD instruction.
+/// This intrinsic corresponds to the <c> VPERMILPD </c> instruction.
 ///
 /// \param A
 ///    A 256-bit vector of [4 x double].
 /// \param C
-///    An immediate integer operand specifying how the values are to be copied.
-///    Bit [0]:
-///    0: Bits [63:0] of the source are copied to bits [63:0] of the
-///    returned vector.
-///    1: Bits [127:64] of the source are copied to bits [63:0] of the
-///    returned vector.
-///    Bit [1]:
-///    0: Bits [63:0] of the source are copied to bits [127:64] of the
-///    returned vector.
-///    1: Bits [127:64] of the source are copied to bits [127:64] of the
-///    returned vector.
-///    Bit [2]:
-///    0: Bits [191:128] of the source are copied to bits [191:128] of the
-///    returned vector.
-///    1: Bits [255:192] of the source are copied to bits [191:128] of the
-///    returned vector.
-///    Bit [3]:
-///    0: Bits [191:128] of the source are copied to bits [255:192] of the
-///    returned vector.
-///    1: Bits [255:192] of the source are copied to bits [255:192] of the
-///    returned vector.
+///    An immediate integer operand specifying how the values are to be
+///    copied. \n
+///    Bit [0]: \n
+///      0: Bits [63:0] of the source are copied to bits [63:0] of the returned
+///         vector. \n
+///      1: Bits [127:64] of the source are copied to bits [63:0] of the
+///         returned vector. \n
+///    Bit [1]: \n
+///      0: Bits [63:0] of the source are copied to bits [127:64] of the
+///         returned vector. \n
+///      1: Bits [127:64] of the source are copied to bits [127:64] of the
+///         returned vector. \n
+///    Bit [2]: \n
+///      0: Bits [191:128] of the source are copied to bits [191:128] of the
+///         returned vector. \n
+///      1: Bits [255:192] of the source are copied to bits [191:128] of the
+///         returned vector. \n
+///    Bit [3]: \n
+///      0: Bits [191:128] of the source are copied to bits [255:192] of the
+///         returned vector. \n
+///      1: Bits [255:192] of the source are copied to bits [255:192] of the
+///         returned vector.
 /// \returns A 256-bit vector of [4 x double] containing the copied values.
 #define _mm256_permute_pd(A, C) __extension__ ({ \
   (__m256d)__builtin_shufflevector((__v4df)(__m256d)(A), \
@@ -1065,8 +1047,8 @@
                                    2 + (((C) >> 2) & 0x1), \
                                    2 + (((C) >> 3) & 0x1)); })
 
-/// \brief Copies the values in a 128-bit vector of [4 x float] as
-///    specified by the immediate integer operand.
+/// \brief Copies the values in a 128-bit vector of [4 x float] as specified by
+///    the immediate integer operand.
 ///
 /// \headerfile <x86intrin.h>
 ///
@@ -1074,48 +1056,49 @@
 /// __m128 _mm_permute_ps(__m128 A, const int C);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPERMILPS instruction.
+/// This intrinsic corresponds to the <c> VPERMILPS </c> instruction.
 ///
 /// \param A
 ///    A 128-bit vector of [4 x float].
 /// \param C
-///    An immediate integer operand specifying how the values are to be copied.
-///    Bits [1:0]:
-///    00: Bits [31:0] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    Bits [3:2]:
-///    00: Bits [31:0] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    Bits [5:4]:
-///    00: Bits [31:0] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    Bits [7:6]:
-///    00: Bits [31:0] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [127:96] of the
-///    returned vector.
+///    An immediate integer operand specifying how the values are to be
+///    copied. \n
+///    Bits [1:0]: \n
+///      00: Bits [31:0] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///    Bits [3:2]: \n
+///      00: Bits [31:0] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///    Bits [5:4]: \n
+///      00: Bits [31:0] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///    Bits [7:6]: \n
+///      00: Bits [31:0] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [127:96] of the
+///          returned vector.
 /// \returns A 128-bit vector of [4 x float] containing the copied values.
 #define _mm_permute_ps(A, C) __extension__ ({ \
   (__m128)__builtin_shufflevector((__v4sf)(__m128)(A), \
@@ -1123,8 +1106,8 @@
                                   ((C) >> 0) & 0x3, ((C) >> 2) & 0x3, \
                                   ((C) >> 4) & 0x3, ((C) >> 6) & 0x3); })
 
-/// \brief Copies the values in a 256-bit vector of [8 x float] as
-///    specified by the immediate integer operand.
+/// \brief Copies the values in a 256-bit vector of [8 x float] as specified by
+///    the immediate integer operand.
 ///
 /// \headerfile <x86intrin.h>
 ///
@@ -1132,84 +1115,85 @@
 /// __m256 _mm256_permute_ps(__m256 A, const int C);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPERMILPS instruction.
+/// This intrinsic corresponds to the <c> VPERMILPS </c> instruction.
 ///
 /// \param A
 ///    A 256-bit vector of [8 x float].
 /// \param C
-///    An immediate integer operand specifying how the values are to be copied.
-///    Bits [1:0]:
-///    00: Bits [31:0] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [31:0] of the
-///    returned vector.
-///    Bits [3:2]:
-///    00: Bits [31:0] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [63:32] of the
-///    returned vector.
-///    Bits [5:4]:
-///    00: Bits [31:0] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [95:64] of the
-///    returned vector.
-///    Bits [7:6]:
-///    00: Bits [31:0] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    01: Bits [63:32] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    10: Bits [95:64] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    11: Bits [127:96] of the source are copied to bits [127:96] of the
-///    returned vector.
-///    Bits [1:0]:
-///    00: Bits [159:128] of the source are copied to bits [159:128] of the
-///    returned vector.
-///    01: Bits [191:160] of the source are copied to bits [159:128] of the
-///    returned vector.
-///    10: Bits [223:192] of the source are copied to bits [159:128] of the
-///    returned vector.
-///    11: Bits [255:224] of the source are copied to bits [159:128] of the
-///    returned vector.
-///    Bits [3:2]:
-///    00: Bits [159:128] of the source are copied to bits [191:160] of the
-///    returned vector.
-///    01: Bits [191:160] of the source are copied to bits [191:160] of the
-///    returned vector.
-///    10: Bits [223:192] of the source are copied to bits [191:160] of the
-///    returned vector.
-///    11: Bits [255:224] of the source are copied to bits [191:160] of the
-///    returned vector.
-///    Bits [5:4]:
-///    00: Bits [159:128] of the source are copied to bits [223:192] of the
-///    returned vector.
-///    01: Bits [191:160] of the source are copied to bits [223:192] of the
-///    returned vector.
-///    10: Bits [223:192] of the source are copied to bits [223:192] of the
-///    returned vector.
-///    11: Bits [255:224] of the source are copied to bits [223:192] of the
-///    returned vector.
-///    Bits [7:6]:
-///    00: Bits [159:128] of the source are copied to bits [255:224] of the
-///    returned vector.
-///    01: Bits [191:160] of the source are copied to bits [255:224] of the
-///    returned vector.
-///    10: Bits [223:192] of the source are copied to bits [255:224] of the
-///    returned vector.
-///    11: Bits [255:224] of the source are copied to bits [255:224] of the
-///    returned vector.
+///    An immediate integer operand specifying how the values are to be \n
+///    copied. \n
+///    Bits [1:0]: \n
+///      00: Bits [31:0] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [31:0] of the
+///          returned vector. \n
+///    Bits [3:2]: \n
+///      00: Bits [31:0] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [63:32] of the
+///          returned vector. \n
+///    Bits [5:4]: \n
+///      00: Bits [31:0] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [95:64] of the
+///          returned vector. \n
+///    Bits [7:6]: \n
+///      00: Bits [31:qq0] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      01: Bits [63:32] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      10: Bits [95:64] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///      11: Bits [127:96] of the source are copied to bits [127:96] of the
+///          returned vector. \n
+///    Bits [1:0]: \n
+///      00: Bits [159:128] of the source are copied to bits [159:128] of the
+///          returned vector. \n
+///      01: Bits [191:160] of the source are copied to bits [159:128] of the
+///          returned vector. \n
+///      10: Bits [223:192] of the source are copied to bits [159:128] of the
+///          returned vector. \n
+///      11: Bits [255:224] of the source are copied to bits [159:128] of the
+///          returned vector. \n
+///    Bits [3:2]: \n
+///      00: Bits [159:128] of the source are copied to bits [191:160] of the
+///          returned vector. \n
+///      01: Bits [191:160] of the source are copied to bits [191:160] of the
+///          returned vector. \n
+///      10: Bits [223:192] of the source are copied to bits [191:160] of the
+///          returned vector. \n
+///      11: Bits [255:224] of the source are copied to bits [191:160] of the
+///          returned vector. \n
+///    Bits [5:4]: \n
+///      00: Bits [159:128] of the source are copied to bits [223:192] of the
+///          returned vector. \n
+///      01: Bits [191:160] of the source are copied to bits [223:192] of the
+///          returned vector. \n
+///      10: Bits [223:192] of the source are copied to bits [223:192] of the
+///          returned vector. \n
+///      11: Bits [255:224] of the source are copied to bits [223:192] of the
+///          returned vector. \n
+///    Bits [7:6]: \n
+///      00: Bits [159:128] of the source are copied to bits [255:224] of the
+///          returned vector. \n
+///      01: Bits [191:160] of the source are copied to bits [255:224] of the
+///          returned vector. \n
+///      10: Bits [223:192] of the source are copied to bits [255:224] of the
+///          returned vector. \n
+///      11: Bits [255:224] of the source are copied to bits [255:224] of the
+///          returned vector.
 /// \returns A 256-bit vector of [8 x float] containing the copied values.
 #define _mm256_permute_ps(A, C) __extension__ ({ \
   (__m256)__builtin_shufflevector((__v8sf)(__m256)(A), \
@@ -1232,7 +1216,7 @@
 /// __m256d _mm256_permute2f128_pd(__m256d V1, __m256d V2, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPERM2F128 instruction.
+/// This intrinsic corresponds to the <c> VPERM2F128 </c> instruction.
 ///
 /// \param V1
 ///    A 256-bit vector of [4 x double].
@@ -1240,25 +1224,25 @@
 ///    A 256-bit vector of [4 x double.
 /// \param M
 ///    An immediate integer operand specifying how the values are to be
-///    permuted.
-///    Bits [1:0]:
-///    00: Bits [127:0] of operand \a V1 are copied to bits [127:0] of the
-///    destination.
-///    01: Bits [255:128] of operand \a V1 are copied to bits [127:0] of the
-///    destination.
-///    10: Bits [127:0] of operand \a V2 are copied to bits [127:0] of the
-///    destination.
-///    11: Bits [255:128] of operand \a V2 are copied to bits [127:0] of the
-///    destination.
-///    Bits [5:4]:
-///    00: Bits [127:0] of operand \a V1 are copied to bits [255:128] of the
-///    destination.                                 
-///    01: Bits [255:128] of operand \a V1 are copied to bits [255:128] of the
-///    destination.
-///    10: Bits [127:0] of operand \a V2 are copied to bits [255:128] of the
-///    destination.
-///    11: Bits [255:128] of operand \a V2 are copied to bits [255:128] of the
-///    destination.
+///    permuted. \n
+///    Bits [1:0]: \n
+///      00: Bits [127:0] of operand \a V1 are copied to bits [127:0] of the
+///          destination. \n
+///      01: Bits [255:128] of operand \a V1 are copied to bits [127:0] of the
+///          destination. \n
+///      10: Bits [127:0] of operand \a V2 are copied to bits [127:0] of the
+///          destination. \n
+///      11: Bits [255:128] of operand \a V2 are copied to bits [127:0] of the
+///          destination. \n
+///    Bits [5:4]: \n
+///      00: Bits [127:0] of operand \a V1 are copied to bits [255:128] of the
+///          destination. \n
+///      01: Bits [255:128] of operand \a V1 are copied to bits [255:128] of the
+///          destination. \n
+///      10: Bits [127:0] of operand \a V2 are copied to bits [255:128] of the
+///          destination. \n
+///      11: Bits [255:128] of operand \a V2 are copied to bits [255:128] of the
+///          destination.
 /// \returns A 256-bit vector of [4 x double] containing the copied values.
 #define _mm256_permute2f128_pd(V1, V2, M) __extension__ ({ \
   (__m256d)__builtin_ia32_vperm2f128_pd256((__v4df)(__m256d)(V1), \
@@ -1273,7 +1257,7 @@
 /// __m256 _mm256_permute2f128_ps(__m256 V1, __m256 V2, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPERM2F128 instruction.
+/// This intrinsic corresponds to the <c> VPERM2F128 </c> instruction.
 ///
 /// \param V1
 ///    A 256-bit vector of [8 x float].
@@ -1281,23 +1265,23 @@
 ///    A 256-bit vector of [8 x float].
 /// \param M
 ///    An immediate integer operand specifying how the values are to be
-///    permuted.
-///    Bits [1:0]:
+///    permuted. \n
+///    Bits [1:0]: \n
 ///    00: Bits [127:0] of operand \a V1 are copied to bits [127:0] of the
-///    destination.
+///    destination. \n
 ///    01: Bits [255:128] of operand \a V1 are copied to bits [127:0] of the
-///    destination.
+///    destination. \n
 ///    10: Bits [127:0] of operand \a V2 are copied to bits [127:0] of the
-///    destination.
+///    destination. \n
 ///    11: Bits [255:128] of operand \a V2 are copied to bits [127:0] of the
-///    destination.
-///    Bits [5:4]:
+///    destination. \n
+///    Bits [5:4]: \n
 ///    00: Bits [127:0] of operand \a V1 are copied to bits [255:128] of the
-///    destination.
+///    destination. \n
 ///    01: Bits [255:128] of operand \a V1 are copied to bits [255:128] of the
-///    destination.
+///    destination. \n
 ///    10: Bits [127:0] of operand \a V2 are copied to bits [255:128] of the
-///    destination.
+///    destination. \n
 ///    11: Bits [255:128] of operand \a V2 are copied to bits [255:128] of the
 ///    destination.
 /// \returns A 256-bit vector of [8 x float] containing the copied values.
@@ -1314,7 +1298,7 @@
 /// __m256i _mm256_permute2f128_si256(__m256i V1, __m256i V2, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPERM2F128 instruction.
+/// This intrinsic corresponds to the <c> VPERM2F128 </c> instruction.
 ///
 /// \param V1
 ///    A 256-bit integer vector.
@@ -1322,22 +1306,22 @@
 ///    A 256-bit integer vector.
 /// \param M
 ///    An immediate integer operand specifying how the values are to be copied.
-///    Bits [1:0]:
+///    Bits [1:0]: \n
 ///    00: Bits [127:0] of operand \a V1 are copied to bits [127:0] of the
-///    destination.
+///    destination. \n
 ///    01: Bits [255:128] of operand \a V1 are copied to bits [127:0] of the
-///    destination.
+///    destination. \n
 ///    10: Bits [127:0] of operand \a V2 are copied to bits [127:0] of the
-///    destination.
+///    destination. \n
 ///    11: Bits [255:128] of operand \a V2 are copied to bits [127:0] of the
-///    destination.
-///    Bits [5:4]:
+///    destination. \n
+///    Bits [5:4]: \n
 ///    00: Bits [127:0] of operand \a V1 are copied to bits [255:128] of the
-///    destination.
+///    destination. \n
 ///    01: Bits [255:128] of operand \a V1 are copied to bits [255:128] of the
-///    destination.
+///    destination. \n
 ///    10: Bits [127:0] of operand \a V2 are copied to bits [255:128] of the
-///    destination.
+///    destination. \n
 ///    11: Bits [255:128] of operand \a V2 are copied to bits [255:128] of the
 ///    destination.
 /// \returns A 256-bit integer vector containing the copied values.
@@ -1356,7 +1340,7 @@
 /// __m256d _mm256_blend_pd(__m256d V1, __m256d V2, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VBLENDPD instruction.
+/// This intrinsic corresponds to the <c> VBLENDPD </c> instruction.
 ///
 /// \param V1
 ///    A 256-bit vector of [4 x double].
@@ -1388,7 +1372,7 @@
 /// __m256 _mm256_blend_ps(__m256 V1, __m256 V2, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VBLENDPS instruction.
+/// This intrinsic corresponds to the <c> VBLENDPS </c> instruction.
 ///
 /// \param V1
 ///    A 256-bit vector of [8 x float].
@@ -1420,7 +1404,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VBLENDVPD instruction.
+/// This intrinsic corresponds to the <c> VBLENDVPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double].
@@ -1448,7 +1432,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VBLENDVPS instruction.
+/// This intrinsic corresponds to the <c> VBLENDVPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
@@ -1474,12 +1458,12 @@
 /// \brief Computes two dot products in parallel, using the lower and upper
 ///    halves of two [8 x float] vectors as input to the two computations, and
 ///    returning the two dot products in the lower and upper halves of the
-///    [8 x float] result. The immediate integer operand controls which
-///    input elements will contribute to the dot product, and where the final
-///    results are returned. In general, for each dot product, the four
-///    corresponding elements of the input vectors are multiplied; the first
-///    two and second two products are summed, then the two sums are added to
-///    form the final result.
+///    [8 x float] result. The immediate integer operand controls which input
+///    elements will contribute to the dot product, and where the final results
+///    are returned. In general, for each dot product, the four corresponding
+///    elements of the input vectors are multiplied; the first two and second
+///    two products are summed, then the two sums are added to form the final
+///    result.
 ///
 /// \headerfile <x86intrin.h>
 ///
@@ -1487,7 +1471,7 @@
 /// __m256 _mm256_dp_ps(__m256 V1, __m256 V2, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VDPPS instruction.
+/// This intrinsic corresponds to the <c> VDPPS </c> instruction.
 ///
 /// \param V1
 ///    A vector of [8 x float] values, treated as two [4 x float] vectors.
@@ -1529,7 +1513,7 @@
 /// __m256 _mm256_shuffle_ps(__m256 a, __m256 b, const int mask);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VSHUFPS instruction.
+/// This intrinsic corresponds to the <c> VSHUFPS </c> instruction.
 ///
 /// \param a
 ///    A 256-bit vector of [8 x float]. The four selected elements in this
@@ -1541,23 +1525,23 @@
 ///    destination, according to the bits specified in the immediate operand.
 /// \param mask
 ///    An immediate value containing an 8-bit value specifying which elements to
-///    copy from \a a and \a b. 
-///    Bits [3:0] specify the values copied from operand a.
-///    Bits [7:4] specify the values copied from operand b.
+///    copy from \a a and \a b \n.
+///    Bits [3:0] specify the values copied from operand \a a. \n
+///    Bits [7:4] specify the values copied from operand \a b. \n
 ///    The destinations within the 256-bit destination are assigned values as
-///    follows, according to the bit value assignments described below:
+///    follows, according to the bit value assignments described below: \n
 ///    Bits [1:0] are used to assign values to bits [31:0] and [159:128] in the
-///    destination.
+///    destination. \n
 ///    Bits [3:2] are used to assign values to bits [63:32] and [191:160] in the
-///    destination.
+///    destination. \n
 ///    Bits [5:4] are used to assign values to bits [95:64] and [223:192] in the
-///    destination.
+///    destination. \n
 ///    Bits [7:6] are used to assign values to bits [127:96] and [255:224] in
-///    the destination.
-///    Bit value assignments:
-///    00: Bits [31:0] and [159:128] are copied from the selected operand.
-///    01: Bits [63:32] and [191:160] are copied from the selected operand.
-///    10: Bits [95:64] and [223:192] are copied from the selected operand.
+///    the destination. \n
+///    Bit value assignments: \n
+///    00: Bits [31:0] and [159:128] are copied from the selected operand. \n
+///    01: Bits [63:32] and [191:160] are copied from the selected operand. \n
+///    10: Bits [95:64] and [223:192] are copied from the selected operand. \n
 ///    11: Bits [127:96] and [255:224] are copied from the selected operand.
 /// \returns A 256-bit vector of [8 x float] containing the shuffled values.
 #define _mm256_shuffle_ps(a, b, mask) __extension__ ({ \
@@ -1587,7 +1571,7 @@
 /// __m256d _mm256_shuffle_pd(__m256d a, __m256d b, const int mask);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VSHUFPD instruction.
+/// This intrinsic corresponds to the <c> VSHUFPD </c> instruction.
 ///
 /// \param a
 ///    A 256-bit vector of [4 x double].
@@ -1595,21 +1579,21 @@
 ///    A 256-bit vector of [4 x double].
 /// \param mask
 ///    An immediate value containing 8-bit values specifying which elements to
-///    copy from \a a and \a b:
+///    copy from \a a and \a b: \n
 ///    Bit [0]=0: Bits [63:0] are copied from \a a to bits [63:0] of the
-///    destination.
+///    destination. \n
 ///    Bit [0]=1: Bits [127:64] are copied from \a a to bits [63:0] of the
-///    destination.
+///    destination. \n
 ///    Bit [1]=0: Bits [63:0] are copied from \a b to bits [127:64] of the
-///    destination.
+///    destination. \n
 ///    Bit [1]=1: Bits [127:64] are copied from \a b to bits [127:64] of the
-///    destination.
+///    destination. \n
 ///    Bit [2]=0: Bits [191:128] are copied from \a a to bits [191:128] of the
-///    destination.
+///    destination. \n
 ///    Bit [2]=1: Bits [255:192] are copied from \a a to bits [191:128] of the
-///    destination.
+///    destination. \n
 ///    Bit [3]=0: Bits [191:128] are copied from \a b to bits [255:192] of the
-///    destination.
+///    destination. \n
 ///    Bit [3]=1: Bits [255:192] are copied from \a b to bits [255:192] of the
 ///    destination.
 /// \returns A 256-bit vector of [4 x double] containing the shuffled values.
@@ -1667,35 +1651,26 @@
 /// __m128d _mm_cmp_pd(__m128d a, __m128d b, const int c);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VCMPPD instruction.
+/// This intrinsic corresponds to the <c> VCMPPD </c> instruction.
 ///
 /// \param a
 ///    A 128-bit vector of [2 x double].
 /// \param b
 ///    A 128-bit vector of [2 x double].
 /// \param c
-/// \parblock
 ///    An immediate integer operand, with bits [4:0] specifying which comparison
-///    operation to use:
-///
-///    00h, 08h, 10h, 18h: Equal
-///
-///    01h, 09h, 11h, 19h: Less than
-///
-///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal (swapped
-///                        operands)
-///
-///    03h, 0Bh, 13h, 1Bh: Unordered
-///
-///    04h, 0Ch, 14h, 1Ch: Not equal
-///
-///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than (swapped operands)
-///
+///    operation to use: \n
+///    00h, 08h, 10h, 18h: Equal \n
+///    01h, 09h, 11h, 19h: Less than \n
+///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal
+///                        (swapped operands) \n
+///    03h, 0Bh, 13h, 1Bh: Unordered \n
+///    04h, 0Ch, 14h, 1Ch: Not equal \n
+///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than
+///                        (swapped operands) \n
 ///    06h, 0Eh, 16h, 1Eh: Not less than or equal / Not greater than or equal
-///                        (swapped operands)
-///
+///                        (swapped operands) \n
 ///    07h, 0Fh, 17h, 1Fh: Ordered
-/// \endparblock
 /// \returns A 128-bit vector of [2 x double] containing the comparison results.
 #define _mm_cmp_pd(a, b, c) __extension__ ({ \
   (__m128d)__builtin_ia32_cmppd((__v2df)(__m128d)(a), \
@@ -1713,7 +1688,7 @@
 /// __m128 _mm_cmp_ps(__m128 a, __m128 b, const int c);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VCMPPS instruction.
+/// This intrinsic corresponds to the <c> VCMPPS </c> instruction.
 ///
 /// \param a
 ///    A 128-bit vector of [4 x float].
@@ -1721,16 +1696,17 @@
 ///    A 128-bit vector of [4 x float].
 /// \param c
 ///    An immediate integer operand, with bits [4:0] specifying which comparison
-///    operation to use:
-///    00h, 08h, 10h, 18h: Equal
-///    01h, 09h, 11h, 19h: Less than
-///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal (swapped
-///                        operands)
-///    03h, 0Bh, 13h, 1Bh: Unordered
-///    04h, 0Ch, 14h, 1Ch: Not equal
-///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than (swapped operands)
+///    operation to use: \n
+///    00h, 08h, 10h, 18h: Equal \n
+///    01h, 09h, 11h, 19h: Less than \n
+///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal
+///                        (swapped operands) \n
+///    03h, 0Bh, 13h, 1Bh: Unordered \n
+///    04h, 0Ch, 14h, 1Ch: Not equal \n
+///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than
+///                        (swapped operands) \n
 ///    06h, 0Eh, 16h, 1Eh: Not less than or equal / Not greater than or equal
-///                       (swapped operands)
+///                        (swapped operands) \n
 ///    07h, 0Fh, 17h, 1Fh: Ordered
 /// \returns A 128-bit vector of [4 x float] containing the comparison results.
 #define _mm_cmp_ps(a, b, c) __extension__ ({ \
@@ -1749,7 +1725,7 @@
 /// __m256d _mm256_cmp_pd(__m256d a, __m256d b, const int c);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VCMPPD instruction.
+/// This intrinsic corresponds to the <c> VCMPPD </c> instruction.
 ///
 /// \param a
 ///    A 256-bit vector of [4 x double].
@@ -1757,16 +1733,17 @@
 ///    A 256-bit vector of [4 x double].
 /// \param c
 ///    An immediate integer operand, with bits [4:0] specifying which comparison
-///    operation to use:
-///    00h, 08h, 10h, 18h: Equal
-///    01h, 09h, 11h, 19h: Less than
-///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal (swapped
-///                        operands)
-///    03h, 0Bh, 13h, 1Bh: Unordered
-///    04h, 0Ch, 14h, 1Ch: Not equal
-///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than (swapped operands)
+///    operation to use: \n
+///    00h, 08h, 10h, 18h: Equal \n
+///    01h, 09h, 11h, 19h: Less than \n
+///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal
+///                        (swapped operands) \n
+///    03h, 0Bh, 13h, 1Bh: Unordered \n
+///    04h, 0Ch, 14h, 1Ch: Not equal \n
+///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than
+///                        (swapped operands) \n
 ///    06h, 0Eh, 16h, 1Eh: Not less than or equal / Not greater than or equal
-///                        (swapped operands)
+///                        (swapped operands) \n
 ///    07h, 0Fh, 17h, 1Fh: Ordered
 /// \returns A 256-bit vector of [4 x double] containing the comparison results.
 #define _mm256_cmp_pd(a, b, c) __extension__ ({ \
@@ -1785,7 +1762,7 @@
 /// __m256 _mm256_cmp_ps(__m256 a, __m256 b, const int c);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VCMPPS instruction.
+/// This intrinsic corresponds to the <c> VCMPPS </c> instruction.
 ///
 /// \param a
 ///    A 256-bit vector of [8 x float].
@@ -1793,16 +1770,17 @@
 ///    A 256-bit vector of [8 x float].
 /// \param c
 ///    An immediate integer operand, with bits [4:0] specifying which comparison
-///    operation to use:
-///    00h, 08h, 10h, 18h: Equal
-///    01h, 09h, 11h, 19h: Less than
-///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal (swapped
-///                        operands)
-///    03h, 0Bh, 13h, 1Bh: Unordered
-///    04h, 0Ch, 14h, 1Ch: Not equal
-///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than (swapped operands)
+///    operation to use: \n
+///    00h, 08h, 10h, 18h: Equal \n
+///    01h, 09h, 11h, 19h: Less than \n
+///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal
+///                        (swapped operands) \n
+///    03h, 0Bh, 13h, 1Bh: Unordered \n
+///    04h, 0Ch, 14h, 1Ch: Not equal \n
+///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than
+///                        (swapped operands) \n
 ///    06h, 0Eh, 16h, 1Eh: Not less than or equal / Not greater than or equal
-///                       (swapped operands)
+///                        (swapped operands) \n
 ///    07h, 0Fh, 17h, 1Fh: Ordered
 /// \returns A 256-bit vector of [8 x float] containing the comparison results.
 #define _mm256_cmp_ps(a, b, c) __extension__ ({ \
@@ -1820,7 +1798,7 @@
 /// __m128d _mm_cmp_sd(__m128d a, __m128d b, const int c);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VCMPSD instruction.
+/// This intrinsic corresponds to the <c> VCMPSD </c> instruction.
 ///
 /// \param a
 ///    A 128-bit vector of [2 x double].
@@ -1828,16 +1806,17 @@
 ///    A 128-bit vector of [2 x double].
 /// \param c
 ///    An immediate integer operand, with bits [4:0] specifying which comparison
-///    operation to use:
-///    00h, 08h, 10h, 18h: Equal
-///    01h, 09h, 11h, 19h: Less than
-///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal (swapped
-///                        operands)
-///    03h, 0Bh, 13h, 1Bh: Unordered
-///    04h, 0Ch, 14h, 1Ch: Not equal
-///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than (swapped operands)
+///    operation to use: \n
+///    00h, 08h, 10h, 18h: Equal \n
+///    01h, 09h, 11h, 19h: Less than \n
+///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal
+///                        (swapped operands) \n
+///    03h, 0Bh, 13h, 1Bh: Unordered \n
+///    04h, 0Ch, 14h, 1Ch: Not equal \n
+///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than
+///                        (swapped operands) \n
 ///    06h, 0Eh, 16h, 1Eh: Not less than or equal / Not greater than or equal
-///                       (swapped operands)
+///                        (swapped operands) \n
 ///    07h, 0Fh, 17h, 1Fh: Ordered
 /// \returns A 128-bit vector of [2 x double] containing the comparison results.
 #define _mm_cmp_sd(a, b, c) __extension__ ({ \
@@ -1855,7 +1834,7 @@
 /// __m128 _mm_cmp_ss(__m128 a, __m128 b, const int c);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VCMPSS instruction.
+/// This intrinsic corresponds to the <c> VCMPSS </c> instruction.
 ///
 /// \param a
 ///    A 128-bit vector of [4 x float].
@@ -1863,16 +1842,17 @@
 ///    A 128-bit vector of [4 x float].
 /// \param c
 ///    An immediate integer operand, with bits [4:0] specifying which comparison
-///    operation to use:
-///    00h, 08h, 10h, 18h: Equal
-///    01h, 09h, 11h, 19h: Less than
-///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal (swapped
-///                        operands)
-///    03h, 0Bh, 13h, 1Bh: Unordered
-///    04h, 0Ch, 14h, 1Ch: Not equal
-///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than (swapped operands)
+///    operation to use: \n
+///    00h, 08h, 10h, 18h: Equal \n
+///    01h, 09h, 11h, 19h: Less than \n
+///    02h, 0Ah, 12h, 1Ah: Less than or equal / Greater than or equal
+///                        (swapped operands) \n
+///    03h, 0Bh, 13h, 1Bh: Unordered \n
+///    04h, 0Ch, 14h, 1Ch: Not equal \n
+///    05h, 0Dh, 15h, 1Dh: Not less than / Not greater than
+///                        (swapped operands) \n
 ///    06h, 0Eh, 16h, 1Eh: Not less than or equal / Not greater than or equal
-///                       (swapped operands)
+///                        (swapped operands) \n
 ///    07h, 0Fh, 17h, 1Fh: Ordered
 /// \returns A 128-bit vector of [4 x float] containing the comparison results.
 #define _mm_cmp_ss(a, b, c) __extension__ ({ \
@@ -1884,7 +1864,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128+COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> VEXTRACTF128+COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x i32].
@@ -1905,7 +1886,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128+COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> VEXTRACTF128+COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 256-bit integer vector of [16 x i16].
@@ -1926,7 +1908,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128+COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> VEXTRACTF128+COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 256-bit integer vector of [32 x i8].
@@ -1948,7 +1931,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128+COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> VEXTRACTF128+COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 256-bit integer vector of [4 x i64].
@@ -1971,7 +1955,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128+COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128+COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A vector of [8 x i32] to be used by the insert operation.
@@ -1997,7 +1982,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128+COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128+COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A vector of [16 x i16] to be used by the insert operation.
@@ -2022,7 +2008,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128+COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128+COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A vector of [32 x i8] to be used by the insert operation.
@@ -2048,7 +2035,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128+COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128+COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A vector of [4 x i64] to be used by the insert operation.
@@ -2073,7 +2061,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTDQ2PD instruction.
+/// This intrinsic corresponds to the <c> VCVTDQ2PD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector of [4 x i32].
@@ -2088,7 +2076,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTDQ2PS instruction.
+/// This intrinsic corresponds to the <c> VCVTDQ2PS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit integer vector.
@@ -2104,7 +2092,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPD2PS instruction.
+/// This intrinsic corresponds to the <c> VCVTPD2PS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double].
@@ -2119,7 +2107,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPS2DQ instruction.
+/// This intrinsic corresponds to the <c> VCVTPS2DQ </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
@@ -2135,7 +2123,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPS2PD instruction.
+/// This intrinsic corresponds to the <c> VCVTPS2PD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -2152,7 +2140,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTTPD2DQ instruction.
+/// This intrinsic corresponds to the <c> VCVTTPD2DQ </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double].
@@ -2169,7 +2157,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPD2DQ instruction.
+/// This intrinsic corresponds to the <c> VCVTPD2DQ </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double].
@@ -2185,7 +2173,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTTPS2DQ instruction.
+/// This intrinsic corresponds to the <c> VCVTTPS2DQ </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
@@ -2196,12 +2184,32 @@
   return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf) __a);
 }
 
+/// \brief Returns the first element of the input vector of [4 x double].
+///
+/// \headerfile <avxintrin.h>
+///
+/// This intrinsic is a utility function and does not correspond to a specific
+///    instruction.
+///
+/// \param __a
+///    A 256-bit vector of [4 x double].
+/// \returns A 64 bit double containing the first element of the input vector.
 static __inline double __DEFAULT_FN_ATTRS
 _mm256_cvtsd_f64(__m256d __a)
 {
  return __a[0];
 }
 
+/// \brief Returns the first element of the input vector of [8 x i32].
+///
+/// \headerfile <avxintrin.h>
+///
+/// This intrinsic is a utility function and does not correspond to a specific
+///    instruction.
+///
+/// \param __a
+///    A 256-bit vector of [8 x i32].
+/// \returns A 32 bit integer containing the first element of the input vector.
 static __inline int __DEFAULT_FN_ATTRS
 _mm256_cvtsi256_si32(__m256i __a)
 {
@@ -2209,6 +2217,16 @@
  return __b[0];
 }
 
+/// \brief Returns the first element of the input vector of [8 x float].
+///
+/// \headerfile <avxintrin.h>
+///
+/// This intrinsic is a utility function and does not correspond to a specific
+///    instruction.
+///
+/// \param __a
+///    A 256-bit vector of [8 x float].
+/// \returns A 32 bit float containing the first element of the input vector.
 static __inline float __DEFAULT_FN_ATTRS
 _mm256_cvtss_f32(__m256 __a)
 {
@@ -2217,22 +2235,23 @@
 
 /* Vector replicate */
 /// \brief Moves and duplicates high-order (odd-indexed) values from a 256-bit
-///    vector of [8 x float] to float values in a 256-bit vector of [8 x float].
-///    Bits [255:224] of \a __a are written to bits [255:224] and [223:192]
-///    of the return value.
-///    Bits [191:160] of \a __a are written to bits [191:160] and [159:128]
-///    of the return value.
-///    Bits [127:96] of \a __a are written to bits [127:96] and [95:64] of
-///    the return value.
-///    Bits [63:32] of \a __a are written to bits [63:32] and [31:0] of the
-///    return value.
+///    vector of [8 x float] to float values in a 256-bit vector of
+///    [8 x float].
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSHDUP instruction.
+/// This intrinsic corresponds to the <c> VMOVSHDUP </c> instruction.
 ///
 /// \param __a
-///    A 256-bit vector of [8 x float].
+///    A 256-bit vector of [8 x float]. \n
+///    Bits [255:224] of \a __a are written to bits [255:224] and [223:192] of
+///    the return value. \n
+///    Bits [191:160] of \a __a are written to bits [191:160] and [159:128] of
+///    the return value. \n
+///    Bits [127:96] of \a __a are written to bits [127:96] and [95:64] of the
+///    return value. \n
+///    Bits [63:32] of \a __a are written to bits [63:32] and [31:0] of the
+///    return value.
 /// \returns A 256-bit vector of [8 x float] containing the moved and duplicated
 ///    values.
 static __inline __m256 __DEFAULT_FN_ATTRS
@@ -2243,21 +2262,21 @@
 
 /// \brief Moves and duplicates low-order (even-indexed) values from a 256-bit
 ///    vector of [8 x float] to float values in a 256-bit vector of [8 x float].
-///    Bits [223:192] of \a __a are written to bits [255:224] and [223:192]
-///    of the return value.
-///    Bits [159:128] of \a __a are written to bits [191:160] and [159:128]
-///    of the return value.
-///    Bits [95:64] of \a __a are written to bits [127:96] and [95:64] of
-///    the return value.
-///    Bits [31:0] of \a __a are written to bits [63:32] and [31:0] of the
-///    return value.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSLDUP instruction.
+/// This intrinsic corresponds to the <c> VMOVSLDUP </c> instruction.
 ///
 /// \param __a
-///    A 256-bit vector of [8 x float].
+///    A 256-bit vector of [8 x float]. \n
+///    Bits [223:192] of \a __a are written to bits [255:224] and [223:192] of
+///    the return value. \n
+///    Bits [159:128] of \a __a are written to bits [191:160] and [159:128] of
+///    the return value. \n
+///    Bits [95:64] of \a __a are written to bits [127:96] and [95:64] of the
+///    return value. \n
+///    Bits [31:0] of \a __a are written to bits [63:32] and [31:0] of the
+///    return value.
 /// \returns A 256-bit vector of [8 x float] containing the moved and duplicated
 ///    values.
 static __inline __m256 __DEFAULT_FN_ATTRS
@@ -2269,17 +2288,17 @@
 /// \brief Moves and duplicates double-precision floating point values from a
 ///    256-bit vector of [4 x double] to double-precision values in a 256-bit
 ///    vector of [4 x double].
-///    Bits [63:0] of \a __a are written to bits [127:64] and [63:0] of the
-///    return value.
-///    Bits [191:128] of \a __a are written to bits [255:192] and [191:128]
-///    of the return value.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDDUP instruction.
+/// This intrinsic corresponds to the <c> VMOVDDUP </c> instruction.
 ///
 /// \param __a
-///    A 256-bit vector of [4 x double].
+///    A 256-bit vector of [4 x double]. \n
+///    Bits [63:0] of \a __a are written to bits [127:64] and [63:0] of the
+///    return value. \n
+///    Bits [191:128] of \a __a are written to bits [255:192] and [191:128] of
+///    the return value.
 /// \returns A 256-bit vector of [4 x double] containing the moved and
 ///    duplicated values.
 static __inline __m256d __DEFAULT_FN_ATTRS
@@ -2294,16 +2313,16 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKHPD instruction.
+/// This intrinsic corresponds to the <c> VUNPCKHPD </c> instruction.
 ///
 /// \param __a
-///    A 256-bit floating-point vector of [4 x double].
-///    Bits [127:64] are written to bits [63:0] of the return value.
-///    Bits [255:192] are written to bits [191:128] of the return value.
+///    A 256-bit floating-point vector of [4 x double]. \n
+///    Bits [127:64] are written to bits [63:0] of the return value. \n
+///    Bits [255:192] are written to bits [191:128] of the return value. \n
 /// \param __b
-///    A 256-bit floating-point vector of [4 x double].
-///    Bits [127:64] are written to bits [127:64] of the return value.
-///    Bits [255:192] are written to bits [255:192] of the return value.
+///    A 256-bit floating-point vector of [4 x double]. \n
+///    Bits [127:64] are written to bits [127:64] of the return value. \n
+///    Bits [255:192] are written to bits [255:192] of the return value. \n
 /// \returns A 256-bit vector of [4 x double] containing the interleaved values.
 static __inline __m256d __DEFAULT_FN_ATTRS
 _mm256_unpackhi_pd(__m256d __a, __m256d __b)
@@ -2316,16 +2335,16 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKLPD instruction.
+/// This intrinsic corresponds to the <c> VUNPCKLPD </c> instruction.
 ///
 /// \param __a
-///    A 256-bit floating-point vector of [4 x double].
-///    Bits [63:0] are written to bits [63:0] of the return value.
+///    A 256-bit floating-point vector of [4 x double]. \n
+///    Bits [63:0] are written to bits [63:0] of the return value. \n
 ///    Bits [191:128] are written to bits [191:128] of the return value.
 /// \param __b
-///    A 256-bit floating-point vector of [4 x double].
-///    Bits [63:0] are written to bits [127:64] of the return value.
-///    Bits [191:128] are written to bits [255:192] of the return value.
+///    A 256-bit floating-point vector of [4 x double]. \n
+///    Bits [63:0] are written to bits [127:64] of the return value. \n
+///    Bits [191:128] are written to bits [255:192] of the return value. \n
 /// \returns A 256-bit vector of [4 x double] containing the interleaved values.
 static __inline __m256d __DEFAULT_FN_ATTRS
 _mm256_unpacklo_pd(__m256d __a, __m256d __b)
@@ -2339,19 +2358,19 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKHPS instruction.
+/// This intrinsic corresponds to the <c> VUNPCKHPS </c> instruction.
 ///
 /// \param __a
-///    A 256-bit vector of [8 x float].
-///    Bits [95:64] are written to bits [31:0] of the return value.
-///    Bits [127:96] are written to bits [95:64] of the return value.
-///    Bits [223:192] are written to bits [159:128] of the return value.
+///    A 256-bit vector of [8 x float]. \n
+///    Bits [95:64] are written to bits [31:0] of the return value. \n
+///    Bits [127:96] are written to bits [95:64] of the return value. \n
+///    Bits [223:192] are written to bits [159:128] of the return value. \n
 ///    Bits [255:224] are written to bits [223:192] of the return value.
 /// \param __b
-///    A 256-bit vector of [8 x float].
-///    Bits [95:64] are written to bits [63:32] of the return value.
-///    Bits [127:96] are written to bits [127:96] of the return value.
-///    Bits [223:192] are written to bits [191:160] of the return value.
+///    A 256-bit vector of [8 x float]. \n
+///    Bits [95:64] are written to bits [63:32] of the return value. \n
+///    Bits [127:96] are written to bits [127:96] of the return value. \n
+///    Bits [223:192] are written to bits [191:160] of the return value. \n
 ///    Bits [255:224] are written to bits [255:224] of the return value.
 /// \returns A 256-bit vector of [8 x float] containing the interleaved values.
 static __inline __m256 __DEFAULT_FN_ATTRS
@@ -2366,19 +2385,19 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKLPS instruction.
+/// This intrinsic corresponds to the <c> VUNPCKLPS </c> instruction.
 ///
 /// \param __a
-///    A 256-bit vector of [8 x float].
-///    Bits [31:0] are written to bits [31:0] of the return value.
-///    Bits [63:32] are written to bits [95:64] of the return value.
-///    Bits [159:128] are written to bits [159:128] of the return value.
+///    A 256-bit vector of [8 x float]. \n
+///    Bits [31:0] are written to bits [31:0] of the return value. \n
+///    Bits [63:32] are written to bits [95:64] of the return value. \n
+///    Bits [159:128] are written to bits [159:128] of the return value. \n
 ///    Bits [191:160] are written to bits [223:192] of the return value.
 /// \param __b
-///    A 256-bit vector of [8 x float].
-///    Bits [31:0] are written to bits [63:32] of the return value.
-///    Bits [63:32] are written to bits [127:96] of the return value.
-///    Bits [159:128] are written to bits [191:160] of the return value.
+///    A 256-bit vector of [8 x float]. \n
+///    Bits [31:0] are written to bits [63:32] of the return value. \n
+///    Bits [63:32] are written to bits [127:96] of the return value. \n
+///    Bits [159:128] are written to bits [191:160] of the return value. \n
 ///    Bits [191:160] are written to bits [255:224] of the return value.
 /// \returns A 256-bit vector of [8 x float] containing the interleaved values.
 static __inline __m256 __DEFAULT_FN_ATTRS
@@ -2391,18 +2410,18 @@
 /// \brief Given two 128-bit floating-point vectors of [2 x double], perform an
 ///    element-by-element comparison of the double-precision element in the
 ///    first source vector and the corresponding element in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the ZF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPD instruction.
+/// This intrinsic corresponds to the <c> VTESTPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -2418,18 +2437,18 @@
 /// \brief Given two 128-bit floating-point vectors of [2 x double], perform an
 ///    element-by-element comparison of the double-precision element in the
 ///    first source vector and the corresponding element in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the CF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPD instruction.
+/// This intrinsic corresponds to the <c> VTESTPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -2445,19 +2464,19 @@
 /// \brief Given two 128-bit floating-point vectors of [2 x double], perform an
 ///    element-by-element comparison of the double-precision element in the
 ///    first source vector and the corresponding element in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns 1 if both the ZF and CF flags are set to 0,
 ///    otherwise it returns 0.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPD instruction.
+/// This intrinsic corresponds to the <c> VTESTPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -2473,18 +2492,18 @@
 /// \brief Given two 128-bit floating-point vectors of [4 x float], perform an
 ///    element-by-element comparison of the single-precision element in the
 ///    first source vector and the corresponding element in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the ZF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPS instruction.
+/// This intrinsic corresponds to the <c> VTESTPS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -2500,18 +2519,18 @@
 /// \brief Given two 128-bit floating-point vectors of [4 x float], perform an
 ///    element-by-element comparison of the single-precision element in the
 ///    first source vector and the corresponding element in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the CF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPS instruction.
+/// This intrinsic corresponds to the <c> VTESTPS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -2527,19 +2546,19 @@
 /// \brief Given two 128-bit floating-point vectors of [4 x float], perform an
 ///    element-by-element comparison of the single-precision element in the
 ///    first source vector and the corresponding element in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns 1 if both the ZF and CF flags are set to 0,
 ///    otherwise it returns 0.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPS instruction.
+/// This intrinsic corresponds to the <c> VTESTPS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -2555,18 +2574,18 @@
 /// \brief Given two 256-bit floating-point vectors of [4 x double], perform an
 ///    element-by-element comparison of the double-precision elements in the
 ///    first source vector and the corresponding elements in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the ZF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPD instruction.
+/// This intrinsic corresponds to the <c> VTESTPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double].
@@ -2582,18 +2601,18 @@
 /// \brief Given two 256-bit floating-point vectors of [4 x double], perform an
 ///    element-by-element comparison of the double-precision elements in the
 ///    first source vector and the corresponding elements in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the CF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPD instruction.
+/// This intrinsic corresponds to the <c> VTESTPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double].
@@ -2609,19 +2628,19 @@
 /// \brief Given two 256-bit floating-point vectors of [4 x double], perform an
 ///    element-by-element comparison of the double-precision elements in the
 ///    first source vector and the corresponding elements in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of double-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns 1 if both the ZF and CF flags are set to 0,
 ///    otherwise it returns 0.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPD instruction.
+/// This intrinsic corresponds to the <c> VTESTPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double].
@@ -2637,18 +2656,18 @@
 /// \brief Given two 256-bit floating-point vectors of [8 x float], perform an
 ///    element-by-element comparison of the single-precision element in the
 ///    first source vector and the corresponding element in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the ZF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPS instruction.
+/// This intrinsic corresponds to the <c> VTESTPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
@@ -2664,18 +2683,18 @@
 /// \brief Given two 256-bit floating-point vectors of [8 x float], perform an
 ///    element-by-element comparison of the single-precision element in the
 ///    first source vector and the corresponding element in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the CF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPS instruction.
+/// This intrinsic corresponds to the <c> VTESTPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
@@ -2691,19 +2710,19 @@
 /// \brief Given two 256-bit floating-point vectors of [8 x float], perform an
 ///    element-by-element comparison of the single-precision elements in the
 ///    first source vector and the corresponding elements in the second source
-///    vector. The EFLAGS register is updated as follows:
+///    vector. The EFLAGS register is updated as follows: \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
-///    ZF flag is set to 1.
+///    ZF flag is set to 1. \n
 ///    If there is at least one pair of single-precision elements where the
 ///    sign-bit of the first element is 0 and the sign-bit of the second element
-///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1.
+///    is 1, the CF flag is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns 1 if both the ZF and CF flags are set to 0,
 ///    otherwise it returns 0.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VTESTPS instruction.
+/// This intrinsic corresponds to the <c> VTESTPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float].
@@ -2717,17 +2736,17 @@
 }
 
 /// \brief Given two 256-bit integer vectors, perform a bit-by-bit comparison
-///    of the two source vectors and update the EFLAGS register as follows:
+///    of the two source vectors and update the EFLAGS register as follows: \n
 ///    If there is at least one pair of bits where both bits are 1, the ZF flag
-///    is set to 0. Otherwise the ZF flag is set to 1.
+///    is set to 0. Otherwise the ZF flag is set to 1. \n
 ///    If there is at least one pair of bits where the bit from the first source
 ///    vector is 0 and the bit from the second source vector is 1, the CF flag
-///    is set to 0. Otherwise the CF flag is set to 1.
+///    is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the ZF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPTEST instruction.
+/// This intrinsic corresponds to the <c> VPTEST </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit integer vector.
@@ -2741,17 +2760,17 @@
 }
 
 /// \brief Given two 256-bit integer vectors, perform a bit-by-bit comparison
-///    of the two source vectors and update the EFLAGS register as follows:
+///    of the two source vectors and update the EFLAGS register as follows: \n
 ///    If there is at least one pair of bits where both bits are 1, the ZF flag
-///    is set to 0. Otherwise the ZF flag is set to 1.
+///    is set to 0. Otherwise the ZF flag is set to 1. \n
 ///    If there is at least one pair of bits where the bit from the first source
 ///    vector is 0 and the bit from the second source vector is 1, the CF flag
-///    is set to 0. Otherwise the CF flag is set to 1.
+///    is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns the value of the CF flag.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPTEST instruction.
+/// This intrinsic corresponds to the <c> VPTEST </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit integer vector.
@@ -2765,18 +2784,18 @@
 }
 
 /// \brief Given two 256-bit integer vectors, perform a bit-by-bit comparison
-///    of the two source vectors and update the EFLAGS register as follows:
+///    of the two source vectors and update the EFLAGS register as follows: \n
 ///    If there is at least one pair of bits where both bits are 1, the ZF flag
-///    is set to 0. Otherwise the ZF flag is set to 1.
+///    is set to 0. Otherwise the ZF flag is set to 1. \n
 ///    If there is at least one pair of bits where the bit from the first source
 ///    vector is 0 and the bit from the second source vector is 1, the CF flag
-///    is set to 0. Otherwise the CF flag is set to 1.
+///    is set to 0. Otherwise the CF flag is set to 1. \n
 ///    This intrinsic returns 1 if both the ZF and CF flags are set to 0,
 ///    otherwise it returns 0.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPTEST instruction.
+/// This intrinsic corresponds to the <c> VPTEST </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit integer vector.
@@ -2796,7 +2815,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVMSKPD instruction.
+/// This intrinsic corresponds to the <c> VMOVMSKPD </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [4 x double] containing the double-precision
@@ -2814,7 +2833,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVMSKPS instruction.
+/// This intrinsic corresponds to the <c> VMOVMSKPS </c> instruction.
 ///
 /// \param __a
 ///    A 256-bit vector of [8 x float] containing the double-precision floating
@@ -2831,7 +2850,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VZEROALL instruction.
+/// This intrinsic corresponds to the <c> VZEROALL </c> instruction.
 static __inline void __DEFAULT_FN_ATTRS
 _mm256_zeroall(void)
 {
@@ -2842,7 +2861,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VZEROUPPER instruction.
+/// This intrinsic corresponds to the <c> VZEROUPPER </c> instruction.
 static __inline void __DEFAULT_FN_ATTRS
 _mm256_zeroupper(void)
 {
@@ -2856,7 +2875,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VBROADCASTSS instruction.
+/// This intrinsic corresponds to the <c> VBROADCASTSS </c> instruction.
 ///
 /// \param __a
 ///    The single-precision floating point value to be broadcast.
@@ -2875,7 +2894,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VBROADCASTSD instruction.
+/// This intrinsic corresponds to the <c> VBROADCASTSD </c> instruction.
 ///
 /// \param __a
 ///    The double-precision floating point value to be broadcast.
@@ -2894,7 +2913,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VBROADCASTSS instruction.
+/// This intrinsic corresponds to the <c> VBROADCASTSS </c> instruction.
 ///
 /// \param __a
 ///    The single-precision floating point value to be broadcast.
@@ -2913,7 +2932,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VBROADCASTF128 instruction.
+/// This intrinsic corresponds to the <c> VBROADCASTF128 </c> instruction.
 ///
 /// \param __a
 ///    The 128-bit vector of [2 x double] to be broadcast.
@@ -2931,7 +2950,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VBROADCASTF128 instruction.
+/// This intrinsic corresponds to the <c> VBROADCASTF128 </c> instruction.
 ///
 /// \param __a
 ///    The 128-bit vector of [4 x float] to be broadcast.
@@ -2949,7 +2968,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPD instruction.
+/// This intrinsic corresponds to the <c> VMOVAPD </c> instruction.
 ///
 /// \param __p
 ///    A 32-byte aligned pointer to a memory location containing
@@ -2966,7 +2985,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPS instruction.
+/// This intrinsic corresponds to the <c> VMOVAPS </c> instruction.
 ///
 /// \param __p
 ///    A 32-byte aligned pointer to a memory location containing float values.
@@ -2982,7 +3001,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVUPD instruction.
+/// This intrinsic corresponds to the <c> VMOVUPD </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location containing double-precision floating
@@ -3002,7 +3021,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVUPS instruction.
+/// This intrinsic corresponds to the <c> VMOVUPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location containing single-precision floating
@@ -3022,7 +3041,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDQA instruction.
+/// This intrinsic corresponds to the <c> VMOVDQA </c> instruction.
 ///
 /// \param __p
 ///    A 32-byte aligned pointer to a 256-bit integer vector containing integer
@@ -3039,7 +3058,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDQU instruction.
+/// This intrinsic corresponds to the <c> VMOVDQU </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 256-bit integer vector containing integer values.
@@ -3060,7 +3079,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VLDDQU instruction.
+/// This intrinsic corresponds to the <c> VLDDQU </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 256-bit integer vector containing integer values.
@@ -3078,7 +3097,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPD instruction.
+/// This intrinsic corresponds to the <c> VMOVAPD </c> instruction.
 ///
 /// \param __p
 ///    A 32-byte aligned pointer to a memory location that will receive the
@@ -3096,7 +3115,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPS instruction.
+/// This intrinsic corresponds to the <c> VMOVAPS </c> instruction.
 ///
 /// \param __p
 ///    A 32-byte aligned pointer to a memory location that will receive the
@@ -3114,7 +3133,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVUPD instruction.
+/// This intrinsic corresponds to the <c> VMOVUPD </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that will receive the double-precision
@@ -3135,7 +3154,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVUPS instruction.
+/// This intrinsic corresponds to the <c> VMOVUPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that will receive the float values.
@@ -3155,7 +3174,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDQA instruction.
+/// This intrinsic corresponds to the <c> VMOVDQA </c> instruction.
 ///
 /// \param __p
 ///    A 32-byte aligned pointer to a memory location that will receive the
@@ -3173,7 +3192,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDQU instruction.
+/// This intrinsic corresponds to the <c> VMOVDQU </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that will receive the integer values.
@@ -3189,14 +3208,14 @@
 }
 
 /* Conditional load ops */
-/// \brief Conditionally loads double-precision floating point elements
-///    from a memory location pointed to by \a __p into a 128-bit vector of
+/// \brief Conditionally loads double-precision floating point elements from a
+///    memory location pointed to by \a __p into a 128-bit vector of
 ///    [2 x double], depending on the mask bits associated with each data
 ///    element.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMASKMOVPD instruction.
+/// This intrinsic corresponds to the <c> VMASKMOVPD </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that contains the double-precision
@@ -3213,14 +3232,14 @@
   return (__m128d)__builtin_ia32_maskloadpd((const __v2df *)__p, (__v2di)__m);
 }
 
-/// \brief Conditionally loads double-precision floating point elements
-///    from a memory location pointed to by \a __p into a 256-bit vector of
+/// \brief Conditionally loads double-precision floating point elements from a
+///    memory location pointed to by \a __p into a 256-bit vector of
 ///    [4 x double], depending on the mask bits associated with each data
 ///    element.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMASKMOVPD instruction.
+/// This intrinsic corresponds to the <c> VMASKMOVPD </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that contains the double-precision
@@ -3238,14 +3257,14 @@
                                                (__v4di)__m);
 }
 
-/// \brief Conditionally loads single-precision floating point elements
-///    from a memory location pointed to by \a __p into a 128-bit vector of
+/// \brief Conditionally loads single-precision floating point elements from a
+///    memory location pointed to by \a __p into a 128-bit vector of
 ///    [4 x float], depending on the mask bits associated with each data
 ///    element.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMASKMOVPS instruction.
+/// This intrinsic corresponds to the <c> VMASKMOVPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that contains the single-precision
@@ -3269,7 +3288,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMASKMOVPS instruction.
+/// This intrinsic corresponds to the <c> VMASKMOVPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that contains the single-precision
@@ -3293,7 +3312,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMASKMOVPS instruction.
+/// This intrinsic corresponds to the <c> VMASKMOVPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that will receive the float values.
@@ -3317,7 +3336,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMASKMOVPD instruction.
+/// This intrinsic corresponds to the <c> VMASKMOVPD </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that will receive the float values.
@@ -3341,7 +3360,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMASKMOVPD instruction.
+/// This intrinsic corresponds to the <c> VMASKMOVPD </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that will receive the float values.
@@ -3365,7 +3384,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMASKMOVPS instruction.
+/// This intrinsic corresponds to the <c> VMASKMOVPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that will receive the float values.
@@ -3390,7 +3409,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVNTDQ instruction.
+/// This intrinsic corresponds to the <c> VMOVNTDQ </c> instruction.
 ///
 /// \param __a
 ///    A pointer to a 32-byte aligned memory location that will receive the
@@ -3409,7 +3428,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVNTPD instruction.
+/// This intrinsic corresponds to the <c> VMOVNTPD </c> instruction.
 ///
 /// \param __a
 ///    A pointer to a 32-byte aligned memory location that will receive the
@@ -3429,7 +3448,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVNTPS instruction.
+/// This intrinsic corresponds to the <c> VMOVNTPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 32-byte aligned memory location that will receive the
@@ -3487,7 +3506,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKLPD+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VUNPCKLPD+VINSERTF128 </c>
+///   instruction.
 ///
 /// \param __a
 ///    A double-precision floating-point value used to initialize bits [255:192]
@@ -3514,7 +3534,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic is a utility function and does not correspond to a specific
-///    instruction.
+///   instruction.
 ///
 /// \param __a
 ///    A single-precision floating-point value used to initialize bits [255:224]
@@ -3554,7 +3574,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic is a utility function and does not correspond to a specific
-///    instruction.
+///   instruction.
 ///
 /// \param __i0
 ///    A 32-bit integral value used to initialize bits [255:224] of the result.
@@ -3586,7 +3606,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic is a utility function and does not correspond to a specific
-///    instruction.
+///   instruction.
 ///
 /// \param __w15
 ///    A 16-bit integral value used to initialize bits [255:240] of the result.
@@ -3637,7 +3657,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic is a utility function and does not correspond to a specific
-///    instruction.
+///   instruction.
 ///
 /// \param __b31
 ///    An 8-bit integral value used to initialize bits [255:248] of the result.
@@ -3727,7 +3747,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKLQDQ+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKLQDQ+VINSERTF128 </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 64-bit integral value used to initialize bits [255:192] of the result.
@@ -3751,7 +3772,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKLPD+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VUNPCKLPD+VINSERTF128 </c>
+///   instruction.
 ///
 /// \param __a
 ///    A double-precision floating-point value used to initialize bits [63:0]
@@ -3779,7 +3801,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic is a utility function and does not correspond to a specific
-///    instruction.
+///   instruction.
 ///
 /// \param __a
 ///    A single-precision floating-point value used to initialize bits [31:0]
@@ -3819,7 +3841,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic is a utility function and does not correspond to a specific
-///    instruction.
+///   instruction.
 ///
 /// \param __i0
 ///    A 32-bit integral value used to initialize bits [31:0] of the result.
@@ -3851,7 +3873,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic is a utility function and does not correspond to a specific
-///    instruction.
+///   instruction.
 ///
 /// \param __w15
 ///    A 16-bit integral value used to initialize bits [15:0] of the result.
@@ -3902,7 +3924,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic is a utility function and does not correspond to a specific
-///    instruction.
+///   instruction.
 ///
 /// \param __b31
 ///    An 8-bit integral value used to initialize bits [7:0] of the result.
@@ -3991,7 +4013,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKLQDQ+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKLQDQ+VINSERTF128 </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 64-bit integral value used to initialize bits [63:0] of the result.
@@ -4015,7 +4038,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDDUP+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VMOVDDUP+VINSERTF128 </c> instruction.
 ///
 /// \param __w
 ///    A double-precision floating-point value used to initialize each vector
@@ -4033,7 +4056,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPERMILPS+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VPERMILPS+VINSERTF128 </c>
+///   instruction.
 ///
 /// \param __w
 ///    A single-precision floating-point value used to initialize each vector
@@ -4051,7 +4075,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPERMILPS+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VPERMILPS+VINSERTF128 </c>
+///   instruction.
 ///
 /// \param __i
 ///    A 32-bit integral value used to initialize each vector element of the
@@ -4069,7 +4094,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSHUFB+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VPSHUFB+VINSERTF128 </c> instruction.
 ///
 /// \param __w
 ///    A 16-bit integral value used to initialize each vector element of the
@@ -4087,7 +4112,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSHUFB+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VPSHUFB+VINSERTF128 </c> instruction.
 ///
 /// \param __b
 ///    An 8-bit integral value used to initialize each vector element of the
@@ -4107,7 +4132,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDDUP+VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VMOVDDUP+VINSERTF128 </c> instruction.
 ///
 /// \param __q
 ///    A 64-bit integral value used to initialize each vector element of the
@@ -4125,7 +4150,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VXORPS instruction.
+/// This intrinsic corresponds to the <c> VXORPS </c> instruction.
 ///
 /// \returns A 256-bit vector of [4 x double] with all elements set to zero.
 static __inline __m256d __DEFAULT_FN_ATTRS
@@ -4139,7 +4164,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VXORPS instruction.
+/// This intrinsic corresponds to the <c> VXORPS </c> instruction.
 ///
 /// \returns A 256-bit vector of [8 x float] with all elements set to zero.
 static __inline __m256 __DEFAULT_FN_ATTRS
@@ -4152,7 +4177,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VXORPS instruction.
+/// This intrinsic corresponds to the <c> VXORPS </c> instruction.
 ///
 /// \returns A 256-bit integer vector initialized to zero.
 static __inline __m256i __DEFAULT_FN_ATTRS
@@ -4389,7 +4414,7 @@
 /// __m256 _mm256_insertf128_ps(__m256 V1, __m128 V2, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128 </c> instruction.
 ///
 /// \param V1
 ///    A 256-bit vector of [8 x float]. This vector is copied to the result
@@ -4401,9 +4426,10 @@
 ///    on the value of parameter \a M.
 /// \param M
 ///    An immediate integer. The least significant bit determines how the values
-///    from the two parameters are interleaved:
+///    from the two parameters are interleaved: \n
 ///    If bit [0] of \a M is 0, \a V2 are copied to bits [127:0] of the result,
-///    and bits [255:128] of \a V1 are copied to bits [255:128] of the result.
+///    and bits [255:128] of \a V1 are copied to bits [255:128] of the
+///    result. \n
 ///    If bit [0] of \a M is 1, \a V2 are copied to bits [255:128] of the
 ///    result, and bits [127:0] of \a V1 are copied to bits [127:0] of the
 ///    result.
@@ -4433,7 +4459,7 @@
 /// __m256d _mm256_insertf128_pd(__m256d V1, __m128d V2, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128 </c> instruction.
 ///
 /// \param V1
 ///    A 256-bit vector of [4 x double]. This vector is copied to the result
@@ -4445,9 +4471,10 @@
 ///    on the value of parameter \a M.
 /// \param M
 ///    An immediate integer. The least significant bit determines how the values
-///    from the two parameters are interleaved:
+///    from the two parameters are interleaved: \n
 ///    If bit [0] of \a M is 0, \a V2 are copied to bits [127:0] of the result,
-///    and bits [255:128] of \a V1 are copied to bits [255:128] of the result.
+///    and bits [255:128] of \a V1 are copied to bits [255:128] of the
+///    result. \n
 ///    If bit [0] of \a M is 1, \a V2 are copied to bits [255:128] of the
 ///    result, and bits [127:0] of \a V1 are copied to bits [127:0] of the
 ///    result.
@@ -4473,7 +4500,7 @@
 /// __m256i _mm256_insertf128_si256(__m256i V1, __m128i V2, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128 </c> instruction.
 ///
 /// \param V1
 ///    A 256-bit integer vector. This vector is copied to the result first, and
@@ -4485,9 +4512,10 @@
 ///     value of parameter \a M.
 /// \param M
 ///    An immediate integer. The least significant bit determines how the values
-///    from the two parameters are interleaved:
+///    from the two parameters are interleaved: \n
 ///    If bit [0] of \a M is 0, \a V2 are copied to bits [127:0] of the result,
-///    and bits [255:128] of \a V1 are copied to bits [255:128] of the result.
+///    and bits [255:128] of \a V1 are copied to bits [255:128] of the
+///    result. \n
 ///    If bit [0] of \a M is 1, \a V2 are copied to bits [255:128] of the
 ///    result, and bits [127:0] of \a V1 are copied to bits [127:0] of the
 ///    result.
@@ -4516,14 +4544,15 @@
 /// __m128 _mm256_extractf128_ps(__m256 V, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128 instruction.
+/// This intrinsic corresponds to the <c> VEXTRACTF128 </c> instruction.
 ///
 /// \param V
 ///    A 256-bit vector of [8 x float].
 /// \param M
 ///    An immediate integer. The least significant bit determines which bits are
-///    extracted from the first parameter:
-///    If bit [0] of \a M is 0, bits [127:0] of \a V are copied to the result.
+///    extracted from the first parameter: \n
+///    If bit [0] of \a M is 0, bits [127:0] of \a V are copied to the
+///    result. \n
 ///    If bit [0] of \a M is 1, bits [255:128] of \a V are copied to the result.
 /// \returns A 128-bit vector of [4 x float] containing the extracted bits.
 #define _mm256_extractf128_ps(V, M) __extension__ ({ \
@@ -4534,7 +4563,7 @@
     (((M) & 1) ? 5 : 1), \
     (((M) & 1) ? 6 : 2), \
     (((M) & 1) ? 7 : 3) );})
-                                                   
+
 /// \brief Extracts either the upper or the lower 128 bits from a 256-bit vector
 ///    of [4 x double], as determined by the immediate integer parameter, and
 ///    returns the extracted bits as a 128-bit vector of [2 x double].
@@ -4545,14 +4574,15 @@
 /// __m128d _mm256_extractf128_pd(__m256d V, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128 instruction.
+/// This intrinsic corresponds to the <c> VEXTRACTF128 </c> instruction.
 ///
 /// \param V
 ///    A 256-bit vector of [4 x double].
 /// \param M
 ///    An immediate integer. The least significant bit determines which bits are
-///    extracted from the first parameter:
-///    If bit [0] of \a M is 0, bits [127:0] of \a V are copied to the result.
+///    extracted from the first parameter: \n
+///    If bit [0] of \a M is 0, bits [127:0] of \a V are copied to the
+///    result. \n
 ///    If bit [0] of \a M is 1, bits [255:128] of \a V are copied to the result.
 /// \returns A 128-bit vector of [2 x double] containing the extracted bits.
 #define _mm256_extractf128_pd(V, M) __extension__ ({ \
@@ -4572,14 +4602,15 @@
 /// __m128i _mm256_extractf128_si256(__m256i V, const int M);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128 instruction.
+/// This intrinsic corresponds to the <c> VEXTRACTF128 </c> instruction.
 ///
 /// \param V
 ///    A 256-bit integer vector.
 /// \param M
 ///    An immediate integer. The least significant bit determines which bits are
-///    extracted from the first parameter:
-///    If bit [0] of \a M is 0, bits [127:0] of \a V are copied to the result.
+///    extracted from the first parameter:  \n
+///    If bit [0] of \a M is 0, bits [127:0] of \a V are copied to the
+///    result. \n
 ///    If bit [0] of \a M is 1, bits [255:128] of \a V are copied to the result.
 /// \returns A 128-bit integer vector containing the extracted bits.
 #define _mm256_extractf128_si256(V, M) __extension__ ({ \
@@ -4597,17 +4628,17 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic corresponds to load instructions followed by the
-///    \c VINSERTF128 instruction.
+///   <c> VINSERTF128 </c> instruction.
 ///
 /// \param __addr_hi
 ///    A pointer to a 128-bit memory location containing 4 consecutive
-///    single-precision floating-point values. These values are to be copied
-///    to bits[255:128] of the result. The address of the memory location does
-///    not have to be aligned.
+///    single-precision floating-point values. These values are to be copied to
+///    bits[255:128] of the result. The address of the memory location does not
+///    have to be aligned.
 /// \param __addr_lo
 ///    A pointer to a 128-bit memory location containing 4 consecutive
-///    single-precision floating-point values. These values are to be copied
-///    to bits[127:0] of the result. The address of the memory location does not
+///    single-precision floating-point values. These values are to be copied to
+///    bits[127:0] of the result. The address of the memory location does not
 ///    have to be aligned.
 /// \returns A 256-bit floating-point vector of [8 x float] containing the
 ///    concatenated result.
@@ -4625,17 +4656,17 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic corresponds to load instructions followed by the
-///    \c VINSERTF128 instruction.
+///   <c> VINSERTF128 </c> instruction.
 ///
 /// \param __addr_hi
 ///    A pointer to a 128-bit memory location containing two consecutive
-///    double-precision floating-point values. These values are to be copied
-///    to bits[255:128] of the result. The address of the memory location does
-///    not have to be aligned.
+///    double-precision floating-point values. These values are to be copied to
+///    bits[255:128] of the result. The address of the memory location does not
+///    have to be aligned.
 /// \param __addr_lo
 ///    A pointer to a 128-bit memory location containing two consecutive
-///    double-precision floating-point values. These values are to be copied
-///    to bits[127:0] of the result. The address of the memory location does not
+///    double-precision floating-point values. These values are to be copied to
+///    bits[127:0] of the result. The address of the memory location does not
 ///    have to be aligned.
 /// \returns A 256-bit floating-point vector of [4 x double] containing the
 ///    concatenated result.
@@ -4653,7 +4684,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic corresponds to load instructions followed by the
-///    \c VINSERTF128 instruction.
+///   <c> VINSERTF128 </c> instruction.
 ///
 /// \param __addr_hi
 ///    A pointer to a 128-bit memory location containing a 128-bit integer
@@ -4677,8 +4708,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128 instruction and the store
-///    instructions.
+/// This intrinsic corresponds to the <c> VEXTRACTF128 </c> instruction and the
+///   store instructions.
 ///
 /// \param __addr_hi
 ///    A pointer to a 128-bit memory location. Bits[255:128] of \a __a are to be
@@ -4706,8 +4737,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128 instruction and the store
-///    instructions.
+/// This intrinsic corresponds to the <c> VEXTRACTF128 </c> instruction and the
+///   store instructions.
 ///
 /// \param __addr_hi
 ///    A pointer to a 128-bit memory location. Bits[255:128] of \a __a are to be
@@ -4735,8 +4766,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VEXTRACTF128 instruction and the store
-///    instructions.
+/// This intrinsic corresponds to the <c> VEXTRACTF128 </c> instruction and the
+///   store instructions.
 ///
 /// \param __addr_hi
 ///    A pointer to a 128-bit memory location. Bits[255:128] of \a __a are to be
@@ -4764,7 +4795,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128 </c> instruction.
 ///
 /// \param __hi
 ///    A 128-bit floating-point vector of [4 x float] to be copied to the upper
@@ -4785,7 +4816,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128 </c> instruction.
 ///
 /// \param __hi
 ///    A 128-bit floating-point vector of [2 x double] to be copied to the upper
@@ -4806,7 +4837,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128 </c> instruction.
 ///
 /// \param __hi
 ///    A 128-bit integer vector to be copied to the upper 128 bits of the
@@ -4828,7 +4859,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128 </c> instruction.
 ///
 /// \param __lo
 ///    A 128-bit floating-point vector of [4 x float] to be copied to the lower
@@ -4851,7 +4882,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128 </c> instruction.
 ///
 /// \param __lo
 ///    A 128-bit floating-point vector of [2 x double] to be copied to the lower
@@ -4873,7 +4904,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VINSERTF128 instruction.
+/// This intrinsic corresponds to the <c> VINSERTF128 </c> instruction.
 ///
 /// \param __lo
 ///    A 128-bit integer vector to be copied to the lower 128 bits of the
diff --git a/lib/Headers/bmiintrin.h b/lib/Headers/bmiintrin.h
index 30acfae..488eb2d 100644
--- a/lib/Headers/bmiintrin.h
+++ b/lib/Headers/bmiintrin.h
@@ -36,7 +36,7 @@
 /// unsigned short _tzcnt_u16(unsigned short a);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c TZCNT instruction.
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
 ///
 /// \param a
 ///    An unsigned 16-bit integer whose trailing zeros are to be counted.
@@ -53,7 +53,7 @@
 /// unsigned int _andn_u32(unsigned int a, unsigned int b);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c ANDN instruction.
+/// This intrinsic corresponds to the <c> ANDN </c> instruction.
 ///
 /// \param a
 ///    An unsigned integer containing one of the operands.
@@ -73,7 +73,7 @@
 /// unsigned int _blsi_u32(unsigned int a);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c BLSI instruction.
+/// This intrinsic corresponds to the <c> BLSI </c> instruction.
 ///
 /// \param a
 ///    An unsigned integer whose bits are to be cleared.
@@ -91,7 +91,7 @@
 /// unsigned int _blsmsk_u32(unsigned int a);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c BLSMSK instruction.
+/// This intrinsic corresponds to the <c> BLSMSK </c> instruction.
 ///
 /// \param a
 ///    An unsigned integer used to create the mask.
@@ -107,7 +107,7 @@
 /// unsigned int _blsr_u32(unsigned int a);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c BLSR instruction.
+/// This intrinsic corresponds to the <c> BLSR </c> instruction.
 ///
 /// \param a
 ///    An unsigned integer containing the operand to be cleared.
@@ -123,7 +123,7 @@
 /// unsigned int _tzcnt_u32(unsigned int a);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c TZCNT instruction.
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
 ///
 /// \param a
 ///    An unsigned 32-bit integer whose trailing zeros are to be counted.
@@ -143,7 +143,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c TZCNT instruction.
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 16-bit integer whose trailing zeros are to be counted.
@@ -160,7 +160,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c ANDN instruction.
+/// This intrinsic corresponds to the <c> ANDN </c> instruction.
 ///
 /// \param __X
 ///    An unsigned integer containing one of the operands.
@@ -180,7 +180,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BEXTR instruction.
+/// This intrinsic corresponds to the <c> BEXTR </c> instruction.
 ///
 /// \param __X
 ///    An unsigned integer whose bits are to be extracted.
@@ -202,7 +202,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BEXTR instruction.
+/// This intrinsic corresponds to the <c> BEXTR </c> instruction.
 ///
 /// \param __X
 ///    An unsigned integer whose bits are to be extracted.
@@ -225,7 +225,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BLSI instruction.
+/// This intrinsic corresponds to the <c> BLSI </c> instruction.
 ///
 /// \param __X
 ///    An unsigned integer whose bits are to be cleared.
@@ -243,7 +243,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BLSMSK instruction.
+/// This intrinsic corresponds to the <c> BLSMSK </c> instruction.
 ///
 /// \param __X
 ///    An unsigned integer used to create the mask.
@@ -259,7 +259,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BLSR instruction.
+/// This intrinsic corresponds to the <c> BLSR </c> instruction.
 ///
 /// \param __X
 ///    An unsigned integer containing the operand to be cleared.
@@ -275,7 +275,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c TZCNT instruction.
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 32-bit integer whose trailing zeros are to be counted.
@@ -291,12 +291,12 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c TZCNT instruction.
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 32-bit integer whose trailing zeros are to be counted.
-/// \returns An 32-bit integer containing the number of trailing zero
-///    bits in the operand.
+/// \returns An 32-bit integer containing the number of trailing zero bits in
+///    the operand.
 static __inline__ int __RELAXED_FN_ATTRS
 _mm_tzcnt_32(unsigned int __X)
 {
@@ -314,7 +314,7 @@
 /// unsigned long long _andn_u64 (unsigned long long a, unsigned long long b);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c ANDN instruction.
+/// This intrinsic corresponds to the <c> ANDN </c> instruction.
 ///
 /// \param a
 ///    An unsigned 64-bit integer containing one of the operands.
@@ -334,7 +334,7 @@
 /// unsigned long long _blsi_u64(unsigned long long a);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c BLSI instruction.
+/// This intrinsic corresponds to the <c> BLSI </c> instruction.
 ///
 /// \param a
 ///    An unsigned 64-bit integer whose bits are to be cleared.
@@ -352,7 +352,7 @@
 /// unsigned long long _blsmsk_u64(unsigned long long a);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c BLSMSK instruction.
+/// This intrinsic corresponds to the <c> BLSMSK </c> instruction.
 ///
 /// \param a
 ///    An unsigned 64-bit integer used to create the mask.
@@ -368,7 +368,7 @@
 /// unsigned long long _blsr_u64(unsigned long long a);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c BLSR instruction.
+/// This intrinsic corresponds to the <c> BLSR </c> instruction.
 ///
 /// \param a
 ///    An unsigned 64-bit integer containing the operand to be cleared.
@@ -384,7 +384,7 @@
 /// unsigned long long _tzcnt_u64(unsigned long long a);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c TZCNT instruction.
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
 ///
 /// \param a
 ///    An unsigned 64-bit integer whose trailing zeros are to be counted.
@@ -397,7 +397,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c ANDN instruction.
+/// This intrinsic corresponds to the <c> ANDN </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 64-bit integer containing one of the operands.
@@ -417,7 +417,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BEXTR instruction.
+/// This intrinsic corresponds to the <c> BEXTR </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 64-bit integer whose bits are to be extracted.
@@ -439,7 +439,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BEXTR instruction.
+/// This intrinsic corresponds to the <c> BEXTR </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 64-bit integer whose bits are to be extracted.
@@ -462,7 +462,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BLSI instruction.
+/// This intrinsic corresponds to the <c> BLSI </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 64-bit integer whose bits are to be cleared.
@@ -480,7 +480,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BLSMSK instruction.
+/// This intrinsic corresponds to the <c> BLSMSK </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 64-bit integer used to create the mask.
@@ -496,7 +496,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c BLSR instruction.
+/// This intrinsic corresponds to the <c> BLSR </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 64-bit integer containing the operand to be cleared.
@@ -512,7 +512,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c TZCNT instruction.
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 64-bit integer whose trailing zeros are to be counted.
@@ -528,12 +528,12 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c TZCNT instruction.
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
 ///
 /// \param __X
 ///    An unsigned 64-bit integer whose trailing zeros are to be counted.
-/// \returns An 64-bit integer containing the number of trailing zero
-///    bits in the operand.
+/// \returns An 64-bit integer containing the number of trailing zero bits in
+///    the operand.
 static __inline__ long long __RELAXED_FN_ATTRS
 _mm_tzcnt_64(unsigned long long __X)
 {
diff --git a/lib/Headers/clzerointrin.h b/lib/Headers/clzerointrin.h
new file mode 100644
index 0000000..ed7478f
--- /dev/null
+++ b/lib/Headers/clzerointrin.h
@@ -0,0 +1,50 @@
+/*===----------------------- clzerointrin.h - CLZERO ----------------------===
+ *
+ * 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 __X86INTRIN_H
+#error "Never use <clzerointrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef _CLZEROINTRIN_H
+#define _CLZEROINTRIN_H
+
+/* Define the default attributes for the functions in this file. */
+#define __DEFAULT_FN_ATTRS \
+  __attribute__((__always_inline__, __nodebug__,  __target__("clzero")))
+
+/// \brief Loads the cache line address and zero's out the cacheline
+///
+/// \headerfile <clzerointrin.h>
+///
+/// This intrinsic corresponds to the <c> CLZERO </c> instruction.
+///
+/// \param __line
+///    A pointer to a cacheline which needs to be zeroed out.
+static __inline__ void __DEFAULT_FN_ATTRS
+_mm_clzero (void * __line)
+{
+  __builtin_ia32_clzero ((void *)__line);
+}
+
+#undef __DEFAULT_FN_ATTRS 
+
+#endif /* _CLZEROINTRIN_H */
diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h
index 10df64c..91da77e 100644
--- a/lib/Headers/emmintrin.h
+++ b/lib/Headers/emmintrin.h
@@ -55,7 +55,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDSD / ADDSD instruction.
+/// This intrinsic corresponds to the <c> VADDSD / ADDSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the source operands.
@@ -75,7 +75,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDPD / ADDPD instruction.
+/// This intrinsic corresponds to the <c> VADDPD / ADDPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the source operands.
@@ -97,7 +97,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSUBSD / SUBSD instruction.
+/// This intrinsic corresponds to the <c> VSUBSD / SUBSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing the minuend.
@@ -117,7 +117,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSUBPD / SUBPD instruction.
+/// This intrinsic corresponds to the <c> VSUBPD / SUBPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing the minuend.
@@ -138,7 +138,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMULSD / MULSD instruction.
+/// This intrinsic corresponds to the <c> VMULSD / MULSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the source operands.
@@ -158,7 +158,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMULPD / MULPD instruction.
+/// This intrinsic corresponds to the <c> VMULPD / MULPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the operands.
@@ -180,7 +180,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VDIVSD / DIVSD instruction.
+/// This intrinsic corresponds to the <c> VDIVSD / DIVSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing the dividend.
@@ -201,7 +201,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VDIVPD / DIVPD instruction.
+/// This intrinsic corresponds to the <c> VDIVPD / DIVPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing the dividend.
@@ -222,7 +222,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSQRTSD / SQRTSD instruction.
+/// This intrinsic corresponds to the <c> VSQRTSD / SQRTSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the operands. The
@@ -246,7 +246,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSQRTPD / SQRTPD instruction.
+/// This intrinsic corresponds to the <c> VSQRTPD / SQRTPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -265,7 +265,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMINSD / MINSD instruction.
+/// This intrinsic corresponds to the <c> VMINSD / MINSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the operands. The
@@ -288,7 +288,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMINPD / MINPD instruction.
+/// This intrinsic corresponds to the <c> VMINPD / MINPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the operands.
@@ -309,7 +309,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMAXSD / MAXSD instruction.
+/// This intrinsic corresponds to the <c> VMAXSD / MAXSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the operands. The
@@ -332,7 +332,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMAXPD / MAXPD instruction.
+/// This intrinsic corresponds to the <c> VMAXPD / MAXPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the operands.
@@ -350,7 +350,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPAND / PAND instruction.
+/// This intrinsic corresponds to the <c> VPAND / PAND </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the source operands.
@@ -369,7 +369,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPANDN / PANDN instruction.
+/// This intrinsic corresponds to the <c> VPANDN / PANDN </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing the left source operand. The
@@ -389,7 +389,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPOR / POR instruction.
+/// This intrinsic corresponds to the <c> VPOR / POR </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the source operands.
@@ -407,7 +407,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPXOR / PXOR instruction.
+/// This intrinsic corresponds to the <c> VPXOR / PXOR </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the source operands.
@@ -427,7 +427,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPEQPD / CMPEQPD instruction.
+/// This intrinsic corresponds to the <c> VCMPEQPD / CMPEQPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -447,7 +447,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLTPD / CMPLTPD instruction.
+/// This intrinsic corresponds to the <c> VCMPLTPD / CMPLTPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -467,7 +467,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLEPD / CMPLEPD instruction.
+/// This intrinsic corresponds to the <c> VCMPLEPD / CMPLEPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -487,7 +487,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLTPD / CMPLTPD instruction.
+/// This intrinsic corresponds to the <c> VCMPLTPD / CMPLTPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -507,7 +507,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLEPD / CMPLEPD instruction.
+/// This intrinsic corresponds to the <c> VCMPLEPD / CMPLEPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -529,7 +529,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPORDPD / CMPORDPD instruction.
+/// This intrinsic corresponds to the <c> VCMPORDPD / CMPORDPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -551,7 +551,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPUNORDPD / CMPUNORDPD instruction.
+/// This intrinsic corresponds to the <c> VCMPUNORDPD / CMPUNORDPD </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -571,7 +572,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNEQPD / CMPNEQPD instruction.
+/// This intrinsic corresponds to the <c> VCMPNEQPD / CMPNEQPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -591,7 +592,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLTPD / CMPNLTPD instruction.
+/// This intrinsic corresponds to the <c> VCMPNLTPD / CMPNLTPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -611,7 +612,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLEPD / CMPNLEPD instruction.
+/// This intrinsic corresponds to the <c> VCMPNLEPD / CMPNLEPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -631,7 +632,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLTPD / CMPNLTPD instruction.
+/// This intrinsic corresponds to the <c> VCMPNLTPD / CMPNLTPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -651,7 +652,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLEPD / CMPNLEPD instruction.
+/// This intrinsic corresponds to the <c> VCMPNLEPD / CMPNLEPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -670,7 +671,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPEQSD / CMPEQSD instruction.
+/// This intrinsic corresponds to the <c> VCMPEQSD / CMPEQSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -694,7 +695,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLTSD / CMPLTSD instruction.
+/// This intrinsic corresponds to the <c> VCMPLTSD / CMPLTSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -718,7 +719,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLESD / CMPLESD instruction.
+/// This intrinsic corresponds to the <c> VCMPLESD / CMPLESD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -734,15 +735,15 @@
   return (__m128d)__builtin_ia32_cmplesd((__v2df)__a, (__v2df)__b);
 }
 
-/// \brief Compares the lower double-precision floating-point values in each
-///    of the two 128-bit floating-point vectors of [2 x double] to determine
-///    if the value in the first parameter is greater than the corresponding
-///    value in the second parameter. The comparison yields 0h for false,
+/// \brief Compares the lower double-precision floating-point values in each of
+///    the two 128-bit floating-point vectors of [2 x double] to determine if
+///    the value in the first parameter is greater than the corresponding value
+///    in the second parameter. The comparison yields 0h for false,
 ///    FFFFFFFFFFFFFFFFh for true.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLTSD / CMPLTSD instruction.
+/// This intrinsic corresponds to the <c> VCMPLTSD / CMPLTSD </c> instruction.
 ///
 /// \param __a
 ///     A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -767,7 +768,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLESD / CMPLESD instruction.
+/// This intrinsic corresponds to the <c> VCMPLESD / CMPLESD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -784,16 +785,16 @@
   return (__m128d) { __c[0], __a[1] };
 }
 
-/// \brief Compares the lower double-precision floating-point values in each
-///    of the two 128-bit floating-point vectors of [2 x double] to determine
-///    if the value in the first parameter is "ordered" with respect to the
+/// \brief Compares the lower double-precision floating-point values in each of
+///    the two 128-bit floating-point vectors of [2 x double] to determine if
+///    the value in the first parameter is "ordered" with respect to the
 ///    corresponding value in the second parameter. The comparison yields 0h for
 ///    false, FFFFFFFFFFFFFFFFh for true. A pair of double-precision values are
 ///    "ordered" with respect to each other if neither value is a NaN.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPORDSD / CMPORDSD instruction.
+/// This intrinsic corresponds to the <c> VCMPORDSD / CMPORDSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -809,16 +810,17 @@
   return (__m128d)__builtin_ia32_cmpordsd((__v2df)__a, (__v2df)__b);
 }
 
-/// \brief Compares the lower double-precision floating-point values in each
-///    of the two 128-bit floating-point vectors of [2 x double] to determine
-///    if the value in the first parameter is "unordered" with respect to the
+/// \brief Compares the lower double-precision floating-point values in each of
+///    the two 128-bit floating-point vectors of [2 x double] to determine if
+///    the value in the first parameter is "unordered" with respect to the
 ///    corresponding value in the second parameter. The comparison yields 0h
 ///    for false, FFFFFFFFFFFFFFFFh for true. A pair of double-precision values
 ///    are "unordered" with respect to each other if one or both values are NaN.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPUNORDSD / CMPUNORDSD instruction.
+/// This intrinsic corresponds to the <c> VCMPUNORDSD / CMPUNORDSD </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -842,7 +844,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNEQSD / CMPNEQSD instruction.
+/// This intrinsic corresponds to the <c> VCMPNEQSD / CMPNEQSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -866,7 +868,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLTSD / CMPNLTSD instruction.
+/// This intrinsic corresponds to the <c> VCMPNLTSD / CMPNLTSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -890,7 +892,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLESD / CMPNLESD instruction.
+/// This intrinsic corresponds to the <c> VCMPNLESD / CMPNLESD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -914,7 +916,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLTSD / CMPNLTSD instruction.
+/// This intrinsic corresponds to the <c> VCMPNLTSD / CMPNLTSD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -939,7 +941,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLESD / CMPNLESD instruction.
+/// This intrinsic corresponds to the <c> VCMPNLESD / CMPNLESD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -962,7 +964,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISD / COMISD instruction.
+/// This intrinsic corresponds to the <c> VCOMISD / COMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -984,7 +986,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISD / COMISD instruction.
+/// This intrinsic corresponds to the <c> VCOMISD / COMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1007,7 +1009,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISD / COMISD instruction.
+/// This intrinsic corresponds to the <c> VCOMISD / COMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1029,7 +1031,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISD / COMISD instruction.
+/// This intrinsic corresponds to the <c> VCOMISD / COMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1052,7 +1054,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISD / COMISD instruction.
+/// This intrinsic corresponds to the <c> VCOMISD / COMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1074,7 +1076,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISD / COMISD instruction.
+/// This intrinsic corresponds to the <c> VCOMISD / COMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1096,7 +1098,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISD / UCOMISD instruction.
+/// This intrinsic corresponds to the <c> VUCOMISD / UCOMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1115,12 +1117,12 @@
 /// \brief Compares the lower double-precision floating-point values in each of
 ///    the two 128-bit floating-point vectors of [2 x double] to determine if
 ///    the value in the first parameter is less than the corresponding value in
-///    the second parameter. The comparison yields 0 for false, 1 for true.
-///    If either of the two lower double-precision values is NaN, 1 is returned.
+///    the second parameter. The comparison yields 0 for false, 1 for true. If
+///    either of the two lower double-precision values is NaN, 1 is returned.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISD / UCOMISD instruction.
+/// This intrinsic corresponds to the <c> VUCOMISD / UCOMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1145,7 +1147,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISD / UCOMISD instruction.
+/// This intrinsic corresponds to the <c> VUCOMISD / UCOMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1169,7 +1171,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISD / UCOMISD instruction.
+/// This intrinsic corresponds to the <c> VUCOMISD / UCOMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1194,7 +1196,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISD / UCOMISD instruction.
+/// This intrinsic corresponds to the <c> VUCOMISD / UCOMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1218,7 +1220,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISD / UCOMISD instruction.
+/// This intrinsic corresponds to the <c> VUCOMISD / UCOMISD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower double-precision value is
@@ -1241,7 +1243,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPD2PS / CVTPD2PS instruction.
+/// This intrinsic corresponds to the <c> VCVTPD2PS / CVTPD2PS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -1260,7 +1262,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPS2PD / CVTPS2PD instruction.
+/// This intrinsic corresponds to the <c> VCVTPS2PD / CVTPS2PD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower two single-precision
@@ -1281,7 +1283,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTDQ2PD / CVTDQ2PD instruction.
+/// This intrinsic corresponds to the <c> VCVTDQ2PD / CVTDQ2PD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector of [4 x i32]. The lower two integer elements are
@@ -1301,7 +1303,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPD2DQ / CVTPD2DQ instruction.
+/// This intrinsic corresponds to the <c> VCVTPD2DQ / CVTPD2DQ </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -1318,7 +1320,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSD2SI / CVTSD2SI instruction.
+/// This intrinsic corresponds to the <c> VCVTSD2SI / CVTSD2SI </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower 64 bits are used in the
@@ -1338,7 +1340,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSD2SS / CVTSD2SS instruction.
+/// This intrinsic corresponds to the <c> VCVTSD2SS / CVTSD2SS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The upper 96 bits of this parameter are
@@ -1362,7 +1364,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSI2SD / CVTSI2SD instruction.
+/// This intrinsic corresponds to the <c> VCVTSI2SD / CVTSI2SD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The upper 64 bits of this parameter are
@@ -1387,7 +1389,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSS2SD / CVTSS2SD instruction.
+/// This intrinsic corresponds to the <c> VCVTSS2SD / CVTSS2SD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The upper 64 bits of this parameter are
@@ -1414,7 +1416,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTTPD2DQ / CVTTPD2DQ instruction.
+/// This intrinsic corresponds to the <c> VCVTTPD2DQ / CVTTPD2DQ </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -1431,7 +1434,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTTSD2SI / CVTTSD2SI instruction.
+/// This intrinsic corresponds to the <c> VCVTTSD2SI / CVTTSD2SI </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower 64 bits are used in the
@@ -1449,7 +1453,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPD2PI instruction.
+/// This intrinsic corresponds to the <c> CVTPD2PI </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -1468,7 +1472,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTTPD2PI instruction.
+/// This intrinsic corresponds to the <c> CVTTPD2PI </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double].
@@ -1485,7 +1489,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPI2PD instruction.
+/// This intrinsic corresponds to the <c> CVTPI2PD </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit vector of [2 x i32].
@@ -1518,7 +1522,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPD / MOVAPD instruction.
+/// This intrinsic corresponds to the <c> VMOVAPD / MOVAPD </c> instruction.
 ///
 /// \param __dp
 ///    A pointer to a 128-bit memory location. The address of the memory
@@ -1536,7 +1540,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDDUP / MOVDDUP instruction.
+/// This intrinsic corresponds to the <c> VMOVDDUP / MOVDDUP </c> instruction.
 ///
 /// \param __dp
 ///    A pointer to a memory location containing a double-precision value.
@@ -1559,9 +1563,9 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPD / MOVAPD instruction + needed
-/// shuffling instructions. In AVX mode, the shuffling may be combined with the
-/// \c VMOVAPD, resulting in only a \c VPERMILPD instruction.
+/// This intrinsic corresponds to the <c> VMOVAPD / MOVAPD </c> instruction +
+/// needed shuffling instructions. In AVX mode, the shuffling may be combined
+/// with the \c VMOVAPD, resulting in only a \c VPERMILPD instruction.
 ///
 /// \param __dp
 ///    A 16-byte aligned pointer to an array of double-precision values to be
@@ -1580,7 +1584,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVUPD / MOVUPD instruction.
+/// This intrinsic corresponds to the <c> VMOVUPD / MOVUPD </c> instruction.
 ///
 /// \param __dp
 ///    A pointer to a 128-bit memory location. The address of the memory
@@ -1595,6 +1599,17 @@
   return ((struct __loadu_pd*)__dp)->__v;
 }
 
+/// \brief Loads a 64-bit integer value to the low element of a 128-bit integer
+///    vector and clears the upper element.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction.
+///
+/// \param __dp
+///    A pointer to a 64-bit memory location. The address of the memory
+///    location does not have to be aligned.
+/// \returns A 128-bit vector of [2 x i64] containing the loaded value.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_loadu_si64(void const *__a)
 {
@@ -1605,6 +1620,17 @@
   return (__m128i){__u, 0L};
 }
 
+/// \brief Loads a 64-bit double-precision value to the low element of a
+///    128-bit integer vector and clears the upper element.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VMOVSD / MOVSD </c> instruction.
+///
+/// \param __dp
+///    An pointer to a memory location containing a double-precision value.
+///    The address of the memory location does not have to be aligned.
+/// \returns A 128-bit vector of [2 x double] containing the loaded value.
 static __inline__ __m128d __DEFAULT_FN_ATTRS
 _mm_load_sd(double const *__dp)
 {
@@ -1621,10 +1647,10 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVHPD / MOVHPD instruction.
+/// This intrinsic corresponds to the <c> VMOVHPD / MOVHPD </c> instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [2 x double].
+///    A 128-bit vector of [2 x double]. \n
 ///    Bits [63:0] are written to bits [63:0] of the result.
 /// \param __dp
 ///    A pointer to a 64-bit memory location containing a double-precision
@@ -1648,10 +1674,10 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVLPD / MOVLPD instruction.
+/// This intrinsic corresponds to the <c> VMOVLPD / MOVLPD </c> instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [2 x double].
+///    A 128-bit vector of [2 x double]. \n
 ///    Bits [127:64] are written to bits [127:64] of the result.
 /// \param __dp
 ///    A pointer to a 64-bit memory location containing a double-precision
@@ -1692,7 +1718,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVQ / MOVQ instruction.
+/// This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction.
 ///
 /// \param __w
 ///    A double-precision floating-point value used to initialize the lower 64
@@ -1712,7 +1738,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDDUP / MOVLHPS instruction.
+/// This intrinsic corresponds to the <c> VMOVDDUP / MOVLHPS </c> instruction.
 ///
 /// \param __w
 ///    A double-precision floating-point value used to initialize each vector
@@ -1729,7 +1755,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKLPD / UNPCKLPD instruction.
+/// This intrinsic corresponds to the <c> VUNPCKLPD / UNPCKLPD </c> instruction.
 ///
 /// \param __w
 ///    A double-precision floating-point value used to initialize the upper 64
@@ -1750,7 +1776,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKLPD / UNPCKLPD instruction.
+/// This intrinsic corresponds to the <c> VUNPCKLPD / UNPCKLPD </c> instruction.
 ///
 /// \param __w
 ///    A double-precision floating-point value used to initialize the lower 64
@@ -1770,7 +1796,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VXORPS / XORPS instruction.
+/// This intrinsic corresponds to the <c> VXORPS / XORPS </c> instruction.
 ///
 /// \returns An initialized 128-bit floating-point vector of [2 x double] with
 ///    all elements set to zero.
@@ -1786,7 +1812,7 @@
 //
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VBLENDPD / BLENDPD instruction.
+/// This intrinsic corresponds to the <c> VBLENDPD / BLENDPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The upper 64 bits are written to the
@@ -1806,7 +1832,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSD / MOVSD instruction.
+/// This intrinsic corresponds to the <c> VMOVSD / MOVSD </c> instruction.
 ///
 /// \param __dp
 ///    A pointer to a 64-bit memory location.
@@ -1839,7 +1865,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPD / MOVAPD instruction.
+/// This intrinsic corresponds to the <c> VMOVAPD / MOVAPD </c> instruction.
 ///
 /// \param __dp
 ///    A pointer to a 128-bit memory location. The address of the memory
@@ -1857,7 +1883,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVUPD / MOVUPD instruction.
+/// This intrinsic corresponds to the <c> VMOVUPD / MOVUPD </c> instruction.
 ///
 /// \param __dp
 ///    A pointer to a 128-bit memory location. The address of the memory
@@ -1879,7 +1905,7 @@
 /// \headerfile <x86intrin.h>
 ///
 /// This intrinsic corresponds to a shuffling instruction followed by a
-/// \c VMOVAPD / MOVAPD instruction.
+/// <c> VMOVAPD / MOVAPD </c> instruction.
 ///
 /// \param __dp
 ///    A pointer to a 16-byte aligned memory location that can store two
@@ -1899,7 +1925,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVHPD / MOVHPD instruction.
+/// This intrinsic corresponds to the <c> VMOVHPD / MOVHPD </c> instruction.
 ///
 /// \param __dp
 ///    A pointer to a 64-bit memory location.
@@ -1919,7 +1945,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVLPD / MOVLPD instruction.
+/// This intrinsic corresponds to the <c> VMOVLPD / MOVLPD </c> instruction.
 ///
 /// \param __dp
 ///    A pointer to a 64-bit memory location.
@@ -1941,7 +1967,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPADDB / PADDB instruction.
+/// This intrinsic corresponds to the <c> VPADDB / PADDB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [16 x i8].
@@ -1962,7 +1988,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPADDW / PADDW instruction.
+/// This intrinsic corresponds to the <c> VPADDW / PADDW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [8 x i16].
@@ -1983,7 +2009,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPADDD / PADDD instruction.
+/// This intrinsic corresponds to the <c> VPADDD / PADDD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x i32].
@@ -2002,7 +2028,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PADDQ instruction.
+/// This intrinsic corresponds to the <c> PADDQ </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer.
@@ -2022,7 +2048,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPADDQ / PADDQ instruction.
+/// This intrinsic corresponds to the <c> VPADDQ / PADDQ </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x i64].
@@ -2043,7 +2069,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPADDSB / PADDSB instruction.
+/// This intrinsic corresponds to the <c> VPADDSB / PADDSB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit signed [16 x i8] vector.
@@ -2065,7 +2091,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPADDSW / PADDSW instruction.
+/// This intrinsic corresponds to the <c> VPADDSW / PADDSW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit signed [8 x i16] vector.
@@ -2086,7 +2112,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPADDUSB / PADDUSB instruction.
+/// This intrinsic corresponds to the <c> VPADDUSB / PADDUSB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit unsigned [16 x i8] vector.
@@ -2107,7 +2133,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPADDUSB / PADDUSB instruction.
+/// This intrinsic corresponds to the <c> VPADDUSB / PADDUSB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit unsigned [8 x i16] vector.
@@ -2127,7 +2153,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPAVGB / PAVGB instruction.
+/// This intrinsic corresponds to the <c> VPAVGB / PAVGB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit unsigned [16 x i8] vector.
@@ -2147,7 +2173,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPAVGW / PAVGW instruction.
+/// This intrinsic corresponds to the <c> VPAVGW / PAVGW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit unsigned [8 x i16] vector.
@@ -2171,7 +2197,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMADDWD / PMADDWD instruction.
+/// This intrinsic corresponds to the <c> VPMADDWD / PMADDWD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit signed [8 x i16] vector.
@@ -2191,7 +2217,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMAXSW / PMAXSW instruction.
+/// This intrinsic corresponds to the <c> VPMAXSW / PMAXSW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit signed [8 x i16] vector.
@@ -2211,7 +2237,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMAXUB / PMAXUB instruction.
+/// This intrinsic corresponds to the <c> VPMAXUB / PMAXUB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit unsigned [16 x i8] vector.
@@ -2231,7 +2257,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMINSW / PMINSW instruction.
+/// This intrinsic corresponds to the <c> VPMINSW / PMINSW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit signed [8 x i16] vector.
@@ -2251,7 +2277,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMINUB / PMINUB instruction.
+/// This intrinsic corresponds to the <c> VPMINUB / PMINUB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit unsigned [16 x i8] vector.
@@ -2271,7 +2297,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMULHW / PMULHW instruction.
+/// This intrinsic corresponds to the <c> VPMULHW / PMULHW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit signed [8 x i16] vector.
@@ -2291,7 +2317,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMULHUW / PMULHUW instruction.
+/// This intrinsic corresponds to the <c> VPMULHUW / PMULHUW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit unsigned [8 x i16] vector.
@@ -2311,7 +2337,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMULLW / PMULLW instruction.
+/// This intrinsic corresponds to the <c> VPMULLW / PMULLW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit signed [8 x i16] vector.
@@ -2331,7 +2357,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMULUDQ instruction.
+/// This intrinsic corresponds to the <c> PMULUDQ </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer containing one of the source operands.
@@ -2350,7 +2376,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMULUDQ / PMULUDQ instruction.
+/// This intrinsic corresponds to the <c> VPMULUDQ / PMULUDQ </c> instruction.
 ///
 /// \param __a
 ///    A [2 x i64] vector containing one of the source operands.
@@ -2365,13 +2391,13 @@
 
 /// \brief Computes the absolute differences of corresponding 8-bit integer
 ///    values in two 128-bit vectors. Sums the first 8 absolute differences, and
-///    separately sums the second 8 absolute differences. Packss these two
+///    separately sums the second 8 absolute differences. Packs these two
 ///    unsigned 16-bit integer sums into the upper and lower elements of a
 ///    [2 x i64] vector.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSADBW / PSADBW instruction.
+/// This intrinsic corresponds to the <c> VPSADBW / PSADBW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing one of the source operands.
@@ -2389,7 +2415,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSUBB / PSUBB instruction.
+/// This intrinsic corresponds to the <c> VPSUBB / PSUBB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the minuends.
@@ -2407,7 +2433,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSUBW / PSUBW instruction.
+/// This intrinsic corresponds to the <c> VPSUBW / PSUBW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the minuends.
@@ -2425,7 +2451,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSUBD / PSUBD instruction.
+/// This intrinsic corresponds to the <c> VPSUBD / PSUBD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the minuends.
@@ -2444,7 +2470,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSUBQ instruction.
+/// This intrinsic corresponds to the <c> PSUBQ </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing the minuend.
@@ -2462,7 +2488,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSUBQ / PSUBQ instruction.
+/// This intrinsic corresponds to the <c> VPSUBQ / PSUBQ </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the minuends.
@@ -2483,7 +2509,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSUBSB / PSUBSB instruction.
+/// This intrinsic corresponds to the <c> VPSUBSB / PSUBSB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the minuends.
@@ -2504,7 +2530,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSUBSW / PSUBSW instruction.
+/// This intrinsic corresponds to the <c> VPSUBSW / PSUBSW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the minuends.
@@ -2524,7 +2550,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSUBUSB / PSUBUSB instruction.
+/// This intrinsic corresponds to the <c> VPSUBUSB / PSUBUSB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the minuends.
@@ -2544,7 +2570,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSUBUSW / PSUBUSW instruction.
+/// This intrinsic corresponds to the <c> VPSUBUSW / PSUBUSW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the minuends.
@@ -2562,7 +2588,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPAND / PAND instruction.
+/// This intrinsic corresponds to the <c> VPAND / PAND </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing one of the source operands.
@@ -2581,7 +2607,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPANDN / PANDN instruction.
+/// This intrinsic corresponds to the <c> VPANDN / PANDN </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector containing the left source operand. The one's complement
@@ -2599,7 +2625,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPOR / POR instruction.
+/// This intrinsic corresponds to the <c> VPOR / POR </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing one of the source operands.
@@ -2617,7 +2643,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPXOR / PXOR instruction.
+/// This intrinsic corresponds to the <c> VPXOR / PXOR </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing one of the source operands.
@@ -2640,13 +2666,13 @@
 /// __m128i _mm_slli_si128(__m128i a, const int imm);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPSLLDQ / PSLLDQ instruction.
+/// This intrinsic corresponds to the <c> VPSLLDQ / PSLLDQ </c> instruction.
 ///
 /// \param a
 ///    A 128-bit integer vector containing the source operand.
 /// \param imm
-///    An immediate value specifying the number of bytes to left-shift
-///    operand \a a.
+///    An immediate value specifying the number of bytes to left-shift operand
+///    \a a.
 /// \returns A 128-bit integer vector containing the left-shifted value.
 #define _mm_slli_si128(a, imm) __extension__ ({                              \
   (__m128i)__builtin_shufflevector(                                          \
@@ -2677,7 +2703,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSLLW / PSLLW instruction.
+/// This intrinsic corresponds to the <c> VPSLLW / PSLLW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2696,7 +2722,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSLLW / PSLLW instruction.
+/// This intrinsic corresponds to the <c> VPSLLW / PSLLW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2715,7 +2741,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSLLD / PSLLD instruction.
+/// This intrinsic corresponds to the <c> VPSLLD / PSLLD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2734,7 +2760,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSLLD / PSLLD instruction.
+/// This intrinsic corresponds to the <c> VPSLLD / PSLLD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2753,7 +2779,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSLLQ / PSLLQ instruction.
+/// This intrinsic corresponds to the <c> VPSLLQ / PSLLQ </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2772,7 +2798,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSLLQ / PSLLQ instruction.
+/// This intrinsic corresponds to the <c> VPSLLQ / PSLLQ </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2792,7 +2818,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRAW / PSRAW instruction.
+/// This intrinsic corresponds to the <c> VPSRAW / PSRAW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2812,7 +2838,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRAW / PSRAW instruction.
+/// This intrinsic corresponds to the <c> VPSRAW / PSRAW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2832,7 +2858,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRAD / PSRAD instruction.
+/// This intrinsic corresponds to the <c> VPSRAD / PSRAD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2852,7 +2878,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRAD / PSRAD instruction.
+/// This intrinsic corresponds to the <c> VPSRAD / PSRAD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2875,7 +2901,7 @@
 /// __m128i _mm_srli_si128(__m128i a, const int imm);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPSRLDQ / PSRLDQ instruction.
+/// This intrinsic corresponds to the <c> VPSRLDQ / PSRLDQ </c> instruction.
 ///
 /// \param a
 ///    A 128-bit integer vector containing the source operand.
@@ -2912,7 +2938,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRLW / PSRLW instruction.
+/// This intrinsic corresponds to the <c> VPSRLW / PSRLW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2931,7 +2957,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRLW / PSRLW instruction.
+/// This intrinsic corresponds to the <c> VPSRLW / PSRLW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2950,7 +2976,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRLD / PSRLD instruction.
+/// This intrinsic corresponds to the <c> VPSRLD / PSRLD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2969,7 +2995,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRLD / PSRLD instruction.
+/// This intrinsic corresponds to the <c> VPSRLD / PSRLD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -2988,7 +3014,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRLQ / PSRLQ instruction.
+/// This intrinsic corresponds to the <c> VPSRLQ / PSRLQ </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -3007,7 +3033,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSRLQ / PSRLQ instruction.
+/// This intrinsic corresponds to the <c> VPSRLQ / PSRLQ </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the source operand.
@@ -3027,7 +3053,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPCMPEQB / PCMPEQB instruction.
+/// This intrinsic corresponds to the <c> VPCMPEQB / PCMPEQB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3046,7 +3072,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPCMPEQW / PCMPEQW instruction.
+/// This intrinsic corresponds to the <c> VPCMPEQW / PCMPEQW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3065,7 +3091,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPCMPEQD / PCMPEQD instruction.
+/// This intrinsic corresponds to the <c> VPCMPEQD / PCMPEQD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3085,7 +3111,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPCMPGTB / PCMPGTB instruction.
+/// This intrinsic corresponds to the <c> VPCMPGTB / PCMPGTB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3107,7 +3133,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPCMPGTW / PCMPGTW instruction.
+/// This intrinsic corresponds to the <c> VPCMPGTW / PCMPGTW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3127,7 +3153,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPCMPGTD / PCMPGTD instruction.
+/// This intrinsic corresponds to the <c> VPCMPGTD / PCMPGTD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3147,7 +3173,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPCMPGTB / PCMPGTB instruction.
+/// This intrinsic corresponds to the <c> VPCMPGTB / PCMPGTB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3167,7 +3193,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPCMPGTW / PCMPGTW instruction.
+/// This intrinsic corresponds to the <c> VPCMPGTW / PCMPGTW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3187,7 +3213,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPCMPGTD / PCMPGTD instruction.
+/// This intrinsic corresponds to the <c> VPCMPGTD / PCMPGTD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3208,7 +3234,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSI2SD / CVTSI2SD instruction.
+/// This intrinsic corresponds to the <c> VCVTSI2SD / CVTSI2SD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The upper 64 bits of this operand are
@@ -3230,7 +3256,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSD2SI / CVTSD2SI instruction.
+/// This intrinsic corresponds to the <c> VCVTSD2SI / CVTSD2SI </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower 64 bits are used in the
@@ -3247,7 +3273,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTTSD2SI / CVTTSD2SI instruction.
+/// This intrinsic corresponds to the <c> VCVTTSD2SI / CVTTSD2SI </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. The lower 64 bits are used in the
@@ -3264,7 +3291,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTDQ2PS / CVTDQ2PS instruction.
+/// This intrinsic corresponds to the <c> VCVTDQ2PS / CVTDQ2PS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
@@ -3279,7 +3306,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPS2DQ / CVTPS2DQ instruction.
+/// This intrinsic corresponds to the <c> VCVTPS2DQ / CVTPS2DQ </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -3296,7 +3323,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTTPS2DQ / CVTTPS2DQ instruction.
+/// This intrinsic corresponds to the <c> VCVTTPS2DQ / CVTTPS2DQ </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -3312,7 +3340,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVD / MOVD instruction.
+/// This intrinsic corresponds to the <c> VMOVD / MOVD </c> instruction.
 ///
 /// \param __a
 ///    A 32-bit signed integer operand.
@@ -3329,7 +3357,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVQ / MOVQ instruction.
+/// This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit signed integer operand containing the value to be converted.
@@ -3346,7 +3374,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVD / MOVD instruction.
+/// This intrinsic corresponds to the <c> VMOVD / MOVD </c> instruction.
 ///
 /// \param __a
 ///    A vector of [4 x i32]. The least significant 32 bits are moved to the
@@ -3365,7 +3393,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVQ / MOVQ instruction.
+/// This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction.
 ///
 /// \param __a
 ///    A vector of [2 x i64]. The least significant 64 bits are moved to the
@@ -3383,7 +3411,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDQA / MOVDQA instruction.
+/// This intrinsic corresponds to the <c> VMOVDQA / MOVDQA </c> instruction.
 ///
 /// \param __p
 ///    An aligned pointer to a memory location containing integer values.
@@ -3399,7 +3427,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDQU / MOVDQU instruction.
+/// This intrinsic corresponds to the <c> VMOVDQU / MOVDQU </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location containing integer values.
@@ -3418,7 +3446,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVQ / MOVQ instruction.
+/// This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction.
 ///
 /// \param __p
 ///    A 128-bit vector of [2 x i64]. Bits [63:0] are written to bits [63:0] of
@@ -3709,7 +3737,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKLQDQ / PUNPCKLQDQ instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKLQDQ / PUNPCKLQDQ </c>
+///   instruction.
 ///
 /// \param __q0
 ///    A 64-bit integral value used to initialize the lower 64 bits of the
@@ -3829,7 +3858,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VXORPS / XORPS instruction.
+/// This intrinsic corresponds to the <c> VXORPS / XORPS </c> instruction.
 ///
 /// \returns An initialized 128-bit integer vector with all elements set to
 ///    zero.
@@ -3844,7 +3873,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPS / MOVAPS instruction.
+/// This intrinsic corresponds to the <c> VMOVAPS / MOVAPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to an aligned memory location that will receive the integer
@@ -3861,7 +3890,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVUPS / MOVUPS instruction.
+/// This intrinsic corresponds to the <c> VMOVUPS / MOVUPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that will receive the integer values.
@@ -3885,7 +3914,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMASKMOVDQU / MASKMOVDQU instruction.
+/// This intrinsic corresponds to the <c> VMASKMOVDQU / MASKMOVDQU </c>
+///   instruction.
 ///
 /// \param __d
 ///    A 128-bit integer vector containing the values to be moved.
@@ -3906,7 +3936,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVLPS / MOVLPS instruction.
+/// This intrinsic corresponds to the <c> VMOVLPS / MOVLPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 64-bit memory location that will receive the lower 64 bits
@@ -3929,7 +3959,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVNTPS / MOVNTPS instruction.
+/// This intrinsic corresponds to the <c> VMOVNTPS / MOVNTPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to the 128-bit aligned memory location used to store the value.
@@ -3947,7 +3977,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVNTPS / MOVNTPS instruction.
+/// This intrinsic corresponds to the <c> VMOVNTPS / MOVNTPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to the 128-bit aligned memory location used to store the value.
@@ -3965,7 +3995,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c MOVNTI instruction.
+/// This intrinsic corresponds to the <c> MOVNTI </c> instruction.
 ///
 /// \param __p
 ///    A pointer to the 32-bit memory location used to store the value.
@@ -3984,7 +4014,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c MOVNTIQ instruction.
+/// This intrinsic corresponds to the <c> MOVNTIQ </c> instruction.
 ///
 /// \param __p
 ///    A pointer to the 64-bit memory location used to store the value.
@@ -4006,12 +4036,12 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CLFLUSH instruction.
+/// This intrinsic corresponds to the <c> CLFLUSH </c> instruction.
 ///
 /// \param __p
 ///    A pointer to the memory location used to identify the cache line to be
 ///    flushed.
-void _mm_clflush(void const *);
+void _mm_clflush(void const * __p);
 
 /// \brief Forces strong memory ordering (serialization) between load
 ///    instructions preceding this instruction and load instructions following
@@ -4020,7 +4050,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c LFENCE instruction.
+/// This intrinsic corresponds to the <c> LFENCE </c> instruction.
 ///
 void _mm_lfence(void);
 
@@ -4031,7 +4061,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c MFENCE instruction.
+/// This intrinsic corresponds to the <c> MFENCE </c> instruction.
 ///
 void _mm_mfence(void);
 
@@ -4046,7 +4076,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPACKSSWB / PACKSSWB instruction.
+/// This intrinsic corresponds to the <c> VPACKSSWB / PACKSSWB </c> instruction.
 ///
 /// \param __a
 ///   A 128-bit integer vector of [8 x i16]. Each 16-bit element is treated as
@@ -4074,7 +4104,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPACKSSDW / PACKSSDW instruction.
+/// This intrinsic corresponds to the <c> VPACKSSDW / PACKSSDW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector of [4 x i32]. Each 32-bit element is treated as
@@ -4102,7 +4132,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPACKUSWB / PACKUSWB instruction.
+/// This intrinsic corresponds to the <c> VPACKUSWB / PACKUSWB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector of [8 x i16]. Each 16-bit element is treated as
@@ -4128,20 +4158,20 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPEXTRW / PEXTRW instruction.
+/// This intrinsic corresponds to the <c> VPEXTRW / PEXTRW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector.
 /// \param __imm
-///    An immediate value. Bits [3:0] selects values from \a __a to be assigned
-///    to bits[15:0] of the result.
-///    000: assign values from bits [15:0] of \a __a.
-///    001: assign values from bits [31:16] of \a __a.
-///    010: assign values from bits [47:32] of \a __a.
-///    011: assign values from bits [63:48] of \a __a.
-///    100: assign values from bits [79:64] of \a __a.
-///    101: assign values from bits [95:80] of \a __a.
-///    110: assign values from bits [111:96] of \a __a.
+///    An immediate value. Bits [2:0] selects values from \a __a to be assigned
+///    to bits[15:0] of the result. \n
+///    000: assign values from bits [15:0] of \a __a. \n
+///    001: assign values from bits [31:16] of \a __a. \n
+///    010: assign values from bits [47:32] of \a __a. \n
+///    011: assign values from bits [63:48] of \a __a. \n
+///    100: assign values from bits [79:64] of \a __a. \n
+///    101: assign values from bits [95:80] of \a __a. \n
+///    110: assign values from bits [111:96] of \a __a. \n
 ///    111: assign values from bits [127:112] of \a __a.
 /// \returns An integer, whose lower 16 bits are selected from the 128-bit
 ///    integer vector parameter and the remaining bits are assigned zeros.
@@ -4159,7 +4189,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPINSRW / PINSRW instruction.
+/// This intrinsic corresponds to the <c> VPINSRW / PINSRW </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector of [8 x i16]. This vector is copied to the
@@ -4186,7 +4216,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPMOVMSKB / PMOVMSKB instruction.
+/// This intrinsic corresponds to the <c> VPMOVMSKB / PMOVMSKB </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector containing the values with bits to be extracted.
@@ -4208,23 +4238,23 @@
 /// __m128i _mm_shuffle_epi32(__m128i a, const int imm);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPSHUFD / PSHUFD instruction.
+/// This intrinsic corresponds to the <c> VPSHUFD / PSHUFD </c> instruction.
 ///
 /// \param a
 ///    A 128-bit integer vector containing the values to be copied.
 /// \param imm
 ///    An immediate value containing an 8-bit value specifying which elements to
 ///    copy from a. The destinations within the 128-bit destination are assigned
-///    values as follows:
-///    Bits [1:0] are used to assign values to bits [31:0] of the result.
-///    Bits [3:2] are used to assign values to bits [63:32] of the result.
-///    Bits [5:4] are used to assign values to bits [95:64] of the result.
-///    Bits [7:6] are used to assign values to bits [127:96] of the result.
-///    Bit value assignments:
-///    00: assign values from bits [31:0] of a.
-///    01: assign values from bits [63:32] of a.
-///    10: assign values from bits [95:64] of a.
-///    11: assign values from bits [127:96] of a.
+///    values as follows: \n
+///    Bits [1:0] are used to assign values to bits [31:0] of the result. \n
+///    Bits [3:2] are used to assign values to bits [63:32] of the result. \n
+///    Bits [5:4] are used to assign values to bits [95:64] of the result. \n
+///    Bits [7:6] are used to assign values to bits [127:96] of the result. \n
+///    Bit value assignments: \n
+///    00: assign values from bits [31:0] of \a a. \n
+///    01: assign values from bits [63:32] of \a a. \n
+///    10: assign values from bits [95:64] of \a a. \n
+///    11: assign values from bits [127:96] of \a a.
 /// \returns A 128-bit integer vector containing the shuffled values.
 #define _mm_shuffle_epi32(a, imm) __extension__ ({ \
   (__m128i)__builtin_shufflevector((__v4si)(__m128i)(a), \
@@ -4242,22 +4272,22 @@
 /// __m128i _mm_shufflelo_epi16(__m128i a, const int imm);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPSHUFLW / PSHUFLW instruction.
+/// This intrinsic corresponds to the <c> VPSHUFLW / PSHUFLW </c> instruction.
 ///
 /// \param a
 ///    A 128-bit integer vector of [8 x i16]. Bits [127:64] are copied to bits
 ///    [127:64] of the result.
 /// \param imm
-///    An 8-bit immediate value specifying which elements to copy from a.
-///    Bits[1:0] are used to assign values to bits [15:0] of the result.
-///    Bits[3:2] are used to assign values to bits [31:16] of the result.
-///    Bits[5:4] are used to assign values to bits [47:32] of the result.
-///    Bits[7:6] are used to assign values to bits [63:48] of the result.
-///    Bit value assignments:
-///    00: assign values from bits [15:0] of a.
-///    01: assign values from bits [31:16] of a.
-///    10: assign values from bits [47:32] of a.
-///    11: assign values from bits [63:48] of a.
+///    An 8-bit immediate value specifying which elements to copy from \a a. \n
+///    Bits[1:0] are used to assign values to bits [15:0] of the result. \n
+///    Bits[3:2] are used to assign values to bits [31:16] of the result. \n
+///    Bits[5:4] are used to assign values to bits [47:32] of the result. \n
+///    Bits[7:6] are used to assign values to bits [63:48] of the result. \n
+///    Bit value assignments: \n
+///    00: assign values from bits [15:0] of \a a. \n
+///    01: assign values from bits [31:16] of \a a. \n
+///    10: assign values from bits [47:32] of \a a. \n
+///    11: assign values from bits [63:48] of \a a. \n
 /// \returns A 128-bit integer vector containing the shuffled values.
 #define _mm_shufflelo_epi16(a, imm) __extension__ ({ \
   (__m128i)__builtin_shufflevector((__v8hi)(__m128i)(a), \
@@ -4276,22 +4306,22 @@
 /// __m128i _mm_shufflehi_epi16(__m128i a, const int imm);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPSHUFHW / PSHUFHW instruction.
+/// This intrinsic corresponds to the <c> VPSHUFHW / PSHUFHW </c> instruction.
 ///
 /// \param a
 ///    A 128-bit integer vector of [8 x i16]. Bits [63:0] are copied to bits
 ///    [63:0] of the result.
 /// \param imm
-///    An 8-bit immediate value specifying which elements to copy from a.
-///    Bits[1:0] are used to assign values to bits [79:64] of the result.
-///    Bits[3:2] are used to assign values to bits [95:80] of the result.
-///    Bits[5:4] are used to assign values to bits [111:96] of the result.
-///    Bits[7:6] are used to assign values to bits [127:112] of the result.
-///    Bit value assignments:
-///    00: assign values from bits [79:64] of a.
-///    01: assign values from bits [95:80] of a.
-///    10: assign values from bits [111:96] of a.
-///    11: assign values from bits [127:112] of a.
+///    An 8-bit immediate value specifying which elements to copy from \a a. \n
+///    Bits[1:0] are used to assign values to bits [79:64] of the result. \n
+///    Bits[3:2] are used to assign values to bits [95:80] of the result. \n
+///    Bits[5:4] are used to assign values to bits [111:96] of the result. \n
+///    Bits[7:6] are used to assign values to bits [127:112] of the result. \n
+///    Bit value assignments: \n
+///    00: assign values from bits [79:64] of \a a. \n
+///    01: assign values from bits [95:80] of \a a. \n
+///    10: assign values from bits [111:96] of \a a. \n
+///    11: assign values from bits [127:112] of \a a. \n
 /// \returns A 128-bit integer vector containing the shuffled values.
 #define _mm_shufflehi_epi16(a, imm) __extension__ ({ \
   (__m128i)__builtin_shufflevector((__v8hi)(__m128i)(a), \
@@ -4307,28 +4337,29 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKHBW / PUNPCKHBW instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKHBW / PUNPCKHBW </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [16 x i8].
-///    Bits [71:64] are written to bits [7:0] of the result
-///    Bits [79:72] are written to bits [23:16] of the result.
-///    Bits [87:80] are written to bits [39:32] of the result.
-///    Bits [95:88] are written to bits [55:48] of the result.
-///    Bits [103:96] are written to bits [71:64] of the result.
-///    Bits [111:104] are written to bits [87:80] of the result.
-///    Bits [119:112] are written to bits [103:96] of the result.
+///    Bits [71:64] are written to bits [7:0] of the result. \n
+///    Bits [79:72] are written to bits [23:16] of the result. \n
+///    Bits [87:80] are written to bits [39:32] of the result. \n
+///    Bits [95:88] are written to bits [55:48] of the result. \n
+///    Bits [103:96] are written to bits [71:64] of the result. \n
+///    Bits [111:104] are written to bits [87:80] of the result. \n
+///    Bits [119:112] are written to bits [103:96] of the result. \n
 ///    Bits [127:120] are written to bits [119:112] of the result.
 /// \param __b
-///    A 128-bit vector of [16 x i8].
-///    Bits [71:64] are written to bits [15:8] of the result.
-///    Bits [79:72] are written to bits [31:24] of the result.
-///    Bits [87:80] are written to bits [47:40] of the result.
-///    Bits [95:88] are written to bits [63:56] of the result.
-///    Bits [103:96] are written to bits [79:72] of the result.
-///    Bits [111:104] are written to bits [95:88] of the result.
-///    Bits [119:112] are written to bits [111:104] of the result.
-///    Bits [127:120] are written to bits [127:120] of the destination.
+///    A 128-bit vector of [16 x i8]. \n
+///    Bits [71:64] are written to bits [15:8] of the result. \n
+///    Bits [79:72] are written to bits [31:24] of the result. \n
+///    Bits [87:80] are written to bits [47:40] of the result. \n
+///    Bits [95:88] are written to bits [63:56] of the result. \n
+///    Bits [103:96] are written to bits [79:72] of the result. \n
+///    Bits [111:104] are written to bits [95:88] of the result. \n
+///    Bits [119:112] are written to bits [111:104] of the result. \n
+///    Bits [127:120] are written to bits [127:120] of the result.
 /// \returns A 128-bit vector of [16 x i8] containing the interleaved values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_unpackhi_epi8(__m128i __a, __m128i __b)
@@ -4341,19 +4372,20 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKHWD / PUNPCKHWD instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKHWD / PUNPCKHWD </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [8 x i16].
-///    Bits [79:64] are written to bits [15:0] of the result.
-///    Bits [95:80] are written to bits [47:32] of the result.
-///    Bits [111:96] are written to bits [79:64] of the result.
+///    Bits [79:64] are written to bits [15:0] of the result. \n
+///    Bits [95:80] are written to bits [47:32] of the result. \n
+///    Bits [111:96] are written to bits [79:64] of the result. \n
 ///    Bits [127:112] are written to bits [111:96] of the result.
 /// \param __b
 ///    A 128-bit vector of [8 x i16].
-///    Bits [79:64] are written to bits [31:16] of the result.
-///    Bits [95:80] are written to bits [63:48] of the result.
-///    Bits [111:96] are written to bits [95:80] of the result.
+///    Bits [79:64] are written to bits [31:16] of the result. \n
+///    Bits [95:80] are written to bits [63:48] of the result. \n
+///    Bits [111:96] are written to bits [95:80] of the result. \n
 ///    Bits [127:112] are written to bits [127:112] of the result.
 /// \returns A 128-bit vector of [8 x i16] containing the interleaved values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
@@ -4367,15 +4399,16 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKHDQ / PUNPCKHDQ instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKHDQ / PUNPCKHDQ </c>
+///   instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [4 x i32].
-///    Bits [95:64] are written to bits [31:0] of the destination.
+///    A 128-bit vector of [4 x i32]. \n
+///    Bits [95:64] are written to bits [31:0] of the destination. \n
 ///    Bits [127:96] are written to bits [95:64] of the destination.
 /// \param __b
-///    A 128-bit vector of [4 x i32].
-///    Bits [95:64] are written to bits [64:32] of the destination.
+///    A 128-bit vector of [4 x i32]. \n
+///    Bits [95:64] are written to bits [64:32] of the destination. \n
 ///    Bits [127:96] are written to bits [127:96] of the destination.
 /// \returns A 128-bit vector of [4 x i32] containing the interleaved values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
@@ -4389,13 +4422,14 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKHQDQ / PUNPCKHQDQ instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKHQDQ / PUNPCKHQDQ </c>
+///   instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [2 x i64].
+///    A 128-bit vector of [2 x i64]. \n
 ///    Bits [127:64] are written to bits [63:0] of the destination.
 /// \param __b
-///    A 128-bit vector of [2 x i64].
+///    A 128-bit vector of [2 x i64]. \n
 ///    Bits [127:64] are written to bits [127:64] of the destination.
 /// \returns A 128-bit vector of [2 x i64] containing the interleaved values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
@@ -4409,27 +4443,28 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKLBW / PUNPCKLBW instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKLBW / PUNPCKLBW </c>
+///   instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [16 x i8].
-///    Bits [7:0] are written to bits [7:0] of the result.
-///    Bits [15:8] are written to bits [23:16] of the result.
-///    Bits [23:16] are written to bits [39:32] of the result.
-///    Bits [31:24] are written to bits [55:48] of the result.
-///    Bits [39:32] are written to bits [71:64] of the result.
-///    Bits [47:40] are written to bits [87:80] of the result.
-///    Bits [55:48] are written to bits [103:96] of the result.
-///    Bits [63:56] are written to bits [119:112] of the destination.
+///    A 128-bit vector of [16 x i8]. \n
+///    Bits [7:0] are written to bits [7:0] of the result. \n
+///    Bits [15:8] are written to bits [23:16] of the result. \n
+///    Bits [23:16] are written to bits [39:32] of the result. \n
+///    Bits [31:24] are written to bits [55:48] of the result. \n
+///    Bits [39:32] are written to bits [71:64] of the result. \n
+///    Bits [47:40] are written to bits [87:80] of the result. \n
+///    Bits [55:48] are written to bits [103:96] of the result. \n
+///    Bits [63:56] are written to bits [119:112] of the result.
 /// \param __b
 ///    A 128-bit vector of [16 x i8].
-///    Bits [7:0] are written to bits [15:8] of the result.
-///    Bits [15:8] are written to bits [31:24] of the result.
-///    Bits [23:16] are written to bits [47:40] of the result.
-///    Bits [31:24] are written to bits [63:56] of the result.
-///    Bits [39:32] are written to bits [79:72] of the result.
-///    Bits [47:40] are written to bits [95:88] of the result.
-///    Bits [55:48] are written to bits [111:104] of the result.
+///    Bits [7:0] are written to bits [15:8] of the result. \n
+///    Bits [15:8] are written to bits [31:24] of the result. \n
+///    Bits [23:16] are written to bits [47:40] of the result. \n
+///    Bits [31:24] are written to bits [63:56] of the result. \n
+///    Bits [39:32] are written to bits [79:72] of the result. \n
+///    Bits [47:40] are written to bits [95:88] of the result. \n
+///    Bits [55:48] are written to bits [111:104] of the result. \n
 ///    Bits [63:56] are written to bits [127:120] of the result.
 /// \returns A 128-bit vector of [16 x i8] containing the interleaved values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
@@ -4444,19 +4479,20 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKLWD / PUNPCKLWD instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKLWD / PUNPCKLWD </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [8 x i16].
-///    Bits [15:0] are written to bits [15:0] of the result.
-///    Bits [31:16] are written to bits [47:32] of the result.
-///    Bits [47:32] are written to bits [79:64] of the result.
+///    Bits [15:0] are written to bits [15:0] of the result. \n
+///    Bits [31:16] are written to bits [47:32] of the result. \n
+///    Bits [47:32] are written to bits [79:64] of the result. \n
 ///    Bits [63:48] are written to bits [111:96] of the result.
 /// \param __b
 ///    A 128-bit vector of [8 x i16].
-///    Bits [15:0] are written to bits [31:16] of the result.
-///    Bits [31:16] are written to bits [63:48] of the result.
-///    Bits [47:32] are written to bits [95:80] of the result.
+///    Bits [15:0] are written to bits [31:16] of the result. \n
+///    Bits [31:16] are written to bits [63:48] of the result. \n
+///    Bits [47:32] are written to bits [95:80] of the result. \n
 ///    Bits [63:48] are written to bits [127:112] of the result.
 /// \returns A 128-bit vector of [8 x i16] containing the interleaved values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
@@ -4470,15 +4506,16 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKLDQ / PUNPCKLDQ instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKLDQ / PUNPCKLDQ </c>
+///   instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [4 x i32].
-///    Bits [31:0] are written to bits [31:0] of the destination.
+///    A 128-bit vector of [4 x i32]. \n
+///    Bits [31:0] are written to bits [31:0] of the destination. \n
 ///    Bits [63:32] are written to bits [95:64] of the destination.
 /// \param __b
-///    A 128-bit vector of [4 x i32].
-///    Bits [31:0] are written to bits [64:32] of the destination.
+///    A 128-bit vector of [4 x i32]. \n
+///    Bits [31:0] are written to bits [64:32] of the destination. \n
 ///    Bits [63:32] are written to bits [127:96] of the destination.
 /// \returns A 128-bit vector of [4 x i32] containing the interleaved values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
@@ -4492,14 +4529,15 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKLQDQ / PUNPCKLQDQ instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKLQDQ / PUNPCKLQDQ </c>
+///   instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [2 x i64].
-///    Bits [63:0] are written to bits [63:0] of the destination.
+///    A 128-bit vector of [2 x i64]. \n
+///    Bits [63:0] are written to bits [63:0] of the destination. \n
 /// \param __b
-///    A 128-bit vector of [2 x i64].
-///    Bits [63:0] are written to bits [127:64] of the destination.
+///    A 128-bit vector of [2 x i64]. \n
+///    Bits [63:0] are written to bits [127:64] of the destination. \n
 /// \returns A 128-bit vector of [2 x i64] containing the interleaved values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_unpacklo_epi64(__m128i __a, __m128i __b)
@@ -4529,7 +4567,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVQ / MOVQ / MOVD instruction.
+/// This intrinsic corresponds to the <c> VMOVQ / MOVQ / MOVD </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit value.
@@ -4546,7 +4584,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVQ / MOVQ instruction.
+/// This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit integer vector operand. The lower 64 bits are moved to the
@@ -4565,13 +4603,13 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKHPD / UNPCKHPD instruction.
+/// This intrinsic corresponds to the <c> VUNPCKHPD / UNPCKHPD </c> instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [2 x double].
+///    A 128-bit vector of [2 x double]. \n
 ///    Bits [127:64] are written to bits [63:0] of the destination.
 /// \param __b
-///    A 128-bit vector of [2 x double].
+///    A 128-bit vector of [2 x double]. \n
 ///    Bits [127:64] are written to bits [127:64] of the destination.
 /// \returns A 128-bit vector of [2 x double] containing the interleaved values.
 static __inline__ __m128d __DEFAULT_FN_ATTRS
@@ -4586,13 +4624,13 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKLPD / UNPCKLPD instruction.
+/// This intrinsic corresponds to the <c> VUNPCKLPD / UNPCKLPD </c> instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [2 x double].
+///    A 128-bit vector of [2 x double]. \n
 ///    Bits [63:0] are written to bits [63:0] of the destination.
 /// \param __b
-///    A 128-bit vector of [2 x double].
+///    A 128-bit vector of [2 x double]. \n
 ///    Bits [63:0] are written to bits [127:64] of the destination.
 /// \returns A 128-bit vector of [2 x double] containing the interleaved values.
 static __inline__ __m128d __DEFAULT_FN_ATTRS
@@ -4607,7 +4645,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVMSKPD / MOVMSKPD instruction.
+/// This intrinsic corresponds to the <c> VMOVMSKPD / MOVMSKPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing the values with sign bits to
@@ -4631,7 +4669,7 @@
 /// __m128d _mm_shuffle_pd(__m128d a, __m128d b, const int i);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VSHUFPD / SHUFPD instruction.
+/// This intrinsic corresponds to the <c> VSHUFPD / SHUFPD </c> instruction.
 ///
 /// \param a
 ///    A 128-bit vector of [2 x double].
@@ -4639,11 +4677,11 @@
 ///    A 128-bit vector of [2 x double].
 /// \param i
 ///    An 8-bit immediate value. The least significant two bits specify which
-///    elements to copy from a and b:
-///    Bit[0] = 0: lower element of a copied to lower element of result.
-///    Bit[0] = 1: upper element of a copied to lower element of result.
-///    Bit[1] = 0: lower element of \a b copied to upper element of result.
-///    Bit[1] = 1: upper element of \a b copied to upper element of result.
+///    elements to copy from a and b: \n
+///    Bit[0] = 0: lower element of a copied to lower element of result. \n
+///    Bit[0] = 1: upper element of a copied to lower element of result. \n
+///    Bit[1] = 0: lower element of \a b copied to upper element of result. \n
+///    Bit[1] = 1: upper element of \a b copied to upper element of result. \n
 /// \returns A 128-bit vector of [2 x double] containing the shuffled values.
 #define _mm_shuffle_pd(a, b, i) __extension__ ({ \
   (__m128d)__builtin_shufflevector((__v2df)(__m128d)(a), (__v2df)(__m128d)(b), \
@@ -4761,7 +4799,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PAUSE instruction.
+/// This intrinsic corresponds to the <c> PAUSE </c> instruction.
 ///
 void _mm_pause(void);
 
@@ -4772,4 +4810,12 @@
 
 #define _MM_SHUFFLE2(x, y) (((x) << 1) | (y))
 
+#define _MM_DENORMALS_ZERO_ON   (0x0040)
+#define _MM_DENORMALS_ZERO_OFF  (0x0000)
+
+#define _MM_DENORMALS_ZERO_MASK (0x0040)
+
+#define _MM_GET_DENORMALS_ZERO_MODE() (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK)
+#define _MM_SET_DENORMALS_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (x)))
+
 #endif /* __EMMINTRIN_H */
diff --git a/lib/Headers/f16cintrin.h b/lib/Headers/f16cintrin.h
index 415bf73..180712f 100644
--- a/lib/Headers/f16cintrin.h
+++ b/lib/Headers/f16cintrin.h
@@ -37,7 +37,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPH2PS instruction.
+/// This intrinsic corresponds to the <c> VCVTPH2PS </c> instruction.
 ///
 /// \param __a
 ///    A 16-bit half-precision float value.
@@ -59,17 +59,17 @@
 /// unsigned short _cvtss_sh(float a, const int imm);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VCVTPS2PH instruction.
+/// This intrinsic corresponds to the <c> VCVTPS2PH </c> instruction.
 ///
 /// \param a
 ///    A 32-bit single-precision float value to be converted to a 16-bit
 ///    half-precision float value.
 /// \param imm
-///    An immediate value controlling rounding using bits [2:0]:
-///    000: Nearest
-///    001: Down
-///    010: Up
-///    011: Truncate
+///    An immediate value controlling rounding using bits [2:0]: \n
+///    000: Nearest \n
+///    001: Down \n
+///    010: Up \n
+///    011: Truncate \n
 ///    1XX: Use MXCSR.RC for rounding
 /// \returns The converted 16-bit half-precision float value.
 #define _cvtss_sh(a, imm)  \
@@ -85,16 +85,16 @@
 /// __m128i _mm_cvtps_ph(__m128 a, const int imm);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VCVTPS2PH instruction.
+/// This intrinsic corresponds to the <c> VCVTPS2PH </c> instruction.
 ///
 /// \param a
 ///    A 128-bit vector containing 32-bit float values.
 /// \param imm
-///    An immediate value controlling rounding using bits [2:0]:
-///    000: Nearest
-///    001: Down
-///    010: Up
-///    011: Truncate
+///    An immediate value controlling rounding using bits [2:0]: \n
+///    000: Nearest \n
+///    001: Down \n
+///    010: Up \n
+///    011: Truncate \n
 ///    1XX: Use MXCSR.RC for rounding
 /// \returns A 128-bit vector containing converted 16-bit half-precision float
 ///    values. The lower 64 bits are used to store the converted 16-bit
@@ -107,7 +107,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPH2PS instruction.
+/// This intrinsic corresponds to the <c> VCVTPH2PS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector containing 16-bit half-precision float values. The lower
diff --git a/lib/Headers/fxsrintrin.h b/lib/Headers/fxsrintrin.h
index 7ddacf2..786081c 100644
--- a/lib/Headers/fxsrintrin.h
+++ b/lib/Headers/fxsrintrin.h
@@ -35,7 +35,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c FXSAVE instruction.
+/// This intrinsic corresponds to the <c> FXSAVE </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 512-byte memory region. The beginning of this memory
@@ -53,7 +53,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c FXRSTOR instruction.
+/// This intrinsic corresponds to the <c> FXRSTOR </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 512-byte memory region. The beginning of this memory
@@ -70,7 +70,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c FXSAVE64 instruction.
+/// This intrinsic corresponds to the <c> FXSAVE64 </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 512-byte memory region. The beginning of this memory
@@ -88,7 +88,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c FXRSTOR64 instruction.
+/// This intrinsic corresponds to the <c> FXRSTOR64 </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 512-byte memory region. The beginning of this memory
diff --git a/lib/Headers/immintrin.h b/lib/Headers/immintrin.h
index a91d164..7f91d49 100644
--- a/lib/Headers/immintrin.h
+++ b/lib/Headers/immintrin.h
@@ -78,17 +78,17 @@
 /// __m128i _mm256_cvtps_ph(__m256 a, const int imm);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VCVTPS2PH instruction.
+/// This intrinsic corresponds to the <c> VCVTPS2PH </c> instruction.
 ///
 /// \param a
 ///    A 256-bit vector containing 32-bit single-precision float values to be
 ///    converted to 16-bit half-precision float values.
 /// \param imm
-///    An immediate value controlling rounding using bits [2:0]:
-///    000: Nearest
-///    001: Down
-///    010: Up
-///    011: Truncate
+///    An immediate value controlling rounding using bits [2:0]: \n
+///    000: Nearest \n
+///    001: Down \n
+///    010: Up \n
+///    011: Truncate \n
 ///    1XX: Use MXCSR.RC for rounding
 /// \returns A 128-bit vector containing the converted 16-bit half-precision
 ///    float values.
@@ -100,7 +100,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTPH2PS instruction.
+/// This intrinsic corresponds to the <c> VCVTPH2PS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector containing 16-bit half-precision float values to be
diff --git a/lib/Headers/intrin.h b/lib/Headers/intrin.h
index 76cbb9a..af87914 100644
--- a/lib/Headers/intrin.h
+++ b/lib/Headers/intrin.h
@@ -65,12 +65,10 @@
 void __cpuid(int[4], int);
 static __inline__
 void __cpuidex(int[4], int, int);
-void __debugbreak(void);
 static __inline__
 __int64 __emul(int, int);
 static __inline__
 unsigned __int64 __emulu(unsigned int, unsigned int);
-void __cdecl __fastfail(unsigned int);
 unsigned int __getcallerseflags(void);
 static __inline__
 void __halt(void);
@@ -81,7 +79,6 @@
 void __incfsword(unsigned long);
 unsigned long __indword(unsigned short);
 void __indwordstring(unsigned short, unsigned long *, unsigned long);
-void __int2c(void);
 void __invlpg(void *);
 unsigned short __inword(unsigned short);
 void __inwordstring(unsigned short, unsigned short *, unsigned long);
@@ -109,10 +106,6 @@
 void __outdwordstring(unsigned short, unsigned long *, unsigned long);
 void __outword(unsigned short, unsigned short);
 void __outwordstring(unsigned short, unsigned short *, unsigned long);
-static __inline__
-unsigned int __popcnt(unsigned int);
-static __inline__
-unsigned short __popcnt16(unsigned short);
 unsigned long __readcr0(void);
 unsigned long __readcr2(void);
 static __inline__
@@ -124,8 +117,6 @@
 static __inline__
 unsigned char __readfsbyte(unsigned long);
 static __inline__
-unsigned long __readfsdword(unsigned long);
-static __inline__
 unsigned __int64 __readfsqword(unsigned long);
 static __inline__
 unsigned short __readfsword(unsigned long);
@@ -149,7 +140,6 @@
 void __svm_vmload(size_t);
 void __svm_vmrun(size_t);
 void __svm_vmsave(size_t);
-void __ud2(void);
 unsigned __int64 __ull_rshift(unsigned __int64, int);
 void __vmx_off(void);
 void __vmx_vmptrst(unsigned __int64 *);
@@ -179,108 +169,34 @@
 unsigned char _bittestandreset(long *, long);
 static __inline__
 unsigned char _bittestandset(long *, long);
-unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64);
-unsigned long __cdecl _byteswap_ulong(unsigned long);
-unsigned short __cdecl _byteswap_ushort(unsigned short);
 void __cdecl _disable(void);
 void __cdecl _enable(void);
 long _InterlockedAddLargeStatistic(__int64 volatile *_Addend, long _Value);
-static __inline__
-long _InterlockedAnd(long volatile *_Value, long _Mask);
-static __inline__
-short _InterlockedAnd16(short volatile *_Value, short _Mask);
-static __inline__
-char _InterlockedAnd8(char volatile *_Value, char _Mask);
 unsigned char _interlockedbittestandreset(long volatile *, long);
 static __inline__
 unsigned char _interlockedbittestandset(long volatile *, long);
-static __inline__
-long __cdecl _InterlockedCompareExchange(long volatile *_Destination,
-                                         long _Exchange, long _Comparand);
 long _InterlockedCompareExchange_HLEAcquire(long volatile *, long, long);
 long _InterlockedCompareExchange_HLERelease(long volatile *, long, long);
-static __inline__
-short _InterlockedCompareExchange16(short volatile *_Destination,
-                                    short _Exchange, short _Comparand);
-static __inline__
-__int64 _InterlockedCompareExchange64(__int64 volatile *_Destination,
-                                      __int64 _Exchange, __int64 _Comparand);
 __int64 _InterlockedcompareExchange64_HLEAcquire(__int64 volatile *, __int64,
                                                  __int64);
 __int64 _InterlockedCompareExchange64_HLERelease(__int64 volatile *, __int64,
                                                  __int64);
-static __inline__
-char _InterlockedCompareExchange8(char volatile *_Destination, char _Exchange,
-                                  char _Comparand);
 void *_InterlockedCompareExchangePointer_HLEAcquire(void *volatile *, void *,
                                                     void *);
 void *_InterlockedCompareExchangePointer_HLERelease(void *volatile *, void *,
                                                     void *);
-static __inline__
-long __cdecl _InterlockedDecrement(long volatile *_Addend);
-static __inline__
-short _InterlockedDecrement16(short volatile *_Addend);
-long _InterlockedExchange(long volatile *_Target, long _Value);
-static __inline__
-short _InterlockedExchange16(short volatile *_Target, short _Value);
-static __inline__
-char _InterlockedExchange8(char volatile *_Target, char _Value);
-static __inline__
-long __cdecl _InterlockedExchangeAdd(long volatile *_Addend, long _Value);
 long _InterlockedExchangeAdd_HLEAcquire(long volatile *, long);
 long _InterlockedExchangeAdd_HLERelease(long volatile *, long);
-static __inline__
-short _InterlockedExchangeAdd16(short volatile *_Addend, short _Value);
 __int64 _InterlockedExchangeAdd64_HLEAcquire(__int64 volatile *, __int64);
 __int64 _InterlockedExchangeAdd64_HLERelease(__int64 volatile *, __int64);
-static __inline__
-char _InterlockedExchangeAdd8(char volatile *_Addend, char _Value);
-static __inline__
-long __cdecl _InterlockedIncrement(long volatile *_Addend);
-static __inline__
-short _InterlockedIncrement16(short volatile *_Addend);
-static __inline__
-long _InterlockedOr(long volatile *_Value, long _Mask);
-static __inline__
-short _InterlockedOr16(short volatile *_Value, short _Mask);
-static __inline__
-char _InterlockedOr8(char volatile *_Value, char _Mask);
-static __inline__
-long _InterlockedXor(long volatile *_Value, long _Mask);
-static __inline__
-short _InterlockedXor16(short volatile *_Value, short _Mask);
-static __inline__
-char _InterlockedXor8(char volatile *_Value, char _Mask);
 void __cdecl _invpcid(unsigned int, void *);
-static __inline__
-unsigned long __cdecl _lrotl(unsigned long, int);
-static __inline__
-unsigned long __cdecl _lrotr(unsigned long, int);
 static __inline__ void
 __attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
 _ReadBarrier(void);
 static __inline__ void
 __attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
 _ReadWriteBarrier(void);
-static __inline__
-void *_ReturnAddress(void);
 unsigned int _rorx_u32(unsigned int, const unsigned int);
-static __inline__
-unsigned int __cdecl _rotl(unsigned int _Value, int _Shift);
-static __inline__
-unsigned short _rotl16(unsigned short _Value, unsigned char _Shift);
-static __inline__
-unsigned __int64 __cdecl _rotl64(unsigned __int64 _Value, int _Shift);
-static __inline__
-unsigned char _rotl8(unsigned char _Value, unsigned char _Shift);
-static __inline__
-unsigned int __cdecl _rotr(unsigned int _Value, int _Shift);
-static __inline__
-unsigned short _rotr16(unsigned short _Value, unsigned char _Shift);
-static __inline__
-unsigned __int64 __cdecl _rotr64(unsigned __int64 _Value, int _Shift);
-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);
@@ -318,8 +234,6 @@
 static __inline__
 void __movsq(unsigned long long *, unsigned long long const *, size_t);
 static __inline__
-unsigned __int64 __popcnt64(unsigned __int64);
-static __inline__
 unsigned char __readgsbyte(unsigned long);
 static __inline__
 unsigned long __readgsdword(unsigned long);
@@ -357,7 +271,6 @@
 unsigned char _bittestandreset64(__int64 *, __int64);
 static __inline__
 unsigned char _bittestandset64(__int64 *, __int64);
-unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64);
 long _InterlockedAnd_np(long volatile *_Value, long _Mask);
 short _InterlockedAnd16_np(short volatile *_Value, short _Mask);
 __int64 _InterlockedAnd64_np(__int64 volatile *_Value, __int64 _Mask);
@@ -383,11 +296,8 @@
                                                  __int64);
 __int64 _InterlockedCompareExchange64_np(__int64 volatile *_Destination,
                                          __int64 _Exchange, __int64 _Comparand);
-void *_InterlockedCompareExchangePointer(void *volatile *_Destination,
-                                         void *_Exchange, void *_Comparand);
 void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination,
                                             void *_Exchange, void *_Comparand);
-void *_InterlockedExchangePointer(void *volatile *_Target, void *_Value);
 long _InterlockedOr_np(long volatile *_Value, long _Mask);
 short _InterlockedOr16_np(short volatile *_Value, short _Mask);
 __int64 _InterlockedOr64_np(__int64 volatile *_Value, __int64 _Mask);
@@ -398,9 +308,6 @@
 char _InterlockedXor8_np(char volatile *_Value, char _Mask);
 unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int);
 __int64 _sarx_i64(__int64, unsigned int);
-#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);
 static __inline__
@@ -988,19 +895,21 @@
 #ifdef __x86_64__
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 __readgsbyte(unsigned long __offset) {
-  return *__ptr_to_addr_space(256, unsigned char, __offset);
+  return *__ptr_to_addr_space(256, unsigned char, (unsigned long long)__offset);
 }
 static __inline__ unsigned short __DEFAULT_FN_ATTRS
 __readgsword(unsigned long __offset) {
-  return *__ptr_to_addr_space(256, unsigned short, __offset);
+  return *__ptr_to_addr_space(256, unsigned short,
+                              (unsigned long long)__offset);
 }
 static __inline__ unsigned long __DEFAULT_FN_ATTRS
 __readgsdword(unsigned long __offset) {
-  return *__ptr_to_addr_space(256, unsigned long, __offset);
+  return *__ptr_to_addr_space(256, unsigned long, (unsigned long long)__offset);
 }
 static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS
 __readgsqword(unsigned long __offset) {
-  return *__ptr_to_addr_space(256, unsigned __int64, __offset);
+  return *__ptr_to_addr_space(256, unsigned __int64,
+                              (unsigned long long)__offset);
 }
 #endif
 #undef __ptr_to_addr_space
@@ -1010,40 +919,33 @@
 #if defined(__i386__) || defined(__x86_64__)
 static __inline__ void __DEFAULT_FN_ATTRS
 __movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) {
-  __asm__("rep movsb" : : "D"(__dst), "S"(__src), "c"(__n)
-                        : "%edi", "%esi", "%ecx");
+  __asm__("rep movsb" : : "D"(__dst), "S"(__src), "c"(__n));
 }
 static __inline__ void __DEFAULT_FN_ATTRS
 __movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) {
-  __asm__("rep movsl" : : "D"(__dst), "S"(__src), "c"(__n)
-                        : "%edi", "%esi", "%ecx");
+  __asm__("rep movsl" : : "D"(__dst), "S"(__src), "c"(__n));
 }
 static __inline__ void __DEFAULT_FN_ATTRS
 __movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) {
-  __asm__("rep movsw" : : "D"(__dst), "S"(__src), "c"(__n)
-                        : "%edi", "%esi", "%ecx");
+  __asm__("rep movsw" : : "D"(__dst), "S"(__src), "c"(__n));
 }
 static __inline__ void __DEFAULT_FN_ATTRS
 __stosd(unsigned long *__dst, unsigned long __x, size_t __n) {
-  __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n)
-                        : "%edi", "%ecx");
+  __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n));
 }
 static __inline__ void __DEFAULT_FN_ATTRS
 __stosw(unsigned short *__dst, unsigned short __x, size_t __n) {
-  __asm__("rep stosw" : : "D"(__dst), "a"(__x), "c"(__n)
-                        : "%edi", "%ecx");
+  __asm__("rep stosw" : : "D"(__dst), "a"(__x), "c"(__n));
 }
 #endif
 #ifdef __x86_64__
 static __inline__ void __DEFAULT_FN_ATTRS
 __movsq(unsigned long long *__dst, unsigned long long const *__src, size_t __n) {
-  __asm__("rep movsq" : : "D"(__dst), "S"(__src), "c"(__n)
-                        : "%edi", "%esi", "%ecx");
+  __asm__("rep movsq" : : "D"(__dst), "S"(__src), "c"(__n));
 }
 static __inline__ void __DEFAULT_FN_ATTRS
 __stosq(unsigned __int64 *__dst, unsigned __int64 __x, size_t __n) {
-  __asm__("rep stosq" : : "D"(__dst), "a"(__x), "c"(__n)
-                        : "%edi", "%ecx");
+  __asm__("rep stosq" : : "D"(__dst), "a"(__x), "c"(__n));
 }
 #endif
 
diff --git a/lib/Headers/mmintrin.h b/lib/Headers/mmintrin.h
index f239dc6..2b36183 100644
--- a/lib/Headers/mmintrin.h
+++ b/lib/Headers/mmintrin.h
@@ -39,7 +39,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c EMMS instruction.
+/// This intrinsic corresponds to the <c> EMMS </c> instruction.
 ///
 static __inline__ void __DEFAULT_FN_ATTRS
 _mm_empty(void)
@@ -52,7 +52,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVD / MOVD instruction.
+/// This intrinsic corresponds to the <c> VMOVD / MOVD </c> instruction.
 ///
 /// \param __i
 ///    A 32-bit integer value.
@@ -69,7 +69,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVD / MOVD instruction.
+/// This intrinsic corresponds to the <c> VMOVD / MOVD </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector.
@@ -85,7 +85,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVQ / MOVD instruction.
+/// This intrinsic corresponds to the <c> VMOVQ / MOVD </c> instruction.
 ///
 /// \param __i
 ///    A 64-bit signed integer.
@@ -101,7 +101,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVQ / MOVD instruction.
+/// This intrinsic corresponds to the <c> VMOVQ / MOVD </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector.
@@ -121,7 +121,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PACKSSWB instruction.
+/// This intrinsic corresponds to the <c> PACKSSWB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16]. Each 16-bit element is treated as a
@@ -151,7 +151,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PACKSSDW instruction.
+/// This intrinsic corresponds to the <c> PACKSSDW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [2 x i32]. Each 32-bit element is treated as a
@@ -181,7 +181,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PACKUSWB instruction.
+/// This intrinsic corresponds to the <c> PACKUSWB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16]. Each 16-bit element is treated as a
@@ -208,19 +208,19 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PUNPCKHBW instruction.
+/// This intrinsic corresponds to the <c> PUNPCKHBW </c> instruction.
 ///
 /// \param __m1
-///    A 64-bit integer vector of [8 x i8].
-///    Bits [39:32] are written to bits [7:0] of the result.
-///    Bits [47:40] are written to bits [23:16] of the result.
-///    Bits [55:48] are written to bits [39:32] of the result.
+///    A 64-bit integer vector of [8 x i8]. \n
+///    Bits [39:32] are written to bits [7:0] of the result. \n
+///    Bits [47:40] are written to bits [23:16] of the result. \n
+///    Bits [55:48] are written to bits [39:32] of the result. \n
 ///    Bits [63:56] are written to bits [55:48] of the result.
 /// \param __m2
 ///    A 64-bit integer vector of [8 x i8].
-///    Bits [39:32] are written to bits [15:8] of the result.
-///    Bits [47:40] are written to bits [31:24] of the result.
-///    Bits [55:48] are written to bits [47:40] of the result.
+///    Bits [39:32] are written to bits [15:8] of the result. \n
+///    Bits [47:40] are written to bits [31:24] of the result. \n
+///    Bits [55:48] are written to bits [47:40] of the result. \n
 ///    Bits [63:56] are written to bits [63:56] of the result.
 /// \returns A 64-bit integer vector of [8 x i8] containing the interleaved
 ///    values.
@@ -235,15 +235,15 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PUNPCKHWD instruction.
+/// This intrinsic corresponds to the <c> PUNPCKHWD </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
-///    Bits [47:32] are written to bits [15:0] of the result.
+///    Bits [47:32] are written to bits [15:0] of the result. \n
 ///    Bits [63:48] are written to bits [47:32] of the result.
 /// \param __m2
 ///    A 64-bit integer vector of [4 x i16].
-///    Bits [47:32] are written to bits [31:16] of the result.
+///    Bits [47:32] are written to bits [31:16] of the result. \n
 ///    Bits [63:48] are written to bits [63:48] of the result.
 /// \returns A 64-bit integer vector of [4 x i16] containing the interleaved
 ///    values.
@@ -258,7 +258,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PUNPCKHDQ instruction.
+/// This intrinsic corresponds to the <c> PUNPCKHDQ </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [2 x i32]. The upper 32 bits are written to
@@ -279,19 +279,19 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PUNPCKLBW instruction.
+/// This intrinsic corresponds to the <c> PUNPCKLBW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [8 x i8].
-///    Bits [7:0] are written to bits [7:0] of the result.
-///    Bits [15:8] are written to bits [23:16] of the result.
-///    Bits [23:16] are written to bits [39:32] of the result.
+///    Bits [7:0] are written to bits [7:0] of the result. \n
+///    Bits [15:8] are written to bits [23:16] of the result. \n
+///    Bits [23:16] are written to bits [39:32] of the result. \n
 ///    Bits [31:24] are written to bits [55:48] of the result.
 /// \param __m2
 ///    A 64-bit integer vector of [8 x i8].
-///    Bits [7:0] are written to bits [15:8] of the result.
-///    Bits [15:8] are written to bits [31:24] of the result.
-///    Bits [23:16] are written to bits [47:40] of the result.
+///    Bits [7:0] are written to bits [15:8] of the result. \n
+///    Bits [15:8] are written to bits [31:24] of the result. \n
+///    Bits [23:16] are written to bits [47:40] of the result. \n
 ///    Bits [31:24] are written to bits [63:56] of the result.
 /// \returns A 64-bit integer vector of [8 x i8] containing the interleaved
 ///    values.
@@ -306,15 +306,15 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PUNPCKLWD instruction.
+/// This intrinsic corresponds to the <c> PUNPCKLWD </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
-///    Bits [15:0] are written to bits [15:0] of the result.
+///    Bits [15:0] are written to bits [15:0] of the result. \n
 ///    Bits [31:16] are written to bits [47:32] of the result.
 /// \param __m2
 ///    A 64-bit integer vector of [4 x i16].
-///    Bits [15:0] are written to bits [31:16] of the result.
+///    Bits [15:0] are written to bits [31:16] of the result. \n
 ///    Bits [31:16] are written to bits [63:48] of the result.
 /// \returns A 64-bit integer vector of [4 x i16] containing the interleaved
 ///    values.
@@ -329,7 +329,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PUNPCKLDQ instruction.
+/// This intrinsic corresponds to the <c> PUNPCKLDQ </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [2 x i32]. The lower 32 bits are written to
@@ -352,7 +352,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PADDB instruction.
+/// This intrinsic corresponds to the <c> PADDB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [8 x i8].
@@ -373,7 +373,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PADDW instruction.
+/// This intrinsic corresponds to the <c> PADDW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
@@ -394,7 +394,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PADDD instruction.
+/// This intrinsic corresponds to the <c> PADDD </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [2 x i32].
@@ -416,7 +416,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PADDSB instruction.
+/// This intrinsic corresponds to the <c> PADDSB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [8 x i8].
@@ -439,7 +439,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PADDSW instruction.
+/// This intrinsic corresponds to the <c> PADDSW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
@@ -461,7 +461,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PADDUSB instruction.
+/// This intrinsic corresponds to the <c> PADDUSB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [8 x i8].
@@ -483,7 +483,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PADDUSW instruction.
+/// This intrinsic corresponds to the <c> PADDUSW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
@@ -504,7 +504,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSUBB instruction.
+/// This intrinsic corresponds to the <c> PSUBB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [8 x i8] containing the minuends.
@@ -525,7 +525,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSUBW instruction.
+/// This intrinsic corresponds to the <c> PSUBW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16] containing the minuends.
@@ -546,7 +546,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSUBD instruction.
+/// This intrinsic corresponds to the <c> PSUBD </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [2 x i32] containing the minuends.
@@ -569,7 +569,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSUBSB instruction.
+/// This intrinsic corresponds to the <c> PSUBSB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [8 x i8] containing the minuends.
@@ -592,7 +592,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSUBSW instruction.
+/// This intrinsic corresponds to the <c> PSUBSW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16] containing the minuends.
@@ -615,7 +615,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSUBUSB instruction.
+/// This intrinsic corresponds to the <c> PSUBUSB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [8 x i8] containing the minuends.
@@ -638,7 +638,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSUBUSW instruction.
+/// This intrinsic corresponds to the <c> PSUBUSW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16] containing the minuends.
@@ -663,7 +663,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMADDWD instruction.
+/// This intrinsic corresponds to the <c> PMADDWD </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
@@ -684,7 +684,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMULHW instruction.
+/// This intrinsic corresponds to the <c> PMULHW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
@@ -705,7 +705,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMULLW instruction.
+/// This intrinsic corresponds to the <c> PMULLW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
@@ -727,7 +727,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSLLW instruction.
+/// This intrinsic corresponds to the <c> PSLLW </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [4 x i16].
@@ -749,7 +749,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSLLW instruction.
+/// This intrinsic corresponds to the <c> PSLLW </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [4 x i16].
@@ -772,7 +772,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSLLD instruction.
+/// This intrinsic corresponds to the <c> PSLLD </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [2 x i32].
@@ -794,7 +794,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSLLD instruction.
+/// This intrinsic corresponds to the <c> PSLLD </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [2 x i32].
@@ -815,7 +815,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSLLQ instruction.
+/// This intrinsic corresponds to the <c> PSLLQ </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector interpreted as a single 64-bit integer.
@@ -835,7 +835,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSLLQ instruction.
+/// This intrinsic corresponds to the <c> PSLLQ </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector interpreted as a single 64-bit integer.
@@ -858,7 +858,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRAW instruction.
+/// This intrinsic corresponds to the <c> PSRAW </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [4 x i16].
@@ -880,7 +880,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRAW instruction.
+/// This intrinsic corresponds to the <c> PSRAW </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [4 x i16].
@@ -903,7 +903,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRAD instruction.
+/// This intrinsic corresponds to the <c> PSRAD </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [2 x i32].
@@ -925,7 +925,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRAD instruction.
+/// This intrinsic corresponds to the <c> PSRAD </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [2 x i32].
@@ -947,7 +947,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRLW instruction.
+/// This intrinsic corresponds to the <c> PSRLW </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [4 x i16].
@@ -968,7 +968,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRLW instruction.
+/// This intrinsic corresponds to the <c> PSRLW </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [4 x i16].
@@ -990,7 +990,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRLD instruction.
+/// This intrinsic corresponds to the <c> PSRLD </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [2 x i32].
@@ -1011,7 +1011,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRLD instruction.
+/// This intrinsic corresponds to the <c> PSRLD </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector of [2 x i32].
@@ -1031,7 +1031,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRLQ instruction.
+/// This intrinsic corresponds to the <c> PSRLQ </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector interpreted as a single 64-bit integer.
@@ -1050,7 +1050,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSRLQ instruction.
+/// This intrinsic corresponds to the <c> PSRLQ </c> instruction.
 ///
 /// \param __m
 ///    A 64-bit integer vector interpreted as a single 64-bit integer.
@@ -1067,7 +1067,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PAND instruction.
+/// This intrinsic corresponds to the <c> PAND </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector.
@@ -1087,7 +1087,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PANDN instruction.
+/// This intrinsic corresponds to the <c> PANDN </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector. The one's complement of this parameter is used
@@ -1106,7 +1106,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c POR instruction.
+/// This intrinsic corresponds to the <c> POR </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector.
@@ -1124,7 +1124,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PXOR instruction.
+/// This intrinsic corresponds to the <c> PXOR </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector.
@@ -1145,7 +1145,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PCMPEQB instruction.
+/// This intrinsic corresponds to the <c> PCMPEQB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [8 x i8].
@@ -1166,7 +1166,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PCMPEQW instruction.
+/// This intrinsic corresponds to the <c> PCMPEQW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
@@ -1187,7 +1187,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PCMPEQD instruction.
+/// This intrinsic corresponds to the <c> PCMPEQD </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [2 x i32].
@@ -1208,7 +1208,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PCMPGTB instruction.
+/// This intrinsic corresponds to the <c> PCMPGTB </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [8 x i8].
@@ -1229,7 +1229,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PCMPGTW instruction.
+/// This intrinsic corresponds to the <c> PCMPGTW </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [4 x i16].
@@ -1250,7 +1250,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PCMPGTD instruction.
+/// This intrinsic corresponds to the <c> PCMPGTD </c> instruction.
 ///
 /// \param __m1
 ///    A 64-bit integer vector of [2 x i32].
@@ -1268,7 +1268,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the the \c VXORPS / XORPS instruction.
+/// This intrinsic corresponds to the the <c> VXORPS / XORPS </c> instruction.
 ///
 /// \returns An initialized 64-bit integer vector with all elements set to zero.
 static __inline__ __m64 __DEFAULT_FN_ATTRS
@@ -1360,7 +1360,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSHUFD / PSHUFD instruction.
+/// This intrinsic corresponds to the <c> VPSHUFD / PSHUFD </c> instruction.
 ///
 /// \param __i
 ///    A 32-bit integer value used to initialize each vector element of the
@@ -1378,7 +1378,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPSHUFLW / PSHUFLW instruction.
+/// This intrinsic corresponds to the <c> VPSHUFLW / PSHUFLW </c> instruction.
 ///
 /// \param __w
 ///    A 16-bit integer value used to initialize each vector element of the
@@ -1395,8 +1395,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPUNPCKLBW + VPSHUFLW / \c PUNPCKLBW +
-///    PSHUFLW instruction.
+/// This intrinsic corresponds to the <c> VPUNPCKLBW + VPSHUFLW / PUNPCKLBW +
+///    PSHUFLW </c> instruction.
 ///
 /// \param __b
 ///    An 8-bit integer value used to initialize each vector element of the
diff --git a/lib/Headers/module.modulemap b/lib/Headers/module.modulemap
index 11ef2f9..95d26ce 100644
--- a/lib/Headers/module.modulemap
+++ b/lib/Headers/module.modulemap
@@ -61,6 +61,7 @@
     textual header "xopintrin.h"
     textual header "fma4intrin.h"
     textual header "mwaitxintrin.h"
+    textual header "clzerointrin.h"
 
     explicit module mm_malloc {
       requires !freestanding
diff --git a/lib/Headers/opencl-c.h b/lib/Headers/opencl-c.h
index 004eca3..3bcb9a3 100644
--- a/lib/Headers/opencl-c.h
+++ b/lib/Headers/opencl-c.h
@@ -16,6 +16,12 @@
 #endif //cl_khr_depth_images
 #endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
 
+#if __OPENCL_C_VERSION__ < CL_VERSION_2_0
+#ifdef cl_khr_3d_image_writes
+#pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable
+#endif //cl_khr_3d_image_writes
+#endif //__OPENCL_C_VERSION__ < CL_VERSION_2_0
+
 #define __ovld __attribute__((overloadable))
 #define __conv __attribute__((convergent))
 
@@ -15490,6 +15496,10 @@
 #define CLK_FILTER_NEAREST              0x10
 #define CLK_FILTER_LINEAR               0x20
 
+#ifdef cl_khr_gl_msaa_sharing
+#pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing : enable
+#endif //cl_khr_gl_msaa_sharing
+
 /**
  * Use the coordinate (coord.xy) to do an element lookup in
  * the 2D image object specified by image.
@@ -15991,9 +16001,11 @@
 void __ovld write_imagei(write_only image1d_array_t image_array, int2 coord, int4 color);
 void __ovld write_imageui(write_only image1d_array_t image_array, int2 coord, uint4 color);
 
+#ifdef cl_khr_3d_image_writes
 void __ovld write_imagef(write_only image3d_t image, int4 coord, float4 color);
 void __ovld write_imagei(write_only image3d_t image, int4 coord, int4 color);
 void __ovld write_imageui(write_only image3d_t image, int4 coord, uint4 color);
+#endif
 
 #ifdef cl_khr_depth_images
 void __ovld write_imagef(write_only image2d_depth_t image, int2 coord, float color);
@@ -16021,16 +16033,20 @@
 void __ovld write_imagef(write_only image2d_depth_t image, int2 coord, int lod, float color);
 void __ovld write_imagef(write_only image2d_array_depth_t image, int4 coord, int lod, float color);
 
+#ifdef cl_khr_3d_image_writes
 void __ovld write_imagef(write_only image3d_t image, int4 coord, int lod, float4 color);
 void __ovld write_imagei(write_only image3d_t image, int4 coord, int lod, int4 color);
 void __ovld write_imageui(write_only image3d_t image, int4 coord, int lod, uint4 color);
+#endif
 #endif //cl_khr_mipmap_image
 
 // Image write functions for half4 type
 #ifdef cl_khr_fp16
 void __ovld write_imageh(write_only image1d_t image, int coord, half4 color);
 void __ovld write_imageh(write_only image2d_t image, int2 coord, half4 color);
+#ifdef cl_khr_3d_image_writes
 void __ovld write_imageh(write_only image3d_t image, int4 coord, half4 color);
+#endif
 void __ovld write_imageh(write_only image1d_array_t image, int2 coord, half4 color);
 void __ovld write_imageh(write_only image2d_array_t image, int4 coord, half4 color);
 void __ovld write_imageh(write_only image1d_buffer_t image, int coord, half4 color);
@@ -16058,9 +16074,11 @@
 void __ovld write_imagei(read_write image1d_array_t image_array, int2 coord, int4 color);
 void __ovld write_imageui(read_write image1d_array_t image_array, int2 coord, uint4 color);
 
+#ifdef cl_khr_3d_image_writes
 void __ovld write_imagef(read_write image3d_t image, int4 coord, float4 color);
 void __ovld write_imagei(read_write image3d_t image, int4 coord, int4 color);
 void __ovld write_imageui(read_write image3d_t image, int4 coord, uint4 color);
+#endif
 
 #ifdef cl_khr_depth_images
 void __ovld write_imagef(read_write image2d_depth_t image, int2 coord, float color);
@@ -16087,16 +16105,20 @@
 void __ovld write_imagef(read_write image2d_depth_t image, int2 coord, int lod, float color);
 void __ovld write_imagef(read_write image2d_array_depth_t image, int4 coord, int lod, float color);
 
+#ifdef cl_khr_3d_image_writes
 void __ovld write_imagef(read_write image3d_t image, int4 coord, int lod, float4 color);
 void __ovld write_imagei(read_write image3d_t image, int4 coord, int lod, int4 color);
 void __ovld write_imageui(read_write image3d_t image, int4 coord, int lod, uint4 color);
+#endif
 #endif //cl_khr_mipmap_image
 
 // Image write functions for half4 type
 #ifdef cl_khr_fp16
 void __ovld write_imageh(read_write image1d_t image, int coord, half4 color);
 void __ovld write_imageh(read_write image2d_t image, int2 coord, half4 color);
+#ifdef cl_khr_3d_image_writes
 void __ovld write_imageh(read_write image3d_t image, int4 coord, half4 color);
+#endif
 void __ovld write_imageh(read_write image1d_array_t image, int2 coord, half4 color);
 void __ovld write_imageh(read_write image2d_array_t image, int4 coord, half4 color);
 void __ovld write_imageh(read_write image1d_buffer_t image, int coord, half4 color);
@@ -16114,7 +16136,9 @@
 int __ovld __cnfn get_image_width(read_only image1d_t image);
 int __ovld __cnfn get_image_width(read_only image1d_buffer_t image);
 int __ovld __cnfn get_image_width(read_only image2d_t image);
+#ifdef cl_khr_3d_image_writes
 int __ovld __cnfn get_image_width(read_only image3d_t image);
+#endif
 int __ovld __cnfn get_image_width(read_only image1d_array_t image);
 int __ovld __cnfn get_image_width(read_only image2d_array_t image);
 #ifdef cl_khr_depth_images
@@ -16131,7 +16155,9 @@
 int __ovld __cnfn get_image_width(write_only image1d_t image);
 int __ovld __cnfn get_image_width(write_only image1d_buffer_t image);
 int __ovld __cnfn get_image_width(write_only image2d_t image);
+#ifdef cl_khr_3d_image_writes
 int __ovld __cnfn get_image_width(write_only image3d_t image);
+#endif
 int __ovld __cnfn get_image_width(write_only image1d_array_t image);
 int __ovld __cnfn get_image_width(write_only image2d_array_t image);
 #ifdef cl_khr_depth_images
@@ -16182,7 +16208,9 @@
 #endif //cl_khr_gl_msaa_sharing
 
 int __ovld __cnfn get_image_height(write_only image2d_t image);
+#ifdef cl_khr_3d_image_writes
 int __ovld __cnfn get_image_height(write_only image3d_t image);
+#endif
 int __ovld __cnfn get_image_height(write_only image2d_array_t image);
 #ifdef cl_khr_depth_images
 int __ovld __cnfn get_image_height(write_only image2d_depth_t image);
@@ -16216,7 +16244,9 @@
  */
 int __ovld __cnfn get_image_depth(read_only image3d_t image);
 
+#ifdef cl_khr_3d_image_writes
 int __ovld __cnfn get_image_depth(write_only image3d_t image);
+#endif
 
 #if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
 int __ovld __cnfn get_image_depth(read_write image3d_t image);
@@ -16234,7 +16264,9 @@
 
 int __ovld get_image_num_mip_levels(write_only image1d_t image);
 int __ovld get_image_num_mip_levels(write_only image2d_t image);
+#ifdef cl_khr_3d_image_writes
 int __ovld get_image_num_mip_levels(write_only image3d_t image);
+#endif
 
 #if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
 int __ovld get_image_num_mip_levels(read_write image1d_t image);
@@ -16320,7 +16352,9 @@
 int __ovld __cnfn get_image_channel_data_type(write_only image1d_t image);
 int __ovld __cnfn get_image_channel_data_type(write_only image1d_buffer_t image);
 int __ovld __cnfn get_image_channel_data_type(write_only image2d_t image);
+#ifdef cl_khr_3d_image_writes
 int __ovld __cnfn get_image_channel_data_type(write_only image3d_t image);
+#endif
 int __ovld __cnfn get_image_channel_data_type(write_only image1d_array_t image);
 int __ovld __cnfn get_image_channel_data_type(write_only image2d_array_t image);
 #ifdef cl_khr_depth_images
@@ -16414,7 +16448,9 @@
 int __ovld __cnfn get_image_channel_order(write_only image1d_t image);
 int __ovld __cnfn get_image_channel_order(write_only image1d_buffer_t image);
 int __ovld __cnfn get_image_channel_order(write_only image2d_t image);
+#ifdef cl_khr_3d_image_writes
 int __ovld __cnfn get_image_channel_order(write_only image3d_t image);
+#endif
 int __ovld __cnfn get_image_channel_order(write_only image1d_array_t image);
 int __ovld __cnfn get_image_channel_order(write_only image2d_array_t image);
 #ifdef cl_khr_depth_images
@@ -16500,7 +16536,9 @@
  * component and the w component is 0.
  */
 int4 __ovld __cnfn get_image_dim(read_only image3d_t image);
+#ifdef cl_khr_3d_image_writes
 int4 __ovld __cnfn get_image_dim(write_only image3d_t image);
+#endif
 #if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
 int4 __ovld __cnfn get_image_dim(read_write image3d_t image);
 #endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
@@ -16710,16 +16748,12 @@
 
 #define MAX_WORK_DIM        3
 
-// ToDo: Remove definition of ndrange_t in Clang as an opaque type and add back
-// the following ndrange_t definition.
-#if 0
 typedef struct {
     unsigned int workDimension;
     size_t globalWorkOffset[MAX_WORK_DIM];
     size_t globalWorkSize[MAX_WORK_DIM];
     size_t localWorkSize[MAX_WORK_DIM];
 } ndrange_t;
-#endif
 
 ndrange_t __ovld ndrange_1D(size_t);
 ndrange_t __ovld ndrange_1D(size_t, size_t);
diff --git a/lib/Headers/pmmintrin.h b/lib/Headers/pmmintrin.h
index 5b10580..a479d9e 100644
--- a/lib/Headers/pmmintrin.h
+++ b/lib/Headers/pmmintrin.h
@@ -37,7 +37,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VLDDQU instruction.
+/// This intrinsic corresponds to the <c> VLDDQU </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 128-bit integer vector containing integer values.
@@ -53,7 +53,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDSUBPS instruction.
+/// This intrinsic corresponds to the <c> VADDSUBPS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing the left source operand.
@@ -72,7 +72,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VHADDPS instruction.
+/// This intrinsic corresponds to the <c> VHADDPS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the source operands.
@@ -95,7 +95,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VHSUBPS instruction.
+/// This intrinsic corresponds to the <c> VHSUBPS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the source operands.
@@ -116,17 +116,17 @@
 /// \brief Moves and duplicates high-order (odd-indexed) values from a 128-bit
 ///    vector of [4 x float] to float values stored in a 128-bit vector of
 ///    [4 x float].
-///    Bits [127:96] of the source are written to bits [127:96] and [95:64] of
-///    the destination.
-///    Bits [63:32] of the source are written to bits [63:32] and [31:0] of the
-///    destination.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSHDUP instruction.
+/// This intrinsic corresponds to the <c> VMOVSHDUP </c> instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [4 x float].
+///    A 128-bit vector of [4 x float]. \n
+///    Bits [127:96] of the source are written to bits [127:96] and [95:64] of
+///    the destination. \n
+///    Bits [63:32] of the source are written to bits [63:32] and [31:0] of the
+///    destination.
 /// \returns A 128-bit vector of [4 x float] containing the moved and duplicated
 ///    values.
 static __inline__ __m128 __DEFAULT_FN_ATTRS
@@ -135,20 +135,19 @@
   return __builtin_shufflevector((__v4sf)__a, (__v4sf)__a, 1, 1, 3, 3);
 }
 
-/// \brief Duplicates low-order (even-indexed) values from a 128-bit
-///    vector of [4 x float] to float values stored in a 128-bit vector of
-///    [4 x float].
-///    Bits [95:64] of the source are written to bits [127:96] and [95:64] of
-///    the destination.
-///    Bits [31:0] of the source are written to bits [63:32] and [31:0] of the
-///    destination.
+/// \brief Duplicates low-order (even-indexed) values from a 128-bit vector of
+///    [4 x float] to float values stored in a 128-bit vector of [4 x float].
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSLDUP instruction.
+/// This intrinsic corresponds to the <c> VMOVSLDUP </c> instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [4 x float].
+///    A 128-bit vector of [4 x float] \n
+///    Bits [95:64] of the source are written to bits [127:96] and [95:64] of
+///    the destination. \n
+///    Bits [31:0] of the source are written to bits [63:32] and [31:0] of the
+///    destination.
 /// \returns A 128-bit vector of [4 x float] containing the moved and duplicated
 ///    values.
 static __inline__ __m128 __DEFAULT_FN_ATTRS
@@ -162,7 +161,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDSUBPD instruction.
+/// This intrinsic corresponds to the <c> VADDSUBPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing the left source operand.
@@ -181,7 +180,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VHADDPD instruction.
+/// This intrinsic corresponds to the <c> VHADDPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the source operands.
@@ -204,7 +203,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VHSUBPD instruction.
+/// This intrinsic corresponds to the <c> VHSUBPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double] containing one of the source operands.
@@ -231,7 +230,7 @@
 /// __m128d _mm_loaddup_pd(double const * dp);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VMOVDDUP instruction.
+/// This intrinsic corresponds to the <c> VMOVDDUP </c> instruction.
 ///
 /// \param dp
 ///    A pointer to a double-precision value to be moved and duplicated.
@@ -245,7 +244,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVDDUP instruction.
+/// This intrinsic corresponds to the <c> VMOVDDUP </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [2 x double]. Bits [63:0] are written to bits
@@ -258,21 +257,13 @@
   return __builtin_shufflevector((__v2df)__a, (__v2df)__a, 0, 0);
 }
 
-#define _MM_DENORMALS_ZERO_ON   (0x0040)
-#define _MM_DENORMALS_ZERO_OFF  (0x0000)
-
-#define _MM_DENORMALS_ZERO_MASK (0x0040)
-
-#define _MM_GET_DENORMALS_ZERO_MODE() (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK)
-#define _MM_SET_DENORMALS_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (x)))
-
 /// \brief Establishes a linear address memory range to be monitored and puts
 ///    the processor in the monitor event pending state. Data stored in the
 ///    monitored address range causes the processor to exit the pending state.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c MONITOR instruction.
+/// This intrinsic corresponds to the <c> MONITOR </c> instruction.
 ///
 /// \param __p
 ///    The memory range to be monitored. The size of the range is determined by
@@ -293,7 +284,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c MWAIT instruction.
+/// This intrinsic corresponds to the <c> MWAIT </c> instruction.
 ///
 /// \param __extensions
 ///    Optional extensions for the monitoring state, which may vary by
diff --git a/lib/Headers/popcntintrin.h b/lib/Headers/popcntintrin.h
index 7e2f167..0b4793e 100644
--- a/lib/Headers/popcntintrin.h
+++ b/lib/Headers/popcntintrin.h
@@ -31,7 +31,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c POPCNT instruction.
+/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
 ///
 /// \param __A
 ///    An unsigned 32-bit integer operand.
@@ -47,7 +47,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c POPCNT instruction.
+/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
 ///
 /// \param __A
 ///    A signed 32-bit integer operand.
@@ -64,7 +64,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c POPCNT instruction.
+/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
 ///
 /// \param __A
 ///    An unsigned 64-bit integer operand.
@@ -80,7 +80,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c POPCNT instruction.
+/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
 ///
 /// \param __A
 ///    A signed 64-bit integer operand.
diff --git a/lib/Headers/prfchwintrin.h b/lib/Headers/prfchwintrin.h
index ba02857..a378912 100644
--- a/lib/Headers/prfchwintrin.h
+++ b/lib/Headers/prfchwintrin.h
@@ -29,12 +29,36 @@
 #define __PRFCHWINTRIN_H
 
 #if defined(__PRFCHW__) || defined(__3dNOW__)
+/// \brief Loads a memory sequence containing the specified memory address into
+///    all data cache levels. The cache-coherency state is set to exclusive.
+///    Data can be read from and written to the cache line without additional
+///    delay.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the \c PREFETCHT0 instruction.
+///
+/// \param __P
+///    A pointer specifying the memory address to be prefetched.
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 _m_prefetch(void *__P)
 {
   __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */);
 }
 
+/// \brief Loads a memory sequence containing the specified memory address into
+///    the L1 data cache and sets the cache-coherency to modified. This
+///    provides a hint to the processor that the cache line will be modified.
+///    It is intended for use when the cache line will be written to shortly
+///    after the prefetch is performed. Note that the effect of this intrinsic
+///    is dependent on the processor implementation.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the \c PREFETCHW instruction.
+///
+/// \param __P
+///    A pointer specifying the memory address to be prefetched.
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 _m_prefetchw(void *__P)
 {
diff --git a/lib/Headers/smmintrin.h b/lib/Headers/smmintrin.h
index e48ab03..30d1038 100644
--- a/lib/Headers/smmintrin.h
+++ b/lib/Headers/smmintrin.h
@@ -46,37 +46,394 @@
 #define _MM_FROUND_RINT      (_MM_FROUND_RAISE_EXC | _MM_FROUND_CUR_DIRECTION)
 #define _MM_FROUND_NEARBYINT (_MM_FROUND_NO_EXC | _MM_FROUND_CUR_DIRECTION)
 
+/// \brief Rounds up each element of the 128-bit vector of [4 x float] to an
+///    integer and returns the rounded values in a 128-bit vector of
+///    [4 x float].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128 _mm_ceil_ps(__m128 X);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDPS / ROUNDPS </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [4 x float] values to be rounded up.
+/// \returns A 128-bit vector of [4 x float] containing the rounded values.
 #define _mm_ceil_ps(X)       _mm_round_ps((X), _MM_FROUND_CEIL)
+
+/// \brief Rounds up each element of the 128-bit vector of [2 x double] to an
+///    integer and returns the rounded values in a 128-bit vector of
+///    [2 x double].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128d _mm_ceil_pd(__m128d X);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDPD / ROUNDPD </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [2 x double] values to be rounded up.
+/// \returns A 128-bit vector of [2 x double] containing the rounded values.
 #define _mm_ceil_pd(X)       _mm_round_pd((X), _MM_FROUND_CEIL)
+
+/// \brief Copies three upper elements of the first 128-bit vector operand to
+///    the corresponding three upper elements of the 128-bit result vector of
+///    [4 x float]. Rounds up the lowest element of the second 128-bit vector
+///    operand to an integer and copies it to the lowest element of the 128-bit
+///    result vector of [4 x float].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128 _mm_ceil_ss(__m128 X, __m128 Y);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDSS / ROUNDSS </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [4 x float]. The values stored in bits [127:32] are
+///    copied to the corresponding bits of the result.
+/// \param Y
+///    A 128-bit vector of [4 x float]. The value stored in bits [31:0] is
+///    rounded up to the nearest integer and copied to the corresponding bits
+///    of the result.
+/// \returns A 128-bit vector of [4 x float] containing the copied and rounded
+///    values.
 #define _mm_ceil_ss(X, Y)    _mm_round_ss((X), (Y), _MM_FROUND_CEIL)
+
+/// \brief Copies the upper element of the first 128-bit vector operand to the
+///    corresponding upper element of the 128-bit result vector of [2 x double].
+///    Rounds up the lower element of the second 128-bit vector operand to an
+///    integer and copies it to the lower element of the 128-bit result vector
+///    of [2 x double].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128d _mm_ceil_sd(__m128d X, __m128d Y);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDSD / ROUNDSD </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [2 x double]. The value stored in bits [127:64] is
+///    copied to the corresponding bits of the result.
+/// \param Y
+///    A 128-bit vector of [2 x double]. The value stored in bits [63:0] is
+///    rounded up to the nearest integer and copied to the corresponding bits
+///    of the result.
+/// \returns A 128-bit vector of [2 x double] containing the copied and rounded
+///    values.
 #define _mm_ceil_sd(X, Y)    _mm_round_sd((X), (Y), _MM_FROUND_CEIL)
 
+/// \brief Rounds down each element of the 128-bit vector of [4 x float] to an
+///    an integer and returns the rounded values in a 128-bit vector of
+///    [4 x float].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128 _mm_floor_ps(__m128 X);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDPS / ROUNDPS </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [4 x float] values to be rounded down.
+/// \returns A 128-bit vector of [4 x float] containing the rounded values.
 #define _mm_floor_ps(X)      _mm_round_ps((X), _MM_FROUND_FLOOR)
+
+/// \brief Rounds down each element of the 128-bit vector of [2 x double] to an
+///    integer and returns the rounded values in a 128-bit vector of
+///    [2 x double].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128d _mm_floor_pd(__m128d X);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDPD / ROUNDPD </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [2 x double].
+/// \returns A 128-bit vector of [2 x double] containing the rounded values.
 #define _mm_floor_pd(X)      _mm_round_pd((X), _MM_FROUND_FLOOR)
+
+/// \brief Copies three upper elements of the first 128-bit vector operand to
+///    the corresponding three upper elements of the 128-bit result vector of
+///    [4 x float]. Rounds down the lowest element of the second 128-bit vector
+///    operand to an integer and copies it to the lowest element of the 128-bit
+///    result vector of [4 x float]. 
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128 _mm_floor_ss(__m128 X, __m128 Y);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDSS / ROUNDSS </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [4 x float]. The values stored in bits [127:32] are
+///    copied to the corresponding bits of the result.
+/// \param Y
+///    A 128-bit vector of [4 x float]. The value stored in bits [31:0] is
+///    rounded down to the nearest integer and copied to the corresponding bits
+///    of the result.
+/// \returns A 128-bit vector of [4 x float] containing the copied and rounded
+///    values.
 #define _mm_floor_ss(X, Y)   _mm_round_ss((X), (Y), _MM_FROUND_FLOOR)
+
+/// \brief Copies the upper element of the first 128-bit vector operand to the
+///    corresponding upper element of the 128-bit result vector of [2 x double].
+///    Rounds down the lower element of the second 128-bit vector operand to an
+///    integer and copies it to the lower element of the 128-bit result vector
+///    of [2 x double].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128d _mm_floor_sd(__m128d X, __m128d Y);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDSD / ROUNDSD </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [2 x double]. The value stored in bits [127:64] is
+///    copied to the corresponding bits of the result.
+/// \param Y
+///    A 128-bit vector of [2 x double]. The value stored in bits [63:0] is
+///    rounded down to the nearest integer and copied to the corresponding bits
+///    of the result.
+/// \returns A 128-bit vector of [2 x double] containing the copied and rounded
+///    values.
 #define _mm_floor_sd(X, Y)   _mm_round_sd((X), (Y), _MM_FROUND_FLOOR)
 
+/// \brief Rounds each element of the 128-bit vector of [4 x float] to an
+///    integer value according to the rounding control specified by the second
+///    argument and returns the rounded values in a 128-bit vector of
+///    [4 x float].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128 _mm_round_ps(__m128 X, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDPS / ROUNDPS </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [4 x float].
+/// \param M
+///    An integer value that specifies the rounding operation. \n
+///    Bits [7:4] are reserved. \n
+///    Bit [3] is a precision exception value: \n
+///      0: A normal PE exception is used \n
+///      1: The PE field is not updated \n
+///    Bit [2] is the rounding control source: \n
+///      0: Use bits [1:0] of \a M \n
+///      1: Use the current MXCSR setting \n
+///    Bits [1:0] contain the rounding control definition: \n
+///      00: Nearest \n
+///      01: Downward (toward negative infinity) \n
+///      10: Upward (toward positive infinity) \n
+///      11: Truncated
+/// \returns A 128-bit vector of [4 x float] containing the rounded values.
 #define _mm_round_ps(X, M) __extension__ ({ \
   (__m128)__builtin_ia32_roundps((__v4sf)(__m128)(X), (M)); })
 
+/// \brief Copies three upper elements of the first 128-bit vector operand to 
+///    the corresponding three upper elements of the 128-bit result vector of
+///    [4 x float]. Rounds the lowest element of the second 128-bit vector
+///    operand to an integer value according to the rounding control specified
+///    by the third argument and copies it to the lowest element of the 128-bit
+///    result vector of [4 x float].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code                       
+/// __m128 _mm_round_ss(__m128 X, __m128 Y, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDSS / ROUNDSS </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [4 x float]. The values stored in bits [127:32] are
+///    copied to the corresponding bits of the result.
+/// \param Y
+///    A 128-bit vector of [4 x float]. The value stored in bits [31:0] is
+///    rounded to the nearest integer using the specified rounding control and
+///    copied to the corresponding bits of the result.
+/// \param M
+///    An integer value that specifies the rounding operation. \n
+///    Bits [7:4] are reserved. \n
+///    Bit [3] is a precision exception value: \n
+///      0: A normal PE exception is used \n
+///      1: The PE field is not updated \n
+///    Bit [2] is the rounding control source: \n
+///      0: Use bits [1:0] of \a M \n
+///      1: Use the current MXCSR setting \n
+///    Bits [1:0] contain the rounding control definition: \n
+///      00: Nearest \n
+///      01: Downward (toward negative infinity) \n
+///      10: Upward (toward positive infinity) \n
+///      11: Truncated
+/// \returns A 128-bit vector of [4 x float] containing the copied and rounded
+///    values.
 #define _mm_round_ss(X, Y, M) __extension__ ({ \
   (__m128)__builtin_ia32_roundss((__v4sf)(__m128)(X), \
                                  (__v4sf)(__m128)(Y), (M)); })
 
+/// \brief Rounds each element of the 128-bit vector of [2 x double] to an
+///    integer value according to the rounding control specified by the second
+///    argument and returns the rounded values in a 128-bit vector of
+///    [2 x double].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128d _mm_round_pd(__m128d X, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDPD / ROUNDPD </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [2 x double].
+/// \param M
+///    An integer value that specifies the rounding operation. \n
+///    Bits [7:4] are reserved. \n
+///    Bit [3] is a precision exception value: \n
+///      0: A normal PE exception is used \n
+///      1: The PE field is not updated \n
+///    Bit [2] is the rounding control source: \n
+///      0: Use bits [1:0] of \a M \n
+///      1: Use the current MXCSR setting \n
+///    Bits [1:0] contain the rounding control definition: \n
+///      00: Nearest \n
+///      01: Downward (toward negative infinity) \n
+///      10: Upward (toward positive infinity) \n
+///      11: Truncated
+/// \returns A 128-bit vector of [2 x double] containing the rounded values.
 #define _mm_round_pd(X, M) __extension__ ({ \
   (__m128d)__builtin_ia32_roundpd((__v2df)(__m128d)(X), (M)); })
 
+
+/// \brief Copies the upper element of the first 128-bit vector operand to the
+///    corresponding upper element of the 128-bit result vector of [2 x double].
+///    Rounds the lower element of the second 128-bit vector operand to an 
+///    integer value according to the rounding control specified by the third
+///    argument and copies it to the lower element of the 128-bit result vector
+///    of [2 x double].
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128d _mm_round_sd(__m128d X, __m128d Y, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VROUNDSD / ROUNDSD </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [2 x double]. The value stored in bits [127:64] is
+///    copied to the corresponding bits of the result.
+/// \param Y
+///    A 128-bit vector of [2 x double]. The value stored in bits [63:0] is
+///    rounded to the nearest integer using the specified rounding control and
+///    copied to the corresponding bits of the result.
+/// \param M
+///    An integer value that specifies the rounding operation. \n
+///    Bits [7:4] are reserved. \n
+///    Bit [3] is a precision exception value: \n
+///      0: A normal PE exception is used \n
+///      1: The PE field is not updated \n
+///    Bit [2] is the rounding control source: \n
+///      0: Use bits [1:0] of \a M \n
+///      1: Use the current MXCSR setting \n
+///    Bits [1:0] contain the rounding control definition: \n
+///      00: Nearest \n
+///      01: Downward (toward negative infinity) \n
+///      10: Upward (toward positive infinity) \n
+///      11: Truncated
+/// \returns A 128-bit vector of [2 x double] containing the copied and rounded
+///    values.
 #define _mm_round_sd(X, Y, M) __extension__ ({ \
   (__m128d)__builtin_ia32_roundsd((__v2df)(__m128d)(X), \
                                   (__v2df)(__m128d)(Y), (M)); })
 
 /* SSE4 Packed Blending Intrinsics.  */
+/// \brief Returns a 128-bit vector of [2 x double] where the values are
+///    selected from either the first or second operand as specified by the
+///    third operand, the control mask.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128d _mm_blend_pd(__m128d V1, __m128d V2, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VBLENDPD / BLENDPD </i> </c>
+/// instruction.
+///
+/// \param V1
+///    A 128-bit vector of [2 x double].
+/// \param V2
+///    A 128-bit vector of [2 x double].
+/// \param M
+///    An immediate integer operand, with mask bits [1:0] specifying how the
+///    values are to be copied. The position of the mask bit corresponds to the
+///    index of a copied value. When a mask bit is 0, the corresponding 64-bit
+///    element in operand \a V1 is copied to the same position in the result.
+///    When a mask bit is 1, the corresponding 64-bit element in operand \a V2
+///    is copied to the same position in the result.
+/// \returns A 128-bit vector of [2 x double] containing the copied values.
 #define _mm_blend_pd(V1, V2, M) __extension__ ({ \
   (__m128d)__builtin_shufflevector((__v2df)(__m128d)(V1), \
                                    (__v2df)(__m128d)(V2), \
                                    (((M) & 0x01) ? 2 : 0), \
                                    (((M) & 0x02) ? 3 : 1)); })
 
+/// \brief Returns a 128-bit vector of [4 x float] where the values are selected
+///    from either the first or second operand as specified by the third
+///    operand, the control mask.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128 _mm_blend_ps(__m128 V1, __m128 V2, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VBLENDPS / BLENDPS </i> </c>
+/// instruction.
+///
+/// \param V1
+///    A 128-bit vector of [4 x float].
+/// \param V2
+///    A 128-bit vector of [4 x float].
+/// \param M
+///    An immediate integer operand, with mask bits [3:0] specifying how the
+///    values are to be copied. The position of the mask bit corresponds to the
+///    index of a copied value. When a mask bit is 0, the corresponding 32-bit
+///    element in operand \a V1 is copied to the same position in the result.
+///    When a mask bit is 1, the corresponding 32-bit element in operand \a V2
+///    is copied to the same position in the result.
+/// \returns A 128-bit vector of [4 x float] containing the copied values.
 #define _mm_blend_ps(V1, V2, M) __extension__ ({ \
   (__m128)__builtin_shufflevector((__v4sf)(__m128)(V1), (__v4sf)(__m128)(V2), \
                                   (((M) & 0x01) ? 4 : 0), \
@@ -84,6 +441,27 @@
                                   (((M) & 0x04) ? 6 : 2), \
                                   (((M) & 0x08) ? 7 : 3)); })
 
+/// \brief Returns a 128-bit vector of [2 x double] where the values are
+///    selected from either the first or second operand as specified by the
+///    third operand, the control mask.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VBLENDVPD / BLENDVPD </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [2 x double].
+/// \param __V2
+///    A 128-bit vector of [2 x double].
+/// \param __M
+///    A 128-bit vector operand, with mask bits 127 and 63 specifying how the
+///    values are to be copied. The position of the mask bit corresponds to the
+///    most significant bit of a copied value. When a mask bit is 0, the
+///    corresponding 64-bit element in operand \a __V1 is copied to the same
+///    position in the result. When a mask bit is 1, the corresponding 64-bit
+///    element in operand \a __V2 is copied to the same position in the result.
+/// \returns A 128-bit vector of [2 x double] containing the copied values.
 static __inline__ __m128d __DEFAULT_FN_ATTRS
 _mm_blendv_pd (__m128d __V1, __m128d __V2, __m128d __M)
 {
@@ -91,6 +469,27 @@
                                             (__v2df)__M);
 }
 
+/// \brief Returns a 128-bit vector of [4 x float] where the values are
+///    selected from either the first or second operand as specified by the
+///    third operand, the control mask.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VBLENDVPS / BLENDVPS </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [4 x float].
+/// \param __V2
+///    A 128-bit vector of [4 x float].
+/// \param __M
+///    A 128-bit vector operand, with mask bits 127, 95, 63, and 31 specifying
+///    how the values are to be copied. The position of the mask bit corresponds
+///    to the most significant bit of a copied value. When a mask bit is 0, the
+///    corresponding 32-bit element in operand \a __V1 is copied to the same
+///    position in the result. When a mask bit is 1, the corresponding 32-bit
+///    element in operand \a __V2 is copied to the same position in the result.
+/// \returns A 128-bit vector of [4 x float] containing the copied values.
 static __inline__ __m128 __DEFAULT_FN_ATTRS
 _mm_blendv_ps (__m128 __V1, __m128 __V2, __m128 __M)
 {
@@ -98,6 +497,27 @@
                                            (__v4sf)__M);
 }
 
+/// \brief Returns a 128-bit vector of [16 x i8] where the values are selected
+///    from either of the first or second operand as specified by the third
+///    operand, the control mask.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPBLENDVB / PBLENDVB </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [16 x i8].
+/// \param __V2
+///    A 128-bit vector of [16 x i8].
+/// \param __M
+///    A 128-bit vector operand, with mask bits 127, 119, 111 ... 7 specifying
+///    how the values are to be copied. The position of the mask bit corresponds
+///    to the most significant bit of a copied value. When a mask bit is 0, the
+///    corresponding 8-bit element in operand \a __V1 is copied to the same
+///    position in the result. When a mask bit is 1, the corresponding 8-bit
+///    element in operand \a __V2 is copied to the same position in the result.
+/// \returns A 128-bit vector of [16 x i8] containing the copied values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_blendv_epi8 (__m128i __V1, __m128i __V2, __m128i __M)
 {
@@ -105,6 +525,31 @@
                                                (__v16qi)__M);
 }
 
+/// \brief Returns a 128-bit vector of [8 x i16] where the values are selected
+///    from either of the first or second operand as specified by the third
+///    operand, the control mask.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128i _mm_blend_epi16(__m128i V1, __m128i V2, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPBLENDW / PBLENDW </i> </c>
+/// instruction.
+///
+/// \param V1
+///    A 128-bit vector of [8 x i16].
+/// \param V2
+///    A 128-bit vector of [8 x i16].
+/// \param M
+///    An immediate integer operand, with mask bits [7:0] specifying how the
+///    values are to be copied. The position of the mask bit corresponds to the
+///    index of a copied value. When a mask bit is 0, the corresponding 16-bit
+///    element in operand \a V1 is copied to the same position in the result.
+///    When a mask bit is 1, the corresponding 16-bit element in operand \a V2
+///    is copied to the same position in the result.
+/// \returns A 128-bit vector of [8 x i16] containing the copied values.
 #define _mm_blend_epi16(V1, V2, M) __extension__ ({ \
   (__m128i)__builtin_shufflevector((__v8hi)(__m128i)(V1), \
                                    (__v8hi)(__m128i)(V2), \
@@ -118,12 +563,41 @@
                                    (((M) & 0x80) ? 15 : 7)); })
 
 /* SSE4 Dword Multiply Instructions.  */
+/// \brief Multiples corresponding elements of two 128-bit vectors of [4 x i32]
+///    and returns the lower 32 bits of the each product in a 128-bit vector of
+///    [4 x i32].
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMULLD / PMULLD </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit integer vector.
+/// \param __V2
+///    A 128-bit integer vector. 
+/// \returns A 128-bit integer vector containing the products of both operands.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_mullo_epi32 (__m128i __V1, __m128i __V2)
 {
   return (__m128i) ((__v4su)__V1 * (__v4su)__V2);
 }
 
+/// \brief Multiplies corresponding even-indexed elements of two 128-bit
+///    vectors of [4 x i32] and returns a 128-bit vector of [2 x i64]
+///    containing the products.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMULDQ / PMULDQ </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [4 x i32].
+/// \param __V2
+///    A 128-bit vector of [4 x i32].
+/// \returns A 128-bit vector of [2 x i64] containing the products of both
+///    operands.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_mul_epi32 (__m128i __V1, __m128i __V2)
 {
@@ -131,15 +605,89 @@
 }
 
 /* SSE4 Floating Point Dot Product Instructions.  */
+/// \brief Computes the dot product of the two 128-bit vectors of [4 x float]
+///    and returns it in the elements of the 128-bit result vector of
+///    [4 x float]. The immediate integer operand controls which input elements
+///    will contribute to the dot product, and where the final results are
+///    returned.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128 _mm_dp_ps(__m128 X, __m128 Y, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VDPPS / DPPS </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [4 x float].
+/// \param Y
+///    A 128-bit vector of [4 x float].
+/// \param M
+///    An immediate integer operand. Mask bits [7:4] determine which elements
+///    of the input vectors are used, with bit [4] corresponding to the lowest
+///    element and bit [7] corresponding to the highest element of each [4 x
+///    float] vector. If a bit is set, the corresponding elements from the two
+///    input vectors are used as an input for dot product; otherwise that input
+///    is treated as zero. Bits [3:0] determine which elements of the result
+///    will receive a copy of the final dot product, with bit [0] corresponding
+///    to the lowest element and bit [3] corresponding to the highest element of
+///    each [4 x float] subvector. If a bit is set, the dot product is returned
+///    in the corresponding element; otherwise that element is set to zero.
+/// \returns A 128-bit vector of [4 x float] containing the dot product.
 #define _mm_dp_ps(X, Y, M) __extension__ ({ \
   (__m128) __builtin_ia32_dpps((__v4sf)(__m128)(X), \
                                (__v4sf)(__m128)(Y), (M)); })
 
+/// \brief Computes the dot product of the two 128-bit vectors of [2 x double]
+///    and returns it in the elements of the 128-bit result vector of
+///    [2 x double]. The immediate integer operand controls which input
+///    elements will contribute to the dot product, and where the final results
+///    are returned.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128d _mm_dp_pd(__m128d X, __m128d Y, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VDPPD / DPPD </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [2 x double].
+/// \param Y
+///    A 128-bit vector of [2 x double].
+/// \param M
+///    An immediate integer operand. Mask bits [5:4] determine which elements
+///    of the input vectors are used, with bit [4] corresponding to the lowest
+///    element and bit [5] corresponding to the highest element of each of [2 x
+///    double] vector. If a bit is set, the corresponding elements from the two
+///    input vectors are used as an input for dot product; otherwise that input
+///    is treated as zero. Bits [1:0] determine which elements of the result
+///    will receive a copy of the final dot product, with bit [0] corresponding
+///    to the lowest element and bit [3] corresponding to the highest element of
+///    each [2 x double] vector. If a bit is set, the dot product is returned in
+///    the corresponding element; otherwise that element is set to zero.
 #define _mm_dp_pd(X, Y, M) __extension__ ({\
   (__m128d) __builtin_ia32_dppd((__v2df)(__m128d)(X), \
                                 (__v2df)(__m128d)(Y), (M)); })
 
 /* SSE4 Streaming Load Hint Instruction.  */
+/// \brief Loads integer values from a 128-bit aligned memory location to a
+///    128-bit integer vector.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VMOVNTDQA / MOVNTDQA </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A pointer to a 128-bit aligned memory location that contains the integer
+///    values.
+/// \returns A 128-bit integer vector containing the data stored at the
+///    specified memory location.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_stream_load_si128 (__m128i const *__V)
 {
@@ -147,48 +695,160 @@
 }
 
 /* SSE4 Packed Integer Min/Max Instructions.  */
+/// \brief Compares the corresponding elements of two 128-bit vectors of
+///    [16 x i8] and returns a 128-bit vector of [16 x i8] containing the lesser
+///    of the two values.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMINSB / PMINSB </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [16 x i8].
+/// \param __V2
+///    A 128-bit vector of [16 x i8]
+/// \returns A 128-bit vector of [16 x i8] containing the lesser values.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_min_epi8 (__m128i __V1, __m128i __V2)
 {
   return (__m128i) __builtin_ia32_pminsb128 ((__v16qi) __V1, (__v16qi) __V2);
 }
 
+/// \brief Compares the corresponding elements of two 128-bit vectors of
+///    [16 x i8] and returns a 128-bit vector of [16 x i8] containing the
+///    greater value of the two.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMAXSB / PMAXSB </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [16 x i8].
+/// \param __V2
+///    A 128-bit vector of [16 x i8].
+/// \returns A 128-bit vector of [16 x i8] containing the greater values.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_max_epi8 (__m128i __V1, __m128i __V2)
 {
   return (__m128i) __builtin_ia32_pmaxsb128 ((__v16qi) __V1, (__v16qi) __V2);
 }
 
+/// \brief Compares the corresponding elements of two 128-bit vectors of
+///    [8 x u16] and returns a 128-bit vector of [8 x u16] containing the lesser
+///    value of the two.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMINUW / PMINUW </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [8 x u16].
+/// \param __V2
+///    A 128-bit vector of [8 x u16].
+/// \returns A 128-bit vector of [8 x u16] containing the lesser values.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_min_epu16 (__m128i __V1, __m128i __V2)
 {
   return (__m128i) __builtin_ia32_pminuw128 ((__v8hi) __V1, (__v8hi) __V2);
 }
 
+/// \brief Compares the corresponding elements of two 128-bit vectors of
+///    [8 x u16] and returns a 128-bit vector of [8 x u16] containing the
+///    greater value of the two.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMAXUW / PMAXUW </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [8 x u16].
+/// \param __V2
+///    A 128-bit vector of [8 x u16].
+/// \returns A 128-bit vector of [8 x u16] containing the greater values.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_max_epu16 (__m128i __V1, __m128i __V2)
 {
   return (__m128i) __builtin_ia32_pmaxuw128 ((__v8hi) __V1, (__v8hi) __V2);
 }
 
+/// \brief Compares the corresponding elements of two 128-bit vectors of
+///    [4 x i32] and returns a 128-bit vector of [4 x i32] containing the lesser
+///    value of the two.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMINSD / PMINSD </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [4 x i32].
+/// \param __V2
+///    A 128-bit vector of [4 x i32].
+/// \returns A 128-bit vector of [4 x i32] containing the lesser values.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_min_epi32 (__m128i __V1, __m128i __V2)
 {
   return (__m128i) __builtin_ia32_pminsd128 ((__v4si) __V1, (__v4si) __V2);
 }
 
+/// \brief Compares the corresponding elements of two 128-bit vectors of 
+///    [4 x i32] and returns a 128-bit vector of [4 x i32] containing the
+///    greater value of the two.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMAXSD / PMAXSD </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [4 x i32].
+/// \param __V2
+///    A 128-bit vector of [4 x i32].
+/// \returns A 128-bit vector of [4 x i32] containing the greater values.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_max_epi32 (__m128i __V1, __m128i __V2)
 {
   return (__m128i) __builtin_ia32_pmaxsd128 ((__v4si) __V1, (__v4si) __V2);
 }
 
+/// \brief Compares the corresponding elements of two 128-bit vectors of
+///    [4 x u32] and returns a 128-bit vector of [4 x u32] containing the lesser
+///    value of the two.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMINUD / PMINUD </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [4 x u32].
+/// \param __V2
+///    A 128-bit vector of [4 x u32].
+/// \returns A 128-bit vector of [4 x u32] containing the lesser values.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_min_epu32 (__m128i __V1, __m128i __V2)
 {
   return (__m128i) __builtin_ia32_pminud128((__v4si) __V1, (__v4si) __V2);
 }
 
+/// \brief Compares the corresponding elements of two 128-bit vectors of
+///    [4 x u32] and returns a 128-bit vector of [4 x u32] containing the
+///    greater value of the two.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMAXUD / PMAXUD </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [4 x u32].
+/// \param __V2
+///    A 128-bit vector of [4 x u32].
+/// \returns A 128-bit vector of [4 x u32] containing the greater values.
 static __inline__  __m128i __DEFAULT_FN_ATTRS
 _mm_max_epu32 (__m128i __V1, __m128i __V2)
 {
@@ -196,7 +856,70 @@
 }
 
 /* SSE4 Insertion and Extraction from XMM Register Instructions.  */
+/// \brief Takes the first argument \a X and inserts an element from the second
+///    argument \a Y as selected by the third argument \a N. That result then
+///    has elements zeroed out also as selected by the third argument \a N. The
+///    resulting 128-bit vector of [4 x float] is then returned.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128 _mm_insert_ps(__m128 X, __m128 Y, const int N);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VINSERTPS </i> </c> instruction.
+///
+/// \param X
+///    A 128-bit vector source operand of [4 x float]. With the exception of
+///    those bits in the result copied from parameter \a Y and zeroed by bits
+///    [3:0] of \a N, all bits from this parameter are copied to the result.
+/// \param Y
+///    A 128-bit vector source operand of [4 x float]. One single-precision
+///    floating-point element from this source, as determined by the immediate
+///    parameter, is copied to the result.
+/// \param N
+///    Specifies which bits from operand \a Y will be copied, which bits in the
+///    result they will be be copied to, and which bits in the result will be
+///    cleared. The following assignments are made: \n
+///    Bits [7:6] specify the bits to copy from operand \a Y: \n
+///      00: Selects bits [31:0] from operand \a Y. \n
+///      01: Selects bits [63:32] from operand \a Y. \n
+///      10: Selects bits [95:64] from operand \a Y. \n
+///      11: Selects bits [127:96] from operand \a Y. \n
+///    Bits [5:4] specify the bits in the result to which the selected bits
+///    from operand \a Y are copied: \n
+///      00: Copies the selected bits from \a Y to result bits [31:0]. \n
+///      01: Copies the selected bits from \a Y to result bits [63:32]. \n
+///      10: Copies the selected bits from \a Y to result bits [95:64]. \n
+///      11: Copies the selected bits from \a Y to result bits [127:96]. \n
+///    Bits[3:0]: If any of these bits are set, the corresponding result
+///    element is cleared.
+/// \returns A 128-bit vector of [4 x float] containing the copied single-
+///    precision floating point elements from the operands.
 #define _mm_insert_ps(X, Y, N) __builtin_ia32_insertps128((X), (Y), (N))
+
+/// \brief Extracts a 32-bit integer from a 128-bit vector of [4 x float] and
+///    returns it, using the immediate value parameter \a N as a selector.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_extract_ps(__m128 X, const int N);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VEXTRACTPS / EXTRACTPS </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [4 x float].
+/// \param N
+///    An immediate value. Bits [1:0] determines which bits from the argument
+///    \a X are extracted and returned: \n 
+///    00: Bits [31:0] of parameter \a X are returned. \n
+///    01: Bits [63:32] of parameter \a X are returned. \n
+///    10: Bits [95:64] of parameter \a X are returned. \n
+///    11: Bits [127:96] of parameter \a X are returned.
+/// \returns A 32-bit integer containing the extracted 32 bits of float data.
 #define _mm_extract_ps(X, N) (__extension__                      \
                               ({ union { int __i; float __f; } __t;  \
                                  __v4sf __a = (__v4sf)(__m128)(X);       \
@@ -217,15 +940,113 @@
                                              _MM_MK_INSERTPS_NDX((N), 0, 0x0e))
 
 /* Insert int into packed integer array at index.  */
+/// \brief Constructs a 128-bit vector of [16 x i8] by first making a copy of
+///    the 128-bit integer vector parameter, and then inserting the lower 8 bits
+///    of an integer parameter \a I into an offset specified by the immediate
+///    value parameter \a N.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128i _mm_insert_epi8(__m128i X, int I, const int N);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPINSRB / PINSRB </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit integer vector of [16 x i8]. This vector is copied to the
+///    result and then one of the sixteen elements in the result vector is
+///    replaced by the lower 8 bits of \a I.
+/// \param I
+///    An integer. The lower 8 bits of this operand are written to the result
+///    beginning at the offset specified by \a N.
+/// \param N
+///    An immediate value. Bits [3:0] specify the bit offset in the result at
+///    which the lower 8 bits of \a I are written. \n
+///    0000: Bits [7:0] of the result are used for insertion. \n
+///    0001: Bits [15:8] of the result are used for insertion. \n
+///    0010: Bits [23:16] of the result are used for insertion. \n
+///    0011: Bits [31:24] of the result are used for insertion. \n
+///    0100: Bits [39:32] of the result are used for insertion. \n
+///    0101: Bits [47:40] of the result are used for insertion. \n
+///    0110: Bits [55:48] of the result are used for insertion. \n
+///    0111: Bits [63:56] of the result are used for insertion. \n
+///    1000: Bits [71:64] of the result are used for insertion. \n
+///    1001: Bits [79:72] of the result are used for insertion. \n
+///    1010: Bits [87:80] of the result are used for insertion. \n
+///    1011: Bits [95:88] of the result are used for insertion. \n
+///    1100: Bits [103:96] of the result are used for insertion. \n
+///    1101: Bits [111:104] of the result are used for insertion. \n
+///    1110: Bits [119:112] of the result are used for insertion. \n
+///    1111: Bits [127:120] of the result are used for insertion.
+/// \returns A 128-bit integer vector containing the constructed values.
 #define _mm_insert_epi8(X, I, N) (__extension__                           \
                                   ({ __v16qi __a = (__v16qi)(__m128i)(X); \
                                      __a[(N) & 15] = (I);                 \
                                      (__m128i)__a;}))
+
+/// \brief Constructs a 128-bit vector of [4 x i32] by first making a copy of
+///    the 128-bit integer vector parameter, and then inserting the 32-bit
+///    integer parameter \a I at the offset specified by the immediate value
+///    parameter \a N.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128i _mm_insert_epi32(__m128i X, int I, const int N);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPINSRD / PINSRD </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit integer vector of [4 x i32]. This vector is copied to the
+///    result and then one of the four elements in the result vector is
+///    replaced by \a I.
+/// \param I
+///    A 32-bit integer that is written to the result beginning at the offset
+///    specified by \a N.
+/// \param N
+///    An immediate value. Bits [1:0] specify the bit offset in the result at
+///    which the integer \a I is written.
+///    00: Bits [31:0] of the result are used for insertion. \n
+///    01: Bits [63:32] of the result are used for insertion. \n
+///    10: Bits [95:64] of the result are used for insertion. \n
+///    11: Bits [127:96] of the result are used for insertion.
+/// \returns A 128-bit integer vector containing the constructed values.
 #define _mm_insert_epi32(X, I, N) (__extension__                         \
                                    ({ __v4si __a = (__v4si)(__m128i)(X); \
                                       __a[(N) & 3] = (I);                \
                                       (__m128i)__a;}))
 #ifdef __x86_64__
+/// \brief Constructs a 128-bit vector of [2 x i64] by first making a copy of
+///    the 128-bit integer vector parameter, and then inserting the 64-bit
+///    integer parameter \a I, using the immediate value parameter \a N as an
+///    insertion location selector. 
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128i _mm_insert_epi64(__m128i X, long long I, const int N);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPINSRQ / PINSRQ </i> </c>
+/// instruction.
+///                                                                      
+/// \param X
+///    A 128-bit integer vector of [2 x i64]. This vector is copied to the
+///    result and then one of the two elements in the result vector is replaced
+///    by \a I.
+/// \param I
+///    A 64-bit integer that is written to the result beginning at the offset
+///    specified by \a N.
+/// \param N
+///    An immediate value. Bit [0] specifies the bit offset in the result at
+///    which the integer \a I is written.
+///    0: Bits [63:0] of the result are used for insertion. \n
+///    1: Bits [127:64] of the result are used for insertion. \n
+/// \returns A 128-bit integer vector containing the constructed values.
 #define _mm_insert_epi64(X, I, N) (__extension__                         \
                                    ({ __v2di __a = (__v2di)(__m128i)(X); \
                                       __a[(N) & 1] = (I);                \
@@ -235,42 +1056,228 @@
 /* Extract int from packed integer array at index.  This returns the element
  * as a zero extended value, so it is unsigned.
  */
+/// \brief Extracts an 8-bit element from the 128-bit integer vector of
+///    [16 x i8], using the immediate value parameter \a N as a selector.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_extract_epi8(__m128i X, const int N);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPEXTRB / PEXTRB </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit integer vector.
+/// \param N
+///    An immediate value. Bits [3:0] specify which 8-bit vector element
+///    from the argument \a X to extract and copy to the result. \n
+///    0000: Bits [7:0] of parameter \a X are extracted. \n
+///    0001: Bits [15:8] of the parameter \a X are extracted. \n
+///    0010: Bits [23:16] of the parameter \a X are extracted. \n
+///    0011: Bits [31:24] of the parameter \a X are extracted. \n
+///    0100: Bits [39:32] of the parameter \a X are extracted. \n
+///    0101: Bits [47:40] of the parameter \a X are extracted. \n
+///    0110: Bits [55:48] of the parameter \a X are extracted. \n
+///    0111: Bits [63:56] of the parameter \a X are extracted. \n
+///    1000: Bits [71:64] of the parameter \a X are extracted. \n
+///    1001: Bits [79:72] of the parameter \a X are extracted. \n
+///    1010: Bits [87:80] of the parameter \a X are extracted. \n
+///    1011: Bits [95:88] of the parameter \a X are extracted. \n
+///    1100: Bits [103:96] of the parameter \a X are extracted. \n
+///    1101: Bits [111:104] of the parameter \a X are extracted. \n
+///    1110: Bits [119:112] of the parameter \a X are extracted. \n
+///    1111: Bits [127:120] of the parameter \a X are extracted.
+/// \returns  An unsigned integer, whose lower 8 bits are selected from the
+///    128-bit integer vector parameter and the remaining bits are assigned
+///    zeros.
 #define _mm_extract_epi8(X, N) (__extension__                           \
                                 ({ __v16qi __a = (__v16qi)(__m128i)(X); \
                                    (int)(unsigned char) __a[(N) & 15];}))
+
+/// \brief Extracts a 32-bit element from the 128-bit integer vector of
+///    [4 x i32], using the immediate value parameter \a N as a selector.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_extract_epi32(__m128i X, const int N);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPEXTRD / PEXTRD </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit integer vector.
+/// \param N
+///    An immediate value. Bits [1:0] specify which 32-bit vector element
+///    from the argument \a X to extract and copy to the result. \n
+///    00: Bits [31:0] of the parameter \a X are extracted. \n
+///    01: Bits [63:32] of the parameter \a X are extracted. \n
+///    10: Bits [95:64] of the parameter \a X are extracted. \n
+///    11: Bits [127:96] of the parameter \a X are exracted.
+/// \returns  An integer, whose lower 32 bits are selected from the 128-bit
+///    integer vector parameter and the remaining bits are assigned zeros.
 #define _mm_extract_epi32(X, N) (__extension__                         \
                                  ({ __v4si __a = (__v4si)(__m128i)(X); \
                                     (int)__a[(N) & 3];}))
 #ifdef __x86_64__
+/// \brief Extracts a 64-bit element from the 128-bit integer vector of
+///    [2 x i64], using the immediate value parameter \a N as a selector.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// long long _mm_extract_epi64(__m128i X, const int N);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPEXTRQ / PEXTRQ </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit integer vector.
+/// \param N
+///    An immediate value. Bit [0] specifies which 64-bit vector element
+///    from the argument \a X to return. \n
+///    0: Bits [63:0] are returned. \n
+///    1: Bits [127:64] are returned. \n
+/// \returns  A 64-bit integer.
 #define _mm_extract_epi64(X, N) (__extension__                         \
                                  ({ __v2di __a = (__v2di)(__m128i)(X); \
                                     (long long)__a[(N) & 1];}))
 #endif /* __x86_64 */
 
 /* SSE4 128-bit Packed Integer Comparisons.  */
+/// \brief Tests whether the specified bits in a 128-bit integer vector are all
+///    zeros.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
+/// instruction.
+///
+/// \param __M
+///    A 128-bit integer vector containing the bits to be tested.
+/// \param __V
+///    A 128-bit integer vector selecting which bits to test in operand \a __M.
+/// \returns TRUE if the specified bits are all zeros; FALSE otherwise.
 static __inline__ int __DEFAULT_FN_ATTRS
 _mm_testz_si128(__m128i __M, __m128i __V)
 {
   return __builtin_ia32_ptestz128((__v2di)__M, (__v2di)__V);
 }
 
+/// \brief Tests whether the specified bits in a 128-bit integer vector are all
+///    ones.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
+/// instruction.
+///
+/// \param __M
+///    A 128-bit integer vector containing the bits to be tested.
+/// \param __V
+///    A 128-bit integer vector selecting which bits to test in operand \a __M.
+/// \returns TRUE if the specified bits are all ones; FALSE otherwise.
 static __inline__ int __DEFAULT_FN_ATTRS
 _mm_testc_si128(__m128i __M, __m128i __V)
 {
   return __builtin_ia32_ptestc128((__v2di)__M, (__v2di)__V);
 }
 
+/// \brief Tests whether the specified bits in a 128-bit integer vector are
+///    neither all zeros nor all ones.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
+/// instruction.
+///
+/// \param __M
+///    A 128-bit integer vector containing the bits to be tested.
+/// \param __V
+///    A 128-bit integer vector selecting which bits to test in operand \a __M.
+/// \returns TRUE if the specified bits are neither all zeros nor all ones;
+///    FALSE otherwise.
 static __inline__ int __DEFAULT_FN_ATTRS
 _mm_testnzc_si128(__m128i __M, __m128i __V)
 {
   return __builtin_ia32_ptestnzc128((__v2di)__M, (__v2di)__V);
 }
 
+/// \brief Tests whether the specified bits in a 128-bit integer vector are all
+///    ones.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_test_all_ones(__m128i V);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
+/// instruction.
+///
+/// \param V
+///    A 128-bit integer vector containing the bits to be tested.
+/// \returns TRUE if the bits specified in the operand are all set to 1; FALSE
+///    otherwise.
 #define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_cmpeq_epi32((V), (V)))
+
+/// \brief Tests whether the specified bits in a 128-bit integer vector are
+///    neither all zeros nor all ones.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_test_mix_ones_zeros(__m128i M, __m128i V);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
+/// instruction.
+///
+/// \param M
+///    A 128-bit integer vector containing the bits to be tested.
+/// \param V
+///    A 128-bit integer vector selecting which bits to test in operand \a M.
+/// \returns TRUE if the specified bits are neither all zeros nor all ones;
+///    FALSE otherwise.
 #define _mm_test_mix_ones_zeros(M, V) _mm_testnzc_si128((M), (V))
+
+/// \brief Tests whether the specified bits in a 128-bit integer vector are all
+///    zeros.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_test_all_zeros(__m128i M, __m128i V);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
+/// instruction.
+///
+/// \param M
+///    A 128-bit integer vector containing the bits to be tested.
+/// \param V
+///    A 128-bit integer vector selecting which bits to test in operand \a M.
+/// \returns TRUE if the specified bits are all zeros; FALSE otherwise.
 #define _mm_test_all_zeros(M, V) _mm_testz_si128 ((M), (V))
 
 /* SSE4 64-bit Packed Integer Comparisons.  */
+/// \brief Compares each of the corresponding 64-bit values of the 128-bit
+///    integer vectors for equality.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPEQQ / PCMPEQQ </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit integer vector.
+/// \param __V2
+///    A 128-bit integer vector.
+/// \returns A 128-bit integer vector containing the comparison results.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cmpeq_epi64(__m128i __V1, __m128i __V2)
 {
@@ -278,6 +1285,20 @@
 }
 
 /* SSE4 Packed Integer Sign-Extension.  */
+/// \brief Sign-extends each of the lower eight 8-bit integer elements of a
+///    128-bit vector of [16 x i8] to 16-bit values and returns them in a
+///    128-bit vector of [8 x i16]. The upper eight elements of the input vector
+///    are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVSXBW / PMOVSXBW </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [16 x i8]. The lower eight 8-bit elements are sign-
+///    extended to 16-bit values.
+/// \returns A 128-bit vector of [8 x i16] containing the sign-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepi8_epi16(__m128i __V)
 {
@@ -286,6 +1307,20 @@
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qs)__V, (__v16qs)__V, 0, 1, 2, 3, 4, 5, 6, 7), __v8hi);
 }
 
+/// \brief Sign-extends each of the lower four 8-bit integer elements of a
+///    128-bit vector of [16 x i8] to 32-bit values and returns them in a
+///    128-bit vector of [4 x i32]. The upper twelve elements of the input
+///    vector are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVSXBD / PMOVSXBD </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [16 x i8]. The lower four 8-bit elements are sign-
+///    extended to 32-bit values.
+/// \returns A 128-bit vector of [4 x i32] containing the sign-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepi8_epi32(__m128i __V)
 {
@@ -294,6 +1329,20 @@
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qs)__V, (__v16qs)__V, 0, 1, 2, 3), __v4si);
 }
 
+/// \brief Sign-extends each of the lower two 8-bit integer elements of a
+///    128-bit integer vector of [16 x i8] to 64-bit values and returns them in
+///    a 128-bit vector of [2 x i64]. The upper fourteen elements of the input
+///    vector are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVSXBQ / PMOVSXBQ </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [16 x i8]. The lower two 8-bit elements are sign-
+///    extended to 64-bit values.
+/// \returns A 128-bit vector of [2 x i64] containing the sign-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepi8_epi64(__m128i __V)
 {
@@ -302,18 +1351,60 @@
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qs)__V, (__v16qs)__V, 0, 1), __v2di);
 }
 
+/// \brief Sign-extends each of the lower four 16-bit integer elements of a
+///    128-bit integer vector of [8 x i16] to 32-bit values and returns them in
+///    a 128-bit vector of [4 x i32]. The upper four elements of the input
+///    vector are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVSXWD / PMOVSXWD </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [8 x i16]. The lower four 16-bit elements are sign-
+///    extended to 32-bit values.
+/// \returns A 128-bit vector of [4 x i32] containing the sign-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepi16_epi32(__m128i __V)
 {
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v8hi)__V, (__v8hi)__V, 0, 1, 2, 3), __v4si);
 }
 
+/// \brief Sign-extends each of the lower two 16-bit integer elements of a
+///    128-bit integer vector of [8 x i16] to 64-bit values and returns them in
+///    a 128-bit vector of [2 x i64]. The upper six elements of the input
+///    vector are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVSXWQ / PMOVSXWQ </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [8 x i16]. The lower two 16-bit elements are sign-
+///    extended to 64-bit values.
+/// \returns A 128-bit vector of [2 x i64] containing the sign-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepi16_epi64(__m128i __V)
 {
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v8hi)__V, (__v8hi)__V, 0, 1), __v2di);
 }
 
+/// \brief Sign-extends each of the lower two 32-bit integer elements of a
+///    128-bit integer vector of [4 x i32] to 64-bit values and returns them in
+///    a 128-bit vector of [2 x i64]. The upper two elements of the input vector
+///    are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVSXDQ / PMOVSXDQ </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [4 x i32]. The lower two 32-bit elements are sign-
+///    extended to 64-bit values.
+/// \returns A 128-bit vector of [2 x i64] containing the sign-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepi32_epi64(__m128i __V)
 {
@@ -321,36 +1412,120 @@
 }
 
 /* SSE4 Packed Integer Zero-Extension.  */
+/// \brief Zero-extends each of the lower eight 8-bit integer elements of a
+///    128-bit vector of [16 x i8] to 16-bit values and returns them in a
+///    128-bit vector of [8 x i16]. The upper eight elements of the input vector
+///    are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVZXBW / PMOVZXBW </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [16 x i8]. The lower eight 8-bit elements are zero-
+///    extended to 16-bit values.
+/// \returns A 128-bit vector of [8 x i16] containing the zero-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepu8_epi16(__m128i __V)
 {
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qu)__V, (__v16qu)__V, 0, 1, 2, 3, 4, 5, 6, 7), __v8hi);
 }
 
+/// \brief Zero-extends each of the lower four 8-bit integer elements of a
+///    128-bit vector of [16 x i8] to 32-bit values and returns them in a
+///    128-bit vector of [4 x i32]. The upper twelve elements of the input
+///    vector are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVZXBD / PMOVZXBD </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [16 x i8]. The lower four 8-bit elements are zero-
+///    extended to 32-bit values.
+/// \returns A 128-bit vector of [4 x i32] containing the zero-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepu8_epi32(__m128i __V)
 {
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qu)__V, (__v16qu)__V, 0, 1, 2, 3), __v4si);
 }
 
+/// \brief Zero-extends each of the lower two 8-bit integer elements of a
+///    128-bit integer vector of [16 x i8] to 64-bit values and returns them in
+///    a 128-bit vector of [2 x i64]. The upper fourteen elements of the input
+///    vector are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVZXBQ / PMOVZXBQ </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [16 x i8]. The lower two 8-bit elements are zero-
+///    extended to 64-bit values.
+/// \returns A 128-bit vector of [2 x i64] containing the zero-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepu8_epi64(__m128i __V)
 {
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qu)__V, (__v16qu)__V, 0, 1), __v2di);
 }
 
+/// \brief Zero-extends each of the lower four 16-bit integer elements of a
+///    128-bit integer vector of [8 x i16] to 32-bit values and returns them in
+///    a 128-bit vector of [4 x i32]. The upper four elements of the input
+///    vector are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVZXWD / PMOVZXWD </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [8 x i16]. The lower four 16-bit elements are zero-
+///    extended to 32-bit values.
+/// \returns A 128-bit vector of [4 x i32] containing the zero-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepu16_epi32(__m128i __V)
 {
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v8hu)__V, (__v8hu)__V, 0, 1, 2, 3), __v4si);
 }
 
+/// \brief Zero-extends each of the lower two 16-bit integer elements of a
+///    128-bit integer vector of [8 x i16] to 64-bit values and returns them in
+///    a 128-bit vector of [2 x i64]. The upper six elements of the input vector
+///    are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVZXWQ / PMOVZXWQ </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [8 x i16]. The lower two 16-bit elements are zero-
+///    extended to 64-bit values.
+/// \returns A 128-bit vector of [2 x i64] containing the zero-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepu16_epi64(__m128i __V)
 {
   return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v8hu)__V, (__v8hu)__V, 0, 1), __v2di);
 }
 
+/// \brief Zero-extends each of the lower two 32-bit integer elements of a
+///    128-bit integer vector of [4 x i32] to 64-bit values and returns them in
+///    a 128-bit vector of [2 x i64]. The upper two elements of the input vector
+///    are unused.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPMOVZXDQ / PMOVZXDQ </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [4 x i32]. The lower two 32-bit elements are zero-
+///    extended to 64-bit values.
+/// \returns A 128-bit vector of [2 x i64] containing the zero-extended values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cvtepu32_epi64(__m128i __V)
 {
@@ -358,6 +1533,29 @@
 }
 
 /* SSE4 Pack with Unsigned Saturation.  */
+/// \brief Converts 32-bit signed integers from both 128-bit integer vector
+///    operands into 16-bit unsigned integers, and returns the packed result.
+///    Values greater than 0xFFFF are saturated to 0xFFFF. Values less than 
+///    0x0000 are saturated to 0x0000.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPACKUSDW / PACKUSDW </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit vector of [4 x i32]. Each 32-bit element is treated as a
+///    signed integer and is converted to a 16-bit unsigned integer with
+///    saturation. Values greater than 0xFFFF are saturated to 0xFFFF. Values
+///    less than 0x0000 are saturated to 0x0000. The converted [4 x i16] values
+///    are written to the lower 64 bits of the result.
+/// \param __V2
+///    A 128-bit vector of [4 x i32]. Each 32-bit element is treated as a
+///    signed integer and is converted to a 16-bit unsigned integer with
+///    saturation. Values greater than 0xFFFF are saturated to 0xFFFF. Values
+///    less than 0x0000 are saturated to 0x0000. The converted [4 x i16] values
+///    are written to the higher 64 bits of the result.
+/// \returns A 128-bit vector of [8 x i16] containing the converted values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_packus_epi32(__m128i __V1, __m128i __V2)
 {
@@ -365,10 +1563,59 @@
 }
 
 /* SSE4 Multiple Packed Sums of Absolute Difference.  */
+/// \brief Subtracts 8-bit unsigned integer values and computes the absolute
+///    values of the differences to the corresponding bits in the destination.
+///    Then sums of the absolute differences are returned according to the bit
+///    fields in the immediate operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128i _mm_mpsadbw_epu8(__m128i X, __m128i Y, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VMPSADBW / MPSADBW </i> </c>
+/// instruction.
+///
+/// \param X
+///    A 128-bit vector of [16 x i8].
+/// \param Y
+///    A 128-bit vector of [16 x i8].
+/// \param M
+///    An 8-bit immediate operand specifying how the absolute differences are to
+///    be calculated, according to the following algorithm:
+///    \code
+///    // M2 represents bit 2 of the immediate operand
+///    // M10 represents bits [1:0] of the immediate operand
+///    i = M2 * 4
+///    j = M10 * 4
+///    for (k = 0; k < 8; k = k + 1) {
+///      d0 = abs(X[i + k + 0] - Y[j + 0])
+///      d1 = abs(X[i + k + 1] - Y[j + 1])
+///      d2 = abs(X[i + k + 2] - Y[j + 2])
+///      d3 = abs(X[i + k + 3] - Y[j + 3])
+///      r[k] = d0 + d1 + d2 + d3
+///    }
+///    \endcode
+/// \returns A 128-bit integer vector containing the sums of the sets of
+///    absolute differences between both operands.
 #define _mm_mpsadbw_epu8(X, Y, M) __extension__ ({ \
   (__m128i) __builtin_ia32_mpsadbw128((__v16qi)(__m128i)(X), \
                                       (__v16qi)(__m128i)(Y), (M)); })
 
+/// \brief Finds the minimum unsigned 16-bit element in the input 128-bit
+///    vector of [8 x u16] and returns it and along with its index.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPHMINPOSUW / PHMINPOSUW </i> </c>
+/// instruction.
+///
+/// \param __V
+///    A 128-bit vector of [8 x u16].
+/// \returns A 128-bit value where bits [15:0] contain the minimum value found
+///    in parameter \a __V, bits [18:16] contain the index of the minimum value
+///    and the remaining bits are set to 0.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_minpos_epu16(__m128i __V)
 {
@@ -410,61 +1657,769 @@
 #define _SIDD_UNIT_MASK                 0x40
 
 /* SSE4.2 Packed Comparison Intrinsics.  */
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with implicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns a 128-bit integer vector representing the result
+///    mask of the comparison.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128i _mm_cmpistrm(__m128i A, __m128i B, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPISTRM / PCMPISTRM </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words, the type of comparison to perform, and the format of the return
+///    value. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B. \n
+///    Bit [6]: Determines whether the result is zero-extended or expanded to 16
+///             bytes. \n
+///      0: The result is zero-extended to 16 bytes. \n
+///      1: The result is expanded to 16 bytes (this expansion is performed by
+///         repeating each bit 8 or 16 times).
+/// \returns Returns a 128-bit integer vector representing the result mask of
+///    the comparison.
 #define _mm_cmpistrm(A, B, M) \
   (__m128i)__builtin_ia32_pcmpistrm128((__v16qi)(__m128i)(A), \
                                        (__v16qi)(__m128i)(B), (int)(M))
+
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with implicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns an integer representing the result index of the
+///    comparison.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpistri(__m128i A, __m128i B, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words, the type of comparison to perform, and the format of the return
+///    value. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n 
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B. \n
+///    Bit [6]: Determines whether the index of the lowest set bit or the
+///             highest set bit is returned. \n
+///      0: The index of the least significant set bit. \n
+///      1: The index of the most significant set bit. \n
+/// \returns Returns an integer representing the result index of the comparison.
 #define _mm_cmpistri(A, B, M) \
   (int)__builtin_ia32_pcmpistri128((__v16qi)(__m128i)(A), \
                                    (__v16qi)(__m128i)(B), (int)(M))
 
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with explicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns a 128-bit integer vector representing the result
+///    mask of the comparison.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// __m128i _mm_cmpestrm(__m128i A, int LA, __m128i B, int LB, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPESTRM / PCMPESTRM </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LA
+///    An integer that specifies the length of the string in \a A.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LB
+///    An integer that specifies the length of the string in \a B.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words, the type of comparison to perform, and the format of the return
+///    value. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B. \n
+///    Bit [6]: Determines whether the result is zero-extended or expanded to 16
+///             bytes. \n
+///      0: The result is zero-extended to 16 bytes. \n
+///      1: The result is expanded to 16 bytes (this expansion is performed by
+///         repeating each bit 8 or 16 times). \n
+/// \returns Returns a 128-bit integer vector representing the result mask of
+///    the comparison.
 #define _mm_cmpestrm(A, LA, B, LB, M) \
   (__m128i)__builtin_ia32_pcmpestrm128((__v16qi)(__m128i)(A), (int)(LA), \
                                        (__v16qi)(__m128i)(B), (int)(LB), \
                                        (int)(M))
+
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with explicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns an integer representing the result index of the
+///    comparison.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpestri(__m128i A, int LA, __m128i B, int LB, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LA
+///    An integer that specifies the length of the string in \a A.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LB
+///    An integer that specifies the length of the string in \a B.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words, the type of comparison to perform, and the format of the return
+///    value. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B. \n
+///    Bit [6]: Determines whether the index of the lowest set bit or the
+///             highest set bit is returned. \n
+///      0: The index of the least significant set bit. \n
+///      1: The index of the most significant set bit. \n
+/// \returns Returns an integer representing the result index of the comparison.
 #define _mm_cmpestri(A, LA, B, LB, M) \
   (int)__builtin_ia32_pcmpestri128((__v16qi)(__m128i)(A), (int)(LA), \
                                    (__v16qi)(__m128i)(B), (int)(LB), \
                                    (int)(M))
 
 /* SSE4.2 Packed Comparison Intrinsics and EFlag Reading.  */
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with implicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns 1 if the bit mask is zero and the length of the
+///    string in \a B is the maximum, otherwise, returns 0.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpistra(__m128i A, __m128i B, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B. \n
+/// \returns Returns 1 if the bit mask is zero and the length of the string in
+///    \a B is the maximum; otherwise, returns 0.
 #define _mm_cmpistra(A, B, M) \
   (int)__builtin_ia32_pcmpistria128((__v16qi)(__m128i)(A), \
                                     (__v16qi)(__m128i)(B), (int)(M))
+
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with implicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns 1 if the bit mask is non-zero, otherwise, returns
+///    0.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpistrc(__m128i A, __m128i B, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B.
+/// \returns Returns 1 if the bit mask is non-zero, otherwise, returns 0.
 #define _mm_cmpistrc(A, B, M) \
   (int)__builtin_ia32_pcmpistric128((__v16qi)(__m128i)(A), \
                                     (__v16qi)(__m128i)(B), (int)(M))
+
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with implicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns bit 0 of the resulting bit mask.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpistro(__m128i A, __m128i B, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B. \n
+/// \returns Returns bit 0 of the resulting bit mask.
 #define _mm_cmpistro(A, B, M) \
   (int)__builtin_ia32_pcmpistrio128((__v16qi)(__m128i)(A), \
                                     (__v16qi)(__m128i)(B), (int)(M))
+
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with implicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns 1 if the length of the string in \a A is less than
+///    the maximum, otherwise, returns 0.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpistrs(__m128i A, __m128i B, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B. \n
+/// \returns Returns 1 if the length of the string in \a A is less than the
+///    maximum, otherwise, returns 0.
 #define _mm_cmpistrs(A, B, M) \
   (int)__builtin_ia32_pcmpistris128((__v16qi)(__m128i)(A), \
                                     (__v16qi)(__m128i)(B), (int)(M))
+
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with implicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns 1 if the length of the string in \a B is less than
+///    the maximum, otherwise, returns 0.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpistrz(__m128i A, __m128i B, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B.
+/// \returns Returns 1 if the length of the string in \a B is less than the
+///    maximum, otherwise, returns 0.
 #define _mm_cmpistrz(A, B, M) \
   (int)__builtin_ia32_pcmpistriz128((__v16qi)(__m128i)(A), \
                                     (__v16qi)(__m128i)(B), (int)(M))
 
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with explicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns 1 if the bit mask is zero and the length of the
+///    string in \a B is the maximum, otherwise, returns 0.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpestra(__m128i A, int LA, __m128i B, int LB, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LA
+///    An integer that specifies the length of the string in \a A.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LB
+///    An integer that specifies the length of the string in \a B.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit 
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B.
+/// \returns Returns 1 if the bit mask is zero and the length of the string in
+///    \a B is the maximum, otherwise, returns 0.
 #define _mm_cmpestra(A, LA, B, LB, M) \
   (int)__builtin_ia32_pcmpestria128((__v16qi)(__m128i)(A), (int)(LA), \
                                     (__v16qi)(__m128i)(B), (int)(LB), \
                                     (int)(M))
+
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with explicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns 1 if the resulting mask is non-zero, otherwise,
+///    returns 0.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpestrc(__m128i A, int LA, __m128i B, int LB, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LA
+///    An integer that specifies the length of the string in \a A.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LB
+///    An integer that specifies the length of the string in \a B.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B. \n
+/// \returns Returns 1 if the resulting mask is non-zero, otherwise, returns 0.
 #define _mm_cmpestrc(A, LA, B, LB, M) \
   (int)__builtin_ia32_pcmpestric128((__v16qi)(__m128i)(A), (int)(LA), \
                                     (__v16qi)(__m128i)(B), (int)(LB), \
                                     (int)(M))
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with explicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns bit 0 of the resulting bit mask.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpestro(__m128i A, int LA, __m128i B, int LB, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LA
+///    An integer that specifies the length of the string in \a A.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LB
+///    An integer that specifies the length of the string in \a B.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B.
+/// \returns Returns bit 0 of the resulting bit mask.
 #define _mm_cmpestro(A, LA, B, LB, M) \
   (int)__builtin_ia32_pcmpestrio128((__v16qi)(__m128i)(A), (int)(LA), \
                                     (__v16qi)(__m128i)(B), (int)(LB), \
                                     (int)(M))
+
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with explicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns 1 if the length of the string in \a A is less than
+///    the maximum, otherwise, returns 0.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpestrs(__m128i A, int LA, __m128i B, int LB, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LA
+///    An integer that specifies the length of the string in \a A.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LB
+///    An integer that specifies the length of the string in \a B.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement in the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B. \n
+/// \returns Returns 1 if the length of the string in \a A is less than the
+///    maximum, otherwise, returns 0.
 #define _mm_cmpestrs(A, LA, B, LB, M) \
   (int)__builtin_ia32_pcmpestris128((__v16qi)(__m128i)(A), (int)(LA), \
                                     (__v16qi)(__m128i)(B), (int)(LB), \
                                     (int)(M))
+
+/// \brief Uses the immediate operand \a M to perform a comparison of string
+///    data with explicitly defined lengths that is contained in source operands
+///    \a A and \a B. Returns 1 if the length of the string in \a B is less than
+///    the maximum, otherwise, returns 0.
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// int _mm_cmpestrz(__m128i A, int LA, __m128i B, int LB, const int M);
+/// \endcode
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPESTRI </i> </c> instruction.
+///
+/// \param A
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LA
+///    An integer that specifies the length of the string in \a A.
+/// \param B
+///    A 128-bit integer vector containing one of the source operands to be
+///    compared.
+/// \param LB
+///    An integer that specifies the length of the string in \a B.
+/// \param M
+///    An 8-bit immediate operand specifying whether the characters are bytes or
+///    words and the type of comparison to perform. \n
+///    Bits [1:0]: Determine source data format. \n
+///      00: 16 unsigned bytes  \n
+///      01: 8 unsigned words \n
+///      10: 16 signed bytes \n
+///      11: 8 signed words \n
+///    Bits [3:2]: Determine comparison type and aggregation method. \n
+///      00: Subset: Each character in \a B is compared for equality with all
+///          the characters in \a A. \n
+///      01: Ranges: Each character in \a B is compared to \a A. The comparison
+///          basis is greater than or equal for even-indexed elements in \a A,
+///          and less than or equal for odd-indexed elements in \a A. \n
+///      10: Match: Compare each pair of corresponding characters in \a A and
+///          \a B for equality. \n
+///      11: Substring: Search \a B for substring matches of \a A. \n
+///    Bits [5:4]: Determine whether to perform a one's complement on the bit
+///                mask of the comparison results. \n
+///      00: No effect. \n
+///      01: Negate the bit mask. \n
+///      10: No effect. \n
+///      11: Negate the bit mask only for bits with an index less than or equal
+///          to the size of \a A or \a B.
+/// \returns Returns 1 if the length of the string in \a B is less than the
+///    maximum, otherwise, returns 0.
 #define _mm_cmpestrz(A, LA, B, LB, M) \
   (int)__builtin_ia32_pcmpestriz128((__v16qi)(__m128i)(A), (int)(LA), \
                                     (__v16qi)(__m128i)(B), (int)(LB), \
                                     (int)(M))
 
 /* SSE4.2 Compare Packed Data -- Greater Than.  */
+/// \brief Compares each of the corresponding 64-bit values of the 128-bit
+///    integer vectors to determine if the values in the first operand are
+///    greater than those in the second operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> VPCMPGTQ / PCMPGTQ </i> </c>
+/// instruction.
+///
+/// \param __V1
+///    A 128-bit integer vector.
+/// \param __V2
+///    A 128-bit integer vector.
+/// \returns A 128-bit integer vector containing the comparison results.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cmpgt_epi64(__m128i __V1, __m128i __V2)
 {
@@ -472,18 +2427,60 @@
 }
 
 /* SSE4.2 Accumulate CRC32.  */
+/// \brief Adds the unsigned integer operand to the CRC-32C checksum of the
+///    unsigned char operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> CRC32B </i> </c> instruction.
+///
+/// \param __C
+///    An unsigned integer operand to add to the CRC-32C checksum of operand
+///    \a  __D.
+/// \param __D
+///    An unsigned 8-bit integer operand used to compute the CRC-32C checksum.
+/// \returns The result of adding operand \a __C to the CRC-32C checksum of
+///    operand \a __D.
 static __inline__ unsigned int __DEFAULT_FN_ATTRS
 _mm_crc32_u8(unsigned int __C, unsigned char __D)
 {
   return __builtin_ia32_crc32qi(__C, __D);
 }
 
+/// \brief Adds the unsigned integer operand to the CRC-32C checksum of the
+///    unsigned short operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> CRC32W </i> </c> instruction.
+///
+/// \param __C
+///    An unsigned integer operand to add to the CRC-32C checksum of operand
+///    \a __D.
+/// \param __D
+///    An unsigned 16-bit integer operand used to compute the CRC-32C checksum.
+/// \returns The result of adding operand \a __C to the CRC-32C checksum of
+///    operand \a __D.
 static __inline__ unsigned int __DEFAULT_FN_ATTRS
 _mm_crc32_u16(unsigned int __C, unsigned short __D)
 {
   return __builtin_ia32_crc32hi(__C, __D);
 }
 
+/// \brief Adds the first unsigned integer operand to the CRC-32C checksum of
+///    the second unsigned integer operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> CRC32L </i> </c> instruction.
+///
+/// \param __C
+///    An unsigned integer operand to add to the CRC-32C checksum of operand
+///    \a __D.
+/// \param __D
+///    An unsigned 32-bit integer operand used to compute the CRC-32C checksum.
+/// \returns The result of adding operand \a __C to the CRC-32C checksum of
+///    operand \a __D.
 static __inline__ unsigned int __DEFAULT_FN_ATTRS
 _mm_crc32_u32(unsigned int __C, unsigned int __D)
 {
@@ -491,6 +2488,20 @@
 }
 
 #ifdef __x86_64__
+/// \brief Adds the unsigned integer operand to the CRC-32C checksum of the
+///    unsigned 64-bit integer operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> <i> CRC32Q </i> </c> instruction.
+///
+/// \param __C
+///    An unsigned integer operand to add to the CRC-32C checksum of operand
+///    \a __D.
+/// \param __D
+///    An unsigned 64-bit integer operand used to compute the CRC-32C checksum.
+/// \returns The result of adding operand \a __C to the CRC-32C checksum of
+///    operand \a __D.
 static __inline__ unsigned long long __DEFAULT_FN_ATTRS
 _mm_crc32_u64(unsigned long long __C, unsigned long long __D)
 {
diff --git a/lib/Headers/stdarg.h b/lib/Headers/stdarg.h
index a57e183..101426f 100644
--- a/lib/Headers/stdarg.h
+++ b/lib/Headers/stdarg.h
@@ -43,10 +43,9 @@
 #define va_copy(dest, src)  __builtin_va_copy(dest, src)
 #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
 
 #endif /* __STDARG_H */
diff --git a/lib/Headers/tgmath.h b/lib/Headers/tgmath.h
index 0b8b5ce..318e118 100644
--- a/lib/Headers/tgmath.h
+++ b/lib/Headers/tgmath.h
@@ -25,14 +25,6 @@
 #ifndef __TGMATH_H
 #define __TGMATH_H
 
-/*
- * Allow additional definitions and implementation-defined values on Apple
- * platforms.
- */
-#if defined(__APPLE__) && __STDC_HOSTED__ && __has_include_next(<tgmath.h>)
-#  include_next <tgmath.h>
-#else
-
 /* C99 7.22 Type-generic math <tgmath.h>. */
 #include <math.h>
 
@@ -1379,5 +1371,4 @@
 #undef _TG_ATTRS
 
 #endif /* __cplusplus */
-#endif /* __has_include_next */
 #endif /* __TGMATH_H */
diff --git a/lib/Headers/tmmintrin.h b/lib/Headers/tmmintrin.h
index a72796b..8066404 100644
--- a/lib/Headers/tmmintrin.h
+++ b/lib/Headers/tmmintrin.h
@@ -483,15 +483,15 @@
 /// \param __b
 ///    A 128-bit integer vector containing the second source operand.
 /// \returns A 128-bit integer vector containing the sums of products of both
-///    operands:
-///    R0 := (__a0 * __b0) + (__a1 * __b1)
-///    R1 := (__a2 * __b2) + (__a3 * __b3)
-///    R2 := (__a4 * __b4) + (__a5 * __b5)
-///    R3 := (__a6 * __b6) + (__a7 * __b7)
-///    R4 := (__a8 * __b8) + (__a9 * __b9)
-///    R5 := (__a10 * __b10) + (__a11 * __b11)
-///    R6 := (__a12 * __b12) + (__a13 * __b13)
-///    R7 := (__a14 * __b14) + (__a15 * __b15)
+///    operands: \n
+///    \a R0 := (\a __a0 * \a __b0) + (\a __a1 * \a __b1) \n
+///    \a R1 := (\a __a2 * \a __b2) + (\a __a3 * \a __b3) \n
+///    \a R2 := (\a __a4 * \a __b4) + (\a __a5 * \a __b5) \n
+///    \a R3 := (\a __a6 * \a __b6) + (\a __a7 * \a __b7) \n
+///    \a R4 := (\a __a8 * \a __b8) + (\a __a9 * \a __b9) \n
+///    \a R5 := (\a __a10 * \a __b10) + (\a __a11 * \a __b11) \n
+///    \a R6 := (\a __a12 * \a __b12) + (\a __a13 * \a __b13) \n
+///    \a R7 := (\a __a14 * \a __b14) + (\a __a15 * \a __b15)
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_maddubs_epi16(__m128i __a, __m128i __b)
 {
@@ -516,11 +516,11 @@
 /// \param __b
 ///    A 64-bit integer vector containing the second source operand.
 /// \returns A 64-bit integer vector containing the sums of products of both
-///    operands:
-///    R0 := (__a0 * __b0) + (__a1 * __b1)
-///    R1 := (__a2 * __b2) + (__a3 * __b3)
-///    R2 := (__a4 * __b4) + (__a5 * __b5)
-///    R3 := (__a6 * __b6) + (__a7 * __b7)
+///    operands: \n
+///    \a R0 := (\a __a0 * \a __b0) + (\a __a1 * \a __b1) \n
+///    \a R1 := (\a __a2 * \a __b2) + (\a __a3 * \a __b3) \n
+///    \a R2 := (\a __a4 * \a __b4) + (\a __a5 * \a __b5) \n
+///    \a R3 := (\a __a6 * \a __b6) + (\a __a7 * \a __b7)
 static __inline__ __m64 __DEFAULT_FN_ATTRS
 _mm_maddubs_pi16(__m64 __a, __m64 __b)
 {
@@ -580,11 +580,11 @@
 /// \param __b
 ///    A 128-bit integer vector containing control bytes corresponding to
 ///    positions in the destination:
-///    Bit 7:
-///    1: Clear the corresponding byte in the destination.
+///    Bit 7: \n
+///    1: Clear the corresponding byte in the destination. \n
 ///    0: Copy the selected source byte to the corresponding byte in the
-///    destination.
-///    Bits [6:4] Reserved.
+///    destination. \n
+///    Bits [6:4] Reserved.  \n
 ///    Bits [3:0] select the source byte to be copied.
 /// \returns A 128-bit integer vector containing the copied or cleared values.
 static __inline__ __m128i __DEFAULT_FN_ATTRS
@@ -606,10 +606,10 @@
 /// \param __b
 ///    A 64-bit integer vector containing control bytes corresponding to
 ///    positions in the destination:
-///    Bit 7:
-///    1: Clear the corresponding byte in the destination.
+///    Bit 7: \n
+///    1: Clear the corresponding byte in the destination. \n
 ///    0: Copy the selected source byte to the corresponding byte in the
-///    destination.
+///    destination. \n
 ///    Bits [3:0] select the source byte to be copied.
 /// \returns A 64-bit integer vector containing the copied or cleared values.
 static __inline__ __m64 __DEFAULT_FN_ATTRS
diff --git a/lib/Headers/x86intrin.h b/lib/Headers/x86intrin.h
index 81a404f..2003029 100644
--- a/lib/Headers/x86intrin.h
+++ b/lib/Headers/x86intrin.h
@@ -80,6 +80,10 @@
 #include <mwaitxintrin.h>
 #endif
 
+#if !defined(_MSC_VER) || __has_feature(modules) || defined(__CLZERO__)
+#include <clzerointrin.h>
+#endif
+
 /* FIXME: LWP */
 
 #endif /* __X86INTRIN_H */
diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h
index f2fdad9..bb8e29c 100644
--- a/lib/Headers/xmmintrin.h
+++ b/lib/Headers/xmmintrin.h
@@ -46,7 +46,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDSS / ADDSS instructions.
+/// This intrinsic corresponds to the <c> VADDSS / ADDSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the source operands.
@@ -69,7 +69,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VADDPS / ADDPS instructions.
+/// This intrinsic corresponds to the <c> VADDPS / ADDPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the source operands.
@@ -88,7 +88,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSUBSS / SUBSS instructions.
+/// This intrinsic corresponds to the <c> VSUBSS / SUBSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing the minuend. The lower 32 bits
@@ -112,7 +112,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSUBPS / SUBPS instructions.
+/// This intrinsic corresponds to the <c> VSUBPS / SUBPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing the minuend.
@@ -131,7 +131,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMULSS / MULSS instructions.
+/// This intrinsic corresponds to the <c> VMULSS / MULSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the source operands.
@@ -154,7 +154,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMULPS / MULPS instructions.
+/// This intrinsic corresponds to the <c> VMULPS / MULPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the source operands.
@@ -173,7 +173,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VDIVSS / DIVSS instructions.
+/// This intrinsic corresponds to the <c> VDIVSS / DIVSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing the dividend. The lower 32
@@ -195,7 +195,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VDIVPS / DIVPS instructions.
+/// This intrinsic corresponds to the <c> VDIVPS / DIVPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing the dividend.
@@ -214,7 +214,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSQRTSS / SQRTSS instructions.
+/// This intrinsic corresponds to the <c> VSQRTSS / SQRTSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -233,7 +233,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSQRTPS / SQRTPS instructions.
+/// This intrinsic corresponds to the <c> VSQRTPS / SQRTPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -250,7 +250,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VRCPSS / RCPSS instructions.
+/// This intrinsic corresponds to the <c> VRCPSS / RCPSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -269,7 +269,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VRCPPS / RCPPS instructions.
+/// This intrinsic corresponds to the <c> VRCPPS / RCPPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -286,7 +286,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VRSQRTSS / RSQRTSS instructions.
+/// This intrinsic corresponds to the <c> VRSQRTSS / RSQRTSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -306,7 +306,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VRSQRTPS / RSQRTPS instructions.
+/// This intrinsic corresponds to the <c> VRSQRTPS / RSQRTPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -324,7 +324,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMINSS / MINSS instructions.
+/// This intrinsic corresponds to the <c> VMINSS / MINSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -341,12 +341,12 @@
   return __builtin_ia32_minss((__v4sf)__a, (__v4sf)__b);
 }
 
-/// \brief Compares two 128-bit vectors of [4 x float] and returns the
-///    lesser of each pair of values.
+/// \brief Compares two 128-bit vectors of [4 x float] and returns the lesser
+///    of each pair of values.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMINPS / MINPS instructions.
+/// This intrinsic corresponds to the <c> VMINPS / MINPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands.
@@ -361,12 +361,12 @@
 }
 
 /// \brief Compares two 32-bit float values in the low-order bits of both
-///    operands and returns the greater value in the low-order bits of
-///    a vector [4 x float].
+///    operands and returns the greater value in the low-order bits of a 128-bit
+///    vector of [4 x float].
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMAXSS / MAXSS instructions.
+/// This intrinsic corresponds to the <c> VMAXSS / MAXSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -388,7 +388,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMAXPS / MAXPS instructions.
+/// This intrinsic corresponds to the <c> VMAXPS / MAXPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands.
@@ -406,7 +406,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VANDPS / ANDPS instructions.
+/// This intrinsic corresponds to the <c> VANDPS / ANDPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector containing one of the source operands.
@@ -426,7 +426,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VANDNPS / ANDNPS instructions.
+/// This intrinsic corresponds to the <c> VANDNPS / ANDNPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing the first source operand. The
@@ -446,7 +446,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VORPS / ORPS instructions.
+/// This intrinsic corresponds to the <c> VORPS / ORPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the source operands.
@@ -465,7 +465,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VXORPS / XORPS instructions.
+/// This intrinsic corresponds to the <c> VXORPS / XORPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the source operands.
@@ -485,7 +485,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPEQSS / CMPEQSS instructions.
+/// This intrinsic corresponds to the <c> VCMPEQSS / CMPEQSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -506,7 +506,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPEQPS / CMPEQPS instructions.
+/// This intrinsic corresponds to the <c> VCMPEQPS / CMPEQPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -526,7 +526,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLTSS / CMPLTSS instructions.
+/// This intrinsic corresponds to the <c> VCMPLTSS / CMPLTSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -548,7 +548,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLTPS / CMPLTPS instructions.
+/// This intrinsic corresponds to the <c> VCMPLTPS / CMPLTPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -569,7 +569,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLESS / CMPLESS instructions.
+/// This intrinsic corresponds to the <c> VCMPLESS / CMPLESS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -591,7 +591,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLEPS / CMPLEPS instructions.
+/// This intrinsic corresponds to the <c> VCMPLEPS / CMPLEPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -611,7 +611,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLTSS / CMPLTSS instructions.
+/// This intrinsic corresponds to the <c> VCMPLTSS / CMPLTSS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -635,7 +635,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLTPS / CMPLTPS instructions.
+/// This intrinsic corresponds to the <c> VCMPLTPS / CMPLTPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -656,7 +656,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLESS / CMPLESS instructions.
+/// This intrinsic corresponds to the <c> VCMPLESS / CMPLESS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -680,7 +680,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPLEPS / CMPLEPS instructions.
+/// This intrinsic corresponds to the <c> VCMPLEPS / CMPLEPS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -699,7 +699,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNEQSS / CMPNEQSS instructions.
+/// This intrinsic corresponds to the <c> VCMPNEQSS / CMPNEQSS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -720,7 +721,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNEQPS / CMPNEQPS instructions.
+/// This intrinsic corresponds to the <c> VCMPNEQPS / CMPNEQPS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -740,7 +742,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLTSS / CMPNLTSS instructions.
+/// This intrinsic corresponds to the <c> VCMPNLTSS / CMPNLTSS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -762,7 +765,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLTPS / CMPNLTPS instructions.
+/// This intrinsic corresponds to the <c> VCMPNLTPS / CMPNLTPS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -783,7 +787,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLESS / CMPNLESS instructions.
+/// This intrinsic corresponds to the <c> VCMPNLESS / CMPNLESS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -805,7 +810,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLEPS / CMPNLEPS instructions.
+/// This intrinsic corresponds to the <c> VCMPNLEPS / CMPNLEPS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -826,7 +832,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLTSS / CMPNLTSS instructions.
+/// This intrinsic corresponds to the <c> VCMPNLTSS / CMPNLTSS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -850,7 +857,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLTPS / CMPNLTPS instructions.
+/// This intrinsic corresponds to the <c> VCMPNLTPS / CMPNLTPS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -871,7 +879,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLESS / CMPNLESS instructions.
+/// This intrinsic corresponds to the <c> VCMPNLESS / CMPNLESS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -895,7 +904,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPNLEPS / CMPNLEPS instructions.
+/// This intrinsic corresponds to the <c> VCMPNLEPS / CMPNLEPS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -916,7 +926,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPORDSS / CMPORDSS instructions.
+/// This intrinsic corresponds to the <c> VCMPORDSS / CMPORDSS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -938,7 +949,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPORDPS / CMPORDPS instructions.
+/// This intrinsic corresponds to the <c> VCMPORDPS / CMPORDPS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -959,7 +971,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPUNORDSS / CMPUNORDSS instructions.
+/// This intrinsic corresponds to the <c> VCMPUNORDSS / CMPUNORDSS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float] containing one of the operands. The lower
@@ -981,7 +994,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCMPUNORDPS / CMPUNORDPS instructions.
+/// This intrinsic corresponds to the <c> VCMPUNORDPS / CMPUNORDPS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -999,7 +1013,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISS / COMISS instructions.
+/// This intrinsic corresponds to the <c> VCOMISS / COMISS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1020,7 +1035,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISS / COMISS instructions.
+/// This intrinsic corresponds to the <c> VCOMISS / COMISS </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1041,7 +1057,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISS / COMISS instructions.
+/// This intrinsic corresponds to the <c> VCOMISS / COMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1062,7 +1078,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISS / COMISS instructions.
+/// This intrinsic corresponds to the <c> VCOMISS / COMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1083,7 +1099,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISS / COMISS instructions.
+/// This intrinsic corresponds to the <c> VCOMISS / COMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1104,7 +1120,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCOMISS / COMISS instructions.
+/// This intrinsic corresponds to the <c> VCOMISS / COMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1125,7 +1141,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISS / UCOMISS instructions.
+/// This intrinsic corresponds to the <c> VUCOMISS / UCOMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1146,7 +1162,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISS / UCOMISS instructions.
+/// This intrinsic corresponds to the <c> VUCOMISS / UCOMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1162,13 +1178,13 @@
 }
 
 /// \brief Performs an unordered comparison of two 32-bit float values using
-///    the low-order bits of both operands to determine if the first operand
-///    is less than or equal to the second operand and returns the result of
-///    the comparison.
+///    the low-order bits of both operands to determine if the first operand is
+///    less than or equal to the second operand and returns the result of the
+///    comparison.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISS / UCOMISS instructions.
+/// This intrinsic corresponds to the <c> VUCOMISS / UCOMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1184,13 +1200,13 @@
 }
 
 /// \brief Performs an unordered comparison of two 32-bit float values using
-///    the low-order bits of both operands to determine if the first operand
-///    is greater than the second operand and returns the result of the
+///    the low-order bits of both operands to determine if the first operand is
+///    greater than the second operand and returns the result of the
 ///    comparison.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISS / UCOMISS instructions.
+/// This intrinsic corresponds to the <c> VUCOMISS / UCOMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1212,7 +1228,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISS / UCOMISS instructions.
+/// This intrinsic corresponds to the <c> VUCOMISS / UCOMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1233,7 +1249,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUCOMISS / UCOMISS instructions.
+/// This intrinsic corresponds to the <c> VUCOMISS / UCOMISS </c> instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1253,7 +1269,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSS2SI / CVTSS2SI instructions.
+/// This intrinsic corresponds to the <c> VCVTSS2SI / CVTSS2SI </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1270,7 +1287,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSS2SI / CVTSS2SI instructions.
+/// This intrinsic corresponds to the <c> VCVTSS2SI / CVTSS2SI </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1289,7 +1307,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSS2SI / CVTSS2SI instructions.
+/// This intrinsic corresponds to the <c> VCVTSS2SI / CVTSS2SI </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1308,7 +1327,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPS2PI instruction.
+/// This intrinsic corresponds to the <c> CVTPS2PI </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -1324,7 +1343,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPS2PI instruction.
+/// This intrinsic corresponds to the <c> CVTPS2PI </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -1341,7 +1360,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTTSS2SI / CVTTSS2SI instructions.
+/// This intrinsic corresponds to the <c> VCVTTSS2SI / CVTTSS2SI </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1359,7 +1379,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTTSS2SI / CVTTSS2SI instructions.
+/// This intrinsic corresponds to the <c> VCVTTSS2SI / CVTTSS2SI </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1378,7 +1399,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTTSS2SI / CVTTSS2SI instructions.
+/// This intrinsic corresponds to the <c> VCVTTSS2SI / CVTTSS2SI </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1397,7 +1419,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTTPS2PI / VTTPS2PI instructions.
+/// This intrinsic corresponds to the <c> CVTTPS2PI / VTTPS2PI </c>
+///   instructions.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -1414,7 +1437,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTTPS2PI instruction.
+/// This intrinsic corresponds to the <c> CVTTPS2PI </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -1432,7 +1455,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSI2SS / CVTSI2SS instruction.
+/// This intrinsic corresponds to the <c> VCVTSI2SS / CVTSI2SS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -1455,7 +1478,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSI2SS / CVTSI2SS instruction.
+/// This intrinsic corresponds to the <c> VCVTSI2SS / CVTSI2SS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -1479,7 +1502,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VCVTSI2SS / CVTSI2SS instruction.
+/// This intrinsic corresponds to the <c> VCVTSI2SS / CVTSI2SS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -1504,7 +1527,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPI2PS instruction.
+/// This intrinsic corresponds to the <c> CVTPI2PS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -1527,7 +1550,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPI2PS instruction.
+/// This intrinsic corresponds to the <c> CVTPI2PS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float].
@@ -1548,7 +1571,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSS / MOVSS instruction.
+/// This intrinsic corresponds to the <c> VMOVSS / MOVSS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
@@ -1566,7 +1589,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVHPD / MOVHPD instruction.
+/// This intrinsic corresponds to the <c> VMOVHPD / MOVHPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. Bits [63:0] are written to bits [63:0]
@@ -1593,7 +1616,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVLPD / MOVLPD instruction.
+/// This intrinsic corresponds to the <c> VMOVLPD / MOVLPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit vector of [4 x float]. Bits [127:64] are written to bits
@@ -1621,7 +1644,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSS / MOVSS instruction.
+/// This intrinsic corresponds to the <c> VMOVSS / MOVSS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 32-bit memory location containing a single-precision
@@ -1644,13 +1667,13 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSS / MOVSS + \c shuffling
+/// This intrinsic corresponds to the <c> VMOVSS / MOVSS + shuffling </c>
 ///    instruction.
 ///
 /// \param __p
 ///    A pointer to a float value to be loaded and duplicated.
-/// \returns A 128-bit vector of [4 x float] containing the loaded
-///    and duplicated values.
+/// \returns A 128-bit vector of [4 x float] containing the loaded and
+///    duplicated values.
 static __inline__ __m128 __DEFAULT_FN_ATTRS
 _mm_load1_ps(const float *__p)
 {
@@ -1668,7 +1691,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPS / MOVAPS instruction.
+/// This intrinsic corresponds to the <c> VMOVAPS / MOVAPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 128-bit memory location. The address of the memory
@@ -1685,7 +1708,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVUPS / MOVUPS instruction.
+/// This intrinsic corresponds to the <c> VMOVUPS / MOVUPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 128-bit memory location. The address of the memory
@@ -1705,7 +1728,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPS / MOVAPS + \c shuffling
+/// This intrinsic corresponds to the <c> VMOVAPS / MOVAPS + shuffling </c>
 ///    instruction.
 ///
 /// \param __p
@@ -1739,7 +1762,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSS / MOVSS instruction.
+/// This intrinsic corresponds to the <c> VMOVSS / MOVSS </c> instruction.
 ///
 /// \param __w
 ///    A single-precision floating-point value used to initialize the lower 32
@@ -1759,7 +1782,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPERMILPS / PERMILPS instruction.
+/// This intrinsic corresponds to the <c> VPERMILPS / PERMILPS </c> instruction.
 ///
 /// \param __w
 ///    A single-precision floating-point value used to initialize each vector
@@ -1778,7 +1801,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPERMILPS / PERMILPS instruction.
+/// This intrinsic corresponds to the <c> VPERMILPS / PERMILPS </c> instruction.
 ///
 /// \param __w
 ///    A single-precision floating-point value used to initialize each vector
@@ -1850,7 +1873,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VXORPS / XORPS instruction.
+/// This intrinsic corresponds to the <c> VXORPS / XORPS </c> instruction.
 ///
 /// \returns An initialized 128-bit floating-point vector of [4 x float] with
 ///    all elements set to zero.
@@ -1865,7 +1888,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VPEXTRQ / MOVQ instruction.
+/// This intrinsic corresponds to the <c> VPEXTRQ / MOVQ </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 64-bit memory location.
@@ -1882,7 +1905,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVLPS / MOVLPS instruction.
+/// This intrinsic corresponds to the <c> VMOVLPS / MOVLPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a memory location that will receive the float values.
@@ -1899,7 +1922,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSS / MOVSS instruction.
+/// This intrinsic corresponds to the <c> VMOVSS / MOVSS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 32-bit memory location.
@@ -1919,7 +1942,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVUPS / MOVUPS instruction.
+/// This intrinsic corresponds to the <c> VMOVUPS / MOVUPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 128-bit memory location. The address of the memory
@@ -1940,7 +1963,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPS / MOVAPS instruction.
+/// This intrinsic corresponds to the <c> VMOVAPS / MOVAPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 128-bit memory location. The address of the memory
@@ -1958,7 +1981,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to \c VMOVAPS / MOVAPS + \c shuffling
+/// This intrinsic corresponds to <c> VMOVAPS / MOVAPS + shuffling </c>
 ///    instruction.
 ///
 /// \param __p
@@ -1978,7 +2001,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to \c VMOVAPS / MOVAPS + \c shuffling
+/// This intrinsic corresponds to <c> VMOVAPS / MOVAPS + shuffling </c>
 ///    instruction.
 ///
 /// \param __p
@@ -1997,7 +2020,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVAPS / MOVAPS + \c shuffling
+/// This intrinsic corresponds to the <c> VMOVAPS / MOVAPS + shuffling </c>
 ///    instruction.
 ///
 /// \param __p
@@ -2030,18 +2053,19 @@
 /// void _mm_prefetch(const void * a, const int sel);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c PREFETCHNTA instruction.
+/// This intrinsic corresponds to the <c> PREFETCHNTA </c> instruction.
 ///
 /// \param a
 ///    A pointer to a memory location containing a cache line of data.
 /// \param sel
-///    A predefined integer constant specifying the type of prefetch operation:
-///    _MM_HINT_NTA: Move data using the non-temporal access (NTA) hint.
-///    The PREFETCHNTA instruction will be generated.
+///    A predefined integer constant specifying the type of prefetch
+///    operation: \n
+///    _MM_HINT_NTA: Move data using the non-temporal access (NTA) hint. The
+///    PREFETCHNTA instruction will be generated. \n
 ///    _MM_HINT_T0: Move data using the T0 hint. The PREFETCHT0 instruction will
-///    be generated.
+///    be generated. \n
 ///    _MM_HINT_T1: Move data using the T1 hint. The PREFETCHT1 instruction will
-///    be generated.
+///    be generated. \n
 ///    _MM_HINT_T2: Move data using the T2 hint. The PREFETCHT2 instruction will
 ///    be generated.
 #define _mm_prefetch(a, sel) (__builtin_prefetch((void *)(a), 0, (sel)))
@@ -2053,7 +2077,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c MOVNTQ instruction.
+/// This intrinsic corresponds to the <c> MOVNTQ </c> instruction.
 ///
 /// \param __p
 ///    A pointer to an aligned memory location used to store the register value.
@@ -2071,7 +2095,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVNTPS / MOVNTPS instruction.
+/// This intrinsic corresponds to the <c> VMOVNTPS / MOVNTPS </c> instruction.
 ///
 /// \param __p
 ///    A pointer to a 128-bit aligned memory location that will receive the
@@ -2095,7 +2119,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c SFENCE instruction.
+/// This intrinsic corresponds to the <c> SFENCE </c> instruction.
 ///
 void _mm_sfence(void);
 
@@ -2112,15 +2136,15 @@
 /// void _mm_extract_pi(__m64 a, int n);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPEXTRW / PEXTRW instruction.
+/// This intrinsic corresponds to the <c> VPEXTRW / PEXTRW </c> instruction.
 ///
 /// \param a
 ///    A 64-bit vector of [4 x i16].
 /// \param n
-///    An immediate integer operand that determines which bits are extracted:
-///    0: Bits [15:0] are copied to the destination.
-///    1: Bits [31:16] are copied to the destination.
-///    2: Bits [47:32] are copied to the destination.
+///    An immediate integer operand that determines which bits are extracted: \n
+///    0: Bits [15:0] are copied to the destination. \n
+///    1: Bits [31:16] are copied to the destination. \n
+///    2: Bits [47:32] are copied to the destination. \n
 ///    3: Bits [63:48] are copied to the destination.
 /// \returns A 16-bit integer containing the extracted 16 bits of packed data.
 #define _mm_extract_pi16(a, n) __extension__ ({ \
@@ -2136,7 +2160,7 @@
 /// void _mm_insert_pi(__m64 a, int d, int n);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VPINSRW / PINSRW instruction.
+/// This intrinsic corresponds to the <c> VPINSRW / PINSRW </c> instruction.
 ///
 /// \param a
 ///    A 64-bit vector of [4 x i16].
@@ -2145,11 +2169,11 @@
 ///    destination at the offset specified by operand \a n.
 /// \param n
 ///    An immediate integer operant that determines which the bits to be used
-///    in the destination.
-///    0: Bits [15:0] are copied to the destination.
-///    1: Bits [31:16] are copied to the destination.
-///    2: Bits [47:32] are copied to the destination.
-///    3: Bits [63:48] are copied to the destination.
+///    in the destination. \n
+///    0: Bits [15:0] are copied to the destination. \n
+///    1: Bits [31:16] are copied to the destination. \n
+///    2: Bits [47:32] are copied to the destination. \n
+///    3: Bits [63:48] are copied to the destination.  \n
 ///    The remaining bits in the destination are copied from the corresponding
 ///    bits in operand \a a.
 /// \returns A 64-bit integer vector containing the copied packed data from the
@@ -2163,7 +2187,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMAXSW instruction.
+/// This intrinsic corresponds to the <c> PMAXSW </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing one of the source operands.
@@ -2182,7 +2206,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMAXUB instruction.
+/// This intrinsic corresponds to the <c> PMAXUB </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing one of the source operands.
@@ -2201,7 +2225,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMINSW instruction.
+/// This intrinsic corresponds to the <c> PMINSW </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing one of the source operands.
@@ -2220,7 +2244,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMINUB instruction.
+/// This intrinsic corresponds to the <c> PMINUB </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing one of the source operands.
@@ -2239,7 +2263,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMOVMSKB instruction.
+/// This intrinsic corresponds to the <c> PMOVMSKB </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing the values with bits to be extracted.
@@ -2257,7 +2281,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PMULHUW instruction.
+/// This intrinsic corresponds to the <c> PMULHUW </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing one of the source operands.
@@ -2279,22 +2303,26 @@
 /// __m64 _mm_shuffle_pi16(__m64 a, const int n);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c PSHUFW instruction.
+/// This intrinsic corresponds to the <c> PSHUFW </c> instruction.
 ///
 /// \param a
 ///    A 64-bit integer vector containing the values to be shuffled.
 /// \param n
 ///    An immediate value containing an 8-bit value specifying which elements to
 ///    copy from \a a. The destinations within the 64-bit destination are
-///    assigned values as follows:
-///    Bits [1:0] are used to assign values to bits [15:0] in the destination.
-///    Bits [3:2] are used to assign values to bits [31:16] in the destination.
-///    Bits [5:4] are used to assign values to bits [47:32] in the destination.
-///    Bits [7:6] are used to assign values to bits [63:48] in the destination.
-///    Bit value assignments:
-///    00: assigned from bits [15:0] of \a a.
-///    01: assigned from bits [31:16] of \a a.
-///    10: assigned from bits [47:32] of \a a.
+///    assigned values as follows: \n
+///    Bits [1:0] are used to assign values to bits [15:0] in the
+///    destination. \n
+///    Bits [3:2] are used to assign values to bits [31:16] in the
+///    destination. \n
+///    Bits [5:4] are used to assign values to bits [47:32] in the
+///    destination. \n
+///    Bits [7:6] are used to assign values to bits [63:48] in the
+///    destination. \n
+///    Bit value assignments: \n
+///    00: assigned from bits [15:0] of \a a. \n
+///    01: assigned from bits [31:16] of \a a. \n
+///    10: assigned from bits [47:32] of \a a. \n
 ///    11: assigned from bits [63:48] of \a a.
 /// \returns A 64-bit integer vector containing the shuffled values.
 #define _mm_shuffle_pi16(a, n) __extension__ ({ \
@@ -2308,7 +2336,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c MASKMOVQ instruction.
+/// This intrinsic corresponds to the <c> MASKMOVQ </c> instruction.
 ///
 /// \param __d
 ///    A 64-bit integer vector containing the values with elements to be copied.
@@ -2333,7 +2361,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PAVGB instruction.
+/// This intrinsic corresponds to the <c> PAVGB </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing one of the source operands.
@@ -2352,7 +2380,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PAVGW instruction.
+/// This intrinsic corresponds to the <c> PAVGW </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing one of the source operands.
@@ -2372,7 +2400,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c PSADBW instruction.
+/// This intrinsic corresponds to the <c> PSADBW </c> instruction.
 ///
 /// \param __a
 ///    A 64-bit integer vector containing one of the source operands.
@@ -2392,23 +2420,37 @@
 #endif
 
 /// \brief Returns the contents of the MXCSR register as a 32-bit unsigned
-///    integer value. There are several groups of macros associated with this
+///    integer value.
+///
+///    There are several groups of macros associated with this
 ///    intrinsic, including:
-///    * For checking exception states: _MM_EXCEPT_INVALID, _MM_EXCEPT_DIV_ZERO,
+///    <ul>
+///    <li>
+///      For checking exception states: _MM_EXCEPT_INVALID, _MM_EXCEPT_DIV_ZERO,
 ///      _MM_EXCEPT_DENORM, _MM_EXCEPT_OVERFLOW, _MM_EXCEPT_UNDERFLOW,
 ///      _MM_EXCEPT_INEXACT. There is a convenience wrapper
 ///      _MM_GET_EXCEPTION_STATE().
-///    * For checking exception masks: _MM_MASK_UNDERFLOW, _MM_MASK_OVERFLOW,
+///    </li>
+///    <li>
+///      For checking exception masks: _MM_MASK_UNDERFLOW, _MM_MASK_OVERFLOW,
 ///      _MM_MASK_INVALID, _MM_MASK_DENORM, _MM_MASK_DIV_ZERO, _MM_MASK_INEXACT.
 ///      There is a convenience wrapper _MM_GET_EXCEPTION_MASK().
-///    * For checking rounding modes: _MM_ROUND_NEAREST, _MM_ROUND_DOWN,
+///    </li>
+///    <li>
+///      For checking rounding modes: _MM_ROUND_NEAREST, _MM_ROUND_DOWN,
 ///      _MM_ROUND_UP, _MM_ROUND_TOWARD_ZERO. There is a convenience wrapper
 ///      _MM_GET_ROUNDING_MODE(x) where x is one of these macros.
-///    * For checking flush-to-zero mode: _MM_FLUSH_ZERO_ON, _MM_FLUSH_ZERO_OFF.
+///    </li>
+///    <li>
+///      For checking flush-to-zero mode: _MM_FLUSH_ZERO_ON, _MM_FLUSH_ZERO_OFF.
 ///      There is a convenience wrapper _MM_GET_FLUSH_ZERO_MODE().
-///    * For checking denormals-are-zero mode: _MM_DENORMALS_ZERO_ON,
+///    </li>
+///    <li>
+///      For checking denormals-are-zero mode: _MM_DENORMALS_ZERO_ON,
 ///      _MM_DENORMALS_ZERO_OFF. There is a convenience wrapper
 ///      _MM_GET_DENORMALS_ZERO_MODE().
+///    </li>
+///    </ul>
 ///
 ///    For example, the expression below checks if an overflow exception has
 ///    occurred:
@@ -2419,31 +2461,45 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VSTMXCSR / STMXCSR instruction.
+/// This intrinsic corresponds to the <c> VSTMXCSR / STMXCSR </c> instruction.
 ///
 /// \returns A 32-bit unsigned integer containing the contents of the MXCSR
 ///    register.
 unsigned int _mm_getcsr(void);
 
-/// \brief Sets the MXCSR register with the 32-bit unsigned integer value. There
-///    are several groups of macros associated with this intrinsic, including:
-///    * For setting exception states: _MM_EXCEPT_INVALID, _MM_EXCEPT_DIV_ZERO,
+/// \brief Sets the MXCSR register with the 32-bit unsigned integer value.
+///
+///    There are several groups of macros associated with this intrinsic,
+///    including:
+///    <ul>
+///    <li>
+///      For setting exception states: _MM_EXCEPT_INVALID, _MM_EXCEPT_DIV_ZERO,
 ///      _MM_EXCEPT_DENORM, _MM_EXCEPT_OVERFLOW, _MM_EXCEPT_UNDERFLOW,
 ///      _MM_EXCEPT_INEXACT. There is a convenience wrapper
 ///      _MM_SET_EXCEPTION_STATE(x) where x is one of these macros.
-///    * For setting exception masks: _MM_MASK_UNDERFLOW, _MM_MASK_OVERFLOW,
+///    </li>
+///    <li>
+///      For setting exception masks: _MM_MASK_UNDERFLOW, _MM_MASK_OVERFLOW,
 ///      _MM_MASK_INVALID, _MM_MASK_DENORM, _MM_MASK_DIV_ZERO, _MM_MASK_INEXACT.
 ///      There is a convenience wrapper _MM_SET_EXCEPTION_MASK(x) where x is one
 ///      of these macros.
-///    * For setting rounding modes: _MM_ROUND_NEAREST, _MM_ROUND_DOWN,
+///    </li>
+///    <li>
+///      For setting rounding modes: _MM_ROUND_NEAREST, _MM_ROUND_DOWN,
 ///      _MM_ROUND_UP, _MM_ROUND_TOWARD_ZERO. There is a convenience wrapper
 ///      _MM_SET_ROUNDING_MODE(x) where x is one of these macros.
-///    * For setting flush-to-zero mode: _MM_FLUSH_ZERO_ON, _MM_FLUSH_ZERO_OFF.
+///    </li>
+///    <li>
+///      For setting flush-to-zero mode: _MM_FLUSH_ZERO_ON, _MM_FLUSH_ZERO_OFF.
 ///      There is a convenience wrapper _MM_SET_FLUSH_ZERO_MODE(x) where x is
 ///      one of these macros.
-///    * For setting denormals-are-zero mode: _MM_DENORMALS_ZERO_ON,
+///    </li>
+///    <li>
+///      For setting denormals-are-zero mode: _MM_DENORMALS_ZERO_ON,
 ///      _MM_DENORMALS_ZERO_OFF. There is a convenience wrapper
 ///      _MM_SET_DENORMALS_ZERO_MODE(x) where x is one of these macros.
+///    </li>
+///    </ul>
 ///
 ///    For example, the following expression causes subsequent floating-point
 ///    operations to round up:
@@ -2457,11 +2513,11 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VLDMXCSR / LDMXCSR instruction.
+/// This intrinsic corresponds to the <c> VLDMXCSR / LDMXCSR </c> instruction.
 ///
 /// \param __i
 ///    A 32-bit unsigned integer value to be written to the MXCSR register.
-void _mm_setcsr(unsigned int);
+void _mm_setcsr(unsigned int __i);
 
 #if defined(__cplusplus)
 } // extern "C"
@@ -2476,7 +2532,7 @@
 /// __m128 _mm_shuffle_ps(__m128 a, __m128 b, const int mask);
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c VSHUFPS / SHUFPS instruction.
+/// This intrinsic corresponds to the <c> VSHUFPS / SHUFPS </c> instruction.
 ///
 /// \param a
 ///    A 128-bit vector of [4 x float].
@@ -2484,18 +2540,23 @@
 ///    A 128-bit vector of [4 x float].
 /// \param mask
 ///    An immediate value containing an 8-bit value specifying which elements to
-///    copy from \ a and \a b.
-///    Bits [3:0] specify the values copied from operand \a a.
-///    Bits [7:4] specify the values copied from operand \a b. The destinations
-///    within the 128-bit destination are assigned values as follows:
-///    Bits [1:0] are used to assign values to bits [31:0] in the destination.
-///    Bits [3:2] are used to assign values to bits [63:32] in the destination.
-///    Bits [5:4] are used to assign values to bits [95:64] in the destination.
-///    Bits [7:6] are used to assign values to bits [127:96] in the destination.
-///    Bit value assignments:
-///    00: Bits [31:0] copied from the specified operand.
-///    01: Bits [63:32] copied from the specified operand.
-///    10: Bits [95:64] copied from the specified operand.
+///    copy from \ a and \a b. \n
+///    Bits [3:0] specify the values copied from operand \a a. \n
+///    Bits [7:4] specify the values copied from operand \a b. \n
+///    The destinations within the 128-bit destination are assigned values as
+///    follows: \n
+///    Bits [1:0] are used to assign values to bits [31:0] in the
+///    destination. \n
+///    Bits [3:2] are used to assign values to bits [63:32] in the
+///    destination. \n
+///    Bits [5:4] are used to assign values to bits [95:64] in the
+///    destination. \n
+///    Bits [7:6] are used to assign values to bits [127:96] in the
+///    destination. \n
+///    Bit value assignments: \n
+///    00: Bits [31:0] copied from the specified operand. \n
+///    01: Bits [63:32] copied from the specified operand. \n
+///    10: Bits [95:64] copied from the specified operand. \n
 ///    11: Bits [127:96] copied from the specified operand.
 /// \returns A 128-bit vector of [4 x float] containing the shuffled values.
 #define _mm_shuffle_ps(a, b, mask) __extension__ ({ \
@@ -2506,20 +2567,19 @@
                                   4 + (((mask) >> 6) & 0x3)); })
 
 /// \brief Unpacks the high-order (index 2,3) values from two 128-bit vectors of
-///    [4 x float] and interleaves them into a 128-bit vector of [4 x
-///    float].
+///    [4 x float] and interleaves them into a 128-bit vector of [4 x float].
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKHPS / UNPCKHPS instruction.
+/// This intrinsic corresponds to the <c> VUNPCKHPS / UNPCKHPS </c> instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [4 x float].
-///    Bits [95:64] are written to bits [31:0] of the destination.
+///    A 128-bit vector of [4 x float]. \n
+///    Bits [95:64] are written to bits [31:0] of the destination. \n
 ///    Bits [127:96] are written to bits [95:64] of the destination.
 /// \param __b
 ///    A 128-bit vector of [4 x float].
-///    Bits [95:64] are written to bits [63:32] of the destination.
+///    Bits [95:64] are written to bits [63:32] of the destination. \n
 ///    Bits [127:96] are written to bits [127:96] of the destination.
 /// \returns A 128-bit vector of [4 x float] containing the interleaved values.
 static __inline__ __m128 __DEFAULT_FN_ATTRS
@@ -2529,20 +2589,19 @@
 }
 
 /// \brief Unpacks the low-order (index 0,1) values from two 128-bit vectors of
-///    [4 x float] and interleaves them into a 128-bit vector of [4 x
-///    float].
+///    [4 x float] and interleaves them into a 128-bit vector of [4 x float].
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKLPS / UNPCKLPS instruction.
+/// This intrinsic corresponds to the <c> VUNPCKLPS / UNPCKLPS </c> instruction.
 ///
 /// \param __a
-///    A 128-bit vector of [4 x float].
-///    Bits [31:0] are written to bits [31:0] of the destination.
+///    A 128-bit vector of [4 x float]. \n
+///    Bits [31:0] are written to bits [31:0] of the destination.  \n
 ///    Bits [63:32] are written to bits [95:64] of the destination.
 /// \param __b
-///    A 128-bit vector of [4 x float].
-///    Bits [31:0] are written to bits [63:32] of the destination.
+///    A 128-bit vector of [4 x float]. \n
+///    Bits [31:0] are written to bits [63:32] of the destination. \n
 ///    Bits [63:32] are written to bits [127:96] of the destination.
 /// \returns A 128-bit vector of [4 x float] containing the interleaved values.
 static __inline__ __m128 __DEFAULT_FN_ATTRS
@@ -2557,7 +2616,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVSS / MOVSS instruction.
+/// This intrinsic corresponds to the <c> VMOVSS / MOVSS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit floating-point vector of [4 x float]. The upper 96 bits are
@@ -2578,7 +2637,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKHPD / UNPCKHPD instruction.
+/// This intrinsic corresponds to the <c> VUNPCKHPD / UNPCKHPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit floating-point vector of [4 x float]. The upper 64 bits are
@@ -2599,7 +2658,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VUNPCKLPD / UNPCKLPD instruction.
+/// This intrinsic corresponds to the <c> VUNPCKLPD / UNPCKLPD </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit floating-point vector of [4 x float]. The lower 64 bits are
@@ -2619,7 +2678,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPI2PS + \c COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 64-bit vector of [4 x i16]. The elements of the destination are copied
@@ -2649,7 +2709,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPI2PS + \c COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 64-bit vector of 16-bit unsigned integer values. The elements of the
@@ -2678,7 +2739,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPI2PS + \c COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 64-bit vector of [8 x i8]. The elements of the destination are copied
@@ -2702,7 +2764,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPI2PS + \c COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 64-bit vector of unsigned 8-bit integer values. The elements of the
@@ -2726,7 +2789,8 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPI2PS + \c COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 64-bit vector of [2 x i32]. The lower elements of the destination are
@@ -2754,12 +2818,13 @@
 ///    packs the results into a 64-bit integer vector of [4 x i16]. If the
 ///    floating-point element is NaN or infinity, or if the floating-point
 ///    element is greater than 0x7FFFFFFF or less than -0x8000, it is converted
-///    to 0x8000. Otherwise if the floating-point element is greater
-///    than 0x7FFF, it is converted to 0x7FFF.
+///    to 0x8000. Otherwise if the floating-point element is greater than
+///    0x7FFF, it is converted to 0x7FFF.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPS2PI + \c COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> CVTPS2PI + \c COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    A 128-bit floating-point vector of [4 x float].
@@ -2783,12 +2848,13 @@
 ///    [8 x i8]. The upper 32 bits of the vector are set to 0. If the
 ///    floating-point element is NaN or infinity, or if the floating-point
 ///    element is greater than 0x7FFFFFFF or less than -0x80, it is converted
-///    to 0x80. Otherwise if the floating-point element is greater
-///    than 0x7F, it is converted to 0x7F.
+///    to 0x80. Otherwise if the floating-point element is greater than 0x7F,
+///    it is converted to 0x7F.
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c CVTPS2PI + \c COMPOSITE instruction.
+/// This intrinsic corresponds to the <c> CVTPS2PI + \c COMPOSITE </c>
+///   instruction.
 ///
 /// \param __a
 ///    128-bit floating-point vector of [4 x float].
@@ -2812,7 +2878,7 @@
 ///
 /// \headerfile <x86intrin.h>
 ///
-/// This intrinsic corresponds to the \c VMOVMSKPS / MOVMSKPS instruction.
+/// This intrinsic corresponds to the <c> VMOVMSKPS / MOVMSKPS </c> instruction.
 ///
 /// \param __a
 ///    A 128-bit floating-point vector of [4 x float].
diff --git a/lib/Headers/xopintrin.h b/lib/Headers/xopintrin.h
index bdf0cec..4a34f77 100644
--- a/lib/Headers/xopintrin.h
+++ b/lib/Headers/xopintrin.h
@@ -198,13 +198,13 @@
 static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_cmov_si128(__m128i __A, __m128i __B, __m128i __C)
 {
-  return (__m128i)__builtin_ia32_vpcmov((__v2di)__A, (__v2di)__B, (__v2di)__C);
+  return (__m128i)(((__v2du)__A & (__v2du)__C) | ((__v2du)__B & ~(__v2du)__C));
 }
 
 static __inline__ __m256i __DEFAULT_FN_ATTRS
 _mm256_cmov_si256(__m256i __A, __m256i __B, __m256i __C)
 {
-  return (__m256i)__builtin_ia32_vpcmov_256((__v4di)__A, (__v4di)__B, (__v4di)__C);
+  return (__m256i)(((__v4du)__A & (__v4du)__C) | ((__v4du)__B & ~(__v4du)__C));
 }
 
 static __inline__ __m128i __DEFAULT_FN_ATTRS
diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt
index 8f51ccb..c9fbfaf 100644
--- a/lib/Index/CMakeLists.txt
+++ b/lib/Index/CMakeLists.txt
@@ -24,5 +24,6 @@
   clangFormat
   clangFrontend
   clangRewrite
+  clangSerialization
   clangToolingCore
   )
diff --git a/lib/Index/CommentToXML.cpp b/lib/Index/CommentToXML.cpp
index ee066cc..08acc96 100644
--- a/lib/Index/CommentToXML.cpp
+++ b/lib/Index/CommentToXML.cpp
@@ -593,9 +593,11 @@
   unsigned Length = Declaration.size();
 
   bool IncompleteFormat = false;
+  format::FormatStyle Style = format::getLLVMStyle();
+  Style.FixNamespaceComments = false;
   tooling::Replacements Replaces =
-      reformat(format::getLLVMStyle(), StringDecl,
-               tooling::Range(Offset, Length), "xmldecl.xd", &IncompleteFormat);
+      reformat(Style, StringDecl, tooling::Range(Offset, Length), "xmldecl.xd",
+               &IncompleteFormat);
   auto FormattedStringDecl = applyAllReplacements(StringDecl, Replaces);
   if (static_cast<bool>(FormattedStringDecl)) {
     Declaration = *FormattedStringDecl;
diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp
index 3aa0152..7681de7 100644
--- a/lib/Index/IndexBody.cpp
+++ b/lib/Index/IndexBody.cpp
@@ -269,7 +269,7 @@
       const Decl *D = *I;
       if (!D)
         continue;
-      if (!IndexCtx.isFunctionLocalDecl(D))
+      if (!isFunctionLocalSymbol(D))
         IndexCtx.indexTopLevelDecl(D);
     }
 
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp
index 1225391..4c5a87b 100644
--- a/lib/Index/IndexDecl.cpp
+++ b/lib/Index/IndexDecl.cpp
@@ -46,10 +46,13 @@
   }
 
   void handleDeclarator(const DeclaratorDecl *D,
-                        const NamedDecl *Parent = nullptr) {
+                        const NamedDecl *Parent = nullptr,
+                        bool isIBType = false) {
     if (!Parent) Parent = D;
 
-    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent);
+    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
+                                 Parent->getLexicalDeclContext(),
+                                 /*isBase=*/false, isIBType);
     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
       // Only index parameters in definitions, parameters in declarations are
@@ -89,11 +92,23 @@
       Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
                              AssociatedProp);
 
-    if (!IndexCtx.handleDecl(D, (unsigned)SymbolRole::Dynamic, Relations))
+    // getLocation() returns beginning token of a method declaration, but for
+    // indexing purposes we want to point to the base name.
+    SourceLocation MethodLoc = D->getSelectorStartLoc();
+    if (MethodLoc.isInvalid())
+      MethodLoc = D->getLocation();
+
+    SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic;
+    if (D->isImplicit())
+      Roles |= (SymbolRoleSet)SymbolRole::Implicit;
+    if (!IndexCtx.handleDecl(D, MethodLoc, Roles, Relations))
       return false;
     IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
-    for (const auto *I : D->parameters())
-      handleDeclarator(I, D);
+    bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
+    for (const auto *I : D->parameters()) {
+      handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
+      hasIBActionAndFirst = false;
+    }
 
     if (D->isThisDeclarationADefinition()) {
       const Stmt *Body = D->getBody();
@@ -166,14 +181,8 @@
 
   bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
     if (D->getSynthesize()) {
-      // For synthesized ivars, use the location of the ObjC implementation,
-      // not the location of the property.
-      // Otherwise the header file containing the @interface will have different
-      // indexing contents based on whether the @implementation was present or
-      // not in the translation unit.
-      return IndexCtx.handleDecl(D,
-                                 cast<Decl>(D->getDeclContext())->getLocation(),
-                                 (unsigned)SymbolRole::Implicit);
+      // handled in VisitObjCPropertyImplDecl
+      return true;
     }
     if (!IndexCtx.handleDecl(D))
       return false;
@@ -216,14 +225,17 @@
   }
 
   bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
-                                 const ObjCContainerDecl *ContD) {
+                                 const ObjCContainerDecl *ContD,
+                                 SourceLocation SuperLoc) {
     ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
     for (ObjCInterfaceDecl::protocol_iterator
          I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
       SourceLocation Loc = *LI;
       ObjCProtocolDecl *PD = *I;
-      TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD,
-          SymbolRoleSet(),
+      SymbolRoleSet roles{};
+      if (Loc == SuperLoc)
+        roles |= (SymbolRoleSet)SymbolRole::Implicit;
+      TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
           SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
     }
     return true;
@@ -232,12 +244,26 @@
   bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
     if (D->isThisDeclarationADefinition()) {
       TRY_TO(IndexCtx.handleDecl(D));
+      SourceLocation SuperLoc = D->getSuperClassLoc();
       if (auto *SuperD = D->getSuperClass()) {
-        TRY_TO(IndexCtx.handleReference(SuperD, D->getSuperClassLoc(), D, D,
-            SymbolRoleSet(),
+        bool hasSuperTypedef = false;
+        if (auto *TInfo = D->getSuperClassTInfo()) {
+          if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
+            if (auto *TD = TT->getDecl()) {
+              hasSuperTypedef = true;
+              TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
+                                              SymbolRoleSet()));
+            }
+          }
+        }
+        SymbolRoleSet superRoles{};
+        if (hasSuperTypedef)
+          superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
+        TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
             SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
       }
-      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
+      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
+                                       SuperLoc));
       TRY_TO(IndexCtx.indexDeclContext(D));
     } else {
       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
@@ -249,7 +275,8 @@
   bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
     if (D->isThisDeclarationADefinition()) {
       TRY_TO(IndexCtx.handleDecl(D));
-      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
+      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
+                                       /*superLoc=*/SourceLocation()));
       TRY_TO(IndexCtx.indexDeclContext(D));
     } else {
       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
@@ -269,12 +296,16 @@
     if (!IndexCtx.handleDecl(D))
       return false;
 
-    // Index the ivars first to make sure the synthesized ivars are indexed
-    // before indexing the methods that can reference them.
-    for (const auto *IvarI : D->ivars())
-      IndexCtx.indexDecl(IvarI);
+    // Visit implicit @synthesize property implementations first as their
+    // location is reported at the name of the @implementation block. This
+    // serves no purpose other than to simplify the FileCheck-based tests.
+    for (const auto *I : D->property_impls()) {
+      if (I->getLocation().isInvalid())
+        IndexCtx.indexDecl(I);
+    }
     for (const auto *I : D->decls()) {
-      if (!isa<ObjCIvarDecl>(I))
+      if (!isa<ObjCPropertyImplDecl>(I) ||
+          cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
         IndexCtx.indexDecl(I);
     }
 
@@ -283,16 +314,18 @@
 
   bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
     const ObjCInterfaceDecl *C = D->getClassInterface();
-    if (C)
-      TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
-                                  SymbolRoleSet(), SymbolRelation{
-                                    (unsigned)SymbolRole::RelationExtendedBy, D
-                                  }));
+    if (!C)
+      return true;
+    TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
+                                   SymbolRelation{
+                                     (unsigned)SymbolRole::RelationExtendedBy, D
+                                   }));
     SourceLocation CategoryLoc = D->getCategoryNameLoc();
     if (!CategoryLoc.isValid())
       CategoryLoc = D->getLocation();
     TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
-    TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
+    TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
+                                     /*superLoc=*/SourceLocation()));
     TRY_TO(IndexCtx.indexDeclContext(D));
     return true;
   }
@@ -333,38 +366,67 @@
         handleObjCMethod(MD, D);
     if (!IndexCtx.handleDecl(D))
       return false;
+    if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
+      IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
+                                   D->getLexicalDeclContext(), false, true);
     IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
     return true;
   }
 
   bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
     ObjCPropertyDecl *PD = D->getPropertyDecl();
-    if (!IndexCtx.handleReference(PD, D->getLocation(),
-                             /*Parent=*/cast<NamedDecl>(D->getDeclContext()),
-                             D->getDeclContext(), SymbolRoleSet(), {},
-                             /*RefE=*/nullptr, D))
+    auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
+    SourceLocation Loc = D->getLocation();
+    SymbolRoleSet Roles = 0;
+    SmallVector<SymbolRelation, 1> Relations;
+
+    if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
+      Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
+    if (Loc.isInvalid()) {
+      Loc = Container->getLocation();
+      Roles |= (SymbolRoleSet)SymbolRole::Implicit;
+    }
+    if (!IndexCtx.handleDecl(D, Loc, Roles, Relations))
       return false;
 
     if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
       return true;
-    assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
-    
-    if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
-      if (!IvarD->getSynthesize())
-        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
-                                 D->getDeclContext(), SymbolRoleSet());
-    }
 
-    auto *ImplD = cast<ObjCImplDecl>(D->getDeclContext());
+    assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
     if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
       if (MD->isPropertyAccessor() &&
-          !hasUserDefined(MD, ImplD))
-        IndexCtx.handleDecl(MD, D->getLocation(), SymbolRoleSet(), {}, ImplD);
+          !hasUserDefined(MD, Container))
+        IndexCtx.handleDecl(MD, Loc, SymbolRoleSet(SymbolRole::Implicit), {},
+                            Container);
     }
     if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
       if (MD->isPropertyAccessor() &&
-          !hasUserDefined(MD, ImplD))
-        IndexCtx.handleDecl(MD, D->getLocation(), SymbolRoleSet(), {}, ImplD);
+          !hasUserDefined(MD, Container))
+        IndexCtx.handleDecl(MD, Loc, SymbolRoleSet(SymbolRole::Implicit), {},
+                            Container);
+    }
+    if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
+      if (IvarD->getSynthesize()) {
+        // For synthesized ivars, use the location of its name in the
+        // corresponding @synthesize. If there isn't one, use the containing
+        // @implementation's location, rather than the property's location,
+        // otherwise the header file containing the @interface will have different
+        // indexing contents based on whether the @implementation was present or
+        // not in the translation unit.
+        SymbolRoleSet IvarRoles = 0;
+        SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
+        if (D->getLocation().isInvalid()) {
+          IvarLoc = Container->getLocation();
+          IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
+        } else if (D->getLocation() == IvarLoc) {
+          IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
+        }
+        if(!IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles))
+          return false;
+      } else {
+        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
+                                 D->getDeclContext(), SymbolRoleSet());
+      }
     }
     return true;
   }
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index b234245..785125c 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -49,13 +49,49 @@
   }
 }
 
+bool index::isFunctionLocalSymbol(const Decl *D) {
+  assert(D);
+
+  if (isa<ParmVarDecl>(D))
+    return true;
+
+  if (isa<TemplateTemplateParmDecl>(D))
+    return true;
+
+  if (isa<ObjCTypeParamDecl>(D))
+    return true;
+
+  if (!D->getParentFunctionOrMethod())
+    return false;
+
+  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+    switch (ND->getFormalLinkage()) {
+      case NoLinkage:
+      case VisibleNoLinkage:
+      case InternalLinkage:
+        return true;
+      case UniqueExternalLinkage:
+        llvm_unreachable("Not a sema linkage");
+      case ExternalLinkage:
+        return false;
+    }
+  }
+
+  return true;
+}
+
 SymbolInfo index::getSymbolInfo(const Decl *D) {
   assert(D);
   SymbolInfo Info;
   Info.Kind = SymbolKind::Unknown;
+  Info.SubKind = SymbolSubKind::None;
   Info.Properties = SymbolPropertySet();
   Info.Lang = SymbolLanguage::C;
 
+  if (isFunctionLocalSymbol(D)) {
+    Info.Properties |= (unsigned)SymbolProperty::Local;
+  }
+
   if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
     switch (TD->getTagKind()) {
     case TTK_Struct:
@@ -93,10 +129,13 @@
 
   } else if (auto *VD = dyn_cast<VarDecl>(D)) {
     Info.Kind = SymbolKind::Variable;
-    if (isa<CXXRecordDecl>(D->getDeclContext())) {
+    if (isa<ParmVarDecl>(D)) {
+      Info.Kind = SymbolKind::Parameter;
+    } else if (isa<CXXRecordDecl>(D->getDeclContext())) {
       Info.Kind = SymbolKind::StaticProperty;
       Info.Lang = SymbolLanguage::CXX;
     }
+
     if (isa<VarTemplatePartialSpecializationDecl>(D)) {
       Info.Lang = SymbolLanguage::CXX;
       Info.Properties |= (unsigned)SymbolProperty::Generic;
@@ -146,15 +185,31 @@
       Info.Lang = SymbolLanguage::ObjC;
       break;
     case Decl::ObjCCategory:
-    case Decl::ObjCCategoryImpl:
+    case Decl::ObjCCategoryImpl: {
       Info.Kind = SymbolKind::Extension;
       Info.Lang = SymbolLanguage::ObjC;
-      break;
-    case Decl::ObjCMethod:
-      if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
-        Info.Kind = SymbolKind::InstanceMethod;
+      const ObjCInterfaceDecl *ClsD = nullptr;
+      if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D))
+        ClsD = CatD->getClassInterface();
       else
+        ClsD = cast<ObjCCategoryImplDecl>(D)->getClassInterface();
+      if (isUnitTestCase(ClsD))
+        Info.Properties |= (unsigned)SymbolProperty::UnitTest;
+      break;
+    }
+    case Decl::ObjCMethod:
+      if (cast<ObjCMethodDecl>(D)->isInstanceMethod()) {
+        const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
+        Info.Kind = SymbolKind::InstanceMethod;
+        if (MD->isPropertyAccessor()) {
+          if (MD->param_size())
+            Info.SubKind = SymbolSubKind::AccessorSetter;
+          else
+            Info.SubKind = SymbolSubKind::AccessorGetter;
+        }
+      } else {
         Info.Kind = SymbolKind::ClassMethod;
+      }
       Info.Lang = SymbolLanguage::ObjC;
       if (isUnitTest(cast<ObjCMethodDecl>(D)))
         Info.Properties |= (unsigned)SymbolProperty::UnitTest;
@@ -183,10 +238,16 @@
       Info.Kind = SymbolKind::NamespaceAlias;
       Info.Lang = SymbolLanguage::CXX;
       break;
-    case Decl::CXXConstructor:
+    case Decl::CXXConstructor: {
       Info.Kind = SymbolKind::Constructor;
       Info.Lang = SymbolLanguage::CXX;
+      auto *CD = cast<CXXConstructorDecl>(D);
+      if (CD->isCopyConstructor())
+        Info.SubKind = SymbolSubKind::CXXCopyConstructor;
+      else if (CD->isMoveConstructor())
+        Info.SubKind = SymbolSubKind::CXXMoveConstructor;
       break;
+    }
     case Decl::CXXDestructor:
       Info.Kind = SymbolKind::Destructor;
       Info.Lang = SymbolLanguage::CXX;
@@ -282,6 +343,8 @@
   APPLY_FOR_ROLE(RelationCalledBy);
   APPLY_FOR_ROLE(RelationExtendedBy);
   APPLY_FOR_ROLE(RelationAccessorOf);
+  APPLY_FOR_ROLE(RelationContainedBy);
+  APPLY_FOR_ROLE(RelationIBTypeOf);
 
 #undef APPLY_FOR_ROLE
 }
@@ -310,6 +373,8 @@
     case SymbolRole::RelationCalledBy: OS << "RelCall"; break;
     case SymbolRole::RelationExtendedBy: OS << "RelExt"; break;
     case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
+    case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
+    case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
     }
   });
 }
@@ -359,10 +424,22 @@
   case SymbolKind::Constructor: return "constructor";
   case SymbolKind::Destructor: return "destructor";
   case SymbolKind::ConversionFunction: return "coversion-func";
+  case SymbolKind::Parameter: return "param";
   }
   llvm_unreachable("invalid symbol kind");
 }
 
+StringRef index::getSymbolSubKindString(SymbolSubKind K) {
+  switch (K) {
+  case SymbolSubKind::None: return "<none>";
+  case SymbolSubKind::CXXCopyConstructor: return "cxx-copy-ctor";
+  case SymbolSubKind::CXXMoveConstructor: return "cxx-move-ctor";
+  case SymbolSubKind::AccessorGetter: return "acc-get";
+  case SymbolSubKind::AccessorSetter: return "acc-set";
+  }
+  llvm_unreachable("invalid symbol subkind");
+}
+
 StringRef index::getSymbolLanguageString(SymbolLanguage K) {
   switch (K) {
   case SymbolLanguage::C: return "C";
@@ -385,6 +462,7 @@
   APPLY_FOR_PROPERTY(IBAnnotated);
   APPLY_FOR_PROPERTY(IBOutletCollection);
   APPLY_FOR_PROPERTY(GKInspectable);
+  APPLY_FOR_PROPERTY(Local);
 
 #undef APPLY_FOR_PROPERTY
 }
@@ -404,6 +482,7 @@
     case SymbolProperty::IBAnnotated: OS << "IB"; break;
     case SymbolProperty::IBOutletCollection: OS << "IBColl"; break;
     case SymbolProperty::GKInspectable: OS << "GKI"; break;
+    case SymbolProperty::Local: OS << "local"; break;
     }
   });
 }
diff --git a/lib/Index/IndexTypeSourceInfo.cpp b/lib/Index/IndexTypeSourceInfo.cpp
index 619a9a4..33848da 100644
--- a/lib/Index/IndexTypeSourceInfo.cpp
+++ b/lib/Index/IndexTypeSourceInfo.cpp
@@ -26,28 +26,44 @@
 
 public:
   TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
-              const DeclContext *DC, bool isBase)
+              const DeclContext *DC, bool isBase, bool isIBType)
     : IndexCtx(indexCtx), Parent(parent), ParentDC(DC), IsBase(isBase) {
     if (IsBase) {
       assert(Parent);
       Relations.emplace_back((unsigned)SymbolRole::RelationBaseOf, Parent);
     }
+    if (isIBType) {
+      assert(Parent);
+      Relations.emplace_back((unsigned)SymbolRole::RelationIBTypeOf, Parent);
+    }
   }
   
   bool shouldWalkTypesOfTypeLocs() const { return false; }
 
-  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-    return IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
-                                    Parent, ParentDC, SymbolRoleSet(),
-                                    Relations);
-  }
-
 #define TRY_TO(CALL_EXPR)                                                      \
   do {                                                                         \
     if (!CALL_EXPR)                                                            \
       return false;                                                            \
   } while (0)
 
+  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+    if (IsBase) {
+      SourceLocation Loc = TL.getNameLoc();
+      TRY_TO(IndexCtx.handleReference(TL.getTypedefNameDecl(), Loc,
+                                      Parent, ParentDC, SymbolRoleSet()));
+      if (auto *CD = TL.getType()->getAsCXXRecordDecl()) {
+        TRY_TO(IndexCtx.handleReference(CD, Loc, Parent, ParentDC,
+                                        (unsigned)SymbolRole::Implicit,
+                                        Relations));
+      }
+    } else {
+      TRY_TO(IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
+                                      Parent, ParentDC, SymbolRoleSet(),
+                                      Relations));
+    }
+    return true;
+  }
+
   bool traverseParamVarHelper(ParmVarDecl *D) {
     TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
     if (D->getTypeSourceInfo())
@@ -93,13 +109,13 @@
 
   bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
     return IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
-                                    Parent, ParentDC, SymbolRoleSet());
+                                    Parent, ParentDC, SymbolRoleSet(), Relations);
   }
 
   bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
     for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
       IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
-                               Parent, ParentDC, SymbolRoleSet());
+                               Parent, ParentDC, SymbolRoleSet(), Relations);
     }
     return true;
   }
@@ -130,23 +146,25 @@
 void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
                                           const NamedDecl *Parent,
                                           const DeclContext *DC,
-                                          bool isBase) {
+                                          bool isBase,
+                                          bool isIBType) {
   if (!TInfo || TInfo->getTypeLoc().isNull())
     return;
   
-  indexTypeLoc(TInfo->getTypeLoc(), Parent, DC, isBase);
+  indexTypeLoc(TInfo->getTypeLoc(), Parent, DC, isBase, isIBType);
 }
 
 void IndexingContext::indexTypeLoc(TypeLoc TL,
                                    const NamedDecl *Parent,
                                    const DeclContext *DC,
-                                   bool isBase) {
+                                   bool isBase,
+                                   bool isIBType) {
   if (TL.isNull())
     return;
 
   if (!DC)
     DC = Parent->getLexicalDeclContext();
-  TypeIndexer(*this, Parent, DC, isBase).TraverseTypeLoc(TL);
+  TypeIndexer(*this, Parent, DC, isBase, isIBType).TraverseTypeLoc(TL);
 }
 
 void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
@@ -185,7 +203,7 @@
 }
 
 void IndexingContext::indexTagDecl(const TagDecl *D) {
-  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
+  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
     return;
 
   if (handleDecl(D)) {
diff --git a/lib/Index/IndexingAction.cpp b/lib/Index/IndexingAction.cpp
index d744293..cac24d4 100644
--- a/lib/Index/IndexingAction.cpp
+++ b/lib/Index/IndexingAction.cpp
@@ -13,6 +13,7 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Serialization/ASTReader.h"
 
 using namespace clang;
 using namespace clang::index;
@@ -173,4 +174,20 @@
   IndexCtx.setASTContext(Unit.getASTContext());
   DataConsumer->initialize(Unit.getASTContext());
   indexTranslationUnit(Unit, IndexCtx);
+  DataConsumer->finish();
+}
+
+void index::indexModuleFile(serialization::ModuleFile &Mod,
+                            ASTReader &Reader,
+                            std::shared_ptr<IndexDataConsumer> DataConsumer,
+                            IndexingOptions Opts) {
+  ASTContext &Ctx = Reader.getContext();
+  IndexingContext IndexCtx(Opts, *DataConsumer);
+  IndexCtx.setASTContext(Ctx);
+  DataConsumer->initialize(Ctx);
+
+  for (const Decl *D :Reader.getModuleFileLevelDecls(Mod)) {
+    IndexCtx.indexTopLevelDecl(D);
+  }
+  DataConsumer->finish();
 }
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index e623a49..9a4028f 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -24,9 +24,7 @@
 bool IndexingContext::handleDecl(const Decl *D,
                                  SymbolRoleSet Roles,
                                  ArrayRef<SymbolRelation> Relations) {
-  return handleDeclOccurrence(D, D->getLocation(), /*IsRef=*/false,
-                              cast<Decl>(D->getDeclContext()), Roles, Relations,
-                              nullptr, nullptr, D->getDeclContext());
+  return handleDecl(D, D->getLocation(), Roles, Relations);
 }
 
 bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc,
@@ -35,9 +33,14 @@
                                  const DeclContext *DC) {
   if (!DC)
     DC = D->getDeclContext();
+
+  const Decl *OrigD = D;
+  if (isa<ObjCPropertyImplDecl>(D)) {
+    D = cast<ObjCPropertyImplDecl>(D)->getPropertyDecl();
+  }
   return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC),
                               Roles, Relations,
-                              nullptr, nullptr, DC);
+                              nullptr, OrigD, DC);
 }
 
 bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
@@ -47,7 +50,7 @@
                                       ArrayRef<SymbolRelation> Relations,
                                       const Expr *RefE,
                                       const Decl *RefD) {
-  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
+  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
     return true;
 
   if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D))
@@ -97,34 +100,6 @@
   return DataConsumer.handleModuleOccurence(ImportD, Roles, FID, Offset);
 }
 
-bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
-  assert(D);
-
-  if (isa<TemplateTemplateParmDecl>(D))
-    return true;
-
-  if (isa<ObjCTypeParamDecl>(D))
-    return true;
-
-  if (!D->getParentFunctionOrMethod())
-    return false;
-
-  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
-    switch (ND->getFormalLinkage()) {
-    case NoLinkage:
-    case VisibleNoLinkage:
-    case InternalLinkage:
-      return true;
-    case UniqueExternalLinkage:
-      llvm_unreachable("Not a sema linkage");
-    case ExternalLinkage:
-      return false;
-    }
-  }
-
-  return true;
-}
-
 bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
   TemplateSpecializationKind TKind = TSK_Undeclared;
   if (const ClassTemplateSpecializationDecl *
@@ -286,7 +261,7 @@
 
   if (IsRef)
     Roles |= (unsigned)SymbolRole::Reference;
-  else if (isDeclADefinition(D, ContainerDC, *Ctx))
+  else if (isDeclADefinition(OrigD, ContainerDC, *Ctx))
     Roles |= (unsigned)SymbolRole::Definition;
   else
     Roles |= (unsigned)SymbolRole::Declaration;
@@ -312,9 +287,20 @@
     Roles |= Rel.Roles;
   };
 
-  if (!IsRef && Parent && !cast<DeclContext>(Parent)->isFunctionOrMethod()) {
-    addRelation(SymbolRelation{(unsigned)SymbolRole::RelationChildOf, Parent});
+  if (Parent) {
+    if (IsRef || (!isa<ParmVarDecl>(D) && isFunctionLocalSymbol(D))) {
+      addRelation(SymbolRelation{
+        (unsigned)SymbolRole::RelationContainedBy,
+        Parent
+      });
+    } else {
+      addRelation(SymbolRelation{
+        (unsigned)SymbolRole::RelationChildOf,
+        Parent
+      });
+    }
   }
+
   for (auto &Rel : Relations) {
     addRelation(SymbolRelation(Rel.Roles,
                                Rel.RelatedSymbol->getCanonicalDecl()));
diff --git a/lib/Index/IndexingContext.h b/lib/Index/IndexingContext.h
index 600fc43..5f42158 100644
--- a/lib/Index/IndexingContext.h
+++ b/lib/Index/IndexingContext.h
@@ -58,7 +58,6 @@
     return false;
   }
 
-  static bool isFunctionLocalDecl(const Decl *D);
   static bool isTemplateImplicitInstantiation(const Decl *D);
 
   bool handleDecl(const Decl *D, SymbolRoleSet Roles = SymbolRoleSet(),
@@ -85,11 +84,13 @@
 
   void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
                            const DeclContext *DC = nullptr,
-                           bool isBase = false);
+                           bool isBase = false,
+                           bool isIBType = false);
 
   void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent,
                     const DeclContext *DC = nullptr,
-                    bool isBase = false);
+                    bool isBase = false,
+                    bool isIBType = false);
 
   void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
                                    const NamedDecl *Parent,
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 58f61c3..73dddd9 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -310,7 +310,7 @@
   // For a template specialization, mangle the template arguments.
   if (const VarTemplateSpecializationDecl *Spec
                               = dyn_cast<VarTemplateSpecializationDecl>(D)) {
-    const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
+    const TemplateArgumentList &Args = Spec->getTemplateArgs();
     Out << '>';
     for (unsigned I = 0, N = Args.size(); I != N; ++I) {
       Out << '#';
@@ -521,7 +521,7 @@
   // For a class template specialization, mangle the template arguments.
   if (const ClassTemplateSpecializationDecl *Spec
                               = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
-    const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
+    const TemplateArgumentList &Args = Spec->getTemplateArgs();
     Out << '>';
     for (unsigned I = 0, N = Args.size(); I != N; ++I) {
       Out << '#';
@@ -654,7 +654,6 @@
         case BuiltinType::OCLEvent:
         case BuiltinType::OCLClkEvent:
         case BuiltinType::OCLQueue:
-        case BuiltinType::OCLNDRange:
         case BuiltinType::OCLReserveID:
         case BuiltinType::OCLSampler:
           IgnoreResults = true;
@@ -911,21 +910,30 @@
 bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD,
                                        const SourceManager &SM,
                                        SmallVectorImpl<char> &Buf) {
+  if (!MD)
+    return true;
+  return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
+                             SM, Buf);
+
+}
+
+bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
+                                       const SourceManager &SM,
+                                       SmallVectorImpl<char> &Buf) {
   // Don't generate USRs for things with invalid locations.
-  if (!MD || MD->getLocation().isInvalid())
+  if (MacroName.empty() || Loc.isInvalid())
     return true;
 
   llvm::raw_svector_ostream Out(Buf);
 
   // Assume that system headers are sane.  Don't put source location
   // information into the USR if the macro comes from a system header.
-  SourceLocation Loc = MD->getLocation();
   bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc);
 
   Out << getUSRSpacePrefix();
   if (ShouldGenerateLocation)
     printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
   Out << "@macro@";
-  Out << MD->getName()->getName();
+  Out << MacroName;
   return false;
 }
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 0aef7ff..4ee3871 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -54,7 +54,7 @@
 
 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {}
 
-HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
+HeaderSearch::HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
                            SourceManager &SourceMgr, DiagnosticsEngine &Diags,
                            const LangOptions &LangOpts,
                            const TargetInfo *Target)
@@ -121,6 +121,13 @@
   return nullptr;
 }
 
+/// \brief Get filenames for all registered header maps.
+void HeaderSearch::getHeaderMapFileNames(
+    SmallVectorImpl<std::string> &Names) const {
+  for (auto &HM : HeaderMaps)
+    Names.push_back(HM.first->getName());
+}
+
 std::string HeaderSearch::getModuleFileName(Module *Module) {
   const FileEntry *ModuleMap =
       getModuleMap().getModuleMapFileForUniquing(Module);
@@ -165,8 +172,10 @@
     //
     // To avoid false-negatives, we form as canonical a path as we can, and map
     // to lower-case in case we're on a case-insensitive file system.
-   auto *Dir =
-        FileMgr.getDirectory(llvm::sys::path::parent_path(ModuleMapPath));
+    std::string Parent = llvm::sys::path::parent_path(ModuleMapPath);
+    if (Parent.empty())
+      Parent = ".";
+    auto *Dir = FileMgr.getDirectory(Parent);
     if (!Dir)
       return std::string();
     auto DirName = FileMgr.getCanonicalName(Dir);
@@ -187,16 +196,36 @@
   Module *Module = ModMap.findModule(ModuleName);
   if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
     return Module;
-  
+
+  StringRef SearchName = ModuleName;
+  Module = lookupModule(ModuleName, SearchName);
+
+  // The facility for "private modules" -- adjacent, optional module maps named
+  // module.private.modulemap that are supposed to define private submodules --
+  // is sometimes misused by frameworks that name their associated private
+  // module FooPrivate, rather than as a submodule named Foo.Private as
+  // intended. Here we compensate for such cases by looking in directories named
+  // Foo.framework, when we previously looked and failed to find a
+  // FooPrivate.framework.
+  if (!Module && SearchName.consume_back("Private"))
+    Module = lookupModule(ModuleName, SearchName);
+  return Module;
+}
+
+Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName) {
+  Module *Module = nullptr;
+
   // Look through the various header search paths to load any available module
   // maps, searching for a module map that describes this module.
   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
     if (SearchDirs[Idx].isFramework()) {
-      // Search for or infer a module map for a framework.
+      // Search for or infer a module map for a framework. Here we use
+      // SearchName rather than ModuleName, to permit finding private modules
+      // named FooPrivate in buggy frameworks named Foo.
       SmallString<128> FrameworkDirName;
       FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
-      llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework");
-      if (const DirectoryEntry *FrameworkDir 
+      llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
+      if (const DirectoryEntry *FrameworkDir
             = FileMgr.getDirectory(FrameworkDirName)) {
         bool IsSystem
           = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
@@ -1065,13 +1094,51 @@
 }
 
 bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
-                                          const FileEntry *File,
-                                          bool isImport, Module *M) {
+                                          const FileEntry *File, bool isImport,
+                                          bool ModulesEnabled, Module *M) {
   ++NumIncluded; // Count # of attempted #includes.
 
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
+  // FIXME: this is a workaround for the lack of proper modules-aware support
+  // for #import / #pragma once
+  auto TryEnterImported = [&](void) -> bool {
+    if (!ModulesEnabled)
+      return false;
+    // Modules with builtins are special; multiple modules use builtins as
+    // modular headers, example:
+    //
+    //    module stddef { header "stddef.h" export * }
+    //
+    // After module map parsing, this expands to:
+    //
+    //    module stddef {
+    //      header "/path_to_builtin_dirs/stddef.h"
+    //      textual "stddef.h"
+    //    }
+    //
+    // It's common that libc++ and system modules will both define such
+    // submodules. Make sure cached results for a builtin header won't
+    // prevent other builtin modules to potentially enter the builtin header.
+    // Note that builtins are header guarded and the decision to actually
+    // enter them is postponed to the controlling macros logic below.
+    bool TryEnterHdr = false;
+    if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
+      TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
+                    ModuleMap::isBuiltinHeader(
+                        llvm::sys::path::filename(File->getName()));
+
+    // Textual headers can be #imported from different modules. Since ObjC
+    // headers find in the wild might rely only on #import and do not contain
+    // controlling macros, be conservative and only try to enter textual headers
+    // if such macro is present.
+    if (!FileInfo.isModuleHeader &&
+        FileInfo.getControllingMacro(ExternalLookup))
+      TryEnterHdr = true;
+    return TryEnterHdr;
+  };
+
   // If this is a #import directive, check that we have not already imported
   // this header.
   if (isImport) {
@@ -1079,11 +1146,12 @@
     FileInfo.isImport = true;
 
     // Has this already been #import'ed or #include'd?
-    if (FileInfo.NumIncludes) return false;
+    if (FileInfo.NumIncludes && !TryEnterImported())
+      return false;
   } else {
     // Otherwise, if this is a #include of a file that was previously #import'd
     // or if this is the second #include of a #pragma once file, ignore it.
-    if (FileInfo.isImport)
+    if (FileInfo.isImport && !TryEnterImported())
       return false;
   }
 
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 37c7aa4..6025a66 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -1713,9 +1713,9 @@
                                          getLangOpts());
         if (!isIdentifierBody(Next)) {
           // End of suffix. Check whether this is on the whitelist.
-          IsUDSuffix = (Chars == 1 && Buffer[0] == 's') ||
-                       NumericLiteralParser::isValidUDSuffix(
-                           getLangOpts(), StringRef(Buffer, Chars));
+          const StringRef CompleteSuffix(Buffer, Chars);
+          IsUDSuffix = StringLiteralParser::isValidUDSuffix(getLangOpts(),
+                                                            CompleteSuffix);
           break;
         }
 
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index 582ed3f..fbfd3fe 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -1708,3 +1708,12 @@
 
   return SpellingPtr-SpellingStart;
 }
+
+/// Determine whether a suffix is a valid ud-suffix. We avoid treating reserved
+/// suffixes as ud-suffixes, because the diagnostic experience is better if we
+/// treat it as an invalid suffix.
+bool StringLiteralParser::isValidUDSuffix(const LangOptions &LangOpts,
+                                          StringRef Suffix) {
+  return NumericLiteralParser::isValidUDSuffix(LangOpts, Suffix) ||
+         Suffix == "sv";
+}
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index c1b7b33..384e570 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -91,6 +91,7 @@
       HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
       SourceModule(nullptr), NumCreatedModules(0) {
   MMapLangOpts.LineComment = true;
+  MMapLangOpts.ModularCodegen = LangOpts.ModularCodegen;
 }
 
 ModuleMap::~ModuleMap() {
@@ -144,7 +145,7 @@
 /// \brief Determine whether the given file name is the name of a builtin
 /// header, supplied by Clang to replace, override, or augment existing system
 /// headers.
-static bool isBuiltinHeader(StringRef FileName) {
+bool ModuleMap::isBuiltinHeader(StringRef FileName) {
   return llvm::StringSwitch<bool>(FileName)
            .Case("float.h", true)
            .Case("iso646.h", true)
@@ -165,7 +166,7 @@
   HeadersMap::iterator Known = Headers.find(File);
   if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
       Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
-      isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
+      ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
     HeaderInfo.loadTopLevelSystemModules();
     return Headers.find(File);
   }
@@ -446,9 +447,19 @@
              I = Known->second.begin(),
              E = Known->second.end();
          I != E; ++I) {
-      if (I->isAvailable() && (!RequestingModule ||
-                               I->getModule()->isSubModuleOf(RequestingModule)))
+
+      if (I->isAvailable() &&
+          (!RequestingModule ||
+           I->getModule()->isSubModuleOf(RequestingModule))) {
+        // When no requesting module is available, the caller is looking if a
+        // header is part a module by only looking into the module map. This is
+        // done by warn_uncovered_module_header checks; don't consider textual
+        // headers part of it in this mode, otherwise we get misleading warnings
+        // that a umbrella header is not including a textual header.
+        if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
+          continue;
         return false;
+      }
     }
     return true;
   }
@@ -544,16 +555,17 @@
   return Context->findSubmodule(Name);
 }
 
-std::pair<Module *, bool> 
-ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
-                              bool IsExplicit) {
+std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
+                                                        Module *Parent,
+                                                        bool IsFramework,
+                                                        bool IsExplicit) {
   // Try to find an existing module with this name.
   if (Module *Sub = lookupModuleQualified(Name, Parent))
     return std::make_pair(Sub, false);
   
   // Create a new module with this name.
-  Module *Result = new Module(Name, SourceLocation(), Parent,
-                              IsFramework, IsExplicit, NumCreatedModules++);
+  Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
+                              IsExplicit, NumCreatedModules++);
   if (!Parent) {
     if (LangOpts.CurrentModule == Name)
       SourceModule = Result;
@@ -827,7 +839,7 @@
       return;
 
   HeaderList.push_back(KH);
-  Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
+  Mod->Headers[headerRoleToKind(Role)].push_back(Header);
 
   bool isCompilingModuleHeader =
       LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
@@ -1490,6 +1502,42 @@
     ActiveModule->NoUndeclaredIncludes = true;
   ActiveModule->Directory = Directory;
 
+  if (!ActiveModule->Parent) {
+    StringRef MapFileName(ModuleMapFile->getName());
+    if (MapFileName.endswith("module.private.modulemap") ||
+        MapFileName.endswith("module_private.map")) {
+      // Adding a top-level module from a private modulemap is likely a
+      // user error; we check to see if there's another top-level module
+      // defined in the non-private map in the same dir, and if so emit a
+      // warning.
+      for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
+        auto const *M = E->getValue();
+        if (!M->Parent &&
+            M->Directory == ActiveModule->Directory &&
+            M->Name != ActiveModule->Name) {
+          Diags.Report(ActiveModule->DefinitionLoc,
+                       diag::warn_mmap_mismatched_top_level_private)
+            << ActiveModule->Name << M->Name;
+          // The pattern we're defending against here is typically due to
+          // a module named FooPrivate which is supposed to be a submodule
+          // called Foo.Private. Emit a fixit in that case.
+          auto D =
+            Diags.Report(ActiveModule->DefinitionLoc,
+                         diag::note_mmap_rename_top_level_private_as_submodule);
+          D << ActiveModule->Name << M->Name;
+          StringRef Bad(ActiveModule->Name);
+          if (Bad.consume_back("Private")) {
+            SmallString<128> Fixed = Bad;
+            Fixed.append(".Private");
+            D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc,
+                                              Fixed);
+          }
+          break;
+        }
+      }
+    }
+  }
+
   bool Done = false;
   do {
     switch (Tok.Kind) {
@@ -1843,7 +1891,7 @@
       // supplied by Clang. Find that builtin header.
       if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
           BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
-          isBuiltinHeader(Header.FileName)) {
+          ModuleMap::isBuiltinHeader(Header.FileName)) {
         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
         llvm::sys::path::append(BuiltinPathName, Header.FileName);
         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp
index 45bdce3..f5e8cdc 100644
--- a/lib/Lex/PPCaching.cpp
+++ b/lib/Lex/PPCaching.cpp
@@ -35,6 +35,29 @@
   BacktrackPositions.pop_back();
 }
 
+Preprocessor::CachedTokensRange Preprocessor::LastCachedTokenRange() {
+  assert(isBacktrackEnabled());
+  auto PrevCachedLexPos = BacktrackPositions.back();
+  return CachedTokensRange{PrevCachedLexPos, CachedLexPos};
+}
+
+void Preprocessor::EraseCachedTokens(CachedTokensRange TokenRange) {
+  assert(TokenRange.Begin <= TokenRange.End);
+  if (CachedLexPos == TokenRange.Begin && TokenRange.Begin != TokenRange.End) {
+    // We have backtracked to the start of the token range as we want to consume
+    // them again. Erase the tokens only after consuming then.
+    assert(!CachedTokenRangeToErase);
+    CachedTokenRangeToErase = TokenRange;
+    return;
+  }
+  // The cached tokens were committed, so they should be erased now.
+  assert(TokenRange.End == CachedLexPos);
+  CachedTokens.erase(CachedTokens.begin() + TokenRange.Begin,
+                     CachedTokens.begin() + TokenRange.End);
+  CachedLexPos = TokenRange.Begin;
+  ExitCachingLexMode();
+}
+
 // Make Preprocessor re-lex the tokens that were lexed since
 // EnableBacktrackAtThisPos() was previously called.
 void Preprocessor::Backtrack() {
@@ -51,6 +74,13 @@
 
   if (CachedLexPos < CachedTokens.size()) {
     Result = CachedTokens[CachedLexPos++];
+    // Erase the some of the cached tokens after they are consumed when
+    // asked to do so.
+    if (CachedTokenRangeToErase &&
+        CachedTokenRangeToErase->End == CachedLexPos) {
+      EraseCachedTokens(*CachedTokenRangeToErase);
+      CachedTokenRangeToErase = None;
+    }
     return;
   }
 
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 85504de..8a56ddf 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1976,30 +1976,36 @@
       SmallString<128> Path;
       Path.reserve(Name.size()+2);
       Path.push_back(isAngled ? '<' : '"');
+      bool isLeadingSeparator = llvm::sys::path::is_absolute(Name);
       for (auto Component : Components) {
-        Path.append(Component);
+        if (isLeadingSeparator)
+          isLeadingSeparator = false;
+        else
+          Path.append(Component);
         // Append the separator the user used, or the close quote
         Path.push_back(
           Path.size() <= Filename.size() ? Filename[Path.size()-1] :
             (isAngled ? '>' : '"'));
       }
-      auto Replacement = Path.str().str();
       // For user files and known standard headers, by default we issue a diagnostic.
       // For other system headers, we don't. They can be controlled separately.
       auto DiagId = (FileCharacter == SrcMgr::C_User || warnByDefaultOnWrongCase(Name)) ?
           diag::pp_nonportable_path : diag::pp_nonportable_system_path;
       SourceRange Range(FilenameTok.getLocation(), CharEnd);
-      Diag(FilenameTok, DiagId) << Replacement <<
-        FixItHint::CreateReplacement(Range, Replacement);
+      Diag(FilenameTok, DiagId) << Path <<
+        FixItHint::CreateReplacement(Range, Path);
     }
   }
 
   // Ask HeaderInfo if we should enter this #include file.  If not, #including
   // this file will have no effect.
+  bool SkipHeader = false;
   if (ShouldEnter &&
       !HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
+                                         getLangOpts().Modules,
                                          SuggestedModule.getModule())) {
     ShouldEnter = false;
+    SkipHeader = true;
     if (Callbacks)
       Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
   }
@@ -2008,6 +2014,14 @@
   if (!ShouldEnter) {
     // If this is a module import, make it visible if needed.
     if (auto *M = SuggestedModule.getModule()) {
+      // When building a pch, -fmodule-name tells the compiler to textually
+      // include headers in the specified module. But it is possible that
+      // ShouldEnter is false because we are skipping the header. In that
+      // case, We are not importing the specified module.
+      if (SkipHeader && getLangOpts().CompilingPCH &&
+          M->getTopLevelModuleName() == getLangOpts().CurrentModule)
+        return;
+
       makeModuleVisible(M, HashLoc);
 
       if (IncludeTok.getIdentifierInfo()->getPPKeywordID() !=
@@ -2032,6 +2046,13 @@
 
   // Determine if we're switching to building a new submodule, and which one.
   if (auto *M = SuggestedModule.getModule()) {
+    // When building a pch, -fmodule-name tells the compiler to textually
+    // include headers in the specified module. We are not building the
+    // specified module.
+    if (getLangOpts().CompilingPCH &&
+        M->getTopLevelModuleName() == getLangOpts().CurrentModule)
+      return;
+
     assert(!CurSubmodule && "should not have marked this as a module yet");
     CurSubmodule = M;
 
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index f3a57e3..de166c7 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -92,12 +92,35 @@
 }
 
 void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
+                                           MacroDirective *ED,
                                            MacroDirective *MD) {
+  // Normally, when a macro is defined, it goes through appendMacroDirective()
+  // above, which chains a macro to previous defines, undefs, etc.
+  // However, in a pch, the whole macro history up to the end of the pch is
+  // stored, so ASTReader goes through this function instead.
+  // However, built-in macros are already registered in the Preprocessor
+  // ctor, and ASTWriter stops writing the macro chain at built-in macros,
+  // so in that case the chain from the pch needs to be spliced to the existing
+  // built-in.
+
   assert(II && MD);
   MacroState &StoredMD = CurSubmoduleState->Macros[II];
-  assert(!StoredMD.getLatest() &&
-         "the macro history was modified before initializing it from a pch");
-  StoredMD = MD;
+
+  if (auto *OldMD = StoredMD.getLatest()) {
+    // shouldIgnoreMacro() in ASTWriter also stops at macros from the
+    // predefines buffer in module builds. However, in module builds, modules
+    // are loaded completely before predefines are processed, so StoredMD
+    // will be nullptr for them when they're loaded. StoredMD should only be
+    // non-nullptr for builtins read from a pch file.
+    assert(OldMD->getMacroInfo()->isBuiltinMacro() &&
+           "only built-ins should have an entry here");
+    assert(!OldMD->getPrevious() && "builtin should only have a single entry");
+    ED->setPrevious(OldMD);
+    StoredMD.setLatest(MD);
+  } else {
+    StoredMD = MD;
+  }
+
   // Setup the identifier as having associated macro history.
   II->setHasMacroDefinition(true);
   if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
@@ -1160,6 +1183,7 @@
       .Case("cxx_attributes", LangOpts.CPlusPlus11)
       .Case("cxx_auto_type", LangOpts.CPlusPlus11)
       .Case("cxx_constexpr", LangOpts.CPlusPlus11)
+      .Case("cxx_constexpr_string_builtins", LangOpts.CPlusPlus11)
       .Case("cxx_decltype", LangOpts.CPlusPlus11)
       .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
       .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 100da51..f81eaa3 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -160,12 +160,23 @@
 
   ~LexingFor_PragmaRAII() {
     if (InMacroArgPreExpansion) {
+      // When committing/backtracking the cached pragma tokens in a macro
+      // argument pre-expansion we want to ensure that either the tokens which
+      // have been committed will be removed from the cache or that the tokens
+      // over which we just backtracked won't remain in the cache after they're
+      // consumed and that the caching will stop after consuming them.
+      // Otherwise the caching will interfere with the way macro expansion
+      // works, because we will continue to cache tokens after consuming the
+      // backtracked tokens, which shouldn't happen when we're dealing with
+      // macro argument pre-expansion.
+      auto CachedTokenRange = PP.LastCachedTokenRange();
       if (Failed) {
         PP.CommitBacktrackedTokens();
       } else {
         PP.Backtrack();
         OutTok = PragmaTok;
       }
+      PP.EraseCachedTokens(CachedTokenRange);
     }
   }
 
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 0f7473b..91319be 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -68,7 +68,7 @@
 //===----------------------------------------------------------------------===//
 ExternalPreprocessorSource::~ExternalPreprocessorSource() { }
 
-Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
+Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
                            DiagnosticsEngine &diags, LangOptions &opts,
                            SourceManager &SM, HeaderSearch &Headers,
                            ModuleLoader &TheModuleLoader,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index ea7ab26..226e261 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -177,8 +177,12 @@
       if (!ClassStack.empty() && !LateAttrs->parseSoon())
         getCurrentClass().LateParsedDeclarations.push_back(LA);
 
-      // consume everything up to and including the matching right parens
-      ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false);
+      // Be sure ConsumeAndStoreUntil doesn't see the start l_paren, since it
+      // recursively consumes balanced parens.
+      LA->Toks.push_back(Tok);
+      ConsumeParen();
+      // Consume everything up to and including the matching right parens.
+      ConsumeAndStoreUntil(tok::r_paren, LA->Toks, /*StopAtSemi=*/true);
 
       Token Eof;
       Eof.startToken();
@@ -302,10 +306,11 @@
 
     // Parse the non-empty comma-separated list of expressions.
     do {
-      bool ShouldEnter = attributeParsedArgsUnevaluated(*AttrName);
+      bool Uneval = attributeParsedArgsUnevaluated(*AttrName);
       EnterExpressionEvaluationContext Unevaluated(
-          Actions, Sema::Unevaluated, /*LambdaContextDecl=*/nullptr,
-          /*IsDecltype=*/false, ShouldEnter);
+          Actions, Uneval ? Sema::Unevaluated : Sema::ConstantEvaluated,
+          /*LambdaContextDecl=*/nullptr,
+          /*IsDecltype=*/false);
 
       ExprResult ArgExpr(
           Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
@@ -351,6 +356,10 @@
     ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
                                ScopeLoc, Syntax);
     return;
+  } else if (AttrKind == AttributeList::AT_ExternalSourceSymbol) {
+    ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+                                       ScopeName, ScopeLoc, Syntax);
+    return;
   } else if (AttrKind == AttributeList::AT_ObjCBridgeRelated) {
     ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
                                     ScopeName, ScopeLoc, Syntax);
@@ -384,6 +393,25 @@
                            ScopeLoc, Syntax);
 }
 
+unsigned Parser::ParseClangAttributeArgs(
+    IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
+    SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
+  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
+
+  AttributeList::Kind AttrKind =
+      AttributeList::getKind(AttrName, ScopeName, Syntax);
+
+  if (AttrKind == AttributeList::AT_ExternalSourceSymbol) {
+    ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+                                       ScopeName, ScopeLoc, Syntax);
+    return Attrs.getList() ? Attrs.getList()->getNumArgs() : 0;
+  }
+
+  return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
+                                  ScopeName, ScopeLoc, Syntax);
+}
+
 bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
                                         SourceLocation AttrNameLoc,
                                         ParsedAttributes &Attrs) {
@@ -1059,6 +1087,119 @@
                Syntax, StrictLoc, ReplacementExpr.get());
 }
 
+/// \brief Parse the contents of the "external_source_symbol" attribute.
+///
+/// external-source-symbol-attribute:
+///   'external_source_symbol' '(' keyword-arg-list ')'
+///
+/// keyword-arg-list:
+///   keyword-arg
+///   keyword-arg ',' keyword-arg-list
+///
+/// keyword-arg:
+///   'language' '=' <string>
+///   'defined_in' '=' <string>
+///   'generated_declaration'
+void Parser::ParseExternalSourceSymbolAttribute(
+    IdentifierInfo &ExternalSourceSymbol, SourceLocation Loc,
+    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
+    SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
+  // Opening '('.
+  BalancedDelimiterTracker T(*this, tok::l_paren);
+  if (T.expectAndConsume())
+    return;
+
+  // Initialize the pointers for the keyword identifiers when required.
+  if (!Ident_language) {
+    Ident_language = PP.getIdentifierInfo("language");
+    Ident_defined_in = PP.getIdentifierInfo("defined_in");
+    Ident_generated_declaration = PP.getIdentifierInfo("generated_declaration");
+  }
+
+  ExprResult Language;
+  bool HasLanguage = false;
+  ExprResult DefinedInExpr;
+  bool HasDefinedIn = false;
+  IdentifierLoc *GeneratedDeclaration = nullptr;
+
+  // Parse the language/defined_in/generated_declaration keywords
+  do {
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_external_source_symbol_expected_keyword);
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return;
+    }
+
+    SourceLocation KeywordLoc = Tok.getLocation();
+    IdentifierInfo *Keyword = Tok.getIdentifierInfo();
+    if (Keyword == Ident_generated_declaration) {
+      if (GeneratedDeclaration) {
+        Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
+        SkipUntil(tok::r_paren, StopAtSemi);
+        return;
+      }
+      GeneratedDeclaration = ParseIdentifierLoc();
+      continue;
+    }
+
+    if (Keyword != Ident_language && Keyword != Ident_defined_in) {
+      Diag(Tok, diag::err_external_source_symbol_expected_keyword);
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return;
+    }
+
+    ConsumeToken();
+    if (ExpectAndConsume(tok::equal, diag::err_expected_after,
+                         Keyword->getName())) {
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return;
+    }
+
+    bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn;
+    if (Keyword == Ident_language)
+      HasLanguage = true;
+    else
+      HasDefinedIn = true;
+
+    if (Tok.isNot(tok::string_literal)) {
+      Diag(Tok, diag::err_expected_string_literal)
+          << /*Source='external_source_symbol attribute'*/ 3
+          << /*language | source container*/ (Keyword != Ident_language);
+      SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
+      continue;
+    }
+    if (Keyword == Ident_language) {
+      if (HadLanguage) {
+        Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
+            << Keyword;
+        ParseStringLiteralExpression();
+        continue;
+      }
+      Language = ParseStringLiteralExpression();
+    } else {
+      assert(Keyword == Ident_defined_in && "Invalid clause keyword!");
+      if (HadDefinedIn) {
+        Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
+            << Keyword;
+        ParseStringLiteralExpression();
+        continue;
+      }
+      DefinedInExpr = ParseStringLiteralExpression();
+    }
+  } while (TryConsumeToken(tok::comma));
+
+  // Closing ')'.
+  if (T.consumeClose())
+    return;
+  if (EndLoc)
+    *EndLoc = T.getCloseLocation();
+
+  ArgsUnion Args[] = {Language.get(), DefinedInExpr.get(),
+                      GeneratedDeclaration};
+  Attrs.addNew(&ExternalSourceSymbol, SourceRange(Loc, T.getCloseLocation()),
+               ScopeName, ScopeLoc, Args, llvm::array_lengthof(Args), Syntax);
+}
+
 /// \brief Parse the contents of the "objc_bridge_related" attribute.
 /// objc_bridge_related '(' related_class ',' opt-class_method ',' opt-instance_method ')'
 /// related_class:
@@ -1506,7 +1647,6 @@
   ObjCDeclContextSwitch ObjCDC(*this);
 
   Decl *SingleDecl = nullptr;
-  Decl *OwnedType = nullptr;
   switch (Tok.getKind()) {
   case tok::kw_template:
   case tok::kw_export:
@@ -1526,9 +1666,8 @@
     ProhibitAttributes(attrs);
     return ParseNamespace(Context, DeclEnd);
   case tok::kw_using:
-    SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
-                                                  DeclEnd, attrs, &OwnedType);
-    break;
+    return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
+                                            DeclEnd, attrs);
   case tok::kw_static_assert:
   case tok::kw__Static_assert:
     ProhibitAttributes(attrs);
@@ -1539,9 +1678,8 @@
   }
 
   // This routine returns a DeclGroup, if the thing we parsed only contains a
-  // single decl, convert it now. Alias declarations can also declare a type;
-  // include that too if it is present.
-  return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType);
+  // single decl, convert it now.
+  return Actions.ConvertDeclToDeclGroup(SingleDecl);
 }
 
 ///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
@@ -1589,7 +1727,7 @@
     DS.complete(TheDecl);
     if (AnonRecord) {
       Decl* decls[] = {AnonRecord, TheDecl};
-      return Actions.BuildDeclaratorGroup(decls, /*TypeMayContainAuto=*/false);
+      return Actions.BuildDeclaratorGroup(decls);
     }
     return Actions.ConvertDeclToDeclGroup(TheDecl);
   }
@@ -2043,8 +2181,6 @@
     }
   }
 
-  bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
-
   // Parse declarator '=' initializer.
   // If a '==' or '+=' is found, suggest a fixit to '='.
   if (isTokenEqualOrEqualTypo()) {
@@ -2104,7 +2240,7 @@
         Actions.ActOnInitializerError(ThisDecl);
       } else
         Actions.AddInitializerToDecl(ThisDecl, Init.get(),
-                                     /*DirectInit=*/false, TypeContainsAuto);
+                                     /*DirectInit=*/false);
     }
   } else if (Tok.is(tok::l_paren)) {
     // Parse C++ direct initializer: '(' expression-list ')'
@@ -2147,7 +2283,7 @@
                                                           T.getCloseLocation(),
                                                           Exprs);
       Actions.AddInitializerToDecl(ThisDecl, Initializer.get(),
-                                   /*DirectInit=*/true, TypeContainsAuto);
+                                   /*DirectInit=*/true);
     }
   } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&
              (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
@@ -2169,11 +2305,10 @@
     if (Init.isInvalid()) {
       Actions.ActOnInitializerError(ThisDecl);
     } else
-      Actions.AddInitializerToDecl(ThisDecl, Init.get(),
-                                   /*DirectInit=*/true, TypeContainsAuto);
+      Actions.AddInitializerToDecl(ThisDecl, Init.get(), /*DirectInit=*/true);
 
   } else {
-    Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
+    Actions.ActOnUninitializedDecl(ThisDecl);
   }
 
   Actions.FinalizeDeclaration(ThisDecl);
@@ -2825,44 +2960,23 @@
             ->Kind == TNK_Type_template) {
         // We have a qualified template-id, e.g., N::A<int>
 
-        // C++ [class.qual]p2:
-        //   In a lookup in which the constructor is an acceptable lookup
-        //   result and the nested-name-specifier nominates a class C:
+        // If this would be a valid constructor declaration with template
+        // arguments, we will reject the attempt to form an invalid type-id
+        // referring to the injected-class-name when we annotate the token,
+        // per C++ [class.qual]p2.
         //
-        //     - if the name specified after the
-        //       nested-name-specifier, when looked up in C, is the
-        //       injected-class-name of C (Clause 9), or
-        //
-        //     - if the name specified after the nested-name-specifier
-        //       is the same as the identifier or the
-        //       simple-template-id's template-name in the last
-        //       component of the nested-name-specifier,
-        //
-        //   the name is instead considered to name the constructor of
-        //   class C.
-        //
-        // Thus, if the template-name is actually the constructor
-        // name, then the code is ill-formed; this interpretation is
-        // reinforced by the NAD status of core issue 635.
+        // To improve diagnostics for this case, parse the declaration as a
+        // constructor (and reject the extra template arguments later).
         TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
         if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
             TemplateId->Name &&
-            Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
-          if (isConstructorDeclarator(/*Unqualified*/false)) {
-            // The user meant this to be an out-of-line constructor
-            // definition, but template arguments are not allowed
-            // there.  Just allow this as a constructor; we'll
-            // complain about it later.
-            goto DoneWithDeclSpec;
-          }
-
-          // The user meant this to name a type, but it actually names
-          // a constructor with some extraneous template
-          // arguments. Complain, then parse it as a type as the user
-          // intended.
-          Diag(TemplateId->TemplateNameLoc,
-               diag::err_out_of_line_template_id_type_names_constructor)
-            << TemplateId->Name << 0 /* template name */;
+            Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS) &&
+            isConstructorDeclarator(/*Unqualified*/false)) {
+          // The user meant this to be an out-of-line constructor
+          // definition, but template arguments are not allowed
+          // there.  Just allow this as a constructor; we'll
+          // complain about it later.
+          goto DoneWithDeclSpec;
         }
 
         DS.getTypeSpecScope() = SS;
@@ -2893,30 +3007,21 @@
       if (Next.isNot(tok::identifier))
         goto DoneWithDeclSpec;
 
-      // If we're in a context where the identifier could be a class name,
-      // check whether this is a constructor declaration.
+      // Check whether this is a constructor declaration. If we're in a
+      // context where the identifier could be a class name, and it has the
+      // shape of a constructor declaration, process it as one.
       if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
           Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
-                                     &SS)) {
-        if (isConstructorDeclarator(/*Unqualified*/false))
-          goto DoneWithDeclSpec;
-
-        // As noted in C++ [class.qual]p2 (cited above), when the name
-        // of the class is qualified in a context where it could name
-        // a constructor, its a constructor name. However, we've
-        // looked at the declarator, and the user probably meant this
-        // to be a type. Complain that it isn't supposed to be treated
-        // as a type, then proceed to parse it as a type.
-        Diag(Next.getLocation(),
-             diag::err_out_of_line_template_id_type_names_constructor)
-          << Next.getIdentifierInfo() << 1 /* type */;
-      }
+                                     &SS) &&
+          isConstructorDeclarator(/*Unqualified*/ false))
+        goto DoneWithDeclSpec;
 
       ParsedType TypeRep =
           Actions.getTypeName(*Next.getIdentifierInfo(), Next.getLocation(),
                               getCurScope(), &SS, false, false, nullptr,
                               /*IsCtorOrDtorName=*/false,
-                              /*NonTrivialSourceInfo=*/true);
+                              /*WantNonTrivialSourceInfo=*/true,
+                              isClassTemplateDeductionContext(DSContext));
 
       // If the referenced identifier is not a type, then this declspec is
       // erroneous: We already checked about that it has no type specifier, and
@@ -2997,6 +3102,31 @@
       if (DS.hasTypeSpecifier())
         goto DoneWithDeclSpec;
 
+      // If the token is an identifier named "__declspec" and Microsoft
+      // extensions are not enabled, it is likely that there will be cascading
+      // parse errors if this really is a __declspec attribute. Attempt to
+      // recognize that scenario and recover gracefully.
+      if (!getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
+          Tok.getIdentifierInfo()->getName().equals("__declspec")) {
+        Diag(Loc, diag::err_ms_attributes_not_enabled);
+
+        // The next token should be an open paren. If it is, eat the entire
+        // attribute declaration and continue.
+        if (NextToken().is(tok::l_paren)) {
+          // Consume the __declspec identifier.
+          ConsumeToken();
+
+          // Eat the parens and everything between them.
+          BalancedDelimiterTracker T(*this, tok::l_paren);
+          if (T.consumeOpen()) {
+            assert(false && "Not a left paren?");
+            return;
+          }
+          T.skipToEnd();
+          continue;
+        }
+      }
+
       // In C++, check to see if this is a scope specifier like foo::bar::, if
       // so handle it as such.  This is important for ctor parsing.
       if (getLangOpts().CPlusPlus) {
@@ -3030,9 +3160,10 @@
         continue;
       }
 
-      ParsedType TypeRep =
-        Actions.getTypeName(*Tok.getIdentifierInfo(),
-                            Tok.getLocation(), getCurScope());
+      ParsedType TypeRep = Actions.getTypeName(
+          *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), nullptr,
+          false, false, nullptr, false, false,
+          isClassTemplateDeductionContext(DSContext));
 
       // 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.
@@ -3055,6 +3186,16 @@
           isConstructorDeclarator(/*Unqualified*/true))
         goto DoneWithDeclSpec;
 
+      // Likewise, if this is a context where the identifier could be a template
+      // name, check whether this is a deduction guide declaration.
+      if (getLangOpts().CPlusPlus1z &&
+          (DSContext == DSC_class || DSContext == DSC_top_level) &&
+          Actions.isDeductionGuideName(getCurScope(), *Tok.getIdentifierInfo(),
+                                       Tok.getLocation()) &&
+          isConstructorDeclarator(/*Unqualified*/ true,
+                                  /*DeductionGuide*/ true))
+        goto DoneWithDeclSpec;
+
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
                                      DiagID, TypeRep, Policy);
       if (isInvalid)
@@ -4674,7 +4815,7 @@
   }
 }
 
-bool Parser::isConstructorDeclarator(bool IsUnqualified) {
+bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide) {
   TentativeParsingAction TPA(*this);
 
   // Parse the C++ scope specifier.
@@ -4695,6 +4836,10 @@
     return false;
   }
 
+  // There may be attributes here, appertaining to the constructor name or type
+  // we just stepped past.
+  SkipCXX11Attributes();
+
   // Current class name must be followed by a left parenthesis.
   if (Tok.isNot(tok::l_paren)) {
     TPA.Revert();
@@ -4762,13 +4907,24 @@
 
     case tok::r_paren:
       // C(X   )
-      if (NextToken().is(tok::colon) || NextToken().is(tok::kw_try)) {
+
+      // Skip past the right-paren and any following attributes to get to
+      // the function body or trailing-return-type.
+      ConsumeParen();
+      SkipCXX11Attributes();
+
+      if (DeductionGuide) {
+        // C(X) -> ... is a deduction guide.
+        IsConstructor = Tok.is(tok::arrow);
+        break;
+      }
+      if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
         // Assume these were meant to be constructors:
         //   C(X)   :    (the name of a bit-field cannot be parenthesized).
         //   C(X)   try  (this is otherwise ill-formed).
         IsConstructor = true;
       }
-      if (NextToken().is(tok::semi) || NextToken().is(tok::l_brace)) {
+      if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
         // If we have a constructor name within the class definition,
         // assume these were meant to be constructors:
         //   C(X)   {
@@ -4779,7 +4935,7 @@
         //
         // FIXME: We can actually do this whether or not the name is qualified,
         // because if it is qualified in this context it must be being used as
-        // a constructor name. However, we do not implement that rule correctly
+        // a constructor name.
         // currently, so we're somewhat conservative here.
         IsConstructor = IsUnqualified;
       }
@@ -4807,9 +4963,10 @@
 ///              [ only if AttReqs & AR_CXX11AttributesParsed ]
 /// Note: vendor can be GNU, MS, etc and can be explicitly controlled via
 /// AttrRequirements bitmask values.
-void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs,
-                                       bool AtomicAllowed,
-                                       bool IdentifierRequired) {
+void Parser::ParseTypeQualifierListOpt(
+    DeclSpec &DS, unsigned AttrReqs, bool AtomicAllowed,
+    bool IdentifierRequired,
+    Optional<llvm::function_ref<void()>> CodeCompletionHandler) {
   if (getLangOpts().CPlusPlus11 && (AttrReqs & AR_CXX11AttributesParsed) &&
       isCXX11AttributeSpecifier()) {
     ParsedAttributesWithRange attrs(AttrFactory);
@@ -4827,7 +4984,10 @@
 
     switch (Tok.getKind()) {
     case tok::code_completion:
-      Actions.CodeCompleteTypeQualifiers(DS);
+      if (CodeCompletionHandler)
+        (*CodeCompletionHandler)();
+      else
+        Actions.CodeCompleteTypeQualifiers(DS);
       return cutOffParsing();
 
     case tok::kw_const:
@@ -5310,21 +5470,29 @@
       // We found something that indicates the start of an unqualified-id.
       // Parse that unqualified-id.
       bool AllowConstructorName;
-      if (D.getDeclSpec().hasTypeSpecifier())
+      bool AllowDeductionGuide;
+      if (D.getDeclSpec().hasTypeSpecifier()) {
         AllowConstructorName = false;
-      else if (D.getCXXScopeSpec().isSet())
+        AllowDeductionGuide = false;
+      } else if (D.getCXXScopeSpec().isSet()) {
         AllowConstructorName =
           (D.getContext() == Declarator::FileContext ||
            D.getContext() == Declarator::MemberContext);
-      else
+        AllowDeductionGuide = false;
+      } else {
         AllowConstructorName = (D.getContext() == Declarator::MemberContext);
+        AllowDeductionGuide = 
+          (D.getContext() == Declarator::FileContext ||
+           D.getContext() == Declarator::MemberContext);
+      }
 
       SourceLocation TemplateKWLoc;
       bool HadScope = D.getCXXScopeSpec().isValid();
       if (ParseUnqualifiedId(D.getCXXScopeSpec(),
                              /*EnteringContext=*/true,
                              /*AllowDestructorName=*/true, AllowConstructorName,
-                             nullptr, TemplateKWLoc, D.getName()) ||
+                             AllowDeductionGuide, nullptr, TemplateKWLoc,
+                             D.getName()) ||
           // Once we're past the identifier, if the scope was bad, mark the
           // whole declarator bad.
           D.getCXXScopeSpec().isInvalid()) {
@@ -5745,7 +5913,11 @@
 
       // Parse cv-qualifier-seq[opt].
       ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed,
-                                /*AtomicAllowed*/ false);
+                                /*AtomicAllowed*/ false,
+                                /*IdentifierRequired=*/false,
+                                llvm::function_ref<void()>([&]() {
+                                  Actions.CodeCompleteFunctionQualifiers(DS, D);
+                                }));
       if (!DS.getSourceRange().getEnd().isInvalid()) {
         EndLoc = DS.getSourceRange().getEnd();
         ConstQualifierLoc = DS.getConstSpecLoc();
@@ -5827,6 +5999,21 @@
     }
   }
 
+  // Collect non-parameter declarations from the prototype if this is a function
+  // declaration. They will be moved into the scope of the function. Only do
+  // this in C and not C++, where the decls will continue to live in the
+  // surrounding context.
+  SmallVector<NamedDecl *, 0> DeclsInPrototype;
+  if (getCurScope()->getFlags() & Scope::FunctionDeclarationScope &&
+      !getLangOpts().CPlusPlus) {
+    for (Decl *D : getCurScope()->decls()) {
+      NamedDecl *ND = dyn_cast<NamedDecl>(D);
+      if (!ND || isa<ParmVarDecl>(ND))
+        continue;
+      DeclsInPrototype.push_back(ND);
+    }
+  }
+
   // Remember that we parsed a function type, and remember the attributes.
   D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
                                              IsAmbiguous,
@@ -5846,6 +6033,7 @@
                                              NoexceptExpr.isUsable() ?
                                                NoexceptExpr.get() : nullptr,
                                              ExceptionSpecTokens,
+                                             DeclsInPrototype,
                                              StartLoc, LocalEndLoc, D,
                                              TrailingReturnType),
                 FnAttrs, EndLoc);
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 332735a..618c8ab 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -421,11 +421,11 @@
 
 /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
 /// using-directive. Assumes that current token is 'using'.
-Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
+Parser::DeclGroupPtrTy
+Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
                                          const ParsedTemplateInfo &TemplateInfo,
-                                               SourceLocation &DeclEnd,
-                                             ParsedAttributesWithRange &attrs,
-                                               Decl **OwnedType) {
+                                         SourceLocation &DeclEnd,
+                                         ParsedAttributesWithRange &attrs) {
   assert(Tok.is(tok::kw_using) && "Not using token");
   ObjCDeclContextSwitch ObjCDC(*this);
   
@@ -447,7 +447,8 @@
         << 0 /* directive */ << R << FixItHint::CreateRemoval(R);
     }
 
-    return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
+    Decl *UsingDir = ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
+    return Actions.ConvertDeclToDeclGroup(UsingDir);
   }
 
   // Otherwise, it must be a using-declaration or an alias-declaration.
@@ -456,7 +457,7 @@
   ProhibitAttributes(attrs);
 
   return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
-                                    AS_none, OwnedType);
+                               AS_none);
 }
 
 /// ParseUsingDirective - Parse C++ using-directive, assumes
@@ -522,58 +523,31 @@
                                      IdentLoc, NamespcName, attrs.getList());
 }
 
-/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
-/// Assumes that 'using' was already seen.
+/// Parse a using-declarator (or the identifier in a C++11 alias-declaration).
 ///
-///     using-declaration: [C++ 7.3.p3: namespace.udecl]
-///       'using' 'typename'[opt] ::[opt] nested-name-specifier
-///               unqualified-id
-///       'using' :: unqualified-id
+///     using-declarator:
+///       'typename'[opt] nested-name-specifier unqualified-id
 ///
-///     alias-declaration: C++11 [dcl.dcl]p1
-///       'using' identifier attribute-specifier-seq[opt] = type-id ;
-///
-Decl *Parser::ParseUsingDeclaration(unsigned Context,
-                                    const ParsedTemplateInfo &TemplateInfo,
-                                    SourceLocation UsingLoc,
-                                    SourceLocation &DeclEnd,
-                                    AccessSpecifier AS,
-                                    Decl **OwnedType) {
-  CXXScopeSpec SS;
-  SourceLocation TypenameLoc;
-  bool HasTypenameKeyword = false;
-
-  // Check for misplaced attributes before the identifier in an
-  // alias-declaration.
-  ParsedAttributesWithRange MisplacedAttrs(AttrFactory);
-  MaybeParseCXX11Attributes(MisplacedAttrs);
+bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) {
+  D.clear();
 
   // Ignore optional 'typename'.
   // FIXME: This is wrong; we should parse this as a typename-specifier.
-  if (TryConsumeToken(tok::kw_typename, TypenameLoc))
-    HasTypenameKeyword = true;
+  TryConsumeToken(tok::kw_typename, D.TypenameLoc);
 
   if (Tok.is(tok::kw___super)) {
     Diag(Tok.getLocation(), diag::err_super_in_using_declaration);
-    SkipUntil(tok::semi);
-    return nullptr;
+    return true;
   }
 
   // Parse nested-name-specifier.
   IdentifierInfo *LastII = nullptr;
-  ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false,
+  ParseOptionalCXXScopeSpecifier(D.SS, nullptr, /*EnteringContext=*/false,
                                  /*MayBePseudoDtor=*/nullptr,
                                  /*IsTypename=*/false,
                                  /*LastII=*/&LastII);
-
-  // Check nested-name specifier.
-  if (SS.isInvalid()) {
-    SkipUntil(tok::semi);
-    return nullptr;
-  }
-
-  SourceLocation TemplateKWLoc;
-  UnqualifiedId Name;
+  if (D.SS.isInvalid())
+    return true;
 
   // Parse the unqualified-id. We allow parsing of both constructor and
   // destructor names and allow the action module to diagnose any semantic
@@ -586,32 +560,75 @@
   //   nested-name-specifier, the name is [...] considered to name the
   //   constructor.
   if (getLangOpts().CPlusPlus11 && Context == Declarator::MemberContext &&
-      Tok.is(tok::identifier) && NextToken().is(tok::semi) &&
-      SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() &&
-      !SS.getScopeRep()->getAsNamespace() &&
-      !SS.getScopeRep()->getAsNamespaceAlias()) {
+      Tok.is(tok::identifier) &&
+      (NextToken().is(tok::semi) || NextToken().is(tok::comma) ||
+       NextToken().is(tok::ellipsis)) &&
+      D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() &&
+      !D.SS.getScopeRep()->getAsNamespace() &&
+      !D.SS.getScopeRep()->getAsNamespaceAlias()) {
     SourceLocation IdLoc = ConsumeToken();
-    ParsedType Type = Actions.getInheritingConstructorName(SS, IdLoc, *LastII);
-    Name.setConstructorName(Type, IdLoc, IdLoc);
-  } else if (ParseUnqualifiedId(
-                 SS, /*EnteringContext=*/false,
-                 /*AllowDestructorName=*/true,
-                 /*AllowConstructorName=*/!(Tok.is(tok::identifier) &&
-                                            NextToken().is(tok::equal)),
-                 nullptr, TemplateKWLoc, Name)) {
-    SkipUntil(tok::semi);
-    return nullptr;
+    ParsedType Type =
+        Actions.getInheritingConstructorName(D.SS, IdLoc, *LastII);
+    D.Name.setConstructorName(Type, IdLoc, IdLoc);
+  } else {
+    if (ParseUnqualifiedId(
+            D.SS, /*EnteringContext=*/false,
+            /*AllowDestructorName=*/true,
+            /*AllowConstructorName=*/!(Tok.is(tok::identifier) &&
+                                       NextToken().is(tok::equal)),
+            /*AllowDeductionGuide=*/false,
+            nullptr, D.TemplateKWLoc, D.Name))
+      return true;
   }
 
+  if (TryConsumeToken(tok::ellipsis, D.EllipsisLoc))
+    Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z ?
+         diag::warn_cxx1z_compat_using_declaration_pack :
+         diag::ext_using_declaration_pack);
+
+  return false;
+}
+
+/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
+/// Assumes that 'using' was already seen.
+///
+///     using-declaration: [C++ 7.3.p3: namespace.udecl]
+///       'using' using-declarator-list[opt] ;
+///
+///     using-declarator-list: [C++1z]
+///       using-declarator '...'[opt]
+///       using-declarator-list ',' using-declarator '...'[opt]
+///
+///     using-declarator-list: [C++98-14]
+///       using-declarator
+///
+///     alias-declaration: C++11 [dcl.dcl]p1
+///       'using' identifier attribute-specifier-seq[opt] = type-id ;
+///
+Parser::DeclGroupPtrTy
+Parser::ParseUsingDeclaration(unsigned Context,
+                              const ParsedTemplateInfo &TemplateInfo,
+                              SourceLocation UsingLoc, SourceLocation &DeclEnd,
+                              AccessSpecifier AS) {
+  // Check for misplaced attributes before the identifier in an
+  // alias-declaration.
+  ParsedAttributesWithRange MisplacedAttrs(AttrFactory);
+  MaybeParseCXX11Attributes(MisplacedAttrs);
+
+  UsingDeclarator D;
+  bool InvalidDeclarator = ParseUsingDeclarator(Context, D);
+
   ParsedAttributesWithRange Attrs(AttrFactory);
   MaybeParseGNUAttributes(Attrs);
   MaybeParseCXX11Attributes(Attrs);
 
   // Maybe this is an alias-declaration.
-  TypeResult TypeAlias;
-  bool IsAliasDecl = Tok.is(tok::equal);
-  Decl *DeclFromDeclSpec = nullptr;
-  if (IsAliasDecl) {
+  if (Tok.is(tok::equal)) {
+    if (InvalidDeclarator) {
+      SkipUntil(tok::semi);
+      return nullptr;
+    }
+
     // If we had any misplaced attributes from earlier, this is where they
     // should have been written.
     if (MisplacedAttrs.Range.isValid()) {
@@ -623,76 +640,21 @@
       Attrs.takeAllFrom(MisplacedAttrs);
     }
 
-    ConsumeToken();
-
-    Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ?
-         diag::warn_cxx98_compat_alias_declaration :
-         diag::ext_alias_declaration);
-
-    // Type alias templates cannot be specialized.
-    int SpecKind = -1;
-    if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
-        Name.getKind() == UnqualifiedId::IK_TemplateId)
-      SpecKind = 0;
-    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
-      SpecKind = 1;
-    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
-      SpecKind = 2;
-    if (SpecKind != -1) {
-      SourceRange Range;
-      if (SpecKind == 0)
-        Range = SourceRange(Name.TemplateId->LAngleLoc,
-                            Name.TemplateId->RAngleLoc);
-      else
-        Range = TemplateInfo.getSourceRange();
-      Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
-        << SpecKind << Range;
-      SkipUntil(tok::semi);
-      return nullptr;
-    }
-
-    // Name must be an identifier.
-    if (Name.getKind() != UnqualifiedId::IK_Identifier) {
-      Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier);
-      // No removal fixit: can't recover from this.
-      SkipUntil(tok::semi);
-      return nullptr;
-    } else if (HasTypenameKeyword)
-      Diag(TypenameLoc, diag::err_alias_declaration_not_identifier)
-        << FixItHint::CreateRemoval(SourceRange(TypenameLoc,
-                             SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc));
-    else if (SS.isNotEmpty())
-      Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
-        << FixItHint::CreateRemoval(SS.getRange());
-
-    TypeAlias = ParseTypeName(nullptr, TemplateInfo.Kind
-                                           ? Declarator::AliasTemplateContext
-                                           : Declarator::AliasDeclContext,
-                              AS, &DeclFromDeclSpec, &Attrs);
-    if (OwnedType)
-      *OwnedType = DeclFromDeclSpec;
-  } else {
-    // C++11 attributes are not allowed on a using-declaration, but GNU ones
-    // are.
-    ProhibitAttributes(MisplacedAttrs);
-    ProhibitAttributes(Attrs);
-
-    // Parse (optional) attributes (most likely GNU strong-using extension).
-    MaybeParseGNUAttributes(Attrs);
+    Decl *DeclFromDeclSpec = nullptr;
+    Decl *AD = ParseAliasDeclarationAfterDeclarator(
+        TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec);
+    return Actions.ConvertDeclToDeclGroup(AD, DeclFromDeclSpec);
   }
 
-  // Eat ';'.
-  DeclEnd = Tok.getLocation();
-  if (ExpectAndConsume(tok::semi, diag::err_expected_after,
-                       !Attrs.empty() ? "attributes list"
-                                      : IsAliasDecl ? "alias declaration"
-                                                    : "using declaration"))
-    SkipUntil(tok::semi);
+  // C++11 attributes are not allowed on a using-declaration, but GNU ones
+  // are.
+  ProhibitAttributes(MisplacedAttrs);
+  ProhibitAttributes(Attrs);
 
   // Diagnose an attempt to declare a templated using-declaration.
   // In C++11, alias-declarations can be templates:
   //   template <...> using id = type;
-  if (TemplateInfo.Kind && !IsAliasDecl) {
+  if (TemplateInfo.Kind) {
     SourceRange R = TemplateInfo.getSourceRange();
     Diag(UsingLoc, diag::err_templated_using_directive_declaration)
       << 1 /* declaration */ << R << FixItHint::CreateRemoval(R);
@@ -703,29 +665,131 @@
     return nullptr;
   }
 
-  // "typename" keyword is allowed for identifiers only,
-  // because it may be a type definition.
-  if (HasTypenameKeyword && Name.getKind() != UnqualifiedId::IK_Identifier) {
-    Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only)
-      << FixItHint::CreateRemoval(SourceRange(TypenameLoc));
-    // Proceed parsing, but reset the HasTypenameKeyword flag.
-    HasTypenameKeyword = false;
+  SmallVector<Decl *, 8> DeclsInGroup;
+  while (true) {
+    // Parse (optional) attributes (most likely GNU strong-using extension).
+    MaybeParseGNUAttributes(Attrs);
+
+    if (InvalidDeclarator)
+      SkipUntil(tok::comma, tok::semi, StopBeforeMatch);
+    else {
+      // "typename" keyword is allowed for identifiers only,
+      // because it may be a type definition.
+      if (D.TypenameLoc.isValid() &&
+          D.Name.getKind() != UnqualifiedId::IK_Identifier) {
+        Diag(D.Name.getSourceRange().getBegin(),
+             diag::err_typename_identifiers_only)
+            << FixItHint::CreateRemoval(SourceRange(D.TypenameLoc));
+        // Proceed parsing, but discard the typename keyword.
+        D.TypenameLoc = SourceLocation();
+      }
+
+      Decl *UD = Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc,
+                                               D.TypenameLoc, D.SS, D.Name,
+                                               D.EllipsisLoc, Attrs.getList());
+      if (UD)
+        DeclsInGroup.push_back(UD);
+    }
+
+    if (!TryConsumeToken(tok::comma))
+      break;
+
+    // Parse another using-declarator.
+    Attrs.clear();
+    InvalidDeclarator = ParseUsingDeclarator(Context, D);
   }
 
-  if (IsAliasDecl) {
-    TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
-    MultiTemplateParamsArg TemplateParamsArg(
-      TemplateParams ? TemplateParams->data() : nullptr,
-      TemplateParams ? TemplateParams->size() : 0);
-    return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
-                                         UsingLoc, Name, Attrs.getList(),
-                                         TypeAlias, DeclFromDeclSpec);
+  if (DeclsInGroup.size() > 1)
+    Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z ?
+         diag::warn_cxx1z_compat_multi_using_declaration :
+         diag::ext_multi_using_declaration);
+
+  // Eat ';'.
+  DeclEnd = Tok.getLocation();
+  if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+                       !Attrs.empty() ? "attributes list"
+                                      : "using declaration"))
+    SkipUntil(tok::semi);
+
+  return Actions.BuildDeclaratorGroup(DeclsInGroup);
+}
+
+Decl *Parser::ParseAliasDeclarationAfterDeclarator(
+    const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
+    UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,
+    ParsedAttributes &Attrs, Decl **OwnedType) {
+  if (ExpectAndConsume(tok::equal)) {
+    SkipUntil(tok::semi);
+    return nullptr;
   }
 
-  return Actions.ActOnUsingDeclaration(getCurScope(), AS,
-                                       /* HasUsingKeyword */ true, UsingLoc,
-                                       SS, Name, Attrs.getList(),
-                                       HasTypenameKeyword, TypenameLoc);
+  Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ?
+       diag::warn_cxx98_compat_alias_declaration :
+       diag::ext_alias_declaration);
+
+  // Type alias templates cannot be specialized.
+  int SpecKind = -1;
+  if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
+      D.Name.getKind() == UnqualifiedId::IK_TemplateId)
+    SpecKind = 0;
+  if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
+    SpecKind = 1;
+  if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
+    SpecKind = 2;
+  if (SpecKind != -1) {
+    SourceRange Range;
+    if (SpecKind == 0)
+      Range = SourceRange(D.Name.TemplateId->LAngleLoc,
+                          D.Name.TemplateId->RAngleLoc);
+    else
+      Range = TemplateInfo.getSourceRange();
+    Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
+      << SpecKind << Range;
+    SkipUntil(tok::semi);
+    return nullptr;
+  }
+
+  // Name must be an identifier.
+  if (D.Name.getKind() != UnqualifiedId::IK_Identifier) {
+    Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier);
+    // No removal fixit: can't recover from this.
+    SkipUntil(tok::semi);
+    return nullptr;
+  } else if (D.TypenameLoc.isValid())
+    Diag(D.TypenameLoc, diag::err_alias_declaration_not_identifier)
+        << FixItHint::CreateRemoval(SourceRange(
+               D.TypenameLoc,
+               D.SS.isNotEmpty() ? D.SS.getEndLoc() : D.TypenameLoc));
+  else if (D.SS.isNotEmpty())
+    Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
+      << FixItHint::CreateRemoval(D.SS.getRange());
+  if (D.EllipsisLoc.isValid())
+    Diag(D.EllipsisLoc, diag::err_alias_declaration_pack_expansion)
+      << FixItHint::CreateRemoval(SourceRange(D.EllipsisLoc));
+
+  Decl *DeclFromDeclSpec = nullptr;
+  TypeResult TypeAlias =
+      ParseTypeName(nullptr,
+                    TemplateInfo.Kind ? Declarator::AliasTemplateContext
+                                      : Declarator::AliasDeclContext,
+                    AS, &DeclFromDeclSpec, &Attrs);
+  if (OwnedType)
+    *OwnedType = DeclFromDeclSpec;
+
+  // Eat ';'.
+  DeclEnd = Tok.getLocation();
+  if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+                       !Attrs.empty() ? "attributes list"
+                                      : "alias declaration"))
+    SkipUntil(tok::semi);
+
+  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
+  MultiTemplateParamsArg TemplateParamsArg(
+    TemplateParams ? TemplateParams->data() : nullptr,
+    TemplateParams ? TemplateParams->size() : 0);
+  return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
+                                       UsingLoc, D.Name, Attrs.getList(),
+                                       TypeAlias, DeclFromDeclSpec);
 }
 
 /// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
@@ -1013,7 +1077,7 @@
     TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
     if (TemplateId->Kind == TNK_Type_template ||
         TemplateId->Kind == TNK_Dependent_template_name) {
-      AnnotateTemplateIdTokenAsType();
+      AnnotateTemplateIdTokenAsType(/*IsClassName*/true);
 
       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
       ParsedType Type = getTypeAnnotation(Tok);
@@ -1061,10 +1125,10 @@
 
     // Parse the full template-id, then turn it into a type.
     if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
-                                TemplateName, true))
+                                TemplateName))
       return true;
-    if (TNK == TNK_Dependent_template_name)
-      AnnotateTemplateIdTokenAsType();
+    if (TNK == TNK_Type_template || TNK == TNK_Dependent_template_name)
+      AnnotateTemplateIdTokenAsType(/*IsClassName*/true);
 
     // If we didn't end up with a typename token, there's nothing more we
     // can do.
@@ -1081,10 +1145,11 @@
 
   // We have an identifier; check whether it is actually a type.
   IdentifierInfo *CorrectedII = nullptr;
-  ParsedType Type =
-      Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true, false, nullptr,
-                          /*IsCtorOrDtorName=*/false,
-                          /*NonTrivialTypeSourceInfo=*/true, &CorrectedII);
+  ParsedType Type = Actions.getTypeName(
+      *Id, IdLoc, getCurScope(), &SS, /*IsClassName=*/true, false, nullptr,
+      /*IsCtorOrDtorName=*/false,
+      /*NonTrivialTypeSourceInfo=*/true,
+      /*IsClassTemplateDeductionContext*/ false, &CorrectedII);
   if (!Type) {
     Diag(IdLoc, diag::err_expected_class_name);
     return true;
@@ -1822,6 +1887,10 @@
       ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
   }
 
+  if (!TagOrTempResult.isInvalid())
+    // Delayed proccessing of attributes.
+    Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs.getList());
+
   const char *PrevSpec = nullptr;
   unsigned DiagID;
   bool Result;
@@ -2220,7 +2289,11 @@
 
   // GNU-style and C++11 attributes are not allowed here, but they will be
   // handled by the caller.  Diagnose everything else.
-  ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed, false);
+  ParseTypeQualifierListOpt(
+      DS, AR_NoAttributesParsed, false,
+      /*IdentifierRequired=*/false, llvm::function_ref<void()>([&]() {
+        Actions.CodeCompleteFunctionQualifiers(DS, D, &VS);
+      }));
   D.ExtendWithDeclSpec(DS);
 
   if (D.isFunctionDeclarator()) {
@@ -2362,8 +2435,8 @@
       // Try to parse an unqualified-id.
       SourceLocation TemplateKWLoc;
       UnqualifiedId Name;
-      if (ParseUnqualifiedId(SS, false, true, true, nullptr, TemplateKWLoc,
-                             Name)) {
+      if (ParseUnqualifiedId(SS, false, true, true, false, nullptr,
+                             TemplateKWLoc, Name)) {
         SkipUntil(tok::semi);
         return nullptr;
       }
@@ -2376,10 +2449,9 @@
       }
 
       return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration(
-          getCurScope(), AS,
-          /* HasUsingKeyword */ false, SourceLocation(), SS, Name,
-          /* AttrList */ nullptr,
-          /* HasTypenameKeyword */ false, SourceLocation())));
+          getCurScope(), AS, /*UsingLoc*/ SourceLocation(),
+          /*TypenameLoc*/ SourceLocation(), SS, Name,
+          /*EllipsisLoc*/ SourceLocation(), /*AttrList*/ nullptr)));
     }
   }
 
@@ -2395,9 +2467,10 @@
   if (Tok.is(tok::kw_template)) {
     assert(!TemplateInfo.TemplateParams &&
            "Nested template improperly parsed?");
+    ObjCDeclContextSwitch ObjCDC(*this);
     SourceLocation DeclEnd;
     return DeclGroupPtrTy::make(
-        DeclGroupRef(ParseDeclarationStartingWithTemplate(
+        DeclGroupRef(ParseTemplateDeclarationOrSpecialization(
             Declarator::MemberContext, DeclEnd, AS, AccessAttrs)));
   }
 
@@ -2434,8 +2507,8 @@
     }
     SourceLocation DeclEnd;
     // Otherwise, it must be a using-declaration or an alias-declaration.
-    return DeclGroupPtrTy::make(DeclGroupRef(ParseUsingDeclaration(
-        Declarator::MemberContext, TemplateInfo, UsingLoc, DeclEnd, AS)));
+    return ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo,
+                                 UsingLoc, DeclEnd, AS);
   }
 
   // Hold late-parsed attributes so we can attach a Decl to them later.
@@ -2477,7 +2550,7 @@
     DS.complete(TheDecl);
     if (AnonRecord) {
       Decl* decls[] = {AnonRecord, TheDecl};
-      return Actions.BuildDeclaratorGroup(decls, /*TypeMayContainAuto=*/false);
+      return Actions.BuildDeclaratorGroup(decls);
     }
     return Actions.ConvertDeclToDeclGroup(TheDecl);
   }
@@ -2707,11 +2780,10 @@
       if (Init.isInvalid())
         SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
       else if (ThisDecl)
-        Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(),
-                                     DS.containsPlaceholderType());
+        Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid());
     } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static)
       // No initializer.
-      Actions.ActOnUninitializedDecl(ThisDecl, DS.containsPlaceholderType());
+      Actions.ActOnUninitializedDecl(ThisDecl);
 
     if (ThisDecl) {
       if (!ThisDecl->isInvalidDecl()) {
@@ -2896,56 +2968,50 @@
 Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
     AccessSpecifier &AS, ParsedAttributesWithRange &AccessAttrs,
     DeclSpec::TST TagType, Decl *TagDecl) {
-  if (getLangOpts().MicrosoftExt &&
-      Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
+  switch (Tok.getKind()) {
+  case tok::kw___if_exists:
+  case tok::kw___if_not_exists:
     ParseMicrosoftIfExistsClassDeclaration(TagType, AS);
     return nullptr;
-  }
 
-  // Check for extraneous top-level semicolon.
-  if (Tok.is(tok::semi)) {
+  case tok::semi:
+    // Check for extraneous top-level semicolon.
     ConsumeExtraSemi(InsideStruct, TagType);
     return nullptr;
-  }
 
-  if (Tok.is(tok::annot_pragma_vis)) {
+    // Handle pragmas that can appear as member declarations.
+  case tok::annot_pragma_vis:
     HandlePragmaVisibility();
     return nullptr;
-  }
-
-  if (Tok.is(tok::annot_pragma_pack)) {
+  case tok::annot_pragma_pack:
     HandlePragmaPack();
     return nullptr;
-  }
-
-  if (Tok.is(tok::annot_pragma_align)) {
+  case tok::annot_pragma_align:
     HandlePragmaAlign();
     return nullptr;
-  }
-
-  if (Tok.is(tok::annot_pragma_ms_pointers_to_members)) {
+  case tok::annot_pragma_ms_pointers_to_members:
     HandlePragmaMSPointersToMembers();
     return nullptr;
-  }
-
-  if (Tok.is(tok::annot_pragma_ms_pragma)) {
+  case tok::annot_pragma_ms_pragma:
     HandlePragmaMSPragma();
     return nullptr;
-  }
-
-  if (Tok.is(tok::annot_pragma_ms_vtordisp)) {
+  case tok::annot_pragma_ms_vtordisp:
     HandlePragmaMSVtorDisp();
     return nullptr;
-  }
+  case tok::annot_pragma_dump:
+    HandlePragmaDump();
+    return nullptr;
 
-  // If we see a namespace here, a close brace was missing somewhere.
-  if (Tok.is(tok::kw_namespace)) {
+  case tok::kw_namespace:
+    // If we see a namespace here, a close brace was missing somewhere.
     DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
     return nullptr;
-  }
 
-  AccessSpecifier NewAS = getAccessSpecifierIfPresent();
-  if (NewAS != AS_none) {
+  case tok::kw_public:
+  case tok::kw_protected:
+  case tok::kw_private: {
+    AccessSpecifier NewAS = getAccessSpecifierIfPresent();
+    assert(NewAS != AS_none);
     // Current token is a C++ access specifier.
     AS = NewAS;
     SourceLocation ASLoc = Tok.getLocation();
@@ -2980,12 +3046,13 @@
     return nullptr;
   }
 
-  if (Tok.is(tok::annot_pragma_openmp))
+  case tok::annot_pragma_openmp:
     return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, AccessAttrs, TagType,
                                                       TagDecl);
 
-  // Parse all the comma separated declarators.
-  return ParseCXXClassMemberDeclaration(AS, AccessAttrs.getList());
+  default:
+    return ParseCXXClassMemberDeclaration(AS, AccessAttrs.getList());
+  }
 }
 
 /// ParseCXXMemberSpecification - Parse the class definition.
@@ -3320,7 +3387,7 @@
     TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
     if (TemplateId->Kind == TNK_Type_template ||
         TemplateId->Kind == TNK_Dependent_template_name) {
-      AnnotateTemplateIdTokenAsType();
+      AnnotateTemplateIdTokenAsType(/*IsClassName*/true);
       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
       TemplateTypeTy = getTypeAnnotation(Tok);
     }
@@ -3483,7 +3550,7 @@
           Actions.CheckBooleanCondition(KeywordLoc, NoexceptExpr.get());
       NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
     } else {
-      NoexceptType = EST_None;
+      NoexceptType = EST_BasicNoexcept;
     }
   } else {
     // There is no argument.
@@ -3756,36 +3823,44 @@
     return false;
   }
 
-  if (ScopeName && ScopeName->getName() == "gnu")
+  if (ScopeName && ScopeName->getName() == "gnu") {
     // GNU-scoped attributes have some special cases to handle GNU-specific
     // behaviors.
     ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
                           ScopeLoc, AttributeList::AS_CXX11, nullptr);
-  else {
-    unsigned NumArgs =
+    return true;
+  }
+
+  unsigned NumArgs;
+  // Some Clang-scoped attributes have some special parsing behavior.
+  if (ScopeName && ScopeName->getName() == "clang")
+    NumArgs =
+        ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
+                                ScopeLoc, AttributeList::AS_CXX11);
+  else
+    NumArgs =
         ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
                                  ScopeName, ScopeLoc, AttributeList::AS_CXX11);
-    
-    const AttributeList *Attr = Attrs.getList();
-    if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
-      // If the attribute is a standard or built-in attribute and we are
-      // parsing an argument list, we need to determine whether this attribute
-      // was allowed to have an argument list (such as [[deprecated]]), and how
-      // many arguments were parsed (so we can diagnose on [[deprecated()]]).
-      if (Attr->getMaxArgs() && !NumArgs) {
-        // The attribute was allowed to have arguments, but none were provided
-        // even though the attribute parsed successfully. This is an error.
-        Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
-        Attr->setInvalid(true);
-      } else if (!Attr->getMaxArgs()) {
-        // The attribute parsed successfully, but was not allowed to have any
-        // arguments. It doesn't matter whether any were provided -- the
-        // presence of the argument list (even if empty) is diagnosed.
-        Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
-            << AttrName
-            << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
-        Attr->setInvalid(true);
-      }
+
+  const AttributeList *Attr = Attrs.getList();
+  if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
+    // If the attribute is a standard or built-in attribute and we are
+    // parsing an argument list, we need to determine whether this attribute
+    // was allowed to have an argument list (such as [[deprecated]]), and how
+    // many arguments were parsed (so we can diagnose on [[deprecated()]]).
+    if (Attr->getMaxArgs() && !NumArgs) {
+      // The attribute was allowed to have arguments, but none were provided
+      // even though the attribute parsed successfully. This is an error.
+      Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
+      Attr->setInvalid(true);
+    } else if (!Attr->getMaxArgs()) {
+      // The attribute parsed successfully, but was not allowed to have any
+      // arguments. It doesn't matter whether any were provided -- the
+      // presence of the argument list (even if empty) is diagnosed.
+      Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
+          << AttrName
+          << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
+      Attr->setInvalid(true);
     }
   }
   return true;
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 4b0a834..56c7685 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -198,7 +198,7 @@
   //   An expression is potentially evaluated unless it appears where an
   //   integral constant expression is required (see 5.19) [...].
   // C++98 and C++11 have no such rule, but this is only a defect in C++98.
-  EnterExpressionEvaluationContext Unevaluated(Actions,
+  EnterExpressionEvaluationContext ConstantEvaluated(Actions,
                                                Sema::ConstantEvaluated);
 
   ExprResult LHS(ParseCastExpression(false, false, isTypeCast));
@@ -1652,9 +1652,10 @@
 
       if (Tok.is(tok::code_completion)) {
         // Code completion for a member access expression.
-        Actions.CodeCompleteMemberReferenceExpr(
-            getCurScope(), LHS.get(), OpLoc, OpKind == tok::arrow,
-            ExprStatementTokLoc == LHS.get()->getLocStart());
+        if (Expr *Base = LHS.get())
+          Actions.CodeCompleteMemberReferenceExpr(
+              getCurScope(), Base, OpLoc, OpKind == tok::arrow,
+              ExprStatementTokLoc == Base->getLocStart());
 
         cutOffParsing();
         return ExprError();
@@ -1692,6 +1693,7 @@
                                     /*AllowDestructorName=*/true,
                                     /*AllowConstructorName=*/
                                       getLangOpts().MicrosoftExt, 
+                                    /*AllowDeductionGuide=*/false,
                                     ObjectType, TemplateKWLoc, Name)) {
         (void)Actions.CorrectDelayedTyposInExpr(LHS);
         LHS = ExprError();
@@ -2407,7 +2409,7 @@
       // fold-expressions, we'll need to allow multiple ArgExprs here.
       if (ArgExprs.size() == 1 && isFoldOperator(Tok.getKind()) &&
           NextToken().is(tok::ellipsis))
-        return ParseFoldExpression(Result, T);
+        return ParseFoldExpression(ArgExprs[0], T);
 
       ExprType = SimpleExpr;
       Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
@@ -2751,6 +2753,7 @@
 
   // Parse the block-declarator.
   Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
+  DeclaratorInfo.setFunctionDefinitionKind(FDK_Definition);
   ParseDeclarator(DeclaratorInfo);
 
   MaybeParseGNUAttributes(DeclaratorInfo);
@@ -2789,6 +2792,7 @@
   // Parse the return type if present.
   DeclSpec DS(AttrFactory);
   Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
+  ParamInfo.setFunctionDefinitionKind(FDK_Definition);
   // FIXME: Since the return type isn't actually parsed, it can't be used to
   // fill ParamInfo with an initial valid range, so do it manually.
   ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation()));
@@ -2842,6 +2846,7 @@
                                              /*NumExceptions=*/0,
                                              /*NoexceptExpr=*/nullptr,
                                              /*ExceptionSpecTokens=*/nullptr,
+                                             /*DeclsInPrototype=*/None,
                                              CaretLoc, CaretLoc,
                                              ParamInfo),
                           attrs, CaretLoc);
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 83e6ae4..cb56ebb 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -100,48 +100,6 @@
              /*AtDigraph*/false);
 }
 
-/// \brief Emits an error for a left parentheses after a double colon.
-///
-/// When a '(' is found after a '::', emit an error.  Attempt to fix the token
-/// stream by removing the '(', and the matching ')' if found.
-void Parser::CheckForLParenAfterColonColon() {
-  if (!Tok.is(tok::l_paren))
-    return;
-
-  Token LParen = Tok;
-  Token NextTok = GetLookAheadToken(1);
-  Token StarTok = NextTok;
-  // Check for (identifier or (*identifier
-  Token IdentifierTok = StarTok.is(tok::star) ? GetLookAheadToken(2) : StarTok;
-  if (IdentifierTok.isNot(tok::identifier))
-    return;
-  // Eat the '('.
-  ConsumeParen();
-  Token RParen;
-  RParen.setLocation(SourceLocation());
-  // Do we have a ')' ?
-  NextTok = StarTok.is(tok::star) ? GetLookAheadToken(2) : GetLookAheadToken(1);
-  if (NextTok.is(tok::r_paren)) {
-    RParen = NextTok;
-    // Eat the '*' if it is present.
-    if (StarTok.is(tok::star))
-      ConsumeToken();
-    // Eat the identifier.
-    ConsumeToken();
-    // Add the identifier token back.
-    PP.EnterToken(IdentifierTok);
-    // Add the '*' back if it was present.
-    if (StarTok.is(tok::star))
-      PP.EnterToken(StarTok);
-    // Eat the ')'.
-    ConsumeParen();
-  }
-
-  Diag(LParen.getLocation(), diag::err_paren_after_colon_colon)
-      << FixItHint::CreateRemoval(LParen.getLocation())
-      << FixItHint::CreateRemoval(RParen.getLocation());
-}
-
 /// \brief Parse global scope or nested-name-specifier if present.
 ///
 /// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
@@ -237,8 +195,6 @@
       if (Actions.ActOnCXXGlobalScopeSpecifier(ConsumeToken(), SS))
         return true;
 
-      CheckForLParenAfterColonColon();
-
       HasScopeSpecifier = true;
     }
   }
@@ -260,7 +216,10 @@
     SourceLocation EndLoc  = ParseDecltypeSpecifier(DS);
 
     SourceLocation CCLoc;
-    if (!TryConsumeToken(tok::coloncolon, CCLoc)) {
+    // Work around a standard defect: 'decltype(auto)::' is not a
+    // nested-name-specifier.
+    if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto ||
+        !TryConsumeToken(tok::coloncolon, CCLoc)) {
       AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc);
       return false;
     }
@@ -354,11 +313,9 @@
       // Commit to parsing the template-id.
       TPA.Commit();
       TemplateTy Template;
-      if (TemplateNameKind TNK
-          = Actions.ActOnDependentTemplateName(getCurScope(),
-                                               SS, TemplateKWLoc, TemplateName,
-                                               ObjectType, EnteringContext,
-                                               Template)) {
+      if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName(
+              getCurScope(), SS, TemplateKWLoc, TemplateName, ObjectType,
+              EnteringContext, Template, /*AllowInjectedClassName*/ true)) {
         if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc,
                                     TemplateName, false))
           return true;
@@ -491,8 +448,6 @@
       Token ColonColon = Tok;
       SourceLocation CCLoc = ConsumeToken();
 
-      CheckForLParenAfterColonColon();
-
       bool IsCorrectedToColon = false;
       bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr;
       if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), IdInfo,
@@ -555,12 +510,10 @@
         Diag(Tok.getLocation(), DiagID)
           << II.getName()
           << FixItHint::CreateInsertion(Tok.getLocation(), "template ");
-        
-        if (TemplateNameKind TNK 
-              = Actions.ActOnDependentTemplateName(getCurScope(), 
-                                                   SS, SourceLocation(),
-                                                   TemplateName, ObjectType,
-                                                   EnteringContext, Template)) {
+
+        if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName(
+                getCurScope(), SS, SourceLocation(), TemplateName, ObjectType,
+                EnteringContext, Template, /*AllowInjectedClassName*/ true)) {
           // Consume the identifier.
           ConsumeToken();
           if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
@@ -596,6 +549,7 @@
                          /*EnteringContext=*/false,
                          /*AllowDestructorName=*/false,
                          /*AllowConstructorName=*/false,
+                         /*AllowDeductionGuide=*/false,
                          /*ObjectType=*/nullptr, TemplateKWLoc, Name))
     return ExprError();
 
@@ -781,7 +735,7 @@
 ///        sometimes skip the initializers for init-captures and not fully
 ///        populate \p Intro. This flag will be set to \c true if we do so.
 /// \return A DiagnosticID if it hit something unexpected. The location for
-///         for the diagnostic is that of the current token.
+///         the diagnostic is that of the current token.
 Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
                                                  bool *SkippedInits) {
   typedef Optional<unsigned> DiagResult;
@@ -948,6 +902,8 @@
           SourceLocation StartLoc = Tok.getLocation();
           InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true);
           Init = ParseInitializer();
+          if (!Init.isInvalid())
+            Init = Actions.CorrectDelayedTyposInExpr(Init.get());
 
           if (Tok.getLocation() != StartLoc) {
             // Back out the lexing of the token after the initializer.
@@ -1244,6 +1200,7 @@
                                            NoexceptExpr.isUsable() ?
                                              NoexceptExpr.get() : nullptr,
                                            /*ExceptionSpecTokens*/nullptr,
+                                           /*DeclsInPrototype=*/None,
                                            LParenLoc, FunLocalRangeEnd, D,
                                            TrailingReturnType),
                   Attr, DeclEndLoc);
@@ -1313,6 +1270,7 @@
                                                /*NumExceptions=*/0,
                                                /*NoexceptExpr=*/nullptr,
                                                /*ExceptionSpecTokens=*/nullptr,
+                                               /*DeclsInPrototype=*/None,
                                                DeclLoc, DeclEndLoc, D,
                                                TrailingReturnType),
                   Attr, DeclEndLoc);
@@ -1685,9 +1643,10 @@
 ///         typename-specifier '(' expression-list[opt] ')'
 /// [C++0x] typename-specifier braced-init-list
 ///
+/// In C++1z onwards, the type specifier can also be a template-name.
 ExprResult
 Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
-  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+  Declarator DeclaratorInfo(DS, Declarator::FunctionalCastContext);
   ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
 
   assert((Tok.is(tok::l_paren) ||
@@ -1860,8 +1819,7 @@
   }
 
   if (!InitExpr.isInvalid())
-    Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization,
-                                 DS.containsPlaceholderType());
+    Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization);
   else
     Actions.ActOnInitializerError(DeclOut);
 
@@ -2063,9 +2021,11 @@
   case UnqualifiedId::IK_OperatorFunctionId:
   case UnqualifiedId::IK_LiteralOperatorId:
     if (AssumeTemplateId) {
-      TNK = Actions.ActOnDependentTemplateName(getCurScope(), SS, TemplateKWLoc,
-                                               Id, ObjectType, EnteringContext,
-                                               Template);
+      // We defer the injected-class-name checks until we've found whether
+      // this template-id is used to form a nested-name-specifier or not.
+      TNK = Actions.ActOnDependentTemplateName(
+          getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext,
+          Template, /*AllowInjectedClassName*/ true);
       if (TNK == TNK_Non_template)
         return true;
     } else {
@@ -2094,10 +2054,9 @@
         Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword)
           << Name
           << FixItHint::CreateInsertion(Id.StartLocation, "template ");
-        TNK = Actions.ActOnDependentTemplateName(getCurScope(),
-                                                 SS, TemplateKWLoc, Id,
-                                                 ObjectType, EnteringContext,
-                                                 Template);
+        TNK = Actions.ActOnDependentTemplateName(
+            getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext,
+            Template, /*AllowInjectedClassName*/ true);
         if (TNK == TNK_Non_template)
           return true;              
       }
@@ -2120,10 +2079,9 @@
     bool MemberOfUnknownSpecialization;
     TemplateName.setIdentifier(Name, NameLoc);
     if (ObjectType) {
-      TNK = Actions.ActOnDependentTemplateName(getCurScope(),
-                                               SS, TemplateKWLoc, TemplateName,
-                                               ObjectType, EnteringContext,
-                                               Template);
+      TNK = Actions.ActOnDependentTemplateName(
+          getCurScope(), SS, TemplateKWLoc, TemplateName, ObjectType,
+          EnteringContext, Template, /*AllowInjectedClassName*/ true);
       if (TNK == TNK_Non_template)
         return true;
     } else {
@@ -2198,7 +2156,7 @@
   // Constructor and destructor names.
   TypeResult Type
     = Actions.ActOnTemplateIdType(SS, TemplateKWLoc,
-                                  Template, NameLoc,
+                                  Template, Name, NameLoc,
                                   LAngleLoc, TemplateArgsPtr, RAngleLoc,
                                   /*IsCtorOrDtorName=*/true);
   if (Type.isInvalid())
@@ -2475,6 +2433,8 @@
 ///
 /// \param AllowConstructorName whether we allow parsing a constructor name.
 ///
+/// \param AllowDeductionGuide whether we allow parsing a deduction guide name.
+///
 /// \param ObjectType if this unqualified-id occurs within a member access
 /// expression, the type of the base object whose member is being accessed.
 ///
@@ -2484,6 +2444,7 @@
 bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
                                 bool AllowDestructorName,
                                 bool AllowConstructorName,
+                                bool AllowDeductionGuide,
                                 ParsedType ObjectType,
                                 SourceLocation& TemplateKWLoc,
                                 UnqualifiedId &Result) {
@@ -2512,6 +2473,7 @@
       return false;
     }
 
+    ParsedTemplateTy TemplateName;
     if (AllowConstructorName && 
         Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {
       // We have parsed a constructor name.
@@ -2520,6 +2482,12 @@
                                           /*IsCtorOrDtorName=*/true,
                                           /*NonTrivialTypeSourceInfo=*/true);
       Result.setConstructorName(Ty, IdLoc, IdLoc);
+    } else if (getLangOpts().CPlusPlus1z &&
+               AllowDeductionGuide && SS.isEmpty() &&
+               Actions.isDeductionGuideName(getCurScope(), *Id, IdLoc,
+                                            &TemplateName)) {
+      // We have parsed a template-name naming a deduction guide.
+      Result.setDeductionGuideName(TemplateName, IdLoc);
     } else {
       // We have parsed an identifier.
       Result.setIdentifier(Id, IdLoc);      
@@ -2612,7 +2580,8 @@
     if (SS.isEmpty() && Tok.is(tok::kw_decltype)) {
       DeclSpec DS(AttrFactory);
       SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
-      if (ParsedType Type = Actions.getDestructorType(DS, ObjectType)) {
+      if (ParsedType Type =
+              Actions.getDestructorTypeForDecltype(DS, ObjectType)) {
         Result.setDestructorName(TildeLoc, Type, EndLoc);
         return false;
       }
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index 4a68942..fa6b75d 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -404,6 +404,10 @@
     return Actions.ActOnInitList(LBraceLoc, None, ConsumeBrace());
   }
 
+  // Enter an appropriate expression evaluation context for an initializer list.
+  EnterExpressionEvaluationContext EnterContext(
+      Actions, EnterExpressionEvaluationContext::InitList);
+
   bool InitExprsOk = true;
 
   while (1) {
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index 9c5b54b..574ed6e 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -40,7 +40,8 @@
   OMPD_target_exit,
   OMPD_update,
   OMPD_distribute_parallel,
-  OMPD_teams_distribute_parallel
+  OMPD_teams_distribute_parallel,
+  OMPD_target_teams_distribute_parallel
 };
 
 class ThreadprivateListParserHelper final {
@@ -114,7 +115,13 @@
     { OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd },
     { OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel },
     { OMPD_teams_distribute_parallel, OMPD_for, OMPD_teams_distribute_parallel_for },
-    { OMPD_teams_distribute_parallel_for, OMPD_simd, OMPD_teams_distribute_parallel_for_simd }
+    { OMPD_teams_distribute_parallel_for, OMPD_simd, OMPD_teams_distribute_parallel_for_simd },
+    { OMPD_target, OMPD_teams, OMPD_target_teams },
+    { OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute },
+    { OMPD_target_teams_distribute, OMPD_parallel, OMPD_target_teams_distribute_parallel },
+    { OMPD_target_teams_distribute, OMPD_simd, OMPD_target_teams_distribute_simd },
+    { OMPD_target_teams_distribute_parallel, OMPD_for, OMPD_target_teams_distribute_parallel_for },
+    { OMPD_target_teams_distribute_parallel_for, OMPD_simd, OMPD_target_teams_distribute_parallel_for_simd }
   };
   enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
   auto Tok = P.getCurToken();
@@ -750,6 +757,11 @@
   case OMPD_teams_distribute_simd:
   case OMPD_teams_distribute_parallel_for_simd:
   case OMPD_teams_distribute_parallel_for:
+  case OMPD_target_teams:
+  case OMPD_target_teams_distribute:
+  case OMPD_target_teams_distribute_parallel_for:
+  case OMPD_target_teams_distribute_parallel_for_simd:
+  case OMPD_target_teams_distribute_simd:
     Diag(Tok, diag::err_omp_unexpected_directive)
         << getOpenMPDirectiveName(DKind);
     break;
@@ -786,7 +798,11 @@
 ///         'target parallel for simd' | 'target simd' |
 ///         'teams distribute' | 'teams distribute simd' |
 ///         'teams distribute parallel for simd' |
-///         'teams distribute parallel for' {clause}
+///         'teams distribute parallel for' | 'target teams' |
+///         'target teams distribute' |
+///         'target teams distribute parallel for' |
+///         'target teams distribute parallel for simd' |
+///         'target teams distribute simd' {clause}
 ///         annot_pragma_openmp_end
 ///
 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
@@ -899,7 +915,12 @@
   case OMPD_teams_distribute:
   case OMPD_teams_distribute_simd:
   case OMPD_teams_distribute_parallel_for_simd:
-  case OMPD_teams_distribute_parallel_for: {
+  case OMPD_teams_distribute_parallel_for:
+  case OMPD_target_teams:
+  case OMPD_target_teams_distribute:
+  case OMPD_target_teams_distribute_parallel_for:
+  case OMPD_target_teams_distribute_parallel_for_simd:
+  case OMPD_target_teams_distribute_simd: {
     ConsumeToken();
     // Parse directive name of the 'critical' directive if any.
     if (DKind == OMPD_critical) {
@@ -1032,7 +1053,7 @@
       IsCorrect = false;
       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
                 StopBeforeMatch);
-    } else if (ParseUnqualifiedId(SS, false, false, false, nullptr,
+    } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
                                   TemplateKWLoc, Name)) {
       IsCorrect = false;
       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
@@ -1458,15 +1479,19 @@
   } else {
     assert(Kind == OMPC_if);
     KLoc.push_back(Tok.getLocation());
+    TentativeParsingAction TPA(*this);
     Arg.push_back(ParseOpenMPDirectiveKind(*this));
     if (Arg.back() != OMPD_unknown) {
       ConsumeToken();
-      if (Tok.is(tok::colon))
+      if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
+        TPA.Commit();
         DelimLoc = ConsumeToken();
-      else
-        Diag(Tok, diag::warn_pragma_expected_colon)
-            << "directive name modifier";
-    }
+      } else {
+        TPA.Revert();
+        Arg.back() = OMPD_unknown;
+      }
+    } else
+      TPA.Revert();
   }
 
   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
@@ -1532,8 +1557,9 @@
   }
   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
                               /*AllowDestructorName*/ false,
-                              /*AllowConstructorName*/ false, nullptr,
-                              TemplateKWLoc, ReductionId);
+                              /*AllowConstructorName*/ false,
+                              /*AllowDeductionGuide*/ false,
+                              nullptr, TemplateKWLoc, ReductionId);
 }
 
 /// Parses clauses with list.
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index d6539c9..8973323 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -486,42 +486,50 @@
 }
 
 namespace {
-  typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
+  enum OpenCLExtState : char {
+    Disable, Enable, Begin, End
+  };
+  typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
 }
 
 void Parser::HandlePragmaOpenCLExtension() {
   assert(Tok.is(tok::annot_pragma_opencl_extension));
-  OpenCLExtData data =
-      OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue());
-  unsigned state = data.getInt();
-  IdentifierInfo *ename = data.getPointer();
+  OpenCLExtData *Data = static_cast<OpenCLExtData*>(Tok.getAnnotationValue());
+  auto State = Data->second;
+  auto Ident = Data->first;
   SourceLocation NameLoc = Tok.getLocation();
   ConsumeToken(); // The annotation token.
 
-  OpenCLOptions &f = Actions.getOpenCLOptions();
-  auto CLVer = getLangOpts().OpenCLVersion;
-  auto &Supp = getTargetInfo().getSupportedOpenCLOpts();
+  auto &Opt = Actions.getOpenCLOptions();
+  auto Name = Ident->getName();
   // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
   // overriding all previously issued extension directives, but only if the
   // behavior is set to disable."
-  if (state == 0 && ename->isStr("all")) {
-#define OPENCLEXT(nm) \
-    if (Supp.is_##nm##_supported_extension(CLVer)) \
-      f.nm = 0;
-#include "clang/Basic/OpenCLExtensions.def"
-  }
-#define OPENCLEXT(nm) else if (ename->isStr(#nm)) \
-   if (Supp.is_##nm##_supported_extension(CLVer)) \
-     f.nm = state; \
-   else if (Supp.is_##nm##_supported_core(CLVer)) \
-     PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << ename; \
-   else \
-     PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << ename;
-#include "clang/Basic/OpenCLExtensions.def"
-  else {
-    PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
-    return;
-  }
+  if (Name == "all") {
+    if (State == Disable) {
+      Opt.disableAll();
+      Opt.enableSupportedCore(getLangOpts().OpenCLVersion);
+    } else {
+      PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
+    }
+  } else if (State == Begin) {
+    if (!Opt.isKnown(Name) ||
+        !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
+      Opt.support(Name);
+    }
+    Actions.setCurrentOpenCLExtension(Name);
+  } else if (State == End) {
+    if (Name != Actions.getCurrentOpenCLExtension())
+      PP.Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
+    Actions.setCurrentOpenCLExtension("");
+  } else if (!Opt.isKnown(Name))
+    PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
+  else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
+    Opt.enable(Name, State == Enable);
+  else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
+    PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
+  else
+    PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
 }
 
 void Parser::HandlePragmaMSPointersToMembers() {
@@ -1441,29 +1449,34 @@
       "OPENCL";
     return;
   }
-  IdentifierInfo *ename = Tok.getIdentifierInfo();
+  IdentifierInfo *Ext = Tok.getIdentifierInfo();
   SourceLocation NameLoc = Tok.getLocation();
 
   PP.Lex(Tok);
   if (Tok.isNot(tok::colon)) {
-    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
     return;
   }
 
   PP.Lex(Tok);
   if (Tok.isNot(tok::identifier)) {
-    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
     return;
   }
-  IdentifierInfo *op = Tok.getIdentifierInfo();
+  IdentifierInfo *Pred = Tok.getIdentifierInfo();
 
-  unsigned state;
-  if (op->isStr("enable")) {
-    state = 1;
-  } else if (op->isStr("disable")) {
-    state = 0;
-  } else {
-    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
+  OpenCLExtState State;
+  if (Pred->isStr("enable")) {
+    State = Enable;
+  } else if (Pred->isStr("disable")) {
+    State = Disable;
+  } else if (Pred->isStr("begin"))
+    State = Begin;
+  else if (Pred->isStr("end"))
+    State = End;
+  else {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
+      << Ext->isStr("all");
     return;
   }
   SourceLocation StateLoc = Tok.getLocation();
@@ -1475,19 +1488,21 @@
     return;
   }
 
-  OpenCLExtData data(ename, state);
+  auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
+  Info->first = Ext;
+  Info->second = State;
   MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
                               1);
   Toks[0].startToken();
   Toks[0].setKind(tok::annot_pragma_opencl_extension);
   Toks[0].setLocation(NameLoc);
-  Toks[0].setAnnotationValue(data.getOpaqueValue());
+  Toks[0].setAnnotationValue(static_cast<void*>(Info));
   Toks[0].setAnnotationEndLoc(StateLoc);
   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
 
   if (PP.getPPCallbacks())
-    PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename, 
-                                               StateLoc, state);
+    PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext, 
+                                               StateLoc, State);
 }
 
 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 30e392f..db6ed6f 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -1898,7 +1898,7 @@
     }
   }
   if (IsCoreturn)
-    return Actions.ActOnCoreturnStmt(ReturnLoc, R.get());
+    return Actions.ActOnCoreturnStmt(getCurScope(), ReturnLoc, R.get());
   return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());
 }
 
diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp
index 293de78..85cd22f 100644
--- a/lib/Parse/ParseStmtAsm.cpp
+++ b/lib/Parse/ParseStmtAsm.cpp
@@ -224,6 +224,7 @@
                                  /*EnteringContext=*/false,
                                  /*AllowDestructorName=*/false,
                                  /*AllowConstructorName=*/false,
+                                 /*AllowDeductionGuide=*/false,
                                  /*ObjectType=*/nullptr, TemplateKWLoc, Id);
     // Perform the lookup.
     Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info,
@@ -457,6 +458,11 @@
             break;
           LineNo = SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second);
           SkippedStartOfLine = Tok.isAtStartOfLine();
+        } else if (Tok.is(tok::semi)) {
+          // A multi-line asm-statement, where next line is a comment
+          InAsmComment = true;
+          FID = ExpLoc.first;
+          LineNo = SrcMgr.getLineNumber(FID, ExpLoc.second);
         }
       } else if (!InAsmComment && Tok.is(tok::r_brace)) {
         // In MSVC mode, braces only participate in brace matching and
@@ -615,10 +621,11 @@
                                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());
+  // Filter out "fpsw" and "mxcsr". They aren't valid GCC asm clobber
+  // constraints. Clang always adds fpsr to the clobber list anyway.
+  llvm::erase_if(Clobbers, [](const std::string &C) {
+    return C == "fpsw" || C == "mxcsr";
+  });
 
   // Build the vector of clobber StringRefs.
   ClobberRefs.insert(ClobberRefs.end(), Clobbers.begin(), Clobbers.end());
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 1f54376..f12e3f5 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -196,9 +196,12 @@
   ParsedAttributesWithRange prefixAttrs(AttrFactory);
   MaybeParseCXX11Attributes(prefixAttrs);
 
-  if (Tok.is(tok::kw_using))
-    return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
-                                            prefixAttrs);
+  if (Tok.is(tok::kw_using)) {
+    // FIXME: We should return the DeclGroup to the caller.
+    ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
+                                     prefixAttrs);
+    return nullptr;
+  }
 
   // Parse the declaration specifiers, stealing any diagnostics from
   // the template parameters.
@@ -997,13 +1000,13 @@
 
   // Build the annotation token.
   if (TNK == TNK_Type_template && AllowTypeAnnotation) {
-    TypeResult Type
-      = Actions.ActOnTemplateIdType(SS, TemplateKWLoc,
-                                    Template, TemplateNameLoc,
-                                    LAngleLoc, TemplateArgsPtr, RAngleLoc);
+    TypeResult Type = Actions.ActOnTemplateIdType(
+        SS, TemplateKWLoc, Template, TemplateName.Identifier,
+        TemplateNameLoc, LAngleLoc, TemplateArgsPtr, RAngleLoc);
     if (Type.isInvalid()) {
-      // If we failed to parse the template ID but skipped ahead to a >, we're not
-      // going to be able to form a token annotation.  Eat the '>' if present.
+      // If we failed to parse the template ID but skipped ahead to a >, we're
+      // not going to be able to form a token annotation.  Eat the '>' if
+      // present.
       TryConsumeToken(tok::greater);
       return true;
     }
@@ -1061,7 +1064,12 @@
 /// If there was a failure when forming the type from the template-id,
 /// a type annotation token will still be created, but will have a
 /// NULL type pointer to signify an error.
-void Parser::AnnotateTemplateIdTokenAsType() {
+///
+/// \param IsClassName Is this template-id appearing in a context where we
+/// know it names a class, such as in an elaborated-type-specifier or
+/// base-specifier? ('typename' and 'template' are unneeded and disallowed
+/// in those contexts.)
+void Parser::AnnotateTemplateIdTokenAsType(bool IsClassName) {
   assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens");
 
   TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
@@ -1076,10 +1084,13 @@
     = Actions.ActOnTemplateIdType(TemplateId->SS,
                                   TemplateId->TemplateKWLoc,
                                   TemplateId->Template,
+                                  TemplateId->Name,
                                   TemplateId->TemplateNameLoc,
                                   TemplateId->LAngleLoc,
                                   TemplateArgsPtr,
-                                  TemplateId->RAngleLoc);
+                                  TemplateId->RAngleLoc,
+                                  /*IsCtorOrDtorName*/false,
+                                  IsClassName);
   // Create the new "type" annotation token.
   Tok.setKind(tok::annot_typename);
   setTypeAnnotation(Tok, Type.isInvalid() ? nullptr : Type.get());
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index e97b5e4..7df2e32 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -493,6 +493,8 @@
   Ident_strict = nullptr;
   Ident_replacement = nullptr;
 
+  Ident_language = Ident_defined_in = Ident_generated_declaration = nullptr;
+
   Ident__except = nullptr;
 
   Ident__exception_code = Ident__exception_info = nullptr;
@@ -934,9 +936,11 @@
     Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
                                                        DS, AnonRecord);
     DS.complete(TheDecl);
+    if (getLangOpts().OpenCL)
+      Actions.setCurrentOpenCLExtensionForDecl(TheDecl);
     if (AnonRecord) {
       Decl* decls[] = {AnonRecord, TheDecl};
-      return Actions.BuildDeclaratorGroup(decls, /*TypeMayContainAuto=*/false);
+      return Actions.BuildDeclaratorGroup(decls);
     }
     return Actions.ConvertDeclToDeclGroup(TheDecl);
   }
@@ -1470,8 +1474,7 @@
     return ANK_Error;
 
   if (Tok.isNot(tok::identifier) || SS.isInvalid()) {
-    if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(EnteringContext, false, SS,
-                                                  !WasScopeAnnotation))
+    if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation))
       return ANK_Error;
     return ANK_Unresolved;
   }
@@ -1484,8 +1487,7 @@
   if (isTentativelyDeclared(Name)) {
     // Identifier has been tentatively declared, and thus cannot be resolved as
     // an expression. Fall back to annotating it as a type.
-    if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(EnteringContext, false, SS,
-                                                  !WasScopeAnnotation))
+    if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation))
       return ANK_Error;
     return Tok.is(tok::annot_typename) ? ANK_Success : ANK_TentativeDecl;
   }
@@ -1623,7 +1625,7 @@
 ///
 /// Note that this routine emits an error if you call it with ::new or ::delete
 /// as the current tokens, so only call it in contexts where these are invalid.
-bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
+bool Parser::TryAnnotateTypeOrScopeToken() {
   assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
           Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) ||
           Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) ||
@@ -1640,7 +1642,7 @@
     if (getLangOpts().MSVCCompat && NextToken().is(tok::kw_typedef)) {
       Token TypedefToken;
       PP.Lex(TypedefToken);
-      bool Result = TryAnnotateTypeOrScopeToken(EnteringContext, NeedType);
+      bool Result = TryAnnotateTypeOrScopeToken();
       PP.EnterToken(Tok);
       Tok = TypedefToken;
       if (!Result)
@@ -1665,8 +1667,7 @@
           Tok.is(tok::annot_decltype)) {
         // Attempt to recover by skipping the invalid 'typename'
         if (Tok.is(tok::annot_decltype) ||
-            (!TryAnnotateTypeOrScopeToken(EnteringContext, NeedType) &&
-             Tok.isAnnotation())) {
+            (!TryAnnotateTypeOrScopeToken() && Tok.isAnnotation())) {
           unsigned DiagID = diag::err_expected_qualified_after_typename;
           // MS compatibility: MSVC permits using known types with typename.
           // e.g. "typedef typename T* pointer_type"
@@ -1702,6 +1703,7 @@
       Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS,
                                      TemplateId->TemplateKWLoc,
                                      TemplateId->Template,
+                                     TemplateId->Name,
                                      TemplateId->TemplateNameLoc,
                                      TemplateId->LAngleLoc,
                                      TemplateArgsPtr,
@@ -1726,33 +1728,25 @@
 
   CXXScopeSpec SS;
   if (getLangOpts().CPlusPlus)
-    if (ParseOptionalCXXScopeSpecifier(SS, nullptr, EnteringContext))
+    if (ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext*/false))
       return true;
 
-  return TryAnnotateTypeOrScopeTokenAfterScopeSpec(EnteringContext, NeedType,
-                                                   SS, !WasScopeAnnotation);
+  return TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation);
 }
 
 /// \brief Try to annotate a type or scope token, having already parsed an
 /// optional scope specifier. \p IsNewScope should be \c true unless the scope
 /// specifier was extracted from an existing tok::annot_cxxscope annotation.
-bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext,
-                                                       bool NeedType,
-                                                       CXXScopeSpec &SS,
+bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS,
                                                        bool IsNewScope) {
   if (Tok.is(tok::identifier)) {
-    IdentifierInfo *CorrectedII = nullptr;
     // Determine whether the identifier is a type name.
     if (ParsedType Ty = Actions.getTypeName(
             *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS,
             false, NextToken().is(tok::period), nullptr,
             /*IsCtorOrDtorName=*/false,
             /*NonTrivialTypeSourceInfo*/ true,
-            NeedType ? &CorrectedII : nullptr)) {
-      // A FixIt was applied as a result of typo correction
-      if (CorrectedII)
-        Tok.setIdentifierInfo(CorrectedII);
-
+            /*IsClassTemplateDeductionContext*/GreaterThanIsOperator)) {
       SourceLocation BeginLoc = Tok.getLocation();
       if (SS.isNotEmpty()) // it was a C++ qualified type name.
         BeginLoc = SS.getBeginLoc();
@@ -1801,11 +1795,11 @@
       UnqualifiedId TemplateName;
       TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
       bool MemberOfUnknownSpecialization;
-      if (TemplateNameKind TNK =
-              Actions.isTemplateName(getCurScope(), SS,
-                                     /*hasTemplateKeyword=*/false, TemplateName,
-                                     /*ObjectType=*/nullptr, EnteringContext,
-                                     Template, MemberOfUnknownSpecialization)) {
+      if (TemplateNameKind TNK = Actions.isTemplateName(
+              getCurScope(), SS,
+              /*hasTemplateKeyword=*/false, TemplateName,
+              /*ObjectType=*/nullptr, /*EnteringContext*/false, Template,
+              MemberOfUnknownSpecialization)) {
         // Consume the identifier.
         ConsumeToken();
         if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
@@ -1974,8 +1968,10 @@
 
   // Parse the unqualified-id.
   SourceLocation TemplateKWLoc; // FIXME: parsed, but unused.
-  if (ParseUnqualifiedId(Result.SS, false, true, true, nullptr, TemplateKWLoc,
-                         Result.Name)) {
+  if (ParseUnqualifiedId(
+          Result.SS, /*EnteringContext*/false, /*AllowDestructorName*/true,
+          /*AllowConstructorName*/true, /*AllowDeductionGuide*/false, nullptr,
+          TemplateKWLoc, Result.Name)) {
     T.skipToEnd();
     return true;
   }
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 5953d02..a987a8c 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -56,6 +56,8 @@
 namespace {
   class UnreachableCodeHandler : public reachable_code::Callback {
     Sema &S;
+    SourceRange PreviousSilenceableCondVal;
+
   public:
     UnreachableCodeHandler(Sema &s) : S(s) {}
 
@@ -64,6 +66,14 @@
                            SourceRange SilenceableCondVal,
                            SourceRange R1,
                            SourceRange R2) override {
+      // Avoid reporting multiple unreachable code diagnostics that are
+      // triggered by the same conditional value.
+      if (PreviousSilenceableCondVal.isValid() &&
+          SilenceableCondVal.isValid() &&
+          PreviousSilenceableCondVal == SilenceableCondVal)
+        return;
+      PreviousSilenceableCondVal = SilenceableCondVal;
+
       unsigned diag = diag::warn_unreachable;
       switch (UK) {
         case reachable_code::UK_Break:
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 4107977..a55cdcc 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -173,6 +173,8 @@
                                              unsigned NumExceptions,
                                              Expr *NoexceptExpr,
                                              CachedTokens *ExceptionSpecTokens,
+                                             ArrayRef<NamedDecl*>
+                                                 DeclsInPrototype,
                                              SourceLocation LocalRangeBegin,
                                              SourceLocation LocalRangeEnd,
                                              Declarator &TheDeclarator,
@@ -204,7 +206,7 @@
   I.Fun.ExceptionSpecType       = ESpecType;
   I.Fun.ExceptionSpecLocBeg     = ESpecRange.getBegin().getRawEncoding();
   I.Fun.ExceptionSpecLocEnd     = ESpecRange.getEnd().getRawEncoding();
-  I.Fun.NumExceptions           = 0;
+  I.Fun.NumExceptionsOrDecls    = 0;
   I.Fun.Exceptions              = nullptr;
   I.Fun.NoexceptExpr            = nullptr;
   I.Fun.HasTrailingReturnType   = TrailingReturnType.isUsable() ||
@@ -240,7 +242,7 @@
   case EST_Dynamic:
     // new[] an exception array if needed
     if (NumExceptions) {
-      I.Fun.NumExceptions = NumExceptions;
+      I.Fun.NumExceptionsOrDecls = NumExceptions;
       I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
       for (unsigned i = 0; i != NumExceptions; ++i) {
         I.Fun.Exceptions[i].Ty = Exceptions[i];
@@ -257,6 +259,17 @@
     I.Fun.ExceptionSpecTokens = ExceptionSpecTokens;
     break;
   }
+
+  if (!DeclsInPrototype.empty()) {
+    assert(ESpecType == EST_None && NumExceptions == 0 &&
+           "cannot have exception specifiers and decls in prototype");
+    I.Fun.NumExceptionsOrDecls = DeclsInPrototype.size();
+    // Copy the array of decls into stable heap storage.
+    I.Fun.DeclsInPrototype = new NamedDecl *[DeclsInPrototype.size()];
+    for (size_t J = 0; J < DeclsInPrototype.size(); ++J)
+      I.Fun.DeclsInPrototype[J] = DeclsInPrototype[J];
+  }
+
   return I;
 }
 
@@ -545,7 +558,7 @@
   // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
   // specifiers are not supported."
   if (S.getLangOpts().OpenCL &&
-      !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
+      !S.getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers")) {
     switch (SC) {
     case SCS_extern:
     case SCS_private_extern:
diff --git a/lib/Sema/MultiplexExternalSemaSource.cpp b/lib/Sema/MultiplexExternalSemaSource.cpp
index 077a56f..c97e4df 100644
--- a/lib/Sema/MultiplexExternalSemaSource.cpp
+++ b/lib/Sema/MultiplexExternalSemaSource.cpp
@@ -94,6 +94,15 @@
   return nullptr;
 }
 
+ExternalASTSource::ExtKind
+MultiplexExternalSemaSource::hasExternalDefinitions(unsigned int ID) {
+  for (const auto &S : Sources)
+    if (auto EK = S->hasExternalDefinitions(ID))
+      if (EK != EK_ReplyHazy)
+        return EK;
+  return EK_ReplyHazy;
+}
+
 bool MultiplexExternalSemaSource::
 FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
   bool AnyDeclsFound = false;
diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp
index 3970b41..b309a36 100644
--- a/lib/Sema/ScopeInfo.cpp
+++ b/lib/Sema/ScopeInfo.cpp
@@ -40,10 +40,15 @@
   FirstCXXTryLoc = SourceLocation();
   FirstSEHTryLoc = SourceLocation();
 
+  // Coroutine state
+  FirstCoroutineStmtLoc = SourceLocation();
+  CoroutinePromise = nullptr;
+  NeedsCoroutineSuspends = true;
+  CoroutineSuspends.first = nullptr;
+  CoroutineSuspends.second = nullptr;
+
   SwitchStack.clear();
   Returns.clear();
-  CoroutinePromise = nullptr;
-  CoroutineStmts.clear();
   ErrorTrap.reset();
   PossiblyUnreachableDiags.clear();
   WeakObjectUses.clear();
@@ -184,7 +189,7 @@
   }
 
   // Has this weak object been seen before?
-  FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
+  FunctionScopeInfo::WeakObjectUseMap::iterator Uses = WeakObjectUses.end();
   if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
     if (!RefExpr->isObjectReceiver())
       return;
@@ -197,10 +202,10 @@
   }
   else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
     Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
-  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-    Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
-  else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
-    Uses = WeakObjectUses.end();
+  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+    if (isa<VarDecl>(DRE->getDecl()))
+      Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
+  } else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
     if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
       if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
         Uses =
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index fc76a86..1677d34 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -207,44 +207,74 @@
     addImplicitTypedef("size_t", Context.getSizeType());
   }
 
-  // Initialize predefined OpenCL types and supported optional core features.
+  // Initialize predefined OpenCL types and supported extensions and (optional)
+  // core features.
   if (getLangOpts().OpenCL) {
-#define OPENCLEXT(Ext) \
-     if (Context.getTargetInfo().getSupportedOpenCLOpts().is_##Ext##_supported_core( \
-         getLangOpts().OpenCLVersion)) \
-       getOpenCLOptions().Ext = 1;
-#include "clang/Basic/OpenCLExtensions.def"
-
+    getOpenCLOptions().addSupport(Context.getTargetInfo().getSupportedOpenCLOpts());
+    getOpenCLOptions().enableSupportedCore(getLangOpts().OpenCLVersion);
     addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
     addImplicitTypedef("event_t", Context.OCLEventTy);
     if (getLangOpts().OpenCLVersion >= 200) {
       addImplicitTypedef("clk_event_t", Context.OCLClkEventTy);
       addImplicitTypedef("queue_t", Context.OCLQueueTy);
-      addImplicitTypedef("ndrange_t", Context.OCLNDRangeTy);
       addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy);
       addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy));
       addImplicitTypedef("atomic_uint",
                          Context.getAtomicType(Context.UnsignedIntTy));
-      addImplicitTypedef("atomic_long", Context.getAtomicType(Context.LongTy));
-      addImplicitTypedef("atomic_ulong",
-                         Context.getAtomicType(Context.UnsignedLongTy));
+      auto AtomicLongT = Context.getAtomicType(Context.LongTy);
+      addImplicitTypedef("atomic_long", AtomicLongT);
+      auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy);
+      addImplicitTypedef("atomic_ulong", AtomicULongT);
       addImplicitTypedef("atomic_float",
                          Context.getAtomicType(Context.FloatTy));
-      addImplicitTypedef("atomic_double",
-                         Context.getAtomicType(Context.DoubleTy));
+      auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy);
+      addImplicitTypedef("atomic_double", AtomicDoubleT);
       // OpenCLC v2.0, s6.13.11.6 requires that atomic_flag is implemented as
       // 32-bit integer and OpenCLC v2.0, s6.1.1 int is always 32-bit wide.
       addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy));
-      addImplicitTypedef("atomic_intptr_t",
-                         Context.getAtomicType(Context.getIntPtrType()));
-      addImplicitTypedef("atomic_uintptr_t",
-                         Context.getAtomicType(Context.getUIntPtrType()));
-      addImplicitTypedef("atomic_size_t",
-                         Context.getAtomicType(Context.getSizeType()));
-      addImplicitTypedef("atomic_ptrdiff_t",
-                         Context.getAtomicType(Context.getPointerDiffType()));
+      auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType());
+      addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT);
+      auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType());
+      addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT);
+      auto AtomicSizeT = Context.getAtomicType(Context.getSizeType());
+      addImplicitTypedef("atomic_size_t", AtomicSizeT);
+      auto AtomicPtrDiffT = Context.getAtomicType(Context.getPointerDiffType());
+      addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT);
+
+      // OpenCL v2.0 s6.13.11.6:
+      // - The atomic_long and atomic_ulong types are supported if the
+      //   cl_khr_int64_base_atomics and cl_khr_int64_extended_atomics
+      //   extensions are supported.
+      // - The atomic_double type is only supported if double precision
+      //   is supported and the cl_khr_int64_base_atomics and
+      //   cl_khr_int64_extended_atomics extensions are supported.
+      // - If the device address space is 64-bits, the data types
+      //   atomic_intptr_t, atomic_uintptr_t, atomic_size_t and
+      //   atomic_ptrdiff_t are supported if the cl_khr_int64_base_atomics and
+      //   cl_khr_int64_extended_atomics extensions are supported.
+      std::vector<QualType> Atomic64BitTypes;
+      Atomic64BitTypes.push_back(AtomicLongT);
+      Atomic64BitTypes.push_back(AtomicULongT);
+      Atomic64BitTypes.push_back(AtomicDoubleT);
+      if (Context.getTypeSize(AtomicSizeT) == 64) {
+        Atomic64BitTypes.push_back(AtomicSizeT);
+        Atomic64BitTypes.push_back(AtomicIntPtrT);
+        Atomic64BitTypes.push_back(AtomicUIntPtrT);
+        Atomic64BitTypes.push_back(AtomicPtrDiffT);
+      }
+      for (auto &I : Atomic64BitTypes)
+        setOpenCLExtensionForType(I,
+            "cl_khr_int64_base_atomics cl_khr_int64_extended_atomics");
+
+      setOpenCLExtensionForType(AtomicDoubleT, "cl_khr_fp64");
     }
-  }
+
+    setOpenCLExtensionForType(Context.DoubleTy, "cl_khr_fp64");
+
+#define GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) \
+    setOpenCLExtensionForType(Context.Id, Ext);
+#include "clang/Basic/OpenCLImageTypes.def"
+    };
 
   if (Context.getTargetInfo().hasBuiltinMSVaList()) {
     DeclarationName MSVaList = &Context.Idents.get("__builtin_ms_va_list");
@@ -297,7 +327,7 @@
   if (!fn) return false;
 
   // If we're in template instantiation, it's an error.
-  if (!ActiveTemplateInstantiations.empty())
+  if (inTemplateInstantiation())
     return false;
 
   // If that function's not in a system header, it's an error.
@@ -976,7 +1006,7 @@
   // and yet we also use the current diag ID on the DiagnosticsEngine. This has
   // been made more painfully obvious by the refactor that introduced this
   // function, but it is possible that the incoming argument can be
-  // eliminnated. If it truly cannot be (for example, there is some reentrancy
+  // eliminated. If it truly cannot be (for example, there is some reentrancy
   // issue I am not seeing yet), then there should at least be a clarifying
   // comment somewhere.
   if (Optional<TemplateDeductionInfo*> Info = isSFINAEContext()) {
@@ -1064,13 +1094,8 @@
   // that is different from the last template instantiation where
   // we emitted an error, print a template instantiation
   // backtrace.
-  if (!DiagnosticIDs::isBuiltinNote(DiagID) &&
-      !ActiveTemplateInstantiations.empty() &&
-      ActiveTemplateInstantiations.back()
-        != LastTemplateInstantiationErrorContext) {
-    PrintInstantiationStack();
-    LastTemplateInstantiationErrorContext = ActiveTemplateInstantiations.back();
-  }
+  if (!DiagnosticIDs::isBuiltinNote(DiagID))
+    PrintContextStack();
 }
 
 Sema::SemaDiagnosticBuilder
@@ -1205,21 +1230,21 @@
   if (CurBSI && CurBSI->TheDecl &&
       !CurBSI->TheDecl->Encloses(CurContext)) {
     // We have switched contexts due to template instantiation.
-    assert(!ActiveTemplateInstantiations.empty());
+    assert(!CodeSynthesisContexts.empty());
     return nullptr;
   }
 
   return CurBSI;
 }
 
-LambdaScopeInfo *Sema::getCurLambda(bool IgnoreCapturedRegions) {
+LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) {
   if (FunctionScopes.empty())
     return nullptr;
 
   auto I = FunctionScopes.rbegin();
-  if (IgnoreCapturedRegions) {
+  if (IgnoreNonLambdaCapturingScope) {
     auto E = FunctionScopes.rend();
-    while (I != E && isa<CapturedRegionScopeInfo>(*I))
+    while (I != E && isa<CapturingScopeInfo>(*I) && !isa<LambdaScopeInfo>(*I))
       ++I;
     if (I == E)
       return nullptr;
@@ -1228,7 +1253,7 @@
   if (CurLSI && CurLSI->Lambda &&
       !CurLSI->Lambda->Encloses(CurContext)) {
     // We have switched contexts due to template instantiation.
-    assert(!ActiveTemplateInstantiations.empty());
+    assert(!CodeSynthesisContexts.empty());
     return nullptr;
   }
 
@@ -1542,3 +1567,85 @@
 Sema::getMismatchingDeleteExpressions() const {
   return DeleteExprs;
 }
+
+void Sema::setOpenCLExtensionForType(QualType T, llvm::StringRef ExtStr) {
+  if (ExtStr.empty())
+    return;
+  llvm::SmallVector<StringRef, 1> Exts;
+  ExtStr.split(Exts, " ", /* limit */ -1, /* keep empty */ false);
+  auto CanT = T.getCanonicalType().getTypePtr();
+  for (auto &I : Exts)
+    OpenCLTypeExtMap[CanT].insert(I.str());
+}
+
+void Sema::setOpenCLExtensionForDecl(Decl *FD, StringRef ExtStr) {
+  llvm::SmallVector<StringRef, 1> Exts;
+  ExtStr.split(Exts, " ", /* limit */ -1, /* keep empty */ false);
+  if (Exts.empty())
+    return;
+  for (auto &I : Exts)
+    OpenCLDeclExtMap[FD].insert(I.str());
+}
+
+void Sema::setCurrentOpenCLExtensionForType(QualType T) {
+  if (CurrOpenCLExtension.empty())
+    return;
+  setOpenCLExtensionForType(T, CurrOpenCLExtension);
+}
+
+void Sema::setCurrentOpenCLExtensionForDecl(Decl *D) {
+  if (CurrOpenCLExtension.empty())
+    return;
+  setOpenCLExtensionForDecl(D, CurrOpenCLExtension);
+}
+
+bool Sema::isOpenCLDisabledDecl(Decl *FD) {
+  auto Loc = OpenCLDeclExtMap.find(FD);
+  if (Loc == OpenCLDeclExtMap.end())
+    return false;
+  for (auto &I : Loc->second) {
+    if (!getOpenCLOptions().isEnabled(I))
+      return true;
+  }
+  return false;
+}
+
+template <typename T, typename DiagLocT, typename DiagInfoT, typename MapT>
+bool Sema::checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc,
+                                         DiagInfoT DiagInfo, MapT &Map,
+                                         unsigned Selector,
+                                         SourceRange SrcRange) {
+  auto Loc = Map.find(D);
+  if (Loc == Map.end())
+    return false;
+  bool Disabled = false;
+  for (auto &I : Loc->second) {
+    if (I != CurrOpenCLExtension && !getOpenCLOptions().isEnabled(I)) {
+      Diag(DiagLoc, diag::err_opencl_requires_extension) << Selector << DiagInfo
+                                                         << I << SrcRange;
+      Disabled = true;
+    }
+  }
+  return Disabled;
+}
+
+bool Sema::checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType QT) {
+  // Check extensions for declared types.
+  Decl *Decl = nullptr;
+  if (auto TypedefT = dyn_cast<TypedefType>(QT.getTypePtr()))
+    Decl = TypedefT->getDecl();
+  if (auto TagT = dyn_cast<TagType>(QT.getCanonicalType().getTypePtr()))
+    Decl = TagT->getDecl();
+  auto Loc = DS.getTypeSpecTypeLoc();
+  if (checkOpenCLDisabledTypeOrDecl(Decl, Loc, QT, OpenCLDeclExtMap))
+    return true;
+
+  // Check extensions for builtin types.
+  return checkOpenCLDisabledTypeOrDecl(QT.getCanonicalType().getTypePtr(), Loc,
+                                       QT, OpenCLTypeExtMap);
+}
+
+bool Sema::checkOpenCLDisabledDecl(const Decl &D, const Expr &E) {
+  return checkOpenCLDisabledTypeOrDecl(&D, E.getLocStart(), "",
+                                       OpenCLDeclExtMap, 1, D.getSourceRange());
+}
diff --git a/lib/Sema/SemaCUDA.cpp b/lib/Sema/SemaCUDA.cpp
index 6f272ec..b938ac3 100644
--- a/lib/Sema/SemaCUDA.cpp
+++ b/lib/Sema/SemaCUDA.cpp
@@ -228,10 +228,8 @@
       [&](const Pair &M1, const Pair &M2) { return GetCFP(M1) < GetCFP(M2); }));
 
   // Erase all functions with lower priority.
-  Matches.erase(
-      llvm::remove_if(
-          Matches, [&](const Pair &Match) { return GetCFP(Match) < BestCFP; }),
-      Matches.end());
+  llvm::erase_if(Matches,
+                 [&](const Pair &Match) { return GetCFP(Match) < BestCFP; });
 }
 
 /// When an implicitly-declared special member has to invoke more than one
@@ -297,7 +295,7 @@
     }
 
     CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
-    Sema::SpecialMemberOverloadResult *SMOR =
+    Sema::SpecialMemberOverloadResult SMOR =
         LookupSpecialMember(BaseClassDecl, CSM,
                             /* ConstArg */ ConstRHS,
                             /* VolatileArg */ false,
@@ -305,11 +303,10 @@
                             /* ConstThis */ false,
                             /* VolatileThis */ false);
 
-    if (!SMOR || !SMOR->getMethod()) {
+    if (!SMOR.getMethod())
       continue;
-    }
 
-    CUDAFunctionTarget BaseMethodTarget = IdentifyCUDATarget(SMOR->getMethod());
+    CUDAFunctionTarget BaseMethodTarget = IdentifyCUDATarget(SMOR.getMethod());
     if (!InferredTarget.hasValue()) {
       InferredTarget = BaseMethodTarget;
     } else {
@@ -341,7 +338,7 @@
     }
 
     CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(FieldType->getDecl());
-    Sema::SpecialMemberOverloadResult *SMOR =
+    Sema::SpecialMemberOverloadResult SMOR =
         LookupSpecialMember(FieldRecDecl, CSM,
                             /* ConstArg */ ConstRHS && !F->isMutable(),
                             /* VolatileArg */ false,
@@ -349,12 +346,11 @@
                             /* ConstThis */ false,
                             /* VolatileThis */ false);
 
-    if (!SMOR || !SMOR->getMethod()) {
+    if (!SMOR.getMethod())
       continue;
-    }
 
     CUDAFunctionTarget FieldMethodTarget =
-        IdentifyCUDATarget(SMOR->getMethod());
+        IdentifyCUDATarget(SMOR.getMethod());
     if (!InferredTarget.hasValue()) {
       InferredTarget = FieldMethodTarget;
     } else {
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index d8971c0..ee4317f 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -933,8 +933,8 @@
 
   // We were able to resolve the template name to an actual template. 
   // Build an appropriate nested-name-specifier.
-  QualType T = CheckTemplateIdType(Template.get(), TemplateNameLoc, 
-                                   TemplateArgs);
+  QualType T =
+      CheckTemplateIdType(Template.get(), TemplateNameLoc, TemplateArgs);
   if (T.isNull())
     return true;
 
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index f4810fb..39e85e7 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -1517,6 +1517,9 @@
         ? InitializationKind::CreateFunctionalCast(OpRange, ListInitialization)
     : InitializationKind::CreateCast(OpRange);
   Expr *SrcExprRaw = SrcExpr.get();
+  // FIXME: Per DR242, we should check for an implicit conversion sequence
+  // or for a constructor that could be invoked by direct-initialization
+  // here, not for an initialization sequence.
   InitializationSequence InitSeq(Self, Entity, InitKind, SrcExprRaw);
 
   // At this point of CheckStaticCast, if the destination is a reference,
@@ -1652,7 +1655,8 @@
   if (NeedToMaterializeTemporary)
     // 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 = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
+    SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcExpr.get()->getType(),
+                                                  SrcExpr.get(),
                                                   /*IsLValueReference*/ false);
 
   return TC_Success;
@@ -1759,13 +1763,12 @@
   if (!DRE)
     return;
   auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl());
-  const FunctionDecl *Definition;
-  if (!FD || !FD->hasBody(Definition))
+  if (!FD)
     return;
 
   // Only warn if we are casting from the default convention to a non-default
   // convention. This can happen when the programmer forgot to apply the calling
-  // convention to the function definition and then inserted this cast to
+  // convention to the function declaration and then inserted this cast to
   // satisfy the type system.
   CallingConv DefaultCC = Self.getASTContext().getDefaultCallingConvention(
       FD->isVariadic(), FD->isCXXInstanceMember());
@@ -1788,7 +1791,7 @@
   // whose address was taken. Try to use the latest macro for the convention.
   // For example, users probably want to write "WINAPI" instead of "__stdcall"
   // to match the Windows header declarations.
-  SourceLocation NameLoc = Definition->getNameInfo().getLoc();
+  SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();
   Preprocessor &PP = Self.getPreprocessor();
   SmallVector<TokenValue, 6> AttrTokens;
   SmallString<64> CCAttrText;
@@ -1916,7 +1919,10 @@
     switch (SrcExpr.get()->getObjectKind()) {
     case OK_Ordinary:
       break;
-    case OK_BitField:        inappropriate = "bit-field";           break;
+    case OK_BitField:
+      msg = diag::err_bad_cxx_cast_bitfield;
+      return TC_NotApplicable;
+      // FIXME: Use a specific diagnostic for the rest of these cases.
     case OK_VectorComponent: inappropriate = "vector element";      break;
     case OK_ObjCProperty:    inappropriate = "property expression"; break;
     case OK_ObjCSubscript:   inappropriate = "container subscripting expression"; 
@@ -2522,7 +2528,8 @@
     }
   }
 
-  if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().cl_khr_fp16) {
+  if (Self.getLangOpts().OpenCL &&
+      !Self.getOpenCLOptions().isEnabled("cl_khr_fp16")) {
     if (DestType->isHalfType()) {
       Self.Diag(SrcExpr.get()->getLocStart(), diag::err_opencl_cast_to_half)
         << DestType << SrcExpr.get()->getSourceRange();
@@ -2620,11 +2627,12 @@
 }
 
 ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
+                                            QualType Type,
                                             SourceLocation LPLoc,
                                             Expr *CastExpr,
                                             SourceLocation RPLoc) {
   assert(LPLoc.isValid() && "List-initialization shouldn't get here.");
-  CastOperation Op(*this, CastTypeInfo->getType(), CastExpr);
+  CastOperation Op(*this, Type, CastExpr);
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
   Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd());
 
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index fd0654b..9858244 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -244,7 +244,7 @@
   // Scopes aren't available during instantiation. Fortunately, builtin
   // functions cannot be template args so they cannot be formed through template
   // instantiation. Therefore checking once during the parse is sufficient.
-  if (!SemaRef.ActiveTemplateInstantiations.empty())
+  if (SemaRef.inTemplateInstantiation())
     return false;
 
   Scope *S = SemaRef.getCurScope();
@@ -408,10 +408,10 @@
   }
 
   // Third argument is always an ndrange_t type.
-  if (!Arg2->getType()->isNDRangeT()) {
+  if (Arg2->getType().getAsString() != "ndrange_t") {
     S.Diag(TheCall->getArg(2)->getLocStart(),
            diag::err_opencl_enqueue_kernel_expected_type)
-        << S.Context.OCLNDRangeTy;
+        << "'ndrange_t'";
     return true;
   }
 
@@ -1242,7 +1242,8 @@
     QualType RHSTy = RHS.get()->getType();
 
     llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch();
-    bool IsPolyUnsigned = Arch == llvm::Triple::aarch64;
+    bool IsPolyUnsigned = Arch == llvm::Triple::aarch64 ||
+                          Arch == llvm::Triple::aarch64_be;
     bool IsInt64Long =
         Context.getTargetInfo().getInt64Type() == TargetInfo::SignedLong;
     QualType EltTy =
@@ -1618,28 +1619,24 @@
   case Mips::BI__builtin_msa_copy_u_b:
   case Mips::BI__builtin_msa_insve_b:
   case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break;
-  case Mips::BI__builtin_msa_sld_b:
   case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break;
   // These intrinsics take an unsigned 3 bit immediate.
   case Mips::BI__builtin_msa_copy_s_h:
   case Mips::BI__builtin_msa_copy_u_h:
   case Mips::BI__builtin_msa_insve_h:
   case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break;
-  case Mips::BI__builtin_msa_sld_h:
   case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break;
   // These intrinsics take an unsigned 2 bit immediate.
   case Mips::BI__builtin_msa_copy_s_w:
   case Mips::BI__builtin_msa_copy_u_w:
   case Mips::BI__builtin_msa_insve_w:
   case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break;
-  case Mips::BI__builtin_msa_sld_w:
   case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break;
   // These intrinsics take an unsigned 1 bit immediate.
   case Mips::BI__builtin_msa_copy_s_d:
   case Mips::BI__builtin_msa_copy_u_d:
   case Mips::BI__builtin_msa_insve_d:
   case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break;
-  case Mips::BI__builtin_msa_sld_d:
   case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break;
   // Memory offsets and immediate loads.
   // These intrinsics take a signed 10 bit immediate.
@@ -1989,6 +1986,109 @@
     << Arg->getSourceRange();
 }
 
+// Check if the gather/scatter scale is legal.
+bool Sema::CheckX86BuiltinGatherScatterScale(unsigned BuiltinID,
+                                             CallExpr *TheCall) {
+  unsigned ArgNum = 0;
+  switch (BuiltinID) {
+  default:
+    return false;
+  case X86::BI__builtin_ia32_gatherpfdpd:
+  case X86::BI__builtin_ia32_gatherpfdps:
+  case X86::BI__builtin_ia32_gatherpfqpd:
+  case X86::BI__builtin_ia32_gatherpfqps:
+  case X86::BI__builtin_ia32_scatterpfdpd:
+  case X86::BI__builtin_ia32_scatterpfdps:
+  case X86::BI__builtin_ia32_scatterpfqpd:
+  case X86::BI__builtin_ia32_scatterpfqps:
+    ArgNum = 3;
+    break;
+  case X86::BI__builtin_ia32_gatherd_pd:
+  case X86::BI__builtin_ia32_gatherd_pd256:
+  case X86::BI__builtin_ia32_gatherq_pd:
+  case X86::BI__builtin_ia32_gatherq_pd256:
+  case X86::BI__builtin_ia32_gatherd_ps:
+  case X86::BI__builtin_ia32_gatherd_ps256:
+  case X86::BI__builtin_ia32_gatherq_ps:
+  case X86::BI__builtin_ia32_gatherq_ps256:
+  case X86::BI__builtin_ia32_gatherd_q:
+  case X86::BI__builtin_ia32_gatherd_q256:
+  case X86::BI__builtin_ia32_gatherq_q:
+  case X86::BI__builtin_ia32_gatherq_q256:
+  case X86::BI__builtin_ia32_gatherd_d:
+  case X86::BI__builtin_ia32_gatherd_d256:
+  case X86::BI__builtin_ia32_gatherq_d:
+  case X86::BI__builtin_ia32_gatherq_d256:
+  case X86::BI__builtin_ia32_gather3div2df:
+  case X86::BI__builtin_ia32_gather3div2di:
+  case X86::BI__builtin_ia32_gather3div4df:
+  case X86::BI__builtin_ia32_gather3div4di:
+  case X86::BI__builtin_ia32_gather3div4sf:
+  case X86::BI__builtin_ia32_gather3div4si:
+  case X86::BI__builtin_ia32_gather3div8sf:
+  case X86::BI__builtin_ia32_gather3div8si:
+  case X86::BI__builtin_ia32_gather3siv2df:
+  case X86::BI__builtin_ia32_gather3siv2di:
+  case X86::BI__builtin_ia32_gather3siv4df:
+  case X86::BI__builtin_ia32_gather3siv4di:
+  case X86::BI__builtin_ia32_gather3siv4sf:
+  case X86::BI__builtin_ia32_gather3siv4si:
+  case X86::BI__builtin_ia32_gather3siv8sf:
+  case X86::BI__builtin_ia32_gather3siv8si:
+  case X86::BI__builtin_ia32_gathersiv8df:
+  case X86::BI__builtin_ia32_gathersiv16sf:
+  case X86::BI__builtin_ia32_gatherdiv8df:
+  case X86::BI__builtin_ia32_gatherdiv16sf:
+  case X86::BI__builtin_ia32_gathersiv8di:
+  case X86::BI__builtin_ia32_gathersiv16si:
+  case X86::BI__builtin_ia32_gatherdiv8di:
+  case X86::BI__builtin_ia32_gatherdiv16si:
+  case X86::BI__builtin_ia32_scatterdiv2df:
+  case X86::BI__builtin_ia32_scatterdiv2di:
+  case X86::BI__builtin_ia32_scatterdiv4df:
+  case X86::BI__builtin_ia32_scatterdiv4di:
+  case X86::BI__builtin_ia32_scatterdiv4sf:
+  case X86::BI__builtin_ia32_scatterdiv4si:
+  case X86::BI__builtin_ia32_scatterdiv8sf:
+  case X86::BI__builtin_ia32_scatterdiv8si:
+  case X86::BI__builtin_ia32_scattersiv2df:
+  case X86::BI__builtin_ia32_scattersiv2di:
+  case X86::BI__builtin_ia32_scattersiv4df:
+  case X86::BI__builtin_ia32_scattersiv4di:
+  case X86::BI__builtin_ia32_scattersiv4sf:
+  case X86::BI__builtin_ia32_scattersiv4si:
+  case X86::BI__builtin_ia32_scattersiv8sf:
+  case X86::BI__builtin_ia32_scattersiv8si:
+  case X86::BI__builtin_ia32_scattersiv8df:
+  case X86::BI__builtin_ia32_scattersiv16sf:
+  case X86::BI__builtin_ia32_scatterdiv8df:
+  case X86::BI__builtin_ia32_scatterdiv16sf:
+  case X86::BI__builtin_ia32_scattersiv8di:
+  case X86::BI__builtin_ia32_scattersiv16si:
+  case X86::BI__builtin_ia32_scatterdiv8di:
+  case X86::BI__builtin_ia32_scatterdiv16si:
+    ArgNum = 4;
+    break;
+  }
+
+  llvm::APSInt Result;
+
+  // We can't check the value of a dependent argument.
+  Expr *Arg = TheCall->getArg(ArgNum);
+  if (Arg->isTypeDependent() || Arg->isValueDependent())
+    return false;
+
+  // Check constant-ness first.
+  if (SemaBuiltinConstantArg(TheCall, ArgNum, Result))
+    return true;
+
+  if (Result == 1 || Result == 2 || Result == 4 || Result == 8)
+    return false;
+
+  return Diag(TheCall->getLocStart(), diag::err_x86_builtin_invalid_scale)
+    << Arg->getSourceRange();
+}
+
 bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   if (BuiltinID == X86::BI__builtin_cpu_supports)
     return SemaBuiltinCpuSupports(*this, TheCall);
@@ -2000,6 +2100,10 @@
   if (CheckX86BuiltinRoundingOrSAE(BuiltinID, TheCall))
     return true;
 
+  // If the intrinsic has a gather/scatter scale immediate make sure its valid.
+  if (CheckX86BuiltinGatherScatterScale(BuiltinID, TheCall))
+    return true;
+
   // For intrinsics which take an immediate value as part of the instruction,
   // range check them here.
   int i = 0, l = 0, u = 0;
@@ -2196,6 +2300,16 @@
   case X86::BI__builtin_ia32_pternlogq256_maskz:
     i = 3; l = 0; u = 255;
     break;
+  case X86::BI__builtin_ia32_gatherpfdpd:
+  case X86::BI__builtin_ia32_gatherpfdps:
+  case X86::BI__builtin_ia32_gatherpfqpd:
+  case X86::BI__builtin_ia32_gatherpfqps:
+  case X86::BI__builtin_ia32_scatterpfdpd:
+  case X86::BI__builtin_ia32_scatterpfdps:
+  case X86::BI__builtin_ia32_scatterpfqpd:
+  case X86::BI__builtin_ia32_scatterpfqps:
+    i = 4; l = 1; u = 2;
+    break;
   case X86::BI__builtin_ia32_pcmpestrm128:
   case X86::BI__builtin_ia32_pcmpestri128:
   case X86::BI__builtin_ia32_pcmpestria128:
@@ -2425,11 +2539,12 @@
 }
 
 /// Handles the checks for format strings, non-POD arguments to vararg
-/// functions, and NULL arguments passed to non-NULL parameters.
+/// functions, NULL arguments passed to non-NULL parameters, and diagnose_if
+/// attributes.
 void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
-                     ArrayRef<const Expr *> Args, bool IsMemberFunction,
-                     SourceLocation Loc, SourceRange Range,
-                     VariadicCallType CallType) {
+                     const Expr *ThisArg, ArrayRef<const Expr *> Args,
+                     bool IsMemberFunction, SourceLocation Loc,
+                     SourceRange Range, VariadicCallType CallType) {
   // FIXME: We should check as much as we can in the template definition.
   if (CurContext->isDependentContext())
     return;
@@ -2448,7 +2563,9 @@
 
   // Refuse POD arguments that weren't caught by the format string
   // checks above.
-  if (CallType != VariadicDoesNotApply) {
+  auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
+  if (CallType != VariadicDoesNotApply &&
+      (!FD || FD->getBuiltinID() != Builtin::BI__noop)) {
     unsigned NumParams = Proto ? Proto->getNumParams()
                        : FDecl && isa<FunctionDecl>(FDecl)
                            ? cast<FunctionDecl>(FDecl)->getNumParams()
@@ -2474,6 +2591,9 @@
         CheckArgumentWithTypeTag(I, Args.data());
     }
   }
+
+  if (FD)
+    diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc);
 }
 
 /// CheckConstructorCall - Check a constructor call for correctness and safety
@@ -2484,8 +2604,8 @@
                                 SourceLocation Loc) {
   VariadicCallType CallType =
     Proto->isVariadic() ? VariadicConstructor : VariadicDoesNotApply;
-  checkCall(FDecl, Proto, Args, /*IsMemberFunction=*/true, Loc, SourceRange(), 
-            CallType);
+  checkCall(FDecl, Proto, /*ThisArg=*/nullptr, Args, /*IsMemberFunction=*/true,
+            Loc, SourceRange(), CallType);
 }
 
 /// CheckFunctionCall - Check a direct function call for various correctness
@@ -2500,14 +2620,20 @@
                                                   TheCall->getCallee());
   Expr** Args = TheCall->getArgs();
   unsigned NumArgs = TheCall->getNumArgs();
+
+  Expr *ImplicitThis = nullptr;
   if (IsMemberOperatorCall) {
     // If this is a call to a member operator, hide the first argument
     // from checkCall.
     // FIXME: Our choice of AST representation here is less than ideal.
+    ImplicitThis = Args[0];
     ++Args;
     --NumArgs;
-  }
-  checkCall(FDecl, Proto, llvm::makeArrayRef(Args, NumArgs), 
+  } else if (IsMemberFunction)
+    ImplicitThis =
+        cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();
+
+  checkCall(FDecl, Proto, ImplicitThis, llvm::makeArrayRef(Args, NumArgs),
             IsMemberFunction, TheCall->getRParenLoc(),
             TheCall->getCallee()->getSourceRange(), CallType);
 
@@ -2543,8 +2669,8 @@
   VariadicCallType CallType =
       Method->isVariadic() ? VariadicMethod : VariadicDoesNotApply;
 
-  checkCall(Method, nullptr, Args,
-            /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), 
+  checkCall(Method, nullptr, /*ThisArg=*/nullptr, Args,
+            /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(),
             CallType);
 
   return false;
@@ -2573,7 +2699,7 @@
     CallType = VariadicFunction;
   }
 
-  checkCall(NDecl, Proto,
+  checkCall(NDecl, Proto, /*ThisArg=*/nullptr,
             llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()),
             /*IsMemberFunction=*/false, TheCall->getRParenLoc(),
             TheCall->getCallee()->getSourceRange(), CallType);
@@ -2586,7 +2712,7 @@
 bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) {
   VariadicCallType CallType = getVariadicCallType(/*FDecl=*/nullptr, Proto,
                                                   TheCall->getCallee());
-  checkCall(/*FDecl=*/nullptr, Proto,
+  checkCall(/*FDecl=*/nullptr, Proto, /*ThisArg=*/nullptr,
             llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()),
             /*IsMemberFunction=*/false, TheCall->getRParenLoc(),
             TheCall->getCallee()->getSourceRange(), CallType);
@@ -3748,14 +3874,18 @@
                 diag::err_typecheck_call_invalid_unary_fp)
       << OrigArg->getType() << OrigArg->getSourceRange();
 
-  // If this is an implicit conversion from float -> double, remove it.
+  // If this is an implicit conversion from float -> float or double, remove it.
   if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
-    Expr *CastArg = Cast->getSubExpr();
-    if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
-      assert(Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) &&
-             "promotion from float to double is the only expected cast here");
-      Cast->setSubExpr(nullptr);
-      TheCall->setArg(NumArgs-1, CastArg);
+    // Only remove standard FloatCasts, leaving other casts inplace
+    if (Cast->getCastKind() == CK_FloatingCast) {
+      Expr *CastArg = Cast->getSubExpr();
+      if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
+          assert((Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
+                  Cast->getType()->isSpecificBuiltinType(BuiltinType::Float)) &&
+               "promotion from float to either float or double is the only expected cast here");
+        Cast->setSubExpr(nullptr);
+        TheCall->setArg(NumArgs-1, CastArg);
+      }
     }
   }
   
@@ -6765,7 +6895,7 @@
   if (!Call || !FDecl) return;
 
   // Ignore template specializations and macros.
-  if (!ActiveTemplateInstantiations.empty()) return;
+  if (inTemplateInstantiation()) return;
   if (Call->getExprLoc().isMacroID()) return;
 
   // Only care about the one template argument, two function parameter std::max
@@ -8218,7 +8348,7 @@
 
 void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) {
   // Disable warning in template instantiations.
-  if (!S.ActiveTemplateInstantiations.empty())
+  if (S.inTemplateInstantiation())
     return;
 
   BinaryOperatorKind op = E->getOpcode();
@@ -8248,7 +8378,7 @@
                                   Expr *Other, const llvm::APSInt &Value,
                                   bool RhsConstant) {
   // Disable warning in template instantiations.
-  if (!S.ActiveTemplateInstantiations.empty())
+  if (S.inTemplateInstantiation())
     return;
 
   // TODO: Investigate using GetExprRange() to get tighter bounds
@@ -8686,7 +8816,7 @@
 
                              SourceLocation CContext) {
   const bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);
-  const bool PruneWarnings = !S.ActiveTemplateInstantiations.empty();
+  const bool PruneWarnings = S.inTemplateInstantiation();
 
   Expr *InnerE = E->IgnoreParenImpCasts();
   // We also want to warn on, e.g., "int i = -1.234"
@@ -10592,6 +10722,12 @@
           CheckArrayAccess(rhs);
         return;
       }
+      case Stmt::CXXOperatorCallExprClass: {
+        const auto *OCE = cast<CXXOperatorCallExpr>(expr);
+        for (const auto *Arg : OCE->arguments())
+          CheckArrayAccess(Arg);
+        return;
+      }
       default:
         return;
     }
@@ -11297,7 +11433,7 @@
   if (Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
     return;
 
-  if (!ActiveTemplateInstantiations.empty())
+  if (inTemplateInstantiation())
     return;
 
   // Strip parens and casts away.
@@ -11816,11 +11952,16 @@
 
 void Sema::RefersToMemberWithReducedAlignment(
     Expr *E,
-    std::function<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action) {
+    llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)>
+        Action) {
   const auto *ME = dyn_cast<MemberExpr>(E);
   if (!ME)
     return;
 
+  // No need to check expressions with an __unaligned-qualified type.
+  if (E->getType().getQualifiers().hasUnaligned())
+    return;
+
   // For a chain of MemberExpr like "a.b.c.d" this list
   // will keep FieldDecl's like [d, c, b].
   SmallVector<FieldDecl *, 4> ReverseMemberChain;
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index d76bde5..ea4a33d 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1334,8 +1334,9 @@
       Builder.AddChunk(CodeCompletionString::CK_RightParen);
       Results.AddResult(Result(Builder.TakeString()));
     }
-  }
-  
+  } else
+    Results.AddResult(Result("__auto_type", CCP_Type));
+
   // GNU extensions
   if (LangOpts.GNUMode) {
     // FIXME: Enable when we actually support decimal floating point.
@@ -1370,6 +1371,21 @@
   // in C++0x as a type specifier.
   Results.AddResult(Result("extern"));
   Results.AddResult(Result("static"));
+
+  if (LangOpts.CPlusPlus11) {
+    CodeCompletionAllocator &Allocator = Results.getAllocator();
+    CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
+
+    // alignas
+    Builder.AddTypedTextChunk("alignas");
+    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
+    Builder.AddPlaceholderChunk("expression");
+    Builder.AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(Result(Builder.TakeString()));
+
+    Results.AddResult(Result("constexpr"));
+    Results.AddResult(Result("thread_local"));
+  }
 }
 
 static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
@@ -1527,6 +1543,21 @@
   Results.AddResult(CodeCompletionResult(Builder.TakeString()));
 }
 
+static void AddStaticAssertResult(CodeCompletionBuilder &Builder,
+                                  ResultBuilder &Results,
+                                  const LangOptions &LangOpts) {
+  if (!LangOpts.CPlusPlus11)
+    return;
+
+  Builder.AddTypedTextChunk("static_assert");
+  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
+  Builder.AddPlaceholderChunk("expression");
+  Builder.AddChunk(CodeCompletionString::CK_Comma);
+  Builder.AddPlaceholderChunk("message");
+  Builder.AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(CodeCompletionResult(Builder.TakeString()));
+}
+
 /// \brief Add language constructs that show up for "ordinary" names.
 static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
                                    Scope *S,
@@ -1611,6 +1642,8 @@
         Results.AddResult(Result(Builder.TakeString()));
       }
 
+      AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
+
       if (CCC == Sema::PCC_Class) {
         AddTypedefResult(Results);
 
@@ -1824,6 +1857,8 @@
     Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
     Builder.AddPlaceholderChunk("identifier");
     Results.AddResult(Result(Builder.TakeString()));
+
+    AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
   }
 
   // Fall through (for statement expressions).
@@ -2253,6 +2288,15 @@
   FunctionProtoTypeLoc BlockProto;
   findTypeLocationForBlockDecl(Param->getTypeSourceInfo(), Block, BlockProto,
                                SuppressBlock);
+  // Try to retrieve the block type information from the property if this is a
+  // parameter in a setter.
+  if (!Block && ObjCMethodParam &&
+      cast<ObjCMethodDecl>(Param->getDeclContext())->isPropertyAccessor()) {
+    if (const auto *PD = cast<ObjCMethodDecl>(Param->getDeclContext())
+                             ->findPropertyDecl(/*CheckOverrides=*/false))
+      findTypeLocationForBlockDecl(PD->getTypeSourceInfo(), Block, BlockProto,
+                                   SuppressBlock);
+  }
 
   if (!Block) {
     // We were unable to find a FunctionProtoTypeLoc with parameter names
@@ -2585,6 +2629,7 @@
                       Result.getAllocator().CopyString(ND->getNameAsString()));
     break;
       
+  case DeclarationName::CXXDeductionGuideName:
   case DeclarationName::CXXUsingDirective:
   case DeclarationName::ObjCZeroArgSelector:
   case DeclarationName::ObjCOneArgSelector:
@@ -3482,6 +3527,11 @@
     Results.AddResult(Result("restrict"));
 
   if (getLangOpts().CPlusPlus) {
+    if (getLangOpts().CPlusPlus11 &&
+        (DS.getTypeSpecType() == DeclSpec::TST_class ||
+         DS.getTypeSpecType() == DeclSpec::TST_struct))
+      Results.AddResult("final");
+
     if (AllowNonIdentifiers) {
       Results.AddResult(Result("operator")); 
     }
@@ -3720,9 +3770,17 @@
       Builder.AddPlaceholderChunk(
           Builder.getAllocator().CopyString(PlaceholderStr));
 
+      // When completing blocks properties that return void the default
+      // property completion result should show up before the setter,
+      // otherwise the setter completion should show up before the default
+      // property completion, as we normally want to use the result of the
+      // call.
       Results.MaybeAddResult(
           Result(Builder.TakeString(), P,
-                 Results.getBasePriority(P) + CCD_BlockPropertySetter),
+                 Results.getBasePriority(P) +
+                     (BlockLoc.getTypePtr()->getReturnType()->isVoidType()
+                          ? CCD_BlockPropertySetter
+                          : -CCD_BlockPropertySetter)),
           CurContext);
     }
   };
@@ -4004,30 +4062,54 @@
                             Results.data(),Results.size());
 }
 
+static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results,
+                                    const LangOptions &LangOpts) {
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
+    Results.AddResult("const");
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
+    Results.AddResult("volatile");
+  if (LangOpts.C99 && !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
+    Results.AddResult("restrict");
+  if (LangOpts.C11 && !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
+    Results.AddResult("_Atomic");
+  if (LangOpts.MSVCCompat && !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
+    Results.AddResult("__unaligned");
+}
+
 void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
                         CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_TypeQualifiers);
   Results.EnterNewScope();
-  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
-    Results.AddResult("const");
-  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
-    Results.AddResult("volatile");
-  if (getLangOpts().C99 &&
-      !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
-    Results.AddResult("restrict");
-  if (getLangOpts().C11 &&
-      !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
-    Results.AddResult("_Atomic");
-  if (getLangOpts().MSVCCompat &&
-      !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
-    Results.AddResult("__unaligned");
+  AddTypeQualifierResults(DS, Results, LangOpts);
   Results.ExitScope();
   HandleCodeCompleteResults(this, CodeCompleter, 
                             Results.getCompletionContext(),
                             Results.data(), Results.size());
 }
 
+void Sema::CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D,
+                                          const VirtSpecifiers *VS) {
+  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
+                        CodeCompletionContext::CCC_TypeQualifiers);
+  Results.EnterNewScope();
+  AddTypeQualifierResults(DS, Results, LangOpts);
+  if (LangOpts.CPlusPlus11) {
+    Results.AddResult("noexcept");
+    if (D.getContext() == Declarator::MemberContext && !D.isCtorOrDtor() &&
+        !D.isStaticMember()) {
+      if (!VS || !VS->isFinalSpecified())
+        Results.AddResult("final");
+      if (!VS || !VS->isOverrideSpecified())
+        Results.AddResult("override");
+    }
+  }
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
+}
+
 void Sema::CodeCompleteBracketDeclarator(Scope *S) {
   CodeCompleteExpression(S, QualType(getASTContext().getSizeType()));
 }
@@ -5222,24 +5304,22 @@
 /// when it has the same number of parameters as we have selector identifiers.
 ///
 /// \param Results the structure into which we'll add results.
-static void AddObjCMethods(ObjCContainerDecl *Container, 
-                           bool WantInstanceMethods,
-                           ObjCMethodKind WantKind,
+static void AddObjCMethods(ObjCContainerDecl *Container,
+                           bool WantInstanceMethods, ObjCMethodKind WantKind,
                            ArrayRef<IdentifierInfo *> SelIdents,
                            DeclContext *CurContext,
-                           VisitedSelectorSet &Selectors,
-                           bool AllowSameLength,
-                           ResultBuilder &Results,
-                           bool InOriginalClass = true) {
+                           VisitedSelectorSet &Selectors, bool AllowSameLength,
+                           ResultBuilder &Results, bool InOriginalClass = true,
+                           bool IsRootClass = false) {
   typedef CodeCompletionResult Result;
   Container = getContainerDef(Container);
   ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
-  bool isRootClass = IFace && !IFace->getSuperClass();
+  IsRootClass = IsRootClass || (IFace && !IFace->getSuperClass());
   for (auto *M : Container->methods()) {
     // The instance methods on the root class can be messaged via the
     // metaclass.
     if (M->isInstanceMethod() == WantInstanceMethods ||
-        (isRootClass && !WantInstanceMethods)) {
+        (IsRootClass && !WantInstanceMethods)) {
       // Check whether the selector identifiers we've been given are a 
       // subset of the identifiers for this particular method.
       if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength))
@@ -5265,8 +5345,8 @@
       for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
                                                 E = Protocols.end(); 
            I != E; ++I)
-        AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 
-                       CurContext, Selectors, AllowSameLength, Results, false);
+        AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                       Selectors, AllowSameLength, Results, false, IsRootClass);
     }
   }
   
@@ -5275,43 +5355,43 @@
   
   // Add methods in protocols.
   for (auto *I : IFace->protocols())
-    AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents,
-                   CurContext, Selectors, AllowSameLength, Results, false);
-  
+    AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                   Selectors, AllowSameLength, Results, false, IsRootClass);
+
   // Add methods in categories.
   for (auto *CatDecl : IFace->known_categories()) {
     AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
-                   CurContext, Selectors, AllowSameLength,
-                   Results, InOriginalClass);
-    
+                   CurContext, Selectors, AllowSameLength, Results,
+                   InOriginalClass, IsRootClass);
+
     // Add a categories protocol methods.
     const ObjCList<ObjCProtocolDecl> &Protocols 
       = CatDecl->getReferencedProtocols();
     for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
                                               E = Protocols.end();
          I != E; ++I)
-      AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 
-                     CurContext, Selectors, AllowSameLength,
-                     Results, false);
-    
+      AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                     Selectors, AllowSameLength, Results, false, IsRootClass);
+
     // Add methods in category implementations.
     if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
-      AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 
-                     CurContext, Selectors, AllowSameLength,
-                     Results, InOriginalClass);
+      AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                     Selectors, AllowSameLength, Results, InOriginalClass,
+                     IsRootClass);
   }
   
   // Add methods in superclass.
+  // Avoid passing in IsRootClass since root classes won't have super classes.
   if (IFace->getSuperClass())
-    AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, 
-                   SelIdents, CurContext, Selectors,
-                   AllowSameLength, Results, false);
+    AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
+                   SelIdents, CurContext, Selectors, AllowSameLength, Results,
+                   /*IsRootClass=*/false);
 
   // Add methods in our implementation, if any.
   if (ObjCImplementationDecl *Impl = IFace->getImplementation())
-    AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
-                   CurContext, Selectors, AllowSameLength,
-                   Results, InOriginalClass);
+    AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                   Selectors, AllowSameLength, Results, InOriginalClass,
+                   IsRootClass);
 }
 
 
@@ -7471,6 +7551,23 @@
   }
   
   Results.ExitScope();
+
+  if (!AtParameterName && !SelIdents.empty() &&
+      SelIdents.front()->getName().startswith("init")) {
+    for (const auto &M : PP.macros()) {
+      if (M.first->getName() != "NS_DESIGNATED_INITIALIZER")
+        continue;
+      Results.EnterNewScope();
+      CodeCompletionBuilder Builder(Results.getAllocator(),
+                                    Results.getCodeCompletionTUInfo());
+      Builder.AddTypedTextChunk(
+          Builder.getAllocator().CopyString(M.first->getName()));
+      Results.AddResult(CodeCompletionResult(Builder.TakeString(), CCP_Macro,
+                                             CXCursor_MacroDefinition));
+      Results.ExitScope();
+    }
+  }
+
   HandleCodeCompleteResults(this, CodeCompleter, 
                             CodeCompletionContext::CCC_Other,
                             Results.data(),Results.size());
diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp
index 3109358..4d0f8a8 100644
--- a/lib/Sema/SemaCoroutine.cpp
+++ b/lib/Sema/SemaCoroutine.cpp
@@ -21,21 +21,34 @@
 using namespace clang;
 using namespace sema;
 
+static bool lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD,
+                         SourceLocation Loc) {
+  DeclarationName DN = S.PP.getIdentifierInfo(Name);
+  LookupResult LR(S, DN, Loc, Sema::LookupMemberName);
+  // Suppress diagnostics when a private member is selected. The same warnings
+  // will be produced again when building the call.
+  LR.suppressDiagnostics();
+  return S.LookupQualifiedName(LR, RD);
+}
+
 /// Look up the std::coroutine_traits<...>::promise_type for the given
 /// function type.
 static QualType lookupPromiseType(Sema &S, const FunctionProtoType *FnType,
-                                  SourceLocation Loc) {
+                                  SourceLocation KwLoc,
+                                  SourceLocation FuncLoc) {
   // FIXME: Cache std::coroutine_traits once we've found it.
   NamespaceDecl *StdExp = S.lookupStdExperimentalNamespace();
   if (!StdExp) {
-    S.Diag(Loc, diag::err_implied_std_coroutine_traits_not_found);
+    S.Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
+        << "std::experimental::coroutine_traits";
     return QualType();
   }
 
   LookupResult Result(S, &S.PP.getIdentifierTable().get("coroutine_traits"),
-                      Loc, Sema::LookupOrdinaryName);
+                      FuncLoc, Sema::LookupOrdinaryName);
   if (!S.LookupQualifiedName(Result, StdExp)) {
-    S.Diag(Loc, diag::err_implied_std_coroutine_traits_not_found);
+    S.Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
+        << "std::experimental::coroutine_traits";
     return QualType();
   }
 
@@ -49,54 +62,105 @@
   }
 
   // Form template argument list for coroutine_traits<R, P1, P2, ...>.
-  TemplateArgumentListInfo Args(Loc, Loc);
+  TemplateArgumentListInfo Args(KwLoc, KwLoc);
   Args.addArgument(TemplateArgumentLoc(
       TemplateArgument(FnType->getReturnType()),
-      S.Context.getTrivialTypeSourceInfo(FnType->getReturnType(), Loc)));
+      S.Context.getTrivialTypeSourceInfo(FnType->getReturnType(), KwLoc)));
   // FIXME: If the function is a non-static member function, add the type
   // of the implicit object parameter before the formal parameters.
   for (QualType T : FnType->getParamTypes())
     Args.addArgument(TemplateArgumentLoc(
-        TemplateArgument(T), S.Context.getTrivialTypeSourceInfo(T, Loc)));
+        TemplateArgument(T), S.Context.getTrivialTypeSourceInfo(T, KwLoc)));
 
   // Build the template-id.
   QualType CoroTrait =
-      S.CheckTemplateIdType(TemplateName(CoroTraits), Loc, Args);
+      S.CheckTemplateIdType(TemplateName(CoroTraits), KwLoc, Args);
   if (CoroTrait.isNull())
     return QualType();
-  if (S.RequireCompleteType(Loc, CoroTrait,
-                            diag::err_coroutine_traits_missing_specialization))
+  if (S.RequireCompleteType(KwLoc, CoroTrait,
+                            diag::err_coroutine_type_missing_specialization))
     return QualType();
 
-  CXXRecordDecl *RD = CoroTrait->getAsCXXRecordDecl();
+  auto *RD = CoroTrait->getAsCXXRecordDecl();
   assert(RD && "specialization of class template is not a class?");
 
   // Look up the ::promise_type member.
-  LookupResult R(S, &S.PP.getIdentifierTable().get("promise_type"), Loc,
+  LookupResult R(S, &S.PP.getIdentifierTable().get("promise_type"), KwLoc,
                  Sema::LookupOrdinaryName);
   S.LookupQualifiedName(R, RD);
   auto *Promise = R.getAsSingle<TypeDecl>();
   if (!Promise) {
-    S.Diag(Loc, diag::err_implied_std_coroutine_traits_promise_type_not_found)
+    S.Diag(FuncLoc,
+           diag::err_implied_std_coroutine_traits_promise_type_not_found)
         << RD;
     return QualType();
   }
-
   // The promise type is required to be a class type.
   QualType PromiseType = S.Context.getTypeDeclType(Promise);
-  if (!PromiseType->getAsCXXRecordDecl()) {
-    // Use the fully-qualified name of the type.
+
+  auto buildElaboratedType = [&]() {
     auto *NNS = NestedNameSpecifier::Create(S.Context, nullptr, StdExp);
     NNS = NestedNameSpecifier::Create(S.Context, NNS, false,
                                       CoroTrait.getTypePtr());
-    PromiseType = S.Context.getElaboratedType(ETK_None, NNS, PromiseType);
+    return S.Context.getElaboratedType(ETK_None, NNS, PromiseType);
+  };
 
-    S.Diag(Loc, diag::err_implied_std_coroutine_traits_promise_type_not_class)
-        << PromiseType;
+  if (!PromiseType->getAsCXXRecordDecl()) {
+    S.Diag(FuncLoc,
+           diag::err_implied_std_coroutine_traits_promise_type_not_class)
+        << buildElaboratedType();
+    return QualType();
+  }
+  if (S.RequireCompleteType(FuncLoc, buildElaboratedType(),
+                            diag::err_coroutine_promise_type_incomplete))
+    return QualType();
+
+  return PromiseType;
+}
+
+/// Look up the std::coroutine_traits<...>::promise_type for the given
+/// function type.
+static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType,
+                                          SourceLocation Loc) {
+  if (PromiseType.isNull())
+    return QualType();
+
+  NamespaceDecl *StdExp = S.lookupStdExperimentalNamespace();
+  assert(StdExp && "Should already be diagnosed");
+
+  LookupResult Result(S, &S.PP.getIdentifierTable().get("coroutine_handle"),
+                      Loc, Sema::LookupOrdinaryName);
+  if (!S.LookupQualifiedName(Result, StdExp)) {
+    S.Diag(Loc, diag::err_implied_coroutine_type_not_found)
+        << "std::experimental::coroutine_handle";
     return QualType();
   }
 
-  return PromiseType;
+  ClassTemplateDecl *CoroHandle = Result.getAsSingle<ClassTemplateDecl>();
+  if (!CoroHandle) {
+    Result.suppressDiagnostics();
+    // We found something weird. Complain about the first thing we found.
+    NamedDecl *Found = *Result.begin();
+    S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_handle);
+    return QualType();
+  }
+
+  // Form template argument list for coroutine_handle<Promise>.
+  TemplateArgumentListInfo Args(Loc, Loc);
+  Args.addArgument(TemplateArgumentLoc(
+      TemplateArgument(PromiseType),
+      S.Context.getTrivialTypeSourceInfo(PromiseType, Loc)));
+
+  // Build the template-id.
+  QualType CoroHandleType =
+      S.CheckTemplateIdType(TemplateName(CoroHandle), Loc, Args);
+  if (CoroHandleType.isNull())
+    return QualType();
+  if (S.RequireCompleteType(Loc, CoroHandleType,
+                            diag::err_coroutine_type_missing_specialization))
+    return QualType();
+
+  return CoroHandleType;
 }
 
 static bool isValidCoroutineContext(Sema &S, SourceLocation Loc,
@@ -160,41 +224,48 @@
   return !Diagnosed;
 }
 
-/// Check that this is a context in which a coroutine suspension can appear.
-static FunctionScopeInfo *checkCoroutineContext(Sema &S, SourceLocation Loc,
-                                                StringRef Keyword) {
-  if (!isValidCoroutineContext(S, Loc, Keyword))
-    return nullptr;
+static ExprResult buildOperatorCoawaitLookupExpr(Sema &SemaRef, Scope *S,
+                                                 SourceLocation Loc) {
+  DeclarationName OpName =
+      SemaRef.Context.DeclarationNames.getCXXOperatorName(OO_Coawait);
+  LookupResult Operators(SemaRef, OpName, SourceLocation(),
+                         Sema::LookupOperatorName);
+  SemaRef.LookupName(Operators, S);
 
-  assert(isa<FunctionDecl>(S.CurContext) && "not in a function scope");
-  auto *FD = cast<FunctionDecl>(S.CurContext);
-  auto *ScopeInfo = S.getCurFunction();
-  assert(ScopeInfo && "missing function scope for function");
+  assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
+  const auto &Functions = Operators.asUnresolvedSet();
+  bool IsOverloaded =
+      Functions.size() > 1 ||
+      (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
+  Expr *CoawaitOp = UnresolvedLookupExpr::Create(
+      SemaRef.Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
+      DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, IsOverloaded,
+      Functions.begin(), Functions.end());
+  assert(CoawaitOp);
+  return CoawaitOp;
+}
 
-  // If we don't have a promise variable, build one now.
-  if (!ScopeInfo->CoroutinePromise) {
-    QualType T = FD->getType()->isDependentType()
-                     ? S.Context.DependentTy
-                     : lookupPromiseType(
-                           S, FD->getType()->castAs<FunctionProtoType>(), Loc);
-    if (T.isNull())
-      return nullptr;
+/// Build a call to 'operator co_await' if there is a suitable operator for
+/// the given expression.
+static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, SourceLocation Loc,
+                                           Expr *E,
+                                           UnresolvedLookupExpr *Lookup) {
+  UnresolvedSet<16> Functions;
+  Functions.append(Lookup->decls_begin(), Lookup->decls_end());
+  return SemaRef.CreateOverloadedUnaryOp(Loc, UO_Coawait, Functions, E);
+}
 
-    // Create and default-initialize the promise.
-    ScopeInfo->CoroutinePromise =
-        VarDecl::Create(S.Context, FD, FD->getLocation(), FD->getLocation(),
-                        &S.PP.getIdentifierTable().get("__promise"), T,
-                        S.Context.getTrivialTypeSourceInfo(T, Loc), SC_None);
-    S.CheckVariableDeclarationType(ScopeInfo->CoroutinePromise);
-    if (!ScopeInfo->CoroutinePromise->isInvalidDecl())
-      S.ActOnUninitializedDecl(ScopeInfo->CoroutinePromise, false);
-  }
-
-  return ScopeInfo;
+static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S,
+                                           SourceLocation Loc, Expr *E) {
+  ExprResult R = buildOperatorCoawaitLookupExpr(SemaRef, S, Loc);
+  if (R.isInvalid())
+    return ExprError();
+  return buildOperatorCoawaitCall(SemaRef, Loc, E,
+                                  cast<UnresolvedLookupExpr>(R.get()));
 }
 
 static Expr *buildBuiltinCall(Sema &S, SourceLocation Loc, Builtin::ID Id,
-                              MutableArrayRef<Expr *> CallArgs) {
+                              MultiExprArg CallArgs) {
   StringRef Name = S.Context.BuiltinInfo.getName(Id);
   LookupResult R(S, &S.Context.Idents.get(Name), Loc, Sema::LookupOrdinaryName);
   S.LookupName(R, S.TUScope, /*AllowBuiltinCreation=*/true);
@@ -213,24 +284,41 @@
   return Call.get();
 }
 
-/// Build a call to 'operator co_await' if there is a suitable operator for
-/// the given expression.
-static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S,
-                                           SourceLocation Loc, Expr *E) {
-  UnresolvedSet<16> Functions;
-  SemaRef.LookupOverloadedOperatorName(OO_Coawait, S, E->getType(), QualType(),
-                                       Functions);
-  return SemaRef.CreateOverloadedUnaryOp(Loc, UO_Coawait, Functions, E);
+static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType,
+                                       SourceLocation Loc) {
+  QualType CoroHandleType = lookupCoroutineHandleType(S, PromiseType, Loc);
+  if (CoroHandleType.isNull())
+    return ExprError();
+
+  DeclContext *LookupCtx = S.computeDeclContext(CoroHandleType);
+  LookupResult Found(S, &S.PP.getIdentifierTable().get("from_address"), Loc,
+                     Sema::LookupOrdinaryName);
+  if (!S.LookupQualifiedName(Found, LookupCtx)) {
+    S.Diag(Loc, diag::err_coroutine_handle_missing_member)
+        << "from_address";
+    return ExprError();
+  }
+
+  Expr *FramePtr =
+      buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_frame, {});
+
+  CXXScopeSpec SS;
+  ExprResult FromAddr =
+      S.BuildDeclarationNameExpr(SS, Found, /*NeedsADL=*/false);
+  if (FromAddr.isInvalid())
+    return ExprError();
+
+  return S.ActOnCallExpr(nullptr, FromAddr.get(), Loc, FramePtr, Loc);
 }
 
 struct ReadySuspendResumeResult {
-  bool IsInvalid;
   Expr *Results[3];
+  OpaqueValueExpr *OpaqueValue;
+  bool IsInvalid;
 };
 
 static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc,
-                                  StringRef Name,
-                                  MutableArrayRef<Expr *> Args) {
+                                  StringRef Name, MultiExprArg Args) {
   DeclarationNameInfo NameInfo(&S.PP.getIdentifierTable().get(Name), Loc);
 
   // FIXME: Fix BuildMemberReferenceExpr to take a const CXXScopeSpec&.
@@ -247,18 +335,23 @@
 
 /// Build calls to await_ready, await_suspend, and await_resume for a co_await
 /// expression.
-static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, SourceLocation Loc,
-                                                  Expr *E) {
+static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise,
+                                                  SourceLocation Loc, Expr *E) {
+  OpaqueValueExpr *Operand = new (S.Context)
+      OpaqueValueExpr(Loc, E->getType(), VK_LValue, E->getObjectKind(), E);
+
   // Assume invalid until we see otherwise.
-  ReadySuspendResumeResult Calls = {true, {}};
+  ReadySuspendResumeResult Calls = {{}, Operand, /*IsInvalid=*/true};
+
+  ExprResult CoroHandleRes = buildCoroutineHandle(S, CoroPromise->getType(), Loc);
+  if (CoroHandleRes.isInvalid())
+    return Calls;
+  Expr *CoroHandle = CoroHandleRes.get();
 
   const StringRef Funcs[] = {"await_ready", "await_suspend", "await_resume"};
+  MultiExprArg Args[] = {None, CoroHandle, None};
   for (size_t I = 0, N = llvm::array_lengthof(Funcs); I != N; ++I) {
-    Expr *Operand = new (S.Context) OpaqueValueExpr(
-      Loc, E->getType(), VK_LValue, E->getObjectKind(), E);
-
-    // FIXME: Pass coroutine handle to await_suspend.
-    ExprResult Result = buildMemberCall(S, Operand, Loc, Funcs[I], None);
+    ExprResult Result = buildMemberCall(S, Operand, Loc, Funcs[I], Args[I]);
     if (Result.isInvalid())
       return Calls;
     Calls.Results[I] = Result.get();
@@ -268,26 +361,177 @@
   return Calls;
 }
 
+static ExprResult buildPromiseCall(Sema &S, VarDecl *Promise,
+                                   SourceLocation Loc, StringRef Name,
+                                   MultiExprArg Args) {
+
+  // Form a reference to the promise.
+  ExprResult PromiseRef = S.BuildDeclRefExpr(
+      Promise, Promise->getType().getNonReferenceType(), VK_LValue, Loc);
+  if (PromiseRef.isInvalid())
+    return ExprError();
+
+  // Call 'yield_value', passing in E.
+  return buildMemberCall(S, PromiseRef.get(), Loc, Name, Args);
+}
+
+VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
+  assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
+  auto *FD = cast<FunctionDecl>(CurContext);
+
+  QualType T =
+      FD->getType()->isDependentType()
+          ? Context.DependentTy
+          : lookupPromiseType(*this, FD->getType()->castAs<FunctionProtoType>(),
+                              Loc, FD->getLocation());
+  if (T.isNull())
+    return nullptr;
+
+  auto *VD = VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
+                             &PP.getIdentifierTable().get("__promise"), T,
+                             Context.getTrivialTypeSourceInfo(T, Loc), SC_None);
+  CheckVariableDeclarationType(VD);
+  if (VD->isInvalidDecl())
+    return nullptr;
+  ActOnUninitializedDecl(VD);
+  assert(!VD->isInvalidDecl());
+  return VD;
+}
+
+/// Check that this is a context in which a coroutine suspension can appear.
+static FunctionScopeInfo *checkCoroutineContext(Sema &S, SourceLocation Loc,
+                                                StringRef Keyword,
+                                                bool IsImplicit = false) {
+  if (!isValidCoroutineContext(S, Loc, Keyword))
+    return nullptr;
+
+  assert(isa<FunctionDecl>(S.CurContext) && "not in a function scope");
+
+  auto *ScopeInfo = S.getCurFunction();
+  assert(ScopeInfo && "missing function scope for function");
+
+  if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
+    ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
+
+  if (ScopeInfo->CoroutinePromise)
+    return ScopeInfo;
+
+  ScopeInfo->CoroutinePromise = S.buildCoroutinePromise(Loc);
+  if (!ScopeInfo->CoroutinePromise)
+    return nullptr;
+
+  return ScopeInfo;
+}
+
+static bool actOnCoroutineBodyStart(Sema &S, Scope *SC, SourceLocation KWLoc,
+                                    StringRef Keyword) {
+  if (!checkCoroutineContext(S, KWLoc, Keyword))
+    return false;
+  auto *ScopeInfo = S.getCurFunction();
+  assert(ScopeInfo->CoroutinePromise);
+
+  // If we have existing coroutine statements then we have already built
+  // the initial and final suspend points.
+  if (!ScopeInfo->NeedsCoroutineSuspends)
+    return true;
+
+  ScopeInfo->setNeedsCoroutineSuspends(false);
+
+  auto *Fn = cast<FunctionDecl>(S.CurContext);
+  SourceLocation Loc = Fn->getLocation();
+  // Build the initial suspend point
+  auto buildSuspends = [&](StringRef Name) mutable -> StmtResult {
+    ExprResult Suspend =
+        buildPromiseCall(S, ScopeInfo->CoroutinePromise, Loc, Name, None);
+    if (Suspend.isInvalid())
+      return StmtError();
+    Suspend = buildOperatorCoawaitCall(S, SC, Loc, Suspend.get());
+    if (Suspend.isInvalid())
+      return StmtError();
+    Suspend = S.BuildResolvedCoawaitExpr(Loc, Suspend.get(),
+                                         /*IsImplicit*/ true);
+    Suspend = S.ActOnFinishFullExpr(Suspend.get());
+    if (Suspend.isInvalid()) {
+      S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
+          << ((Name == "initial_suspend") ? 0 : 1);
+      S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
+      return StmtError();
+    }
+    return cast<Stmt>(Suspend.get());
+  };
+
+  StmtResult InitSuspend = buildSuspends("initial_suspend");
+  if (InitSuspend.isInvalid())
+    return true;
+
+  StmtResult FinalSuspend = buildSuspends("final_suspend");
+  if (FinalSuspend.isInvalid())
+    return true;
+
+  ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
+
+  return true;
+}
+
 ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
-  auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await");
-  if (!Coroutine) {
+  if (!actOnCoroutineBodyStart(*this, S, Loc, "co_await")) {
     CorrectDelayedTyposInExpr(E);
     return ExprError();
   }
+
   if (E->getType()->isPlaceholderType()) {
     ExprResult R = CheckPlaceholderExpr(E);
     if (R.isInvalid()) return ExprError();
     E = R.get();
   }
+  ExprResult Lookup = buildOperatorCoawaitLookupExpr(*this, S, Loc);
+  if (Lookup.isInvalid())
+    return ExprError();
+  return BuildUnresolvedCoawaitExpr(Loc, E,
+                                   cast<UnresolvedLookupExpr>(Lookup.get()));
+}
 
-  ExprResult Awaitable = buildOperatorCoawaitCall(*this, S, Loc, E);
+ExprResult Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *E,
+                                            UnresolvedLookupExpr *Lookup) {
+  auto *FSI = checkCoroutineContext(*this, Loc, "co_await");
+  if (!FSI)
+    return ExprError();
+
+  if (E->getType()->isPlaceholderType()) {
+    ExprResult R = CheckPlaceholderExpr(E);
+    if (R.isInvalid())
+      return ExprError();
+    E = R.get();
+  }
+
+  auto *Promise = FSI->CoroutinePromise;
+  if (Promise->getType()->isDependentType()) {
+    Expr *Res =
+        new (Context) DependentCoawaitExpr(Loc, Context.DependentTy, E, Lookup);
+    return Res;
+  }
+
+  auto *RD = Promise->getType()->getAsCXXRecordDecl();
+  if (lookupMember(*this, "await_transform", RD, Loc)) {
+    ExprResult R = buildPromiseCall(*this, Promise, Loc, "await_transform", E);
+    if (R.isInvalid()) {
+      Diag(Loc,
+           diag::note_coroutine_promise_implicit_await_transform_required_here)
+          << E->getSourceRange();
+      return ExprError();
+    }
+    E = R.get();
+  }
+  ExprResult Awaitable = buildOperatorCoawaitCall(*this, Loc, E, Lookup);
   if (Awaitable.isInvalid())
     return ExprError();
 
-  return BuildCoawaitExpr(Loc, Awaitable.get());
+  return BuildResolvedCoawaitExpr(Loc, Awaitable.get());
 }
-ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) {
-  auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await");
+
+ExprResult Sema::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *E,
+                                  bool IsImplicit) {
+  auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await", IsImplicit);
   if (!Coroutine)
     return ExprError();
 
@@ -298,8 +542,8 @@
   }
 
   if (E->getType()->isDependentType()) {
-    Expr *Res = new (Context) CoawaitExpr(Loc, Context.DependentTy, E);
-    Coroutine->CoroutineStmts.push_back(Res);
+    Expr *Res = new (Context)
+        CoawaitExpr(Loc, Context.DependentTy, E, IsImplicit);
     return Res;
   }
 
@@ -309,42 +553,27 @@
     E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
 
   // Build the await_ready, await_suspend, await_resume calls.
-  ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
+  ReadySuspendResumeResult RSS =
+      buildCoawaitCalls(*this, Coroutine->CoroutinePromise, Loc, E);
   if (RSS.IsInvalid)
     return ExprError();
 
-  Expr *Res = new (Context) CoawaitExpr(Loc, E, RSS.Results[0], RSS.Results[1],
-                                        RSS.Results[2]);
-  Coroutine->CoroutineStmts.push_back(Res);
+  Expr *Res =
+      new (Context) CoawaitExpr(Loc, E, RSS.Results[0], RSS.Results[1],
+                                RSS.Results[2], RSS.OpaqueValue, IsImplicit);
+
   return Res;
 }
 
-static ExprResult buildPromiseCall(Sema &S, FunctionScopeInfo *Coroutine,
-                                   SourceLocation Loc, StringRef Name,
-                                   MutableArrayRef<Expr *> Args) {
-  assert(Coroutine->CoroutinePromise && "no promise for coroutine");
-
-  // Form a reference to the promise.
-  auto *Promise = Coroutine->CoroutinePromise;
-  ExprResult PromiseRef = S.BuildDeclRefExpr(
-      Promise, Promise->getType().getNonReferenceType(), VK_LValue, Loc);
-  if (PromiseRef.isInvalid())
-    return ExprError();
-
-  // Call 'yield_value', passing in E.
-  return buildMemberCall(S, PromiseRef.get(), Loc, Name, Args);
-}
-
 ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
-  auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
-  if (!Coroutine) {
+  if (!actOnCoroutineBodyStart(*this, S, Loc, "co_yield")) {
     CorrectDelayedTyposInExpr(E);
     return ExprError();
   }
 
   // Build yield_value call.
-  ExprResult Awaitable =
-      buildPromiseCall(*this, Coroutine, Loc, "yield_value", E);
+  ExprResult Awaitable = buildPromiseCall(
+      *this, getCurFunction()->CoroutinePromise, Loc, "yield_value", E);
   if (Awaitable.isInvalid())
     return ExprError();
 
@@ -368,7 +597,6 @@
 
   if (E->getType()->isDependentType()) {
     Expr *Res = new (Context) CoyieldExpr(Loc, Context.DependentTy, E);
-    Coroutine->CoroutineStmts.push_back(Res);
     return Res;
   }
 
@@ -378,28 +606,29 @@
     E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
 
   // Build the await_ready, await_suspend, await_resume calls.
-  ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
+  ReadySuspendResumeResult RSS =
+      buildCoawaitCalls(*this, Coroutine->CoroutinePromise, Loc, E);
   if (RSS.IsInvalid)
     return ExprError();
 
   Expr *Res = new (Context) CoyieldExpr(Loc, E, RSS.Results[0], RSS.Results[1],
-                                        RSS.Results[2]);
-  Coroutine->CoroutineStmts.push_back(Res);
+                                        RSS.Results[2], RSS.OpaqueValue);
+
   return Res;
 }
 
-StmtResult Sema::ActOnCoreturnStmt(SourceLocation Loc, Expr *E) {
-  auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return");
-  if (!Coroutine) {
+StmtResult Sema::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *E) {
+  if (!actOnCoroutineBodyStart(*this, S, Loc, "co_return")) {
     CorrectDelayedTyposInExpr(E);
     return StmtError();
   }
   return BuildCoreturnStmt(Loc, E);
 }
 
-StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E) {
-  auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return");
-  if (!Coroutine)
+StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
+                                   bool IsImplicit) {
+  auto *FSI = checkCoroutineContext(*this, Loc, "co_return", IsImplicit);
+  if (!FSI)
     return StmtError();
 
   if (E && E->getType()->isPlaceholderType() &&
@@ -412,20 +641,20 @@
   // FIXME: If the operand is a reference to a variable that's about to go out
   // of scope, we should treat the operand as an xvalue for this overload
   // resolution.
+  VarDecl *Promise = FSI->CoroutinePromise;
   ExprResult PC;
   if (E && (isa<InitListExpr>(E) || !E->getType()->isVoidType())) {
-    PC = buildPromiseCall(*this, Coroutine, Loc, "return_value", E);
+    PC = buildPromiseCall(*this, Promise, Loc, "return_value", E);
   } else {
     E = MakeFullDiscardedValueExpr(E).get();
-    PC = buildPromiseCall(*this, Coroutine, Loc, "return_void", None);
+    PC = buildPromiseCall(*this, Promise, Loc, "return_void", None);
   }
   if (PC.isInvalid())
     return StmtError();
 
   Expr *PCE = ActOnFinishFullExpr(PC.get()).get();
 
-  Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE);
-  Coroutine->CoroutineStmts.push_back(Res);
+  Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
   return Res;
 }
 
@@ -482,14 +711,103 @@
   return OperatorDelete;
 }
 
-// Builds allocation and deallocation for the coroutine. Returns false on
-// failure.
-static bool buildAllocationAndDeallocation(Sema &S, SourceLocation Loc,
-                                           FunctionScopeInfo *Fn,
-                                           Expr *&Allocation,
-                                           Stmt *&Deallocation) {
-  TypeSourceInfo *TInfo = Fn->CoroutinePromise->getTypeSourceInfo();
-  QualType PromiseType = TInfo->getType();
+namespace {
+class SubStmtBuilder : public CoroutineBodyStmt::CtorArgs {
+  Sema &S;
+  FunctionDecl &FD;
+  FunctionScopeInfo &Fn;
+  bool IsValid;
+  SourceLocation Loc;
+  QualType RetType;
+  SmallVector<Stmt *, 4> ParamMovesVector;
+  const bool IsPromiseDependentType;
+  CXXRecordDecl *PromiseRecordDecl = nullptr;
+
+public:
+  SubStmtBuilder(Sema &S, FunctionDecl &FD, FunctionScopeInfo &Fn, Stmt *Body)
+      : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
+        IsPromiseDependentType(
+            !Fn.CoroutinePromise ||
+            Fn.CoroutinePromise->getType()->isDependentType()) {
+    this->Body = Body;
+    if (!IsPromiseDependentType) {
+      PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl();
+      assert(PromiseRecordDecl && "Type should have already been checked");
+    }
+    this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend() &&
+                    makeOnException() && makeOnFallthrough() &&
+                    makeNewAndDeleteExpr() && makeReturnObject() &&
+                    makeParamMoves();
+  }
+
+  bool isInvalid() const { return !this->IsValid; }
+
+  bool makePromiseStmt();
+  bool makeInitialAndFinalSuspend();
+  bool makeNewAndDeleteExpr();
+  bool makeOnFallthrough();
+  bool makeOnException();
+  bool makeReturnObject();
+  bool makeParamMoves();
+};
+}
+
+void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) {
+  FunctionScopeInfo *Fn = getCurFunction();
+  assert(Fn && Fn->CoroutinePromise && "not a coroutine");
+
+  if (!Body) {
+    assert(FD->isInvalidDecl() &&
+           "a null body is only allowed for invalid declarations");
+    return;
+  }
+
+  if (isa<CoroutineBodyStmt>(Body)) {
+    // FIXME(EricWF): Nothing todo. the body is already a transformed coroutine
+    // body statement.
+    return;
+  }
+
+  // Coroutines [stmt.return]p1:
+  //   A return statement shall not appear in a coroutine.
+  if (Fn->FirstReturnLoc.isValid()) {
+    assert(Fn->FirstCoroutineStmtLoc.isValid() &&
+                   "first coroutine location not set");
+    Diag(Fn->FirstReturnLoc, diag::err_return_in_coroutine);
+    Diag(Fn->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
+            << Fn->getFirstCoroutineStmtKeyword();
+  }
+  SubStmtBuilder Builder(*this, *FD, *Fn, Body);
+  if (Builder.isInvalid())
+    return FD->setInvalidDecl();
+
+  // Build body for the coroutine wrapper statement.
+  Body = CoroutineBodyStmt::Create(Context, Builder);
+}
+
+bool SubStmtBuilder::makePromiseStmt() {
+  // Form a declaration statement for the promise declaration, so that AST
+  // visitors can more easily find it.
+  StmtResult PromiseStmt =
+      S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(Fn.CoroutinePromise), Loc, Loc);
+  if (PromiseStmt.isInvalid())
+    return false;
+
+  this->Promise = PromiseStmt.get();
+  return true;
+}
+
+bool SubStmtBuilder::makeInitialAndFinalSuspend() {
+  if (Fn.hasInvalidCoroutineSuspends())
+    return false;
+  this->InitialSuspend = cast<Expr>(Fn.CoroutineSuspends.first);
+  this->FinalSuspend = cast<Expr>(Fn.CoroutineSuspends.second);
+  return true;
+}
+
+bool SubStmtBuilder::makeNewAndDeleteExpr() {
+  // Form and check allocation and deallocation calls.
+  QualType PromiseType = Fn.CoroutinePromise->getType();
   if (PromiseType->isDependentType())
     return true;
 
@@ -532,8 +850,6 @@
   if (NewExpr.isInvalid())
     return false;
 
-  Allocation = NewExpr.get();
-
   // Make delete call.
 
   QualType OpDeleteQualType = OperatorDelete->getType();
@@ -559,149 +875,110 @@
   if (DeleteExpr.isInvalid())
     return false;
 
-  Deallocation = DeleteExpr.get();
+  this->Allocate = NewExpr.get();
+  this->Deallocate = DeleteExpr.get();
 
   return true;
 }
 
-void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) {
-  FunctionScopeInfo *Fn = getCurFunction();
-  assert(Fn && !Fn->CoroutineStmts.empty() && "not a coroutine");
+bool SubStmtBuilder::makeOnFallthrough() {
+  if (!PromiseRecordDecl)
+    return true;
 
-  // Coroutines [stmt.return]p1:
-  //   A return statement shall not appear in a coroutine.
-  if (Fn->FirstReturnLoc.isValid()) {
-    Diag(Fn->FirstReturnLoc, diag::err_return_in_coroutine);
-    auto *First = Fn->CoroutineStmts[0];
-    Diag(First->getLocStart(), diag::note_declared_coroutine_here)
-        << (isa<CoawaitExpr>(First) ? 0 :
-            isa<CoyieldExpr>(First) ? 1 : 2);
-  }
+  // [dcl.fct.def.coroutine]/4
+  // The unqualified-ids 'return_void' and 'return_value' are looked up in
+  // the scope of class P. If both are found, the program is ill-formed.
+  const bool HasRVoid = lookupMember(S, "return_void", PromiseRecordDecl, Loc);
+  const bool HasRValue = lookupMember(S, "return_value", PromiseRecordDecl, Loc);
 
-  bool AnyCoawaits = false;
-  bool AnyCoyields = false;
-  for (auto *CoroutineStmt : Fn->CoroutineStmts) {
-    AnyCoawaits |= isa<CoawaitExpr>(CoroutineStmt);
-    AnyCoyields |= isa<CoyieldExpr>(CoroutineStmt);
-  }
-
-  if (!AnyCoawaits && !AnyCoyields)
-    Diag(Fn->CoroutineStmts.front()->getLocStart(),
-         diag::ext_coroutine_without_co_await_co_yield);
-
-  SourceLocation Loc = FD->getLocation();
-
-  // Form a declaration statement for the promise declaration, so that AST
-  // visitors can more easily find it.
-  StmtResult PromiseStmt =
-      ActOnDeclStmt(ConvertDeclToDeclGroup(Fn->CoroutinePromise), Loc, Loc);
-  if (PromiseStmt.isInvalid())
-    return FD->setInvalidDecl();
-
-  // Form and check implicit 'co_await p.initial_suspend();' statement.
-  ExprResult InitialSuspend =
-      buildPromiseCall(*this, Fn, Loc, "initial_suspend", None);
-  // FIXME: Support operator co_await here.
-  if (!InitialSuspend.isInvalid())
-    InitialSuspend = BuildCoawaitExpr(Loc, InitialSuspend.get());
-  InitialSuspend = ActOnFinishFullExpr(InitialSuspend.get());
-  if (InitialSuspend.isInvalid())
-    return FD->setInvalidDecl();
-
-  // Form and check implicit 'co_await p.final_suspend();' statement.
-  ExprResult FinalSuspend =
-      buildPromiseCall(*this, Fn, Loc, "final_suspend", None);
-  // FIXME: Support operator co_await here.
-  if (!FinalSuspend.isInvalid())
-    FinalSuspend = BuildCoawaitExpr(Loc, FinalSuspend.get());
-  FinalSuspend = ActOnFinishFullExpr(FinalSuspend.get());
-  if (FinalSuspend.isInvalid())
-    return FD->setInvalidDecl();
-
-  // Form and check allocation and deallocation calls.
-  Expr *Allocation = nullptr;
-  Stmt *Deallocation = nullptr;
-  if (!buildAllocationAndDeallocation(*this, Loc, Fn, Allocation, Deallocation))
-    return FD->setInvalidDecl();
-
-  // control flowing off the end of the coroutine.
-  // Also try to form 'p.set_exception(std::current_exception());' to handle
-  // uncaught exceptions.
-  ExprResult SetException;
   StmtResult Fallthrough;
-  if (Fn->CoroutinePromise &&
-      !Fn->CoroutinePromise->getType()->isDependentType()) {
-    CXXRecordDecl *RD = Fn->CoroutinePromise->getType()->getAsCXXRecordDecl();
-    assert(RD && "Type should have already been checked");
-    // [dcl.fct.def.coroutine]/4
-    // The unqualified-ids 'return_void' and 'return_value' are looked up in
-    // the scope of class P. If both are found, the program is ill-formed.
-    DeclarationName RVoidDN = PP.getIdentifierInfo("return_void");
-    LookupResult RVoidResult(*this, RVoidDN, Loc, Sema::LookupMemberName);
-    const bool HasRVoid = LookupQualifiedName(RVoidResult, RD);
-
-    DeclarationName RValueDN = PP.getIdentifierInfo("return_value");
-    LookupResult RValueResult(*this, RValueDN, Loc, Sema::LookupMemberName);
-    const bool HasRValue = LookupQualifiedName(RValueResult, RD);
-
-    if (HasRVoid && HasRValue) {
-      // FIXME Improve this diagnostic
-      Diag(FD->getLocation(), diag::err_coroutine_promise_return_ill_formed)
-          << RD;
-      return FD->setInvalidDecl();
-    } else if (HasRVoid) {
-      // If the unqualified-id return_void is found, flowing off the end of a
-      // coroutine is equivalent to a co_return with no operand. Otherwise,
-      // flowing off the end of a coroutine results in undefined behavior.
-      Fallthrough = BuildCoreturnStmt(FD->getLocation(), nullptr);
-      Fallthrough = ActOnFinishFullStmt(Fallthrough.get());
-      if (Fallthrough.isInvalid())
-        return FD->setInvalidDecl();
-    }
-
-    // [dcl.fct.def.coroutine]/3
-    // The unqualified-id set_exception is found in the scope of P by class
-    // member access lookup (3.4.5).
-    DeclarationName SetExDN = PP.getIdentifierInfo("set_exception");
-    LookupResult SetExResult(*this, SetExDN, Loc, Sema::LookupMemberName);
-    if (LookupQualifiedName(SetExResult, RD)) {
-      // Form the call 'p.set_exception(std::current_exception())'
-      SetException = buildStdCurrentExceptionCall(*this, Loc);
-      if (SetException.isInvalid())
-        return FD->setInvalidDecl();
-      Expr *E = SetException.get();
-      SetException = buildPromiseCall(*this, Fn, Loc, "set_exception", E);
-      SetException = ActOnFinishFullExpr(SetException.get(), Loc);
-      if (SetException.isInvalid())
-        return FD->setInvalidDecl();
-    }
+  if (HasRVoid && HasRValue) {
+    // FIXME Improve this diagnostic
+    S.Diag(FD.getLocation(), diag::err_coroutine_promise_return_ill_formed)
+        << PromiseRecordDecl;
+    return false;
+  } else if (HasRVoid) {
+    // If the unqualified-id return_void is found, flowing off the end of a
+    // coroutine is equivalent to a co_return with no operand. Otherwise,
+    // flowing off the end of a coroutine results in undefined behavior.
+    Fallthrough = S.BuildCoreturnStmt(FD.getLocation(), nullptr,
+                                      /*IsImplicit*/false);
+    Fallthrough = S.ActOnFinishFullStmt(Fallthrough.get());
+    if (Fallthrough.isInvalid())
+      return false;
   }
 
+  this->OnFallthrough = Fallthrough.get();
+  return true;
+}
+
+bool SubStmtBuilder::makeOnException() {
+  // Try to form 'p.set_exception(std::current_exception());' to handle
+  // uncaught exceptions.
+  // TODO: Post WG21 Issaquah 2016 renamed set_exception to unhandled_exception
+  // TODO: and dropped exception_ptr parameter. Make it so.
+
+  if (!PromiseRecordDecl)
+    return true;
+
+  // If exceptions are disabled, don't try to build OnException.
+  if (!S.getLangOpts().CXXExceptions)
+    return true;
+
+  ExprResult SetException;
+
+  // [dcl.fct.def.coroutine]/3
+  // The unqualified-id set_exception is found in the scope of P by class
+  // member access lookup (3.4.5).
+  if (lookupMember(S, "set_exception", PromiseRecordDecl, Loc)) {
+    // Form the call 'p.set_exception(std::current_exception())'
+    SetException = buildStdCurrentExceptionCall(S, Loc);
+    if (SetException.isInvalid())
+      return false;
+    Expr *E = SetException.get();
+    SetException = buildPromiseCall(S, Fn.CoroutinePromise, Loc, "set_exception", E);
+    SetException = S.ActOnFinishFullExpr(SetException.get(), Loc);
+    if (SetException.isInvalid())
+      return false;
+  }
+
+  this->OnException = SetException.get();
+  return true;
+}
+
+bool SubStmtBuilder::makeReturnObject() {
+
   // Build implicit 'p.get_return_object()' expression and form initialization
   // of return type from it.
   ExprResult ReturnObject =
-      buildPromiseCall(*this, Fn, Loc, "get_return_object", None);
+      buildPromiseCall(S, Fn.CoroutinePromise, Loc, "get_return_object", None);
   if (ReturnObject.isInvalid())
-    return FD->setInvalidDecl();
-  QualType RetType = FD->getReturnType();
+    return false;
+  QualType RetType = FD.getReturnType();
   if (!RetType->isDependentType()) {
     InitializedEntity Entity =
         InitializedEntity::InitializeResult(Loc, RetType, false);
-    ReturnObject = PerformMoveOrCopyInitialization(Entity, nullptr, RetType,
+    ReturnObject = S.PerformMoveOrCopyInitialization(Entity, nullptr, RetType,
                                                    ReturnObject.get());
     if (ReturnObject.isInvalid())
-      return FD->setInvalidDecl();
+      return false;
   }
-  ReturnObject = ActOnFinishFullExpr(ReturnObject.get(), Loc);
+  ReturnObject = S.ActOnFinishFullExpr(ReturnObject.get(), Loc);
   if (ReturnObject.isInvalid())
-    return FD->setInvalidDecl();
+    return false;
 
+  this->ReturnValue = ReturnObject.get();
+  return true;
+}
+
+bool SubStmtBuilder::makeParamMoves() {
   // FIXME: Perform move-initialization of parameters into frame-local copies.
-  SmallVector<Expr*, 16> ParamMoves;
+  return true;
+}
 
-  // Build body for the coroutine wrapper statement.
-  Body = new (Context) CoroutineBodyStmt(
-      Body, PromiseStmt.get(), InitialSuspend.get(), FinalSuspend.get(),
-      SetException.get(), Fallthrough.get(), Allocation, Deallocation,
-      ReturnObject.get(), ParamMoves);
+StmtResult Sema::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
+  CoroutineBodyStmt *Res = CoroutineBodyStmt::Create(Context, Args);
+  if (!Res)
+    return StmtError();
+  return Res;
 }
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 5d13c8f..d7d7122 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -67,7 +67,7 @@
   TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false,
                        bool AllowTemplates=false)
       : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass),
-        AllowClassTemplates(AllowTemplates) {
+        AllowTemplates(AllowTemplates) {
     WantExpressionKeywords = false;
     WantCXXNamedCasts = false;
     WantRemainingKeywords = false;
@@ -76,7 +76,7 @@
   bool ValidateCandidate(const TypoCorrection &candidate) override {
     if (NamedDecl *ND = candidate.getCorrectionDecl()) {
       bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
-      bool AllowedTemplate = AllowClassTemplates && isa<ClassTemplateDecl>(ND);
+      bool AllowedTemplate = AllowTemplates && getAsTypeTemplateDecl(ND);
       return (IsType || AllowedTemplate) &&
              (AllowInvalidDecl || !ND->isInvalidDecl());
     }
@@ -86,7 +86,7 @@
  private:
   bool AllowInvalidDecl;
   bool WantClassName;
-  bool AllowClassTemplates;
+  bool AllowTemplates;
 };
 
 } // end anonymous namespace
@@ -252,7 +252,13 @@
                              ParsedType ObjectTypePtr,
                              bool IsCtorOrDtorName,
                              bool WantNontrivialTypeSourceInfo,
+                             bool IsClassTemplateDeductionContext,
                              IdentifierInfo **CorrectedII) {
+  // FIXME: Consider allowing this outside C++1z mode as an extension.
+  bool AllowDeducedTemplate = IsClassTemplateDeductionContext &&
+                              getLangOpts().CPlusPlus1z && !IsCtorOrDtorName &&
+                              !isClassName && !HasTrailingDot;
+
   // Determine where we will perform name lookup.
   DeclContext *LookupCtx = nullptr;
   if (ObjectTypePtr) {
@@ -334,10 +340,11 @@
   case LookupResult::NotFound:
   case LookupResult::NotFoundInCurrentInstantiation:
     if (CorrectedII) {
-      TypoCorrection Correction = CorrectTypo(
-          Result.getLookupNameInfo(), Kind, S, SS,
-          llvm::make_unique<TypeNameValidatorCCC>(true, isClassName),
-          CTK_ErrorRecovery);
+      TypoCorrection Correction =
+          CorrectTypo(Result.getLookupNameInfo(), Kind, S, SS,
+                      llvm::make_unique<TypeNameValidatorCCC>(
+                          true, isClassName, AllowDeducedTemplate),
+                      CTK_ErrorRecovery);
       IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo();
       TemplateTy Template;
       bool MemberOfUnknownSpecialization;
@@ -359,7 +366,8 @@
         ParsedType Ty = getTypeName(*NewII, NameLoc, S, NewSSPtr,
                                     isClassName, HasTrailingDot, ObjectTypePtr,
                                     IsCtorOrDtorName,
-                                    WantNontrivialTypeSourceInfo);
+                                    WantNontrivialTypeSourceInfo,
+                                    IsClassTemplateDeductionContext);
         if (Ty) {
           diagnoseTypo(Correction,
                        PDiag(diag::err_unknown_type_or_class_name_suggest)
@@ -391,7 +399,8 @@
     // Look to see if we have a type anywhere in the list of results.
     for (LookupResult::iterator Res = Result.begin(), ResEnd = Result.end();
          Res != ResEnd; ++Res) {
-      if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res)) {
+      if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res) ||
+          (AllowDeducedTemplate && getAsTypeTemplateDecl(*Res))) {
         if (!IIDecl ||
             (*Res)->getLocation().getRawEncoding() <
               IIDecl->getLocation().getRawEncoding())
@@ -425,33 +434,29 @@
 
   QualType T;
   if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
+    // C++ [class.qual]p2: A lookup that would find the injected-class-name
+    // instead names the constructors of the class, except when naming a class.
+    // This is ill-formed when we're not actually forming a ctor or dtor name.
+    auto *LookupRD = dyn_cast_or_null<CXXRecordDecl>(LookupCtx);
+    auto *FoundRD = dyn_cast<CXXRecordDecl>(TD);
+    if (!isClassName && !IsCtorOrDtorName && LookupRD && FoundRD &&
+        FoundRD->isInjectedClassName() &&
+        declaresSameEntity(LookupRD, cast<Decl>(FoundRD->getParent())))
+      Diag(NameLoc, diag::err_out_of_line_qualified_id_type_names_constructor)
+          << &II << /*Type*/1;
+
     DiagnoseUseOfDecl(IIDecl, NameLoc);
 
     T = Context.getTypeDeclType(TD);
     MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);
-
-    // NOTE: avoid constructing an ElaboratedType(Loc) if this is a
-    // constructor or destructor name (in such a case, the scope specifier
-    // will be attached to the enclosing Expr or Decl node).
-    if (SS && SS->isNotEmpty() && !IsCtorOrDtorName) {
-      if (WantNontrivialTypeSourceInfo) {
-        // Construct a type with type-source information.
-        TypeLocBuilder Builder;
-        Builder.pushTypeSpec(T).setNameLoc(NameLoc);
-
-        T = getElaboratedType(ETK_None, *SS, T);
-        ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
-        ElabTL.setElaboratedKeywordLoc(SourceLocation());
-        ElabTL.setQualifierLoc(SS->getWithLocInContext(Context));
-        return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
-      } else {
-        T = getElaboratedType(ETK_None, *SS, T);
-      }
-    }
   } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
     (void)DiagnoseUseOfDecl(IDecl, NameLoc);
     if (!HasTrailingDot)
       T = Context.getObjCInterfaceType(IDecl);
+  } else if (AllowDeducedTemplate) {
+    if (auto *TD = getAsTypeTemplateDecl(IIDecl))
+      T = Context.getDeducedTemplateSpecializationType(TemplateName(TD),
+                                                       QualType(), false);
   }
 
   if (T.isNull()) {
@@ -459,6 +464,27 @@
     Result.suppressDiagnostics();
     return nullptr;
   }
+
+  // NOTE: avoid constructing an ElaboratedType(Loc) if this is a
+  // constructor or destructor name (in such a case, the scope specifier
+  // will be attached to the enclosing Expr or Decl node).
+  if (SS && SS->isNotEmpty() && !IsCtorOrDtorName &&
+      !isa<ObjCInterfaceDecl>(IIDecl)) {
+    if (WantNontrivialTypeSourceInfo) {
+      // Construct a type with type-source information.
+      TypeLocBuilder Builder;
+      Builder.pushTypeSpec(T).setNameLoc(NameLoc);
+
+      T = getElaboratedType(ETK_None, *SS, T);
+      ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
+      ElabTL.setElaboratedKeywordLoc(SourceLocation());
+      ElabTL.setQualifierLoc(SS->getWithLocInContext(Context));
+      return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+    } else {
+      T = getElaboratedType(ETK_None, *SS, T);
+    }
+  }
+
   return ParsedType::make(T);
 }
 
@@ -636,6 +662,7 @@
       if (Corrected.getCorrectionSpecifier())
         tmpSS.MakeTrivial(Context, Corrected.getCorrectionSpecifier(),
                           SourceRange(IILoc));
+      // FIXME: Support class template argument deduction here.
       SuggestedType =
           getTypeName(*Corrected.getCorrectionAsIdentifierInfo(), IILoc, S,
                       tmpSS.isSet() ? &tmpSS : SS, false, false, nullptr,
@@ -656,7 +683,8 @@
                        Name, nullptr, true, TemplateResult,
                        MemberOfUnknownSpecialization) == TNK_Type_template) {
       TemplateName TplName = TemplateResult.get();
-      Diag(IILoc, diag::err_template_missing_args) << TplName;
+      Diag(IILoc, diag::err_template_missing_args)
+        << (int)getTemplateNameKindForDiagnostics(TplName) << TplName;
       if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) {
         Diag(TplDecl->getLocation(), diag::note_template_decl_here)
           << TplDecl->getTemplateParameters()->getSourceRange();
@@ -782,6 +810,13 @@
   if (NextToken.is(tok::coloncolon)) {
     NestedNameSpecInfo IdInfo(Name, NameLoc, NextToken.getLocation());
     BuildCXXNestedNameSpecifier(S, IdInfo, false, SS, nullptr, false);
+  } else if (getLangOpts().CPlusPlus && SS.isSet() &&
+             isCurrentClassName(*Name, S, &SS)) {
+    // Per [class.qual]p2, this names the constructors of SS, not the
+    // injected-class-name. We don't have a classification for that.
+    // There's not much point caching this result, since the parser
+    // will reject it later.
+    return NameClassification::Unknown();
   }
 
   LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
@@ -1044,7 +1079,8 @@
   }
 
   // We can have a type template here if we're classifying a template argument.
-  if (isa<TemplateDecl>(FirstDecl) && !isa<FunctionTemplateDecl>(FirstDecl))
+  if (isa<TemplateDecl>(FirstDecl) && !isa<FunctionTemplateDecl>(FirstDecl) &&
+      !isa<VarTemplateDecl>(FirstDecl))
     return NameClassification::TypeTemplate(
         TemplateName(cast<TemplateDecl>(FirstDecl)));
 
@@ -1071,6 +1107,24 @@
   return BuildDeclarationNameExpr(SS, Result, ADL);
 }
 
+Sema::TemplateNameKindForDiagnostics
+Sema::getTemplateNameKindForDiagnostics(TemplateName Name) {
+  auto *TD = Name.getAsTemplateDecl();
+  if (!TD)
+    return TemplateNameKindForDiagnostics::DependentTemplate;
+  if (isa<ClassTemplateDecl>(TD))
+    return TemplateNameKindForDiagnostics::ClassTemplate;
+  if (isa<FunctionTemplateDecl>(TD))
+    return TemplateNameKindForDiagnostics::FunctionTemplate;
+  if (isa<VarTemplateDecl>(TD))
+    return TemplateNameKindForDiagnostics::VarTemplate;
+  if (isa<TypeAliasTemplateDecl>(TD))
+    return TemplateNameKindForDiagnostics::AliasTemplate;
+  if (isa<TemplateTemplateParmDecl>(TD))
+    return TemplateNameKindForDiagnostics::TemplateTemplateParam;
+  return TemplateNameKindForDiagnostics::DependentTemplate;
+}
+
 // Determines the context to return to after temporarily entering a
 // context.  This depends in an unnecessarily complicated way on the
 // exact ordering of callbacks from the parser.
@@ -3034,7 +3088,7 @@
         //   [...] A member shall not be declared twice in the
         //   member-specification, except that a nested class or member
         //   class template can be declared and then later defined.
-        if (ActiveTemplateInstantiations.empty()) {
+        if (!inTemplateInstantiation()) {
           unsigned NewDiag;
           if (isa<CXXConstructorDecl>(OldMethod))
             NewDiag = diag::err_constructor_redeclared;
@@ -4503,7 +4557,7 @@
     // trivial in almost all cases, except if a union member has an in-class
     // initializer:
     //   union { int n = 0; };
-    ActOnUninitializedDecl(Anon, /*TypeMayContainAuto=*/false);
+    ActOnUninitializedDecl(Anon);
   }
   Anon->setImplicit();
 
@@ -4621,6 +4675,34 @@
     NameInfo.setLoc(Name.StartLocation);
     return NameInfo;
 
+  case UnqualifiedId::IK_DeductionGuideName: {
+    // C++ [temp.deduct.guide]p3:
+    //   The simple-template-id shall name a class template specialization.
+    //   The template-name shall be the same identifier as the template-name
+    //   of the simple-template-id.
+    // These together intend to imply that the template-name shall name a
+    // class template.
+    // FIXME: template<typename T> struct X {};
+    //        template<typename T> using Y = X<T>;
+    //        Y(int) -> Y<int>;
+    //   satisfies these rules but does not name a class template.
+    TemplateName TN = Name.TemplateName.get().get();
+    auto *Template = TN.getAsTemplateDecl();
+    if (!Template || !isa<ClassTemplateDecl>(Template)) {
+      Diag(Name.StartLocation,
+           diag::err_deduction_guide_name_not_class_template)
+        << (int)getTemplateNameKindForDiagnostics(TN) << TN;
+      if (Template)
+        Diag(Template->getLocation(), diag::note_template_decl_here);
+      return DeclarationNameInfo();
+    }
+
+    NameInfo.setName(
+        Context.DeclarationNames.getCXXDeductionGuideName(Template));
+    NameInfo.setLoc(Name.StartLocation);
+    return NameInfo;
+  }
+
   case UnqualifiedId::IK_OperatorFunctionId:
     NameInfo.setName(Context.DeclarationNames.getCXXOperatorName(
                                            Name.OperatorFunctionId.Operator));
@@ -4838,6 +4920,9 @@
       Dcl && Dcl->getDeclContext()->isFileContext())
     Dcl->setTopLevelDeclInObjCContainer();
 
+  if (getLangOpts().OpenCL)
+    setCurrentOpenCLExtensionForDecl(Dcl);
+
   return Dcl;
 }
 
@@ -5378,8 +5463,13 @@
          diag::err_concept_wrong_decl_kind);
 
   if (D.getName().Kind != UnqualifiedId::IK_Identifier) {
-    Diag(D.getName().StartLocation, diag::err_typedef_not_identifier)
-      << D.getName().getSourceRange();
+    if (D.getName().Kind == UnqualifiedId::IK_DeductionGuideName)
+      Diag(D.getName().StartLocation,
+           diag::err_deduction_guide_invalid_specifier)
+          << "typedef";
+    else
+      Diag(D.getName().StartLocation, diag::err_typedef_not_identifier)
+          << D.getName().getSourceRange();
     return nullptr;
   }
 
@@ -5645,13 +5735,17 @@
   if (OldDecl->isInvalidDecl())
     return;
 
+  bool IsTemplate = false;
   if (TemplateDecl *OldTD = dyn_cast<TemplateDecl>(OldDecl)) {
     OldDecl = OldTD->getTemplatedDecl();
+    IsTemplate = true;
     if (!IsSpecialization)
       IsDefinition = false;
   }
-  if (TemplateDecl *NewTD = dyn_cast<TemplateDecl>(NewDecl))
+  if (TemplateDecl *NewTD = dyn_cast<TemplateDecl>(NewDecl)) {
     NewDecl = NewTD->getTemplatedDecl();
+    IsTemplate = true;
+  }
 
   if (!OldDecl || !NewDecl)
     return;
@@ -5704,9 +5798,10 @@
   }
 
   // A redeclaration is not allowed to drop a dllimport attribute, the only
-  // exceptions being inline function definitions, local extern declarations,
-  // qualified friend declarations or special MSVC extension: in the last case,
-  // the declaration is treated as if it were marked dllexport.
+  // exceptions being inline function definitions (except for function
+  // templates), local extern declarations, qualified friend declarations or
+  // special MSVC extension: in the last case, the declaration is treated as if
+  // it were marked dllexport.
   bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;
   bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
   if (const auto *VD = dyn_cast<VarDecl>(NewDecl)) {
@@ -5721,7 +5816,8 @@
                         FD->getFriendObjectKind() == Decl::FOK_Declared;
   }
 
-  if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember &&
+  if (OldImportAttr && !HasNewAttr &&
+      (!IsInline || (IsMicrosoft && IsTemplate)) && !IsStaticDataMember &&
       !NewDecl->isLocalExternDecl() && !IsQualifiedFriend) {
     if (IsMicrosoft && IsDefinition) {
       S.Diag(NewDecl->getLocation(),
@@ -5898,8 +5994,7 @@
       Name = II;
     }
   } else if (!II) {
-    Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
-      << Name;
+    Diag(D.getIdentifierLoc(), diag::err_bad_variable_name) << Name;
     return nullptr;
   }
 
@@ -5939,7 +6034,7 @@
       NR = NR->getPointeeType();
     }
 
-    if (!getOpenCLOptions().cl_khr_fp16) {
+    if (!getOpenCLOptions().isEnabled("cl_khr_fp16")) {
       // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and
       // half array type (unless the cl_khr_fp16 extension is enabled).
       if (Context.getBaseElementType(R)->isHalfType()) {
@@ -6013,7 +6108,7 @@
     }
   }
 
-  bool IsExplicitSpecialization = false;
+  bool IsMemberSpecialization = false;
   bool IsVariableTemplateSpecialization = false;
   bool IsPartialSpecialization = false;
   bool IsVariableTemplate = false;
@@ -6025,7 +6120,7 @@
                             D.getIdentifierLoc(), II,
                             R, TInfo, SC);
 
-    if (D.getDeclSpec().containsPlaceholderType() && R->getContainedAutoType())
+    if (R->getContainedDeducedType())
       ParsingInitForAutoVars.insert(NewVD);
 
     if (D.isInvalidType())
@@ -6091,7 +6186,7 @@
             ? D.getName().TemplateId
             : nullptr,
         TemplateParamLists,
-        /*never a friend*/ false, IsExplicitSpecialization, Invalid);
+        /*never a friend*/ false, IsMemberSpecialization, Invalid);
 
     if (TemplateParams) {
       if (!TemplateParams->size() &&
@@ -6161,7 +6256,7 @@
 
     // If this decl has an auto type in need of deduction, make a note of the
     // Decl so we can diagnose uses of it in its own initializer.
-    if (D.getDeclSpec().containsPlaceholderType() && R->getContainedAutoType())
+    if (R->getContainedDeducedType())
       ParsingInitForAutoVars.insert(NewVD);
 
     if (D.isInvalidType() || Invalid) {
@@ -6317,7 +6412,7 @@
           << (IsPartialSpecialization ? 1 : 0)
           << FixItHint::CreateRemoval(
                  D.getDeclSpec().getModulePrivateSpecLoc());
-    else if (IsExplicitSpecialization)
+    else if (IsMemberSpecialization)
       Diag(NewVD->getLocation(), diag::err_module_private_specialization)
         << 2
         << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
@@ -6422,16 +6517,17 @@
     }
   }
 
-  // Diagnose shadowed variables before filtering for scope.
-  if (D.getCXXScopeSpec().isEmpty())
-    CheckShadow(S, NewVD, Previous);
+  // Find the shadowed declaration before filtering for scope.
+  NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
+                                ? getShadowedDeclaration(NewVD, Previous)
+                                : nullptr;
 
   // Don't consider existing declarations that are in a different
   // scope and are out-of-semantic-context declarations (if the new
   // declaration has linkage).
   FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewVD),
                        D.getCXXScopeSpec().isNotEmpty() ||
-                       IsExplicitSpecialization ||
+                       IsMemberSpecialization ||
                        IsVariableTemplateSpecialization);
 
   // Check whether the previous declaration is in the same block scope. This
@@ -6446,7 +6542,7 @@
     D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
   } else {
     // If this is an explicit specialization of a static data member, check it.
-    if (IsExplicitSpecialization && !NewVD->isInvalidDecl() &&
+    if (IsMemberSpecialization && !NewVD->isInvalidDecl() &&
         CheckMemberSpecialization(NewVD, Previous))
       NewVD->setInvalidDecl();
 
@@ -6519,6 +6615,10 @@
     }
   }
 
+  // Diagnose shadowed variables iff this isn't a redeclaration.
+  if (ShadowedDecl && !D.isRedeclaration())
+    CheckShadow(NewVD, ShadowedDecl, Previous);
+
   ProcessPragmaWeak(S, NewVD);
 
   // If this is the first declaration of an extern C variable, update
@@ -6557,7 +6657,7 @@
   if (D.isRedeclaration() && !Previous.empty()) {
     checkDLLAttributeRedeclaration(
         *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewVD,
-        IsExplicitSpecialization, D.isFunctionDefinition());
+        IsMemberSpecialization, D.isFunctionDefinition());
   }
 
   if (NewTemplate) {
@@ -6592,34 +6692,41 @@
   return SourceLocation();
 }
 
+/// \brief Return the declaration shadowed by the given variable \p D, or null
+/// if it doesn't shadow any declaration or shadowing warnings are disabled.
+NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D,
+                                        const LookupResult &R) {
+  // Return if warning is ignored.
+  if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
+    return nullptr;
+
+  // Don't diagnose declarations at file scope.
+  if (D->hasGlobalStorage())
+    return nullptr;
+
+  // Only diagnose if we're shadowing an unambiguous field or variable.
+  if (R.getResultKind() != LookupResult::Found)
+    return nullptr;
+
+  NamedDecl *ShadowedDecl = R.getFoundDecl();
+  return isa<VarDecl>(ShadowedDecl) || isa<FieldDecl>(ShadowedDecl)
+             ? ShadowedDecl
+             : nullptr;
+}
+
 /// \brief Diagnose variable or built-in function shadowing.  Implements
 /// -Wshadow.
 ///
 /// This method is called whenever a VarDecl is added to a "useful"
 /// scope.
 ///
-/// \param S the scope in which the shadowing name is being declared
+/// \param ShadowedDecl the declaration that is shadowed by the given variable
 /// \param R the lookup of the name
 ///
-void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
-  // Return if warning is ignored.
-  if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
-    return;
-
-  // Don't diagnose declarations at file scope.
-  if (D->hasGlobalStorage())
-    return;
-
+void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl,
+                       const LookupResult &R) {
   DeclContext *NewDC = D->getDeclContext();
 
-  // Only diagnose if we're shadowing an unambiguous field or variable.
-  if (R.getResultKind() != LookupResult::Found)
-    return;
-
-  NamedDecl* ShadowedDecl = R.getFoundDecl();
-  if (!isa<VarDecl>(ShadowedDecl) && !isa<FieldDecl>(ShadowedDecl))
-    return;
-
   if (FieldDecl *FD = dyn_cast<FieldDecl>(ShadowedDecl)) {
     // Fields are not shadowed by variables in C++ static methods.
     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewDC))
@@ -6729,7 +6836,8 @@
   LookupResult R(*this, D->getDeclName(), D->getLocation(),
                  Sema::LookupOrdinaryName, Sema::ForRedeclaration);
   LookupName(R, S);
-  CheckShadow(S, D, R);
+  if (NamedDecl *ShadowedDecl = getShadowedDeclaration(D, R))
+    CheckShadow(D, ShadowedDecl, R);
 }
 
 /// Check if 'E', which is an expression that is about to be modified, refers
@@ -6909,7 +7017,7 @@
   // OpenCL v1.2 s6.8 - The static qualifier is valid only in program
   // scope.
   if (getLangOpts().OpenCLVersion == 120 &&
-      !getOpenCLOptions().cl_clang_storage_class_specifiers &&
+      !getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers") &&
       NewVD->isStaticLocal()) {
     Diag(NewVD->getLocation(), diag::err_static_function_scope);
     NewVD->setInvalidDecl();
@@ -7413,6 +7521,7 @@
   case DeclSpec::SCS_mutable:
     SemaRef.Diag(D.getDeclSpec().getStorageClassSpecLoc(),
                  diag::err_typecheck_sclass_func);
+    D.getMutableDeclSpec().ClearStorageClassSpecs();
     D.setInvalidType();
     break;
   case DeclSpec::SCS_unspecified: break;
@@ -7455,11 +7564,12 @@
     // Determine whether the function was written with a
     // prototype. This true when:
     //   - there is a prototype in the declarator, or
-    //   - the type R of the function is some kind of typedef or other reference
-    //     to a type name (which eventually refers to a function type).
+    //   - the type R of the function is some kind of typedef or other non-
+    //     attributed reference to a type name (which eventually refers to a
+    //     function type).
     bool HasPrototype =
       (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) ||
-      (!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
+      (!R->getAsAdjusted<FunctionType>() && R->isFunctionProtoType());
 
     NewFD = FunctionDecl::Create(SemaRef.Context, DC,
                                  D.getLocStart(), NameInfo, R,
@@ -7545,6 +7655,12 @@
                                      R, TInfo, isInline, isExplicit,
                                      isConstexpr, SourceLocation());
 
+  } else if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) {
+    SemaRef.CheckDeductionGuideDeclarator(D, R, SC);
+
+    return CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getLocStart(),
+                                         isExplicit, NameInfo, R, TInfo,
+                                         D.getLocEnd());
   } else if (DC->isRecord()) {
     // If the name of the function is the same as the name of the record,
     // then this must be an invalid constructor that has a return type.
@@ -7586,7 +7702,7 @@
   ValidKernelParam,
   PtrPtrKernelParam,
   PtrKernelParam,
-  PrivatePtrKernelParam,
+  InvalidAddrSpacePtrKernelParam,
   InvalidKernelParam,
   RecordKernelParam
 };
@@ -7596,8 +7712,10 @@
     QualType PointeeType = PT->getPointeeType();
     if (PointeeType->isPointerType())
       return PtrPtrKernelParam;
-    return PointeeType.getAddressSpace() == 0 ? PrivatePtrKernelParam
-                                              : PtrKernelParam;
+    if (PointeeType.getAddressSpace() == LangAS::opencl_generic ||
+        PointeeType.getAddressSpace() == 0)
+      return InvalidAddrSpacePtrKernelParam;
+    return PtrKernelParam;
   }
 
   // TODO: Forbid the other integer types (size_t, ptrdiff_t...) when they can
@@ -7615,7 +7733,7 @@
   // OpenCL extension spec v1.2 s9.5:
   // This extension adds support for half scalar and vector types as built-in
   // types that can be used for arithmetic operations, conversions etc.
-  if (!S.getOpenCLOptions().cl_khr_fp16 && PT->isHalfType())
+  if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16") && PT->isHalfType())
     return InvalidKernelParam;
 
   if (PT->isRecordType())
@@ -7645,11 +7763,12 @@
     D.setInvalidType();
     return;
 
-  case PrivatePtrKernelParam:
-    // OpenCL v1.2 s6.9.a:
-    // A kernel function argument cannot be declared as a
-    // pointer to the private address space.
-    S.Diag(Param->getLocation(), diag::err_opencl_private_ptr_kernel_param);
+  case InvalidAddrSpacePtrKernelParam:
+    // OpenCL v1.0 s6.5:
+    // __kernel function arguments declared to be a pointer of a type can point
+    // to one of the following address spaces only : __global, __local or
+    // __constant.
+    S.Diag(Param->getLocation(), diag::err_kernel_arg_address_space);
     D.setInvalidType();
     return;
 
@@ -7736,7 +7855,7 @@
       // do not allow OpenCL objects to be passed as elements of the struct or
       // union.
       if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam ||
-          ParamType == PrivatePtrKernelParam) {
+          ParamType == InvalidAddrSpacePtrKernelParam) {
         S.Diag(Param->getLocation(),
                diag::err_record_with_pointers_kernel_param)
           << PT->isUnionType()
@@ -7768,6 +7887,28 @@
   } while (!VisitStack.empty());
 }
 
+/// Find the DeclContext in which a tag is implicitly declared if we see an
+/// elaborated type specifier in the specified context, and lookup finds
+/// nothing.
+static DeclContext *getTagInjectionContext(DeclContext *DC) {
+  while (!DC->isFileContext() && !DC->isFunctionOrMethod())
+    DC = DC->getParent();
+  return DC;
+}
+
+/// Find the Scope in which a tag is implicitly declared if we see an
+/// elaborated type specifier in the specified context, and lookup finds
+/// nothing.
+static Scope *getTagInjectionScope(Scope *S, const LangOptions &LangOpts) {
+  while (S->isClassScope() ||
+         (LangOpts.CPlusPlus &&
+          S->isFunctionPrototypeScope()) ||
+         ((S->getFlags() & Scope::DeclScope) == 0) ||
+         (S->getEntity() && S->getEntity()->isTransparentContext()))
+    S = S->getParent();
+  return S;
+}
+
 NamedDecl*
 Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
                               TypeSourceInfo *TInfo, LookupResult &Previous,
@@ -7793,7 +7934,7 @@
 
   bool isFriend = false;
   FunctionTemplateDecl *FunctionTemplate = nullptr;
-  bool isExplicitSpecialization = false;
+  bool isMemberSpecialization = false;
   bool isFunctionTemplateSpecialization = false;
 
   bool isDependentClassScopeExplicitSpecialization = false;
@@ -7849,7 +7990,7 @@
     }
 
     SetNestedNameSpecifier(NewFD, D);
-    isExplicitSpecialization = false;
+    isMemberSpecialization = false;
     isFunctionTemplateSpecialization = false;
     if (D.isInvalidType())
       NewFD->setInvalidDecl();
@@ -7864,7 +8005,7 @@
                 D.getName().getKind() == UnqualifiedId::IK_TemplateId
                     ? D.getName().TemplateId
                     : nullptr,
-                TemplateParamLists, isFriend, isExplicitSpecialization,
+                TemplateParamLists, isFriend, isMemberSpecialization,
                 Invalid)) {
       if (TemplateParams->size() > 0) {
         // This is a function template
@@ -8008,7 +8149,8 @@
     //  The explicit specifier shall be used only in the declaration of a
     //  constructor or conversion function within its class definition;
     //  see 12.3.1 and 12.3.2.
-    if (isExplicit && !NewFD->isInvalidDecl()) {
+    if (isExplicit && !NewFD->isInvalidDecl() &&
+        !isa<CXXDeductionGuideDecl>(NewFD)) {
       if (!CurContext->isRecord()) {
         // 'explicit' was specified outside of the class.
         Diag(D.getDeclSpec().getExplicitSpecLoc(),
@@ -8197,7 +8339,7 @@
   // Filter out previous declarations that don't match the scope.
   FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewFD),
                        D.getCXXScopeSpec().isNotEmpty() ||
-                       isExplicitSpecialization ||
+                       isMemberSpecialization ||
                        isFunctionTemplateSpecialization);
 
   // Handle GNU asm-label extension (encoded as an attribute).
@@ -8222,8 +8364,9 @@
   // Copy the parameter declarations from the declarator D to the function
   // declaration NewFD, if they are available.  First scavenge them into Params.
   SmallVector<ParmVarDecl*, 16> Params;
-  if (D.isFunctionDeclarator()) {
-    DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
+  unsigned FTIIdx;
+  if (D.isFunctionDeclarator(FTIIdx)) {
+    DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(FTIIdx).Fun;
 
     // Check for C99 6.7.5.3p10 - foo(void) is a non-varargs
     // function that takes no arguments, not a function that takes a
@@ -8241,6 +8384,41 @@
           NewFD->setInvalidDecl();
       }
     }
+
+    if (!getLangOpts().CPlusPlus) {
+      // In C, find all the tag declarations from the prototype and move them
+      // into the function DeclContext. Remove them from the surrounding tag
+      // injection context of the function, which is typically but not always
+      // the TU.
+      DeclContext *PrototypeTagContext =
+          getTagInjectionContext(NewFD->getLexicalDeclContext());
+      for (NamedDecl *NonParmDecl : FTI.getDeclsInPrototype()) {
+        auto *TD = dyn_cast<TagDecl>(NonParmDecl);
+
+        // We don't want to reparent enumerators. Look at their parent enum
+        // instead.
+        if (!TD) {
+          if (auto *ECD = dyn_cast<EnumConstantDecl>(NonParmDecl))
+            TD = cast<EnumDecl>(ECD->getDeclContext());
+        }
+        if (!TD)
+          continue;
+        DeclContext *TagDC = TD->getLexicalDeclContext();
+        if (!TagDC->containsDecl(TD))
+          continue;
+        TagDC->removeDecl(TD);
+        TD->setDeclContext(NewFD);
+        NewFD->addDecl(TD);
+
+        // Preserve the lexical DeclContext if it is not the surrounding tag
+        // injection context of the FD. In this example, the semantic context of
+        // E will be f and the lexical context will be S, while both the
+        // semantic and lexical contexts of S will be f:
+        //   void f(struct S { enum E { a } f; } s);
+        if (TagDC != PrototypeTagContext)
+          TD->setLexicalDeclContext(TagDC);
+      }
+    }
   } else if (const FunctionProtoType *FT = R->getAs<FunctionProtoType>()) {
     // When we're declaring a function with a typedef, typeof, etc as in the
     // following example, we'll need to synthesize (unnamed)
@@ -8266,15 +8444,6 @@
   // Finally, we know we have the right number of parameters, install them.
   NewFD->setParams(Params);
 
-  // Find all anonymous symbols defined during the declaration of this function
-  // and add to NewFD. This lets us track decls such 'enum Y' in:
-  //
-  //   void f(enum Y {AA} x) {}
-  //
-  // which would otherwise incorrectly end up in the translation unit scope.
-  NewFD->setDeclsInPrototypeScope(DeclsInPrototypeScope);
-  DeclsInPrototypeScope.clear();
-
   if (D.getDeclSpec().isNoreturnSpecified())
     NewFD->addAttr(
         ::new(Context) C11NoReturnAttr(D.getDeclSpec().getNoreturnSpecLoc(),
@@ -8320,7 +8489,6 @@
 
   if (!getLangOpts().CPlusPlus) {
     // Perform semantic checking on the function declaration.
-    bool isExplicitSpecialization=false;
     if (!NewFD->isInvalidDecl() && NewFD->isMain())
       CheckMain(NewFD, D.getDeclSpec());
 
@@ -8329,7 +8497,7 @@
 
     if (!NewFD->isInvalidDecl())
       D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
-                                                  isExplicitSpecialization));
+                                                  isMemberSpecialization));
     else if (!Previous.empty())
       // Recover gracefully from an invalid redeclaration.
       D.setRedeclaration(true);
@@ -8464,7 +8632,7 @@
             << FixItHint::CreateRemoval(
                                       D.getDeclSpec().getStorageClassSpecLoc());
       }
-    } else if (isExplicitSpecialization && isa<CXXMethodDecl>(NewFD)) {
+    } else if (isMemberSpecialization && isa<CXXMethodDecl>(NewFD)) {
       if (CheckMemberSpecialization(NewFD, Previous))
           NewFD->setInvalidDecl();
     }
@@ -8479,7 +8647,7 @@
 
       if (!NewFD->isInvalidDecl())
         D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
-                                                    isExplicitSpecialization));
+                                                    isMemberSpecialization));
       else if (!Previous.empty())
         // Recover gracefully from an invalid redeclaration.
         D.setRedeclaration(true);
@@ -8585,7 +8753,7 @@
     } else if (!D.isFunctionDefinition() &&
                isa<CXXMethodDecl>(NewFD) && NewFD->isOutOfLine() &&
                !isFriend && !isFunctionTemplateSpecialization &&
-               !isExplicitSpecialization) {
+               !isMemberSpecialization) {
       // An out-of-line member function declaration must also be a
       // definition (C++ [class.mfct]p2).
       // Note that this is not the case for explicit specializations of
@@ -8646,7 +8814,7 @@
   if (D.isRedeclaration() && !Previous.empty()) {
     checkDLLAttributeRedeclaration(
         *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewFD,
-        isExplicitSpecialization || isFunctionTemplateSpecialization,
+        isMemberSpecialization || isFunctionTemplateSpecialization,
         D.isFunctionDefinition());
   }
 
@@ -8771,15 +8939,16 @@
 /// that have been instantiated via C++ template instantiation (called
 /// via InstantiateDecl).
 ///
-/// \param IsExplicitSpecialization whether this new function declaration is
-/// an explicit specialization of the previous declaration.
+/// \param IsMemberSpecialization whether this new function declaration is
+/// a member specialization (that replaces any definition provided by the
+/// previous declaration).
 ///
 /// This sets NewFD->isInvalidDecl() to true if there was an error.
 ///
 /// \returns true if the function declaration is a redeclaration.
 bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
                                     LookupResult &Previous,
-                                    bool IsExplicitSpecialization) {
+                                    bool IsMemberSpecialization) {
   assert(!NewFD->getReturnType()->isVariablyModifiedType() &&
          "Variably modified return types are not handled here");
 
@@ -8892,7 +9061,7 @@
 
       // Warn that we did this, if we're not performing template instantiation.
       // In that case, we'll have warned already when the template was defined.
-      if (ActiveTemplateInstantiations.empty()) {
+      if (!inTemplateInstantiation()) {
         SourceLocation AddConstLoc;
         if (FunctionTypeLoc FTL = MD->getTypeSourceInfo()->getTypeLoc()
                 .IgnoreParens().getAs<FunctionTypeLoc>())
@@ -8929,7 +9098,7 @@
 
       // If this is an explicit specialization of a member that is a function
       // template, mark it as a member specialization.
-      if (IsExplicitSpecialization &&
+      if (IsMemberSpecialization &&
           NewTemplateDecl->getInstantiatedFromMemberTemplate()) {
         NewTemplateDecl->setMemberSpecialization();
         assert(OldTemplateDecl->isMemberSpecialization());
@@ -8979,6 +9148,15 @@
     } else if (CXXConversionDecl *Conversion
                = dyn_cast<CXXConversionDecl>(NewFD)) {
       ActOnConversionDeclarator(Conversion);
+    } else if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(NewFD)) {
+      if (auto *TD = Guide->getDescribedFunctionTemplate())
+        CheckDeductionGuideTemplate(TD);
+
+      // A deduction guide is not on the list of entities that can be
+      // explicitly specialized.
+      if (Guide->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+        Diag(Guide->getLocStart(), diag::err_deduction_guide_specialized)
+            << /*explicit specialization*/ 1;
     }
 
     // Find any virtual functions that this function overrides.
@@ -9024,27 +9202,16 @@
       ASTContext::GetBuiltinTypeError Error;
       LookupPredefedObjCSuperType(*this, S, NewFD->getIdentifier());
       QualType T = Context.GetBuiltinType(BuiltinID, Error);
-      if (!T.isNull() && !Context.hasSameType(T, NewFD->getType())) {
-        auto WithoutExceptionSpec = [&](QualType T) -> QualType {
-          auto *Proto = T->getAs<FunctionProtoType>();
-          if (!Proto)
-            return T;
-          return Context.getFunctionType(
-              Proto->getReturnType(), Proto->getParamTypes(),
-              Proto->getExtProtoInfo().withExceptionSpec(EST_None));
-        };
-
-        // If the type of the builtin differs only in its exception
-        // specification, that's OK.
-        // FIXME: If the types do differ in this way, it would be better to
-        // retain the 'noexcept' form of the type.
-        if (!getLangOpts().CPlusPlus1z ||
-            !Context.hasSameType(WithoutExceptionSpec(T),
-                                 WithoutExceptionSpec(NewFD->getType())))
-          // The type of this function differs from the type of the builtin,
-          // so forget about the builtin entirely.
-          Context.BuiltinInfo.forgetBuiltin(BuiltinID, Context.Idents);
-      }
+      // If the type of the builtin differs only in its exception
+      // specification, that's OK.
+      // FIXME: If the types do differ in this way, it would be better to
+      // retain the 'noexcept' form of the type.
+      if (!T.isNull() &&
+          !Context.hasSameFunctionTypeIgnoringExceptionSpec(T,
+                                                            NewFD->getType()))
+        // The type of this function differs from the type of the builtin,
+        // so forget about the builtin entirely.
+        Context.BuiltinInfo.forgetBuiltin(BuiltinID, Context.Idents);
     }
 
     // If this function is declared as being extern "C", then check to see if
@@ -9620,6 +9787,20 @@
   }
 } // end anonymous namespace
 
+namespace {
+  // Simple wrapper to add the name of a variable or (if no variable is
+  // available) a DeclarationName into a diagnostic.
+  struct VarDeclOrName {
+    VarDecl *VDecl;
+    DeclarationName Name;
+
+    friend const Sema::SemaDiagnosticBuilder &
+    operator<<(const Sema::SemaDiagnosticBuilder &Diag, VarDeclOrName VN) {
+      return VN.VDecl ? Diag << VN.VDecl : Diag << VN.Name;
+    }
+  };
+} // end anonymous namespace
+
 QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
                                             DeclarationName Name, QualType Type,
                                             TypeSourceInfo *TSI,
@@ -9629,14 +9810,38 @@
   assert((!VDecl || !VDecl->isInitCapture()) &&
          "init captures are expected to be deduced prior to initialization");
 
-  // FIXME: Deduction for a decomposition declaration does weird things if the
-  // initializer is an array.
+  VarDeclOrName VN{VDecl, Name};
 
-  ArrayRef<Expr *> DeduceInits = Init;
+  DeducedType *Deduced = Type->getContainedDeducedType();
+  assert(Deduced && "deduceVarTypeFromInitializer for non-deduced type");
+
+  // C++11 [dcl.spec.auto]p3
+  if (!Init) {
+    assert(VDecl && "no init for init capture deduction?");
+    Diag(VDecl->getLocation(), diag::err_auto_var_requires_init)
+      << VDecl->getDeclName() << Type;
+    return QualType();
+  }
+
+  ArrayRef<Expr*> DeduceInits = Init;
   if (DirectInit) {
-    if (auto *PL = dyn_cast<ParenListExpr>(Init))
+    if (auto *PL = dyn_cast_or_null<ParenListExpr>(Init))
       DeduceInits = PL->exprs();
-    else if (auto *IL = dyn_cast<InitListExpr>(Init))
+  }
+
+  if (isa<DeducedTemplateSpecializationType>(Deduced)) {
+    assert(VDecl && "non-auto type for init capture deduction?");
+    InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
+    InitializationKind Kind = InitializationKind::CreateForInit(
+        VDecl->getLocation(), DirectInit, Init);
+    // FIXME: Initialization should not be taking a mutable list of inits. 
+    SmallVector<Expr*, 8> InitsCopy(DeduceInits.begin(), DeduceInits.end());
+    return DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind,
+                                                       InitsCopy);
+  }
+
+  if (DirectInit) {
+    if (auto *IL = dyn_cast<InitListExpr>(Init))
       DeduceInits = IL->inits();
   }
 
@@ -9647,7 +9852,7 @@
     Diag(Init->getLocStart(), IsInitCapture
                                   ? diag::err_init_capture_no_expression
                                   : diag::err_auto_var_init_no_expression)
-        << Name << Type << Range;
+        << VN << Type << Range;
     return QualType();
   }
 
@@ -9655,7 +9860,7 @@
     Diag(DeduceInits[1]->getLocStart(),
          IsInitCapture ? diag::err_init_capture_multiple_expressions
                        : diag::err_auto_var_init_multiple_expressions)
-        << Name << Type << Range;
+        << VN << Type << Range;
     return QualType();
   }
 
@@ -9664,7 +9869,7 @@
     Diag(Init->getLocStart(), IsInitCapture
                                   ? diag::err_init_capture_paren_braces
                                   : diag::err_auto_var_init_paren_braces)
-        << isa<InitListExpr>(Init) << Name << Type << Range;
+        << isa<InitListExpr>(Init) << VN << Type << Range;
     return QualType();
   }
 
@@ -9680,6 +9885,15 @@
     DefaultedAnyToId = true;
   }
 
+  // C++ [dcl.decomp]p1:
+  //   If the assignment-expression [...] has array type A and no ref-qualifier
+  //   is present, e has type cv A
+  if (VDecl && isa<DecompositionDecl>(VDecl) &&
+      Context.hasSameUnqualifiedType(Type, Context.getAutoDeductType()) &&
+      DeduceInit->getType()->isConstantArrayType())
+    return Context.getQualifiedType(DeduceInit->getType(),
+                                    Type.getQualifiers());
+
   QualType DeducedType;
   if (DeduceAutoType(TSI, DeduceInit, DeducedType) == DAR_Failed) {
     if (!IsInitCapture)
@@ -9687,13 +9901,13 @@
     else if (isa<InitListExpr>(Init))
       Diag(Range.getBegin(),
            diag::err_init_capture_deduction_failure_from_init_list)
-          << Name
+          << VN
           << (DeduceInit->getType().isNull() ? TSI->getType()
                                              : DeduceInit->getType())
           << DeduceInit->getSourceRange();
     else
       Diag(Range.getBegin(), diag::err_init_capture_deduction_failure)
-          << Name << TSI->getType()
+          << VN << TSI->getType()
           << (DeduceInit->getType().isNull() ? TSI->getType()
                                              : DeduceInit->getType())
           << DeduceInit->getSourceRange();
@@ -9704,20 +9918,49 @@
   // checks.
   // We only want to warn outside of template instantiations, though:
   // inside a template, the 'id' could have come from a parameter.
-  if (ActiveTemplateInstantiations.empty() && !DefaultedAnyToId &&
-      !IsInitCapture && !DeducedType.isNull() && DeducedType->isObjCIdType()) {
+  if (!inTemplateInstantiation() && !DefaultedAnyToId && !IsInitCapture &&
+      !DeducedType.isNull() && DeducedType->isObjCIdType()) {
     SourceLocation Loc = TSI->getTypeLoc().getBeginLoc();
-    Diag(Loc, diag::warn_auto_var_is_id) << Name << Range;
+    Diag(Loc, diag::warn_auto_var_is_id) << VN << Range;
   }
 
   return DeducedType;
 }
 
+bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
+                                         Expr *Init) {
+  QualType DeducedType = deduceVarTypeFromInitializer(
+      VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(),
+      VDecl->getSourceRange(), DirectInit, Init);
+  if (DeducedType.isNull()) {
+    VDecl->setInvalidDecl();
+    return true;
+  }
+
+  VDecl->setType(DeducedType);
+  assert(VDecl->isLinkageValid());
+
+  // In ARC, infer lifetime.
+  if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
+    VDecl->setInvalidDecl();
+
+  // If this is a redeclaration, check that the type we just deduced matches
+  // the previously declared type.
+  if (VarDecl *Old = VDecl->getPreviousDecl()) {
+    // We never need to merge the type, because we cannot form an incomplete
+    // array of auto, nor deduce such a type.
+    MergeVarDeclTypes(VDecl, Old, /*MergeTypeWithPrevious*/ false);
+  }
+
+  // Check the deduced type is valid for a variable declaration.
+  CheckVariableDeclarationType(VDecl);
+  return VDecl->isInvalidDecl();
+}
+
 /// AddInitializerToDecl - Adds the initializer Init to the
 /// declaration dcl. If DirectInit is true, this is C++ direct
 /// initialization rather than copy initialization.
-void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
-                                bool DirectInit, bool TypeMayContainAuto) {
+void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
   // If there is no declaration, there was an error parsing it.  Just ignore
   // the initializer.
   if (!RealDecl || RealDecl->isInvalidDecl()) {
@@ -9741,13 +9984,8 @@
     return;
   }
 
-  // C++1z [dcl.dcl]p1 grammar implies that a parenthesized initializer is not
-  // permitted.
-  if (isa<DecompositionDecl>(VDecl) && DirectInit && isa<ParenListExpr>(Init))
-    Diag(VDecl->getLocation(), diag::err_decomp_decl_paren_init) << VDecl;
-
   // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
-  if (TypeMayContainAuto && VDecl->getType()->isUndeducedType()) {
+  if (VDecl->getType()->isUndeducedType()) {
     // Attempt typo correction early so that the type of the init expression can
     // be deduced based on the chosen correction if the original init contains a
     // TypoExpr.
@@ -9758,32 +9996,7 @@
     }
     Init = Res.get();
 
-    QualType DeducedType = deduceVarTypeFromInitializer(
-        VDecl, VDecl->getDeclName(), VDecl->getType(),
-        VDecl->getTypeSourceInfo(), VDecl->getSourceRange(), DirectInit, Init);
-    if (DeducedType.isNull()) {
-      RealDecl->setInvalidDecl();
-      return;
-    }
-
-    VDecl->setType(DeducedType);
-    assert(VDecl->isLinkageValid());
-
-    // In ARC, infer lifetime.
-    if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
-      VDecl->setInvalidDecl();
-
-    // If this is a redeclaration, check that the type we just deduced matches
-    // the previously declared type.
-    if (VarDecl *Old = VDecl->getPreviousDecl()) {
-      // We never need to merge the type, because we cannot form an incomplete
-      // array of auto, nor deduce such a type.
-      MergeVarDeclTypes(VDecl, Old, /*MergeTypeWithPrevious*/ false);
-    }
-
-    // Check the deduced type is valid for a variable declaration.
-    CheckVariableDeclarationType(VDecl);
-    if (VDecl->isInvalidDecl())
+    if (DeduceVariableDeclarationType(VDecl, DirectInit, Init))
       return;
   }
 
@@ -9902,15 +10115,8 @@
       }
 
     InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
-    InitializationKind Kind =
-        DirectInit
-            ? CXXDirectInit
-                  ? InitializationKind::CreateDirect(VDecl->getLocation(),
-                                                     Init->getLocStart(),
-                                                     Init->getLocEnd())
-                  : InitializationKind::CreateDirectList(VDecl->getLocation())
-            : InitializationKind::CreateCopy(VDecl->getLocation(),
-                                             Init->getLocStart());
+    InitializationKind Kind = InitializationKind::CreateForInit(
+        VDecl->getLocation(), DirectInit, Init);
 
     MultiExprArg Args = Init;
     if (CXXDirectInit)
@@ -10219,8 +10425,7 @@
          TargetType->getContainedAutoType();
 }
 
-void Sema::ActOnUninitializedDecl(Decl *RealDecl,
-                                  bool TypeMayContainAuto) {
+void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
   // If there is no declaration, there was an error parsing it. Just ignore it.
   if (!RealDecl)
     return;
@@ -10235,13 +10440,9 @@
       return;
     }
 
-    // C++11 [dcl.spec.auto]p3
-    if (TypeMayContainAuto && Type->getContainedAutoType()) {
-      Diag(Var->getLocation(), diag::err_auto_var_requires_init)
-        << Var->getDeclName() << Type;
-      Var->setInvalidDecl();
+    if (Type->isUndeducedType() &&
+        DeduceVariableDeclarationType(Var, false, nullptr))
       return;
-    }
 
     // C++11 [class.static.data]p3: A static data member can be declared with
     // the constexpr specifier; if so, its declaration shall specify
@@ -10620,7 +10821,7 @@
   // Apply section attributes and pragmas to global variables.
   bool GlobalStorage = var->hasGlobalStorage();
   if (GlobalStorage && var->isThisDeclarationADefinition() &&
-      ActiveTemplateInstantiations.empty()) {
+      !inTemplateInstantiation()) {
     PragmaStack<StringLiteral *> *Stack = nullptr;
     int SectionFlags = ASTContext::PSF_Implicit | ASTContext::PSF_Read;
     if (var->getType().isConstQualified())
@@ -10792,7 +10993,8 @@
   if (unsigned MaxAlign = Context.getTargetInfo().getMaxTLSAlign()) {
     // Protect the check so that it's not performed on dependent types and
     // dependent alignments (we can't determine the alignment in that case).
-    if (VD->getTLSKind() && !hasDependentAlignment(VD)) {
+    if (VD->getTLSKind() && !hasDependentAlignment(VD) &&
+        !VD->isInvalidDecl()) {
       CharUnits MaxAlignChars = Context.toCharUnitsFromBits(MaxAlign);
       if (Context.getDeclAlign(VD) > MaxAlignChars) {
         Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
@@ -10972,6 +11174,11 @@
   }
 }
 
+static bool hasDeducedAuto(DeclaratorDecl *DD) {
+  auto *VD = dyn_cast<VarDecl>(DD);
+  return VD && !VD->getType()->hasAutoForTrailingReturnType();
+}
+
 Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
                                                    ArrayRef<Decl *> Group) {
   SmallVector<Decl*, 8> Decls;
@@ -10982,29 +11189,46 @@
   DeclaratorDecl *FirstDeclaratorInGroup = nullptr;
   DecompositionDecl *FirstDecompDeclaratorInGroup = nullptr;
   bool DiagnosedMultipleDecomps = false;
+  DeclaratorDecl *FirstNonDeducedAutoInGroup = nullptr;
+  bool DiagnosedNonDeducedAuto = false;
 
   for (unsigned i = 0, e = Group.size(); i != e; ++i) {
     if (Decl *D = Group[i]) {
-      auto *DD = dyn_cast<DeclaratorDecl>(D);
-      if (DD && !FirstDeclaratorInGroup)
-        FirstDeclaratorInGroup = DD;
+      // For declarators, there are some additional syntactic-ish checks we need
+      // to perform.
+      if (auto *DD = dyn_cast<DeclaratorDecl>(D)) {
+        if (!FirstDeclaratorInGroup)
+          FirstDeclaratorInGroup = DD;
+        if (!FirstDecompDeclaratorInGroup)
+          FirstDecompDeclaratorInGroup = dyn_cast<DecompositionDecl>(D);
+        if (!FirstNonDeducedAutoInGroup && DS.hasAutoTypeSpec() &&
+            !hasDeducedAuto(DD))
+          FirstNonDeducedAutoInGroup = DD;
 
-      auto *Decomp = dyn_cast<DecompositionDecl>(D);
-      if (Decomp && !FirstDecompDeclaratorInGroup)
-        FirstDecompDeclaratorInGroup = Decomp;
+        if (FirstDeclaratorInGroup != DD) {
+          // A decomposition declaration cannot be combined with any other
+          // declaration in the same group.
+          if (FirstDecompDeclaratorInGroup && !DiagnosedMultipleDecomps) {
+            Diag(FirstDecompDeclaratorInGroup->getLocation(),
+                 diag::err_decomp_decl_not_alone)
+                << FirstDeclaratorInGroup->getSourceRange()
+                << DD->getSourceRange();
+            DiagnosedMultipleDecomps = true;
+          }
 
-      // A decomposition declaration cannot be combined with any other
-      // declaration in the same group.
-      auto *OtherDD = FirstDeclaratorInGroup;
-      if (OtherDD == FirstDecompDeclaratorInGroup)
-        OtherDD = DD;
-      if (OtherDD && FirstDecompDeclaratorInGroup &&
-          OtherDD != FirstDecompDeclaratorInGroup &&
-          !DiagnosedMultipleDecomps) {
-        Diag(FirstDecompDeclaratorInGroup->getLocation(),
-             diag::err_decomp_decl_not_alone)
-          << OtherDD->getSourceRange();
-        DiagnosedMultipleDecomps = true;
+          // A declarator that uses 'auto' in any way other than to declare a
+          // variable with a deduced type cannot be combined with any other
+          // declarator in the same group.
+          if (FirstNonDeducedAutoInGroup && !DiagnosedNonDeducedAuto) {
+            Diag(FirstNonDeducedAutoInGroup->getLocation(),
+                 diag::err_auto_non_deduced_not_alone)
+                << FirstNonDeducedAutoInGroup->getType()
+                       ->hasAutoForTrailingReturnType()
+                << FirstDeclaratorInGroup->getSourceRange()
+                << DD->getSourceRange();
+            DiagnosedNonDeducedAuto = true;
+          }
+        }
       }
 
       Decls.push_back(D);
@@ -11020,50 +11244,40 @@
     }
   }
 
-  return BuildDeclaratorGroup(Decls, DS.containsPlaceholderType());
+  return BuildDeclaratorGroup(Decls);
 }
 
 /// BuildDeclaratorGroup - convert a list of declarations into a declaration
 /// group, performing any necessary semantic checking.
 Sema::DeclGroupPtrTy
-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
+Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group) {
+  // C++14 [dcl.spec.auto]p7: (DR1347)
+  //   If the type that replaces the placeholder type is not the same in each
   //   deduction, the program is ill-formed.
-  // FIXME: When initializer-list support is added, a distinction is needed
-  // between the deduced type U and the deduced type which 'auto' stands for.
-  //   auto a = 0, b = { 1, 2, 3 };
-  // is legal because the deduced type U is 'int' in both cases.
-  if (TypeMayContainAuto && Group.size() > 1) {
+  if (Group.size() > 1) {
     QualType Deduced;
-    CanQualType DeducedCanon;
     VarDecl *DeducedDecl = nullptr;
     for (unsigned i = 0, e = Group.size(); i != e; ++i) {
-      if (VarDecl *D = dyn_cast<VarDecl>(Group[i])) {
-        AutoType *AT = D->getType()->getContainedAutoType();
-        // Don't reissue diagnostics when instantiating a template.
-        if (AT && D->isInvalidDecl())
-          break;
-        QualType U = AT ? AT->getDeducedType() : QualType();
-        if (!U.isNull()) {
-          CanQualType UCanon = Context.getCanonicalType(U);
-          if (Deduced.isNull()) {
-            Deduced = U;
-            DeducedCanon = UCanon;
-            DeducedDecl = D;
-          } else if (DeducedCanon != UCanon) {
-            Diag(D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
-                 diag::err_auto_different_deductions)
-              << (unsigned)AT->getKeyword()
-              << Deduced << DeducedDecl->getDeclName()
-              << U << D->getDeclName()
-              << DeducedDecl->getInit()->getSourceRange()
-              << D->getInit()->getSourceRange();
-            D->setInvalidDecl();
-            break;
-          }
-        }
+      VarDecl *D = dyn_cast<VarDecl>(Group[i]);
+      if (!D || D->isInvalidDecl())
+        break;
+      DeducedType *DT = D->getType()->getContainedDeducedType();
+      if (!DT || DT->getDeducedType().isNull())
+        continue;
+      if (Deduced.isNull()) {
+        Deduced = DT->getDeducedType();
+        DeducedDecl = D;
+      } else if (!Context.hasSameType(DT->getDeducedType(), Deduced)) {
+        auto *AT = dyn_cast<AutoType>(DT);
+        Diag(D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
+             diag::err_auto_different_deductions)
+          << (AT ? (unsigned)AT->getKeyword() : 3)
+          << Deduced << DeducedDecl->getDeclName()
+          << DT->getDeducedType() << D->getDeclName()
+          << DeducedDecl->getInit()->getSourceRange()
+          << D->getInit()->getSourceRange();
+        D->setInvalidDecl();
+        break;
       }
     }
   }
@@ -11258,7 +11472,7 @@
 void Sema::DiagnoseUnusedParameters(ArrayRef<ParmVarDecl *> Parameters) {
   // Don't diagnose unused-parameter errors in template instantiations; we
   // will already have done so in the template itself.
-  if (!ActiveTemplateInstantiations.empty())
+  if (inTemplateInstantiation())
     return;
 
   for (const ParmVarDecl *Parameter : Parameters) {
@@ -11476,8 +11690,6 @@
 Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
                                    const FunctionDecl *EffectiveDefinition,
                                    SkipBodyInfo *SkipBody) {
-  // Don't complain if we're in GNU89 mode and the previous definition
-  // was an extern inline function.
   const FunctionDecl *Definition = EffectiveDefinition;
   if (!Definition)
     if (!FD->isDefined(Definition))
@@ -11562,9 +11774,6 @@
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
                                     SkipBodyInfo *SkipBody) {
-  // Clear the last template instantiation error context.
-  LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
-
   if (!D)
     return D;
   FunctionDecl *FD = nullptr;
@@ -11574,6 +11783,18 @@
   else
     FD = cast<FunctionDecl>(D);
 
+  // Check for defining attributes before the check for redefinition.
+  if (const auto *Attr = FD->getAttr<AliasAttr>()) {
+    Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 0;
+    FD->dropAttr<AliasAttr>();
+    FD->setInvalidDecl();
+  }
+  if (const auto *Attr = FD->getAttr<IFuncAttr>()) {
+    Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 1;
+    FD->dropAttr<IFuncAttr>();
+    FD->setInvalidDecl();
+  }
+
   // See if this is a redefinition.
   if (!FD->isLateTemplateParsed()) {
     CheckForFunctionRedefinition(FD, nullptr, SkipBody);
@@ -11598,14 +11819,14 @@
   // captures during transformation of nested lambdas, it is necessary to
   // have the LSI properly restored.
   if (isGenericLambdaCallOperatorSpecialization(FD)) {
-    assert(ActiveTemplateInstantiations.size() &&
-      "There should be an active template instantiation on the stack "
-      "when instantiating a generic lambda!");
+    assert(inTemplateInstantiation() &&
+           "There should be an active template instantiation on the stack "
+           "when instantiating a generic lambda!");
     RebuildLambdaScopeInfo(cast<CXXMethodDecl>(D), *this);
-  }
-  else
+  } else {
     // Enter a new function scope
     PushFunctionScope();
+  }
 
   // Builtin functions cannot be defined.
   if (unsigned BuiltinID = FD->getBuiltinID()) {
@@ -11632,6 +11853,29 @@
   CheckParmsForFunctionDef(FD->parameters(),
                            /*CheckParameterNames=*/true);
 
+  // Add non-parameter declarations already in the function to the current
+  // scope.
+  if (FnBodyScope) {
+    for (Decl *NPD : FD->decls()) {
+      auto *NonParmDecl = dyn_cast<NamedDecl>(NPD);
+      if (!NonParmDecl)
+        continue;
+      assert(!isa<ParmVarDecl>(NonParmDecl) &&
+             "parameters should not be in newly created FD yet");
+
+      // If the decl has a name, make it accessible in the current scope.
+      if (NonParmDecl->getDeclName())
+        PushOnScopeChains(NonParmDecl, FnBodyScope, /*AddToContext=*/false);
+
+      // Similarly, dive into enums and fish their constants out, making them
+      // accessible in this scope.
+      if (auto *ED = dyn_cast<EnumDecl>(NonParmDecl)) {
+        for (auto *EI : ED->enumerators())
+          PushOnScopeChains(EI, FnBodyScope, /*AddToContext=*/false);
+      }
+    }
+  }
+
   // Introduce our parameters into the function scope
   for (auto Param : FD->parameters()) {
     Param->setOwningFunction(FD);
@@ -11644,39 +11888,6 @@
     }
   }
 
-  // If we had any tags defined in the function prototype,
-  // introduce them into the function scope.
-  if (FnBodyScope) {
-    for (ArrayRef<NamedDecl *>::iterator
-             I = FD->getDeclsInPrototypeScope().begin(),
-             E = FD->getDeclsInPrototypeScope().end();
-         I != E; ++I) {
-      NamedDecl *D = *I;
-
-      // Some of these decls (like enums) may have been pinned to the
-      // translation unit for lack of a real context earlier. If so, remove
-      // from the translation unit and reattach to the current context.
-      if (D->getLexicalDeclContext() == Context.getTranslationUnitDecl()) {
-        // Is the decl actually in the context?
-        if (Context.getTranslationUnitDecl()->containsDecl(D))
-          Context.getTranslationUnitDecl()->removeDecl(D);
-        // Either way, reassign the lexical decl context to our FunctionDecl.
-        D->setLexicalDeclContext(CurContext);
-      }
-
-      // If the decl has a non-null name, make accessible in the current scope.
-      if (!D->getName().empty())
-        PushOnScopeChains(D, FnBodyScope, /*AddToContext=*/false);
-
-      // Similarly, dive into enums and fish their constants out, making them
-      // accessible in this scope.
-      if (auto *ED = dyn_cast<EnumDecl>(D)) {
-        for (auto *EI : ED->enumerators())
-          PushOnScopeChains(EI, FnBodyScope, /*AddToContext=*/false);
-      }
-    }
-  }
-
   // Ensure that the function's exception specification is instantiated.
   if (const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>())
     ResolveExceptionSpec(D->getLocation(), FPT);
@@ -11730,7 +11941,7 @@
 
   // We can't delay parsing the body of a function template with a deduced
   // return type (yet).
-  if (D.getDeclSpec().containsPlaceholderType()) {
+  if (D.getDeclSpec().hasAutoTypeSpec()) {
     // If the placeholder introduces a non-deduced trailing return type,
     // we can still delay parsing it.
     if (D.getNumTypeObjects()) {
@@ -11778,7 +11989,7 @@
   sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
   sema::AnalysisBasedWarnings::Policy *ActivePolicy = nullptr;
 
-  if (getLangOpts().CoroutinesTS && !getCurFunction()->CoroutineStmts.empty())
+  if (getLangOpts().CoroutinesTS && getCurFunction()->CoroutinePromise)
     CheckCompletedCoroutineBody(FD, Body);
 
   if (FD) {
@@ -11899,7 +12110,7 @@
           !LangOpts.CPlusPlus) {
         TypeSourceInfo *TI = FD->getTypeSourceInfo();
         TypeLoc TL = TI->getTypeLoc();
-        FunctionTypeLoc FTL = TL.castAs<FunctionTypeLoc>();
+        FunctionTypeLoc FTL = TL.getAsAdjusted<FunctionTypeLoc>();
         Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 1;
       }
     }
@@ -12161,6 +12372,7 @@
                                              /*NumExceptions=*/0,
                                              /*NoexceptExpr=*/nullptr,
                                              /*ExceptionSpecTokens=*/nullptr,
+                                             /*DeclsInPrototype=*/None,
                                              Loc, Loc, D),
                 DS.getAttributes(),
                 SourceLocation());
@@ -12434,7 +12646,8 @@
   return Tag == TTK_Struct || Tag == TTK_Class || Tag == TTK_Interface;
 }
 
-Sema::NonTagKind Sema::getNonTagTypeDeclKind(const Decl *PrevDecl) {
+Sema::NonTagKind Sema::getNonTagTypeDeclKind(const Decl *PrevDecl,
+                                             TagTypeKind TTK) {
   if (isa<TypedefDecl>(PrevDecl))
     return NTK_Typedef;
   else if (isa<TypeAliasDecl>(PrevDecl))
@@ -12445,7 +12658,17 @@
     return NTK_TypeAliasTemplate;
   else if (isa<TemplateTemplateParmDecl>(PrevDecl))
     return NTK_TemplateTemplateArgument;
-  return NTK_Unknown;
+  switch (TTK) {
+  case TTK_Struct:
+  case TTK_Interface:
+  case TTK_Class:
+    return getLangOpts().CPlusPlus ? NTK_NonClass : NTK_NonStruct;
+  case TTK_Union:
+    return NTK_NonUnion;
+  case TTK_Enum:
+    return NTK_NonEnum;
+  }
+  llvm_unreachable("invalid TTK");
 }
 
 /// \brief Determine whether a tag with a given kind is acceptable
@@ -12480,7 +12703,7 @@
     if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Previous))
       isTemplate = Record->getDescribedClassTemplate();
 
-    if (!ActiveTemplateInstantiations.empty()) {
+    if (inTemplateInstantiation()) {
       // In a template instantiation, do not offer fix-its for tag mismatches
       // since they usually mess up the template instead of fixing the problem.
       Diag(NewTagLoc, diag::warn_struct_class_tag_mismatch)
@@ -12605,28 +12828,6 @@
   return false;
 }
 
-/// Find the DeclContext in which a tag is implicitly declared if we see an
-/// elaborated type specifier in the specified context, and lookup finds
-/// nothing.
-static DeclContext *getTagInjectionContext(DeclContext *DC) {
-  while (!DC->isFileContext() && !DC->isFunctionOrMethod())
-    DC = DC->getParent();
-  return DC;
-}
-
-/// Find the Scope in which a tag is implicitly declared if we see an
-/// elaborated type specifier in the specified context, and lookup finds
-/// nothing.
-static Scope *getTagInjectionScope(Scope *S, const LangOptions &LangOpts) {
-  while (S->isClassScope() ||
-         (LangOpts.CPlusPlus &&
-          S->isFunctionPrototypeScope()) ||
-         ((S->getFlags() & Scope::DeclScope) == 0) ||
-         (S->getEntity() && S->getEntity()->isTransparentContext()))
-    S = S->getParent();
-  return S;
-}
-
 /// \brief This is invoked when we see 'struct foo' or 'struct {'.  In the
 /// former case, Name will be non-null.  In the later case, Name will be null.
 /// TagSpec indicates what kind of tag this is. TUK indicates whether this is a
@@ -12658,8 +12859,8 @@
   TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
   bool ScopedEnum = ScopedEnumKWLoc.isValid();
 
-  // FIXME: Check explicit specializations more carefully.
-  bool isExplicitSpecialization = false;
+  // FIXME: Check member specializations more carefully.
+  bool isMemberSpecialization = false;
   bool Invalid = false;
 
   // We only need to do this matching if we have template parameters
@@ -12670,7 +12871,7 @@
     if (TemplateParameterList *TemplateParams =
             MatchTemplateParametersToScopeSpecifier(
                 KWLoc, NameLoc, SS, nullptr, TemplateParameterLists,
-                TUK == TUK_Friend, isExplicitSpecialization, Invalid)) {
+                TUK == TUK_Friend, isMemberSpecialization, Invalid)) {
       if (Kind == TTK_Enum) {
         Diag(KWLoc, diag::err_enum_template);
         return nullptr;
@@ -12697,7 +12898,7 @@
         // The "template<>" header is extraneous.
         Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
           << TypeWithKeyword::getTagTypeKindName(Kind) << Name;
-        isExplicitSpecialization = true;
+        isMemberSpecialization = true;
       }
     }
   }
@@ -13017,7 +13218,7 @@
     if (auto *Shadow = dyn_cast<UsingShadowDecl>(DirectPrevDecl)) {
       auto *OldTag = dyn_cast<TagDecl>(PrevDecl);
       if (SS.isEmpty() && TUK != TUK_Reference && TUK != TUK_Friend &&
-          isDeclInScope(Shadow, SearchDC, S, isExplicitSpecialization) &&
+          isDeclInScope(Shadow, SearchDC, S, isMemberSpecialization) &&
           !(OldTag && isAcceptableTagRedeclContext(
                           *this, OldTag->getDeclContext(), SearchDC))) {
         Diag(KWLoc, diag::err_using_decl_conflict_reverse);
@@ -13037,7 +13238,7 @@
       // rementions the tag), reuse the decl.
       if (TUK == TUK_Reference || TUK == TUK_Friend ||
           isDeclInScope(DirectPrevDecl, SearchDC, S,
-                        SS.isNotEmpty() || isExplicitSpecialization)) {
+                        SS.isNotEmpty() || isMemberSpecialization)) {
         // Make sure that this wasn't declared as an enum and now used as a
         // struct or something similar.
         if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind,
@@ -13142,7 +13343,7 @@
               // is from an implicit instantiation, don't emit an error
               // here; we'll catch this in the general case below.
               bool IsExplicitSpecializationAfterInstantiation = false;
-              if (isExplicitSpecialization) {
+              if (isMemberSpecialization) {
                 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Def))
                   IsExplicitSpecializationAfterInstantiation =
                     RD->getTemplateSpecializationKind() !=
@@ -13228,19 +13429,20 @@
       // (non-redeclaration) lookup.
       if ((TUK == TUK_Reference || TUK == TUK_Friend) &&
           !Previous.isForRedeclaration()) {
-        NonTagKind NTK = getNonTagTypeDeclKind(PrevDecl);
-        Diag(NameLoc, diag::err_tag_reference_non_tag) << NTK;
+        NonTagKind NTK = getNonTagTypeDeclKind(PrevDecl, Kind);
+        Diag(NameLoc, diag::err_tag_reference_non_tag) << PrevDecl << NTK
+                                                       << Kind;
         Diag(PrevDecl->getLocation(), diag::note_declared_at);
         Invalid = true;
 
       // Otherwise, only diagnose if the declaration is in scope.
       } else if (!isDeclInScope(DirectPrevDecl, SearchDC, S,
-                                SS.isNotEmpty() || isExplicitSpecialization)) {
+                                SS.isNotEmpty() || isMemberSpecialization)) {
         // do nothing
 
       // Diagnose implicit declarations introduced by elaborated types.
       } else if (TUK == TUK_Reference || TUK == TUK_Friend) {
-        NonTagKind NTK = getNonTagTypeDeclKind(PrevDecl);
+        NonTagKind NTK = getNonTagTypeDeclKind(PrevDecl, Kind);
         Diag(NameLoc, diag::err_tag_reference_conflict) << NTK;
         Diag(PrevDecl->getLocation(), diag::note_previous_decl) << PrevDecl;
         Invalid = true;
@@ -13367,7 +13569,7 @@
       // for explicit specializations, because they have similar checking
       // (with more specific diagnostics) in the call to
       // CheckMemberSpecialization, below.
-      if (!isExplicitSpecialization &&
+      if (!isMemberSpecialization &&
           (TUK == TUK_Definition || TUK == TUK_Declaration) &&
           diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc))
         Invalid = true;
@@ -13398,7 +13600,7 @@
   }
 
   if (ModulePrivateLoc.isValid()) {
-    if (isExplicitSpecialization)
+    if (isMemberSpecialization)
       Diag(New->getLocation(), diag::err_module_private_specialization)
         << 2
         << FixItHint::CreateRemoval(ModulePrivateLoc);
@@ -13411,7 +13613,7 @@
 
   // If this is a specialization of a member class (of a class template),
   // check the specialization.
-  if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
+  if (isMemberSpecialization && CheckMemberSpecialization(New, Previous))
     Invalid = true;
 
   // If we're declaring or defining a tag in function prototype scope in C,
@@ -13430,15 +13632,11 @@
     } else if (!PrevDecl) {
       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);
-
   // 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);
@@ -13457,6 +13655,9 @@
   if (TUK == TUK_Definition)
     New->startDefinition();
 
+  if (Attr)
+    ProcessDeclAttributeList(S, New, Attr);
+
   // If this has an identifier, add it to the scope stack.
   if (TUK == TUK_Friend) {
     // We might be replacing an existing declaration in the lookup tables;
@@ -13579,8 +13780,11 @@
       RD->completeDefinition();
   }
 
-  if (isa<CXXRecordDecl>(Tag))
+  if (auto *RD = dyn_cast<CXXRecordDecl>(Tag)) {
     FieldCollector->FinishClass();
+    if (Context.getLangOpts().Modules)
+      RD->computeODRHash();
+  }
 
   // Exit this scope of this tag's definition.
   PopDeclContext();
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index ffb1051..3979383 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -32,6 +32,7 @@
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/SemaInternal.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/MathExtras.h"
 
@@ -246,6 +247,28 @@
   return true;
 }
 
+/// \brief Wrapper around checkUInt32Argument, with an extra check to be sure
+/// that the result will fit into a regular (signed) int. All args have the same
+/// purpose as they do in checkUInt32Argument.
+static bool checkPositiveIntArgument(Sema &S, const AttributeList &Attr,
+                                     const Expr *Expr, int &Val,
+                                     unsigned Idx = UINT_MAX) {
+  uint32_t UVal;
+  if (!checkUInt32Argument(S, Attr, Expr, UVal, Idx))
+    return false;
+
+  if (UVal > (uint32_t)std::numeric_limits<int>::max()) {
+    llvm::APSInt I(32); // for toString
+    I = UVal;
+    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
+        << I.toString(10, false) << 32 << /* Unsigned */ 0;
+    return false;
+  }
+
+  Val = UVal;
+  return true;
+}
+
 /// \brief Diagnose mutually exclusive attributes when present on a given
 /// declaration. Returns true if diagnosed.
 template <typename AttrTy>
@@ -730,6 +753,69 @@
                                      Attr.getAttributeSpellingListIndex()));
 }
 
+/// \brief Checks to be sure that the given parameter number is inbounds, and is
+/// an some integral type. Will emit appropriate diagnostics if this returns
+/// false.
+///
+/// FuncParamNo is expected to be from the user, so is base-1. AttrArgNo is used
+/// to actually retrieve the argument, so it's base-0.
+static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD,
+                                    const AttributeList &Attr,
+                                    unsigned FuncParamNo, unsigned AttrArgNo) {
+  assert(Attr.isArgExpr(AttrArgNo) && "Expected expression argument");
+  uint64_t Idx;
+  if (!checkFunctionOrMethodParameterIndex(S, FD, Attr, FuncParamNo,
+                                           Attr.getArgAsExpr(AttrArgNo), Idx))
+    return false;
+
+  const ParmVarDecl *Param = FD->getParamDecl(Idx);
+  if (!Param->getType()->isIntegerType() && !Param->getType()->isCharType()) {
+    SourceLocation SrcLoc = Attr.getArgAsExpr(AttrArgNo)->getLocStart();
+    S.Diag(SrcLoc, diag::err_attribute_integers_only)
+        << Attr.getName() << Param->getSourceRange();
+    return false;
+  }
+  return true;
+}
+
+static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (!checkAttributeAtLeastNumArgs(S, Attr, 1) ||
+      !checkAttributeAtMostNumArgs(S, Attr, 2))
+    return;
+
+  const auto *FD = cast<FunctionDecl>(D);
+  if (!FD->getReturnType()->isPointerType()) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_return_pointers_only)
+        << Attr.getName();
+    return;
+  }
+
+  const Expr *SizeExpr = Attr.getArgAsExpr(0);
+  int SizeArgNo;
+  // Parameter indices are 1-indexed, hence Index=1
+  if (!checkPositiveIntArgument(S, Attr, SizeExpr, SizeArgNo, /*Index=*/1))
+    return;
+
+  if (!checkParamIsIntegerType(S, FD, Attr, SizeArgNo, /*AttrArgNo=*/0))
+    return;
+
+  // Args are 1-indexed, so 0 implies that the arg was not present
+  int NumberArgNo = 0;
+  if (Attr.getNumArgs() == 2) {
+    const Expr *NumberExpr = Attr.getArgAsExpr(1);
+    // Parameter indices are 1-based, hence Index=2
+    if (!checkPositiveIntArgument(S, Attr, NumberExpr, NumberArgNo,
+                                  /*Index=*/2))
+      return;
+
+    if (!checkParamIsIntegerType(S, FD, Attr, NumberArgNo, /*AttrArgNo=*/1))
+      return;
+  }
+
+  D->addAttr(::new (S.Context) AllocSizeAttr(
+      Attr.getRange(), S.Context, SizeArgNo, NumberArgNo,
+      Attr.getAttributeSpellingListIndex()));
+}
 
 static bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
                                       const AttributeList &Attr,
@@ -805,34 +891,117 @@
                                Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleEnableIfAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  S.Diag(Attr.getLoc(), diag::ext_clang_enable_if);
-
-  Expr *Cond = Attr.getArgAsExpr(0);
+static bool checkFunctionConditionAttr(Sema &S, Decl *D,
+                                       const AttributeList &Attr,
+                                       Expr *&Cond, StringRef &Msg) {
+  Cond = Attr.getArgAsExpr(0);
   if (!Cond->isTypeDependent()) {
     ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
     if (Converted.isInvalid())
-      return;
+      return false;
     Cond = Converted.get();
   }
 
-  StringRef Msg;
   if (!S.checkStringLiteralArgumentAttr(Attr, 1, Msg))
-    return;
+    return false;
+
+  if (Msg.empty())
+    Msg = "<no message provided>";
 
   SmallVector<PartialDiagnosticAt, 8> Diags;
   if (!Cond->isValueDependent() &&
       !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
                                                 Diags)) {
-    S.Diag(Attr.getLoc(), diag::err_enable_if_never_constant_expr);
+    S.Diag(Attr.getLoc(), diag::err_attr_cond_never_constant_expr)
+        << Attr.getName();
     for (const PartialDiagnosticAt &PDiag : Diags)
       S.Diag(PDiag.first, PDiag.second);
+    return false;
+  }
+  return true;
+}
+
+static void handleEnableIfAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  S.Diag(Attr.getLoc(), diag::ext_clang_enable_if);
+
+  Expr *Cond;
+  StringRef Msg;
+  if (checkFunctionConditionAttr(S, D, Attr, Cond, Msg))
+    D->addAttr(::new (S.Context)
+                   EnableIfAttr(Attr.getRange(), S.Context, Cond, Msg,
+                                Attr.getAttributeSpellingListIndex()));
+}
+
+namespace {
+/// Determines if a given Expr references any of the given function's
+/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
+class ArgumentDependenceChecker
+    : public RecursiveASTVisitor<ArgumentDependenceChecker> {
+#ifndef NDEBUG
+  const CXXRecordDecl *ClassType;
+#endif
+  llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms;
+  bool Result;
+
+public:
+  ArgumentDependenceChecker(const FunctionDecl *FD) {
+#ifndef NDEBUG
+    if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
+      ClassType = MD->getParent();
+    else
+      ClassType = nullptr;
+#endif
+    Parms.insert(FD->param_begin(), FD->param_end());
+  }
+
+  bool referencesArgs(Expr *E) {
+    Result = false;
+    TraverseStmt(E);
+    return Result;
+  }
+
+  bool VisitCXXThisExpr(CXXThisExpr *E) {
+    assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
+           "`this` doesn't refer to the enclosing class?");
+    Result = true;
+    return false;
+  }
+
+  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+    if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
+      if (Parms.count(PVD)) {
+        Result = true;
+        return false;
+      }
+    return true;
+  }
+};
+}
+
+static void handleDiagnoseIfAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  S.Diag(Attr.getLoc(), diag::ext_clang_diagnose_if);
+
+  Expr *Cond;
+  StringRef Msg;
+  if (!checkFunctionConditionAttr(S, D, Attr, Cond, Msg))
+    return;
+
+  StringRef DiagTypeStr;
+  if (!S.checkStringLiteralArgumentAttr(Attr, 2, DiagTypeStr))
+    return;
+
+  DiagnoseIfAttr::DiagnosticType DiagType;
+  if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) {
+    S.Diag(Attr.getArgAsExpr(2)->getLocStart(),
+           diag::err_diagnose_if_invalid_diagnostic_type);
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             EnableIfAttr(Attr.getRange(), S.Context, Cond, Msg,
-                          Attr.getAttributeSpellingListIndex()));
+  auto *FD = cast<FunctionDecl>(D);
+  bool ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
+  D->addAttr(::new (S.Context) DiagnoseIfAttr(
+      Attr.getRange(), S.Context, Cond, Msg, DiagType, ArgDependent, FD,
+      Attr.getAttributeSpellingListIndex()));
 }
 
 static void handlePassObjectSizeAttr(Sema &S, Decl *D,
@@ -1251,7 +1420,7 @@
   // check if the attribute came from a macro expansion or a template
   // instantiation.
   if (NonNullArgs.empty() && Attr.getLoc().isFileID() &&
-      S.ActiveTemplateInstantiations.empty()) {
+      !S.inTemplateInstantiation()) {
     bool AnyPointers = isFunctionOrMethodVariadic(D);
     for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
          I != E && !AnyPointers; ++I) {
@@ -2240,6 +2409,32 @@
   }
 }
 
+static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
+                                           const AttributeList &Attr) {
+  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
+    return;
+  assert(checkAttributeAtMostNumArgs(S, Attr, 3) &&
+         "Invalid number of arguments in an external_source_symbol attribute");
+
+  if (!isa<NamedDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+        << Attr.getName() << ExpectedNamedDecl;
+    return;
+  }
+
+  StringRef Language;
+  if (const auto *SE = dyn_cast_or_null<StringLiteral>(Attr.getArgAsExpr(0)))
+    Language = SE->getString();
+  StringRef DefinedIn;
+  if (const auto *SE = dyn_cast_or_null<StringLiteral>(Attr.getArgAsExpr(1)))
+    DefinedIn = SE->getString();
+  bool IsGeneratedDeclaration = Attr.getArgAsIdent(2) != nullptr;
+
+  D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
+      Attr.getRange(), S.Context, Language, DefinedIn, IsGeneratedDeclaration,
+      Attr.getAttributeSpellingListIndex()));
+}
+
 template <class T>
 static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range,
                               typename T::VisibilityType value,
@@ -3024,8 +3219,9 @@
   }
 
   if (!RD->isCompleteDefinition()) {
-    S.Diag(Attr.getLoc(),
-        diag::warn_transparent_union_attribute_not_definition);
+    if (!RD->isBeingDefined())
+      S.Diag(Attr.getLoc(),
+             diag::warn_transparent_union_attribute_not_definition);
     return;
   }
 
@@ -4228,6 +4424,19 @@
                                     Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleXRayLogArgsAttr(Sema &S, Decl *D,
+                                  const AttributeList &Attr) {
+  uint64_t ArgCount;
+  if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, Attr.getArgAsExpr(0),
+                                           ArgCount))
+    return;
+
+  // ArgCount isn't a parameter index [0;n), it's a count [1;n] - hence + 1.
+  D->addAttr(::new (S.Context)
+             XRayLogArgsAttr(Attr.getRange(), S.Context, ++ArgCount,
+             Attr.getAttributeSpellingListIndex()));
+}
+
 //===----------------------------------------------------------------------===//
 // Checker-specific attribute handlers.
 //===----------------------------------------------------------------------===//
@@ -4666,12 +4875,6 @@
     return;
   }
 
-  if (!isa<CXXRecordDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedClass;
-    return;
-  }
-
   StringRef StrRef;
   SourceLocation LiteralLoc;
   if (!S.checkStringLiteralArgumentAttr(Attr, 0, StrRef, &LiteralLoc))
@@ -4963,6 +5166,32 @@
   D->addAttr(UsedAttr::CreateImplicit(S.Context));
 }
 
+static void handleAVRInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (!isFunctionOrMethod(D)) {
+    S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
+        << "'interrupt'" << ExpectedFunction;
+    return;
+  }
+
+  if (!checkAttributeNumArgs(S, Attr, 0))
+    return;
+
+  handleSimpleAttribute<AVRInterruptAttr>(S, D, Attr);
+}
+
+static void handleAVRSignalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (!isFunctionOrMethod(D)) {
+    S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
+        << "'signal'" << ExpectedFunction;
+    return;
+  }
+
+  if (!checkAttributeNumArgs(S, Attr, 0))
+    return;
+
+  handleSimpleAttribute<AVRSignalAttr>(S, D, Attr);
+}
+
 static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // Dispatch the interrupt attribute based on the current target.
   switch (S.Context.getTargetInfo().getTriple().getArch()) {
@@ -4977,6 +5206,9 @@
   case llvm::Triple::x86_64:
     handleAnyX86InterruptAttr(S, D, Attr);
     break;
+  case llvm::Triple::avr:
+    handleAVRInterruptAttr(S, D, Attr);
+    break;
   default:
     handleARMInterruptAttr(S, D, Attr);
     break;
@@ -5537,6 +5769,9 @@
   case AttributeList::AT_AMDGPUNumVGPR:
     handleAMDGPUNumVGPRAttr(S, D, Attr);
     break;
+  case AttributeList::AT_AVRSignal:
+    handleAVRSignalAttr(S, D, Attr);
+    break;
   case AttributeList::AT_IBAction:
     handleSimpleAttribute<IBActionAttr>(S, D, Attr);
     break;
@@ -5558,6 +5793,9 @@
   case AttributeList::AT_AlignValue:
     handleAlignValueAttr(S, D, Attr);
     break;
+  case AttributeList::AT_AllocSize:
+    handleAllocSizeAttr(S, D, Attr);
+    break;
   case AttributeList::AT_AlwaysInline:
     handleAlwaysInlineAttr(S, D, Attr);
     break;
@@ -5600,9 +5838,15 @@
   case AttributeList::AT_EnableIf:
     handleEnableIfAttr(S, D, Attr);
     break;
+  case AttributeList::AT_DiagnoseIf:
+    handleDiagnoseIfAttr(S, D, Attr);
+    break;
   case AttributeList::AT_ExtVectorType:
     handleExtVectorTypeAttr(S, scope, D, Attr);
     break;
+  case AttributeList::AT_ExternalSourceSymbol:
+    handleExternalSourceSymbolAttr(S, D, Attr);
+    break;
   case AttributeList::AT_MinSize:
     handleMinSizeAttr(S, D, Attr);
     break;
@@ -6054,6 +6298,9 @@
   case AttributeList::AT_XRayInstrument:
     handleSimpleAttribute<XRayInstrumentAttr>(S, D, Attr);
     break;
+  case AttributeList::AT_XRayLogArgs:
+    handleXRayLogArgsAttr(S, D, Attr);
+    break;
   }
 }
 
@@ -6113,6 +6360,15 @@
   }
 }
 
+// Helper for delayed proccessing TransparentUnion attribute.
+void Sema::ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList) {
+  for (const AttributeList *Attr = AttrList; Attr; Attr = Attr->getNext())
+    if (Attr->getKind() == AttributeList::AT_TransparentUnion) {
+      handleTransparentUnionAttr(*this, D, *Attr);
+      break;
+    }
+}
+
 // Annotation attributes are the only attributes allowed after an access
 // specifier.
 bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index fd33b31..668d4b2 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -647,6 +647,17 @@
     Invalid = true;
   }
 
+  // FIXME: It's not clear what should happen if multiple declarations of a
+  // deduction guide have different explicitness. For now at least we simply
+  // reject any case where the explicitness changes.
+  auto *NewGuide = dyn_cast<CXXDeductionGuideDecl>(New);
+  if (NewGuide && NewGuide->isExplicitSpecified() !=
+                      cast<CXXDeductionGuideDecl>(Old)->isExplicitSpecified()) {
+    Diag(New->getLocation(), diag::err_deduction_guide_explicit_mismatch)
+      << NewGuide->isExplicitSpecified();
+    Diag(Old->getLocation(), diag::note_previous_declaration);
+  }
+
   // C++11 [dcl.fct.default]p4: If a friend declaration specifies a default
   // argument expression, that declaration shall be a definition and shall be
   // the only declaration of the function or function template in the
@@ -2705,8 +2716,7 @@
   if (D->isInvalidDecl() || D->hasAttr<OverrideAttr>())
     return;
   CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D);
-  if (!MD || MD->isImplicit() || MD->hasAttr<FinalAttr>() ||
-      isa<CXXDestructorDecl>(MD))
+  if (!MD || MD->isImplicit() || MD->hasAttr<FinalAttr>())
     return;
 
   SourceLocation Loc = MD->getLocation();
@@ -2716,10 +2726,12 @@
   SpellingLoc = getSourceManager().getSpellingLoc(SpellingLoc);
   if (SpellingLoc.isValid() && getSourceManager().isInSystemHeader(SpellingLoc))
       return;
-    
+
   if (MD->size_overridden_methods() > 0) {
-    Diag(MD->getLocation(), diag::warn_function_marked_not_override_overriding)
-      << MD->getDeclName();
+    unsigned DiagID = isa<CXXDestructorDecl>(MD)
+                          ? diag::warn_destructor_marked_not_override_overriding
+                          : diag::warn_function_marked_not_override_overriding;
+    Diag(MD->getLocation(), DiagID) << MD->getDeclName();
     const CXXMethodDecl *OMD = *MD->begin_overridden_methods();
     Diag(OMD->getLocation(), diag::note_overridden_virtual_function);
   }
@@ -2758,6 +2770,56 @@
   return nullptr;
 }
 
+// Check if there is a field shadowing.
+void Sema::CheckShadowInheritedFields(const SourceLocation &Loc,
+                                      DeclarationName FieldName,
+                                      const CXXRecordDecl *RD) {
+  if (Diags.isIgnored(diag::warn_shadow_field, Loc))
+    return;
+
+  // To record a shadowed field in a base
+  std::map<CXXRecordDecl*, NamedDecl*> Bases;
+  auto FieldShadowed = [&](const CXXBaseSpecifier *Specifier,
+                           CXXBasePath &Path) {
+    const auto Base = Specifier->getType()->getAsCXXRecordDecl();
+    // Record an ambiguous path directly
+    if (Bases.find(Base) != Bases.end())
+      return true;
+    for (const auto Field : Base->lookup(FieldName)) {
+      if ((isa<FieldDecl>(Field) || isa<IndirectFieldDecl>(Field)) &&
+          Field->getAccess() != AS_private) {
+        assert(Field->getAccess() != AS_none);
+        assert(Bases.find(Base) == Bases.end());
+        Bases[Base] = Field;
+        return true;
+      }
+    }
+    return false;
+  };
+
+  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                     /*DetectVirtual=*/true);
+  if (!RD->lookupInBases(FieldShadowed, Paths))
+    return;
+
+  for (const auto &P : Paths) {
+    auto Base = P.back().Base->getType()->getAsCXXRecordDecl();
+    auto It = Bases.find(Base);
+    // Skip duplicated bases
+    if (It == Bases.end())
+      continue;
+    auto BaseField = It->second;
+    assert(BaseField->getAccess() != AS_private);
+    if (AS_none !=
+        CXXRecordDecl::MergeAccess(P.Access, BaseField->getAccess())) {
+      Diag(Loc, diag::warn_shadow_field)
+        << FieldName.getAsString() << RD->getName() << Base->getName();
+      Diag(BaseField->getLocation(), diag::note_shadow_field);
+      Bases.erase(It);
+    }
+  }
+}
+
 /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
 /// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
 /// bitfield width if there is one, 'InitExpr' specifies the initializer if
@@ -2957,6 +3019,8 @@
       if (!Member)
         return nullptr;
     }
+
+    CheckShadowInheritedFields(Loc, Name, cast<CXXRecordDecl>(CurContext));
   } else {
     Member = HandleDeclarator(S, D, TemplateParameterLists);
     if (!Member)
@@ -3673,6 +3737,9 @@
     BaseType = GetTypeFromParser(TemplateTypeTy, &TInfo);
   } else if (DS.getTypeSpecType() == TST_decltype) {
     BaseType = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc());
+  } else if (DS.getTypeSpecType() == TST_decltype_auto) {
+    Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid);
+    return true;
   } else {
     LookupResult R(*this, MemberOrBase, IdLoc, LookupOrdinaryName);
     LookupParsedName(R, S, &SS);
@@ -4246,98 +4313,30 @@
       CtorArg = CastForMoving(SemaRef, CtorArg.get());
     }
 
-    // When the field we are copying is an array, create index variables for 
-    // each dimension of the array. We use these index variables to subscript
-    // the source array, and other clients (e.g., CodeGen) will perform the
-    // necessary iteration with these index variables.
-    SmallVector<VarDecl *, 4> IndexVariables;
-    QualType BaseType = Field->getType();
-    QualType SizeType = SemaRef.Context.getSizeType();
-    bool InitializingArray = false;
-    while (const ConstantArrayType *Array
-                          = SemaRef.Context.getAsConstantArrayType(BaseType)) {
-      InitializingArray = true;
-      // Create the iteration variable for this array index.
-      IdentifierInfo *IterationVarName = nullptr;
-      {
-        SmallString<8> Str;
-        llvm::raw_svector_ostream OS(Str);
-        OS << "__i" << IndexVariables.size();
-        IterationVarName = &SemaRef.Context.Idents.get(OS.str());
-      }
-      VarDecl *IterationVar
-        = VarDecl::Create(SemaRef.Context, SemaRef.CurContext, Loc, Loc,
-                          IterationVarName, SizeType,
-                        SemaRef.Context.getTrivialTypeSourceInfo(SizeType, Loc),
-                          SC_None);
-      IndexVariables.push_back(IterationVar);
-      
-      // Create a reference to the iteration variable.
-      ExprResult IterationVarRef
-        = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
-      assert(!IterationVarRef.isInvalid() &&
-             "Reference to invented variable cannot fail!");
-      IterationVarRef = SemaRef.DefaultLvalueConversion(IterationVarRef.get());
-      assert(!IterationVarRef.isInvalid() &&
-             "Conversion of invented variable cannot fail!");
+    InitializedEntity Entity =
+        Indirect ? InitializedEntity::InitializeMember(Indirect, nullptr,
+                                                       /*Implicit*/ true)
+                 : InitializedEntity::InitializeMember(Field, nullptr,
+                                                       /*Implicit*/ true);
 
-      // Subscript the array with this iteration variable.
-      CtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CtorArg.get(), Loc,
-                                                        IterationVarRef.get(),
-                                                        Loc);
-      if (CtorArg.isInvalid())
-        return true;
-
-      BaseType = Array->getElementType();
-    }
-
-    // The array subscript expression is an lvalue, which is wrong for moving.
-    if (Moving && InitializingArray)
-      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
-    // of array-subscript entities. 
-    SmallVector<InitializedEntity, 4> Entities;
-    Entities.reserve(1 + IndexVariables.size());
-    if (Indirect)
-      Entities.push_back(InitializedEntity::InitializeMember(Indirect));
-    else
-      Entities.push_back(InitializedEntity::InitializeMember(Field));
-    for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I)
-      Entities.push_back(InitializedEntity::InitializeElement(SemaRef.Context,
-                                                              0,
-                                                              Entities.back()));
-    
     // Direct-initialize to use the copy constructor.
     InitializationKind InitKind =
       InitializationKind::CreateDirect(Loc, SourceLocation(), SourceLocation());
     
     Expr *CtorArgE = CtorArg.getAs<Expr>();
-    InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind,
-                                   CtorArgE);
-
-    ExprResult MemberInit
-      = InitSeq.Perform(SemaRef, Entities.back(), InitKind, 
-                        MultiExprArg(&CtorArgE, 1));
+    InitializationSequence InitSeq(SemaRef, Entity, InitKind, CtorArgE);
+    ExprResult MemberInit =
+        InitSeq.Perform(SemaRef, Entity, InitKind, MultiExprArg(&CtorArgE, 1));
     MemberInit = SemaRef.MaybeCreateExprWithCleanups(MemberInit);
     if (MemberInit.isInvalid())
       return true;
 
-    if (Indirect) {
-      assert(IndexVariables.size() == 0 && 
-             "Indirect field improperly initialized");
-      CXXMemberInit
-        = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect, 
-                                                   Loc, Loc, 
-                                                   MemberInit.getAs<Expr>(), 
-                                                   Loc);
-    } else
-      CXXMemberInit = CXXCtorInitializer::Create(SemaRef.Context, Field, Loc, 
-                                                 Loc, MemberInit.getAs<Expr>(), 
-                                                 Loc,
-                                                 IndexVariables.data(),
-                                                 IndexVariables.size());
+    if (Indirect)
+      CXXMemberInit = new (SemaRef.Context) CXXCtorInitializer(
+          SemaRef.Context, Indirect, Loc, Loc, MemberInit.getAs<Expr>(), Loc);
+    else
+      CXXMemberInit = new (SemaRef.Context) CXXCtorInitializer(
+          SemaRef.Context, Field, Loc, Loc, MemberInit.getAs<Expr>(), Loc);
     return false;
   }
 
@@ -4348,9 +4347,11 @@
     SemaRef.Context.getBaseElementType(Field->getType());
   
   if (FieldBaseElementType->isRecordType()) {
-    InitializedEntity InitEntity 
-      = Indirect? InitializedEntity::InitializeMember(Indirect)
-                : InitializedEntity::InitializeMember(Field);
+    InitializedEntity InitEntity =
+        Indirect ? InitializedEntity::InitializeMember(Indirect, nullptr,
+                                                       /*Implicit*/ true)
+                 : InitializedEntity::InitializeMember(Field, nullptr,
+                                                       /*Implicit*/ true);
     InitializationKind InitKind = 
       InitializationKind::CreateDefault(Loc);
 
@@ -5081,6 +5082,10 @@
     DiagnoseUseOfDecl(Dtor, Location);
   }
 
+  // We only potentially invoke the destructors of potentially constructed
+  // subobjects.
+  bool VisitVirtualBases = !ClassDecl->isAbstract();
+
   llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
 
   // Bases.
@@ -5089,8 +5094,11 @@
     const RecordType *RT = Base.getType()->getAs<RecordType>();
 
     // Remember direct virtual bases.
-    if (Base.isVirtual())
+    if (Base.isVirtual()) {
+      if (!VisitVirtualBases)
+        continue;
       DirectVirtualBases.insert(RT);
+    }
 
     CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
     // If our base class is invalid, we probably can't get its dtor anyway.
@@ -5112,6 +5120,9 @@
     MarkFunctionReferenced(Location, Dtor);
     DiagnoseUseOfDecl(Dtor, Location);
   }
+
+  if (!VisitVirtualBases)
+    return;
   
   // Virtual bases.
   for (const auto &VBase : ClassDecl->vbases()) {
@@ -5461,6 +5472,44 @@
   }
 }
 
+static void checkForMultipleExportedDefaultConstructors(Sema &S,
+                                                        CXXRecordDecl *Class) {
+  // Only the MS ABI has default constructor closures, so we don't need to do
+  // this semantic checking anywhere else.
+  if (!S.Context.getTargetInfo().getCXXABI().isMicrosoft())
+    return;
+
+  CXXConstructorDecl *LastExportedDefaultCtor = nullptr;
+  for (Decl *Member : Class->decls()) {
+    // Look for exported default constructors.
+    auto *CD = dyn_cast<CXXConstructorDecl>(Member);
+    if (!CD || !CD->isDefaultConstructor())
+      continue;
+    auto *Attr = CD->getAttr<DLLExportAttr>();
+    if (!Attr)
+      continue;
+
+    // If the class is non-dependent, mark the default arguments as ODR-used so
+    // that we can properly codegen the constructor closure.
+    if (!Class->isDependentContext()) {
+      for (ParmVarDecl *PD : CD->parameters()) {
+        (void)S.CheckCXXDefaultArgExpr(Attr->getLocation(), CD, PD);
+        S.DiscardCleanupsInEvaluationContext();
+      }
+    }
+
+    if (LastExportedDefaultCtor) {
+      S.Diag(LastExportedDefaultCtor->getLocation(),
+             diag::err_attribute_dll_ambiguous_default_ctor)
+          << Class;
+      S.Diag(CD->getLocation(), diag::note_entity_declared_at)
+          << CD->getDeclName();
+      return;
+    }
+    LastExportedDefaultCtor = CD;
+  }
+}
+
 /// \brief Check class-level dllimport/dllexport attribute.
 void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
   Attr *ClassAttr = getDLLAttr(Class);
@@ -5814,7 +5863,7 @@
 /// \param ConstRHS True if this is a copy operation with a const object
 ///        on its RHS, that is, if the argument to the outer special member
 ///        function is 'const' and this is not a field marked 'mutable'.
-static Sema::SpecialMemberOverloadResult *lookupCallFromSpecialMember(
+static Sema::SpecialMemberOverloadResult lookupCallFromSpecialMember(
     Sema &S, CXXRecordDecl *Class, Sema::CXXSpecialMember CSM,
     unsigned FieldQuals, bool ConstRHS) {
   unsigned LHSQuals = 0;
@@ -5937,13 +5986,13 @@
   if (CSM == Sema::CXXDefaultConstructor)
     return ClassDecl->hasConstexprDefaultConstructor();
 
-  Sema::SpecialMemberOverloadResult *SMOR =
+  Sema::SpecialMemberOverloadResult SMOR =
       lookupCallFromSpecialMember(S, ClassDecl, CSM, Quals, ConstRHS);
-  if (!SMOR || !SMOR->getMethod())
+  if (!SMOR.getMethod())
     // A constructor we wouldn't select can't be "involved in initializing"
     // anything.
     return true;
-  return SMOR->getMethod()->isConstexpr();
+  return SMOR.getMethod()->isConstexpr();
 }
 
 /// Determine whether the specified special member function would be constexpr
@@ -6053,27 +6102,23 @@
 }
 
 static Sema::ImplicitExceptionSpecification
+ComputeDefaultedSpecialMemberExceptionSpec(
+    Sema &S, SourceLocation Loc, CXXMethodDecl *MD, Sema::CXXSpecialMember CSM,
+    Sema::InheritedConstructorInfo *ICI);
+
+static Sema::ImplicitExceptionSpecification
 computeImplicitExceptionSpec(Sema &S, SourceLocation Loc, CXXMethodDecl *MD) {
-  switch (S.getSpecialMember(MD)) {
-  case Sema::CXXDefaultConstructor:
-    return S.ComputeDefaultedDefaultCtorExceptionSpec(Loc, MD);
-  case Sema::CXXCopyConstructor:
-    return S.ComputeDefaultedCopyCtorExceptionSpec(MD);
-  case Sema::CXXCopyAssignment:
-    return S.ComputeDefaultedCopyAssignmentExceptionSpec(MD);
-  case Sema::CXXMoveConstructor:
-    return S.ComputeDefaultedMoveCtorExceptionSpec(MD);
-  case Sema::CXXMoveAssignment:
-    return S.ComputeDefaultedMoveAssignmentExceptionSpec(MD);
-  case Sema::CXXDestructor:
-    return S.ComputeDefaultedDtorExceptionSpec(MD);
-  case Sema::CXXInvalid:
-    break;
-  }
-  assert(cast<CXXConstructorDecl>(MD)->getInheritedConstructor() &&
+  auto CSM = S.getSpecialMember(MD);
+  if (CSM != Sema::CXXInvalid)
+    return ComputeDefaultedSpecialMemberExceptionSpec(S, Loc, MD, CSM, nullptr);
+
+  auto *CD = cast<CXXConstructorDecl>(MD);
+  assert(CD->getInheritedConstructor() &&
          "only special members have implicit exception specs");
-  return S.ComputeInheritingCtorExceptionSpec(Loc,
-                                              cast<CXXConstructorDecl>(MD));
+  Sema::InheritedConstructorInfo ICI(
+      S, Loc, CD->getInheritedConstructor().getShadowDecl());
+  return ComputeDefaultedSpecialMemberExceptionSpec(
+      S, Loc, CD, Sema::CXXDefaultConstructor, &ICI);
 }
 
 static FunctionProtoType::ExtProtoInfo getImplicitMethodEPI(Sema &S,
@@ -6328,45 +6373,35 @@
 }
 
 namespace {
-struct SpecialMemberDeletionInfo {
+/// CRTP base class for visiting operations performed by a special member
+/// function (or inherited constructor).
+template<typename Derived>
+struct SpecialMemberVisitor {
   Sema &S;
   CXXMethodDecl *MD;
   Sema::CXXSpecialMember CSM;
   Sema::InheritedConstructorInfo *ICI;
-  bool Diagnose;
 
   // Properties of the special member, computed for convenience.
-  bool IsConstructor, IsAssignment, IsMove, ConstArg;
-  SourceLocation Loc;
+  bool IsConstructor = false, IsAssignment = false, ConstArg = false;
 
-  bool AllFieldsAreConst;
-
-  SpecialMemberDeletionInfo(Sema &S, CXXMethodDecl *MD,
-                            Sema::CXXSpecialMember CSM,
-                            Sema::InheritedConstructorInfo *ICI, bool Diagnose)
-      : S(S), MD(MD), CSM(CSM), ICI(ICI), Diagnose(Diagnose),
-        IsConstructor(false), IsAssignment(false), IsMove(false),
-        ConstArg(false), Loc(MD->getLocation()), AllFieldsAreConst(true) {
+  SpecialMemberVisitor(Sema &S, CXXMethodDecl *MD, Sema::CXXSpecialMember CSM,
+                       Sema::InheritedConstructorInfo *ICI)
+      : S(S), MD(MD), CSM(CSM), ICI(ICI) {
     switch (CSM) {
-      case Sema::CXXDefaultConstructor:
-      case Sema::CXXCopyConstructor:
-        IsConstructor = true;
-        break;
-      case Sema::CXXMoveConstructor:
-        IsConstructor = true;
-        IsMove = true;
-        break;
-      case Sema::CXXCopyAssignment:
-        IsAssignment = true;
-        break;
-      case Sema::CXXMoveAssignment:
-        IsAssignment = true;
-        IsMove = true;
-        break;
-      case Sema::CXXDestructor:
-        break;
-      case Sema::CXXInvalid:
-        llvm_unreachable("invalid special member kind");
+    case Sema::CXXDefaultConstructor:
+    case Sema::CXXCopyConstructor:
+    case Sema::CXXMoveConstructor:
+      IsConstructor = true;
+      break;
+    case Sema::CXXCopyAssignment:
+    case Sema::CXXMoveAssignment:
+      IsAssignment = true;
+      break;
+    case Sema::CXXDestructor:
+      break;
+    case Sema::CXXInvalid:
+      llvm_unreachable("invalid special member kind");
     }
 
     if (MD->getNumParams()) {
@@ -6376,20 +6411,108 @@
     }
   }
 
+  Derived &getDerived() { return static_cast<Derived&>(*this); }
+
+  /// Is this a "move" special member?
+  bool isMove() const {
+    return CSM == Sema::CXXMoveConstructor || CSM == Sema::CXXMoveAssignment;
+  }
+
+  /// Look up the corresponding special member in the given class.
+  Sema::SpecialMemberOverloadResult lookupIn(CXXRecordDecl *Class,
+                                             unsigned Quals, bool IsMutable) {
+    return lookupCallFromSpecialMember(S, Class, CSM, Quals,
+                                       ConstArg && !IsMutable);
+  }
+
+  /// Look up the constructor for the specified base class to see if it's
+  /// overridden due to this being an inherited constructor.
+  Sema::SpecialMemberOverloadResult lookupInheritedCtor(CXXRecordDecl *Class) {
+    if (!ICI)
+      return {};
+    assert(CSM == Sema::CXXDefaultConstructor);
+    auto *BaseCtor =
+      cast<CXXConstructorDecl>(MD)->getInheritedConstructor().getConstructor();
+    if (auto *MD = ICI->findConstructorForBase(Class, BaseCtor).first)
+      return MD;
+    return {};
+  }
+
+  /// A base or member subobject.
+  typedef llvm::PointerUnion<CXXBaseSpecifier*, FieldDecl*> Subobject;
+
+  /// Get the location to use for a subobject in diagnostics.
+  static SourceLocation getSubobjectLoc(Subobject Subobj) {
+    // FIXME: For an indirect virtual base, the direct base leading to
+    // the indirect virtual base would be a more useful choice.
+    if (auto *B = Subobj.dyn_cast<CXXBaseSpecifier*>())
+      return B->getBaseTypeLoc();
+    else
+      return Subobj.get<FieldDecl*>()->getLocation();
+  }
+
+  enum BasesToVisit {
+    /// Visit all non-virtual (direct) bases.
+    VisitNonVirtualBases,
+    /// Visit all direct bases, virtual or not.
+    VisitDirectBases,
+    /// Visit all non-virtual bases, and all virtual bases if the class
+    /// is not abstract.
+    VisitPotentiallyConstructedBases,
+    /// Visit all direct or virtual bases.
+    VisitAllBases
+  };
+
+  // Visit the bases and members of the class.
+  bool visit(BasesToVisit Bases) {
+    CXXRecordDecl *RD = MD->getParent();
+
+    if (Bases == VisitPotentiallyConstructedBases)
+      Bases = RD->isAbstract() ? VisitNonVirtualBases : VisitAllBases;
+
+    for (auto &B : RD->bases())
+      if ((Bases == VisitDirectBases || !B.isVirtual()) &&
+          getDerived().visitBase(&B))
+        return true;
+
+    if (Bases == VisitAllBases)
+      for (auto &B : RD->vbases())
+        if (getDerived().visitBase(&B))
+          return true;
+
+    for (auto *F : RD->fields())
+      if (!F->isInvalidDecl() && !F->isUnnamedBitfield() &&
+          getDerived().visitField(F))
+        return true;
+
+    return false;
+  }
+};
+}
+
+namespace {
+struct SpecialMemberDeletionInfo
+    : SpecialMemberVisitor<SpecialMemberDeletionInfo> {
+  bool Diagnose;
+
+  SourceLocation Loc;
+
+  bool AllFieldsAreConst;
+
+  SpecialMemberDeletionInfo(Sema &S, CXXMethodDecl *MD,
+                            Sema::CXXSpecialMember CSM,
+                            Sema::InheritedConstructorInfo *ICI, bool Diagnose)
+      : SpecialMemberVisitor(S, MD, CSM, ICI), Diagnose(Diagnose),
+        Loc(MD->getLocation()), AllFieldsAreConst(true) {}
+
   bool inUnion() const { return MD->getParent()->isUnion(); }
 
   Sema::CXXSpecialMember getEffectiveCSM() {
     return ICI ? Sema::CXXInvalid : CSM;
   }
 
-  /// Look up the corresponding special member in the given class.
-  Sema::SpecialMemberOverloadResult *lookupIn(CXXRecordDecl *Class,
-                                              unsigned Quals, bool IsMutable) {
-    return lookupCallFromSpecialMember(S, Class, CSM, Quals,
-                                       ConstArg && !IsMutable);
-  }
-
-  typedef llvm::PointerUnion<CXXBaseSpecifier*, FieldDecl*> Subobject;
+  bool visitBase(CXXBaseSpecifier *Base) { return shouldDeleteForBase(Base); }
+  bool visitField(FieldDecl *Field) { return shouldDeleteForField(Field); }
 
   bool shouldDeleteForBase(CXXBaseSpecifier *Base);
   bool shouldDeleteForField(FieldDecl *FD);
@@ -6398,7 +6521,7 @@
   bool shouldDeleteForClassSubobject(CXXRecordDecl *Class, Subobject Subobj,
                                      unsigned Quals);
   bool shouldDeleteForSubobjectCall(Subobject Subobj,
-                                    Sema::SpecialMemberOverloadResult *SMOR,
+                                    Sema::SpecialMemberOverloadResult SMOR,
                                     bool IsDtorCallInCtor);
 
   bool isAccessible(Subobject Subobj, CXXMethodDecl *D);
@@ -6428,16 +6551,16 @@
 /// Check whether we should delete a special member due to the implicit
 /// definition containing a call to a special member of a subobject.
 bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
-    Subobject Subobj, Sema::SpecialMemberOverloadResult *SMOR,
+    Subobject Subobj, Sema::SpecialMemberOverloadResult SMOR,
     bool IsDtorCallInCtor) {
-  CXXMethodDecl *Decl = SMOR->getMethod();
+  CXXMethodDecl *Decl = SMOR.getMethod();
   FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
 
   int DiagKind = -1;
 
-  if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted)
+  if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted)
     DiagKind = !Decl ? 0 : 1;
-  else if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
+  else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
     DiagKind = 2;
   else if (!isAccessible(Subobj, Decl))
     DiagKind = 3;
@@ -6507,7 +6630,7 @@
   // -- any direct or virtual base class or non-static data member has a
   //    type with a destructor that is deleted or inaccessible
   if (IsConstructor) {
-    Sema::SpecialMemberOverloadResult *SMOR =
+    Sema::SpecialMemberOverloadResult SMOR =
         S.LookupSpecialMember(Class, Sema::CXXDestructor,
                               false, false, false, false, false);
     if (shouldDeleteForSubobjectCall(Subobj, SMOR, true))
@@ -6527,23 +6650,20 @@
     return false;
   // If we have an inheriting constructor, check whether we're calling an
   // inherited constructor instead of a default constructor.
-  if (ICI) {
-    assert(CSM == Sema::CXXDefaultConstructor);
-    auto *BaseCtor =
-        ICI->findConstructorForBase(BaseClass, cast<CXXConstructorDecl>(MD)
-                                                   ->getInheritedConstructor()
-                                                   .getConstructor())
-            .first;
-    if (BaseCtor) {
-      if (BaseCtor->isDeleted() && Diagnose) {
-        S.Diag(Base->getLocStart(),
-               diag::note_deleted_special_member_class_subobject)
-          << getEffectiveCSM() << MD->getParent() << /*IsField*/false
-          << Base->getType() << /*Deleted*/1 << /*IsDtorCallInCtor*/false;
-        S.NoteDeletedFunction(BaseCtor);
-      }
-      return BaseCtor->isDeleted();
+  Sema::SpecialMemberOverloadResult SMOR = lookupInheritedCtor(BaseClass);
+  if (auto *BaseCtor = SMOR.getMethod()) {
+    // Note that we do not check access along this path; other than that,
+    // this is the same as shouldDeleteForSubobjectCall(Base, BaseCtor, false);
+    // FIXME: Check that the base has a usable destructor! Sink this into
+    // shouldDeleteForClassSubobject.
+    if (BaseCtor->isDeleted() && Diagnose) {
+      S.Diag(Base->getLocStart(),
+             diag::note_deleted_special_member_class_subobject)
+        << getEffectiveCSM() << MD->getParent() << /*IsField*/false
+        << Base->getType() << /*Deleted*/1 << /*IsDtorCallInCtor*/false;
+      S.NoteDeletedFunction(BaseCtor);
     }
+    return BaseCtor->isDeleted();
   }
   return shouldDeleteForClassSubobject(BaseClass, Base, 0);
 }
@@ -6592,7 +6712,7 @@
     if (FieldType->isReferenceType()) {
       if (Diagnose)
         S.Diag(FD->getLocation(), diag::note_deleted_assign_field)
-          << IsMove << MD->getParent() << FD << FieldType << /*Reference*/0;
+          << isMove() << MD->getParent() << FD << FieldType << /*Reference*/0;
       return true;
     }
     if (!FieldRecord && FieldType.isConstQualified()) {
@@ -6600,7 +6720,7 @@
       // -- a non-static data member of const non-class type (or array thereof)
       if (Diagnose)
         S.Diag(FD->getLocation(), diag::note_deleted_assign_field)
-          << IsMove << MD->getParent() << FD << FD->getType() << /*Const*/1;
+          << isMove() << MD->getParent() << FD << FD->getType() << /*Const*/1;
       return true;
     }
   }
@@ -6771,24 +6891,15 @@
 
   SpecialMemberDeletionInfo SMI(*this, MD, CSM, ICI, Diagnose);
 
-  for (auto &BI : RD->bases())
-    if ((SMI.IsAssignment || !BI.isVirtual()) &&
-        SMI.shouldDeleteForBase(&BI))
-      return true;
-
   // Per DR1611, do not consider virtual bases of constructors of abstract
-  // classes, since we are not going to construct them. For assignment
-  // operators, we only assign (and thus only consider) direct bases.
-  if ((!RD->isAbstract() || !SMI.IsConstructor) && !SMI.IsAssignment) {
-    for (auto &BI : RD->vbases())
-      if (SMI.shouldDeleteForBase(&BI))
-        return true;
-  }
-
-  for (auto *FI : RD->fields())
-    if (!FI->isInvalidDecl() && !FI->isUnnamedBitfield() &&
-        SMI.shouldDeleteForField(FI))
-      return true;
+  // classes, since we are not going to construct them.
+  // Per DR1658, do not consider virtual bases of destructors of abstract
+  // classes either.
+  // Per DR2180, for assignment operators we only assign (and thus only
+  // consider) direct bases.
+  if (SMI.visit(SMI.IsAssignment ? SMI.VisitDirectBases
+                                 : SMI.VisitPotentiallyConstructedBases))
+    return true;
 
   if (SMI.shouldDeleteForAllConstMembers())
     return true;
@@ -6902,18 +7013,18 @@
   case Sema::CXXMoveConstructor:
   case Sema::CXXMoveAssignment:
   NeedOverloadResolution:
-    Sema::SpecialMemberOverloadResult *SMOR =
+    Sema::SpecialMemberOverloadResult SMOR =
         lookupCallFromSpecialMember(S, RD, CSM, Quals, ConstRHS);
 
     // The standard doesn't describe how to behave if the lookup is ambiguous.
     // We treat it as not making the member non-trivial, just like the standard
     // mandates for the default constructor. This should rarely matter, because
     // the member will also be deleted.
-    if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
+    if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
       return true;
 
-    if (!SMOR->getMethod()) {
-      assert(SMOR->getKind() ==
+    if (!SMOR.getMethod()) {
+      assert(SMOR.getKind() ==
              Sema::SpecialMemberOverloadResult::NoMemberOrDeleted);
       return false;
     }
@@ -6921,8 +7032,8 @@
     // We deliberately don't check if we found a deleted special member. We're
     // not supposed to!
     if (Selected)
-      *Selected = SMOR->getMethod();
-    return SMOR->getMethod()->isTrivial();
+      *Selected = SMOR.getMethod();
+    return SMOR.getMethod()->isTrivial();
   }
 
   llvm_unreachable("unknown special method kind");
@@ -8061,6 +8172,154 @@
   return Conversion;
 }
 
+namespace {
+/// Utility class to accumulate and print a diagnostic listing the invalid
+/// specifier(s) on a declaration.
+struct BadSpecifierDiagnoser {
+  BadSpecifierDiagnoser(Sema &S, SourceLocation Loc, unsigned DiagID)
+      : S(S), Diagnostic(S.Diag(Loc, DiagID)) {}
+  ~BadSpecifierDiagnoser() {
+    Diagnostic << Specifiers;
+  }
+
+  template<typename T> void check(SourceLocation SpecLoc, T Spec) {
+    return check(SpecLoc, DeclSpec::getSpecifierName(Spec));
+  }
+  void check(SourceLocation SpecLoc, DeclSpec::TST Spec) {
+    return check(SpecLoc,
+                 DeclSpec::getSpecifierName(Spec, S.getPrintingPolicy()));
+  }
+  void check(SourceLocation SpecLoc, const char *Spec) {
+    if (SpecLoc.isInvalid()) return;
+    Diagnostic << SourceRange(SpecLoc, SpecLoc);
+    if (!Specifiers.empty()) Specifiers += " ";
+    Specifiers += Spec;
+  }
+
+  Sema &S;
+  Sema::SemaDiagnosticBuilder Diagnostic;
+  std::string Specifiers;
+};
+}
+
+/// Check the validity of a declarator that we parsed for a deduction-guide.
+/// These aren't actually declarators in the grammar, so we need to check that
+/// the user didn't specify any pieces that are not part of the deduction-guide
+/// grammar.
+void Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
+                                         StorageClass &SC) {
+  TemplateName GuidedTemplate = D.getName().TemplateName.get().get();
+  TemplateDecl *GuidedTemplateDecl = GuidedTemplate.getAsTemplateDecl();
+  assert(GuidedTemplateDecl && "missing template decl for deduction guide");
+
+  // C++ [temp.deduct.guide]p3:
+  //   A deduction-gide shall be declared in the same scope as the
+  //   corresponding class template.
+  if (!CurContext->getRedeclContext()->Equals(
+          GuidedTemplateDecl->getDeclContext()->getRedeclContext())) {
+    Diag(D.getIdentifierLoc(), diag::err_deduction_guide_wrong_scope)
+      << GuidedTemplateDecl;
+    Diag(GuidedTemplateDecl->getLocation(), diag::note_template_decl_here);
+  }
+
+  auto &DS = D.getMutableDeclSpec();
+  // We leave 'friend' and 'virtual' to be rejected in the normal way.
+  if (DS.hasTypeSpecifier() || DS.getTypeQualifiers() ||
+      DS.getStorageClassSpecLoc().isValid() || DS.isInlineSpecified() ||
+      DS.isNoreturnSpecified() || DS.isConstexprSpecified() ||
+      DS.isConceptSpecified()) {
+    BadSpecifierDiagnoser Diagnoser(
+        *this, D.getIdentifierLoc(),
+        diag::err_deduction_guide_invalid_specifier);
+
+    Diagnoser.check(DS.getStorageClassSpecLoc(), DS.getStorageClassSpec());
+    DS.ClearStorageClassSpecs();
+    SC = SC_None;
+
+    // 'explicit' is permitted.
+    Diagnoser.check(DS.getInlineSpecLoc(), "inline");
+    Diagnoser.check(DS.getNoreturnSpecLoc(), "_Noreturn");
+    Diagnoser.check(DS.getConstexprSpecLoc(), "constexpr");
+    Diagnoser.check(DS.getConceptSpecLoc(), "concept");
+    DS.ClearConstexprSpec();
+    DS.ClearConceptSpec();
+
+    Diagnoser.check(DS.getConstSpecLoc(), "const");
+    Diagnoser.check(DS.getRestrictSpecLoc(), "__restrict");
+    Diagnoser.check(DS.getVolatileSpecLoc(), "volatile");
+    Diagnoser.check(DS.getAtomicSpecLoc(), "_Atomic");
+    Diagnoser.check(DS.getUnalignedSpecLoc(), "__unaligned");
+    DS.ClearTypeQualifiers();
+
+    Diagnoser.check(DS.getTypeSpecComplexLoc(), DS.getTypeSpecComplex());
+    Diagnoser.check(DS.getTypeSpecSignLoc(), DS.getTypeSpecSign());
+    Diagnoser.check(DS.getTypeSpecWidthLoc(), DS.getTypeSpecWidth());
+    Diagnoser.check(DS.getTypeSpecTypeLoc(), DS.getTypeSpecType());
+    DS.ClearTypeSpecType();
+  }
+
+  if (D.isInvalidType())
+    return;
+
+  // Check the declarator is simple enough.
+  bool FoundFunction = false;
+  for (const DeclaratorChunk &Chunk : llvm::reverse(D.type_objects())) {
+    if (Chunk.Kind == DeclaratorChunk::Paren)
+      continue;
+    if (Chunk.Kind != DeclaratorChunk::Function || FoundFunction) {
+      Diag(D.getDeclSpec().getLocStart(),
+          diag::err_deduction_guide_with_complex_decl)
+        << D.getSourceRange();
+      break;
+    }
+    if (!Chunk.Fun.hasTrailingReturnType()) {
+      Diag(D.getName().getLocStart(),
+           diag::err_deduction_guide_no_trailing_return_type);
+      break;
+    }
+
+    // Check that the return type is written as a specialization of
+    // the template specified as the deduction-guide's name.
+    ParsedType TrailingReturnType = Chunk.Fun.getTrailingReturnType();
+    TypeSourceInfo *TSI = nullptr;
+    QualType RetTy = GetTypeFromParser(TrailingReturnType, &TSI);
+    assert(TSI && "deduction guide has valid type but invalid return type?");
+    bool AcceptableReturnType = false;
+    bool MightInstantiateToSpecialization = false;
+    if (auto RetTST =
+            TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>()) {
+      TemplateName SpecifiedName = RetTST.getTypePtr()->getTemplateName();
+      bool TemplateMatches =
+          Context.hasSameTemplateName(SpecifiedName, GuidedTemplate);
+      if (SpecifiedName.getKind() == TemplateName::Template && TemplateMatches)
+        AcceptableReturnType = true;
+      else {
+        // This could still instantiate to the right type, unless we know it
+        // names the wrong class template.
+        auto *TD = SpecifiedName.getAsTemplateDecl();
+        MightInstantiateToSpecialization = !(TD && isa<ClassTemplateDecl>(TD) &&
+                                             !TemplateMatches);
+      }
+    } else if (!RetTy.hasQualifiers() && RetTy->isDependentType()) {
+      MightInstantiateToSpecialization = true;
+    }
+
+    if (!AcceptableReturnType) {
+      Diag(TSI->getTypeLoc().getLocStart(),
+           diag::err_deduction_guide_bad_trailing_return_type)
+        << GuidedTemplate << TSI->getType() << MightInstantiateToSpecialization
+        << TSI->getTypeLoc().getSourceRange();
+    }
+
+    // Keep going to check that we don't have any inner declarator pieces (we
+    // could still have a function returning a pointer to a function).
+    FoundFunction = true;
+  }
+
+  if (D.isFunctionDefinition())
+    Diag(D.getIdentifierLoc(), diag::err_deduction_guide_defines_function);
+}
+
 //===----------------------------------------------------------------------===//
 // Namespace Handling
 //===----------------------------------------------------------------------===//
@@ -8425,7 +8684,7 @@
       CheckTemplateIdType(TemplateName(StdInitializerList), Loc, Args));
 }
 
-bool Sema::isInitListConstructor(const CXXConstructorDecl* Ctor) {
+bool Sema::isInitListConstructor(const FunctionDecl *Ctor) {
   // C++ [dcl.init.list]p2:
   //   A constructor is an initializer-list constructor if its first parameter
   //   is of type std::initializer_list<E> or reference to possibly cv-qualified
@@ -8598,15 +8857,19 @@
 
 Decl *Sema::ActOnUsingDeclaration(Scope *S,
                                   AccessSpecifier AS,
-                                  bool HasUsingKeyword,
                                   SourceLocation UsingLoc,
+                                  SourceLocation TypenameLoc,
                                   CXXScopeSpec &SS,
                                   UnqualifiedId &Name,
-                                  AttributeList *AttrList,
-                                  bool HasTypenameKeyword,
-                                  SourceLocation TypenameLoc) {
+                                  SourceLocation EllipsisLoc,
+                                  AttributeList *AttrList) {
   assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
 
+  if (SS.isEmpty()) {
+    Diag(Name.getLocStart(), diag::err_using_requires_qualname);
+    return nullptr;
+  }
+
   switch (Name.getKind()) {
   case UnqualifiedId::IK_ImplicitSelfParam:
   case UnqualifiedId::IK_Identifier:
@@ -8637,6 +8900,9 @@
     Diag(Name.getLocStart(), diag::err_using_decl_template_id)
       << SourceRange(Name.TemplateId->LAngleLoc, Name.TemplateId->RAngleLoc);
     return nullptr;
+
+  case UnqualifiedId::IK_DeductionGuideName:
+    llvm_unreachable("cannot parse qualified deduction guide name");
   }
 
   DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
@@ -8645,21 +8911,30 @@
     return nullptr;
 
   // Warn about access declarations.
-  if (!HasUsingKeyword) {
+  if (UsingLoc.isInvalid()) {
     Diag(Name.getLocStart(),
          getLangOpts().CPlusPlus11 ? diag::err_access_decl
                                    : diag::warn_access_decl_deprecated)
       << FixItHint::CreateInsertion(SS.getRange().getBegin(), "using ");
   }
 
-  if (DiagnoseUnexpandedParameterPack(SS, UPPC_UsingDeclaration) ||
-      DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC_UsingDeclaration))
-    return nullptr;
+  if (EllipsisLoc.isInvalid()) {
+    if (DiagnoseUnexpandedParameterPack(SS, UPPC_UsingDeclaration) ||
+        DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC_UsingDeclaration))
+      return nullptr;
+  } else {
+    if (!SS.getScopeRep()->containsUnexpandedParameterPack() &&
+        !TargetNameInfo.containsUnexpandedParameterPack()) {
+      Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
+        << SourceRange(SS.getBeginLoc(), TargetNameInfo.getEndLoc());
+      EllipsisLoc = SourceLocation();
+    }
+  }
 
-  NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
-                                        TargetNameInfo, AttrList,
-                                        /* IsInstantiation */ false,
-                                        HasTypenameKeyword, TypenameLoc);
+  NamedDecl *UD =
+      BuildUsingDeclaration(S, AS, UsingLoc, TypenameLoc.isValid(), TypenameLoc,
+                            SS, TargetNameInfo, EllipsisLoc, AttrList,
+                            /*IsInstantiation*/false);
   if (UD)
     PushOnScopeChains(UD, S, /*AddToContext*/ false);
 
@@ -8722,6 +8997,7 @@
              diag::err_using_decl_nested_name_specifier_is_current_class)
           << Using->getQualifierLoc().getSourceRange();
         Diag(Orig->getLocation(), diag::note_using_decl_target);
+        Using->setInvalidDecl();
         return true;
       }
 
@@ -8731,6 +9007,7 @@
         << cast<CXXRecordDecl>(CurContext)
         << Using->getQualifierLoc().getSourceRange();
       Diag(Orig->getLocation(), diag::note_using_decl_target);
+      Using->setInvalidDecl();
       return true;
     }
   }
@@ -8754,7 +9031,7 @@
     // We can have UsingDecls in our Previous results because we use the same
     // LookupResult for checking whether the UsingDecl itself is a valid
     // redeclaration.
-    if (isa<UsingDecl>(D))
+    if (isa<UsingDecl>(D) || isa<UsingPackDecl>(D))
       continue;
 
     if (IsEquivalentForUsingDecl(Context, D, Target)) {
@@ -8800,6 +9077,7 @@
 
     Diag(Target->getLocation(), diag::note_using_decl_target);
     Diag(OldDecl->getLocation(), diag::note_using_decl_conflict);
+    Using->setInvalidDecl();
     return true;
   }
 
@@ -8812,6 +9090,7 @@
     Diag(Using->getLocation(), diag::err_using_decl_conflict);
     Diag(Target->getLocation(), diag::note_using_decl_target);
     Diag(Tag->getLocation(), diag::note_using_decl_conflict);
+    Using->setInvalidDecl();
     return true;
   }
 
@@ -8821,6 +9100,7 @@
   Diag(Using->getLocation(), diag::err_using_decl_conflict);
   Diag(Target->getLocation(), diag::note_using_decl_target);
   Diag(NonTag->getLocation(), diag::note_using_decl_conflict);
+  Using->setInvalidDecl();
   return true;
 }
 
@@ -9028,23 +9308,19 @@
 ///   the lookup differently for these declarations.
 NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
                                        SourceLocation UsingLoc,
+                                       bool HasTypenameKeyword,
+                                       SourceLocation TypenameLoc,
                                        CXXScopeSpec &SS,
                                        DeclarationNameInfo NameInfo,
+                                       SourceLocation EllipsisLoc,
                                        AttributeList *AttrList,
-                                       bool IsInstantiation,
-                                       bool HasTypenameKeyword,
-                                       SourceLocation TypenameLoc) {
+                                       bool IsInstantiation) {
   assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
   SourceLocation IdentLoc = NameInfo.getLoc();
   assert(IdentLoc.isValid() && "Invalid TargetName location.");
 
   // FIXME: We ignore attributes for now.
 
-  if (SS.isEmpty()) {
-    Diag(IdentLoc, diag::err_using_requires_qualname);
-    return nullptr;
-  }
-
   // For an inheriting constructor declaration, the name of the using
   // declaration is the name of a constructor in this class, not in the
   // base class.
@@ -9078,8 +9354,23 @@
     F.done();
   } else {
     assert(IsInstantiation && "no scope in non-instantiation");
-    assert(CurContext->isRecord() && "scope not record in instantiation");
-    LookupQualifiedName(Previous, CurContext);
+    if (CurContext->isRecord())
+      LookupQualifiedName(Previous, CurContext);
+    else {
+      // No redeclaration check is needed here; in non-member contexts we
+      // diagnosed all possible conflicts with other using-declarations when
+      // building the template:
+      //
+      // For a dependent non-type using declaration, the only valid case is
+      // if we instantiate to a single enumerator. We check for conflicts
+      // between shadow declarations we introduce, and we check in the template
+      // definition for conflicts between a non-type using declaration and any
+      // other declaration, which together covers all cases.
+      //
+      // A dependent typename using declaration will never successfully
+      // instantiate, since it will always name a class member, so we reject
+      // that in the template definition.
+    }
   }
 
   // Check for invalid redeclarations.
@@ -9088,22 +9379,24 @@
     return nullptr;
 
   // Check for bad qualifiers.
-  if (CheckUsingDeclQualifier(UsingLoc, SS, NameInfo, IdentLoc))
+  if (CheckUsingDeclQualifier(UsingLoc, HasTypenameKeyword, SS, NameInfo,
+                              IdentLoc))
     return nullptr;
 
   DeclContext *LookupContext = computeDeclContext(SS);
   NamedDecl *D;
   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
-  if (!LookupContext) {
+  if (!LookupContext || EllipsisLoc.isValid()) {
     if (HasTypenameKeyword) {
       // FIXME: not all declaration name kinds are legal here
       D = UnresolvedUsingTypenameDecl::Create(Context, CurContext,
                                               UsingLoc, TypenameLoc,
                                               QualifierLoc,
-                                              IdentLoc, NameInfo.getName());
+                                              IdentLoc, NameInfo.getName(),
+                                              EllipsisLoc);
     } else {
       D = UnresolvedUsingValueDecl::Create(Context, CurContext, UsingLoc, 
-                                           QualifierLoc, NameInfo);
+                                           QualifierLoc, NameInfo, EllipsisLoc);
     }
     D->setAccess(AS);
     CurContext->addDecl(D);
@@ -9150,21 +9443,34 @@
   // invalid).
   if (R.empty() &&
       NameInfo.getName().getNameKind() != DeclarationName::CXXConstructorName) {
+    // HACK: Work around a bug in libstdc++'s detection of ::gets. Sometimes
+    // it will believe that glibc provides a ::gets in cases where it does not,
+    // and will try to pull it into namespace std with a using-declaration.
+    // Just ignore the using-declaration in that case.
+    auto *II = NameInfo.getName().getAsIdentifierInfo();
+    if (getLangOpts().CPlusPlus14 && II && II->isStr("gets") &&
+        CurContext->isStdNamespace() &&
+        isa<TranslationUnitDecl>(LookupContext) &&
+        getSourceManager().isInSystemHeader(UsingLoc))
+      return nullptr;
     if (TypoCorrection Corrected = CorrectTypo(
             R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
             llvm::make_unique<UsingValidatorCCC>(
                 HasTypenameKeyword, IsInstantiation, SS.getScopeRep(),
                 dyn_cast<CXXRecordDecl>(CurContext)),
             CTK_ErrorRecovery)) {
-      // We reject any correction for which ND would be NULL.
-      NamedDecl *ND = Corrected.getCorrectionDecl();
-
       // We reject candidates where DroppedSpecifier == true, hence the
       // literal '0' below.
       diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest)
                                 << NameInfo.getName() << LookupContext << 0
                                 << SS.getRange());
 
+      // If we picked a correction with no attached Decl we can't do anything
+      // useful with it, bail out.
+      NamedDecl *ND = Corrected.getCorrectionDecl();
+      if (!ND)
+        return BuildInvalid();
+
       // If we corrected to an inheriting constructor, handle it as one.
       auto *RD = dyn_cast<CXXRecordDecl>(ND);
       if (RD && RD->isInjectedClassName()) {
@@ -9263,6 +9569,19 @@
   return UD;
 }
 
+NamedDecl *Sema::BuildUsingPackDecl(NamedDecl *InstantiatedFrom,
+                                    ArrayRef<NamedDecl *> Expansions) {
+  assert(isa<UnresolvedUsingValueDecl>(InstantiatedFrom) ||
+         isa<UnresolvedUsingTypenameDecl>(InstantiatedFrom) ||
+         isa<UsingPackDecl>(InstantiatedFrom));
+
+  auto *UPD =
+      UsingPackDecl::Create(Context, CurContext, InstantiatedFrom, Expansions);
+  UPD->setAccess(InstantiatedFrom->getAccess());
+  CurContext->addDecl(UPD);
+  return UPD;
+}
+
 /// Additional checks for a using declaration referring to a constructor name.
 bool Sema::CheckInheritingConstructorUsingDecl(UsingDecl *UD) {
   assert(!UD->hasTypename() && "expecting a constructor name");
@@ -9299,6 +9618,8 @@
                                        const CXXScopeSpec &SS,
                                        SourceLocation NameLoc,
                                        const LookupResult &Prev) {
+  NestedNameSpecifier *Qual = SS.getScopeRep();
+
   // C++03 [namespace.udecl]p8:
   // C++0x [namespace.udecl]p10:
   //   A using-declaration is a declaration and can therefore be used
@@ -9306,10 +9627,28 @@
   //   allowed.
   //
   // That's in non-member contexts.
-  if (!CurContext->getRedeclContext()->isRecord())
+  if (!CurContext->getRedeclContext()->isRecord()) {
+    // A dependent qualifier outside a class can only ever resolve to an
+    // enumeration type. Therefore it conflicts with any other non-type
+    // declaration in the same scope.
+    // FIXME: How should we check for dependent type-type conflicts at block
+    // scope?
+    if (Qual->isDependent() && !HasTypenameKeyword) {
+      for (auto *D : Prev) {
+        if (!isa<TypeDecl>(D) && !isa<UsingDecl>(D) && !isa<UsingPackDecl>(D)) {
+          bool OldCouldBeEnumerator =
+              isa<UnresolvedUsingValueDecl>(D) || isa<EnumConstantDecl>(D);
+          Diag(NameLoc,
+               OldCouldBeEnumerator ? diag::err_redefinition
+                                    : diag::err_redefinition_different_kind)
+              << Prev.getLookupName();
+          Diag(D->getLocation(), diag::note_previous_definition);
+          return true;
+        }
+      }
+    }
     return false;
-
-  NestedNameSpecifier *Qual = SS.getScopeRep();
+  }
 
   for (LookupResult::iterator I = Prev.begin(), E = Prev.end(); I != E; ++I) {
     NamedDecl *D = *I;
@@ -9353,6 +9692,7 @@
 /// in the current context is appropriately related to the current
 /// scope.  If an error is found, diagnoses it and returns true.
 bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc,
+                                   bool HasTypename,
                                    const CXXScopeSpec &SS,
                                    const DeclarationNameInfo &NameInfo,
                                    SourceLocation NameLoc) {
@@ -9363,9 +9703,11 @@
     // C++0x [namespace.udecl]p8:
     //   A using-declaration for a class member shall be a member-declaration.
 
-    // If we weren't able to compute a valid scope, it must be a
-    // dependent class scope.
-    if (!NamedContext || NamedContext->getRedeclContext()->isRecord()) {
+    // If we weren't able to compute a valid scope, it might validly be a
+    // dependent class scope or a dependent enumeration unscoped scope. If
+    // we have a 'typename' keyword, the scope must resolve to a class type.
+    if ((HasTypename && !NamedContext) ||
+        (NamedContext && NamedContext->getRedeclContext()->isRecord())) {
       auto *RD = NamedContext
                      ? cast<CXXRecordDecl>(NamedContext->getRedeclContext())
                      : nullptr;
@@ -9425,7 +9767,8 @@
         if (getLangOpts().CPlusPlus11) {
           // Convert 'using X::Y;' to 'auto &Y = X::Y;'.
           FixIt = FixItHint::CreateReplacement(
-              UsingLoc, "constexpr auto " + NameInfo.getName().getAsString() + " = ");
+              UsingLoc,
+              "constexpr auto " + NameInfo.getName().getAsString() + " = ");
         }
 
         Diag(UsingLoc, diag::note_using_decl_class_member_workaround)
@@ -9435,7 +9778,7 @@
       return true;
     }
 
-    // Otherwise, everything is known to be fine.
+    // Otherwise, this might be valid.
     return false;
   }
 
@@ -9766,118 +10109,113 @@
   return AliasDecl;
 }
 
-Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
-                                               CXXMethodDecl *MD) {
+namespace {
+struct SpecialMemberExceptionSpecInfo
+    : SpecialMemberVisitor<SpecialMemberExceptionSpecInfo> {
+  SourceLocation Loc;
+  Sema::ImplicitExceptionSpecification ExceptSpec;
+
+  SpecialMemberExceptionSpecInfo(Sema &S, CXXMethodDecl *MD,
+                                 Sema::CXXSpecialMember CSM,
+                                 Sema::InheritedConstructorInfo *ICI,
+                                 SourceLocation Loc)
+      : SpecialMemberVisitor(S, MD, CSM, ICI), Loc(Loc), ExceptSpec(S) {}
+
+  bool visitBase(CXXBaseSpecifier *Base);
+  bool visitField(FieldDecl *FD);
+
+  void visitClassSubobject(CXXRecordDecl *Class, Subobject Subobj,
+                           unsigned Quals);
+
+  void visitSubobjectCall(Subobject Subobj,
+                          Sema::SpecialMemberOverloadResult SMOR);
+};
+}
+
+bool SpecialMemberExceptionSpecInfo::visitBase(CXXBaseSpecifier *Base) {
+  auto *RT = Base->getType()->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  auto *BaseClass = cast<CXXRecordDecl>(RT->getDecl());
+  Sema::SpecialMemberOverloadResult SMOR = lookupInheritedCtor(BaseClass);
+  if (auto *BaseCtor = SMOR.getMethod()) {
+    visitSubobjectCall(Base, BaseCtor);
+    return false;
+  }
+
+  visitClassSubobject(BaseClass, Base, 0);
+  return false;
+}
+
+bool SpecialMemberExceptionSpecInfo::visitField(FieldDecl *FD) {
+  if (CSM == Sema::CXXDefaultConstructor && FD->hasInClassInitializer()) {
+    Expr *E = FD->getInClassInitializer();
+    if (!E)
+      // FIXME: It's a little wasteful to build and throw away a
+      // CXXDefaultInitExpr here.
+      // FIXME: We should have a single context note pointing at Loc, and
+      // this location should be MD->getLocation() instead, since that's
+      // the location where we actually use the default init expression.
+      E = S.BuildCXXDefaultInitExpr(Loc, FD).get();
+    if (E)
+      ExceptSpec.CalledExpr(E);
+  } else if (auto *RT = S.Context.getBaseElementType(FD->getType())
+                            ->getAs<RecordType>()) {
+    visitClassSubobject(cast<CXXRecordDecl>(RT->getDecl()), FD,
+                        FD->getType().getCVRQualifiers());
+  }
+  return false;
+}
+
+void SpecialMemberExceptionSpecInfo::visitClassSubobject(CXXRecordDecl *Class,
+                                                         Subobject Subobj,
+                                                         unsigned Quals) {
+  FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
+  bool IsMutable = Field && Field->isMutable();
+  visitSubobjectCall(Subobj, lookupIn(Class, Quals, IsMutable));
+}
+
+void SpecialMemberExceptionSpecInfo::visitSubobjectCall(
+    Subobject Subobj, Sema::SpecialMemberOverloadResult SMOR) {
+  // Note, if lookup fails, it doesn't matter what exception specification we
+  // choose because the special member will be deleted.
+  if (CXXMethodDecl *MD = SMOR.getMethod())
+    ExceptSpec.CalledDecl(getSubobjectLoc(Subobj), MD);
+}
+
+static Sema::ImplicitExceptionSpecification
+ComputeDefaultedSpecialMemberExceptionSpec(
+    Sema &S, SourceLocation Loc, CXXMethodDecl *MD, Sema::CXXSpecialMember CSM,
+    Sema::InheritedConstructorInfo *ICI) {
   CXXRecordDecl *ClassDecl = MD->getParent();
 
   // C++ [except.spec]p14:
   //   An implicitly declared special member function (Clause 12) shall have an 
   //   exception-specification. [...]
-  ImplicitExceptionSpecification ExceptSpec(*this);
+  SpecialMemberExceptionSpecInfo Info(S, MD, CSM, ICI, Loc);
   if (ClassDecl->isInvalidDecl())
-    return ExceptSpec;
+    return Info.ExceptSpec;
 
-  // Direct base-class constructors.
-  for (const auto &B : ClassDecl->bases()) {
-    if (B.isVirtual()) // Handled below.
-      continue;
-    
-    if (const RecordType *BaseType = B.getType()->getAs<RecordType>()) {
-      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
-      CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl);
-      // If this is a deleted function, add it anyway. This might be conformant
-      // with the standard. This might not. I'm not sure. It might not matter.
-      if (Constructor)
-        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
-    }
-  }
+  // C++1z [except.spec]p7:
+  //   [Look for exceptions thrown by] a constructor selected [...] to
+  //   initialize a potentially constructed subobject,
+  // C++1z [except.spec]p8:
+  //   The exception specification for an implicitly-declared destructor, or a
+  //   destructor without a noexcept-specifier, is potentially-throwing if and
+  //   only if any of the destructors for any of its potentially constructed
+  //   subojects is potentially throwing.
+  // FIXME: We respect the first rule but ignore the "potentially constructed"
+  // in the second rule to resolve a core issue (no number yet) that would have
+  // us reject:
+  //   struct A { virtual void f() = 0; virtual ~A() noexcept(false) = 0; };
+  //   struct B : A {};
+  //   struct C : B { void f(); };
+  // ... due to giving B::~B() a non-throwing exception specification.
+  Info.visit(Info.IsConstructor ? Info.VisitPotentiallyConstructedBases
+                                : Info.VisitAllBases);
 
-  // Virtual base-class constructors.
-  for (const auto &B : ClassDecl->vbases()) {
-    if (const RecordType *BaseType = B.getType()->getAs<RecordType>()) {
-      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
-      CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl);
-      // If this is a deleted function, add it anyway. This might be conformant
-      // with the standard. This might not. I'm not sure. It might not matter.
-      if (Constructor)
-        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
-    }
-  }
-
-  // Field constructors.
-  for (const auto *F : ClassDecl->fields()) {
-    if (F->hasInClassInitializer()) {
-      if (Expr *E = F->getInClassInitializer())
-        ExceptSpec.CalledExpr(E);
-    } else if (const RecordType *RecordTy
-              = Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
-      CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
-      CXXConstructorDecl *Constructor = LookupDefaultConstructor(FieldRecDecl);
-      // If this is a deleted function, add it anyway. This might be conformant
-      // with the standard. This might not. I'm not sure. It might not matter.
-      // In particular, the problem is that this function never gets called. It
-      // might just be ill-formed because this function attempts to refer to
-      // a deleted function here.
-      if (Constructor)
-        ExceptSpec.CalledDecl(F->getLocation(), Constructor);
-    }
-  }
-
-  return ExceptSpec;
-}
-
-Sema::ImplicitExceptionSpecification
-Sema::ComputeInheritingCtorExceptionSpec(SourceLocation Loc,
-                                         CXXConstructorDecl *CD) {
-  CXXRecordDecl *ClassDecl = CD->getParent();
-
-  // C++ [except.spec]p14:
-  //   An inheriting constructor [...] shall have an exception-specification. [...]
-  ImplicitExceptionSpecification ExceptSpec(*this);
-  if (ClassDecl->isInvalidDecl())
-    return ExceptSpec;
-
-  auto Inherited = CD->getInheritedConstructor();
-  InheritedConstructorInfo ICI(*this, Loc, Inherited.getShadowDecl());
-
-  // Direct and virtual base-class constructors.
-  for (bool VBase : {false, true}) {
-    for (CXXBaseSpecifier &B :
-         VBase ? ClassDecl->vbases() : ClassDecl->bases()) {
-      // Don't visit direct vbases twice.
-      if (B.isVirtual() != VBase)
-        continue;
-
-      CXXRecordDecl *BaseClass = B.getType()->getAsCXXRecordDecl();
-      if (!BaseClass)
-        continue;
-
-      CXXConstructorDecl *Constructor =
-          ICI.findConstructorForBase(BaseClass, Inherited.getConstructor())
-              .first;
-      if (!Constructor)
-        Constructor = LookupDefaultConstructor(BaseClass);
-      if (Constructor)
-        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
-    }
-  }
-
-  // Field constructors.
-  for (const auto *F : ClassDecl->fields()) {
-    if (F->hasInClassInitializer()) {
-      if (Expr *E = F->getInClassInitializer())
-        ExceptSpec.CalledExpr(E);
-    } else if (const RecordType *RecordTy
-              = Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
-      CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
-      CXXConstructorDecl *Constructor = LookupDefaultConstructor(FieldRecDecl);
-      if (Constructor)
-        ExceptSpec.CalledDecl(F->getLocation(), Constructor);
-    }
-  }
-
-  return ExceptSpec;
+  return Info.ExceptSpec;
 }
 
 namespace {
@@ -9889,19 +10227,34 @@
   bool WasAlreadyBeingDeclared;
 
   DeclaringSpecialMember(Sema &S, CXXRecordDecl *RD, Sema::CXXSpecialMember CSM)
-    : S(S), D(RD, CSM), SavedContext(S, RD) {
+      : S(S), D(RD, CSM), SavedContext(S, RD) {
     WasAlreadyBeingDeclared = !S.SpecialMembersBeingDeclared.insert(D).second;
     if (WasAlreadyBeingDeclared)
       // This almost never happens, but if it does, ensure that our cache
       // doesn't contain a stale result.
       S.SpecialMemberCache.clear();
-
-    // FIXME: Register a note to be produced if we encounter an error while
-    // declaring the special member.
+    else {
+      // Register a note to be produced if we encounter an error while
+      // declaring the special member.
+      Sema::CodeSynthesisContext Ctx;
+      Ctx.Kind = Sema::CodeSynthesisContext::DeclaringSpecialMember;
+      // FIXME: We don't have a location to use here. Using the class's
+      // location maintains the fiction that we declare all special members
+      // with the class, but (1) it's not clear that lying about that helps our
+      // users understand what's going on, and (2) there may be outer contexts
+      // on the stack (some of which are relevant) and printing them exposes
+      // our lies.
+      Ctx.PointOfInstantiation = RD->getLocation();
+      Ctx.Entity = RD;
+      Ctx.SpecialMember = CSM;
+      S.pushCodeSynthesisContext(Ctx);
+    }
   }
   ~DeclaringSpecialMember() {
-    if (!WasAlreadyBeingDeclared)
+    if (!WasAlreadyBeingDeclared) {
       S.SpecialMembersBeingDeclared.erase(D);
+      S.popCodeSynthesisContext();
+    }
   }
 
   /// \brief Are we already trying to declare this special member?
@@ -9923,7 +10276,7 @@
   R.resolveKind();
   R.suppressDiagnostics();
 
-  CheckFunctionDeclaration(S, FD, R, /*IsExplicitSpecialization*/false);
+  CheckFunctionDeclaration(S, FD, R, /*IsMemberSpecialization*/false);
 }
 
 CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
@@ -10207,45 +10560,6 @@
   DiagnoseUninitializedFields(*this, Constructor);
 }
 
-Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD) {
-  CXXRecordDecl *ClassDecl = MD->getParent();
-
-  // C++ [except.spec]p14: 
-  //   An implicitly declared special member function (Clause 12) shall have 
-  //   an exception-specification.
-  ImplicitExceptionSpecification ExceptSpec(*this);
-  if (ClassDecl->isInvalidDecl())
-    return ExceptSpec;
-
-  // Direct base-class destructors.
-  for (const auto &B : ClassDecl->bases()) {
-    if (B.isVirtual()) // Handled below.
-      continue;
-    
-    if (const RecordType *BaseType = B.getType()->getAs<RecordType>())
-      ExceptSpec.CalledDecl(B.getLocStart(),
-                   LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl())));
-  }
-
-  // Virtual base-class destructors.
-  for (const auto &B : ClassDecl->vbases()) {
-    if (const RecordType *BaseType = B.getType()->getAs<RecordType>())
-      ExceptSpec.CalledDecl(B.getLocStart(),
-                  LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl())));
-  }
-
-  // Field destructors.
-  for (const auto *F : ClassDecl->fields()) {
-    if (const RecordType *RecordTy
-        = Context.getBaseElementType(F->getType())->getAs<RecordType>())
-      ExceptSpec.CalledDecl(F->getLocation(),
-                  LookupDestructor(cast<CXXRecordDecl>(RecordTy->getDecl())));
-  }
-
-  return ExceptSpec;
-}
-
 CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
   // C++ [class.dtor]p2:
   //   If a class has no user-declared destructor, a destructor is
@@ -10360,64 +10674,11 @@
       DelayedExceptionSpecChecks.clear();
       return;
     }
-  }
-}
-
-static void checkDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) {
-  // Don't do anything for template patterns.
-  if (Class->getDescribedClassTemplate())
-    return;
-
-  CallingConv ExpectedCallingConv = S.Context.getDefaultCallingConvention(
-      /*IsVariadic=*/false, /*IsCXXMethod=*/true);
-
-  CXXConstructorDecl *LastExportedDefaultCtor = nullptr;
-  for (Decl *Member : Class->decls()) {
-    auto *CD = dyn_cast<CXXConstructorDecl>(Member);
-    if (!CD) {
-      // Recurse on nested classes.
-      if (auto *NestedRD = dyn_cast<CXXRecordDecl>(Member))
-        checkDefaultArgExprsForConstructors(S, NestedRD);
-      continue;
-    } else if (!CD->isDefaultConstructor() || !CD->hasAttr<DLLExportAttr>()) {
-      continue;
-    }
-
-    CallingConv ActualCallingConv =
-        CD->getType()->getAs<FunctionProtoType>()->getCallConv();
-
-    // Skip default constructors with typical calling conventions and no default
-    // arguments.
-    unsigned NumParams = CD->getNumParams();
-    if (ExpectedCallingConv == ActualCallingConv && NumParams == 0)
-      continue;
-
-    if (LastExportedDefaultCtor) {
-      S.Diag(LastExportedDefaultCtor->getLocation(),
-             diag::err_attribute_dll_ambiguous_default_ctor) << Class;
-      S.Diag(CD->getLocation(), diag::note_entity_declared_at)
-          << CD->getDeclName();
-      return;
-    }
-    LastExportedDefaultCtor = CD;
-
-    for (unsigned I = 0; I != NumParams; ++I) {
-      (void)S.CheckCXXDefaultArgExpr(Class->getLocation(), CD,
-                                     CD->getParamDecl(I));
-      S.DiscardCleanupsInEvaluationContext();
-    }
+    checkForMultipleExportedDefaultConstructors(*this, Record);
   }
 }
 
 void Sema::ActOnFinishCXXNonNestedClass(Decl *D) {
-  auto *RD = dyn_cast<CXXRecordDecl>(D);
-
-  // Default constructors that are annotated with __declspec(dllexport) which
-  // have default arguments or don't use the standard calling convention are
-  // wrapped with a thunk called the default constructor closure.
-  if (RD && Context.getTargetInfo().getCXXABI().isMicrosoft())
-    checkDefaultArgExprsForConstructors(*this, RD);
-
   referenceDLLExportedClassMethods();
 }
 
@@ -10885,62 +11146,6 @@
   return Result;
 }
 
-Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD) {
-  CXXRecordDecl *ClassDecl = MD->getParent();
-
-  ImplicitExceptionSpecification ExceptSpec(*this);
-  if (ClassDecl->isInvalidDecl())
-    return ExceptSpec;
-
-  const FunctionProtoType *T = MD->getType()->castAs<FunctionProtoType>();
-  assert(T->getNumParams() == 1 && "not a copy assignment op");
-  unsigned ArgQuals =
-      T->getParamType(0).getNonReferenceType().getCVRQualifiers();
-
-  // C++ [except.spec]p14:
-  //   An implicitly declared special member function (Clause 12) shall have an
-  //   exception-specification. [...]
-
-  // It is unspecified whether or not an implicit copy assignment operator
-  // attempts to deduplicate calls to assignment operators of virtual bases are
-  // made. As such, this exception specification is effectively unspecified.
-  // Based on a similar decision made for constness in C++0x, we're erring on
-  // the side of assuming such calls to be made regardless of whether they
-  // actually happen.
-  for (const auto &Base : ClassDecl->bases()) {
-    if (Base.isVirtual())
-      continue;
-
-    CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
-    if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl,
-                                                            ArgQuals, false, 0))
-      ExceptSpec.CalledDecl(Base.getLocStart(), CopyAssign);
-  }
-
-  for (const auto &Base : ClassDecl->vbases()) {
-    CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
-    if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl,
-                                                            ArgQuals, false, 0))
-      ExceptSpec.CalledDecl(Base.getLocStart(), CopyAssign);
-  }
-
-  for (const auto *Field : ClassDecl->fields()) {
-    QualType FieldType = Context.getBaseElementType(Field->getType());
-    if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
-      if (CXXMethodDecl *CopyAssign =
-          LookupCopyingAssignment(FieldClassDecl,
-                                  ArgQuals | FieldType.getCVRQualifiers(),
-                                  false, 0))
-        ExceptSpec.CalledDecl(Field->getLocation(), CopyAssign);
-    }
-  }
-
-  return ExceptSpec;
-}
-
 CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
   // Note: The following rules are largely analoguous to the copy
   // constructor rules. Note that virtual bases are not taken into account
@@ -11284,59 +11489,6 @@
   }
 }
 
-Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD) {
-  CXXRecordDecl *ClassDecl = MD->getParent();
-
-  ImplicitExceptionSpecification ExceptSpec(*this);
-  if (ClassDecl->isInvalidDecl())
-    return ExceptSpec;
-
-  // C++0x [except.spec]p14:
-  //   An implicitly declared special member function (Clause 12) shall have an 
-  //   exception-specification. [...]
-
-  // It is unspecified whether or not an implicit move assignment operator
-  // attempts to deduplicate calls to assignment operators of virtual bases are
-  // made. As such, this exception specification is effectively unspecified.
-  // Based on a similar decision made for constness in C++0x, we're erring on
-  // the side of assuming such calls to be made regardless of whether they
-  // actually happen.
-  // Note that a move constructor is not implicitly declared when there are
-  // virtual bases, but it can still be user-declared and explicitly defaulted.
-  for (const auto &Base : ClassDecl->bases()) {
-    if (Base.isVirtual())
-      continue;
-
-    CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
-    if (CXXMethodDecl *MoveAssign = LookupMovingAssignment(BaseClassDecl,
-                                                           0, false, 0))
-      ExceptSpec.CalledDecl(Base.getLocStart(), MoveAssign);
-  }
-
-  for (const auto &Base : ClassDecl->vbases()) {
-    CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
-    if (CXXMethodDecl *MoveAssign = LookupMovingAssignment(BaseClassDecl,
-                                                           0, false, 0))
-      ExceptSpec.CalledDecl(Base.getLocStart(), MoveAssign);
-  }
-
-  for (const auto *Field : ClassDecl->fields()) {
-    QualType FieldType = Context.getBaseElementType(Field->getType());
-    if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
-      if (CXXMethodDecl *MoveAssign =
-              LookupMovingAssignment(FieldClassDecl,
-                                     FieldType.getCVRQualifiers(),
-                                     false, 0))
-        ExceptSpec.CalledDecl(Field->getLocation(), MoveAssign);
-    }
-  }
-
-  return ExceptSpec;
-}
-
 CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
   assert(ClassDecl->needsImplicitMoveAssignment());
 
@@ -11447,13 +11599,13 @@
 
       // If we're not actually going to call a move assignment for this base,
       // or the selected move assignment is trivial, skip it.
-      Sema::SpecialMemberOverloadResult *SMOR =
+      Sema::SpecialMemberOverloadResult SMOR =
         S.LookupSpecialMember(Base, Sema::CXXMoveAssignment,
                               /*ConstArg*/false, /*VolatileArg*/false,
                               /*RValueThis*/true, /*ConstThis*/false,
                               /*VolatileThis*/false);
-      if (!SMOR->getMethod() || SMOR->getMethod()->isTrivial() ||
-          !SMOR->getMethod()->isMoveAssignmentOperator())
+      if (!SMOR.getMethod() || SMOR.getMethod()->isTrivial() ||
+          !SMOR.getMethod()->isMoveAssignmentOperator())
         continue;
 
       if (BaseSpec->isVirtual()) {
@@ -11484,7 +11636,7 @@
         // Only walk over bases that have defaulted move assignment operators.
         // We assume that any user-provided move assignment operator handles
         // the multiple-moves-of-vbase case itself somehow.
-        if (!SMOR->getMethod()->isDefaulted())
+        if (!SMOR.getMethod()->isDefaulted())
           continue;
 
         // We're going to move the base classes of Base. Add them to the list.
@@ -11721,52 +11873,6 @@
   }
 }
 
-Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD) {
-  CXXRecordDecl *ClassDecl = MD->getParent();
-
-  ImplicitExceptionSpecification ExceptSpec(*this);
-  if (ClassDecl->isInvalidDecl())
-    return ExceptSpec;
-
-  const FunctionProtoType *T = MD->getType()->castAs<FunctionProtoType>();
-  assert(T->getNumParams() >= 1 && "not a copy ctor");
-  unsigned Quals = T->getParamType(0).getNonReferenceType().getCVRQualifiers();
-
-  // C++ [except.spec]p14:
-  //   An implicitly declared special member function (Clause 12) shall have an 
-  //   exception-specification. [...]
-  for (const auto &Base : ClassDecl->bases()) {
-    // Virtual bases are handled below.
-    if (Base.isVirtual())
-      continue;
-    
-    CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
-    if (CXXConstructorDecl *CopyConstructor =
-          LookupCopyingConstructor(BaseClassDecl, Quals))
-      ExceptSpec.CalledDecl(Base.getLocStart(), CopyConstructor);
-  }
-  for (const auto &Base : ClassDecl->vbases()) {
-    CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
-    if (CXXConstructorDecl *CopyConstructor =
-          LookupCopyingConstructor(BaseClassDecl, Quals))
-      ExceptSpec.CalledDecl(Base.getLocStart(), CopyConstructor);
-  }
-  for (const auto *Field : ClassDecl->fields()) {
-    QualType FieldType = Context.getBaseElementType(Field->getType());
-    if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
-      if (CXXConstructorDecl *CopyConstructor =
-              LookupCopyingConstructor(FieldClassDecl,
-                                       Quals | FieldType.getCVRQualifiers()))
-      ExceptSpec.CalledDecl(Field->getLocation(), CopyConstructor);
-    }
-  }
-
-  return ExceptSpec;
-}
-
 CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
                                                     CXXRecordDecl *ClassDecl) {
   // C++ [class.copy]p4:
@@ -11894,65 +12000,6 @@
   }
 }
 
-Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD) {
-  CXXRecordDecl *ClassDecl = MD->getParent();
-
-  // C++ [except.spec]p14:
-  //   An implicitly declared special member function (Clause 12) shall have an 
-  //   exception-specification. [...]
-  ImplicitExceptionSpecification ExceptSpec(*this);
-  if (ClassDecl->isInvalidDecl())
-    return ExceptSpec;
-
-  // Direct base-class constructors.
-  for (const auto &B : ClassDecl->bases()) {
-    if (B.isVirtual()) // Handled below.
-      continue;
-    
-    if (const RecordType *BaseType = B.getType()->getAs<RecordType>()) {
-      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
-      CXXConstructorDecl *Constructor =
-          LookupMovingConstructor(BaseClassDecl, 0);
-      // If this is a deleted function, add it anyway. This might be conformant
-      // with the standard. This might not. I'm not sure. It might not matter.
-      if (Constructor)
-        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
-    }
-  }
-
-  // Virtual base-class constructors.
-  for (const auto &B : ClassDecl->vbases()) {
-    if (const RecordType *BaseType = B.getType()->getAs<RecordType>()) {
-      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
-      CXXConstructorDecl *Constructor =
-          LookupMovingConstructor(BaseClassDecl, 0);
-      // If this is a deleted function, add it anyway. This might be conformant
-      // with the standard. This might not. I'm not sure. It might not matter.
-      if (Constructor)
-        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
-    }
-  }
-
-  // Field constructors.
-  for (const auto *F : ClassDecl->fields()) {
-    QualType FieldType = Context.getBaseElementType(F->getType());
-    if (CXXRecordDecl *FieldRecDecl = FieldType->getAsCXXRecordDecl()) {
-      CXXConstructorDecl *Constructor =
-          LookupMovingConstructor(FieldRecDecl, FieldType.getCVRQualifiers());
-      // If this is a deleted function, add it anyway. This might be conformant
-      // with the standard. This might not. I'm not sure. It might not matter.
-      // In particular, the problem is that this function never gets called. It
-      // might just be ill-formed because this function attempts to refer to
-      // a deleted function here.
-      if (Constructor)
-        ExceptSpec.CalledDecl(F->getLocation(), Constructor);
-    }
-  }
-
-  return ExceptSpec;
-}
-
 CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
                                                     CXXRecordDecl *ClassDecl) {
   assert(ClassDecl->needsImplicitMoveConstructor());
@@ -12322,6 +12369,10 @@
   if (Field->getInClassInitializer())
     return CXXDefaultInitExpr::Create(Context, Loc, Field);
 
+  // If we might have already tried and failed to instantiate, don't try again.
+  if (Field->isInvalidDecl())
+    return ExprError();
+
   // Maybe we haven't instantiated the in-class initializer. Go check the
   // pattern FieldDecl to see if it has one.
   CXXRecordDecl *ParentRD = cast<CXXRecordDecl>(Field->getParent());
@@ -12351,8 +12402,11 @@
     }
 
     if (InstantiateInClassInitializer(Loc, Field, Pattern,
-                                      getTemplateInstantiationArgs(Field)))
+                                      getTemplateInstantiationArgs(Field))) {
+      // Don't diagnose this again.
+      Field->setInvalidDecl();
       return ExprError();
+    }
     return CXXDefaultInitExpr::Create(Context, Loc, Field);
   }
 
@@ -12374,7 +12428,9 @@
   Diag(Loc, diag::err_in_class_initializer_not_yet_parsed)
       << OutermostClass << Field;
   Diag(Field->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed);
-
+  // Recover by marking the field invalid, unless we're in a SFINAE context.
+  if (!isSFINAEContext())
+    Field->setInvalidDecl();
   return ExprError();
 }
 
@@ -12739,7 +12795,7 @@
           PmArgs->getType()->getAs<TemplateTypeParmType>();
       if (TArgs && TArgs->getDepth() == PmType->getDepth() &&
           TArgs->getIndex() == PmType->getIndex()) {
-        if (SemaRef.ActiveTemplateInstantiations.empty())
+        if (!SemaRef.inTemplateInstantiation())
           SemaRef.Diag(TpDecl->getLocation(),
                        diag::ext_string_literal_operator_template);
         return false;
@@ -12911,7 +12967,7 @@
     //   Literal suffix identifiers that do not start with an underscore
     //   are reserved for future standardization.
     Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved)
-      << NumericLiteralParser::isValidUDSuffix(getLangOpts(), LiteralName);
+      << StringLiteralParser::isValidUDSuffix(getLangOpts(), LiteralName);
   }
 
   return false;
@@ -13234,10 +13290,10 @@
   //   for a class.*
   //
   //   * The class-key of the elaborated-type-specifier is required.
-  if (!ActiveTemplateInstantiations.empty()) {
-    // Do not complain about the form of friend template types during
-    // template instantiation; we will already have complained when the
-    // template was declared.
+  if (!CodeSynthesisContexts.empty()) {
+    // Do not complain about the form of friend template types during any kind
+    // of code synthesis. For template instantiation, we will have complained
+    // when the template was defined.
   } else {
     if (!T->isElaboratedTypeSpecifier()) {
       // If we evaluated the type to a record type, suggest putting
@@ -13302,13 +13358,13 @@
                                     MultiTemplateParamsArg TempParamLists) {
   TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
 
-  bool isExplicitSpecialization = false;
+  bool IsMemberSpecialization = false;
   bool Invalid = false;
 
   if (TemplateParameterList *TemplateParams =
           MatchTemplateParametersToScopeSpecifier(
               TagLoc, NameLoc, SS, nullptr, TempParamLists, /*friend*/ true,
-              isExplicitSpecialization, Invalid)) {
+              IsMemberSpecialization, Invalid)) {
     if (TemplateParams->size() > 0) {
       // This is a declaration of a class template.
       if (Invalid)
@@ -13323,7 +13379,7 @@
       // The "template<>" header is extraneous.
       Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
         << TypeWithKeyword::getTagTypeKindName(Kind) << Name;
-      isExplicitSpecialization = true;
+      IsMemberSpecialization = true;
     }
   }
 
@@ -13733,6 +13789,9 @@
     case UnqualifiedId::IK_ConversionFunctionId:
       DiagArg = 2;
       break;
+    case UnqualifiedId::IK_DeductionGuideName:
+      DiagArg = 3;
+      break;
     case UnqualifiedId::IK_Identifier:
     case UnqualifiedId::IK_ImplicitSelfParam:
     case UnqualifiedId::IK_LiteralOperatorId:
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index d172c95..b43e5b9 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1712,7 +1712,7 @@
     DeclsInGroup.push_back(PDecl);
   }
 
-  return BuildDeclaratorGroup(DeclsInGroup, false);
+  return BuildDeclaratorGroup(DeclsInGroup);
 }
 
 Decl *Sema::
@@ -2019,7 +2019,7 @@
 
   DeclsInGroup.push_back(ObjCImpDecl);
 
-  return BuildDeclaratorGroup(DeclsInGroup, false);
+  return BuildDeclaratorGroup(DeclsInGroup);
 }
 
 void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
@@ -3043,7 +3043,7 @@
     DeclsInGroup.push_back(IDecl);
   }
 
-  return BuildDeclaratorGroup(DeclsInGroup, false);
+  return BuildDeclaratorGroup(DeclsInGroup);
 }
 
 static bool tryMatchRecordTypes(ASTContext &Context,
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index 3561bd0..deb6cbb 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -288,14 +288,15 @@
   // The new function declaration is only missing an empty exception
   // specification "throw()". If the throw() specification came from a
   // function in a system header that has C linkage, just add an empty
-  // exception specification to the "new" declaration. This is an
-  // egregious workaround for glibc, which adds throw() specifications
-  // to many libc functions as an optimization. Unfortunately, that
-  // optimization isn't permitted by the C++ standard, so we're forced
-  // to work around it here.
+  // exception specification to the "new" declaration. Note that C library
+  // implementations are permitted to add these nothrow exception
+  // specifications.
+  //
+  // Likewise if the old function is a builtin.
   if (MissingEmptyExceptionSpecification && NewProto &&
       (Old->getLocation().isInvalid() ||
-       Context.getSourceManager().isInSystemHeader(Old->getLocation())) &&
+       Context.getSourceManager().isInSystemHeader(Old->getLocation()) ||
+       Old->getBuiltinID()) &&
       Old->isExternC()) {
     New->setType(Context.getFunctionType(
         NewProto->getReturnType(), NewProto->getParamTypes(),
@@ -1166,6 +1167,7 @@
   case Expr::ExprWithCleanupsClass:
   case Expr::ExtVectorElementExprClass:
   case Expr::InitListExprClass:
+  case Expr::ArrayInitLoopExprClass:
   case Expr::MemberExprClass:
   case Expr::ObjCIsaExprClass:
   case Expr::ObjCIvarRefExprClass:
@@ -1180,6 +1182,7 @@
   case Expr::ArraySubscriptExprClass:
   case Expr::OMPArraySectionExprClass:
   case Expr::BinaryOperatorClass:
+  case Expr::DependentCoawaitExprClass:
   case Expr::CompoundAssignOperatorClass:
   case Expr::CStyleCastExprClass:
   case Expr::CXXStaticCastExprClass:
@@ -1259,6 +1262,7 @@
   case Expr::ImaginaryLiteralClass:
   case Expr::ImplicitValueInitExprClass:
   case Expr::IntegerLiteralClass:
+  case Expr::ArrayInitIndexExprClass:
   case Expr::NoInitExprClass:
   case Expr::ObjCEncodeExprClass:
   case Expr::ObjCStringLiteralClass:
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5182e16..c5b2e1b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -333,10 +333,8 @@
       Diag(Loc, diag::err_binding_cannot_appear_in_own_initializer)
         << D->getDeclName();
     } else {
-      const AutoType *AT = cast<VarDecl>(D)->getType()->getContainedAutoType();
-
       Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
-        << D->getDeclName() << (unsigned)AT->getKeyword();
+        << D->getDeclName() << cast<VarDecl>(D)->getType();
     }
     return true;
   }
@@ -363,6 +361,9 @@
 
     if (getLangOpts().CUDA && !CheckCUDACall(Loc, FD))
       return true;
+
+    if (diagnoseArgIndependentDiagnoseIfAttrs(FD, Loc))
+      return true;
   }
 
   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
@@ -377,6 +378,7 @@
     Diag(D->getLocation(), diag::note_entity_declared_at) << D;
     return true;
   }
+
   DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass,
                              ObjCPropertyAccess);
 
@@ -657,7 +659,7 @@
     return E;
 
   // OpenCL usually rejects direct accesses to values of 'half' type.
-  if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16 &&
+  if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp16") &&
       T->isHalfType()) {
     Diag(E->getExprLoc(), diag::err_opencl_half_load_store)
       << 0 << T;
@@ -817,8 +819,16 @@
   // double.
   const BuiltinType *BTy = Ty->getAs<BuiltinType>();
   if (BTy && (BTy->getKind() == BuiltinType::Half ||
-              BTy->getKind() == BuiltinType::Float))
-    E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
+              BTy->getKind() == BuiltinType::Float)) {
+    if (getLangOpts().OpenCL &&
+        !getOpenCLOptions().isEnabled("cl_khr_fp64")) {
+        if (BTy->getKind() == BuiltinType::Half) {
+            E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get();
+        }
+    } else {
+      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:
@@ -1186,7 +1196,7 @@
   */
   return Float128AndLongDouble &&
     (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) !=
-     &llvm::APFloat::IEEEdouble);
+     &llvm::APFloat::IEEEdouble());
 }
 
 typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType);
@@ -1431,7 +1441,7 @@
 
   // The controlling expression is an unevaluated operand, so side effects are
   // likely unintended.
-  if (ActiveTemplateInstantiations.empty() &&
+  if (!inTemplateInstantiation() &&
       ControllingExpr->HasSideEffects(Context, false))
     Diag(ControllingExpr->getExprLoc(),
          diag::warn_side_effects_unevaluated_context);
@@ -1878,9 +1888,10 @@
         // During a default argument instantiation the CurContext points
         // to a CXXMethodDecl; but we can't apply a this-> fixit inside a
         // function parameter list, hence add an explicit check.
-        bool isDefaultArgument = !ActiveTemplateInstantiations.empty() &&
-                              ActiveTemplateInstantiations.back().Kind ==
-            ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation;
+        bool isDefaultArgument =
+            !CodeSynthesisContexts.empty() &&
+            CodeSynthesisContexts.back().Kind ==
+                CodeSynthesisContext::DefaultFunctionArgumentInstantiation;
         CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);
         bool isInstance = CurMethod &&
                           CurMethod->isInstance() &&
@@ -2769,6 +2780,9 @@
 /// were not overloaded, and it doesn't promise that the declaration
 /// will in fact be used.
 static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {
+  if (D->isInvalidDecl())
+    return true;
+
   if (isa<TypedefNameDecl>(D)) {
     S.Diag(Loc, diag::err_unexpected_typedef) << D->getDeclName();
     return true;
@@ -3023,6 +3037,9 @@
       break;
     }
 
+    case Decl::CXXDeductionGuide:
+      llvm_unreachable("building reference to deduction guide");
+
     case Decl::MSProperty:
       valueKind = VK_LValue;
       break;
@@ -3378,7 +3395,7 @@
   if (Literal.isFloatingLiteral()) {
     QualType Ty;
     if (Literal.isHalf){
-      if (getOpenCLOptions().cl_khr_fp16)
+      if (getOpenCLOptions().isEnabled("cl_khr_fp16"))
         Ty = Context.HalfTy;
       else {
         Diag(Tok.getLocation(), diag::err_half_const_requires_fp16);
@@ -3397,10 +3414,13 @@
 
     if (Ty == Context.DoubleTy) {
       if (getLangOpts().SinglePrecisionConstants) {
-        Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
+        const BuiltinType *BTy = Ty->getAs<BuiltinType>();
+        if (BTy->getKind() != BuiltinType::Float) {
+          Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
+        }
       } else if (getLangOpts().OpenCL &&
-                 !((getLangOpts().OpenCLVersion >= 120) ||
-                   getOpenCLOptions().cl_khr_fp64)) {
+                 !getOpenCLOptions().isEnabled("cl_khr_fp64")) {
+        // Impose single-precision float type when cl_khr_fp64 is not enabled.
         Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64);
         Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
       }
@@ -3676,7 +3696,7 @@
   // The operand for sizeof and alignof is in an unevaluated expression context,
   // so side effects could result in unintended consequences.
   if ((ExprKind == UETT_SizeOf || ExprKind == UETT_AlignOf) &&
-      ActiveTemplateInstantiations.empty() && E->HasSideEffects(Context, false))
+      !inTemplateInstantiation() && E->HasSideEffects(Context, false))
     Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context);
 
   if (CheckObjCTraitOperandConstraints(*this, ExprTy, E->getExprLoc(),
@@ -3951,7 +3971,8 @@
       T = cast<DecltypeType>(Ty)->desugar();
       break;
     case Type::Auto:
-      T = cast<AutoType>(Ty)->getDeducedType();
+    case Type::DeducedTemplateSpecialization:
+      T = cast<DeducedType>(Ty)->getDeducedType();
       break;
     case Type::TypeOfExpr:
       T = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
@@ -5140,12 +5161,30 @@
   return OverloadDecl;
 }
 
-static bool isNumberOfArgsValidForCall(Sema &S, const FunctionDecl *Callee,
-                                       std::size_t NumArgs) {
-  if (S.TooManyArguments(Callee->getNumParams(), NumArgs,
-                         /*PartialOverloading=*/false))
-    return Callee->isVariadic();
-  return Callee->getMinRequiredArguments() <= NumArgs;
+static void checkDirectCallValidity(Sema &S, const Expr *Fn,
+                                    FunctionDecl *Callee,
+                                    MultiExprArg ArgExprs) {
+  // `Callee` (when called with ArgExprs) may be ill-formed. enable_if (and
+  // similar attributes) really don't like it when functions are called with an
+  // invalid number of args.
+  if (S.TooManyArguments(Callee->getNumParams(), ArgExprs.size(),
+                         /*PartialOverloading=*/false) &&
+      !Callee->isVariadic())
+    return;
+  if (Callee->getMinRequiredArguments() > ArgExprs.size())
+    return;
+
+  if (const EnableIfAttr *Attr = S.CheckEnableIf(Callee, ArgExprs, true)) {
+    S.Diag(Fn->getLocStart(),
+           isa<CXXMethodDecl>(Callee)
+               ? diag::err_ovl_no_viable_member_function_in_call
+               : diag::err_ovl_no_viable_function_in_call)
+        << Callee << Callee->getSourceRange();
+    S.Diag(Callee->getLocation(),
+           diag::note_ovl_candidate_disabled_by_function_cond_attr)
+        << Attr->getCond()->getSourceRange() << Attr->getMessage();
+    return;
+  }
 }
 
 /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
@@ -5278,25 +5317,10 @@
                                            Fn->getLocStart()))
       return ExprError();
 
-    // CheckEnableIf assumes that the we're passing in a sane number of args for
-    // FD, but that doesn't always hold true here. This is because, in some
-    // cases, we'll emit a diag about an ill-formed function call, but then
-    // we'll continue on as if the function call wasn't ill-formed. So, if the
-    // number of args looks incorrect, don't do enable_if checks; we should've
-    // already emitted an error about the bad call.
-    if (FD->hasAttr<EnableIfAttr>() &&
-        isNumberOfArgsValidForCall(*this, FD, ArgExprs.size())) {
-      if (const EnableIfAttr *Attr = CheckEnableIf(FD, ArgExprs, true)) {
-        Diag(Fn->getLocStart(),
-             isa<CXXMethodDecl>(FD)
-                 ? diag::err_ovl_no_viable_member_function_in_call
-                 : diag::err_ovl_no_viable_function_in_call)
-            << FD << FD->getSourceRange();
-        Diag(FD->getLocation(),
-             diag::note_ovl_candidate_disabled_by_enable_if_attr)
-            << Attr->getCond()->getSourceRange() << Attr->getMessage();
-      }
-    }
+    if (getLangOpts().OpenCL && checkOpenCLDisabledDecl(*FD, *Fn))
+      return ExprError();
+
+    checkDirectCallValidity(*this, Fn, FD, ArgExprs);
   }
 
   return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, ArgExprs, RParenLoc,
@@ -5357,6 +5381,15 @@
     return ExprError();
   }
 
+  // Interrupt handlers don't save off the VFP regs automatically on ARM,
+  // so there's some risk when calling out to non-interrupt handler functions
+  // that the callee might not preserve them. This is easy to diagnose here,
+  // but can be very challenging to debug.
+  if (auto *Caller = getCurFunctionDecl())
+    if (Caller->hasAttr<ARMInterruptAttr>())
+      if (!FDecl || !FDecl->hasAttr<ARMInterruptAttr>())
+        Diag(Fn->getExprLoc(), diag::warn_arm_interrupt_calling_convention);
+
   // Promote the function operand.
   // We special-case function promotion here because we only allow promoting
   // builtin functions to function pointers in the callee of a call.
@@ -6302,92 +6335,98 @@
   Qualifiers lhQual = lhptee.getQualifiers();
   Qualifiers rhQual = rhptee.getQualifiers();
 
+  unsigned ResultAddrSpace = 0;
+  unsigned LAddrSpace = lhQual.getAddressSpace();
+  unsigned RAddrSpace = rhQual.getAddressSpace();
+  if (S.getLangOpts().OpenCL) {
+    // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address
+    // spaces is disallowed.
+    if (lhQual.isAddressSpaceSupersetOf(rhQual))
+      ResultAddrSpace = LAddrSpace;
+    else if (rhQual.isAddressSpaceSupersetOf(lhQual))
+      ResultAddrSpace = RAddrSpace;
+    else {
+      S.Diag(Loc,
+             diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)
+          << LHSTy << RHSTy << 2 << LHS.get()->getSourceRange()
+          << RHS.get()->getSourceRange();
+      return QualType();
+    }
+  }
+
   unsigned MergedCVRQual = lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers();
+  auto LHSCastKind = CK_BitCast, RHSCastKind = CK_BitCast;
   lhQual.removeCVRQualifiers();
   rhQual.removeCVRQualifiers();
 
+  // OpenCL v2.0 specification doesn't extend compatibility of type qualifiers
+  // (C99 6.7.3) for address spaces. We assume that the check should behave in
+  // the same manner as it's defined for CVR qualifiers, so for OpenCL two
+  // qual types are compatible iff
+  //  * corresponded types are compatible
+  //  * CVR qualifiers are equal
+  //  * address spaces are equal
+  // Thus for conditional operator we merge CVR and address space unqualified
+  // pointees and if there is a composite type we return a pointer to it with
+  // merged qualifiers.
+  if (S.getLangOpts().OpenCL) {
+    LHSCastKind = LAddrSpace == ResultAddrSpace
+                      ? CK_BitCast
+                      : CK_AddressSpaceConversion;
+    RHSCastKind = RAddrSpace == ResultAddrSpace
+                      ? CK_BitCast
+                      : CK_AddressSpaceConversion;
+    lhQual.removeAddressSpace();
+    rhQual.removeAddressSpace();
+  }
+
   lhptee = S.Context.getQualifiedType(lhptee.getUnqualifiedType(), lhQual);
   rhptee = S.Context.getQualifiedType(rhptee.getUnqualifiedType(), rhQual);
 
-  // For OpenCL:
-  // 1. If LHS and RHS types match exactly and:
-  //  (a) AS match => use standard C rules, no bitcast or addrspacecast
-  //  (b) AS overlap => generate addrspacecast
-  //  (c) AS don't overlap => give an error
-  // 2. if LHS and RHS types don't match:
-  //  (a) AS match => use standard C rules, generate bitcast
-  //  (b) AS overlap => generate addrspacecast instead of bitcast
-  //  (c) AS don't overlap => give an error
-
-  // For OpenCL, non-null composite type is returned only for cases 1a and 1b.
   QualType CompositeTy = S.Context.mergeTypes(lhptee, rhptee);
 
-  // OpenCL cases 1c, 2a, 2b, and 2c.
   if (CompositeTy.isNull()) {
     // In this situation, we assume void* type. No especially good
     // reason, but this is what gcc does, and we do have to pick
     // to get a consistent AST.
     QualType incompatTy;
-    if (S.getLangOpts().OpenCL) {
-      // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address
-      // spaces is disallowed.
-      unsigned ResultAddrSpace;
-      if (lhQual.isAddressSpaceSupersetOf(rhQual)) {
-        // Cases 2a and 2b.
-        ResultAddrSpace = lhQual.getAddressSpace();
-      } else if (rhQual.isAddressSpaceSupersetOf(lhQual)) {
-        // Cases 2a and 2b.
-        ResultAddrSpace = rhQual.getAddressSpace();
-      } else {
-        // Cases 1c and 2c.
-        S.Diag(Loc,
-               diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)
-            << LHSTy << RHSTy << 2 << LHS.get()->getSourceRange()
-            << RHS.get()->getSourceRange();
-        return QualType();
-      }
-
-      // Continue handling cases 2a and 2b.
-      incompatTy = S.Context.getPointerType(
-          S.Context.getAddrSpaceQualType(S.Context.VoidTy, ResultAddrSpace));
-      LHS = S.ImpCastExprToType(LHS.get(), incompatTy,
-                                (lhQual.getAddressSpace() != ResultAddrSpace)
-                                    ? CK_AddressSpaceConversion /* 2b */
-                                    : CK_BitCast /* 2a */);
-      RHS = S.ImpCastExprToType(RHS.get(), incompatTy,
-                                (rhQual.getAddressSpace() != ResultAddrSpace)
-                                    ? CK_AddressSpaceConversion /* 2b */
-                                    : CK_BitCast /* 2a */);
-    } else {
-      S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers)
-          << LHSTy << RHSTy << LHS.get()->getSourceRange()
-          << RHS.get()->getSourceRange();
-      incompatTy = S.Context.getPointerType(S.Context.VoidTy);
-      LHS = S.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
-      RHS = S.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
-    }
+    incompatTy = S.Context.getPointerType(
+        S.Context.getAddrSpaceQualType(S.Context.VoidTy, ResultAddrSpace));
+    LHS = S.ImpCastExprToType(LHS.get(), incompatTy, LHSCastKind);
+    RHS = S.ImpCastExprToType(RHS.get(), incompatTy, RHSCastKind);
+    // FIXME: For OpenCL the warning emission and cast to void* leaves a room
+    // for casts between types with incompatible address space qualifiers.
+    // For the following code the compiler produces casts between global and
+    // local address spaces of the corresponded innermost pointees:
+    // local int *global *a;
+    // global int *global *b;
+    // a = (0 ? a : b); // see C99 6.5.16.1.p1.
+    S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers)
+        << LHSTy << RHSTy << LHS.get()->getSourceRange()
+        << RHS.get()->getSourceRange();
     return incompatTy;
   }
 
   // The pointer types are compatible.
-  QualType ResultTy = CompositeTy.withCVRQualifiers(MergedCVRQual);
-  auto LHSCastKind = CK_BitCast, RHSCastKind = CK_BitCast;
+  // In case of OpenCL ResultTy should have the address space qualifier
+  // which is a superset of address spaces of both the 2nd and the 3rd
+  // operands of the conditional operator.
+  QualType ResultTy = [&, ResultAddrSpace]() {
+    if (S.getLangOpts().OpenCL) {
+      Qualifiers CompositeQuals = CompositeTy.getQualifiers();
+      CompositeQuals.setAddressSpace(ResultAddrSpace);
+      return S.Context
+          .getQualifiedType(CompositeTy.getUnqualifiedType(), CompositeQuals)
+          .withCVRQualifiers(MergedCVRQual);
+    } else
+      return CompositeTy.withCVRQualifiers(MergedCVRQual);
+  }();
   if (IsBlockPointer)
     ResultTy = S.Context.getBlockPointerType(ResultTy);
   else {
-    // Cases 1a and 1b for OpenCL.
-    auto ResultAddrSpace = ResultTy.getQualifiers().getAddressSpace();
-    LHSCastKind = lhQual.getAddressSpace() == ResultAddrSpace
-                      ? CK_BitCast /* 1a */
-                      : CK_AddressSpaceConversion /* 1b */;
-    RHSCastKind = rhQual.getAddressSpace() == ResultAddrSpace
-                      ? CK_BitCast /* 1a */
-                      : CK_AddressSpaceConversion /* 1b */;
     ResultTy = S.Context.getPointerType(ResultTy);
   }
 
-  // For case 1a of OpenCL, S.ImpCastExprToType will not insert bitcast
-  // if the target type does not change.
   LHS = S.ImpCastExprToType(LHS.get(), ResultTy, LHSCastKind);
   RHS = S.ImpCastExprToType(RHS.get(), ResultTy, RHSCastKind);
   return ResultTy;
@@ -7357,10 +7396,31 @@
   Sema::AssignConvertType ConvTy = Sema::Compatible;
 
   // For blocks we enforce that qualifiers are identical.
-  if (lhptee.getLocalQualifiers() != rhptee.getLocalQualifiers())
+  Qualifiers LQuals = lhptee.getLocalQualifiers();
+  Qualifiers RQuals = rhptee.getLocalQualifiers();
+  if (S.getLangOpts().OpenCL) {
+    LQuals.removeAddressSpace();
+    RQuals.removeAddressSpace();
+  }
+  if (LQuals != RQuals)
     ConvTy = Sema::CompatiblePointerDiscardsQualifiers;
 
-  if (!S.Context.typesAreBlockPointerCompatible(LHSType, RHSType))
+  // FIXME: OpenCL doesn't define the exact compile time semantics for a block
+  // assignment.
+  // The current behavior is similar to C++ lambdas. A block might be
+  // assigned to a variable iff its return type and parameters are compatible
+  // (C99 6.2.7) with the corresponding return type and parameters of the LHS of
+  // an assignment. Presumably it should behave in way that a function pointer
+  // assignment does in C, so for each parameter and return type:
+  //  * CVR and address space of LHS should be a superset of CVR and address
+  //  space of RHS.
+  //  * unqualified types should be compatible.
+  if (S.getLangOpts().OpenCL) {
+    if (!S.Context.typesAreBlockPointerCompatible(
+            S.Context.getQualifiedType(LHSType.getUnqualifiedType(), LQuals),
+            S.Context.getQualifiedType(RHSType.getUnqualifiedType(), RQuals)))
+      return Sema::IncompatibleBlockPointer;
+  } else if (!S.Context.typesAreBlockPointerCompatible(LHSType, RHSType))
     return Sema::IncompatibleBlockPointer;
 
   return ConvTy;
@@ -7582,7 +7642,12 @@
     // U^ -> void*
     if (RHSType->getAs<BlockPointerType>()) {
       if (LHSPointer->getPointeeType()->isVoidType()) {
-        Kind = CK_BitCast;
+        unsigned AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace();
+        unsigned AddrSpaceR = RHSType->getAs<BlockPointerType>()
+                                  ->getPointeeType()
+                                  .getAddressSpace();
+        Kind =
+            AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;
         return Compatible;
       }
     }
@@ -7594,7 +7659,13 @@
   if (isa<BlockPointerType>(LHSType)) {
     // U^ -> T^
     if (RHSType->isBlockPointerType()) {
-      Kind = CK_BitCast;
+      unsigned AddrSpaceL = LHSType->getAs<BlockPointerType>()
+                                ->getPointeeType()
+                                .getAddressSpace();
+      unsigned AddrSpaceR = RHSType->getAs<BlockPointerType>()
+                                ->getPointeeType()
+                                .getAddressSpace();
+      Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;
       return checkBlockPointerTypesForAssignment(*this, LHSType, RHSType);
     }
 
@@ -9210,7 +9281,7 @@
       !(LHSType->isBlockPointerType() && IsRelational) &&
       !LHS.get()->getLocStart().isMacroID() &&
       !RHS.get()->getLocStart().isMacroID() &&
-      ActiveTemplateInstantiations.empty()) {
+      !inTemplateInstantiation()) {
     // For non-floating point types, check for self-comparisons of the form
     // x == x, x != x, x < x, etc.  These always evaluate to a constant, and
     // often indicate logic errors in the program.
@@ -9621,6 +9692,18 @@
     return ResultTy;
   }
 
+  if (getLangOpts().OpenCLVersion >= 200) {
+    if (LHSIsNull && RHSType->isQueueT()) {
+      LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
+      return ResultTy;
+    }
+
+    if (LHSType->isQueueT() && RHSIsNull) {
+      RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
+      return ResultTy;
+    }
+  }
+
   return InvalidOperands(Loc, LHS, RHS);
 }
 
@@ -9670,8 +9753,7 @@
   // For non-floating point types, check for self-comparisons of the form
   // x == x, x != x, x < x, etc.  These always evaluate to a constant, and
   // often indicate logic errors in the program.
-  if (!LHSType->hasFloatingRepresentation() &&
-      ActiveTemplateInstantiations.empty()) {
+  if (!LHSType->hasFloatingRepresentation() && !inTemplateInstantiation()) {
     if (DeclRefExpr* DRL
           = dyn_cast<DeclRefExpr>(LHS.get()->IgnoreParenImpCasts()))
       if (DeclRefExpr* DRR
@@ -9759,7 +9841,7 @@
       !LHS.get()->getType()->isBooleanType() &&
       RHS.get()->getType()->isIntegerType() && !RHS.get()->isValueDependent() &&
       // Don't warn in macros or template instantiations.
-      !Loc.isMacroID() && ActiveTemplateInstantiations.empty()) {
+      !Loc.isMacroID() && !inTemplateInstantiation()) {
     // If the RHS can be constant folded, and if it constant folds to something
     // that isn't 0 or 1 (which indicate a potential logical operation that
     // happened to fold to true/false) then warn.
@@ -10175,7 +10257,7 @@
   // OpenCL v1.2 s6.1.1.1 p2:
   // The half data type can only be used to declare a pointer to a buffer that
   // contains half values
-  if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16 &&
+  if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp16") &&
     LHSType->isHalfType()) {
     Diag(Loc, diag::err_opencl_half_load_store) << 1
         << LHSType.getUnqualifiedType();
@@ -10295,7 +10377,7 @@
     return;
 
   // Don't warn in template instantiations.
-  if (!ActiveTemplateInstantiations.empty())
+  if (inTemplateInstantiation())
     return;
 
   // Scope isn't fine-grained enough to whitelist the specific cases, so
@@ -10890,7 +10972,7 @@
 /// suppressed in the event of macro expansions.
 static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr,
                                    SourceLocation OpLoc) {
-  if (!S.ActiveTemplateInstantiations.empty())
+  if (S.inTemplateInstantiation())
     return;
   if (OpLoc.isInvalid() || OpLoc.isMacroID())
     return;
@@ -11446,7 +11528,7 @@
       return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr);
 
     // Don't resolve overloads if the other type is overloadable.
-    if (pty->getKind() == BuiltinType::Overload) {
+    if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload) {
       // We can't actually test that if we still have a placeholder,
       // though.  Fortunately, none of the exceptions we see in that
       // code below are valid when the LHS is an overload set.  Note
@@ -11471,17 +11553,16 @@
     // An overload in the RHS can potentially be resolved by the type
     // being assigned to.
     if (Opc == BO_Assign && pty->getKind() == BuiltinType::Overload) {
-      if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent())
-        return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
-
-      if (LHSExpr->getType()->isOverloadableType())
+      if (getLangOpts().CPlusPlus &&
+          (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent() ||
+           LHSExpr->getType()->isOverloadableType()))
         return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
 
       return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr);
     }
 
     // Don't resolve overloads if the other type is overloadable.
-    if (pty->getKind() == BuiltinType::Overload &&
+    if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload &&
         LHSExpr->getType()->isOverloadableType())
       return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
 
@@ -11627,7 +11708,7 @@
                  Context.getLangOpts().OpenCLVersion < 120) {
         // OpenCL v1.1 6.3.h: The logical operator not (!) does not
         // operate on scalar float types.
-        if (!resultType->isIntegerType())
+        if (!resultType->isIntegerType() && !resultType->isPointerType())
           return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
                            << resultType << Input.get()->getSourceRange());
       }
@@ -13068,8 +13149,16 @@
         //   evaluate [...] a lambda-expression.
         D = diag::err_lambda_in_constant_expression;
       }
-      for (const auto *L : Rec.Lambdas)
-        Diag(L->getLocStart(), D);
+
+      // C++1z allows lambda expressions as core constant expressions.
+      // FIXME: In C++1z, reinstate the restrictions on lambda expressions (CWG
+      // 1607) from appearing within template-arguments and array-bounds that
+      // are part of function-signatures.  Be mindful that P0315 (Lambdas in
+      // unevaluated contexts) might lift some of these restrictions in a 
+      // future version.
+      if (Rec.Context != ConstantEvaluated || !getLangOpts().CPlusPlus1z)
+        for (const auto *L : Rec.Lambdas)
+          Diag(L->getLocStart(), D);
     } else {
       // Mark the capture expressions odr-used. This was deferred
       // during lambda expression creation.
@@ -13121,41 +13210,63 @@
   return TransformToPotentiallyEvaluated(E);
 }
 
-static bool IsPotentiallyEvaluatedContext(Sema &SemaRef) {
-  // Do not mark anything as "used" within a dependent context; wait for
-  // an instantiation.
-  if (SemaRef.CurContext->isDependentContext())
-    return false;
-
+/// Are we within a context in which some evaluation could be performed (be it
+/// constant evaluation or runtime evaluation)? Sadly, this notion is not quite
+/// captured by C++'s idea of an "unevaluated context".
+static bool isEvaluatableContext(Sema &SemaRef) {
   switch (SemaRef.ExprEvalContexts.back().Context) {
     case Sema::Unevaluated:
     case Sema::UnevaluatedAbstract:
-      // We are in an expression that is not potentially evaluated; do nothing.
-      // (Depending on how you read the standard, we actually do need to do
-      // something here for null pointer constants, but the standard's
-      // definition of a null pointer constant is completely crazy.)
-      return false;
-
     case Sema::DiscardedStatement:
-      // These are technically a potentially evaluated but they have the effect
-      // of suppressing use marking.
+      // Expressions in this context are never evaluated.
       return false;
 
+    case Sema::UnevaluatedList:
     case Sema::ConstantEvaluated:
     case Sema::PotentiallyEvaluated:
-      // We are in a potentially evaluated expression (or a constant-expression
-      // in C++03); we need to do implicit template instantiation, implicitly
-      // define class members, and mark most declarations as used.
+      // Expressions in this context could be evaluated.
       return true;
 
     case Sema::PotentiallyEvaluatedIfUsed:
       // Referenced declarations will only be used if the construct in the
-      // containing expression is used.
+      // containing expression is used, at which point we'll be given another
+      // turn to mark them.
       return false;
   }
   llvm_unreachable("Invalid context");
 }
 
+/// Are we within a context in which references to resolved functions or to
+/// variables result in odr-use?
+static bool isOdrUseContext(Sema &SemaRef, bool SkipDependentUses = true) {
+  // An expression in a template is not really an expression until it's been
+  // instantiated, so it doesn't trigger odr-use.
+  if (SkipDependentUses && SemaRef.CurContext->isDependentContext())
+    return false;
+
+  switch (SemaRef.ExprEvalContexts.back().Context) {
+    case Sema::Unevaluated:
+    case Sema::UnevaluatedList:
+    case Sema::UnevaluatedAbstract:
+    case Sema::DiscardedStatement:
+      return false;
+
+    case Sema::ConstantEvaluated:
+    case Sema::PotentiallyEvaluated:
+      return true;
+
+    case Sema::PotentiallyEvaluatedIfUsed:
+      return false;
+  }
+  llvm_unreachable("Invalid context");
+}
+
+static bool isImplicitlyDefinableConstexprFunction(FunctionDecl *Func) {
+  CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Func);
+  return Func->isConstexpr() &&
+         (Func->isImplicitlyInstantiable() || (MD && !MD->isUserProvided()));
+}
+
 /// \brief Mark a function referenced, and check whether it is odr-used
 /// (C++ [basic.def.odr]p2, C99 6.9p3)
 void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
@@ -13171,7 +13282,7 @@
   //
   // We (incorrectly) mark overload resolution as an unevaluated context, so we
   // can just check that here.
-  bool OdrUse = MightBeOdrUse && IsPotentiallyEvaluatedContext(*this);
+  bool OdrUse = MightBeOdrUse && isOdrUseContext(*this);
 
   // Determine whether we require a function definition to exist, per
   // C++11 [temp.inst]p3:
@@ -13180,27 +13291,11 @@
   //   specialization is implicitly instantiated when the specialization is
   //   referenced in a context that requires a function definition to exist.
   //
-  // We consider constexpr function templates to be referenced in a context
-  // that requires a definition to exist whenever they are referenced.
-  //
-  // FIXME: This instantiates constexpr functions too frequently. If this is
-  // really an unevaluated context (and we're not just in the definition of a
-  // function template or overload resolution or other cases which we
-  // incorrectly consider to be unevaluated contexts), and we're not in a
-  // subexpression which we actually need to evaluate (for instance, a
-  // template argument, array bound or an expression in a braced-init-list),
-  // we are not permitted to instantiate this constexpr function definition.
-  //
-  // FIXME: This also implicitly defines special members too frequently. They
-  // are only supposed to be implicitly defined if they are odr-used, but they
-  // are not odr-used from constant expressions in unevaluated contexts.
-  // However, they cannot be referenced if they are deleted, and they are
-  // deleted whenever the implicit definition of the special member would
-  // fail (with very few exceptions).
-  CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Func);
+  // That is either when this is an odr-use, or when a usage of a constexpr
+  // function occurs within an evaluatable context.
   bool NeedDefinition =
-      OdrUse || (Func->isConstexpr() && (Func->isImplicitlyInstantiable() ||
-                                         (MD && !MD->isUserProvided())));
+      OdrUse || (isEvaluatableContext(*this) &&
+                 isImplicitlyDefinableConstexprFunction(Func));
 
   // C++14 [temp.expl.spec]p6:
   //   If a template [...] is explicitly specialized then that specialization
@@ -13311,7 +13406,7 @@
     if (!AlreadyInstantiated || Func->isConstexpr()) {
       if (isa<CXXRecordDecl>(Func->getDeclContext()) &&
           cast<CXXRecordDecl>(Func->getDeclContext())->isLocalClass() &&
-          ActiveTemplateInstantiations.size())
+          CodeSynthesisContexts.size())
         PendingLocalImplicitInstantiations.push_back(
             std::make_pair(Func, PointOfInstantiation));
       else if (Func->isConstexpr())
@@ -13494,6 +13589,13 @@
     }
     return false;
   }
+  // OpenCL v2.0 s6.12.5: Blocks cannot reference/capture other blocks
+  if (S.getLangOpts().OpenCL && IsBlock &&
+      Var->getType()->isBlockPointerType()) {
+    if (Diagnose)
+      S.Diag(Loc, diag::err_opencl_block_ref_block);
+    return false;
+  }
 
   return true;
 }
@@ -13531,16 +13633,55 @@
   }
 
   // Warn about implicitly autoreleasing indirect parameters captured by blocks.
-  if (auto *PT = dyn_cast<PointerType>(CaptureType)) {
+  if (const auto *PT = CaptureType->getAs<PointerType>()) {
+    // This function finds out whether there is an AttributedType of kind
+    // attr_objc_ownership in Ty. The existence of AttributedType of kind
+    // attr_objc_ownership implies __autoreleasing was explicitly specified
+    // rather than being added implicitly by the compiler.
+    auto IsObjCOwnershipAttributedType = [](QualType Ty) {
+      while (const auto *AttrTy = Ty->getAs<AttributedType>()) {
+        if (AttrTy->getAttrKind() == AttributedType::attr_objc_ownership)
+          return true;
+
+        // Peel off AttributedTypes that are not of kind objc_ownership.
+        Ty = AttrTy->getModifiedType();
+      }
+
+      return false;
+    };
+
     QualType PointeeTy = PT->getPointeeType();
-    if (isa<ObjCObjectPointerType>(PointeeTy.getCanonicalType()) &&
+
+    if (PointeeTy->getAs<ObjCObjectPointerType>() &&
         PointeeTy.getObjCLifetime() == Qualifiers::OCL_Autoreleasing &&
-        !isa<AttributedType>(PointeeTy)) {
+        !IsObjCOwnershipAttributedType(PointeeTy)) {
       if (BuildAndDiagnose) {
         SourceLocation VarLoc = Var->getLocation();
         S.Diag(Loc, diag::warn_block_capture_autoreleasing);
-        S.Diag(VarLoc, diag::note_declare_parameter_autoreleasing) <<
-            FixItHint::CreateInsertion(VarLoc, "__autoreleasing");
+        {
+          auto AddAutoreleaseNote =
+              S.Diag(VarLoc, diag::note_declare_parameter_autoreleasing);
+          // Provide a fix-it for the '__autoreleasing' keyword at the
+          // appropriate location in the variable's type.
+          if (const auto *TSI = Var->getTypeSourceInfo()) {
+            PointerTypeLoc PTL =
+                TSI->getTypeLoc().getAsAdjusted<PointerTypeLoc>();
+            if (PTL) {
+              SourceLocation Loc = PTL.getPointeeLoc().getEndLoc();
+              Loc = Lexer::getLocForEndOfToken(Loc, 0, S.getSourceManager(),
+                                               S.getLangOpts());
+              if (Loc.isValid()) {
+                StringRef CharAtLoc = Lexer::getSourceText(
+                    CharSourceRange::getCharRange(Loc, Loc.getLocWithOffset(1)),
+                    S.getSourceManager(), S.getLangOpts());
+                AddAutoreleaseNote << FixItHint::CreateInsertion(
+                    Loc, CharAtLoc.empty() || !isWhitespace(CharAtLoc[0])
+                             ? " __autoreleasing "
+                             : " __autoreleasing");
+              }
+            }
+          }
+        }
         S.Diag(VarLoc, diag::note_declare_parameter_strong);
       }
     }
@@ -13852,8 +13993,10 @@
 
     // Check whether we've already captured it.
     if (isVariableAlreadyCapturedInScopeInfo(CSI, Var, Nested, CaptureType, 
-                                             DeclRefType)) 
+                                             DeclRefType)) {
+      CSI->getCapture(Var).markUsed(BuildAndDiagnose);
       break;
+    }
     // If we are instantiating a generic lambda call operator body, 
     // we do not want to capture new variables.  What was captured
     // during either a lambdas transformation or initial parsing
@@ -14094,47 +14237,11 @@
   Var->setReferenced();
 
   TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
-  bool MarkODRUsed = true;
 
-  // If the context is not potentially evaluated, this is not an odr-use and
-  // does not trigger instantiation.
-  if (!IsPotentiallyEvaluatedContext(SemaRef)) {
-    if (SemaRef.isUnevaluatedContext())
-      return;
-
-    // If we don't yet know whether this context is going to end up being an
-    // evaluated context, and we're referencing a variable from an enclosing
-    // scope, add a potential capture.
-    //
-    // FIXME: Is this necessary? These contexts are only used for default
-    // arguments, where local variables can't be used.
-    const bool RefersToEnclosingScope =
-        (SemaRef.CurContext != Var->getDeclContext() &&
-         Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());
-    if (RefersToEnclosingScope) {
-      if (LambdaScopeInfo *const LSI =
-              SemaRef.getCurLambda(/*IgnoreCapturedRegions=*/true)) {
-        // If a variable could potentially be odr-used, defer marking it so
-        // until we finish analyzing the full expression for any
-        // lvalue-to-rvalue
-        // or discarded value conversions that would obviate odr-use.
-        // Add it to the list of potential captures that will be analyzed
-        // later (ActOnFinishFullExpr) for eventual capture and odr-use marking
-        // unless the variable is a reference that was initialized by a constant
-        // expression (this will never need to be captured or odr-used).
-        assert(E && "Capture variable should be used in an expression.");
-        if (!Var->getType()->isReferenceType() ||
-            !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context))
-          LSI->addPotentialCapture(E->IgnoreParens());
-      }
-    }
-
-    if (!isTemplateInstantiation(TSK))
-      return;
-
-    // Instantiate, but do not mark as odr-used, variable templates.
-    MarkODRUsed = false;
-  }
+  bool OdrUseContext = isOdrUseContext(SemaRef);
+  bool NeedDefinition =
+      OdrUseContext || (isEvaluatableContext(SemaRef) &&
+                        Var->isUsableInConstantExpressions(SemaRef.Context));
 
   VarTemplateSpecializationDecl *VarSpec =
       dyn_cast<VarTemplateSpecializationDecl>(Var);
@@ -14144,14 +14251,15 @@
   // If this might be a member specialization of a static data member, check
   // the specialization is visible. We already did the checks for variable
   // template specializations when we created them.
-  if (TSK != TSK_Undeclared && !isa<VarTemplateSpecializationDecl>(Var))
+  if (NeedDefinition && TSK != TSK_Undeclared &&
+      !isa<VarTemplateSpecializationDecl>(Var))
     SemaRef.checkSpecializationVisibility(Loc, Var);
 
   // Perform implicit instantiation of static data members, static data member
   // templates of class templates, and variable template specializations. Delay
   // instantiations of variable templates, except for those that could be used
   // in a constant expression.
-  if (isTemplateInstantiation(TSK)) {
+  if (NeedDefinition && isTemplateInstantiation(TSK)) {
     bool TryInstantiating = TSK == TSK_ImplicitInstantiation;
 
     if (TryInstantiating && !isa<VarTemplateSpecializationDecl>(Var)) {
@@ -14190,9 +14298,6 @@
     }
   }
 
-  if (!MarkODRUsed)
-    return;
-
   // Per C++11 [basic.def.odr], a variable is odr-used "unless it satisfies
   // the requirements for appearing in a constant expression (5.19) and, if
   // it is an object, the lvalue-to-rvalue conversion (4.1)
@@ -14201,14 +14306,42 @@
   // Note that we use the C++11 definition everywhere because nothing in
   // C++03 depends on whether we get the C++03 version correct. The second
   // part does not apply to references, since they are not objects.
-  if (E && IsVariableAConstantExpression(Var, SemaRef.Context)) {
+  if (OdrUseContext && E &&
+      IsVariableAConstantExpression(Var, SemaRef.Context)) {
     // A reference initialized by a constant expression can never be
     // odr-used, so simply ignore it.
     if (!Var->getType()->isReferenceType())
       SemaRef.MaybeODRUseExprs.insert(E);
-  } else
+  } else if (OdrUseContext) {
     MarkVarDeclODRUsed(Var, Loc, SemaRef,
                        /*MaxFunctionScopeIndex ptr*/ nullptr);
+  } else if (isOdrUseContext(SemaRef, /*SkipDependentUses*/false)) {
+    // If this is a dependent context, we don't need to mark variables as
+    // odr-used, but we may still need to track them for lambda capture.
+    // FIXME: Do we also need to do this inside dependent typeid expressions
+    // (which are modeled as unevaluated at this point)?
+    const bool RefersToEnclosingScope =
+        (SemaRef.CurContext != Var->getDeclContext() &&
+         Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());
+    if (RefersToEnclosingScope) {
+      LambdaScopeInfo *const LSI =
+          SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true);
+      if (LSI && !LSI->CallOperator->Encloses(Var->getDeclContext())) {
+        // If a variable could potentially be odr-used, defer marking it so
+        // until we finish analyzing the full expression for any
+        // lvalue-to-rvalue
+        // or discarded value conversions that would obviate odr-use.
+        // Add it to the list of potential captures that will be analyzed
+        // later (ActOnFinishFullExpr) for eventual capture and odr-use marking
+        // unless the variable is a reference that was initialized by a constant
+        // expression (this will never need to be captured or odr-used).
+        assert(E && "Capture variable should be used in an expression.");
+        if (!Var->getType()->isReferenceType() ||
+            !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context))
+          LSI->addPotentialCapture(E->IgnoreParens());
+      }
+    }
+  }
 }
 
 /// \brief Mark a variable referenced, and check whether it is odr-used
@@ -14304,9 +14437,13 @@
 }
 
 namespace {
-  // Mark all of the declarations referenced
+  // Mark all of the declarations used by a type as referenced.
   // FIXME: Not fully implemented yet! We need to have a better understanding
-  // of when we're entering
+  // of when we're entering a context we should not recurse into.
+  // FIXME: This is and EvaluatedExprMarker are more-or-less equivalent to
+  // TreeTransforms rebuilding the type in a new context. Rather than
+  // duplicating the TreeTransform logic, we should consider reusing it here.
+  // Currently that causes problems when rebuilding LambdaExprs.
   class MarkReferencedDecls : public RecursiveASTVisitor<MarkReferencedDecls> {
     Sema &S;
     SourceLocation Loc;
@@ -14317,33 +14454,28 @@
     MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) { }
 
     bool TraverseTemplateArgument(const TemplateArgument &Arg);
-    bool TraverseRecordType(RecordType *T);
   };
 }
 
 bool MarkReferencedDecls::TraverseTemplateArgument(
     const TemplateArgument &Arg) {
-  if (Arg.getKind() == TemplateArgument::Declaration) {
-    if (Decl *D = Arg.getAsDecl())
-      S.MarkAnyDeclReferenced(Loc, D, true);
+  {
+    // A non-type template argument is a constant-evaluated context.
+    EnterExpressionEvaluationContext Evaluated(S, Sema::ConstantEvaluated);
+    if (Arg.getKind() == TemplateArgument::Declaration) {
+      if (Decl *D = Arg.getAsDecl())
+        S.MarkAnyDeclReferenced(Loc, D, true);
+    } else if (Arg.getKind() == TemplateArgument::Expression) {
+      S.MarkDeclarationsReferencedInExpr(Arg.getAsExpr(), false);
+    }
   }
 
   return Inherited::TraverseTemplateArgument(Arg);
 }
 
-bool MarkReferencedDecls::TraverseRecordType(RecordType *T) {
-  if (ClassTemplateSpecializationDecl *Spec
-                  = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
-    const TemplateArgumentList &Args = Spec->getTemplateArgs();
-    return TraverseTemplateArguments(Args.data(), Args.size());
-  }
-
-  return true;
-}
-
 void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {
   MarkReferencedDecls Marker(*this, Loc);
-  Marker.TraverseType(Context.getCanonicalType(T));
+  Marker.TraverseType(T);
 }
 
 namespace {
@@ -14450,6 +14582,7 @@
                                const PartialDiagnostic &PD) {
   switch (ExprEvalContexts.back().Context) {
   case Unevaluated:
+  case UnevaluatedList:
   case UnevaluatedAbstract:
   case DiscardedStatement:
     // The argument will never be evaluated, so don't complain.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 262235a..561e12d 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -323,20 +323,31 @@
   return nullptr;
 }
 
-ParsedType Sema::getDestructorType(const DeclSpec& DS, ParsedType ObjectType) {
-    if (DS.getTypeSpecType() == DeclSpec::TST_error || !ObjectType)
-      return nullptr;
-    assert(DS.getTypeSpecType() == DeclSpec::TST_decltype
-           && "only get destructor types from declspecs");
-    QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc());
-    QualType SearchType = GetTypeFromParser(ObjectType);
-    if (SearchType->isDependentType() || Context.hasSameUnqualifiedType(SearchType, T)) {
-      return ParsedType::make(T);
-    }
+ParsedType Sema::getDestructorTypeForDecltype(const DeclSpec &DS,
+                                              ParsedType ObjectType) {
+  if (DS.getTypeSpecType() == DeclSpec::TST_error)
+    return nullptr;
 
+  if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto) {
+    Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid);
+    return nullptr;
+  }
+
+  assert(DS.getTypeSpecType() == DeclSpec::TST_decltype &&
+         "unexpected type in getDestructorType");
+  QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc());
+
+  // If we know the type of the object, check that the correct destructor
+  // type was named now; we can give better diagnostics this way.
+  QualType SearchType = GetTypeFromParser(ObjectType);
+  if (!SearchType.isNull() && !SearchType->isDependentType() &&
+      !Context.hasSameUnqualifiedType(T, SearchType)) {
     Diag(DS.getTypeSpecTypeLoc(), diag::err_destructor_expr_type_mismatch)
       << T << SearchType;
     return nullptr;
+  }
+
+  return ParsedType::make(T);
 }
 
 bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
@@ -448,7 +459,7 @@
   if (E->getType()->isVariablyModifiedType())
     return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid)
                      << E->getType());
-  else if (ActiveTemplateInstantiations.empty() &&
+  else if (!inTemplateInstantiation() &&
            E->HasSideEffects(Context, WasEvaluated)) {
     // The expression operand for typeid is in an unevaluated expression
     // context, so side effects could result in unintended consequences.
@@ -520,17 +531,17 @@
   else if (QT->isArrayType())
     Ty = Ty->getBaseElementTypeUnsafe();
 
-  const auto *RD = Ty->getAsCXXRecordDecl();
-  if (!RD)
+  const auto *TD = Ty->getAsTagDecl();
+  if (!TD)
     return;
 
-  if (const auto *Uuid = RD->getMostRecentDecl()->getAttr<UuidAttr>()) {
+  if (const auto *Uuid = TD->getMostRecentDecl()->getAttr<UuidAttr>()) {
     UuidAttrs.insert(Uuid);
     return;
   }
 
   // __uuidof can grab UUIDs from template arguments.
-  if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
+  if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(TD)) {
     const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
     for (const TemplateArgument &TA : TAL.asArray()) {
       const UuidAttr *UuidForTA = nullptr;
@@ -968,7 +979,7 @@
   }
 
   if (ThisTy.isNull() && isLambdaCallOperator(CurContext) &&
-      !ActiveTemplateInstantiations.empty()) {
+      inTemplateInstantiation()) {
 
     assert(isa<CXXRecordDecl>(DC) &&
            "Trying to get 'this' type from static method?");
@@ -1106,6 +1117,7 @@
             dyn_cast<CapturingScopeInfo>(FunctionScopes[idx])) {
       if (CSI->CXXThisCaptureIndex != 0) {
         // 'this' is already being captured; there isn't anything more to do.
+        CSI->Captures[CSI->CXXThisCaptureIndex - 1].markUsed(BuildAndDiagnose);
         break;
       }
       LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI);
@@ -1255,18 +1267,40 @@
   }
 
   bool ListInitialization = LParenLoc.isInvalid();
-  assert((!ListInitialization || (Exprs.size() == 1 && isa<InitListExpr>(Exprs[0])))
-         && "List initialization must have initializer list as expression.");
+  assert((!ListInitialization ||
+          (Exprs.size() == 1 && isa<InitListExpr>(Exprs[0]))) &&
+         "List initialization must have initializer list as expression.");
   SourceRange FullRange = SourceRange(TyBeginLoc,
       ListInitialization ? Exprs[0]->getSourceRange().getEnd() : RParenLoc);
 
+  InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo);
+  InitializationKind Kind =
+      Exprs.size()
+          ? ListInitialization
+                ? InitializationKind::CreateDirectList(TyBeginLoc)
+                : InitializationKind::CreateDirect(TyBeginLoc, LParenLoc,
+                                                   RParenLoc)
+          : InitializationKind::CreateValue(TyBeginLoc, LParenLoc, RParenLoc);
+
+  // C++1z [expr.type.conv]p1:
+  //   If the type is a placeholder for a deduced class type, [...perform class
+  //   template argument deduction...]
+  DeducedType *Deduced = Ty->getContainedDeducedType();
+  if (Deduced && isa<DeducedTemplateSpecializationType>(Deduced)) {
+    Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity,
+                                                     Kind, Exprs);
+    if (Ty.isNull())
+      return ExprError();
+    Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
+  }
+
   // C++ [expr.type.conv]p1:
   // If the expression list is a single expression, the type conversion
   // expression is equivalent (in definedness, and if defined in meaning) to the
   // corresponding cast expression.
   if (Exprs.size() == 1 && !ListInitialization) {
     Expr *Arg = Exprs[0];
-    return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc);
+    return BuildCXXFunctionalCastExpr(TInfo, Ty, LParenLoc, Arg, RParenLoc);
   }
 
   // C++14 [expr.type.conv]p2: The expression T(), where T is a
@@ -1291,16 +1325,6 @@
                           diag::err_invalid_incomplete_type_use, FullRange))
     return ExprError();
 
-  if (RequireNonAbstractType(TyBeginLoc, Ty,
-                             diag::err_allocation_of_abstract_type))
-    return ExprError();
-
-  InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo);
-  InitializationKind Kind =
-      Exprs.size() ? ListInitialization
-      ? InitializationKind::CreateDirectList(TyBeginLoc)
-      : InitializationKind::CreateDirect(TyBeginLoc, LParenLoc, RParenLoc)
-      : InitializationKind::CreateValue(TyBeginLoc, LParenLoc, RParenLoc);
   InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
   ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs);
 
@@ -1321,7 +1345,7 @@
     // is sometimes handled by initialization and sometimes not.
     QualType ResultType = Result.get()->getType();
     Result = CXXFunctionalCastExpr::Create(
-        Context, ResultType, Expr::getValueKindForType(TInfo->getType()), TInfo,
+        Context, ResultType, Expr::getValueKindForType(Ty), TInfo,
         CK_NoOp, Result.get(), /*Path=*/nullptr, LParenLoc, RParenLoc);
   }
 
@@ -1508,14 +1532,12 @@
                   SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
                   SourceLocation PlacementRParen, SourceRange TypeIdParens,
                   Declarator &D, Expr *Initializer) {
-  bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
-
   Expr *ArraySize = nullptr;
   // If the specified type is an array, unwrap it and save the expression.
   if (D.getNumTypeObjects() > 0 &&
       D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
-     DeclaratorChunk &Chunk = D.getTypeObject(0);
-    if (TypeContainsAuto)
+    DeclaratorChunk &Chunk = D.getTypeObject(0);
+    if (D.getDeclSpec().hasAutoTypeSpec())
       return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto)
         << D.getSourceRange());
     if (Chunk.Arr.hasStatic)
@@ -1592,8 +1614,7 @@
                      TInfo,
                      ArraySize,
                      DirectInitRange,
-                     Initializer,
-                     TypeContainsAuto);
+                     Initializer);
 }
 
 static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
@@ -1625,8 +1646,7 @@
                   TypeSourceInfo *AllocTypeInfo,
                   Expr *ArraySize,
                   SourceRange DirectInitRange,
-                  Expr *Initializer,
-                  bool TypeMayContainAuto) {
+                  Expr *Initializer) {
   SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
   SourceLocation StartLoc = Range.getBegin();
 
@@ -1651,8 +1671,38 @@
     NumInits = List->getNumExprs();
   }
 
+  // C++11 [expr.new]p15:
+  //   A new-expression that creates an object of type T initializes that
+  //   object as follows:
+  InitializationKind Kind
+  //     - If the new-initializer is omitted, the object is default-
+  //       initialized (8.5); if no initialization is performed,
+  //       the object has indeterminate value
+    = initStyle == CXXNewExpr::NoInit
+        ? InitializationKind::CreateDefault(TypeRange.getBegin())
+  //     - Otherwise, the new-initializer is interpreted according to the
+  //       initialization rules of 8.5 for direct-initialization.
+        : initStyle == CXXNewExpr::ListInit
+            ? InitializationKind::CreateDirectList(TypeRange.getBegin())
+            : InitializationKind::CreateDirect(TypeRange.getBegin(),
+                                               DirectInitRange.getBegin(),
+                                               DirectInitRange.getEnd());
+
   // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
-  if (TypeMayContainAuto && AllocType->isUndeducedType()) {
+  auto *Deduced = AllocType->getContainedDeducedType();
+  if (Deduced && isa<DeducedTemplateSpecializationType>(Deduced)) {
+    if (ArraySize)
+      return ExprError(Diag(ArraySize->getExprLoc(),
+                            diag::err_deduced_class_template_compound_type)
+                       << /*array*/ 2 << ArraySize->getSourceRange());
+
+    InitializedEntity Entity
+      = InitializedEntity::InitializeNew(StartLoc, AllocType);
+    AllocType = DeduceTemplateSpecializationFromInitializer(
+        AllocTypeInfo, Entity, Kind, MultiExprArg(Inits, NumInits));
+    if (AllocType.isNull())
+      return ExprError();
+  } else if (Deduced) {
     if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
       return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
                        << AllocType << TypeRange);
@@ -1939,23 +1989,6 @@
     else
       InitType = AllocType;
 
-    // C++11 [expr.new]p15:
-    //   A new-expression that creates an object of type T initializes that
-    //   object as follows:
-    InitializationKind Kind
-    //     - If the new-initializer is omitted, the object is default-
-    //       initialized (8.5); if no initialization is performed,
-    //       the object has indeterminate value
-      = initStyle == CXXNewExpr::NoInit
-          ? InitializationKind::CreateDefault(TypeRange.getBegin())
-    //     - Otherwise, the new-initializer is interpreted according to the
-    //       initialization rules of 8.5 for direct-initialization.
-          : initStyle == CXXNewExpr::ListInit
-              ? InitializationKind::CreateDirectList(TypeRange.getBegin())
-              : InitializationKind::CreateDirect(TypeRange.getBegin(),
-                                                 DirectInitRange.getBegin(),
-                                                 DirectInitRange.getEnd());
-
     InitializedEntity Entity
       = InitializedEntity::InitializeNew(StartLoc, InitType);
     InitializationSequence InitSeq(*this, Entity, Kind,
@@ -3882,6 +3915,12 @@
                              From->getValueKind()).get();
     break;
 
+  case ICK_Zero_Queue_Conversion:
+    From = ImpCastExprToType(From, ToType,
+                             CK_ZeroToOCLQueue,
+                             From->getValueKind()).get();
+    break;
+
   case ICK_Lvalue_To_Rvalue:
   case ICK_Array_To_Pointer:
   case ICK_Function_To_Pointer:
@@ -5203,8 +5242,7 @@
   //
   // This actually refers very narrowly to the lvalue-to-rvalue conversion, not
   // to the array-to-pointer or function-to-pointer conversions.
-  if (!TTy->getAs<TagType>())
-    TTy = TTy.getUnqualifiedType();
+  TTy = TTy.getNonLValueExprType(Self.Context);
 
   InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
   InitializationSequence InitSeq(Self, Entity, Kind, From);
@@ -5411,13 +5449,19 @@
     if (CompareReferenceRelationship(
             QuestionLoc, LTy, RTy, DerivedToBase,
             ObjCConversion, ObjCLifetimeConversion) == Ref_Compatible &&
-        !DerivedToBase && !ObjCConversion && !ObjCLifetimeConversion) {
+        !DerivedToBase && !ObjCConversion && !ObjCLifetimeConversion &&
+        // [...] subject to the constraint that the reference must bind
+        // directly [...]
+        !RHS.get()->refersToBitField() &&
+        !RHS.get()->refersToVectorElement()) {
       RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK);
       RTy = RHS.get()->getType();
     } else if (CompareReferenceRelationship(
                    QuestionLoc, RTy, LTy, DerivedToBase,
                    ObjCConversion, ObjCLifetimeConversion) == Ref_Compatible &&
-               !DerivedToBase && !ObjCConversion && !ObjCLifetimeConversion) {
+               !DerivedToBase && !ObjCConversion && !ObjCLifetimeConversion &&
+               !LHS.get()->refersToBitField() &&
+               !LHS.get()->refersToVectorElement()) {
       LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK);
       LTy = LHS.get()->getType();
     }
@@ -5485,9 +5529,6 @@
   if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) {
     if (LTy->isRecordType()) {
       // The operands have class type. Make a temporary copy.
-      if (RequireNonAbstractType(QuestionLoc, LTy,
-                                 diag::err_allocation_of_abstract_type))
-        return QualType();
       InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
 
       ExprResult LHSCopy = PerformCopyInitialization(Entity,
@@ -6402,6 +6443,23 @@
   return false;
 }
 
+/// \brief Check if it's ok to try and recover dot pseudo destructor calls on
+/// pointer objects.
+static bool
+canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef,
+                                                   QualType DestructedType) {
+  // If this is a record type, check if its destructor is callable.
+  if (auto *RD = DestructedType->getAsCXXRecordDecl()) {
+    if (CXXDestructorDecl *D = SemaRef.LookupDestructor(RD))
+      return SemaRef.CanUseDecl(D, /*TreatUnavailableAsInvalid=*/false);
+    return false;
+  }
+
+  // Otherwise, check if it's a type for which it's valid to use a pseudo-dtor.
+  return DestructedType->isDependentType() || DestructedType->isScalarType() ||
+         DestructedType->isVectorType();
+}
+
 ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
                                            SourceLocation OpLoc,
                                            tok::TokenKind OpKind,
@@ -6436,15 +6494,36 @@
       = DestructedTypeInfo->getTypeLoc().getLocalSourceRange().getBegin();
     if (!DestructedType->isDependentType() && !ObjectType->isDependentType()) {
       if (!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
-        Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
-          << ObjectType << DestructedType << Base->getSourceRange()
-          << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
+        // Detect dot pseudo destructor calls on pointer objects, e.g.:
+        //   Foo *foo;
+        //   foo.~Foo();
+        if (OpKind == tok::period && ObjectType->isPointerType() &&
+            Context.hasSameUnqualifiedType(DestructedType,
+                                           ObjectType->getPointeeType())) {
+          auto Diagnostic =
+              Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+              << ObjectType << /*IsArrow=*/0 << Base->getSourceRange();
 
-        // Recover by setting the destructed type to the object type.
-        DestructedType = ObjectType;
-        DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType,
-                                                           DestructedTypeStart);
-        Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
+          // Issue a fixit only when the destructor is valid.
+          if (canRecoverDotPseudoDestructorCallsOnPointerObjects(
+                  *this, DestructedType))
+            Diagnostic << FixItHint::CreateReplacement(OpLoc, "->");
+
+          // Recover by setting the object type to the destructed type and the
+          // operator to '->'.
+          ObjectType = DestructedType;
+          OpKind = tok::arrow;
+        } else {
+          Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
+              << ObjectType << DestructedType << Base->getSourceRange()
+              << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
+
+          // Recover by setting the destructed type to the object type.
+          DestructedType = ObjectType;
+          DestructedTypeInfo =
+              Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart);
+          Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
+        }
       } else if (DestructedType.getObjCLifetime() !=
                                                 ObjectType.getObjCLifetime()) {
 
@@ -6537,7 +6616,8 @@
   if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
     ParsedType T = getTypeName(*SecondTypeName.Identifier,
                                SecondTypeName.StartLocation,
-                               S, &SS, true, false, ObjectTypePtrForLookup);
+                               S, &SS, true, false, ObjectTypePtrForLookup,
+                               /*IsCtorOrDtorName*/true);
     if (!T &&
         ((SS.isSet() && !computeDeclContext(SS, false)) ||
          (!SS.isSet() && ObjectType->isDependentType()))) {
@@ -6566,10 +6646,12 @@
     TypeResult T = ActOnTemplateIdType(TemplateId->SS,
                                        TemplateId->TemplateKWLoc,
                                        TemplateId->Template,
+                                       TemplateId->Name,
                                        TemplateId->TemplateNameLoc,
                                        TemplateId->LAngleLoc,
                                        TemplateArgsPtr,
-                                       TemplateId->RAngleLoc);
+                                       TemplateId->RAngleLoc,
+                                       /*IsCtorOrDtorName*/true);
     if (T.isInvalid() || !T.get()) {
       // Recover by assuming we had the right type all along.
       DestructedType = ObjectType;
@@ -6594,7 +6676,8 @@
     if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) {
       ParsedType T = getTypeName(*FirstTypeName.Identifier,
                                  FirstTypeName.StartLocation,
-                                 S, &SS, true, false, ObjectTypePtrForLookup);
+                                 S, &SS, true, false, ObjectTypePtrForLookup,
+                                 /*IsCtorOrDtorName*/true);
       if (!T) {
         Diag(FirstTypeName.StartLocation,
              diag::err_pseudo_dtor_destructor_non_type)
@@ -6615,10 +6698,12 @@
       TypeResult T = ActOnTemplateIdType(TemplateId->SS,
                                          TemplateId->TemplateKWLoc,
                                          TemplateId->Template,
+                                         TemplateId->Name,
                                          TemplateId->TemplateNameLoc,
                                          TemplateId->LAngleLoc,
                                          TemplateArgsPtr,
-                                         TemplateId->RAngleLoc);
+                                         TemplateId->RAngleLoc,
+                                         /*IsCtorOrDtorName*/true);
       if (T.isInvalid() || !T.get()) {
         // Recover by dropping this type.
         ScopeType = QualType();
@@ -6712,6 +6797,11 @@
   CXXMemberCallExpr *CE =
     new (Context) CXXMemberCallExpr(Context, ME, None, ResultType, VK,
                                     Exp.get()->getLocEnd());
+
+  if (CheckFunctionCall(Method, CE,
+                        Method->getType()->castAs<FunctionProtoType>()))
+    return ExprError();
+
   return CE;
 }
 
@@ -6727,8 +6817,7 @@
   // The operand may have been modified when checking the placeholder type.
   Operand = R.get();
 
-  if (ActiveTemplateInstantiations.empty() &&
-      Operand->HasSideEffects(Context, false)) {
+  if (!inTemplateInstantiation() && Operand->HasSideEffects(Context, false)) {
     // The expression operand for noexcept is in an unevaluated expression
     // context, so side effects could result in unintended consequences.
     Diag(Operand->getExprLoc(), diag::warn_side_effects_unevaluated_context);
@@ -7185,14 +7274,6 @@
 
   ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); }
 
-  ExprResult TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
-    return Owned(E);
-  }
-
-  ExprResult TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
-    return Owned(E);
-  }
-
   ExprResult Transform(Expr *E) {
     ExprResult Res;
     while (true) {
@@ -7258,6 +7339,8 @@
     while (TypoCorrection TC = State.Consumer->getNextCorrection()) {
       if (InitDecl && TC.getFoundDecl() == InitDecl)
         continue;
+      // FIXME: If we would typo-correct to an invalid declaration, it's
+      // probably best to just suppress all errors from this typo correction.
       ExprResult NE = State.RecoveryHandler ?
           State.RecoveryHandler(SemaRef, E, TC) :
           attemptRecovery(SemaRef, *State.Consumer, TC);
@@ -7463,17 +7546,11 @@
                                    UnqualifiedId &Name) {
   DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
 
-  // Check for unexpanded parameter packs.
-  SmallVector<UnexpandedParameterPack, 4> Unexpanded;
-  collectUnexpandedParameterPacks(SS, Unexpanded);
-  collectUnexpandedParameterPacks(TargetNameInfo, Unexpanded);
-  if (!Unexpanded.empty()) {
-    DiagnoseUnexpandedParameterPacks(KeywordLoc,
-                                     IsIfExists? UPPC_IfExists
-                                               : UPPC_IfNotExists,
-                                     Unexpanded);
+  // Check for an unexpanded parameter pack.
+  auto UPPC = IsIfExists ? UPPC_IfExists : UPPC_IfNotExists;
+  if (DiagnoseUnexpandedParameterPack(SS, UPPC) ||
+      DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC))
     return IER_Error;
-  }
 
   return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo);
 }
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 806a3d8..f08bdc5 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -134,6 +134,7 @@
   assert(!AbstractInstanceResult);
   switch (SemaRef.ExprEvalContexts.back().Context) {
   case Sema::Unevaluated:
+  case Sema::UnevaluatedList:
     if (isField && SemaRef.getLangOpts().CPlusPlus11)
       AbstractInstanceResult = IMA_Field_Uneval_Context;
     break;
@@ -972,7 +973,7 @@
 
   // C++1z [expr.ref]p2:
   //   For the first option (dot) the first expression shall be a glvalue [...]
-  if (!IsArrow && BaseExpr->isRValue()) {
+  if (!IsArrow && BaseExpr && BaseExpr->isRValue()) {
     ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
     if (Converted.isInvalid())
       return ExprError();
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 7dbd660..67876c2 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -1984,13 +1984,24 @@
     }
   }
 
+  Selector GetterSel;
+  Selector SetterSel;
+  if (auto PD = IFace->FindPropertyDeclaration(
+          &propertyName, ObjCPropertyQueryKind::OBJC_PR_query_class)) {
+    GetterSel = PD->getGetterName();
+    SetterSel = PD->getSetterName();
+  } else {
+    GetterSel = PP.getSelectorTable().getNullarySelector(&propertyName);
+    SetterSel = SelectorTable::constructSetterSelector(
+        PP.getIdentifierTable(), PP.getSelectorTable(), &propertyName);
+  }
+
   // Search for a declared property first.
-  Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName);
-  ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel);
+  ObjCMethodDecl *Getter = IFace->lookupClassMethod(GetterSel);
 
   // If this reference is in an @implementation, check for 'private' methods.
   if (!Getter)
-    Getter = IFace->lookupPrivateClassMethod(Sel);
+    Getter = IFace->lookupPrivateClassMethod(GetterSel);
 
   if (Getter) {
     // FIXME: refactor/share with ActOnMemberReference().
@@ -2000,11 +2011,6 @@
   }
 
   // Look for the matching setter, in case it is needed.
-  Selector SetterSel =
-    SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
-                                            PP.getSelectorTable(),
-                                           &propertyName);
-
   ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
   if (!Setter) {
     // If this reference is in an @implementation, also check for 'private'
@@ -2260,6 +2266,52 @@
                      edit::rewriteObjCRedundantCallWithLiteral);
 }
 
+static void checkFoundationAPI(Sema &S, SourceLocation Loc,
+                               const ObjCMethodDecl *Method,
+                               ArrayRef<Expr *> Args, QualType ReceiverType,
+                               bool IsClassObjectCall) {
+  // Check if this is a performSelector method that uses a selector that returns
+  // a record or a vector type.
+  if (Method->getMethodFamily() != OMF_performSelector || Args.empty())
+    return;
+  const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
+  if (!SE)
+    return;
+  ObjCMethodDecl *ImpliedMethod;
+  if (!IsClassObjectCall) {
+    const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>();
+    if (!OPT || !OPT->getInterfaceDecl())
+      return;
+    ImpliedMethod =
+        OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
+    if (!ImpliedMethod)
+      ImpliedMethod =
+          OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
+  } else {
+    const auto *IT = ReceiverType->getAs<ObjCInterfaceType>();
+    if (!IT)
+      return;
+    ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
+    if (!ImpliedMethod)
+      ImpliedMethod =
+          IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
+  }
+  if (!ImpliedMethod)
+    return;
+  QualType Ret = ImpliedMethod->getReturnType();
+  if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
+    QualType Ret = ImpliedMethod->getReturnType();
+    S.Diag(Loc, diag::warn_objc_unsafe_perform_selector)
+        << Method->getSelector()
+        << (!Ret->isRecordType()
+                ? /*Vector*/ 2
+                : Ret->isUnionType() ? /*Union*/ 1 : /*Struct*/ 0);
+    S.Diag(ImpliedMethod->getLocStart(),
+           diag::note_objc_unsafe_perform_selector_method_declared_here)
+        << ImpliedMethod->getSelector() << Ret;
+  }
+}
+
 /// \brief Diagnose use of %s directive in an NSString which is being passed
 /// as formatting string to formatting method.
 static void
@@ -2462,6 +2514,9 @@
     if (!isImplicit)
       checkCocoaAPI(*this, Result);
   }
+  if (Method)
+    checkFoundationAPI(*this, SelLoc, Method, makeArrayRef(Args, NumArgs),
+                       ReceiverType, /*IsClassObjectCall=*/true);
   return MaybeBindToTemporary(Result);
 }
 
@@ -2920,7 +2975,8 @@
     
     case OMF_performSelector:
       if (Method && NumArgs >= 1) {
-        if (ObjCSelectorExpr *SelExp = dyn_cast<ObjCSelectorExpr>(Args[0])) {
+        if (const auto *SelExp =
+                dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
           Selector ArgSel = SelExp->getSelector();
           ObjCMethodDecl *SelMethod = 
             LookupInstanceMethodInGlobalPool(ArgSel,
@@ -2987,6 +3043,26 @@
     if (!isImplicit)
       checkCocoaAPI(*this, Result);
   }
+  if (Method) {
+    bool IsClassObjectCall = ClassMessage;
+    // 'self' message receivers in class methods should be treated as message
+    // sends to the class object in order for the semantic checks to be
+    // performed correctly. Messages to 'super' already count as class messages,
+    // so they don't need to be handled here.
+    if (Receiver && isSelfExpr(Receiver)) {
+      if (const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
+        if (OPT->getObjectType()->isObjCClass()) {
+          if (const auto *CurMeth = getCurMethodDecl()) {
+            IsClassObjectCall = true;
+            ReceiverType =
+                Context.getObjCInterfaceType(CurMeth->getClassInterface());
+          }
+        }
+      }
+    }
+    checkFoundationAPI(*this, SelLoc, Method, makeArrayRef(Args, NumArgs),
+                       ReceiverType, IsClassObjectCall);
+  }
 
   if (getLangOpts().ObjCAutoRefCount) {
     // In ARC, annotate delegate init calls.
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index a0ea8e1..3970e83 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -623,6 +623,11 @@
   assert((ILE->getType() != SemaRef.Context.VoidTy) &&
          "Should not have void type");
 
+  // A transparent ILE is not performing aggregate initialization and should
+  // not be filled in.
+  if (ILE->isTransparent())
+    return;
+
   if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
     const RecordDecl *RDecl = RType->getDecl();
     if (RDecl->isUnion() && ILE->getInitializedFieldInUnion())
@@ -902,7 +907,7 @@
   // Don't warn during template instantiation. If the initialization was
   // non-dependent, we warned during the initial parse; otherwise, the
   // type might not be scalar in some uses of the template.
-  if (!S.ActiveTemplateInstantiations.empty())
+  if (S.inTemplateInstantiation())
     return;
 
   unsigned DiagID = 0;
@@ -1684,7 +1689,7 @@
     // If this is an incomplete array type, the actual type needs to
     // be calculated here.
     llvm::APSInt Zero(maxElements.getBitWidth(), maxElements.isUnsigned());
-    if (maxElements == Zero) {
+    if (maxElements == Zero && !Entity.isVariableLengthArrayNew()) {
       // Sizing an array implicitly to zero is not allowed by ISO C,
       // but is supported by GNU.
       SemaRef.Diag(IList->getLocStart(),
@@ -2237,6 +2242,10 @@
     }
 
     unsigned FieldIndex = 0;
+
+    if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+      FieldIndex = CXXRD->getNumBases();
+
     for (auto *FI : RT->getDecl()->fields()) {
       if (FI->isUnnamedBitfield())
         continue;
@@ -2910,7 +2919,7 @@
   case EK_Variable:
   case EK_Member:
   case EK_Binding:
-    return VariableOrMember->getDeclName();
+    return Variable.VariableOrMember->getDeclName();
 
   case EK_LambdaCapture:
     return DeclarationName(Capture.VarID);
@@ -2938,7 +2947,7 @@
   case EK_Variable:
   case EK_Member:
   case EK_Binding:
-    return VariableOrMember;
+    return Variable.VariableOrMember;
 
   case EK_Parameter:
   case EK_Parameter_CF_Audited:
@@ -3048,6 +3057,7 @@
   case SK_CastDerivedToBaseLValue:
   case SK_BindReference:
   case SK_BindReferenceToTemporary:
+  case SK_FinalCopy:
   case SK_ExtraneousCopyToTemporary:
   case SK_UserConversion:
   case SK_QualificationConversionRValue:
@@ -3064,7 +3074,10 @@
   case SK_CAssignment:
   case SK_StringInit:
   case SK_ObjCObjectConversion:
+  case SK_ArrayLoopIndex:
+  case SK_ArrayLoopInit:
   case SK_ArrayInit:
+  case SK_GNUArrayInit:
   case SK_ParenthesizedArrayInit:
   case SK_PassByIndirectCopyRestore:
   case SK_PassByIndirectRestore:
@@ -3073,6 +3086,7 @@
   case SK_StdInitializerListConstructorCall:
   case SK_OCLSamplerInit:
   case SK_OCLZeroEvent:
+  case SK_OCLZeroQueue:
     break;
 
   case SK_ConversionSequence:
@@ -3082,7 +3096,14 @@
 }
 
 bool InitializationSequence::isDirectReferenceBinding() const {
-  return !Steps.empty() && Steps.back().Kind == SK_BindReference;
+  // There can be some lvalue adjustments after the SK_BindReference step.
+  for (auto I = Steps.rbegin(); I != Steps.rend(); ++I) {
+    if (I->Kind == SK_BindReference)
+      return true;
+    if (I->Kind == SK_BindReferenceToTemporary)
+      return false;
+  }
+  return false;
 }
 
 bool InitializationSequence::isAmbiguous() const {
@@ -3099,6 +3120,8 @@
   case FK_IncompatWideStringIntoWideChar:
   case FK_AddressOfOverloadFailed: // FIXME: Could do better
   case FK_NonConstLValueReferenceBindingToTemporary:
+  case FK_NonConstLValueReferenceBindingToBitfield:
+  case FK_NonConstLValueReferenceBindingToVectorElement:
   case FK_NonConstLValueReferenceBindingToUnrelated:
   case FK_RValueReferenceBindingToLValue:
   case FK_ReferenceInitDropsQualifiers:
@@ -3167,6 +3190,13 @@
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddFinalCopy(QualType T) {
+  Step S;
+  S.Kind = SK_FinalCopy;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::AddExtraneousCopyToTemporary(QualType T) {
   Step S;
   S.Kind = SK_ExtraneousCopyToTemporary;
@@ -3283,9 +3313,20 @@
   Steps.push_back(S);
 }
 
-void InitializationSequence::AddArrayInitStep(QualType T) {
+void InitializationSequence::AddArrayInitStep(QualType T, bool IsGNUExtension) {
   Step S;
-  S.Kind = SK_ArrayInit;
+  S.Kind = IsGNUExtension ? SK_GNUArrayInit : SK_ArrayInit;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddArrayInitLoopStep(QualType T, QualType EltT) {
+  Step S;
+  S.Kind = SK_ArrayLoopIndex;
+  S.Type = EltT;
+  Steps.insert(Steps.begin(), S);
+
+  S.Kind = SK_ArrayLoopInit;
   S.Type = T;
   Steps.push_back(S);
 }
@@ -3334,6 +3375,13 @@
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddOCLZeroQueueStep(QualType T) {
+  Step S;
+  S.Kind = SK_OCLZeroQueue;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::RewrapReferenceInitList(QualType T,
                                                      InitListExpr *Syntactic) {
   assert(Syntactic->getNumInits() == 1 &&
@@ -3535,6 +3583,9 @@
 /// \brief Attempt initialization by constructor (C++ [dcl.init]), which
 /// enumerates the constructors of the initialized entity and performs overload
 /// resolution to select the best.
+/// \param DestType       The destination class type.
+/// \param DestArrayType  The destination type, which is either DestType or
+///                       a (possibly multidimensional) array of DestType.
 /// \param IsListInit     Is this list-initialization?
 /// \param IsInitListCopy Is this non-list-initialization resulting from a
 ///                       list-initialization from {x} where x is the same
@@ -3543,6 +3594,7 @@
                                          const InitializedEntity &Entity,
                                          const InitializationKind &Kind,
                                          MultiExprArg Args, QualType DestType,
+                                         QualType DestArrayType,
                                          InitializationSequence &Sequence,
                                          bool IsListInit = false,
                                          bool IsInitListCopy = false) {
@@ -3574,17 +3626,7 @@
       UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isRValue() &&
       S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) {
     // Convert qualifications if necessary.
-    QualType InitType = UnwrappedArgs[0]->getType();
-    ImplicitConversionSequence ICS;
-    ICS.setStandard();
-    ICS.Standard.setAsIdentityConversion();
-    ICS.Standard.setFromType(InitType);
-    ICS.Standard.setAllToTypes(InitType);
-    if (!S.Context.hasSameType(InitType, DestType)) {
-      ICS.Standard.Third = ICK_Qualification;
-      ICS.Standard.setToType(2, DestType);
-    }
-    Sequence.AddConversionSequenceStep(ICS, DestType);
+    Sequence.AddQualificationConversionStep(DestType, VK_RValue);
     if (ILE)
       Sequence.RewrapReferenceInitList(DestType, ILE);
     return;
@@ -3686,7 +3728,7 @@
   // subsumed by the initialization.
   bool HadMultipleCandidates = (CandidateSet.size() > 1);
   Sequence.AddConstructorInitializationStep(
-      Best->FoundDecl, CtorDecl, DestType, HadMultipleCandidates,
+      Best->FoundDecl, CtorDecl, DestArrayType, HadMultipleCandidates,
       IsListInit | IsInitListCopy, AsInitializerList);
 }
 
@@ -3854,8 +3896,9 @@
           S.IsDerivedFrom(InitList->getLocStart(), InitType, DestType)) {
         Expr *InitListAsExpr = InitList;
         TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, DestType,
-                                     Sequence, /*InitListSyntax*/ false,
-                                     /*IsInitListCopy*/ true);
+                                     DestType, Sequence,
+                                     /*InitListSyntax*/false,
+                                     /*IsInitListCopy*/true);
         return;
       }
     }
@@ -3910,7 +3953,7 @@
       //   - Otherwise, if T is a class type, constructors are considered.
       Expr *InitListAsExpr = InitList;
       TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, DestType,
-                                   Sequence, /*InitListSyntax*/ true);
+                                   DestType, Sequence, /*InitListSyntax*/true);
     } else
       Sequence.SetFailed(InitializationSequence::FK_InitListBadDestinationType);
     return;
@@ -3943,6 +3986,8 @@
       ImplicitConversionSequence ICS;
       ICS.setStandard();
       ICS.Standard.setAsIdentityConversion();
+      if (!E->isRValue())
+        ICS.Standard.First = ICK_Lvalue_To_Rvalue;
       // If E is of a floating-point type, then the conversion is ill-formed
       // due to narrowing, but go through the motions in order to produce the
       // right diagnostic.
@@ -4002,12 +4047,10 @@
 
 /// \brief Try a reference initialization that involves calling a conversion
 /// function.
-static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
-                                             const InitializedEntity &Entity,
-                                             const InitializationKind &Kind,
-                                             Expr *Initializer,
-                                             bool AllowRValues,
-                                             InitializationSequence &Sequence) {
+static OverloadingResult TryRefInitWithConversionFunction(
+    Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind,
+    Expr *Initializer, bool AllowRValues, bool IsLValueRef,
+    InitializationSequence &Sequence) {
   QualType DestType = Entity.getType();
   QualType cv1T1 = DestType->getAs<ReferenceType>()->getPointeeType();
   QualType T1 = cv1T1.getUnqualifiedType();
@@ -4123,58 +4166,68 @@
   // use this initialization. Mark it as referenced.
   Function->setReferenced();
 
-  // Compute the returned type of the conversion.
+  // Compute the returned type and value kind of the conversion.
+  QualType cv3T3;
   if (isa<CXXConversionDecl>(Function))
-    T2 = Function->getReturnType();
+    cv3T3 = Function->getReturnType();
   else
-    T2 = cv1T1;
+    cv3T3 = T1;
+
+  ExprValueKind VK = VK_RValue;
+  if (cv3T3->isLValueReferenceType())
+    VK = VK_LValue;
+  else if (const auto *RRef = cv3T3->getAs<RValueReferenceType>())
+    VK = RRef->getPointeeType()->isFunctionType() ? VK_LValue : VK_XValue;
+  cv3T3 = cv3T3.getNonLValueExprType(S.Context);
 
   // Add the user-defined conversion step.
   bool HadMultipleCandidates = (CandidateSet.size() > 1);
-  Sequence.AddUserConversionStep(Function, Best->FoundDecl,
-                                 T2.getNonLValueExprType(S.Context),
+  Sequence.AddUserConversionStep(Function, Best->FoundDecl, cv3T3,
                                  HadMultipleCandidates);
 
-  // Determine whether we need to perform derived-to-base or
-  // cv-qualification adjustments.
-  ExprValueKind VK = VK_RValue;
-  if (T2->isLValueReferenceType())
-    VK = VK_LValue;
-  else if (const RValueReferenceType *RRef = T2->getAs<RValueReferenceType>())
-    VK = RRef->getPointeeType()->isFunctionType() ? VK_LValue : VK_XValue;
-
+  // Determine whether we'll need to perform derived-to-base adjustments or
+  // other conversions.
   bool NewDerivedToBase = false;
   bool NewObjCConversion = false;
   bool NewObjCLifetimeConversion = false;
   Sema::ReferenceCompareResult NewRefRelationship
-    = S.CompareReferenceRelationship(DeclLoc, T1,
-                                     T2.getNonLValueExprType(S.Context),
+    = S.CompareReferenceRelationship(DeclLoc, T1, cv3T3,
                                      NewDerivedToBase, NewObjCConversion,
                                      NewObjCLifetimeConversion);
+
+  // Add the final conversion sequence, if necessary.
   if (NewRefRelationship == Sema::Ref_Incompatible) {
-    // If the type we've converted to is not reference-related to the
-    // type we're looking for, then there is another conversion step
-    // we need to perform to produce a temporary of the right type
-    // that we'll be binding to.
+    assert(!isa<CXXConstructorDecl>(Function) &&
+           "should not have conversion after constructor");
+
     ImplicitConversionSequence ICS;
     ICS.setStandard();
     ICS.Standard = Best->FinalConversion;
-    T2 = ICS.Standard.getToType(2);
-    Sequence.AddConversionSequenceStep(ICS, T2);
-  } else if (NewDerivedToBase)
-    Sequence.AddDerivedToBaseCastStep(
-                                S.Context.getQualifiedType(T1,
-                                  T2.getNonReferenceType().getQualifiers()),
-                                      VK);
+    Sequence.AddConversionSequenceStep(ICS, ICS.Standard.getToType(2));
+
+    // Every implicit conversion results in a prvalue, except for a glvalue
+    // derived-to-base conversion, which we handle below.
+    cv3T3 = ICS.Standard.getToType(2);
+    VK = VK_RValue;
+  }
+
+  //   If the converted initializer is a prvalue, its type T4 is adjusted to
+  //   type "cv1 T4" and the temporary materialization conversion is applied.
+  //
+  // We adjust the cv-qualifications to match the reference regardless of
+  // whether we have a prvalue so that the AST records the change. In this
+  // case, T4 is "cv3 T3".
+  QualType cv1T4 = S.Context.getQualifiedType(cv3T3, cv1T1.getQualifiers());
+  if (cv1T4.getQualifiers() != cv3T3.getQualifiers())
+    Sequence.AddQualificationConversionStep(cv1T4, VK);
+  Sequence.AddReferenceBindingStep(cv1T4, VK == VK_RValue);
+  VK = IsLValueRef ? VK_LValue : VK_XValue;
+
+  if (NewDerivedToBase)
+    Sequence.AddDerivedToBaseCastStep(cv1T1, VK);
   else if (NewObjCConversion)
-    Sequence.AddObjCObjectConversionStep(
-                                S.Context.getQualifiedType(T1,
-                                  T2.getNonReferenceType().getQualifiers()));
+    Sequence.AddObjCObjectConversionStep(cv1T1);
 
-  if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers())
-    Sequence.AddQualificationConversionStep(cv1T1, VK);
-
-  Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType());
   return OR_Success;
 }
 
@@ -4208,54 +4261,11 @@
                                  T1Quals, cv2T2, T2, T2Quals, Sequence);
 }
 
-/// Converts the target of reference initialization so that it has the
-/// appropriate qualifiers and value kind.
-///
-/// In this case, 'x' is an 'int' lvalue, but it needs to be 'const int'.
-/// \code
-///   int x;
-///   const int &r = x;
-/// \endcode
-///
-/// In this case the reference is binding to a bitfield lvalue, which isn't
-/// valid. Perform a load to create a lifetime-extended temporary instead.
-/// \code
-///   const int &r = someStruct.bitfield;
-/// \endcode
-static ExprValueKind
-convertQualifiersAndValueKindIfNecessary(Sema &S,
-                                         InitializationSequence &Sequence,
-                                         Expr *Initializer,
-                                         QualType cv1T1,
-                                         Qualifiers T1Quals,
-                                         Qualifiers T2Quals,
-                                         bool IsLValueRef) {
-  bool IsNonAddressableType = Initializer->refersToBitField() ||
-                              Initializer->refersToVectorElement();
-
-  if (IsNonAddressableType) {
-    // C++11 [dcl.init.ref]p5: [...] Otherwise, the reference shall be an
-    // lvalue reference to a non-volatile const type, or the reference shall be
-    // an rvalue reference.
-    //
-    // If not, we can't make a temporary and bind to that. Give up and allow the
-    // error to be diagnosed later.
-    if (IsLValueRef && (!T1Quals.hasConst() || T1Quals.hasVolatile())) {
-      assert(Initializer->isGLValue());
-      return Initializer->getValueKind();
-    }
-
-    // Force a load so we can materialize a temporary.
-    Sequence.AddLValueToRValueStep(cv1T1.getUnqualifiedType());
-    return VK_RValue;
-  }
-
-  if (T1Quals != T2Quals) {
-    Sequence.AddQualificationConversionStep(cv1T1,
-                                            Initializer->getValueKind());
-  }
-
-  return Initializer->getValueKind();
+/// Determine whether an expression is a non-referenceable glvalue (one to
+/// which a reference can never bind). Attemting to bind a reference to
+/// such a glvalue will always create a temporary.
+static bool isNonReferenceableGLValue(Expr *E) {
+  return E->refersToBitField() || E->refersToVectorElement();
 }
 
 /// \brief Reference initialization without resolving overloaded functions.
@@ -4293,31 +4303,28 @@
   OverloadingResult ConvOvlResult = OR_Success;
   bool T1Function = T1->isFunctionType();
   if (isLValueRef || T1Function) {
-    if (InitCategory.isLValue() &&
+    if (InitCategory.isLValue() && !isNonReferenceableGLValue(Initializer) &&
         (RefRelationship == Sema::Ref_Compatible ||
          (Kind.isCStyleOrFunctionalCast() &&
           RefRelationship == Sema::Ref_Related))) {
       //   - is an lvalue (but is not a bit-field), and "cv1 T1" is
       //     reference-compatible with "cv2 T2," or
-      //
-      // Per C++ [over.best.ics]p2, we don't diagnose whether the lvalue is a
-      // bit-field when we're determining whether the reference initialization
-      // can occur. However, we do pay attention to whether it is a bit-field
-      // to decide whether we're actually binding to a temporary created from
-      // the bit-field.
+      if (T1Quals != T2Quals)
+        // Convert to cv1 T2. This should only add qualifiers unless this is a
+        // c-style cast. The removal of qualifiers in that case notionally
+        // happens after the reference binding, but that doesn't matter.
+        Sequence.AddQualificationConversionStep(
+            S.Context.getQualifiedType(T2, T1Quals),
+            Initializer->getValueKind());
       if (DerivedToBase)
-        Sequence.AddDerivedToBaseCastStep(
-                         S.Context.getQualifiedType(T1, T2Quals),
-                         VK_LValue);
+        Sequence.AddDerivedToBaseCastStep(cv1T1, VK_LValue);
       else if (ObjCConversion)
-        Sequence.AddObjCObjectConversionStep(
-                                     S.Context.getQualifiedType(T1, T2Quals));
+        Sequence.AddObjCObjectConversionStep(cv1T1);
 
-      ExprValueKind ValueKind =
-        convertQualifiersAndValueKindIfNecessary(S, Sequence, Initializer,
-                                                 cv1T1, T1Quals, T2Quals,
-                                                 isLValueRef);
-      Sequence.AddReferenceBindingStep(cv1T1, ValueKind == VK_RValue);
+      // We only create a temporary here when binding a reference to a
+      // bit-field or vector element. Those cases are't supposed to be
+      // handled by this bullet, but the outcome is the same either way.
+      Sequence.AddReferenceBindingStep(cv1T1, false);
       return;
     }
 
@@ -4332,7 +4339,8 @@
     if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() &&
         (isLValueRef || InitCategory.isRValue())) {
       ConvOvlResult = TryRefInitWithConversionFunction(
-          S, Entity, Kind, Initializer, /*AllowRValues*/isRValueRef, Sequence);
+          S, Entity, Kind, Initializer, /*AllowRValues*/ isRValueRef,
+          /*IsLValueRef*/ isLValueRef, Sequence);
       if (ConvOvlResult == OR_Success)
         return;
       if (ConvOvlResult != OR_No_Viable_Function)
@@ -4352,33 +4360,51 @@
       Sequence.SetOverloadFailure(
                         InitializationSequence::FK_ReferenceInitOverloadFailed,
                                   ConvOvlResult);
-    else
-      Sequence.SetFailed(InitCategory.isLValue()
-        ? (RefRelationship == Sema::Ref_Related
-             ? InitializationSequence::FK_ReferenceInitDropsQualifiers
-             : InitializationSequence::FK_NonConstLValueReferenceBindingToUnrelated)
-        : InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary);
-
+    else if (!InitCategory.isLValue())
+      Sequence.SetFailed(
+          InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary);
+    else {
+      InitializationSequence::FailureKind FK;
+      switch (RefRelationship) {
+      case Sema::Ref_Compatible:
+        if (Initializer->refersToBitField())
+          FK = InitializationSequence::
+              FK_NonConstLValueReferenceBindingToBitfield;
+        else if (Initializer->refersToVectorElement())
+          FK = InitializationSequence::
+              FK_NonConstLValueReferenceBindingToVectorElement;
+        else
+          llvm_unreachable("unexpected kind of compatible initializer");
+        break;
+      case Sema::Ref_Related:
+        FK = InitializationSequence::FK_ReferenceInitDropsQualifiers;
+        break;
+      case Sema::Ref_Incompatible:
+        FK = InitializationSequence::
+            FK_NonConstLValueReferenceBindingToUnrelated;
+        break;
+      }
+      Sequence.SetFailed(FK);
+    }
     return;
   }
 
   //    - If the initializer expression
-  // C++14-and-before:
-  //      - is an xvalue, class prvalue, array prvalue, or function lvalue and
-  //        "cv1 T1" is reference-compatible with "cv2 T2"
-  // C++1z:
-  //      - is an rvalue or function lvalue and "cv1 T1" is reference-compatible
-  //        with "cv2 T2"
-  // Note: functions are handled below.
+  //      - is an
+  // [<=14] xvalue (but not a bit-field), class prvalue, array prvalue, or
+  // [1z]   rvalue (but not a bit-field) or
+  //        function lvalue and "cv1 T1" is reference-compatible with "cv2 T2"
+  //
+  // Note: functions are handled above and below rather than here...
   if (!T1Function &&
       (RefRelationship == Sema::Ref_Compatible ||
        (Kind.isCStyleOrFunctionalCast() &&
         RefRelationship == Sema::Ref_Related)) &&
-      (InitCategory.isXValue() ||
+      ((InitCategory.isXValue() && !isNonReferenceableGLValue(Initializer)) ||
        (InitCategory.isPRValue() &&
         (S.getLangOpts().CPlusPlus1z || T2->isRecordType() ||
          T2->isArrayType())))) {
-    ExprValueKind ValueKind = InitCategory.isXValue()? VK_XValue : VK_RValue;
+    ExprValueKind ValueKind = InitCategory.isXValue() ? VK_XValue : VK_RValue;
     if (InitCategory.isPRValue() && T2->isRecordType()) {
       // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the
       // compiler the freedom to perform a copy here or bind to the
@@ -4395,19 +4421,22 @@
         CheckCXX98CompatAccessibleCopy(S, Entity, Initializer);
     }
 
+    // C++1z [dcl.init.ref]/5.2.1.2:
+    //   If the converted initializer is a prvalue, its type T4 is adjusted
+    //   to type "cv1 T4" and the temporary materialization conversion is
+    //   applied.
+    QualType cv1T4 = S.Context.getQualifiedType(cv2T2, T1Quals);
+    if (T1Quals != T2Quals)
+      Sequence.AddQualificationConversionStep(cv1T4, ValueKind);
+    Sequence.AddReferenceBindingStep(cv1T4, ValueKind == VK_RValue);
+    ValueKind = isLValueRef ? VK_LValue : VK_XValue;
+
+    //   In any case, the reference is bound to the resulting glvalue (or to
+    //   an appropriate base class subobject).
     if (DerivedToBase)
-      Sequence.AddDerivedToBaseCastStep(S.Context.getQualifiedType(T1, T2Quals),
-                                        ValueKind);
+      Sequence.AddDerivedToBaseCastStep(cv1T1, ValueKind);
     else if (ObjCConversion)
-      Sequence.AddObjCObjectConversionStep(
-                                       S.Context.getQualifiedType(T1, T2Quals));
-
-    ValueKind = convertQualifiersAndValueKindIfNecessary(S, Sequence,
-                                                         Initializer, cv1T1,
-                                                         T1Quals, T2Quals,
-                                                         isLValueRef);
-
-    Sequence.AddReferenceBindingStep(cv1T1, ValueKind == VK_RValue);
+      Sequence.AddObjCObjectConversionStep(cv1T1);
     return;
   }
 
@@ -4420,7 +4449,8 @@
   if (T2->isRecordType()) {
     if (RefRelationship == Sema::Ref_Incompatible) {
       ConvOvlResult = TryRefInitWithConversionFunction(
-          S, Entity, Kind, Initializer, /*AllowRValues*/true, Sequence);
+          S, Entity, Kind, Initializer, /*AllowRValues*/ true,
+          /*IsLValueRef*/ isLValueRef, Sequence);
       if (ConvOvlResult)
         Sequence.SetOverloadFailure(
             InitializationSequence::FK_ReferenceInitOverloadFailed,
@@ -4528,23 +4558,21 @@
   if (const RecordType *RT = T->getAs<RecordType>()) {
     if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
       bool NeedZeroInitialization = true;
-      if (!S.getLangOpts().CPlusPlus11) {
-        // C++98:
-        // -- if T is a class type (clause 9) with a user-declared constructor
-        //    (12.1), then the default constructor for T is called (and the
-        //    initialization is ill-formed if T has no accessible default
-        //    constructor);
-        if (ClassDecl->hasUserDeclaredConstructor())
-          NeedZeroInitialization = false;
-      } else {
-        // C++11:
-        // -- if T is a class type (clause 9) with either no default constructor
-        //    (12.1 [class.ctor]) or a default constructor that is user-provided
-        //    or deleted, then the object is default-initialized;
-        CXXConstructorDecl *CD = S.LookupDefaultConstructor(ClassDecl);
-        if (!CD || !CD->getCanonicalDecl()->isDefaulted() || CD->isDeleted())
-          NeedZeroInitialization = false;
-      }
+      // C++98:
+      // -- if T is a class type (clause 9) with a user-declared constructor
+      //    (12.1), then the default constructor for T is called (and the
+      //    initialization is ill-formed if T has no accessible default
+      //    constructor);
+      // C++11:
+      // -- if T is a class type (clause 9) with either no default constructor
+      //    (12.1 [class.ctor]) or a default constructor that is user-provided
+      //    or deleted, then the object is default-initialized;
+      //
+      // Note that the C++11 rule is the same as the C++98 rule if there are no
+      // defaulted or deleted constructors, so we just use it unconditionally.
+      CXXConstructorDecl *CD = S.LookupDefaultConstructor(ClassDecl);
+      if (!CD || !CD->getCanonicalDecl()->isDefaulted() || CD->isDeleted())
+        NeedZeroInitialization = false;
 
       // -- if T is a (possibly cv-qualified) non-union class type without a
       //    user-provided or deleted default constructor, then the object is
@@ -4578,8 +4606,10 @@
       MultiExprArg Args(&InitListAsExpr, InitList ? 1 : 0);
       bool InitListSyntax = InitList;
 
-      return TryConstructorInitialization(S, Entity, Kind, Args, T, Sequence,
-                                          InitListSyntax);
+      // FIXME: Instead of creating a CXXConstructExpr of array type here,
+      // wrap a class-typed CXXConstructExpr in an ArrayInitLoopExpr.
+      return TryConstructorInitialization(
+          S, Entity, Kind, Args, T, Entity.getType(), Sequence, InitListSyntax);
     }
   }
 
@@ -4602,7 +4632,8 @@
   //       constructor for T is called (and the initialization is ill-formed if
   //       T has no accessible default constructor);
   if (DestType->isRecordType() && S.getLangOpts().CPlusPlus) {
-    TryConstructorInitialization(S, Entity, Kind, None, DestType, Sequence);
+    TryConstructorInitialization(S, Entity, Kind, None, DestType,
+                                 Entity.getType(), Sequence);
     return;
   }
 
@@ -4655,15 +4686,7 @@
 
     // Try to complete the type we're converting to.
     if (S.isCompleteType(Kind.getLocation(), DestType)) {
-      DeclContext::lookup_result R = S.LookupConstructors(DestRecordDecl);
-      // The container holding the constructors can under certain conditions
-      // be changed while iterating. To be safe we copy the lookup results
-      // to a new container.
-      SmallVector<NamedDecl*, 8> CopyOfCon(R.begin(), R.end());
-      for (SmallVectorImpl<NamedDecl *>::iterator
-             Con = CopyOfCon.begin(), ConEnd = CopyOfCon.end();
-           Con != ConEnd; ++Con) {
-        NamedDecl *D = *Con;
+      for (NamedDecl *D : S.LookupConstructors(DestRecordDecl)) {
         auto Info = getConstructorInfo(D);
         if (!Info.Constructor)
           continue;
@@ -4746,26 +4769,55 @@
     Sequence.AddUserConversionStep(Function, Best->FoundDecl,
                                    DestType.getUnqualifiedType(),
                                    HadMultipleCandidates);
+
+    // C++14 and before:
+    //   - if the function is a constructor, the call initializes a temporary
+    //     of the cv-unqualified version of the destination type. The [...]
+    //     temporary [...] is then used to direct-initialize, according to the
+    //     rules above, the object that is the destination of the
+    //     copy-initialization.
+    // Note that this just performs a simple object copy from the temporary.
+    //
+    // C++1z:
+    //   - if the function is a constructor, the call is a prvalue of the
+    //     cv-unqualified version of the destination type whose return object
+    //     is initialized by the constructor. The call is used to
+    //     direct-initialize, according to the rules above, the object that
+    //     is the destination of the copy-initialization.
+    // Therefore we need to do nothing further.
+    //
+    // FIXME: Mark this copy as extraneous.
+    if (!S.getLangOpts().CPlusPlus1z)
+      Sequence.AddFinalCopy(DestType);
+    else if (DestType.hasQualifiers())
+      Sequence.AddQualificationConversionStep(DestType, VK_RValue);
     return;
   }
 
   // Add the user-defined conversion step that calls the conversion function.
   QualType ConvType = Function->getCallResultType();
-  if (ConvType->getAs<RecordType>()) {
-    // If we're converting to a class type, there may be an copy of
-    // the resulting temporary object (possible to create an object of
-    // a base class type). That copy is not a separate conversion, so
-    // we just make a note of the actual destination type (possibly a
-    // base class of the type returned by the conversion function) and
-    // let the user-defined conversion step handle the conversion.
-    Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType,
-                                   HadMultipleCandidates);
-    return;
-  }
-
   Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType,
                                  HadMultipleCandidates);
 
+  if (ConvType->getAs<RecordType>()) {
+    //   The call is used to direct-initialize [...] the object that is the
+    //   destination of the copy-initialization.
+    //
+    // In C++1z, this does not call a constructor if we enter /17.6.1:
+    //   - If the initializer expression is a prvalue and the cv-unqualified
+    //     version of the source type is the same as the class of the
+    //     destination [... do not make an extra copy]
+    //
+    // FIXME: Mark this copy as extraneous.
+    if (!S.getLangOpts().CPlusPlus1z ||
+        Function->getReturnType()->isReferenceType() ||
+        !S.Context.hasSameUnqualifiedType(ConvType, DestType))
+      Sequence.AddFinalCopy(DestType);
+    else if (!S.Context.hasSameType(ConvType, DestType))
+      Sequence.AddQualificationConversionStep(DestType, VK_RValue);
+    return;
+  }
+
   // If the conversion following the call to the conversion function
   // is interesting, add it as a separate step.
   if (Best->FinalConversion.First || Best->FinalConversion.Second ||
@@ -4981,6 +5033,20 @@
   return true;
 }
 
+static bool TryOCLZeroQueueInitialization(Sema &S,
+                                          InitializationSequence &Sequence,
+                                          QualType DestType,
+                                          Expr *Initializer) {
+  if (!S.getLangOpts().OpenCL || S.getLangOpts().OpenCLVersion < 200 ||
+      !DestType->isQueueT() ||
+      !Initializer->isIntegerConstantExpr(S.getASTContext()) ||
+      (Initializer->EvaluateKnownConstInt(S.getASTContext()) != 0))
+    return false;
+
+  Sequence.AddOCLZeroQueueStep(DestType);
+  return true;
+}
+
 InitializationSequence::InitializationSequence(Sema &S,
                                                const InitializedEntity &Entity,
                                                const InitializationKind &Kind,
@@ -5003,6 +5069,42 @@
       cast<FunctionDecl>(DRE->getDecl()));
 }
 
+/// Determine whether we can perform an elementwise array copy for this kind
+/// of entity.
+static bool canPerformArrayCopy(const InitializedEntity &Entity) {
+  switch (Entity.getKind()) {
+  case InitializedEntity::EK_LambdaCapture:
+    // C++ [expr.prim.lambda]p24:
+    //   For array members, the array elements are direct-initialized in
+    //   increasing subscript order.
+    return true;
+
+  case InitializedEntity::EK_Variable:
+    // C++ [dcl.decomp]p1:
+    //   [...] each element is copy-initialized or direct-initialized from the
+    //   corresponding element of the assignment-expression [...]
+    return isa<DecompositionDecl>(Entity.getDecl());
+
+  case InitializedEntity::EK_Member:
+    // C++ [class.copy.ctor]p14:
+    //   - if the member is an array, each element is direct-initialized with
+    //     the corresponding subobject of x
+    return Entity.isImplicitMemberInitializer();
+
+  case InitializedEntity::EK_ArrayElement:
+    // All the above cases are intended to apply recursively, even though none
+    // of them actually say that.
+    if (auto *E = Entity.getParent())
+      return canPerformArrayCopy(*E);
+    break;
+
+  default:
+    break;
+  }
+
+  return false;
+}
+
 void InitializationSequence::InitializeFrom(Sema &S,
                                             const InitializedEntity &Entity,
                                             const InitializationKind &Kind,
@@ -5125,6 +5227,34 @@
       }
     }
 
+    // Some kinds of initialization permit an array to be initialized from
+    // another array of the same type, and perform elementwise initialization.
+    if (Initializer && isa<ConstantArrayType>(DestAT) &&
+        S.Context.hasSameUnqualifiedType(Initializer->getType(),
+                                         Entity.getType()) &&
+        canPerformArrayCopy(Entity)) {
+      // If source is a prvalue, use it directly.
+      if (Initializer->getValueKind() == VK_RValue) {
+        AddArrayInitStep(DestType, /*IsGNUExtension*/false);
+        return;
+      }
+
+      // Emit element-at-a-time copy loop.
+      InitializedEntity Element =
+          InitializedEntity::InitializeElement(S.Context, 0, Entity);
+      QualType InitEltT =
+          Context.getAsArrayType(Initializer->getType())->getElementType();
+      OpaqueValueExpr OVE(Initializer->getExprLoc(), InitEltT,
+                          Initializer->getValueKind(),
+                          Initializer->getObjectKind());
+      Expr *OVEAsExpr = &OVE;
+      InitializeFrom(S, Element, Kind, OVEAsExpr, TopLevelOfInitList,
+                     TreatUnavailableAsInvalid);
+      if (!Failed())
+        AddArrayInitLoopStep(Entity.getType(), InitEltT);
+      return;
+    }
+
     // Note: as an GNU C extension, we allow initialization of an
     // array from a compound literal that creates an array of the same
     // type, so long as the initializer has no side effects.
@@ -5138,7 +5268,7 @@
       else if (Initializer->HasSideEffects(S.Context))
         SetFailed(FK_NonConstantArrayInit);
       else {
-        AddArrayInitStep(DestType);
+        AddArrayInitStep(DestType, /*IsGNUExtension*/true);
       }
     }
     // Note: as a GNU C++ extension, we allow list-initialization of a
@@ -5179,6 +5309,9 @@
     if (TryOCLZeroEventInitialization(S, *this, DestType, Initializer))
       return;
 
+    if (TryOCLZeroQueueInitialization(S, *this, DestType, Initializer))
+       return;
+
     // Handle initialization in C
     AddCAssignmentStep(DestType);
     MaybeProduceObjCObject(S, *this, Entity);
@@ -5198,7 +5331,7 @@
          (Context.hasSameUnqualifiedType(SourceType, DestType) ||
           S.IsDerivedFrom(Initializer->getLocStart(), SourceType, DestType))))
       TryConstructorInitialization(S, Entity, Kind, Args,
-                                   DestType, *this);
+                                   DestType, DestType, *this);
     //     - Otherwise (i.e., for the remaining copy-initialization cases),
     //       user-defined conversion sequences that can convert from the source
     //       type to the destination type or (when a conversion function is
@@ -5382,7 +5515,7 @@
 
 /// \brief Whether the given entity, when initialized with an object
 /// created for that initialization, requires destruction.
-static bool shouldDestroyTemporary(const InitializedEntity &Entity) {
+static bool shouldDestroyEntity(const InitializedEntity &Entity) {
   switch (Entity.getKind()) {
     case InitializedEntity::EK_Result:
     case InitializedEntity::EK_New:
@@ -5686,11 +5819,6 @@
       << Entity.getMethodDecl()->getDeclName();
 }
 
-static bool isReferenceBinding(const InitializationSequence::Step &s) {
-  return s.Kind == InitializationSequence::SK_BindReference ||
-         s.Kind == InitializationSequence::SK_BindReferenceToTemporary;
-}
-
 /// Returns true if the parameters describe a constructor initialization of
 /// an explicit temporary object, e.g. "Point(x, y)".
 static bool isExplicitTemporary(const InitializedEntity &Entity,
@@ -5793,7 +5921,8 @@
     S.MarkFunctionReferenced(Loc, Constructor);
 
     CurInit = new (S.Context) CXXTemporaryObjectExpr(
-        S.Context, Constructor, TSInfo,
+        S.Context, Constructor,
+        Entity.getType().getNonLValueExprType(S.Context), TSInfo,
         ConstructorArgs, ParenOrBraceRange, HadMultipleCandidates,
         IsListInitialization, IsStdInitListInitialization,
         ConstructorInitRequiresZeroInit);
@@ -5820,7 +5949,7 @@
     // If the entity allows NRVO, mark the construction as elidable
     // unconditionally.
     if (Entity.allowsNRVO())
-      CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
+      CurInit = S.BuildCXXConstructExpr(Loc, Step.Type,
                                         Step.Function.FoundDecl,
                                         Constructor, /*Elidable=*/true,
                                         ConstructorArgs,
@@ -5831,7 +5960,7 @@
                                         ConstructKind,
                                         ParenOrBraceRange);
     else
-      CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
+      CurInit = S.BuildCXXConstructExpr(Loc, Step.Type,
                                         Step.Function.FoundDecl,
                                         Constructor,
                                         ConstructorArgs,
@@ -6125,7 +6254,7 @@
   if (!InitExpr)
     return;
 
-  if (!S.ActiveTemplateInstantiations.empty())
+  if (S.inTemplateInstantiation())
     return;
 
   QualType DestType = InitExpr->getType();
@@ -6258,6 +6387,8 @@
     return E;
 
   // C++1z [conv.rval]/1: T shall be a complete type.
+  // FIXME: Does this ever matter (can we form a prvalue of incomplete type)?
+  // If so, we should check for a non-abstract class type here too.
   QualType T = E->getType();
   if (RequireCompleteType(E->getExprLoc(), T, diag::err_incomplete_type))
     return ExprError();
@@ -6381,6 +6512,7 @@
                                      Entity.getType();
 
   ExprResult CurInit((Expr *)nullptr);
+  SmallVector<Expr*, 4> ArrayLoopCommonExprs;
 
   // For initialization steps that start with a single initializer,
   // grab the only argument out the Args and place it into the "current"
@@ -6392,6 +6524,7 @@
   case SK_CastDerivedToBaseLValue:
   case SK_BindReference:
   case SK_BindReferenceToTemporary:
+  case SK_FinalCopy:
   case SK_ExtraneousCopyToTemporary:
   case SK_UserConversion:
   case SK_QualificationConversionLValue:
@@ -6407,14 +6540,18 @@
   case SK_CAssignment:
   case SK_StringInit:
   case SK_ObjCObjectConversion:
+  case SK_ArrayLoopIndex:
+  case SK_ArrayLoopInit:
   case SK_ArrayInit:
+  case SK_GNUArrayInit:
   case SK_ParenthesizedArrayInit:
   case SK_PassByIndirectCopyRestore:
   case SK_PassByIndirectRestore:
   case SK_ProduceObjCObject:
   case SK_StdInitializerList:
   case SK_OCLSamplerInit:
-  case SK_OCLZeroEvent: {
+  case SK_OCLZeroEvent:
+  case SK_OCLZeroQueue: {
     assert(Args.size() == 1);
     CurInit = Args[0];
     if (!CurInit.get()) return ExprError();
@@ -6428,6 +6565,24 @@
     break;
   }
 
+  // Promote from an unevaluated context to an unevaluated list context in
+  // C++11 list-initialization; we need to instantiate entities usable in
+  // constant expressions here in order to perform narrowing checks =(
+  EnterExpressionEvaluationContext Evaluated(
+      S, EnterExpressionEvaluationContext::InitList,
+      CurInit.get() && isa<InitListExpr>(CurInit.get()));
+
+  // C++ [class.abstract]p2:
+  //   no objects of an abstract class can be created except as subobjects
+  //   of a class derived from it
+  auto checkAbstractType = [&](QualType T) -> bool {
+    if (Entity.getKind() == InitializedEntity::EK_Base ||
+        Entity.getKind() == InitializedEntity::EK_Delegating)
+      return false;
+    return S.RequireNonAbstractType(Kind.getLocation(), T,
+                                    diag::err_allocation_of_abstract_type);
+  };
+
   // Walk through the computed steps for the initialization sequence,
   // performing the specified conversions along the way.
   bool ConstructorInitRequiresZeroInit = false;
@@ -6479,30 +6634,6 @@
     }
 
     case SK_BindReference:
-      // References cannot bind to bit-fields (C++ [dcl.init.ref]p5).
-      if (CurInit.get()->refersToBitField()) {
-        // We don't necessarily have an unambiguous source bit-field.
-        FieldDecl *BitField = CurInit.get()->getSourceBitField();
-        S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield)
-          << Entity.getType().isVolatileQualified()
-          << (BitField ? BitField->getDeclName() : DeclarationName())
-          << (BitField != nullptr)
-          << CurInit.get()->getSourceRange();
-        if (BitField)
-          S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
-
-        return ExprError();
-      }
-
-      if (CurInit.get()->refersToVectorElement()) {
-        // References cannot bind to vector elements.
-        S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element)
-          << Entity.getType().isVolatileQualified()
-          << CurInit.get()->getSourceRange();
-        PrintInitLocationNote(S, Entity);
-        return ExprError();
-      }
-
       // Reference binding does not have any corresponding ASTs.
 
       // Check exception specifications
@@ -6532,15 +6663,15 @@
 
       // Materialize the temporary into memory.
       MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
-          Entity.getType().getNonReferenceType(), CurInit.get(),
-          Entity.getType()->isLValueReferenceType());
+          Step->Type, CurInit.get(), Entity.getType()->isLValueReferenceType());
 
       // Maybe lifetime-extend the temporary's subobjects to match the
       // entity's lifetime.
       if (const InitializedEntity *ExtendingEntity =
               getEntityForTemporaryLifetimeExtension(&Entity))
         if (performReferenceExtension(MTE, ExtendingEntity))
-          warnOnLifetimeExtension(S, Entity, CurInit.get(), /*IsInitializerList=*/false,
+          warnOnLifetimeExtension(S, Entity, CurInit.get(),
+                                  /*IsInitializerList=*/false,
                                   ExtendingEntity->getDecl());
 
       // If we're binding to an Objective-C object that has lifetime, we
@@ -6557,6 +6688,21 @@
       break;
     }
 
+    case SK_FinalCopy:
+      if (checkAbstractType(Step->Type))
+        return ExprError();
+
+      // If the overall initialization is initializing a temporary, we already
+      // bound our argument if it was necessary to do so. If not (if we're
+      // ultimately initializing a non-temporary), our argument needs to be
+      // bound since it's initializing a function parameter.
+      // FIXME: This is a mess. Rationalize temporary destruction.
+      if (!shouldBindAsTemporary(Entity))
+        CurInit = S.MaybeBindToTemporary(CurInit.get());
+      CurInit = CopyObject(S, Step->Type, Entity, CurInit,
+                           /*IsExtraneousCopy=*/false);
+      break;
+
     case SK_ExtraneousCopyToTemporary:
       CurInit = CopyObject(S, Step->Type, Entity, CurInit,
                            /*IsExtraneousCopy=*/true);
@@ -6566,7 +6712,6 @@
       // We have a user-defined conversion that invokes either a constructor
       // or a conversion function.
       CastKind CastKind;
-      bool IsCopy = false;
       FunctionDecl *Fn = Step->Function.Function;
       DeclAccessPair FoundFn = Step->Function.FoundDecl;
       bool HadMultipleCandidates = Step->Function.HadMultipleCandidates;
@@ -6575,7 +6720,6 @@
         // Build a call to the selected constructor.
         SmallVector<Expr*, 8> ConstructorArgs;
         SourceLocation Loc = CurInit.get()->getLocStart();
-        CurInit.get(); // Ownership transferred into MultiExprArg, below.
 
         // Determine the arguments required to actually perform the constructor
         // call.
@@ -6604,11 +6748,6 @@
           return ExprError();
 
         CastKind = CK_ConstructorConversion;
-        QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
-        if (S.Context.hasSameUnqualifiedType(SourceType, Class) ||
-            S.IsDerivedFrom(Loc, SourceType, Class))
-          IsCopy = true;
-
         CreatedObject = true;
       } else {
         // Build a call to the conversion function.
@@ -6621,48 +6760,38 @@
         // FIXME: Should we move this initialization into a separate
         // 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.get(),
-                                                /*Qualifier=*/nullptr,
-                                                FoundFn, Conversion);
-        if(CurInitExprRes.isInvalid())
+        CurInit = S.PerformObjectArgumentInitialization(CurInit.get(),
+                                                        /*Qualifier=*/nullptr,
+                                                        FoundFn, Conversion);
+        if (CurInit.isInvalid())
           return ExprError();
-        CurInit = CurInitExprRes;
 
         // Build the actual call to the conversion function.
         CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion,
                                            HadMultipleCandidates);
-        if (CurInit.isInvalid() || !CurInit.get())
+        if (CurInit.isInvalid())
           return ExprError();
 
         CastKind = CK_UserDefinedConversion;
-
         CreatedObject = Conversion->getReturnType()->isRecordType();
       }
 
-      // C++14 and before:
-      //   - if the function is a constructor, the call initializes a temporary
-      //     of the cv-unqualified version of the destination type [...]
-      // C++1z:
-      //   - if the function is a constructor, the call is a prvalue of the
-      //     cv-unqualified version of the destination type whose return object
-      //     is initialized by the constructor [...]
-      // Both:
-      //     The [..] call is used to direct-initialize, according to the rules
-      //     above, the object that is the destination of the
-      //     copy-initialization.
-      // In C++14 and before, that always means the "constructors are
-      // considered" bullet, because we have arrived at a reference-related
-      // type. In C++1z, it only means that if the types are different or we
-      // didn't produce a prvalue, so just check for that case here.
-      bool RequiresCopy = !IsCopy && !isReferenceBinding(Steps.back());
-      if (S.getLangOpts().CPlusPlus1z && CurInit.get()->isRValue() &&
-          S.Context.hasSameUnqualifiedType(
-              Entity.getType().getNonReferenceType(), CurInit.get()->getType()))
-        RequiresCopy = false;
-      bool MaybeBindToTemp = RequiresCopy || shouldBindAsTemporary(Entity);
+      if (CreatedObject && checkAbstractType(CurInit.get()->getType()))
+        return ExprError();
 
-      if (!MaybeBindToTemp && CreatedObject && shouldDestroyTemporary(Entity)) {
+      CurInit = ImplicitCastExpr::Create(S.Context, CurInit.get()->getType(),
+                                         CastKind, CurInit.get(), nullptr,
+                                         CurInit.get()->getValueKind());
+
+      if (shouldBindAsTemporary(Entity))
+        // The overall entity is temporary, so this expression should be
+        // destroyed at the end of its full-expression.
+        CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
+      else if (CreatedObject && shouldDestroyEntity(Entity)) {
+        // The object outlasts the full-expression, but we need to prepare for
+        // a destructor being run on it.
+        // FIXME: It makes no sense to do this here. This should happen
+        // regardless of how we initialized the entity.
         QualType T = CurInit.get()->getType();
         if (const RecordType *Record = T->getAs<RecordType>()) {
           CXXDestructorDecl *Destructor
@@ -6674,15 +6803,6 @@
             return ExprError();
         }
       }
-
-      CurInit = ImplicitCastExpr::Create(S.Context, CurInit.get()->getType(),
-                                         CastKind, CurInit.get(), nullptr,
-                                         CurInit.get()->getValueKind());
-      if (MaybeBindToTemp)
-        CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
-      if (RequiresCopy)
-        CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
-                             CurInit, /*IsExtraneousCopy=*/false);
       break;
     }
 
@@ -6733,7 +6853,7 @@
       CurInit = CurInitExprRes;
 
       if (Step->Kind == SK_ConversionSequenceNoNarrowing &&
-          S.getLangOpts().CPlusPlus && !CurInit.get()->isValueDependent())
+          S.getLangOpts().CPlusPlus)
         DiagnoseNarrowingInInitList(S, *Step->ICS, SourceType, Entity.getType(),
                                     CurInit.get());
 
@@ -6741,6 +6861,9 @@
     }
 
     case SK_ListInitialization: {
+      if (checkAbstractType(Step->Type))
+        return ExprError();
+
       InitListExpr *InitList = cast<InitListExpr>(CurInit.get());
       // If we're not initializing the top-level entity, we need to create an
       // InitializeTemporary entity for our target type.
@@ -6777,6 +6900,9 @@
     }
 
     case SK_ConstructorInitializationFromList: {
+      if (checkAbstractType(Step->Type))
+        return ExprError();
+
       // When an initializer list is passed for a parameter of type "reference
       // to object", we don't get an EK_Temporary entity, but instead an
       // EK_Parameter entity with reference type.
@@ -6820,6 +6946,9 @@
 
     case SK_ConstructorInitialization:
     case SK_StdInitializerListConstructorCall: {
+      if (checkAbstractType(Step->Type))
+        return ExprError();
+
       // When an initializer list is passed for a parameter of type "reference
       // to object", we don't get an EK_Temporary entity, but instead an
       // EK_Parameter entity with reference type.
@@ -6831,13 +6960,15 @@
       bool UseTemporary = Entity.getType()->isReferenceType();
       bool IsStdInitListInit =
           Step->Kind == SK_StdInitializerListConstructorCall;
+      Expr *Source = CurInit.get();
       CurInit = PerformConstructorInitialization(
-          S, UseTemporary ? TempEntity : Entity, Kind, Args, *Step,
+          S, UseTemporary ? TempEntity : Entity, Kind,
+          Source ? MultiExprArg(Source) : Args, *Step,
           ConstructorInitRequiresZeroInit,
-          /*IsListInitialization*/IsStdInitListInit,
-          /*IsStdInitListInitialization*/IsStdInitListInit,
-          /*LBraceLoc*/SourceLocation(),
-          /*RBraceLoc*/SourceLocation());
+          /*IsListInitialization*/ IsStdInitListInit,
+          /*IsStdInitListInitialization*/ IsStdInitListInit,
+          /*LBraceLoc*/ SourceLocation(),
+          /*RBraceLoc*/ SourceLocation());
       break;
     }
 
@@ -6859,7 +6990,7 @@
                                                     Kind.getRange().getBegin());
 
         CurInit = new (S.Context) CXXScalarValueInitExpr(
-            TSInfo->getType().getNonLValueExprType(S.Context), TSInfo,
+            Entity.getType().getNonLValueExprType(S.Context), TSInfo,
             Kind.getRange().getEnd());
       } else {
         CurInit = new (S.Context) ImplicitValueInitExpr(Step->Type);
@@ -6916,13 +7047,36 @@
                           CurInit.get()->getValueKind());
       break;
 
-    case SK_ArrayInit:
+    case SK_ArrayLoopIndex: {
+      Expr *Cur = CurInit.get();
+      Expr *BaseExpr = new (S.Context)
+          OpaqueValueExpr(Cur->getExprLoc(), Cur->getType(),
+                          Cur->getValueKind(), Cur->getObjectKind(), Cur);
+      Expr *IndexExpr =
+          new (S.Context) ArrayInitIndexExpr(S.Context.getSizeType());
+      CurInit = S.CreateBuiltinArraySubscriptExpr(
+          BaseExpr, Kind.getLocation(), IndexExpr, Kind.getLocation());
+      ArrayLoopCommonExprs.push_back(BaseExpr);
+      break;
+    }
+
+    case SK_ArrayLoopInit: {
+      assert(!ArrayLoopCommonExprs.empty() &&
+             "mismatched SK_ArrayLoopIndex and SK_ArrayLoopInit");
+      Expr *Common = ArrayLoopCommonExprs.pop_back_val();
+      CurInit = new (S.Context) ArrayInitLoopExpr(Step->Type, Common,
+                                                  CurInit.get());
+      break;
+    }
+
+    case SK_GNUArrayInit:
       // Okay: we checked everything before creating this step. Note that
       // this is a GNU extension.
       S.Diag(Kind.getLocation(), diag::ext_array_init_copy)
         << Step->Type << CurInit.get()->getType()
         << CurInit.get()->getSourceRange();
-
+      LLVM_FALLTHROUGH;
+    case SK_ArrayInit:
       // If the destination type is an incomplete array type, update the
       // type accordingly.
       if (ResultType) {
@@ -7088,6 +7242,15 @@
                                     CurInit.get()->getValueKind());
       break;
     }
+    case SK_OCLZeroQueue: {
+      assert(Step->Type->isQueueT() &&
+             "Event initialization on non queue type.");
+
+      CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
+                                    CK_ZeroToOCLQueue,
+                                    CurInit.get()->getValueKind());
+      break;
+    }
     }
   }
 
@@ -7350,6 +7513,25 @@
       << Args[0]->getSourceRange();
     break;
 
+  case FK_NonConstLValueReferenceBindingToBitfield: {
+    // We don't necessarily have an unambiguous source bit-field.
+    FieldDecl *BitField = Args[0]->getSourceBitField();
+    S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield)
+      << DestType.isVolatileQualified()
+      << (BitField ? BitField->getDeclName() : DeclarationName())
+      << (BitField != nullptr)
+      << Args[0]->getSourceRange();
+    if (BitField)
+      S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
+    break;
+  }
+
+  case FK_NonConstLValueReferenceBindingToVectorElement:
+    S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element)
+      << DestType.isVolatileQualified()
+      << Args[0]->getSourceRange();
+    break;
+
   case FK_RValueReferenceBindingToLValue:
     S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref)
       << DestType.getNonReferenceType() << Args[0]->getType()
@@ -7581,7 +7763,8 @@
     (void)Ovl;
     assert(Ovl == OR_Success && "Inconsistent overload resolution");
     CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
-    S.Diag(CtorDecl->getLocation(), diag::note_constructor_declared_here);
+    S.Diag(CtorDecl->getLocation(),
+           diag::note_explicit_ctor_deduction_guide_here) << false;
     break;
   }
   }
@@ -7647,6 +7830,14 @@
       OS << "non-const lvalue reference bound to temporary";
       break;
 
+    case FK_NonConstLValueReferenceBindingToBitfield:
+      OS << "non-const lvalue reference bound to bit-field";
+      break;
+
+    case FK_NonConstLValueReferenceBindingToVectorElement:
+      OS << "non-const lvalue reference bound to vector element";
+      break;
+
     case FK_NonConstLValueReferenceBindingToUnrelated:
       OS << "non-const lvalue reference bound to unrelated type";
       break;
@@ -7743,15 +7934,15 @@
       break;
 
     case SK_CastDerivedToBaseRValue:
-      OS << "derived-to-base case (rvalue" << S->Type.getAsString() << ")";
+      OS << "derived-to-base (rvalue)";
       break;
 
     case SK_CastDerivedToBaseXValue:
-      OS << "derived-to-base case (xvalue" << S->Type.getAsString() << ")";
+      OS << "derived-to-base (xvalue)";
       break;
 
     case SK_CastDerivedToBaseLValue:
-      OS << "derived-to-base case (lvalue" << S->Type.getAsString() << ")";
+      OS << "derived-to-base (lvalue)";
       break;
 
     case SK_BindReference:
@@ -7762,6 +7953,10 @@
       OS << "bind reference to a temporary";
       break;
 
+    case SK_FinalCopy:
+      OS << "final copy in class direct-initialization";
+      break;
+
     case SK_ExtraneousCopyToTemporary:
       OS << "extraneous C++03 copy to temporary";
       break;
@@ -7838,10 +8033,22 @@
       OS << "Objective-C object conversion";
       break;
 
+    case SK_ArrayLoopIndex:
+      OS << "indexing for array initialization loop";
+      break;
+
+    case SK_ArrayLoopInit:
+      OS << "array initialization loop";
+      break;
+
     case SK_ArrayInit:
       OS << "array initialization";
       break;
 
+    case SK_GNUArrayInit:
+      OS << "array initialization (GNU extension)";
+      break;
+
     case SK_ParenthesizedArrayInit:
       OS << "parenthesized array initialization";
       break;
@@ -7873,6 +8080,10 @@
     case SK_OCLZeroEvent:
       OS << "OpenCL event_t from zero";
       break;
+
+    case SK_OCLZeroQueue:
+      OS << "OpenCL queue_t from zero";
+      break;
     }
 
     OS << " [" << S->Type.getAsString() << ']';
@@ -7910,6 +8121,7 @@
   switch (SCS->getNarrowingKind(S.Context, PostInit, ConstantValue,
                                 ConstantType)) {
   case NK_Not_Narrowing:
+  case NK_Dependent_Narrowing:
     // No narrowing occurred.
     return;
 
@@ -8016,3 +8228,219 @@
 
   return Result;
 }
+
+QualType Sema::DeduceTemplateSpecializationFromInitializer(
+    TypeSourceInfo *TSInfo, const InitializedEntity &Entity,
+    const InitializationKind &Kind, MultiExprArg Inits) {
+  auto *DeducedTST = dyn_cast<DeducedTemplateSpecializationType>(
+      TSInfo->getType()->getContainedDeducedType());
+  assert(DeducedTST && "not a deduced template specialization type");
+
+  // We can only perform deduction for class templates.
+  auto TemplateName = DeducedTST->getTemplateName();
+  auto *Template =
+      dyn_cast_or_null<ClassTemplateDecl>(TemplateName.getAsTemplateDecl());
+  if (!Template) {
+    Diag(Kind.getLocation(),
+         diag::err_deduced_non_class_template_specialization_type)
+      << (int)getTemplateNameKindForDiagnostics(TemplateName) << TemplateName;
+    if (auto *TD = TemplateName.getAsTemplateDecl())
+      Diag(TD->getLocation(), diag::note_template_decl_here);
+    return QualType();
+  }
+
+  // Can't deduce from dependent arguments.
+  if (Expr::hasAnyTypeDependentArguments(Inits))
+    return Context.DependentTy;
+
+  // FIXME: Perform "exact type" matching first, per CWG discussion?
+  //        Or implement this via an implied 'T(T) -> T' deduction guide?
+
+  // FIXME: Do we need/want a std::initializer_list<T> special case?
+
+  // Look up deduction guides, including those synthesized from constructors.
+  //
+  // C++1z [over.match.class.deduct]p1:
+  //   A set of functions and function templates is formed comprising:
+  //   - For each constructor of the class template designated by the
+  //     template-name, a function template [...]
+  //  - For each deduction-guide, a function or function template [...]
+  DeclarationNameInfo NameInfo(
+      Context.DeclarationNames.getCXXDeductionGuideName(Template),
+      TSInfo->getTypeLoc().getEndLoc());
+  LookupResult Guides(*this, NameInfo, LookupOrdinaryName);
+  LookupQualifiedName(Guides, Template->getDeclContext());
+
+  // FIXME: Do not diagnose inaccessible deduction guides. The standard isn't
+  // clear on this, but they're not found by name so access does not apply.
+  Guides.suppressDiagnostics();
+
+  // Figure out if this is list-initialization.
+  InitListExpr *ListInit =
+      (Inits.size() == 1 && Kind.getKind() != InitializationKind::IK_Direct)
+          ? dyn_cast<InitListExpr>(Inits[0])
+          : nullptr;
+
+  // C++1z [over.match.class.deduct]p1:
+  //   Initialization and overload resolution are performed as described in
+  //   [dcl.init] and [over.match.ctor], [over.match.copy], or [over.match.list]
+  //   (as appropriate for the type of initialization performed) for an object
+  //   of a hypothetical class type, where the selected functions and function
+  //   templates are considered to be the constructors of that class type
+  //
+  // Since we know we're initializing a class type of a type unrelated to that
+  // of the initializer, this reduces to something fairly reasonable.
+  OverloadCandidateSet Candidates(Kind.getLocation(),
+                                  OverloadCandidateSet::CSK_Normal);
+  OverloadCandidateSet::iterator Best;
+  auto tryToResolveOverload =
+      [&](bool OnlyListConstructors) -> OverloadingResult {
+    Candidates.clear();
+    for (auto I = Guides.begin(), E = Guides.end(); I != E; ++I) {
+      NamedDecl *D = (*I)->getUnderlyingDecl();
+      if (D->isInvalidDecl())
+        continue;
+
+      auto *TD = dyn_cast<FunctionTemplateDecl>(D);
+      auto *GD = dyn_cast_or_null<CXXDeductionGuideDecl>(
+          TD ? TD->getTemplatedDecl() : dyn_cast<FunctionDecl>(D));
+      if (!GD)
+        continue;
+
+      // C++ [over.match.ctor]p1: (non-list copy-initialization from non-class)
+      //   For copy-initialization, the candidate functions are all the
+      //   converting constructors (12.3.1) of that class.
+      // C++ [over.match.copy]p1: (non-list copy-initialization from class)
+      //   The converting constructors of T are candidate functions.
+      if (Kind.isCopyInit() && !ListInit) {
+        // Only consider converting constructors.
+        if (GD->isExplicit())
+          continue;
+
+        // When looking for a converting constructor, deduction guides that
+        // could never be called with one argument are not interesting to
+        // check or note.
+        if (GD->getMinRequiredArguments() > 1 ||
+            (GD->getNumParams() == 0 && !GD->isVariadic()))
+          continue;
+      }
+
+      // C++ [over.match.list]p1.1: (first phase list initialization)
+      //   Initially, the candidate functions are the initializer-list
+      //   constructors of the class T
+      if (OnlyListConstructors && !isInitListConstructor(GD))
+        continue;
+
+      // C++ [over.match.list]p1.2: (second phase list initialization)
+      //   the candidate functions are all the constructors of the class T
+      // C++ [over.match.ctor]p1: (all other cases)
+      //   the candidate functions are all the constructors of the class of
+      //   the object being initialized
+
+      // C++ [over.best.ics]p4:
+      //   When [...] the constructor [...] is a candidate by
+      //    - [over.match.copy] (in all cases)
+      // FIXME: The "second phase of [over.match.list] case can also
+      // theoretically happen here, but it's not clear whether we can
+      // ever have a parameter of the right type.
+      bool SuppressUserConversions = Kind.isCopyInit();
+
+      if (TD)
+        AddTemplateOverloadCandidate(TD, I.getPair(), /*ExplicitArgs*/ nullptr,
+                                     Inits, Candidates,
+                                     SuppressUserConversions);
+      else
+        AddOverloadCandidate(GD, I.getPair(), Inits, Candidates,
+                             SuppressUserConversions);
+    }
+    return Candidates.BestViableFunction(*this, Kind.getLocation(), Best);
+  };
+
+  OverloadingResult Result = OR_No_Viable_Function;
+
+  // C++11 [over.match.list]p1, per DR1467: for list-initialization, first
+  // try initializer-list constructors.
+  if (ListInit) {
+    bool TryListConstructors = true;
+
+    // Try list constructors unless the list is empty and the class has one or
+    // more default constructors, in which case those constructors win.
+    if (!ListInit->getNumInits()) {
+      for (NamedDecl *D : Guides) {
+        auto *FD = dyn_cast<FunctionDecl>(D->getUnderlyingDecl());
+        if (FD && FD->getMinRequiredArguments() == 0) {
+          TryListConstructors = false;
+          break;
+        }
+      }
+    }
+
+    if (TryListConstructors)
+      Result = tryToResolveOverload(/*OnlyListConstructor*/true);
+    // Then unwrap the initializer list and try again considering all
+    // constructors.
+    Inits = MultiExprArg(ListInit->getInits(), ListInit->getNumInits());
+  }
+
+  // If list-initialization fails, or if we're doing any other kind of
+  // initialization, we (eventually) consider constructors.
+  if (Result == OR_No_Viable_Function)
+    Result = tryToResolveOverload(/*OnlyListConstructor*/false);
+
+  switch (Result) {
+  case OR_Ambiguous:
+    Diag(Kind.getLocation(), diag::err_deduced_class_template_ctor_ambiguous)
+      << TemplateName;
+    // FIXME: For list-initialization candidates, it'd usually be better to
+    // list why they were not viable when given the initializer list itself as
+    // an argument.
+    Candidates.NoteCandidates(*this, OCD_ViableCandidates, Inits);
+    return QualType();
+
+  case OR_No_Viable_Function: {
+    CXXRecordDecl *Primary =
+        cast<ClassTemplateDecl>(Template)->getTemplatedDecl();
+    bool Complete =
+        isCompleteType(Kind.getLocation(), Context.getTypeDeclType(Primary));
+    Diag(Kind.getLocation(),
+         Complete ? diag::err_deduced_class_template_ctor_no_viable
+                  : diag::err_deduced_class_template_incomplete)
+      << TemplateName << !Guides.empty();
+    Candidates.NoteCandidates(*this, OCD_AllCandidates, Inits);
+    return QualType();
+  }
+
+  case OR_Deleted: {
+    Diag(Kind.getLocation(), diag::err_deduced_class_template_deleted)
+      << TemplateName;
+    NoteDeletedFunction(Best->Function);
+    return QualType();
+  }
+
+  case OR_Success:
+    // C++ [over.match.list]p1:
+    //   In copy-list-initialization, if an explicit constructor is chosen, the
+    //   initialization is ill-formed.
+    if (Kind.isCopyInit() && ListInit &&
+        cast<CXXDeductionGuideDecl>(Best->Function)->isExplicit()) {
+      bool IsDeductionGuide = !Best->Function->isImplicit();
+      Diag(Kind.getLocation(), diag::err_deduced_class_template_explicit)
+          << TemplateName << IsDeductionGuide;
+      Diag(Best->Function->getLocation(),
+           diag::note_explicit_ctor_deduction_guide_here)
+          << IsDeductionGuide;
+      return QualType();
+    }
+
+    // Make sure we didn't select an unusable deduction guide, and mark it
+    // as referenced.
+    DiagnoseUseOfDecl(Best->Function, Kind.getLocation());
+    MarkFunctionReferenced(Kind.getLocation(), Best->Function);
+    break;
+  }
+
+  // C++ [dcl.type.class.deduct]p1:
+  //  The placeholder is replaced by the return type of the function selected
+  //  by overload resolution for class template deduction.
+  return SubstAutoType(TSInfo->getType(), Best->Function->getReturnType());
+}
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 0715650..fc823f4 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -312,7 +312,7 @@
   //   In the following contexts [...] the one-definition rule requires closure
   //   types in different translation units to "correspond":
   bool IsInNonspecializedTemplate =
-    !ActiveTemplateInstantiations.empty() || CurContext->isDependentContext();
+      inTemplateInstantiation() || CurContext->isDependentContext();
   switch (Kind) {
   case Normal: {
     //  -- the bodies of non-exported nonspecialized template functions
@@ -1274,7 +1274,7 @@
                                 ConvTy, 
                                 ConvTSI,
                                 /*isInline=*/true, /*isExplicit=*/false,
-                                /*isConstexpr=*/false, 
+                                /*isConstexpr=*/S.getLangOpts().CPlusPlus1z, 
                                 CallOperator->getBody()->getLocEnd());
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);
@@ -1384,10 +1384,7 @@
 }
 
 static ExprResult performLambdaVarCaptureInitialization(
-    Sema &S, LambdaScopeInfo::Capture &Capture,
-    FieldDecl *Field,
-    SmallVectorImpl<VarDecl *> &ArrayIndexVars,
-    SmallVectorImpl<unsigned> &ArrayIndexStarts) {
+    Sema &S, const LambdaScopeInfo::Capture &Capture, FieldDecl *Field) {
   assert(Capture.isVariableCapture() && "not a variable capture");
 
   auto *Var = Capture.getVariable();
@@ -1411,69 +1408,11 @@
     return ExprError();
   Expr *Ref = RefResult.get();
 
-  QualType FieldType = Field->getType();
-
-  // When the variable has array type, create index variables for each
-  // dimension of the array. We use these index variables to subscript
-  // the source array, and other clients (e.g., CodeGen) will perform
-  // the necessary iteration with these index variables.
-  //
-  // FIXME: This is dumb. Add a proper AST representation for array
-  // copy-construction and use it here.
-  SmallVector<VarDecl *, 4> IndexVariables;
-  QualType BaseType = FieldType;
-  QualType SizeType = S.Context.getSizeType();
-  ArrayIndexStarts.push_back(ArrayIndexVars.size());
-  while (const ConstantArrayType *Array
-                        = S.Context.getAsConstantArrayType(BaseType)) {
-    // Create the iteration variable for this array index.
-    IdentifierInfo *IterationVarName = nullptr;
-    {
-      SmallString<8> Str;
-      llvm::raw_svector_ostream OS(Str);
-      OS << "__i" << IndexVariables.size();
-      IterationVarName = &S.Context.Idents.get(OS.str());
-    }
-    VarDecl *IterationVar = VarDecl::Create(
-        S.Context, S.CurContext, Loc, Loc, IterationVarName, SizeType,
-        S.Context.getTrivialTypeSourceInfo(SizeType, Loc), SC_None);
-    IterationVar->setImplicit();
-    IndexVariables.push_back(IterationVar);
-    ArrayIndexVars.push_back(IterationVar);
-    
-    // Create a reference to the iteration variable.
-    ExprResult IterationVarRef =
-        S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
-    assert(!IterationVarRef.isInvalid() &&
-           "Reference to invented variable cannot fail!");
-    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.get(), Loc);
-    if (Subscript.isInvalid())
-      return ExprError();
-
-    Ref = Subscript.get();
-    BaseType = Array->getElementType();
-  }
-
-  // Construct the entity that we will be initializing. For an array, this
-  // will be first element in the array, which may require several levels
-  // of array-subscript entities. 
-  SmallVector<InitializedEntity, 4> Entities;
-  Entities.reserve(1 + IndexVariables.size());
-  Entities.push_back(InitializedEntity::InitializeLambdaCapture(
-      Var->getIdentifier(), FieldType, Loc));
-  for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I)
-    Entities.push_back(
-        InitializedEntity::InitializeElement(S.Context, 0, Entities.back()));
-
+  auto Entity = InitializedEntity::InitializeLambdaCapture(
+      Var->getIdentifier(), Field->getType(), Loc);
   InitializationKind InitKind = InitializationKind::CreateDirect(Loc, Loc, Loc);
-  InitializationSequence Init(S, Entities.back(), InitKind, Ref);
-  return Init.Perform(S, Entities.back(), InitKind, Ref);
+  InitializationSequence Init(S, Entity, InitKind, Ref);
+  return Init.Perform(S, Entity, InitKind, Ref);
 }
          
 ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, 
@@ -1499,6 +1438,43 @@
   llvm_unreachable("Unknown implicit capture style");
 }
 
+bool Sema::CaptureHasSideEffects(const LambdaScopeInfo::Capture &From) {
+  if (!From.isVLATypeCapture()) {
+    Expr *Init = From.getInitExpr();
+    if (Init && Init->HasSideEffects(Context))
+      return true;
+  }
+
+  if (!From.isCopyCapture())
+    return false;
+
+  const QualType T = From.isThisCapture()
+                         ? getCurrentThisType()->getPointeeType()
+                         : From.getCaptureType();
+
+  if (T.isVolatileQualified())
+    return true;
+
+  const Type *BaseT = T->getBaseElementTypeUnsafe();
+  if (const CXXRecordDecl *RD = BaseT->getAsCXXRecordDecl())
+    return !RD->isCompleteDefinition() || !RD->hasTrivialCopyConstructor() ||
+           !RD->hasTrivialDestructor();
+
+  return false;
+}
+
+void Sema::DiagnoseUnusedLambdaCapture(const LambdaScopeInfo::Capture &From) {
+  if (CaptureHasSideEffects(From))
+    return;
+
+  auto diag = Diag(From.getLocation(), diag::warn_unused_lambda_capture);
+  if (From.isThisCapture())
+    diag << "'this'";
+  else
+    diag << From.getVariable();
+  diag << From.isNonODRUsed();
+}
+
 ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
                                  LambdaScopeInfo *LSI) {
   // Collect information from the lambda scope.
@@ -1514,8 +1490,6 @@
   bool ExplicitResultType;
   CleanupInfo LambdaCleanup;
   bool ContainsUnexpandedParameterPack;
-  SmallVector<VarDecl *, 4> ArrayIndexVars;
-  SmallVector<unsigned, 4> ArrayIndexStarts;
   {
     CallOperator = LSI->CallOperator;
     Class = LSI->Lambda;
@@ -1539,24 +1513,26 @@
     // Translate captures.
     auto CurField = Class->field_begin();
     for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I, ++CurField) {
-      LambdaScopeInfo::Capture From = LSI->Captures[I];
+      const LambdaScopeInfo::Capture &From = LSI->Captures[I];
       assert(!From.isBlockCapture() && "Cannot capture __block variables");
       bool IsImplicit = I >= LSI->NumExplicitCaptures;
 
+      // Warn about unused explicit captures.
+      if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed())
+        DiagnoseUnusedLambdaCapture(From);
+
       // Handle 'this' capture.
       if (From.isThisCapture()) {
         Captures.push_back(
             LambdaCapture(From.getLocation(), IsImplicit,
                           From.isCopyCapture() ? LCK_StarThis : LCK_This));
         CaptureInits.push_back(From.getInitExpr());
-        ArrayIndexStarts.push_back(ArrayIndexVars.size());
         continue;
       }
       if (From.isVLATypeCapture()) {
         Captures.push_back(
             LambdaCapture(From.getLocation(), IsImplicit, LCK_VLAType));
         CaptureInits.push_back(nullptr);
-        ArrayIndexStarts.push_back(ArrayIndexVars.size());
         continue;
       }
 
@@ -1566,13 +1542,11 @@
                                        Var, From.getEllipsisLoc()));
       Expr *Init = From.getInitExpr();
       if (!Init) {
-        auto InitResult = performLambdaVarCaptureInitialization(
-            *this, From, *CurField, ArrayIndexVars, ArrayIndexStarts);
+        auto InitResult =
+            performLambdaVarCaptureInitialization(*this, From, *CurField);
         if (InitResult.isInvalid())
           return ExprError();
         Init = InitResult.get();
-      } else {
-        ArrayIndexStarts.push_back(ArrayIndexVars.size());
       }
       CaptureInits.push_back(Init);
     }
@@ -1609,8 +1583,7 @@
                                           CaptureDefault, CaptureDefaultLoc,
                                           Captures, 
                                           ExplicitParams, ExplicitResultType,
-                                          CaptureInits, ArrayIndexVars, 
-                                          ArrayIndexStarts, EndLoc,
+                                          CaptureInits, EndLoc,
                                           ContainsUnexpandedParameterPack);
   // If the lambda expression's call operator is not explicitly marked constexpr
   // and we are not in a dependent context, analyze the call operator to infer
@@ -1633,6 +1606,7 @@
     //   A lambda-expression shall not appear in an unevaluated operand
     //   (Clause 5).
     case Unevaluated:
+    case UnevaluatedList:
     case UnevaluatedAbstract:
     // C++1y [expr.const]p2:
     //   A conditional-expression e is a core constant expression unless the
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 1fc6d4f..e393f90 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -450,15 +450,18 @@
   //   Given a set of declarations in a single declarative region [...]
   //   exactly one declaration shall declare a class name or enumeration name
   //   that is not a typedef name and the other declarations shall all refer to
-  //   the same variable or enumerator, or all refer to functions and function
-  //   templates; in this case the class name or enumeration name is hidden.
+  //   the same variable, non-static data member, or enumerator, or all refer
+  //   to functions and function templates; in this case the class name or
+  //   enumeration name is hidden.
   // C++ [basic.scope.hiding]p2:
   //   A class name or enumeration name can be hidden by the name of a
   //   variable, data member, function, or enumerator declared in the same
   //   scope.
+  // An UnresolvedUsingValueDecl always instantiates to one of these.
   D = D->getUnderlyingDecl();
   return isa<VarDecl>(D) || isa<EnumConstantDecl>(D) || isa<FunctionDecl>(D) ||
-         isa<FunctionTemplateDecl>(D) || isa<FieldDecl>(D);
+         isa<FunctionTemplateDecl>(D) || isa<FieldDecl>(D) ||
+         isa<UnresolvedUsingValueDecl>(D);
 }
 
 /// Resolves the result kind of this lookup.
@@ -771,6 +774,7 @@
 /// that need to be declared in the given declaration context, do so.
 static void DeclareImplicitMemberFunctionsWithName(Sema &S,
                                                    DeclarationName Name,
+                                                   SourceLocation Loc,
                                                    const DeclContext *DC) {
   if (!DC)
     return;
@@ -813,6 +817,10 @@
     }
     break;
 
+  case DeclarationName::CXXDeductionGuideName:
+    S.DeclareImplicitDeductionGuides(Name.getCXXDeductionGuideTemplate(), Loc);
+    break;
+
   default:
     break;
   }
@@ -825,7 +833,8 @@
 
   // Lazily declare C++ special member functions.
   if (S.getLangOpts().CPlusPlus)
-    DeclareImplicitMemberFunctionsWithName(S, R.getLookupName(), DC);
+    DeclareImplicitMemberFunctionsWithName(S, R.getLookupName(), R.getNameLoc(),
+                                           DC);
 
   // Perform lookup into this declaration context.
   DeclContext::lookup_result DR = DC->lookup(R.getLookupName());
@@ -1038,7 +1047,7 @@
   if (isImplicitlyDeclaredMemberFunctionName(Name)) {
     for (Scope *PreS = S; PreS; PreS = PreS->getParent())
       if (DeclContext *DC = PreS->getEntity())
-        DeclareImplicitMemberFunctionsWithName(*this, Name, DC);
+        DeclareImplicitMemberFunctionsWithName(*this, Name, R.getNameLoc(), DC);
   }
 
   // Implicitly declare member functions with the name we're looking for, if in
@@ -1423,14 +1432,13 @@
 }
 
 llvm::DenseSet<Module*> &Sema::getLookupModules() {
-  unsigned N = ActiveTemplateInstantiations.size();
-  for (unsigned I = ActiveTemplateInstantiationLookupModules.size();
+  unsigned N = CodeSynthesisContexts.size();
+  for (unsigned I = CodeSynthesisContextLookupModules.size();
        I != N; ++I) {
-    Module *M =
-        getDefiningModule(*this, ActiveTemplateInstantiations[I].Entity);
+    Module *M = getDefiningModule(*this, CodeSynthesisContexts[I].Entity);
     if (M && !LookupModulesCache.insert(M).second)
       M = nullptr;
-    ActiveTemplateInstantiationLookupModules.push_back(M);
+    CodeSynthesisContextLookupModules.push_back(M);
   }
   return LookupModulesCache;
 }
@@ -1551,7 +1559,7 @@
          || (isa<FunctionDecl>(DC) && !SemaRef.getLangOpts().CPlusPlus))
             ? isVisible(SemaRef, cast<NamedDecl>(DC))
             : SemaRef.hasVisibleDefinition(cast<NamedDecl>(DC))) {
-      if (SemaRef.ActiveTemplateInstantiations.empty() &&
+      if (SemaRef.CodeSynthesisContexts.empty() &&
           // FIXME: Do something better in this case.
           !SemaRef.getLangOpts().ModulesLocalVisibility) {
         // Cache the fact that this declaration is implicitly visible because
@@ -2691,6 +2699,7 @@
 
     // Non-deduced auto types only get here for error cases.
     case Type::Auto:
+    case Type::DeducedTemplateSpecialization:
       break;
 
     // If T is an Objective-C object or interface type, or a pointer to an 
@@ -2811,13 +2820,13 @@
   Functions.append(Operators.begin(), Operators.end());
 }
 
-Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
-                                                            CXXSpecialMember SM,
-                                                            bool ConstArg,
-                                                            bool VolatileArg,
-                                                            bool RValueThis,
-                                                            bool ConstThis,
-                                                            bool VolatileThis) {
+Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
+                                                           CXXSpecialMember SM,
+                                                           bool ConstArg,
+                                                           bool VolatileArg,
+                                                           bool RValueThis,
+                                                           bool ConstThis,
+                                                           bool VolatileThis) {
   assert(CanDeclareSpecialMemberFunction(RD) &&
          "doing special member lookup into record that isn't fully complete");
   RD = RD->getDefinition();
@@ -2828,6 +2837,9 @@
     assert((SM != CXXDefaultConstructor && SM != CXXDestructor) &&
            "parameter-less special members can't have qualified arguments");
 
+  // FIXME: Get the caller to pass in a location for the lookup.
+  SourceLocation LookupLoc = RD->getLocation();
+
   llvm::FoldingSetNodeID ID;
   ID.AddPointer(RD);
   ID.AddInteger(SM);
@@ -2838,15 +2850,15 @@
   ID.AddInteger(VolatileThis);
 
   void *InsertPoint;
-  SpecialMemberOverloadResult *Result =
+  SpecialMemberOverloadResultEntry *Result =
     SpecialMemberCache.FindNodeOrInsertPos(ID, InsertPoint);
 
   // This was already cached
   if (Result)
-    return Result;
+    return *Result;
 
-  Result = BumpAlloc.Allocate<SpecialMemberOverloadResult>();
-  Result = new (Result) SpecialMemberOverloadResult(ID);
+  Result = BumpAlloc.Allocate<SpecialMemberOverloadResultEntry>();
+  Result = new (Result) SpecialMemberOverloadResultEntry(ID);
   SpecialMemberCache.InsertNode(Result, InsertPoint);
 
   if (SM == CXXDestructor) {
@@ -2858,7 +2870,7 @@
     Result->setKind(DD->isDeleted() ?
                     SpecialMemberOverloadResult::NoMemberOrDeleted :
                     SpecialMemberOverloadResult::Success);
-    return Result;
+    return *Result;
   }
 
   // Prepare for overload resolution. Here we construct a synthetic argument
@@ -2909,7 +2921,7 @@
       VK = VK_RValue;
   }
 
-  OpaqueValueExpr FakeArg(SourceLocation(), ArgType, VK);
+  OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK);
 
   if (SM != CXXDefaultConstructor) {
     NumArgs = 1;
@@ -2923,13 +2935,13 @@
   if (VolatileThis)
     ThisTy.addVolatile();
   Expr::Classification Classification =
-    OpaqueValueExpr(SourceLocation(), ThisTy,
+    OpaqueValueExpr(LookupLoc, ThisTy,
                     RValueThis ? VK_RValue : VK_LValue).Classify(Context);
 
   // Now we perform lookup on the name we computed earlier and do overload
   // resolution. Lookup is only performed directly into the class since there
   // will always be a (possibly implicit) declaration to shadow any others.
-  OverloadCandidateSet OCS(RD->getLocation(), OverloadCandidateSet::CSK_Normal);
+  OverloadCandidateSet OCS(LookupLoc, OverloadCandidateSet::CSK_Normal);
   DeclContext::lookup_result R = RD->lookup(Name);
 
   if (R.empty()) {
@@ -2941,7 +2953,7 @@
            "lookup for a constructor or assignment operator was empty");
     Result->setMethod(nullptr);
     Result->setKind(SpecialMemberOverloadResult::NoMemberOrDeleted);
-    return Result;
+    return *Result;
   }
 
   // Copy the candidates as our processing of them may load new declarations
@@ -2984,7 +2996,7 @@
   }
 
   OverloadCandidateSet::iterator Best;
-  switch (OCS.BestViableFunction(*this, SourceLocation(), Best)) {
+  switch (OCS.BestViableFunction(*this, LookupLoc, Best)) {
     case OR_Success:
       Result->setMethod(cast<CXXMethodDecl>(Best->Function));
       Result->setKind(SpecialMemberOverloadResult::Success);
@@ -3006,16 +3018,16 @@
       break;
   }
 
-  return Result;
+  return *Result;
 }
 
 /// \brief Look up the default constructor for the given class.
 CXXConstructorDecl *Sema::LookupDefaultConstructor(CXXRecordDecl *Class) {
-  SpecialMemberOverloadResult *Result =
+  SpecialMemberOverloadResult Result =
     LookupSpecialMember(Class, CXXDefaultConstructor, false, false, false,
                         false, false);
 
-  return cast_or_null<CXXConstructorDecl>(Result->getMethod());
+  return cast_or_null<CXXConstructorDecl>(Result.getMethod());
 }
 
 /// \brief Look up the copying constructor for the given class.
@@ -3023,21 +3035,21 @@
                                                    unsigned Quals) {
   assert(!(Quals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
          "non-const, non-volatile qualifiers for copy ctor arg");
-  SpecialMemberOverloadResult *Result =
+  SpecialMemberOverloadResult Result =
     LookupSpecialMember(Class, CXXCopyConstructor, Quals & Qualifiers::Const,
                         Quals & Qualifiers::Volatile, false, false, false);
 
-  return cast_or_null<CXXConstructorDecl>(Result->getMethod());
+  return cast_or_null<CXXConstructorDecl>(Result.getMethod());
 }
 
 /// \brief Look up the moving constructor for the given class.
 CXXConstructorDecl *Sema::LookupMovingConstructor(CXXRecordDecl *Class,
                                                   unsigned Quals) {
-  SpecialMemberOverloadResult *Result =
+  SpecialMemberOverloadResult Result =
     LookupSpecialMember(Class, CXXMoveConstructor, Quals & Qualifiers::Const,
                         Quals & Qualifiers::Volatile, false, false, false);
 
-  return cast_or_null<CXXConstructorDecl>(Result->getMethod());
+  return cast_or_null<CXXConstructorDecl>(Result.getMethod());
 }
 
 /// \brief Look up the constructors for the given class.
@@ -3065,13 +3077,13 @@
          "non-const, non-volatile qualifiers for copy assignment arg");
   assert(!(ThisQuals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
          "non-const, non-volatile qualifiers for copy assignment this");
-  SpecialMemberOverloadResult *Result =
+  SpecialMemberOverloadResult Result =
     LookupSpecialMember(Class, CXXCopyAssignment, Quals & Qualifiers::Const,
                         Quals & Qualifiers::Volatile, RValueThis,
                         ThisQuals & Qualifiers::Const,
                         ThisQuals & Qualifiers::Volatile);
 
-  return Result->getMethod();
+  return Result.getMethod();
 }
 
 /// \brief Look up the moving assignment operator for the given class.
@@ -3081,13 +3093,13 @@
                                             unsigned ThisQuals) {
   assert(!(ThisQuals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
          "non-const, non-volatile qualifiers for copy assignment this");
-  SpecialMemberOverloadResult *Result =
+  SpecialMemberOverloadResult Result =
     LookupSpecialMember(Class, CXXMoveAssignment, Quals & Qualifiers::Const,
                         Quals & Qualifiers::Volatile, RValueThis,
                         ThisQuals & Qualifiers::Const,
                         ThisQuals & Qualifiers::Volatile);
 
-  return Result->getMethod();
+  return Result.getMethod();
 }
 
 /// \brief Look for the destructor of the given class.
@@ -3099,7 +3111,7 @@
 CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) {
   return cast<CXXDestructorDecl>(LookupSpecialMember(Class, CXXDestructor,
                                                      false, false, false,
-                                                     false, false)->getMethod());
+                                                     false, false).getMethod());
 }
 
 /// LookupLiteralOperator - Determine which literal operator should be used for
@@ -3424,6 +3436,12 @@
           SM == ShadowMaps.rbegin())
         continue;
 
+      // A shadow declaration that's created by a resolved using declaration
+      // is not hidden by the same using declaration.
+      if (isa<UsingShadowDecl>(ND) && isa<UsingDecl>(D) &&
+          cast<UsingShadowDecl>(ND)->getUsingDecl() == D)
+        continue;
+
       // We've found a declaration that hides this one.
       return D;
     }
@@ -4492,9 +4510,8 @@
   if (SS && SS->isInvalid())
     return nullptr;
 
-  // Never try to correct typos during template deduction or
-  // instantiation.
-  if (!ActiveTemplateInstantiations.empty())
+  // Never try to correct typos during any kind of code synthesis.
+  if (!CodeSynthesisContexts.empty())
     return nullptr;
 
   // Don't try to correct 'super'.
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 9ab80b4..3481b82 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -1146,9 +1146,11 @@
                                  diag::err_abstract_type_in_decl,
                                  AbstractSynthesizedIvarType)) {
         Diag(property->getLocation(), diag::note_property_declare);
+        // An abstract type is as bad as an incomplete type.
+        CompleteTypeErr = true;
+      }
+      if (CompleteTypeErr)
         Ivar->setInvalidDecl();
-      } else if (CompleteTypeErr)
-          Ivar->setInvalidDecl();
       ClassImpDecl->addDecl(Ivar);
       IDecl->makeDeclVisibleInContext(Ivar);
 
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index f4f0ba6..7d47997 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -326,8 +326,8 @@
   Scope *getCurScope() { return Stack.back().CurScope; }
   SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
 
-  // Do the check specified in \a Check to all component lists and return true
-  // if any issue is found.
+  /// Do the check specified in \a Check to all component lists and return true
+  /// if any issue is found.
   bool checkMappableExprComponentListsForDecl(
       ValueDecl *VD, bool CurrentRegionOnly,
       const llvm::function_ref<
@@ -355,8 +355,8 @@
     return false;
   }
 
-  // Create a new mappable expression component list associated with a given
-  // declaration and initialize it with the provided list of components.
+  /// Create a new mappable expression component list associated with a given
+  /// declaration and initialize it with the provided list of components.
   void addMappableExpressionComponents(
       ValueDecl *VD,
       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
@@ -919,7 +919,7 @@
             OpenMPClauseKind WhereFoundClauseKind) {
           // Only the map clause information influences how a variable is
           // captured. E.g. is_device_ptr does not require changing the default
-          // behaviour.
+          // behavior.
           if (WhereFoundClauseKind != OMPC_map)
             return false;
 
@@ -1089,7 +1089,7 @@
             auto *VDPrivate = buildVarDecl(
                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
-            ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
+            ActOnUninitializedDecl(VDPrivate);
             if (VDPrivate->isInvalidDecl())
               continue;
             PrivateCopies.push_back(buildDeclRefExpr(
@@ -1607,6 +1607,28 @@
                              Params);
     break;
   }
+  case OMPD_target_teams:
+  case OMPD_target_parallel: {
+    Sema::CapturedParamNameType ParamsTarget[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    // Start a captured region for 'target' with no implicit parameters.
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             ParamsTarget);
+    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
+    QualType KmpInt32PtrTy =
+        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
+    Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
+        std::make_pair(".global_tid.", KmpInt32PtrTy),
+        std::make_pair(".bound_tid.", KmpInt32PtrTy),
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    // Start a captured region for 'teams' or 'parallel'.  Both regions have
+    // the same implicit parameters.
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             ParamsTeamsOrParallel);
+    break;
+  }
   case OMPD_simd:
   case OMPD_for:
   case OMPD_for_simd:
@@ -1621,7 +1643,6 @@
   case OMPD_atomic:
   case OMPD_target_data:
   case OMPD_target:
-  case OMPD_target_parallel:
   case OMPD_target_parallel_for:
   case OMPD_target_parallel_for_simd:
   case OMPD_target_simd: {
@@ -1697,7 +1718,11 @@
   case OMPD_teams_distribute:
   case OMPD_teams_distribute_simd:
   case OMPD_teams_distribute_parallel_for_simd:
-  case OMPD_teams_distribute_parallel_for: {
+  case OMPD_teams_distribute_parallel_for:
+  case OMPD_target_teams_distribute:
+  case OMPD_target_teams_distribute_parallel_for:
+  case OMPD_target_teams_distribute_parallel_for_simd:
+  case OMPD_target_teams_distribute_simd: {
     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
     QualType KmpInt32PtrTy =
         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
@@ -1732,6 +1757,12 @@
   }
 }
 
+int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
+  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
+  getOpenMPCaptureRegions(CaptureRegions, DKind);
+  return CaptureRegions.size();
+}
+
 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
                                              Expr *CaptureExpr, bool WithInit,
                                              bool AsExpression) {
@@ -1752,12 +1783,12 @@
     }
     WithInit = true;
   }
-  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty);
+  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
+                                          CaptureExpr->getLocStart());
   if (!WithInit)
     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
   S.CurContext->addHiddenDecl(CED);
-  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false,
-                         /*TypeMayContainAuto=*/true);
+  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
   return CED;
 }
 
@@ -1791,16 +1822,49 @@
   return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get());
 }
 
+namespace {
+// OpenMP directives parsed in this section are represented as a
+// CapturedStatement with an associated statement.  If a syntax error
+// is detected during the parsing of the associated statement, the
+// compiler must abort processing and close the CapturedStatement.
+//
+// Combined directives such as 'target parallel' have more than one
+// nested CapturedStatements.  This RAII ensures that we unwind out
+// of all the nested CapturedStatements when an error is found.
+class CaptureRegionUnwinderRAII {
+private:
+  Sema &S;
+  bool &ErrorFound;
+  OpenMPDirectiveKind DKind;
+
+public:
+  CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
+                            OpenMPDirectiveKind DKind)
+      : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
+  ~CaptureRegionUnwinderRAII() {
+    if (ErrorFound) {
+      int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
+      while (--ThisCaptureLevel >= 0)
+        S.ActOnCapturedRegionError();
+    }
+  }
+};
+} // namespace
+
 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
                                       ArrayRef<OMPClause *> Clauses) {
+  bool ErrorFound = false;
+  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
+      *this, ErrorFound, DSAStack->getCurrentDirective());
   if (!S.isUsable()) {
-    ActOnCapturedRegionError();
+    ErrorFound = true;
     return StmtError();
   }
 
   OMPOrderedClause *OC = nullptr;
   OMPScheduleClause *SC = nullptr;
   SmallVector<OMPLinearClause *, 4> LCs;
+  SmallVector<OMPClauseWithPreInit *, 8> PICs;
   // This is required for proper codegen.
   for (auto *Clause : Clauses) {
     if (isOpenMPPrivate(Clause->getClauseKind()) ||
@@ -1817,15 +1881,8 @@
       }
       DSAStack->setForceVarCapturing(/*V=*/false);
     } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) {
-      // Mark all variables in private list clauses as used in inner region.
-      // Required for proper codegen of combined directives.
-      // TODO: add processing for other clauses.
-      if (auto *C = OMPClauseWithPreInit::get(Clause)) {
-        if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
-          for (auto *D : DS->decls())
-            MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
-        }
-      }
+      if (auto *C = OMPClauseWithPreInit::get(Clause))
+        PICs.push_back(C);
       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
         if (auto *E = C->getPostUpdateExpr())
           MarkDeclarationsReferencedInExpr(E);
@@ -1838,7 +1895,6 @@
     else if (Clause->getClauseKind() == OMPC_linear)
       LCs.push_back(cast<OMPLinearClause>(Clause));
   }
-  bool ErrorFound = false;
   // OpenMP, 2.7.1 Loop Construct, Restrictions
   // The nonmonotonic modifier cannot be specified if an ordered clause is
   // specified.
@@ -1869,13 +1925,54 @@
     ErrorFound = true;
   }
   if (ErrorFound) {
-    ActOnCapturedRegionError();
     return StmtError();
   }
-  return ActOnCapturedRegionEnd(S.get());
+  StmtResult SR = S;
+  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
+  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
+  for (auto ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
+    // Mark all variables in private list clauses as used in inner region.
+    // Required for proper codegen of combined directives.
+    // TODO: add processing for other clauses.
+    if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) {
+      for (auto *C : PICs) {
+        OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
+        // Find the particular capture region for the clause if the
+        // directive is a combined one with multiple capture regions.
+        // If the directive is not a combined one, the capture region
+        // associated with the clause is OMPD_unknown and is generated
+        // only once.
+        if (CaptureRegion == ThisCaptureRegion ||
+            CaptureRegion == OMPD_unknown) {
+          if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
+            for (auto *D : DS->decls())
+              MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
+          }
+        }
+      }
+    }
+    SR = ActOnCapturedRegionEnd(SR.get());
+  }
+  return SR;
 }
 
-static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
+static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
+                              OpenMPDirectiveKind CancelRegion,
+                              SourceLocation StartLoc) {
+  // CancelRegion is only needed for cancel and cancellation_point.
+  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
+    return false;
+
+  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
+      CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
+    return false;
+
+  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
+      << getOpenMPDirectiveName(CancelRegion);
+  return true;
+}
+
+static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
                                   OpenMPDirectiveKind CurrentRegion,
                                   const DeclarationNameInfo &CurrentName,
                                   OpenMPDirectiveKind CancelRegion,
@@ -1930,7 +2027,8 @@
     // Allow some constructs (except teams) to be orphaned (they could be
     // used in functions, called from OpenMP regions with the required
     // preconditions).
-    if (ParentRegion == OMPD_unknown && !isOpenMPTeamsDirective(CurrentRegion))
+    if (ParentRegion == OMPD_unknown &&
+        !isOpenMPNestingTeamsDirective(CurrentRegion))
       return false;
     if (CurrentRegion == OMPD_cancellation_point ||
         CurrentRegion == OMPD_cancel) {
@@ -2023,7 +2121,7 @@
                           !(isOpenMPSimdDirective(ParentRegion) ||
                             Stack->isParentOrderedRegion());
       Recommend = ShouldBeInOrderedRegion;
-    } else if (isOpenMPTeamsDirective(CurrentRegion)) {
+    } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
       // OpenMP [2.16, Nesting of Regions]
       // If specified, a teams construct must be contained within a target
       // construct.
@@ -2032,7 +2130,10 @@
       Recommend = ShouldBeInTargetRegion;
       Stack->setParentTeamsRegionLoc(Stack->getConstructLoc());
     }
-    if (!NestingProhibited && ParentRegion == OMPD_teams) {
+    if (!NestingProhibited &&
+        !isOpenMPTargetExecutionDirective(CurrentRegion) &&
+        !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
+        (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
       // OpenMP [2.16, Nesting of Regions]
       // distribute, parallel, parallel sections, parallel workshare, and the
       // parallel loop and parallel loop SIMD constructs are the only OpenMP
@@ -2046,7 +2147,8 @@
       // OpenMP 4.5 [2.17 Nesting of Regions]
       // The region associated with the distribute construct must be strictly
       // nested inside a teams region
-      NestingProhibited = ParentRegion != OMPD_teams;
+      NestingProhibited =
+          (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
       Recommend = ShouldBeInTeamsRegion;
     }
     if (!NestingProhibited &&
@@ -2170,7 +2272,9 @@
     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
   StmtResult Res = StmtError();
-  if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
+  // First check CancelRegion which is then used in checkNestingOfRegions.
+  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
+      checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
                             StartLoc))
     return StmtError();
 
@@ -2183,7 +2287,11 @@
 
     // Check default data sharing attributes for referenced variables.
     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
-    DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
+    int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
+    Stmt *S = AStmt;
+    while (--ThisCaptureLevel >= 0)
+      S = cast<CapturedStmt>(S)->getCapturedStmt();
+    DSAChecker.Visit(S);
     if (DSAChecker.isErrorFound())
       return StmtError();
     // Generate list of implicitly defined firstprivate variables.
@@ -2414,6 +2522,33 @@
         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
     AllowedNameModifiers.push_back(OMPD_parallel);
     break;
+  case OMPD_target_teams:
+    Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
+                                          EndLoc);
+    AllowedNameModifiers.push_back(OMPD_target);
+    break;
+  case OMPD_target_teams_distribute:
+    Res = ActOnOpenMPTargetTeamsDistributeDirective(
+        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
+    AllowedNameModifiers.push_back(OMPD_target);
+    break;
+  case OMPD_target_teams_distribute_parallel_for:
+    Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
+        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
+    AllowedNameModifiers.push_back(OMPD_target);
+    AllowedNameModifiers.push_back(OMPD_parallel);
+    break;
+  case OMPD_target_teams_distribute_parallel_for_simd:
+    Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
+        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
+    AllowedNameModifiers.push_back(OMPD_target);
+    AllowedNameModifiers.push_back(OMPD_parallel);
+    break;
+  case OMPD_target_teams_distribute_simd:
+    Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
+        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
+    AllowedNameModifiers.push_back(OMPD_target);
+    break;
   case OMPD_declare_target:
   case OMPD_end_declare_target:
   case OMPD_threadprivate:
@@ -3359,7 +3494,7 @@
   return nullptr;
 }
 
-/// \brief Build instillation of the counter be used for codegen.
+/// \brief Build initialization of the counter to be used for codegen.
 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; }
 
 /// \brief Build step of the counter be used for codegen.
@@ -3851,14 +3986,16 @@
   Scope *CurScope = DSA.getCurScope();
   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
     if (PreCond.isUsable()) {
-      PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd,
-                                   PreCond.get(), IterSpaces[Cnt].PreCond);
+      PreCond =
+          SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
+                             PreCond.get(), IterSpaces[Cnt].PreCond);
     }
     auto N = IterSpaces[Cnt].NumIterations;
+    SourceLocation Loc = N->getExprLoc();
     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
     if (LastIteration32.isUsable())
       LastIteration32 = SemaRef.BuildBinOp(
-          CurScope, SourceLocation(), BO_Mul, LastIteration32.get(),
+          CurScope, Loc, BO_Mul, LastIteration32.get(),
           SemaRef
               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
                                          Sema::AA_Converting,
@@ -3866,7 +4003,7 @@
               .get());
     if (LastIteration64.isUsable())
       LastIteration64 = SemaRef.BuildBinOp(
-          CurScope, SourceLocation(), BO_Mul, LastIteration64.get(),
+          CurScope, Loc, BO_Mul, LastIteration64.get(),
           SemaRef
               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
                                          Sema::AA_Converting,
@@ -3901,7 +4038,8 @@
   ExprResult NumIterations = LastIteration;
   {
     LastIteration = SemaRef.BuildBinOp(
-        CurScope, SourceLocation(), BO_Sub, LastIteration.get(),
+        CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
+        LastIteration.get(),
         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
     if (!LastIteration.isUsable())
       return 0;
@@ -3920,7 +4058,7 @@
 
     // Prepare SaveRef + 1.
     NumIterations = SemaRef.BuildBinOp(
-        CurScope, SourceLocation(), BO_Add, SaveRef.get(),
+        CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
     if (!NumIterations.isUsable())
       return 0;
@@ -3935,33 +4073,32 @@
     // Lower bound variable, initialized with zero.
     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
-    SemaRef.AddInitializerToDecl(
-        LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
-        /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
+    SemaRef.AddInitializerToDecl(LBDecl,
+                                 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
+                                 /*DirectInit*/ false);
 
     // Upper bound variable, initialized with last iteration number.
     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
-                                 /*DirectInit*/ false,
-                                 /*TypeMayContainAuto*/ false);
+                                 /*DirectInit*/ false);
 
     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
     // This will be used to implement clause 'lastprivate'.
     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
-    SemaRef.AddInitializerToDecl(
-        ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
-        /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
+    SemaRef.AddInitializerToDecl(ILDecl,
+                                 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
+                                 /*DirectInit*/ false);
 
     // Stride variable returned by runtime (we initialize it to 1 by default).
     VarDecl *STDecl =
         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
-    SemaRef.AddInitializerToDecl(
-        STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
-        /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
+    SemaRef.AddInitializerToDecl(STDecl,
+                                 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
+                                 /*DirectInit*/ false);
 
     // Build expression: UB = min(UB, LastIteration)
     // It is necessary for CodeGen of directives with static scheduling.
@@ -4062,6 +4199,36 @@
       return 0;
   }
 
+  // Create: increment expression for distribute loop when combined in a same
+  // directive with for as IV = IV + ST; ensure upper bound expression based
+  // on PrevUB instead of NumIterations - used to implement 'for' when found
+  // in combination with 'distribute', like in 'distribute parallel for'
+  SourceLocation DistIncLoc;
+  ExprResult DistCond, DistInc, PrevEUB;
+  if (isOpenMPLoopBoundSharingDirective(DKind)) {
+    DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
+    assert(DistCond.isUsable() && "distribute cond expr was not built");
+
+    DistInc =
+        SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
+    assert(DistInc.isUsable() && "distribute inc expr was not built");
+    DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
+                                 DistInc.get());
+    DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
+    assert(DistInc.isUsable() && "distribute inc expr was not built");
+
+    // Build expression: UB = min(UB, prevUB) for #for in composite or combined
+    // construct
+    SourceLocation DistEUBLoc;
+    ExprResult IsUBGreater =
+        SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
+    ExprResult CondOp = SemaRef.ActOnConditionalOp(
+        DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
+    PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
+                                 CondOp.get());
+    PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
+  }
+
   // Build updates and final values of the loop counters.
   bool HasErrors = false;
   Built.Counters.resize(NestedLoopCount);
@@ -4176,6 +4343,8 @@
   Built.NUB = NextUB.get();
   Built.PrevLB = PrevLB.get();
   Built.PrevUB = PrevUB.get();
+  Built.DistInc = DistInc.get();
+  Built.PrevEUB = PrevEUB.get();
 
   Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
   // Fill data for doacross depend clauses.
@@ -5709,12 +5878,6 @@
 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
                                             SourceLocation EndLoc,
                                             OpenMPDirectiveKind CancelRegion) {
-  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
-      CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
-    Diag(StartLoc, diag::err_omp_wrong_cancel_region)
-        << getOpenMPDirectiveName(CancelRegion);
-    return StmtError();
-  }
   if (DSAStack->isParentNowaitRegion()) {
     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
     return StmtError();
@@ -5731,12 +5894,6 @@
                                             SourceLocation StartLoc,
                                             SourceLocation EndLoc,
                                             OpenMPDirectiveKind CancelRegion) {
-  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
-      CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
-    Diag(StartLoc, diag::err_omp_wrong_cancel_region)
-        << getOpenMPDirectiveName(CancelRegion);
-    return StmtError();
-  }
   if (DSAStack->isParentNowaitRegion()) {
     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
     return StmtError();
@@ -6124,11 +6281,10 @@
   OMPLoopDirective::HelperExprs B;
   // In presence of clause 'collapse' with number of loops, it will
   // define the nested loops number.
-  unsigned NestedLoopCount =
-      CheckOpenMPLoop(OMPD_teams_distribute_simd,
-                      getCollapseNumberExpr(Clauses),
-                      nullptr /*ordered not a clause on distribute*/, AStmt,
-                      *this, *DSAStack, VarsWithImplicitDSA, B);
+  unsigned NestedLoopCount = CheckOpenMPLoop(
+      OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
+      nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
+      VarsWithImplicitDSA, B);
 
   if (NestedLoopCount == 0)
     return StmtError();
@@ -6248,6 +6404,185 @@
       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
 }
 
+StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
+                                                 Stmt *AStmt,
+                                                 SourceLocation StartLoc,
+                                                 SourceLocation EndLoc) {
+  if (!AStmt)
+    return StmtError();
+
+  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();
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
+                                         AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
+  if (!AStmt)
+    return StmtError();
+
+  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();
+
+  OMPLoopDirective::HelperExprs B;
+  // In presence of clause 'collapse' with number of loops, it will
+  // define the nested loops number.
+  auto NestedLoopCount = CheckOpenMPLoop(
+      OMPD_target_teams_distribute,
+      getCollapseNumberExpr(Clauses),
+      nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
+      VarsWithImplicitDSA, B);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  assert((CurContext->isDependentContext() || B.builtAll()) &&
+         "omp target teams distribute loop exprs were not built");
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPTargetTeamsDistributeDirective::Create(
+      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
+}
+
+StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
+  if (!AStmt)
+    return StmtError();
+
+  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();
+
+  OMPLoopDirective::HelperExprs B;
+  // In presence of clause 'collapse' with number of loops, it will
+  // define the nested loops number.
+  auto NestedLoopCount = CheckOpenMPLoop(
+      OMPD_target_teams_distribute_parallel_for,
+      getCollapseNumberExpr(Clauses),
+      nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
+      VarsWithImplicitDSA, B);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  assert((CurContext->isDependentContext() || B.builtAll()) &&
+         "omp target teams distribute parallel for loop exprs were not built");
+
+  if (!CurContext->isDependentContext()) {
+    // Finalize the clauses that need pre-built expressions for CodeGen.
+    for (auto C : Clauses) {
+      if (auto *LC = dyn_cast<OMPLinearClause>(C))
+        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
+          return StmtError();
+    }
+  }
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPTargetTeamsDistributeParallelForDirective::Create(
+      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
+}
+
+StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
+  if (!AStmt)
+    return StmtError();
+
+  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();
+
+  OMPLoopDirective::HelperExprs B;
+  // In presence of clause 'collapse' with number of loops, it will
+  // define the nested loops number.
+  auto NestedLoopCount = CheckOpenMPLoop(
+      OMPD_target_teams_distribute_parallel_for_simd,
+      getCollapseNumberExpr(Clauses),
+      nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
+      VarsWithImplicitDSA, B);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  assert((CurContext->isDependentContext() || B.builtAll()) &&
+         "omp target teams distribute parallel for simd loop exprs were not "
+         "built");
+
+  if (!CurContext->isDependentContext()) {
+    // Finalize the clauses that need pre-built expressions for CodeGen.
+    for (auto C : Clauses) {
+      if (auto *LC = dyn_cast<OMPLinearClause>(C))
+        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
+          return StmtError();
+    }
+  }
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
+      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
+}
+
+StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
+  if (!AStmt)
+    return StmtError();
+
+  auto *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();
+
+  OMPLoopDirective::HelperExprs B;
+  // In presence of clause 'collapse' with number of loops, it will
+  // define the nested loops number.
+  auto NestedLoopCount = CheckOpenMPLoop(
+      OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
+      nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
+      VarsWithImplicitDSA, B);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  assert((CurContext->isDependentContext() || B.builtAll()) &&
+         "omp target teams distribute simd loop exprs were not built");
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPTargetTeamsDistributeSimdDirective::Create(
+      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
+}
+
 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
                                              SourceLocation StartLoc,
                                              SourceLocation LParenLoc,
@@ -6334,6 +6669,322 @@
   return Res;
 }
 
+// An OpenMP directive such as 'target parallel' has two captured regions:
+// for the 'target' and 'parallel' respectively.  This function returns
+// the region in which to capture expressions associated with a clause.
+// A return value of OMPD_unknown signifies that the expression should not
+// be captured.
+static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
+    OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
+    OpenMPDirectiveKind NameModifier = OMPD_unknown) {
+  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
+
+  switch (CKind) {
+  case OMPC_if:
+    switch (DKind) {
+    case OMPD_target_parallel:
+      // If this clause applies to the nested 'parallel' region, capture within
+      // the 'target' region, otherwise do not capture.
+      if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
+        CaptureRegion = OMPD_target;
+      break;
+    case OMPD_cancel:
+    case OMPD_parallel:
+    case OMPD_parallel_sections:
+    case OMPD_parallel_for:
+    case OMPD_parallel_for_simd:
+    case OMPD_target:
+    case OMPD_target_simd:
+    case OMPD_target_parallel_for:
+    case OMPD_target_parallel_for_simd:
+    case OMPD_target_teams:
+    case OMPD_target_teams_distribute:
+    case OMPD_target_teams_distribute_simd:
+    case OMPD_target_teams_distribute_parallel_for:
+    case OMPD_target_teams_distribute_parallel_for_simd:
+    case OMPD_teams_distribute_parallel_for:
+    case OMPD_teams_distribute_parallel_for_simd:
+    case OMPD_distribute_parallel_for:
+    case OMPD_distribute_parallel_for_simd:
+    case OMPD_task:
+    case OMPD_taskloop:
+    case OMPD_taskloop_simd:
+    case OMPD_target_data:
+    case OMPD_target_enter_data:
+    case OMPD_target_exit_data:
+    case OMPD_target_update:
+      // Do not capture if-clause expressions.
+      break;
+    case OMPD_threadprivate:
+    case OMPD_taskyield:
+    case OMPD_barrier:
+    case OMPD_taskwait:
+    case OMPD_cancellation_point:
+    case OMPD_flush:
+    case OMPD_declare_reduction:
+    case OMPD_declare_simd:
+    case OMPD_declare_target:
+    case OMPD_end_declare_target:
+    case OMPD_teams:
+    case OMPD_simd:
+    case OMPD_for:
+    case OMPD_for_simd:
+    case OMPD_sections:
+    case OMPD_section:
+    case OMPD_single:
+    case OMPD_master:
+    case OMPD_critical:
+    case OMPD_taskgroup:
+    case OMPD_distribute:
+    case OMPD_ordered:
+    case OMPD_atomic:
+    case OMPD_distribute_simd:
+    case OMPD_teams_distribute:
+    case OMPD_teams_distribute_simd:
+      llvm_unreachable("Unexpected OpenMP directive with if-clause");
+    case OMPD_unknown:
+      llvm_unreachable("Unknown OpenMP directive");
+    }
+    break;
+  case OMPC_num_threads:
+    switch (DKind) {
+    case OMPD_target_parallel:
+      CaptureRegion = OMPD_target;
+      break;
+    case OMPD_cancel:
+    case OMPD_parallel:
+    case OMPD_parallel_sections:
+    case OMPD_parallel_for:
+    case OMPD_parallel_for_simd:
+    case OMPD_target:
+    case OMPD_target_simd:
+    case OMPD_target_parallel_for:
+    case OMPD_target_parallel_for_simd:
+    case OMPD_target_teams:
+    case OMPD_target_teams_distribute:
+    case OMPD_target_teams_distribute_simd:
+    case OMPD_target_teams_distribute_parallel_for:
+    case OMPD_target_teams_distribute_parallel_for_simd:
+    case OMPD_teams_distribute_parallel_for:
+    case OMPD_teams_distribute_parallel_for_simd:
+    case OMPD_distribute_parallel_for:
+    case OMPD_distribute_parallel_for_simd:
+    case OMPD_task:
+    case OMPD_taskloop:
+    case OMPD_taskloop_simd:
+    case OMPD_target_data:
+    case OMPD_target_enter_data:
+    case OMPD_target_exit_data:
+    case OMPD_target_update:
+      // Do not capture num_threads-clause expressions.
+      break;
+    case OMPD_threadprivate:
+    case OMPD_taskyield:
+    case OMPD_barrier:
+    case OMPD_taskwait:
+    case OMPD_cancellation_point:
+    case OMPD_flush:
+    case OMPD_declare_reduction:
+    case OMPD_declare_simd:
+    case OMPD_declare_target:
+    case OMPD_end_declare_target:
+    case OMPD_teams:
+    case OMPD_simd:
+    case OMPD_for:
+    case OMPD_for_simd:
+    case OMPD_sections:
+    case OMPD_section:
+    case OMPD_single:
+    case OMPD_master:
+    case OMPD_critical:
+    case OMPD_taskgroup:
+    case OMPD_distribute:
+    case OMPD_ordered:
+    case OMPD_atomic:
+    case OMPD_distribute_simd:
+    case OMPD_teams_distribute:
+    case OMPD_teams_distribute_simd:
+      llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
+    case OMPD_unknown:
+      llvm_unreachable("Unknown OpenMP directive");
+    }
+    break;
+  case OMPC_num_teams:
+    switch (DKind) {
+    case OMPD_target_teams:
+      CaptureRegion = OMPD_target;
+      break;
+    case OMPD_cancel:
+    case OMPD_parallel:
+    case OMPD_parallel_sections:
+    case OMPD_parallel_for:
+    case OMPD_parallel_for_simd:
+    case OMPD_target:
+    case OMPD_target_simd:
+    case OMPD_target_parallel:
+    case OMPD_target_parallel_for:
+    case OMPD_target_parallel_for_simd:
+    case OMPD_target_teams_distribute:
+    case OMPD_target_teams_distribute_simd:
+    case OMPD_target_teams_distribute_parallel_for:
+    case OMPD_target_teams_distribute_parallel_for_simd:
+    case OMPD_teams_distribute_parallel_for:
+    case OMPD_teams_distribute_parallel_for_simd:
+    case OMPD_distribute_parallel_for:
+    case OMPD_distribute_parallel_for_simd:
+    case OMPD_task:
+    case OMPD_taskloop:
+    case OMPD_taskloop_simd:
+    case OMPD_target_data:
+    case OMPD_target_enter_data:
+    case OMPD_target_exit_data:
+    case OMPD_target_update:
+    case OMPD_teams:
+    case OMPD_teams_distribute:
+    case OMPD_teams_distribute_simd:
+      // Do not capture num_teams-clause expressions.
+      break;
+    case OMPD_threadprivate:
+    case OMPD_taskyield:
+    case OMPD_barrier:
+    case OMPD_taskwait:
+    case OMPD_cancellation_point:
+    case OMPD_flush:
+    case OMPD_declare_reduction:
+    case OMPD_declare_simd:
+    case OMPD_declare_target:
+    case OMPD_end_declare_target:
+    case OMPD_simd:
+    case OMPD_for:
+    case OMPD_for_simd:
+    case OMPD_sections:
+    case OMPD_section:
+    case OMPD_single:
+    case OMPD_master:
+    case OMPD_critical:
+    case OMPD_taskgroup:
+    case OMPD_distribute:
+    case OMPD_ordered:
+    case OMPD_atomic:
+    case OMPD_distribute_simd:
+      llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
+    case OMPD_unknown:
+      llvm_unreachable("Unknown OpenMP directive");
+    }
+    break;
+  case OMPC_thread_limit:
+    switch (DKind) {
+    case OMPD_target_teams:
+      CaptureRegion = OMPD_target;
+      break;
+    case OMPD_cancel:
+    case OMPD_parallel:
+    case OMPD_parallel_sections:
+    case OMPD_parallel_for:
+    case OMPD_parallel_for_simd:
+    case OMPD_target:
+    case OMPD_target_simd:
+    case OMPD_target_parallel:
+    case OMPD_target_parallel_for:
+    case OMPD_target_parallel_for_simd:
+    case OMPD_target_teams_distribute:
+    case OMPD_target_teams_distribute_simd:
+    case OMPD_target_teams_distribute_parallel_for:
+    case OMPD_target_teams_distribute_parallel_for_simd:
+    case OMPD_teams_distribute_parallel_for:
+    case OMPD_teams_distribute_parallel_for_simd:
+    case OMPD_distribute_parallel_for:
+    case OMPD_distribute_parallel_for_simd:
+    case OMPD_task:
+    case OMPD_taskloop:
+    case OMPD_taskloop_simd:
+    case OMPD_target_data:
+    case OMPD_target_enter_data:
+    case OMPD_target_exit_data:
+    case OMPD_target_update:
+    case OMPD_teams:
+    case OMPD_teams_distribute:
+    case OMPD_teams_distribute_simd:
+      // Do not capture thread_limit-clause expressions.
+      break;
+    case OMPD_threadprivate:
+    case OMPD_taskyield:
+    case OMPD_barrier:
+    case OMPD_taskwait:
+    case OMPD_cancellation_point:
+    case OMPD_flush:
+    case OMPD_declare_reduction:
+    case OMPD_declare_simd:
+    case OMPD_declare_target:
+    case OMPD_end_declare_target:
+    case OMPD_simd:
+    case OMPD_for:
+    case OMPD_for_simd:
+    case OMPD_sections:
+    case OMPD_section:
+    case OMPD_single:
+    case OMPD_master:
+    case OMPD_critical:
+    case OMPD_taskgroup:
+    case OMPD_distribute:
+    case OMPD_ordered:
+    case OMPD_atomic:
+    case OMPD_distribute_simd:
+      llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
+    case OMPD_unknown:
+      llvm_unreachable("Unknown OpenMP directive");
+    }
+    break;
+  case OMPC_schedule:
+  case OMPC_dist_schedule:
+  case OMPC_firstprivate:
+  case OMPC_lastprivate:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_default:
+  case OMPC_proc_bind:
+  case OMPC_final:
+  case OMPC_safelen:
+  case OMPC_simdlen:
+  case OMPC_collapse:
+  case OMPC_private:
+  case OMPC_shared:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
+  case OMPC_untied:
+  case OMPC_mergeable:
+  case OMPC_threadprivate:
+  case OMPC_flush:
+  case OMPC_read:
+  case OMPC_write:
+  case OMPC_update:
+  case OMPC_capture:
+  case OMPC_seq_cst:
+  case OMPC_depend:
+  case OMPC_device:
+  case OMPC_threads:
+  case OMPC_simd:
+  case OMPC_map:
+  case OMPC_priority:
+  case OMPC_grainsize:
+  case OMPC_nogroup:
+  case OMPC_num_tasks:
+  case OMPC_hint:
+  case OMPC_defaultmap:
+  case OMPC_unknown:
+  case OMPC_uniform:
+  case OMPC_to:
+  case OMPC_from:
+  case OMPC_use_device_ptr:
+  case OMPC_is_device_ptr:
+    llvm_unreachable("Unexpected OpenMP clause.");
+  }
+  return CaptureRegion;
+}
+
 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
                                      Expr *Condition, SourceLocation StartLoc,
                                      SourceLocation LParenLoc,
@@ -6341,6 +6992,8 @@
                                      SourceLocation ColonLoc,
                                      SourceLocation EndLoc) {
   Expr *ValExpr = Condition;
+  Stmt *HelperValStmt = nullptr;
+  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
       !Condition->isInstantiationDependent() &&
       !Condition->containsUnexpandedParameterPack()) {
@@ -6349,10 +7002,20 @@
       return nullptr;
 
     ValExpr = MakeFullExpr(Val.get()).get();
+
+    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
+    CaptureRegion =
+        getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
+    if (CaptureRegion != OMPD_unknown) {
+      llvm::MapVector<Expr *, DeclRefExpr *> Captures;
+      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
+      HelperValStmt = buildPreInits(Context, Captures);
+    }
   }
 
-  return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,
-                                   NameModifierLoc, ColonLoc, EndLoc);
+  return new (Context)
+      OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
+                  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
 }
 
 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
@@ -6448,6 +7111,8 @@
                                              SourceLocation LParenLoc,
                                              SourceLocation EndLoc) {
   Expr *ValExpr = NumThreads;
+  Stmt *HelperValStmt = nullptr;
+  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
 
   // OpenMP [2.5, Restrictions]
   //  The num_threads expression must evaluate to a positive integer value.
@@ -6455,8 +7120,16 @@
                                  /*StrictlyPositive=*/true))
     return nullptr;
 
-  return new (Context)
-      OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
+  CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
+  if (CaptureRegion != OMPD_unknown) {
+    llvm::MapVector<Expr *, DeclRefExpr *> Captures;
+    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
+    HelperValStmt = buildPreInits(Context, Captures);
+  }
+
+  return new (Context) OMPNumThreadsClause(
+      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
 }
 
 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
@@ -7248,12 +7921,13 @@
       continue;
     }
 
+    auto CurrDir = DSAStack->getCurrentDirective();
     // Variably modified types are not supported for tasks.
     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
-        isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
+        isOpenMPTaskingDirective(CurrDir)) {
       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
           << getOpenMPClauseName(OMPC_private) << Type
-          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
+          << getOpenMPDirectiveName(CurrDir);
       bool IsDecl =
           !VD ||
           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
@@ -7266,7 +7940,14 @@
     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
     // A list item cannot appear in both a map clause and a data-sharing
     // attribute clause on the same construct
-    if (DSAStack->getCurrentDirective() == OMPD_target) {
+    if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
+        CurrDir == OMPD_target_teams || 
+        CurrDir == OMPD_target_teams_distribute ||
+        CurrDir == OMPD_target_teams_distribute_parallel_for ||
+        CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
+        CurrDir == OMPD_target_teams_distribute_simd ||
+        CurrDir == OMPD_target_parallel_for_simd ||
+        CurrDir == OMPD_target_parallel_for) {
       OpenMPClauseKind ConflictKind;
       if (DSAStack->checkMappableExprComponentListsForDecl(
               VD, /*CurrentRegionOnly=*/true,
@@ -7278,7 +7959,7 @@
         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
             << getOpenMPClauseName(OMPC_private)
             << getOpenMPClauseName(ConflictKind)
-            << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
+            << getOpenMPDirectiveName(CurrDir);
         ReportOriginalDSA(*this, DSAStack, D, DVar);
         continue;
       }
@@ -7296,7 +7977,7 @@
     Type = Type.getUnqualifiedType();
     auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
-    ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
+    ActOnUninitializedDecl(VDPrivate);
     if (VDPrivate->isInvalidDecl())
       continue;
     auto VDPrivateRefExpr = buildDeclRefExpr(
@@ -7523,7 +8204,14 @@
       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
       // A list item cannot appear in both a map clause and a data-sharing
       // attribute clause on the same construct
-      if (CurrDir == OMPD_target) {
+      if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
+          CurrDir == OMPD_target_teams || 
+          CurrDir == OMPD_target_teams_distribute ||
+          CurrDir == OMPD_target_teams_distribute_parallel_for ||
+          CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
+          CurrDir == OMPD_target_teams_distribute_simd ||
+          CurrDir == OMPD_target_parallel_for_simd ||
+          CurrDir == OMPD_target_parallel_for) {
         OpenMPClauseKind ConflictKind;
         if (DSAStack->checkMappableExprComponentListsForDecl(
                 VD, /*CurrentRegionOnly=*/true,
@@ -7595,7 +8283,7 @@
                                        RefExpr->getExprLoc());
       AddInitializerToDecl(VDPrivate,
                            DefaultLvalueConversion(VDInitRefExpr).get(),
-                           /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
+                           /*DirectInit=*/false);
     }
     if (VDPrivate->isInvalidDecl()) {
       if (IsImplicitClause) {
@@ -8445,10 +9133,9 @@
       }
     }
     if (Init && DeclareReductionRef.isUnset()) {
-      AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false,
-                           /*TypeMayContainAuto=*/false);
+      AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
     } else if (!Init)
-      ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false);
+      ActOnUninitializedDecl(RHSVD);
     if (RHSVD->isInvalidDecl())
       continue;
     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
@@ -8697,7 +9384,7 @@
     else
       InitExpr = VD ? SimpleRefExpr : Ref;
     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
-                         /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
+                         /*DirectInit=*/false);
     auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
 
     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
@@ -10039,7 +10726,11 @@
       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
       // A list item cannot appear in both a map clause and a data-sharing
       // attribute clause on the same construct
-      if (DKind == OMPD_target && VD) {
+      if ((DKind == OMPD_target || DKind == OMPD_target_teams ||
+           DKind == OMPD_target_teams_distribute ||
+           DKind == OMPD_target_teams_distribute_parallel_for ||
+           DKind == OMPD_target_teams_distribute_parallel_for_simd ||
+           DKind == OMPD_target_teams_distribute_simd) && VD) {
         auto DVar = DSAS->getTopDSA(VD, false);
         if (isOpenMPPrivate(DVar.CKind)) {
           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
@@ -10331,6 +11022,8 @@
                                            SourceLocation LParenLoc,
                                            SourceLocation EndLoc) {
   Expr *ValExpr = NumTeams;
+  Stmt *HelperValStmt = nullptr;
+  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
 
   // OpenMP [teams Constrcut, Restrictions]
   // The num_teams expression must evaluate to a positive integer value.
@@ -10338,7 +11031,16 @@
                                  /*StrictlyPositive=*/true))
     return nullptr;
 
-  return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
+  CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
+  if (CaptureRegion != OMPD_unknown) {
+    llvm::MapVector<Expr *, DeclRefExpr *> Captures;
+    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
+    HelperValStmt = buildPreInits(Context, Captures);
+  }
+
+  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
+                                         StartLoc, LParenLoc, EndLoc);
 }
 
 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
@@ -10346,6 +11048,8 @@
                                               SourceLocation LParenLoc,
                                               SourceLocation EndLoc) {
   Expr *ValExpr = ThreadLimit;
+  Stmt *HelperValStmt = nullptr;
+  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
 
   // OpenMP [teams Constrcut, Restrictions]
   // The thread_limit expression must evaluate to a positive integer value.
@@ -10353,8 +11057,16 @@
                                  /*StrictlyPositive=*/true))
     return nullptr;
 
-  return new (Context)
-      OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
+  CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
+  if (CaptureRegion != OMPD_unknown) {
+    llvm::MapVector<Expr *, DeclRefExpr *> Captures;
+    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
+    HelperValStmt = buildPreInits(Context, Captures);
+  }
+
+  return new (Context) OMPThreadLimitClause(
+      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
 }
 
 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
@@ -10771,7 +11483,7 @@
                                            RefExpr->getExprLoc());
     AddInitializerToDecl(VDPrivate,
                          DefaultLvalueConversion(VDInitRefExpr).get(),
-                         /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
+                         /*DirectInit=*/false);
 
     // If required, build a capture to implement the privatization initialized
     // with the current list item value.
@@ -10809,7 +11521,7 @@
                                               SourceLocation EndLoc) {
   MappableVarListInfo MVLI(VarList);
   for (auto &RefExpr : VarList) {
-    assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
+    assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
     SourceLocation ELoc;
     SourceRange ERange;
     Expr *SimpleRefExpr = RefExpr;
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 6985d69..8b53258 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -29,6 +29,7 @@
 #include "clang/Sema/Template.h"
 #include "clang/Sema/TemplateDeduction.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
@@ -329,6 +330,11 @@
     } else if (FromType->isIntegralType(Ctx) && ToType->isRealFloatingType()) {
       llvm::APSInt IntConstantValue;
       const Expr *Initializer = IgnoreNarrowingConversion(Converted);
+
+      // If it's value-dependent, we can't tell whether it's narrowing.
+      if (Initializer->isValueDependent())
+        return NK_Dependent_Narrowing;
+
       if (Initializer &&
           Initializer->isIntegerConstantExpr(IntConstantValue, Ctx)) {
         // Convert the integer to the floating type.
@@ -362,6 +368,11 @@
         Ctx.getFloatingTypeOrder(FromType, ToType) == 1) {
       // FromType is larger than ToType.
       const Expr *Initializer = IgnoreNarrowingConversion(Converted);
+
+      // If it's value-dependent, we can't tell whether it's narrowing.
+      if (Initializer->isValueDependent())
+        return NK_Dependent_Narrowing;
+
       if (Initializer->isCXX11ConstantExpr(Ctx, &ConstantValue)) {
         // Constant!
         assert(ConstantValue.isFloat());
@@ -403,6 +414,11 @@
       // Not all values of FromType can be represented in ToType.
       llvm::APSInt InitializerValue;
       const Expr *Initializer = IgnoreNarrowingConversion(Converted);
+
+      // If it's value-dependent, we can't tell whether it's narrowing.
+      if (Initializer->isValueDependent())
+        return NK_Dependent_Narrowing;
+
       if (!Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) {
         // Such conversions on variables are always narrowing.
         return NK_Variable_Narrowing;
@@ -574,7 +590,6 @@
   Result.Result = static_cast<unsigned>(TDK);
   Result.HasDiagnostic = false;
   switch (TDK) {
-  case Sema::TDK_Success:
   case Sema::TDK_Invalid:
   case Sema::TDK_InstantiationDepth:
   case Sema::TDK_TooManyArguments:
@@ -589,7 +604,8 @@
     Result.Data = Info.Param.getOpaqueValue();
     break;
 
-  case Sema::TDK_DeducedMismatch: {
+  case Sema::TDK_DeducedMismatch:
+  case Sema::TDK_DeducedMismatchNested: {
     // FIXME: Should allocate from normal heap so that we can free this later.
     auto *Saved = new (Context) DFIDeducedMismatchArgs;
     Saved->FirstArg = Info.FirstArg;
@@ -630,9 +646,9 @@
     }
     break;
 
-  case Sema::TDK_FailedOverloadResolution:
-    Result.Data = Info.Expression;
-    break;
+  case Sema::TDK_Success:
+  case Sema::TDK_NonDependentConversionFailure:
+    llvm_unreachable("not a deduction failure");
   }
 
   return Result;
@@ -647,13 +663,14 @@
   case Sema::TDK_TooManyArguments:
   case Sema::TDK_TooFewArguments:
   case Sema::TDK_InvalidExplicitArguments:
-  case Sema::TDK_FailedOverloadResolution:
   case Sema::TDK_CUDATargetMismatch:
+  case Sema::TDK_NonDependentConversionFailure:
     break;
 
   case Sema::TDK_Inconsistent:
   case Sema::TDK_Underqualified:
   case Sema::TDK_DeducedMismatch:
+  case Sema::TDK_DeducedMismatchNested:
   case Sema::TDK_NonDeducedMismatch:
     // FIXME: Destroy the data?
     Data = nullptr;
@@ -689,9 +706,10 @@
   case Sema::TDK_TooFewArguments:
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_DeducedMismatch:
+  case Sema::TDK_DeducedMismatchNested:
   case Sema::TDK_NonDeducedMismatch:
-  case Sema::TDK_FailedOverloadResolution:
   case Sema::TDK_CUDATargetMismatch:
+  case Sema::TDK_NonDependentConversionFailure:
     return TemplateParameter();
 
   case Sema::TDK_Incomplete:
@@ -722,11 +740,12 @@
   case Sema::TDK_Inconsistent:
   case Sema::TDK_Underqualified:
   case Sema::TDK_NonDeducedMismatch:
-  case Sema::TDK_FailedOverloadResolution:
   case Sema::TDK_CUDATargetMismatch:
+  case Sema::TDK_NonDependentConversionFailure:
     return nullptr;
 
   case Sema::TDK_DeducedMismatch:
+  case Sema::TDK_DeducedMismatchNested:
     return static_cast<DFIDeducedMismatchArgs*>(Data)->TemplateArgs;
 
   case Sema::TDK_SubstitutionFailure:
@@ -750,13 +769,14 @@
   case Sema::TDK_TooFewArguments:
   case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_SubstitutionFailure:
-  case Sema::TDK_FailedOverloadResolution:
   case Sema::TDK_CUDATargetMismatch:
+  case Sema::TDK_NonDependentConversionFailure:
     return nullptr;
 
   case Sema::TDK_Inconsistent:
   case Sema::TDK_Underqualified:
   case Sema::TDK_DeducedMismatch:
+  case Sema::TDK_DeducedMismatchNested:
   case Sema::TDK_NonDeducedMismatch:
     return &static_cast<DFIArguments*>(Data)->FirstArg;
 
@@ -778,13 +798,14 @@
   case Sema::TDK_TooFewArguments:
   case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_SubstitutionFailure:
-  case Sema::TDK_FailedOverloadResolution:
   case Sema::TDK_CUDATargetMismatch:
+  case Sema::TDK_NonDependentConversionFailure:
     return nullptr;
 
   case Sema::TDK_Inconsistent:
   case Sema::TDK_Underqualified:
   case Sema::TDK_DeducedMismatch:
+  case Sema::TDK_DeducedMismatchNested:
   case Sema::TDK_NonDeducedMismatch:
     return &static_cast<DFIArguments*>(Data)->SecondArg;
 
@@ -796,26 +817,21 @@
   return nullptr;
 }
 
-Expr *DeductionFailureInfo::getExpr() {
-  if (static_cast<Sema::TemplateDeductionResult>(Result) ==
-        Sema::TDK_FailedOverloadResolution)
-    return static_cast<Expr*>(Data);
-
-  return nullptr;
-}
-
 llvm::Optional<unsigned> DeductionFailureInfo::getCallArgIndex() {
-  if (static_cast<Sema::TemplateDeductionResult>(Result) ==
-        Sema::TDK_DeducedMismatch)
+  switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+  case Sema::TDK_DeducedMismatch:
+  case Sema::TDK_DeducedMismatchNested:
     return static_cast<DFIDeducedMismatchArgs*>(Data)->CallArgIndex;
 
-  return llvm::None;
+  default:
+    return llvm::None;
+  }
 }
 
 void OverloadCandidateSet::destroyCandidates() {
   for (iterator i = begin(), e = end(); i != e; ++i) {
-    for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii)
-      i->Conversions[ii].~ImplicitConversionSequence();
+    for (auto &C : i->Conversions)
+      C.~ImplicitConversionSequence();
     if (!i->Viable && i->FailureKind == ovl_fail_bad_deduction)
       i->DeductionFailure.Destroy();
   }
@@ -823,8 +839,8 @@
 
 void OverloadCandidateSet::clear() {
   destroyCandidates();
-  ConversionSequenceAllocator.Reset();
-  NumInlineSequences = 0;
+  SlabAllocator.Reset();
+  NumInlineBytesUsed = 0;
   Candidates.clear();
   Functions.clear();
 }
@@ -981,16 +997,23 @@
         Match = *I;
         return Ovl_Match;
       }
-    } else if (isa<UsingDecl>(OldD)) {
+    } else if (isa<UsingDecl>(OldD) || isa<UsingPackDecl>(OldD)) {
       // We can overload with these, which can show up when doing
       // redeclaration checks for UsingDecls.
       assert(Old.getLookupKind() == LookupUsingDeclName);
     } else if (isa<TagDecl>(OldD)) {
       // We can always overload with tags by hiding them.
-    } else if (isa<UnresolvedUsingValueDecl>(OldD)) {
+    } else if (auto *UUD = dyn_cast<UnresolvedUsingValueDecl>(OldD)) {
       // Optimistically assume that an unresolved using decl will
       // overload; if it doesn't, we'll have to diagnose during
       // template instantiation.
+      //
+      // Exception: if the scope is dependent and this is not a class
+      // member, the using declaration can only introduce an enumerator.
+      if (UUD->getQualifier()->isDependent() && !UUD->isCXXClassMember()) {
+        Match = *I;
+        return Ovl_NonFunction;
+      }
     } else {
       // (C++ 13p1):
       //   Only function declarations can be overloaded; object and type
@@ -1727,7 +1750,7 @@
                                     ToType == S.Context.Float128Ty));
       if (Float128AndLongDouble &&
           (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) !=
-           &llvm::APFloat::IEEEdouble))
+           &llvm::APFloat::IEEEdouble()))
         return false;
     }
     // Floating point conversions (C++ 4.8).
@@ -1778,6 +1801,11 @@
              From->EvaluateKnownConstInt(S.getASTContext()) == 0) {
     SCS.Second = ICK_Zero_Event_Conversion;
     FromType = ToType;
+  } else if (ToType->isQueueT() &&
+             From->isIntegerConstantExpr(S.getASTContext()) &&
+             (From->EvaluateKnownConstInt(S.getASTContext()) == 0)) {
+    SCS.Second = ICK_Zero_Queue_Conversion;
+    FromType = ToType;
   } else {
     // No second conversion required.
     SCS.Second = ICK_Identity;
@@ -4236,7 +4264,7 @@
     return Ref_Related;
 }
 
-/// \brief Look for a user-defined conversion to an value reference-compatible
+/// \brief Look for a user-defined conversion to a value reference-compatible
 ///        with DeclType. Return true if something definite is found.
 static bool
 FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
@@ -4773,6 +4801,9 @@
     // Type is an aggregate, argument is an init list. At this point it comes
     // down to checking whether the initialization works.
     // FIXME: Find out whether this parameter is consumed or not.
+    // FIXME: Expose SemaInit's aggregate initialization code so that we don't
+    // need to call into the initialization code here; overload resolution
+    // should not be doing that.
     InitializedEntity Entity =
         InitializedEntity::InitializeParameter(S.Context, ToType,
                                                /*Consumed=*/false);
@@ -5152,6 +5183,7 @@
   case ICK_Function_Conversion:
   case ICK_Integral_Promotion:
   case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere.
+  case ICK_Zero_Queue_Conversion:
     return true;
 
   case ICK_Boolean_Conversion:
@@ -5279,6 +5311,9 @@
   QualType PreNarrowingType;
   switch (SCS->getNarrowingKind(S.Context, Result.get(), PreNarrowingValue,
                                 PreNarrowingType)) {
+  case NK_Dependent_Narrowing:
+    // Implicit conversion to a narrower type, but the expression is
+    // value-dependent so we can't tell whether it's actually narrowing.
   case NK_Variable_Narrowing:
     // Implicit conversion to a narrower type, and the value is not a constant
     // expression. We'll diagnose this in a moment.
@@ -5297,6 +5332,11 @@
     break;
   }
 
+  if (Result.get()->isValueDependent()) {
+    Value = APValue();
+    return Result;
+  }
+
   // Check the expression is a constant expression.
   SmallVector<PartialDiagnosticAt, 8> Notes;
   Expr::EvalResult Eval;
@@ -5343,7 +5383,7 @@
 
   APValue V;
   auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true);
-  if (!R.isInvalid())
+  if (!R.isInvalid() && !R.get()->isValueDependent())
     Value = V.getInt();
   return R;
 }
@@ -5798,7 +5838,8 @@
                            OverloadCandidateSet &CandidateSet,
                            bool SuppressUserConversions,
                            bool PartialOverloading,
-                           bool AllowExplicit) {
+                           bool AllowExplicit,
+                           ConversionSequenceList EarlyConversions) {
   const FunctionProtoType *Proto
     = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());
   assert(Proto && "Functions without a prototype cannot be overloaded");
@@ -5814,10 +5855,10 @@
       // function, e.g., X::f(). We use an empty type for the implied
       // object argument (C++ [over.call.func]p3), and the acting context
       // is irrelevant.
-      AddMethodCandidate(Method, FoundDecl, Method->getParent(),
-                         QualType(), Expr::Classification::makeSimpleLValue(),
-                         Args, CandidateSet, SuppressUserConversions,
-                         PartialOverloading);
+      AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(),
+                         Expr::Classification::makeSimpleLValue(), Args,
+                         CandidateSet, SuppressUserConversions,
+                         PartialOverloading, EarlyConversions);
       return;
     }
     // We treat a constructor like a non-member function, since its object
@@ -5850,7 +5891,8 @@
   EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   // Add this candidate
-  OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size());
+  OverloadCandidate &Candidate =
+      CandidateSet.addCandidate(Args.size(), EarlyConversions);
   Candidate.FoundDecl = FoundDecl;
   Candidate.Function = Function;
   Candidate.Viable = true;
@@ -5871,6 +5913,28 @@
       Candidate.FailureKind = ovl_fail_illegal_constructor;
       return;
     }
+
+    // C++ [over.match.funcs]p8: (proposed DR resolution)
+    //   A constructor inherited from class type C that has a first parameter
+    //   of type "reference to P" (including such a constructor instantiated
+    //   from a template) is excluded from the set of candidate functions when
+    //   constructing an object of type cv D if the argument list has exactly
+    //   one argument and D is reference-related to P and P is reference-related
+    //   to C.
+    auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl.getDecl());
+    if (Shadow && Args.size() == 1 && Constructor->getNumParams() >= 1 &&
+        Constructor->getParamDecl(0)->getType()->isReferenceType()) {
+      QualType P = Constructor->getParamDecl(0)->getType()->getPointeeType();
+      QualType C = Context.getRecordType(Constructor->getParent());
+      QualType D = Context.getRecordType(Shadow->getParent());
+      SourceLocation Loc = Args.front()->getExprLoc();
+      if ((Context.hasSameUnqualifiedType(P, C) || IsDerivedFrom(Loc, P, C)) &&
+          (Context.hasSameUnqualifiedType(D, P) || IsDerivedFrom(Loc, D, P))) {
+        Candidate.Viable = false;
+        Candidate.FailureKind = ovl_fail_inhctor_slice;
+        return;
+      }
+    }
   }
 
   unsigned NumParams = Proto->getNumParams();
@@ -5914,7 +5978,10 @@
   // Determine the implicit conversion sequences for each of the
   // arguments.
   for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) {
-    if (ArgIdx < NumParams) {
+    if (Candidate.Conversions[ArgIdx].isInitialized()) {
+      // We already formed a conversion sequence for this parameter during
+      // template argument deduction.
+    } else if (ArgIdx < NumParams) {
       // (C++ 13.3.2p3): for F to be a viable function, there shall
       // exist for each argument an implicit conversion sequence
       // (13.3.3.1) that converts that argument to the corresponding
@@ -5946,6 +6013,12 @@
     Candidate.DeductionFailure.Data = FailedAttr;
     return;
   }
+
+  if (LangOpts.OpenCL && isOpenCLDisabledDecl(Function)) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_ext_disabled;
+    return;
+  }
 }
 
 ObjCMethodDecl *
@@ -6058,66 +6131,87 @@
   return Result;
 }
 
-EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
-                                  bool MissingImplicitThis) {
-  auto EnableIfAttrs = getOrderedEnableIfAttrs(Function);
-  if (EnableIfAttrs.empty())
-    return nullptr;
-
-  SFINAETrap Trap(*this);
-  SmallVector<Expr *, 16> ConvertedArgs;
-  bool InitializationFailed = false;
+static bool
+convertArgsForAvailabilityChecks(Sema &S, FunctionDecl *Function, Expr *ThisArg,
+                                 ArrayRef<Expr *> Args, Sema::SFINAETrap &Trap,
+                                 bool MissingImplicitThis, Expr *&ConvertedThis,
+                                 SmallVectorImpl<Expr *> &ConvertedArgs) {
+  if (ThisArg) {
+    CXXMethodDecl *Method = cast<CXXMethodDecl>(Function);
+    assert(!isa<CXXConstructorDecl>(Method) &&
+           "Shouldn't have `this` for ctors!");
+    assert(!Method->isStatic() && "Shouldn't have `this` for static methods!");
+    ExprResult R = S.PerformObjectArgumentInitialization(
+        ThisArg, /*Qualifier=*/nullptr, Method, Method);
+    if (R.isInvalid())
+      return false;
+    ConvertedThis = R.get();
+  } else {
+    if (auto *MD = dyn_cast<CXXMethodDecl>(Function)) {
+      (void)MD;
+      assert((MissingImplicitThis || MD->isStatic() ||
+              isa<CXXConstructorDecl>(MD)) &&
+             "Expected `this` for non-ctor instance methods");
+    }
+    ConvertedThis = nullptr;
+  }
 
   // Ignore any variadic arguments. Converting them is pointless, since the
-  // user can't refer to them in the enable_if condition.
+  // user can't refer to them in the function condition.
   unsigned ArgSizeNoVarargs = std::min(Function->param_size(), Args.size());
 
   // Convert the arguments.
   for (unsigned I = 0; I != ArgSizeNoVarargs; ++I) {
     ExprResult R;
-    if (I == 0 && !MissingImplicitThis && isa<CXXMethodDecl>(Function) &&
-        !cast<CXXMethodDecl>(Function)->isStatic() &&
-        !isa<CXXConstructorDecl>(Function)) {
-      CXXMethodDecl *Method = cast<CXXMethodDecl>(Function);
-      R = PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr,
-                                              Method, Method);
-    } else {
-      R = PerformCopyInitialization(InitializedEntity::InitializeParameter(
-                                        Context, Function->getParamDecl(I)),
+    R = S.PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                        S.Context, Function->getParamDecl(I)),
                                     SourceLocation(), Args[I]);
-    }
 
-    if (R.isInvalid()) {
-      InitializationFailed = true;
-      break;
-    }
+    if (R.isInvalid())
+      return false;
 
     ConvertedArgs.push_back(R.get());
   }
 
-  if (InitializationFailed || Trap.hasErrorOccurred())
-    return EnableIfAttrs[0];
+  if (Trap.hasErrorOccurred())
+    return false;
 
   // Push default arguments if needed.
   if (!Function->isVariadic() && Args.size() < Function->getNumParams()) {
     for (unsigned i = Args.size(), e = Function->getNumParams(); i != e; ++i) {
       ParmVarDecl *P = Function->getParamDecl(i);
-      ExprResult R = PerformCopyInitialization(
-          InitializedEntity::InitializeParameter(Context,
+      ExprResult R = S.PerformCopyInitialization(
+          InitializedEntity::InitializeParameter(S.Context,
                                                  Function->getParamDecl(i)),
           SourceLocation(),
           P->hasUninstantiatedDefaultArg() ? P->getUninstantiatedDefaultArg()
                                            : P->getDefaultArg());
-      if (R.isInvalid()) {
-        InitializationFailed = true;
-        break;
-      }
+      if (R.isInvalid())
+        return false;
       ConvertedArgs.push_back(R.get());
     }
 
-    if (InitializationFailed || Trap.hasErrorOccurred())
-      return EnableIfAttrs[0];
+    if (Trap.hasErrorOccurred())
+      return false;
   }
+  return true;
+}
+
+EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
+                                  bool MissingImplicitThis) {
+  SmallVector<EnableIfAttr *, 4> EnableIfAttrs =
+      getOrderedEnableIfAttrs(Function);
+  if (EnableIfAttrs.empty())
+    return nullptr;
+
+  SFINAETrap Trap(*this);
+  SmallVector<Expr *, 16> ConvertedArgs;
+  // FIXME: We should look into making enable_if late-parsed.
+  Expr *DiscardedThis;
+  if (!convertArgsForAvailabilityChecks(
+          *this, Function, /*ThisArg=*/nullptr, Args, Trap,
+          /*MissingImplicitThis=*/true, DiscardedThis, ConvertedArgs))
+    return EnableIfAttrs[0];
 
   for (auto *EIA : EnableIfAttrs) {
     APValue Result;
@@ -6133,6 +6227,75 @@
   return nullptr;
 }
 
+template <typename CheckFn>
+static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const FunctionDecl *FD,
+                                        bool ArgDependent, SourceLocation Loc,
+                                        CheckFn &&IsSuccessful) {
+  SmallVector<const DiagnoseIfAttr *, 8> Attrs;
+  for (const auto *DIA : FD->specific_attrs<DiagnoseIfAttr>()) {
+    if (ArgDependent == DIA->getArgDependent())
+      Attrs.push_back(DIA);
+  }
+
+  // Common case: No diagnose_if attributes, so we can quit early.
+  if (Attrs.empty())
+    return false;
+
+  auto WarningBegin = std::stable_partition(
+      Attrs.begin(), Attrs.end(),
+      [](const DiagnoseIfAttr *DIA) { return DIA->isError(); });
+
+  // Note that diagnose_if attributes are late-parsed, so they appear in the
+  // correct order (unlike enable_if attributes).
+  auto ErrAttr = llvm::find_if(llvm::make_range(Attrs.begin(), WarningBegin),
+                               IsSuccessful);
+  if (ErrAttr != WarningBegin) {
+    const DiagnoseIfAttr *DIA = *ErrAttr;
+    S.Diag(Loc, diag::err_diagnose_if_succeeded) << DIA->getMessage();
+    S.Diag(DIA->getLocation(), diag::note_from_diagnose_if)
+        << DIA->getParent() << DIA->getCond()->getSourceRange();
+    return true;
+  }
+
+  for (const auto *DIA : llvm::make_range(WarningBegin, Attrs.end()))
+    if (IsSuccessful(DIA)) {
+      S.Diag(Loc, diag::warn_diagnose_if_succeeded) << DIA->getMessage();
+      S.Diag(DIA->getLocation(), diag::note_from_diagnose_if)
+          << DIA->getParent() << DIA->getCond()->getSourceRange();
+    }
+
+  return false;
+}
+
+bool Sema::diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function,
+                                               const Expr *ThisArg,
+                                               ArrayRef<const Expr *> Args,
+                                               SourceLocation Loc) {
+  return diagnoseDiagnoseIfAttrsWith(
+      *this, Function, /*ArgDependent=*/true, Loc,
+      [&](const DiagnoseIfAttr *DIA) {
+        APValue Result;
+        // It's sane to use the same Args for any redecl of this function, since
+        // EvaluateWithSubstitution only cares about the position of each
+        // argument in the arg list, not the ParmVarDecl* it maps to.
+        if (!DIA->getCond()->EvaluateWithSubstitution(
+                Result, Context, DIA->getParent(), Args, ThisArg))
+          return false;
+        return Result.isInt() && Result.getInt().getBoolValue();
+      });
+}
+
+bool Sema::diagnoseArgIndependentDiagnoseIfAttrs(const FunctionDecl *Function,
+                                                 SourceLocation Loc) {
+  return diagnoseDiagnoseIfAttrsWith(
+      *this, Function, /*ArgDependent=*/false, Loc,
+      [&](const DiagnoseIfAttr *DIA) {
+        bool Result;
+        return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) &&
+               Result;
+      });
+}
+
 /// \brief Add all of the function declarations in the given function set to
 /// the overload candidate set.
 void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
@@ -6148,8 +6311,8 @@
         AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(),
                            cast<CXXMethodDecl>(FD)->getParent(),
                            Args[0]->getType(), Args[0]->Classify(Context),
-                           Args.slice(1), CandidateSet,
-                           SuppressUserConversions, PartialOverloading);
+                           Args.slice(1), CandidateSet, SuppressUserConversions,
+                           PartialOverloading);
       else
         AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet,
                              SuppressUserConversions, PartialOverloading);
@@ -6157,13 +6320,12 @@
       FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D);
       if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
           !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic())
-        AddMethodTemplateCandidate(FunTmpl, F.getPair(),
-                              cast<CXXRecordDecl>(FunTmpl->getDeclContext()),
-                                   ExplicitTemplateArgs,
-                                   Args[0]->getType(),
-                                   Args[0]->Classify(Context), Args.slice(1),
-                                   CandidateSet, SuppressUserConversions,
-                                   PartialOverloading);
+        AddMethodTemplateCandidate(
+            FunTmpl, F.getPair(),
+            cast<CXXRecordDecl>(FunTmpl->getDeclContext()),
+            ExplicitTemplateArgs, Args[0]->getType(),
+            Args[0]->Classify(Context), Args.slice(1), CandidateSet,
+            SuppressUserConversions, PartialOverloading);
       else
         AddTemplateOverloadCandidate(FunTmpl, F.getPair(),
                                      ExplicitTemplateArgs, Args,
@@ -6191,15 +6353,13 @@
     assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) &&
            "Expected a member function template");
     AddMethodTemplateCandidate(TD, FoundDecl, ActingContext,
-                               /*ExplicitArgs*/ nullptr,
-                               ObjectType, ObjectClassification,
-                               Args, CandidateSet,
+                               /*ExplicitArgs*/ nullptr, ObjectType,
+                               ObjectClassification, Args, CandidateSet,
                                SuppressUserConversions);
   } else {
     AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext,
-                       ObjectType, ObjectClassification,
-                       Args,
-                       CandidateSet, SuppressUserConversions);
+                       ObjectType, ObjectClassification, Args, CandidateSet,
+                       SuppressUserConversions);
   }
 }
 
@@ -6217,7 +6377,8 @@
                          ArrayRef<Expr *> Args,
                          OverloadCandidateSet &CandidateSet,
                          bool SuppressUserConversions,
-                         bool PartialOverloading) {
+                         bool PartialOverloading,
+                         ConversionSequenceList EarlyConversions) {
   const FunctionProtoType *Proto
     = dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>());
   assert(Proto && "Methods without a prototype cannot be overloaded");
@@ -6238,7 +6399,8 @@
   EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   // Add this candidate
-  OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1);
+  OverloadCandidate &Candidate =
+      CandidateSet.addCandidate(Args.size() + 1, EarlyConversions);
   Candidate.FoundDecl = FoundDecl;
   Candidate.Function = Method;
   Candidate.IsSurrogate = false;
@@ -6300,7 +6462,10 @@
   // Determine the implicit conversion sequences for each of the
   // arguments.
   for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) {
-    if (ArgIdx < NumParams) {
+    if (Candidate.Conversions[ArgIdx + 1].isInitialized()) {
+      // We already formed a conversion sequence for this parameter during
+      // template argument deduction.
+    } else if (ArgIdx < NumParams) {
       // (C++ 13.3.2p3): for F to be a viable function, there shall
       // exist for each argument an implicit conversion sequence
       // (13.3.3.1) that converts that argument to the corresponding
@@ -6361,19 +6526,32 @@
   //   functions.
   TemplateDeductionInfo Info(CandidateSet.getLocation());
   FunctionDecl *Specialization = nullptr;
-  if (TemplateDeductionResult Result
-      = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs, Args,
-                                Specialization, Info, PartialOverloading)) {
-    OverloadCandidate &Candidate = CandidateSet.addCandidate();
+  ConversionSequenceList Conversions;
+  if (TemplateDeductionResult Result = DeduceTemplateArguments(
+          MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info,
+          PartialOverloading, [&](ArrayRef<QualType> ParamTypes) {
+            return CheckNonDependentConversions(
+                MethodTmpl, ParamTypes, Args, CandidateSet, Conversions,
+                SuppressUserConversions, ActingContext, ObjectType,
+                ObjectClassification);
+          })) {
+    OverloadCandidate &Candidate =
+        CandidateSet.addCandidate(Conversions.size(), Conversions);
     Candidate.FoundDecl = FoundDecl;
     Candidate.Function = MethodTmpl->getTemplatedDecl();
     Candidate.Viable = false;
-    Candidate.FailureKind = ovl_fail_bad_deduction;
     Candidate.IsSurrogate = false;
-    Candidate.IgnoreObjectArgument = false;
+    Candidate.IgnoreObjectArgument =
+        cast<CXXMethodDecl>(Candidate.Function)->isStatic() ||
+        ObjectType.isNull();
     Candidate.ExplicitCallArguments = Args.size();
-    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
-                                                          Info);
+    if (Result == TDK_NonDependentConversionFailure)
+      Candidate.FailureKind = ovl_fail_bad_conversion;
+    else {
+      Candidate.FailureKind = ovl_fail_bad_deduction;
+      Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+                                                            Info);
+    }
     return;
   }
 
@@ -6384,7 +6562,8 @@
          "Specialization is not a member function?");
   AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl,
                      ActingContext, ObjectType, ObjectClassification, Args,
-                     CandidateSet, SuppressUserConversions, PartialOverloading);
+                     CandidateSet, SuppressUserConversions, PartialOverloading,
+                     Conversions);
 }
 
 /// \brief Add a C++ function template specialization as a candidate
@@ -6412,19 +6591,33 @@
   //   functions.
   TemplateDeductionInfo Info(CandidateSet.getLocation());
   FunctionDecl *Specialization = nullptr;
-  if (TemplateDeductionResult Result
-        = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, Args,
-                                  Specialization, Info, PartialOverloading)) {
-    OverloadCandidate &Candidate = CandidateSet.addCandidate();
+  ConversionSequenceList Conversions;
+  if (TemplateDeductionResult Result = DeduceTemplateArguments(
+          FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info,
+          PartialOverloading, [&](ArrayRef<QualType> ParamTypes) {
+            return CheckNonDependentConversions(FunctionTemplate, ParamTypes,
+                                                Args, CandidateSet, Conversions,
+                                                SuppressUserConversions);
+          })) {
+    OverloadCandidate &Candidate =
+        CandidateSet.addCandidate(Conversions.size(), Conversions);
     Candidate.FoundDecl = FoundDecl;
     Candidate.Function = FunctionTemplate->getTemplatedDecl();
     Candidate.Viable = false;
-    Candidate.FailureKind = ovl_fail_bad_deduction;
     Candidate.IsSurrogate = false;
-    Candidate.IgnoreObjectArgument = false;
+    // Ignore the object argument if there is one, since we don't have an object
+    // type.
+    Candidate.IgnoreObjectArgument =
+        isa<CXXMethodDecl>(Candidate.Function) &&
+        !isa<CXXConstructorDecl>(Candidate.Function);
     Candidate.ExplicitCallArguments = Args.size();
-    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
-                                                          Info);
+    if (Result == TDK_NonDependentConversionFailure)
+      Candidate.FailureKind = ovl_fail_bad_conversion;
+    else {
+      Candidate.FailureKind = ovl_fail_bad_deduction;
+      Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+                                                            Info);
+    }
     return;
   }
 
@@ -6432,7 +6625,64 @@
   // deduction as a candidate.
   assert(Specialization && "Missing function template specialization?");
   AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet,
-                       SuppressUserConversions, PartialOverloading);
+                       SuppressUserConversions, PartialOverloading,
+                       /*AllowExplicit*/false, Conversions);
+}
+
+/// Check that implicit conversion sequences can be formed for each argument
+/// whose corresponding parameter has a non-dependent type, per DR1391's
+/// [temp.deduct.call]p10.
+bool Sema::CheckNonDependentConversions(
+    FunctionTemplateDecl *FunctionTemplate, ArrayRef<QualType> ParamTypes,
+    ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet,
+    ConversionSequenceList &Conversions, bool SuppressUserConversions,
+    CXXRecordDecl *ActingContext, QualType ObjectType,
+    Expr::Classification ObjectClassification) {
+  // FIXME: The cases in which we allow explicit conversions for constructor
+  // arguments never consider calling a constructor template. It's not clear
+  // that is correct.
+  const bool AllowExplicit = false;
+
+  auto *FD = FunctionTemplate->getTemplatedDecl();
+  auto *Method = dyn_cast<CXXMethodDecl>(FD);
+  bool HasThisConversion = Method && !isa<CXXConstructorDecl>(Method);
+  unsigned ThisConversions = HasThisConversion ? 1 : 0;
+
+  Conversions =
+      CandidateSet.allocateConversionSequences(ThisConversions + Args.size());
+
+  // Overload resolution is always an unevaluated context.
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
+
+  // For a method call, check the 'this' conversion here too. DR1391 doesn't
+  // require that, but this check should never result in a hard error, and
+  // overload resolution is permitted to sidestep instantiations.
+  if (HasThisConversion && !cast<CXXMethodDecl>(FD)->isStatic() &&
+      !ObjectType.isNull()) {
+    Conversions[0] = TryObjectArgumentInitialization(
+        *this, CandidateSet.getLocation(), ObjectType, ObjectClassification,
+        Method, ActingContext);
+    if (Conversions[0].isBad())
+      return true;
+  }
+
+  for (unsigned I = 0, N = std::min(ParamTypes.size(), Args.size()); I != N;
+       ++I) {
+    QualType ParamType = ParamTypes[I];
+    if (!ParamType->isDependentType()) {
+      Conversions[ThisConversions + I]
+        = TryCopyInitialization(*this, Args[I], ParamType,
+                                SuppressUserConversions,
+                                /*InOverloadResolution=*/true,
+                                /*AllowObjCWritebackConversion=*/
+                                  getLangOpts().ObjCAutoRefCount,
+                                AllowExplicit);
+      if (Conversions[ThisConversions + I].isBad())
+        return true;
+    }
+  }
+
+  return false;
 }
 
 /// Determine whether this is an allowable conversion from the result
@@ -6840,10 +7090,8 @@
          Oper != OperEnd;
          ++Oper)
       AddMethodCandidate(Oper.getPair(), Args[0]->getType(),
-                         Args[0]->Classify(Context), 
-                         Args.slice(1),
-                         CandidateSet,
-                         /* SuppressUserConversions = */ false);
+                         Args[0]->Classify(Context), Args.slice(1),
+                         CandidateSet, /*SuppressUserConversions=*/false);
   }
 }
 
@@ -8671,8 +8919,8 @@
 
   // Define functions that don't require ill-formed conversions for a given
   // argument to be better candidates than functions that do.
-  unsigned NumArgs = Cand1.NumConversions;
-  assert(Cand2.NumConversions == NumArgs && "Overload candidate mismatch");
+  unsigned NumArgs = Cand1.Conversions.size();
+  assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch");
   bool HasBetterConversion = false;
   for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) {
     bool Cand1Bad = IsIllFormedConversion(Cand1.Conversions[ArgIdx]);
@@ -8743,6 +8991,12 @@
     // C++14 [over.match.best]p1 section 2 bullet 3.
   }
 
+  //    -- F1 is generated from a deduction-guide and F2 is not
+  auto *Guide1 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand1.Function);
+  auto *Guide2 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand2.Function);
+  if (Guide1 && Guide2 && Guide1->isImplicit() != Guide2->isImplicit())
+    return Guide2->isImplicit();
+
   //    -- F1 is a non-template function and F2 is a function template
   //       specialization, or, if not that,
   bool Cand1IsSpecialization = Cand1.Function &&
@@ -8913,9 +9167,7 @@
                S.IdentifyCUDAPreference(Caller, Cand->Function) ==
                    Sema::CFP_WrongSide;
       };
-      Candidates.erase(std::remove_if(Candidates.begin(), Candidates.end(),
-                                      IsWrongSideCandidate),
-                       Candidates.end());
+      llvm::erase_if(Candidates, IsWrongSideCandidate);
     }
   }
 
@@ -9121,7 +9373,7 @@
   std::string FnDesc;
   OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Found, Fn, FnDesc);
   PartialDiagnostic PD = PDiag(diag::note_ovl_candidate)
-                             << (unsigned) K << FnDesc;
+                             << (unsigned) K << Fn << FnDesc;
 
   HandleFunctionTypeMismatch(PD, Fn->getType(), DestType);
   Diag(Fn->getLocation(), PD);
@@ -9554,9 +9806,25 @@
     int which = 0;
     if (isa<TemplateTypeParmDecl>(ParamD))
       which = 0;
-    else if (isa<NonTypeTemplateParmDecl>(ParamD))
+    else if (isa<NonTypeTemplateParmDecl>(ParamD)) {
+      // Deduction might have failed because we deduced arguments of two
+      // different types for a non-type template parameter.
+      // FIXME: Use a different TDK value for this.
+      QualType T1 =
+          DeductionFailure.getFirstArg()->getNonTypeTemplateArgumentType();
+      QualType T2 =
+          DeductionFailure.getSecondArg()->getNonTypeTemplateArgumentType();
+      if (!S.Context.hasSameType(T1, T2)) {
+        S.Diag(Templated->getLocation(),
+               diag::note_ovl_candidate_inconsistent_deduction_types)
+          << ParamD->getDeclName() << *DeductionFailure.getFirstArg() << T1
+          << *DeductionFailure.getSecondArg() << T2;
+        MaybeEmitInheritedConstructorNote(S, Found);
+        return;
+      }
+
       which = 1;
-    else {
+    } else {
       which = 2;
     }
 
@@ -9640,15 +9908,8 @@
     return;
   }
 
-  case Sema::TDK_FailedOverloadResolution: {
-    OverloadExpr::FindResult R = OverloadExpr::find(DeductionFailure.getExpr());
-    S.Diag(Templated->getLocation(),
-           diag::note_ovl_candidate_failed_overload_resolution)
-        << R.Expression->getName();
-    return;
-  }
-
-  case Sema::TDK_DeducedMismatch: {
+  case Sema::TDK_DeducedMismatch:
+  case Sema::TDK_DeducedMismatchNested: {
     // Format the template argument list into the argument string.
     SmallString<128> TemplateArgString;
     if (TemplateArgumentList *Args =
@@ -9661,7 +9922,8 @@
     S.Diag(Templated->getLocation(), diag::note_ovl_candidate_deduced_mismatch)
         << (*DeductionFailure.getCallArgIndex() + 1)
         << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg()
-        << TemplateArgString;
+        << TemplateArgString
+        << (DeductionFailure.Result == Sema::TDK_DeducedMismatchNested);
     break;
   }
 
@@ -9791,10 +10053,17 @@
   EnableIfAttr *Attr = static_cast<EnableIfAttr*>(Cand->DeductionFailure.Data);
 
   S.Diag(Callee->getLocation(),
-         diag::note_ovl_candidate_disabled_by_enable_if_attr)
+         diag::note_ovl_candidate_disabled_by_function_cond_attr)
       << Attr->getCond()->getSourceRange() << Attr->getMessage();
 }
 
+static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) {
+  FunctionDecl *Callee = Cand->Function;
+
+  S.Diag(Callee->getLocation(),
+         diag::note_ovl_candidate_disabled_by_extension);
+}
+
 /// Generates a 'note' diagnostic for an overload candidate.  We've
 /// already generated a primary error at the call site.
 ///
@@ -9814,21 +10083,20 @@
   FunctionDecl *Fn = Cand->Function;
 
   // Note deleted candidates, but only if they're viable.
-  if (Cand->Viable && (Fn->isDeleted() ||
-      S.isFunctionConsideredUnavailable(Fn))) {
-    std::string FnDesc;
-    OverloadCandidateKind FnKind =
+  if (Cand->Viable) {
+    if (Fn->isDeleted() || S.isFunctionConsideredUnavailable(Fn)) {
+      std::string FnDesc;
+      OverloadCandidateKind FnKind =
         ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc);
 
-    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted)
-      << FnKind << FnDesc
-      << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0);
-    MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
-    return;
-  }
+      S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted)
+        << FnKind << FnDesc
+        << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0);
+      MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
+      return;
+    }
 
-  // We don't really have anything else to say about viable candidates.
-  if (Cand->Viable) {
+    // We don't really have anything else to say about viable candidates.
     S.NoteOverloadCandidate(Cand->FoundDecl, Fn);
     return;
   }
@@ -9856,7 +10124,7 @@
 
   case ovl_fail_bad_conversion: {
     unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0);
-    for (unsigned N = Cand->NumConversions; I != N; ++I)
+    for (unsigned N = Cand->Conversions.size(); I != N; ++I)
       if (Cand->Conversions[I].isBad())
         return DiagnoseBadConversion(S, Cand, I, TakingCandidateAddress);
 
@@ -9872,6 +10140,20 @@
   case ovl_fail_enable_if:
     return DiagnoseFailedEnableIfAttr(S, Cand);
 
+  case ovl_fail_ext_disabled:
+    return DiagnoseOpenCLExtensionDisabled(S, Cand);
+
+  case ovl_fail_inhctor_slice:
+    // It's generally not interesting to note copy/move constructors here.
+    if (cast<CXXConstructorDecl>(Fn)->isCopyOrMoveConstructor())
+      return;
+    S.Diag(Fn->getLocation(),
+           diag::note_ovl_candidate_inherited_constructor_slice)
+      << (Fn->getPrimaryTemplate() ? 1 : 0)
+      << Fn->getParamDecl(0)->getType()->isRValueReferenceType();
+    MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
+    return;
+
   case ovl_fail_addr_not_available: {
     bool Available = checkAddressOfCandidateIsAvailable(S, Cand->Function);
     (void)Available;
@@ -9916,12 +10198,12 @@
 static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc,
                                          SourceLocation OpLoc,
                                          OverloadCandidate *Cand) {
-  assert(Cand->NumConversions <= 2 && "builtin operator is not binary");
+  assert(Cand->Conversions.size() <= 2 && "builtin operator is not binary");
   std::string TypeStr("operator");
   TypeStr += Opc;
   TypeStr += "(";
   TypeStr += Cand->BuiltinTypes.ParamTypes[0].getAsString();
-  if (Cand->NumConversions == 1) {
+  if (Cand->Conversions.size() == 1) {
     TypeStr += ")";
     S.Diag(OpLoc, diag::note_ovl_builtin_unary_candidate) << TypeStr;
   } else {
@@ -9934,9 +10216,7 @@
 
 static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
                                          OverloadCandidate *Cand) {
-  unsigned NoOperands = Cand->NumConversions;
-  for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) {
-    const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx];
+  for (const ImplicitConversionSequence &ICS : Cand->Conversions) {
     if (ICS.isBad()) break; // all meaningless after first invalid
     if (!ICS.isAmbiguous()) continue;
 
@@ -9956,7 +10236,8 @@
 static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) {
   switch ((Sema::TemplateDeductionResult)DFI.Result) {
   case Sema::TDK_Success:
-    llvm_unreachable("TDK_success while diagnosing bad deduction");
+  case Sema::TDK_NonDependentConversionFailure:
+    llvm_unreachable("non-deduction failure while diagnosing bad deduction");
 
   case Sema::TDK_Invalid:
   case Sema::TDK_Incomplete:
@@ -9968,13 +10249,13 @@
 
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_DeducedMismatch:
+  case Sema::TDK_DeducedMismatchNested:
   case Sema::TDK_NonDeducedMismatch:
   case Sema::TDK_MiscellaneousDeductionFailure:
   case Sema::TDK_CUDATargetMismatch:
     return 3;
 
   case Sema::TDK_InstantiationDepth:
-  case Sema::TDK_FailedOverloadResolution:
     return 4;
 
   case Sema::TDK_InvalidExplicitArguments:
@@ -10059,11 +10340,11 @@
 
         // If there's any ordering between the defined conversions...
         // FIXME: this might not be transitive.
-        assert(L->NumConversions == R->NumConversions);
+        assert(L->Conversions.size() == R->Conversions.size());
 
         int leftBetter = 0;
         unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument);
-        for (unsigned E = L->NumConversions; I != E; ++I) {
+        for (unsigned E = L->Conversions.size(); I != E; ++I) {
           switch (CompareImplicitConversionSequences(S, Loc,
                                                      L->Conversions[I],
                                                      R->Conversions[I])) {
@@ -10112,7 +10393,8 @@
 }
 
 /// CompleteNonViableCandidate - Normally, overload resolution only
-/// computes up to the first. Produces the FixIt set if possible.
+/// computes up to the first bad conversion. Produces the FixIt set if
+/// possible.
 static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
                                        ArrayRef<Expr *> Args) {
   assert(!Cand->Viable);
@@ -10125,71 +10407,67 @@
   // Use a implicit copy initialization to check conversion fixes.
   Cand->Fix.setConversionChecker(TryCopyInitialization);
 
-  // Skip forward to the first bad conversion.
-  unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
-  unsigned ConvCount = Cand->NumConversions;
-  while (true) {
+  // Attempt to fix the bad conversion.
+  unsigned ConvCount = Cand->Conversions.size();
+  for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); /**/;
+       ++ConvIdx) {
     assert(ConvIdx != ConvCount && "no bad conversion in candidate");
-    ConvIdx++;
-    if (Cand->Conversions[ConvIdx - 1].isBad()) {
-      Unfixable = !Cand->TryToFixBadConversion(ConvIdx - 1, S);
+    if (Cand->Conversions[ConvIdx].isInitialized() &&
+        Cand->Conversions[ConvIdx].isBad()) {
+      Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S);
       break;
     }
   }
 
-  if (ConvIdx == ConvCount)
-    return;
-
-  assert(!Cand->Conversions[ConvIdx].isInitialized() &&
-         "remaining conversion is initialized?");
-
   // FIXME: this should probably be preserved from the overload
   // operation somehow.
   bool SuppressUserConversions = false;
 
-  const FunctionProtoType* Proto;
-  unsigned ArgIdx = ConvIdx;
+  unsigned ConvIdx = 0;
+  ArrayRef<QualType> ParamTypes;
 
   if (Cand->IsSurrogate) {
     QualType ConvType
       = Cand->Surrogate->getConversionType().getNonReferenceType();
     if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
       ConvType = ConvPtrType->getPointeeType();
-    Proto = ConvType->getAs<FunctionProtoType>();
-    ArgIdx--;
+    ParamTypes = ConvType->getAs<FunctionProtoType>()->getParamTypes();
+    // Conversion 0 is 'this', which doesn't have a corresponding argument.
+    ConvIdx = 1;
   } else if (Cand->Function) {
-    Proto = Cand->Function->getType()->getAs<FunctionProtoType>();
+    ParamTypes =
+        Cand->Function->getType()->getAs<FunctionProtoType>()->getParamTypes();
     if (isa<CXXMethodDecl>(Cand->Function) &&
-        !isa<CXXConstructorDecl>(Cand->Function))
-      ArgIdx--;
+        !isa<CXXConstructorDecl>(Cand->Function)) {
+      // Conversion 0 is 'this', which doesn't have a corresponding argument.
+      ConvIdx = 1;
+    }
   } else {
-    // Builtin binary operator with a bad first conversion.
+    // Builtin operator.
     assert(ConvCount <= 3);
-    for (; ConvIdx != ConvCount; ++ConvIdx)
-      Cand->Conversions[ConvIdx]
-        = TryCopyInitialization(S, Args[ConvIdx],
-                                Cand->BuiltinTypes.ParamTypes[ConvIdx],
-                                SuppressUserConversions,
-                                /*InOverloadResolution*/ true,
-                                /*AllowObjCWritebackConversion=*/
-                                  S.getLangOpts().ObjCAutoRefCount);
-    return;
+    ParamTypes = Cand->BuiltinTypes.ParamTypes;
   }
 
   // Fill in the rest of the conversions.
-  unsigned NumParams = Proto->getNumParams();
-  for (; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
-    if (ArgIdx < NumParams) {
-      Cand->Conversions[ConvIdx] = TryCopyInitialization(
-          S, Args[ArgIdx], Proto->getParamType(ArgIdx), SuppressUserConversions,
-          /*InOverloadResolution=*/true,
-          /*AllowObjCWritebackConversion=*/
-          S.getLangOpts().ObjCAutoRefCount);
-      // Store the FixIt in the candidate if it exists.
-      if (!Unfixable && Cand->Conversions[ConvIdx].isBad())
-        Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S);
-    }
-    else
+  for (unsigned ArgIdx = 0; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
+    if (Cand->Conversions[ConvIdx].isInitialized()) {
+      // We've already checked this conversion.
+    } else if (ArgIdx < ParamTypes.size()) {
+      if (ParamTypes[ArgIdx]->isDependentType())
+        Cand->Conversions[ConvIdx].setAsIdentityConversion(
+            Args[ArgIdx]->getType());
+      else {
+        Cand->Conversions[ConvIdx] =
+            TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ArgIdx],
+                                  SuppressUserConversions,
+                                  /*InOverloadResolution=*/true,
+                                  /*AllowObjCWritebackConversion=*/
+                                  S.getLangOpts().ObjCAutoRefCount);
+        // Store the FixIt in the candidate if it exists.
+        if (!Unfixable && Cand->Conversions[ConvIdx].isBad())
+          Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S);
+      }
+    } else
       Cand->Conversions[ConvIdx].setEllipsis();
   }
 }
@@ -11213,7 +11491,7 @@
                        TemplateArgumentListInfo *ExplicitTemplateArgs,
                        ArrayRef<Expr *> Args,
                        bool *DoDiagnoseEmptyLookup = nullptr) {
-  if (SemaRef.ActiveTemplateInstantiations.empty() || !SS.isEmpty())
+  if (!SemaRef.inTemplateInstantiation() || !SS.isEmpty())
     return false;
 
   for (DeclContext *DC = SemaRef.CurContext; DC; DC = DC->getParent()) {
@@ -11394,6 +11672,12 @@
 
   assert(!R.empty() && "lookup results empty despite recovery");
 
+  // If recovery created an ambiguity, just bail out.
+  if (R.isAmbiguous()) {
+    R.suppressDiagnostics();
+    return ExprError();
+  }
+
   // Build an implicit member call if appropriate.  Just drop the
   // casts and such from the call, we don't really care.
   ExprResult NewFn = ExprError();
@@ -11754,6 +12038,10 @@
       if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
         return ExprError();
 
+      if (CheckFunctionCall(FnDecl, TheCall,
+                            FnDecl->getType()->castAs<FunctionProtoType>()))
+        return ExprError();
+
       return MaybeBindToTemporary(TheCall);
     } else {
       // We matched a built-in operator. Convert the arguments, then
@@ -11984,16 +12272,20 @@
           return ExprError();
 
         ArrayRef<const Expr *> ArgsArray(Args, 2);
+        const Expr *ImplicitThis = nullptr;
         // Cut off the implicit 'this'.
-        if (isa<CXXMethodDecl>(FnDecl))
+        if (isa<CXXMethodDecl>(FnDecl)) {
+          ImplicitThis = ArgsArray[0];
           ArgsArray = ArgsArray.slice(1);
+        }
 
         // Check for a self move.
         if (Op == OO_Equal)
           DiagnoseSelfMove(Args[0], Args[1], OpLoc);
 
-        checkCall(FnDecl, nullptr, ArgsArray, isa<CXXMethodDecl>(FnDecl), OpLoc, 
-                  TheCall->getSourceRange(), VariadicDoesNotApply);
+        checkCall(FnDecl, nullptr, ImplicitThis, ArgsArray,
+                  isa<CXXMethodDecl>(FnDecl), OpLoc, TheCall->getSourceRange(),
+                  VariadicDoesNotApply);
 
         return MaybeBindToTemporary(TheCall);
       } else {
@@ -12202,6 +12494,10 @@
         if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl))
           return ExprError();
 
+        if (CheckFunctionCall(Method, TheCall,
+                              Method->getType()->castAs<FunctionProtoType>()))
+          return ExprError();
+
         return MaybeBindToTemporary(TheCall);
       } else {
         // We matched a built-in operator. Convert the arguments, then
@@ -12391,11 +12687,10 @@
                            ObjectClassification, Args, CandidateSet,
                            /*SuppressUserConversions=*/false);
       } else {
-        AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(Func),
-                                   I.getPair(), ActingDC, TemplateArgs,
-                                   ObjectType,  ObjectClassification,
-                                   Args, CandidateSet,
-                                   /*SuppressUsedConversions=*/false);
+        AddMethodTemplateCandidate(
+            cast<FunctionTemplateDecl>(Func), I.getPair(), ActingDC,
+            TemplateArgs, ObjectType, ObjectClassification, Args, CandidateSet,
+            /*SuppressUsedConversions=*/false);
       }
     }
 
@@ -12508,7 +12803,7 @@
            diag::err_ovl_no_viable_member_function_in_call)
           << Method << Method->getSourceRange();
       Diag(Method->getLocation(),
-           diag::note_ovl_candidate_disabled_by_enable_if_attr)
+           diag::note_ovl_candidate_disabled_by_function_cond_attr)
           << Attr->getCond()->getSourceRange() << Attr->getMessage();
       return ExprError();
     }
@@ -12590,9 +12885,8 @@
   for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
        Oper != OperEnd; ++Oper) {
     AddMethodCandidate(Oper.getPair(), Object.get()->getType(),
-                       Object.get()->Classify(Context),
-                       Args, CandidateSet,
-                       /*SuppressUserConversions=*/ false);
+                       Object.get()->Classify(Context), Args, CandidateSet,
+                       /*SuppressUserConversions=*/false);
   }
 
   // C++ [over.call.object]p2:
@@ -12746,9 +13040,9 @@
 
   // Build the full argument list for the method call (the implicit object
   // parameter is placed at the beginning of the list).
-  std::unique_ptr<Expr * []> MethodArgs(new Expr *[Args.size() + 1]);
+  SmallVector<Expr *, 8> MethodArgs(Args.size() + 1);
   MethodArgs[0] = Object.get();
-  std::copy(Args.begin(), Args.end(), &MethodArgs[1]);
+  std::copy(Args.begin(), Args.end(), MethodArgs.begin() + 1);
 
   // Once we've built TheCall, all of the expressions are properly
   // owned.
@@ -12757,10 +13051,8 @@
   ResultTy = ResultTy.getNonLValueExprType(Context);
 
   CXXOperatorCallExpr *TheCall = new (Context)
-      CXXOperatorCallExpr(Context, OO_Call, NewFn.get(),
-                          llvm::makeArrayRef(MethodArgs.get(), Args.size() + 1),
-                          ResultTy, VK, RParenLoc, false);
-  MethodArgs.reset();
+      CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy,
+                          VK, RParenLoc, false);
 
   if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method))
     return true;
@@ -12943,7 +13235,11 @@
                                       Base, ResultTy, VK, OpLoc, false);
 
   if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))
-          return ExprError();
+    return ExprError();
+
+  if (CheckFunctionCall(Method, TheCall,
+                        Method->getType()->castAs<FunctionProtoType>()))
+    return ExprError();
 
   return MaybeBindToTemporary(TheCall);
 }
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 50f0a22..3f6c467 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1810,7 +1810,7 @@
 
         D->setType(FirstType);
 
-        if (ActiveTemplateInstantiations.empty()) {
+        if (!inTemplateInstantiation()) {
           SourceLocation Loc =
               D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
           Diag(Loc, diag::warn_auto_var_is_id)
@@ -1881,8 +1881,7 @@
       SemaRef.inferObjCARCLifetime(Decl))
     Decl->setInvalidDecl();
 
-  SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false,
-                               /*TypeMayContainAuto=*/false);
+  SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false);
   SemaRef.FinalizeDeclaration(Decl);
   SemaRef.CurContext->addHiddenDecl(Decl);
   return false;
@@ -2005,8 +2004,7 @@
 
   // Claim the type doesn't contain auto: we've already done the checking.
   DeclGroupPtrTy RangeGroup =
-      BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
-                           /*TypeMayContainAuto=*/ false);
+      BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1));
   StmtResult RangeDecl = ActOnDeclStmt(RangeGroup, RangeLoc, RangeLoc);
   if (RangeDecl.isInvalid()) {
     LoopVar->setInvalidDecl();
@@ -2408,8 +2406,7 @@
     // Attach  *__begin  as initializer for VD. Don't touch it if we're just
     // trying to determine whether this would be a valid range.
     if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) {
-      AddInitializerToDecl(LoopVar, DerefExpr.get(), /*DirectInit=*/false,
-                           /*TypeMayContainAuto=*/true);
+      AddInitializerToDecl(LoopVar, DerefExpr.get(), /*DirectInit=*/false);
       if (LoopVar->isInvalidDecl())
         NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
     }
@@ -2746,15 +2743,17 @@
   // ...automatic...
   if (!VD->hasLocalStorage()) return false;
 
+  // Return false if VD is a __block variable. We don't want to implicitly move
+  // out of a __block variable during a return because we cannot assume the
+  // variable will no longer be used.
+  if (VD->hasAttr<BlocksAttr>()) return false;
+
   if (AllowParamOrMoveConstructible)
     return true;
 
   // ...non-volatile...
   if (VD->getType().isVolatileQualified()) return false;
 
-  // __block variables can't be allocated in a way that permits NRVO.
-  if (VD->hasAttr<BlocksAttr>()) return false;
-
   // Variables with higher required alignment than their type's ABI
   // alignment cannot use NRVO.
   if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() &&
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 9a18244..76de9e2 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -22,6 +22,7 @@
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/MC/MCParser/MCAsmParser.h"
 using namespace clang;
 using namespace sema;
@@ -137,6 +138,56 @@
   return false;
 }
 
+// Extracting the register name from the Expression value,
+// if there is no register name to extract, returns ""
+static StringRef extractRegisterName(const Expr *Expression,
+                                     const TargetInfo &Target) {
+  Expression = Expression->IgnoreImpCasts();
+  if (const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(Expression)) {
+    // Handle cases where the expression is a variable
+    const VarDecl *Variable = dyn_cast<VarDecl>(AsmDeclRef->getDecl());
+    if (Variable && Variable->getStorageClass() == SC_Register) {
+      if (AsmLabelAttr *Attr = Variable->getAttr<AsmLabelAttr>())
+        if (Target.isValidGCCRegisterName(Attr->getLabel()))
+          return Target.getNormalizedGCCRegisterName(Attr->getLabel(), true);
+    }
+  }
+  return "";
+}
+
+// Checks if there is a conflict between the input and output lists with the
+// clobbers list. If there's a conflict, returns the location of the
+// conflicted clobber, else returns nullptr
+static SourceLocation
+getClobberConflictLocation(MultiExprArg Exprs, StringLiteral **Constraints,
+                           StringLiteral **Clobbers, int NumClobbers,
+                           const TargetInfo &Target, ASTContext &Cont) {
+  llvm::StringSet<> InOutVars;
+  // Collect all the input and output registers from the extended asm
+  // statement in order to check for conflicts with the clobber list
+  for (unsigned int i = 0; i < Exprs.size(); ++i) {
+    StringRef Constraint = Constraints[i]->getString();
+    StringRef InOutReg = Target.getConstraintRegister(
+        Constraint, extractRegisterName(Exprs[i], Target));
+    if (InOutReg != "")
+      InOutVars.insert(InOutReg);
+  }
+  // Check for each item in the clobber list if it conflicts with the input
+  // or output
+  for (int i = 0; i < NumClobbers; ++i) {
+    StringRef Clobber = Clobbers[i]->getString();
+    // We only check registers, therefore we don't check cc and memory
+    // clobbers
+    if (Clobber == "cc" || Clobber == "memory")
+      continue;
+    Clobber = Target.getNormalizedGCCRegisterName(Clobber, true);
+    // Go over the output's registers we collected
+    if (InOutVars.count(Clobber))
+      return Clobbers[i]->getLocStart();
+  }
+  return SourceLocation();
+}
+
 StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
                                  bool IsVolatile, unsigned NumOutputs,
                                  unsigned NumInputs, IdentifierInfo **Names,
@@ -543,6 +594,13 @@
     return StmtError();
   }
 
+  // Check for conflicts between clobber list and input or output lists
+  SourceLocation ConstraintLoc =
+      getClobberConflictLocation(Exprs, Constraints, Clobbers, NumClobbers,
+                                 Context.getTargetInfo(), Context);
+  if (ConstraintLoc.isValid())
+    return Diag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber);
+  
   return NS;
 }
 
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index 87fd889..01fa856 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -225,16 +225,12 @@
 
 static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const AttributeList &A,
                                     SourceRange Range) {
-  // OpenCL v2.0 s6.11.5 - opencl_unroll_hint can have 0 arguments (compiler
+  // Although the feature was introduced only in OpenCL C v2.0 s6.11.5, it's
+  // useful for OpenCL 1.x too and doesn't require HW support.
+  // opencl_unroll_hint can have 0 arguments (compiler
   // determines unrolling factor) or 1 argument (the unroll factor provided
   // by the user).
 
-  if (S.getLangOpts().OpenCLVersion < 200) {
-    S.Diag(A.getLoc(), diag::err_attribute_requires_opencl_version)
-        << A.getName() << "2.0" << 1;
-    return nullptr;
-  }
-
   unsigned NumArgs = A.getNumArgs();
 
   if (NumArgs > 1) {
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 4846b25..f6c6ccb 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -45,6 +45,26 @@
   return SourceRange(Ps[0]->getTemplateLoc(), Ps[N-1]->getRAngleLoc());
 }
 
+namespace clang {
+/// \brief [temp.constr.decl]p2: A template's associated constraints are
+/// defined as a single constraint-expression derived from the introduced
+/// constraint-expressions [ ... ].
+///
+/// \param Params The template parameter list and optional requires-clause.
+///
+/// \param FD The underlying templated function declaration for a function
+/// template.
+static Expr *formAssociatedConstraints(TemplateParameterList *Params,
+                                       FunctionDecl *FD);
+}
+
+static Expr *clang::formAssociatedConstraints(TemplateParameterList *Params,
+                                              FunctionDecl *FD) {
+  // FIXME: Concepts: collect additional introduced constraint-expressions
+  assert(!FD && "Cannot collect constraints from function declaration yet.");
+  return Params->getRequiresClause();
+}
+
 /// \brief Determine whether the declaration found is acceptable as the name
 /// of a template and, if so, return that template declaration. Otherwise,
 /// returns NULL.
@@ -88,14 +108,14 @@
   return nullptr;
 }
 
-void Sema::FilterAcceptableTemplateNames(LookupResult &R, 
+void Sema::FilterAcceptableTemplateNames(LookupResult &R,
                                          bool AllowFunctionTemplates) {
   // The set of class templates we've already seen.
   llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates;
   LookupResult::Filter filter = R.makeFilter();
   while (filter.hasNext()) {
     NamedDecl *Orig = filter.next();
-    NamedDecl *Repl = isAcceptableTemplateName(Context, Orig, 
+    NamedDecl *Repl = isAcceptableTemplateName(Context, Orig,
                                                AllowFunctionTemplates);
     if (!Repl)
       filter.erase();
@@ -131,7 +151,7 @@
   for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I)
     if (isAcceptableTemplateName(Context, *I, AllowFunctionTemplates))
       return true;
-  
+
   return false;
 }
 
@@ -222,6 +242,37 @@
   return TemplateKind;
 }
 
+bool Sema::isDeductionGuideName(Scope *S, const IdentifierInfo &Name,
+                                SourceLocation NameLoc,
+                                ParsedTemplateTy *Template) {
+  CXXScopeSpec SS;
+  bool MemberOfUnknownSpecialization = false;
+
+  // We could use redeclaration lookup here, but we don't need to: the
+  // syntactic form of a deduction guide is enough to identify it even
+  // if we can't look up the template name at all.
+  LookupResult R(*this, DeclarationName(&Name), NameLoc, LookupOrdinaryName);
+  LookupTemplateName(R, S, SS, /*ObjectType*/QualType(),
+                     /*EnteringContext*/false, MemberOfUnknownSpecialization);
+
+  if (R.empty()) return false;
+  if (R.isAmbiguous()) {
+    // FIXME: Diagnose an ambiguity if we find at least one template.
+    R.suppressDiagnostics();
+    return false;
+  }
+
+  // We only treat template-names that name type templates as valid deduction
+  // guide names.
+  TemplateDecl *TD = R.getAsSingle<TemplateDecl>();
+  if (!TD || !getAsTypeTemplateDecl(TD))
+    return false;
+
+  if (Template)
+    *Template = TemplateTy::make(TemplateName(TD));
+  return true;
+}
+
 bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II,
                                        SourceLocation IILoc,
                                        Scope *S,
@@ -265,7 +316,7 @@
     assert((isDependent || !ObjectType->isIncompleteType() ||
             ObjectType->castAs<TagType>()->isBeingDefined()) &&
            "Caller should have completed object type");
-    
+
     // Template names cannot appear inside an Objective-C class or object type.
     if (ObjectType->isObjCObjectOrInterfaceType()) {
       Found.clear();
@@ -312,7 +363,7 @@
   } else {
     // Perform unqualified name lookup in the current scope.
     LookupName(Found, S);
-    
+
     if (!ObjectType.isNull())
       AllowFunctionTemplatesInLookup = false;
   }
@@ -429,7 +480,12 @@
   bool MightBeCxx11UnevalField =
       getLangOpts().CPlusPlus11 && isUnevaluatedContext();
 
-  if (!MightBeCxx11UnevalField && !isAddressOfOperand &&
+  // Check if the nested name specifier is an enum type.
+  bool IsEnum = false;
+  if (NestedNameSpecifier *NNS = SS.getScopeRep())
+    IsEnum = dyn_cast_or_null<EnumType>(NNS->getAsType());
+
+  if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum &&
       isa<CXXMethodDecl>(DC) && cast<CXXMethodDecl>(DC)->isInstance()) {
     QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType(Context);
 
@@ -724,8 +780,22 @@
 ///
 /// \returns the (possibly-promoted) parameter type if valid;
 /// otherwise, produces a diagnostic and returns a NULL type.
-QualType
-Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
+QualType Sema::CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI,
+                                                 SourceLocation Loc) {
+  if (TSI->getType()->isUndeducedType()) {
+    // C++1z [temp.dep.expr]p3:
+    //   An id-expression is type-dependent if it contains
+    //    - an identifier associated by name lookup with a non-type
+    //      template-parameter declared with a type that contains a
+    //      placeholder type (7.1.7.4),
+    TSI = SubstAutoTypeSourceInfo(TSI, Context.DependentTy);
+  }
+
+  return CheckNonTypeTemplateParameterType(TSI->getType(), Loc);
+}
+
+QualType Sema::CheckNonTypeTemplateParameterType(QualType T,
+                                                 SourceLocation Loc) {
   // We don't allow variably-modified types as the type of non-type template
   // parameters.
   if (T->isVariablyModifiedType()) {
@@ -754,10 +824,6 @@
       T->isDependentType() ||
       // Allow use of auto in template parameter declarations.
       T->isUndeducedType()) {
-    if (T->isUndeducedType()) {
-      Diag(Loc, diag::warn_cxx14_compat_template_nontype_parm_auto_type)
-          << QualType(T->getContainedAutoType(), 0);
-    }
     // C++ [temp.param]p5: The top-level cv-qualifiers on the template-parameter
     // are ignored when determining its type.
     return T.getUnqualifiedType();
@@ -783,13 +849,18 @@
                                           SourceLocation EqualLoc,
                                           Expr *Default) {
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
-  QualType T = TInfo->getType();
+
+  if (TInfo->getType()->isUndeducedType()) {
+    Diag(D.getIdentifierLoc(),
+         diag::warn_cxx14_compat_template_nontype_parm_auto_type)
+      << QualType(TInfo->getType()->getContainedAutoType(), 0);
+  }
 
   assert(S->isTemplateParamScope() &&
          "Non-type template parameter not in template parameter scope!");
   bool Invalid = false;
 
-  T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc());
+  QualType T = CheckNonTypeTemplateParameterType(TInfo, D.getIdentifierLoc());
   if (T.isNull()) {
     T = Context.IntTy; // Recover with an 'int' type.
     Invalid = true;
@@ -870,7 +941,7 @@
                                      Depth, Position, IsParameterPack,
                                      Name, Params);
   Param->setAccess(AS_public);
-  
+
   // If the template template parameter has a name, then link the identifier
   // into the scope and lookup mechanisms.
   if (Name) {
@@ -1000,8 +1071,8 @@
     if (RequireCompleteDeclContext(SS, SemanticContext))
       return true;
 
-    // If we're adding a template to a dependent context, we may need to 
-    // rebuilding some of the types used within the template parameter list, 
+    // If we're adding a template to a dependent context, we may need to
+    // rebuilding some of the types used within the template parameter list,
     // now that we know what the current instantiation is.
     if (SemanticContext->isDependentContext()) {
       ContextRAII SavedContext(*this, SemanticContext);
@@ -1117,6 +1188,9 @@
     }
   }
 
+  // TODO Memory management; associated constraints are not always stored.
+  Expr *const CurAC = formAssociatedConstraints(TemplateParams, nullptr);
+
   if (PrevClassTemplate) {
     // Ensure that the template parameter lists are compatible. Skip this check
     // for a friend in a dependent context: the template parameter list itself
@@ -1128,6 +1202,29 @@
                                         TPL_TemplateMatch))
       return true;
 
+    // Check for matching associated constraints on redeclarations.
+    const Expr *const PrevAC = PrevClassTemplate->getAssociatedConstraints();
+    const bool RedeclACMismatch = [&] {
+      if (!(CurAC || PrevAC))
+        return false; // Nothing to check; no mismatch.
+      if (CurAC && PrevAC) {
+        llvm::FoldingSetNodeID CurACInfo, PrevACInfo;
+        CurAC->Profile(CurACInfo, Context, /*Canonical=*/true);
+        PrevAC->Profile(PrevACInfo, Context, /*Canonical=*/true);
+        if (CurACInfo == PrevACInfo)
+          return false; // All good; no mismatch.
+      }
+      return true;
+    }();
+
+    if (RedeclACMismatch) {
+      Diag(CurAC ? CurAC->getLocStart() : NameLoc,
+           diag::err_template_different_associated_constraints);
+      Diag(PrevAC ? PrevAC->getLocStart() : PrevClassTemplate->getLocation(),
+           diag::note_template_prev_declaration) << /*declaration*/0;
+      return true;
+    }
+
     // C++ [temp.class]p4:
     //   In a redeclaration, partial specialization, explicit
     //   specialization or explicit instantiation of a class template,
@@ -1204,9 +1301,17 @@
     }
   }
 
+  // If this is a templated friend in a dependent context we should not put it
+  // on the redecl chain. In some cases, the templated friend can be the most
+  // recent declaration tricking the template instantiator to make substitutions
+  // there.
+  // FIXME: Figure out how to combine with shouldLinkDependentDeclWithPrevious
+  bool ShouldAddRedecl
+    = !(TUK == TUK_Friend && CurContext->isDependentContext());
+
   CXXRecordDecl *NewClass =
     CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name,
-                          PrevClassTemplate?
+                          PrevClassTemplate && ShouldAddRedecl ?
                             PrevClassTemplate->getTemplatedDecl() : nullptr,
                           /*DelayTypeCreation=*/true);
   SetNestedNameSpecifier(NewClass, SS);
@@ -1222,15 +1327,24 @@
     AddMsStructLayoutForRecord(NewClass);
   }
 
+  // Attach the associated constraints when the declaration will not be part of
+  // a decl chain.
+  Expr *const ACtoAttach =
+      PrevClassTemplate && ShouldAddRedecl ? nullptr : CurAC;
+
   ClassTemplateDecl *NewTemplate
     = ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
                                 DeclarationName(Name), TemplateParams,
-                                NewClass, PrevClassTemplate);
+                                NewClass, ACtoAttach);
+
+  if (ShouldAddRedecl)
+    NewTemplate->setPreviousDecl(PrevClassTemplate);
+
   NewClass->setDescribedClassTemplate(NewTemplate);
-  
+
   if (ModulePrivateLoc.isValid())
     NewTemplate->setModulePrivate();
-  
+
   // Build the type for the class template declaration now.
   QualType T = NewTemplate->getInjectedClassNameSpecialization();
   T = Context.getInjectedClassNameType(NewClass, T);
@@ -1301,6 +1415,368 @@
   return NewTemplate;
 }
 
+namespace {
+/// Transform to convert portions of a constructor declaration into the
+/// corresponding deduction guide, per C++1z [over.match.class.deduct]p1.
+struct ConvertConstructorToDeductionGuideTransform {
+  ConvertConstructorToDeductionGuideTransform(Sema &S,
+                                              ClassTemplateDecl *Template)
+      : SemaRef(S), Template(Template) {}
+
+  Sema &SemaRef;
+  ClassTemplateDecl *Template;
+
+  DeclContext *DC = Template->getDeclContext();
+  CXXRecordDecl *Primary = Template->getTemplatedDecl();
+  DeclarationName DeductionGuideName =
+      SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(Template);
+
+  QualType DeducedType = SemaRef.Context.getTypeDeclType(Primary);
+
+  // Index adjustment to apply to convert depth-1 template parameters into
+  // depth-0 template parameters.
+  unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size();
+
+  /// Transform a constructor declaration into a deduction guide.
+  NamedDecl *transformConstructor(FunctionTemplateDecl *FTD,
+                                  CXXConstructorDecl *CD) {
+    SmallVector<TemplateArgument, 16> SubstArgs;
+
+    LocalInstantiationScope Scope(SemaRef);
+
+    // C++ [over.match.class.deduct]p1:
+    // -- For each constructor of the class template designated by the
+    //    template-name, a function template with the following properties:
+
+    //    -- The template parameters are the template parameters of the class
+    //       template followed by the template parameters (including default
+    //       template arguments) of the constructor, if any.
+    TemplateParameterList *TemplateParams = Template->getTemplateParameters();
+    if (FTD) {
+      TemplateParameterList *InnerParams = FTD->getTemplateParameters();
+      SmallVector<NamedDecl *, 16> AllParams;
+      AllParams.reserve(TemplateParams->size() + InnerParams->size());
+      AllParams.insert(AllParams.begin(),
+                       TemplateParams->begin(), TemplateParams->end());
+      SubstArgs.reserve(InnerParams->size());
+
+      // Later template parameters could refer to earlier ones, so build up
+      // a list of substituted template arguments as we go.
+      for (NamedDecl *Param : *InnerParams) {
+        MultiLevelTemplateArgumentList Args;
+        Args.addOuterTemplateArguments(SubstArgs);
+        Args.addOuterRetainedLevel();
+        NamedDecl *NewParam = transformTemplateParameter(Param, Args);
+        if (!NewParam)
+          return nullptr;
+        AllParams.push_back(NewParam);
+        SubstArgs.push_back(SemaRef.Context.getCanonicalTemplateArgument(
+            SemaRef.Context.getInjectedTemplateArg(NewParam)));
+      }
+      TemplateParams = TemplateParameterList::Create(
+          SemaRef.Context, InnerParams->getTemplateLoc(),
+          InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
+          /*FIXME: RequiresClause*/ nullptr);
+    }
+
+    // If we built a new template-parameter-list, track that we need to
+    // substitute references to the old parameters into references to the
+    // new ones.
+    MultiLevelTemplateArgumentList Args;
+    if (FTD) {
+      Args.addOuterTemplateArguments(SubstArgs);
+      Args.addOuterRetainedLevel();
+    }
+
+    FunctionProtoTypeLoc FPTL = CD->getTypeSourceInfo()->getTypeLoc()
+                                   .getAsAdjusted<FunctionProtoTypeLoc>();
+    assert(FPTL && "no prototype for constructor declaration");
+
+    // Transform the type of the function, adjusting the return type and
+    // replacing references to the old parameters with references to the
+    // new ones.
+    TypeLocBuilder TLB;
+    SmallVector<ParmVarDecl*, 8> Params;
+    QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args);
+    if (NewType.isNull())
+      return nullptr;
+    TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType);
+
+    return buildDeductionGuide(TemplateParams, CD->isExplicit(), NewTInfo,
+                               CD->getLocStart(), CD->getLocation(),
+                               CD->getLocEnd());
+  }
+
+  /// Build a deduction guide with the specified parameter types.
+  NamedDecl *buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
+    SourceLocation Loc = Template->getLocation();
+
+    // Build the requested type.
+    FunctionProtoType::ExtProtoInfo EPI;
+    EPI.HasTrailingReturn = true;
+    QualType Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,
+                                                DeductionGuideName, EPI);
+    TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(Result, Loc);
+
+    FunctionProtoTypeLoc FPTL =
+        TSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
+
+    // Build the parameters, needed during deduction / substitution.
+    SmallVector<ParmVarDecl*, 4> Params;
+    for (auto T : ParamTypes) {
+      ParmVarDecl *NewParam = ParmVarDecl::Create(
+          SemaRef.Context, DC, Loc, Loc, nullptr, T,
+          SemaRef.Context.getTrivialTypeSourceInfo(T, Loc), SC_None, nullptr);
+      NewParam->setScopeInfo(0, Params.size());
+      FPTL.setParam(Params.size(), NewParam);
+      Params.push_back(NewParam);
+    }
+
+    return buildDeductionGuide(Template->getTemplateParameters(), false, TSI,
+                               Loc, Loc, Loc);
+  }
+
+private:
+  /// Transform a constructor template parameter into a deduction guide template
+  /// parameter, rebuilding any internal references to earlier parameters and
+  /// renumbering as we go.
+  NamedDecl *transformTemplateParameter(NamedDecl *TemplateParam,
+                                        MultiLevelTemplateArgumentList &Args) {
+    if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam)) {
+      // TemplateTypeParmDecl's index cannot be changed after creation, so
+      // substitute it directly.
+      auto *NewTTP = TemplateTypeParmDecl::Create(
+          SemaRef.Context, DC, TTP->getLocStart(), TTP->getLocation(),
+          /*Depth*/0, Depth1IndexAdjustment + TTP->getIndex(),
+          TTP->getIdentifier(), TTP->wasDeclaredWithTypename(),
+          TTP->isParameterPack());
+      if (TTP->hasDefaultArgument()) {
+        TypeSourceInfo *InstantiatedDefaultArg =
+            SemaRef.SubstType(TTP->getDefaultArgumentInfo(), Args,
+                              TTP->getDefaultArgumentLoc(), TTP->getDeclName());
+        if (InstantiatedDefaultArg)
+          NewTTP->setDefaultArgument(InstantiatedDefaultArg);
+      }
+      SemaRef.CurrentInstantiationScope->InstantiatedLocal(TemplateParam,
+                                                           NewTTP);
+      return NewTTP;
+    }
+
+    if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
+      return transformTemplateParameterImpl(TTP, Args);
+
+    return transformTemplateParameterImpl(
+        cast<NonTypeTemplateParmDecl>(TemplateParam), Args);
+  }
+  template<typename TemplateParmDecl>
+  TemplateParmDecl *
+  transformTemplateParameterImpl(TemplateParmDecl *OldParam,
+                                 MultiLevelTemplateArgumentList &Args) {
+    // Ask the template instantiator to do the heavy lifting for us, then adjust
+    // the index of the parameter once it's done.
+    auto *NewParam =
+        cast_or_null<TemplateParmDecl>(SemaRef.SubstDecl(OldParam, DC, Args));
+    assert(NewParam->getDepth() == 0 && "unexpected template param depth");
+    NewParam->setPosition(NewParam->getPosition() + Depth1IndexAdjustment);
+    return NewParam;
+  }
+
+  QualType transformFunctionProtoType(TypeLocBuilder &TLB,
+                                      FunctionProtoTypeLoc TL,
+                                      SmallVectorImpl<ParmVarDecl*> &Params,
+                                      MultiLevelTemplateArgumentList &Args) {
+    SmallVector<QualType, 4> ParamTypes;
+    const FunctionProtoType *T = TL.getTypePtr();
+
+    //    -- The types of the function parameters are those of the constructor.
+    for (auto *OldParam : TL.getParams()) {
+      ParmVarDecl *NewParam = transformFunctionTypeParam(OldParam, Args);
+      if (!NewParam)
+        return QualType();
+      ParamTypes.push_back(NewParam->getType());
+      Params.push_back(NewParam);
+    }
+
+    //    -- The return type is the class template specialization designated by
+    //       the template-name and template arguments corresponding to the
+    //       template parameters obtained from the class template.
+    //
+    // We use the injected-class-name type of the primary template instead.
+    // This has the convenient property that it is different from any type that
+    // the user can write in a deduction-guide (because they cannot enter the
+    // context of the template), so implicit deduction guides can never collide
+    // with explicit ones.
+    QualType ReturnType = DeducedType;
+    TLB.pushTypeSpec(ReturnType).setNameLoc(Primary->getLocation());
+
+    // Resolving a wording defect, we also inherit the variadicness of the
+    // constructor.
+    FunctionProtoType::ExtProtoInfo EPI;
+    EPI.Variadic = T->isVariadic();
+    EPI.HasTrailingReturn = true;
+
+    QualType Result = SemaRef.BuildFunctionType(
+        ReturnType, ParamTypes, TL.getLocStart(), DeductionGuideName, EPI);
+    if (Result.isNull())
+      return QualType();
+
+    FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
+    NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
+    NewTL.setLParenLoc(TL.getLParenLoc());
+    NewTL.setRParenLoc(TL.getRParenLoc());
+    NewTL.setExceptionSpecRange(SourceRange());
+    NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
+    for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I)
+      NewTL.setParam(I, Params[I]);
+
+    return Result;
+  }
+
+  ParmVarDecl *
+  transformFunctionTypeParam(ParmVarDecl *OldParam,
+                             MultiLevelTemplateArgumentList &Args) {
+    TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
+    TypeSourceInfo *NewDI =
+        Args.getNumLevels()
+            ? SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
+                                OldParam->getDeclName())
+            : OldDI;
+    if (!NewDI)
+      return nullptr;
+
+    // Canonicalize the type. This (for instance) replaces references to
+    // typedef members of the current instantiations with the definitions of
+    // those typedefs, avoiding triggering instantiation of the deduced type
+    // during deduction.
+    // FIXME: It would be preferable to retain type sugar and source
+    // information here (and handle this in substitution instead).
+    NewDI = SemaRef.Context.getTrivialTypeSourceInfo(
+        SemaRef.Context.getCanonicalType(NewDI->getType()),
+        OldParam->getLocation());
+
+    // Resolving a wording defect, we also inherit default arguments from the
+    // constructor.
+    ExprResult NewDefArg;
+    if (OldParam->hasDefaultArg()) {
+      NewDefArg = Args.getNumLevels()
+                      ? SemaRef.SubstExpr(OldParam->getDefaultArg(), Args)
+                      : OldParam->getDefaultArg();
+      if (NewDefArg.isInvalid())
+        return nullptr;
+    }
+
+    ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,
+                                                OldParam->getInnerLocStart(),
+                                                OldParam->getLocation(),
+                                                OldParam->getIdentifier(),
+                                                NewDI->getType(),
+                                                NewDI,
+                                                OldParam->getStorageClass(),
+                                                NewDefArg.get());
+    NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(),
+                           OldParam->getFunctionScopeIndex());
+    return NewParam;
+  }
+
+  NamedDecl *buildDeductionGuide(TemplateParameterList *TemplateParams,
+                                 bool Explicit, TypeSourceInfo *TInfo,
+                                 SourceLocation LocStart, SourceLocation Loc,
+                                 SourceLocation LocEnd) {
+    DeclarationNameInfo Name(DeductionGuideName, Loc);
+    ArrayRef<ParmVarDecl *> Params =
+        TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams();
+
+    // Build the implicit deduction guide template.
+    auto *Guide =
+        CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, Explicit,
+                                      Name, TInfo->getType(), TInfo, LocEnd);
+    Guide->setImplicit();
+    Guide->setParams(Params);
+
+    for (auto *Param : Params)
+      Param->setDeclContext(Guide);
+
+    auto *GuideTemplate = FunctionTemplateDecl::Create(
+        SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
+    GuideTemplate->setImplicit();
+    Guide->setDescribedFunctionTemplate(GuideTemplate);
+
+    if (isa<CXXRecordDecl>(DC)) {
+      Guide->setAccess(AS_public);
+      GuideTemplate->setAccess(AS_public);
+    }
+
+    DC->addDecl(GuideTemplate);
+    return GuideTemplate;
+  }
+};
+}
+
+void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
+                                          SourceLocation Loc) {
+  DeclContext *DC = Template->getDeclContext();
+  if (DC->isDependentContext())
+    return;
+
+  ConvertConstructorToDeductionGuideTransform Transform(
+      *this, cast<ClassTemplateDecl>(Template));
+  if (!isCompleteType(Loc, Transform.DeducedType))
+    return;
+
+  // Check whether we've already declared deduction guides for this template.
+  // FIXME: Consider storing a flag on the template to indicate this.
+  auto Existing = DC->lookup(Transform.DeductionGuideName);
+  for (auto *D : Existing)
+    if (D->isImplicit())
+      return;
+
+  // In case we were expanding a pack when we attempted to declare deduction
+  // guides, turn off pack expansion for everything we're about to do.
+  ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
+  // Create a template instantiation record to track the "instantiation" of
+  // constructors into deduction guides.
+  // FIXME: Add a kind for this to give more meaningful diagnostics. But can
+  // this substitution process actually fail?
+  InstantiatingTemplate BuildingDeductionGuides(*this, Loc, Template);
+
+  // Convert declared constructors into deduction guide templates.
+  // FIXME: Skip constructors for which deduction must necessarily fail (those
+  // for which some class template parameter without a default argument never
+  // appears in a deduced context).
+  bool AddedAny = false;
+  bool AddedCopyOrMove = false;
+  for (NamedDecl *D : LookupConstructors(Transform.Primary)) {
+    D = D->getUnderlyingDecl();
+    if (D->isInvalidDecl() || D->isImplicit())
+      continue;
+    D = cast<NamedDecl>(D->getCanonicalDecl());
+
+    auto *FTD = dyn_cast<FunctionTemplateDecl>(D);
+    auto *CD =
+        dyn_cast_or_null<CXXConstructorDecl>(FTD ? FTD->getTemplatedDecl() : D);
+    // Class-scope explicit specializations (MS extension) do not result in
+    // deduction guides.
+    if (!CD || (!FTD && CD->isFunctionTemplateSpecialization()))
+      continue;
+
+    Transform.transformConstructor(FTD, CD);
+    AddedAny = true;
+
+    AddedCopyOrMove |= CD->isCopyOrMoveConstructor();
+  }
+
+  // Synthesize an X() -> X<...> guide if there were no declared constructors.
+  // FIXME: The standard doesn't say (how) to do this.
+  if (!AddedAny)
+    Transform.buildSimpleDeductionGuide(None);
+
+  // Synthesize an X(X<...>) -> X<...> guide if there was no declared constructor
+  // resembling a copy or move constructor.
+  // FIXME: The standard doesn't say (how) to do this.
+  if (!AddedCopyOrMove)
+    Transform.buildSimpleDeductionGuide(Transform.DeducedType);
+}
+
 /// \brief Diagnose the presence of a default template argument on a
 /// template parameter, which is ill-formed in certain contexts.
 ///
@@ -1321,7 +1797,7 @@
     //   A default template-argument shall not be specified in a
     //   function template declaration or a function template
     //   definition [...]
-    //   If a friend function template declaration specifies a default 
+    //   If a friend function template declaration specifies a default
     //   template-argument, that declaration shall be a definition and shall be
     //   the only declaration of the function template in the translation unit.
     // (C++98/03 doesn't have this wording; see DR226).
@@ -1633,25 +2109,27 @@
   typedef RecursiveASTVisitor<DependencyChecker> super;
 
   unsigned Depth;
+  bool FindLessThanDepth;
+
+  // Whether we're looking for a use of a template parameter that makes the
+  // overall construct type-dependent / a dependent type. This is strictly
+  // best-effort for now; we may fail to match at all for a dependent type
+  // in some cases if this is set.
+  bool IgnoreNonTypeDependent;
+
   bool Match;
   SourceLocation MatchLoc;
 
-  DependencyChecker(unsigned Depth) : Depth(Depth), Match(false) {}
+  DependencyChecker(unsigned Depth, bool IgnoreNonTypeDependent,
+                    bool FindLessThanDepth = false)
+      : Depth(Depth), FindLessThanDepth(FindLessThanDepth),
+        IgnoreNonTypeDependent(IgnoreNonTypeDependent), Match(false) {}
 
-  DependencyChecker(TemplateParameterList *Params) : Match(false) {
-    NamedDecl *ND = Params->getParam(0);
-    if (TemplateTypeParmDecl *PD = dyn_cast<TemplateTypeParmDecl>(ND)) {
-      Depth = PD->getDepth();
-    } else if (NonTypeTemplateParmDecl *PD =
-                 dyn_cast<NonTypeTemplateParmDecl>(ND)) {
-      Depth = PD->getDepth();
-    } else {
-      Depth = cast<TemplateTemplateParmDecl>(ND)->getDepth();
-    }
-  }
+  DependencyChecker(TemplateParameterList *Params, bool IgnoreNonTypeDependent)
+      : DependencyChecker(Params->getDepth(), IgnoreNonTypeDependent) {}
 
   bool Matches(unsigned ParmDepth, SourceLocation Loc = SourceLocation()) {
-    if (ParmDepth >= Depth) {
+    if (FindLessThanDepth ^ (ParmDepth >= Depth)) {
       Match = true;
       MatchLoc = Loc;
       return true;
@@ -1659,12 +2137,31 @@
     return false;
   }
 
+  bool TraverseStmt(Stmt *S, DataRecursionQueue *Q = nullptr) {
+    // Prune out non-type-dependent expressions if requested. This can
+    // sometimes result in us failing to find a template parameter reference
+    // (if a value-dependent expression creates a dependent type), but this
+    // mode is best-effort only.
+    if (auto *E = dyn_cast_or_null<Expr>(S))
+      if (IgnoreNonTypeDependent && !E->isTypeDependent())
+        return true;
+    return super::TraverseStmt(S, Q);
+  }
+
+  bool TraverseTypeLoc(TypeLoc TL) {
+    if (IgnoreNonTypeDependent && !TL.isNull() &&
+        !TL.getType()->isDependentType())
+      return true;
+    return super::TraverseTypeLoc(TL);
+  }
+
   bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
     return !Matches(TL.getTypePtr()->getDepth(), TL.getNameLoc());
   }
 
   bool VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
-    return !Matches(T->getDepth());
+    // For a best-effort search, keep looking until we find a location.
+    return IgnoreNonTypeDependent || !Matches(T->getDepth());
   }
 
   bool TraverseTemplateName(TemplateName N) {
@@ -1702,7 +2199,7 @@
 /// list.
 static bool
 DependsOnTemplateParameters(QualType T, TemplateParameterList *Params) {
-  DependencyChecker Checker(Params);
+  DependencyChecker Checker(Params, /*IgnoreNonTypeDependent*/false);
   Checker.TraverseType(T);
   return Checker.Match;
 }
@@ -1719,10 +2216,10 @@
         return NNSLoc.getTypeLoc().getSourceRange();
     } else
       break;
-    
+
     NNSLoc = NNSLoc.getPrefix();
   }
-  
+
   return SourceRange();
 }
 
@@ -1749,8 +2246,9 @@
 /// matching template parameters to scope specifiers in friend
 /// declarations.
 ///
-/// \param IsExplicitSpecialization will be set true if the entity being
-/// declared is an explicit specialization, false otherwise.
+/// \param IsMemberSpecialization will be set true if the scope specifier
+/// denotes a fully-specialized type, and therefore this is a declaration of
+/// a member specialization.
 ///
 /// \returns the template parameter list, if any, that corresponds to the
 /// name that is preceded by the scope specifier @p SS. This template
@@ -1762,37 +2260,37 @@
     SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS,
     TemplateIdAnnotation *TemplateId,
     ArrayRef<TemplateParameterList *> ParamLists, bool IsFriend,
-    bool &IsExplicitSpecialization, bool &Invalid) {
-  IsExplicitSpecialization = false;
+    bool &IsMemberSpecialization, bool &Invalid) {
+  IsMemberSpecialization = false;
   Invalid = false;
-  
+
   // The sequence of nested types to which we will match up the template
   // parameter lists. We first build this list by starting with the type named
   // by the nested-name-specifier and walking out until we run out of types.
   SmallVector<QualType, 4> NestedTypes;
   QualType T;
   if (SS.getScopeRep()) {
-    if (CXXRecordDecl *Record 
+    if (CXXRecordDecl *Record
               = dyn_cast_or_null<CXXRecordDecl>(computeDeclContext(SS, true)))
       T = Context.getTypeDeclType(Record);
     else
       T = QualType(SS.getScopeRep()->getAsType(), 0);
   }
-  
+
   // If we found an explicit specialization that prevents us from needing
   // 'template<>' headers, this will be set to the location of that
   // explicit specialization.
   SourceLocation ExplicitSpecLoc;
-  
+
   while (!T.isNull()) {
     NestedTypes.push_back(T);
-    
+
     // Retrieve the parent of a record type.
     if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) {
       // If this type is an explicit specialization, we're done.
       if (ClassTemplateSpecializationDecl *Spec
           = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
-        if (!isa<ClassTemplatePartialSpecializationDecl>(Spec) && 
+        if (!isa<ClassTemplatePartialSpecializationDecl>(Spec) &&
             Spec->getSpecializationKind() == TSK_ExplicitSpecialization) {
           ExplicitSpecLoc = Spec->getLocation();
           break;
@@ -1802,14 +2300,14 @@
         ExplicitSpecLoc = Record->getLocation();
         break;
       }
-      
+
       if (TypeDecl *Parent = dyn_cast<TypeDecl>(Record->getParent()))
         T = Context.getTypeDeclType(Parent);
       else
         T = QualType();
       continue;
-    } 
-    
+    }
+
     if (const TemplateSpecializationType *TST
                                      = T->getAs<TemplateSpecializationType>()) {
       if (TemplateDecl *Template = TST->getTemplateName().getAsTemplateDecl()) {
@@ -1817,10 +2315,10 @@
           T = Context.getTypeDeclType(Parent);
         else
           T = QualType();
-        continue;        
+        continue;
       }
     }
-    
+
     // Look one step prior in a dependent template specialization type.
     if (const DependentTemplateSpecializationType *DependentTST
                           = T->getAs<DependentTemplateSpecializationType>()) {
@@ -1830,7 +2328,7 @@
         T = QualType();
       continue;
     }
-    
+
     // Look one step prior in a dependent name type.
     if (const DependentNameType *DependentName = T->getAs<DependentNameType>()){
       if (NestedNameSpecifier *NNS = DependentName->getQualifier())
@@ -1839,18 +2337,18 @@
         T = QualType();
       continue;
     }
-    
+
     // Retrieve the parent of an enumeration type.
     if (const EnumType *EnumT = T->getAs<EnumType>()) {
       // FIXME: Forward-declared enums require a TSK_ExplicitSpecialization
       // check here.
       EnumDecl *Enum = EnumT->getDecl();
-      
+
       // Get to the parent type.
       if (TypeDecl *Parent = dyn_cast<TypeDecl>(Enum->getParent()))
         T = Context.getTypeDeclType(Parent);
       else
-        T = QualType();      
+        T = QualType();
       continue;
     }
 
@@ -1873,7 +2371,7 @@
       Diag(DeclLoc, diag::err_specialize_member_of_template)
         << !Recovery << Range;
       Invalid = true;
-      IsExplicitSpecialization = false;
+      IsMemberSpecialization = false;
       return true;
     }
 
@@ -1902,21 +2400,21 @@
   for (unsigned TypeIdx = 0, NumTypes = NestedTypes.size(); TypeIdx != NumTypes;
        ++TypeIdx) {
     T = NestedTypes[TypeIdx];
-    
+
     // Whether we expect a 'template<>' header.
     bool NeedEmptyTemplateHeader = false;
 
     // Whether we expect a template header with parameters.
     bool NeedNonemptyTemplateHeader = false;
-    
+
     // For a dependent type, the set of template parameters that we
     // expect to see.
     TemplateParameterList *ExpectedTemplateParams = nullptr;
 
     // C++0x [temp.expl.spec]p15:
-    //   A member or a member template may be nested within many enclosing 
-    //   class templates. In an explicit specialization for such a member, the 
-    //   member declaration shall be preceded by a template<> for each 
+    //   A member or a member template may be nested within many enclosing
+    //   class templates. In an explicit specialization for such a member, the
+    //   member declaration shall be preceded by a template<> for each
     //   enclosing class template that is explicitly specialized.
     if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) {
       if (ClassTemplatePartialSpecializationDecl *Partial
@@ -1933,38 +2431,38 @@
                      = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
         // C++0x [temp.expl.spec]p4:
         //   Members of an explicitly specialized class template are defined
-        //   in the same manner as members of normal classes, and not using 
-        //   the template<> syntax. 
+        //   in the same manner as members of normal classes, and not using
+        //   the template<> syntax.
         if (Spec->getSpecializationKind() != TSK_ExplicitSpecialization)
           NeedEmptyTemplateHeader = true;
         else
           continue;
       } else if (Record->getTemplateSpecializationKind()) {
-        if (Record->getTemplateSpecializationKind() 
+        if (Record->getTemplateSpecializationKind()
                                                 != TSK_ExplicitSpecialization &&
             TypeIdx == NumTypes - 1)
-          IsExplicitSpecialization = true;
-        
+          IsMemberSpecialization = true;
+
         continue;
       }
     } else if (const TemplateSpecializationType *TST
                                      = T->getAs<TemplateSpecializationType>()) {
       if (TemplateDecl *Template = TST->getTemplateName().getAsTemplateDecl()) {
         ExpectedTemplateParams = Template->getTemplateParameters();
-        NeedNonemptyTemplateHeader = true;        
+        NeedNonemptyTemplateHeader = true;
       }
     } else if (T->getAs<DependentTemplateSpecializationType>()) {
       // FIXME:  We actually could/should check the template arguments here
       // against the corresponding template parameter list.
       NeedNonemptyTemplateHeader = false;
-    } 
-    
+    }
+
     // C++ [temp.expl.spec]p16:
-    //   In an explicit specialization declaration for a member of a class 
-    //   template or a member template that ap- pears in namespace scope, the 
-    //   member template and some of its enclosing class templates may remain 
-    //   unspecialized, except that the declaration shall not explicitly 
-    //   specialize a class member template if its en- closing class templates 
+    //   In an explicit specialization declaration for a member of a class
+    //   template or a member template that ap- pears in namespace scope, the
+    //   member template and some of its enclosing class templates may remain
+    //   unspecialized, except that the declaration shall not explicitly
+    //   specialize a class member template if its en- closing class templates
     //   are not explicitly specialized as well.
     if (ParamIdx < ParamLists.size()) {
       if (ParamLists[ParamIdx]->size() == 0) {
@@ -1974,17 +2472,17 @@
       } else
         SawNonEmptyTemplateParameterList = true;
     }
-    
+
     if (NeedEmptyTemplateHeader) {
       // If we're on the last of the types, and we need a 'template<>' header
-      // here, then it's an explicit specialization.
+      // here, then it's a member specialization.
       if (TypeIdx == NumTypes - 1)
-        IsExplicitSpecialization = true;
+        IsMemberSpecialization = true;
 
       if (ParamIdx < ParamLists.size()) {
         if (ParamLists[ParamIdx]->size() > 0) {
           // The header has template parameters when it shouldn't. Complain.
-          Diag(ParamLists[ParamIdx]->getTemplateLoc(), 
+          Diag(ParamLists[ParamIdx]->getTemplateLoc(),
                diag::err_template_param_list_matches_nontemplate)
             << T
             << SourceRange(ParamLists[ParamIdx]->getLAngleLoc(),
@@ -2016,7 +2514,7 @@
         if (ParamIdx < ParamLists.size() &&
             DependsOnTemplateParameters(T, ParamLists[ParamIdx]))
           ExpectedTemplateParams = nullptr;
-        else 
+        else
           continue;
       }
 
@@ -2032,11 +2530,11 @@
             CheckTemplateParameterList(ParamLists[ParamIdx], nullptr,
                                        TPC_ClassTemplateMember))
           Invalid = true;
-        
+
         ++ParamIdx;
         continue;
       }
-      
+
       Diag(DeclLoc, diag::err_template_spec_needs_template_parameters)
         << T
         << getRangeOfTypeInNestedNameSpecifier(Context, T, SS);
@@ -2052,7 +2550,6 @@
     if (TemplateId && !IsFriend) {
       // We don't have a template header for the declaration itself, but we
       // should.
-      IsExplicitSpecialization = true;
       DiagnoseMissingExplicitSpecialization(SourceRange(TemplateId->LAngleLoc,
                                                         TemplateId->RAngleLoc));
 
@@ -2086,10 +2583,10 @@
     // not required, and there were any 'template<>' headers, note where the
     // specialization occurred.
     if (ExplicitSpecLoc.isValid() && HasAnyExplicitSpecHeader)
-      Diag(ExplicitSpecLoc, 
+      Diag(ExplicitSpecLoc,
            diag::note_explicit_template_spec_does_not_need_header)
         << NestedTypes.back();
-    
+
     // We have a template parameter list with no corresponding scope, which
     // means that the resulting template declaration can't be instantiated
     // properly (we'll end up with dependent nodes when we shouldn't).
@@ -2098,11 +2595,11 @@
   }
 
   // C++ [temp.expl.spec]p16:
-  //   In an explicit specialization declaration for a member of a class 
-  //   template or a member template that ap- pears in namespace scope, the 
-  //   member template and some of its enclosing class templates may remain 
-  //   unspecialized, except that the declaration shall not explicitly 
-  //   specialize a class member template if its en- closing class templates 
+  //   In an explicit specialization declaration for a member of a class
+  //   template or a member template that ap- pears in namespace scope, the
+  //   member template and some of its enclosing class templates may remain
+  //   unspecialized, except that the declaration shall not explicitly
+  //   specialize a class member template if its en- closing class templates
   //   are not explicitly specialized as well.
   if (ParamLists.back()->size() == 0 &&
       CheckExplicitSpecialization(ParamLists[ParamIdx]->getSourceRange(),
@@ -2127,14 +2624,14 @@
         << Template->getDeclName();
     return;
   }
-  
+
   if (OverloadedTemplateStorage *OST = Name.getAsOverloadedTemplate()) {
-    for (OverloadedTemplateStorage::iterator I = OST->begin(), 
+    for (OverloadedTemplateStorage::iterator I = OST->begin(),
                                           IEnd = OST->end();
          I != IEnd; ++I)
       Diag((*I)->getLocation(), diag::note_template_declared_here)
         << 0 << (*I)->getDeclName();
-    
+
     return;
   }
 }
@@ -2287,15 +2784,7 @@
     // A<T, T> have identical types when A is declared as:
     //
     //   template<typename T, typename U = T> struct A;
-    TemplateName CanonName = Context.getCanonicalTemplateName(Name);
-    CanonType = Context.getTemplateSpecializationType(CanonName,
-                                                      Converted);
-
-    // FIXME: CanonType is not actually the canonical type, and unfortunately
-    // it is a TemplateSpecializationType that we will never use again.
-    // In the future, we need to teach getTemplateSpecializationType to only
-    // build the canonical type and return that to us.
-    CanonType = Context.getCanonicalType(CanonType);
+    CanonType = Context.getCanonicalTemplateSpecializationType(Name, Converted);
 
     // This might work out to be a current instantiation, in which
     // case the canonical type needs to be the InjectedClassNameType.
@@ -2376,14 +2865,51 @@
 
 TypeResult
 Sema::ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
-                          TemplateTy TemplateD, SourceLocation TemplateLoc,
+                          TemplateTy TemplateD, IdentifierInfo *TemplateII,
+                          SourceLocation TemplateIILoc,
                           SourceLocation LAngleLoc,
                           ASTTemplateArgsPtr TemplateArgsIn,
                           SourceLocation RAngleLoc,
-                          bool IsCtorOrDtorName) {
+                          bool IsCtorOrDtorName, bool IsClassName) {
   if (SS.isInvalid())
     return true;
 
+  if (!IsCtorOrDtorName && !IsClassName && SS.isSet()) {
+    DeclContext *LookupCtx = computeDeclContext(SS, /*EnteringContext*/false);
+
+    // C++ [temp.res]p3:
+    //   A qualified-id that refers to a type and in which the
+    //   nested-name-specifier depends on a template-parameter (14.6.2)
+    //   shall be prefixed by the keyword typename to indicate that the
+    //   qualified-id denotes a type, forming an
+    //   elaborated-type-specifier (7.1.5.3).
+    if (!LookupCtx && isDependentScopeSpecifier(SS)) {
+      Diag(SS.getBeginLoc(), diag::err_typename_missing_template)
+        << SS.getScopeRep() << TemplateII->getName();
+      // Recover as if 'typename' were specified.
+      // FIXME: This is not quite correct recovery as we don't transform SS
+      // into the corresponding dependent form (and we don't diagnose missing
+      // 'template' keywords within SS as a result).
+      return ActOnTypenameType(nullptr, SourceLocation(), SS, TemplateKWLoc,
+                               TemplateD, TemplateII, TemplateIILoc, LAngleLoc,
+                               TemplateArgsIn, RAngleLoc);
+    }
+
+    // Per C++ [class.qual]p2, if the template-id was an injected-class-name,
+    // it's not actually allowed to be used as a type in most cases. Because
+    // we annotate it before we know whether it's valid, we have to check for
+    // this case here.
+    auto *LookupRD = dyn_cast_or_null<CXXRecordDecl>(LookupCtx);
+    if (LookupRD && LookupRD->getIdentifier() == TemplateII) {
+      Diag(TemplateIILoc,
+           TemplateKWLoc.isInvalid()
+               ? diag::err_out_of_line_qualified_id_type_names_constructor
+               : diag::ext_out_of_line_qualified_id_type_names_constructor)
+        << TemplateII << 0 /*injected-class-name used as template name*/
+        << 1 /*if any keyword was present, it was 'template'*/;
+    }
+  }
+
   TemplateName Template = TemplateD.get();
 
   // Translate the parser's template argument list in our AST format.
@@ -2403,16 +2929,15 @@
     SpecTL.setElaboratedKeywordLoc(SourceLocation());
     SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
     SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
-    SpecTL.setTemplateNameLoc(TemplateLoc);
+    SpecTL.setTemplateNameLoc(TemplateIILoc);
     SpecTL.setLAngleLoc(LAngleLoc);
     SpecTL.setRAngleLoc(RAngleLoc);
     for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I)
       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
     return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
   }
-  
-  QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs);
 
+  QualType Result = CheckTemplateIdType(Template, TemplateIILoc, TemplateArgs);
   if (Result.isNull())
     return true;
 
@@ -2421,7 +2946,7 @@
   TemplateSpecializationTypeLoc SpecTL
     = TLB.push<TemplateSpecializationTypeLoc>(Result);
   SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
-  SpecTL.setTemplateNameLoc(TemplateLoc);
+  SpecTL.setTemplateNameLoc(TemplateIILoc);
   SpecTL.setLAngleLoc(LAngleLoc);
   SpecTL.setRAngleLoc(RAngleLoc);
   for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i)
@@ -2437,7 +2962,7 @@
     ElabTL.setElaboratedKeywordLoc(SourceLocation());
     ElabTL.setQualifierLoc(SS.getWithLocInContext(Context));
   }
-  
+
   return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result));
 }
 
@@ -2452,11 +2977,11 @@
                                         ASTTemplateArgsPtr TemplateArgsIn,
                                         SourceLocation RAngleLoc) {
   TemplateName Template = TemplateD.get();
-  
+
   // Translate the parser's template argument list in our AST format.
   TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
   translateTemplateArguments(TemplateArgsIn, TemplateArgs);
-  
+
   // Determine the tag kind
   TagTypeKind TagKind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
   ElaboratedTypeKeyword Keyword
@@ -2464,11 +2989,11 @@
 
   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
     QualType T = Context.getDependentTemplateSpecializationType(Keyword,
-                                                          DTN->getQualifier(), 
-                                                          DTN->getIdentifier(), 
+                                                          DTN->getQualifier(),
+                                                          DTN->getIdentifier(),
                                                                 TemplateArgs);
-    
-    // Build type-source information.    
+
+    // Build type-source information.
     TypeLocBuilder TLB;
     DependentTemplateSpecializationTypeLoc SpecTL
       = TLB.push<DependentTemplateSpecializationTypeLoc>(T);
@@ -2489,21 +3014,22 @@
     //   If the identifier resolves to a typedef-name or the simple-template-id
     //   resolves to an alias template specialization, the
     //   elaborated-type-specifier is ill-formed.
-    Diag(TemplateLoc, diag::err_tag_reference_non_tag) << NTK_TypeAliasTemplate;
+    Diag(TemplateLoc, diag::err_tag_reference_non_tag)
+        << TAT << NTK_TypeAliasTemplate << TagKind;
     Diag(TAT->getLocation(), diag::note_declared_at);
   }
-  
+
   QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs);
   if (Result.isNull())
     return TypeResult(true);
-  
+
   // Check the tag kind
   if (const RecordType *RT = Result->getAs<RecordType>()) {
     RecordDecl *D = RT->getDecl();
-    
+
     IdentifierInfo *Id = D->getIdentifier();
     assert(Id && "templated class must have an identifier");
-    
+
     if (!isAcceptableTagRedeclaration(D, TagKind, TUK == TUK_Definition,
                                       TagLoc, Id)) {
       Diag(TagLoc, diag::err_use_with_wrong_tag)
@@ -2533,10 +3059,6 @@
   return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result));
 }
 
-static bool CheckTemplatePartialSpecializationArgs(
-    Sema &S, SourceLocation NameLoc, TemplateParameterList *TemplateParams,
-    unsigned ExplicitArgs, SmallVectorImpl<TemplateArgument> &TemplateArgs);
-
 static bool CheckTemplateSpecializationScope(Sema &S, NamedDecl *Specialized,
                                              NamedDecl *PrevDecl,
                                              SourceLocation Loc,
@@ -2618,6 +3140,117 @@
   return TemplateArgs;
 }
 
+template<typename PartialSpecDecl>
+static void checkMoreSpecializedThanPrimary(Sema &S, PartialSpecDecl *Partial) {
+  if (Partial->getDeclContext()->isDependentContext())
+    return;
+
+  // FIXME: Get the TDK from deduction in order to provide better diagnostics
+  // for non-substitution-failure issues?
+  TemplateDeductionInfo Info(Partial->getLocation());
+  if (S.isMoreSpecializedThanPrimary(Partial, Info))
+    return;
+
+  auto *Template = Partial->getSpecializedTemplate();
+  S.Diag(Partial->getLocation(),
+         diag::ext_partial_spec_not_more_specialized_than_primary)
+      << isa<VarTemplateDecl>(Template);
+
+  if (Info.hasSFINAEDiagnostic()) {
+    PartialDiagnosticAt Diag = {SourceLocation(),
+                                PartialDiagnostic::NullDiagnostic()};
+    Info.takeSFINAEDiagnostic(Diag);
+    SmallString<128> SFINAEArgString;
+    Diag.second.EmitToString(S.getDiagnostics(), SFINAEArgString);
+    S.Diag(Diag.first,
+           diag::note_partial_spec_not_more_specialized_than_primary)
+      << SFINAEArgString;
+  }
+
+  S.Diag(Template->getLocation(), diag::note_template_decl_here);
+}
+
+static void
+noteNonDeducibleParameters(Sema &S, TemplateParameterList *TemplateParams,
+                           const llvm::SmallBitVector &DeducibleParams) {
+  for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) {
+    if (!DeducibleParams[I]) {
+      NamedDecl *Param = cast<NamedDecl>(TemplateParams->getParam(I));
+      if (Param->getDeclName())
+        S.Diag(Param->getLocation(), diag::note_non_deducible_parameter)
+            << Param->getDeclName();
+      else
+        S.Diag(Param->getLocation(), diag::note_non_deducible_parameter)
+            << "(anonymous)";
+    }
+  }
+}
+
+
+template<typename PartialSpecDecl>
+static void checkTemplatePartialSpecialization(Sema &S,
+                                               PartialSpecDecl *Partial) {
+  // C++1z [temp.class.spec]p8: (DR1495)
+  //   - The specialization shall be more specialized than the primary
+  //     template (14.5.5.2).
+  checkMoreSpecializedThanPrimary(S, Partial);
+
+  // C++ [temp.class.spec]p8: (DR1315)
+  //   - Each template-parameter shall appear at least once in the
+  //     template-id outside a non-deduced context.
+  // C++1z [temp.class.spec.match]p3 (P0127R2)
+  //   If the template arguments of a partial specialization cannot be
+  //   deduced because of the structure of its template-parameter-list
+  //   and the template-id, the program is ill-formed.
+  auto *TemplateParams = Partial->getTemplateParameters();
+  llvm::SmallBitVector DeducibleParams(TemplateParams->size());
+  S.MarkUsedTemplateParameters(Partial->getTemplateArgs(), true,
+                               TemplateParams->getDepth(), DeducibleParams);
+
+  if (!DeducibleParams.all()) {
+    unsigned NumNonDeducible = DeducibleParams.size() - DeducibleParams.count();
+    S.Diag(Partial->getLocation(), diag::ext_partial_specs_not_deducible)
+      << isa<VarTemplatePartialSpecializationDecl>(Partial)
+      << (NumNonDeducible > 1)
+      << SourceRange(Partial->getLocation(),
+                     Partial->getTemplateArgsAsWritten()->RAngleLoc);
+    noteNonDeducibleParameters(S, TemplateParams, DeducibleParams);
+  }
+}
+
+void Sema::CheckTemplatePartialSpecialization(
+    ClassTemplatePartialSpecializationDecl *Partial) {
+  checkTemplatePartialSpecialization(*this, Partial);
+}
+
+void Sema::CheckTemplatePartialSpecialization(
+    VarTemplatePartialSpecializationDecl *Partial) {
+  checkTemplatePartialSpecialization(*this, Partial);
+}
+
+void Sema::CheckDeductionGuideTemplate(FunctionTemplateDecl *TD) {
+  // C++1z [temp.param]p11:
+  //   A template parameter of a deduction guide template that does not have a
+  //   default-argument shall be deducible from the parameter-type-list of the
+  //   deduction guide template.
+  auto *TemplateParams = TD->getTemplateParameters();
+  llvm::SmallBitVector DeducibleParams(TemplateParams->size());
+  MarkDeducedTemplateParameters(TD, DeducibleParams);
+  for (unsigned I = 0; I != TemplateParams->size(); ++I) {
+    // A parameter pack is deducible (to an empty pack).
+    auto *Param = TemplateParams->getParam(I);
+    if (Param->isParameterPack() || hasVisibleDefaultArgument(Param))
+      DeducibleParams[I] = true;
+  }
+
+  if (!DeducibleParams.all()) {
+    unsigned NumNonDeducible = DeducibleParams.size() - DeducibleParams.count();
+    Diag(TD->getLocation(), diag::err_deduction_guide_template_not_deducible)
+      << (NumNonDeducible > 1);
+    noteNonDeducibleParameters(*this, TemplateParams, DeducibleParams);
+  }
+}
+
 DeclResult Sema::ActOnVarTemplateSpecialization(
     Scope *S, Declarator &D, TypeSourceInfo *DI, SourceLocation TemplateKWLoc,
     TemplateParameterList *TemplateParams, StorageClass SC,
@@ -2667,11 +3300,12 @@
   // Find the variable template (partial) specialization declaration that
   // corresponds to these arguments.
   if (IsPartialSpecialization) {
-    if (CheckTemplatePartialSpecializationArgs(
-            *this, TemplateNameLoc, VarTemplate->getTemplateParameters(),
-            TemplateArgs.size(), Converted))
+    if (CheckTemplatePartialSpecializationArgs(TemplateNameLoc, VarTemplate,
+                                               TemplateArgs.size(), Converted))
       return true;
 
+    // FIXME: Move these checks to CheckTemplatePartialSpecializationArgs so we
+    // also do them during instantiation.
     bool InstantiationDependent;
     if (!Name.isDependent() &&
         !TemplateSpecializationType::anyDependentTemplateArguments(
@@ -2743,32 +3377,7 @@
     if (PrevPartial && PrevPartial->getInstantiatedFromMember())
       PrevPartial->setMemberSpecialization();
 
-    // Check that all of the template parameters of the variable template
-    // partial specialization are deducible from the template
-    // arguments. If not, this variable template partial specialization
-    // will never be used.
-    llvm::SmallBitVector DeducibleParams(TemplateParams->size());
-    MarkUsedTemplateParameters(Partial->getTemplateArgs(), true,
-                               TemplateParams->getDepth(), DeducibleParams);
-
-    if (!DeducibleParams.all()) {
-      unsigned NumNonDeducible =
-          DeducibleParams.size() - DeducibleParams.count();
-      Diag(TemplateNameLoc, diag::warn_partial_specs_not_deducible)
-        << /*variable template*/ 1 << (NumNonDeducible > 1)
-        << SourceRange(TemplateNameLoc, RAngleLoc);
-      for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) {
-        if (!DeducibleParams[I]) {
-          NamedDecl *Param = cast<NamedDecl>(TemplateParams->getParam(I));
-          if (Param->getDeclName())
-            Diag(Param->getLocation(), diag::note_partial_spec_unused_parameter)
-                << Param->getDeclName();
-          else
-            Diag(Param->getLocation(), diag::note_partial_spec_unused_parameter)
-                << "(anonymous)";
-        }
-      }
-    }
+    CheckTemplatePartialSpecialization(Partial);
   } else {
     // Create a new class template specialization declaration node for
     // this explicit specialization or friend declaration.
@@ -3123,7 +3732,8 @@
                                                   UnqualifiedId &Name,
                                                   ParsedType ObjectType,
                                                   bool EnteringContext,
-                                                  TemplateTy &Result) {
+                                                  TemplateTy &Result,
+                                                  bool AllowInjectedClassName) {
   if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent())
     Diag(TemplateKWLoc,
          getLangOpts().CPlusPlus11 ?
@@ -3171,6 +3781,24 @@
       return TNK_Non_template;
     } else {
       // We found something; return it.
+      auto *LookupRD = dyn_cast<CXXRecordDecl>(LookupCtx);
+      if (!AllowInjectedClassName && SS.isSet() && LookupRD &&
+          Name.getKind() == UnqualifiedId::IK_Identifier && Name.Identifier &&
+          LookupRD->getIdentifier() == Name.Identifier) {
+        // C++14 [class.qual]p2:
+        //   In a lookup in which function names are not ignored and the
+        //   nested-name-specifier nominates a class C, if the name specified
+        //   [...] is the injected-class-name of C, [...] the name is instead
+        //   considered to name the constructor
+        //
+        // We don't get here if naming the constructor would be valid, so we
+        // just reject immediately and recover by treating the
+        // injected-class-name as naming the template.
+        Diag(Name.getLocStart(),
+             diag::ext_out_of_line_qualified_id_type_names_constructor)
+          << Name.Identifier << 0 /*injected-class-name used as template name*/
+          << 1 /*'template' keyword was used*/;
+      }
       return TNK;
     }
   }
@@ -3225,7 +3853,7 @@
     SourceRange SR = AL.getSourceRange();
     TemplateName Name = Arg.getAsTemplate();
     Diag(SR.getBegin(), diag::err_template_missing_args)
-      << Name << SR;
+      << (int)getTemplateNameKindForDiagnostics(Name) << Name << SR;
     if (TemplateDecl *Decl = Name.getAsTemplateDecl())
       Diag(Decl->getLocation(), diag::note_template_decl_here);
 
@@ -3304,7 +3932,7 @@
 
   // Add the converted template type argument.
   ArgType = Context.getCanonicalType(ArgType);
-  
+
   // Objective-C ARC:
   //   If an explicitly-specified template argument type is a lifetime type
   //   with no lifetime qualifier, the __strong lifetime qualifier is inferred.
@@ -3315,7 +3943,7 @@
     Qs.setObjCLifetime(Qualifiers::OCL_Strong);
     ArgType = Context.getQualifiedType(ArgType, Qs);
   }
-  
+
   Converted.push_back(TemplateArgument(ArgType));
   return false;
 }
@@ -3347,7 +3975,7 @@
                              SourceLocation TemplateLoc,
                              SourceLocation RAngleLoc,
                              TemplateTypeParmDecl *Param,
-                         SmallVectorImpl<TemplateArgument> &Converted) {
+                             SmallVectorImpl<TemplateArgument> &Converted) {
   TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo();
 
   // If the argument type is dependent, instantiate it now based
@@ -3445,7 +4073,7 @@
 /// \param Converted the list of template arguments provided for template
 /// parameters that precede \p Param in the template parameter list.
 ///
-/// \param QualifierLoc Will be set to the nested-name-specifier (with 
+/// \param QualifierLoc Will be set to the nested-name-specifier (with
 /// source-location information) that precedes the template name.
 ///
 /// \returns the substituted template argument, or NULL if an error occurred.
@@ -3556,6 +4184,39 @@
                 TempTempParm->getDefaultArgument().getTemplateNameLoc());
 }
 
+/// Convert a template-argument that we parsed as a type into a template, if
+/// possible. C++ permits injected-class-names to perform dual service as
+/// template template arguments and as template type arguments.
+static TemplateArgumentLoc convertTypeTemplateArgumentToTemplate(TypeLoc TLoc) {
+  // Extract and step over any surrounding nested-name-specifier.
+  NestedNameSpecifierLoc QualLoc;
+  if (auto ETLoc = TLoc.getAs<ElaboratedTypeLoc>()) {
+    if (ETLoc.getTypePtr()->getKeyword() != ETK_None)
+      return TemplateArgumentLoc();
+
+    QualLoc = ETLoc.getQualifierLoc();
+    TLoc = ETLoc.getNamedTypeLoc();
+  }
+
+  // If this type was written as an injected-class-name, it can be used as a
+  // template template argument.
+  if (auto InjLoc = TLoc.getAs<InjectedClassNameTypeLoc>())
+    return TemplateArgumentLoc(InjLoc.getTypePtr()->getTemplateName(),
+                               QualLoc, InjLoc.getNameLoc());
+
+  // If this type was written as an injected-class-name, it may have been
+  // converted to a RecordType during instantiation. If the RecordType is
+  // *not* wrapped in a TemplateSpecializationType and denotes a class
+  // template specialization, it must have come from an injected-class-name.
+  if (auto RecLoc = TLoc.getAs<RecordTypeLoc>())
+    if (auto *CTSD =
+            dyn_cast<ClassTemplateSpecializationDecl>(RecLoc.getDecl()))
+      return TemplateArgumentLoc(TemplateName(CTSD->getSpecializedTemplate()),
+                                 QualLoc, RecLoc.getNameLoc());
+
+  return TemplateArgumentLoc();
+}
+
 /// \brief Check that the given template argument corresponds to the given
 /// template parameter.
 ///
@@ -3762,6 +4423,17 @@
       return true;
   }
 
+  // C++1z [temp.local]p1: (DR1004)
+  //   When [the injected-class-name] is used [...] as a template-argument for
+  //   a template template-parameter [...] it refers to the class template
+  //   itself.
+  if (Arg.getArgument().getKind() == TemplateArgument::Type) {
+    TemplateArgumentLoc ConvertedArg = convertTypeTemplateArgumentToTemplate(
+        Arg.getTypeSourceInfo()->getTypeLoc());
+    if (!ConvertedArg.getArgument().isNull())
+      Arg = ConvertedArg;
+  }
+
   switch (Arg.getArgument().getKind()) {
   case TemplateArgument::Null:
     llvm_unreachable("Should never see a NULL template argument here");
@@ -3796,7 +4468,7 @@
   return false;
 }
 
-/// \brief Diagnose an arity mismatch in the 
+/// \brief Diagnose an arity mismatch in the
 static bool diagnoseArityMismatch(Sema &S, TemplateDecl *Template,
                                   SourceLocation TemplateLoc,
                                   TemplateArgumentListInfo &TemplateArgs) {
@@ -3806,13 +4478,11 @@
 
   SourceRange Range;
   if (NumArgs > NumParams)
-    Range = SourceRange(TemplateArgs[NumParams].getLocation(), 
+    Range = SourceRange(TemplateArgs[NumParams].getLocation(),
                         TemplateArgs.getRAngleLoc());
   S.Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
     << (NumArgs > NumParams)
-    << (isa<ClassTemplateDecl>(Template)? 0 :
-        isa<FunctionTemplateDecl>(Template)? 1 :
-        isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
+    << (int)S.getTemplateNameKindForDiagnostics(TemplateName(Template))
     << Template << Range;
   S.Diag(Template->getLocation(), diag::note_template_decl_here)
     << Params->getSourceRange();
@@ -3877,11 +4547,11 @@
 
 /// \brief Check that the given template argument list is well-formed
 /// for specializing the given template.
-bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
-                                     SourceLocation TemplateLoc,
-                                     TemplateArgumentListInfo &TemplateArgs,
-                                     bool PartialTemplateArgs,
-                          SmallVectorImpl<TemplateArgument> &Converted) {
+bool Sema::CheckTemplateArgumentList(
+    TemplateDecl *Template, SourceLocation TemplateLoc,
+    TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
+    SmallVectorImpl<TemplateArgument> &Converted,
+    bool UpdateArgsWithConversions) {
   // Make a copy of the template arguments for processing.  Only make the
   // changes at the end when successful in matching the arguments to the
   // template.
@@ -3920,9 +4590,7 @@
         // Not enough arguments for this parameter pack.
         Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
           << false
-          << (isa<ClassTemplateDecl>(Template)? 0 :
-              isa<FunctionTemplateDecl>(Template)? 1 :
-              isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
+          << (int)getTemplateNameKindForDiagnostics(TemplateName(Template))
           << Template;
         Diag(Template->getLocation(), diag::note_template_decl_here)
           << Params->getSourceRange();
@@ -4121,7 +4789,8 @@
 
   // No problems found with the new argument list, propagate changes back
   // to caller.
-  TemplateArgs = std::move(NewArgs);
+  if (UpdateArgsWithConversions)
+    TemplateArgs = std::move(NewArgs);
 
   return false;
 }
@@ -4139,7 +4808,7 @@
     UnnamedLocalNoLinkageFinder(Sema &S, SourceRange SR) : S(S), SR(SR) { }
 
     bool Visit(QualType T) {
-      return inherited::Visit(T.getTypePtr());
+      return T.isNull() ? false : inherited::Visit(T.getTypePtr());
     }
 
 #define TYPE(Class, Parent) \
@@ -4261,6 +4930,11 @@
   return Visit(T->getDeducedType());
 }
 
+bool UnnamedLocalNoLinkageFinder::VisitDeducedTemplateSpecializationType(
+    const DeducedTemplateSpecializationType *T) {
+  return Visit(T->getDeducedType());
+}
+
 bool UnnamedLocalNoLinkageFinder::VisitRecordType(const RecordType* T) {
   return VisitTagDecl(T->getDecl());
 }
@@ -4392,17 +5066,7 @@
   //
   // C++11 allows these, and even in C++03 we allow them as an extension with
   // a warning.
-  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) {
+  if (LangOpts.CPlusPlus11 || Arg->hasUnnamedOrLocalType()) {
     UnnamedLocalNoLinkageFinder Finder(*this, SR);
     (void)Finder.Visit(Context.getCanonicalType(Arg));
   }
@@ -4430,20 +5094,20 @@
 
   if (!S.getLangOpts().CPlusPlus11)
     return NPV_NotNullPointer;
-  
+
   // Determine whether we have a constant expression.
   ExprResult ArgRV = S.DefaultFunctionArrayConversion(Arg);
   if (ArgRV.isInvalid())
     return NPV_Error;
   Arg = ArgRV.get();
-  
+
   Expr::EvalResult EvalResult;
   SmallVector<PartialDiagnosticAt, 8> Notes;
   EvalResult.Diag = &Notes;
   if (!Arg->EvaluateAsRValue(EvalResult, S.Context) ||
       EvalResult.HasSideEffects) {
     SourceLocation DiagLoc = Arg->getExprLoc();
-    
+
     // If our only note is the usual "invalid subexpression" note, just point
     // the caret at its location rather than producing an essentially
     // redundant note.
@@ -4452,21 +5116,21 @@
       DiagLoc = Notes[0].first;
       Notes.clear();
     }
-    
+
     S.Diag(DiagLoc, diag::err_template_arg_not_address_constant)
       << Arg->getType() << Arg->getSourceRange();
     for (unsigned I = 0, N = Notes.size(); I != N; ++I)
       S.Diag(Notes[I].first, Notes[I].second);
-    
+
     S.Diag(Param->getLocation(), diag::note_template_param_here);
     return NPV_Error;
   }
-  
+
   // C++11 [temp.arg.nontype]p1:
   //   - an address constant expression of type std::nullptr_t
   if (Arg->getType()->isNullPtrType())
     return NPV_NullPointer;
-  
+
   //   - a constant expression that evaluates to a null pointer value (4.10); or
   //   - a constant expression that evaluates to a null member pointer value
   //     (4.11); or
@@ -4479,7 +5143,7 @@
         S.IsQualificationConversion(Arg->getType(), ParamType, false,
                                      ObjCLifetimeConversion))
       return NPV_NullPointer;
-    
+
     // The types didn't match, but we know we got a null pointer; complain,
     // then recover as if the types were correct.
     S.Diag(Arg->getExprLoc(), diag::err_template_arg_wrongtype_null_constant)
@@ -4499,7 +5163,7 @@
     S.Diag(Param->getLocation(), diag::note_template_param_here);
     return NPV_NullPointer;
   }
-  
+
   // FIXME: If we ever want to support general, address-constant expressions
   // as non-type template arguments, we should return the ExprResult here to
   // be interpreted by the caller.
@@ -5002,9 +5666,28 @@
 
   // If the parameter type somehow involves auto, deduce the type now.
   if (getLangOpts().CPlusPlus1z && ParamType->isUndeducedType()) {
+    // During template argument deduction, we allow 'decltype(auto)' to
+    // match an arbitrary dependent argument.
+    // FIXME: The language rules don't say what happens in this case.
+    // FIXME: We get an opaque dependent type out of decltype(auto) if the
+    // expression is merely instantiation-dependent; is this enough?
+    if (CTAK == CTAK_Deduced && Arg->isTypeDependent()) {
+      auto *AT = dyn_cast<AutoType>(ParamType);
+      if (AT && AT->isDecltypeAuto()) {
+        Converted = TemplateArgument(Arg);
+        return Arg;
+      }
+    }
+
+    // When checking a deduced template argument, deduce from its type even if
+    // the type is dependent, in order to check the types of non-type template
+    // arguments line up properly in partial ordering.
+    Optional<unsigned> Depth;
+    if (CTAK != CTAK_Specified)
+      Depth = Param->getDepth() + 1;
     if (DeduceAutoType(
             Context.getTrivialTypeSourceInfo(ParamType, Param->getLocation()),
-                       Arg, ParamType) == DAR_Failed) {
+            Arg, ParamType, Depth) == DAR_Failed) {
       Diag(Arg->getExprLoc(),
            diag::err_non_type_template_parm_type_deduction_failure)
         << Param->getDeclName() << Param->getType() << Arg->getType()
@@ -5023,6 +5706,36 @@
     }
   }
 
+  // We should have already dropped all cv-qualifiers by now.
+  assert(!ParamType.hasQualifiers() &&
+         "non-type template parameter type cannot be qualified");
+
+  if (CTAK == CTAK_Deduced &&
+      !Context.hasSameType(ParamType.getNonLValueExprType(Context),
+                           Arg->getType())) {
+    // FIXME: If either type is dependent, we skip the check. This isn't
+    // correct, since during deduction we're supposed to have replaced each
+    // template parameter with some unique (non-dependent) placeholder.
+    // FIXME: If the argument type contains 'auto', we carry on and fail the
+    // type check in order to force specific types to be more specialized than
+    // 'auto'. It's not clear how partial ordering with 'auto' is supposed to
+    // work.
+    if ((ParamType->isDependentType() || Arg->isTypeDependent()) &&
+        !Arg->getType()->getContainedAutoType()) {
+      Converted = TemplateArgument(Arg);
+      return Arg;
+    }
+    // FIXME: This attempts to implement C++ [temp.deduct.type]p17. Per DR1770,
+    // we should actually be checking the type of the template argument in P,
+    // not the type of the template argument deduced from A, against the
+    // template parameter type.
+    Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
+      << Arg->getType()
+      << ParamType.getUnqualifiedType();
+    Diag(Param->getLocation(), diag::note_template_param_here);
+    return ExprError();
+  }
+
   // If either the parameter has a dependent type or the argument is
   // type-dependent, there's nothing we can check now.
   if (ParamType->isDependentType() || Arg->isTypeDependent()) {
@@ -5031,35 +5744,12 @@
     return Arg;
   }
 
-  // We should have already dropped all cv-qualifiers by now.
-  assert(!ParamType.hasQualifiers() &&
-         "non-type template parameter type cannot be qualified");
-
-  if (CTAK == CTAK_Deduced &&
-      !Context.hasSameUnqualifiedType(ParamType, Arg->getType())) {
-    // C++ [temp.deduct.type]p17:
-    //   If, in the declaration of a function template with a non-type
-    //   template-parameter, the non-type template-parameter is used
-    //   in an expression in the function parameter-list and, if the
-    //   corresponding template-argument is deduced, the
-    //   template-argument type shall match the type of the
-    //   template-parameter exactly, except that a template-argument
-    //   deduced from an array bound may be of any integral type.
-    Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
-      << Arg->getType().getUnqualifiedType()
-      << ParamType.getUnqualifiedType();
-    Diag(Param->getLocation(), diag::note_template_param_here);
-    return ExprError();
-  }
+  // The initialization of the parameter from the argument is
+  // a constant-evaluated context.
+  EnterExpressionEvaluationContext ConstantEvaluated(*this,
+                                                     Sema::ConstantEvaluated);
 
   if (getLangOpts().CPlusPlus1z) {
-    // FIXME: We can do some limited checking for a value-dependent but not
-    // type-dependent argument.
-    if (Arg->isValueDependent()) {
-      Converted = TemplateArgument(Arg);
-      return Arg;
-    }
-
     // C++1z [temp.arg.nontype]p1:
     //   A template-argument for a non-type template parameter shall be
     //   a converted constant expression of the type of the template-parameter.
@@ -5069,6 +5759,13 @@
     if (ArgResult.isInvalid())
       return ExprError();
 
+    // For a value-dependent argument, CheckConvertedConstantExpression is
+    // permitted (and expected) to be unable to determine a value.
+    if (ArgResult.get()->isValueDependent()) {
+      Converted = TemplateArgument(ArgResult.get());
+      return ArgResult;
+    }
+
     QualType CanonParamType = Context.getCanonicalType(ParamType);
 
     // Convert the APValue to a TemplateArgument.
@@ -5173,14 +5870,6 @@
     //      conversions (4.7) are applied.
 
     if (getLangOpts().CPlusPlus11) {
-      // We can't check arbitrary value-dependent arguments.
-      // FIXME: If there's no viable conversion to the template parameter type,
-      // we should be able to diagnose that prior to instantiation.
-      if (Arg->isValueDependent()) {
-        Converted = TemplateArgument(Arg);
-        return Arg;
-      }
-
       // C++ [temp.arg.nontype]p1:
       //   A template-argument for a non-type, non-template template-parameter
       //   shall be one of:
@@ -5195,6 +5884,12 @@
       if (ArgResult.isInvalid())
         return ExprError();
 
+      // We can't check arbitrary value-dependent arguments.
+      if (ArgResult.get()->isValueDependent()) {
+        Converted = TemplateArgument(ArgResult.get());
+        return ArgResult;
+      }
+
       // Widen the argument value to sizeof(parameter type). This is almost
       // always a no-op, except when the parameter type is bool. In
       // that case, this may extend the argument from 1 bit to 8 bits.
@@ -5233,7 +5928,7 @@
     } else if (!Arg->isValueDependent()) {
       class TmplArgICEDiagnoser : public VerifyICEDiagnoser {
         QualType T;
-        
+
       public:
         TmplArgICEDiagnoser(QualType T) : T(T) { }
 
@@ -5295,14 +5990,14 @@
       Value.setIsSigned(IntegerType->isSignedIntegerOrEnumerationType());
     } else {
       llvm::APSInt OldValue = Value;
-      
+
       // Coerce the template argument's value to the value it will have
       // based on the template parameter's type.
       unsigned AllowedBits = Context.getTypeSize(IntegerType);
       if (Value.getBitWidth() != AllowedBits)
         Value = Value.extOrTrunc(AllowedBits);
       Value.setIsSigned(IntegerType->isSignedIntegerOrEnumerationType());
-      
+
       // Complain if an unsigned parameter received a negative value.
       if (IntegerType->isUnsignedIntegerOrEnumerationType()
                && (OldValue.isSigned() && OldValue.isNegative())) {
@@ -5311,7 +6006,7 @@
           << Arg->getSourceRange();
         Diag(Param->getLocation(), diag::note_template_param_here);
       }
-      
+
       // Complain if we overflowed the template parameter's type.
       unsigned RequiredBits;
       if (IntegerType->isUnsignedIntegerOrEnumerationType())
@@ -5330,7 +6025,7 @@
     }
 
     Converted = TemplateArgument(Context, Value,
-                                 ParamType->isEnumeralType() 
+                                 ParamType->isEnumeralType()
                                    ? Context.getCanonicalType(ParamType)
                                    : IntegerType);
     return Arg;
@@ -5442,17 +6137,17 @@
       Converted = TemplateArgument(Arg);
       return Arg;
     }
-    
+
     switch (isNullPointerValueTemplateArgument(*this, Param, ParamType, Arg)) {
     case NPV_NotNullPointer:
       Diag(Arg->getExprLoc(), diag::err_template_arg_not_convertible)
         << Arg->getType() << ParamType;
       Diag(Param->getLocation(), diag::note_template_param_here);
       return ExprError();
-      
+
     case NPV_Error:
       return ExprError();
-      
+
     case NPV_NullPointer:
       Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
       Converted = TemplateArgument(Context.getCanonicalType(ParamType),
@@ -5471,6 +6166,10 @@
   return Arg;
 }
 
+static void DiagnoseTemplateParameterListArityMismatch(
+    Sema &S, TemplateParameterList *New, TemplateParameterList *Old,
+    Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc);
+
 /// \brief Check a template argument against its corresponding
 /// template template parameter.
 ///
@@ -5487,6 +6186,9 @@
     return false;
   }
 
+  if (Template->isInvalidDecl())
+    return true;
+
   // C++0x [temp.arg.template]p1:
   //   A template-argument for a template template-parameter shall be
   //   the name of a class template or an alias template, expressed as an
@@ -5514,6 +6216,25 @@
   if (Param->isExpandedParameterPack())
     Params = Param->getExpansionTemplateParameters(ArgumentPackIndex);
 
+  // C++1z [temp.arg.template]p3: (DR 150)
+  //   A template-argument matches a template template-parameter P when P
+  //   is at least as specialized as the template-argument A.
+  if (getLangOpts().RelaxedTemplateTemplateArgs) {
+    // Quick check for the common case:
+    //   If P contains a parameter pack, then A [...] matches P if each of A's
+    //   template parameters matches the corresponding template parameter in
+    //   the template-parameter-list of P.
+    if (TemplateParameterListsAreEqual(
+            Template->getTemplateParameters(), Params, false,
+            TPL_TemplateTemplateArgumentMatch, Arg.getLocation()))
+      return false;
+
+    if (isTemplateTemplateParameterAtLeastAsSpecializedAs(Params, Template,
+                                                          Arg.getLocation()))
+      return false;
+    // FIXME: Produce better diagnostics for deduction failures.
+  }
+
   return !TemplateParameterListsAreEqual(Template->getTemplateParameters(),
                                          Params,
                                          true,
@@ -5613,8 +6334,9 @@
     if (RefExpr.isInvalid())
       return ExprError();
 
-    if (T->isFunctionType() || T->isArrayType()) {
-      // Decay functions and arrays.
+    if (!Context.hasSameUnqualifiedType(ParamType->getPointeeType(), T) &&
+        (T->isFunctionType() || T->isArrayType())) {
+      // Decay functions and arrays unless we're forming a pointer to array.
       RefExpr = DefaultFunctionArrayConversion(RefExpr.get());
       if (RefExpr.isInvalid())
         return ExprError();
@@ -5699,10 +6421,19 @@
                                Context.getTrivialTypeSourceInfo(OrigT, Loc),
                                Loc, Loc);
   }
-  
+
   return E;
 }
 
+static bool isDependentOnOuter(NonTypeTemplateParmDecl *NTTP) {
+  if (NTTP->getDepth() == 0 || !NTTP->getType()->isDependentType())
+    return false;
+  DependencyChecker Checker(NTTP->getDepth(), /*IgnoreNonTypeDependent*/ false,
+                            /*FindLessThanDepth*/ true);
+  Checker.TraverseType(NTTP->getType());
+  return Checker.Match;
+}
+
 /// \brief Match two template parameters within template parameter lists.
 static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old,
                                        bool Complain,
@@ -5725,7 +6456,7 @@
     return false;
   }
 
-  // Check that both are parameter packs are neither are parameter packs.
+  // Check that both are parameter packs or neither are parameter packs.
   // However, if we are matching a template template argument to a
   // template template parameter, the template template parameter can have
   // a parameter pack where the template template argument does not.
@@ -5759,11 +6490,10 @@
 
     // If we are matching a template template argument to a template
     // template parameter and one of the non-type template parameter types
-    // is dependent, then we must wait until template instantiation time
-    // to actually compare the arguments.
+    // is dependent on an outer template's parameter, then we must wait until
+    // template instantiation time to actually compare the arguments.
     if (Kind == Sema::TPL_TemplateTemplateArgumentMatch &&
-        (OldNTTP->getType()->isDependentType() ||
-         NewNTTP->getType()->isDependentType()))
+        (isDependentOnOuter(OldNTTP) || isDependentOnOuter(NewNTTP)))
       return true;
 
     if (!S.Context.hasSameType(OldNTTP->getType(), NewNTTP->getType())) {
@@ -6062,7 +6792,7 @@
       // Do not warn for class scope explicit specialization during
       // instantiation, warning was already emitted during pattern
       // semantic analysis.
-      if (!S.ActiveTemplateInstantiations.size())
+      if (!S.inTemplateInstantiation())
         S.Diag(Loc, diag::ext_function_specialization_in_class)
           << Specialized;
     } else {
@@ -6080,7 +6810,7 @@
       << Specialized;
     return true;
   }
-  
+
   // C++ [temp.class.spec]p6:
   //   A class template partial specialization may be declared or redeclared
   //   in any namespace scope in which its definition may be defined (14.5.1
@@ -6158,12 +6888,12 @@
   return false;
 }
 
-static SourceRange findTemplateParameter(unsigned Depth, Expr *E) {
-  if (!E->isInstantiationDependent())
+static SourceRange findTemplateParameterInType(unsigned Depth, Expr *E) {
+  if (!E->isTypeDependent())
     return SourceLocation();
-  DependencyChecker Checker(Depth);
+  DependencyChecker Checker(Depth, /*IgnoreNonTypeDependent*/true);
   Checker.TraverseStmt(E);
-  if (Checker.Match && Checker.MatchLoc.isInvalid())
+  if (Checker.MatchLoc.isInvalid())
     return E->getSourceRange();
   return Checker.MatchLoc;
 }
@@ -6171,9 +6901,9 @@
 static SourceRange findTemplateParameter(unsigned Depth, TypeLoc TL) {
   if (!TL.getType()->isDependentType())
     return SourceLocation();
-  DependencyChecker Checker(Depth);
+  DependencyChecker Checker(Depth, /*IgnoreNonTypeDependent*/true);
   Checker.TraverseTypeLoc(TL);
-  if (Checker.Match && Checker.MatchLoc.isInvalid())
+  if (Checker.MatchLoc.isInvalid())
     return TL.getSourceRange();
   return Checker.MatchLoc;
 }
@@ -6225,8 +6955,16 @@
     //        shall not involve a template parameter of the partial
     //        specialization except when the argument expression is a
     //        simple identifier.
+    //     -- The type of a template parameter corresponding to a
+    //        specialized non-type argument shall not be dependent on a
+    //        parameter of the specialization.
+    // DR1315 removes the first bullet, leaving an incoherent set of rules.
+    // We implement a compromise between the original rules and DR1315:
+    //     --  A specialized non-type template argument shall not be
+    //         type-dependent and the corresponding template parameter
+    //         shall have a non-dependent type.
     SourceRange ParamUseRange =
-        findTemplateParameter(Param->getDepth(), ArgExpr);
+        findTemplateParameterInType(Param->getDepth(), ArgExpr);
     if (ParamUseRange.isValid()) {
       if (IsDefaultArgument) {
         S.Diag(TemplateNameLoc,
@@ -6242,26 +6980,15 @@
       return true;
     }
 
-    //     -- The type of a template parameter corresponding to a
-    //        specialized non-type argument shall not be dependent on a
-    //        parameter of the specialization.
-    //
-    // FIXME: We need to delay this check until instantiation in some cases:
-    //
-    //   template<template<typename> class X> struct A {
-    //     template<typename T, X<T> N> struct B;
-    //     template<typename T> struct B<T, 0>;
-    //   };
-    //   template<typename> using X = int;
-    //   A<X>::B<int, 0> b;
     ParamUseRange = findTemplateParameter(
-            Param->getDepth(), Param->getTypeSourceInfo()->getTypeLoc());
+        Param->getDepth(), Param->getTypeSourceInfo()->getTypeLoc());
     if (ParamUseRange.isValid()) {
       S.Diag(IsDefaultArgument ? TemplateNameLoc : ArgExpr->getLocStart(),
              diag::err_dependent_typed_non_type_arg_in_partial_spec)
-        << Param->getType() << ParamUseRange;
+        << Param->getType();
       S.Diag(Param->getLocation(), diag::note_template_param_here)
-        << (IsDefaultArgument ? ParamUseRange : SourceRange());
+        << (IsDefaultArgument ? ParamUseRange : SourceRange())
+        << ParamUseRange;
       return true;
     }
   }
@@ -6273,27 +7000,32 @@
 /// partial specialization according to C++ [temp.class.spec]p9.
 ///
 /// \param TemplateNameLoc the location of the template name.
-/// \param TemplateParams the template parameters of the primary class
+/// \param PrimaryTemplate the template parameters of the primary class
 ///        template.
 /// \param NumExplicit the number of explicitly-specified template arguments.
 /// \param TemplateArgs the template arguments of the class template
 ///        partial specialization.
 ///
 /// \returns \c true if there was an error, \c false otherwise.
-static bool CheckTemplatePartialSpecializationArgs(
-    Sema &S, SourceLocation TemplateNameLoc,
-    TemplateParameterList *TemplateParams, unsigned NumExplicit,
-    SmallVectorImpl<TemplateArgument> &TemplateArgs) {
-  const TemplateArgument *ArgList = TemplateArgs.data();
+bool Sema::CheckTemplatePartialSpecializationArgs(
+    SourceLocation TemplateNameLoc, TemplateDecl *PrimaryTemplate,
+    unsigned NumExplicit, ArrayRef<TemplateArgument> TemplateArgs) {
+  // We have to be conservative when checking a template in a dependent
+  // context.
+  if (PrimaryTemplate->getDeclContext()->isDependentContext())
+    return false;
 
+  TemplateParameterList *TemplateParams =
+      PrimaryTemplate->getTemplateParameters();
   for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
     NonTypeTemplateParmDecl *Param
       = dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(I));
     if (!Param)
       continue;
 
-    if (CheckNonTypeTemplatePartialSpecializationArgs(
-            S, TemplateNameLoc, Param, &ArgList[I], 1, I >= NumExplicit))
+    if (CheckNonTypeTemplatePartialSpecializationArgs(*this, TemplateNameLoc,
+                                                      Param, &TemplateArgs[I],
+                                                      1, I >= NumExplicit))
       return true;
   }
 
@@ -6334,7 +7066,7 @@
     return true;
   }
 
-  bool isExplicitSpecialization = false;
+  bool isMemberSpecialization = false;
   bool isPartialSpecialization = false;
 
   // Check the validity of the template headers that introduce this
@@ -6345,7 +7077,7 @@
   TemplateParameterList *TemplateParams =
       MatchTemplateParametersToScopeSpecifier(
           KWLoc, TemplateNameLoc, SS, &TemplateId,
-          TemplateParameterLists, TUK == TUK_Friend, isExplicitSpecialization,
+          TemplateParameterLists, TUK == TUK_Friend, isMemberSpecialization,
           Invalid);
   if (Invalid)
     return true;
@@ -6395,8 +7127,6 @@
                                 SourceRange(TemplateParams->getTemplateLoc(),
                                             TemplateParams->getRAngleLoc()))
         << SourceRange(LAngleLoc, RAngleLoc);
-    else
-      isExplicitSpecialization = true;
   } else {
     assert(TUK == TUK_Friend && "should have a 'template<>' for this decl");
   }
@@ -6437,11 +7167,12 @@
   // Find the class template (partial) specialization declaration that
   // corresponds to these arguments.
   if (isPartialSpecialization) {
-    if (CheckTemplatePartialSpecializationArgs(
-            *this, TemplateNameLoc, ClassTemplate->getTemplateParameters(),
-            TemplateArgs.size(), Converted))
+    if (CheckTemplatePartialSpecializationArgs(TemplateNameLoc, ClassTemplate,
+                                               TemplateArgs.size(), Converted))
       return true;
 
+    // FIXME: Move this to CheckTemplatePartialSpecializationArgs so we
+    // also do it during instantiation.
     bool InstantiationDependent;
     if (!Name.isDependent() &&
         !TemplateSpecializationType::anyDependentTemplateArguments(
@@ -6486,6 +7217,9 @@
       //
       //   -- The argument list of the specialization shall not be identical
       //      to the implicit argument list of the primary template.
+      //
+      // This rule has since been removed, because it's redundant given DR1495,
+      // but we keep it because it produces better diagnostics and recovery.
       Diag(TemplateNameLoc, diag::err_partial_spec_args_match_primary_template)
         << /*class template*/0 << (TUK == TUK_Definition)
         << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc));
@@ -6528,34 +7262,7 @@
     if (PrevPartial && PrevPartial->getInstantiatedFromMember())
       PrevPartial->setMemberSpecialization();
 
-    // Check that all of the template parameters of the class template
-    // partial specialization are deducible from the template
-    // arguments. If not, this class template partial specialization
-    // will never be used.
-    llvm::SmallBitVector DeducibleParams(TemplateParams->size());
-    MarkUsedTemplateParameters(Partial->getTemplateArgs(), true,
-                               TemplateParams->getDepth(),
-                               DeducibleParams);
-
-    if (!DeducibleParams.all()) {
-      unsigned NumNonDeducible = DeducibleParams.size()-DeducibleParams.count();
-      Diag(TemplateNameLoc, diag::warn_partial_specs_not_deducible)
-        << /*class template*/0 << (NumNonDeducible > 1)
-        << SourceRange(TemplateNameLoc, RAngleLoc);
-      for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) {
-        if (!DeducibleParams[I]) {
-          NamedDecl *Param = cast<NamedDecl>(TemplateParams->getParam(I));
-          if (Param->getDeclName())
-            Diag(Param->getLocation(),
-                 diag::note_partial_spec_unused_parameter)
-              << Param->getDeclName();
-          else
-            Diag(Param->getLocation(),
-                 diag::note_partial_spec_unused_parameter)
-              << "(anonymous)";
-        }
-      }
-    }
+    CheckTemplatePartialSpecialization(Partial);
   } else {
     // Create a new class template specialization declaration node for
     // this explicit specialization or friend declaration.
@@ -6632,8 +7339,7 @@
       TUK = TUK_Declaration;
     } else if (Def) {
       SourceRange Range(TemplateNameLoc, RAngleLoc);
-      Diag(TemplateNameLoc, diag::err_redefinition)
-        << Context.getTypeDeclType(Specialization) << Range;
+      Diag(TemplateNameLoc, diag::err_redefinition) << Specialization << Range;
       Diag(Def->getLocation(), diag::note_previous_definition);
       Specialization->setInvalidDecl();
       return true;
@@ -6654,7 +7360,7 @@
     Diag(Specialization->getLocation(), diag::err_module_private_specialization)
       << (isPartialSpecialization? 1 : 0)
       << FixItHint::CreateRemoval(ModulePrivateLoc);
-  
+
   // Build the fully-sugared type for this class template
   // specialization as the user wrote in the specialization
   // itself. This means that we'll pretty-print the type retrieved
@@ -7134,7 +7840,7 @@
                                          SpecInfo->getPointOfInstantiation(),
                                              HasNoEffect))
     return true;
-  
+
   // Mark the prior declaration as an explicit specialization, so that later
   // clients know that this is an explicit specialization.
   if (!isFriend) {
@@ -7508,8 +8214,8 @@
   ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(TD);
 
   if (!ClassTemplate) {
-    NonTagKind NTK = getNonTagTypeDeclKind(TD);
-    Diag(TemplateNameLoc, diag::err_tag_reference_non_tag) << NTK;
+    NonTagKind NTK = getNonTagTypeDeclKind(TD, Kind);
+    Diag(TemplateNameLoc, diag::err_tag_reference_non_tag) << TD << NTK << Kind;
     Diag(TD->getLocation(), diag::note_previous_use);
     return true;
   }
@@ -7672,6 +8378,7 @@
   Specialization->setTemplateKeywordLoc(TemplateLoc);
   Specialization->setBraceRange(SourceRange());
 
+  bool PreviouslyDLLExported = Specialization->hasAttr<DLLExportAttr>();
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
 
@@ -7734,8 +8441,9 @@
 
     // Fix a TSK_ImplicitInstantiation followed by a
     // TSK_ExplicitInstantiationDefinition
-    if (Old_TSK == TSK_ImplicitInstantiation &&
-        Specialization->hasAttr<DLLExportAttr>() &&
+    bool NewlyDLLExported =
+        !PreviouslyDLLExported && Specialization->hasAttr<DLLExportAttr>();
+    if (Old_TSK == TSK_ImplicitInstantiation && NewlyDLLExported &&
         (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
          Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
       // In the MS ABI, an explicit instantiation definition can add a dll
@@ -7923,18 +8631,18 @@
     return true;
 
   // C++ [dcl.stc]p1:
-  //   A storage-class-specifier shall not be specified in [...] an explicit 
+  //   A storage-class-specifier shall not be specified in [...] an explicit
   //   instantiation (14.7.2) directive.
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
     Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_of_typedef)
       << Name;
     return true;
-  } else if (D.getDeclSpec().getStorageClassSpec() 
+  } else if (D.getDeclSpec().getStorageClassSpec()
                                                 != DeclSpec::SCS_unspecified) {
     // Complain about then remove the storage class specifier.
     Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_storage_class)
       << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
-    
+
     D.getMutableDeclSpec().ClearStorageClassSpecs();
   }
 
@@ -7964,6 +8672,14 @@
     return true;
   }
 
+  // A deduction guide is not on the list of entities that can be explicitly
+  // instantiated.
+  if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) {
+    Diag(D.getDeclSpec().getLocStart(), diag::err_deduction_guide_specialized)
+      << /*explicit instantiation*/ 0;
+    return true;
+  }
+
   // C++0x [temp.explicit]p2:
   //   There are two forms of explicit instantiation: an explicit instantiation
   //   definition and an explicit instantiation declaration. An explicit
@@ -8316,7 +9032,7 @@
   // Create the resulting type.
   ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind);
   QualType Result = Context.getDependentNameType(Kwd, NNS, Name);
-  
+
   // Create type-source location information for this type.
   TypeLocBuilder TLB;
   DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(Result);
@@ -8332,7 +9048,7 @@
                         SourceLocation IdLoc) {
   if (SS.isInvalid())
     return true;
-  
+
   if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
     Diag(TypenameLoc,
          getLangOpts().CPlusPlus11 ?
@@ -8368,7 +9084,8 @@
                         const CXXScopeSpec &SS,
                         SourceLocation TemplateKWLoc,
                         TemplateTy TemplateIn,
-                        SourceLocation TemplateNameLoc,
+                        IdentifierInfo *TemplateII,
+                        SourceLocation TemplateIILoc,
                         SourceLocation LAngleLoc,
                         ASTTemplateArgsPtr TemplateArgsIn,
                         SourceLocation RAngleLoc) {
@@ -8378,11 +9095,24 @@
            diag::warn_cxx98_compat_typename_outside_of_template :
            diag::ext_typename_outside_of_template)
       << FixItHint::CreateRemoval(TypenameLoc);
-  
+
+  // Strangely, non-type results are not ignored by this lookup, so the
+  // program is ill-formed if it finds an injected-class-name.
+  if (TypenameLoc.isValid()) {
+    auto *LookupRD =
+        dyn_cast_or_null<CXXRecordDecl>(computeDeclContext(SS, false));
+    if (LookupRD && LookupRD->getIdentifier() == TemplateII) {
+      Diag(TemplateIILoc,
+           diag::ext_out_of_line_qualified_id_type_names_constructor)
+        << TemplateII << 0 /*injected-class-name used as template name*/
+        << (TemplateKWLoc.isValid() ? 1 : 0 /*'template'/'typename' keyword*/);
+    }
+  }
+
   // Translate the parser's template argument list in our AST format.
   TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
   translateTemplateArguments(TemplateArgsIn, TemplateArgs);
-  
+
   TemplateName Template = TemplateIn.get();
   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
     // Construct a dependent template specialization type.
@@ -8392,42 +9122,42 @@
                                                           DTN->getQualifier(),
                                                           DTN->getIdentifier(),
                                                                 TemplateArgs);
-    
+
     // Create source-location information for this type.
     TypeLocBuilder Builder;
-    DependentTemplateSpecializationTypeLoc SpecTL 
+    DependentTemplateSpecializationTypeLoc SpecTL
     = Builder.push<DependentTemplateSpecializationTypeLoc>(T);
     SpecTL.setElaboratedKeywordLoc(TypenameLoc);
     SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
     SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
-    SpecTL.setTemplateNameLoc(TemplateNameLoc);
+    SpecTL.setTemplateNameLoc(TemplateIILoc);
     SpecTL.setLAngleLoc(LAngleLoc);
     SpecTL.setRAngleLoc(RAngleLoc);
     for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
     return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
   }
-  
-  QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
+
+  QualType T = CheckTemplateIdType(Template, TemplateIILoc, TemplateArgs);
   if (T.isNull())
     return true;
-  
+
   // Provide source-location information for the template specialization type.
   TypeLocBuilder Builder;
   TemplateSpecializationTypeLoc SpecTL
     = Builder.push<TemplateSpecializationTypeLoc>(T);
   SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
-  SpecTL.setTemplateNameLoc(TemplateNameLoc);
+  SpecTL.setTemplateNameLoc(TemplateIILoc);
   SpecTL.setLAngleLoc(LAngleLoc);
   SpecTL.setRAngleLoc(RAngleLoc);
   for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
     SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
-  
+
   T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T);
   ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
   TL.setElaboratedKeywordLoc(TypenameLoc);
   TL.setQualifierLoc(SS.getWithLocInContext(Context));
-  
+
   TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
   return CreateParsedType(T, TSI);
 }
@@ -8472,9 +9202,9 @@
 /// \brief Build the type that describes a C++ typename specifier,
 /// e.g., "typename T::type".
 QualType
-Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, 
+Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
                         SourceLocation KeywordLoc,
-                        NestedNameSpecifierLoc QualifierLoc, 
+                        NestedNameSpecifierLoc QualifierLoc,
                         const IdentifierInfo &II,
                         SourceLocation IILoc) {
   CXXScopeSpec SS;
@@ -8485,8 +9215,8 @@
     // If the nested-name-specifier is dependent and couldn't be
     // resolved to a type, build a typename type.
     assert(QualifierLoc.getNestedNameSpecifier()->isDependent());
-    return Context.getDependentNameType(Keyword, 
-                                        QualifierLoc.getNestedNameSpecifier(), 
+    return Context.getDependentNameType(Keyword,
+                                        QualifierLoc.getNestedNameSpecifier(),
                                         &II);
   }
 
@@ -8538,20 +9268,55 @@
 
   case LookupResult::NotFoundInCurrentInstantiation:
     // Okay, it's a member of an unknown instantiation.
-    return Context.getDependentNameType(Keyword, 
-                                        QualifierLoc.getNestedNameSpecifier(), 
+    return Context.getDependentNameType(Keyword,
+                                        QualifierLoc.getNestedNameSpecifier(),
                                         &II);
 
   case LookupResult::Found:
     if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
+      // C++ [class.qual]p2:
+      //   In a lookup in which function names are not ignored and the
+      //   nested-name-specifier nominates a class C, if the name specified
+      //   after the nested-name-specifier, when looked up in C, is the
+      //   injected-class-name of C [...] then the name is instead considered
+      //   to name the constructor of class C.
+      //
+      // Unlike in an elaborated-type-specifier, function names are not ignored
+      // in typename-specifier lookup. However, they are ignored in all the
+      // contexts where we form a typename type with no keyword (that is, in
+      // mem-initializer-ids, base-specifiers, and elaborated-type-specifiers).
+      //
+      // FIXME: That's not strictly true: mem-initializer-id lookup does not
+      // ignore functions, but that appears to be an oversight.
+      auto *LookupRD = dyn_cast_or_null<CXXRecordDecl>(Ctx);
+      auto *FoundRD = dyn_cast<CXXRecordDecl>(Type);
+      if (Keyword == ETK_Typename && LookupRD && FoundRD &&
+          FoundRD->isInjectedClassName() &&
+          declaresSameEntity(LookupRD, cast<Decl>(FoundRD->getParent())))
+        Diag(IILoc, diag::ext_out_of_line_qualified_id_type_names_constructor)
+            << &II << 1 << 0 /*'typename' keyword used*/;
+
       // We found a type. Build an ElaboratedType, since the
       // typename-specifier was just sugar.
       MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
-      return Context.getElaboratedType(ETK_Typename, 
+      return Context.getElaboratedType(Keyword,
                                        QualifierLoc.getNestedNameSpecifier(),
                                        Context.getTypeDeclType(Type));
     }
 
+    // C++ [dcl.type.simple]p2:
+    //   A type-specifier of the form
+    //     typename[opt] nested-name-specifier[opt] template-name
+    //   is a placeholder for a deduced class type [...].
+    if (getLangOpts().CPlusPlus1z) {
+      if (auto *TD = getAsTypeTemplateDecl(Result.getFoundDecl())) {
+        return Context.getElaboratedType(
+            Keyword, QualifierLoc.getNestedNameSpecifier(),
+            Context.getDeducedTemplateSpecializationType(TemplateName(TD),
+                                                         QualType(), false));
+      }
+    }
+
     DiagID = diag::err_typename_nested_not_type;
     Referenced = Result.getFoundDecl();
     break;
@@ -8614,7 +9379,7 @@
       this->Loc = Loc;
       this->Entity = Entity;
     }
-      
+
     ExprResult TransformLambdaExpr(LambdaExpr *E) {
       // Lambdas never need to be transformed.
       return E;
@@ -8665,15 +9430,15 @@
 }
 
 bool Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) {
-  if (SS.isInvalid()) 
+  if (SS.isInvalid())
     return true;
 
   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
   CurrentInstantiationRebuilder Rebuilder(*this, SS.getRange().getBegin(),
                                           DeclarationName());
-  NestedNameSpecifierLoc Rebuilt 
+  NestedNameSpecifierLoc Rebuilt
     = Rebuilder.TransformNestedNameSpecifierLoc(QualifierLoc);
-  if (!Rebuilt) 
+  if (!Rebuilt)
     return true;
 
   SS.Adopt(Rebuilt);
@@ -8686,36 +9451,36 @@
                                                TemplateParameterList *Params) {
   for (unsigned I = 0, N = Params->size(); I != N; ++I) {
     Decl *Param = Params->getParam(I);
-    
+
     // There is nothing to rebuild in a type parameter.
     if (isa<TemplateTypeParmDecl>(Param))
       continue;
-    
+
     // Rebuild the template parameter list of a template template parameter.
-    if (TemplateTemplateParmDecl *TTP 
+    if (TemplateTemplateParmDecl *TTP
         = dyn_cast<TemplateTemplateParmDecl>(Param)) {
       if (RebuildTemplateParamsInCurrentInstantiation(
             TTP->getTemplateParameters()))
         return true;
-      
+
       continue;
     }
-    
+
     // Rebuild the type of a non-type template parameter.
     NonTypeTemplateParmDecl *NTTP = cast<NonTypeTemplateParmDecl>(Param);
-    TypeSourceInfo *NewTSI 
-      = RebuildTypeInCurrentInstantiation(NTTP->getTypeSourceInfo(), 
-                                          NTTP->getLocation(), 
+    TypeSourceInfo *NewTSI
+      = RebuildTypeInCurrentInstantiation(NTTP->getTypeSourceInfo(),
+                                          NTTP->getLocation(),
                                           NTTP->getDeclName());
     if (!NewTSI)
       return true;
-    
+
     if (NewTSI != NTTP->getTypeSourceInfo()) {
       NTTP->setTypeSourceInfo(NewTSI);
       NTTP->setType(NewTSI->getType());
     }
   }
-  
+
   return false;
 }
 
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index dc96d3f..4116ae9 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -19,6 +19,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeOrdering.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/Template.h"
@@ -105,16 +106,26 @@
 
 static Sema::TemplateDeductionResult
 DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
-                        const TemplateArgument *Params, unsigned NumParams,
-                        const TemplateArgument *Args, unsigned NumArgs,
+                        ArrayRef<TemplateArgument> Params,
+                        ArrayRef<TemplateArgument> Args,
                         TemplateDeductionInfo &Info,
                         SmallVectorImpl<DeducedTemplateArgument> &Deduced,
                         bool NumberOfArgumentsMustMatch);
 
+static void MarkUsedTemplateParameters(ASTContext &Ctx,
+                                       const TemplateArgument &TemplateArg,
+                                       bool OnlyDeduced, unsigned Depth,
+                                       llvm::SmallBitVector &Used);
+
+static void MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
+                                       bool OnlyDeduced, unsigned Level,
+                                       llvm::SmallBitVector &Deduced);
+
 /// \brief If the given expression is of a form that permits the deduction
 /// of a non-type template parameter, return the declaration of that
 /// non-type template parameter.
-static NonTypeTemplateParmDecl *getDeducedParameterFromExpr(Expr *E) {
+static NonTypeTemplateParmDecl *
+getDeducedParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) {
   // If we are within an alias template, the expression may have undergone
   // any number of parameter substitutions already.
   while (1) {
@@ -128,7 +139,9 @@
   }
 
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-    return dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
+    if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
+      if (NTTP->getDepth() == Info.getDeducedDepth())
+        return NTTP;
 
   return nullptr;
 }
@@ -158,6 +171,20 @@
   if (Y.isNull())
     return X;
 
+  // If we have two non-type template argument values deduced for the same
+  // parameter, they must both match the type of the parameter, and thus must
+  // match each other's type. As we're only keeping one of them, we must check
+  // for that now. The exception is that if either was deduced from an array
+  // bound, the type is permitted to differ.
+  if (!X.wasDeducedFromArrayBound() && !Y.wasDeducedFromArrayBound()) {
+    QualType XType = X.getNonTypeTemplateArgumentType();
+    if (!XType.isNull()) {
+      QualType YType = Y.getNonTypeTemplateArgumentType();
+      if (YType.isNull() || !Context.hasSameType(XType, YType))
+        return DeducedTemplateArgument();
+    }
+  }
+
   switch (X.getKind()) {
   case TemplateArgument::Null:
     llvm_unreachable("Non-deduced template arguments handled above");
@@ -184,9 +211,7 @@
         Y.getKind() == TemplateArgument::Declaration ||
         (Y.getKind() == TemplateArgument::Integral &&
          hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral())))
-      return DeducedTemplateArgument(X,
-                                     X.wasDeducedFromArrayBound() &&
-                                     Y.wasDeducedFromArrayBound());
+      return X.wasDeducedFromArrayBound() ? Y : X;
 
     // All other combinations are incompatible.
     return DeducedTemplateArgument();
@@ -208,37 +233,38 @@
     // All other combinations are incompatible.
     return DeducedTemplateArgument();
 
-  case TemplateArgument::Expression:
-    // If we deduced a dependent expression in one case and either an integral
-    // constant or a declaration in another case, keep the integral constant
-    // or declaration.
-    if (Y.getKind() == TemplateArgument::Integral ||
-        Y.getKind() == TemplateArgument::Declaration)
-      return DeducedTemplateArgument(Y, X.wasDeducedFromArrayBound() &&
-                                     Y.wasDeducedFromArrayBound());
+  case TemplateArgument::Expression: {
+    if (Y.getKind() != TemplateArgument::Expression)
+      return checkDeducedTemplateArguments(Context, Y, X);
 
-    if (Y.getKind() == TemplateArgument::Expression) {
-      // Compare the expressions for equality
-      llvm::FoldingSetNodeID ID1, ID2;
-      X.getAsExpr()->Profile(ID1, Context, true);
-      Y.getAsExpr()->Profile(ID2, Context, true);
-      if (ID1 == ID2)
-        return X;
-    }
+    // Compare the expressions for equality
+    llvm::FoldingSetNodeID ID1, ID2;
+    X.getAsExpr()->Profile(ID1, Context, true);
+    Y.getAsExpr()->Profile(ID2, Context, true);
+    if (ID1 == ID2)
+      return X.wasDeducedFromArrayBound() ? Y : X;
 
-    // All other combinations are incompatible.
+    // Differing dependent expressions are incompatible.
     return DeducedTemplateArgument();
+  }
 
   case TemplateArgument::Declaration:
+    assert(!X.wasDeducedFromArrayBound());
+
     // If we deduced a declaration and a dependent expression, keep the
     // declaration.
     if (Y.getKind() == TemplateArgument::Expression)
       return X;
 
     // If we deduced a declaration and an integral constant, keep the
-    // integral constant.
-    if (Y.getKind() == TemplateArgument::Integral)
+    // integral constant and whichever type did not come from an array
+    // bound.
+    if (Y.getKind() == TemplateArgument::Integral) {
+      if (Y.wasDeducedFromArrayBound())
+        return TemplateArgument(Context, Y.getAsIntegral(),
+                                X.getParamTypeForDecl());
       return Y;
+    }
 
     // If we deduced two declarations, make sure they they refer to the
     // same declaration.
@@ -260,9 +286,8 @@
     if (Y.getKind() == TemplateArgument::Integral)
       return Y;
 
-    // If we deduced two null pointers, make sure they have the same type.
-    if (Y.getKind() == TemplateArgument::NullPtr &&
-        Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType()))
+    // If we deduced two null pointers, they are the same.
+    if (Y.getKind() == TemplateArgument::NullPtr)
       return X;
 
     // All other combinations are incompatible.
@@ -273,54 +298,86 @@
         X.pack_size() != Y.pack_size())
       return DeducedTemplateArgument();
 
+    llvm::SmallVector<TemplateArgument, 8> NewPack;
     for (TemplateArgument::pack_iterator XA = X.pack_begin(),
                                       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()))
-            .isNull())
+      TemplateArgument Merged = checkDeducedTemplateArguments(
+          Context, DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
+          DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()));
+      if (Merged.isNull())
         return DeducedTemplateArgument();
+      NewPack.push_back(Merged);
     }
 
-    return X;
+    return DeducedTemplateArgument(
+        TemplateArgument::CreatePackCopy(Context, NewPack),
+        X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound());
   }
 
   llvm_unreachable("Invalid TemplateArgument Kind!");
 }
 
 /// \brief Deduce the value of the given non-type template parameter
+/// as the given deduced template argument. All non-type template parameter
+/// deduction is funneled through here.
+static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
+    Sema &S, TemplateParameterList *TemplateParams,
+    NonTypeTemplateParmDecl *NTTP, const DeducedTemplateArgument &NewDeduced,
+    QualType ValueType, TemplateDeductionInfo &Info,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  assert(NTTP->getDepth() == Info.getDeducedDepth() &&
+         "deducing non-type template argument with wrong depth");
+
+  DeducedTemplateArgument Result = checkDeducedTemplateArguments(
+      S.Context, Deduced[NTTP->getIndex()], NewDeduced);
+  if (Result.isNull()) {
+    Info.Param = NTTP;
+    Info.FirstArg = Deduced[NTTP->getIndex()];
+    Info.SecondArg = NewDeduced;
+    return Sema::TDK_Inconsistent;
+  }
+
+  Deduced[NTTP->getIndex()] = Result;
+  if (!S.getLangOpts().CPlusPlus1z)
+    return Sema::TDK_Success;
+
+  if (NTTP->isExpandedParameterPack())
+    // FIXME: We may still need to deduce parts of the type here! But we
+    // don't have any way to find which slice of the type to use, and the
+    // type stored on the NTTP itself is nonsense. Perhaps the type of an
+    // expanded NTTP should be a pack expansion type?
+    return Sema::TDK_Success;
+
+  // Get the type of the parameter for deduction.
+  QualType ParamType = NTTP->getType();
+  if (auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
+    ParamType = Expansion->getPattern();
+
+  // FIXME: It's not clear how deduction of a parameter of reference
+  // type from an argument (of non-reference type) should be performed.
+  // For now, we just remove reference types from both sides and let
+  // the final check for matching types sort out the mess.
+  return DeduceTemplateArgumentsByTypeMatch(
+      S, TemplateParams, ParamType.getNonReferenceType(),
+      ValueType.getNonReferenceType(), Info, Deduced, TDF_SkipNonDependent,
+      /*PartialOrdering=*/false,
+      /*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound());
+}
+
+/// \brief Deduce the value of the given non-type template parameter
 /// from the given integral constant.
 static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
     Sema &S, TemplateParameterList *TemplateParams,
     NonTypeTemplateParmDecl *NTTP, const llvm::APSInt &Value,
     QualType ValueType, bool DeducedFromArrayBound, TemplateDeductionInfo &Info,
     SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
-  assert(NTTP->getDepth() == 0 &&
-         "Cannot deduce non-type template argument with depth > 0");
-
-  DeducedTemplateArgument NewDeduced(S.Context, Value, ValueType,
-                                     DeducedFromArrayBound);
-  DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
-                                                     Deduced[NTTP->getIndex()],
-                                                                 NewDeduced);
-  if (Result.isNull()) {
-    Info.Param = NTTP;
-    Info.FirstArg = Deduced[NTTP->getIndex()];
-    Info.SecondArg = NewDeduced;
-    return Sema::TDK_Inconsistent;
-  }
-
-  Deduced[NTTP->getIndex()] = Result;
-  return S.getLangOpts().CPlusPlus1z
-             ? DeduceTemplateArgumentsByTypeMatch(
-                   S, TemplateParams, NTTP->getType(), ValueType, Info, Deduced,
-                   TDF_ParamWithReferenceType | TDF_SkipNonDependent,
-                   /*PartialOrdering=*/false,
-                   /*ArrayBound=*/DeducedFromArrayBound)
-             : Sema::TDK_Success;
+  return DeduceNonTypeTemplateArgument(
+      S, TemplateParams, NTTP,
+      DeducedTemplateArgument(S.Context, Value, ValueType,
+                              DeducedFromArrayBound),
+      ValueType, Info, Deduced);
 }
 
 /// \brief Deduce the value of the given non-type template parameter
@@ -335,94 +392,37 @@
                               S.Context.NullPtrTy, NTTP->getLocation()),
                           NullPtrType, CK_NullToPointer)
           .get();
-  DeducedTemplateArgument NewDeduced(Value);
-  DeducedTemplateArgument Result = checkDeducedTemplateArguments(
-      S.Context, Deduced[NTTP->getIndex()], NewDeduced);
-
-  if (Result.isNull()) {
-    Info.Param = NTTP;
-    Info.FirstArg = Deduced[NTTP->getIndex()];
-    Info.SecondArg = NewDeduced;
-    return Sema::TDK_Inconsistent;
-  }
-
-  Deduced[NTTP->getIndex()] = Result;
-  return S.getLangOpts().CPlusPlus1z
-             ? DeduceTemplateArgumentsByTypeMatch(
-                   S, TemplateParams, NTTP->getType(), Value->getType(), Info,
-                   Deduced, TDF_ParamWithReferenceType | TDF_SkipNonDependent)
-             : Sema::TDK_Success;
+  return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
+                                       DeducedTemplateArgument(Value),
+                                       Value->getType(), Info, Deduced);
 }
 
 /// \brief Deduce the value of the given non-type template parameter
 /// from the given type- or value-dependent expression.
 ///
 /// \returns true if deduction succeeded, false otherwise.
-static Sema::TemplateDeductionResult
-DeduceNonTypeTemplateArgument(Sema &S,
-                              TemplateParameterList *TemplateParams,
-                              NonTypeTemplateParmDecl *NTTP,
-                              Expr *Value,
-                              TemplateDeductionInfo &Info,
-                    SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
-  assert(NTTP->getDepth() == 0 &&
-         "Cannot deduce non-type template argument with depth > 0");
-  assert((Value->isTypeDependent() || Value->isValueDependent()) &&
-         "Expression template argument must be type- or value-dependent.");
-
-  DeducedTemplateArgument NewDeduced(Value);
-  DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
-                                                     Deduced[NTTP->getIndex()],
-                                                                 NewDeduced);
-
-  if (Result.isNull()) {
-    Info.Param = NTTP;
-    Info.FirstArg = Deduced[NTTP->getIndex()];
-    Info.SecondArg = NewDeduced;
-    return Sema::TDK_Inconsistent;
-  }
-
-  Deduced[NTTP->getIndex()] = Result;
-  return S.getLangOpts().CPlusPlus1z
-             ? DeduceTemplateArgumentsByTypeMatch(
-                   S, TemplateParams, NTTP->getType(), Value->getType(), Info,
-                   Deduced, TDF_ParamWithReferenceType | TDF_SkipNonDependent)
-             : Sema::TDK_Success;
+static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
+    Sema &S, TemplateParameterList *TemplateParams,
+    NonTypeTemplateParmDecl *NTTP, Expr *Value, TemplateDeductionInfo &Info,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
+                                       DeducedTemplateArgument(Value),
+                                       Value->getType(), Info, Deduced);
 }
 
 /// \brief Deduce the value of the given non-type template parameter
 /// from the given declaration.
 ///
 /// \returns true if deduction succeeded, false otherwise.
-static Sema::TemplateDeductionResult
-DeduceNonTypeTemplateArgument(Sema &S,
-                            TemplateParameterList *TemplateParams,
-                            NonTypeTemplateParmDecl *NTTP,
-                            ValueDecl *D, QualType T,
-                            TemplateDeductionInfo &Info,
-                            SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
-  assert(NTTP->getDepth() == 0 &&
-         "Cannot deduce non-type template argument with depth > 0");
-
+static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
+    Sema &S, TemplateParameterList *TemplateParams,
+    NonTypeTemplateParmDecl *NTTP, ValueDecl *D, QualType T,
+    TemplateDeductionInfo &Info,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
-  TemplateArgument New(D, NTTP->getType());
-  DeducedTemplateArgument NewDeduced(New);
-  DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
-                                                     Deduced[NTTP->getIndex()],
-                                                                 NewDeduced);
-  if (Result.isNull()) {
-    Info.Param = NTTP;
-    Info.FirstArg = Deduced[NTTP->getIndex()];
-    Info.SecondArg = NewDeduced;
-    return Sema::TDK_Inconsistent;
-  }
-
-  Deduced[NTTP->getIndex()] = Result;
-  return S.getLangOpts().CPlusPlus1z
-             ? DeduceTemplateArgumentsByTypeMatch(
-                   S, TemplateParams, NTTP->getType(), T, Info, Deduced,
-                   TDF_ParamWithReferenceType | TDF_SkipNonDependent)
-             : Sema::TDK_Success;
+  TemplateArgument New(D, T);
+  return DeduceNonTypeTemplateArgument(
+      S, TemplateParams, NTTP, DeducedTemplateArgument(New), T, Info, Deduced);
 }
 
 static Sema::TemplateDeductionResult
@@ -441,6 +441,10 @@
 
   if (TemplateTemplateParmDecl *TempParam
         = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
+    // If we're not deducing at this depth, there's nothing to deduce.
+    if (TempParam->getDepth() != Info.getDeducedDepth())
+      return Sema::TDK_Success;
+
     DeducedTemplateArgument NewDeduced(S.Context.getCanonicalTemplateName(Arg));
     DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
                                                  Deduced[TempParam->getIndex()],
@@ -508,9 +512,9 @@
     // Perform template argument deduction on each template
     // argument. Ignore any missing/extra arguments, since they could be
     // filled in by default arguments.
-    return DeduceTemplateArguments(S, TemplateParams, Param->getArgs(),
-                                   Param->getNumArgs(), SpecArg->getArgs(),
-                                   SpecArg->getNumArgs(), Info, Deduced,
+    return DeduceTemplateArguments(S, TemplateParams,
+                                   Param->template_arguments(),
+                                   SpecArg->template_arguments(), Info, Deduced,
                                    /*NumberOfArgumentsMustMatch=*/false);
   }
 
@@ -542,10 +546,9 @@
     return Result;
 
   // Perform template argument deduction for the template arguments.
-  return DeduceTemplateArguments(
-      S, TemplateParams, Param->getArgs(), Param->getNumArgs(),
-      SpecArg->getTemplateArgs().data(), SpecArg->getTemplateArgs().size(),
-      Info, Deduced, /*NumberOfArgumentsMustMatch=*/true);
+  return DeduceTemplateArguments(S, TemplateParams, Param->template_arguments(),
+                                 SpecArg->getTemplateArgs().asArray(), Info,
+                                 Deduced, /*NumberOfArgumentsMustMatch=*/true);
 }
 
 /// \brief Determines whether the given type is an opaque type that
@@ -635,29 +638,68 @@
                      SmallVectorImpl<DeducedTemplateArgument> &Deduced,
                      TemplateDeductionInfo &Info, TemplateArgument Pattern)
       : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
+    // Dig out the partially-substituted pack, if there is one.
+    const TemplateArgument *PartialPackArgs = nullptr;
+    unsigned NumPartialPackArgs = 0;
+    std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
+    if (auto *Scope = S.CurrentInstantiationScope)
+      if (auto *Partial = Scope->getPartiallySubstitutedPack(
+              &PartialPackArgs, &NumPartialPackArgs))
+        PartialPackDepthIndex = getDepthAndIndex(Partial);
+
     // Compute the set of template parameter indices that correspond to
     // parameter packs expanded by the pack expansion.
     {
       llvm::SmallBitVector SawIndices(TemplateParams->size());
+
+      auto AddPack = [&](unsigned Index) {
+        if (SawIndices[Index])
+          return;
+        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);
+      };
+
+      // First look for unexpanded packs in the pattern.
       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);
-        }
+        if (Depth == Info.getDeducedDepth())
+          AddPack(Index);
       }
+      assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
+
+      // This pack expansion will have been partially expanded iff the only
+      // unexpanded parameter pack within it is the partially-substituted pack.
+      IsPartiallyExpanded =
+          Packs.size() == 1 &&
+          PartialPackDepthIndex ==
+              std::make_pair(Info.getDeducedDepth(), Packs.front().Index);
+
+      // Skip over the pack elements that were expanded into separate arguments.
+      if (IsPartiallyExpanded)
+        PackElements += NumPartialPackArgs;
+
+      // We can also have deduced template parameters that do not actually
+      // appear in the pattern, but can be deduced by it (the type of a non-type
+      // template parameter pack, in particular). These won't have prevented us
+      // from partially expanding the pack.
+      llvm::SmallBitVector Used(TemplateParams->size());
+      MarkUsedTemplateParameters(S.Context, Pattern, /*OnlyDeduced*/true,
+                                 Info.getDeducedDepth(), Used);
+      for (int Index = Used.find_first(); Index != -1;
+           Index = Used.find_next(Index))
+        if (TemplateParams->getParam(Index)->isParameterPack())
+          AddPack(Index);
     }
-    assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
 
     for (auto &Pack : Packs) {
       if (Info.PendingDeducedPacks.size() > Pack.Index)
@@ -666,17 +708,19 @@
         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);
+      if (PartialPackDepthIndex ==
+            std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
+        Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
+        // We pre-populate the deduced value of the partially-substituted
+        // pack with the specified value. This is not entirely correct: the
+        // value is supposed to have been substituted, not deduced, but the
+        // cases where this is observable require an exact type match anyway.
+        //
+        // FIXME: If we could represent a "depth i, index j, pack elem k"
+        // parameter, we could substitute the partially-substituted pack
+        // everywhere and avoid this.
+        if (Pack.New.size() > PackElements)
+          Deduced[Pack.Index] = Pack.New[PackElements];
       }
     }
   }
@@ -686,6 +730,10 @@
       Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
   }
 
+  /// Determine whether this pack has already been partially expanded into a
+  /// sequence of (prior) function parameters / template arguments.
+  bool isPartiallyExpanded() { return IsPartiallyExpanded; }
+
   /// 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
@@ -693,17 +741,25 @@
     // 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();
+      if (!Pack.New.empty() || !DeducedArg.isNull()) {
+        while (Pack.New.size() < PackElements)
+          Pack.New.push_back(DeducedTemplateArgument());
+        if (Pack.New.size() == PackElements)
+          Pack.New.push_back(DeducedArg);
+        else
+          Pack.New[PackElements] = DeducedArg;
+        DeducedArg = Pack.New.size() > PackElements + 1
+                         ? Pack.New[PackElements + 1]
+                         : DeducedTemplateArgument();
       }
     }
+    ++PackElements;
   }
 
   /// \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) {
+  Sema::TemplateDeductionResult finish() {
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
     for (auto &Pack : Packs) {
@@ -712,7 +768,7 @@
 
       // Build or find a new value for this pack.
       DeducedTemplateArgument NewPack;
-      if (HasAnyArguments && Pack.New.empty()) {
+      if (PackElements && 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
@@ -731,6 +787,11 @@
         std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
         NewPack = DeducedTemplateArgument(
             TemplateArgument(llvm::makeArrayRef(ArgumentPack, Pack.New.size())),
+            // FIXME: This is wrong, it's possible that some pack elements are
+            // deduced from an array bound and others are not:
+            //   template<typename ...T, T ...V> void g(const T (&...p)[V]);
+            //   g({1, 2, 3}, {{}, {}});
+            // ... should deduce T = {int, size_t (from array bound)}.
             Pack.New[0].wasDeducedFromArrayBound());
       }
 
@@ -779,6 +840,8 @@
   TemplateParameterList *TemplateParams;
   SmallVectorImpl<DeducedTemplateArgument> &Deduced;
   TemplateDeductionInfo &Info;
+  unsigned PackElements = 0;
+  bool IsPartiallyExpanded = false;
 
   SmallVector<DeducedPack, 2> Packs;
 };
@@ -882,10 +945,7 @@
     QualType Pattern = Expansion->getPattern();
     PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
 
-    bool HasAnyArguments = false;
     for (; ArgIdx < NumArgs; ++ArgIdx) {
-      HasAnyArguments = true;
-
       // Deduce template arguments from the pattern.
       if (Sema::TemplateDeductionResult Result
             = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, Pattern,
@@ -898,7 +958,7 @@
 
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
-    if (auto Result = PackScope.finish(HasAnyArguments))
+    if (auto Result = PackScope.finish())
       return Result;
   }
 
@@ -966,6 +1026,32 @@
   return Param == Arg;
 }
 
+/// Get the index of the first template parameter that was originally from the
+/// innermost template-parameter-list. This is 0 except when we concatenate
+/// the template parameter lists of a class template and a constructor template
+/// when forming an implicit deduction guide.
+static unsigned getFirstInnerIndex(FunctionTemplateDecl *FTD) {
+  auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
+  if (!Guide || !Guide->isImplicit())
+    return 0;
+  return Guide->getDeducedTemplate()->getTemplateParameters()->size();
+}
+
+/// Determine whether a type denotes a forwarding reference.
+static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex) {
+  // C++1z [temp.deduct.call]p3:
+  //   A forwarding reference is an rvalue reference to a cv-unqualified
+  //   template parameter that does not represent a template parameter of a
+  //   class template.
+  if (auto *ParamRef = Param->getAs<RValueReferenceType>()) {
+    if (ParamRef->getPointeeType().getQualifiers())
+      return false;
+    auto *TypeParm = ParamRef->getPointeeType()->getAs<TemplateTypeParmType>();
+    return TypeParm && TypeParm->getIndex() >= FirstInnerIndex;
+  }
+  return false;
+}
+
 /// \brief Deduce the template arguments by comparing the parameter type and
 /// the argument type (C++ [temp.deduct.type]).
 ///
@@ -1086,21 +1172,15 @@
       //   taking the address of a function template (14.8.2.2) or when deducing
       //   template arguments from a function declaration (14.8.2.6) and Pi and
       //   Ai are parameters of the top-level parameter-type-list of P and A,
-      //   respectively, Pi is adjusted if it is an rvalue reference to a
-      //   cv-unqualified template parameter and Ai is an lvalue reference, in
+      //   respectively, Pi is adjusted if it is a forwarding reference and Ai
+      //   is an lvalue reference, in
       //   which case the type of Pi is changed to be the template parameter
       //   type (i.e., T&& is changed to simply T). [ Note: As a result, when
       //   Pi is T&& and Ai is X&, the adjusted Pi will be T, causing T to be
       //   deduced as X&. - end note ]
       TDF &= ~TDF_TopLevelParameterTypeList;
-
-      if (const RValueReferenceType *ParamRef
-                                        = Param->getAs<RValueReferenceType>()) {
-        if (isa<TemplateTypeParmType>(ParamRef->getPointeeType()) &&
-            !ParamRef->getPointeeType().getQualifiers())
-          if (Arg->isLValueReferenceType())
-            Param = ParamRef->getPointeeType();
-      }
+      if (isForwardingReference(Param, 0) && Arg->isLValueReferenceType())
+        Param = Param->getPointeeType();
     }
   }
 
@@ -1113,8 +1193,10 @@
   //     cv-list T
   if (const TemplateTypeParmType *TemplateTypeParm
         = Param->getAs<TemplateTypeParmType>()) {
-    // Just skip any attempts to deduce from a placeholder type.
-    if (Arg->isPlaceholderType())
+    // Just skip any attempts to deduce from a placeholder type or a parameter
+    // at a different depth.
+    if (Arg->isPlaceholderType() ||
+        Info.getDeducedDepth() != TemplateTypeParm->getDepth())
       return Sema::TDK_Success;
 
     unsigned Index = TemplateTypeParm->getIndex();
@@ -1141,7 +1223,8 @@
       return Sema::TDK_Underqualified;
     }
 
-    assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
+    assert(TemplateTypeParm->getDepth() == Info.getDeducedDepth() &&
+           "saw template type parameter with wrong depth");
     assert(Arg != S.Context.OverloadTy && "Unresolved overloaded function");
     QualType DeducedType = Arg;
 
@@ -1393,14 +1476,14 @@
 
       // Determine the array bound is something we can deduce.
       NonTypeTemplateParmDecl *NTTP
-        = getDeducedParameterFromExpr(DependentArrayParm->getSizeExpr());
+        = getDeducedParameterFromExpr(Info, DependentArrayParm->getSizeExpr());
       if (!NTTP)
         return Sema::TDK_Success;
 
       // We can perform template argument deduction for the given non-type
       // template parameter.
-      assert(NTTP->getDepth() == 0 &&
-             "Cannot deduce non-type template argument at depth > 0");
+      assert(NTTP->getDepth() == Info.getDeducedDepth() &&
+             "saw non-type template parameter with wrong depth");
       if (const ConstantArrayType *ConstantArrayArg
             = dyn_cast<ConstantArrayType>(ArrayArg)) {
         llvm::APSInt Size(ConstantArrayArg->getSize());
@@ -1678,14 +1761,18 @@
 
         // Perform deduction on the vector size, if we can.
         NonTypeTemplateParmDecl *NTTP
-          = getDeducedParameterFromExpr(VectorParam->getSizeExpr());
+          = getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr());
         if (!NTTP)
           return Sema::TDK_Success;
 
         llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
         ArgSize = VectorArg->getNumElements();
+        // Note that we use the "array bound" rules here; just like in that
+        // case, we don't have any particular type for the vector size, but
+        // we can provide one if necessary.
         return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize,
-                                             S.Context.IntTy, false, Info, Deduced);
+                                             S.Context.IntTy, true, Info,
+                                             Deduced);
       }
 
       if (const DependentSizedExtVectorType *VectorArg
@@ -1700,7 +1787,7 @@
 
         // Perform deduction on the vector size, if we can.
         NonTypeTemplateParmDecl *NTTP
-          = getDeducedParameterFromExpr(VectorParam->getSizeExpr());
+          = getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr());
         if (!NTTP)
           return Sema::TDK_Success;
 
@@ -1719,6 +1806,7 @@
     case Type::Decltype:
     case Type::UnaryTransform:
     case Type::Auto:
+    case Type::DeducedTemplateSpecialization:
     case Type::DependentTemplateSpecialization:
     case Type::PackExpansion:
     case Type::Pipe:
@@ -1808,7 +1896,7 @@
 
   case TemplateArgument::Expression: {
     if (NonTypeTemplateParmDecl *NTTP
-          = getDeducedParameterFromExpr(Param.getAsExpr())) {
+          = getDeducedParameterFromExpr(Info, Param.getAsExpr())) {
       if (Arg.getKind() == TemplateArgument::Integral)
         return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
                                              Arg.getAsIntegral(),
@@ -1851,45 +1939,34 @@
 ///
 /// \returns true if there is another template argument (which will be at
 /// \c Args[ArgIdx]), false otherwise.
-static bool hasTemplateArgumentForDeduction(const TemplateArgument *&Args,
-                                            unsigned &ArgIdx,
-                                            unsigned &NumArgs) {
-  if (ArgIdx == NumArgs)
+static bool hasTemplateArgumentForDeduction(ArrayRef<TemplateArgument> &Args,
+                                            unsigned &ArgIdx) {
+  if (ArgIdx == Args.size())
     return false;
 
   const TemplateArgument &Arg = Args[ArgIdx];
   if (Arg.getKind() != TemplateArgument::Pack)
     return true;
 
-  assert(ArgIdx == NumArgs - 1 && "Pack not at the end of argument list?");
-  Args = Arg.pack_begin();
-  NumArgs = Arg.pack_size();
+  assert(ArgIdx == Args.size() - 1 && "Pack not at the end of argument list?");
+  Args = Arg.pack_elements();
   ArgIdx = 0;
-  return ArgIdx < NumArgs;
+  return ArgIdx < Args.size();
 }
 
 /// \brief Determine whether the given set of template arguments has a pack
 /// expansion that is not the last template argument.
-static bool hasPackExpansionBeforeEnd(const TemplateArgument *Args,
-                                      unsigned NumArgs) {
-  unsigned ArgIdx = 0;
-  while (ArgIdx < NumArgs) {
-    const TemplateArgument &Arg = Args[ArgIdx];
-
-    // Unwrap argument packs.
-    if (Args[ArgIdx].getKind() == TemplateArgument::Pack) {
-      Args = Arg.pack_begin();
-      NumArgs = Arg.pack_size();
-      ArgIdx = 0;
-      continue;
-    }
-
-    ++ArgIdx;
-    if (ArgIdx == NumArgs)
-      return false;
-
-    if (Arg.isPackExpansion())
+static bool hasPackExpansionBeforeEnd(ArrayRef<TemplateArgument> Args) {
+  bool FoundPackExpansion = false;
+  for (const auto &A : Args) {
+    if (FoundPackExpansion)
       return true;
+
+    if (A.getKind() == TemplateArgument::Pack)
+      return hasPackExpansionBeforeEnd(A.pack_elements());
+
+    if (A.isPackExpansion())
+      FoundPackExpansion = true;
   }
 
   return false;
@@ -1897,8 +1974,8 @@
 
 static Sema::TemplateDeductionResult
 DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
-                        const TemplateArgument *Params, unsigned NumParams,
-                        const TemplateArgument *Args, unsigned NumArgs,
+                        ArrayRef<TemplateArgument> Params,
+                        ArrayRef<TemplateArgument> Args,
                         TemplateDeductionInfo &Info,
                         SmallVectorImpl<DeducedTemplateArgument> &Deduced,
                         bool NumberOfArgumentsMustMatch) {
@@ -1906,7 +1983,7 @@
   //   If the template argument list of P contains a pack expansion that is not
   //   the last template argument, the entire template argument list is a
   //   non-deduced context.
-  if (hasPackExpansionBeforeEnd(Params, NumParams))
+  if (hasPackExpansionBeforeEnd(Params))
     return Sema::TDK_Success;
 
   // C++0x [temp.deduct.type]p9:
@@ -1914,21 +1991,21 @@
   //   respective template argument list P is compared with the corresponding
   //   argument Ai of the corresponding template argument list of A.
   unsigned ArgIdx = 0, ParamIdx = 0;
-  for (; hasTemplateArgumentForDeduction(Params, ParamIdx, NumParams);
-       ++ParamIdx) {
+  for (; hasTemplateArgumentForDeduction(Params, ParamIdx); ++ParamIdx) {
     if (!Params[ParamIdx].isPackExpansion()) {
       // The simple case: deduce template arguments by matching Pi and Ai.
 
       // Check whether we have enough arguments.
-      if (!hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs))
-        return NumberOfArgumentsMustMatch ? Sema::TDK_TooFewArguments
-                                          : Sema::TDK_Success;
+      if (!hasTemplateArgumentForDeduction(Args, ArgIdx))
+        return NumberOfArgumentsMustMatch
+                   ? Sema::TDK_MiscellaneousDeductionFailure
+                   : Sema::TDK_Success;
 
-      if (Args[ArgIdx].isPackExpansion()) {
-        // FIXME: We follow the logic of C++0x [temp.deduct.type]p22 here,
-        // but applied to pack expansions that are template arguments.
+      // C++1z [temp.deduct.type]p9:
+      //   During partial ordering, if Ai was originally a pack expansion [and]
+      //   Pi is not a pack expansion, template argument deduction fails.
+      if (Args[ArgIdx].isPackExpansion())
         return Sema::TDK_MiscellaneousDeductionFailure;
-      }
 
       // Perform deduction for this Pi/Ai pair.
       if (Sema::TemplateDeductionResult Result
@@ -1961,10 +2038,7 @@
     // 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;
-    for (; hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs); ++ArgIdx) {
-      HasAnyArguments = true;
-
+    for (; hasTemplateArgumentForDeduction(Args, ArgIdx); ++ArgIdx) {
       // Deduce template arguments from the pattern.
       if (Sema::TemplateDeductionResult Result
             = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
@@ -1976,7 +2050,7 @@
 
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
-    if (auto Result = PackScope.finish(HasAnyArguments))
+    if (auto Result = PackScope.finish())
       return Result;
   }
 
@@ -1990,16 +2064,21 @@
                         const TemplateArgumentList &ArgList,
                         TemplateDeductionInfo &Info,
                         SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
-  return DeduceTemplateArguments(S, TemplateParams,
-                                 ParamList.data(), ParamList.size(),
-                                 ArgList.data(), ArgList.size(),
-                                 Info, Deduced, false);
+  return DeduceTemplateArguments(S, TemplateParams, ParamList.asArray(),
+                                 ArgList.asArray(), Info, Deduced,
+                                 /*NumberOfArgumentsMustMatch*/false);
 }
 
 /// \brief Determine whether two template arguments are the same.
 static bool isSameTemplateArg(ASTContext &Context,
-                              const TemplateArgument &X,
-                              const TemplateArgument &Y) {
+                              TemplateArgument X,
+                              const TemplateArgument &Y,
+                              bool PackExpansionMatchesPack = false) {
+  // If we're checking deduced arguments (X) against original arguments (Y),
+  // we will have flattened packs to non-expansions in X.
+  if (PackExpansionMatchesPack && X.isPackExpansion() && !Y.isPackExpansion())
+    X = X.getPackExpansionPattern();
+
   if (X.getKind() != Y.getKind())
     return false;
 
@@ -2025,7 +2104,7 @@
                     Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer();
 
     case TemplateArgument::Integral:
-      return X.getAsIntegral() == Y.getAsIntegral();
+      return hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral());
 
     case TemplateArgument::Expression: {
       llvm::FoldingSetNodeID XID, YID;
@@ -2042,7 +2121,7 @@
                                         XPEnd = X.pack_end(),
                                            YP = Y.pack_begin();
            XP != XPEnd; ++XP, ++YP)
-        if (!isSameTemplateArg(Context, *XP, *YP))
+        if (!isSameTemplateArg(Context, *XP, *YP, PackExpansionMatchesPack))
           return false;
 
       return true;
@@ -2059,7 +2138,8 @@
 ///
 /// \param NTTPType For a declaration template argument, the type of
 /// the non-type template parameter that corresponds to this template
-/// argument.
+/// argument. Can be null if no type sugar is available to add to the
+/// type from the template argument.
 ///
 /// \param Loc The source location to use for the resulting template
 /// argument.
@@ -2075,12 +2155,16 @@
         Arg, Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
 
   case TemplateArgument::Declaration: {
+    if (NTTPType.isNull())
+      NTTPType = Arg.getParamTypeForDecl();
     Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
                   .getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(E), E);
   }
 
   case TemplateArgument::NullPtr: {
+    if (NTTPType.isNull())
+      NTTPType = Arg.getNullPtrType();
     Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
                   .getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true),
@@ -2129,39 +2213,21 @@
                                DeducedTemplateArgument Arg,
                                NamedDecl *Template,
                                TemplateDeductionInfo &Info,
-                               bool InFunctionTemplate,
+                               bool IsDeduced,
                                SmallVectorImpl<TemplateArgument> &Output) {
-  // First, for a non-type template parameter type that is
-  // initialized by a declaration, we need the type of the
-  // corresponding non-type template parameter.
-  QualType NTTPType;
-  if (NonTypeTemplateParmDecl *NTTP =
-          dyn_cast<NonTypeTemplateParmDecl>(Param)) {
-    NTTPType = NTTP->getType();
-    if (NTTPType->isDependentType()) {
-      TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
-      NTTPType = S.SubstType(NTTPType,
-                             MultiLevelTemplateArgumentList(TemplateArgs),
-                             NTTP->getLocation(),
-                             NTTP->getDeclName());
-      if (NTTPType.isNull())
-        return true;
-    }
-  }
-
   auto ConvertArg = [&](DeducedTemplateArgument Arg,
                         unsigned ArgumentPackIndex) {
     // Convert the deduced template argument into a template
     // argument that we can check, almost as if the user had written
     // the template argument explicitly.
     TemplateArgumentLoc ArgLoc =
-        S.getTrivialTemplateArgumentLoc(Arg, NTTPType, Info.getLocation());
+        S.getTrivialTemplateArgumentLoc(Arg, QualType(), Info.getLocation());
 
     // Check the template argument, converting it as necessary.
     return S.CheckTemplateArgument(
         Param, ArgLoc, Template, Template->getLocation(),
         Template->getSourceRange().getEnd(), ArgumentPackIndex, Output,
-        InFunctionTemplate
+        IsDeduced
             ? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound
                                               : Sema::CTAK_Deduced)
             : Sema::CTAK_Specified);
@@ -2179,6 +2245,16 @@
       InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound());
       assert(InnerArg.getKind() != TemplateArgument::Pack &&
              "deduced nested pack");
+      if (P.isNull()) {
+        // We deduced arguments for some elements of this pack, but not for
+        // all of them. This happens if we get a conditionally-non-deduced
+        // context in a pack expansion (such as an overload set in one of the
+        // arguments).
+        S.Diag(Param->getLocation(),
+               diag::err_template_arg_deduced_incomplete_pack)
+          << Arg << Param;
+        return true;
+      }
       if (ConvertArg(InnerArg, PackedArgsBuilder.size()))
         return true;
 
@@ -2187,22 +2263,28 @@
     }
 
     // If the pack is empty, we still need to substitute into the parameter
-    // itself, in case that substitution fails. For non-type parameters, we did
-    // this above. For type parameters, no substitution is ever required.
-    auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param);
-    if (TTP && PackedArgsBuilder.empty()) {
-      // Set up a template instantiation context.
+    // itself, in case that substitution fails.
+    if (PackedArgsBuilder.empty()) {
       LocalInstantiationScope Scope(S);
-      Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
-                                       TTP, Output,
-                                       Template->getSourceRange());
-      if (Inst.isInvalid())
-        return true;
-
       TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
-      if (!S.SubstDecl(TTP, S.CurContext,
-                       MultiLevelTemplateArgumentList(TemplateArgs)))
-        return true;
+      MultiLevelTemplateArgumentList Args(TemplateArgs);
+
+      if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+        Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
+                                         NTTP, Output,
+                                         Template->getSourceRange());
+        if (Inst.isInvalid() ||
+            S.SubstType(NTTP->getType(), Args, NTTP->getLocation(),
+                        NTTP->getDeclName()).isNull())
+          return true;
+      } else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
+        Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
+                                         TTP, Output,
+                                         Template->getSourceRange());
+        if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args))
+          return true;
+      }
+      // For type parameters, no substitution is ever required.
     }
 
     // Create the resulting argument pack.
@@ -2214,43 +2296,169 @@
   return ConvertArg(Arg, 0);
 }
 
-/// Complete template argument deduction for a class template partial
-/// specialization.
-static Sema::TemplateDeductionResult
-FinishTemplateArgumentDeduction(Sema &S,
-                                ClassTemplatePartialSpecializationDecl *Partial,
-                                const TemplateArgumentList &TemplateArgs,
-                      SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                                TemplateDeductionInfo &Info) {
+// FIXME: This should not be a template, but
+// ClassTemplatePartialSpecializationDecl sadly does not derive from
+// TemplateDecl.
+template<typename TemplateDeclT>
+static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments(
+    Sema &S, TemplateDeclT *Template, bool IsDeduced,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+    TemplateDeductionInfo &Info, SmallVectorImpl<TemplateArgument> &Builder,
+    LocalInstantiationScope *CurrentInstantiationScope = nullptr,
+    unsigned NumAlreadyConverted = 0, bool PartialOverloading = false) {
+  TemplateParameterList *TemplateParams = Template->getTemplateParameters();
+
+  for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
+    NamedDecl *Param = TemplateParams->getParam(I);
+
+    if (!Deduced[I].isNull()) {
+      if (I < NumAlreadyConverted) {
+        // 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 &&
+            CurrentInstantiationScope->getPartiallySubstitutedPack() == Param) {
+          // Forget the partially-substituted pack; its substitution is now
+          // complete.
+          CurrentInstantiationScope->ResetPartiallySubstitutedPack();
+          // We still need to check the argument in case it was extended by
+          // deduction.
+        } else {
+          // We have already fully type-checked and converted this
+          // argument, because it was explicitly-specified. Just record the
+          // presence of this argument.
+          Builder.push_back(Deduced[I]);
+          continue;
+        }
+      }
+
+      // We may have deduced this argument, so it still needs to be
+      // checked and converted.
+      if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Template, Info,
+                                         IsDeduced, Builder)) {
+        Info.Param = makeTemplateParameter(Param);
+        // FIXME: These template arguments are temporary. Free them!
+        Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
+        return Sema::TDK_SubstitutionFailure;
+      }
+
+      continue;
+    }
+
+    // C++0x [temp.arg.explicit]p3:
+    //    A trailing template parameter pack (14.5.3) not otherwise deduced will
+    //    be deduced to an empty sequence of template arguments.
+    // FIXME: Where did the word "trailing" come from?
+    if (Param->isTemplateParameterPack()) {
+      // We may have had explicitly-specified template arguments for this
+      // template parameter pack. If so, our empty deduction extends the
+      // explicitly-specified set (C++0x [temp.arg.explicit]p9).
+      const TemplateArgument *ExplicitArgs;
+      unsigned NumExplicitArgs;
+      if (CurrentInstantiationScope &&
+          CurrentInstantiationScope->getPartiallySubstitutedPack(
+              &ExplicitArgs, &NumExplicitArgs) == Param) {
+        Builder.push_back(TemplateArgument(
+            llvm::makeArrayRef(ExplicitArgs, NumExplicitArgs)));
+
+        // Forget the partially-substituted pack; its substitution is now
+        // complete.
+        CurrentInstantiationScope->ResetPartiallySubstitutedPack();
+      } else {
+        // Go through the motions of checking the empty argument pack against
+        // the parameter pack.
+        DeducedTemplateArgument DeducedPack(TemplateArgument::getEmptyPack());
+        if (ConvertDeducedTemplateArgument(S, Param, DeducedPack, Template,
+                                           Info, IsDeduced, Builder)) {
+          Info.Param = makeTemplateParameter(Param);
+          // FIXME: These template arguments are temporary. Free them!
+          Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
+          return Sema::TDK_SubstitutionFailure;
+        }
+      }
+      continue;
+    }
+
+    // Substitute into the default template argument, if available.
+    bool HasDefaultArg = false;
+    TemplateDecl *TD = dyn_cast<TemplateDecl>(Template);
+    if (!TD) {
+      assert(isa<ClassTemplatePartialSpecializationDecl>(Template));
+      return Sema::TDK_Incomplete;
+    }
+
+    TemplateArgumentLoc DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
+        TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder,
+        HasDefaultArg);
+
+    // If there was no default argument, deduction is incomplete.
+    if (DefArg.getArgument().isNull()) {
+      Info.Param = makeTemplateParameter(
+          const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+      Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
+      if (PartialOverloading) break;
+
+      return HasDefaultArg ? Sema::TDK_SubstitutionFailure
+                           : Sema::TDK_Incomplete;
+    }
+
+    // Check whether we can actually use the default argument.
+    if (S.CheckTemplateArgument(Param, DefArg, TD, TD->getLocation(),
+                                TD->getSourceRange().getEnd(), 0, Builder,
+                                Sema::CTAK_Specified)) {
+      Info.Param = makeTemplateParameter(
+                         const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+      // FIXME: These template arguments are temporary. Free them!
+      Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
+      return Sema::TDK_SubstitutionFailure;
+    }
+
+    // If we get here, we successfully used the default template argument.
+  }
+
+  return Sema::TDK_Success;
+}
+
+static DeclContext *getAsDeclContextOrEnclosing(Decl *D) {
+  if (auto *DC = dyn_cast<DeclContext>(D))
+    return DC;
+  return D->getDeclContext();
+}
+
+template<typename T> struct IsPartialSpecialization {
+  static constexpr bool value = false;
+};
+template<>
+struct IsPartialSpecialization<ClassTemplatePartialSpecializationDecl> {
+  static constexpr bool value = true;
+};
+template<>
+struct IsPartialSpecialization<VarTemplatePartialSpecializationDecl> {
+  static constexpr bool value = true;
+};
+
+/// Complete template argument deduction for a partial specialization.
+template <typename T>
+static typename std::enable_if<IsPartialSpecialization<T>::value,
+                               Sema::TemplateDeductionResult>::type
+FinishTemplateArgumentDeduction(
+    Sema &S, T *Partial, bool IsPartialOrdering,
+    const TemplateArgumentList &TemplateArgs,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+    TemplateDeductionInfo &Info) {
   // Unevaluated SFINAE context.
   EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
   Sema::SFINAETrap Trap(S);
 
-  Sema::ContextRAII SavedContext(S, Partial);
+  Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Partial));
 
   // C++ [temp.deduct.type]p2:
   //   [...] or if any template argument remains neither deduced nor
   //   explicitly specified, template argument deduction fails.
   SmallVector<TemplateArgument, 4> Builder;
-  TemplateParameterList *PartialParams = Partial->getTemplateParameters();
-  for (unsigned I = 0, N = PartialParams->size(); I != N; ++I) {
-    NamedDecl *Param = PartialParams->getParam(I);
-    if (Deduced[I].isNull()) {
-      Info.Param = makeTemplateParameter(Param);
-      return Sema::TDK_Incomplete;
-    }
-
-    // We have deduced this argument, so it still needs to be
-    // checked and converted.
-    if (ConvertDeducedTemplateArgument(S, Param, Deduced[I],
-                                       Partial, Info, false,
-                                       Builder)) {
-      Info.Param = makeTemplateParameter(Param);
-      // FIXME: These template arguments are temporary. Free them!
-      Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
-      return Sema::TDK_SubstitutionFailure;
-    }
-  }
+  if (auto Result = ConvertDeducedTemplateArguments(
+          S, Partial, IsPartialOrdering, Deduced, Info, Builder))
+    return Result;
 
   // Form the template argument list from the deduced template arguments.
   TemplateArgumentList *DeducedArgumentList
@@ -2264,11 +2472,11 @@
   // and are equivalent to the template arguments originally provided
   // to the class template.
   LocalInstantiationScope InstScope(S);
-  ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
-  const ASTTemplateArgumentListInfo *PartialTemplArgInfo
-    = Partial->getTemplateArgsAsWritten();
-  const TemplateArgumentLoc *PartialTemplateArgs
-    = PartialTemplArgInfo->getTemplateArgs();
+  auto *Template = Partial->getSpecializedTemplate();
+  const ASTTemplateArgumentListInfo *PartialTemplArgInfo =
+      Partial->getTemplateArgsAsWritten();
+  const TemplateArgumentLoc *PartialTemplateArgs =
+      PartialTemplArgInfo->getTemplateArgs();
 
   TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc,
                                     PartialTemplArgInfo->RAngleLoc);
@@ -2279,21 +2487,19 @@
     if (ParamIdx >= Partial->getTemplateParameters()->size())
       ParamIdx = Partial->getTemplateParameters()->size() - 1;
 
-    Decl *Param
-      = const_cast<NamedDecl *>(
-                          Partial->getTemplateParameters()->getParam(ParamIdx));
+    Decl *Param = const_cast<NamedDecl *>(
+        Partial->getTemplateParameters()->getParam(ParamIdx));
     Info.Param = makeTemplateParameter(Param);
     Info.FirstArg = PartialTemplateArgs[ArgIdx].getArgument();
     return Sema::TDK_SubstitutionFailure;
   }
 
   SmallVector<TemplateArgument, 4> ConvertedInstArgs;
-  if (S.CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
-                                  InstArgs, false, ConvertedInstArgs))
+  if (S.CheckTemplateArgumentList(Template, Partial->getLocation(), InstArgs,
+                                  false, ConvertedInstArgs))
     return Sema::TDK_SubstitutionFailure;
 
-  TemplateParameterList *TemplateParams
-    = ClassTemplate->getTemplateParameters();
+  TemplateParameterList *TemplateParams = Template->getTemplateParameters();
   for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
     TemplateArgument InstArg = ConvertedInstArgs.data()[I];
     if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg)) {
@@ -2310,6 +2516,48 @@
   return Sema::TDK_Success;
 }
 
+/// Complete template argument deduction for a class or variable template,
+/// when partial ordering against a partial specialization.
+// FIXME: Factor out duplication with partial specialization version above.
+static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction(
+    Sema &S, TemplateDecl *Template, bool PartialOrdering,
+    const TemplateArgumentList &TemplateArgs,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+    TemplateDeductionInfo &Info) {
+  // Unevaluated SFINAE context.
+  EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+  Sema::SFINAETrap Trap(S);
+
+  Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Template));
+
+  // C++ [temp.deduct.type]p2:
+  //   [...] or if any template argument remains neither deduced nor
+  //   explicitly specified, template argument deduction fails.
+  SmallVector<TemplateArgument, 4> Builder;
+  if (auto Result = ConvertDeducedTemplateArguments(
+          S, Template, /*IsDeduced*/PartialOrdering, Deduced, Info, Builder))
+    return Result;
+
+  // Check that we produced the correct argument list.
+  TemplateParameterList *TemplateParams = Template->getTemplateParameters();
+  for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
+    TemplateArgument InstArg = Builder[I];
+    if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg,
+                           /*PackExpansionMatchesPack*/true)) {
+      Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
+      Info.FirstArg = TemplateArgs[I];
+      Info.SecondArg = InstArg;
+      return Sema::TDK_NonDeducedMismatch;
+    }
+  }
+
+  if (Trap.hasErrorOccurred())
+    return Sema::TDK_SubstitutionFailure;
+
+  return Sema::TDK_Success;
+}
+
+
 /// \brief Perform template argument deduction to determine whether
 /// the given template arguments match the given class template
 /// partial specialization per C++ [temp.class.spec.match].
@@ -2348,112 +2596,13 @@
   if (Trap.hasErrorOccurred())
     return Sema::TDK_SubstitutionFailure;
 
-  return ::FinishTemplateArgumentDeduction(*this, Partial, TemplateArgs,
-                                           Deduced, Info);
-}
-
-/// Complete template argument deduction for a variable template partial
-/// specialization.
-/// TODO: Unify with ClassTemplatePartialSpecializationDecl version?
-///       May require unifying ClassTemplate(Partial)SpecializationDecl and
-///        VarTemplate(Partial)SpecializationDecl with a new data
-///        structure Template(Partial)SpecializationDecl, and
-///        using Template(Partial)SpecializationDecl as input type.
-static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction(
-    Sema &S, VarTemplatePartialSpecializationDecl *Partial,
-    const TemplateArgumentList &TemplateArgs,
-    SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-    TemplateDeductionInfo &Info) {
-  // Unevaluated SFINAE context.
-  EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
-  Sema::SFINAETrap Trap(S);
-
-  // C++ [temp.deduct.type]p2:
-  //   [...] or if any template argument remains neither deduced nor
-  //   explicitly specified, template argument deduction fails.
-  SmallVector<TemplateArgument, 4> Builder;
-  TemplateParameterList *PartialParams = Partial->getTemplateParameters();
-  for (unsigned I = 0, N = PartialParams->size(); I != N; ++I) {
-    NamedDecl *Param = PartialParams->getParam(I);
-    if (Deduced[I].isNull()) {
-      Info.Param = makeTemplateParameter(Param);
-      return Sema::TDK_Incomplete;
-    }
-
-    // We have deduced this argument, so it still needs to be
-    // checked and converted.
-    if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Partial,
-                                       Info, false, Builder)) {
-      Info.Param = makeTemplateParameter(Param);
-      // FIXME: These template arguments are temporary. Free them!
-      Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
-      return Sema::TDK_SubstitutionFailure;
-    }
-  }
-
-  // Form the template argument list from the deduced template arguments.
-  TemplateArgumentList *DeducedArgumentList = TemplateArgumentList::CreateCopy(
-      S.Context, Builder);
-
-  Info.reset(DeducedArgumentList);
-
-  // Substitute the deduced template arguments into the template
-  // arguments of the class template partial specialization, and
-  // verify that the instantiated template arguments are both valid
-  // and are equivalent to the template arguments originally provided
-  // to the class template.
-  LocalInstantiationScope InstScope(S);
-  VarTemplateDecl *VarTemplate = Partial->getSpecializedTemplate();
-  const ASTTemplateArgumentListInfo *PartialTemplArgInfo
-    = Partial->getTemplateArgsAsWritten();
-  const TemplateArgumentLoc *PartialTemplateArgs
-    = PartialTemplArgInfo->getTemplateArgs();
-
-  TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc,
-                                    PartialTemplArgInfo->RAngleLoc);
-
-  if (S.Subst(PartialTemplateArgs, PartialTemplArgInfo->NumTemplateArgs,
-              InstArgs, MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
-    unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx;
-    if (ParamIdx >= Partial->getTemplateParameters()->size())
-      ParamIdx = Partial->getTemplateParameters()->size() - 1;
-
-    Decl *Param = const_cast<NamedDecl *>(
-        Partial->getTemplateParameters()->getParam(ParamIdx));
-    Info.Param = makeTemplateParameter(Param);
-    Info.FirstArg = PartialTemplateArgs[ArgIdx].getArgument();
-    return Sema::TDK_SubstitutionFailure;
-  }
-  SmallVector<TemplateArgument, 4> ConvertedInstArgs;
-  if (S.CheckTemplateArgumentList(VarTemplate, Partial->getLocation(), InstArgs,
-                                  false, ConvertedInstArgs))
-    return Sema::TDK_SubstitutionFailure;
-
-  TemplateParameterList *TemplateParams = VarTemplate->getTemplateParameters();
-  for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
-    TemplateArgument InstArg = ConvertedInstArgs.data()[I];
-    if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg)) {
-      Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
-      Info.FirstArg = TemplateArgs[I];
-      Info.SecondArg = InstArg;
-      return Sema::TDK_NonDeducedMismatch;
-    }
-  }
-
-  if (Trap.hasErrorOccurred())
-    return Sema::TDK_SubstitutionFailure;
-
-  return Sema::TDK_Success;
+  return ::FinishTemplateArgumentDeduction(
+      *this, Partial, /*PartialOrdering=*/false, TemplateArgs, Deduced, Info);
 }
 
 /// \brief Perform template argument deduction to determine whether
 /// the given template arguments match the given variable template
 /// partial specialization per C++ [temp.class.spec.match].
-/// TODO: Unify with ClassTemplatePartialSpecializationDecl version?
-///       May require unifying ClassTemplate(Partial)SpecializationDecl and
-///        VarTemplate(Partial)SpecializationDecl with a new data
-///        structure Template(Partial)SpecializationDecl, and
-///        using Template(Partial)SpecializationDecl as input type.
 Sema::TemplateDeductionResult
 Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
                               const TemplateArgumentList &TemplateArgs,
@@ -2487,8 +2636,8 @@
   if (Trap.hasErrorOccurred())
     return Sema::TDK_SubstitutionFailure;
 
-  return ::FinishTemplateArgumentDeduction(*this, Partial, TemplateArgs,
-                                           Deduced, Info);
+  return ::FinishTemplateArgumentDeduction(
+      *this, Partial, /*PartialOrdering=*/false, TemplateArgs, Deduced, Info);
 }
 
 /// \brief Determine whether the given type T is a simple-template-id type.
@@ -2561,19 +2710,16 @@
   // Enter a new template instantiation context where we check the
   // explicitly-specified template arguments against this function template,
   // and then substitute them into the function parameter types.
-  SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
-  InstantiatingTemplate Inst(*this, Info.getLocation(), FunctionTemplate,
-                             DeducedArgs,
-           ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution,
-                             Info);
+  SmallVector<TemplateArgument, 4> DeducedArgs;
+  InstantiatingTemplate Inst(
+      *this, Info.getLocation(), FunctionTemplate, DeducedArgs,
+      CodeSynthesisContext::ExplicitTemplateArgumentSubstitution, Info);
   if (Inst.isInvalid())
     return TDK_InstantiationDepth;
 
-  if (CheckTemplateArgumentList(FunctionTemplate,
-                                SourceLocation(),
-                                ExplicitTemplateArgs,
-                                true,
-                                Builder) || Trap.hasErrorOccurred()) {
+  if (CheckTemplateArgumentList(FunctionTemplate, SourceLocation(),
+                                ExplicitTemplateArgs, true, Builder, false) ||
+      Trap.hasErrorOccurred()) {
     unsigned Index = Builder.size();
     if (Index >= TemplateParams->size())
       Index = TemplateParams->size() - 1;
@@ -2805,23 +2951,49 @@
   return true;
 }
 
+/// Find the pack index for a particular parameter index in an instantiation of
+/// a function template with specific arguments.
+///
+/// \return The pack index for whichever pack produced this parameter, or -1
+///         if this was not produced by a parameter. Intended to be used as the
+///         ArgumentPackSubstitutionIndex for further substitutions.
+// FIXME: We should track this in OriginalCallArgs so we don't need to
+// reconstruct it here.
+static unsigned getPackIndexForParam(Sema &S,
+                                     FunctionTemplateDecl *FunctionTemplate,
+                                     const MultiLevelTemplateArgumentList &Args,
+                                     unsigned ParamIdx) {
+  unsigned Idx = 0;
+  for (auto *PD : FunctionTemplate->getTemplatedDecl()->parameters()) {
+    if (PD->isParameterPack()) {
+      unsigned NumExpansions =
+          S.getNumArgumentsInExpansion(PD->getType(), Args).getValueOr(1);
+      if (Idx + NumExpansions > ParamIdx)
+        return ParamIdx - Idx;
+      Idx += NumExpansions;
+    } else {
+      if (Idx == ParamIdx)
+        return -1; // Not a pack expansion
+      ++Idx;
+    }
+  }
+
+  llvm_unreachable("parameter index would not be produced from template");
+}
+
 /// \brief Finish template argument deduction for a function template,
 /// checking the deduced template arguments for completeness and forming
 /// the function template specialization.
 ///
 /// \param OriginalCallArgs If non-NULL, the original call arguments against
 /// which the deduced argument types should be compared.
-Sema::TemplateDeductionResult
-Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
-                       SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                                      unsigned NumExplicitlySpecified,
-                                      FunctionDecl *&Specialization,
-                                      TemplateDeductionInfo &Info,
-        SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs,
-                                      bool PartialOverloading) {
-  TemplateParameterList *TemplateParams
-    = FunctionTemplate->getTemplateParameters();
-
+Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
+    FunctionTemplateDecl *FunctionTemplate,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+    unsigned NumExplicitlySpecified, FunctionDecl *&Specialization,
+    TemplateDeductionInfo &Info,
+    SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs,
+    bool PartialOverloading, llvm::function_ref<bool()> CheckNonDependent) {
   // Unevaluated SFINAE context.
   EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
   SFINAETrap Trap(*this);
@@ -2829,10 +3001,9 @@
   // Enter a new template instantiation context while we instantiate the
   // actual function declaration.
   SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
-  InstantiatingTemplate Inst(*this, Info.getLocation(), FunctionTemplate,
-                             DeducedArgs,
-              ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
-                             Info);
+  InstantiatingTemplate Inst(
+      *this, Info.getLocation(), FunctionTemplate, DeducedArgs,
+      CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info);
   if (Inst.isInvalid())
     return TDK_InstantiationDepth;
 
@@ -2842,114 +3013,23 @@
   //   [...] or if any template argument remains neither deduced nor
   //   explicitly specified, template argument deduction fails.
   SmallVector<TemplateArgument, 4> Builder;
-  for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
-    NamedDecl *Param = TemplateParams->getParam(I);
+  if (auto Result = ConvertDeducedTemplateArguments(
+          *this, FunctionTemplate, /*IsDeduced*/true, Deduced, Info, Builder,
+          CurrentInstantiationScope, NumExplicitlySpecified,
+          PartialOverloading))
+    return Result;
 
-    if (!Deduced[I].isNull()) {
-      if (I < NumExplicitlySpecified) {
-        // We have already fully type-checked and converted this
-        // 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.
-      if (ConvertDeducedTemplateArgument(*this, Param, Deduced[I],
-                                         FunctionTemplate, Info,
-                                         true, Builder)) {
-        Info.Param = makeTemplateParameter(Param);
-        // FIXME: These template arguments are temporary. Free them!
-        Info.reset(TemplateArgumentList::CreateCopy(Context, Builder));
-        return TDK_SubstitutionFailure;
-      }
-
-      continue;
-    }
-
-    // C++0x [temp.arg.explicit]p3:
-    //    A trailing template parameter pack (14.5.3) not otherwise deduced will
-    //    be deduced to an empty sequence of template arguments.
-    // FIXME: Where did the word "trailing" come from?
-    if (Param->isTemplateParameterPack()) {
-      // We may have had explicitly-specified template arguments for this
-      // template parameter pack. If so, our empty deduction extends the
-      // explicitly-specified set (C++0x [temp.arg.explicit]p9).
-      const TemplateArgument *ExplicitArgs;
-      unsigned NumExplicitArgs;
-      if (CurrentInstantiationScope &&
-          CurrentInstantiationScope->getPartiallySubstitutedPack(&ExplicitArgs,
-                                                             &NumExplicitArgs)
-            == Param) {
-        Builder.push_back(TemplateArgument(
-            llvm::makeArrayRef(ExplicitArgs, NumExplicitArgs)));
-
-        // Forget the partially-substituted pack; its substitution is now
-        // complete.
-        CurrentInstantiationScope->ResetPartiallySubstitutedPack();
-      } else {
-        // Go through the motions of checking the empty argument pack against
-        // the parameter pack.
-        DeducedTemplateArgument DeducedPack(TemplateArgument::getEmptyPack());
-        if (ConvertDeducedTemplateArgument(*this, Param, DeducedPack,
-                                           FunctionTemplate, Info, true,
-                                           Builder)) {
-          Info.Param = makeTemplateParameter(Param);
-          // FIXME: These template arguments are temporary. Free them!
-          Info.reset(TemplateArgumentList::CreateCopy(Context, Builder));
-          return TDK_SubstitutionFailure;
-        }
-      }
-      continue;
-    }
-
-    // Substitute into the default template argument, if available.
-    bool HasDefaultArg = false;
-    TemplateArgumentLoc DefArg
-      = SubstDefaultTemplateArgumentIfAvailable(FunctionTemplate,
-                                              FunctionTemplate->getLocation(),
-                                  FunctionTemplate->getSourceRange().getEnd(),
-                                                Param,
-                                                Builder, HasDefaultArg);
-
-    // If there was no default argument, deduction is incomplete.
-    if (DefArg.getArgument().isNull()) {
-      Info.Param = makeTemplateParameter(
-                         const_cast<NamedDecl *>(TemplateParams->getParam(I)));
-      Info.reset(TemplateArgumentList::CreateCopy(Context, Builder));
-      if (PartialOverloading) break;
-
-      return HasDefaultArg ? TDK_SubstitutionFailure : TDK_Incomplete;
-    }
-
-    // Check whether we can actually use the default argument.
-    if (CheckTemplateArgument(Param, DefArg,
-                              FunctionTemplate,
-                              FunctionTemplate->getLocation(),
-                              FunctionTemplate->getSourceRange().getEnd(),
-                              0, Builder,
-                              CTAK_Specified)) {
-      Info.Param = makeTemplateParameter(
-                         const_cast<NamedDecl *>(TemplateParams->getParam(I)));
-      // FIXME: These template arguments are temporary. Free them!
-      Info.reset(TemplateArgumentList::CreateCopy(Context, Builder));
-      return TDK_SubstitutionFailure;
-    }
-
-    // If we get here, we successfully used the default template argument.
-  }
+  // C++ [temp.deduct.call]p10: [DR1391]
+  //   If deduction succeeds for all parameters that contain
+  //   template-parameters that participate in template argument deduction,
+  //   and all template arguments are explicitly specified, deduced, or
+  //   obtained from default template arguments, remaining parameters are then
+  //   compared with the corresponding arguments. For each remaining parameter
+  //   P with a type that was non-dependent before substitution of any
+  //   explicitly-specified template arguments, if the corresponding argument
+  //   A cannot be implicitly converted to P, deduction fails.
+  if (CheckNonDependent())
+    return TDK_NonDependentConversionFailure;
 
   // Form the template argument list from the deduced template arguments.
   TemplateArgumentList *DeducedArgumentList
@@ -2961,9 +3041,9 @@
   DeclContext *Owner = FunctionTemplate->getDeclContext();
   if (FunctionTemplate->getFriendObjectKind())
     Owner = FunctionTemplate->getLexicalDeclContext();
+  MultiLevelTemplateArgumentList SubstArgs(*DeducedArgumentList);
   Specialization = cast_or_null<FunctionDecl>(
-                      SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner,
-                         MultiLevelTemplateArgumentList(*DeducedArgumentList)));
+      SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner, SubstArgs));
   if (!Specialization || Specialization->isInvalidDecl())
     return TDK_SubstitutionFailure;
 
@@ -2989,19 +3069,46 @@
     //   In general, the deduction process attempts to find template argument
     //   values that will make the deduced A identical to A (after the type A
     //   is transformed as described above). [...]
+    llvm::SmallDenseMap<std::pair<unsigned, QualType>, QualType> DeducedATypes;
     for (unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
       OriginalCallArg OriginalArg = (*OriginalCallArgs)[I];
-      unsigned ParamIdx = OriginalArg.ArgIdx;
 
+      auto ParamIdx = OriginalArg.ArgIdx;
       if (ParamIdx >= Specialization->getNumParams())
+        // FIXME: This presumably means a pack ended up smaller than we
+        // expected while deducing. Should this not result in deduction
+        // failure? Can it even happen?
         continue;
 
-      QualType DeducedA = Specialization->getParamDecl(ParamIdx)->getType();
+      QualType DeducedA;
+      if (!OriginalArg.DecomposedParam) {
+        // P is one of the function parameters, just look up its substituted
+        // type.
+        DeducedA = Specialization->getParamDecl(ParamIdx)->getType();
+      } else {
+        // P is a decomposed element of a parameter corresponding to a
+        // braced-init-list argument. Substitute back into P to find the
+        // deduced A.
+        QualType &CacheEntry =
+            DeducedATypes[{ParamIdx, OriginalArg.OriginalParamType}];
+        if (CacheEntry.isNull()) {
+          ArgumentPackSubstitutionIndexRAII PackIndex(
+              *this, getPackIndexForParam(*this, FunctionTemplate, SubstArgs,
+                                          ParamIdx));
+          CacheEntry =
+              SubstType(OriginalArg.OriginalParamType, SubstArgs,
+                        Specialization->getTypeSpecStartLoc(),
+                        Specialization->getDeclName());
+        }
+        DeducedA = CacheEntry;
+      }
+
       if (CheckOriginalCallArgDeduction(*this, OriginalArg, DeducedA)) {
         Info.FirstArg = TemplateArgument(DeducedA);
         Info.SecondArg = TemplateArgument(OriginalArg.OriginalArgType);
         Info.CallArgIndex = OriginalArg.ArgIdx;
-        return TDK_DeducedMismatch;
+        return OriginalArg.DecomposedParam ? TDK_DeducedMismatchNested
+                                           : TDK_DeducedMismatch;
       }
     }
   }
@@ -3153,12 +3260,9 @@
 /// \returns true if the caller should not attempt to perform any template
 /// argument deduction based on this P/A pair because the argument is an
 /// overloaded function set that could not be resolved.
-static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S,
-                                          TemplateParameterList *TemplateParams,
-                                                      QualType &ParamType,
-                                                      QualType &ArgType,
-                                                      Expr *Arg,
-                                                      unsigned &TDF) {
+static bool AdjustFunctionParmAndArgTypesForDeduction(
+    Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex,
+    QualType &ParamType, QualType &ArgType, Expr *Arg, unsigned &TDF) {
   // C++0x [temp.deduct.call]p3:
   //   If P is a cv-qualified type, the top level cv-qualifiers of P's type
   //   are ignored for type deduction.
@@ -3189,13 +3293,10 @@
       ArgType = Arg->getType();
     }
 
-    // C++0x [temp.deduct.call]p3:
-    //   If P is an rvalue reference to a cv-unqualified template
-    //   parameter and the argument is an lvalue, the type "lvalue
-    //   reference to A" is used in place of A for type deduction.
-    if (ParamRefType->isRValueReferenceType() &&
-        !ParamType.getQualifiers() &&
-        isa<TemplateTypeParmType>(ParamType) &&
+    // C++1z [temp.deduct.call]p3:
+    //   If P is a forwarding reference and the argument is an lvalue, the type
+    //   "lvalue reference to A" is used in place of A for type deduction.
+    if (isForwardingReference(QualType(ParamRefType, 0), FirstInnerIndex) &&
         Arg->isLValue())
       ArgType = S.Context.getLValueReferenceType(ArgType);
   } else {
@@ -3253,109 +3354,103 @@
 hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate,
                                QualType T);
 
-static Sema::TemplateDeductionResult DeduceTemplateArgumentByListElement(
-    Sema &S, TemplateParameterList *TemplateParams, QualType ParamType,
-    Expr *Arg, TemplateDeductionInfo &Info,
-    SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF);
+static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument(
+    Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex,
+    QualType ParamType, Expr *Arg, TemplateDeductionInfo &Info,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+    SmallVectorImpl<Sema::OriginalCallArg> &OriginalCallArgs,
+    bool DecomposedParam, unsigned ArgIdx, unsigned TDF);
 
 /// \brief Attempt template argument deduction from an initializer list
 ///        deemed to be an argument in a function call.
-static bool
-DeduceFromInitializerList(Sema &S, TemplateParameterList *TemplateParams,
-                          QualType AdjustedParamType, InitListExpr *ILE,
-                          TemplateDeductionInfo &Info,
-                          SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                          unsigned TDF, Sema::TemplateDeductionResult &Result) {
+static Sema::TemplateDeductionResult DeduceFromInitializerList(
+    Sema &S, TemplateParameterList *TemplateParams, QualType AdjustedParamType,
+    InitListExpr *ILE, TemplateDeductionInfo &Info,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+    SmallVectorImpl<Sema::OriginalCallArg> &OriginalCallArgs, unsigned ArgIdx,
+    unsigned TDF) {
+  // C++ [temp.deduct.call]p1: (CWG 1591)
+  //   If removing references and cv-qualifiers from P gives
+  //   std::initializer_list<P0> or P0[N] for some P0 and N and the argument is
+  //   a non-empty initializer list, then deduction is performed instead for
+  //   each element of the initializer list, taking P0 as a function template
+  //   parameter type and the initializer element as its argument
+  //
+  // We've already removed references and cv-qualifiers here.
+  if (!ILE->getNumInits())
+    return Sema::TDK_Success;
 
-  // [temp.deduct.call] p1 (post CWG-1591)
-  // If removing references and cv-qualifiers from P gives
-  // std::initializer_list<P0> or P0[N] for some P0 and N and the argument is a
-  // non-empty initializer list (8.5.4), then deduction is performed instead for
-  // each element of the initializer list, taking P0 as a function template
-  // parameter type and the initializer element as its argument, and in the
-  // P0[N] case, if N is a non-type template parameter, N is deduced from the
-  // length of the initializer list. Otherwise, an initializer list argument
-  // causes the parameter to be considered a non-deduced context
-
-  const bool IsConstSizedArray = AdjustedParamType->isConstantArrayType();
-
-  const bool IsDependentSizedArray =
-      !IsConstSizedArray && AdjustedParamType->isDependentSizedArrayType();
-
-  QualType ElTy;  // The element type of the std::initializer_list or the array.
-
-  const bool IsSTDList = !IsConstSizedArray && !IsDependentSizedArray &&
-                         S.isStdInitializerList(AdjustedParamType, &ElTy);
-
-  if (!IsConstSizedArray && !IsDependentSizedArray && !IsSTDList)
-    return false;
-
-  Result = Sema::TDK_Success;
-  // If we are not deducing against the 'T' in a std::initializer_list<T> then
-  // deduce against the 'T' in T[N].
-  if (ElTy.isNull()) {
-    assert(!IsSTDList);
-    ElTy = S.Context.getAsArrayType(AdjustedParamType)->getElementType();
+  QualType ElTy;
+  auto *ArrTy = S.Context.getAsArrayType(AdjustedParamType);
+  if (ArrTy)
+    ElTy = ArrTy->getElementType();
+  else if (!S.isStdInitializerList(AdjustedParamType, &ElTy)) {
+    //   Otherwise, an initializer list argument causes the parameter to be
+    //   considered a non-deduced context
+    return Sema::TDK_Success;
   }
+
   // Deduction only needs to be done for dependent types.
   if (ElTy->isDependentType()) {
     for (Expr *E : ILE->inits()) {
-      if ((Result = DeduceTemplateArgumentByListElement(S, TemplateParams, ElTy,
-                                                        E, Info, Deduced, TDF)))
-        return true;
+      if (auto Result = DeduceTemplateArgumentsFromCallArgument(
+              S, TemplateParams, 0, ElTy, E, Info, Deduced, OriginalCallArgs, true,
+              ArgIdx, TDF))
+        return Result;
     }
   }
-  if (IsDependentSizedArray) {
-    const DependentSizedArrayType *ArrTy =
-        S.Context.getAsDependentSizedArrayType(AdjustedParamType);
+
+  //   in the P0[N] case, if N is a non-type template parameter, N is deduced
+  //   from the length of the initializer list.
+  if (auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
     // Determine the array bound is something we can deduce.
     if (NonTypeTemplateParmDecl *NTTP =
-            getDeducedParameterFromExpr(ArrTy->getSizeExpr())) {
+            getDeducedParameterFromExpr(Info, DependentArrTy->getSizeExpr())) {
       // We can perform template argument deduction for the given non-type
       // template parameter.
-      assert(NTTP->getDepth() == 0 &&
-             "Cannot deduce non-type template argument at depth > 0");
-      llvm::APInt Size(S.Context.getIntWidth(NTTP->getType()),
-                       ILE->getNumInits());
-
-      Result = DeduceNonTypeTemplateArgument(
-          S, TemplateParams, NTTP, llvm::APSInt(Size), NTTP->getType(),
-          /*ArrayBound=*/true, Info, Deduced);
+      // C++ [temp.deduct.type]p13:
+      //   The type of N in the type T[N] is std::size_t.
+      QualType T = S.Context.getSizeType();
+      llvm::APInt Size(S.Context.getIntWidth(T), ILE->getNumInits());
+      if (auto Result = DeduceNonTypeTemplateArgument(
+              S, TemplateParams, NTTP, llvm::APSInt(Size), T,
+              /*ArrayBound=*/true, Info, Deduced))
+        return Result;
     }
   }
-  return true;
+
+  return Sema::TDK_Success;
 }
 
-/// \brief Perform template argument deduction by matching a parameter type
-///        against a single expression, where the expression is an element of
-///        an initializer list that was originally matched against a parameter
-///        of type \c initializer_list\<ParamType\>.
-static Sema::TemplateDeductionResult
-DeduceTemplateArgumentByListElement(Sema &S,
-                                    TemplateParameterList *TemplateParams,
-                                    QualType ParamType, Expr *Arg,
-                                    TemplateDeductionInfo &Info,
-                              SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                                    unsigned TDF) {
-  // Handle the case where an init list contains another init list as the
-  // element.
-  if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) {
-    Sema::TemplateDeductionResult Result;
-    if (!DeduceFromInitializerList(S, TemplateParams,
-                                   ParamType.getNonReferenceType(), ILE, Info,
-                                   Deduced, TDF, Result))
-      return Sema::TDK_Success; // Just ignore this expression.
-
-    return Result;
-  }
-
-  // For all other cases, just match by type.
+/// \brief Perform template argument deduction per [temp.deduct.call] for a
+///        single parameter / argument pair.
+static Sema::TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument(
+    Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex,
+    QualType ParamType, Expr *Arg, TemplateDeductionInfo &Info,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+    SmallVectorImpl<Sema::OriginalCallArg> &OriginalCallArgs,
+    bool DecomposedParam, unsigned ArgIdx, unsigned TDF) {
   QualType ArgType = Arg->getType();
-  if (AdjustFunctionParmAndArgTypesForDeduction(S, TemplateParams, ParamType,
-                                                ArgType, Arg, TDF)) {
-    Info.Expression = Arg;
-    return Sema::TDK_FailedOverloadResolution;
-  }
+  QualType OrigParamType = ParamType;
+
+  //   If P is a reference type [...]
+  //   If P is a cv-qualified type [...]
+  if (AdjustFunctionParmAndArgTypesForDeduction(
+          S, TemplateParams, FirstInnerIndex, ParamType, ArgType, Arg, TDF))
+    return Sema::TDK_Success;
+
+  //   If [...] the argument is a non-empty initializer list [...]
+  if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg))
+    return DeduceFromInitializerList(S, TemplateParams, ParamType, ILE, Info,
+                                     Deduced, OriginalCallArgs, ArgIdx, TDF);
+
+  //   [...] the deduction process attempts to find template argument values
+  //   that will make the deduced A identical to A
+  //
+  // Keep track of the argument type and corresponding parameter index,
+  // so we can check for compatibility between the deduced A and A.
+  OriginalCallArgs.push_back(
+      Sema::OriginalCallArg(OrigParamType, DecomposedParam, ArgIdx, ArgType));
   return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, ParamType,
                                             ArgType, Info, Deduced, TDF);
 }
@@ -3378,23 +3473,31 @@
 /// \param Info the argument will be updated to provide additional information
 /// about template argument deduction.
 ///
+/// \param CheckNonDependent A callback to invoke to check conversions for
+/// non-dependent parameters, between deduction and substitution, per DR1391.
+/// If this returns true, substitution will be skipped and we return
+/// TDK_NonDependentConversionFailure. The callback is passed the parameter
+/// types (after substituting explicit template arguments).
+///
 /// \returns the result of template argument deduction.
 Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
     FunctionTemplateDecl *FunctionTemplate,
     TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
     FunctionDecl *&Specialization, TemplateDeductionInfo &Info,
-    bool PartialOverloading) {
+    bool PartialOverloading,
+    llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent) {
   if (FunctionTemplate->isInvalidDecl())
     return TDK_Invalid;
 
   FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
   unsigned NumParams = Function->getNumParams();
 
+  unsigned FirstInnerIndex = getFirstInnerIndex(FunctionTemplate);
+
   // C++ [temp.deduct.call]p1:
   //   Template argument deduction is done by comparing each function template
   //   parameter type (call it P) with the type of the corresponding argument
   //   of the call (call it A) as described below.
-  unsigned CheckArgs = Args.size();
   if (Args.size() < Function->getMinRequiredArguments() && !PartialOverloading)
     return TDK_TooFewArguments;
   else if (TooManyArguments(NumParams, Args.size(), PartialOverloading)) {
@@ -3402,9 +3505,7 @@
       = Function->getType()->getAs<FunctionProtoType>();
     if (Proto->isTemplateVariadic())
       /* Do nothing */;
-    else if (Proto->isVariadic())
-      CheckArgs = NumParams;
-    else
+    else if (!Proto->isVariadic())
       return TDK_TooManyArguments;
   }
 
@@ -3414,7 +3515,7 @@
   TemplateParameterList *TemplateParams
     = FunctionTemplate->getTemplateParameters();
   SmallVector<DeducedTemplateArgument, 4> Deduced;
-  SmallVector<QualType, 4> ParamTypes;
+  SmallVector<QualType, 8> ParamTypes;
   unsigned NumExplicitlySpecified = 0;
   if (ExplicitTemplateArgs) {
     TemplateDeductionResult Result =
@@ -3434,140 +3535,96 @@
       ParamTypes.push_back(Function->getParamDecl(I)->getType());
   }
 
+  SmallVector<OriginalCallArg, 8> OriginalCallArgs;
+
+  // Deduce an argument of type ParamType from an expression with index ArgIdx.
+  auto DeduceCallArgument = [&](QualType ParamType, unsigned ArgIdx) {
+    // C++ [demp.deduct.call]p1: (DR1391)
+    //   Template argument deduction is done by comparing each function template
+    //   parameter that contains template-parameters that participate in
+    //   template argument deduction ...
+    if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType))
+      return Sema::TDK_Success;
+
+    //   ... with the type of the corresponding argument
+    return DeduceTemplateArgumentsFromCallArgument(
+        *this, TemplateParams, FirstInnerIndex, ParamType, Args[ArgIdx], Info, Deduced,
+        OriginalCallArgs, /*Decomposed*/false, ArgIdx, /*TDF*/ 0);
+  };
+
   // Deduce template arguments from the function parameters.
   Deduced.resize(TemplateParams->size());
-  unsigned ArgIdx = 0;
-  SmallVector<OriginalCallArg, 4> OriginalCallArgs;
-  for (unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size();
+  SmallVector<QualType, 8> ParamTypesForArgChecking;
+  for (unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
        ParamIdx != NumParamTypes; ++ParamIdx) {
-    QualType OrigParamType = ParamTypes[ParamIdx];
-    QualType ParamType = OrigParamType;
+    QualType ParamType = ParamTypes[ParamIdx];
 
-    const PackExpansionType *ParamExpansion
-      = dyn_cast<PackExpansionType>(ParamType);
+    const PackExpansionType *ParamExpansion =
+        dyn_cast<PackExpansionType>(ParamType);
     if (!ParamExpansion) {
       // Simple case: matching a function parameter to a function argument.
-      if (ArgIdx >= CheckArgs)
+      if (ArgIdx >= Args.size())
         break;
 
-      Expr *Arg = Args[ArgIdx++];
-      QualType ArgType = Arg->getType();
-
-      unsigned TDF = 0;
-      if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams,
-                                                    ParamType, ArgType, Arg,
-                                                    TDF))
-        continue;
-
-      // If we have nothing to deduce, we're done.
-      if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType))
-        continue;
-
-      // If the argument is an initializer list ...
-      if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) {
-        TemplateDeductionResult Result;
-        // Removing references was already done.
-        if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE,
-                                       Info, Deduced, TDF, Result))
-          continue;
-
-        if (Result)
-          return Result;
-        // Don't track the argument type, since an initializer list has none.
-        continue;
-      }
-
-      // Keep track of the argument type and corresponding parameter index,
-      // so we can check for compatibility between the deduced A and A.
-      OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx-1,
-                                                 ArgType));
-
-      if (TemplateDeductionResult Result
-            = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams,
-                                                 ParamType, ArgType,
-                                                 Info, Deduced, TDF))
+      ParamTypesForArgChecking.push_back(ParamType);
+      if (auto Result = DeduceCallArgument(ParamType, ArgIdx++))
         return Result;
 
       continue;
     }
 
+    QualType ParamPattern = ParamExpansion->getPattern();
+    PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info,
+                                 ParamPattern);
+
     // C++0x [temp.deduct.call]p1:
     //   For a function parameter pack that occurs at the end of the
     //   parameter-declaration-list, the type A of each remaining argument of
     //   the call is compared with the type P of the declarator-id of the
     //   function parameter pack. Each comparison deduces template arguments
     //   for subsequent positions in the template parameter packs expanded by
-    //   the function parameter pack. For a function parameter pack that does
-    //   not occur at the end of the parameter-declaration-list, the type of
-    //   the parameter pack is a non-deduced context.
-    if (ParamIdx + 1 < NumParamTypes)
-      break;
-
-    QualType ParamPattern = ParamExpansion->getPattern();
-    PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info,
-                                 ParamPattern);
-
-    bool HasAnyArguments = false;
-    for (; ArgIdx < Args.size(); ++ArgIdx) {
-      HasAnyArguments = true;
-
-      QualType OrigParamType = ParamPattern;
-      ParamType = OrigParamType;
-      Expr *Arg = Args[ArgIdx];
-      QualType ArgType = Arg->getType();
-
-      unsigned TDF = 0;
-      if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams,
-                                                    ParamType, ArgType, Arg,
-                                                    TDF)) {
-        // We can't actually perform any deduction for this argument, so stop
-        // deduction at this point.
-        ++ArgIdx;
-        break;
+    //   the function parameter pack. When a function parameter pack appears
+    //   in a non-deduced context [not at the end of the list], the type of
+    //   that parameter pack is never deduced.
+    //
+    // FIXME: The above rule allows the size of the parameter pack to change
+    // after we skip it (in the non-deduced case). That makes no sense, so
+    // we instead notionally deduce the pack against N arguments, where N is
+    // the length of the explicitly-specified pack if it's expanded by the
+    // parameter pack and 0 otherwise, and we treat each deduction as a
+    // non-deduced context.
+    if (ParamIdx + 1 == NumParamTypes) {
+      for (; ArgIdx < Args.size(); PackScope.nextPackElement(), ++ArgIdx) {
+        ParamTypesForArgChecking.push_back(ParamPattern);
+        if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx))
+          return Result;
       }
-
-      // As above, initializer lists need special handling.
-      if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) {
-        TemplateDeductionResult Result;
-        if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE,
-                                       Info, Deduced, TDF, Result)) {
-          ++ArgIdx;
-          break;
+    } else {
+      // If the parameter type contains an explicitly-specified pack that we
+      // could not expand, skip the number of parameters notionally created
+      // by the expansion.
+      Optional<unsigned> NumExpansions = ParamExpansion->getNumExpansions();
+      if (NumExpansions && !PackScope.isPartiallyExpanded()) {
+        for (unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
+             ++I, ++ArgIdx) {
+          ParamTypesForArgChecking.push_back(ParamPattern);
+          // FIXME: Should we add OriginalCallArgs for these? What if the
+          // corresponding argument is a list?
+          PackScope.nextPackElement();
         }
-
-        if (Result)
-          return Result;
-      } else {
-
-        // Keep track of the argument type and corresponding argument index,
-        // so we can check for compatibility between the deduced A and A.
-        if (hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType))
-          OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx,
-                                                     ArgType));
-
-        if (TemplateDeductionResult Result
-            = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams,
-                                                 ParamType, ArgType, Info,
-                                                 Deduced, TDF))
-          return Result;
       }
-
-      PackScope.nextPackElement();
     }
 
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
-    if (auto Result = PackScope.finish(HasAnyArguments))
+    if (auto Result = PackScope.finish())
       return Result;
-
-    // After we've matching against a parameter pack, we're done.
-    break;
   }
 
-  return FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
-                                         NumExplicitlySpecified, Specialization,
-                                         Info, &OriginalCallArgs,
-                                         PartialOverloading);
+  return FinishTemplateArgumentDeduction(
+      FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
+      &OriginalCallArgs, PartialOverloading,
+      [&]() { return CheckNonDependent(ParamTypesForArgChecking); });
 }
 
 QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType,
@@ -4035,15 +4092,26 @@
 }
 
 namespace {
-  /// Substitute the 'auto' type specifier within a type for a given replacement
-  /// type.
-  class SubstituteAutoTransform :
-    public TreeTransform<SubstituteAutoTransform> {
+  /// Substitute the 'auto' specifier or deduced template specialization type
+  /// specifier within a type for a given replacement type.
+  class SubstituteDeducedTypeTransform :
+      public TreeTransform<SubstituteDeducedTypeTransform> {
     QualType Replacement;
+    bool UseTypeSugar;
   public:
-    SubstituteAutoTransform(Sema &SemaRef, QualType Replacement)
-        : TreeTransform<SubstituteAutoTransform>(SemaRef),
-          Replacement(Replacement) {}
+    SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement,
+                            bool UseTypeSugar = true)
+        : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef),
+          Replacement(Replacement), UseTypeSugar(UseTypeSugar) {}
+
+    QualType TransformDesugared(TypeLocBuilder &TLB, DeducedTypeLoc TL) {
+      assert(isa<TemplateTypeParmType>(Replacement) &&
+             "unexpected unsugared replacement kind");
+      QualType Result = Replacement;
+      TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
+      NewTL.setNameLoc(TL.getNameLoc());
+      return Result;
+    }
 
     QualType TransformAutoType(TypeLocBuilder &TLB, AutoTypeLoc TL) {
       // If we're building the type pattern to deduce against, don't wrap the
@@ -4053,23 +4121,29 @@
       //   auto &&lref = lvalue;
       // must transform into "rvalue reference to T" not "rvalue reference to
       // auto type deduced as T" in order for [temp.deduct.call]p3 to apply.
-      if (!Replacement.isNull() && isa<TemplateTypeParmType>(Replacement)) {
-        QualType Result = Replacement;
-        TemplateTypeParmTypeLoc NewTL =
-          TLB.push<TemplateTypeParmTypeLoc>(Result);
-        NewTL.setNameLoc(TL.getNameLoc());
-        return Result;
-      } else {
-        bool Dependent =
-          !Replacement.isNull() && Replacement->isDependentType();
-        QualType Result =
-          SemaRef.Context.getAutoType(Dependent ? QualType() : Replacement,
-                                      TL.getTypePtr()->getKeyword(),
-                                      Dependent);
-        AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
-        NewTL.setNameLoc(TL.getNameLoc());
-        return Result;
-      }
+      //
+      // FIXME: Is this still necessary?
+      if (!UseTypeSugar)
+        return TransformDesugared(TLB, TL);
+
+      QualType Result = SemaRef.Context.getAutoType(
+          Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull());
+      auto NewTL = TLB.push<AutoTypeLoc>(Result);
+      NewTL.setNameLoc(TL.getNameLoc());
+      return Result;
+    }
+
+    QualType TransformDeducedTemplateSpecializationType(
+        TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
+      if (!UseTypeSugar)
+        return TransformDesugared(TLB, TL);
+
+      QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
+          TL.getTypePtr()->getTemplateName(),
+          Replacement, Replacement.isNull());
+      auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
+      NewTL.setNameLoc(TL.getNameLoc());
+      return Result;
     }
 
     ExprResult TransformLambdaExpr(LambdaExpr *E) {
@@ -4088,18 +4162,29 @@
 }
 
 Sema::DeduceAutoResult
-Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result) {
-  return DeduceAutoType(Type->getTypeLoc(), Init, Result);
+Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result,
+                     Optional<unsigned> DependentDeductionDepth) {
+  return DeduceAutoType(Type->getTypeLoc(), Init, Result,
+                        DependentDeductionDepth);
 }
 
 /// \brief Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
 ///
+/// Note that this is done even if the initializer is dependent. (This is
+/// necessary to support partial ordering of templates using 'auto'.)
+/// A dependent type will be produced when deducing from a dependent type.
+///
 /// \param Type the type pattern using the auto type-specifier.
 /// \param Init the initializer for the variable whose type is to be deduced.
 /// \param Result if type deduction was successful, this will be set to the
 ///        deduced type.
+/// \param DependentDeductionDepth Set if we should permit deduction in
+///        dependent cases. This is necessary for template partial ordering with
+///        'auto' template parameters. The value specified is the template
+///        parameter depth at which we should perform 'auto' deduction.
 Sema::DeduceAutoResult
-Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result) {
+Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result,
+                     Optional<unsigned> DependentDeductionDepth) {
   if (Init->getType()->isNonOverloadPlaceholderType()) {
     ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
     if (NonPlaceholder.isInvalid())
@@ -4107,12 +4192,16 @@
     Init = NonPlaceholder.get();
   }
 
-  if (Init->isTypeDependent() || Type.getType()->isDependentType()) {
-    Result = SubstituteAutoTransform(*this, Context.DependentTy).Apply(Type);
+  if (!DependentDeductionDepth &&
+      (Type.getType()->isDependentType() || Init->isTypeDependent())) {
+    Result = SubstituteDeducedTypeTransform(*this, QualType()).Apply(Type);
     assert(!Result.isNull() && "substituting DependentTy can't fail");
     return DAR_Succeeded;
   }
 
+  // Find the depth of template parameter to synthesize.
+  unsigned Depth = DependentDeductionDepth.getValueOr(0);
+
   // If this is a 'decltype(auto)' specifier, do the decltype dance.
   // Since 'decltype(auto)' can only occur at the top of the type, we
   // don't need to go digging for it.
@@ -4128,7 +4217,7 @@
         return DAR_FailedAlreadyDiagnosed;
       // FIXME: Support a non-canonical deduced type for 'auto'.
       Deduced = Context.getCanonicalType(Deduced);
-      Result = SubstituteAutoTransform(*this, Deduced).Apply(Type);
+      Result = SubstituteDeducedTypeTransform(*this, Deduced).Apply(Type);
       if (Result.isNull())
         return DAR_FailedAlreadyDiagnosed;
       return DAR_Succeeded;
@@ -4145,33 +4234,52 @@
   LocalInstantiationScope InstScope(*this);
 
   // Build template<class TemplParam> void Func(FuncParam);
-  TemplateTypeParmDecl *TemplParam =
-    TemplateTypeParmDecl::Create(Context, nullptr, SourceLocation(), Loc, 0, 0,
-                                 nullptr, false, false);
+  TemplateTypeParmDecl *TemplParam = TemplateTypeParmDecl::Create(
+      Context, nullptr, SourceLocation(), Loc, Depth, 0, nullptr, false, false);
   QualType TemplArg = QualType(TemplParam->getTypeForDecl(), 0);
   NamedDecl *TemplParamPtr = TemplParam;
   FixedSizeTemplateParameterListStorage<1, false> TemplateParamsSt(
       Loc, Loc, TemplParamPtr, Loc, nullptr);
 
-  QualType FuncParam = SubstituteAutoTransform(*this, TemplArg).Apply(Type);
+  QualType FuncParam =
+      SubstituteDeducedTypeTransform(*this, TemplArg, /*UseTypeSugar*/false)
+          .Apply(Type);
   assert(!FuncParam.isNull() &&
          "substituting template parameter for 'auto' failed");
 
   // Deduce type of TemplParam in Func(Init)
   SmallVector<DeducedTemplateArgument, 1> Deduced;
   Deduced.resize(1);
-  QualType InitType = Init->getType();
-  unsigned TDF = 0;
 
-  TemplateDeductionInfo Info(Loc);
+  TemplateDeductionInfo Info(Loc, Depth);
+
+  // If deduction failed, don't diagnose if the initializer is dependent; it
+  // might acquire a matching type in the instantiation.
+  auto DeductionFailed = [&]() -> DeduceAutoResult {
+    if (Init->isTypeDependent()) {
+      Result = SubstituteDeducedTypeTransform(*this, QualType()).Apply(Type);
+      assert(!Result.isNull() && "substituting DependentTy can't fail");
+      return DAR_Succeeded;
+    }
+    return DAR_Failed;
+  };
+
+  SmallVector<OriginalCallArg, 4> OriginalCallArgs;
 
   InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
   if (InitList) {
+    // Notionally, we substitute std::initializer_list<T> for 'auto' and deduce
+    // against that. Such deduction only succeeds if removing cv-qualifiers and
+    // references results in std::initializer_list<T>.
+    if (!Type.getType().getNonReferenceType()->getAs<AutoType>())
+      return DAR_Failed;
+
     for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) {
-      if (DeduceTemplateArgumentByListElement(*this, TemplateParamsSt.get(),
-                                              TemplArg, InitList->getInit(i),
-                                              Info, Deduced, TDF))
-        return DAR_Failed;
+      if (DeduceTemplateArgumentsFromCallArgument(
+              *this, TemplateParamsSt.get(), 0, TemplArg, InitList->getInit(i),
+              Info, Deduced, OriginalCallArgs, /*Decomposed*/ true,
+              /*ArgIdx*/ 0, /*TDF*/ 0))
+        return DeductionFailed();
     }
   } else {
     if (!getLangOpts().CPlusPlus && Init->refersToBitField()) {
@@ -4179,18 +4287,15 @@
       return DAR_FailedAlreadyDiagnosed;
     }
 
-    if (AdjustFunctionParmAndArgTypesForDeduction(
-            *this, TemplateParamsSt.get(), FuncParam, InitType, Init, TDF))
-      return DAR_Failed;
-
-    if (DeduceTemplateArgumentsByTypeMatch(*this, TemplateParamsSt.get(),
-                                           FuncParam, InitType, Info, Deduced,
-                                           TDF))
-      return DAR_Failed;
+    if (DeduceTemplateArgumentsFromCallArgument(
+            *this, TemplateParamsSt.get(), 0, FuncParam, Init, Info, Deduced,
+            OriginalCallArgs, /*Decomposed*/ false, /*ArgIdx*/ 0, /*TDF*/ 0))
+      return DeductionFailed();
   }
 
+  // Could be null if somehow 'auto' appears in a non-deduced context.
   if (Deduced[0].getKind() != TemplateArgument::Type)
-    return DAR_Failed;
+    return DeductionFailed();
 
   QualType DeducedType = Deduced[0].getAsType();
 
@@ -4200,18 +4305,20 @@
       return DAR_FailedAlreadyDiagnosed;
   }
 
-  Result = SubstituteAutoTransform(*this, DeducedType).Apply(Type);
+  Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type);
   if (Result.isNull())
-   return DAR_FailedAlreadyDiagnosed;
+    return DAR_FailedAlreadyDiagnosed;
 
   // Check that the deduced argument type is compatible with the original
   // argument type per C++ [temp.deduct.call]p4.
-  if (!InitList && !Result.isNull() &&
-      CheckOriginalCallArgDeduction(*this,
-                                    Sema::OriginalCallArg(FuncParam,0,InitType),
-                                    Result)) {
-    Result = QualType();
-    return DAR_Failed;
+  QualType DeducedA = InitList ? Deduced[0].getAsType() : Result;
+  for (const OriginalCallArg &OriginalArg : OriginalCallArgs) {
+    assert((bool)InitList == OriginalArg.DecomposedParam &&
+           "decomposed non-init-list in auto deduction?");
+    if (CheckOriginalCallArgDeduction(*this, OriginalArg, DeducedA)) {
+      Result = QualType();
+      return DeductionFailed();
+    }
   }
 
   return DAR_Succeeded;
@@ -4219,14 +4326,25 @@
 
 QualType Sema::SubstAutoType(QualType TypeWithAuto,
                              QualType TypeToReplaceAuto) {
-  return SubstituteAutoTransform(*this, TypeToReplaceAuto).
-               TransformType(TypeWithAuto);
+  if (TypeToReplaceAuto->isDependentType())
+    TypeToReplaceAuto = QualType();
+  return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto)
+      .TransformType(TypeWithAuto);
 }
 
-TypeSourceInfo* Sema::SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
-                             QualType TypeToReplaceAuto) {
-    return SubstituteAutoTransform(*this, TypeToReplaceAuto).
-               TransformType(TypeWithAuto);
+TypeSourceInfo *Sema::SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
+                                              QualType TypeToReplaceAuto) {
+  if (TypeToReplaceAuto->isDependentType())
+    TypeToReplaceAuto = QualType();
+  return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto)
+      .TransformType(TypeWithAuto);
+}
+
+QualType Sema::ReplaceAutoType(QualType TypeWithAuto,
+                               QualType TypeToReplaceAuto) {
+  return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto,
+                                        /*UseTypeSugar*/ false)
+      .TransformType(TypeWithAuto);
 }
 
 void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) {
@@ -4260,12 +4378,6 @@
   return StillUndeduced;
 }
 
-static void
-MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
-                           bool OnlyDeduced,
-                           unsigned Level,
-                           llvm::SmallBitVector &Deduced);
-
 /// \brief If this is a non-static member function,
 static void
 AddImplicitObjectParameterType(ASTContext &Context,
@@ -4398,6 +4510,10 @@
     if (Deduced[ArgIdx].isNull())
       break;
 
+  // FIXME: We fail to implement [temp.deduct.type]p1 along this path. We need
+  // to substitute the deduced arguments back into the template and check that
+  // we get the right type.
+
   if (ArgIdx == NumArgs) {
     // All template arguments were deduced. FT1 is at least as specialized
     // as FT2.
@@ -4601,12 +4717,12 @@
     // FIXME: Can we order the candidates in some sane way?
     for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I) {
       PartialDiagnostic PD = CandidateDiag;
-      PD << getTemplateArgumentBindingsText(
-          cast<FunctionDecl>(*I)->getPrimaryTemplate()->getTemplateParameters(),
-                    *cast<FunctionDecl>(*I)->getTemplateSpecializationArgs());
+      const auto *FD = cast<FunctionDecl>(*I);
+      PD << FD << getTemplateArgumentBindingsText(
+                      FD->getPrimaryTemplate()->getTemplateParameters(),
+                      *FD->getTemplateSpecializationArgs());
       if (!TargetType.isNull())
-        HandleFunctionTypeMismatch(PD, cast<FunctionDecl>(*I)->getType(),
-                                   TargetType);
+        HandleFunctionTypeMismatch(PD, FD->getType(), TargetType);
       Diag((*I)->getLocation(), PD);
     }
   }
@@ -4614,21 +4730,17 @@
   return SpecEnd;
 }
 
-/// \brief Returns the more specialized class template partial specialization
-/// according to the rules of partial ordering of class template partial
-/// specializations (C++ [temp.class.order]).
+/// Determine whether one partial specialization, P1, is at least as
+/// specialized than another, P2.
 ///
-/// \param PS1 the first class template partial specialization
-///
-/// \param PS2 the second class template partial specialization
-///
-/// \returns the more specialized class template partial specialization. If
-/// neither partial specialization is more specialized, returns NULL.
-ClassTemplatePartialSpecializationDecl *
-Sema::getMoreSpecializedPartialSpecialization(
-                                  ClassTemplatePartialSpecializationDecl *PS1,
-                                  ClassTemplatePartialSpecializationDecl *PS2,
-                                              SourceLocation Loc) {
+/// \tparam TemplateLikeDecl The kind of P2, which must be a
+/// TemplateDecl or {Class,Var}TemplatePartialSpecializationDecl.
+/// \param T1 The injected-class-name of P1 (faked for a variable template).
+/// \param T2 The injected-class-name of P2 (faked for a variable template).
+template<typename TemplateLikeDecl>
+static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2,
+                                     TemplateLikeDecl *P2,
+                                     TemplateDeductionInfo &Info) {
   // C++ [temp.class.order]p1:
   //   For two class template partial specializations, the first is at least as
   //   specialized as the second if, given the following rewrite to two
@@ -4654,37 +4766,50 @@
   // template partial specialization's template arguments, for
   // example.
   SmallVector<DeducedTemplateArgument, 4> Deduced;
-  TemplateDeductionInfo Info(Loc);
 
+  // Determine whether P1 is at least as specialized as P2.
+  Deduced.resize(P2->getTemplateParameters()->size());
+  if (DeduceTemplateArgumentsByTypeMatch(S, P2->getTemplateParameters(),
+                                         T2, T1, Info, Deduced, TDF_None,
+                                         /*PartialOrdering=*/true))
+    return false;
+
+  SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
+                                               Deduced.end());
+  Sema::InstantiatingTemplate Inst(S, Info.getLocation(), P2, DeducedArgs,
+                                   Info);
+  auto *TST1 = T1->castAs<TemplateSpecializationType>();
+  if (FinishTemplateArgumentDeduction(
+          S, P2, /*PartialOrdering=*/true,
+          TemplateArgumentList(TemplateArgumentList::OnStack,
+                               TST1->template_arguments()),
+          Deduced, Info))
+    return false;
+
+  return true;
+}
+
+/// \brief Returns the more specialized class template partial specialization
+/// according to the rules of partial ordering of class template partial
+/// specializations (C++ [temp.class.order]).
+///
+/// \param PS1 the first class template partial specialization
+///
+/// \param PS2 the second class template partial specialization
+///
+/// \returns the more specialized class template partial specialization. If
+/// neither partial specialization is more specialized, returns NULL.
+ClassTemplatePartialSpecializationDecl *
+Sema::getMoreSpecializedPartialSpecialization(
+                                  ClassTemplatePartialSpecializationDecl *PS1,
+                                  ClassTemplatePartialSpecializationDecl *PS2,
+                                              SourceLocation Loc) {
   QualType PT1 = PS1->getInjectedSpecializationType();
   QualType PT2 = PS2->getInjectedSpecializationType();
 
-  // Determine whether PS1 is at least as specialized as PS2
-  Deduced.resize(PS2->getTemplateParameters()->size());
-  bool Better1 = !DeduceTemplateArgumentsByTypeMatch(*this,
-                                            PS2->getTemplateParameters(),
-                                            PT2, PT1, Info, Deduced, TDF_None,
-                                            /*PartialOrdering=*/true);
-  if (Better1) {
-    SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),Deduced.end());
-    InstantiatingTemplate Inst(*this, Loc, PS2, DeducedArgs, Info);
-    Better1 = !::FinishTemplateArgumentDeduction(
-        *this, PS2, PS1->getTemplateArgs(), Deduced, Info);
-  }
-
-  // Determine whether PS2 is at least as specialized as PS1
-  Deduced.clear();
-  Deduced.resize(PS1->getTemplateParameters()->size());
-  bool Better2 = !DeduceTemplateArgumentsByTypeMatch(
-      *this, PS1->getTemplateParameters(), PT1, PT2, Info, Deduced, TDF_None,
-      /*PartialOrdering=*/true);
-  if (Better2) {
-    SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
-                                                 Deduced.end());
-    InstantiatingTemplate Inst(*this, Loc, PS1, DeducedArgs, Info);
-    Better2 = !::FinishTemplateArgumentDeduction(
-        *this, PS1, PS2->getTemplateArgs(), Deduced, Info);
-  }
+  TemplateDeductionInfo Info(Loc);
+  bool Better1 = isAtLeastAsSpecializedAs(*this, PT1, PT2, PS2, Info);
+  bool Better2 = isAtLeastAsSpecializedAs(*this, PT2, PT1, PS1, Info);
 
   if (Better1 == Better2)
     return nullptr;
@@ -4692,18 +4817,26 @@
   return Better1 ? PS1 : PS2;
 }
 
-/// TODO: Unify with ClassTemplatePartialSpecializationDecl version?
-///       May require unifying ClassTemplate(Partial)SpecializationDecl and
-///        VarTemplate(Partial)SpecializationDecl with a new data
-///        structure Template(Partial)SpecializationDecl, and
-///        using Template(Partial)SpecializationDecl as input type.
+bool Sema::isMoreSpecializedThanPrimary(
+    ClassTemplatePartialSpecializationDecl *Spec, TemplateDeductionInfo &Info) {
+  ClassTemplateDecl *Primary = Spec->getSpecializedTemplate();
+  QualType PrimaryT = Primary->getInjectedClassNameSpecialization();
+  QualType PartialT = Spec->getInjectedSpecializationType();
+  if (!isAtLeastAsSpecializedAs(*this, PartialT, PrimaryT, Primary, Info))
+    return false;
+  if (isAtLeastAsSpecializedAs(*this, PrimaryT, PartialT, Spec, Info)) {
+    Info.clearSFINAEDiagnostic();
+    return false;
+  }
+  return true;
+}
+
 VarTemplatePartialSpecializationDecl *
 Sema::getMoreSpecializedPartialSpecialization(
     VarTemplatePartialSpecializationDecl *PS1,
     VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc) {
-  SmallVector<DeducedTemplateArgument, 4> Deduced;
-  TemplateDeductionInfo Info(Loc);
-
+  // Pretend the variable template specializations are class template
+  // specializations and form a fake injected class name type for comparison.
   assert(PS1->getSpecializedTemplate() == PS2->getSpecializedTemplate() &&
          "the partial specializations being compared should specialize"
          " the same template.");
@@ -4714,47 +4847,102 @@
   QualType PT2 = Context.getTemplateSpecializationType(
       CanonTemplate, PS2->getTemplateArgs().asArray());
 
-  // Determine whether PS1 is at least as specialized as PS2
-  Deduced.resize(PS2->getTemplateParameters()->size());
-  bool Better1 = !DeduceTemplateArgumentsByTypeMatch(
-      *this, PS2->getTemplateParameters(), PT2, PT1, Info, Deduced, TDF_None,
-      /*PartialOrdering=*/true);
-  if (Better1) {
-    SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
-                                                 Deduced.end());
-    InstantiatingTemplate Inst(*this, Loc, PS2, DeducedArgs, Info);
-    Better1 = !::FinishTemplateArgumentDeduction(*this, PS2,
-                                                 PS1->getTemplateArgs(),
-                                                 Deduced, Info);
-  }
-
-  // Determine whether PS2 is at least as specialized as PS1
-  Deduced.clear();
-  Deduced.resize(PS1->getTemplateParameters()->size());
-  bool Better2 = !DeduceTemplateArgumentsByTypeMatch(*this,
-                                            PS1->getTemplateParameters(),
-                                            PT1, PT2, Info, Deduced, TDF_None,
-                                            /*PartialOrdering=*/true);
-  if (Better2) {
-    SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),Deduced.end());
-    InstantiatingTemplate Inst(*this, Loc, PS1, DeducedArgs, Info);
-    Better2 = !::FinishTemplateArgumentDeduction(*this, PS1,
-                                                 PS2->getTemplateArgs(),
-                                                 Deduced, Info);
-  }
+  TemplateDeductionInfo Info(Loc);
+  bool Better1 = isAtLeastAsSpecializedAs(*this, PT1, PT2, PS2, Info);
+  bool Better2 = isAtLeastAsSpecializedAs(*this, PT2, PT1, PS1, Info);
 
   if (Better1 == Better2)
     return nullptr;
 
-  return Better1? PS1 : PS2;
+  return Better1 ? PS1 : PS2;
 }
 
-static void
-MarkUsedTemplateParameters(ASTContext &Ctx,
-                           const TemplateArgument &TemplateArg,
-                           bool OnlyDeduced,
-                           unsigned Depth,
-                           llvm::SmallBitVector &Used);
+bool Sema::isMoreSpecializedThanPrimary(
+    VarTemplatePartialSpecializationDecl *Spec, TemplateDeductionInfo &Info) {
+  TemplateDecl *Primary = Spec->getSpecializedTemplate();
+  // FIXME: Cache the injected template arguments rather than recomputing
+  // them for each partial specialization.
+  SmallVector<TemplateArgument, 8> PrimaryArgs;
+  Context.getInjectedTemplateArgs(Primary->getTemplateParameters(),
+                                  PrimaryArgs);
+
+  TemplateName CanonTemplate =
+      Context.getCanonicalTemplateName(TemplateName(Primary));
+  QualType PrimaryT = Context.getTemplateSpecializationType(
+      CanonTemplate, PrimaryArgs);
+  QualType PartialT = Context.getTemplateSpecializationType(
+      CanonTemplate, Spec->getTemplateArgs().asArray());
+  if (!isAtLeastAsSpecializedAs(*this, PartialT, PrimaryT, Primary, Info))
+    return false;
+  if (isAtLeastAsSpecializedAs(*this, PrimaryT, PartialT, Spec, Info)) {
+    Info.clearSFINAEDiagnostic();
+    return false;
+  }
+  return true;
+}
+
+bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
+     TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc) {
+  // C++1z [temp.arg.template]p4: (DR 150)
+  //   A template template-parameter P is at least as specialized as a
+  //   template template-argument A if, given the following rewrite to two
+  //   function templates...
+
+  // Rather than synthesize function templates, we merely perform the
+  // equivalent partial ordering by performing deduction directly on
+  // the template parameter lists of the template template parameters.
+  //
+  //   Given an invented class template X with the template parameter list of
+  //   A (including default arguments):
+  TemplateName X = Context.getCanonicalTemplateName(TemplateName(AArg));
+  TemplateParameterList *A = AArg->getTemplateParameters();
+
+  //    - Each function template has a single function parameter whose type is
+  //      a specialization of X with template arguments corresponding to the
+  //      template parameters from the respective function template
+  SmallVector<TemplateArgument, 8> AArgs;
+  Context.getInjectedTemplateArgs(A, AArgs);
+
+  // Check P's arguments against A's parameter list. This will fill in default
+  // template arguments as needed. AArgs are already correct by construction.
+  // We can't just use CheckTemplateIdType because that will expand alias
+  // templates.
+  SmallVector<TemplateArgument, 4> PArgs;
+  {
+    SFINAETrap Trap(*this);
+
+    Context.getInjectedTemplateArgs(P, PArgs);
+    TemplateArgumentListInfo PArgList(P->getLAngleLoc(), P->getRAngleLoc());
+    for (unsigned I = 0, N = P->size(); I != N; ++I) {
+      // Unwrap packs that getInjectedTemplateArgs wrapped around pack
+      // expansions, to form an "as written" argument list.
+      TemplateArgument Arg = PArgs[I];
+      if (Arg.getKind() == TemplateArgument::Pack) {
+        assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion());
+        Arg = *Arg.pack_begin();
+      }
+      PArgList.addArgument(getTrivialTemplateArgumentLoc(
+          Arg, QualType(), P->getParam(I)->getLocation()));
+    }
+    PArgs.clear();
+
+    // C++1z [temp.arg.template]p3:
+    //   If the rewrite produces an invalid type, then P is not at least as
+    //   specialized as A.
+    if (CheckTemplateArgumentList(AArg, Loc, PArgList, false, PArgs) ||
+        Trap.hasErrorOccurred())
+      return false;
+  }
+
+  QualType AType = Context.getTemplateSpecializationType(X, AArgs);
+  QualType PType = Context.getTemplateSpecializationType(X, PArgs);
+
+  //   ... the function template corresponding to P is at least as specialized
+  //   as the function template corresponding to A according to the partial
+  //   ordering rules for function templates.
+  TemplateDeductionInfo Info(Loc, A->getDepth());
+  return isAtLeastAsSpecializedAs(*this, PType, AType, AArg, Info);
+}
 
 /// \brief Mark the template parameters that are used by the given
 /// expression.
@@ -4965,7 +5153,7 @@
     //   not the last template argument, the entire template argument list is a
     //   non-deduced context.
     if (OnlyDeduced &&
-        hasPackExpansionBeforeEnd(Spec->getArgs(), Spec->getNumArgs()))
+        hasPackExpansionBeforeEnd(Spec->template_arguments()))
       break;
 
     for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
@@ -5055,8 +5243,9 @@
     break;
 
   case Type::Auto:
+  case Type::DeducedTemplateSpecialization:
     MarkUsedTemplateParameters(Ctx,
-                               cast<AutoType>(T)->getDeducedType(),
+                               cast<DeducedType>(T)->getDeducedType(),
                                OnlyDeduced, Depth, Used);
 
   // None of these types have any template parameters in them.
@@ -5140,7 +5329,7 @@
   //   the last template argument, the entire template argument list is a
   //   non-deduced context.
   if (OnlyDeduced &&
-      hasPackExpansionBeforeEnd(TemplateArgs.data(), TemplateArgs.size()))
+      hasPackExpansionBeforeEnd(TemplateArgs.asArray()))
     return;
 
   for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 321fd69..314dfe3 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -184,7 +184,7 @@
   return Result;
 }
 
-bool Sema::ActiveTemplateInstantiation::isInstantiationRecord() const {
+bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
   switch (Kind) {
   case TemplateInstantiation:
   case ExceptionSpecInstantiation:
@@ -196,19 +196,19 @@
     return true;
 
   case DefaultTemplateArgumentChecking:
+  case DeclaringSpecialMember:
     return false;
   }
 
-  llvm_unreachable("Invalid InstantiationKind!");
+  llvm_unreachable("Invalid SynthesisKind!");
 }
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
-    Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind,
+    Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind,
     SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
     Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
     sema::TemplateDeductionInfo *DeductionInfo)
-    : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext(
-                            SemaRef.InNonInstantiationSFINAEContext) {
+    : SemaRef(SemaRef) {
   // Don't allow further instantiation if a fatal error and an uncompilable
   // error have occurred. Any diagnostics we might have raised will not be
   // visible, and we do not need to construct a correct AST.
@@ -219,7 +219,7 @@
   }
   Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
   if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
+    CodeSynthesisContext Inst;
     Inst.Kind = Kind;
     Inst.PointOfInstantiation = PointOfInstantiation;
     Inst.Entity = Entity;
@@ -228,14 +228,12 @@
     Inst.NumTemplateArgs = TemplateArgs.size();
     Inst.DeductionInfo = DeductionInfo;
     Inst.InstantiationRange = InstantiationRange;
+    SemaRef.pushCodeSynthesisContext(Inst);
+
     AlreadyInstantiating =
         !SemaRef.InstantiatingSpecializations
              .insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind))
              .second;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-    if (!Inst.isInstantiationRecord())
-      ++SemaRef.NonInstantiationEntries;
   }
 }
 
@@ -243,14 +241,14 @@
     Sema &SemaRef, SourceLocation PointOfInstantiation, Decl *Entity,
     SourceRange InstantiationRange)
     : InstantiatingTemplate(SemaRef,
-                            ActiveTemplateInstantiation::TemplateInstantiation,
+                            CodeSynthesisContext::TemplateInstantiation,
                             PointOfInstantiation, InstantiationRange, Entity) {}
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionDecl *Entity,
     ExceptionSpecification, SourceRange InstantiationRange)
     : InstantiatingTemplate(
-          SemaRef, ActiveTemplateInstantiation::ExceptionSpecInstantiation,
+          SemaRef, CodeSynthesisContext::ExceptionSpecInstantiation,
           PointOfInstantiation, InstantiationRange, Entity) {}
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
@@ -259,7 +257,7 @@
     SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
-          ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation,
+          CodeSynthesisContext::DefaultTemplateArgumentInstantiation,
           PointOfInstantiation, InstantiationRange, getAsNamedDecl(Param),
           Template, TemplateArgs) {}
 
@@ -267,24 +265,35 @@
     Sema &SemaRef, SourceLocation PointOfInstantiation,
     FunctionTemplateDecl *FunctionTemplate,
     ArrayRef<TemplateArgument> TemplateArgs,
-    ActiveTemplateInstantiation::InstantiationKind Kind,
+    CodeSynthesisContext::SynthesisKind Kind,
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
     : InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation,
                             InstantiationRange, FunctionTemplate, nullptr,
                             TemplateArgs, &DeductionInfo) {
   assert(
-    Kind == ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution ||
-    Kind == ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution);
+    Kind == CodeSynthesisContext::ExplicitTemplateArgumentSubstitution ||
+    Kind == CodeSynthesisContext::DeducedTemplateArgumentSubstitution);
 }
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
+    TemplateDecl *Template,
+    ArrayRef<TemplateArgument> TemplateArgs,
+    sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
+    : InstantiatingTemplate(
+          SemaRef,
+          CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
+          PointOfInstantiation, InstantiationRange, Template, nullptr,
+          TemplateArgs, &DeductionInfo) {}
+
+Sema::InstantiatingTemplate::InstantiatingTemplate(
+    Sema &SemaRef, SourceLocation PointOfInstantiation,
     ClassTemplatePartialSpecializationDecl *PartialSpec,
     ArrayRef<TemplateArgument> TemplateArgs,
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
-          ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
+          CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
           PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
           TemplateArgs, &DeductionInfo) {}
 
@@ -295,7 +304,7 @@
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
-          ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
+          CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
           PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
           TemplateArgs, &DeductionInfo) {}
 
@@ -304,7 +313,7 @@
     ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
-          ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation,
+          CodeSynthesisContext::DefaultFunctionArgumentInstantiation,
           PointOfInstantiation, InstantiationRange, Param, nullptr,
           TemplateArgs) {}
 
@@ -314,7 +323,7 @@
     SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
-          ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution,
+          CodeSynthesisContext::PriorTemplateArgumentSubstitution,
           PointOfInstantiation, InstantiationRange, Param, Template,
           TemplateArgs) {}
 
@@ -324,7 +333,7 @@
     SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
-          ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution,
+          CodeSynthesisContext::PriorTemplateArgumentSubstitution,
           PointOfInstantiation, InstantiationRange, Param, Template,
           TemplateArgs) {}
 
@@ -333,36 +342,59 @@
     NamedDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
     SourceRange InstantiationRange)
     : InstantiatingTemplate(
-          SemaRef, ActiveTemplateInstantiation::DefaultTemplateArgumentChecking,
+          SemaRef, CodeSynthesisContext::DefaultTemplateArgumentChecking,
           PointOfInstantiation, InstantiationRange, Param, Template,
           TemplateArgs) {}
 
+void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {
+  Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext;
+  InNonInstantiationSFINAEContext = false;
+
+  CodeSynthesisContexts.push_back(Ctx);
+
+  if (!Ctx.isInstantiationRecord())
+    ++NonInstantiationEntries;
+}
+
+void Sema::popCodeSynthesisContext() {
+  auto &Active = CodeSynthesisContexts.back();
+  if (!Active.isInstantiationRecord()) {
+    assert(NonInstantiationEntries > 0);
+    --NonInstantiationEntries;
+  }
+
+  InNonInstantiationSFINAEContext = Active.SavedInNonInstantiationSFINAEContext;
+
+  // Name lookup no longer looks in this template's defining module.
+  assert(CodeSynthesisContexts.size() >=
+             CodeSynthesisContextLookupModules.size() &&
+         "forgot to remove a lookup module for a template instantiation");
+  if (CodeSynthesisContexts.size() ==
+      CodeSynthesisContextLookupModules.size()) {
+    if (Module *M = CodeSynthesisContextLookupModules.back())
+      LookupModulesCache.erase(M);
+    CodeSynthesisContextLookupModules.pop_back();
+  }
+
+  // If we've left the code synthesis context for the current context stack,
+  // stop remembering that we've emitted that stack.
+  if (CodeSynthesisContexts.size() ==
+      LastEmittedCodeSynthesisContextDepth)
+    LastEmittedCodeSynthesisContextDepth = 0;
+
+  CodeSynthesisContexts.pop_back();
+}
+
 void Sema::InstantiatingTemplate::Clear() {
   if (!Invalid) {
-    auto &Active = SemaRef.ActiveTemplateInstantiations.back();
-    if (!Active.isInstantiationRecord()) {
-      assert(SemaRef.NonInstantiationEntries > 0);
-      --SemaRef.NonInstantiationEntries;
-    }
-    SemaRef.InNonInstantiationSFINAEContext
-      = SavedInNonInstantiationSFINAEContext;
-
-    // Name lookup no longer looks in this template's defining module.
-    assert(SemaRef.ActiveTemplateInstantiations.size() >=
-           SemaRef.ActiveTemplateInstantiationLookupModules.size() &&
-           "forgot to remove a lookup module for a template instantiation");
-    if (SemaRef.ActiveTemplateInstantiations.size() ==
-        SemaRef.ActiveTemplateInstantiationLookupModules.size()) {
-      if (Module *M = SemaRef.ActiveTemplateInstantiationLookupModules.back())
-        SemaRef.LookupModulesCache.erase(M);
-      SemaRef.ActiveTemplateInstantiationLookupModules.pop_back();
-    }
-
-    if (!AlreadyInstantiating)
+    if (!AlreadyInstantiating) {
+      auto &Active = SemaRef.CodeSynthesisContexts.back();
       SemaRef.InstantiatingSpecializations.erase(
           std::make_pair(Active.Entity, Active.Kind));
+    }
 
-    SemaRef.ActiveTemplateInstantiations.pop_back();
+    SemaRef.popCodeSynthesisContext();
+
     Invalid = true;
   }
 }
@@ -371,8 +403,8 @@
                                         SourceLocation PointOfInstantiation,
                                            SourceRange InstantiationRange) {
   assert(SemaRef.NonInstantiationEntries <=
-                                   SemaRef.ActiveTemplateInstantiations.size());
-  if ((SemaRef.ActiveTemplateInstantiations.size() - 
+         SemaRef.CodeSynthesisContexts.size());
+  if ((SemaRef.CodeSynthesisContexts.size() - 
           SemaRef.NonInstantiationEntries)
         <= SemaRef.getLangOpts().InstantiationDepth)
     return false;
@@ -390,18 +422,18 @@
 /// notes.
 void Sema::PrintInstantiationStack() {
   // Determine which template instantiations to skip, if any.
-  unsigned SkipStart = ActiveTemplateInstantiations.size(), SkipEnd = SkipStart;
+  unsigned SkipStart = CodeSynthesisContexts.size(), SkipEnd = SkipStart;
   unsigned Limit = Diags.getTemplateBacktraceLimit();
-  if (Limit && Limit < ActiveTemplateInstantiations.size()) {
+  if (Limit && Limit < CodeSynthesisContexts.size()) {
     SkipStart = Limit / 2 + Limit % 2;
-    SkipEnd = ActiveTemplateInstantiations.size() - Limit / 2;
+    SkipEnd = CodeSynthesisContexts.size() - Limit / 2;
   }
 
   // FIXME: In all of these cases, we need to show the template arguments
   unsigned InstantiationIdx = 0;
-  for (SmallVectorImpl<ActiveTemplateInstantiation>::reverse_iterator
-         Active = ActiveTemplateInstantiations.rbegin(),
-         ActiveEnd = ActiveTemplateInstantiations.rend();
+  for (SmallVectorImpl<CodeSynthesisContext>::reverse_iterator
+         Active = CodeSynthesisContexts.rbegin(),
+         ActiveEnd = CodeSynthesisContexts.rend();
        Active != ActiveEnd;
        ++Active, ++InstantiationIdx) {
     // Skip this instantiation?
@@ -410,21 +442,20 @@
         // Note that we're skipping instantiations.
         Diags.Report(Active->PointOfInstantiation,
                      diag::note_instantiation_contexts_suppressed)
-          << unsigned(ActiveTemplateInstantiations.size() - Limit);
+          << unsigned(CodeSynthesisContexts.size() - Limit);
       }
       continue;
     }
 
     switch (Active->Kind) {
-    case ActiveTemplateInstantiation::TemplateInstantiation: {
+    case CodeSynthesisContext::TemplateInstantiation: {
       Decl *D = Active->Entity;
       if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
         unsigned DiagID = diag::note_template_member_class_here;
         if (isa<ClassTemplateSpecializationDecl>(Record))
           DiagID = diag::note_template_class_instantiation_here;
         Diags.Report(Active->PointOfInstantiation, DiagID)
-          << Context.getTypeDeclType(Record)
-          << Active->InstantiationRange;
+          << Record << Active->InstantiationRange;
       } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
         unsigned DiagID;
         if (Function->getPrimaryTemplate())
@@ -459,7 +490,7 @@
       break;
     }
 
-    case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation: {
+    case CodeSynthesisContext::DefaultTemplateArgumentInstantiation: {
       TemplateDecl *Template = cast<TemplateDecl>(Active->Template);
       SmallVector<char, 128> TemplateArgsStr;
       llvm::raw_svector_ostream OS(TemplateArgsStr);
@@ -473,7 +504,7 @@
       break;
     }
 
-    case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution: {
+    case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution: {
       FunctionTemplateDecl *FnTmpl = cast<FunctionTemplateDecl>(Active->Entity);
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_explicit_template_arg_substitution_here)
@@ -485,20 +516,9 @@
       break;
     }
 
-    case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
-      if (ClassTemplatePartialSpecializationDecl *PartialSpec =
-            dyn_cast<ClassTemplatePartialSpecializationDecl>(Active->Entity)) {
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_partial_spec_deduct_instantiation_here)
-          << Context.getTypeDeclType(PartialSpec)
-          << getTemplateArgumentBindingsText(
-                                         PartialSpec->getTemplateParameters(), 
-                                             Active->TemplateArgs, 
-                                             Active->NumTemplateArgs)
-          << Active->InstantiationRange;
-      } else {
-        FunctionTemplateDecl *FnTmpl
-          = cast<FunctionTemplateDecl>(Active->Entity);
+    case CodeSynthesisContext::DeducedTemplateArgumentSubstitution: {
+      if (FunctionTemplateDecl *FnTmpl =
+              dyn_cast<FunctionTemplateDecl>(Active->Entity)) {
         Diags.Report(Active->PointOfInstantiation,
                      diag::note_function_template_deduction_instantiation_here)
           << FnTmpl
@@ -506,10 +526,35 @@
                                              Active->TemplateArgs, 
                                              Active->NumTemplateArgs)
           << Active->InstantiationRange;
+      } else {
+        bool IsVar = isa<VarTemplateDecl>(Active->Entity) ||
+                     isa<VarTemplateSpecializationDecl>(Active->Entity);
+        bool IsTemplate = false;
+        TemplateParameterList *Params;
+        if (auto *D = dyn_cast<TemplateDecl>(Active->Entity)) {
+          IsTemplate = true;
+          Params = D->getTemplateParameters();
+        } else if (auto *D = dyn_cast<ClassTemplatePartialSpecializationDecl>(
+                       Active->Entity)) {
+          Params = D->getTemplateParameters();
+        } else if (auto *D = dyn_cast<VarTemplatePartialSpecializationDecl>(
+                       Active->Entity)) {
+          Params = D->getTemplateParameters();
+        } else {
+          llvm_unreachable("unexpected template kind");
+        }
+
+        Diags.Report(Active->PointOfInstantiation,
+                     diag::note_deduced_template_arg_substitution_here)
+          << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity)
+          << getTemplateArgumentBindingsText(Params, Active->TemplateArgs, 
+                                             Active->NumTemplateArgs)
+          << Active->InstantiationRange;
       }
       break;
+    }
 
-    case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation: {
+    case CodeSynthesisContext::DefaultFunctionArgumentInstantiation: {
       ParmVarDecl *Param = cast<ParmVarDecl>(Active->Entity);
       FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
 
@@ -525,7 +570,7 @@
       break;
     }
 
-    case ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution: {
+    case CodeSynthesisContext::PriorTemplateArgumentSubstitution: {
       NamedDecl *Parm = cast<NamedDecl>(Active->Entity);
       std::string Name;
       if (!Parm->getName().empty())
@@ -549,7 +594,7 @@
       break;
     }
 
-    case ActiveTemplateInstantiation::DefaultTemplateArgumentChecking: {
+    case CodeSynthesisContext::DefaultTemplateArgumentChecking: {
       TemplateParameterList *TemplateParams = nullptr;
       if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
         TemplateParams = Template->getTemplateParameters();
@@ -567,12 +612,18 @@
       break;
     }
 
-    case ActiveTemplateInstantiation::ExceptionSpecInstantiation:
+    case CodeSynthesisContext::ExceptionSpecInstantiation:
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_template_exception_spec_instantiation_here)
         << cast<FunctionDecl>(Active->Entity)
         << Active->InstantiationRange;
       break;
+
+    case CodeSynthesisContext::DeclaringSpecialMember:
+      Diags.Report(Active->PointOfInstantiation,
+                   diag::note_in_declaration_of_implicit_special_member)
+        << cast<CXXRecordDecl>(Active->Entity) << Active->SpecialMember;
+      break;
     }
   }
 }
@@ -581,39 +632,49 @@
   if (InNonInstantiationSFINAEContext)
     return Optional<TemplateDeductionInfo *>(nullptr);
 
-  for (SmallVectorImpl<ActiveTemplateInstantiation>::const_reverse_iterator
-         Active = ActiveTemplateInstantiations.rbegin(),
-         ActiveEnd = ActiveTemplateInstantiations.rend();
+  for (SmallVectorImpl<CodeSynthesisContext>::const_reverse_iterator
+         Active = CodeSynthesisContexts.rbegin(),
+         ActiveEnd = CodeSynthesisContexts.rend();
        Active != ActiveEnd;
        ++Active) 
   {
-    switch(Active->Kind) {
-    case ActiveTemplateInstantiation::TemplateInstantiation:
+    switch (Active->Kind) {
+    case CodeSynthesisContext::TemplateInstantiation:
       // An instantiation of an alias template may or may not be a SFINAE
       // context, depending on what else is on the stack.
       if (isa<TypeAliasTemplateDecl>(Active->Entity))
         break;
       // Fall through.
-    case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation:
-    case ActiveTemplateInstantiation::ExceptionSpecInstantiation:
+    case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
+    case CodeSynthesisContext::ExceptionSpecInstantiation:
       // This is a template instantiation, so there is no SFINAE.
       return None;
 
-    case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation:
-    case ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution:
-    case ActiveTemplateInstantiation::DefaultTemplateArgumentChecking:
+    case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
+    case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
+    case CodeSynthesisContext::DefaultTemplateArgumentChecking:
       // A default template argument instantiation and substitution into
       // template parameters with arguments for prior parameters may or may 
       // not be a SFINAE context; look further up the stack.
       break;
 
-    case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution:
-    case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
+    case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
+    case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
       // We're either substitution explicitly-specified template arguments
       // or deduced template arguments, so SFINAE applies.
       assert(Active->DeductionInfo && "Missing deduction info pointer");
       return Active->DeductionInfo;
+
+    case CodeSynthesisContext::DeclaringSpecialMember:
+      // This happens in a context unrelated to template instantiation, so
+      // there is no SFINAE.
+      return None;
     }
+
+    // The inner context was transparent for SFINAE. If it occurred within a
+    // non-instantiation SFINAE context, then SFINAE applies.
+    if (Active->SavedInNonInstantiationSFINAEContext)
+      return Optional<TemplateDeductionInfo *>(nullptr);
   }
 
   return None;
@@ -782,7 +843,8 @@
     TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
                           SourceLocation NameLoc,
                           QualType ObjectType = QualType(),
-                          NamedDecl *FirstQualifierInScope = nullptr);
+                          NamedDecl *FirstQualifierInScope = nullptr,
+                          bool AllowInjectedClassName = false);
 
     const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH);
 
@@ -1016,11 +1078,10 @@
                                                                     T);
 }
 
-TemplateName TemplateInstantiator::TransformTemplateName(CXXScopeSpec &SS,
-                                                         TemplateName Name,
-                                                         SourceLocation NameLoc,
-                                                         QualType ObjectType,
-                                             NamedDecl *FirstQualifierInScope) {
+TemplateName TemplateInstantiator::TransformTemplateName(
+    CXXScopeSpec &SS, TemplateName Name, SourceLocation NameLoc,
+    QualType ObjectType, NamedDecl *FirstQualifierInScope,
+    bool AllowInjectedClassName) {
   if (TemplateTemplateParmDecl *TTP
        = dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())) {
     if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
@@ -1071,9 +1132,10 @@
     Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
     return Arg.getAsTemplate();
   }
-  
-  return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType, 
-                                          FirstQualifierInScope);  
+
+  return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType,
+                                          FirstQualifierInScope,
+                                          AllowInjectedClassName);
 }
 
 ExprResult 
@@ -1096,6 +1158,23 @@
     return E;
 
   TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
+
+  if (TemplateArgs.getNumLevels() != TemplateArgs.getNumSubstitutedLevels()) {
+    // We're performing a partial substitution, so the substituted argument
+    // could be dependent. As a result we can't create a SubstNonType*Expr
+    // node now, since that represents a fully-substituted argument.
+    // FIXME: We should have some AST representation for this.
+    if (Arg.getKind() == TemplateArgument::Pack) {
+      // FIXME: This won't work for alias templates.
+      assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
+             "unexpected pack arguments in partial substitution");
+      Arg = Arg.pack_begin()->getPackExpansionPattern();
+    }
+    assert(Arg.getKind() == TemplateArgument::Expression &&
+           "unexpected nontype template argument kind in partial substitution");
+    return Arg.getAsExpr();
+  }
+
   if (NTTP->isParameterPack()) {
     assert(Arg.getKind() == TemplateArgument::Pack && 
            "Missing argument pack");
@@ -1404,12 +1483,9 @@
     NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
                                   TransformDecl(TL.getNameLoc(), OldTTPDecl));
 
-  QualType Result
-    = getSema().Context.getTemplateTypeParmType(T->getDepth()
-                                                 - TemplateArgs.getNumLevels(),
-                                                T->getIndex(),
-                                                T->isParameterPack(),
-                                                NewTTPDecl);
+  QualType Result = getSema().Context.getTemplateTypeParmType(
+      T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(),
+      T->isParameterPack(), NewTTPDecl);
   TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());
   return Result;
@@ -1465,13 +1541,17 @@
 /// a cast expression) or that the entity has no name (e.g., an
 /// unnamed function parameter).
 ///
+/// \param AllowDeducedTST Whether a DeducedTemplateSpecializationType is
+/// acceptable as the top level type of the result.
+///
 /// \returns If the instantiation succeeds, the instantiated
 /// type. Otherwise, produces diagnostics and returns a NULL type.
 TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
                                 const MultiLevelTemplateArgumentList &Args,
                                 SourceLocation Loc,
-                                DeclarationName Entity) {
-  assert(!ActiveTemplateInstantiations.empty() &&
+                                DeclarationName Entity,
+                                bool AllowDeducedTST) {
+  assert(!CodeSynthesisContexts.empty() &&
          "Cannot perform an instantiation without some context on the "
          "instantiation stack");
   
@@ -1480,14 +1560,15 @@
     return T;
 
   TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
-  return Instantiator.TransformType(T);
+  return AllowDeducedTST ? Instantiator.TransformTypeWithDeducedTST(T)
+                         : Instantiator.TransformType(T);
 }
 
 TypeSourceInfo *Sema::SubstType(TypeLoc TL,
                                 const MultiLevelTemplateArgumentList &Args,
                                 SourceLocation Loc,
                                 DeclarationName Entity) {
-  assert(!ActiveTemplateInstantiations.empty() &&
+  assert(!CodeSynthesisContexts.empty() &&
          "Cannot perform an instantiation without some context on the "
          "instantiation stack");
   
@@ -1517,7 +1598,7 @@
 QualType Sema::SubstType(QualType T,
                          const MultiLevelTemplateArgumentList &TemplateArgs,
                          SourceLocation Loc, DeclarationName Entity) {
-  assert(!ActiveTemplateInstantiations.empty() &&
+  assert(!CodeSynthesisContexts.empty() &&
          "Cannot perform an instantiation without some context on the "
          "instantiation stack");
 
@@ -1562,7 +1643,7 @@
                                 DeclarationName Entity,
                                 CXXRecordDecl *ThisContext,
                                 unsigned ThisTypeQuals) {
-  assert(!ActiveTemplateInstantiations.empty() &&
+  assert(!CodeSynthesisContexts.empty() &&
          "Cannot perform an instantiation without some context on the "
          "instantiation stack");
 
@@ -1687,7 +1768,7 @@
       // Instantiate default arguments for methods of local classes (DR1484)
       // and non-defining declarations.
       Sema::ContextRAII SavedContext(*this, OwningFunc);
-      LocalInstantiationScope Local(*this);
+      LocalInstantiationScope Local(*this, true);
       ExprResult NewArg = SubstExpr(Arg, TemplateArgs);
       if (NewArg.isUsable()) {
         // It would be nice if we still had this.
@@ -1734,7 +1815,7 @@
     SmallVectorImpl<QualType> &ParamTypes,
     SmallVectorImpl<ParmVarDecl *> *OutParams,
     ExtParameterInfoBuilder &ParamInfos) {
-  assert(!ActiveTemplateInstantiations.empty() &&
+  assert(!CodeSynthesisContexts.empty() &&
          "Cannot perform an instantiation without some context on the "
          "instantiation stack");
   
@@ -2240,9 +2321,6 @@
   if (auto *L = getASTMutationListener())
     L->DefaultMemberInitializerInstantiated(Instantiation);
 
-  // Exit the scope of this instantiation.
-  SavedContext.pop();
-
   // Return true if the in-class initializer is still missing.
   return !Instantiation->getInClassInitializer();
 }
@@ -2256,16 +2334,18 @@
   };
 }
 
-bool Sema::InstantiateClassTemplateSpecialization(
-    SourceLocation PointOfInstantiation,
+/// Get the instantiation pattern to use to instantiate the definition of a
+/// given ClassTemplateSpecializationDecl (either the pattern of the primary
+/// template or of a partial specialization).
+static CXXRecordDecl *
+getPatternForClassTemplateSpecialization(
+    Sema &S, SourceLocation PointOfInstantiation,
     ClassTemplateSpecializationDecl *ClassTemplateSpec,
     TemplateSpecializationKind TSK, bool Complain) {
-  // Perform the actual instantiation on the canonical declaration.
-  ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
-                                         ClassTemplateSpec->getCanonicalDecl());
-  if (ClassTemplateSpec->isInvalidDecl())
-    return true;
-  
+  Sema::InstantiatingTemplate Inst(S, PointOfInstantiation, ClassTemplateSpec);
+  if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
+    return nullptr;
+
   ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
   CXXRecordDecl *Pattern = nullptr;
 
@@ -2285,15 +2365,13 @@
   for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
     ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
     TemplateDeductionInfo Info(FailedCandidates.getLocation());
-    if (TemplateDeductionResult Result
-          = DeduceTemplateArguments(Partial,
-                                    ClassTemplateSpec->getTemplateArgs(),
-                                    Info)) {
+    if (Sema::TemplateDeductionResult Result = S.DeduceTemplateArguments(
+            Partial, ClassTemplateSpec->getTemplateArgs(), Info)) {
       // Store the failed-deduction information for use in diagnostics, later.
       // TODO: Actually use the failed-deduction info?
       FailedCandidates.addCandidate().set(
           DeclAccessPair::make(Template, AS_public), Partial,
-          MakeDeductionFailureInfo(Context, Result, Info));
+          MakeDeductionFailureInfo(S.Context, Result, Info));
       (void)Result;
     } else {
       Matched.push_back(PartialSpecMatchResult());
@@ -2323,9 +2401,8 @@
       for (SmallVectorImpl<MatchResult>::iterator P = Best + 1,
                                                PEnd = Matched.end();
            P != PEnd; ++P) {
-        if (getMoreSpecializedPartialSpecialization(P->Partial, Best->Partial,
-                                                    PointOfInstantiation) 
-              == P->Partial)
+        if (S.getMoreSpecializedPartialSpecialization(
+                P->Partial, Best->Partial, PointOfInstantiation) == P->Partial)
           Best = P;
       }
       
@@ -2336,9 +2413,9 @@
                                                PEnd = Matched.end();
            P != PEnd; ++P) {
         if (P != Best &&
-            getMoreSpecializedPartialSpecialization(P->Partial, Best->Partial,
-                                                    PointOfInstantiation)
-              != Best->Partial) {
+            S.getMoreSpecializedPartialSpecialization(P->Partial, Best->Partial,
+                                                      PointOfInstantiation) !=
+                Best->Partial) {
           Ambiguous = true;
           break;
         }
@@ -2346,20 +2423,20 @@
        
       if (Ambiguous) {
         // Partial ordering did not produce a clear winner. Complain.
+        Inst.Clear();
         ClassTemplateSpec->setInvalidDecl();
-        Diag(PointOfInstantiation, diag::err_partial_spec_ordering_ambiguous)
+        S.Diag(PointOfInstantiation, diag::err_partial_spec_ordering_ambiguous)
           << ClassTemplateSpec;
         
         // Print the matching partial specializations.
         for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
                                                  PEnd = Matched.end();
              P != PEnd; ++P)
-          Diag(P->Partial->getLocation(), diag::note_partial_spec_match)
-            << getTemplateArgumentBindingsText(
-                                            P->Partial->getTemplateParameters(),
-                                               *P->Args);
+          S.Diag(P->Partial->getLocation(), diag::note_partial_spec_match)
+            << S.getTemplateArgumentBindingsText(
+                   P->Partial->getTemplateParameters(), *P->Args);
 
-        return true;
+        return nullptr;
       }
     }
     
@@ -2392,13 +2469,27 @@
     Pattern = OrigTemplate->getTemplatedDecl();
   }
 
-  bool Result = InstantiateClass(PointOfInstantiation, ClassTemplateSpec, 
-                                 Pattern,
-                                getTemplateInstantiationArgs(ClassTemplateSpec),
-                                 TSK,
-                                 Complain);
+  return Pattern;
+}
 
-  return Result;
+bool Sema::InstantiateClassTemplateSpecialization(
+    SourceLocation PointOfInstantiation,
+    ClassTemplateSpecializationDecl *ClassTemplateSpec,
+    TemplateSpecializationKind TSK, bool Complain) {
+  // Perform the actual instantiation on the canonical declaration.
+  ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
+      ClassTemplateSpec->getCanonicalDecl());
+  if (ClassTemplateSpec->isInvalidDecl())
+    return true;
+
+  CXXRecordDecl *Pattern = getPatternForClassTemplateSpecialization(
+      *this, PointOfInstantiation, ClassTemplateSpec, TSK, Complain);
+  if (!Pattern)
+    return true;
+
+  return InstantiateClass(PointOfInstantiation, ClassTemplateSpec, Pattern,
+                          getTemplateInstantiationArgs(ClassTemplateSpec), TSK,
+                          Complain);
 }
 
 /// \brief Instantiates the definitions of all of the member
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 6b6abc7..cab55ea 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -168,39 +168,59 @@
                         Aligned->getSpellingListIndex());
 }
 
-static void instantiateDependentEnableIfAttr(
+static Expr *instantiateDependentFunctionAttrCondition(
     Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
-    const EnableIfAttr *A, const Decl *Tmpl, Decl *New) {
+    const Attr *A, Expr *OldCond, const Decl *Tmpl, FunctionDecl *New) {
   Expr *Cond = nullptr;
   {
-    EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
-    ExprResult Result = S.SubstExpr(A->getCond(), TemplateArgs);
+    Sema::ContextRAII SwitchContext(S, New);
+    EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated);
+    ExprResult Result = S.SubstExpr(OldCond, TemplateArgs);
     if (Result.isInvalid())
-      return;
+      return nullptr;
     Cond = Result.getAs<Expr>();
   }
   if (!Cond->isTypeDependent()) {
     ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
     if (Converted.isInvalid())
-      return;
+      return nullptr;
     Cond = Converted.get();
   }
 
   SmallVector<PartialDiagnosticAt, 8> Diags;
-  if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
-      !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(New),
-                                                Diags)) {
-    S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr);
-    for (int I = 0, N = Diags.size(); I != N; ++I)
-      S.Diag(Diags[I].first, Diags[I].second);
-    return;
+  if (OldCond->isValueDependent() && !Cond->isValueDependent() &&
+      !Expr::isPotentialConstantExprUnevaluated(Cond, New, Diags)) {
+    S.Diag(A->getLocation(), diag::err_attr_cond_never_constant_expr) << A;
+    for (const auto &P : Diags)
+      S.Diag(P.first, P.second);
+    return nullptr;
   }
+  return Cond;
+}
 
-  EnableIfAttr *EIA = new (S.getASTContext())
-                        EnableIfAttr(A->getLocation(), S.getASTContext(), Cond,
-                                     A->getMessage(),
-                                     A->getSpellingListIndex());
-  New->addAttr(EIA);
+static void instantiateDependentEnableIfAttr(
+    Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
+    const EnableIfAttr *EIA, const Decl *Tmpl, FunctionDecl *New) {
+  Expr *Cond = instantiateDependentFunctionAttrCondition(
+      S, TemplateArgs, EIA, EIA->getCond(), Tmpl, New);
+
+  if (Cond)
+    New->addAttr(new (S.getASTContext()) EnableIfAttr(
+        EIA->getLocation(), S.getASTContext(), Cond, EIA->getMessage(),
+        EIA->getSpellingListIndex()));
+}
+
+static void instantiateDependentDiagnoseIfAttr(
+    Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
+    const DiagnoseIfAttr *DIA, const Decl *Tmpl, FunctionDecl *New) {
+  Expr *Cond = instantiateDependentFunctionAttrCondition(
+      S, TemplateArgs, DIA, DIA->getCond(), Tmpl, New);
+
+  if (Cond)
+    New->addAttr(new (S.getASTContext()) DiagnoseIfAttr(
+        DIA->getLocation(), S.getASTContext(), Cond, DIA->getMessage(),
+        DIA->getDiagnosticType(), DIA->getArgDependent(), New,
+        DIA->getSpellingListIndex()));
 }
 
 // Constructs and adds to New a new instance of CUDALaunchBoundsAttr using
@@ -334,7 +354,13 @@
 
     if (const auto *EnableIf = dyn_cast<EnableIfAttr>(TmplAttr)) {
       instantiateDependentEnableIfAttr(*this, TemplateArgs, EnableIf, Tmpl,
-                                       New);
+                                       cast<FunctionDecl>(New));
+      continue;
+    }
+
+    if (const auto *DiagnoseIf = dyn_cast<DiagnoseIfAttr>(TmplAttr)) {
+      instantiateDependentDiagnoseIfAttr(*this, TemplateArgs, DiagnoseIf, Tmpl,
+                                         cast<FunctionDecl>(New));
       continue;
     }
 
@@ -631,10 +657,9 @@
                                              ArrayRef<BindingDecl*> *Bindings) {
 
   // Do substitution on the type of the declaration
-  TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
-                                         TemplateArgs,
-                                         D->getTypeSpecStartLoc(),
-                                         D->getDeclName());
+  TypeSourceInfo *DI = SemaRef.SubstType(
+      D->getTypeSourceInfo(), TemplateArgs, D->getTypeSpecStartLoc(),
+      D->getDeclName(), /*AllowDeducedTST*/true);
   if (!DI)
     return nullptr;
 
@@ -1193,8 +1218,10 @@
 
   ClassTemplateDecl *Inst
     = ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(),
-                                D->getIdentifier(), InstParams, RecordInst,
-                                PrevClassTemplate);
+                                D->getIdentifier(), InstParams, RecordInst);
+  assert(!(isFriend && Owner->isDependentContext()));
+  Inst->setPreviousDecl(PrevClassTemplate);
+
   RecordInst->setDescribedClassTemplate(Inst);
 
   if (isFriend) {
@@ -1470,8 +1497,11 @@
                              TSK_ImplicitInstantiation,
                              /*Complain=*/true);
 
-    SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs,
-                                    TSK_ImplicitInstantiation);
+    // For nested local classes, we will instantiate the members when we
+    // reach the end of the outermost (non-nested) local class.
+    if (!D->isCXXClassMember())
+      SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs,
+                                      TSK_ImplicitInstantiation);
 
     // This class may have local implicit instantiations that need to be
     // performed within this scope.
@@ -1569,13 +1599,18 @@
                                          TemplateArgs);
   }
 
-  FunctionDecl *Function =
-      FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(),
-                           D->getNameInfo(), T, TInfo,
-                           D->getCanonicalDecl()->getStorageClass(),
-                           D->isInlineSpecified(), D->hasWrittenPrototype(),
-                           D->isConstexpr());
-  Function->setRangeEnd(D->getSourceRange().getEnd());
+  FunctionDecl *Function;
+  if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D))
+    Function = CXXDeductionGuideDecl::Create(
+        SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(),
+        D->getNameInfo(), T, TInfo, D->getSourceRange().getEnd());
+  else {
+    Function = FunctionDecl::Create(
+        SemaRef.Context, DC, D->getInnerLocStart(), D->getNameInfo(), T, TInfo,
+        D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(),
+        D->hasWrittenPrototype(), D->isConstexpr());
+    Function->setRangeEnd(D->getSourceRange().getEnd());
+  }
 
   if (D->isInlined())
     Function->setImplicitlyInline();
@@ -1625,8 +1660,6 @@
     FunctionTemplate->setLexicalDeclContext(LexicalDC);
 
     if (isFriend && D->isThisDeclarationADefinition()) {
-      // TODO: should we remember this connection regardless of whether
-      // the friend declaration provided a body?
       FunctionTemplate->setInstantiatedFromMemberTemplate(
                                            D->getDescribedFunctionTemplate());
     }
@@ -1637,13 +1670,10 @@
                             TemplateArgumentList::CreateCopy(SemaRef.Context,
                                                              Innermost),
                                                 /*InsertPos=*/nullptr);
-  } else if (isFriend) {
-    // Note, we need this connection even if the friend doesn't have a body.
-    // Its body may exist but not have been attached yet due to deferred
-    // parsing.
-    // FIXME: It might be cleaner to set this when attaching the body to the
-    // friend function declaration, however that would require finding all the
-    // instantiations and modifying them.
+  } else if (isFriend && D->isThisDeclarationADefinition()) {
+    // Do not connect the friend to the template unless it's actually a
+    // definition. We don't want non-template functions to be marked as being
+    // template instantiations.
     Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
   }
 
@@ -2044,13 +2074,10 @@
   // TODO: don't always clone when decls are refcounted.
   assert(D->getTypeForDecl()->isTemplateTypeParmType());
 
-  TemplateTypeParmDecl *Inst =
-    TemplateTypeParmDecl::Create(SemaRef.Context, Owner,
-                                 D->getLocStart(), D->getLocation(),
-                                 D->getDepth() - TemplateArgs.getNumLevels(),
-                                 D->getIndex(), D->getIdentifier(),
-                                 D->wasDeclaredWithTypename(),
-                                 D->isParameterPack());
+  TemplateTypeParmDecl *Inst = TemplateTypeParmDecl::Create(
+      SemaRef.Context, Owner, D->getLocStart(), D->getLocation(),
+      D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), D->getIndex(),
+      D->getIdentifier(), D->wasDeclaredWithTypename(), D->isParameterPack());
   Inst->setAccess(AS_public);
 
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
@@ -2085,18 +2112,18 @@
     ExpandedParameterPackTypes.reserve(D->getNumExpansionTypes());
     ExpandedParameterPackTypesAsWritten.reserve(D->getNumExpansionTypes());
     for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
-      TypeSourceInfo *NewDI =SemaRef.SubstType(D->getExpansionTypeSourceInfo(I),
-                                               TemplateArgs,
-                                               D->getLocation(),
-                                               D->getDeclName());
+      TypeSourceInfo *NewDI =
+          SemaRef.SubstType(D->getExpansionTypeSourceInfo(I), TemplateArgs,
+                            D->getLocation(), D->getDeclName());
       if (!NewDI)
         return nullptr;
 
-      ExpandedParameterPackTypesAsWritten.push_back(NewDI);
-      QualType NewT =SemaRef.CheckNonTypeTemplateParameterType(NewDI->getType(),
-                                                              D->getLocation());
+      QualType NewT =
+          SemaRef.CheckNonTypeTemplateParameterType(NewDI, D->getLocation());
       if (NewT.isNull())
         return nullptr;
+
+      ExpandedParameterPackTypesAsWritten.push_back(NewDI);
       ExpandedParameterPackTypes.push_back(NewT);
     }
 
@@ -2136,12 +2163,12 @@
         if (!NewDI)
           return nullptr;
 
-        ExpandedParameterPackTypesAsWritten.push_back(NewDI);
-        QualType NewT = SemaRef.CheckNonTypeTemplateParameterType(
-                                                              NewDI->getType(),
-                                                              D->getLocation());
+        QualType NewT =
+            SemaRef.CheckNonTypeTemplateParameterType(NewDI, D->getLocation());
         if (NewT.isNull())
           return nullptr;
+
+        ExpandedParameterPackTypesAsWritten.push_back(NewDI);
         ExpandedParameterPackTypes.push_back(NewT);
       }
 
@@ -2161,6 +2188,7 @@
       if (!NewPattern)
         return nullptr;
 
+      SemaRef.CheckNonTypeTemplateParameterType(NewPattern, D->getLocation());
       DI = SemaRef.CheckPackExpansion(NewPattern, Expansion.getEllipsisLoc(),
                                       NumExpansions);
       if (!DI)
@@ -2176,8 +2204,7 @@
       return nullptr;
 
     // Check that this type is acceptable for a non-type template parameter.
-    T = SemaRef.CheckNonTypeTemplateParameterType(DI->getType(),
-                                                  D->getLocation());
+    T = SemaRef.CheckNonTypeTemplateParameterType(DI, D->getLocation());
     if (T.isNull()) {
       T = SemaRef.Context.IntTy;
       Invalid = true;
@@ -2188,17 +2215,14 @@
   if (IsExpandedParameterPack)
     Param = NonTypeTemplateParmDecl::Create(
         SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
-        D->getDepth() - TemplateArgs.getNumLevels(), D->getPosition(),
-        D->getIdentifier(), T, DI, ExpandedParameterPackTypes,
+        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+        D->getPosition(), D->getIdentifier(), T, DI, ExpandedParameterPackTypes,
         ExpandedParameterPackTypesAsWritten);
   else
-    Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner,
-                                            D->getInnerLocStart(),
-                                            D->getLocation(),
-                                    D->getDepth() - TemplateArgs.getNumLevels(),
-                                            D->getPosition(),
-                                            D->getIdentifier(), T,
-                                            D->isParameterPack(), DI);
+    Param = NonTypeTemplateParmDecl::Create(
+        SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
+        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+        D->getPosition(), D->getIdentifier(), T, D->isParameterPack(), DI);
 
   Param->setAccess(AS_public);
   if (Invalid)
@@ -2319,19 +2343,15 @@
   // Build the template template parameter.
   TemplateTemplateParmDecl *Param;
   if (IsExpandedParameterPack)
-    Param = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner,
-                                             D->getLocation(),
-                                   D->getDepth() - TemplateArgs.getNumLevels(),
-                                             D->getPosition(),
-                                             D->getIdentifier(), InstParams,
-                                             ExpandedParams);
+    Param = TemplateTemplateParmDecl::Create(
+        SemaRef.Context, Owner, D->getLocation(),
+        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+        D->getPosition(), D->getIdentifier(), InstParams, ExpandedParams);
   else
-    Param = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner,
-                                             D->getLocation(),
-                                   D->getDepth() - TemplateArgs.getNumLevels(),
-                                             D->getPosition(),
-                                             D->isParameterPack(),
-                                             D->getIdentifier(), InstParams);
+    Param = TemplateTemplateParmDecl::Create(
+        SemaRef.Context, Owner, D->getLocation(),
+        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+        D->getPosition(), D->isParameterPack(), D->getIdentifier(), InstParams);
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
     NestedNameSpecifierLoc QualifierLoc =
         D->getDefaultArgument().getTemplateQualifierLoc();
@@ -2430,8 +2450,8 @@
   }
 
   if (!NewUD->isInvalidDecl() &&
-      SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), SS, NameInfo,
-                                      D->getLocation()))
+      SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), D->hasTypename(),
+                                      SS, NameInfo, D->getLocation()))
     NewUD->setInvalidDecl();
 
   SemaRef.Context.setInstantiatedFromUsingDecl(NewUD, D);
@@ -2495,8 +2515,73 @@
   return nullptr;
 }
 
-Decl * TemplateDeclInstantiator
-    ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+template <typename T>
+Decl *TemplateDeclInstantiator::instantiateUnresolvedUsingDecl(
+    T *D, bool InstantiatingPackElement) {
+  // If this is a pack expansion, expand it now.
+  if (D->isPackExpansion() && !InstantiatingPackElement) {
+    SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+    SemaRef.collectUnexpandedParameterPacks(D->getQualifierLoc(), Unexpanded);
+    SemaRef.collectUnexpandedParameterPacks(D->getNameInfo(), Unexpanded);
+
+    // Determine whether the set of unexpanded parameter packs can and should
+    // be expanded.
+    bool Expand = true;
+    bool RetainExpansion = false;
+    Optional<unsigned> NumExpansions;
+    if (SemaRef.CheckParameterPacksForExpansion(
+          D->getEllipsisLoc(), D->getSourceRange(), Unexpanded, TemplateArgs,
+            Expand, RetainExpansion, NumExpansions))
+      return nullptr;
+
+    // This declaration cannot appear within a function template signature,
+    // so we can't have a partial argument list for a parameter pack.
+    assert(!RetainExpansion &&
+           "should never need to retain an expansion for UsingPackDecl");
+
+    if (!Expand) {
+      // We cannot fully expand the pack expansion now, so substitute into the
+      // pattern and create a new pack expansion.
+      Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1);
+      return instantiateUnresolvedUsingDecl(D, true);
+    }
+
+    // Within a function, we don't have any normal way to check for conflicts
+    // between shadow declarations from different using declarations in the
+    // same pack expansion, but this is always ill-formed because all expansions
+    // must produce (conflicting) enumerators.
+    //
+    // Sadly we can't just reject this in the template definition because it
+    // could be valid if the pack is empty or has exactly one expansion.
+    if (D->getDeclContext()->isFunctionOrMethod() && *NumExpansions > 1) {
+      SemaRef.Diag(D->getEllipsisLoc(),
+                   diag::err_using_decl_redeclaration_expansion);
+      return nullptr;
+    }
+
+    // Instantiate the slices of this pack and build a UsingPackDecl.
+    SmallVector<NamedDecl*, 8> Expansions;
+    for (unsigned I = 0; I != *NumExpansions; ++I) {
+      Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
+      Decl *Slice = instantiateUnresolvedUsingDecl(D, true);
+      if (!Slice)
+        return nullptr;
+      // Note that we can still get unresolved using declarations here, if we
+      // had arguments for all packs but the pattern also contained other
+      // template arguments (this only happens during partial substitution, eg
+      // into the body of a generic lambda in a function template).
+      Expansions.push_back(cast<NamedDecl>(Slice));
+    }
+
+    auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions);
+    if (isDeclWithinFunction(D))
+      SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewD);
+    return NewD;
+  }
+
+  UnresolvedUsingTypenameDecl *TD = dyn_cast<UnresolvedUsingTypenameDecl>(D);
+  SourceLocation TypenameLoc = TD ? TD->getTypenameLoc() : SourceLocation();
+
   NestedNameSpecifierLoc QualifierLoc
     = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),
                                           TemplateArgs);
@@ -2506,44 +2591,51 @@
   CXXScopeSpec SS;
   SS.Adopt(QualifierLoc);
 
-  // Since NameInfo refers to a typename, it cannot be a C++ special name.
-  // Hence, no transformation is required for it.
-  DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation());
-  NamedDecl *UD =
-    SemaRef.BuildUsingDeclaration(/*Scope*/ nullptr, D->getAccess(),
-                                  D->getUsingLoc(), SS, NameInfo, nullptr,
-                                  /*instantiation*/ true,
-                                  /*typename*/ true, D->getTypenameLoc());
-  if (UD)
-    SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D);
-
-  return UD;
-}
-
-Decl * TemplateDeclInstantiator
-    ::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
-  NestedNameSpecifierLoc QualifierLoc
-      = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs);
-  if (!QualifierLoc)
-    return nullptr;
-
-  CXXScopeSpec SS;
-  SS.Adopt(QualifierLoc);
-
   DeclarationNameInfo NameInfo
     = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
 
-  NamedDecl *UD =
-    SemaRef.BuildUsingDeclaration(/*Scope*/ nullptr, D->getAccess(),
-                                  D->getUsingLoc(), SS, NameInfo, nullptr,
-                                  /*instantiation*/ true,
-                                  /*typename*/ false, SourceLocation());
+  // Produce a pack expansion only if we're not instantiating a particular
+  // slice of a pack expansion.
+  bool InstantiatingSlice = D->getEllipsisLoc().isValid() &&
+                            SemaRef.ArgumentPackSubstitutionIndex != -1;
+  SourceLocation EllipsisLoc =
+      InstantiatingSlice ? SourceLocation() : D->getEllipsisLoc();
+
+  NamedDecl *UD = SemaRef.BuildUsingDeclaration(
+      /*Scope*/ nullptr, D->getAccess(), D->getUsingLoc(),
+      /*HasTypename*/ TD, TypenameLoc, SS, NameInfo, EllipsisLoc, nullptr,
+      /*IsInstantiation*/ true);
   if (UD)
-    SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D);
+    SemaRef.Context.setInstantiatedFromUsingDecl(UD, D);
 
   return UD;
 }
 
+Decl *TemplateDeclInstantiator::VisitUnresolvedUsingTypenameDecl(
+    UnresolvedUsingTypenameDecl *D) {
+  return instantiateUnresolvedUsingDecl(D);
+}
+
+Decl *TemplateDeclInstantiator::VisitUnresolvedUsingValueDecl(
+    UnresolvedUsingValueDecl *D) {
+  return instantiateUnresolvedUsingDecl(D);
+}
+
+Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) {
+  SmallVector<NamedDecl*, 8> Expansions;
+  for (auto *UD : D->expansions()) {
+    if (auto *NewUD =
+            SemaRef.FindInstantiatedDecl(D->getLocation(), UD, TemplateArgs))
+      Expansions.push_back(cast<NamedDecl>(NewUD));
+    else
+      return nullptr;
+  }
+
+  auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions);
+  if (isDeclWithinFunction(D))
+    SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewD);
+  return NewD;
+}
 
 Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(
                                      ClassScopeFunctionSpecializationDecl *Decl) {
@@ -2680,6 +2772,11 @@
   return VisitFunctionDecl(D, nullptr);
 }
 
+Decl *
+TemplateDeclInstantiator::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
+  return VisitFunctionDecl(D, nullptr);
+}
+
 Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
   return VisitCXXMethodDecl(D, nullptr);
 }
@@ -3014,6 +3111,12 @@
                                         Converted))
     return nullptr;
 
+  // Check these arguments are valid for a template partial specialization.
+  if (SemaRef.CheckTemplatePartialSpecializationArgs(
+          PartialSpec->getLocation(), ClassTemplate, InstTemplateArgs.size(),
+          Converted))
+    return nullptr;
+
   // Figure out where to insert this class template partial specialization
   // in the member template's set of class template partial specializations.
   void *InsertPos = nullptr;
@@ -3084,6 +3187,9 @@
   InstPartialSpec->setInstantiatedFromMember(PartialSpec);
   InstPartialSpec->setTypeAsWritten(WrittenTy);
 
+  // Check the completed partial specialization.
+  SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec);
+
   // Add this partial specialization to the set of class template partial
   // specializations.
   ClassTemplate->AddPartialSpecialization(InstPartialSpec,
@@ -3136,6 +3242,12 @@
                                         InstTemplateArgs, false, Converted))
     return nullptr;
 
+  // Check these arguments are valid for a template partial specialization.
+  if (SemaRef.CheckTemplatePartialSpecializationArgs(
+          PartialSpec->getLocation(), VarTemplate, InstTemplateArgs.size(),
+          Converted))
+    return nullptr;
+
   // Figure out where to insert this variable template partial specialization
   // in the member template's set of variable template partial specializations.
   void *InsertPos = nullptr;
@@ -3210,6 +3322,9 @@
   InstPartialSpec->setInstantiatedFromMember(PartialSpec);
   InstPartialSpec->setTypeAsWritten(WrittenTy);
 
+  // Check the completed partial specialization.
+  SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec);
+
   // Add this partial specialization to the set of variable template partial
   // specializations. The instantiation of the initializer is not necessary.
   VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/nullptr);
@@ -3434,6 +3549,8 @@
   if (Tmpl->isDeleted())
     New->setDeletedAsWritten();
 
+  New->setImplicit(Tmpl->isImplicit());
+
   // Forward the mangling number from the template to the instantiated decl.
   SemaRef.Context.setManglingNumber(New,
                                     SemaRef.Context.getManglingNumber(Tmpl));
@@ -3446,8 +3563,8 @@
   // into a template instantiation for this specific function template
   // specialization, which is not a SFINAE context, so that we diagnose any
   // further errors in the declaration itself.
-  typedef Sema::ActiveTemplateInstantiation ActiveInstType;
-  ActiveInstType &ActiveInst = SemaRef.ActiveTemplateInstantiations.back();
+  typedef Sema::CodeSynthesisContext ActiveInstType;
+  ActiveInstType &ActiveInst = SemaRef.CodeSynthesisContexts.back();
   if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution ||
       ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) {
     if (FunctionTemplateDecl *FunTmpl
@@ -3526,6 +3643,27 @@
   return false;
 }
 
+/// In the MS ABI, we need to instantiate default arguments of dllexported
+/// default constructors along with the constructor definition. This allows IR
+/// gen to emit a constructor closure which calls the default constructor with
+/// its default arguments.
+static void InstantiateDefaultCtorDefaultArgs(Sema &S,
+                                              CXXConstructorDecl *Ctor) {
+  assert(S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+         Ctor->isDefaultConstructor());
+  unsigned NumParams = Ctor->getNumParams();
+  if (NumParams == 0)
+    return;
+  DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>();
+  if (!Attr)
+    return;
+  for (unsigned I = 0; I != NumParams; ++I) {
+    (void)S.CheckCXXDefaultArgExpr(Attr->getLocation(), Ctor,
+                                   Ctor->getParamDecl(I));
+    S.DiscardCleanupsInEvaluationContext();
+  }
+}
+
 /// \brief Instantiate the definition of the given function from its
 /// template.
 ///
@@ -3703,11 +3841,17 @@
                                          TemplateArgs))
       return;
 
-    // If this is a constructor, instantiate the member initializers.
-    if (const CXXConstructorDecl *Ctor =
-          dyn_cast<CXXConstructorDecl>(PatternDecl)) {
-      InstantiateMemInitializers(cast<CXXConstructorDecl>(Function), Ctor,
+    if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Function)) {
+      // If this is a constructor, instantiate the member initializers.
+      InstantiateMemInitializers(Ctor, cast<CXXConstructorDecl>(PatternDecl),
                                  TemplateArgs);
+
+      // If this is an MS ABI dllexport default constructor, instantiate any
+      // default arguments.
+      if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+          Ctor->isDefaultConstructor()) {
+        InstantiateDefaultCtorDefaultArgs(*this, Ctor);
+      }
     }
 
     // Instantiate the function body.
@@ -3716,6 +3860,8 @@
     if (Body.isInvalid())
       Function->setInvalidDecl();
 
+    // FIXME: finishing the function body while in an expression evaluation
+    // context seems wrong. Investigate more.
     ActOnFinishFunctionBody(Function, Body.get(),
                             /*IsInstantiation=*/true);
 
@@ -3939,7 +4085,6 @@
     }
 
     if (!Init.isInvalid()) {
-      bool TypeMayContainAuto = true;
       Expr *InitExpr = Init.get();
 
       if (Var->hasAttr<DLLImportAttr>() &&
@@ -3948,9 +4093,9 @@
         // Do not dynamically initialize dllimport variables.
       } else if (InitExpr) {
         bool DirectInit = OldVar->isDirectInit();
-        AddInitializerToDecl(Var, InitExpr, DirectInit, TypeMayContainAuto);
+        AddInitializerToDecl(Var, InitExpr, DirectInit);
       } else
-        ActOnUninitializedDecl(Var, TypeMayContainAuto);
+        ActOnUninitializedDecl(Var);
     } else {
       // FIXME: Not too happy about invalidating the declaration
       // because of a bogus initializer.
@@ -3973,7 +4118,7 @@
     if (Var->isCXXForRangeDecl())
       return;
 
-    ActOnUninitializedDecl(Var, false);
+    ActOnUninitializedDecl(Var);
   }
 }
 
@@ -4513,22 +4658,36 @@
                             Pattern);
 }
 
-static bool isInstantiationOf(UsingDecl *Pattern,
-                              UsingDecl *Instance,
+static bool isInstantiationOf(UsingDecl *Pattern, UsingDecl *Instance,
                               ASTContext &C) {
   return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);
 }
 
-static bool isInstantiationOf(UnresolvedUsingValueDecl *Pattern,
-                              UsingDecl *Instance,
-                              ASTContext &C) {
-  return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);
-}
-
-static bool isInstantiationOf(UnresolvedUsingTypenameDecl *Pattern,
-                              UsingDecl *Instance,
-                              ASTContext &C) {
-  return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);
+template<typename T>
+static bool isInstantiationOfUnresolvedUsingDecl(T *Pattern, Decl *Other,
+                                                 ASTContext &Ctx) {
+  // An unresolved using declaration can instantiate to an unresolved using
+  // declaration, or to a using declaration or a using declaration pack.
+  //
+  // Multiple declarations can claim to be instantiated from an unresolved
+  // using declaration if it's a pack expansion. We want the UsingPackDecl
+  // in that case, not the individual UsingDecls within the pack.
+  bool OtherIsPackExpansion;
+  NamedDecl *OtherFrom;
+  if (auto *OtherUUD = dyn_cast<T>(Other)) {
+    OtherIsPackExpansion = OtherUUD->isPackExpansion();
+    OtherFrom = Ctx.getInstantiatedFromUsingDecl(OtherUUD);
+  } else if (auto *OtherUPD = dyn_cast<UsingPackDecl>(Other)) {
+    OtherIsPackExpansion = true;
+    OtherFrom = OtherUPD->getInstantiatedFromUsingDecl();
+  } else if (auto *OtherUD = dyn_cast<UsingDecl>(Other)) {
+    OtherIsPackExpansion = false;
+    OtherFrom = Ctx.getInstantiatedFromUsingDecl(OtherUD);
+  } else {
+    return false;
+  }
+  return Pattern->isPackExpansion() == OtherIsPackExpansion &&
+         declaresSameEntity(OtherFrom, Pattern);
 }
 
 static bool isInstantiationOfStaticDataMember(VarDecl *Pattern,
@@ -4549,49 +4708,40 @@
 // Other is the prospective instantiation
 // D is the prospective pattern
 static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
-  if (D->getKind() != Other->getKind()) {
-    if (UnresolvedUsingTypenameDecl *UUD
-          = dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
-      if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
-        return isInstantiationOf(UUD, UD, Ctx);
-      }
-    }
+  if (auto *UUD = dyn_cast<UnresolvedUsingTypenameDecl>(D))
+    return isInstantiationOfUnresolvedUsingDecl(UUD, Other, Ctx);
 
-    if (UnresolvedUsingValueDecl *UUD
-          = dyn_cast<UnresolvedUsingValueDecl>(D)) {
-      if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
-        return isInstantiationOf(UUD, UD, Ctx);
-      }
-    }
+  if (auto *UUD = dyn_cast<UnresolvedUsingValueDecl>(D))
+    return isInstantiationOfUnresolvedUsingDecl(UUD, Other, Ctx);
 
+  if (D->getKind() != Other->getKind())
     return false;
-  }
 
-  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other))
+  if (auto *Record = dyn_cast<CXXRecordDecl>(Other))
     return isInstantiationOf(cast<CXXRecordDecl>(D), Record);
 
-  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Other))
+  if (auto *Function = dyn_cast<FunctionDecl>(Other))
     return isInstantiationOf(cast<FunctionDecl>(D), Function);
 
-  if (EnumDecl *Enum = dyn_cast<EnumDecl>(Other))
+  if (auto *Enum = dyn_cast<EnumDecl>(Other))
     return isInstantiationOf(cast<EnumDecl>(D), Enum);
 
-  if (VarDecl *Var = dyn_cast<VarDecl>(Other))
+  if (auto *Var = dyn_cast<VarDecl>(Other))
     if (Var->isStaticDataMember())
       return isInstantiationOfStaticDataMember(cast<VarDecl>(D), Var);
 
-  if (ClassTemplateDecl *Temp = dyn_cast<ClassTemplateDecl>(Other))
+  if (auto *Temp = dyn_cast<ClassTemplateDecl>(Other))
     return isInstantiationOf(cast<ClassTemplateDecl>(D), Temp);
 
-  if (FunctionTemplateDecl *Temp = dyn_cast<FunctionTemplateDecl>(Other))
+  if (auto *Temp = dyn_cast<FunctionTemplateDecl>(Other))
     return isInstantiationOf(cast<FunctionTemplateDecl>(D), Temp);
 
-  if (ClassTemplatePartialSpecializationDecl *PartialSpec
-        = dyn_cast<ClassTemplatePartialSpecializationDecl>(Other))
+  if (auto *PartialSpec =
+          dyn_cast<ClassTemplatePartialSpecializationDecl>(Other))
     return isInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(D),
                              PartialSpec);
 
-  if (FieldDecl *Field = dyn_cast<FieldDecl>(Other)) {
+  if (auto *Field = dyn_cast<FieldDecl>(Other)) {
     if (!Field->getDeclName()) {
       // This is an unnamed field.
       return declaresSameEntity(Ctx.getInstantiatedFromUnnamedFieldDecl(Field),
@@ -4599,14 +4749,14 @@
     }
   }
 
-  if (UsingDecl *Using = dyn_cast<UsingDecl>(Other))
+  if (auto *Using = dyn_cast<UsingDecl>(Other))
     return isInstantiationOf(cast<UsingDecl>(D), Using, Ctx);
 
-  if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(Other))
+  if (auto *Shadow = dyn_cast<UsingShadowDecl>(Other))
     return isInstantiationOf(cast<UsingShadowDecl>(D), Shadow, Ctx);
 
-  return D->getDeclName() && isa<NamedDecl>(Other) &&
-    D->getDeclName() == cast<NamedDecl>(Other)->getDeclName();
+  return D->getDeclName() &&
+         D->getDeclName() == cast<NamedDecl>(Other)->getDeclName();
 }
 
 template<typename ForwardIterator>
@@ -4802,6 +4952,28 @@
           DC = FD->getLexicalDeclContext();
           continue;
         }
+        // An implicit deduction guide acts as if it's within the class template
+        // specialization described by its name and first N template params.
+        auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FD);
+        if (Guide && Guide->isImplicit()) {
+          TemplateDecl *TD = Guide->getDeducedTemplate();
+          // Convert the arguments to an "as-written" list.
+          TemplateArgumentListInfo Args(Loc, Loc);
+          for (TemplateArgument Arg : TemplateArgs.getInnermost().take_front(
+                                        TD->getTemplateParameters()->size())) {
+            ArrayRef<TemplateArgument> Unpacked(Arg);
+            if (Arg.getKind() == TemplateArgument::Pack)
+              Unpacked = Arg.pack_elements();
+            for (TemplateArgument UnpackedArg : Unpacked)
+              Args.addArgument(
+                  getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc));
+          }
+          QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args);
+          if (T.isNull())
+            return nullptr;
+          DC = T->getAsCXXRecordDecl();
+          continue;
+        }
       }
 
       DC = DC->getParent();
@@ -4842,8 +5014,14 @@
     }
 
     NamedDecl *Result = nullptr;
-    if (D->getDeclName()) {
-      DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName());
+    // FIXME: If the name is a dependent name, this lookup won't necessarily
+    // find it. Does that ever matter?
+    if (auto Name = D->getDeclName()) {
+      DeclarationNameInfo NameInfo(Name, D->getLocation());
+      Name = SubstDeclarationNameInfo(NameInfo, TemplateArgs).getName();
+      if (!Name)
+        return nullptr;
+      DeclContext::lookup_result Found = ParentDC->lookup(Name);
       Result = findInstantiationOf(Context, D, Found.begin(), Found.end());
     } else {
       // Since we don't have a name for the entity we're looking for,
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index c278639..9f57200 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -321,6 +321,7 @@
   case DeclarationName::CXXOperatorName:
   case DeclarationName::CXXLiteralOperatorName:
   case DeclarationName::CXXUsingDirective:
+  case DeclarationName::CXXDeductionGuideName:
     return false;
 
   case DeclarationName::CXXConstructorName:
@@ -390,21 +391,18 @@
 void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);  
-}  
-
-void Sema::collectUnexpandedParameterPacks(CXXScopeSpec &SS,
-                                           SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
-  NestedNameSpecifier *Qualifier = SS.getScopeRep();
-  if (!Qualifier)
-    return;
-  
-  NestedNameSpecifierLoc QualifierLoc(Qualifier, SS.location_data());
-  CollectUnexpandedParameterPacksVisitor(Unexpanded)
-    .TraverseNestedNameSpecifierLoc(QualifierLoc);
 }
 
-void Sema::collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
-                         SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
+void Sema::collectUnexpandedParameterPacks(
+    NestedNameSpecifierLoc NNS,
+    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
+  CollectUnexpandedParameterPacksVisitor(Unexpanded)
+      .TraverseNestedNameSpecifierLoc(NNS);
+}
+
+void Sema::collectUnexpandedParameterPacks(
+    const DeclarationNameInfo &NameInfo,
+    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
   CollectUnexpandedParameterPacksVisitor(Unexpanded)
     .TraverseDeclarationNameInfo(NameInfo);
 }
@@ -772,7 +770,7 @@
       }
 
       if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) {
-        for (unsigned i = 0; i != Chunk.Fun.NumExceptions; ++i) {
+        for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) {
           if (Chunk.Fun.Exceptions[i]
                   .Ty.get()
                   ->containsUnexpandedParameterPack())
@@ -1017,6 +1015,11 @@
   CheckFoldOperand(*this, LHS);
   CheckFoldOperand(*this, RHS);
 
+  auto DiscardOperands = [&] {
+    CorrectDelayedTyposInExpr(LHS);
+    CorrectDelayedTyposInExpr(RHS);
+  };
+
   // [expr.prim.fold]p3:
   //   In a binary fold, op1 and op2 shall be the same fold-operator, and
   //   either e1 shall contain an unexpanded parameter pack or e2 shall contain
@@ -1024,6 +1027,7 @@
   if (LHS && RHS &&
       LHS->containsUnexpandedParameterPack() ==
           RHS->containsUnexpandedParameterPack()) {
+    DiscardOperands();
     return Diag(EllipsisLoc,
                 LHS->containsUnexpandedParameterPack()
                     ? diag::err_fold_expression_packs_both_sides
@@ -1037,6 +1041,7 @@
   if (!LHS || !RHS) {
     Expr *Pack = LHS ? LHS : RHS;
     assert(Pack && "fold expression with neither LHS nor RHS");
+    DiscardOperands();
     if (!Pack->containsUnexpandedParameterPack())
       return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
              << Pack->getSourceRange();
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 9bfc6cc..4fe0cf3 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -718,6 +718,7 @@
       /*NumExceptions=*/0,
       /*NoexceptExpr=*/nullptr,
       /*ExceptionSpecTokens=*/nullptr,
+      /*DeclsInPrototype=*/None,
       loc, loc, declarator));
 
   // For consistency, make sure the state still has us as processing
@@ -741,7 +742,7 @@
     if (!(RemoveTQs & Qual.first))
       continue;
 
-    if (S.ActiveTemplateInstantiations.empty()) {
+    if (!S.inTemplateInstantiation()) {
       if (TypeQuals & Qual.first)
         S.Diag(Qual.second, DiagID)
           << DeclSpec::getSpecifierName(Qual.first) << TypeSoFar
@@ -1400,14 +1401,6 @@
       Result = Context.LongDoubleTy;
     else
       Result = Context.DoubleTy;
-
-    if (S.getLangOpts().OpenCL &&
-        !((S.getLangOpts().OpenCLVersion >= 120) ||
-          S.getOpenCLOptions().cl_khr_fp64)) {
-      S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
-          << Result << "cl_khr_fp64";
-      declarator.setInvalidType(true);
-    }
     break;
   case DeclSpec::TST_float128:
     if (!S.Context.getTargetInfo().hasFloat128Type())
@@ -1459,48 +1452,6 @@
     Result = S.GetTypeFromParser(DS.getRepAsType());
     if (Result.isNull()) {
       declarator.setInvalidType(true);
-    } else if (S.getLangOpts().OpenCL) {
-      if (Result->getAs<AtomicType>()) {
-        StringRef TypeName = Result.getBaseTypeIdentifier()->getName();
-        bool NoExtTypes =
-            llvm::StringSwitch<bool>(TypeName)
-                .Cases("atomic_int", "atomic_uint", "atomic_float",
-                       "atomic_flag", true)
-                .Default(false);
-        if (!S.getOpenCLOptions().cl_khr_int64_base_atomics && !NoExtTypes) {
-          S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
-              << Result << "cl_khr_int64_base_atomics";
-          declarator.setInvalidType(true);
-        }
-        if (!S.getOpenCLOptions().cl_khr_int64_extended_atomics &&
-            !NoExtTypes) {
-          S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
-              << Result << "cl_khr_int64_extended_atomics";
-          declarator.setInvalidType(true);
-        }
-        if (!S.getOpenCLOptions().cl_khr_fp64 &&
-            !TypeName.compare("atomic_double")) {
-          S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
-              << Result << "cl_khr_fp64";
-          declarator.setInvalidType(true);
-        }
-      } else if (!S.getOpenCLOptions().cl_khr_gl_msaa_sharing &&
-                 (Result->isOCLImage2dArrayMSAADepthROType() ||
-                  Result->isOCLImage2dArrayMSAADepthWOType() ||
-                  Result->isOCLImage2dArrayMSAADepthRWType() ||
-                  Result->isOCLImage2dArrayMSAAROType() ||
-                  Result->isOCLImage2dArrayMSAARWType() ||
-                  Result->isOCLImage2dArrayMSAAWOType() ||
-                  Result->isOCLImage2dMSAADepthROType() ||
-                  Result->isOCLImage2dMSAADepthRWType() ||
-                  Result->isOCLImage2dMSAADepthWOType() ||
-                  Result->isOCLImage2dMSAAROType() ||
-                  Result->isOCLImage2dMSAARWType() ||
-                  Result->isOCLImage2dMSAAWOType())) {
-        S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
-            << Result << "cl_khr_gl_msaa_sharing";
-        declarator.setInvalidType(true);
-      }
     }
 
     // TypeQuals handled by caller.
@@ -1551,47 +1502,7 @@
     break;
 
   case DeclSpec::TST_auto:
-    // TypeQuals handled by caller.
-    // If auto is mentioned in a lambda parameter context, convert it to a 
-    // template parameter type immediately, with the appropriate depth and 
-    // index, and update sema's state (LambdaScopeInfo) for the current lambda 
-    // being analyzed (which tracks the invented type template parameter).
-    if (declarator.getContext() == Declarator::LambdaExprParameterContext) {
-      sema::LambdaScopeInfo *LSI = S.getCurLambda();
-      assert(LSI && "No LambdaScopeInfo on the stack!");
-      const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth;
-      const unsigned AutoParameterPosition = LSI->AutoTemplateParams.size();
-      const bool IsParameterPack = declarator.hasEllipsis();
-
-      // Turns out we must create the TemplateTypeParmDecl here to 
-      // retrieve the corresponding template parameter type. 
-      TemplateTypeParmDecl *CorrespondingTemplateParam =
-        TemplateTypeParmDecl::Create(Context, 
-        // Temporarily add to the TranslationUnit DeclContext.  When the 
-        // associated TemplateParameterList is attached to a template
-        // declaration (such as FunctionTemplateDecl), the DeclContext 
-        // for each template parameter gets updated appropriately via
-        // a call to AdoptTemplateParameterList. 
-        Context.getTranslationUnitDecl(), 
-        /*KeyLoc*/ SourceLocation(), 
-        /*NameLoc*/ declarator.getLocStart(),  
-        TemplateParameterDepth, 
-        AutoParameterPosition,  // our template param index 
-        /* Identifier*/ nullptr, false, IsParameterPack);
-      LSI->AutoTemplateParams.push_back(CorrespondingTemplateParam);
-      // Replace the 'auto' in the function parameter with this invented 
-      // template type parameter.
-      Result = QualType(CorrespondingTemplateParam->getTypeForDecl(), 0);
-    } else {
-      // If auto appears in the declaration of a template parameter, treat
-      // the parameter as type-dependent.
-      bool IsDependent =
-        S.getLangOpts().CPlusPlus1z &&
-        declarator.getContext() == Declarator::TemplateParamContext;
-      Result = Context.getAutoType(QualType(),
-                                   AutoTypeKeyword::Auto,
-                                   IsDependent);
-    }
+    Result = Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false);
     break;
 
   case DeclSpec::TST_auto_type:
@@ -1636,6 +1547,10 @@
     break;
   }
 
+  if (S.getLangOpts().OpenCL &&
+      S.checkOpenCLDisabledTypeDeclSpec(DS, Result))
+    declarator.setInvalidType(true);
+
   // Handle complex types.
   if (DS.getTypeSpecComplex() == DeclSpec::TSC_complex) {
     if (S.getLangOpts().Freestanding)
@@ -2818,6 +2733,12 @@
                      D.getDeclSpec().getAttributes().getList());
     break;
 
+  case UnqualifiedId::IK_DeductionGuideName:
+    // Deduction guides have a trailing return type and no type in their
+    // decl-specifier sequence. Use a placeholder return type for now.
+    T = SemaRef.Context.DependentTy;
+    break;
+
   case UnqualifiedId::IK_ConversionFunctionId:
     // The result type of a conversion function is the type that it
     // converts to.
@@ -2830,12 +2751,20 @@
     distributeTypeAttrsFromDeclarator(state, T);
 
   // C++11 [dcl.spec.auto]p5: reject 'auto' if it is not in an allowed context.
-  if (D.getDeclSpec().containsPlaceholderType()) {
+  if (DeducedType *Deduced = T->getContainedDeducedType()) {
+    AutoType *Auto = dyn_cast<AutoType>(Deduced);
     int Error = -1;
 
+    // Is this a 'auto' or 'decltype(auto)' type (as opposed to __auto_type or
+    // class template argument deduction)?
+    bool IsCXXAutoType =
+        (Auto && Auto->getKeyword() != AutoTypeKeyword::GNUAutoType);
+
     switch (D.getContext()) {
     case Declarator::LambdaExprContext:
-      llvm_unreachable("Can't specify a type specifier in lambda grammar");
+      // Declared return type of a lambda-declarator is implicit and is always
+      // 'auto'.
+      break;
     case Declarator::ObjCParameterContext:
     case Declarator::ObjCResultContext:
     case Declarator::PrototypeContext:
@@ -2843,9 +2772,35 @@
       break;
     case Declarator::LambdaExprParameterContext:
       // In C++14, generic lambdas allow 'auto' in their parameters.
-      if (!(SemaRef.getLangOpts().CPlusPlus14 
-              && D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto))
+      if (!SemaRef.getLangOpts().CPlusPlus14 ||
+          !Auto || Auto->getKeyword() != AutoTypeKeyword::Auto)
         Error = 16;
+      else {
+        // If auto is mentioned in a lambda parameter context, convert it to a 
+        // template parameter type.
+        sema::LambdaScopeInfo *LSI = SemaRef.getCurLambda();
+        assert(LSI && "No LambdaScopeInfo on the stack!");
+        const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth;
+        const unsigned AutoParameterPosition = LSI->AutoTemplateParams.size();
+        const bool IsParameterPack = D.hasEllipsis();
+
+        // Create the TemplateTypeParmDecl here to retrieve the corresponding
+        // template parameter type. Template parameters are temporarily added
+        // to the TU until the associated TemplateDecl is created.
+        TemplateTypeParmDecl *CorrespondingTemplateParam =
+            TemplateTypeParmDecl::Create(
+                SemaRef.Context, SemaRef.Context.getTranslationUnitDecl(),
+                /*KeyLoc*/SourceLocation(), /*NameLoc*/D.getLocStart(),
+                TemplateParameterDepth, AutoParameterPosition,
+                /*Identifier*/nullptr, false, IsParameterPack);
+        LSI->AutoTemplateParams.push_back(CorrespondingTemplateParam);
+        // Replace the 'auto' in the function parameter with this invented 
+        // template type parameter.
+        // FIXME: Retain some type sugar to indicate that this was written
+        // as 'auto'.
+        T = SemaRef.ReplaceAutoType(
+            T, QualType(CorrespondingTemplateParam->getTypeForDecl(), 0));
+      }
       break;
     case Declarator::MemberContext: {
       if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
@@ -2859,6 +2814,8 @@
       case TTK_Class:  Error = 5; /* Class member */ break;
       case TTK_Interface: Error = 6; /* Interface member */ break;
       }
+      if (D.getDeclSpec().isFriendSpecified())
+        Error = 20; // Friend type
       break;
     }
     case Declarator::CXXCatchContext:
@@ -2866,8 +2823,10 @@
       Error = 7; // Exception declaration
       break;
     case Declarator::TemplateParamContext:
-      if (!SemaRef.getLangOpts().CPlusPlus1z)
-        Error = 8; // Template parameter
+      if (isa<DeducedTemplateSpecializationType>(Deduced))
+        Error = 19; // Template parameter
+      else if (!SemaRef.getLangOpts().CPlusPlus1z)
+        Error = 8; // Template parameter (until C++1z)
       break;
     case Declarator::BlockLiteralContext:
       Error = 9; // Block literal
@@ -2880,15 +2839,17 @@
       Error = 12; // Type alias
       break;
     case Declarator::TrailingReturnContext:
-      if (!SemaRef.getLangOpts().CPlusPlus14 ||
-          D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto_type)
+      if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType)
         Error = 13; // Function return type
       break;
     case Declarator::ConversionIdContext:
-      if (!SemaRef.getLangOpts().CPlusPlus14 ||
-          D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto_type)
+      if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType)
         Error = 14; // conversion-type-id
       break;
+    case Declarator::FunctionalCastContext:
+      if (isa<DeducedTemplateSpecializationType>(Deduced))
+        break;
+      LLVM_FALLTHROUGH;
     case Declarator::TypeNameContext:
       Error = 15; // Generic
       break;
@@ -2897,9 +2858,14 @@
     case Declarator::ForContext:
     case Declarator::InitStmtContext:
     case Declarator::ConditionContext:
+      // FIXME: P0091R3 (erroneously) does not permit class template argument
+      // deduction in conditions, for-init-statements, and other declarations
+      // that are not simple-declarations.
       break;
     case Declarator::CXXNewContext:
-      if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto_type)
+      // FIXME: P0091R3 does not permit class template argument deduction here,
+      // but we follow GCC and allow it anyway.
+      if (!IsCXXAutoType && !isa<DeducedTemplateSpecializationType>(Deduced))
         Error = 17; // 'new' type
       break;
     case Declarator::KNRTypeListContext:
@@ -2913,8 +2879,7 @@
     // In Objective-C it is an error to use 'auto' on a function declarator
     // (and everywhere for '__auto_type').
     if (D.isFunctionDeclarator() &&
-        (!SemaRef.getLangOpts().CPlusPlus11 ||
-         D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto_type))
+        (!SemaRef.getLangOpts().CPlusPlus11 || !IsCXXAutoType))
       Error = 13;
 
     bool HaveTrailing = false;
@@ -2924,21 +2889,11 @@
     // level. Check all declarator chunks (outermost first) anyway, to give
     // better diagnostics.
     // We don't support '__auto_type' with trailing return types.
-    if (SemaRef.getLangOpts().CPlusPlus11 &&
-        D.getDeclSpec().getTypeSpecType() != DeclSpec::TST_auto_type) {
-      for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
-        unsigned chunkIndex = e - i - 1;
-        state.setCurrentChunkIndex(chunkIndex);
-        DeclaratorChunk &DeclType = D.getTypeObject(chunkIndex);
-        if (DeclType.Kind == DeclaratorChunk::Function) {
-          const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
-          if (FTI.hasTrailingReturnType()) {
-            HaveTrailing = true;
-            Error = -1;
-            break;
-          }
-        }
-      }
+    // FIXME: Should we only do this for 'auto' and not 'decltype(auto)'?
+    if (SemaRef.getLangOpts().CPlusPlus11 && IsCXXAutoType &&
+        D.hasTrailingReturnType()) {
+      HaveTrailing = true;
+      Error = -1;
     }
 
     SourceRange AutoRange = D.getDeclSpec().getTypeSpecTypeLoc();
@@ -2946,15 +2901,28 @@
       AutoRange = D.getName().getSourceRange();
 
     if (Error != -1) {
-      unsigned Keyword;
-      switch (D.getDeclSpec().getTypeSpecType()) {
-      case DeclSpec::TST_auto: Keyword = 0; break;
-      case DeclSpec::TST_decltype_auto: Keyword = 1; break;
-      case DeclSpec::TST_auto_type: Keyword = 2; break;
-      default: llvm_unreachable("unknown auto TypeSpecType");
+      unsigned Kind;
+      if (Auto) {
+        switch (Auto->getKeyword()) {
+        case AutoTypeKeyword::Auto: Kind = 0; break;
+        case AutoTypeKeyword::DecltypeAuto: Kind = 1; break;
+        case AutoTypeKeyword::GNUAutoType: Kind = 2; break;
+        }
+      } else {
+        assert(isa<DeducedTemplateSpecializationType>(Deduced) &&
+               "unknown auto type");
+        Kind = 3;
       }
+
+      auto *DTST = dyn_cast<DeducedTemplateSpecializationType>(Deduced);
+      TemplateName TN = DTST ? DTST->getTemplateName() : TemplateName();
+
       SemaRef.Diag(AutoRange.getBegin(), diag::err_auto_not_allowed)
-        << Keyword << Error << AutoRange;
+        << Kind << Error << (int)SemaRef.getTemplateNameKindForDiagnostics(TN)
+        << QualType(Deduced, 0) << AutoRange;
+      if (auto *TD = TN.getAsTemplateDecl())
+        SemaRef.Diag(TD->getLocation(), diag::note_template_decl_here);
+
       T = SemaRef.Context.IntTy;
       D.setInvalidType(true);
     } else if (!HaveTrailing) {
@@ -2994,6 +2962,7 @@
       DiagID = diag::err_type_defined_in_alias_template;
       break;
     case Declarator::TypeNameContext:
+    case Declarator::FunctionalCastContext:
     case Declarator::ConversionIdContext:
     case Declarator::TemplateParamContext:
     case Declarator::CXXNewContext:
@@ -3206,7 +3175,7 @@
       if (Attr->getKind() == AttributeList::AT_OpenCLKernel) {
         llvm::Triple::ArchType arch = S.Context.getTargetInfo().getTriple().getArch();
         if (arch == llvm::Triple::spir || arch == llvm::Triple::spir64 ||
-            arch == llvm::Triple::amdgcn) {
+            arch == llvm::Triple::amdgcn || arch == llvm::Triple::r600) {
           CC = CC_OpenCLKernel;
         }
         break;
@@ -3486,6 +3455,68 @@
   return file;
 }
 
+/// Creates a fix-it to insert a C-style nullability keyword at \p pointerLoc,
+/// taking into account whitespace before and after.
+static void fixItNullability(Sema &S, DiagnosticBuilder &Diag,
+                             SourceLocation PointerLoc,
+                             NullabilityKind Nullability) {
+  assert(PointerLoc.isValid());
+  if (PointerLoc.isMacroID())
+    return;
+
+  SourceLocation FixItLoc = S.getLocForEndOfToken(PointerLoc);
+  if (!FixItLoc.isValid() || FixItLoc == PointerLoc)
+    return;
+
+  const char *NextChar = S.SourceMgr.getCharacterData(FixItLoc);
+  if (!NextChar)
+    return;
+
+  SmallString<32> InsertionTextBuf{" "};
+  InsertionTextBuf += getNullabilitySpelling(Nullability);
+  InsertionTextBuf += " ";
+  StringRef InsertionText = InsertionTextBuf.str();
+
+  if (isWhitespace(*NextChar)) {
+    InsertionText = InsertionText.drop_back();
+  } else if (NextChar[-1] == '[') {
+    if (NextChar[0] == ']')
+      InsertionText = InsertionText.drop_back().drop_front();
+    else
+      InsertionText = InsertionText.drop_front();
+  } else if (!isIdentifierBody(NextChar[0], /*allow dollar*/true) &&
+             !isIdentifierBody(NextChar[-1], /*allow dollar*/true)) {
+    InsertionText = InsertionText.drop_back().drop_front();
+  }
+
+  Diag << FixItHint::CreateInsertion(FixItLoc, InsertionText);
+}
+
+static void emitNullabilityConsistencyWarning(Sema &S,
+                                              SimplePointerKind PointerKind,
+                                              SourceLocation PointerLoc) {
+  assert(PointerLoc.isValid());
+
+  if (PointerKind == SimplePointerKind::Array) {
+    S.Diag(PointerLoc, diag::warn_nullability_missing_array);
+  } else {
+    S.Diag(PointerLoc, diag::warn_nullability_missing)
+      << static_cast<unsigned>(PointerKind);
+  }
+
+  if (PointerLoc.isMacroID())
+    return;
+
+  auto addFixIt = [&](NullabilityKind Nullability) {
+    auto Diag = S.Diag(PointerLoc, diag::note_nullability_fix_it);
+    Diag << static_cast<unsigned>(Nullability);
+    Diag << static_cast<unsigned>(PointerKind);
+    fixItNullability(S, Diag, PointerLoc, Nullability);
+  };
+  addFixIt(NullabilityKind::Nullable);
+  addFixIt(NullabilityKind::NonNull);
+}
+
 /// Complains about missing nullability if the file containing \p pointerLoc
 /// has other uses of nullability (either the keywords or the \c assume_nonnull
 /// pragma).
@@ -3522,12 +3553,7 @@
   }
 
   // Complain about missing nullability.
-  if (pointerKind == SimplePointerKind::Array) {
-    S.Diag(pointerLoc, diag::warn_nullability_missing_array);
-  } else {
-    S.Diag(pointerLoc, diag::warn_nullability_missing)
-      << static_cast<unsigned>(pointerKind);
-  }
+  emitNullabilityConsistencyWarning(S, pointerKind, pointerLoc);
 }
 
 /// Marks that a nullability feature has been used in the file containing
@@ -3552,13 +3578,8 @@
   if (fileNullability.PointerLoc.isInvalid())
     return;
 
-  if (fileNullability.PointerKind ==
-        static_cast<unsigned>(SimplePointerKind::Array)) {
-    S.Diag(fileNullability.PointerLoc, diag::warn_nullability_missing_array);
-  } else {
-    S.Diag(fileNullability.PointerLoc, diag::warn_nullability_missing)
-      << static_cast<unsigned>(fileNullability.PointerKind);
-  }
+  auto kind = static_cast<SimplePointerKind>(fileNullability.PointerKind);
+  emitNullabilityConsistencyWarning(S, kind, fileNullability.PointerLoc);
 }
 
 /// Returns true if any of the declarator chunks before \p endIndex include a
@@ -3623,17 +3644,32 @@
 
   // If T is 'decltype(auto)', the only declarators we can have are parens
   // and at most one function declarator if this is a function declaration.
-  if (const AutoType *AT = T->getAs<AutoType>()) {
-    if (AT->isDecltypeAuto()) {
+  // If T is a deduced class template specialization type, we can have no
+  // declarator chunks at all.
+  if (auto *DT = T->getAs<DeducedType>()) {
+    const AutoType *AT = T->getAs<AutoType>();
+    bool IsClassTemplateDeduction = isa<DeducedTemplateSpecializationType>(DT);
+    if ((AT && AT->isDecltypeAuto()) || IsClassTemplateDeduction) {
       for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) {
         unsigned Index = E - I - 1;
         DeclaratorChunk &DeclChunk = D.getTypeObject(Index);
-        unsigned DiagId = diag::err_decltype_auto_compound_type;
+        unsigned DiagId = IsClassTemplateDeduction
+                              ? diag::err_deduced_class_template_compound_type
+                              : diag::err_decltype_auto_compound_type;
         unsigned DiagKind = 0;
         switch (DeclChunk.Kind) {
         case DeclaratorChunk::Paren:
+          // FIXME: Rejecting this is a little silly.
+          if (IsClassTemplateDeduction) {
+            DiagKind = 4;
+            break;
+          }
           continue;
         case DeclaratorChunk::Function: {
+          if (IsClassTemplateDeduction) {
+            DiagKind = 3;
+            break;
+          }
           unsigned FnIndex;
           if (D.isFunctionDeclarationContext() &&
               D.isFunctionDeclarator(FnIndex) && FnIndex == Index)
@@ -3834,6 +3870,7 @@
     case Declarator::TemplateParamContext:
     case Declarator::TemplateTypeArgContext:
     case Declarator::TypeNameContext:
+    case Declarator::FunctionalCastContext:
       // Don't infer in these contexts.
       break;
     }
@@ -3892,20 +3929,10 @@
       if (pointerLoc.isValid() &&
           complainAboutInferringWithinChunk !=
             PointerWrappingDeclaratorKind::None) {
-        SourceLocation fixItLoc = S.getLocForEndOfToken(pointerLoc);
-        StringRef insertionText = " _Nonnull ";
-        if (const char *nextChar = S.SourceMgr.getCharacterData(fixItLoc)) {
-          if (isWhitespace(*nextChar)) {
-            insertionText = insertionText.drop_back();
-          } else if (!isIdentifierBody(nextChar[0], /*allow dollar*/true) &&
-                     !isIdentifierBody(nextChar[-1], /*allow dollar*/true)) {
-            insertionText = insertionText.drop_back().drop_front();
-          }
-        }
-
-        S.Diag(pointerLoc, diag::warn_nullability_inferred_on_nested_type)
-          << static_cast<int>(complainAboutInferringWithinChunk)
-          << FixItHint::CreateInsertion(fixItLoc, insertionText);
+        auto Diag =
+            S.Diag(pointerLoc, diag::warn_nullability_inferred_on_nested_type);
+        Diag << static_cast<int>(complainAboutInferringWithinChunk);
+        fixItNullability(S, Diag, pointerLoc, NullabilityKind::NonNull);
       }
 
       if (inferNullabilityInnerOnly)
@@ -3932,7 +3959,7 @@
 
   // If the type itself could have nullability but does not, infer pointer
   // nullability and perform consistency checking.
-  if (S.ActiveTemplateInstantiations.empty()) {
+  if (S.CodeSynthesisContexts.empty()) {
     if (T->canHaveNullability() && !T->getNullability(S.Context)) {
       if (isVaList(T)) {
         // Record that we've seen a pointer, but do nothing else.
@@ -4133,7 +4160,7 @@
       if (!D.isInvalidType()) {
         // trailing-return-type is only required if we're declaring a function,
         // and not, for instance, a pointer to a function.
-        if (D.getDeclSpec().containsPlaceholderType() &&
+        if (D.getDeclSpec().hasAutoTypeSpec() &&
             !FTI.hasTrailingReturnType() && chunkIndex == 0 &&
             !S.getLangOpts().CPlusPlus14) {
           S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
@@ -4145,16 +4172,25 @@
         } else if (FTI.hasTrailingReturnType()) {
           // T must be exactly 'auto' at this point. See CWG issue 681.
           if (isa<ParenType>(T)) {
-            S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
+            S.Diag(D.getLocStart(),
                  diag::err_trailing_return_in_parens)
-              << T << D.getDeclSpec().getSourceRange();
+              << T << D.getSourceRange();
             D.setInvalidType(true);
+          } else if (D.getName().getKind() ==
+                         UnqualifiedId::IK_DeductionGuideName) {
+            if (T != Context.DependentTy) {
+              S.Diag(D.getDeclSpec().getLocStart(),
+                     diag::err_deduction_guide_with_complex_decl)
+                  << D.getSourceRange();
+              D.setInvalidType(true);
+            }
           } else if (D.getContext() != Declarator::LambdaExprContext &&
                      (T.hasQualifiers() || !isa<AutoType>(T) ||
-                      cast<AutoType>(T)->getKeyword() != AutoTypeKeyword::Auto)) {
+                      cast<AutoType>(T)->getKeyword() !=
+                          AutoTypeKeyword::Auto)) {
             S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
-                 diag::err_trailing_return_without_auto)
-              << T << D.getDeclSpec().getSourceRange();
+                   diag::err_trailing_return_without_auto)
+                << T << D.getDeclSpec().getSourceRange();
             D.setInvalidType(true);
           }
           T = S.GetTypeFromParser(FTI.getTrailingReturnType(), &TInfo);
@@ -4168,7 +4204,7 @@
 
       // C99 6.7.5.3p1: The return type may not be a function or array type.
       // For conversion functions, we'll diagnose this particular error later.
-      if ((T->isArrayType() || T->isFunctionType()) &&
+      if (!D.isInvalidType() && (T->isArrayType() || T->isFunctionType()) &&
           (D.getName().getKind() != UnqualifiedId::IK_ConversionFunctionId)) {
         unsigned diagID = diag::err_func_returning_array_function;
         // Last processing chunk in block context means this function chunk
@@ -4185,7 +4221,7 @@
       // FIXME: This really should be in BuildFunctionType.
       if (T->isHalfType()) {
         if (S.getLangOpts().OpenCL) {
-          if (!S.getOpenCLOptions().cl_khr_fp16) {
+          if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) {
             S.Diag(D.getIdentifierLoc(), diag::err_opencl_invalid_return)
                 << T << 0 /*pointer hint*/;
             D.setInvalidType(true);
@@ -4418,7 +4454,7 @@
             // Disallow half FP parameters.
             // FIXME: This really should be in BuildFunctionType.
             if (S.getLangOpts().OpenCL) {
-              if (!S.getOpenCLOptions().cl_khr_fp16) {
+              if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) {
                 S.Diag(Param->getLocation(),
                   diag::err_opencl_half_param) << ParamTy;
                 D.setInvalidType();
@@ -4452,6 +4488,11 @@
             HasAnyInterestingExtParameterInfos = true;
           }
 
+          if (Param->hasAttr<PassObjectSizeAttr>()) {
+            ExtParameterInfos[i] = ExtParameterInfos[i].withHasPassObjectSize();
+            HasAnyInterestingExtParameterInfos = true;
+          }
+
           ParamTys.push_back(ParamTy);
         }
 
@@ -4469,7 +4510,7 @@
         if (FTI.getExceptionSpecType() == EST_Dynamic) {
           // FIXME: It's rather inefficient to have to split into two vectors
           // here.
-          unsigned N = FTI.NumExceptions;
+          unsigned N = FTI.getNumExceptions();
           DynamicExceptions.reserve(N);
           DynamicExceptionRanges.reserve(N);
           for (unsigned I = 0; I != N; ++I) {
@@ -4584,14 +4625,18 @@
     //
     // Core issue 547 also allows cv-qualifiers on function types that are
     // top-level template type arguments.
-    bool FreeFunction;
-    if (!D.getCXXScopeSpec().isSet()) {
-      FreeFunction = ((D.getContext() != Declarator::MemberContext &&
-                       D.getContext() != Declarator::LambdaExprContext) ||
-                      D.getDeclSpec().isFriendSpecified());
+    enum { NonMember, Member, DeductionGuide } Kind = NonMember;
+    if (D.getName().getKind() == UnqualifiedId::IK_DeductionGuideName)
+      Kind = DeductionGuide;
+    else if (!D.getCXXScopeSpec().isSet()) {
+      if ((D.getContext() == Declarator::MemberContext ||
+           D.getContext() == Declarator::LambdaExprContext) &&
+          !D.getDeclSpec().isFriendSpecified())
+        Kind = Member;
     } else {
       DeclContext *DC = S.computeDeclContext(D.getCXXScopeSpec());
-      FreeFunction = (DC && !DC->isRecord());
+      if (!DC || DC->isRecord())
+        Kind = Member;
     }
 
     // C++11 [dcl.fct]p6 (w/DR1417):
@@ -4611,7 +4656,7 @@
     //
     // ... for instance.
     if (IsQualifiedFunction &&
-        !(!FreeFunction &&
+        !(Kind == Member &&
           D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) &&
         !IsTypedefName &&
         D.getContext() != Declarator::TemplateTypeArgContext) {
@@ -4639,7 +4684,7 @@
       }
 
       S.Diag(Loc, diag::err_invalid_qualified_function_type)
-        << FreeFunction << D.isFunctionDeclarator() << T
+        << Kind << D.isFunctionDeclarator() << T
         << getFunctionQualifiersAsString(FnTy)
         << FixItHint::CreateRemoval(RemovalRange);
 
@@ -4723,6 +4768,7 @@
     case Declarator::ObjCParameterContext:  // FIXME: special diagnostic here?
     case Declarator::ObjCResultContext:     // FIXME: special diagnostic here?
     case Declarator::TypeNameContext:
+    case Declarator::FunctionalCastContext:
     case Declarator::CXXNewContext:
     case Declarator::AliasDeclContext:
     case Declarator::AliasTemplateContext:
@@ -5273,7 +5319,7 @@
         ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
         TL.setParam(tpi++, Param);
       }
-      // FIXME: exception specs
+      TL.setExceptionSpecRange(FTI.getExceptionSpecRange());
     }
     void VisitParenTypeLoc(ParenTypeLoc TL) {
       assert(Chunk.Kind == DeclaratorChunk::Paren);
@@ -6903,8 +6949,10 @@
       (TAL == TAL_DeclSpec || TAL == TAL_DeclChunk)) {
     Declarator &D = state.getDeclarator();
     if (state.getCurrentChunkIndex() > 0 &&
-        D.getTypeObject(state.getCurrentChunkIndex() - 1).Kind ==
-            DeclaratorChunk::Pointer) {
+        (D.getTypeObject(state.getCurrentChunkIndex() - 1).Kind ==
+             DeclaratorChunk::Pointer ||
+         D.getTypeObject(state.getCurrentChunkIndex() - 1).Kind ==
+             DeclaratorChunk::BlockPointer)) {
       type = state.getSema().Context.getAddrSpaceQualType(
           type, LangAS::opencl_generic);
     } else if (state.getCurrentChunkIndex() == 0 &&
@@ -7520,7 +7568,7 @@
   if (ER.isInvalid()) return QualType();
   E = ER.get();
 
-  if (AsUnevaluated && ActiveTemplateInstantiations.empty() &&
+  if (AsUnevaluated && CodeSynthesisContexts.empty() &&
       E->HasSideEffects(Context, false)) {
     // The expression operand for decltype is in an unevaluated expression
     // context, so side effects could result in unintended consequences.
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index dd857f4..7a89c9d 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -307,6 +307,17 @@
   ///
   QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
 
+  /// \brief Transform a type that is permitted to produce a
+  /// DeducedTemplateSpecializationType.
+  ///
+  /// This is used in the (relatively rare) contexts where it is acceptable
+  /// for transformation to produce a class template type with deduced
+  /// template arguments.
+  /// @{
+  QualType TransformTypeWithDeducedTST(QualType T);
+  TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
+  /// @}
+
   /// \brief Transform the given statement.
   ///
   /// By default, this routine transforms a statement by delegating to the
@@ -457,6 +468,10 @@
     return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
   }
 
+  /// Transform the set of declarations in an OverloadExpr.
+  bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
+                                  LookupResult &R);
+
   /// \brief Transform the given nested-name-specifier with source-location
   /// information.
   ///
@@ -501,7 +516,8 @@
   TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
                         SourceLocation NameLoc,
                         QualType ObjectType = QualType(),
-                        NamedDecl *FirstQualifierInScope = nullptr);
+                        NamedDecl *FirstQualifierInScope = nullptr,
+                        bool AllowInjectedClassName = false);
 
   /// \brief Transform the given template argument.
   ///
@@ -667,6 +683,16 @@
   OMPClause *Transform ## Class(Class *S);
 #include "clang/Basic/OpenMPKinds.def"
 
+  /// \brief Build a new qualified type given its unqualified type and type
+  /// qualifiers.
+  ///
+  /// By default, this routine adds type qualifiers only to types that can
+  /// have qualifiers, and silently suppresses those qualifiers that are not
+  /// permitted. Subclasses may override this routine to provide different
+  /// behavior.
+  QualType RebuildQualifiedType(QualType T, SourceLocation Loc,
+                                Qualifiers Quals);
+
   /// \brief Build a new pointer type given its pointee type.
   ///
   /// By default, performs semantic analysis when building the pointer type.
@@ -821,7 +847,7 @@
 
   /// \brief Rebuild an unresolved typename type, given the decl that
   /// the UnresolvedUsingTypenameDecl was transformed to.
-  QualType RebuildUnresolvedUsingType(Decl *D);
+  QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
 
   /// \brief Build a new typedef type.
   QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
@@ -871,6 +897,14 @@
                                        /*IsDependent*/ false);
   }
 
+  /// By default, builds a new DeducedTemplateSpecializationType with the given
+  /// deduced type.
+  QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
+      QualType Deduced) {
+    return SemaRef.Context.getDeducedTemplateSpecializationType(
+        Template, Deduced, /*IsDependent*/ false);
+  }
+
   /// \brief Build a new template specialization type.
   ///
   /// By default, performs semantic analysis when building the template
@@ -885,7 +919,7 @@
   /// By default, builds a new ParenType type from the inner type.
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildParenType(QualType InnerType) {
-    return SemaRef.Context.getParenType(InnerType);
+    return SemaRef.BuildParenType(InnerType);
   }
 
   /// \brief Build a new qualified name type.
@@ -912,14 +946,15 @@
                                           NestedNameSpecifierLoc QualifierLoc,
                                           const IdentifierInfo *Name,
                                           SourceLocation NameLoc,
-                                          TemplateArgumentListInfo &Args) {
+                                          TemplateArgumentListInfo &Args,
+                                          bool AllowInjectedClassName) {
     // Rebuild the template name.
     // TODO: avoid TemplateName abstraction
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
     TemplateName InstName
       = getDerived().RebuildTemplateName(SS, *Name, NameLoc, QualType(),
-                                         nullptr);
+                                         nullptr, AllowInjectedClassName);
 
     if (InstName.isNull())
       return QualType();
@@ -954,7 +989,8 @@
                                     SourceLocation KeywordLoc,
                                     NestedNameSpecifierLoc QualifierLoc,
                                     const IdentifierInfo *Id,
-                                    SourceLocation IdLoc) {
+                                    SourceLocation IdLoc,
+                                    bool DeducedTSTContext) {
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
 
@@ -966,9 +1002,25 @@
                                                     Id);
     }
 
-    if (Keyword == ETK_None || Keyword == ETK_Typename)
-      return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
-                                       *Id, IdLoc);
+    if (Keyword == ETK_None || Keyword == ETK_Typename) {
+      QualType T = SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
+                                             *Id, IdLoc);
+      // If a dependent name resolves to a deduced template specialization type,
+      // check that we're in one of the syntactic contexts permitting it.
+      if (!DeducedTSTContext) {
+        if (auto *Deduced = dyn_cast_or_null<DeducedTemplateSpecializationType>(
+                T.isNull() ? nullptr : T->getContainedDeducedType())) {
+          SemaRef.Diag(IdLoc, diag::err_dependent_deduced_tst)
+            << (int)SemaRef.getTemplateNameKindForDiagnostics(
+                   Deduced->getTemplateName())
+            << QualType(QualifierLoc.getNestedNameSpecifier()->getAsType(), 0);
+          if (auto *TD = Deduced->getTemplateName().getAsTemplateDecl())
+            SemaRef.Diag(TD->getLocation(), diag::note_template_decl_here);
+          return QualType();
+        }
+      }
+      return T;
+    }
 
     TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
 
@@ -1013,8 +1065,9 @@
         case LookupResult::FoundOverloaded:
         case LookupResult::FoundUnresolvedValue: {
           NamedDecl *SomeDecl = Result.getRepresentativeDecl();
-          Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl);
-          SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) << NTK;
+          Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
+          SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) << SomeDecl
+                                                               << NTK << Kind;
           SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
           break;
         }
@@ -1083,7 +1136,8 @@
                                    const IdentifierInfo &Name,
                                    SourceLocation NameLoc,
                                    QualType ObjectType,
-                                   NamedDecl *FirstQualifierInScope);
+                                   NamedDecl *FirstQualifierInScope,
+                                   bool AllowInjectedClassName);
 
   /// \brief Build a new template name given a nested name specifier and the
   /// overloaded operator name that is referred to as a template.
@@ -1095,7 +1149,8 @@
   TemplateName RebuildTemplateName(CXXScopeSpec &SS,
                                    OverloadedOperatorKind Operator,
                                    SourceLocation NameLoc,
-                                   QualType ObjectType);
+                                   QualType ObjectType,
+                                   bool AllowInjectedClassName);
 
   /// \brief Build a new template name given a template template parameter pack
   /// and the
@@ -1307,16 +1362,28 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result) {
-    return getSema().BuildCoreturnStmt(CoreturnLoc, Result);
+  StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
+                                 bool IsImplicit) {
+    return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
   }
 
   /// \brief Build a new co_await expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Result) {
-    return getSema().BuildCoawaitExpr(CoawaitLoc, Result);
+  ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Result,
+                                bool IsImplicit) {
+    return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Result, IsImplicit);
+  }
+
+  /// \brief Build a new co_await expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
+                                         Expr *Result,
+                                         UnresolvedLookupExpr *Lookup) {
+    return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
   }
 
   /// \brief Build a new co_yield expression.
@@ -1327,6 +1394,10 @@
     return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
   }
 
+  StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
+    return getSema().BuildCoroutineBodyStmt(Args);
+  }
+
   /// \brief Build a new Objective-C \@try statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -2927,16 +2998,17 @@
   ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
                                           SourceLocation IvarLoc,
                                           bool IsArrow, bool IsFreeIvar) {
-    // FIXME: We lose track of the IsFreeIvar bit.
     CXXScopeSpec SS;
     DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
-    return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
-                                              /*FIXME:*/IvarLoc, IsArrow,
-                                              SS, SourceLocation(),
-                                              /*FirstQualifierInScope=*/nullptr,
-                                              NameInfo,
-                                              /*TemplateArgs=*/nullptr,
-                                              /*S=*/nullptr);
+    ExprResult Result = getSema().BuildMemberReferenceExpr(
+        BaseArg, BaseArg->getType(),
+        /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
+        /*FirstQualifierInScope=*/nullptr, NameInfo,
+        /*TemplateArgs=*/nullptr,
+        /*S=*/nullptr);
+    if (IsFreeIvar && Result.isUsable())
+      cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
+    return Result;
   }
 
   /// \brief Build a new Objective-C property reference expression.
@@ -3140,6 +3212,10 @@
   TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
                                             NamedDecl *FirstQualifierInScope,
                                             CXXScopeSpec &SS);
+
+  QualType TransformDependentNameType(TypeLocBuilder &TLB,
+                                      DependentNameTypeLoc TL,
+                                      bool DeducibleTSTContext);
 };
 
 template<typename Derived>
@@ -3220,6 +3296,9 @@
   if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
     Init = ExprTemp->getSubExpr();
 
+  if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init))
+    Init = AIL->getCommonExpr();
+
   if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
     Init = MTE->GetTemporaryExpr();
 
@@ -3554,6 +3633,19 @@
   case DeclarationName::CXXUsingDirective:
     return NameInfo;
 
+  case DeclarationName::CXXDeductionGuideName: {
+    TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
+    TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
+        getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
+    if (!NewTemplate)
+      return DeclarationNameInfo();
+
+    DeclarationNameInfo NewNameInfo(NameInfo);
+    NewNameInfo.setName(
+        SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate));
+    return NewNameInfo;
+  }
+
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
   case DeclarationName::CXXConversionFunctionName: {
@@ -3593,7 +3685,8 @@
                                               TemplateName Name,
                                               SourceLocation NameLoc,
                                               QualType ObjectType,
-                                              NamedDecl *FirstQualifierInScope) {
+                                              NamedDecl *FirstQualifierInScope,
+                                              bool AllowInjectedClassName) {
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
     TemplateDecl *Template = QTN->getTemplateDecl();
     assert(Template && "qualified template name must refer to a template");
@@ -3630,11 +3723,12 @@
                                               *DTN->getIdentifier(),
                                               NameLoc,
                                               ObjectType,
-                                              FirstQualifierInScope);
+                                              FirstQualifierInScope,
+                                              AllowInjectedClassName);
     }
 
     return getDerived().RebuildTemplateName(SS, DTN->getOperator(), NameLoc,
-                                            ObjectType);
+                                            ObjectType, AllowInjectedClassName);
   }
 
   if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
@@ -4026,11 +4120,57 @@
   llvm_unreachable("unhandled type loc!");
 }
 
-/// FIXME: By default, this routine adds type qualifiers only to types
-/// that can have qualifiers, and silently suppresses those qualifiers
-/// that are not permitted (e.g., qualifiers on reference or function
-/// types). This is the right thing for template instantiation, but
-/// probably not for other clients.
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
+  if (!isa<DependentNameType>(T))
+    return TransformType(T);
+
+  if (getDerived().AlreadyTransformed(T))
+    return T;
+  TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
+                                                getDerived().getBaseLocation());
+  TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
+  return NewDI ? NewDI->getType() : QualType();
+}
+
+template<typename Derived>
+TypeSourceInfo *
+TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
+  if (!isa<DependentNameType>(DI->getType()))
+    return TransformType(DI);
+
+  // Refine the base location to the type's location.
+  TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
+                       getDerived().getBaseEntity());
+  if (getDerived().AlreadyTransformed(DI->getType()))
+    return DI;
+
+  TypeLocBuilder TLB;
+
+  TypeLoc TL = DI->getTypeLoc();
+  TLB.reserve(TL.getFullDataSize());
+
+  Qualifiers Quals;
+  auto QTL = TL.getAs<QualifiedTypeLoc>();
+  if (QTL)
+    TL = QTL.getUnqualifiedLoc();
+
+  auto DNTL = TL.castAs<DependentNameTypeLoc>();
+
+  QualType Result = getDerived().TransformDependentNameType(
+      TLB, DNTL, /*DeducedTSTContext*/true);
+  if (Result.isNull())
+    return nullptr;
+
+  if (QTL) {
+    Result = getDerived().RebuildQualifiedType(
+        Result, QTL.getBeginLoc(), QTL.getType().getLocalQualifiers());
+    TLB.TypeWasModifiedSafely(Result);
+  }
+
+  return TLB.getTypeSourceInfo(SemaRef.Context, Result);
+}
+
 template<typename Derived>
 QualType
 TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
@@ -4041,64 +4181,71 @@
   if (Result.isNull())
     return QualType();
 
-  // Silently suppress qualifiers if the result type can't be qualified.
-  // FIXME: this is the right thing for template instantiation, but
-  // probably not for other clients.
-  if (Result->isFunctionType() || Result->isReferenceType())
-    return Result;
+  Result = getDerived().RebuildQualifiedType(Result, T.getBeginLoc(), Quals);
+
+  // RebuildQualifiedType might have updated the type, but not in a way
+  // that invalidates the TypeLoc. (There's no location information for
+  // qualifiers.)
+  TLB.TypeWasModifiedSafely(Result);
+
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
+                                                      SourceLocation Loc,
+                                                      Qualifiers Quals) {
+  // C++ [dcl.fct]p7:
+  //   [When] adding cv-qualifications on top of the function type [...] the
+  //   cv-qualifiers are ignored.
+  // C++ [dcl.ref]p1:
+  //   when the cv-qualifiers are introduced through the use of a typedef-name
+  //   or decltype-specifier [...] the cv-qualifiers are ignored.
+  // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
+  // applied to a reference type.
+  // FIXME: This removes all qualifiers, not just cv-qualifiers!
+  if (T->isFunctionType() || T->isReferenceType())
+    return T;
 
   // Suppress Objective-C lifetime qualifiers if they don't make sense for the
   // resulting type.
   if (Quals.hasObjCLifetime()) {
-    if (!Result->isObjCLifetimeType() && !Result->isDependentType())
+    if (!T->isObjCLifetimeType() && !T->isDependentType())
       Quals.removeObjCLifetime();
-    else if (Result.getObjCLifetime()) {
+    else if (T.getObjCLifetime()) {
       // Objective-C ARC:
       //   A lifetime qualifier applied to a substituted template parameter
       //   overrides the lifetime qualifier from the template argument.
       const AutoType *AutoTy;
       if (const SubstTemplateTypeParmType *SubstTypeParam
-                                = dyn_cast<SubstTemplateTypeParmType>(Result)) {
+                                = dyn_cast<SubstTemplateTypeParmType>(T)) {
         QualType Replacement = SubstTypeParam->getReplacementType();
         Qualifiers Qs = Replacement.getQualifiers();
         Qs.removeObjCLifetime();
-        Replacement
-          = SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(),
-                                             Qs);
-        Result = SemaRef.Context.getSubstTemplateTypeParmType(
-                                        SubstTypeParam->getReplacedParameter(),
-                                                              Replacement);
-        TLB.TypeWasModifiedSafely(Result);
-      } else if ((AutoTy = dyn_cast<AutoType>(Result)) && AutoTy->isDeduced()) {
+        Replacement = SemaRef.Context.getQualifiedType(
+            Replacement.getUnqualifiedType(), Qs);
+        T = SemaRef.Context.getSubstTemplateTypeParmType(
+            SubstTypeParam->getReplacedParameter(), Replacement);
+      } else if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
         // 'auto' types behave the same way as template parameters.
         QualType Deduced = AutoTy->getDeducedType();
         Qualifiers Qs = Deduced.getQualifiers();
         Qs.removeObjCLifetime();
-        Deduced = SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(),
-                                                   Qs);
-        Result = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
-                                AutoTy->isDependentType());
-        TLB.TypeWasModifiedSafely(Result);
+        Deduced =
+            SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
+        T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
+                                        AutoTy->isDependentType());
       } else {
         // Otherwise, complain about the addition of a qualifier to an
         // already-qualified type.
-        SourceRange R = T.getUnqualifiedLoc().getSourceRange();
-        SemaRef.Diag(R.getBegin(), diag::err_attr_objc_ownership_redundant)
-          << Result << R;
-
+        // FIXME: Why is this check not in Sema::BuildQualifiedType?
+        SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
         Quals.removeObjCLifetime();
       }
     }
   }
-  if (!Quals.empty()) {
-    Result = SemaRef.BuildQualifiedType(Result, T.getBeginLoc(), Quals);
-    // BuildQualifiedType might not add qualifiers if they are invalid.
-    if (Result.hasLocalQualifiers())
-      TLB.push<QualifiedTypeLoc>(Result);
-    // No location information to preserve.
-  }
 
-  return Result;
+  return SemaRef.BuildQualifiedType(T, Loc, Quals);
 }
 
 template<typename Derived>
@@ -4144,11 +4291,9 @@
     TemplateSpecializationTypeLoc SpecTL =
         TL.castAs<TemplateSpecializationTypeLoc>();
 
-    TemplateName Template
-    = getDerived().TransformTemplateName(SS,
-                                         SpecTL.getTypePtr()->getTemplateName(),
-                                         SpecTL.getTemplateNameLoc(),
-                                         ObjectType, UnqualLookup);
+    TemplateName Template = getDerived().TransformTemplateName(
+        SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
+        ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
     if (Template.isNull())
       return nullptr;
 
@@ -4162,7 +4307,8 @@
       = getDerived().RebuildTemplateName(SS,
                                          *SpecTL.getTypePtr()->getIdentifier(),
                                          SpecTL.getTemplateNameLoc(),
-                                         ObjectType, UnqualLookup);
+                                         ObjectType, UnqualLookup,
+                                         /*AllowInjectedClassName*/true);
     if (Template.isNull())
       return nullptr;
 
@@ -4473,8 +4619,15 @@
   if (ElementType.isNull())
     return QualType();
 
-  ExprResult SizeResult
-    = getDerived().TransformExpr(T->getSizeExpr());
+  ExprResult SizeResult;
+  {
+    EnterExpressionEvaluationContext Context(SemaRef,
+                                             Sema::PotentiallyEvaluated);
+    SizeResult = getDerived().TransformExpr(T->getSizeExpr());
+  }
+  if (SizeResult.isInvalid())
+    return QualType();
+  SizeResult = SemaRef.ActOnFinishFullExpr(SizeResult.get());
   if (SizeResult.isInvalid())
     return QualType();
 
@@ -5015,6 +5168,7 @@
   NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
   NewTL.setLParenLoc(TL.getLParenLoc());
   NewTL.setRParenLoc(TL.getRParenLoc());
+  NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
   NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
   for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
     NewTL.setParam(i, ParamDecls[i]);
@@ -5157,7 +5311,7 @@
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
-    Result = getDerived().RebuildUnresolvedUsingType(D);
+    Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
     if (Result.isNull())
       return QualType();
   }
@@ -5332,6 +5486,37 @@
 }
 
 template<typename Derived>
+QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
+    TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
+  const DeducedTemplateSpecializationType *T = TL.getTypePtr();
+
+  CXXScopeSpec SS;
+  TemplateName TemplateName = getDerived().TransformTemplateName(
+      SS, T->getTemplateName(), TL.getTemplateNameLoc());
+  if (TemplateName.isNull())
+    return QualType();
+
+  QualType OldDeduced = T->getDeducedType();
+  QualType NewDeduced;
+  if (!OldDeduced.isNull()) {
+    NewDeduced = getDerived().TransformType(OldDeduced);
+    if (NewDeduced.isNull())
+      return QualType();
+  }
+
+  QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
+      TemplateName, NewDeduced);
+  if (Result.isNull())
+    return QualType();
+
+  DeducedTemplateSpecializationTypeLoc NewTL =
+      TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
+  NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
+
+  return Result;
+}
+
+template<typename Derived>
 QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
                                                      RecordTypeLoc TL) {
   const RecordType *T = TL.getTypePtr();
@@ -5706,7 +5891,8 @@
               Template.getAsTemplateDecl())) {
         SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
                      diag::err_tag_reference_non_tag)
-            << Sema::NTK_TypeAliasTemplate;
+            << TAT << Sema::NTK_TypeAliasTemplate
+            << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword());
         SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
       }
     }
@@ -5800,8 +5986,14 @@
 }
 
 template<typename Derived>
-QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
-                                                      DependentNameTypeLoc TL) {
+QualType TreeTransform<Derived>::TransformDependentNameType(
+    TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
+  return TransformDependentNameType(TLB, TL, false);
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformDependentNameType(
+    TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
   const DependentNameType *T = TL.getTypePtr();
 
   NestedNameSpecifierLoc QualifierLoc
@@ -5814,7 +6006,8 @@
                                             TL.getElaboratedKeywordLoc(),
                                             QualifierLoc,
                                             T->getIdentifier(),
-                                            TL.getNameLoc());
+                                            TL.getNameLoc(),
+                                            DeducedTSTContext);
   if (Result.isNull())
     return QualType();
 
@@ -5868,12 +6061,10 @@
                                               NewTemplateArgs))
     return QualType();
 
-  QualType Result
-    = getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(),
-                                                              QualifierLoc,
-                                                            T->getIdentifier(),
-                                                       TL.getTemplateNameLoc(),
-                                                            NewTemplateArgs);
+  QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
+      T->getKeyword(), QualifierLoc, T->getIdentifier(),
+      TL.getTemplateNameLoc(), NewTemplateArgs,
+      /*AllowInjectedClassName*/ false);
   if (Result.isNull())
     return QualType();
 
@@ -6658,7 +6849,91 @@
 TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
   // The coroutine body should be re-formed by the caller if necessary.
   // FIXME: The coroutine body is always rebuilt by ActOnFinishFunctionBody
-  return getDerived().TransformStmt(S->getBody());
+  CoroutineBodyStmt::CtorArgs BodyArgs;
+
+  auto *ScopeInfo = SemaRef.getCurFunction();
+  auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
+  assert(ScopeInfo && !ScopeInfo->CoroutinePromise &&
+         ScopeInfo->NeedsCoroutineSuspends &&
+         ScopeInfo->CoroutineSuspends.first == nullptr &&
+         ScopeInfo->CoroutineSuspends.second == nullptr &&
+         "expected clean scope info");
+
+  // Set that we have (possibly-invalid) suspend points before we do anything
+  // that may fail.
+  ScopeInfo->setNeedsCoroutineSuspends(false);
+
+  // The new CoroutinePromise object needs to be built and put into the current
+  // FunctionScopeInfo before any transformations or rebuilding occurs.
+  auto *Promise = S->getPromiseDecl();
+  auto *NewPromise = SemaRef.buildCoroutinePromise(FD->getLocation());
+  if (!NewPromise)
+    return StmtError();
+  getDerived().transformedLocalDecl(Promise, NewPromise);
+  ScopeInfo->CoroutinePromise = NewPromise;
+  StmtResult PromiseStmt = SemaRef.ActOnDeclStmt(
+          SemaRef.ConvertDeclToDeclGroup(NewPromise),
+          FD->getLocation(), FD->getLocation());
+  assert(!PromiseStmt.isInvalid());
+  BodyArgs.Promise = PromiseStmt.get();
+
+  // Transform the implicit coroutine statements we built during the initial
+  // parse.
+  StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
+  if (InitSuspend.isInvalid())
+    return StmtError();
+  StmtResult FinalSuspend =
+      getDerived().TransformStmt(S->getFinalSuspendStmt());
+  if (FinalSuspend.isInvalid())
+    return StmtError();
+  ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
+  assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
+  BodyArgs.InitialSuspend = cast<Expr>(InitSuspend.get());
+  BodyArgs.FinalSuspend = cast<Expr>(FinalSuspend.get());
+
+  StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
+  if (BodyRes.isInvalid())
+    return StmtError();
+  BodyArgs.Body = BodyRes.get();
+
+  if (S->getFallthroughHandler()) {
+    StmtResult Res = getDerived().TransformStmt(S->getFallthroughHandler());
+    if (Res.isInvalid())
+      return StmtError();
+    BodyArgs.OnFallthrough = Res.get();
+  }
+
+  if (S->getExceptionHandler()) {
+    StmtResult Res = getDerived().TransformStmt(S->getExceptionHandler());
+    if (Res.isInvalid())
+      return StmtError();
+    BodyArgs.OnException = Res.get();
+  }
+
+  // Transform any additional statements we may have already built
+  if (S->getAllocate() && S->getDeallocate()) {
+    ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
+    if (AllocRes.isInvalid())
+      return StmtError();
+    BodyArgs.Allocate = AllocRes.get();
+
+    ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
+    if (DeallocRes.isInvalid())
+      return StmtError();
+    BodyArgs.Deallocate = DeallocRes.get();
+  }
+
+  Expr *ReturnObject = S->getReturnValueInit();
+  if (ReturnObject) {
+    ExprResult Res = getDerived().TransformInitializer(ReturnObject,
+            /*NoCopyInit*/false);
+    if (Res.isInvalid())
+      return StmtError();
+    BodyArgs.ReturnValue = Res.get();
+  }
+
+  // Do a partial rebuild of the coroutine body and stash it in the ScopeInfo
+  return getDerived().RebuildCoroutineBodyStmt(BodyArgs);
 }
 
 template<typename Derived>
@@ -6671,7 +6946,8 @@
 
   // Always rebuild; we don't know if this needs to be injected into a new
   // context or if the promise type has changed.
-  return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get());
+  return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
+                                          S->isImplicit());
 }
 
 template<typename Derived>
@@ -6684,7 +6960,29 @@
 
   // Always rebuild; we don't know if this needs to be injected into a new
   // context or if the promise type has changed.
-  return getDerived().RebuildCoawaitExpr(E->getKeywordLoc(), Result.get());
+  return getDerived().RebuildCoawaitExpr(E->getKeywordLoc(), Result.get(),
+                                         E->isImplicit());
+}
+
+template <typename Derived>
+ExprResult
+TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
+  ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
+                                                        /*NotCopyInit*/ false);
+  if (OperandResult.isInvalid())
+    return ExprError();
+
+  ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
+          E->getOperatorCoawaitLookup());
+
+  if (LookupResult.isInvalid())
+    return ExprError();
+
+  // Always rebuild; we don't know if this needs to be injected into a new
+  // context or if the promise type has changed.
+  return getDerived().RebuildDependentCoawaitExpr(
+      E->getKeywordLoc(), OperandResult.get(),
+      cast<UnresolvedLookupExpr>(LookupResult.get()));
 }
 
 template<typename Derived>
@@ -7228,8 +7526,12 @@
     StmtResult Body;
     {
       Sema::CompoundScopeRAII CompoundScope(getSema());
-      Body = getDerived().TransformStmt(
-          cast<CapturedStmt>(D->getAssociatedStmt())->getCapturedStmt());
+      int ThisCaptureLevel =
+          Sema::getOpenMPCaptureLevels(D->getDirectiveKind());
+      Stmt *CS = D->getAssociatedStmt();
+      while (--ThisCaptureLevel >= 0)
+        CS = cast<CapturedStmt>(CS)->getCapturedStmt();
+      Body = getDerived().TransformStmt(CS);
     }
     AssociatedStmt =
         getDerived().getSema().ActOnOpenMPRegionEnd(Body, TClauses);
@@ -7722,6 +8024,66 @@
   return Res;
 }
 
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
+    OMPTargetTeamsDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams, DirName,
+                                             nullptr, D->getLocStart());
+  auto Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
+    OMPTargetTeamsDistributeDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams_distribute,
+      DirName, nullptr, D->getLocStart());
+  auto Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
+    OMPTargetTeamsDistributeParallelForDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(
+      OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
+      D->getLocStart());
+  auto Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::
+    TransformOMPTargetTeamsDistributeParallelForSimdDirective(
+        OMPTargetTeamsDistributeParallelForSimdDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(
+      OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
+      D->getLocStart());
+  auto Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
+    OMPTargetTeamsDistributeSimdDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(
+      OMPD_target_teams_distribute_simd, DirName, nullptr, D->getLocStart());
+  auto Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
 
 //===----------------------------------------------------------------------===//
 // OpenMP clause transformation
@@ -8748,12 +9110,18 @@
   // base (and therefore couldn't do the check) and a
   // nested-name-qualifier (and therefore could do the lookup).
   NamedDecl *FirstQualifierInScope = nullptr;
+  DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
+  if (MemberNameInfo.getName()) {
+    MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
+    if (!MemberNameInfo.getName())
+      return ExprError();
+  }
 
   return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
                                         E->isArrow(),
                                         QualifierLoc,
                                         TemplateKWLoc,
-                                        E->getMemberNameInfo(),
+                                        MemberNameInfo,
                                         Member,
                                         FoundDecl,
                                         (E->hasExplicitTemplateArgs()
@@ -9045,6 +9413,20 @@
 
 template<typename Derived>
 ExprResult
+TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
+  llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
+  return ExprError();
+}
+
+template<typename Derived>
+ExprResult
+TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
+  llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
+  return ExprError();
+}
+
+template<typename Derived>
+ExprResult
 TreeTransform<Derived>::TransformImplicitValueInitExpr(
                                                      ImplicitValueInitExpr *E) {
   TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
@@ -9344,7 +9726,8 @@
 ExprResult
 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
                                                      CXXFunctionalCastExpr *E) {
-  TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
+  TypeSourceInfo *Type =
+      getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
   if (!Type)
     return ExprError();
 
@@ -9533,8 +9916,8 @@
 ExprResult
 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
   // Transform the type that we're allocating
-  TypeSourceInfo *AllocTypeInfo
-    = getDerived().TransformType(E->getAllocatedTypeSourceInfo());
+  TypeSourceInfo *AllocTypeInfo =
+      getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
   if (!AllocTypeInfo)
     return ExprError();
 
@@ -9765,6 +10148,62 @@
                                                      Destroyed);
 }
 
+template <typename Derived>
+bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
+                                                        bool RequiresADL,
+                                                        LookupResult &R) {
+  // Transform all the decls.
+  bool AllEmptyPacks = true;
+  for (auto *OldD : Old->decls()) {
+    Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
+    if (!InstD) {
+      // Silently ignore these if a UsingShadowDecl instantiated to nothing.
+      // This can happen because of dependent hiding.
+      if (isa<UsingShadowDecl>(OldD))
+        continue;
+      else {
+        R.clear();
+        return true;
+      }
+    }
+
+    // Expand using pack declarations.
+    NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
+    ArrayRef<NamedDecl*> Decls = SingleDecl;
+    if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
+      Decls = UPD->expansions();
+
+    // Expand using declarations.
+    for (auto *D : Decls) {
+      if (auto *UD = dyn_cast<UsingDecl>(D)) {
+        for (auto *SD : UD->shadows())
+          R.addDecl(SD);
+      } else {
+        R.addDecl(D);
+      }
+    }
+
+    AllEmptyPacks &= Decls.empty();
+  };
+
+  // C++ [temp.res]/8.4.2:
+  //   The program is ill-formed, no diagnostic required, if [...] lookup for
+  //   a name in the template definition found a using-declaration, but the
+  //   lookup in the corresponding scope in the instantiation odoes not find
+  //   any declarations because the using-declaration was a pack expansion and
+  //   the corresponding pack is empty
+  if (AllEmptyPacks && !RequiresADL) {
+    getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
+        << isa<UnresolvedMemberExpr>(Old) << Old->getNameInfo().getName();
+    return true;
+  }
+
+  // Resolve a kind, but don't do any further analysis.  If it's
+  // ambiguous, the callee needs to deal with it.
+  R.resolveKind();
+  return false;
+}
+
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformUnresolvedLookupExpr(
@@ -9772,37 +10211,9 @@
   LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
                  Sema::LookupOrdinaryName);
 
-  // Transform all the decls.
-  for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(),
-         E = Old->decls_end(); I != E; ++I) {
-    NamedDecl *InstD = static_cast<NamedDecl*>(
-                                 getDerived().TransformDecl(Old->getNameLoc(),
-                                                            *I));
-    if (!InstD) {
-      // Silently ignore these if a UsingShadowDecl instantiated to nothing.
-      // This can happen because of dependent hiding.
-      if (isa<UsingShadowDecl>(*I))
-        continue;
-      else {
-        R.clear();
-        return ExprError();
-      }
-    }
-
-    // Expand using declarations.
-    if (isa<UsingDecl>(InstD)) {
-      UsingDecl *UD = cast<UsingDecl>(InstD);
-      for (auto *I : UD->shadows())
-        R.addDecl(I);
-      continue;
-    }
-
-    R.addDecl(InstD);
-  }
-
-  // Resolve a kind, but don't do any further analysis.  If it's
-  // ambiguous, the callee needs to deal with it.
-  R.resolveKind();
+  // Transform the declaration set.
+  if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
+    return ExprError();
 
   // Rebuild the nested-name qualifier, if present.
   CXXScopeSpec SS;
@@ -10217,7 +10628,8 @@
 ExprResult
 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
                                                     CXXTemporaryObjectExpr *E) {
-  TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
+  TypeSourceInfo *T =
+      getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
   if (!T)
     return ExprError();
 
@@ -10337,6 +10749,18 @@
 
   LSI->CallOperator = NewCallOperator;
 
+  for (unsigned I = 0, NumParams = NewCallOperator->getNumParams();
+       I != NumParams; ++I) {
+    auto *P = NewCallOperator->getParamDecl(I);
+    if (P->hasUninstantiatedDefaultArg()) {
+      EnterExpressionEvaluationContext Eval(
+          getSema(), Sema::PotentiallyEvaluatedIfUsed, P);
+      ExprResult R = getDerived().TransformExpr(
+          E->getCallOperator()->getParamDecl(I)->getDefaultArg());
+      P->setDefaultArg(R.get());
+    }
+  }
+
   getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
   getDerived().transformedLocalDecl(E->getCallOperator(), NewCallOperator);
 
@@ -10502,7 +10926,8 @@
 ExprResult
 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
                                                   CXXUnresolvedConstructExpr *E) {
-  TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
+  TypeSourceInfo *T =
+      getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
   if (!T)
     return ExprError();
 
@@ -10658,35 +11083,9 @@
   LookupResult R(SemaRef, Old->getMemberNameInfo(),
                  Sema::LookupOrdinaryName);
 
-  // Transform all the decls.
-  for (UnresolvedMemberExpr::decls_iterator I = Old->decls_begin(),
-         E = Old->decls_end(); I != E; ++I) {
-    NamedDecl *InstD = static_cast<NamedDecl*>(
-                                getDerived().TransformDecl(Old->getMemberLoc(),
-                                                           *I));
-    if (!InstD) {
-      // Silently ignore these if a UsingShadowDecl instantiated to nothing.
-      // This can happen because of dependent hiding.
-      if (isa<UsingShadowDecl>(*I))
-        continue;
-      else {
-        R.clear();
-        return ExprError();
-      }
-    }
-
-    // Expand using declarations.
-    if (isa<UsingDecl>(InstD)) {
-      UsingDecl *UD = cast<UsingDecl>(InstD);
-      for (auto *I : UD->shadows())
-        R.addDecl(I);
-      continue;
-    }
-
-    R.addDecl(InstD);
-  }
-
-  R.resolveKind();
+  // Transform the declaration set.
+  if (TransformOverloadExprDecls(Old, /*RequiresADL*/false, R))
+    return ExprError();
 
   // Determine the naming class.
   if (Old->getNamingClass()) {
@@ -11801,21 +12200,48 @@
 }
 
 template<typename Derived>
-QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) {
+QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
+                                                            Decl *D) {
   assert(D && "no decl found");
   if (D->isInvalidDecl()) return QualType();
 
   // FIXME: Doesn't account for ObjCInterfaceDecl!
   TypeDecl *Ty;
-  if (isa<UsingDecl>(D)) {
-    UsingDecl *Using = cast<UsingDecl>(D);
+  if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
+    // A valid resolved using typename pack expansion decl can have multiple
+    // UsingDecls, but they must each have exactly one type, and it must be
+    // the same type in every case. But we must have at least one expansion!
+    if (UPD->expansions().empty()) {
+      getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
+          << UPD->isCXXClassMember() << UPD;
+      return QualType();
+    }
+
+    // We might still have some unresolved types. Try to pick a resolved type
+    // if we can. The final instantiation will check that the remaining
+    // unresolved types instantiate to the type we pick.
+    QualType FallbackT;
+    QualType T;
+    for (auto *E : UPD->expansions()) {
+      QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
+      if (ThisT.isNull())
+        continue;
+      else if (ThisT->getAs<UnresolvedUsingType>())
+        FallbackT = ThisT;
+      else if (T.isNull())
+        T = ThisT;
+      else
+        assert(getSema().Context.hasSameType(ThisT, T) &&
+               "mismatched resolved types in using pack expansion");
+    }
+    return T.isNull() ? FallbackT : T;
+  } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
     assert(Using->hasTypename() &&
            "UnresolvedUsingTypenameDecl transformed to non-typename using");
 
     // A valid resolved using typename decl points to exactly one type decl.
     assert(++Using->shadow_begin() == Using->shadow_end());
     Ty = cast<TypeDecl>((*Using->shadow_begin())->getTargetDecl());
-
   } else {
     assert(isa<UnresolvedUsingTypenameDecl>(D) &&
            "UnresolvedUsingTypenameDecl transformed to non-using decl");
@@ -11886,7 +12312,8 @@
                                             const IdentifierInfo &Name,
                                             SourceLocation NameLoc,
                                             QualType ObjectType,
-                                            NamedDecl *FirstQualifierInScope) {
+                                            NamedDecl *FirstQualifierInScope,
+                                            bool AllowInjectedClassName) {
   UnqualifiedId TemplateName;
   TemplateName.setIdentifier(&Name, NameLoc);
   Sema::TemplateTy Template;
@@ -11895,7 +12322,7 @@
                                        SS, TemplateKWLoc, TemplateName,
                                        ParsedType::make(ObjectType),
                                        /*EnteringContext=*/false,
-                                       Template);
+                                       Template, AllowInjectedClassName);
   return Template.get();
 }
 
@@ -11904,7 +12331,8 @@
 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
                                             OverloadedOperatorKind Operator,
                                             SourceLocation NameLoc,
-                                            QualType ObjectType) {
+                                            QualType ObjectType,
+                                            bool AllowInjectedClassName) {
   UnqualifiedId Name;
   // FIXME: Bogus location information.
   SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
@@ -11915,7 +12343,7 @@
                                        SS, TemplateKWLoc, Name,
                                        ParsedType::make(ObjectType),
                                        /*EnteringContext=*/false,
-                                       Template);
+                                       Template, AllowInjectedClassName);
   return Template.get();
 }
 
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
index 79ccffc..684ec24 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/lib/Serialization/ASTCommon.cpp
@@ -147,9 +147,6 @@
   case BuiltinType::OCLQueue:
     ID = PREDEF_TYPE_QUEUE_ID;
     break;
-  case BuiltinType::OCLNDRange:
-    ID = PREDEF_TYPE_NDRANGE_ID;
-    break;
   case BuiltinType::OCLReserveID:
     ID = PREDEF_TYPE_RESERVE_ID_ID;
     break;
@@ -254,6 +251,7 @@
   case Decl::VarTemplateSpecialization:
   case Decl::VarTemplatePartialSpecialization:
   case Decl::Function:
+  case Decl::CXXDeductionGuide:
   case Decl::CXXMethod:
   case Decl::CXXConstructor:
   case Decl::CXXDestructor:
@@ -285,6 +283,7 @@
   case Decl::NonTypeTemplateParm:
   case Decl::TemplateTemplateParm:
   case Decl::Using:
+  case Decl::UsingPack:
   case Decl::ObjCMethod:
   case Decl::ObjCCategory:
   case Decl::ObjCCategoryImpl:
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 14cc774..be0cc9a 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -26,6 +26,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/ODRHash.h"
 #include "clang/AST/RawCommentList.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLocVisitor.h"
@@ -72,6 +73,7 @@
 #include "llvm/Bitcode/BitstreamReader.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -481,7 +483,7 @@
   // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
   // the transitive closure of its imports, since unrelated modules cannot be
   // imported until after this module finishes validation.
-  ModuleFile *TopImport = *ModuleMgr.rbegin();
+  ModuleFile *TopImport = &*ModuleMgr.rbegin();
   while (!TopImport->ImportedBy.empty())
     TopImport = TopImport->ImportedBy[0];
   if (TopImport->Kind != MK_ImplicitModule)
@@ -735,7 +737,7 @@
   return std::make_pair(KeyLen, DataLen);
 }
 
-ASTSelectorLookupTrait::internal_key_type 
+ASTSelectorLookupTrait::internal_key_type
 ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {
   using namespace llvm::support;
   SelectorTable &SelTable = Reader.getContext().Selectors;
@@ -756,8 +758,8 @@
   return SelTable.getSelector(N, Args.data());
 }
 
-ASTSelectorLookupTrait::data_type 
-ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, 
+ASTSelectorLookupTrait::data_type
+ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d,
                                  unsigned DataLen) {
   using namespace llvm::support;
 
@@ -943,6 +945,10 @@
   case DeclarationName::CXXLiteralOperatorName:
     Data = (uint64_t)Name.getCXXLiteralIdentifier();
     break;
+  case DeclarationName::CXXDeductionGuideName:
+    Data = (uint64_t)Name.getCXXDeductionGuideTemplate()
+               ->getDeclName().getAsIdentifierInfo();
+    break;
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
   case DeclarationName::CXXConversionFunctionName:
@@ -959,6 +965,7 @@
   switch (Kind) {
   case DeclarationName::Identifier:
   case DeclarationName::CXXLiteralOperatorName:
+  case DeclarationName::CXXDeductionGuideName:
     ID.AddString(((IdentifierInfo*)Data)->getName());
     break;
   case DeclarationName::ObjCZeroArgSelector:
@@ -1002,6 +1009,8 @@
   uint64_t Data;
   switch (Kind) {
   case DeclarationName::Identifier:
+  case DeclarationName::CXXLiteralOperatorName:
+  case DeclarationName::CXXDeductionGuideName:
     Data = (uint64_t)Reader.getLocalIdentifier(
         F, endian::readNext<uint32_t, little, unaligned>(d));
     break;
@@ -1016,10 +1025,6 @@
   case DeclarationName::CXXOperatorName:
     Data = *d++; // OverloadedOperatorKind
     break;
-  case DeclarationName::CXXLiteralOperatorName:
-    Data = (uint64_t)Reader.getLocalIdentifier(
-        F, endian::readNext<uint32_t, little, unaligned>(d));
-    break;
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
   case DeclarationName::CXXConversionFunctionName:
@@ -1103,7 +1108,7 @@
   return false;
 }
 
-void ASTReader::Error(StringRef Msg) {
+void ASTReader::Error(StringRef Msg) const {
   Error(diag::err_fe_pch_malformed, Msg);
   if (Context.getLangOpts().Modules && !Diags.isDiagnosticInFlight() &&
       !PP.getHeaderSearchInfo().getModuleCachePath().empty()) {
@@ -1113,7 +1118,7 @@
 }
 
 void ASTReader::Error(unsigned DiagID,
-                      StringRef Arg1, StringRef Arg2) {
+                      StringRef Arg1, StringRef Arg2) const {
   if (Diags.isDiagnosticInFlight())
     Diags.SetDelayedDiagnostic(DiagID, Arg1, Arg2);
   else
@@ -1196,7 +1201,7 @@
   RecordData Record;
   while (true) {
     llvm::BitstreamEntry E = SLocEntryCursor.advanceSkippingSubblocks();
-    
+
     switch (E.Kind) {
     case llvm::BitstreamEntry::SubBlock: // Handled for us already.
     case llvm::BitstreamEntry::Error:
@@ -1208,7 +1213,7 @@
       // The interesting case.
       break;
     }
-    
+
     // Read a record.
     Record.clear();
     StringRef Blob;
@@ -1278,10 +1283,15 @@
     unsigned RecCode = SLocEntryCursor.readRecord(Code, Record, &Blob);
 
     if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) {
+      if (!llvm::zlib::isAvailable()) {
+        Error("zlib is not available");
+        return nullptr;
+      }
       SmallString<0> Uncompressed;
-      if (llvm::zlib::uncompress(Blob, Uncompressed, Record[0]) !=
-          llvm::zlib::StatusOK) {
-        Error("could not decompress embedded file contents");
+      if (llvm::Error E =
+              llvm::zlib::uncompress(Blob, Uncompressed, Record[0])) {
+        Error("could not decompress embedded file contents: " +
+              llvm::toString(std::move(E)));
         return nullptr;
       }
       return llvm::MemoryBuffer::getMemBufferCopy(Uncompressed, Name);
@@ -1304,7 +1314,7 @@
     Error("incorrectly-formatted source location entry in AST file");
     return true;
   }
-  
+
   RecordData Record;
   StringRef Blob;
   switch (SLocEntryCursor.readRecord(Entry.ID, Record, &Blob)) {
@@ -1420,7 +1430,7 @@
 SourceLocation ASTReader::getImportLocation(ModuleFile *F) {
   if (F->ImportLoc.isValid())
     return F->ImportLoc;
-  
+
   // Otherwise we have a PCH. It's considered to be "imported" at the first
   // location of its includer.
   if (F->ImportedBy.empty() || !F->ImportedBy[0]) {
@@ -1482,7 +1492,7 @@
     // be able to reseek within the block and read entries.
     unsigned Flags = BitstreamCursor::AF_DontPopBlockAtEnd;
     llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(Flags);
-    
+
     switch (Entry.Kind) {
     case llvm::BitstreamEntry::SubBlock: // Handled for us already.
     case llvm::BitstreamEntry::Error:
@@ -1574,13 +1584,17 @@
   }
 }
 
-PreprocessedEntityID 
-ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const {
-  ContinuousRangeMap<uint32_t, int, 2>::const_iterator 
+PreprocessedEntityID
+ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M,
+                                         unsigned LocalID) const {
+  if (!M.ModuleOffsetMap.empty())
+    ReadModuleOffsetMap(M);
+
+  ContinuousRangeMap<uint32_t, int, 2>::const_iterator
     I = M.PreprocessedEntityRemap.find(LocalID - NUM_PREDEF_PP_ENTITY_IDS);
-  assert(I != M.PreprocessedEntityRemap.end() 
+  assert(I != M.PreprocessedEntityRemap.end()
          && "Invalid index into preprocessed entity index remap");
-  
+
   return LocalID + I->second;
 }
 
@@ -1588,21 +1602,21 @@
   return llvm::hash_combine(ikey.Size, ikey.ModTime);
 }
 
-HeaderFileInfoTrait::internal_key_type 
+HeaderFileInfoTrait::internal_key_type
 HeaderFileInfoTrait::GetInternalKey(const FileEntry *FE) {
   internal_key_type ikey = {FE->getSize(),
                             M.HasTimestamps ? FE->getModificationTime() : 0,
                             FE->getName(), /*Imported*/ false};
   return ikey;
 }
-    
+
 bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) {
   if (a.Size != b.Size || (a.ModTime && b.ModTime && a.ModTime != b.ModTime))
     return false;
 
   if (llvm::sys::path::is_absolute(a.Filename) && a.Filename == b.Filename)
     return true;
-  
+
   // Determine whether the actual files are equivalent.
   FileManager &FileMgr = Reader.getFileManager();
   auto GetFile = [&](const internal_key_type &Key) -> const FileEntry* {
@@ -1618,7 +1632,7 @@
   const FileEntry *FEB = GetFile(b);
   return FEA && FEA == FEB;
 }
-    
+
 std::pair<unsigned, unsigned>
 HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {
   using namespace llvm::support;
@@ -1638,7 +1652,7 @@
   return ikey;
 }
 
-HeaderFileInfoTrait::data_type 
+HeaderFileInfoTrait::data_type
 HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
                               unsigned DataLen) {
   const unsigned char *End = d + DataLen;
@@ -1658,7 +1672,7 @@
       M, endian::readNext<uint32_t, little, unaligned>(d));
   if (unsigned FrameworkOffset =
           endian::readNext<uint32_t, little, unaligned>(d)) {
-    // The framework offset is 1 greater than the actual offset, 
+    // The framework offset is 1 greater than the actual offset,
     // since 0 is used as an indicator for "no framework name".
     StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
     HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
@@ -1707,20 +1721,20 @@
   // Note that we are loading defined macros.
   Deserializing Macros(this);
 
-  for (auto &I : llvm::reverse(ModuleMgr)) {
-    BitstreamCursor &MacroCursor = I->MacroCursor;
+  for (ModuleFile &I : llvm::reverse(ModuleMgr)) {
+    BitstreamCursor &MacroCursor = I.MacroCursor;
 
     // If there was no preprocessor block, skip this file.
     if (MacroCursor.getBitcodeBytes().empty())
       continue;
 
     BitstreamCursor Cursor = MacroCursor;
-    Cursor.JumpToBit(I->MacroStartOffset);
+    Cursor.JumpToBit(I.MacroStartOffset);
 
     RecordData Record;
     while (true) {
       llvm::BitstreamEntry E = Cursor.advanceSkippingSubblocks();
-      
+
       switch (E.Kind) {
       case llvm::BitstreamEntry::SubBlock: // Handled for us already.
       case llvm::BitstreamEntry::Error:
@@ -1728,21 +1742,21 @@
         return;
       case llvm::BitstreamEntry::EndBlock:
         goto NextCursor;
-        
+
       case llvm::BitstreamEntry::Record:
         Record.clear();
         switch (Cursor.readRecord(E.ID, Record)) {
         default:  // Default behavior: ignore.
           break;
-          
+
         case PP_MACRO_OBJECT_LIKE:
         case PP_MACRO_FUNCTION_LIKE: {
-          IdentifierInfo *II = getLocalIdentifier(*I, Record[0]);
+          IdentifierInfo *II = getLocalIdentifier(I, Record[0]);
           if (II->isOutOfDate())
             updateOutOfDateIdentifier(*II);
           break;
         }
-          
+
         case PP_TOKEN:
           // Ignore tokens.
           break;
@@ -1794,7 +1808,7 @@
           IdTable->find_hashed(Name, NameHash, &Trait);
       if (Pos == IdTable->end())
         return false;
-      
+
       // Dereferencing the iterator has the effect of building the
       // IdentifierInfo node and populating it with the various
       // declarations it needs.
@@ -1802,7 +1816,7 @@
       Found = *Pos;
       return true;
     }
-    
+
     // \brief Retrieve the identifier info found within the module
     // files.
     IdentifierInfo *getIdentifierInfo() const { return Found; }
@@ -1838,7 +1852,7 @@
 void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) {
   if (!II)
     return;
-  
+
   II->setOutOfDate(false);
 
   // Update the generation for this identifier.
@@ -1953,7 +1967,7 @@
   }
 
   if (Latest)
-    PP.setLoadedMacroDirective(II, Latest);
+    PP.setLoadedMacroDirective(II, Earliest, Latest);
 }
 
 ASTReader::InputFileInfo
@@ -2000,7 +2014,7 @@
   BitstreamCursor &Cursor = F.InputFilesCursor;
   SavedStreamPosition SavedPosition(Cursor);
   Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
-  
+
   InputFileInfo FI = readInputFileInfo(F, ID);
   off_t StoredSize = FI.StoredSize;
   time_t StoredTime = FI.StoredTime;
@@ -2149,7 +2163,7 @@
 ASTReader::ASTReadResult ASTReader::ReadOptionsBlock(
     BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
     bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
-    std::string &SuggestedPredefines, bool ValidateDiagnosticOptions) {
+    std::string &SuggestedPredefines) {
   if (Stream.EnterSubBlock(OPTIONS_BLOCK_ID))
     return Failure;
 
@@ -2158,7 +2172,7 @@
   ASTReadResult Result = Success;
   while (true) {
     llvm::BitstreamEntry Entry = Stream.advance();
-    
+
     switch (Entry.Kind) {
     case llvm::BitstreamEntry::Error:
     case llvm::BitstreamEntry::SubBlock:
@@ -2191,15 +2205,6 @@
       break;
     }
 
-    case DIAGNOSTIC_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
-      if (ValidateDiagnosticOptions &&
-          !AllowCompatibleConfigurationMismatch &&
-          ParseDiagnosticOptions(Record, Complain, Listener))
-        return OutOfDate;
-      break;
-    }
-
     case FILE_SYSTEM_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
       if (!AllowCompatibleConfigurationMismatch &&
@@ -2240,18 +2245,40 @@
     return Failure;
   }
 
+  // Lambda to read the unhashed control block the first time it's called.
+  //
+  // For PCM files, the unhashed control block cannot be read until after the
+  // MODULE_NAME record.  However, PCH files have no MODULE_NAME, and yet still
+  // need to look ahead before reading the IMPORTS record.  For consistency,
+  // this block is always read somehow (see BitstreamEntry::EndBlock).
+  bool HasReadUnhashedControlBlock = false;
+  auto readUnhashedControlBlockOnce = [&]() {
+    if (!HasReadUnhashedControlBlock) {
+      HasReadUnhashedControlBlock = true;
+      if (ASTReadResult Result =
+              readUnhashedControlBlock(F, ImportedBy, ClientLoadCapabilities))
+        return Result;
+    }
+    return Success;
+  };
+
   // Read all of the records and blocks in the control block.
   RecordData Record;
   unsigned NumInputs = 0;
   unsigned NumUserInputs = 0;
   while (true) {
     llvm::BitstreamEntry Entry = Stream.advance();
-    
+
     switch (Entry.Kind) {
     case llvm::BitstreamEntry::Error:
       Error("malformed block record in AST file");
       return Failure;
     case llvm::BitstreamEntry::EndBlock: {
+      // Validate the module before returning.  This call catches an AST with
+      // no module name and no imports.
+      if (ASTReadResult Result = readUnhashedControlBlockOnce())
+        return Result;
+
       // Validate input files.
       const HeaderSearchOptions &HSOpts =
           PP.getHeaderSearchInfo().getHeaderSearchOpts();
@@ -2323,13 +2350,10 @@
           // FIXME: Allow this for files explicitly specified with -include-pch.
           bool AllowCompatibleConfigurationMismatch =
               F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule;
-          const HeaderSearchOptions &HSOpts =
-              PP.getHeaderSearchInfo().getHeaderSearchOpts();
 
           Result = ReadOptionsBlock(Stream, ClientLoadCapabilities,
                                     AllowCompatibleConfigurationMismatch,
-                                    *Listener, SuggestedPredefines,
-                                    HSOpts.ModulesValidateDiagnosticOptions);
+                                    *Listener, SuggestedPredefines);
           if (Result == Failure) {
             Error("malformed block record in AST file");
             return Result;
@@ -2349,7 +2373,7 @@
           return Failure;
         }
         continue;
-          
+
       default:
         if (Stream.SkipBlock()) {
           Error("malformed block record in AST file");
@@ -2357,7 +2381,7 @@
         }
         continue;
       }
-      
+
     case llvm::BitstreamEntry::Record:
       // The interesting case.
       break;
@@ -2403,13 +2427,14 @@
       break;
     }
 
-    case SIGNATURE:
-      assert((!F.Signature || F.Signature == Record[0]) && "signature changed");
-      F.Signature = Record[0];
-      break;
-
     case IMPORTS: {
-      // Load each of the imported PCH files. 
+      // Validate the AST before processing any imports (otherwise, untangling
+      // them can be error-prone and expensive).  A module will have a name and
+      // will already have been validated, but this catches the PCH case.
+      if (ASTReadResult Result = readUnhashedControlBlockOnce())
+        return Result;
+
+      // Load each of the imported PCH files.
       unsigned Idx = 0, N = Record.size();
       while (Idx < N) {
         // Read information about the AST file.
@@ -2421,7 +2446,10 @@
             ReadUntranslatedSourceLocation(Record[Idx++]);
         off_t StoredSize = (off_t)Record[Idx++];
         time_t StoredModTime = (time_t)Record[Idx++];
-        ASTFileSignature StoredSignature = Record[Idx++];
+        ASTFileSignature StoredSignature = {
+            {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++]}}};
         auto ImportedFile = ReadPath(F, Record, Idx);
 
         // If our client can't cope with us being out of date, we can't cope with
@@ -2473,6 +2501,12 @@
       F.ModuleName = Blob;
       if (Listener)
         Listener->ReadModuleName(F.ModuleName);
+
+      // Validate the AST as soon as we have a name so we can exit early on
+      // failure.
+      if (ASTReadResult Result = readUnhashedControlBlockOnce())
+        return Result;
+
       break;
 
     case MODULE_DIRECTORY: {
@@ -2513,6 +2547,7 @@
       F.InputFileOffsets =
           (const llvm::support::unaligned_uint64_t *)Blob.data();
       F.InputFilesLoaded.resize(NumInputs);
+      F.NumUserInputFiles = NumUserInputs;
       break;
     }
   }
@@ -2531,7 +2566,7 @@
   RecordData Record;
   while (true) {
     llvm::BitstreamEntry Entry = Stream.advance();
-    
+
     switch (Entry.Kind) {
     case llvm::BitstreamEntry::Error:
       Error("error at end of module block in AST file");
@@ -2546,7 +2581,7 @@
       if (DC->hasExternalLexicalStorage() &&
           !getContext().getLangOpts().CPlusPlus)
         DC->setMustBuildLookupTable();
-      
+
       return Success;
     }
     case llvm::BitstreamEntry::SubBlock:
@@ -2569,7 +2604,7 @@
         F.MacroCursor = Stream;
         if (!PP.getExternalSource())
           PP.setExternalSource(this);
-        
+
         if (Stream.SkipBlock() ||
             ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {
           Error("malformed block record in AST file");
@@ -2577,7 +2612,7 @@
         }
         F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo();
         break;
-        
+
       case PREPROCESSOR_DETAIL_BLOCK_ID:
         F.PreprocessorDetailCursor = Stream;
         if (Stream.SkipBlock() ||
@@ -2588,23 +2623,24 @@
             }
         F.PreprocessorDetailStartOffset
         = F.PreprocessorDetailCursor.GetCurrentBitNo();
-        
+
         if (!PP.getPreprocessingRecord())
           PP.createPreprocessingRecord();
         if (!PP.getPreprocessingRecord()->getExternalSource())
           PP.getPreprocessingRecord()->SetExternalSource(*this);
         break;
-        
+
       case SOURCE_MANAGER_BLOCK_ID:
         if (ReadSourceManagerBlock(F))
           return Failure;
         break;
-        
+
       case SUBMODULE_BLOCK_ID:
-        if (ASTReadResult Result = ReadSubmoduleBlock(F, ClientLoadCapabilities))
+        if (ASTReadResult Result =
+                ReadSubmoduleBlock(F, ClientLoadCapabilities))
           return Result;
         break;
-        
+
       case COMMENTS_BLOCK_ID: {
         BitstreamCursor C = Stream;
         if (Stream.SkipBlock() ||
@@ -2615,7 +2651,7 @@
         CommentsCursors.push_back(std::make_pair(C, &F));
         break;
       }
-        
+
       default:
         if (Stream.SkipBlock()) {
           Error("malformed block record in AST file");
@@ -2624,7 +2660,7 @@
         break;
       }
       continue;
-    
+
     case llvm::BitstreamEntry::Record:
       // The interesting case.
       break;
@@ -2646,21 +2682,21 @@
       F.LocalNumTypes = Record[0];
       unsigned LocalBaseTypeIndex = Record[1];
       F.BaseTypeIndex = getTotalNumTypes();
-        
+
       if (F.LocalNumTypes > 0) {
         // Introduce the global -> local mapping for types within this module.
         GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F));
-        
+
         // Introduce the local -> global mapping for types within this module.
         F.TypeRemap.insertOrReplace(
-          std::make_pair(LocalBaseTypeIndex, 
+          std::make_pair(LocalBaseTypeIndex,
                          F.BaseTypeIndex - LocalBaseTypeIndex));
 
         TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes);
       }
       break;
     }
-        
+
     case DECL_OFFSET: {
       if (F.LocalNumDecls != 0) {
         Error("duplicate DECL_OFFSET record in AST file");
@@ -2670,18 +2706,18 @@
       F.LocalNumDecls = Record[0];
       unsigned LocalBaseDeclID = Record[1];
       F.BaseDeclID = getTotalNumDecls();
-        
+
       if (F.LocalNumDecls > 0) {
-        // Introduce the global -> local mapping for declarations within this 
+        // Introduce the global -> local mapping for declarations within this
         // module.
         GlobalDeclMap.insert(
           std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F));
-        
+
         // Introduce the local -> global mapping for declarations within this
         // module.
         F.DeclRemap.insertOrReplace(
           std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID));
-        
+
         // Introduce the global -> local mapping for declarations within this
         // module.
         F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID;
@@ -2690,7 +2726,7 @@
       }
       break;
     }
-        
+
     case TU_UPDATE_LEXICAL: {
       DeclContext *TU = Context.getTranslationUnitDecl();
       LexicalContents Contents(
@@ -2722,7 +2758,7 @@
             (const unsigned char *)F.IdentifierTableData + sizeof(uint32_t),
             (const unsigned char *)F.IdentifierTableData,
             ASTIdentifierLookupTrait(*this, F));
-        
+
         PP.getIdentifierTable().setExternalIdentifierLookup(this);
       }
       break;
@@ -2736,13 +2772,13 @@
       F.LocalNumIdentifiers = Record[0];
       unsigned LocalBaseIdentifierID = Record[1];
       F.BaseIdentifierID = getTotalNumIdentifiers();
-        
+
       if (F.LocalNumIdentifiers > 0) {
         // Introduce the global -> local mapping for identifiers within this
         // module.
-        GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1, 
+        GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1,
                                                   &F));
-        
+
         // Introduce the local -> global mapping for identifiers within this
         // module.
         F.IdentifierRemap.insertOrReplace(
@@ -2766,6 +2802,14 @@
         EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
       break;
 
+    case MODULAR_CODEGEN_DECLS:
+      // FIXME: Skip reading this record if our ASTConsumer doesn't care about
+      // them (ie: if we're not codegenerating this module).
+      if (F.Kind == MK_MainFile)
+        for (unsigned I = 0, N = Record.size(); I != N; ++I)
+          EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
+      break;
+
     case SPECIAL_TYPES:
       if (SpecialTypes.empty()) {
         for (unsigned I = 0, N = Record.size(); I != N; ++I)
@@ -2809,11 +2853,11 @@
         Error("invalid weak identifiers record");
         return Failure;
       }
-        
-      // FIXME: Ignore weak undeclared identifiers from non-original PCH 
+
+      // FIXME: Ignore weak undeclared identifiers from non-original PCH
       // files. This isn't the way to do it :)
       WeakUndeclaredIdentifiers.clear();
-        
+
       // Translate the weak, undeclared identifiers into global IDs.
       for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) {
         WeakUndeclaredIdentifiers.push_back(
@@ -2831,13 +2875,13 @@
       F.LocalNumSelectors = Record[0];
       unsigned LocalBaseSelectorID = Record[1];
       F.BaseSelectorID = getTotalNumSelectors();
-        
+
       if (F.LocalNumSelectors > 0) {
-        // Introduce the global -> local mapping for selectors within this 
+        // Introduce the global -> local mapping for selectors within this
         // module.
         GlobalSelectorMap.insert(std::make_pair(getTotalNumSelectors()+1, &F));
-        
-        // Introduce the local -> global mapping for selectors within this 
+
+        // Introduce the local -> global mapping for selectors within this
         // module.
         F.SelectorRemap.insertOrReplace(
           std::make_pair(LocalBaseSelectorID,
@@ -2847,7 +2891,7 @@
       }
       break;
     }
-        
+
     case METHOD_POOL:
       F.SelectorLookupTableData = (const unsigned char *)Blob.data();
       if (Record[0])
@@ -2862,7 +2906,7 @@
     case REFERENCED_SELECTOR_POOL:
       if (!Record.empty()) {
         for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) {
-          ReferencedSelectorsData.push_back(getGlobalSelectorID(F, 
+          ReferencedSelectorsData.push_back(getGlobalSelectorID(F,
                                                                 Record[Idx++]));
           ReferencedSelectorsData.push_back(ReadSourceLocation(F, Record, Idx).
                                               getRawEncoding());
@@ -2874,7 +2918,7 @@
       if (!Record.empty() && Listener)
         Listener->ReadCounter(F, Record[0]);
       break;
-      
+
     case FILE_SORTED_DECLS:
       F.FileSortedDecls = (const DeclID *)Blob.data();
       F.NumFileSortedDecls = Record[0];
@@ -2911,85 +2955,14 @@
       // This module. Base was 2 when being compiled.
       F.SLocRemap.insertOrReplace(std::make_pair(2U,
                                   static_cast<int>(F.SLocEntryBaseOffset - 2)));
-      
+
       TotalNumSLocEntries += F.LocalNumSLocEntries;
       break;
     }
 
-    case MODULE_OFFSET_MAP: {
-      // Additional remapping information.
-      const unsigned char *Data = (const unsigned char*)Blob.data();
-      const unsigned char *DataEnd = Data + Blob.size();
-
-      // If we see this entry before SOURCE_LOCATION_OFFSETS, add placeholders.
-      if (F.SLocRemap.find(0) == F.SLocRemap.end()) {
-        F.SLocRemap.insert(std::make_pair(0U, 0));
-        F.SLocRemap.insert(std::make_pair(2U, 1));
-      }
-
-      // Continuous range maps we may be updating in our module.
-      typedef ContinuousRangeMap<uint32_t, int, 2>::Builder
-          RemapBuilder;
-      RemapBuilder SLocRemap(F.SLocRemap);
-      RemapBuilder IdentifierRemap(F.IdentifierRemap);
-      RemapBuilder MacroRemap(F.MacroRemap);
-      RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap);
-      RemapBuilder SubmoduleRemap(F.SubmoduleRemap);
-      RemapBuilder SelectorRemap(F.SelectorRemap);
-      RemapBuilder DeclRemap(F.DeclRemap);
-      RemapBuilder TypeRemap(F.TypeRemap);
-
-      while (Data < DataEnd) {
-        using namespace llvm::support;
-        uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data);
-        StringRef Name = StringRef((const char*)Data, Len);
-        Data += Len;
-        ModuleFile *OM = ModuleMgr.lookup(Name);
-        if (!OM) {
-          Error("SourceLocation remap refers to unknown module");
-          return Failure;
-        }
-
-        uint32_t SLocOffset =
-            endian::readNext<uint32_t, little, unaligned>(Data);
-        uint32_t IdentifierIDOffset =
-            endian::readNext<uint32_t, little, unaligned>(Data);
-        uint32_t MacroIDOffset =
-            endian::readNext<uint32_t, little, unaligned>(Data);
-        uint32_t PreprocessedEntityIDOffset =
-            endian::readNext<uint32_t, little, unaligned>(Data);
-        uint32_t SubmoduleIDOffset =
-            endian::readNext<uint32_t, little, unaligned>(Data);
-        uint32_t SelectorIDOffset =
-            endian::readNext<uint32_t, little, unaligned>(Data);
-        uint32_t DeclIDOffset =
-            endian::readNext<uint32_t, little, unaligned>(Data);
-        uint32_t TypeIndexOffset =
-            endian::readNext<uint32_t, little, unaligned>(Data);
-
-        uint32_t None = std::numeric_limits<uint32_t>::max();
-
-        auto mapOffset = [&](uint32_t Offset, uint32_t BaseOffset,
-                             RemapBuilder &Remap) {
-          if (Offset != None)
-            Remap.insert(std::make_pair(Offset,
-                                        static_cast<int>(BaseOffset - Offset)));
-        };
-        mapOffset(SLocOffset, OM->SLocEntryBaseOffset, SLocRemap);
-        mapOffset(IdentifierIDOffset, OM->BaseIdentifierID, IdentifierRemap);
-        mapOffset(MacroIDOffset, OM->BaseMacroID, MacroRemap);
-        mapOffset(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID,
-                  PreprocessedEntityRemap);
-        mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap);
-        mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap);
-        mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap);
-        mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap);
-
-        // Global -> local mappings.
-        F.GlobalToLocalDeclIDs[OM] = DeclIDOffset;
-      }
+    case MODULE_OFFSET_MAP:
+      F.ModuleOffsetMap = Blob;
       break;
-    }
 
     case SOURCE_MANAGER_LINE_TABLE:
       if (ParseLineTable(F, Record))
@@ -3003,7 +2976,7 @@
         Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file");
         return Failure;
       }
-      
+
       F.PreloadSLocEntries.swap(Record);
       break;
     }
@@ -3018,12 +2991,12 @@
         Error("Invalid VTABLE_USES record");
         return Failure;
       }
-        
+
       // Later tables overwrite earlier ones.
       // FIXME: Modules will have some trouble with this. This is clearly not
       // the right way to do this.
       VTableUses.clear();
-        
+
       for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) {
         VTableUses.push_back(getGlobalDeclID(F, Record[Idx++]));
         VTableUses.push_back(
@@ -3065,13 +3038,13 @@
       F.NumPreprocessedEntities = Blob.size() / sizeof(PPEntityOffset);
 
       unsigned LocalBasePreprocessedEntityID = Record[0];
-      
+
       unsigned StartingID;
       if (!PP.getPreprocessingRecord())
         PP.createPreprocessingRecord();
       if (!PP.getPreprocessingRecord()->getExternalSource())
         PP.getPreprocessingRecord()->SetExternalSource(*this);
-      StartingID 
+      StartingID
         = PP.getPreprocessingRecord()
             ->allocateLoadedEntities(F.NumPreprocessedEntities);
       F.BasePreprocessedEntityID = StartingID;
@@ -3080,7 +3053,7 @@
         // Introduce the global -> local mapping for preprocessed entities in
         // this module.
         GlobalPreprocessedEntityMap.insert(std::make_pair(StartingID, &F));
-       
+
         // Introduce the local -> global mapping for preprocessed entities in
         // this module.
         F.PreprocessedEntityRemap.insertOrReplace(
@@ -3090,7 +3063,7 @@
 
       break;
     }
-        
+
     case DECL_UPDATE_OFFSETS: {
       if (Record.size() % 2 != 0) {
         Error("invalid DECL_UPDATE_OFFSETS block in AST file");
@@ -3113,24 +3086,16 @@
         Error("duplicate OBJC_CATEGORIES_MAP record in AST file");
         return Failure;
       }
-      
+
       F.LocalNumObjCCategoriesInMap = Record[0];
       F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)Blob.data();
       break;
     }
-        
+
     case OBJC_CATEGORIES:
       F.ObjCCategories.swap(Record);
       break;
 
-    case DIAG_PRAGMA_MAPPINGS:
-      if (F.PragmaDiagMappings.empty())
-        F.PragmaDiagMappings.swap(Record);
-      else
-        F.PragmaDiagMappings.insert(F.PragmaDiagMappings.end(),
-                                    Record.begin(), Record.end());
-      break;
-        
     case CUDA_SPECIAL_DECL_REFS:
       // Later tables overwrite earlier ones.
       // FIXME: Modules will have trouble with this.
@@ -3147,32 +3112,62 @@
           = HeaderFileInfoLookupTable::Create(
                    (const unsigned char *)F.HeaderFileInfoTableData + Record[0],
                    (const unsigned char *)F.HeaderFileInfoTableData,
-                   HeaderFileInfoTrait(*this, F, 
+                   HeaderFileInfoTrait(*this, F,
                                        &PP.getHeaderSearchInfo(),
                                        Blob.data() + Record[2]));
-        
+
         PP.getHeaderSearchInfo().SetExternalSource(this);
         if (!PP.getHeaderSearchInfo().getExternalLookup())
           PP.getHeaderSearchInfo().SetExternalLookup(this);
       }
       break;
     }
-        
+
     case FP_PRAGMA_OPTIONS:
       // Later tables overwrite earlier ones.
       FPPragmaOptions.swap(Record);
       break;
 
     case OPENCL_EXTENSIONS:
-      // Later tables overwrite earlier ones.
-      OpenCLExtensions.swap(Record);
+      for (unsigned I = 0, E = Record.size(); I != E; ) {
+        auto Name = ReadString(Record, I);
+        auto &Opt = OpenCLExtensions.OptMap[Name];
+        Opt.Supported = Record[I++] != 0;
+        Opt.Enabled = Record[I++] != 0;
+        Opt.Avail = Record[I++];
+        Opt.Core = Record[I++];
+      }
+      break;
+
+    case OPENCL_EXTENSION_TYPES:
+      for (unsigned I = 0, E = Record.size(); I != E;) {
+        auto TypeID = static_cast<::TypeID>(Record[I++]);
+        auto *Type = GetType(TypeID).getTypePtr();
+        auto NumExt = static_cast<unsigned>(Record[I++]);
+        for (unsigned II = 0; II != NumExt; ++II) {
+          auto Ext = ReadString(Record, I);
+          OpenCLTypeExtMap[Type].insert(Ext);
+        }
+      }
+      break;
+
+    case OPENCL_EXTENSION_DECLS:
+      for (unsigned I = 0, E = Record.size(); I != E;) {
+        auto DeclID = static_cast<::DeclID>(Record[I++]);
+        auto *Decl = GetDecl(DeclID);
+        auto NumExt = static_cast<unsigned>(Record[I++]);
+        for (unsigned II = 0; II != NumExt; ++II) {
+          auto Ext = ReadString(Record, I);
+          OpenCLDeclExtMap[Decl].insert(Ext);
+        }
+      }
       break;
 
     case TENTATIVE_DEFINITIONS:
       for (unsigned I = 0, N = Record.size(); I != N; ++I)
         TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I]));
       break;
-        
+
     case KNOWN_NAMESPACES:
       for (unsigned I = 0, N = Record.size(); I != N; ++I)
         KnownNamespaces.push_back(getGlobalDeclID(F, Record[I]));
@@ -3215,8 +3210,11 @@
         for (unsigned I = 0, N = Record.size(); I != N; /**/) {
           unsigned GlobalID = getGlobalSubmoduleID(F, Record[I++]);
           SourceLocation Loc = ReadSourceLocation(F, Record, I);
-          if (GlobalID)
+          if (GlobalID) {
             ImportedModules.push_back(ImportedSubmodule(GlobalID, Loc));
+            if (DeserializationListener)
+              DeserializationListener->ModuleImportRead(GlobalID, Loc);
+          }
         }
       }
       break;
@@ -3293,6 +3291,87 @@
   }
 }
 
+void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
+  assert(!F.ModuleOffsetMap.empty() && "no module offset map to read");
+
+  // Additional remapping information.
+  const unsigned char *Data = (const unsigned char*)F.ModuleOffsetMap.data();
+  const unsigned char *DataEnd = Data + F.ModuleOffsetMap.size();
+  F.ModuleOffsetMap = StringRef();
+
+  // If we see this entry before SOURCE_LOCATION_OFFSETS, add placeholders.
+  if (F.SLocRemap.find(0) == F.SLocRemap.end()) {
+    F.SLocRemap.insert(std::make_pair(0U, 0));
+    F.SLocRemap.insert(std::make_pair(2U, 1));
+  }
+
+  // Continuous range maps we may be updating in our module.
+  typedef ContinuousRangeMap<uint32_t, int, 2>::Builder
+      RemapBuilder;
+  RemapBuilder SLocRemap(F.SLocRemap);
+  RemapBuilder IdentifierRemap(F.IdentifierRemap);
+  RemapBuilder MacroRemap(F.MacroRemap);
+  RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap);
+  RemapBuilder SubmoduleRemap(F.SubmoduleRemap);
+  RemapBuilder SelectorRemap(F.SelectorRemap);
+  RemapBuilder DeclRemap(F.DeclRemap);
+  RemapBuilder TypeRemap(F.TypeRemap);
+
+  while (Data < DataEnd) {
+    // FIXME: Looking up dependency modules by filename is horrible.
+    using namespace llvm::support;
+    uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data);
+    StringRef Name = StringRef((const char*)Data, Len);
+    Data += Len;
+    ModuleFile *OM = ModuleMgr.lookup(Name);
+    if (!OM) {
+      std::string Msg =
+          "SourceLocation remap refers to unknown module, cannot find ";
+      Msg.append(Name);
+      Error(Msg);
+      return;
+    }
+
+    uint32_t SLocOffset =
+        endian::readNext<uint32_t, little, unaligned>(Data);
+    uint32_t IdentifierIDOffset =
+        endian::readNext<uint32_t, little, unaligned>(Data);
+    uint32_t MacroIDOffset =
+        endian::readNext<uint32_t, little, unaligned>(Data);
+    uint32_t PreprocessedEntityIDOffset =
+        endian::readNext<uint32_t, little, unaligned>(Data);
+    uint32_t SubmoduleIDOffset =
+        endian::readNext<uint32_t, little, unaligned>(Data);
+    uint32_t SelectorIDOffset =
+        endian::readNext<uint32_t, little, unaligned>(Data);
+    uint32_t DeclIDOffset =
+        endian::readNext<uint32_t, little, unaligned>(Data);
+    uint32_t TypeIndexOffset =
+        endian::readNext<uint32_t, little, unaligned>(Data);
+
+    uint32_t None = std::numeric_limits<uint32_t>::max();
+
+    auto mapOffset = [&](uint32_t Offset, uint32_t BaseOffset,
+                         RemapBuilder &Remap) {
+      if (Offset != None)
+        Remap.insert(std::make_pair(Offset,
+                                    static_cast<int>(BaseOffset - Offset)));
+    };
+    mapOffset(SLocOffset, OM->SLocEntryBaseOffset, SLocRemap);
+    mapOffset(IdentifierIDOffset, OM->BaseIdentifierID, IdentifierRemap);
+    mapOffset(MacroIDOffset, OM->BaseMacroID, MacroRemap);
+    mapOffset(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID,
+              PreprocessedEntityRemap);
+    mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap);
+    mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap);
+    mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap);
+    mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap);
+
+    // Global -> local mappings.
+    F.GlobalToLocalDeclIDs[OM] = DeclIDOffset;
+  }
+}
+
 ASTReader::ASTReadResult
 ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
                                   const ModuleFile *ImportedBy,
@@ -3312,8 +3391,7 @@
   // usable header search context.
   assert(!F.ModuleName.empty() &&
          "MODULE_NAME should come before MODULE_MAP_FILE");
-  if (F.Kind == MK_ImplicitModule &&
-      (*ModuleMgr.begin())->Kind != MK_MainFile) {
+  if (F.Kind == MK_ImplicitModule && ModuleMgr.begin()->Kind != MK_MainFile) {
     // An implicitly-loaded module file should have its module listed in some
     // module map file that we've already loaded.
     Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
@@ -3515,7 +3593,7 @@
   if (TriedLoadingGlobalIndex || !UseGlobalIndex ||
       !Context.getLangOpts().Modules)
     return true;
-  
+
   // Try to load the global index.
   TriedLoadingGlobalIndex = true;
   StringRef ModuleCachePath
@@ -3578,7 +3656,8 @@
 ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
                                             ModuleKind Type,
                                             SourceLocation ImportLoc,
-                                            unsigned ClientLoadCapabilities) {
+                                            unsigned ClientLoadCapabilities,
+                                            SmallVectorImpl<ImportedSubmodule> *Imported) {
   llvm::SaveAndRestore<SourceLocation>
     SetCurImportLocRAII(CurrentImportLoc, ImportLoc);
 
@@ -3590,10 +3669,10 @@
 
   unsigned NumModules = ModuleMgr.size();
   SmallVector<ImportedModule, 4> Loaded;
-  switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type, ImportLoc,
-                                                /*ImportedBy=*/nullptr, Loaded,
-                                                0, 0, 0,
-                                                ClientLoadCapabilities)) {
+  switch (ASTReadResult ReadResult =
+              ReadASTCore(FileName, Type, ImportLoc,
+                          /*ImportedBy=*/nullptr, Loaded, 0, 0,
+                          ASTFileSignature(), ClientLoadCapabilities)) {
   case Failure:
   case Missing:
   case OutOfDate:
@@ -3604,11 +3683,10 @@
     for (const ImportedModule &IM : Loaded)
       LoadedSet.insert(IM.Mod);
 
-    ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end(),
-                            LoadedSet,
+    ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, LoadedSet,
                             Context.getLangOpts().Modules
-                              ? &PP.getHeaderSearchInfo().getModuleMap()
-                              : nullptr);
+                                ? &PP.getHeaderSearchInfo().getModuleMap()
+                                : nullptr);
 
     // If we find that any modules are unusable, the global index is going
     // to be out-of-date. Just remove it.
@@ -3638,12 +3716,12 @@
         return Result;
     }
 
-    // Once read, set the ModuleFile bit base offset and update the size in 
+    // Once read, set the ModuleFile bit base offset and update the size in
     // bits of all files we've seen.
     F.GlobalBitOffset = TotalModulesSizeInBits;
     TotalModulesSizeInBits += F.SizeInBits;
     GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F));
-    
+
     // Preload SLocEntries.
     for (unsigned I = 0, N = F.PreloadSLocEntries.size(); I != N; ++I) {
       int Index = int(F.PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID;
@@ -3713,7 +3791,7 @@
   // Mark selectors as out of date.
   for (auto Sel : SelectorGeneration)
     SelectorOutOfDate[Sel.first] = true;
-  
+
   // Resolve any unresolved module exports.
   for (unsigned I = 0, N = UnresolvedModuleRefs.size(); I != N; ++I) {
     UnresolvedModuleRef &Unresolved = UnresolvedModuleRefs[I];
@@ -3744,10 +3822,14 @@
   }
   UnresolvedModuleRefs.clear();
 
+  if (Imported)
+    Imported->append(ImportedModules.begin(),
+                     ImportedModules.end());
+
   // FIXME: How do we load the 'use'd modules? They may not be submodules.
   // Might be unnecessary as use declarations are only used to build the
   // module itself.
-  
+
   InitializeContext();
 
   if (SemaObj)
@@ -3758,7 +3840,7 @@
 
   ModuleFile &PrimaryModule = ModuleMgr.getPrimaryModule();
   if (PrimaryModule.OriginalSourceFileID.isValid()) {
-    PrimaryModule.OriginalSourceFileID 
+    PrimaryModule.OriginalSourceFileID
       = FileID::get(PrimaryModule.SLocEntryBaseID
                     + PrimaryModule.OriginalSourceFileID.getOpaqueValue() - 1);
 
@@ -3771,11 +3853,11 @@
       SourceMgr.setMainFileID(PrimaryModule.OriginalSourceFileID);
     }
   }
-  
+
   // For any Objective-C class definitions we have already loaded, make sure
   // that we load any additional categories.
   for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) {
-    loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(), 
+    loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(),
                        ObjCClassesLoaded[I],
                        PreviousGeneration);
   }
@@ -3887,7 +3969,7 @@
   BitstreamCursor &Stream = F.Stream;
   Stream = BitstreamCursor(PCHContainerRdr.ExtractPCH(*F.Buffer));
   F.SizeInBits = F.Buffer->getBufferSize() * 8;
-  
+
   // Sniff for the signature.
   if (!startsWithASTFileMagic(Stream)) {
     Diag(diag::err_module_file_invalid) << moduleKindForDiagnostic(Type)
@@ -3899,14 +3981,14 @@
   bool HaveReadControlBlock = false;
   while (true) {
     llvm::BitstreamEntry Entry = Stream.advance();
-    
+
     switch (Entry.Kind) {
     case llvm::BitstreamEntry::Error:
     case llvm::BitstreamEntry::Record:
     case llvm::BitstreamEntry::EndBlock:
       Error("invalid record at top-level of AST file");
       return Failure;
-        
+
     case llvm::BitstreamEntry::SubBlock:
       break;
     }
@@ -3951,6 +4033,12 @@
       Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc));
       return Success;
 
+    case UNHASHED_CONTROL_BLOCK_ID:
+      // This block is handled using look-ahead during ReadControlBlock.  We
+      // shouldn't get here!
+      Error("malformed block record in AST file");
+      return Failure;
+
     default:
       if (Stream.SkipBlock()) {
         Error("malformed block record in AST file");
@@ -3963,6 +4051,93 @@
   return Success;
 }
 
+ASTReader::ASTReadResult
+ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
+                                    unsigned ClientLoadCapabilities) {
+  const HeaderSearchOptions &HSOpts =
+      PP.getHeaderSearchInfo().getHeaderSearchOpts();
+  bool AllowCompatibleConfigurationMismatch =
+      F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule;
+
+  ASTReadResult Result = readUnhashedControlBlockImpl(
+      &F, F.Data, ClientLoadCapabilities, AllowCompatibleConfigurationMismatch,
+      Listener.get(),
+      WasImportedBy ? false : HSOpts.ModulesValidateDiagnosticOptions);
+
+  if (DisableValidation || WasImportedBy ||
+      (AllowConfigurationMismatch && Result == ConfigurationMismatch))
+    return Success;
+
+  if (Result == Failure)
+    Error("malformed block record in AST file");
+
+  return Result;
+}
+
+ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
+    ModuleFile *F, llvm::StringRef StreamData, unsigned ClientLoadCapabilities,
+    bool AllowCompatibleConfigurationMismatch, ASTReaderListener *Listener,
+    bool ValidateDiagnosticOptions) {
+  // Initialize a stream.
+  BitstreamCursor Stream(StreamData);
+
+  // Sniff for the signature.
+  if (!startsWithASTFileMagic(Stream))
+    return Failure;
+
+  // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
+  if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
+    return Failure;
+
+  // Read all of the records in the options block.
+  RecordData Record;
+  ASTReadResult Result = Success;
+  while (1) {
+    llvm::BitstreamEntry Entry = Stream.advance();
+
+    switch (Entry.Kind) {
+    case llvm::BitstreamEntry::Error:
+    case llvm::BitstreamEntry::SubBlock:
+      return Failure;
+
+    case llvm::BitstreamEntry::EndBlock:
+      return Result;
+
+    case llvm::BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read and process a record.
+    Record.clear();
+    switch (
+        (UnhashedControlBlockRecordTypes)Stream.readRecord(Entry.ID, Record)) {
+    case SIGNATURE: {
+      if (F)
+        std::copy(Record.begin(), Record.end(), F->Signature.data());
+      break;
+    }
+    case DIAGNOSTIC_OPTIONS: {
+      bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
+      if (Listener && ValidateDiagnosticOptions &&
+          !AllowCompatibleConfigurationMismatch &&
+          ParseDiagnosticOptions(Record, Complain, *Listener))
+        return OutOfDate;
+      break;
+    }
+    case DIAG_PRAGMA_MAPPINGS:
+      if (!F)
+        break;
+      if (F->PragmaDiagMappings.empty())
+        F->PragmaDiagMappings.swap(Record);
+      else
+        F->PragmaDiagMappings.insert(F->PragmaDiagMappings.end(),
+                                     Record.begin(), Record.end());
+      break;
+    }
+  }
+}
+
 /// Parse a record and blob containing module file extension metadata.
 static bool parseModuleFileExtensionMetadata(
               const SmallVectorImpl<uint64_t> &Record,
@@ -4037,26 +4212,26 @@
 void ASTReader::InitializeContext() {
   // If there's a listener, notify them that we "read" the translation unit.
   if (DeserializationListener)
-    DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, 
+    DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID,
                                       Context.getTranslationUnitDecl());
 
   // FIXME: Find a better way to deal with collisions between these
   // built-in types. Right now, we just ignore the problem.
-  
+
   // Load the special types.
   if (SpecialTypes.size() >= NumSpecialTypeIDs) {
     if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) {
       if (!Context.CFConstantStringTypeDecl)
         Context.setCFConstantStringType(GetType(String));
     }
-    
+
     if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
       QualType FileType = GetType(File);
       if (FileType.isNull()) {
         Error("FILE type is NULL");
         return;
       }
-      
+
       if (!Context.FILEDecl) {
         if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
           Context.setFILEDecl(Typedef->getDecl());
@@ -4070,14 +4245,14 @@
         }
       }
     }
-    
+
     if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) {
       QualType Jmp_bufType = GetType(Jmp_buf);
       if (Jmp_bufType.isNull()) {
         Error("jmp_buf type is NULL");
         return;
       }
-      
+
       if (!Context.jmp_bufDecl) {
         if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
           Context.setjmp_bufDecl(Typedef->getDecl());
@@ -4091,14 +4266,14 @@
         }
       }
     }
-    
+
     if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) {
       QualType Sigjmp_bufType = GetType(Sigjmp_buf);
       if (Sigjmp_bufType.isNull()) {
         Error("sigjmp_buf type is NULL");
         return;
       }
-      
+
       if (!Context.sigjmp_bufDecl) {
         if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
           Context.setsigjmp_bufDecl(Typedef->getDecl());
@@ -4146,7 +4321,7 @@
       }
     }
   }
-  
+
   ReadPragmaDiagnosticMappings(Context.getDiagnostics());
 
   // If there were any CUDA special declarations, deserialize them.
@@ -4179,23 +4354,24 @@
 static ASTFileSignature readASTFileSignature(StringRef PCH) {
   BitstreamCursor Stream(PCH);
   if (!startsWithASTFileMagic(Stream))
-    return 0;
+    return ASTFileSignature();
 
-  // Scan for the CONTROL_BLOCK_ID block.
-  if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID))
-    return 0;
+  // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
+  if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
+    return ASTFileSignature();
 
-  // Scan for SIGNATURE inside the control block.
+  // Scan for SIGNATURE inside the diagnostic options block.
   ASTReader::RecordData Record;
   while (true) {
     llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
     if (Entry.Kind != llvm::BitstreamEntry::Record)
-      return 0;
+      return ASTFileSignature();
 
     Record.clear();
     StringRef Blob;
     if (SIGNATURE == Stream.readRecord(Entry.ID, Record, &Blob))
-      return Record[0];
+      return {{{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2],
+                (uint32_t)Record[3], (uint32_t)Record[4]}}};
   }
 }
 
@@ -4221,7 +4397,7 @@
     Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
     return std::string();
   }
-  
+
   // Scan for the CONTROL_BLOCK_ID block.
   if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) {
     Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
@@ -4234,12 +4410,12 @@
     llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
     if (Entry.Kind == llvm::BitstreamEntry::EndBlock)
       return std::string();
-    
+
     if (Entry.Kind != llvm::BitstreamEntry::Record) {
       Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
       return std::string();
     }
-    
+
     Record.clear();
     StringRef Blob;
     if (Stream.readRecord(Entry.ID, Record, &Blob) == ORIGINAL_FILE)
@@ -4314,7 +4490,8 @@
   }
 
   // Initialize the stream
-  BitstreamCursor Stream(PCHContainerRdr.ExtractPCH(**Buffer));
+  StringRef Bytes = PCHContainerRdr.ExtractPCH(**Buffer);
+  BitstreamCursor Stream(Bytes);
 
   // Sniff for the signature.
   if (!startsWithASTFileMagic(Stream))
@@ -4342,8 +4519,7 @@
         std::string IgnoredSuggestedPredefines;
         if (ReadOptionsBlock(Stream, ARR_ConfigurationMismatch | ARR_OutOfDate,
                              /*AllowCompatibleConfigurationMismatch*/ false,
-                             Listener, IgnoredSuggestedPredefines,
-                             ValidateDiagnosticOptions) != Success)
+                             Listener, IgnoredSuggestedPredefines) != Success)
           return true;
         break;
       }
@@ -4388,7 +4564,7 @@
 
       if (Listener.ReadFullVersionInformation(Blob))
         return true;
-      
+
       break;
     }
     case MODULE_NAME:
@@ -4464,6 +4640,7 @@
 
   // Look for module file extension blocks, if requested.
   if (FindModuleFileExtensions) {
+    BitstreamCursor SavedStream = Stream;
     while (!SkipCursorToBlock(Stream, EXTENSION_BLOCK_ID)) {
       bool DoneWithExtensionBlock = false;
       while (!DoneWithExtensionBlock) {
@@ -4502,8 +4679,16 @@
        }
       }
     }
+    Stream = SavedStream;
   }
 
+  // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
+  if (readUnhashedControlBlockImpl(
+          nullptr, Bytes, ARR_ConfigurationMismatch | ARR_OutOfDate,
+          /*AllowCompatibleConfigurationMismatch*/ false, &Listener,
+          ValidateDiagnosticOptions) != Success)
+    return true;
+
   return false;
 }
 
@@ -4534,7 +4719,7 @@
   RecordData Record;
   while (true) {
     llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks();
-    
+
     switch (Entry.Kind) {
     case llvm::BitstreamEntry::SubBlock: // Handled for us already.
     case llvm::BitstreamEntry::Error:
@@ -4586,6 +4771,7 @@
       bool InferExplicitSubmodules = Record[Idx++];
       bool InferExportWildcard = Record[Idx++];
       bool ConfigMacrosExhaustive = Record[Idx++];
+      bool WithCodegen = Record[Idx++];
 
       Module *ParentModule = nullptr;
       if (Parent)
@@ -4593,8 +4779,9 @@
 
       // Retrieve this (sub)module from the module map, creating it if
       // necessary.
-      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, IsFramework,
-                                                IsExplicit).first;
+      CurrentModule =
+          ModMap.findOrCreateModule(Name, ParentModule, IsFramework, IsExplicit)
+              .first;
 
       // FIXME: set the definition loc for CurrentModule, or call
       // ModMap.setInferredModuleAllowedBy()
@@ -4630,9 +4817,10 @@
       CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;
       CurrentModule->InferExportWildcard = InferExportWildcard;
       CurrentModule->ConfigMacrosExhaustive = ConfigMacrosExhaustive;
+      CurrentModule->WithCodegen = WithCodegen;
       if (DeserializationListener)
         DeserializationListener->ModuleRead(GlobalID, CurrentModule);
-      
+
       SubmodulesLoaded[GlobalIndex] = CurrentModule;
 
       // Clear out data that will be replaced by what is in the module file.
@@ -4672,7 +4860,7 @@
       }
       break;
     }
-        
+
     case SUBMODULE_HEADER:
     case SUBMODULE_EXCLUDED_HEADER:
     case SUBMODULE_PRIVATE_HEADER:
@@ -4706,17 +4894,17 @@
       }
       break;
     }
-        
+
     case SUBMODULE_METADATA: {
       F.BaseSubmoduleID = getTotalNumSubmodules();
       F.LocalNumSubmodules = Record[0];
       unsigned LocalBaseSubmoduleID = Record[1];
       if (F.LocalNumSubmodules > 0) {
-        // Introduce the global -> local mapping for submodules within this 
+        // Introduce the global -> local mapping for submodules within this
         // module.
         GlobalSubmoduleMap.insert(std::make_pair(getTotalNumSubmodules()+1,&F));
-        
-        // Introduce the local -> global mapping for submodules within this 
+
+        // Introduce the local -> global mapping for submodules within this
         // module.
         F.SubmoduleRemap.insertOrReplace(
           std::make_pair(LocalBaseSubmoduleID,
@@ -4726,7 +4914,7 @@
       }
       break;
     }
-        
+
     case SUBMODULE_IMPORTS: {
       for (unsigned Idx = 0; Idx != Record.size(); ++Idx) {
         UnresolvedModuleRef Unresolved;
@@ -4750,8 +4938,8 @@
         Unresolved.IsWildcard = Record[Idx + 1];
         UnresolvedModuleRefs.push_back(Unresolved);
       }
-      
-      // Once we've loaded the set of exports, there's no reason to keep 
+
+      // Once we've loaded the set of exports, there's no reason to keep
       // the parsed, unresolved exports around.
       CurrentModule->UnresolvedExports.clear();
       break;
@@ -4964,7 +5152,7 @@
 ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) {
   GlobalPreprocessedEntityMapType::iterator
   I = GlobalPreprocessedEntityMap.find(GlobalIndex);
-  assert(I != GlobalPreprocessedEntityMap.end() && 
+  assert(I != GlobalPreprocessedEntityMap.end() &&
          "Corrupted global preprocessed entity map");
   ModuleFile *M = I->second;
   unsigned LocalIndex = GlobalIndex - M->BasePreprocessedEntityID;
@@ -5000,8 +5188,8 @@
     Error("no preprocessing record");
     return nullptr;
   }
-  
-  SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);  
+
+  SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);
   M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset);
 
   llvm::BitstreamEntry Entry =
@@ -5040,7 +5228,7 @@
 
     return ME;
   }
-      
+
   case PPD_MACRO_DEFINITION: {
     // Decode the identifier info and then check again; if the macro is
     // still defined and associated with the identifier,
@@ -5052,14 +5240,14 @@
 
     return MD;
   }
-      
+
   case PPD_INCLUSION_DIRECTIVE: {
     const char *FullFileNameStart = Blob.data() + Record[0];
     StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]);
     const FileEntry *File = nullptr;
     if (!FullFileName.empty())
       File = PP.getFileManager().getFile(FullFileName);
-    
+
     // FIXME: Stable encoding
     InclusionDirective::InclusionKind Kind
       = static_cast<InclusionDirective::InclusionKind>(Record[2]);
@@ -5200,11 +5388,11 @@
   ModuleFile &M = *PPInfo.first;
   unsigned LocalIndex = PPInfo.second;
   const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
-  
+
   SourceLocation Loc = TranslateSourceLocation(M, PPOffs.getBegin());
   if (Loc.isInvalid())
     return false;
-  
+
   if (SourceMgr.isInFileID(SourceMgr.getFileLoc(Loc), FID))
     return true;
   else
@@ -5216,9 +5404,9 @@
   /// \brief Visitor used to search for information about a header file.
   class HeaderFileInfoVisitor {
     const FileEntry *FE;
-    
+
     Optional<HeaderFileInfo> HFI;
-    
+
   public:
     explicit HeaderFileInfoVisitor(const FileEntry *FE)
       : FE(FE) { }
@@ -5237,7 +5425,7 @@
       HFI = *Pos;
       return true;
     }
-    
+
     Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; }
   };
 
@@ -5248,53 +5436,88 @@
   ModuleMgr.visit(Visitor);
   if (Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo())
     return *HFI;
-  
+
   return HeaderFileInfo();
 }
 
 void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
-  // FIXME: Make it work properly with modules.
-  SmallVector<DiagnosticsEngine::DiagState *, 32> DiagStates;
-  for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
-    ModuleFile &F = *(*I);
+  using DiagState = DiagnosticsEngine::DiagState;
+  SmallVector<DiagState *, 32> DiagStates;
+
+  for (ModuleFile &F : ModuleMgr) {
     unsigned Idx = 0;
+    auto &Record = F.PragmaDiagMappings;
+    if (Record.empty())
+      continue;
+
     DiagStates.clear();
-    assert(!Diag.DiagStates.empty());
-    DiagStates.push_back(&Diag.DiagStates.front()); // the command-line one.
-    while (Idx < F.PragmaDiagMappings.size()) {
-      SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
-      unsigned DiagStateID = F.PragmaDiagMappings[Idx++];
-      if (DiagStateID != 0) {
-        Diag.DiagStatePoints.push_back(
-                    DiagnosticsEngine::DiagStatePoint(DiagStates[DiagStateID-1],
-                    FullSourceLoc(Loc, SourceMgr)));
-        continue;
-      }
-      
-      assert(DiagStateID == 0);
+
+    auto ReadDiagState =
+        [&](const DiagState &BasedOn, SourceLocation Loc,
+            bool IncludeNonPragmaStates) -> DiagnosticsEngine::DiagState * {
+      unsigned BackrefID = Record[Idx++];
+      if (BackrefID != 0)
+        return DiagStates[BackrefID - 1];
+
       // A new DiagState was created here.
-      Diag.DiagStates.push_back(*Diag.GetCurDiagState());
-      DiagnosticsEngine::DiagState *NewState = &Diag.DiagStates.back();
+      Diag.DiagStates.push_back(BasedOn);
+      DiagState *NewState = &Diag.DiagStates.back();
       DiagStates.push_back(NewState);
-      Diag.DiagStatePoints.push_back(
-          DiagnosticsEngine::DiagStatePoint(NewState,
-                                            FullSourceLoc(Loc, SourceMgr)));
-      while (true) {
-        assert(Idx < F.PragmaDiagMappings.size() &&
-               "Invalid data, didn't find '-1' marking end of diag/map pairs");
-        if (Idx >= F.PragmaDiagMappings.size()) {
-          break; // Something is messed up but at least avoid infinite loop in
-                 // release build.
-        }
-        unsigned DiagID = F.PragmaDiagMappings[Idx++];
-        if (DiagID == (unsigned)-1) {
-          break; // no more diag/map pairs for this location.
-        }
-        diag::Severity Map = (diag::Severity)F.PragmaDiagMappings[Idx++];
+      while (Idx + 1 < Record.size() && Record[Idx] != unsigned(-1)) {
+        unsigned DiagID = Record[Idx++];
+        diag::Severity Map = (diag::Severity)Record[Idx++];
         DiagnosticMapping Mapping = Diag.makeUserMapping(Map, Loc);
-        Diag.GetCurDiagState()->setMapping(DiagID, Mapping);
+        if (Mapping.isPragma() || IncludeNonPragmaStates)
+          NewState->setMapping(DiagID, Mapping);
+      }
+      assert(Idx != Record.size() && Record[Idx] == unsigned(-1) &&
+             "Invalid data, didn't find '-1' marking end of diag/map pairs");
+      ++Idx;
+      return NewState;
+    };
+
+    auto *FirstState = ReadDiagState(
+        F.isModule() ? DiagState() : *Diag.DiagStatesByLoc.CurDiagState,
+        SourceLocation(), F.isModule());
+    SourceLocation CurStateLoc =
+        ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
+    auto *CurState = ReadDiagState(*FirstState, CurStateLoc, false);
+
+    if (!F.isModule()) {
+      Diag.DiagStatesByLoc.CurDiagState = CurState;
+      Diag.DiagStatesByLoc.CurDiagStateLoc = CurStateLoc;
+
+      // Preserve the property that the imaginary root file describes the
+      // current state.
+      auto &T = Diag.DiagStatesByLoc.Files[FileID()].StateTransitions;
+      if (T.empty())
+        T.push_back({CurState, 0});
+      else
+        T[0].State = CurState;
+    }
+
+    while (Idx < Record.size()) {
+      SourceLocation Loc = ReadSourceLocation(F, Record[Idx++]);
+      auto IDAndOffset = SourceMgr.getDecomposedLoc(Loc);
+      assert(IDAndOffset.second == 0 && "not a start location for a FileID");
+      unsigned Transitions = Record[Idx++];
+
+      // Note that we don't need to set up Parent/ParentOffset here, because
+      // we won't be changing the diagnostic state within imported FileIDs
+      // (other than perhaps appending to the main source file, which has no
+      // parent).
+      auto &F = Diag.DiagStatesByLoc.Files[IDAndOffset.first];
+      F.StateTransitions.reserve(F.StateTransitions.size() + Transitions);
+      for (unsigned I = 0; I != Transitions; ++I) {
+        unsigned Offset = Record[Idx++];
+        auto *State =
+            ReadDiagState(*FirstState, Loc.getLocWithOffset(Offset), false);
+        F.StateTransitions.push_back({State, Offset});
       }
     }
+
+    // Don't try to read these mappings again.
+    Record.clear();
   }
 }
 
@@ -5416,7 +5639,7 @@
     QualType ClassType = readType(*Loc.F, Record, Idx);
     if (PointeeType.isNull() || ClassType.isNull())
       return QualType();
-    
+
     return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr());
   }
 
@@ -5526,7 +5749,7 @@
     return Context.getTypeDeclType(
                   ReadDeclAs<UnresolvedUsingTypenameDecl>(*Loc.F, Record, Idx));
   }
-      
+
   case TYPE_TYPEDEF: {
     if (Record.size() != 2) {
       Error("incorrect encoding of typedef type");
@@ -5571,6 +5794,14 @@
     return Context.getAutoType(Deduced, Keyword, IsDependent);
   }
 
+  case TYPE_DEDUCED_TEMPLATE_SPECIALIZATION: {
+    TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx);
+    QualType Deduced = readType(*Loc.F, Record, Idx);
+    bool IsDependent = Deduced.isNull() ? Record[Idx++] : false;
+    return Context.getDeducedTemplateSpecializationType(Name, Deduced,
+                                                        IsDependent);
+  }
+
   case TYPE_RECORD: {
     if (Record.size() != 2) {
       Error("incorrect encoding of record type");
@@ -5831,26 +6062,27 @@
 }
 
 class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {
-  ASTReader &Reader;
-  ModuleFile &F;
+  ModuleFile *F;
+  ASTReader *Reader;
   const ASTReader::RecordData &Record;
   unsigned &Idx;
 
-  SourceLocation ReadSourceLocation(const ASTReader::RecordData &R,
-                                    unsigned &I) {
-    return Reader.ReadSourceLocation(F, R, I);
+  SourceLocation ReadSourceLocation() {
+    return Reader->ReadSourceLocation(*F, Record, Idx);
   }
 
-  template<typename T>
-  T *ReadDeclAs(const ASTReader::RecordData &Record, unsigned &Idx) {
-    return Reader.ReadDeclAs<T>(F, Record, Idx);
+  TypeSourceInfo *GetTypeSourceInfo() {
+    return Reader->GetTypeSourceInfo(*F, Record, Idx);
   }
-  
+
+  NestedNameSpecifierLoc ReadNestedNameSpecifierLoc() {
+    return Reader->ReadNestedNameSpecifierLoc(*F, Record, Idx);
+  }
+
 public:
-  TypeLocReader(ASTReader &Reader, ModuleFile &F,
+  TypeLocReader(ModuleFile &F, ASTReader &Reader,
                 const ASTReader::RecordData &Record, unsigned &Idx)
-    : Reader(Reader), F(F), Record(Record), Idx(Idx)
-  { }
+      : F(&F), Reader(&Reader), Record(Record), Idx(Idx) {}
 
   // We want compile-time assurance that we've enumerated all of
   // these, so unfortunately we have to declare them first, then
@@ -5869,7 +6101,7 @@
 }
 
 void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
-  TL.setBuiltinLoc(ReadSourceLocation(Record, Idx));
+  TL.setBuiltinLoc(ReadSourceLocation());
   if (TL.needsExtraLocalData()) {
     TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
     TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
@@ -5879,11 +6111,11 @@
 }
 
 void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
-  TL.setStarLoc(ReadSourceLocation(Record, Idx));
+  TL.setStarLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
@@ -5895,27 +6127,27 @@
 }
 
 void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
-  TL.setCaretLoc(ReadSourceLocation(Record, Idx));
+  TL.setCaretLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
-  TL.setAmpLoc(ReadSourceLocation(Record, Idx));
+  TL.setAmpLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
-  TL.setAmpAmpLoc(ReadSourceLocation(Record, Idx));
+  TL.setAmpAmpLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
-  TL.setStarLoc(ReadSourceLocation(Record, Idx));
-  TL.setClassTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
+  TL.setStarLoc(ReadSourceLocation());
+  TL.setClassTInfo(GetTypeSourceInfo());
 }
 
 void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
-  TL.setLBracketLoc(ReadSourceLocation(Record, Idx));
-  TL.setRBracketLoc(ReadSourceLocation(Record, Idx));
+  TL.setLBracketLoc(ReadSourceLocation());
+  TL.setRBracketLoc(ReadSourceLocation());
   if (Record[Idx++])
-    TL.setSizeExpr(Reader.ReadExpr(F));
+    TL.setSizeExpr(Reader->ReadExpr(*F));
   else
     TL.setSizeExpr(nullptr);
 }
@@ -5939,24 +6171,26 @@
 
 void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
                                         DependentSizedExtVectorTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
-  TL.setLocalRangeBegin(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setLocalRangeEnd(ReadSourceLocation(Record, Idx));
+  TL.setLocalRangeBegin(ReadSourceLocation());
+  TL.setLParenLoc(ReadSourceLocation());
+  TL.setRParenLoc(ReadSourceLocation());
+  TL.setExceptionSpecRange(SourceRange(Reader->ReadSourceLocation(*F, Record, Idx),
+                                       Reader->ReadSourceLocation(*F, Record, Idx)));
+  TL.setLocalRangeEnd(ReadSourceLocation());
   for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i) {
-    TL.setParam(i, ReadDeclAs<ParmVarDecl>(Record, Idx));
+    TL.setParam(i, Reader->ReadDeclAs<ParmVarDecl>(*F, Record, Idx));
   }
 }
 
@@ -5968,173 +6202,178 @@
   VisitFunctionTypeLoc(TL);
 }
 void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
-  TL.setTypeofLoc(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
+  TL.setTypeofLoc(ReadSourceLocation());
+  TL.setLParenLoc(ReadSourceLocation());
+  TL.setRParenLoc(ReadSourceLocation());
 }
 void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
-  TL.setTypeofLoc(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
+  TL.setTypeofLoc(ReadSourceLocation());
+  TL.setLParenLoc(ReadSourceLocation());
+  TL.setRParenLoc(ReadSourceLocation());
+  TL.setUnderlyingTInfo(GetTypeSourceInfo());
 }
 void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
-  TL.setKWLoc(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
+  TL.setKWLoc(ReadSourceLocation());
+  TL.setLParenLoc(ReadSourceLocation());
+  TL.setRParenLoc(ReadSourceLocation());
+  TL.setUnderlyingTInfo(GetTypeSourceInfo());
 }
 
 void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
+}
+
+void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc(
+    DeducedTemplateSpecializationTypeLoc TL) {
+  TL.setTemplateNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
-  TL.setAttrNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setAttrNameLoc(ReadSourceLocation());
   if (TL.hasAttrOperand()) {
     SourceRange range;
-    range.setBegin(ReadSourceLocation(Record, Idx));
-    range.setEnd(ReadSourceLocation(Record, Idx));
+    range.setBegin(ReadSourceLocation());
+    range.setEnd(ReadSourceLocation());
     TL.setAttrOperandParensRange(range);
   }
   if (TL.hasAttrExprOperand()) {
     if (Record[Idx++])
-      TL.setAttrExprOperand(Reader.ReadExpr(F));
+      TL.setAttrExprOperand(Reader->ReadExpr(*F));
     else
       TL.setAttrExprOperand(nullptr);
   } else if (TL.hasAttrEnumOperand())
-    TL.setAttrEnumOperandLoc(ReadSourceLocation(Record, Idx));
+    TL.setAttrEnumOperandLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
                                             SubstTemplateTypeParmTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc(
                                           SubstTemplateTypeParmPackTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 void TypeLocReader::VisitTemplateSpecializationTypeLoc(
                                            TemplateSpecializationTypeLoc TL) {
-  TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx));
-  TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
-  TL.setRAngleLoc(ReadSourceLocation(Record, Idx));
+  TL.setTemplateKeywordLoc(ReadSourceLocation());
+  TL.setTemplateNameLoc(ReadSourceLocation());
+  TL.setLAngleLoc(ReadSourceLocation());
+  TL.setRAngleLoc(ReadSourceLocation());
   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
-    TL.setArgLocInfo(i,
-        Reader.GetTemplateArgumentLocInfo(F,
-                                          TL.getTypePtr()->getArg(i).getKind(),
-                                          Record, Idx));
+    TL.setArgLocInfo(
+        i,
+        Reader->GetTemplateArgumentLocInfo(
+            *F, TL.getTypePtr()->getArg(i).getKind(), Record, Idx));
 }
 void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
+  TL.setLParenLoc(ReadSourceLocation());
+  TL.setRParenLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
-  TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
+  TL.setElaboratedKeywordLoc(ReadSourceLocation());
+  TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
 }
 
 void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
-  TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setElaboratedKeywordLoc(ReadSourceLocation());
+  TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
        DependentTemplateSpecializationTypeLoc TL) {
-  TL.setElaboratedKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
-  TL.setTemplateKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx));
-  TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
-  TL.setRAngleLoc(ReadSourceLocation(Record, Idx));
+  TL.setElaboratedKeywordLoc(ReadSourceLocation());
+  TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
+  TL.setTemplateKeywordLoc(ReadSourceLocation());
+  TL.setTemplateNameLoc(ReadSourceLocation());
+  TL.setLAngleLoc(ReadSourceLocation());
+  TL.setRAngleLoc(ReadSourceLocation());
   for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
-    TL.setArgLocInfo(I,
-        Reader.GetTemplateArgumentLocInfo(F,
-                                          TL.getTypePtr()->getArg(I).getKind(),
-                                          Record, Idx));
+    TL.setArgLocInfo(
+        I,
+        Reader->GetTemplateArgumentLocInfo(
+            *F, TL.getTypePtr()->getArg(I).getKind(), Record, Idx));
 }
 
 void TypeLocReader::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
-  TL.setEllipsisLoc(ReadSourceLocation(Record, Idx));
+  TL.setEllipsisLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
-  TL.setNameLoc(ReadSourceLocation(Record, Idx));
+  TL.setNameLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
   if (TL.getNumProtocols()) {
-    TL.setProtocolLAngleLoc(ReadSourceLocation(Record, Idx));
-    TL.setProtocolRAngleLoc(ReadSourceLocation(Record, Idx));
+    TL.setProtocolLAngleLoc(ReadSourceLocation());
+    TL.setProtocolRAngleLoc(ReadSourceLocation());
   }
   for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
-    TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));
+    TL.setProtocolLoc(i, ReadSourceLocation());
 }
 
 void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
   TL.setHasBaseTypeAsWritten(Record[Idx++]);
-  TL.setTypeArgsLAngleLoc(ReadSourceLocation(Record, Idx));
-  TL.setTypeArgsRAngleLoc(ReadSourceLocation(Record, Idx));
+  TL.setTypeArgsLAngleLoc(ReadSourceLocation());
+  TL.setTypeArgsRAngleLoc(ReadSourceLocation());
   for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i)
-    TL.setTypeArgTInfo(i, Reader.GetTypeSourceInfo(F, Record, Idx));
-  TL.setProtocolLAngleLoc(ReadSourceLocation(Record, Idx));
-  TL.setProtocolRAngleLoc(ReadSourceLocation(Record, Idx));
+    TL.setTypeArgTInfo(i, GetTypeSourceInfo());
+  TL.setProtocolLAngleLoc(ReadSourceLocation());
+  TL.setProtocolRAngleLoc(ReadSourceLocation());
   for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
-    TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));
+    TL.setProtocolLoc(i, ReadSourceLocation());
 }
 
 void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
-  TL.setStarLoc(ReadSourceLocation(Record, Idx));
+  TL.setStarLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
-  TL.setKWLoc(ReadSourceLocation(Record, Idx));
-  TL.setLParenLoc(ReadSourceLocation(Record, Idx));
-  TL.setRParenLoc(ReadSourceLocation(Record, Idx));
+  TL.setKWLoc(ReadSourceLocation());
+  TL.setLParenLoc(ReadSourceLocation());
+  TL.setRParenLoc(ReadSourceLocation());
 }
 
 void TypeLocReader::VisitPipeTypeLoc(PipeTypeLoc TL) {
-  TL.setKWLoc(ReadSourceLocation(Record, Idx));
+  TL.setKWLoc(ReadSourceLocation());
 }
 
-TypeSourceInfo *ASTReader::GetTypeSourceInfo(ModuleFile &F,
-                                             const RecordData &Record,
-                                             unsigned &Idx) {
+TypeSourceInfo *
+ASTReader::GetTypeSourceInfo(ModuleFile &F, const ASTReader::RecordData &Record,
+                             unsigned &Idx) {
   QualType InfoTy = readType(F, Record, Idx);
   if (InfoTy.isNull())
     return nullptr;
 
   TypeSourceInfo *TInfo = getContext().CreateTypeSourceInfo(InfoTy);
-  TypeLocReader TLR(*this, F, Record, Idx);
+  TypeLocReader TLR(F, *this, Record, Idx);
   for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
     TLR.Visit(TL);
   return TInfo;
@@ -6266,9 +6505,6 @@
     case PREDEF_TYPE_QUEUE_ID:
       T = Context.OCLQueueTy;
       break;
-    case PREDEF_TYPE_NDRANGE_ID:
-      T = Context.OCLNDRangeTy;
-      break;
     case PREDEF_TYPE_RESERVE_ID_ID:
       T = Context.OCLReserveIDTy;
       break;
@@ -6317,18 +6553,21 @@
   return GetType(getGlobalTypeID(F, LocalID));
 }
 
-serialization::TypeID 
+serialization::TypeID
 ASTReader::getGlobalTypeID(ModuleFile &F, unsigned LocalID) const {
   unsigned FastQuals = LocalID & Qualifiers::FastMask;
   unsigned LocalIndex = LocalID >> Qualifiers::FastWidth;
-  
+
   if (LocalIndex < NUM_PREDEF_TYPE_IDS)
     return LocalID;
 
+  if (!F.ModuleOffsetMap.empty())
+    ReadModuleOffsetMap(F);
+
   ContinuousRangeMap<uint32_t, int, 2>::iterator I
     = F.TypeRemap.find(LocalIndex - NUM_PREDEF_TYPE_IDS);
   assert(I != F.TypeRemap.end() && "Invalid index into type index remap");
-  
+
   unsigned GlobalIndex = LocalIndex + I->second;
   return (GlobalIndex << Qualifiers::FastWidth) | FastQuals;
 }
@@ -6344,18 +6583,18 @@
   case TemplateArgument::Type:
     return GetTypeSourceInfo(F, Record, Index);
   case TemplateArgument::Template: {
-    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, 
+    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record,
                                                                      Index);
     SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
     return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
                                    SourceLocation());
   }
   case TemplateArgument::TemplateExpansion: {
-    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, 
+    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record,
                                                                      Index);
     SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
     SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index);
-    return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, 
+    return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
                                    EllipsisLoc);
   }
   case TemplateArgument::Null:
@@ -6399,12 +6638,6 @@
   return GetDecl(ID);
 }
 
-template<typename TemplateSpecializationDecl>
-static void completeRedeclChainForTemplateSpecialization(Decl *D) {
-  if (auto *TSD = dyn_cast<TemplateSpecializationDecl>(D))
-    TSD->getSpecializedTemplate()->LoadLazySpecializations();
-}
-
 void ASTReader::CompleteRedeclChain(const Decl *D) {
   if (NumCurrentElementsDeserializing) {
     // We arrange to not care about the complete redeclaration chain while we're
@@ -6500,15 +6733,18 @@
   return Bases;
 }
 
-serialization::DeclID 
+serialization::DeclID
 ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const {
   if (LocalID < NUM_PREDEF_DECL_IDS)
     return LocalID;
 
+  if (!F.ModuleOffsetMap.empty())
+    ReadModuleOffsetMap(F);
+
   ContinuousRangeMap<uint32_t, int, 2>::iterator I
     = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS);
   assert(I != F.DeclRemap.end() && "Invalid index into decl index remap");
-  
+
   return LocalID + I->second;
 }
 
@@ -6518,7 +6754,7 @@
   if (ID < NUM_PREDEF_DECL_IDS)
     return false;
 
-  return ID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && 
+  return ID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID &&
          ID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls;
 }
 
@@ -6650,11 +6886,11 @@
   return DeclsLoaded[Index];
 }
 
-DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, 
+DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
                                                   DeclID GlobalID) {
   if (GlobalID < NUM_PREDEF_DECL_IDS)
     return GlobalID;
-  
+
   GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID);
   assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
   ModuleFile *Owner = I->second;
@@ -6663,18 +6899,18 @@
     = M.GlobalToLocalDeclIDs.find(Owner);
   if (Pos == M.GlobalToLocalDeclIDs.end())
     return 0;
-      
+
   return GlobalID - Owner->BaseDeclID + Pos->second;
 }
 
-serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F, 
+serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F,
                                             const RecordData &Record,
                                             unsigned &Idx) {
   if (Idx >= Record.size()) {
     Error("Corrupted AST file");
     return 0;
   }
-  
+
   return getGlobalDeclID(F, Record[Idx++]);
 }
 
@@ -6690,6 +6926,9 @@
   // Offset here is a global offset across the entire chain.
   RecordLocation Loc = getLocalBitOffset(Offset);
   Loc.F->DeclsCursor.JumpToBit(Loc.Offset);
+  assert(NumCurrentElementsDeserializing == 0 &&
+         "should not be called while already deserializing");
+  Deserializing D(this);
   return ReadStmtFromStream(*Loc.F);
 }
 
@@ -6806,7 +7045,7 @@
                              EndLoc, DIDComp);
   if (EndIt != DInfo.Decls.end())
     ++EndIt;
-  
+
   for (ArrayRef<serialization::LocalDeclID>::iterator
          DIt = BeginIt; DIt != EndIt; ++DIt)
     Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt)));
@@ -7017,23 +7256,23 @@
     std::fprintf(stderr, "\n");
     GlobalIndex->printStats();
   }
-  
+
   std::fprintf(stderr, "\n");
   dump();
   std::fprintf(stderr, "\n");
 }
 
 template<typename Key, typename ModuleFile, unsigned InitialCapacity>
-static void 
+LLVM_DUMP_METHOD static void
 dumpModuleIDMap(StringRef Name,
-                const ContinuousRangeMap<Key, ModuleFile *, 
+                const ContinuousRangeMap<Key, ModuleFile *,
                                          InitialCapacity> &Map) {
   if (Map.begin() == Map.end())
     return;
-  
+
   typedef ContinuousRangeMap<Key, ModuleFile *, InitialCapacity> MapType;
   llvm::errs() << Name << ":\n";
-  for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end(); 
+  for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
        I != IEnd; ++I) {
     llvm::errs() << "  " << I->first << " -> " << I->second->FileName
       << "\n";
@@ -7050,22 +7289,19 @@
   dumpModuleIDMap("Global macro map", GlobalMacroMap);
   dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap);
   dumpModuleIDMap("Global selector map", GlobalSelectorMap);
-  dumpModuleIDMap("Global preprocessed entity map", 
+  dumpModuleIDMap("Global preprocessed entity map",
                   GlobalPreprocessedEntityMap);
-  
+
   llvm::errs() << "\n*** PCH/Modules Loaded:";
-  for (ModuleManager::ModuleConstIterator M = ModuleMgr.begin(), 
-                                       MEnd = ModuleMgr.end();
-       M != MEnd; ++M)
-    (*M)->dump();
+  for (ModuleFile &M : ModuleMgr)
+    M.dump();
 }
 
 /// Return the amount of memory used by memory buffers, breaking down
 /// by heap-backed versus mmap'ed memory.
 void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
-  for (ModuleConstIterator I = ModuleMgr.begin(),
-      E = ModuleMgr.end(); I != E; ++I) {
-    if (llvm::MemoryBuffer *buf = (*I)->Buffer.get()) {
+  for (ModuleFile &I : ModuleMgr) {
+    if (llvm::MemoryBuffer *buf = I.Buffer.get()) {
       size_t bytes = buf->getBufferSize();
       switch (buf->getBufferKind()) {
         case llvm::MemoryBuffer::MemoryBuffer_Malloc:
@@ -7097,14 +7333,9 @@
     SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0];
   }
 
-  // FIXME: What happens if these are changed by a module import?
-  if (!OpenCLExtensions.empty()) {
-    unsigned I = 0;
-#define OPENCLEXT(nm)  SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++];
-#include "clang/Basic/OpenCLExtensions.def"
-
-    assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS");
-  }
+  SemaObj->OpenCLFeatures.copy(OpenCLExtensions);
+  SemaObj->OpenCLTypeExtMap = OpenCLTypeExtMap;
+  SemaObj->OpenCLDeclExtMap = OpenCLDeclExtMap;
 
   UpdateSema();
 }
@@ -7304,7 +7535,7 @@
     bool operator()(ModuleFile &M) {
       if (!M.SelectorLookupTable)
         return false;
-      
+
       // If we've already searched this module file, skip it now.
       if (M.Generation <= PriorGeneration)
         return true;
@@ -7334,14 +7565,14 @@
       FactoryHasMoreThanOneDecl = Data.FactoryHasMoreThanOneDecl;
       return true;
     }
-    
+
     /// \brief Retrieve the instance methods found by this visitor.
-    ArrayRef<ObjCMethodDecl *> getInstanceMethods() const { 
-      return InstanceMethods; 
+    ArrayRef<ObjCMethodDecl *> getInstanceMethods() const {
+      return InstanceMethods;
     }
 
     /// \brief Retrieve the instance methods found by this visitor.
-    ArrayRef<ObjCMethodDecl *> getFactoryMethods() const { 
+    ArrayRef<ObjCMethodDecl *> getFactoryMethods() const {
       return FactoryMethods;
     }
 
@@ -7363,14 +7594,14 @@
     S.addMethodToGlobalList(&List, Methods[I]);
   }
 }
-                             
+
 void ASTReader::ReadMethodPool(Selector Sel) {
   // Get the selector generation and update it to the current generation.
   unsigned &Generation = SelectorGeneration[Sel];
   unsigned PriorGeneration = Generation;
   Generation = getGeneration();
   SelectorOutOfDate[Sel] = false;
-  
+
   // Search for methods defined with this selector.
   ++NumMethodPoolLookups;
   ReadMethodPoolVisitor Visitor(*this, Sel, PriorGeneration);
@@ -7384,7 +7615,7 @@
 
   if (!getSema())
     return;
-  
+
   Sema &S = *getSema();
   Sema::GlobalMethodPool::iterator Pos
     = S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethods())).first;
@@ -7409,9 +7640,9 @@
 void ASTReader::ReadKnownNamespaces(
                           SmallVectorImpl<NamespaceDecl *> &Namespaces) {
   Namespaces.clear();
-  
+
   for (unsigned I = 0, N = KnownNamespaces.size(); I != N; ++I) {
-    if (NamespaceDecl *Namespace 
+    if (NamespaceDecl *Namespace
                 = dyn_cast_or_null<NamespaceDecl>(GetDecl(KnownNamespaces[I])))
       Namespaces.push_back(Namespace);
   }
@@ -7500,7 +7731,7 @@
        SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
   if (ReferencedSelectorsData.empty())
     return;
-  
+
   // If there are @selector references added them to its pool. This is for
   // implementation of -Wselector.
   unsigned int DataSize = ReferencedSelectorsData.size()-1;
@@ -7520,9 +7751,9 @@
     return;
 
   for (unsigned I = 0, N = WeakUndeclaredIdentifiers.size(); I < N; /*none*/) {
-    IdentifierInfo *WeakId 
+    IdentifierInfo *WeakId
       = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
-    IdentifierInfo *AliasId 
+    IdentifierInfo *AliasId
       = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
     SourceLocation Loc
       = SourceLocation::getFromRawEncoding(WeakUndeclaredIdentifiers[I++]);
@@ -7542,7 +7773,7 @@
     VT.DefinitionRequired = VTableUses[Idx++];
     VTables.push_back(VT);
   }
-  
+
   VTableUses.clear();
 }
 
@@ -7554,7 +7785,7 @@
       = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);
 
     Pending.push_back(std::make_pair(D, Loc));
-  }  
+  }
   PendingInstantiations.clear();
 }
 
@@ -7686,12 +7917,15 @@
 IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) {
   if (LocalID < NUM_PREDEF_IDENT_IDS)
     return LocalID;
-  
+
+  if (!M.ModuleOffsetMap.empty())
+    ReadModuleOffsetMap(M);
+
   ContinuousRangeMap<uint32_t, int, 2>::iterator I
     = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS);
-  assert(I != M.IdentifierRemap.end() 
+  assert(I != M.IdentifierRemap.end()
          && "Invalid index into identifier index remap");
-  
+
   return LocalID + I->second;
 }
 
@@ -7712,7 +7946,7 @@
     ModuleFile *M = I->second;
     unsigned Index = ID - M->BaseMacroID;
     MacrosLoaded[ID] = ReadMacroRecord(*M, M->MacroOffsets[Index]);
-    
+
     if (DeserializationListener)
       DeserializationListener->MacroRead(ID + NUM_PREDEF_MACRO_IDS,
                                          MacrosLoaded[ID]);
@@ -7725,6 +7959,9 @@
   if (LocalID < NUM_PREDEF_MACRO_IDS)
     return LocalID;
 
+  if (!M.ModuleOffsetMap.empty())
+    ReadModuleOffsetMap(M);
+
   ContinuousRangeMap<uint32_t, int, 2>::iterator I
     = M.MacroRemap.find(LocalID - NUM_PREDEF_MACRO_IDS);
   assert(I != M.MacroRemap.end() && "Invalid index into macro index remap");
@@ -7736,12 +7973,15 @@
 ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) {
   if (LocalID < NUM_PREDEF_SUBMODULE_IDS)
     return LocalID;
-  
+
+  if (!M.ModuleOffsetMap.empty())
+    ReadModuleOffsetMap(M);
+
   ContinuousRangeMap<uint32_t, int, 2>::iterator I
     = M.SubmoduleRemap.find(LocalID - NUM_PREDEF_SUBMODULE_IDS);
-  assert(I != M.SubmoduleRemap.end() 
+  assert(I != M.SubmoduleRemap.end()
          && "Invalid index into submodule index remap");
-  
+
   return LocalID + I->second;
 }
 
@@ -7750,12 +7990,12 @@
     assert(GlobalID == 0 && "Unhandled global submodule ID");
     return nullptr;
   }
-  
+
   if (GlobalID > SubmodulesLoaded.size()) {
     Error("submodule ID out of range in AST file");
     return nullptr;
   }
-  
+
   return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS];
 }
 
@@ -7800,7 +8040,8 @@
 
   // If there is only a single PCH, return it instead.
   // Chained PCH are not suported.
-  if (ModuleMgr.size() == 1) {
+  const auto &PCHChain = ModuleMgr.pch_modules();
+  if (std::distance(std::begin(PCHChain), std::end(PCHChain))) {
     ModuleFile &MF = ModuleMgr.getPrimaryModule();
     StringRef ModuleName = llvm::sys::path::filename(MF.OriginalSourceFileName);
     StringRef FileName = llvm::sys::path::filename(MF.FileName);
@@ -7810,6 +8051,18 @@
   return None;
 }
 
+ExternalASTSource::ExtKind ASTReader::hasExternalDefinitions(unsigned ID) {
+  const Module *M = getSubmodule(ID);
+  if (!M || !M->WithCodegen)
+    return EK_ReplyHazy;
+
+  ModuleFile *MF = ModuleMgr.lookup(M->getASTFile());
+  assert(MF); // ?
+  if (MF->Kind == ModuleKind::MK_MainFile)
+    return EK_Never;
+  return EK_Always;
+}
+
 Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) {
   return DecodeSelector(getGlobalSelectorID(M, LocalID));
 }
@@ -7852,17 +8105,20 @@
 ASTReader::getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const {
   if (LocalID < NUM_PREDEF_SELECTOR_IDS)
     return LocalID;
-  
+
+  if (!M.ModuleOffsetMap.empty())
+    ReadModuleOffsetMap(M);
+
   ContinuousRangeMap<uint32_t, int, 2>::iterator I
     = M.SelectorRemap.find(LocalID - NUM_PREDEF_SELECTOR_IDS);
-  assert(I != M.SelectorRemap.end() 
+  assert(I != M.SelectorRemap.end()
          && "Invalid index into selector index remap");
-  
+
   return LocalID + I->second;
 }
 
 DeclarationName
-ASTReader::ReadDeclarationName(ModuleFile &F, 
+ASTReader::ReadDeclarationName(ModuleFile &F,
                                const RecordData &Record, unsigned &Idx) {
   DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
   switch (Kind) {
@@ -7882,6 +8138,10 @@
     return Context.DeclarationNames.getCXXDestructorName(
                           Context.getCanonicalType(readType(F, Record, Idx)));
 
+  case DeclarationName::CXXDeductionGuideName:
+    return Context.DeclarationNames.getCXXDeductionGuideName(
+                          ReadDeclAs<TemplateDecl>(F, Record, Idx));
+
   case DeclarationName::CXXConversionFunctionName:
     return Context.DeclarationNames.getCXXConversionFunctionName(
                           Context.getCanonicalType(readType(F, Record, Idx)));
@@ -7929,6 +8189,7 @@
   case DeclarationName::ObjCOneArgSelector:
   case DeclarationName::ObjCMultiArgSelector:
   case DeclarationName::CXXUsingDirective:
+  case DeclarationName::CXXDeductionGuideName:
     break;
   }
 }
@@ -7956,7 +8217,7 @@
 }
 
 TemplateName
-ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record, 
+ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record,
                             unsigned &Idx) {
   TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];
   switch (Kind) {
@@ -7983,7 +8244,7 @@
     NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);
     if (Record[Idx++])  // isIdentifier
       return Context.getDependentTemplateName(NNS,
-                                               GetIdentifierInfo(F, Record, 
+                                               GetIdentifierInfo(F, Record,
                                                                  Idx));
     return Context.getDependentTemplateName(NNS,
                                          (OverloadedOperatorKind)Record[Idx++]);
@@ -7996,17 +8257,17 @@
     TemplateName replacement = ReadTemplateName(F, Record, Idx);
     return Context.getSubstTemplateTemplateParm(param, replacement);
   }
-      
+
   case TemplateName::SubstTemplateTemplateParmPack: {
-    TemplateTemplateParmDecl *Param 
+    TemplateTemplateParmDecl *Param
       = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);
     if (!Param)
       return TemplateName();
-    
+
     TemplateArgument ArgPack = ReadTemplateArgument(F, Record, Idx);
     if (ArgPack.getKind() != TemplateArgument::Pack)
       return TemplateName();
-    
+
     return Context.getSubstTemplateTemplateParmPack(Param, ArgPack);
   }
   }
@@ -8044,7 +8305,7 @@
     QualType T = readType(F, Record, Idx);
     return TemplateArgument(Context, Value, T);
   }
-  case TemplateArgument::Template: 
+  case TemplateArgument::Template:
     return TemplateArgument(ReadTemplateName(F, Record, Idx));
   case TemplateArgument::TemplateExpansion: {
     TemplateName Name = ReadTemplateName(F, Record, Idx);
@@ -8120,7 +8381,7 @@
   TypeSourceInfo *TInfo = GetTypeSourceInfo(F, Record, Idx);
   SourceRange Range = ReadSourceRange(F, Record, Idx);
   SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Idx);
-  CXXBaseSpecifier Result(Range, isVirtual, isBaseOfClass, AS, TInfo, 
+  CXXBaseSpecifier Result(Range, isVirtual, isBaseOfClass, AS, TInfo,
                           EllipsisLoc);
   Result.setInheritConstructors(inheritConstructors);
   return Result;
@@ -8162,49 +8423,29 @@
     Expr *Init = ReadExpr(F);
     SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx);
     SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx);
-    bool IsWritten = Record[Idx++];
-    unsigned SourceOrderOrNumArrayIndices;
-    SmallVector<VarDecl *, 8> Indices;
-    if (IsWritten) {
-      SourceOrderOrNumArrayIndices = Record[Idx++];
-    } else {
-      SourceOrderOrNumArrayIndices = Record[Idx++];
-      Indices.reserve(SourceOrderOrNumArrayIndices);
-      for (unsigned i = 0; i != SourceOrderOrNumArrayIndices; ++i)
-        Indices.push_back(ReadDeclAs<VarDecl>(F, Record, Idx));
-    }
 
     CXXCtorInitializer *BOMInit;
-    if (Type == CTOR_INITIALIZER_BASE) {
+    if (Type == CTOR_INITIALIZER_BASE)
       BOMInit = new (Context)
           CXXCtorInitializer(Context, TInfo, IsBaseVirtual, LParenLoc, Init,
                              RParenLoc, MemberOrEllipsisLoc);
-    } else if (Type == CTOR_INITIALIZER_DELEGATING) {
+    else if (Type == CTOR_INITIALIZER_DELEGATING)
       BOMInit = new (Context)
           CXXCtorInitializer(Context, TInfo, LParenLoc, Init, RParenLoc);
-    } else if (IsWritten) {
-      if (Member)
-        BOMInit = new (Context) CXXCtorInitializer(
-            Context, Member, MemberOrEllipsisLoc, LParenLoc, Init, RParenLoc);
-      else
-        BOMInit = new (Context)
-            CXXCtorInitializer(Context, IndirectMember, MemberOrEllipsisLoc,
-                               LParenLoc, Init, RParenLoc);
-    } else {
-      if (IndirectMember) {
-        assert(Indices.empty() && "Indirect field improperly initialized");
-        BOMInit = new (Context)
-            CXXCtorInitializer(Context, IndirectMember, MemberOrEllipsisLoc,
-                               LParenLoc, Init, RParenLoc);
-      } else {
-        BOMInit = CXXCtorInitializer::Create(
-            Context, Member, MemberOrEllipsisLoc, LParenLoc, Init, RParenLoc,
-            Indices.data(), Indices.size());
-      }
+    else if (Member)
+      BOMInit = new (Context)
+          CXXCtorInitializer(Context, Member, MemberOrEllipsisLoc, LParenLoc,
+                             Init, RParenLoc);
+    else
+      BOMInit = new (Context)
+          CXXCtorInitializer(Context, IndirectMember, MemberOrEllipsisLoc,
+                             LParenLoc, Init, RParenLoc);
+
+    if (/*IsWritten*/Record[Idx++]) {
+      unsigned SourceOrder = Record[Idx++];
+      BOMInit->setSourceOrder(SourceOrder);
     }
 
-    if (IsWritten)
-      BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices);
     CtorInitializers[i] = BOMInit;
   }
 
@@ -8267,7 +8508,7 @@
 }
 
 NestedNameSpecifierLoc
-ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record, 
+ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record,
                                       unsigned &Idx) {
   unsigned N = Record[Idx++];
   NestedNameSpecifierLocBuilder Builder;
@@ -8276,7 +8517,7 @@
       = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
     switch (Kind) {
     case NestedNameSpecifier::Identifier: {
-      IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);      
+      IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);
       SourceRange Range = ReadSourceRange(F, Record, Idx);
       Builder.Extend(Context, II, Range.getBegin(), Range.getEnd());
       break;
@@ -8305,7 +8546,7 @@
       SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
 
       // FIXME: 'template' keyword location not saved anywhere, so we fake it.
-      Builder.Extend(Context, 
+      Builder.Extend(Context,
                      Template? T->getTypeLoc().getBeginLoc() : SourceLocation(),
                      T->getTypeLoc(), ColonColonLoc);
       break;
@@ -8374,7 +8615,7 @@
   return Filename;
 }
 
-VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, 
+VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record,
                                          unsigned &Idx) {
   unsigned Major = Record[Idx++];
   unsigned Minor = Record[Idx++];
@@ -8386,18 +8627,18 @@
   return VersionTuple(Major, Minor - 1, Subminor - 1);
 }
 
-CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F, 
+CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F,
                                           const RecordData &Record,
                                           unsigned &Idx) {
   CXXDestructorDecl *Decl = ReadDeclAs<CXXDestructorDecl>(F, Record, Idx);
   return CXXTemporary::Create(Context, Decl);
 }
 
-DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
+DiagnosticBuilder ASTReader::Diag(unsigned DiagID) const {
   return Diag(CurrentImportLoc, DiagID);
 }
 
-DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
+DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) const {
   return Diags.Report(Loc, DiagID);
 }
 
@@ -8472,10 +8713,29 @@
       }
     }
   NextCursor:
+    // De-serialized SourceLocations get negative FileIDs for other modules,
+    // potentially invalidating the original order. Sort it again.
+    std::sort(Comments.begin(), Comments.end(),
+              BeforeThanCompare<RawComment>(SourceMgr));
     Context.Comments.addDeserializedComments(Comments);
   }
 }
 
+void ASTReader::visitInputFiles(serialization::ModuleFile &MF,
+                                bool IncludeSystem, bool Complain,
+                    llvm::function_ref<void(const serialization::InputFile &IF,
+                                            bool isSystem)> Visitor) {
+  unsigned NumUserInputs = MF.NumUserInputFiles;
+  unsigned NumInputs = MF.InputFilesLoaded.size();
+  assert(NumUserInputs <= NumInputs);
+  unsigned N = IncludeSystem ? NumInputs : NumUserInputs;
+  for (unsigned I = 0; I < N; ++I) {
+    bool IsSystem = I >= NumUserInputs;
+    InputFile IF = getInputFile(MF, I+1, Complain);
+    Visitor(IF, IsSystem);
+  }
+}
+
 std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
   // If we know the owning module, use it.
   if (Module *M = D->getImportedOwningModule())
@@ -8577,7 +8837,7 @@
 
   // If we deserialized any C++ or Objective-C class definitions, any
   // Objective-C protocol definitions, or any redeclarable templates, make sure
-  // that all redeclarations point to the definitions. Note that this can only 
+  // that all redeclarations point to the definitions. Note that this can only
   // happen now, after the redeclaration chains have been fully wired.
   for (Decl *D : PendingDefinitions) {
     if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
@@ -8732,7 +8992,7 @@
       // completed. We only really need to mark FieldDecls as invalid here.
       if (!isa<TagDecl>(D))
         D->setInvalidDecl();
-      
+
       // Ensure we don't accidentally recursively enter deserialization while
       // we're producing our diagnostic.
       Deserializing RecursionGuard(this);
@@ -8772,24 +9032,504 @@
       continue;
 
     bool Diagnosed = false;
-    for (auto *RD : Merge.second) {
+    CXXRecordDecl *FirstRecord = Merge.first;
+    std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
+    for (CXXRecordDecl *SecondRecord : Merge.second) {
       // Multiple different declarations got merged together; tell the user
       // where they came from.
-      if (Merge.first != RD) {
-        // FIXME: Walk the definition, figure out what's different,
-        // and diagnose that.
-        if (!Diagnosed) {
-          std::string Module = getOwningModuleNameForDiagnostic(Merge.first);
-          Diag(Merge.first->getLocation(),
-               diag::err_module_odr_violation_different_definitions)
-            << Merge.first << Module.empty() << Module;
-          Diagnosed = true;
+      if (FirstRecord == SecondRecord)
+        continue;
+
+      std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
+      using DeclHashes = llvm::SmallVector<std::pair<Decl *, unsigned>, 4>;
+      DeclHashes FirstHashes;
+      DeclHashes SecondHashes;
+      ODRHash Hash;
+
+      auto PopulateHashes = [&Hash, FirstRecord](DeclHashes &Hashes,
+                                                 CXXRecordDecl *Record) {
+        for (auto *D : Record->decls()) {
+          // Due to decl merging, the first CXXRecordDecl is the parent of
+          // Decls in both records.
+          if (!ODRHash::isWhitelistedDecl(D, FirstRecord))
+            continue;
+          Hash.clear();
+          Hash.AddSubDecl(D);
+          Hashes.emplace_back(D, Hash.CalculateHash());
+        }
+      };
+      PopulateHashes(FirstHashes, FirstRecord);
+      PopulateHashes(SecondHashes, SecondRecord);
+
+      // Used with err_module_odr_violation_mismatch_decl and
+      // note_module_odr_violation_mismatch_decl
+      enum {
+        EndOfClass,
+        PublicSpecifer,
+        PrivateSpecifer,
+        ProtectedSpecifer,
+        StaticAssert,
+        Field,
+        CXXMethod,
+        Other
+      } FirstDiffType = Other,
+        SecondDiffType = Other;
+
+      auto DifferenceSelector = [](Decl *D) {
+        assert(D && "valid Decl required");
+        switch (D->getKind()) {
+        default:
+          return Other;
+        case Decl::AccessSpec:
+          switch (D->getAccess()) {
+          case AS_public:
+            return PublicSpecifer;
+          case AS_private:
+            return PrivateSpecifer;
+          case AS_protected:
+            return ProtectedSpecifer;
+          case AS_none:
+            break;
+          }
+          llvm_unreachable("Invalid access specifier");
+        case Decl::StaticAssert:
+          return StaticAssert;
+        case Decl::Field:
+          return Field;
+        case Decl::CXXMethod:
+          return CXXMethod;
+        }
+      };
+
+      Decl *FirstDecl = nullptr;
+      Decl *SecondDecl = nullptr;
+      auto FirstIt = FirstHashes.begin();
+      auto SecondIt = SecondHashes.begin();
+
+      // If there is a diagnoseable difference, FirstDiffType and
+      // SecondDiffType will not be Other and FirstDecl and SecondDecl will be
+      // filled in if not EndOfClass.
+      while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
+        if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
+            FirstIt->second == SecondIt->second) {
+          ++FirstIt;
+          ++SecondIt;
+          continue;
         }
 
-        Diag(RD->getLocation(),
-             diag::note_module_odr_violation_different_definitions)
-          << getOwningModuleNameForDiagnostic(RD);
+        FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
+        SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
+
+        FirstDiffType = FirstDecl ? DifferenceSelector(FirstDecl) : EndOfClass;
+        SecondDiffType =
+            SecondDecl ? DifferenceSelector(SecondDecl) : EndOfClass;
+
+        break;
       }
+
+      if (FirstDiffType == Other || SecondDiffType == Other) {
+        // Reaching this point means an unexpected Decl was encountered
+        // or no difference was detected.  This causes a generic error
+        // message to be emitted.
+        Diag(FirstRecord->getLocation(),
+             diag::err_module_odr_violation_different_definitions)
+            << FirstRecord << FirstModule.empty() << FirstModule;
+
+        Diag(SecondRecord->getLocation(),
+             diag::note_module_odr_violation_different_definitions)
+            << SecondModule;
+        Diagnosed = true;
+        break;
+      }
+
+      if (FirstDiffType != SecondDiffType) {
+        SourceLocation FirstLoc;
+        SourceRange FirstRange;
+        if (FirstDiffType == EndOfClass) {
+          FirstLoc = FirstRecord->getBraceRange().getEnd();
+        } else {
+          FirstLoc = FirstIt->first->getLocation();
+          FirstRange = FirstIt->first->getSourceRange();
+        }
+        Diag(FirstLoc, diag::err_module_odr_violation_mismatch_decl)
+            << FirstRecord << FirstModule.empty() << FirstModule << FirstRange
+            << FirstDiffType;
+
+        SourceLocation SecondLoc;
+        SourceRange SecondRange;
+        if (SecondDiffType == EndOfClass) {
+          SecondLoc = SecondRecord->getBraceRange().getEnd();
+        } else {
+          SecondLoc = SecondDecl->getLocation();
+          SecondRange = SecondDecl->getSourceRange();
+        }
+        Diag(SecondLoc, diag::note_module_odr_violation_mismatch_decl)
+            << SecondModule << SecondRange << SecondDiffType;
+        Diagnosed = true;
+        break;
+      }
+
+      assert(FirstDiffType == SecondDiffType);
+
+      // Used with err_module_odr_violation_mismatch_decl_diff and
+      // note_module_odr_violation_mismatch_decl_diff
+      enum ODRDeclDifference{
+        StaticAssertCondition,
+        StaticAssertMessage,
+        StaticAssertOnlyMessage,
+        FieldName,
+        FieldTypeName,
+        FieldSingleBitField,
+        FieldDifferentWidthBitField,
+        FieldSingleMutable,
+        FieldSingleInitializer,
+        FieldDifferentInitializers,
+        MethodName,
+        MethodDeleted,
+        MethodVirtual,
+        MethodStatic,
+        MethodVolatile,
+        MethodConst,
+        MethodInline,
+      };
+
+      // These lambdas have the common portions of the ODR diagnostics.  This
+      // has the same return as Diag(), so addition parameters can be passed
+      // in with operator<<
+      auto ODRDiagError = [FirstRecord, &FirstModule, this](
+          SourceLocation Loc, SourceRange Range, ODRDeclDifference DiffType) {
+        return Diag(Loc, diag::err_module_odr_violation_mismatch_decl_diff)
+               << FirstRecord << FirstModule.empty() << FirstModule << Range
+               << DiffType;
+      };
+      auto ODRDiagNote = [&SecondModule, this](
+          SourceLocation Loc, SourceRange Range, ODRDeclDifference DiffType) {
+        return Diag(Loc, diag::note_module_odr_violation_mismatch_decl_diff)
+               << SecondModule << Range << DiffType;
+      };
+
+      auto ComputeODRHash = [&Hash](const Stmt* S) {
+        assert(S);
+        Hash.clear();
+        Hash.AddStmt(S);
+        return Hash.CalculateHash();
+      };
+
+      auto ComputeDeclNameODRHash = [&Hash](const DeclarationName Name) {
+        Hash.clear();
+        Hash.AddDeclarationName(Name);
+        return Hash.CalculateHash();
+      };
+
+      switch (FirstDiffType) {
+      case Other:
+      case EndOfClass:
+      case PublicSpecifer:
+      case PrivateSpecifer:
+      case ProtectedSpecifer:
+        llvm_unreachable("Invalid diff type");
+
+      case StaticAssert: {
+        StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl);
+        StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl);
+
+        Expr *FirstExpr = FirstSA->getAssertExpr();
+        Expr *SecondExpr = SecondSA->getAssertExpr();
+        unsigned FirstODRHash = ComputeODRHash(FirstExpr);
+        unsigned SecondODRHash = ComputeODRHash(SecondExpr);
+        if (FirstODRHash != SecondODRHash) {
+          ODRDiagError(FirstExpr->getLocStart(), FirstExpr->getSourceRange(),
+                       StaticAssertCondition);
+          ODRDiagNote(SecondExpr->getLocStart(),
+                      SecondExpr->getSourceRange(), StaticAssertCondition);
+          Diagnosed = true;
+          break;
+        }
+
+        StringLiteral *FirstStr = FirstSA->getMessage();
+        StringLiteral *SecondStr = SecondSA->getMessage();
+        assert((FirstStr || SecondStr) && "Both messages cannot be empty");
+        if ((FirstStr && !SecondStr) || (!FirstStr && SecondStr)) {
+          SourceLocation FirstLoc, SecondLoc;
+          SourceRange FirstRange, SecondRange;
+          if (FirstStr) {
+            FirstLoc = FirstStr->getLocStart();
+            FirstRange = FirstStr->getSourceRange();
+          } else {
+            FirstLoc = FirstSA->getLocStart();
+            FirstRange = FirstSA->getSourceRange();
+          }
+          if (SecondStr) {
+            SecondLoc = SecondStr->getLocStart();
+            SecondRange = SecondStr->getSourceRange();
+          } else {
+            SecondLoc = SecondSA->getLocStart();
+            SecondRange = SecondSA->getSourceRange();
+          }
+          ODRDiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
+              << (FirstStr == nullptr);
+          ODRDiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
+              << (SecondStr == nullptr);
+          Diagnosed = true;
+          break;
+        }
+
+        if (FirstStr && SecondStr &&
+            FirstStr->getString() != SecondStr->getString()) {
+          ODRDiagError(FirstStr->getLocStart(), FirstStr->getSourceRange(),
+                       StaticAssertMessage);
+          ODRDiagNote(SecondStr->getLocStart(), SecondStr->getSourceRange(),
+                      StaticAssertMessage);
+          Diagnosed = true;
+          break;
+        }
+        break;
+      }
+      case Field: {
+        FieldDecl *FirstField = cast<FieldDecl>(FirstDecl);
+        FieldDecl *SecondField = cast<FieldDecl>(SecondDecl);
+        IdentifierInfo *FirstII = FirstField->getIdentifier();
+        IdentifierInfo *SecondII = SecondField->getIdentifier();
+        if (FirstII->getName() != SecondII->getName()) {
+          ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
+                       FieldName)
+              << FirstII;
+          ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
+                      FieldName)
+              << SecondII;
+
+          Diagnosed = true;
+          break;
+        }
+
+        assert(
+            Context.hasSameType(FirstField->getType(), SecondField->getType()));
+
+        QualType FirstType = FirstField->getType();
+        QualType SecondType = SecondField->getType();
+        const TypedefType *FirstTypedef = dyn_cast<TypedefType>(FirstType);
+        const TypedefType *SecondTypedef = dyn_cast<TypedefType>(SecondType);
+
+        if ((FirstTypedef && !SecondTypedef) ||
+            (!FirstTypedef && SecondTypedef)) {
+          ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
+                       FieldTypeName)
+              << FirstII << FirstType;
+          ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
+                      FieldTypeName)
+              << SecondII << SecondType;
+
+          Diagnosed = true;
+          break;
+        }
+
+        if (FirstTypedef && SecondTypedef) {
+          unsigned FirstHash = ComputeDeclNameODRHash(
+              FirstTypedef->getDecl()->getDeclName());
+          unsigned SecondHash = ComputeDeclNameODRHash(
+              SecondTypedef->getDecl()->getDeclName());
+          if (FirstHash != SecondHash) {
+            ODRDiagError(FirstField->getLocation(),
+                         FirstField->getSourceRange(), FieldTypeName)
+                << FirstII << FirstType;
+            ODRDiagNote(SecondField->getLocation(),
+                        SecondField->getSourceRange(), FieldTypeName)
+                << SecondII << SecondType;
+
+            Diagnosed = true;
+            break;
+          }
+        }
+
+        const bool IsFirstBitField = FirstField->isBitField();
+        const bool IsSecondBitField = SecondField->isBitField();
+        if (IsFirstBitField != IsSecondBitField) {
+          ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
+                       FieldSingleBitField)
+              << FirstII << IsFirstBitField;
+          ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
+                      FieldSingleBitField)
+              << SecondII << IsSecondBitField;
+          Diagnosed = true;
+          break;
+        }
+
+        if (IsFirstBitField && IsSecondBitField) {
+          ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
+                       FieldDifferentWidthBitField)
+              << FirstII << FirstField->getBitWidth()->getSourceRange();
+          ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
+                      FieldDifferentWidthBitField)
+              << SecondII << SecondField->getBitWidth()->getSourceRange();
+          Diagnosed = true;
+          break;
+        }
+
+        const bool IsFirstMutable = FirstField->isMutable();
+        const bool IsSecondMutable = SecondField->isMutable();
+        if (IsFirstMutable != IsSecondMutable) {
+          ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
+                       FieldSingleMutable)
+              << FirstII << IsFirstMutable;
+          ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
+                      FieldSingleMutable)
+              << SecondII << IsSecondMutable;
+          Diagnosed = true;
+          break;
+        }
+
+        const Expr *FirstInitializer = FirstField->getInClassInitializer();
+        const Expr *SecondInitializer = SecondField->getInClassInitializer();
+        if ((!FirstInitializer && SecondInitializer) ||
+            (FirstInitializer && !SecondInitializer)) {
+          ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
+                       FieldSingleInitializer)
+              << FirstII << (FirstInitializer != nullptr);
+          ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
+                      FieldSingleInitializer)
+              << SecondII << (SecondInitializer != nullptr);
+          Diagnosed = true;
+          break;
+        }
+
+        if (FirstInitializer && SecondInitializer) {
+          unsigned FirstInitHash = ComputeODRHash(FirstInitializer);
+          unsigned SecondInitHash = ComputeODRHash(SecondInitializer);
+          if (FirstInitHash != SecondInitHash) {
+            ODRDiagError(FirstField->getLocation(),
+                         FirstField->getSourceRange(),
+                         FieldDifferentInitializers)
+                << FirstII << FirstInitializer->getSourceRange();
+            ODRDiagNote(SecondField->getLocation(),
+                        SecondField->getSourceRange(),
+                        FieldDifferentInitializers)
+                << SecondII << SecondInitializer->getSourceRange();
+            Diagnosed = true;
+            break;
+          }
+        }
+
+        break;
+      }
+      case CXXMethod: {
+        const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
+        const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
+        auto FirstName = FirstMethod->getDeclName();
+        auto SecondName = SecondMethod->getDeclName();
+        if (FirstName != SecondName) {
+          ODRDiagError(FirstMethod->getLocation(),
+                       FirstMethod->getSourceRange(), MethodName)
+              << FirstName;
+          ODRDiagNote(SecondMethod->getLocation(),
+                      SecondMethod->getSourceRange(), MethodName)
+              << SecondName;
+
+          Diagnosed = true;
+          break;
+        }
+
+        const bool FirstDeleted = FirstMethod->isDeleted();
+        const bool SecondDeleted = SecondMethod->isDeleted();
+        if (FirstDeleted != SecondDeleted) {
+          ODRDiagError(FirstMethod->getLocation(),
+                       FirstMethod->getSourceRange(), MethodDeleted)
+              << FirstName << FirstDeleted;
+
+          ODRDiagNote(SecondMethod->getLocation(),
+                      SecondMethod->getSourceRange(), MethodDeleted)
+              << SecondName << SecondDeleted;
+          Diagnosed = true;
+          break;
+        }
+
+        const bool FirstVirtual = FirstMethod->isVirtualAsWritten();
+        const bool SecondVirtual = SecondMethod->isVirtualAsWritten();
+        const bool FirstPure = FirstMethod->isPure();
+        const bool SecondPure = SecondMethod->isPure();
+        if ((FirstVirtual || SecondVirtual) &&
+            (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
+          ODRDiagError(FirstMethod->getLocation(),
+                       FirstMethod->getSourceRange(), MethodVirtual)
+              << FirstName << FirstPure << FirstVirtual;
+          ODRDiagNote(SecondMethod->getLocation(),
+                      SecondMethod->getSourceRange(), MethodVirtual)
+              << SecondName << SecondPure << SecondVirtual;
+          Diagnosed = true;
+          break;
+        }
+
+        // CXXMethodDecl::isStatic uses the canonical Decl.  With Decl merging,
+        // FirstDecl is the canonical Decl of SecondDecl, so the storage
+        // class needs to be checked instead.
+        const auto FirstStorage = FirstMethod->getStorageClass();
+        const auto SecondStorage = SecondMethod->getStorageClass();
+        const bool FirstStatic = FirstStorage == SC_Static;
+        const bool SecondStatic = SecondStorage == SC_Static;
+        if (FirstStatic != SecondStatic) {
+          ODRDiagError(FirstMethod->getLocation(),
+                       FirstMethod->getSourceRange(), MethodStatic)
+              << FirstName << FirstStatic;
+          ODRDiagNote(SecondMethod->getLocation(),
+                      SecondMethod->getSourceRange(), MethodStatic)
+              << SecondName << SecondStatic;
+          Diagnosed = true;
+          break;
+        }
+
+        const bool FirstVolatile = FirstMethod->isVolatile();
+        const bool SecondVolatile = SecondMethod->isVolatile();
+        if (FirstVolatile != SecondVolatile) {
+          ODRDiagError(FirstMethod->getLocation(),
+                       FirstMethod->getSourceRange(), MethodVolatile)
+              << FirstName << FirstVolatile;
+          ODRDiagNote(SecondMethod->getLocation(),
+                      SecondMethod->getSourceRange(), MethodVolatile)
+              << SecondName << SecondVolatile;
+          Diagnosed = true;
+          break;
+        }
+
+        const bool FirstConst = FirstMethod->isConst();
+        const bool SecondConst = SecondMethod->isConst();
+        if (FirstConst != SecondConst) {
+          ODRDiagError(FirstMethod->getLocation(),
+                       FirstMethod->getSourceRange(), MethodConst)
+              << FirstName << FirstConst;
+          ODRDiagNote(SecondMethod->getLocation(),
+                      SecondMethod->getSourceRange(), MethodConst)
+              << SecondName << SecondConst;
+          Diagnosed = true;
+          break;
+        }
+
+        const bool FirstInline = FirstMethod->isInlineSpecified();
+        const bool SecondInline = SecondMethod->isInlineSpecified();
+        if (FirstInline != SecondInline) {
+          ODRDiagError(FirstMethod->getLocation(),
+                       FirstMethod->getSourceRange(), MethodInline)
+              << FirstName << FirstInline;
+          ODRDiagNote(SecondMethod->getLocation(),
+                      SecondMethod->getSourceRange(), MethodInline)
+              << SecondName << SecondInline;
+          Diagnosed = true;
+          break;
+        }
+
+        break;
+      }
+      }
+
+      if (Diagnosed == true)
+        continue;
+
+      Diag(FirstRecord->getLocation(),
+           diag::err_module_odr_violation_different_definitions)
+          << FirstRecord << FirstModule.empty() << FirstModule;
+
+      Diag(SecondRecord->getLocation(),
+           diag::note_module_odr_violation_different_definitions)
+          << SecondModule;
+      Diagnosed = true;
     }
 
     if (!Diagnosed) {
@@ -8807,7 +9547,7 @@
 }
 
 void ASTReader::StartedDeserializing() {
-  if (++NumCurrentElementsDeserializing == 1 && ReadTimer.get()) 
+  if (++NumCurrentElementsDeserializing == 1 && ReadTimer.get())
     ReadTimer->startTimer();
 }
 
@@ -8875,44 +9615,26 @@
   }
 }
 
-ASTReader::ASTReader(
-  Preprocessor &PP, ASTContext &Context,
-  const PCHContainerReader &PCHContainerRdr,
-  ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
-  StringRef isysroot, bool DisableValidation,
-  bool AllowASTWithCompilerErrors,
-  bool AllowConfigurationMismatch, bool ValidateSystemInputs,
-  bool UseGlobalIndex,
-  std::unique_ptr<llvm::Timer> ReadTimer)
-    : Listener(DisableValidation ?
-        cast<ASTReaderListener>(new SimpleASTReaderListener(PP)) :
-        cast<ASTReaderListener>(new PCHValidator(PP, *this))),
-      DeserializationListener(nullptr),
-      OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()),
-      FileMgr(PP.getFileManager()), PCHContainerRdr(PCHContainerRdr),
-      Diags(PP.getDiagnostics()), SemaObj(nullptr), PP(PP), Context(Context),
-      Consumer(nullptr), ModuleMgr(PP.getFileManager(), PCHContainerRdr),
-      DummyIdResolver(PP),
-      ReadTimer(std::move(ReadTimer)),
-      PragmaMSStructState(-1),
-      PragmaMSPointersToMembersState(-1),
-      isysroot(isysroot), DisableValidation(DisableValidation),
+ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
+                     const PCHContainerReader &PCHContainerRdr,
+                     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
+                     StringRef isysroot, bool DisableValidation,
+                     bool AllowASTWithCompilerErrors,
+                     bool AllowConfigurationMismatch, bool ValidateSystemInputs,
+                     bool UseGlobalIndex,
+                     std::unique_ptr<llvm::Timer> ReadTimer)
+    : Listener(DisableValidation
+                   ? cast<ASTReaderListener>(new SimpleASTReaderListener(PP))
+                   : cast<ASTReaderListener>(new PCHValidator(PP, *this))),
+      SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
+      PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),
+      Context(Context), ModuleMgr(PP.getFileManager(), PCHContainerRdr),
+      DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
+      DisableValidation(DisableValidation),
       AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
       AllowConfigurationMismatch(AllowConfigurationMismatch),
       ValidateSystemInputs(ValidateSystemInputs),
-      UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false),
-      ProcessingUpdateRecords(false),
-      CurrSwitchCaseStmts(&SwitchCaseStmts), NumSLocEntriesRead(0),
-      TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
-      NumMacrosRead(0), TotalNumMacros(0), NumIdentifierLookups(0),
-      NumIdentifierLookupHits(0), NumSelectorsRead(0),
-      NumMethodPoolEntriesRead(0), NumMethodPoolLookups(0),
-      NumMethodPoolHits(0), NumMethodPoolTableLookups(0),
-      NumMethodPoolTableHits(0), TotalNumMethodPoolEntries(0),
-      NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
-      NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
-      TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0),
-      PassingDeclsToConsumer(false), ReadingKind(Read_None) {
+      UseGlobalIndex(UseGlobalIndex), CurrSwitchCaseStmts(&SwitchCaseStmts) {
   SourceMgr.setExternalSLocEntrySource(this);
 
   for (const auto &Ext : Extensions) {
@@ -8936,3 +9658,10 @@
 IdentifierResolver &ASTReader::getIdResolver() {
   return SemaObj ? SemaObj->IdResolver : DummyIdResolver;
 }
+
+unsigned ASTRecordReader::readRecord(llvm::BitstreamCursor &Cursor,
+                                     unsigned AbbrevID) {
+  Idx = 0;
+  Record.clear();
+  return Cursor.readRecord(AbbrevID, Record);
+}
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 07df754..d33a475 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -35,13 +35,11 @@
 namespace clang {
   class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> {
     ASTReader &Reader;
-    ModuleFile &F;
-    uint64_t Offset;
+    ASTRecordReader &Record;
+    ASTReader::RecordLocation Loc;
     const DeclID ThisDeclID;
     const SourceLocation ThisDeclLoc;
     typedef ASTReader::RecordData RecordData;
-    const RecordData &Record;
-    unsigned &Idx;
     TypeID TypeIDForTypeDecl;
     unsigned AnonymousDeclNumber;
     GlobalDeclID NamedDeclForTagDecl;
@@ -56,85 +54,75 @@
 
     uint64_t GetCurrentCursorOffset();
 
-    uint64_t ReadLocalOffset(const RecordData &R, unsigned &I) {
-      uint64_t LocalOffset = R[I++];
-      assert(LocalOffset < Offset && "offset point after current record");
-      return LocalOffset ? Offset - LocalOffset : 0;
+    uint64_t ReadLocalOffset() {
+      uint64_t LocalOffset = Record.readInt();
+      assert(LocalOffset < Loc.Offset && "offset point after current record");
+      return LocalOffset ? Loc.Offset - LocalOffset : 0;
     }
 
-    uint64_t ReadGlobalOffset(ModuleFile &F, const RecordData &R, unsigned &I) {
-      uint64_t Local = ReadLocalOffset(R, I);
-      return Local ? Reader.getGlobalBitOffset(F, Local) : 0;
+    uint64_t ReadGlobalOffset() {
+      uint64_t Local = ReadLocalOffset();
+      return Local ? Record.getGlobalBitOffset(Local) : 0;
     }
 
-    SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) {
-      return Reader.ReadSourceLocation(F, R, I);
+    SourceLocation ReadSourceLocation() {
+      return Record.readSourceLocation();
     }
 
-    SourceRange ReadSourceRange(const RecordData &R, unsigned &I) {
-      return Reader.ReadSourceRange(F, R, I);
+    SourceRange ReadSourceRange() {
+      return Record.readSourceRange();
     }
 
-    TypeSourceInfo *GetTypeSourceInfo(const RecordData &R, unsigned &I) {
-      return Reader.GetTypeSourceInfo(F, R, I);
+    TypeSourceInfo *GetTypeSourceInfo() {
+      return Record.getTypeSourceInfo();
     }
 
-    serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {
-      return Reader.ReadDeclID(F, R, I);
+    serialization::DeclID ReadDeclID() {
+      return Record.readDeclID();
     }
 
-    std::string ReadString(const RecordData &R, unsigned &I) {
-      return Reader.ReadString(R, I);
+    std::string ReadString() {
+      return Record.readString();
     }
 
     void ReadDeclIDList(SmallVectorImpl<DeclID> &IDs) {
-      for (unsigned I = 0, Size = Record[Idx++]; I != Size; ++I)
-        IDs.push_back(ReadDeclID(Record, Idx));
+      for (unsigned I = 0, Size = Record.readInt(); I != Size; ++I)
+        IDs.push_back(ReadDeclID());
     }
 
-    Decl *ReadDecl(const RecordData &R, unsigned &I) {
-      return Reader.ReadDecl(F, R, I);
+    Decl *ReadDecl() {
+      return Record.readDecl();
     }
 
     template<typename T>
-    T *ReadDeclAs(const RecordData &R, unsigned &I) {
-      return Reader.ReadDeclAs<T>(F, R, I);
+    T *ReadDeclAs() {
+      return Record.readDeclAs<T>();
     }
 
-    void ReadQualifierInfo(QualifierInfo &Info,
-                           const RecordData &R, unsigned &I) {
-      Reader.ReadQualifierInfo(F, Info, R, I);
-    }
-    
-    void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name,
-                                const RecordData &R, unsigned &I) {
-      Reader.ReadDeclarationNameLoc(F, DNLoc, Name, R, I);
-    }
-    
-    void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo,
-                                const RecordData &R, unsigned &I) {
-      Reader.ReadDeclarationNameInfo(F, NameInfo, R, I);
+    void ReadQualifierInfo(QualifierInfo &Info) {
+      Record.readQualifierInfo(Info);
     }
 
-    serialization::SubmoduleID readSubmoduleID(const RecordData &R, 
-                                               unsigned &I) {
-      if (I >= R.size())
+    void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name) {
+      Record.readDeclarationNameLoc(DNLoc, Name);
+    }
+
+    serialization::SubmoduleID readSubmoduleID() {
+      if (Record.getIdx() == Record.size())
         return 0;
-      
-      return Reader.getGlobalSubmoduleID(F, R[I++]);
+
+      return Record.getGlobalSubmoduleID(Record.readInt());
     }
-    
-    Module *readModule(const RecordData &R, unsigned &I) {
-      return Reader.getSubmodule(readSubmoduleID(R, I));
+
+    Module *readModule() {
+      return Record.getSubmodule(readSubmoduleID());
     }
 
     void ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update);
-    void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data,
-                               const RecordData &R, unsigned &I);
+    void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data);
     void MergeDefinitionData(CXXRecordDecl *D,
                              struct CXXRecordDecl::DefinitionData &&NewDD);
-    void ReadObjCDefinitionData(struct ObjCInterfaceDecl::DefinitionData &Data,
-                                const RecordData &R, unsigned &I);
+    void ReadObjCDefinitionData(struct ObjCInterfaceDecl::DefinitionData &Data);
     void MergeDefinitionData(ObjCInterfaceDecl *D,
                              struct ObjCInterfaceDecl::DefinitionData &&NewDD);
 
@@ -218,11 +206,11 @@
     FindExistingResult findExisting(NamedDecl *D);
 
   public:
-    ASTDeclReader(ASTReader &Reader, ASTReader::RecordLocation Loc,
-                  DeclID thisDeclID, SourceLocation ThisDeclLoc,
-                  const RecordData &Record, unsigned &Idx)
-        : Reader(Reader), F(*Loc.F), Offset(Loc.Offset), ThisDeclID(thisDeclID),
-          ThisDeclLoc(ThisDeclLoc), Record(Record), Idx(Idx),
+    ASTDeclReader(ASTReader &Reader, ASTRecordReader &Record,
+                  ASTReader::RecordLocation Loc,
+                  DeclID thisDeclID, SourceLocation ThisDeclLoc)
+        : Reader(Reader), Record(Record), Loc(Loc),
+          ThisDeclID(thisDeclID), ThisDeclLoc(ThisDeclLoc),
           TypeIDForTypeDecl(0), NamedDeclForTagDecl(0),
           TypedefNameForLinkage(nullptr), HasPendingBody(false),
           IsDeclMarkedUsed(false) {}
@@ -252,10 +240,10 @@
     /// \brief Determine whether this declaration has a pending body.
     bool hasPendingBody() const { return HasPendingBody; }
 
+    void ReadFunctionDefinition(FunctionDecl *FD);
     void Visit(Decl *D);
 
-    void UpdateDecl(Decl *D, ModuleFile &ModuleFile,
-                    const RecordData &Record);
+    void UpdateDecl(Decl *D);
 
     static void setNextObjCCategory(ObjCCategoryDecl *Cat,
                                     ObjCCategoryDecl *Next) {
@@ -305,6 +293,7 @@
     void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
     void VisitDeclaratorDecl(DeclaratorDecl *DD);
     void VisitFunctionDecl(FunctionDecl *FD);
+    void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *GD);
     void VisitCXXMethodDecl(CXXMethodDecl *D);
     void VisitCXXConstructorDecl(CXXConstructorDecl *D);
     void VisitCXXDestructorDecl(CXXDestructorDecl *D);
@@ -328,6 +317,7 @@
     void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
     void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
     void VisitUsingDecl(UsingDecl *D);
+    void VisitUsingPackDecl(UsingPackDecl *D);
     void VisitUsingShadowDecl(UsingShadowDecl *D);
     void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
     void VisitLinkageSpecDecl(LinkageSpecDecl *D);
@@ -430,7 +420,18 @@
 }
 
 uint64_t ASTDeclReader::GetCurrentCursorOffset() {
-  return F.DeclsCursor.GetCurrentBitNo() + F.GlobalBitOffset;
+  return Loc.F->DeclsCursor.GetCurrentBitNo() + Loc.F->GlobalBitOffset;
+}
+
+void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {
+  if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
+    CD->NumCtorInitializers = Record.readInt();
+    if (CD->NumCtorInitializers)
+      CD->CtorInitializers = ReadGlobalOffset();
+  }
+  // Store the offset of the body so we can lazily load it later.
+  Reader.PendingBodies[FD] = GetCurrentCursorOffset();
+  HasPendingBody = true;
 }
 
 void ASTDeclReader::Visit(Decl *D) {
@@ -445,11 +446,10 @@
     if (DD->DeclInfo) {
       DeclaratorDecl::ExtInfo *Info =
           DD->DeclInfo.get<DeclaratorDecl::ExtInfo *>();
-      Info->TInfo =
-          GetTypeSourceInfo(Record, Idx);
+      Info->TInfo = GetTypeSourceInfo();
     }
     else {
-      DD->DeclInfo = GetTypeSourceInfo(Record, Idx);
+      DD->DeclInfo = GetTypeSourceInfo();
     }
   }
 
@@ -470,15 +470,8 @@
     // We only read it if FD doesn't already have a body (e.g., from another
     // module).
     // FIXME: Can we diagnose ODR violations somehow?
-    if (Record[Idx++]) {
-      if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
-        CD->NumCtorInitializers = Record[Idx++];
-        if (CD->NumCtorInitializers)
-          CD->CtorInitializers = ReadGlobalOffset(F, Record, Idx);
-      }
-      Reader.PendingBodies[FD] = GetCurrentCursorOffset();
-      HasPendingBody = true;
-    }
+    if (Record.readInt())
+      ReadFunctionDefinition(FD);
   }
 }
 
@@ -491,8 +484,8 @@
     // example, a function parameter can be used in decltype() in trailing
     // return type of the function).  Use the translation unit DeclContext as a
     // placeholder.
-    GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
-    GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+    GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID();
+    GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID();
     if (!LexicalDCIDForTemplateParmDecl)
       LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl;
     Reader.addPendingDeclContextInfo(D,
@@ -500,8 +493,8 @@
                                      LexicalDCIDForTemplateParmDecl);
     D->setDeclContext(Reader.getContext().getTranslationUnitDecl()); 
   } else {
-    DeclContext *SemaDC = ReadDeclAs<DeclContext>(Record, Idx);
-    DeclContext *LexicalDC = ReadDeclAs<DeclContext>(Record, Idx);
+    DeclContext *SemaDC = ReadDeclAs<DeclContext>();
+    DeclContext *LexicalDC = ReadDeclAs<DeclContext>();
     if (!LexicalDC)
       LexicalDC = SemaDC;
     DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC);
@@ -511,27 +504,27 @@
                            Reader.getContext());
   }
   D->setLocation(ThisDeclLoc);
-  D->setInvalidDecl(Record[Idx++]);
-  if (Record[Idx++]) { // hasAttrs
+  D->setInvalidDecl(Record.readInt());
+  if (Record.readInt()) { // hasAttrs
     AttrVec Attrs;
-    Reader.ReadAttributes(F, Attrs, Record, Idx);
+    Record.readAttributes(Attrs);
     // Avoid calling setAttrs() directly because it uses Decl::getASTContext()
     // internally which is unsafe during derialization.
     D->setAttrsImpl(Attrs, Reader.getContext());
   }
-  D->setImplicit(Record[Idx++]);
-  D->Used = Record[Idx++];
+  D->setImplicit(Record.readInt());
+  D->Used = Record.readInt();
   IsDeclMarkedUsed |= D->Used;
-  D->setReferenced(Record[Idx++]);
-  D->setTopLevelDeclInObjCContainer(Record[Idx++]);
-  D->setAccess((AccessSpecifier)Record[Idx++]);
+  D->setReferenced(Record.readInt());
+  D->setTopLevelDeclInObjCContainer(Record.readInt());
+  D->setAccess((AccessSpecifier)Record.readInt());
   D->FromASTFile = true;
-  D->setModulePrivate(Record[Idx++]);
+  D->setModulePrivate(Record.readInt());
   D->Hidden = D->isModulePrivate();
 
   // Determine whether this declaration is part of a (sub)module. If so, it
   // may not yet be visible.
-  if (unsigned SubmoduleID = readSubmoduleID(Record, Idx)) {
+  if (unsigned SubmoduleID = readSubmoduleID()) {
     // Store the owning submodule ID in the declaration.
     D->setOwningModuleID(SubmoduleID);
 
@@ -557,22 +550,22 @@
 
 void ASTDeclReader::VisitPragmaCommentDecl(PragmaCommentDecl *D) {
   VisitDecl(D);
-  D->setLocation(ReadSourceLocation(Record, Idx));
-  D->CommentKind = (PragmaMSCommentKind)Record[Idx++];
-  std::string Arg = ReadString(Record, Idx);
+  D->setLocation(ReadSourceLocation());
+  D->CommentKind = (PragmaMSCommentKind)Record.readInt();
+  std::string Arg = ReadString();
   memcpy(D->getTrailingObjects<char>(), Arg.data(), Arg.size());
   D->getTrailingObjects<char>()[Arg.size()] = '\0';
 }
 
 void ASTDeclReader::VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D) {
   VisitDecl(D);
-  D->setLocation(ReadSourceLocation(Record, Idx));
-  std::string Name = ReadString(Record, Idx);
+  D->setLocation(ReadSourceLocation());
+  std::string Name = ReadString();
   memcpy(D->getTrailingObjects<char>(), Name.data(), Name.size());
   D->getTrailingObjects<char>()[Name.size()] = '\0';
 
   D->ValueStart = Name.size() + 1;
-  std::string Value = ReadString(Record, Idx);
+  std::string Value = ReadString();
   memcpy(D->getTrailingObjects<char>() + D->ValueStart, Value.data(),
          Value.size());
   D->getTrailingObjects<char>()[D->ValueStart + Value.size()] = '\0';
@@ -584,27 +577,32 @@
 
 void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) {
   VisitDecl(ND);
-  ND->setDeclName(Reader.ReadDeclarationName(F, Record, Idx));
-  AnonymousDeclNumber = Record[Idx++];
+  ND->setDeclName(Record.readDeclarationName());
+  AnonymousDeclNumber = Record.readInt();
 }
 
 void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
   VisitNamedDecl(TD);
-  TD->setLocStart(ReadSourceLocation(Record, Idx));
+  TD->setLocStart(ReadSourceLocation());
   // Delay type reading until after we have fully initialized the decl.
-  TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
+  TypeIDForTypeDecl = Record.getGlobalTypeID(Record.readInt());
 }
 
 ASTDeclReader::RedeclarableResult
 ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
   RedeclarableResult Redecl = VisitRedeclarable(TD);
   VisitTypeDecl(TD);
-  TypeSourceInfo *TInfo = GetTypeSourceInfo(Record, Idx);
-  if (Record[Idx++]) { // isModed
-    QualType modedT = Reader.readType(F, Record, Idx);
+  TypeSourceInfo *TInfo = GetTypeSourceInfo();
+  if (Record.readInt()) { // isModed
+    QualType modedT = Record.readType();
     TD->setModedTypeSourceInfo(TInfo, modedT);
   } else
     TD->setTypeSourceInfo(TInfo);
+  // Read and discard the declaration for which this is a typedef name for
+  // linkage, if it exists. We cannot rely on our type to pull in this decl,
+  // because it might have been merged with a type from another module and
+  // thus might not refer to our version of the declaration.
+  ReadDecl();
   return Redecl;
 }
 
@@ -615,7 +613,7 @@
 
 void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) {
   RedeclarableResult Redecl = VisitTypedefNameDecl(TD);
-  if (auto *Template = ReadDeclAs<TypeAliasTemplateDecl>(Record, Idx))
+  if (auto *Template = ReadDeclAs<TypeAliasTemplateDecl>())
     // Merged when we merge the template.
     TD->setDescribedAliasTemplate(Template);
   else
@@ -626,27 +624,27 @@
   RedeclarableResult Redecl = VisitRedeclarable(TD);
   VisitTypeDecl(TD);
   
-  TD->IdentifierNamespace = Record[Idx++];
-  TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
+  TD->IdentifierNamespace = Record.readInt();
+  TD->setTagKind((TagDecl::TagKind)Record.readInt());
   if (!isa<CXXRecordDecl>(TD))
-    TD->setCompleteDefinition(Record[Idx++]);
-  TD->setEmbeddedInDeclarator(Record[Idx++]);
-  TD->setFreeStanding(Record[Idx++]);
-  TD->setCompleteDefinitionRequired(Record[Idx++]);
-  TD->setBraceRange(ReadSourceRange(Record, Idx));
+    TD->setCompleteDefinition(Record.readInt());
+  TD->setEmbeddedInDeclarator(Record.readInt());
+  TD->setFreeStanding(Record.readInt());
+  TD->setCompleteDefinitionRequired(Record.readInt());
+  TD->setBraceRange(ReadSourceRange());
   
-  switch (Record[Idx++]) {
+  switch (Record.readInt()) {
   case 0:
     break;
   case 1: { // ExtInfo
     TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo();
-    ReadQualifierInfo(*Info, Record, Idx);
+    ReadQualifierInfo(*Info);
     TD->TypedefNameDeclOrQualifier = Info;
     break;
   }
   case 2: // TypedefNameForAnonDecl
-    NamedDeclForTagDecl = ReadDeclID(Record, Idx);
-    TypedefNameForLinkage = Reader.GetIdentifierInfo(F, Record, Idx);
+    NamedDeclForTagDecl = ReadDeclID();
+    TypedefNameForLinkage = Record.getIdentifierInfo();
     break;
   default:
     llvm_unreachable("unexpected tag info kind");
@@ -659,16 +657,16 @@
 
 void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
   VisitTagDecl(ED);
-  if (TypeSourceInfo *TI = Reader.GetTypeSourceInfo(F, Record, Idx))
+  if (TypeSourceInfo *TI = GetTypeSourceInfo())
     ED->setIntegerTypeSourceInfo(TI);
   else
-    ED->setIntegerType(Reader.readType(F, Record, Idx));
-  ED->setPromotionType(Reader.readType(F, Record, Idx));
-  ED->setNumPositiveBits(Record[Idx++]);
-  ED->setNumNegativeBits(Record[Idx++]);
-  ED->IsScoped = Record[Idx++];
-  ED->IsScopedUsingClassTag = Record[Idx++];
-  ED->IsFixed = Record[Idx++];
+    ED->setIntegerType(Record.readType());
+  ED->setPromotionType(Record.readType());
+  ED->setNumPositiveBits(Record.readInt());
+  ED->setNumNegativeBits(Record.readInt());
+  ED->IsScoped = Record.readInt();
+  ED->IsScopedUsingClassTag = Record.readInt();
+  ED->IsFixed = Record.readInt();
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
@@ -695,9 +693,10 @@
     }
   }
 
-  if (EnumDecl *InstED = ReadDeclAs<EnumDecl>(Record, Idx)) {
-    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
-    SourceLocation POI = ReadSourceLocation(Record, Idx);
+  if (EnumDecl *InstED = ReadDeclAs<EnumDecl>()) {
+    TemplateSpecializationKind TSK =
+        (TemplateSpecializationKind)Record.readInt();
+    SourceLocation POI = ReadSourceLocation();
     ED->setInstantiationOfMemberEnum(Reader.getContext(), InstED, TSK);
     ED->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
   }
@@ -706,33 +705,33 @@
 ASTDeclReader::RedeclarableResult
 ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
   RedeclarableResult Redecl = VisitTagDecl(RD);
-  RD->setHasFlexibleArrayMember(Record[Idx++]);
-  RD->setAnonymousStructOrUnion(Record[Idx++]);
-  RD->setHasObjectMember(Record[Idx++]);
-  RD->setHasVolatileMember(Record[Idx++]);
+  RD->setHasFlexibleArrayMember(Record.readInt());
+  RD->setAnonymousStructOrUnion(Record.readInt());
+  RD->setHasObjectMember(Record.readInt());
+  RD->setHasVolatileMember(Record.readInt());
   return Redecl;
 }
 
 void ASTDeclReader::VisitValueDecl(ValueDecl *VD) {
   VisitNamedDecl(VD);
-  VD->setType(Reader.readType(F, Record, Idx));
+  VD->setType(Record.readType());
 }
 
 void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
   VisitValueDecl(ECD);
-  if (Record[Idx++])
-    ECD->setInitExpr(Reader.ReadExpr(F));
-  ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
+  if (Record.readInt())
+    ECD->setInitExpr(Record.readExpr());
+  ECD->setInitVal(Record.readAPSInt());
   mergeMergeable(ECD);
 }
 
 void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
   VisitValueDecl(DD);
-  DD->setInnerLocStart(ReadSourceLocation(Record, Idx));
-  if (Record[Idx++]) { // hasExtInfo
+  DD->setInnerLocStart(ReadSourceLocation());
+  if (Record.readInt()) { // hasExtInfo
     DeclaratorDecl::ExtInfo *Info
         = new (Reader.getContext()) DeclaratorDecl::ExtInfo();
-    ReadQualifierInfo(*Info, Record, Idx);
+    ReadQualifierInfo(*Info);
     DD->DeclInfo = Info;
   }
 }
@@ -741,74 +740,74 @@
   RedeclarableResult Redecl = VisitRedeclarable(FD);
   VisitDeclaratorDecl(FD);
 
-  ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName(), Record, Idx);
-  FD->IdentifierNamespace = Record[Idx++];
-  
+  ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName());
+  FD->IdentifierNamespace = Record.readInt();
+
   // FunctionDecl's body is handled last at ASTDeclReader::Visit,
   // after everything else is read.
 
-  FD->SClass = (StorageClass)Record[Idx++];
-  FD->IsInline = Record[Idx++];
-  FD->IsInlineSpecified = Record[Idx++];
-  FD->IsVirtualAsWritten = Record[Idx++];
-  FD->IsPure = Record[Idx++];
-  FD->HasInheritedPrototype = Record[Idx++];
-  FD->HasWrittenPrototype = Record[Idx++];
-  FD->IsDeleted = Record[Idx++];
-  FD->IsTrivial = Record[Idx++];
-  FD->IsDefaulted = Record[Idx++];
-  FD->IsExplicitlyDefaulted = Record[Idx++];
-  FD->HasImplicitReturnZero = Record[Idx++];
-  FD->IsConstexpr = Record[Idx++];
-  FD->HasSkippedBody = Record[Idx++];
-  FD->IsLateTemplateParsed = Record[Idx++];
-  FD->setCachedLinkage(Linkage(Record[Idx++]));
-  FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
+  FD->SClass = (StorageClass)Record.readInt();
+  FD->IsInline = Record.readInt();
+  FD->IsInlineSpecified = Record.readInt();
+  FD->IsExplicitSpecified = Record.readInt();
+  FD->IsVirtualAsWritten = Record.readInt();
+  FD->IsPure = Record.readInt();
+  FD->HasInheritedPrototype = Record.readInt();
+  FD->HasWrittenPrototype = Record.readInt();
+  FD->IsDeleted = Record.readInt();
+  FD->IsTrivial = Record.readInt();
+  FD->IsDefaulted = Record.readInt();
+  FD->IsExplicitlyDefaulted = Record.readInt();
+  FD->HasImplicitReturnZero = Record.readInt();
+  FD->IsConstexpr = Record.readInt();
+  FD->UsesSEHTry = Record.readInt();
+  FD->HasSkippedBody = Record.readInt();
+  FD->IsLateTemplateParsed = Record.readInt();
+  FD->setCachedLinkage(Linkage(Record.readInt()));
+  FD->EndRangeLoc = ReadSourceLocation();
 
-  switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
+  switch ((FunctionDecl::TemplatedKind)Record.readInt()) {
   case FunctionDecl::TK_NonTemplate:
     mergeRedeclarable(FD, Redecl);
     break;
   case FunctionDecl::TK_FunctionTemplate:
     // Merged when we merge the template.
-    FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>(Record, 
-                                                                      Idx));
+    FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>());
     break;
   case FunctionDecl::TK_MemberSpecialization: {
-    FunctionDecl *InstFD = ReadDeclAs<FunctionDecl>(Record, Idx);
-    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
-    SourceLocation POI = ReadSourceLocation(Record, Idx);
+    FunctionDecl *InstFD = ReadDeclAs<FunctionDecl>();
+    TemplateSpecializationKind TSK =
+        (TemplateSpecializationKind)Record.readInt();
+    SourceLocation POI = ReadSourceLocation();
     FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK);
     FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
     mergeRedeclarable(FD, Redecl);
     break;
   }
   case FunctionDecl::TK_FunctionTemplateSpecialization: {
-    FunctionTemplateDecl *Template = ReadDeclAs<FunctionTemplateDecl>(Record, 
-                                                                      Idx);
-    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
-    
+    FunctionTemplateDecl *Template = ReadDeclAs<FunctionTemplateDecl>();
+    TemplateSpecializationKind TSK =
+        (TemplateSpecializationKind)Record.readInt();
+
     // Template arguments.
     SmallVector<TemplateArgument, 8> TemplArgs;
-    Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx,
-                                    /*Canonicalize*/ true);
+    Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
 
     // Template args as written.
     SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
     SourceLocation LAngleLoc, RAngleLoc;
-    bool HasTemplateArgumentsAsWritten = Record[Idx++];
+    bool HasTemplateArgumentsAsWritten = Record.readInt();
     if (HasTemplateArgumentsAsWritten) {
-      unsigned NumTemplateArgLocs = Record[Idx++];
+      unsigned NumTemplateArgLocs = Record.readInt();
       TemplArgLocs.reserve(NumTemplateArgLocs);
       for (unsigned i=0; i != NumTemplateArgLocs; ++i)
-        TemplArgLocs.push_back(
-            Reader.ReadTemplateArgumentLoc(F, Record, Idx));
-  
-      LAngleLoc = ReadSourceLocation(Record, Idx);
-      RAngleLoc = ReadSourceLocation(Record, Idx);
+        TemplArgLocs.push_back(Record.readTemplateArgumentLoc());
+
+      LAngleLoc = ReadSourceLocation();
+      RAngleLoc = ReadSourceLocation();
     }
-    
-    SourceLocation POI = ReadSourceLocation(Record, Idx);
+
+    SourceLocation POI = ReadSourceLocation();
 
     ASTContext &C = Reader.getContext();
     TemplateArgumentList *TemplArgList
@@ -827,8 +826,7 @@
     if (FD->isCanonicalDecl()) { // if canonical add to template's set.
       // The template that contains the specializations set. It's not safe to
       // use getCanonicalDecl on Template since it may still be initializing.
-      FunctionTemplateDecl *CanonTemplate
-        = ReadDeclAs<FunctionTemplateDecl>(Record, Idx);
+      FunctionTemplateDecl *CanonTemplate = ReadDeclAs<FunctionTemplateDecl>();
       // Get the InsertPos by FindNodeOrInsertPos() instead of calling
       // InsertNode(FTInfo) directly to avoid the getASTContext() call in
       // FunctionTemplateSpecializationInfo's Profile().
@@ -853,18 +851,18 @@
   case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
     // Templates.
     UnresolvedSet<8> TemplDecls;
-    unsigned NumTemplates = Record[Idx++];
+    unsigned NumTemplates = Record.readInt();
     while (NumTemplates--)
-      TemplDecls.addDecl(ReadDeclAs<NamedDecl>(Record, Idx));
-    
+      TemplDecls.addDecl(ReadDeclAs<NamedDecl>());
+
     // Templates args.
     TemplateArgumentListInfo TemplArgs;
-    unsigned NumArgs = Record[Idx++];
+    unsigned NumArgs = Record.readInt();
     while (NumArgs--)
-      TemplArgs.addArgument(Reader.ReadTemplateArgumentLoc(F, Record, Idx));
-    TemplArgs.setLAngleLoc(ReadSourceLocation(Record, Idx));
-    TemplArgs.setRAngleLoc(ReadSourceLocation(Record, Idx));
-    
+      TemplArgs.addArgument(Record.readTemplateArgumentLoc());
+    TemplArgs.setLAngleLoc(ReadSourceLocation());
+    TemplArgs.setRAngleLoc(ReadSourceLocation());
+
     FD->setDependentTemplateSpecialization(Reader.getContext(),
                                            TemplDecls, TemplArgs);
     // These are not merged; we don't need to merge redeclarations of dependent
@@ -874,55 +872,55 @@
   }
 
   // Read in the parameters.
-  unsigned NumParams = Record[Idx++];
+  unsigned NumParams = Record.readInt();
   SmallVector<ParmVarDecl *, 16> Params;
   Params.reserve(NumParams);
   for (unsigned I = 0; I != NumParams; ++I)
-    Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
+    Params.push_back(ReadDeclAs<ParmVarDecl>());
   FD->setParams(Reader.getContext(), Params);
 }
 
 void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
   VisitNamedDecl(MD);
-  if (Record[Idx++]) {
+  if (Record.readInt()) {
     // Load the body on-demand. Most clients won't care, because method
     // definitions rarely show up in headers.
     Reader.PendingBodies[MD] = GetCurrentCursorOffset();
     HasPendingBody = true;
-    MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
-    MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
+    MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>());
+    MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>());
   }
-  MD->setInstanceMethod(Record[Idx++]);
-  MD->setVariadic(Record[Idx++]);
-  MD->setPropertyAccessor(Record[Idx++]);
-  MD->setDefined(Record[Idx++]);
-  MD->IsOverriding = Record[Idx++];
-  MD->HasSkippedBody = Record[Idx++];
+  MD->setInstanceMethod(Record.readInt());
+  MD->setVariadic(Record.readInt());
+  MD->setPropertyAccessor(Record.readInt());
+  MD->setDefined(Record.readInt());
+  MD->IsOverriding = Record.readInt();
+  MD->HasSkippedBody = Record.readInt();
 
-  MD->IsRedeclaration = Record[Idx++];
-  MD->HasRedeclaration = Record[Idx++];
+  MD->IsRedeclaration = Record.readInt();
+  MD->HasRedeclaration = Record.readInt();
   if (MD->HasRedeclaration)
     Reader.getContext().setObjCMethodRedeclaration(MD,
-                                       ReadDeclAs<ObjCMethodDecl>(Record, Idx));
+                                       ReadDeclAs<ObjCMethodDecl>());
 
-  MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
-  MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
-  MD->SetRelatedResultType(Record[Idx++]);
-  MD->setReturnType(Reader.readType(F, Record, Idx));
-  MD->setReturnTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
-  MD->DeclEndLoc = ReadSourceLocation(Record, Idx);
-  unsigned NumParams = Record[Idx++];
+  MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record.readInt());
+  MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record.readInt());
+  MD->SetRelatedResultType(Record.readInt());
+  MD->setReturnType(Record.readType());
+  MD->setReturnTypeSourceInfo(GetTypeSourceInfo());
+  MD->DeclEndLoc = ReadSourceLocation();
+  unsigned NumParams = Record.readInt();
   SmallVector<ParmVarDecl *, 16> Params;
   Params.reserve(NumParams);
   for (unsigned I = 0; I != NumParams; ++I)
-    Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
+    Params.push_back(ReadDeclAs<ParmVarDecl>());
 
-  MD->SelLocsKind = Record[Idx++];
-  unsigned NumStoredSelLocs = Record[Idx++];
+  MD->SelLocsKind = Record.readInt();
+  unsigned NumStoredSelLocs = Record.readInt();
   SmallVector<SourceLocation, 16> SelLocs;
   SelLocs.reserve(NumStoredSelLocs);
   for (unsigned i = 0; i != NumStoredSelLocs; ++i)
-    SelLocs.push_back(ReadSourceLocation(Record, Idx));
+    SelLocs.push_back(ReadSourceLocation());
 
   MD->setParamsAndSelLocs(Reader.getContext(), Params, SelLocs);
 }
@@ -930,68 +928,67 @@
 void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
   VisitTypedefNameDecl(D);
 
-  D->Variance = Record[Idx++];
-  D->Index = Record[Idx++];
-  D->VarianceLoc = ReadSourceLocation(Record, Idx);
-  D->ColonLoc = ReadSourceLocation(Record, Idx);
+  D->Variance = Record.readInt();
+  D->Index = Record.readInt();
+  D->VarianceLoc = ReadSourceLocation();
+  D->ColonLoc = ReadSourceLocation();
 }
 
 void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
   VisitNamedDecl(CD);
-  CD->setAtStartLoc(ReadSourceLocation(Record, Idx));
-  CD->setAtEndRange(ReadSourceRange(Record, Idx));
+  CD->setAtStartLoc(ReadSourceLocation());
+  CD->setAtEndRange(ReadSourceRange());
 }
 
 ObjCTypeParamList *ASTDeclReader::ReadObjCTypeParamList() {
-  unsigned numParams = Record[Idx++];
+  unsigned numParams = Record.readInt();
   if (numParams == 0)
     return nullptr;
 
   SmallVector<ObjCTypeParamDecl *, 4> typeParams;
   typeParams.reserve(numParams);
   for (unsigned i = 0; i != numParams; ++i) {
-    auto typeParam = ReadDeclAs<ObjCTypeParamDecl>(Record, Idx);
+    auto typeParam = ReadDeclAs<ObjCTypeParamDecl>();
     if (!typeParam)
       return nullptr;
 
     typeParams.push_back(typeParam);
   }
 
-  SourceLocation lAngleLoc = ReadSourceLocation(Record, Idx);
-  SourceLocation rAngleLoc = ReadSourceLocation(Record, Idx);
+  SourceLocation lAngleLoc = ReadSourceLocation();
+  SourceLocation rAngleLoc = ReadSourceLocation();
 
   return ObjCTypeParamList::create(Reader.getContext(), lAngleLoc,
                                    typeParams, rAngleLoc);
 }
 
 void ASTDeclReader::ReadObjCDefinitionData(
-         struct ObjCInterfaceDecl::DefinitionData &Data,
-         const RecordData &R, unsigned &I) {
+         struct ObjCInterfaceDecl::DefinitionData &Data) {
   // Read the superclass.
-  Data.SuperClassTInfo = GetTypeSourceInfo(Record, Idx);
+  Data.SuperClassTInfo = GetTypeSourceInfo();
 
-  Data.EndLoc = ReadSourceLocation(Record, Idx);
-  Data.HasDesignatedInitializers = Record[Idx++];
-   
+  Data.EndLoc = ReadSourceLocation();
+  Data.HasDesignatedInitializers = Record.readInt();
+
   // Read the directly referenced protocols and their SourceLocations.
-  unsigned NumProtocols = Record[Idx++];
+  unsigned NumProtocols = Record.readInt();
   SmallVector<ObjCProtocolDecl *, 16> Protocols;
   Protocols.reserve(NumProtocols);
   for (unsigned I = 0; I != NumProtocols; ++I)
-    Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+    Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>());
   SmallVector<SourceLocation, 16> ProtoLocs;
   ProtoLocs.reserve(NumProtocols);
   for (unsigned I = 0; I != NumProtocols; ++I)
-    ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
+    ProtoLocs.push_back(ReadSourceLocation());
   Data.ReferencedProtocols.set(Protocols.data(), NumProtocols, ProtoLocs.data(),
                                Reader.getContext());
- 
+
   // Read the transitive closure of protocols referenced by this class.
-  NumProtocols = Record[Idx++];
+  NumProtocols = Record.readInt();
   Protocols.clear();
   Protocols.reserve(NumProtocols);
   for (unsigned I = 0; I != NumProtocols; ++I)
-    Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+    Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>());
   Data.AllReferencedProtocols.set(Protocols.data(), NumProtocols,
                                   Reader.getContext());
 }
@@ -1004,15 +1001,15 @@
 void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
   RedeclarableResult Redecl = VisitRedeclarable(ID);
   VisitObjCContainerDecl(ID);
-  TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
+  TypeIDForTypeDecl = Record.getGlobalTypeID(Record.readInt());
   mergeRedeclarable(ID, Redecl);
 
   ID->TypeParamList = ReadObjCTypeParamList();
-  if (Record[Idx++]) {
+  if (Record.readInt()) {
     // Read the definition.
     ID->allocateDefinitionData();
 
-    ReadObjCDefinitionData(ID->data(), Record, Idx);
+    ReadObjCDefinitionData(ID->data());
     ObjCInterfaceDecl *Canon = ID->getCanonicalDecl();
     if (Canon->Data.getPointer()) {
       // If we already have a definition, keep the definition invariant and
@@ -1023,14 +1020,14 @@
       // Set the definition data of the canonical declaration, so other
       // redeclarations will see it.
       ID->getCanonicalDecl()->Data = ID->Data;
-    
+
       // We will rebuild this list lazily.
       ID->setIvarList(nullptr);
     }
 
     // Note that we have deserialized a definition.
     Reader.PendingDefinitions.insert(ID);
-    
+
     // Note that we've loaded this Objective-C class.
     Reader.ObjCClassesLoaded.push_back(ID);
   } else {
@@ -1040,10 +1037,10 @@
 
 void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
   VisitFieldDecl(IVD);
-  IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
+  IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record.readInt());
   // This field will be built lazily.
   IVD->setNextIvar(nullptr);
-  bool synth = Record[Idx++];
+  bool synth = Record.readInt();
   IVD->setSynthesize(synth);
 }
 
@@ -1051,27 +1048,27 @@
   RedeclarableResult Redecl = VisitRedeclarable(PD);
   VisitObjCContainerDecl(PD);
   mergeRedeclarable(PD, Redecl);
-  
-  if (Record[Idx++]) {
+
+  if (Record.readInt()) {
     // Read the definition.
     PD->allocateDefinitionData();
-    
+
     // Set the definition data of the canonical declaration, so other
     // redeclarations will see it.
     PD->getCanonicalDecl()->Data = PD->Data;
 
-    unsigned NumProtoRefs = Record[Idx++];
+    unsigned NumProtoRefs = Record.readInt();
     SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
     ProtoRefs.reserve(NumProtoRefs);
     for (unsigned I = 0; I != NumProtoRefs; ++I)
-      ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+      ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>());
     SmallVector<SourceLocation, 16> ProtoLocs;
     ProtoLocs.reserve(NumProtoRefs);
     for (unsigned I = 0; I != NumProtoRefs; ++I)
-      ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
+      ProtoLocs.push_back(ReadSourceLocation());
     PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
                         Reader.getContext());
-    
+
     // Note that we have deserialized a definition.
     Reader.PendingDefinitions.insert(PD);
   } else {
@@ -1085,105 +1082,103 @@
 
 void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
   VisitObjCContainerDecl(CD);
-  CD->setCategoryNameLoc(ReadSourceLocation(Record, Idx));
-  CD->setIvarLBraceLoc(ReadSourceLocation(Record, Idx));
-  CD->setIvarRBraceLoc(ReadSourceLocation(Record, Idx));
-  
+  CD->setCategoryNameLoc(ReadSourceLocation());
+  CD->setIvarLBraceLoc(ReadSourceLocation());
+  CD->setIvarRBraceLoc(ReadSourceLocation());
+
   // Note that this category has been deserialized. We do this before
   // deserializing the interface declaration, so that it will consider this
   /// category.
   Reader.CategoriesDeserialized.insert(CD);
 
-  CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
+  CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>();
   CD->TypeParamList = ReadObjCTypeParamList();
-  unsigned NumProtoRefs = Record[Idx++];
+  unsigned NumProtoRefs = Record.readInt();
   SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
   ProtoRefs.reserve(NumProtoRefs);
   for (unsigned I = 0; I != NumProtoRefs; ++I)
-    ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+    ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>());
   SmallVector<SourceLocation, 16> ProtoLocs;
   ProtoLocs.reserve(NumProtoRefs);
   for (unsigned I = 0; I != NumProtoRefs; ++I)
-    ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
+    ProtoLocs.push_back(ReadSourceLocation());
   CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
                       Reader.getContext());
 }
 
 void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
   VisitNamedDecl(CAD);
-  CAD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
+  CAD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>());
 }
 
 void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
   VisitNamedDecl(D);
-  D->setAtLoc(ReadSourceLocation(Record, Idx));
-  D->setLParenLoc(ReadSourceLocation(Record, Idx));
-  QualType T = Reader.readType(F, Record, Idx);
-  TypeSourceInfo *TSI = GetTypeSourceInfo(Record, Idx);
+  D->setAtLoc(ReadSourceLocation());
+  D->setLParenLoc(ReadSourceLocation());
+  QualType T = Record.readType();
+  TypeSourceInfo *TSI = GetTypeSourceInfo();
   D->setType(T, TSI);
   D->setPropertyAttributes(
-                      (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
+      (ObjCPropertyDecl::PropertyAttributeKind)Record.readInt());
   D->setPropertyAttributesAsWritten(
-                      (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
+      (ObjCPropertyDecl::PropertyAttributeKind)Record.readInt());
   D->setPropertyImplementation(
-                            (ObjCPropertyDecl::PropertyControl)Record[Idx++]);
-  D->setGetterName(Reader.ReadDeclarationName(F,Record, Idx).getObjCSelector());
-  D->setSetterName(Reader.ReadDeclarationName(F,Record, Idx).getObjCSelector());
-  D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
-  D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
-  D->setPropertyIvarDecl(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
+      (ObjCPropertyDecl::PropertyControl)Record.readInt());
+  D->setGetterName(Record.readDeclarationName().getObjCSelector());
+  D->setSetterName(Record.readDeclarationName().getObjCSelector());
+  D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>());
+  D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>());
+  D->setPropertyIvarDecl(ReadDeclAs<ObjCIvarDecl>());
 }
 
 void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
   VisitObjCContainerDecl(D);
-  D->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
+  D->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>());
 }
 
 void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
   VisitObjCImplDecl(D);
-  D->setIdentifier(Reader.GetIdentifierInfo(F, Record, Idx));
-  D->CategoryNameLoc = ReadSourceLocation(Record, Idx);
+  D->CategoryNameLoc = ReadSourceLocation();
 }
 
 void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
   VisitObjCImplDecl(D);
-  D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
-  D->SuperLoc = ReadSourceLocation(Record, Idx);
-  D->setIvarLBraceLoc(ReadSourceLocation(Record, Idx));
-  D->setIvarRBraceLoc(ReadSourceLocation(Record, Idx));
-  D->setHasNonZeroConstructors(Record[Idx++]);
-  D->setHasDestructors(Record[Idx++]);
-  D->NumIvarInitializers = Record[Idx++];
+  D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>());
+  D->SuperLoc = ReadSourceLocation();
+  D->setIvarLBraceLoc(ReadSourceLocation());
+  D->setIvarRBraceLoc(ReadSourceLocation());
+  D->setHasNonZeroConstructors(Record.readInt());
+  D->setHasDestructors(Record.readInt());
+  D->NumIvarInitializers = Record.readInt();
   if (D->NumIvarInitializers)
-    D->IvarInitializers = ReadGlobalOffset(F, Record, Idx);
+    D->IvarInitializers = ReadGlobalOffset();
 }
 
 void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
   VisitDecl(D);
-  D->setAtLoc(ReadSourceLocation(Record, Idx));
-  D->setPropertyDecl(ReadDeclAs<ObjCPropertyDecl>(Record, Idx));
-  D->PropertyIvarDecl = ReadDeclAs<ObjCIvarDecl>(Record, Idx);
-  D->IvarLoc = ReadSourceLocation(Record, Idx);
-  D->setGetterCXXConstructor(Reader.ReadExpr(F));
-  D->setSetterCXXAssignment(Reader.ReadExpr(F));
+  D->setAtLoc(ReadSourceLocation());
+  D->setPropertyDecl(ReadDeclAs<ObjCPropertyDecl>());
+  D->PropertyIvarDecl = ReadDeclAs<ObjCIvarDecl>();
+  D->IvarLoc = ReadSourceLocation();
+  D->setGetterCXXConstructor(Record.readExpr());
+  D->setSetterCXXAssignment(Record.readExpr());
 }
 
 void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
   VisitDeclaratorDecl(FD);
-  FD->Mutable = Record[Idx++];
-  if (int BitWidthOrInitializer = Record[Idx++]) {
+  FD->Mutable = Record.readInt();
+  if (int BitWidthOrInitializer = Record.readInt()) {
     FD->InitStorage.setInt(
           static_cast<FieldDecl::InitStorageKind>(BitWidthOrInitializer - 1));
     if (FD->InitStorage.getInt() == FieldDecl::ISK_CapturedVLAType) {
       // Read captured variable length array.
-      FD->InitStorage.setPointer(
-          Reader.readType(F, Record, Idx).getAsOpaquePtr());
+      FD->InitStorage.setPointer(Record.readType().getAsOpaquePtr());
     } else {
-      FD->InitStorage.setPointer(Reader.ReadExpr(F));
+      FD->InitStorage.setPointer(Record.readExpr());
     }
   }
   if (!FD->getDeclName()) {
-    if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>(Record, Idx))
+    if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>())
       Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
   }
   mergeMergeable(FD);
@@ -1191,19 +1186,19 @@
 
 void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) {
   VisitDeclaratorDecl(PD);
-  PD->GetterId = Reader.GetIdentifierInfo(F, Record, Idx);
-  PD->SetterId = Reader.GetIdentifierInfo(F, Record, Idx);
+  PD->GetterId = Record.getIdentifierInfo();
+  PD->SetterId = Record.getIdentifierInfo();
 }
 
 void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
   VisitValueDecl(FD);
 
-  FD->ChainingSize = Record[Idx++];
+  FD->ChainingSize = Record.readInt();
   assert(FD->ChainingSize >= 2 && "Anonymous chaining must be >= 2");
   FD->Chaining = new (Reader.getContext())NamedDecl*[FD->ChainingSize];
 
   for (unsigned I = 0; I != FD->ChainingSize; ++I)
-    FD->Chaining[I] = ReadDeclAs<NamedDecl>(Record, Idx);
+    FD->Chaining[I] = ReadDeclAs<NamedDecl>();
 
   mergeMergeable(FD);
 }
@@ -1212,22 +1207,23 @@
   RedeclarableResult Redecl = VisitRedeclarable(VD);
   VisitDeclaratorDecl(VD);
 
-  VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];
-  VD->VarDeclBits.TSCSpec = Record[Idx++];
-  VD->VarDeclBits.InitStyle = Record[Idx++];
+  VD->VarDeclBits.SClass = (StorageClass)Record.readInt();
+  VD->VarDeclBits.TSCSpec = Record.readInt();
+  VD->VarDeclBits.InitStyle = Record.readInt();
   if (!isa<ParmVarDecl>(VD)) {
-    VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = Record[Idx++];
-    VD->NonParmVarDeclBits.ExceptionVar = Record[Idx++];
-    VD->NonParmVarDeclBits.NRVOVariable = Record[Idx++];
-    VD->NonParmVarDeclBits.CXXForRangeDecl = Record[Idx++];
-    VD->NonParmVarDeclBits.ARCPseudoStrong = Record[Idx++];
-    VD->NonParmVarDeclBits.IsInline = Record[Idx++];
-    VD->NonParmVarDeclBits.IsInlineSpecified = Record[Idx++];
-    VD->NonParmVarDeclBits.IsConstexpr = Record[Idx++];
-    VD->NonParmVarDeclBits.IsInitCapture = Record[Idx++];
-    VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = Record[Idx++];
+    VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition =
+        Record.readInt();
+    VD->NonParmVarDeclBits.ExceptionVar = Record.readInt();
+    VD->NonParmVarDeclBits.NRVOVariable = Record.readInt();
+    VD->NonParmVarDeclBits.CXXForRangeDecl = Record.readInt();
+    VD->NonParmVarDeclBits.ARCPseudoStrong = Record.readInt();
+    VD->NonParmVarDeclBits.IsInline = Record.readInt();
+    VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt();
+    VD->NonParmVarDeclBits.IsConstexpr = Record.readInt();
+    VD->NonParmVarDeclBits.IsInitCapture = Record.readInt();
+    VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = Record.readInt();
   }
-  Linkage VarLinkage = Linkage(Record[Idx++]);
+  Linkage VarLinkage = Linkage(Record.readInt());
   VD->setCachedLinkage(VarLinkage);
 
   // Reconstruct the one piece of the IdentifierNamespace that we need.
@@ -1235,8 +1231,8 @@
       VD->getLexicalDeclContext()->isFunctionOrMethod())
     VD->setLocalExternDecl();
 
-  if (uint64_t Val = Record[Idx++]) {
-    VD->setInit(Reader.ReadExpr(F));
+  if (uint64_t Val = Record.readInt()) {
+    VD->setInit(Record.readExpr());
     if (Val > 1) { // IsInitKnownICE = 1, IsInitNotICE = 2, IsInitICE = 3
       EvaluatedStmt *Eval = VD->ensureEvaluatedStmt();
       Eval->CheckedICE = true;
@@ -1247,7 +1243,7 @@
   enum VarKind {
     VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
   };
-  switch ((VarKind)Record[Idx++]) {
+  switch ((VarKind)Record.readInt()) {
   case VarNotTemplate:
     // Only true variables (not parameters or implicit parameters) can be
     // merged; the other kinds are not really redeclarable at all.
@@ -1257,12 +1253,13 @@
     break;
   case VarTemplate:
     // Merged when we merge the template.
-    VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>(Record, Idx));
+    VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>());
     break;
   case StaticDataMemberSpecialization: { // HasMemberSpecializationInfo.
-    VarDecl *Tmpl = ReadDeclAs<VarDecl>(Record, Idx);
-    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
-    SourceLocation POI = ReadSourceLocation(Record, Idx);
+    VarDecl *Tmpl = ReadDeclAs<VarDecl>();
+    TemplateSpecializationKind TSK =
+        (TemplateSpecializationKind)Record.readInt();
+    SourceLocation POI = ReadSourceLocation();
     Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
     mergeRedeclarable(VD, Redecl);
     break;
@@ -1278,10 +1275,10 @@
 
 void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
   VisitVarDecl(PD);
-  unsigned isObjCMethodParam = Record[Idx++];
-  unsigned scopeDepth = Record[Idx++];
-  unsigned scopeIndex = Record[Idx++];
-  unsigned declQualifier = Record[Idx++];
+  unsigned isObjCMethodParam = Record.readInt();
+  unsigned scopeDepth = Record.readInt();
+  unsigned scopeIndex = Record.readInt();
+  unsigned declQualifier = Record.readInt();
   if (isObjCMethodParam) {
     assert(scopeDepth == 0);
     PD->setObjCMethodScopeInfo(scopeIndex);
@@ -1289,10 +1286,10 @@
   } else {
     PD->setScopeInfo(scopeDepth, scopeIndex);
   }
-  PD->ParmVarDeclBits.IsKNRPromoted = Record[Idx++];
-  PD->ParmVarDeclBits.HasInheritedDefaultArg = Record[Idx++];
-  if (Record[Idx++]) // hasUninstantiatedDefaultArg.
-    PD->setUninstantiatedDefaultArg(Reader.ReadExpr(F));
+  PD->ParmVarDeclBits.IsKNRPromoted = Record.readInt();
+  PD->ParmVarDeclBits.HasInheritedDefaultArg = Record.readInt();
+  if (Record.readInt()) // hasUninstantiatedDefaultArg.
+    PD->setUninstantiatedDefaultArg(Record.readExpr());
 
   // FIXME: If this is a redeclaration of a function from another module, handle
   // inheritance of default arguments.
@@ -1302,45 +1299,45 @@
   VisitVarDecl(DD);
   BindingDecl **BDs = DD->getTrailingObjects<BindingDecl*>();
   for (unsigned I = 0; I != DD->NumBindings; ++I)
-    BDs[I] = ReadDeclAs<BindingDecl>(Record, Idx);
+    BDs[I] = ReadDeclAs<BindingDecl>();
 }
 
 void ASTDeclReader::VisitBindingDecl(BindingDecl *BD) {
   VisitValueDecl(BD);
-  BD->Binding = Reader.ReadExpr(F);
+  BD->Binding = Record.readExpr();
 }
 
 void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
   VisitDecl(AD);
-  AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr(F)));
-  AD->setRParenLoc(ReadSourceLocation(Record, Idx));
+  AD->setAsmString(cast<StringLiteral>(Record.readExpr()));
+  AD->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
   VisitDecl(BD);
-  BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt(F)));
-  BD->setSignatureAsWritten(GetTypeSourceInfo(Record, Idx));
-  unsigned NumParams = Record[Idx++];
+  BD->setBody(cast_or_null<CompoundStmt>(Record.readStmt()));
+  BD->setSignatureAsWritten(GetTypeSourceInfo());
+  unsigned NumParams = Record.readInt();
   SmallVector<ParmVarDecl *, 16> Params;
   Params.reserve(NumParams);
   for (unsigned I = 0; I != NumParams; ++I)
-    Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
+    Params.push_back(ReadDeclAs<ParmVarDecl>());
   BD->setParams(Params);
 
-  BD->setIsVariadic(Record[Idx++]);
-  BD->setBlockMissingReturnType(Record[Idx++]);
-  BD->setIsConversionFromLambda(Record[Idx++]);
+  BD->setIsVariadic(Record.readInt());
+  BD->setBlockMissingReturnType(Record.readInt());
+  BD->setIsConversionFromLambda(Record.readInt());
 
-  bool capturesCXXThis = Record[Idx++];
-  unsigned numCaptures = Record[Idx++];
+  bool capturesCXXThis = Record.readInt();
+  unsigned numCaptures = Record.readInt();
   SmallVector<BlockDecl::Capture, 16> captures;
   captures.reserve(numCaptures);
   for (unsigned i = 0; i != numCaptures; ++i) {
-    VarDecl *decl = ReadDeclAs<VarDecl>(Record, Idx);
-    unsigned flags = Record[Idx++];
+    VarDecl *decl = ReadDeclAs<VarDecl>();
+    unsigned flags = Record.readInt();
     bool byRef = (flags & 1);
     bool nested = (flags & 2);
-    Expr *copyExpr = ((flags & 4) ? Reader.ReadExpr(F) : nullptr);
+    Expr *copyExpr = ((flags & 4) ? Record.readExpr() : nullptr);
 
     captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr));
   }
@@ -1349,40 +1346,40 @@
 
 void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) {
   VisitDecl(CD);
-  unsigned ContextParamPos = Record[Idx++];
-  CD->setNothrow(Record[Idx++] != 0);
+  unsigned ContextParamPos = Record.readInt();
+  CD->setNothrow(Record.readInt() != 0);
   // Body is set by VisitCapturedStmt.
   for (unsigned I = 0; I < CD->NumParams; ++I) {
     if (I != ContextParamPos)
-      CD->setParam(I, ReadDeclAs<ImplicitParamDecl>(Record, Idx));
+      CD->setParam(I, ReadDeclAs<ImplicitParamDecl>());
     else
-      CD->setContextParam(I, ReadDeclAs<ImplicitParamDecl>(Record, Idx));
+      CD->setContextParam(I, ReadDeclAs<ImplicitParamDecl>());
   }
 }
 
 void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
   VisitDecl(D);
-  D->setLanguage((LinkageSpecDecl::LanguageIDs)Record[Idx++]);
-  D->setExternLoc(ReadSourceLocation(Record, Idx));
-  D->setRBraceLoc(ReadSourceLocation(Record, Idx));
+  D->setLanguage((LinkageSpecDecl::LanguageIDs)Record.readInt());
+  D->setExternLoc(ReadSourceLocation());
+  D->setRBraceLoc(ReadSourceLocation());
 }
 
 void ASTDeclReader::VisitExportDecl(ExportDecl *D) {
   VisitDecl(D);
-  D->RBraceLoc = ReadSourceLocation(Record, Idx);
+  D->RBraceLoc = ReadSourceLocation();
 }
 
 void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
   VisitNamedDecl(D);
-  D->setLocStart(ReadSourceLocation(Record, Idx));
+  D->setLocStart(ReadSourceLocation());
 }
 
 void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
   RedeclarableResult Redecl = VisitRedeclarable(D);
   VisitNamedDecl(D);
-  D->setInline(Record[Idx++]);
-  D->LocStart = ReadSourceLocation(Record, Idx);
-  D->RBraceLoc = ReadSourceLocation(Record, Idx);
+  D->setInline(Record.readInt());
+  D->LocStart = ReadSourceLocation();
+  D->RBraceLoc = ReadSourceLocation();
 
   // Defer loading the anonymous namespace until we've finished merging
   // this namespace; loading it might load a later declaration of the
@@ -1390,7 +1387,7 @@
   // get merged before newer ones try to merge.
   GlobalDeclID AnonNamespace = 0;
   if (Redecl.getFirstID() == ThisDeclID) {
-    AnonNamespace = ReadDeclID(Record, Idx);
+    AnonNamespace = ReadDeclID();
   } else {
     // Link this namespace back to the first declaration, which has already
     // been deserialized.
@@ -1404,7 +1401,7 @@
     // any other module's anonymous namespaces, so don't attach the anonymous
     // namespace at all.
     NamespaceDecl *Anon = cast<NamespaceDecl>(Reader.GetDecl(AnonNamespace));
-    if (!F.isModule())
+    if (!Record.isModule())
       D->setAnonymousNamespace(Anon);
   }
 }
@@ -1412,31 +1409,40 @@
 void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
   RedeclarableResult Redecl = VisitRedeclarable(D);
   VisitNamedDecl(D);
-  D->NamespaceLoc = ReadSourceLocation(Record, Idx);
-  D->IdentLoc = ReadSourceLocation(Record, Idx);
-  D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
-  D->Namespace = ReadDeclAs<NamedDecl>(Record, Idx);
+  D->NamespaceLoc = ReadSourceLocation();
+  D->IdentLoc = ReadSourceLocation();
+  D->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  D->Namespace = ReadDeclAs<NamedDecl>();
   mergeRedeclarable(D, Redecl);
 }
 
 void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
   VisitNamedDecl(D);
-  D->setUsingLoc(ReadSourceLocation(Record, Idx));
-  D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
-  ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
-  D->FirstUsingShadow.setPointer(ReadDeclAs<UsingShadowDecl>(Record, Idx));
-  D->setTypename(Record[Idx++]);
-  if (NamedDecl *Pattern = ReadDeclAs<NamedDecl>(Record, Idx))
+  D->setUsingLoc(ReadSourceLocation());
+  D->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  ReadDeclarationNameLoc(D->DNLoc, D->getDeclName());
+  D->FirstUsingShadow.setPointer(ReadDeclAs<UsingShadowDecl>());
+  D->setTypename(Record.readInt());
+  if (NamedDecl *Pattern = ReadDeclAs<NamedDecl>())
     Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern);
   mergeMergeable(D);
 }
 
+void ASTDeclReader::VisitUsingPackDecl(UsingPackDecl *D) {
+  VisitNamedDecl(D);
+  D->InstantiatedFrom = ReadDeclAs<NamedDecl>();
+  NamedDecl **Expansions = D->getTrailingObjects<NamedDecl*>();
+  for (unsigned I = 0; I != D->NumExpansions; ++I)
+    Expansions[I] = ReadDeclAs<NamedDecl>();
+  mergeMergeable(D);
+}
+
 void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
   RedeclarableResult Redecl = VisitRedeclarable(D);
   VisitNamedDecl(D);
-  D->setTargetDecl(ReadDeclAs<NamedDecl>(Record, Idx));
-  D->UsingOrNextShadow = ReadDeclAs<NamedDecl>(Record, Idx);
-  UsingShadowDecl *Pattern = ReadDeclAs<UsingShadowDecl>(Record, Idx);
+  D->setTargetDecl(ReadDeclAs<NamedDecl>());
+  D->UsingOrNextShadow = ReadDeclAs<NamedDecl>();
+  UsingShadowDecl *Pattern = ReadDeclAs<UsingShadowDecl>();
   if (Pattern)
     Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern);
   mergeRedeclarable(D, Redecl);
@@ -1445,115 +1451,116 @@
 void ASTDeclReader::VisitConstructorUsingShadowDecl(
     ConstructorUsingShadowDecl *D) {
   VisitUsingShadowDecl(D);
-  D->NominatedBaseClassShadowDecl =
-      ReadDeclAs<ConstructorUsingShadowDecl>(Record, Idx);
-  D->ConstructedBaseClassShadowDecl =
-      ReadDeclAs<ConstructorUsingShadowDecl>(Record, Idx);
-  D->IsVirtual = Record[Idx++];
+  D->NominatedBaseClassShadowDecl = ReadDeclAs<ConstructorUsingShadowDecl>();
+  D->ConstructedBaseClassShadowDecl = ReadDeclAs<ConstructorUsingShadowDecl>();
+  D->IsVirtual = Record.readInt();
 }
 
 void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
   VisitNamedDecl(D);
-  D->UsingLoc = ReadSourceLocation(Record, Idx);
-  D->NamespaceLoc = ReadSourceLocation(Record, Idx);
-  D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
-  D->NominatedNamespace = ReadDeclAs<NamedDecl>(Record, Idx);
-  D->CommonAncestor = ReadDeclAs<DeclContext>(Record, Idx);
+  D->UsingLoc = ReadSourceLocation();
+  D->NamespaceLoc = ReadSourceLocation();
+  D->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  D->NominatedNamespace = ReadDeclAs<NamedDecl>();
+  D->CommonAncestor = ReadDeclAs<DeclContext>();
 }
 
 void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
   VisitValueDecl(D);
-  D->setUsingLoc(ReadSourceLocation(Record, Idx));
-  D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
-  ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
+  D->setUsingLoc(ReadSourceLocation());
+  D->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  ReadDeclarationNameLoc(D->DNLoc, D->getDeclName());
+  D->EllipsisLoc = ReadSourceLocation();
   mergeMergeable(D);
 }
 
 void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
                                                UnresolvedUsingTypenameDecl *D) {
   VisitTypeDecl(D);
-  D->TypenameLocation = ReadSourceLocation(Record, Idx);
-  D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
+  D->TypenameLocation = ReadSourceLocation();
+  D->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  D->EllipsisLoc = ReadSourceLocation();
   mergeMergeable(D);
 }
 
 void ASTDeclReader::ReadCXXDefinitionData(
-                                   struct CXXRecordDecl::DefinitionData &Data,
-                                   const RecordData &Record, unsigned &Idx) {
+                                   struct CXXRecordDecl::DefinitionData &Data) {
   // Note: the caller has deserialized the IsLambda bit already.
-  Data.UserDeclaredConstructor = Record[Idx++];
-  Data.UserDeclaredSpecialMembers = Record[Idx++];
-  Data.Aggregate = Record[Idx++];
-  Data.PlainOldData = Record[Idx++];
-  Data.Empty = Record[Idx++];
-  Data.Polymorphic = Record[Idx++];
-  Data.Abstract = Record[Idx++];
-  Data.IsStandardLayout = Record[Idx++];
-  Data.HasNoNonEmptyBases = Record[Idx++];
-  Data.HasPrivateFields = Record[Idx++];
-  Data.HasProtectedFields = Record[Idx++];
-  Data.HasPublicFields = Record[Idx++];
-  Data.HasMutableFields = Record[Idx++];
-  Data.HasVariantMembers = Record[Idx++];
-  Data.HasOnlyCMembers = Record[Idx++];
-  Data.HasInClassInitializer = Record[Idx++];
-  Data.HasUninitializedReferenceMember = Record[Idx++];
-  Data.HasUninitializedFields = Record[Idx++];
-  Data.HasInheritedConstructor = Record[Idx++];
-  Data.HasInheritedAssignment = Record[Idx++];
-  Data.NeedOverloadResolutionForMoveConstructor = Record[Idx++];
-  Data.NeedOverloadResolutionForMoveAssignment = Record[Idx++];
-  Data.NeedOverloadResolutionForDestructor = Record[Idx++];
-  Data.DefaultedMoveConstructorIsDeleted = Record[Idx++];
-  Data.DefaultedMoveAssignmentIsDeleted = Record[Idx++];
-  Data.DefaultedDestructorIsDeleted = Record[Idx++];
-  Data.HasTrivialSpecialMembers = Record[Idx++];
-  Data.DeclaredNonTrivialSpecialMembers = Record[Idx++];
-  Data.HasIrrelevantDestructor = Record[Idx++];
-  Data.HasConstexprNonCopyMoveConstructor = Record[Idx++];
-  Data.HasDefaultedDefaultConstructor = Record[Idx++];
-  Data.DefaultedDefaultConstructorIsConstexpr = Record[Idx++];
-  Data.HasConstexprDefaultConstructor = Record[Idx++];
-  Data.HasNonLiteralTypeFieldsOrBases = Record[Idx++];
-  Data.ComputedVisibleConversions = Record[Idx++];
-  Data.UserProvidedDefaultConstructor = Record[Idx++];
-  Data.DeclaredSpecialMembers = Record[Idx++];
-  Data.ImplicitCopyConstructorHasConstParam = Record[Idx++];
-  Data.ImplicitCopyAssignmentHasConstParam = Record[Idx++];
-  Data.HasDeclaredCopyConstructorWithConstParam = Record[Idx++];
-  Data.HasDeclaredCopyAssignmentWithConstParam = Record[Idx++];
+  Data.UserDeclaredConstructor = Record.readInt();
+  Data.UserDeclaredSpecialMembers = Record.readInt();
+  Data.Aggregate = Record.readInt();
+  Data.PlainOldData = Record.readInt();
+  Data.Empty = Record.readInt();
+  Data.Polymorphic = Record.readInt();
+  Data.Abstract = Record.readInt();
+  Data.IsStandardLayout = Record.readInt();
+  Data.HasNoNonEmptyBases = Record.readInt();
+  Data.HasPrivateFields = Record.readInt();
+  Data.HasProtectedFields = Record.readInt();
+  Data.HasPublicFields = Record.readInt();
+  Data.HasMutableFields = Record.readInt();
+  Data.HasVariantMembers = Record.readInt();
+  Data.HasOnlyCMembers = Record.readInt();
+  Data.HasInClassInitializer = Record.readInt();
+  Data.HasUninitializedReferenceMember = Record.readInt();
+  Data.HasUninitializedFields = Record.readInt();
+  Data.HasInheritedConstructor = Record.readInt();
+  Data.HasInheritedAssignment = Record.readInt();
+  Data.NeedOverloadResolutionForMoveConstructor = Record.readInt();
+  Data.NeedOverloadResolutionForMoveAssignment = Record.readInt();
+  Data.NeedOverloadResolutionForDestructor = Record.readInt();
+  Data.DefaultedMoveConstructorIsDeleted = Record.readInt();
+  Data.DefaultedMoveAssignmentIsDeleted = Record.readInt();
+  Data.DefaultedDestructorIsDeleted = Record.readInt();
+  Data.HasTrivialSpecialMembers = Record.readInt();
+  Data.DeclaredNonTrivialSpecialMembers = Record.readInt();
+  Data.HasIrrelevantDestructor = Record.readInt();
+  Data.HasConstexprNonCopyMoveConstructor = Record.readInt();
+  Data.HasDefaultedDefaultConstructor = Record.readInt();
+  Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt();
+  Data.HasConstexprDefaultConstructor = Record.readInt();
+  Data.HasNonLiteralTypeFieldsOrBases = Record.readInt();
+  Data.ComputedVisibleConversions = Record.readInt();
+  Data.UserProvidedDefaultConstructor = Record.readInt();
+  Data.DeclaredSpecialMembers = Record.readInt();
+  Data.ImplicitCopyConstructorCanHaveConstParamForVBase = Record.readInt();
+  Data.ImplicitCopyConstructorCanHaveConstParamForNonVBase = Record.readInt();
+  Data.ImplicitCopyAssignmentHasConstParam = Record.readInt();
+  Data.HasDeclaredCopyConstructorWithConstParam = Record.readInt();
+  Data.HasDeclaredCopyAssignmentWithConstParam = Record.readInt();
+  Data.ODRHash = Record.readInt();
 
-  Data.NumBases = Record[Idx++];
+  Data.NumBases = Record.readInt();
   if (Data.NumBases)
-    Data.Bases = ReadGlobalOffset(F, Record, Idx);
-  Data.NumVBases = Record[Idx++];
+    Data.Bases = ReadGlobalOffset();
+  Data.NumVBases = Record.readInt();
   if (Data.NumVBases)
-    Data.VBases = ReadGlobalOffset(F, Record, Idx);
-  
-  Reader.ReadUnresolvedSet(F, Data.Conversions, Record, Idx);
-  Reader.ReadUnresolvedSet(F, Data.VisibleConversions, Record, Idx);
+    Data.VBases = ReadGlobalOffset();
+
+  Record.readUnresolvedSet(Data.Conversions);
+  Record.readUnresolvedSet(Data.VisibleConversions);
   assert(Data.Definition && "Data.Definition should be already set!");
-  Data.FirstFriend = ReadDeclID(Record, Idx);
+  Data.FirstFriend = ReadDeclID();
 
   if (Data.IsLambda) {
     typedef LambdaCapture Capture;
     CXXRecordDecl::LambdaDefinitionData &Lambda
       = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data);
-    Lambda.Dependent = Record[Idx++];
-    Lambda.IsGenericLambda = Record[Idx++];
-    Lambda.CaptureDefault = Record[Idx++];
-    Lambda.NumCaptures = Record[Idx++];
-    Lambda.NumExplicitCaptures = Record[Idx++];
-    Lambda.ManglingNumber = Record[Idx++];
-    Lambda.ContextDecl = ReadDeclID(Record, Idx);
+    Lambda.Dependent = Record.readInt();
+    Lambda.IsGenericLambda = Record.readInt();
+    Lambda.CaptureDefault = Record.readInt();
+    Lambda.NumCaptures = Record.readInt();
+    Lambda.NumExplicitCaptures = Record.readInt();
+    Lambda.ManglingNumber = Record.readInt();
+    Lambda.ContextDecl = ReadDeclID();
     Lambda.Captures 
       = (Capture*)Reader.Context.Allocate(sizeof(Capture)*Lambda.NumCaptures);
     Capture *ToCapture = Lambda.Captures;
-    Lambda.MethodTyInfo = GetTypeSourceInfo(Record, Idx);
+    Lambda.MethodTyInfo = GetTypeSourceInfo();
     for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
-      SourceLocation Loc = ReadSourceLocation(Record, Idx);
-      bool IsImplicit = Record[Idx++];
-      LambdaCaptureKind Kind = static_cast<LambdaCaptureKind>(Record[Idx++]);
+      SourceLocation Loc = ReadSourceLocation();
+      bool IsImplicit = Record.readInt();
+      LambdaCaptureKind Kind = static_cast<LambdaCaptureKind>(Record.readInt());
       switch (Kind) {
       case LCK_StarThis: 
       case LCK_This:
@@ -1562,8 +1569,8 @@
         break;
       case LCK_ByCopy:
       case LCK_ByRef:
-        VarDecl *Var = ReadDeclAs<VarDecl>(Record, Idx);
-        SourceLocation EllipsisLoc = ReadSourceLocation(Record, Idx);
+        VarDecl *Var = ReadDeclAs<VarDecl>();
+        SourceLocation EllipsisLoc = ReadSourceLocation();
         *ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc);
         break;
       }
@@ -1647,11 +1654,13 @@
   // ComputedVisibleConversions is handled below.
   MATCH_FIELD(UserProvidedDefaultConstructor)
   OR_FIELD(DeclaredSpecialMembers)
-  MATCH_FIELD(ImplicitCopyConstructorHasConstParam)
+  MATCH_FIELD(ImplicitCopyConstructorCanHaveConstParamForVBase)
+  MATCH_FIELD(ImplicitCopyConstructorCanHaveConstParamForNonVBase)
   MATCH_FIELD(ImplicitCopyAssignmentHasConstParam)
   OR_FIELD(HasDeclaredCopyConstructorWithConstParam)
   OR_FIELD(HasDeclaredCopyAssignmentWithConstParam)
   MATCH_FIELD(IsLambda)
+  MATCH_FIELD(ODRHash)
 #undef OR_FIELD
 #undef MATCH_FIELD
 
@@ -1685,14 +1694,14 @@
 
   // Determine whether this is a lambda closure type, so that we can
   // allocate the appropriate DefinitionData structure.
-  bool IsLambda = Record[Idx++];
+  bool IsLambda = Record.readInt();
   if (IsLambda)
     DD = new (C) CXXRecordDecl::LambdaDefinitionData(D, nullptr, false, false,
                                                      LCD_None);
   else
     DD = new (C) struct CXXRecordDecl::DefinitionData(D);
 
-  ReadCXXDefinitionData(*DD, Record, Idx);
+  ReadCXXDefinitionData(*DD);
 
   // We might already have a definition for this record. This can happen either
   // because we're reading an update record, or because we've already done some
@@ -1726,7 +1735,7 @@
   enum CXXRecKind {
     CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
   };
-  switch ((CXXRecKind)Record[Idx++]) {
+  switch ((CXXRecKind)Record.readInt()) {
   case CXXRecNotTemplate:
     // Merged when we merge the folding set entry in the primary template.
     if (!isa<ClassTemplateSpecializationDecl>(D))
@@ -1734,7 +1743,7 @@
     break;
   case CXXRecTemplate: {
     // Merged when we merge the template.
-    ClassTemplateDecl *Template = ReadDeclAs<ClassTemplateDecl>(Record, Idx);
+    ClassTemplateDecl *Template = ReadDeclAs<ClassTemplateDecl>();
     D->TemplateOrInstantiation = Template;
     if (!Template->getTemplatedDecl()) {
       // We've not actually loaded the ClassTemplateDecl yet, because we're
@@ -1748,9 +1757,10 @@
     break;
   }
   case CXXRecMemberSpecialization: {
-    CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(Record, Idx);
-    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
-    SourceLocation POI = ReadSourceLocation(Record, Idx);
+    CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>();
+    TemplateSpecializationKind TSK =
+        (TemplateSpecializationKind)Record.readInt();
+    SourceLocation POI = ReadSourceLocation();
     MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK);
     MSI->setPointOfInstantiation(POI);
     D->TemplateOrInstantiation = MSI;
@@ -1759,7 +1769,7 @@
   }
   }
 
-  bool WasDefinition = Record[Idx++];
+  bool WasDefinition = Record.readInt();
   if (WasDefinition)
     ReadCXXRecordDefinition(D, /*Update*/false);
   else
@@ -1769,7 +1779,7 @@
   // Lazily load the key function to avoid deserializing every method so we can
   // compute it.
   if (WasDefinition) {
-    DeclID KeyFn = ReadDeclID(Record, Idx);
+    DeclID KeyFn = ReadDeclID();
     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
@@ -1780,21 +1790,25 @@
   return Redecl;
 }
 
+void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
+  VisitFunctionDecl(D);
+}
+
 void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
   VisitFunctionDecl(D);
 
-  unsigned NumOverridenMethods = Record[Idx++];
+  unsigned NumOverridenMethods = Record.readInt();
   if (D->isCanonicalDecl()) {
     while (NumOverridenMethods--) {
       // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
       // MD may be initializing.
-      if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx))
+      if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>())
         Reader.getContext().addOverriddenMethod(D, MD->getCanonicalDecl());
     }
   } else {
     // We don't care about which declarations this used to override; we get
     // the relevant information from the canonical declaration.
-    Idx += NumOverridenMethods;
+    Record.skipInts(NumOverridenMethods);
   }
 }
 
@@ -1802,21 +1816,19 @@
   // We need the inherited constructor information to merge the declaration,
   // so we have to read it before we call VisitCXXMethodDecl.
   if (D->isInheritingConstructor()) {
-    auto *Shadow = ReadDeclAs<ConstructorUsingShadowDecl>(Record, Idx);
-    auto *Ctor = ReadDeclAs<CXXConstructorDecl>(Record, Idx);
+    auto *Shadow = ReadDeclAs<ConstructorUsingShadowDecl>();
+    auto *Ctor = ReadDeclAs<CXXConstructorDecl>();
     *D->getTrailingObjects<InheritedConstructor>() =
         InheritedConstructor(Shadow, Ctor);
   }
 
   VisitCXXMethodDecl(D);
-
-  D->IsExplicitSpecified = Record[Idx++];
 }
 
 void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
   VisitCXXMethodDecl(D);
 
-  if (auto *OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx)) {
+  if (auto *OperatorDelete = ReadDeclAs<FunctionDecl>()) {
     auto *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl());
     // FIXME: Check consistency if we have an old and new operator delete.
     if (!Canon->OperatorDelete)
@@ -1826,65 +1838,64 @@
 
 void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
   VisitCXXMethodDecl(D);
-  D->IsExplicitSpecified = Record[Idx++];
 }
 
 void ASTDeclReader::VisitImportDecl(ImportDecl *D) {
   VisitDecl(D);
-  D->ImportedAndComplete.setPointer(readModule(Record, Idx));
-  D->ImportedAndComplete.setInt(Record[Idx++]);
+  D->ImportedAndComplete.setPointer(readModule());
+  D->ImportedAndComplete.setInt(Record.readInt());
   SourceLocation *StoredLocs = D->getTrailingObjects<SourceLocation>();
   for (unsigned I = 0, N = Record.back(); I != N; ++I)
-    StoredLocs[I] = ReadSourceLocation(Record, Idx);
-  ++Idx; // The number of stored source locations.
+    StoredLocs[I] = ReadSourceLocation();
+  Record.skipInts(1); // The number of stored source locations.
 }
 
 void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
   VisitDecl(D);
-  D->setColonLoc(ReadSourceLocation(Record, Idx));
+  D->setColonLoc(ReadSourceLocation());
 }
 
 void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
   VisitDecl(D);
-  if (Record[Idx++]) // hasFriendDecl
-    D->Friend = ReadDeclAs<NamedDecl>(Record, Idx);
+  if (Record.readInt()) // hasFriendDecl
+    D->Friend = ReadDeclAs<NamedDecl>();
   else
-    D->Friend = GetTypeSourceInfo(Record, Idx);
+    D->Friend = GetTypeSourceInfo();
   for (unsigned i = 0; i != D->NumTPLists; ++i)
     D->getTrailingObjects<TemplateParameterList *>()[i] =
-        Reader.ReadTemplateParameterList(F, Record, Idx);
-  D->NextFriend = ReadDeclID(Record, Idx);
-  D->UnsupportedFriend = (Record[Idx++] != 0);
-  D->FriendLoc = ReadSourceLocation(Record, Idx);
+        Record.readTemplateParameterList();
+  D->NextFriend = ReadDeclID();
+  D->UnsupportedFriend = (Record.readInt() != 0);
+  D->FriendLoc = ReadSourceLocation();
 }
 
 void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
   VisitDecl(D);
-  unsigned NumParams = Record[Idx++];
+  unsigned NumParams = Record.readInt();
   D->NumParams = NumParams;
   D->Params = new TemplateParameterList*[NumParams];
   for (unsigned i = 0; i != NumParams; ++i)
-    D->Params[i] = Reader.ReadTemplateParameterList(F, Record, Idx);
-  if (Record[Idx++]) // HasFriendDecl
-    D->Friend = ReadDeclAs<NamedDecl>(Record, Idx);
+    D->Params[i] = Record.readTemplateParameterList();
+  if (Record.readInt()) // HasFriendDecl
+    D->Friend = ReadDeclAs<NamedDecl>();
   else
-    D->Friend = GetTypeSourceInfo(Record, Idx);
-  D->FriendLoc = ReadSourceLocation(Record, Idx);
+    D->Friend = GetTypeSourceInfo();
+  D->FriendLoc = ReadSourceLocation();
 }
 
 DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
   VisitNamedDecl(D);
 
-  DeclID PatternID = ReadDeclID(Record, Idx);
+  DeclID PatternID = ReadDeclID();
   NamedDecl *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID));
-  TemplateParameterList* TemplateParams
-      = Reader.ReadTemplateParameterList(F, Record, Idx); 
+  TemplateParameterList *TemplateParams = Record.readTemplateParameterList();
+  // FIXME handle associated constraints
   D->init(TemplatedDecl, TemplateParams);
 
   return PatternID;
 }
 
-ASTDeclReader::RedeclarableResult 
+ASTDeclReader::RedeclarableResult
 ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   RedeclarableResult Redecl = VisitRedeclarable(D);
 
@@ -1901,17 +1912,17 @@
   // for the 'common' pointer.
   if (ThisDeclID == Redecl.getFirstID()) {
     if (RedeclarableTemplateDecl *RTD
-          = ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx)) {
+          = ReadDeclAs<RedeclarableTemplateDecl>()) {
       assert(RTD->getKind() == D->getKind() &&
              "InstantiatedFromMemberTemplate kind mismatch");
       D->setInstantiatedFromMemberTemplate(RTD);
-      if (Record[Idx++])
+      if (Record.readInt())
         D->setMemberSpecialization();
     }
   }
 
   DeclID PatternID = VisitTemplateDecl(D);
-  D->IdentifierNamespace = Record[Idx++];
+  D->IdentifierNamespace = Record.readInt();
 
   mergeRedeclarable(D, Redecl, PatternID);
 
@@ -1991,14 +2002,14 @@
 ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
     ClassTemplateSpecializationDecl *D) {
   RedeclarableResult Redecl = VisitCXXRecordDeclImpl(D);
-  
+
   ASTContext &C = Reader.getContext();
-  if (Decl *InstD = ReadDecl(Record, Idx)) {
+  if (Decl *InstD = ReadDecl()) {
     if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
       D->SpecializedTemplate = CTD;
     } else {
       SmallVector<TemplateArgument, 8> TemplArgs;
-      Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
+      Record.readTemplateArgumentList(TemplArgs);
       TemplateArgumentList *ArgList
         = TemplateArgumentList::CreateCopy(C, TemplArgs);
       ClassTemplateSpecializationDecl::SpecializedPartialSpecialization *PS
@@ -2012,15 +2023,14 @@
   }
 
   SmallVector<TemplateArgument, 8> TemplArgs;
-  Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx,
-                                  /*Canonicalize*/ true);
+  Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
   D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
-  D->PointOfInstantiation = ReadSourceLocation(Record, Idx);
-  D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++];
+  D->PointOfInstantiation = ReadSourceLocation();
+  D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
 
-  bool writtenAsCanonicalDecl = Record[Idx++];
+  bool writtenAsCanonicalDecl = Record.readInt();
   if (writtenAsCanonicalDecl) {
-    ClassTemplateDecl *CanonPattern = ReadDeclAs<ClassTemplateDecl>(Record,Idx);
+    ClassTemplateDecl *CanonPattern = ReadDeclAs<ClassTemplateDecl>();
     if (D->isCanonicalDecl()) { // It's kept in the folding set.
       // Set this as, or find, the canonical declaration for this specialization
       ClassTemplateSpecializationDecl *CanonSpec;
@@ -2050,12 +2060,12 @@
   }
 
   // Explicit info.
-  if (TypeSourceInfo *TyInfo = GetTypeSourceInfo(Record, Idx)) {
+  if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) {
     ClassTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo
         = new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo;
     ExplicitInfo->TypeAsWritten = TyInfo;
-    ExplicitInfo->ExternLoc = ReadSourceLocation(Record, Idx);
-    ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(Record, Idx);
+    ExplicitInfo->ExternLoc = ReadSourceLocation();
+    ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation();
     D->ExplicitInfo = ExplicitInfo;
   }
 
@@ -2066,21 +2076,21 @@
                                     ClassTemplatePartialSpecializationDecl *D) {
   RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D);
 
-  D->TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx);
-  D->ArgsAsWritten = Reader.ReadASTTemplateArgumentListInfo(F, Record, Idx);
+  D->TemplateParams = Record.readTemplateParameterList();
+  D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
 
   // These are read/set from/to the first declaration.
   if (ThisDeclID == Redecl.getFirstID()) {
     D->InstantiatedFromMember.setPointer(
-      ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx));
-    D->InstantiatedFromMember.setInt(Record[Idx++]);
+      ReadDeclAs<ClassTemplatePartialSpecializationDecl>());
+    D->InstantiatedFromMember.setInt(Record.readInt());
   }
 }
 
 void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
                                     ClassScopeFunctionSpecializationDecl *D) {
   VisitDecl(D);
-  D->Specialization = ReadDeclAs<CXXMethodDecl>(Record, Idx);
+  D->Specialization = ReadDeclAs<CXXMethodDecl>();
 }
 
 void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
@@ -2110,12 +2120,12 @@
   RedeclarableResult Redecl = VisitVarDeclImpl(D);
 
   ASTContext &C = Reader.getContext();
-  if (Decl *InstD = ReadDecl(Record, Idx)) {
+  if (Decl *InstD = ReadDecl()) {
     if (VarTemplateDecl *VTD = dyn_cast<VarTemplateDecl>(InstD)) {
       D->SpecializedTemplate = VTD;
     } else {
       SmallVector<TemplateArgument, 8> TemplArgs;
-      Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
+      Record.readTemplateArgumentList(TemplArgs);
       TemplateArgumentList *ArgList = TemplateArgumentList::CreateCopy(
           C, TemplArgs);
       VarTemplateSpecializationDecl::SpecializedPartialSpecialization *PS =
@@ -2129,25 +2139,24 @@
   }
 
   // Explicit info.
-  if (TypeSourceInfo *TyInfo = GetTypeSourceInfo(Record, Idx)) {
+  if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) {
     VarTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo =
         new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo;
     ExplicitInfo->TypeAsWritten = TyInfo;
-    ExplicitInfo->ExternLoc = ReadSourceLocation(Record, Idx);
-    ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(Record, Idx);
+    ExplicitInfo->ExternLoc = ReadSourceLocation();
+    ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation();
     D->ExplicitInfo = ExplicitInfo;
   }
 
   SmallVector<TemplateArgument, 8> TemplArgs;
-  Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx,
-                                  /*Canonicalize*/ true);
+  Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
   D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
-  D->PointOfInstantiation = ReadSourceLocation(Record, Idx);
-  D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++];
+  D->PointOfInstantiation = ReadSourceLocation();
+  D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
 
-  bool writtenAsCanonicalDecl = Record[Idx++];
+  bool writtenAsCanonicalDecl = Record.readInt();
   if (writtenAsCanonicalDecl) {
-    VarTemplateDecl *CanonPattern = ReadDeclAs<VarTemplateDecl>(Record, Idx);
+    VarTemplateDecl *CanonPattern = ReadDeclAs<VarTemplateDecl>();
     if (D->isCanonicalDecl()) { // It's kept in the folding set.
       // FIXME: If it's already present, merge it.
       if (VarTemplatePartialSpecializationDecl *Partial =
@@ -2172,63 +2181,63 @@
     VarTemplatePartialSpecializationDecl *D) {
   RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D);
 
-  D->TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx);
-  D->ArgsAsWritten = Reader.ReadASTTemplateArgumentListInfo(F, Record, Idx);
+  D->TemplateParams = Record.readTemplateParameterList();
+  D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
 
   // These are read/set from/to the first declaration.
   if (ThisDeclID == Redecl.getFirstID()) {
     D->InstantiatedFromMember.setPointer(
-        ReadDeclAs<VarTemplatePartialSpecializationDecl>(Record, Idx));
-    D->InstantiatedFromMember.setInt(Record[Idx++]);
+        ReadDeclAs<VarTemplatePartialSpecializationDecl>());
+    D->InstantiatedFromMember.setInt(Record.readInt());
   }
 }
 
 void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   VisitTypeDecl(D);
 
-  D->setDeclaredWithTypename(Record[Idx++]);
+  D->setDeclaredWithTypename(Record.readInt());
 
-  if (Record[Idx++])
-    D->setDefaultArgument(GetTypeSourceInfo(Record, Idx));
+  if (Record.readInt())
+    D->setDefaultArgument(GetTypeSourceInfo());
 }
 
 void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
   VisitDeclaratorDecl(D);
   // TemplateParmPosition.
-  D->setDepth(Record[Idx++]);
-  D->setPosition(Record[Idx++]);
+  D->setDepth(Record.readInt());
+  D->setPosition(Record.readInt());
   if (D->isExpandedParameterPack()) {
     auto TypesAndInfos =
         D->getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
     for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
-      new (&TypesAndInfos[I].first) QualType(Reader.readType(F, Record, Idx));
-      TypesAndInfos[I].second = GetTypeSourceInfo(Record, Idx);
+      new (&TypesAndInfos[I].first) QualType(Record.readType());
+      TypesAndInfos[I].second = GetTypeSourceInfo();
     }
   } else {
     // Rest of NonTypeTemplateParmDecl.
-    D->ParameterPack = Record[Idx++];
-    if (Record[Idx++])
-      D->setDefaultArgument(Reader.ReadExpr(F));
+    D->ParameterPack = Record.readInt();
+    if (Record.readInt())
+      D->setDefaultArgument(Record.readExpr());
   }
 }
 
 void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
   VisitTemplateDecl(D);
   // TemplateParmPosition.
-  D->setDepth(Record[Idx++]);
-  D->setPosition(Record[Idx++]);
+  D->setDepth(Record.readInt());
+  D->setPosition(Record.readInt());
   if (D->isExpandedParameterPack()) {
     TemplateParameterList **Data =
         D->getTrailingObjects<TemplateParameterList *>();
     for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
          I != N; ++I)
-      Data[I] = Reader.ReadTemplateParameterList(F, Record, Idx);
+      Data[I] = Record.readTemplateParameterList();
   } else {
     // Rest of TemplateTemplateParmDecl.
-    D->ParameterPack = Record[Idx++];
-    if (Record[Idx++])
+    D->ParameterPack = Record.readInt();
+    if (Record.readInt())
       D->setDefaultArgument(Reader.getContext(),
-                            Reader.ReadTemplateArgumentLoc(F, Record, Idx));
+                            Record.readTemplateArgumentLoc());
   }
 }
 
@@ -2238,10 +2247,10 @@
 
 void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
   VisitDecl(D);
-  D->AssertExprAndFailed.setPointer(Reader.ReadExpr(F));
-  D->AssertExprAndFailed.setInt(Record[Idx++]);
-  D->Message = cast_or_null<StringLiteral>(Reader.ReadExpr(F));
-  D->RParenLoc = ReadSourceLocation(Record, Idx);
+  D->AssertExprAndFailed.setPointer(Record.readExpr());
+  D->AssertExprAndFailed.setInt(Record.readInt());
+  D->Message = cast_or_null<StringLiteral>(Record.readExpr());
+  D->RParenLoc = ReadSourceLocation();
 }
 
 void ASTDeclReader::VisitEmptyDecl(EmptyDecl *D) {
@@ -2250,15 +2259,15 @@
 
 std::pair<uint64_t, uint64_t>
 ASTDeclReader::VisitDeclContext(DeclContext *DC) {
-  uint64_t LexicalOffset = ReadLocalOffset(Record, Idx);
-  uint64_t VisibleOffset = ReadLocalOffset(Record, Idx);
+  uint64_t LexicalOffset = ReadLocalOffset();
+  uint64_t VisibleOffset = ReadLocalOffset();
   return std::make_pair(LexicalOffset, VisibleOffset);
 }
 
 template <typename T>
 ASTDeclReader::RedeclarableResult
 ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
-  DeclID FirstDeclID = ReadDeclID(Record, Idx);
+  DeclID FirstDeclID = ReadDeclID();
   Decl *MergeWith = nullptr;
 
   bool IsKeyDecl = ThisDeclID == FirstDeclID;
@@ -2272,7 +2281,7 @@
     FirstDeclID = ThisDeclID;
     IsKeyDecl = true;
     IsFirstLocalDecl = true;
-  } else if (unsigned N = Record[Idx++]) {
+  } else if (unsigned N = Record.readInt()) {
     // This declaration was the first local declaration, but may have imported
     // other declarations.
     IsKeyDecl = N == 1;
@@ -2284,13 +2293,13 @@
     // FIXME: Provide a known merge target to the second and subsequent such
     // declaration.
     for (unsigned I = 0; I != N - 1; ++I)
-      MergeWith = ReadDecl(Record, Idx/*, MergeWith*/);
+      MergeWith = ReadDecl();
 
-    RedeclOffset = ReadLocalOffset(Record, Idx);
+    RedeclOffset = ReadLocalOffset();
   } else {
     // This declaration was not the first local declaration. Read the first
     // local declaration now, to trigger the import of other redeclarations.
-    (void)ReadDecl(Record, Idx);
+    (void)ReadDecl();
   }
 
   T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
@@ -2301,7 +2310,7 @@
     // loaded & attached later on.
     D->RedeclLink = Redeclarable<T>::PreviousDeclLink(FirstDecl);
     D->First = FirstDecl->getCanonicalDecl();
-  }    
+  }
 
   T *DAsT = static_cast<T*>(D);
 
@@ -2354,10 +2363,10 @@
                                          DeclID DsID, bool IsKeyDecl) {
   auto *DPattern = D->getTemplatedDecl();
   auto *ExistingPattern = Existing->getTemplatedDecl();
-  RedeclarableResult Result(/*MergeWith*/ ExistingPattern,  
-                            DPattern->getCanonicalDecl()->getGlobalID(), 
+  RedeclarableResult Result(/*MergeWith*/ ExistingPattern,
+                            DPattern->getCanonicalDecl()->getGlobalID(),
                             IsKeyDecl);
-  
+
   if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
     // Merge with any existing definition.
     // FIXME: This is duplicated in several places. Refactor.
@@ -2457,17 +2466,17 @@
   SmallVector<Expr *, 16> Vars;
   Vars.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i) {
-    Vars.push_back(Reader.ReadExpr(F));
+    Vars.push_back(Record.readExpr());
   }
   D->setVars(Vars);
 }
 
 void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
   VisitValueDecl(D);
-  D->setLocation(Reader.ReadSourceLocation(F, Record, Idx));
-  D->setCombiner(Reader.ReadExpr(F));
-  D->setInitializer(Reader.ReadExpr(F));
-  D->PrevDeclInScope = Reader.ReadDeclID(F, Record, Idx);
+  D->setLocation(ReadSourceLocation());
+  D->setCombiner(Record.readExpr());
+  D->setInitializer(Record.readExpr());
+  D->PrevDeclInScope = ReadDeclID();
 }
 
 void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
@@ -2479,12 +2488,11 @@
 //===----------------------------------------------------------------------===//
 
 /// \brief Reads attributes from the current stream position.
-void ASTReader::ReadAttributes(ModuleFile &F, AttrVec &Attrs,
-                               const RecordData &Record, unsigned &Idx) {
-  for (unsigned i = 0, e = Record[Idx++]; i != e; ++i) {
+void ASTReader::ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs) {
+  for (unsigned i = 0, e = Record.readInt(); i != e; ++i) {
     Attr *New = nullptr;
-    attr::Kind Kind = (attr::Kind)Record[Idx++];
-    SourceRange Range = ReadSourceRange(F, Record, Idx);
+    attr::Kind Kind = (attr::Kind)Record.readInt();
+    SourceRange Range = Record.readSourceRange();
 
 #include "clang/Serialization/AttrPCHRead.inc"
 
@@ -2521,8 +2529,8 @@
 
   // An ImportDecl or VarDecl imported from a module will get emitted when
   // we import the relevant module.
-  if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && Ctx.DeclMustBeEmitted(D) &&
-      D->getImportedOwningModule())
+  if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && D->getImportedOwningModule() &&
+      Ctx.DeclMustBeEmitted(D))
     return false;
 
   if (isa<FileScopeAsmDecl>(D) || 
@@ -2656,6 +2664,45 @@
   return true;
 }
 
+/// Determine whether the attributes we can overload on are identical for A and
+/// B. Will ignore any overloadable attrs represented in the type of A and B.
+static bool hasSameOverloadableAttrs(const FunctionDecl *A,
+                                     const FunctionDecl *B) {
+  // Note that pass_object_size attributes are represented in the function's
+  // ExtParameterInfo, so we don't need to check them here.
+
+  SmallVector<const EnableIfAttr *, 4> AEnableIfs;
+  // Since this is an equality check, we can ignore that enable_if attrs show up
+  // in reverse order.
+  for (const auto *EIA : A->specific_attrs<EnableIfAttr>())
+    AEnableIfs.push_back(EIA);
+
+  SmallVector<const EnableIfAttr *, 4> BEnableIfs;
+  for (const auto *EIA : B->specific_attrs<EnableIfAttr>())
+    BEnableIfs.push_back(EIA);
+
+  // Two very common cases: either we have 0 enable_if attrs, or we have an
+  // unequal number of enable_if attrs.
+  if (AEnableIfs.empty() && BEnableIfs.empty())
+    return true;
+
+  if (AEnableIfs.size() != BEnableIfs.size())
+    return false;
+
+  llvm::FoldingSetNodeID Cand1ID, Cand2ID;
+  for (unsigned I = 0, E = AEnableIfs.size(); I != E; ++I) {
+    Cand1ID.clear();
+    Cand2ID.clear();
+
+    AEnableIfs[I]->getCond()->Profile(Cand1ID, A->getASTContext(), true);
+    BEnableIfs[I]->getCond()->Profile(Cand2ID, B->getASTContext(), true);
+    if (Cand1ID != Cand2ID)
+      return false;
+  }
+
+  return true;
+}
+
 /// \brief Determine whether the two declarations refer to the same entity.
 static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
   assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");
@@ -2711,8 +2758,24 @@
                         CtorY->getInheritedConstructor().getConstructor()))
         return false;
     }
-    return (FuncX->getLinkageInternal() == FuncY->getLinkageInternal()) &&
-      FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType());
+    ASTContext &C = FuncX->getASTContext();
+    if (!C.hasSameType(FuncX->getType(), FuncY->getType())) {
+      // We can get functions with different types on the redecl chain in C++17
+      // if they have differing exception specifications and at least one of
+      // the excpetion specs is unresolved.
+      // FIXME: Do we need to check for C++14 deduced return types here too?
+      auto *XFPT = FuncX->getType()->getAs<FunctionProtoType>();
+      auto *YFPT = FuncY->getType()->getAs<FunctionProtoType>();
+      if (C.getLangOpts().CPlusPlus1z && XFPT && YFPT &&
+          (isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) ||
+           isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) &&
+          C.hasSameFunctionTypeIgnoringExceptionSpec(FuncX->getType(),
+                                                     FuncY->getType()))
+        return true;
+      return false;
+    }
+    return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() &&
+           hasSameOverloadableAttrs(FuncX, FuncY);
   }
 
   // Variables with the same type and linkage match.
@@ -3265,13 +3328,12 @@
   Deserializing ADecl(this);
 
   DeclsCursor.JumpToBit(Loc.Offset);
-  RecordData Record;
+  ASTRecordReader Record(*this, *Loc.F);
+  ASTDeclReader Reader(*this, Record, Loc, ID, DeclLoc);
   unsigned Code = DeclsCursor.ReadCode();
-  unsigned Idx = 0;
-  ASTDeclReader Reader(*this, Loc, ID, DeclLoc, Record,Idx);
 
   Decl *D = nullptr;
-  switch ((DeclCode)DeclsCursor.readRecord(Code, Record)) {
+  switch ((DeclCode)Record.readRecord(DeclsCursor, Code)) {
   case DECL_CONTEXT_LEXICAL:
   case DECL_CONTEXT_VISIBLE:
     llvm_unreachable("Record cannot be de-serialized with ReadDeclRecord");
@@ -3311,6 +3373,9 @@
   case DECL_USING:
     D = UsingDecl::CreateDeserialized(Context, ID);
     break;
+  case DECL_USING_PACK:
+    D = UsingPackDecl::CreateDeserialized(Context, ID, Record.readInt());
+    break;
   case DECL_USING_SHADOW:
     D = UsingShadowDecl::CreateDeserialized(Context, ID);
     break;
@@ -3329,6 +3394,9 @@
   case DECL_CXX_RECORD:
     D = CXXRecordDecl::CreateDeserialized(Context, ID);
     break;
+  case DECL_CXX_DEDUCTION_GUIDE:
+    D = CXXDeductionGuideDecl::CreateDeserialized(Context, ID);
+    break;
   case DECL_CXX_METHOD:
     D = CXXMethodDecl::CreateDeserialized(Context, ID);
     break;
@@ -3348,7 +3416,7 @@
     D = AccessSpecDecl::CreateDeserialized(Context, ID);
     break;
   case DECL_FRIEND:
-    D = FriendDecl::CreateDeserialized(Context, ID, Record[Idx++]);
+    D = FriendDecl::CreateDeserialized(Context, ID, Record.readInt());
     break;
   case DECL_FRIEND_TEMPLATE:
     D = FriendTemplateDecl::CreateDeserialized(Context, ID);
@@ -3384,14 +3452,15 @@
     D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID);
     break;
   case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK:
-    D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, Record[Idx++]);
+    D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID,
+                                                    Record.readInt());
     break;
   case DECL_TEMPLATE_TEMPLATE_PARM:
     D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID);
     break;
   case DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK:
     D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID,
-                                                     Record[Idx++]);
+                                                     Record.readInt());
     break;
   case DECL_TYPE_ALIAS_TEMPLATE:
     D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID);
@@ -3448,7 +3517,7 @@
     D = ParmVarDecl::CreateDeserialized(Context, ID);
     break;
   case DECL_DECOMPOSITION:
-    D = DecompositionDecl::CreateDeserialized(Context, ID, Record[Idx++]);
+    D = DecompositionDecl::CreateDeserialized(Context, ID, Record.readInt());
     break;
   case DECL_BINDING:
     D = BindingDecl::CreateDeserialized(Context, ID);
@@ -3463,7 +3532,7 @@
     D = MSPropertyDecl::CreateDeserialized(Context, ID);
     break;
   case DECL_CAPTURED:
-    D = CapturedDecl::CreateDeserialized(Context, ID, Record[Idx++]);
+    D = CapturedDecl::CreateDeserialized(Context, ID, Record.readInt());
     break;
   case DECL_CXX_BASE_SPECIFIERS:
     Error("attempt to read a C++ base-specifier record as a declaration");
@@ -3477,7 +3546,7 @@
     D = ImportDecl::CreateDeserialized(Context, ID, Record.back());
     break;
   case DECL_OMP_THREADPRIVATE:
-    D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record[Idx++]);
+    D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record.readInt());
     break;
   case DECL_OMP_DECLARE_REDUCTION:
     D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID);
@@ -3486,11 +3555,11 @@
     D = OMPCapturedExprDecl::CreateDeserialized(Context, ID);
     break;
   case DECL_PRAGMA_COMMENT:
-    D = PragmaCommentDecl::CreateDeserialized(Context, ID, Record[Idx++]);
+    D = PragmaCommentDecl::CreateDeserialized(Context, ID, Record.readInt());
     break;
   case DECL_PRAGMA_DETECT_MISMATCH:
     D = PragmaDetectMismatchDecl::CreateDeserialized(Context, ID,
-                                                     Record[Idx++]);
+                                                     Record.readInt());
     break;
   case DECL_EMPTY:
     D = EmptyDecl::CreateDeserialized(Context, ID);
@@ -3519,7 +3588,7 @@
         ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, Offsets.second, ID))
       return nullptr;
   }
-  assert(Idx == Record.size());
+  assert(Record.getIdx() == Record.size());
 
   // Load any relevant update records.
   PendingUpdateRecords.push_back(std::make_pair(ID, D));
@@ -3559,16 +3628,15 @@
       llvm::BitstreamCursor &Cursor = F->DeclsCursor;
       SavedStreamPosition SavedPosition(Cursor);
       Cursor.JumpToBit(Offset);
-      RecordData Record;
       unsigned Code = Cursor.ReadCode();
-      unsigned RecCode = Cursor.readRecord(Code, Record);
+      ASTRecordReader Record(*this, *F);
+      unsigned RecCode = Record.readRecord(Cursor, Code);
       (void)RecCode;
       assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
 
-      unsigned Idx = 0;
-      ASTDeclReader Reader(*this, RecordLocation(F, Offset), ID,
-                           SourceLocation(), Record, Idx);
-      Reader.UpdateDecl(D, *F, Record);
+      ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID,
+                           SourceLocation());
+      Reader.UpdateDecl(D);
 
       // We might have made this declaration interesting. If so, remember that
       // we need to hand it off to the consumer.
@@ -3775,15 +3843,14 @@
   }
 }
 
-void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
-                               const RecordData &Record) {
-  while (Idx < Record.size()) {
-    switch ((DeclUpdateKind)Record[Idx++]) {
+void ASTDeclReader::UpdateDecl(Decl *D) {
+  while (Record.getIdx() < Record.size()) {
+    switch ((DeclUpdateKind)Record.readInt()) {
     case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
       auto *RD = cast<CXXRecordDecl>(D);
       // FIXME: If we also have an update record for instantiating the
       // definition of D, we need that to happen before we get here.
-      Decl *MD = Reader.ReadDecl(ModuleFile, Record, Idx);
+      Decl *MD = Record.readDecl();
       assert(MD && "couldn't read decl from update record");
       // FIXME: We should call addHiddenDecl instead, to add the member
       // to its DeclContext.
@@ -3793,17 +3860,16 @@
 
     case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
       // It will be added to the template's specializations set when loaded.
-      (void)Reader.ReadDecl(ModuleFile, Record, Idx);
+      (void)Record.readDecl();
       break;
 
     case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
-      NamespaceDecl *Anon
-        = Reader.ReadDeclAs<NamespaceDecl>(ModuleFile, Record, Idx);
-      
+      NamespaceDecl *Anon = ReadDeclAs<NamespaceDecl>();
+
       // Each module has its own anonymous namespace, which is disjoint from
       // any other module's anonymous namespaces, so don't attach the anonymous
       // namespace at all.
-      if (!ModuleFile.isModule()) {
+      if (!Record.isModule()) {
         if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D))
           TU->setAnonymousNamespace(Anon);
         else
@@ -3814,7 +3880,7 @@
 
     case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
       cast<VarDecl>(D)->getMemberSpecializationInfo()->setPointOfInstantiation(
-          Reader.ReadSourceLocation(ModuleFile, Record, Idx));
+          ReadSourceLocation());
       break;
 
     case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT: {
@@ -3823,7 +3889,7 @@
       // We have to read the default argument regardless of whether we use it
       // so that hypothetical further update records aren't messed up.
       // TODO: Add a function to skip over the next expr record.
-      auto DefaultArg = Reader.ReadExpr(F);
+      auto DefaultArg = Record.readExpr();
 
       // Only apply the update if the parameter still has an uninstantiated
       // default argument.
@@ -3834,7 +3900,7 @@
 
     case UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER: {
       auto FD = cast<FieldDecl>(D);
-      auto DefaultInit = Reader.ReadExpr(F);
+      auto DefaultInit = Record.readExpr();
 
       // Only apply the update if the field still has an uninstantiated
       // default member initializer.
@@ -3857,7 +3923,7 @@
         return;
       }
 
-      if (Record[Idx++]) {
+      if (Record.readInt()) {
         // Maintain AST consistency: any later redeclarations of this function
         // are inline if this one is. (We might have merged another declaration
         // into this one.)
@@ -3865,16 +3931,9 @@
           FD->setImplicitlyInline();
         });
       }
-      FD->setInnerLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
-      if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
-        CD->NumCtorInitializers = Record[Idx++];
-        if (CD->NumCtorInitializers)
-          CD->CtorInitializers = ReadGlobalOffset(F, Record, Idx);
-      }
-      // Store the offset of the body so we can lazily load it later.
-      Reader.PendingBodies[FD] = GetCurrentCursorOffset();
-      HasPendingBody = true;
-      assert(Idx == Record.size() && "lazy body must be last");
+      FD->setInnerLocStart(ReadSourceLocation());
+      ReadFunctionDefinition(FD);
+      assert(Record.getIdx() == Record.size() && "lazy body must be last");
       break;
     }
 
@@ -3887,15 +3946,14 @@
       ReadCXXRecordDefinition(RD, /*Update*/true);
 
       // Visible update is handled separately.
-      uint64_t LexicalOffset = ReadLocalOffset(Record, Idx);
+      uint64_t LexicalOffset = ReadLocalOffset();
       if (!HadRealDefinition && LexicalOffset) {
-        Reader.ReadLexicalDeclContextStorage(ModuleFile, ModuleFile.DeclsCursor,
-                                             LexicalOffset, RD);
+        Record.readLexicalDeclContextStorage(LexicalOffset, RD);
         Reader.PendingFakeDefinitionData.erase(OldDD);
       }
 
-      auto TSK = (TemplateSpecializationKind)Record[Idx++];
-      SourceLocation POI = Reader.ReadSourceLocation(ModuleFile, Record, Idx);
+      auto TSK = (TemplateSpecializationKind)Record.readInt();
+      SourceLocation POI = ReadSourceLocation();
       if (MemberSpecializationInfo *MSInfo =
               RD->getMemberSpecializationInfo()) {
         MSInfo->setTemplateSpecializationKind(TSK);
@@ -3906,11 +3964,11 @@
         Spec->setTemplateSpecializationKind(TSK);
         Spec->setPointOfInstantiation(POI);
 
-        if (Record[Idx++]) {
+        if (Record.readInt()) {
           auto PartialSpec =
-              ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx);
+              ReadDeclAs<ClassTemplatePartialSpecializationDecl>();
           SmallVector<TemplateArgument, 8> TemplArgs;
-          Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
+          Record.readTemplateArgumentList(TemplArgs);
           auto *TemplArgList = TemplateArgumentList::CreateCopy(
               Reader.getContext(), TemplArgs);
 
@@ -3922,14 +3980,14 @@
         }
       }
 
-      RD->setTagKind((TagTypeKind)Record[Idx++]);
-      RD->setLocation(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
-      RD->setLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
-      RD->setBraceRange(Reader.ReadSourceRange(ModuleFile, Record, Idx));
+      RD->setTagKind((TagTypeKind)Record.readInt());
+      RD->setLocation(ReadSourceLocation());
+      RD->setLocStart(ReadSourceLocation());
+      RD->setBraceRange(ReadSourceRange());
 
-      if (Record[Idx++]) {
+      if (Record.readInt()) {
         AttrVec Attrs;
-        Reader.ReadAttributes(F, Attrs, Record, Idx);
+        Record.readAttributes(Attrs);
         // If the declaration already has attributes, we assume that some other
         // AST file already loaded them.
         if (!D->hasAttrs())
@@ -3941,7 +3999,7 @@
     case UPD_CXX_RESOLVED_DTOR_DELETE: {
       // Set the 'operator delete' directly to avoid emitting another update
       // record.
-      auto *Del = Reader.ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
+      auto *Del = ReadDeclAs<FunctionDecl>();
       auto *First = cast<CXXDestructorDecl>(D->getCanonicalDecl());
       // FIXME: Check consistency if we have an old and new operator delete.
       if (!First->OperatorDelete)
@@ -3952,7 +4010,7 @@
     case UPD_CXX_RESOLVED_EXCEPTION_SPEC: {
       FunctionProtoType::ExceptionSpecInfo ESI;
       SmallVector<QualType, 8> ExceptionStorage;
-      Reader.readExceptionSpec(ModuleFile, ExceptionStorage, ESI, Record, Idx);
+      Record.readExceptionSpec(ExceptionStorage, ESI);
 
       // Update this declaration's exception specification, if needed.
       auto *FD = cast<FunctionDecl>(D);
@@ -3974,7 +4032,7 @@
 
     case UPD_CXX_DEDUCED_RETURN_TYPE: {
       // FIXME: Also do this when merging redecls.
-      QualType DeducedResultType = Reader.readType(ModuleFile, Record, Idx);
+      QualType DeducedResultType = Record.readType();
       for (auto *Redecl : merged_redecls(D)) {
         // FIXME: If the return type is already deduced, check that it matches.
         FunctionDecl *FD = cast<FunctionDecl>(Redecl);
@@ -3990,20 +4048,20 @@
     }
 
     case UPD_MANGLING_NUMBER:
-      Reader.Context.setManglingNumber(cast<NamedDecl>(D), Record[Idx++]);
+      Reader.Context.setManglingNumber(cast<NamedDecl>(D), Record.readInt());
       break;
 
     case UPD_STATIC_LOCAL_NUMBER:
-      Reader.Context.setStaticLocalNumber(cast<VarDecl>(D), Record[Idx++]);
+      Reader.Context.setStaticLocalNumber(cast<VarDecl>(D), Record.readInt());
       break;
 
     case UPD_DECL_MARKED_OPENMP_THREADPRIVATE:
       D->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
-          Reader.Context, ReadSourceRange(Record, Idx)));
+          Reader.Context, ReadSourceRange()));
       break;
 
     case UPD_DECL_EXPORTED: {
-      unsigned SubmoduleID = readSubmoduleID(Record, Idx);
+      unsigned SubmoduleID = readSubmoduleID();
       auto *Exported = cast<NamedDecl>(D);
       if (auto *TD = dyn_cast<TagDecl>(Exported))
         Exported = TD->getDefinition();
@@ -4027,7 +4085,7 @@
     case UPD_DECL_MARKED_OPENMP_DECLARETARGET:
     case UPD_ADDED_ATTR_TO_RECORD:
       AttrVec Attrs;
-      Reader.ReadAttributes(F, Attrs, Record, Idx);
+      Record.readAttributes(Attrs);
       assert(Attrs.size() == 1);
       D->addAttr(Attrs[0]);
       break;
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 032ceef..6a4482b 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -26,62 +26,47 @@
 
   class ASTStmtReader : public StmtVisitor<ASTStmtReader> {
     friend class OMPClauseReader;
-    typedef ASTReader::RecordData RecordData;
-    
-    ASTReader &Reader;
-    ModuleFile &F;
+
+    ASTRecordReader &Record;
     llvm::BitstreamCursor &DeclsCursor;
-    const ASTReader::RecordData &Record;
-    unsigned &Idx;
 
-    Token ReadToken(const RecordData &R, unsigned &I) {
-      return Reader.ReadToken(F, R, I);
+    SourceLocation ReadSourceLocation() {
+      return Record.readSourceLocation();
     }
 
-    SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) {
-      return Reader.ReadSourceLocation(F, R, I);
+    SourceRange ReadSourceRange() {
+      return Record.readSourceRange();
     }
 
-    SourceRange ReadSourceRange(const RecordData &R, unsigned &I) {
-      return Reader.ReadSourceRange(F, R, I);
+    std::string ReadString() {
+      return Record.readString();
     }
 
-    std::string ReadString(const RecordData &R, unsigned &I) {
-      return Reader.ReadString(R, I);
+    TypeSourceInfo *GetTypeSourceInfo() {
+      return Record.getTypeSourceInfo();
     }
-        
-    TypeSourceInfo *GetTypeSourceInfo(const RecordData &R, unsigned &I) {
-      return Reader.GetTypeSourceInfo(F, R, I);
+
+    Decl *ReadDecl() {
+      return Record.readDecl();
     }
-    
-    serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {
-      return Reader.ReadDeclID(F, R, I);
-    }
-    
-    Decl *ReadDecl(const RecordData &R, unsigned &I) {
-      return Reader.ReadDecl(F, R, I);
-    }
-    
+
     template<typename T>
-    T *ReadDeclAs(const RecordData &R, unsigned &I) {
-      return Reader.ReadDeclAs<T>(F, R, I);
+    T *ReadDeclAs() {
+      return Record.readDeclAs<T>();
     }
 
-    void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name,
-                                const ASTReader::RecordData &R, unsigned &I) {
-      Reader.ReadDeclarationNameLoc(F, DNLoc, Name, R, I);
+    void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc,
+                                DeclarationName Name) {
+      Record.readDeclarationNameLoc(DNLoc, Name);
     }
-    
-    void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo,
-                                const ASTReader::RecordData &R, unsigned &I) {
-      Reader.ReadDeclarationNameInfo(F, NameInfo, R, I);
+
+    void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo) {
+      Record.readDeclarationNameInfo(NameInfo);
     }
 
   public:
-    ASTStmtReader(ASTReader &Reader, ModuleFile &F,
-                  llvm::BitstreamCursor &Cursor,
-                  const ASTReader::RecordData &Record, unsigned &Idx)
-      : Reader(Reader), F(F), DeclsCursor(Cursor), Record(Record), Idx(Idx) { }
+    ASTStmtReader(ASTRecordReader &Record, llvm::BitstreamCursor &Cursor)
+        : Record(Record), DeclsCursor(Cursor) {}
 
     /// \brief The number of record fields required for the Stmt class
     /// itself.
@@ -109,106 +94,103 @@
 void ASTStmtReader::ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
                                               TemplateArgumentLoc *ArgsLocArray,
                                               unsigned NumTemplateArgs) {
-  SourceLocation TemplateKWLoc = ReadSourceLocation(Record, Idx);
+  SourceLocation TemplateKWLoc = ReadSourceLocation();
   TemplateArgumentListInfo ArgInfo;
-  ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx));
-  ArgInfo.setRAngleLoc(ReadSourceLocation(Record, Idx));
+  ArgInfo.setLAngleLoc(ReadSourceLocation());
+  ArgInfo.setRAngleLoc(ReadSourceLocation());
   for (unsigned i = 0; i != NumTemplateArgs; ++i)
-    ArgInfo.addArgument(
-        Reader.ReadTemplateArgumentLoc(F, Record, Idx));
+    ArgInfo.addArgument(Record.readTemplateArgumentLoc());
   Args.initializeFrom(TemplateKWLoc, ArgInfo, ArgsLocArray);
 }
 
 void ASTStmtReader::VisitStmt(Stmt *S) {
-  assert(Idx == NumStmtFields && "Incorrect statement field count");
+  assert(Record.getIdx() == NumStmtFields && "Incorrect statement field count");
 }
 
 void ASTStmtReader::VisitNullStmt(NullStmt *S) {
   VisitStmt(S);
-  S->setSemiLoc(ReadSourceLocation(Record, Idx));
-  S->HasLeadingEmptyMacro = Record[Idx++];
+  S->setSemiLoc(ReadSourceLocation());
+  S->HasLeadingEmptyMacro = Record.readInt();
 }
 
 void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
   VisitStmt(S);
   SmallVector<Stmt *, 16> Stmts;
-  unsigned NumStmts = Record[Idx++];
+  unsigned NumStmts = Record.readInt();
   while (NumStmts--)
-    Stmts.push_back(Reader.ReadSubStmt());
-  S->setStmts(Reader.getContext(), Stmts);
-  S->LBraceLoc = ReadSourceLocation(Record, Idx);
-  S->RBraceLoc = ReadSourceLocation(Record, Idx);
+    Stmts.push_back(Record.readSubStmt());
+  S->setStmts(Record.getContext(), Stmts);
+  S->LBraceLoc = ReadSourceLocation();
+  S->RBraceLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitSwitchCase(SwitchCase *S) {
   VisitStmt(S);
-  Reader.RecordSwitchCaseID(S, Record[Idx++]);
-  S->setKeywordLoc(ReadSourceLocation(Record, Idx));
-  S->setColonLoc(ReadSourceLocation(Record, Idx));
+  Record.recordSwitchCaseID(S, Record.readInt());
+  S->setKeywordLoc(ReadSourceLocation());
+  S->setColonLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitCaseStmt(CaseStmt *S) {
   VisitSwitchCase(S);
-  S->setLHS(Reader.ReadSubExpr());
-  S->setRHS(Reader.ReadSubExpr());
-  S->setSubStmt(Reader.ReadSubStmt());
-  S->setEllipsisLoc(ReadSourceLocation(Record, Idx));
+  S->setLHS(Record.readSubExpr());
+  S->setRHS(Record.readSubExpr());
+  S->setSubStmt(Record.readSubStmt());
+  S->setEllipsisLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitDefaultStmt(DefaultStmt *S) {
   VisitSwitchCase(S);
-  S->setSubStmt(Reader.ReadSubStmt());
+  S->setSubStmt(Record.readSubStmt());
 }
 
 void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
   VisitStmt(S);
-  LabelDecl *LD = ReadDeclAs<LabelDecl>(Record, Idx);
+  LabelDecl *LD = ReadDeclAs<LabelDecl>();
   LD->setStmt(S);
   S->setDecl(LD);
-  S->setSubStmt(Reader.ReadSubStmt());
-  S->setIdentLoc(ReadSourceLocation(Record, Idx));
+  S->setSubStmt(Record.readSubStmt());
+  S->setIdentLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) {
   VisitStmt(S);
-  uint64_t NumAttrs = Record[Idx++];
+  uint64_t NumAttrs = Record.readInt();
   AttrVec Attrs;
-  Reader.ReadAttributes(F, Attrs, Record, Idx);
+  Record.readAttributes(Attrs);
   (void)NumAttrs;
   assert(NumAttrs == S->NumAttrs);
   assert(NumAttrs == Attrs.size());
   std::copy(Attrs.begin(), Attrs.end(), S->getAttrArrayPtr());
-  S->SubStmt = Reader.ReadSubStmt();
-  S->AttrLoc = ReadSourceLocation(Record, Idx);
+  S->SubStmt = Record.readSubStmt();
+  S->AttrLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitIfStmt(IfStmt *S) {
   VisitStmt(S);
-  S->setConstexpr(Record[Idx++]);
-  S->setInit(Reader.ReadSubStmt());
-  S->setConditionVariable(Reader.getContext(),
-                          ReadDeclAs<VarDecl>(Record, Idx));
-  S->setCond(Reader.ReadSubExpr());
-  S->setThen(Reader.ReadSubStmt());
-  S->setElse(Reader.ReadSubStmt());
-  S->setIfLoc(ReadSourceLocation(Record, Idx));
-  S->setElseLoc(ReadSourceLocation(Record, Idx));
+  S->setConstexpr(Record.readInt());
+  S->setInit(Record.readSubStmt());
+  S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
+  S->setCond(Record.readSubExpr());
+  S->setThen(Record.readSubStmt());
+  S->setElse(Record.readSubStmt());
+  S->setIfLoc(ReadSourceLocation());
+  S->setElseLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
   VisitStmt(S);
-  S->setInit(Reader.ReadSubStmt());
-  S->setConditionVariable(Reader.getContext(),
-                          ReadDeclAs<VarDecl>(Record, Idx));
-  S->setCond(Reader.ReadSubExpr());
-  S->setBody(Reader.ReadSubStmt());
-  S->setSwitchLoc(ReadSourceLocation(Record, Idx));
-  if (Record[Idx++])
+  S->setInit(Record.readSubStmt());
+  S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
+  S->setCond(Record.readSubExpr());
+  S->setBody(Record.readSubStmt());
+  S->setSwitchLoc(ReadSourceLocation());
+  if (Record.readInt())
     S->setAllEnumCasesCovered();
 
   SwitchCase *PrevSC = nullptr;
-  for (unsigned N = Record.size(); Idx != N; ++Idx) {
-    SwitchCase *SC = Reader.getSwitchCaseWithID(Record[Idx]);
+  for (auto E = Record.size(); Record.getIdx() != E; ) {
+    SwitchCase *SC = Record.getSwitchCaseWithID(Record.readInt());
     if (PrevSC)
       PrevSC->setNextSwitchCase(SC);
     else
@@ -220,81 +202,80 @@
 
 void ASTStmtReader::VisitWhileStmt(WhileStmt *S) {
   VisitStmt(S);
-  S->setConditionVariable(Reader.getContext(),
-                          ReadDeclAs<VarDecl>(Record, Idx));
+  S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
 
-  S->setCond(Reader.ReadSubExpr());
-  S->setBody(Reader.ReadSubStmt());
-  S->setWhileLoc(ReadSourceLocation(Record, Idx));
+  S->setCond(Record.readSubExpr());
+  S->setBody(Record.readSubStmt());
+  S->setWhileLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitDoStmt(DoStmt *S) {
   VisitStmt(S);
-  S->setCond(Reader.ReadSubExpr());
-  S->setBody(Reader.ReadSubStmt());
-  S->setDoLoc(ReadSourceLocation(Record, Idx));
-  S->setWhileLoc(ReadSourceLocation(Record, Idx));
-  S->setRParenLoc(ReadSourceLocation(Record, Idx));
+  S->setCond(Record.readSubExpr());
+  S->setBody(Record.readSubStmt());
+  S->setDoLoc(ReadSourceLocation());
+  S->setWhileLoc(ReadSourceLocation());
+  S->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitForStmt(ForStmt *S) {
   VisitStmt(S);
-  S->setInit(Reader.ReadSubStmt());
-  S->setCond(Reader.ReadSubExpr());
-  S->setConditionVariable(Reader.getContext(),
-                          ReadDeclAs<VarDecl>(Record, Idx));
-  S->setInc(Reader.ReadSubExpr());
-  S->setBody(Reader.ReadSubStmt());
-  S->setForLoc(ReadSourceLocation(Record, Idx));
-  S->setLParenLoc(ReadSourceLocation(Record, Idx));
-  S->setRParenLoc(ReadSourceLocation(Record, Idx));
+  S->setInit(Record.readSubStmt());
+  S->setCond(Record.readSubExpr());
+  S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
+  S->setInc(Record.readSubExpr());
+  S->setBody(Record.readSubStmt());
+  S->setForLoc(ReadSourceLocation());
+  S->setLParenLoc(ReadSourceLocation());
+  S->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitGotoStmt(GotoStmt *S) {
   VisitStmt(S);
-  S->setLabel(ReadDeclAs<LabelDecl>(Record, Idx));
-  S->setGotoLoc(ReadSourceLocation(Record, Idx));
-  S->setLabelLoc(ReadSourceLocation(Record, Idx));
+  S->setLabel(ReadDeclAs<LabelDecl>());
+  S->setGotoLoc(ReadSourceLocation());
+  S->setLabelLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
   VisitStmt(S);
-  S->setGotoLoc(ReadSourceLocation(Record, Idx));
-  S->setStarLoc(ReadSourceLocation(Record, Idx));
-  S->setTarget(Reader.ReadSubExpr());
+  S->setGotoLoc(ReadSourceLocation());
+  S->setStarLoc(ReadSourceLocation());
+  S->setTarget(Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitContinueStmt(ContinueStmt *S) {
   VisitStmt(S);
-  S->setContinueLoc(ReadSourceLocation(Record, Idx));
+  S->setContinueLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitBreakStmt(BreakStmt *S) {
   VisitStmt(S);
-  S->setBreakLoc(ReadSourceLocation(Record, Idx));
+  S->setBreakLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitReturnStmt(ReturnStmt *S) {
   VisitStmt(S);
-  S->setRetValue(Reader.ReadSubExpr());
-  S->setReturnLoc(ReadSourceLocation(Record, Idx));
-  S->setNRVOCandidate(ReadDeclAs<VarDecl>(Record, Idx));
+  S->setRetValue(Record.readSubExpr());
+  S->setReturnLoc(ReadSourceLocation());
+  S->setNRVOCandidate(ReadDeclAs<VarDecl>());
 }
 
 void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
   VisitStmt(S);
-  S->setStartLoc(ReadSourceLocation(Record, Idx));
-  S->setEndLoc(ReadSourceLocation(Record, Idx));
+  S->setStartLoc(ReadSourceLocation());
+  S->setEndLoc(ReadSourceLocation());
 
-  if (Idx + 1 == Record.size()) {
+  if (Record.size() - Record.getIdx() == 1) {
     // Single declaration
-    S->setDeclGroup(DeclGroupRef(ReadDecl(Record, Idx)));
+    S->setDeclGroup(DeclGroupRef(ReadDecl()));
   } else {
     SmallVector<Decl *, 16> Decls;
-    Decls.reserve(Record.size() - Idx);    
-    for (unsigned N = Record.size(); Idx != N; )
-      Decls.push_back(ReadDecl(Record, Idx));
-    S->setDeclGroup(DeclGroupRef(DeclGroup::Create(Reader.getContext(),
+    int N = Record.size() - Record.getIdx();
+    Decls.reserve(N);
+    for (int I = 0; I < N; ++I)
+      Decls.push_back(ReadDecl());
+    S->setDeclGroup(DeclGroupRef(DeclGroup::Create(Record.getContext(),
                                                    Decls.data(),
                                                    Decls.size())));
   }
@@ -302,18 +283,18 @@
 
 void ASTStmtReader::VisitAsmStmt(AsmStmt *S) {
   VisitStmt(S);
-  S->NumOutputs = Record[Idx++];
-  S->NumInputs = Record[Idx++];
-  S->NumClobbers = Record[Idx++];
-  S->setAsmLoc(ReadSourceLocation(Record, Idx));
-  S->setVolatile(Record[Idx++]);
-  S->setSimple(Record[Idx++]);
+  S->NumOutputs = Record.readInt();
+  S->NumInputs = Record.readInt();
+  S->NumClobbers = Record.readInt();
+  S->setAsmLoc(ReadSourceLocation());
+  S->setVolatile(Record.readInt());
+  S->setSimple(Record.readInt());
 }
 
 void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) {
   VisitAsmStmt(S);
-  S->setRParenLoc(ReadSourceLocation(Record, Idx));
-  S->setAsmString(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
+  S->setRParenLoc(ReadSourceLocation());
+  S->setAsmString(cast_or_null<StringLiteral>(Record.readSubStmt()));
 
   unsigned NumOutputs = S->getNumOutputs();
   unsigned NumInputs = S->getNumInputs();
@@ -324,34 +305,34 @@
   SmallVector<StringLiteral*, 16> Constraints;
   SmallVector<Stmt*, 16> Exprs;
   for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) {
-    Names.push_back(Reader.GetIdentifierInfo(F, Record, Idx));
-    Constraints.push_back(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
-    Exprs.push_back(Reader.ReadSubStmt());
+    Names.push_back(Record.getIdentifierInfo());
+    Constraints.push_back(cast_or_null<StringLiteral>(Record.readSubStmt()));
+    Exprs.push_back(Record.readSubStmt());
   }
 
   // Constraints
   SmallVector<StringLiteral*, 16> Clobbers;
   for (unsigned I = 0; I != NumClobbers; ++I)
-    Clobbers.push_back(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
+    Clobbers.push_back(cast_or_null<StringLiteral>(Record.readSubStmt()));
 
-  S->setOutputsAndInputsAndClobbers(Reader.getContext(),
-                                    Names.data(), Constraints.data(), 
-                                    Exprs.data(), NumOutputs, NumInputs, 
+  S->setOutputsAndInputsAndClobbers(Record.getContext(),
+                                    Names.data(), Constraints.data(),
+                                    Exprs.data(), NumOutputs, NumInputs,
                                     Clobbers.data(), NumClobbers);
 }
 
 void ASTStmtReader::VisitMSAsmStmt(MSAsmStmt *S) {
   VisitAsmStmt(S);
-  S->LBraceLoc = ReadSourceLocation(Record, Idx);
-  S->EndLoc = ReadSourceLocation(Record, Idx);
-  S->NumAsmToks = Record[Idx++];
-  std::string AsmStr = ReadString(Record, Idx);
+  S->LBraceLoc = ReadSourceLocation();
+  S->EndLoc = ReadSourceLocation();
+  S->NumAsmToks = Record.readInt();
+  std::string AsmStr = ReadString();
 
   // Read the tokens.
   SmallVector<Token, 16> AsmToks;
   AsmToks.reserve(S->NumAsmToks);
   for (unsigned i = 0, e = S->NumAsmToks; i != e; ++i) {
-    AsmToks.push_back(ReadToken(Record, Idx));
+    AsmToks.push_back(Record.readToken());
   }
 
   // The calls to reserve() for the FooData vectors are mandatory to
@@ -363,7 +344,7 @@
   ClobbersData.reserve(S->NumClobbers);
   Clobbers.reserve(S->NumClobbers);
   for (unsigned i = 0, e = S->NumClobbers; i != e; ++i) {
-    ClobbersData.push_back(ReadString(Record, Idx));
+    ClobbersData.push_back(ReadString());
     Clobbers.push_back(ClobbersData.back());
   }
 
@@ -376,12 +357,12 @@
   ConstraintsData.reserve(NumOperands);
   Constraints.reserve(NumOperands);
   for (unsigned i = 0; i != NumOperands; ++i) {
-    Exprs.push_back(cast<Expr>(Reader.ReadSubStmt()));
-    ConstraintsData.push_back(ReadString(Record, Idx));
+    Exprs.push_back(cast<Expr>(Record.readSubStmt()));
+    ConstraintsData.push_back(ReadString());
     Constraints.push_back(ConstraintsData.back());
   }
 
-  S->initialize(Reader.getContext(), AsmStr, AsmToks,
+  S->initialize(Record.getContext(), AsmStr, AsmToks,
                 Constraints, Exprs, Clobbers);
 }
 
@@ -400,6 +381,11 @@
   llvm_unreachable("unimplemented");
 }
 
+void ASTStmtReader::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
+  // FIXME: Implement coroutine serialization.
+  llvm_unreachable("unimplemented");
+}
+
 void ASTStmtReader::VisitCoyieldExpr(CoyieldExpr *S) {
   // FIXME: Implement coroutine serialization.
   llvm_unreachable("unimplemented");
@@ -407,229 +393,229 @@
 
 void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) {
   VisitStmt(S);
-  ++Idx;
-  S->setCapturedDecl(ReadDeclAs<CapturedDecl>(Record, Idx));
-  S->setCapturedRegionKind(static_cast<CapturedRegionKind>(Record[Idx++]));
-  S->setCapturedRecordDecl(ReadDeclAs<RecordDecl>(Record, Idx));
+  Record.skipInts(1);
+  S->setCapturedDecl(ReadDeclAs<CapturedDecl>());
+  S->setCapturedRegionKind(static_cast<CapturedRegionKind>(Record.readInt()));
+  S->setCapturedRecordDecl(ReadDeclAs<RecordDecl>());
 
   // Capture inits
   for (CapturedStmt::capture_init_iterator I = S->capture_init_begin(),
                                            E = S->capture_init_end();
        I != E; ++I)
-    *I = Reader.ReadSubExpr();
+    *I = Record.readSubExpr();
 
   // Body
-  S->setCapturedStmt(Reader.ReadSubStmt());
+  S->setCapturedStmt(Record.readSubStmt());
   S->getCapturedDecl()->setBody(S->getCapturedStmt());
 
   // Captures
   for (auto &I : S->captures()) {
-    I.VarAndKind.setPointer(ReadDeclAs<VarDecl>(Record, Idx));
-    I.VarAndKind
-        .setInt(static_cast<CapturedStmt::VariableCaptureKind>(Record[Idx++]));
-    I.Loc = ReadSourceLocation(Record, Idx);
+    I.VarAndKind.setPointer(ReadDeclAs<VarDecl>());
+    I.VarAndKind.setInt(
+        static_cast<CapturedStmt::VariableCaptureKind>(Record.readInt()));
+    I.Loc = ReadSourceLocation();
   }
 }
 
 void ASTStmtReader::VisitExpr(Expr *E) {
   VisitStmt(E);
-  E->setType(Reader.readType(F, Record, Idx));
-  E->setTypeDependent(Record[Idx++]);
-  E->setValueDependent(Record[Idx++]);
-  E->setInstantiationDependent(Record[Idx++]);
-  E->ExprBits.ContainsUnexpandedParameterPack = Record[Idx++];
-  E->setValueKind(static_cast<ExprValueKind>(Record[Idx++]));
-  E->setObjectKind(static_cast<ExprObjectKind>(Record[Idx++]));
-  assert(Idx == NumExprFields && "Incorrect expression field count");
+  E->setType(Record.readType());
+  E->setTypeDependent(Record.readInt());
+  E->setValueDependent(Record.readInt());
+  E->setInstantiationDependent(Record.readInt());
+  E->ExprBits.ContainsUnexpandedParameterPack = Record.readInt();
+  E->setValueKind(static_cast<ExprValueKind>(Record.readInt()));
+  E->setObjectKind(static_cast<ExprObjectKind>(Record.readInt()));
+  assert(Record.getIdx() == NumExprFields &&
+         "Incorrect expression field count");
 }
 
 void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
   VisitExpr(E);
-  E->setLocation(ReadSourceLocation(Record, Idx));
-  E->Type = (PredefinedExpr::IdentType)Record[Idx++];
-  E->FnName = cast_or_null<StringLiteral>(Reader.ReadSubExpr());
+  E->setLocation(ReadSourceLocation());
+  E->Type = (PredefinedExpr::IdentType)Record.readInt();
+  E->FnName = cast_or_null<StringLiteral>(Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
   VisitExpr(E);
 
-  E->DeclRefExprBits.HasQualifier = Record[Idx++];
-  E->DeclRefExprBits.HasFoundDecl = Record[Idx++];
-  E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record[Idx++];
-  E->DeclRefExprBits.HadMultipleCandidates = Record[Idx++];
-  E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = Record[Idx++];
+  E->DeclRefExprBits.HasQualifier = Record.readInt();
+  E->DeclRefExprBits.HasFoundDecl = Record.readInt();
+  E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record.readInt();
+  E->DeclRefExprBits.HadMultipleCandidates = Record.readInt();
+  E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = Record.readInt();
   unsigned NumTemplateArgs = 0;
   if (E->hasTemplateKWAndArgsInfo())
-    NumTemplateArgs = Record[Idx++];
+    NumTemplateArgs = Record.readInt();
 
   if (E->hasQualifier())
     new (E->getTrailingObjects<NestedNameSpecifierLoc>())
-        NestedNameSpecifierLoc(
-            Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
+        NestedNameSpecifierLoc(Record.readNestedNameSpecifierLoc());
 
   if (E->hasFoundDecl())
-    *E->getTrailingObjects<NamedDecl *>() = ReadDeclAs<NamedDecl>(Record, Idx);
+    *E->getTrailingObjects<NamedDecl *>() = ReadDeclAs<NamedDecl>();
 
   if (E->hasTemplateKWAndArgsInfo())
     ReadTemplateKWAndArgsInfo(
         *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
         E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs);
 
-  E->setDecl(ReadDeclAs<ValueDecl>(Record, Idx));
-  E->setLocation(ReadSourceLocation(Record, Idx));
-  ReadDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record, Idx);
+  E->setDecl(ReadDeclAs<ValueDecl>());
+  E->setLocation(ReadSourceLocation());
+  ReadDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
 }
 
 void ASTStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
   VisitExpr(E);
-  E->setLocation(ReadSourceLocation(Record, Idx));
-  E->setValue(Reader.getContext(), Reader.ReadAPInt(Record, Idx));
+  E->setLocation(ReadSourceLocation());
+  E->setValue(Record.getContext(), Record.readAPInt());
 }
 
 void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
   VisitExpr(E);
-  E->setRawSemantics(static_cast<Stmt::APFloatSemantics>(Record[Idx++]));
-  E->setExact(Record[Idx++]);
-  E->setValue(Reader.getContext(),
-              Reader.ReadAPFloat(Record, E->getSemantics(), Idx));
-  E->setLocation(ReadSourceLocation(Record, Idx));
+  E->setRawSemantics(static_cast<Stmt::APFloatSemantics>(Record.readInt()));
+  E->setExact(Record.readInt());
+  E->setValue(Record.getContext(), Record.readAPFloat(E->getSemantics()));
+  E->setLocation(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitImaginaryLiteral(ImaginaryLiteral *E) {
   VisitExpr(E);
-  E->setSubExpr(Reader.ReadSubExpr());
+  E->setSubExpr(Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitStringLiteral(StringLiteral *E) {
   VisitExpr(E);
-  unsigned Len = Record[Idx++];
-  assert(Record[Idx] == E->getNumConcatenated() &&
+  unsigned Len = Record.readInt();
+  assert(Record.peekInt() == E->getNumConcatenated() &&
          "Wrong number of concatenated tokens!");
-  ++Idx;
+  Record.skipInts(1);
   StringLiteral::StringKind kind =
-        static_cast<StringLiteral::StringKind>(Record[Idx++]);
-  bool isPascal = Record[Idx++];
+        static_cast<StringLiteral::StringKind>(Record.readInt());
+  bool isPascal = Record.readInt();
 
   // Read string data
-  SmallString<16> Str(&Record[Idx], &Record[Idx] + Len);
-  E->setString(Reader.getContext(), Str, kind, isPascal);
-  Idx += Len;
+  auto B = &Record.peekInt();
+  SmallString<16> Str(B, B + Len);
+  E->setString(Record.getContext(), Str, kind, isPascal);
+  Record.skipInts(Len);
 
   // Read source locations
   for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
-    E->setStrTokenLoc(I, ReadSourceLocation(Record, Idx));
+    E->setStrTokenLoc(I, ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitCharacterLiteral(CharacterLiteral *E) {
   VisitExpr(E);
-  E->setValue(Record[Idx++]);
-  E->setLocation(ReadSourceLocation(Record, Idx));
-  E->setKind(static_cast<CharacterLiteral::CharacterKind>(Record[Idx++]));
+  E->setValue(Record.readInt());
+  E->setLocation(ReadSourceLocation());
+  E->setKind(static_cast<CharacterLiteral::CharacterKind>(Record.readInt()));
 }
 
 void ASTStmtReader::VisitParenExpr(ParenExpr *E) {
   VisitExpr(E);
-  E->setLParen(ReadSourceLocation(Record, Idx));
-  E->setRParen(ReadSourceLocation(Record, Idx));
-  E->setSubExpr(Reader.ReadSubExpr());
+  E->setLParen(ReadSourceLocation());
+  E->setRParen(ReadSourceLocation());
+  E->setSubExpr(Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) {
   VisitExpr(E);
-  unsigned NumExprs = Record[Idx++];
-  E->Exprs = new (Reader.getContext()) Stmt*[NumExprs];
+  unsigned NumExprs = Record.readInt();
+  E->Exprs = new (Record.getContext()) Stmt*[NumExprs];
   for (unsigned i = 0; i != NumExprs; ++i)
-    E->Exprs[i] = Reader.ReadSubStmt();
+    E->Exprs[i] = Record.readSubStmt();
   E->NumExprs = NumExprs;
-  E->LParenLoc = ReadSourceLocation(Record, Idx);
-  E->RParenLoc = ReadSourceLocation(Record, Idx);
+  E->LParenLoc = ReadSourceLocation();
+  E->RParenLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) {
   VisitExpr(E);
-  E->setSubExpr(Reader.ReadSubExpr());
-  E->setOpcode((UnaryOperator::Opcode)Record[Idx++]);
-  E->setOperatorLoc(ReadSourceLocation(Record, Idx));
+  E->setSubExpr(Record.readSubExpr());
+  E->setOpcode((UnaryOperator::Opcode)Record.readInt());
+  E->setOperatorLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
   VisitExpr(E);
-  assert(E->getNumComponents() == Record[Idx]);
-  ++Idx;
-  assert(E->getNumExpressions() == Record[Idx]);
-  ++Idx;
-  E->setOperatorLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
-  E->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
+  assert(E->getNumComponents() == Record.peekInt());
+  Record.skipInts(1);
+  assert(E->getNumExpressions() == Record.peekInt());
+  Record.skipInts(1);
+  E->setOperatorLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
+  E->setTypeSourceInfo(GetTypeSourceInfo());
   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
-    OffsetOfNode::Kind Kind = static_cast<OffsetOfNode::Kind>(Record[Idx++]);
-    SourceLocation Start = ReadSourceLocation(Record, Idx);
-    SourceLocation End = ReadSourceLocation(Record, Idx);
+    OffsetOfNode::Kind Kind = static_cast<OffsetOfNode::Kind>(Record.readInt());
+    SourceLocation Start = ReadSourceLocation();
+    SourceLocation End = ReadSourceLocation();
     switch (Kind) {
     case OffsetOfNode::Array:
-      E->setComponent(I, OffsetOfNode(Start, Record[Idx++], End));
+      E->setComponent(I, OffsetOfNode(Start, Record.readInt(), End));
       break;
 
     case OffsetOfNode::Field:
       E->setComponent(
-          I, OffsetOfNode(Start, ReadDeclAs<FieldDecl>(Record, Idx), End));
+          I, OffsetOfNode(Start, ReadDeclAs<FieldDecl>(), End));
       break;
 
     case OffsetOfNode::Identifier:
       E->setComponent(
           I,
-          OffsetOfNode(Start, Reader.GetIdentifierInfo(F, Record, Idx), End));
+          OffsetOfNode(Start, Record.getIdentifierInfo(), End));
       break;
 
     case OffsetOfNode::Base: {
-      CXXBaseSpecifier *Base = new (Reader.getContext()) CXXBaseSpecifier();
-      *Base = Reader.ReadCXXBaseSpecifier(F, Record, Idx);
+      CXXBaseSpecifier *Base = new (Record.getContext()) CXXBaseSpecifier();
+      *Base = Record.readCXXBaseSpecifier();
       E->setComponent(I, OffsetOfNode(Base));
       break;
     }
     }
   }
-  
+
   for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
-    E->setIndexExpr(I, Reader.ReadSubExpr());
+    E->setIndexExpr(I, Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
   VisitExpr(E);
-  E->setKind(static_cast<UnaryExprOrTypeTrait>(Record[Idx++]));
-  if (Record[Idx] == 0) {
-    E->setArgument(Reader.ReadSubExpr());
-    ++Idx;
+  E->setKind(static_cast<UnaryExprOrTypeTrait>(Record.readInt()));
+  if (Record.peekInt() == 0) {
+    E->setArgument(Record.readSubExpr());
+    Record.skipInts(1);
   } else {
-    E->setArgument(GetTypeSourceInfo(Record, Idx));
+    E->setArgument(GetTypeSourceInfo());
   }
-  E->setOperatorLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
+  E->setOperatorLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
   VisitExpr(E);
-  E->setLHS(Reader.ReadSubExpr());
-  E->setRHS(Reader.ReadSubExpr());
-  E->setRBracketLoc(ReadSourceLocation(Record, Idx));
+  E->setLHS(Record.readSubExpr());
+  E->setRHS(Record.readSubExpr());
+  E->setRBracketLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
   VisitExpr(E);
-  E->setBase(Reader.ReadSubExpr());
-  E->setLowerBound(Reader.ReadSubExpr());
-  E->setLength(Reader.ReadSubExpr());
-  E->setColonLoc(ReadSourceLocation(Record, Idx));
-  E->setRBracketLoc(ReadSourceLocation(Record, Idx));
+  E->setBase(Record.readSubExpr());
+  E->setLowerBound(Record.readSubExpr());
+  E->setLength(Record.readSubExpr());
+  E->setColonLoc(ReadSourceLocation());
+  E->setRBracketLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitCallExpr(CallExpr *E) {
   VisitExpr(E);
-  E->setNumArgs(Reader.getContext(), Record[Idx++]);
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
-  E->setCallee(Reader.ReadSubExpr());
+  E->setNumArgs(Record.getContext(), Record.readInt());
+  E->setRParenLoc(ReadSourceLocation());
+  E->setCallee(Record.readSubExpr());
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
-    E->setArg(I, Reader.ReadSubExpr());
+    E->setArg(I, Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
@@ -644,74 +630,74 @@
 
 void ASTStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) {
   VisitExpr(E);
-  E->setBase(Reader.ReadSubExpr());
-  E->setIsaMemberLoc(ReadSourceLocation(Record, Idx));
-  E->setOpLoc(ReadSourceLocation(Record, Idx));
-  E->setArrow(Record[Idx++]);
+  E->setBase(Record.readSubExpr());
+  E->setIsaMemberLoc(ReadSourceLocation());
+  E->setOpLoc(ReadSourceLocation());
+  E->setArrow(Record.readInt());
 }
 
 void ASTStmtReader::
 VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
   VisitExpr(E);
-  E->Operand = Reader.ReadSubExpr();
-  E->setShouldCopy(Record[Idx++]);
+  E->Operand = Record.readSubExpr();
+  E->setShouldCopy(Record.readInt());
 }
 
 void ASTStmtReader::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
   VisitExplicitCastExpr(E);
-  E->LParenLoc = ReadSourceLocation(Record, Idx);
-  E->BridgeKeywordLoc = ReadSourceLocation(Record, Idx);
-  E->Kind = Record[Idx++];
+  E->LParenLoc = ReadSourceLocation();
+  E->BridgeKeywordLoc = ReadSourceLocation();
+  E->Kind = Record.readInt();
 }
 
 void ASTStmtReader::VisitCastExpr(CastExpr *E) {
   VisitExpr(E);
-  unsigned NumBaseSpecs = Record[Idx++];
+  unsigned NumBaseSpecs = Record.readInt();
   assert(NumBaseSpecs == E->path_size());
-  E->setSubExpr(Reader.ReadSubExpr());
-  E->setCastKind((CastKind)Record[Idx++]);
+  E->setSubExpr(Record.readSubExpr());
+  E->setCastKind((CastKind)Record.readInt());
   CastExpr::path_iterator BaseI = E->path_begin();
   while (NumBaseSpecs--) {
-    CXXBaseSpecifier *BaseSpec = new (Reader.getContext()) CXXBaseSpecifier;
-    *BaseSpec = Reader.ReadCXXBaseSpecifier(F, Record, Idx);
+    CXXBaseSpecifier *BaseSpec = new (Record.getContext()) CXXBaseSpecifier;
+    *BaseSpec = Record.readCXXBaseSpecifier();
     *BaseI++ = BaseSpec;
   }
 }
 
 void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
   VisitExpr(E);
-  E->setLHS(Reader.ReadSubExpr());
-  E->setRHS(Reader.ReadSubExpr());
-  E->setOpcode((BinaryOperator::Opcode)Record[Idx++]);
-  E->setOperatorLoc(ReadSourceLocation(Record, Idx));
-  E->setFPContractable((bool)Record[Idx++]);
+  E->setLHS(Record.readSubExpr());
+  E->setRHS(Record.readSubExpr());
+  E->setOpcode((BinaryOperator::Opcode)Record.readInt());
+  E->setOperatorLoc(ReadSourceLocation());
+  E->setFPContractable((bool)Record.readInt());
 }
 
 void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
   VisitBinaryOperator(E);
-  E->setComputationLHSType(Reader.readType(F, Record, Idx));
-  E->setComputationResultType(Reader.readType(F, Record, Idx));
+  E->setComputationLHSType(Record.readType());
+  E->setComputationResultType(Record.readType());
 }
 
 void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) {
   VisitExpr(E);
-  E->SubExprs[ConditionalOperator::COND] = Reader.ReadSubExpr();
-  E->SubExprs[ConditionalOperator::LHS] = Reader.ReadSubExpr();
-  E->SubExprs[ConditionalOperator::RHS] = Reader.ReadSubExpr();
-  E->QuestionLoc = ReadSourceLocation(Record, Idx);
-  E->ColonLoc = ReadSourceLocation(Record, Idx);
+  E->SubExprs[ConditionalOperator::COND] = Record.readSubExpr();
+  E->SubExprs[ConditionalOperator::LHS] = Record.readSubExpr();
+  E->SubExprs[ConditionalOperator::RHS] = Record.readSubExpr();
+  E->QuestionLoc = ReadSourceLocation();
+  E->ColonLoc = ReadSourceLocation();
 }
 
 void
 ASTStmtReader::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
   VisitExpr(E);
-  E->OpaqueValue = cast<OpaqueValueExpr>(Reader.ReadSubExpr());
-  E->SubExprs[BinaryConditionalOperator::COMMON] = Reader.ReadSubExpr();
-  E->SubExprs[BinaryConditionalOperator::COND] = Reader.ReadSubExpr();
-  E->SubExprs[BinaryConditionalOperator::LHS] = Reader.ReadSubExpr();
-  E->SubExprs[BinaryConditionalOperator::RHS] = Reader.ReadSubExpr();
-  E->QuestionLoc = ReadSourceLocation(Record, Idx);
-  E->ColonLoc = ReadSourceLocation(Record, Idx);
+  E->OpaqueValue = cast<OpaqueValueExpr>(Record.readSubExpr());
+  E->SubExprs[BinaryConditionalOperator::COMMON] = Record.readSubExpr();
+  E->SubExprs[BinaryConditionalOperator::COND] = Record.readSubExpr();
+  E->SubExprs[BinaryConditionalOperator::LHS] = Record.readSubExpr();
+  E->SubExprs[BinaryConditionalOperator::RHS] = Record.readSubExpr();
+  E->QuestionLoc = ReadSourceLocation();
+  E->ColonLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
@@ -720,54 +706,54 @@
 
 void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
   VisitCastExpr(E);
-  E->setTypeInfoAsWritten(GetTypeSourceInfo(Record, Idx));
+  E->setTypeInfoAsWritten(GetTypeSourceInfo());
 }
 
 void ASTStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) {
   VisitExplicitCastExpr(E);
-  E->setLParenLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
+  E->setLParenLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
   VisitExpr(E);
-  E->setLParenLoc(ReadSourceLocation(Record, Idx));
-  E->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
-  E->setInitializer(Reader.ReadSubExpr());
-  E->setFileScope(Record[Idx++]);
+  E->setLParenLoc(ReadSourceLocation());
+  E->setTypeSourceInfo(GetTypeSourceInfo());
+  E->setInitializer(Record.readSubExpr());
+  E->setFileScope(Record.readInt());
 }
 
 void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
   VisitExpr(E);
-  E->setBase(Reader.ReadSubExpr());
-  E->setAccessor(Reader.GetIdentifierInfo(F, Record, Idx));
-  E->setAccessorLoc(ReadSourceLocation(Record, Idx));
+  E->setBase(Record.readSubExpr());
+  E->setAccessor(Record.getIdentifierInfo());
+  E->setAccessorLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitInitListExpr(InitListExpr *E) {
   VisitExpr(E);
-  if (InitListExpr *SyntForm = cast_or_null<InitListExpr>(Reader.ReadSubStmt()))
+  if (InitListExpr *SyntForm = cast_or_null<InitListExpr>(Record.readSubStmt()))
     E->setSyntacticForm(SyntForm);
-  E->setLBraceLoc(ReadSourceLocation(Record, Idx));
-  E->setRBraceLoc(ReadSourceLocation(Record, Idx));
-  bool isArrayFiller = Record[Idx++];
+  E->setLBraceLoc(ReadSourceLocation());
+  E->setRBraceLoc(ReadSourceLocation());
+  bool isArrayFiller = Record.readInt();
   Expr *filler = nullptr;
   if (isArrayFiller) {
-    filler = Reader.ReadSubExpr();
+    filler = Record.readSubExpr();
     E->ArrayFillerOrUnionFieldInit = filler;
   } else
-    E->ArrayFillerOrUnionFieldInit = ReadDeclAs<FieldDecl>(Record, Idx);
-  E->sawArrayRangeDesignator(Record[Idx++]);
-  unsigned NumInits = Record[Idx++];
-  E->reserveInits(Reader.getContext(), NumInits);
+    E->ArrayFillerOrUnionFieldInit = ReadDeclAs<FieldDecl>();
+  E->sawArrayRangeDesignator(Record.readInt());
+  unsigned NumInits = Record.readInt();
+  E->reserveInits(Record.getContext(), NumInits);
   if (isArrayFiller) {
     for (unsigned I = 0; I != NumInits; ++I) {
-      Expr *init = Reader.ReadSubExpr();
-      E->updateInit(Reader.getContext(), I, init ? init : filler);
+      Expr *init = Record.readSubExpr();
+      E->updateInit(Record.getContext(), I, init ? init : filler);
     }
   } else {
     for (unsigned I = 0; I != NumInits; ++I)
-      E->updateInit(Reader.getContext(), I, Reader.ReadSubExpr());
+      E->updateInit(Record.getContext(), I, Record.readSubExpr());
   }
 }
 
@@ -775,22 +761,20 @@
   typedef DesignatedInitExpr::Designator Designator;
 
   VisitExpr(E);
-  unsigned NumSubExprs = Record[Idx++];
+  unsigned NumSubExprs = Record.readInt();
   assert(NumSubExprs == E->getNumSubExprs() && "Wrong number of subexprs");
   for (unsigned I = 0; I != NumSubExprs; ++I)
-    E->setSubExpr(I, Reader.ReadSubExpr());
-  E->setEqualOrColonLoc(ReadSourceLocation(Record, Idx));
-  E->setGNUSyntax(Record[Idx++]);
+    E->setSubExpr(I, Record.readSubExpr());
+  E->setEqualOrColonLoc(ReadSourceLocation());
+  E->setGNUSyntax(Record.readInt());
 
   SmallVector<Designator, 4> Designators;
-  while (Idx < Record.size()) {
-    switch ((DesignatorTypes)Record[Idx++]) {
+  while (Record.getIdx() < Record.size()) {
+    switch ((DesignatorTypes)Record.readInt()) {
     case DESIG_FIELD_DECL: {
-      FieldDecl *Field = ReadDeclAs<FieldDecl>(Record, Idx);
-      SourceLocation DotLoc
-        = ReadSourceLocation(Record, Idx);
-      SourceLocation FieldLoc
-        = ReadSourceLocation(Record, Idx);
+      FieldDecl *Field = ReadDeclAs<FieldDecl>();
+      SourceLocation DotLoc = ReadSourceLocation();
+      SourceLocation FieldLoc = ReadSourceLocation();
       Designators.push_back(Designator(Field->getIdentifier(), DotLoc,
                                        FieldLoc));
       Designators.back().setField(Field);
@@ -798,162 +782,165 @@
     }
 
     case DESIG_FIELD_NAME: {
-      const IdentifierInfo *Name = Reader.GetIdentifierInfo(F, Record, Idx);
-      SourceLocation DotLoc
-        = ReadSourceLocation(Record, Idx);
-      SourceLocation FieldLoc
-        = ReadSourceLocation(Record, Idx);
+      const IdentifierInfo *Name = Record.getIdentifierInfo();
+      SourceLocation DotLoc = ReadSourceLocation();
+      SourceLocation FieldLoc = ReadSourceLocation();
       Designators.push_back(Designator(Name, DotLoc, FieldLoc));
       break;
     }
 
     case DESIG_ARRAY: {
-      unsigned Index = Record[Idx++];
-      SourceLocation LBracketLoc
-        = ReadSourceLocation(Record, Idx);
-      SourceLocation RBracketLoc
-        = ReadSourceLocation(Record, Idx);
+      unsigned Index = Record.readInt();
+      SourceLocation LBracketLoc = ReadSourceLocation();
+      SourceLocation RBracketLoc = ReadSourceLocation();
       Designators.push_back(Designator(Index, LBracketLoc, RBracketLoc));
       break;
     }
 
     case DESIG_ARRAY_RANGE: {
-      unsigned Index = Record[Idx++];
-      SourceLocation LBracketLoc
-        = ReadSourceLocation(Record, Idx);
-      SourceLocation EllipsisLoc
-        = ReadSourceLocation(Record, Idx);
-      SourceLocation RBracketLoc
-        = ReadSourceLocation(Record, Idx);
+      unsigned Index = Record.readInt();
+      SourceLocation LBracketLoc = ReadSourceLocation();
+      SourceLocation EllipsisLoc = ReadSourceLocation();
+      SourceLocation RBracketLoc = ReadSourceLocation();
       Designators.push_back(Designator(Index, LBracketLoc, EllipsisLoc,
                                        RBracketLoc));
       break;
     }
     }
   }
-  E->setDesignators(Reader.getContext(), 
+  E->setDesignators(Record.getContext(),
                     Designators.data(), Designators.size());
 }
 
 void ASTStmtReader::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
   VisitExpr(E);
-  E->setBase(Reader.ReadSubExpr());
-  E->setUpdater(Reader.ReadSubExpr());
+  E->setBase(Record.readSubExpr());
+  E->setUpdater(Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitNoInitExpr(NoInitExpr *E) {
   VisitExpr(E);
 }
 
+void ASTStmtReader::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
+  VisitExpr(E);
+  E->SubExprs[0] = Record.readSubExpr();
+  E->SubExprs[1] = Record.readSubExpr();
+}
+
+void ASTStmtReader::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
+  VisitExpr(E);
+}
+
 void ASTStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
   VisitExpr(E);
 }
 
 void ASTStmtReader::VisitVAArgExpr(VAArgExpr *E) {
   VisitExpr(E);
-  E->setSubExpr(Reader.ReadSubExpr());
-  E->setWrittenTypeInfo(GetTypeSourceInfo(Record, Idx));
-  E->setBuiltinLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
-  E->setIsMicrosoftABI(Record[Idx++]);
+  E->setSubExpr(Record.readSubExpr());
+  E->setWrittenTypeInfo(GetTypeSourceInfo());
+  E->setBuiltinLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
+  E->setIsMicrosoftABI(Record.readInt());
 }
 
 void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) {
   VisitExpr(E);
-  E->setAmpAmpLoc(ReadSourceLocation(Record, Idx));
-  E->setLabelLoc(ReadSourceLocation(Record, Idx));
-  E->setLabel(ReadDeclAs<LabelDecl>(Record, Idx));
+  E->setAmpAmpLoc(ReadSourceLocation());
+  E->setLabelLoc(ReadSourceLocation());
+  E->setLabel(ReadDeclAs<LabelDecl>());
 }
 
 void ASTStmtReader::VisitStmtExpr(StmtExpr *E) {
   VisitExpr(E);
-  E->setLParenLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
-  E->setSubStmt(cast_or_null<CompoundStmt>(Reader.ReadSubStmt()));
+  E->setLParenLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
+  E->setSubStmt(cast_or_null<CompoundStmt>(Record.readSubStmt()));
 }
 
 void ASTStmtReader::VisitChooseExpr(ChooseExpr *E) {
   VisitExpr(E);
-  E->setCond(Reader.ReadSubExpr());
-  E->setLHS(Reader.ReadSubExpr());
-  E->setRHS(Reader.ReadSubExpr());
-  E->setBuiltinLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
-  E->setIsConditionTrue(Record[Idx++]);
+  E->setCond(Record.readSubExpr());
+  E->setLHS(Record.readSubExpr());
+  E->setRHS(Record.readSubExpr());
+  E->setBuiltinLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
+  E->setIsConditionTrue(Record.readInt());
 }
 
 void ASTStmtReader::VisitGNUNullExpr(GNUNullExpr *E) {
   VisitExpr(E);
-  E->setTokenLocation(ReadSourceLocation(Record, Idx));
+  E->setTokenLocation(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
   VisitExpr(E);
   SmallVector<Expr *, 16> Exprs;
-  unsigned NumExprs = Record[Idx++];
+  unsigned NumExprs = Record.readInt();
   while (NumExprs--)
-    Exprs.push_back(Reader.ReadSubExpr());
-  E->setExprs(Reader.getContext(), Exprs);
-  E->setBuiltinLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
+    Exprs.push_back(Record.readSubExpr());
+  E->setExprs(Record.getContext(), Exprs);
+  E->setBuiltinLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitConvertVectorExpr(ConvertVectorExpr *E) {
   VisitExpr(E);
-  E->BuiltinLoc = ReadSourceLocation(Record, Idx);
-  E->RParenLoc = ReadSourceLocation(Record, Idx);
-  E->TInfo = GetTypeSourceInfo(Record, Idx);
-  E->SrcExpr = Reader.ReadSubExpr();
+  E->BuiltinLoc = ReadSourceLocation();
+  E->RParenLoc = ReadSourceLocation();
+  E->TInfo = GetTypeSourceInfo();
+  E->SrcExpr = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitBlockExpr(BlockExpr *E) {
   VisitExpr(E);
-  E->setBlockDecl(ReadDeclAs<BlockDecl>(Record, Idx));
+  E->setBlockDecl(ReadDeclAs<BlockDecl>());
 }
 
 void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
   VisitExpr(E);
-  E->NumAssocs = Record[Idx++];
-  E->AssocTypes = new (Reader.getContext()) TypeSourceInfo*[E->NumAssocs];
+  E->NumAssocs = Record.readInt();
+  E->AssocTypes = new (Record.getContext()) TypeSourceInfo*[E->NumAssocs];
   E->SubExprs =
-   new(Reader.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs];
+   new(Record.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs];
 
-  E->SubExprs[GenericSelectionExpr::CONTROLLING] = Reader.ReadSubExpr();
+  E->SubExprs[GenericSelectionExpr::CONTROLLING] = Record.readSubExpr();
   for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
-    E->AssocTypes[I] = GetTypeSourceInfo(Record, Idx);
-    E->SubExprs[GenericSelectionExpr::END_EXPR+I] = Reader.ReadSubExpr();
+    E->AssocTypes[I] = GetTypeSourceInfo();
+    E->SubExprs[GenericSelectionExpr::END_EXPR+I] = Record.readSubExpr();
   }
-  E->ResultIndex = Record[Idx++];
+  E->ResultIndex = Record.readInt();
 
-  E->GenericLoc = ReadSourceLocation(Record, Idx);
-  E->DefaultLoc = ReadSourceLocation(Record, Idx);
-  E->RParenLoc = ReadSourceLocation(Record, Idx);
+  E->GenericLoc = ReadSourceLocation();
+  E->DefaultLoc = ReadSourceLocation();
+  E->RParenLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
   VisitExpr(E);
-  unsigned numSemanticExprs = Record[Idx++];
+  unsigned numSemanticExprs = Record.readInt();
   assert(numSemanticExprs + 1 == E->PseudoObjectExprBits.NumSubExprs);
-  E->PseudoObjectExprBits.ResultIndex = Record[Idx++];
+  E->PseudoObjectExprBits.ResultIndex = Record.readInt();
 
   // Read the syntactic expression.
-  E->getSubExprsBuffer()[0] = Reader.ReadSubExpr();
+  E->getSubExprsBuffer()[0] = Record.readSubExpr();
 
   // Read all the semantic expressions.
   for (unsigned i = 0; i != numSemanticExprs; ++i) {
-    Expr *subExpr = Reader.ReadSubExpr();
+    Expr *subExpr = Record.readSubExpr();
     E->getSubExprsBuffer()[i+1] = subExpr;
   }
 }
 
 void ASTStmtReader::VisitAtomicExpr(AtomicExpr *E) {
   VisitExpr(E);
-  E->Op = AtomicExpr::AtomicOp(Record[Idx++]);
+  E->Op = AtomicExpr::AtomicOp(Record.readInt());
   E->NumSubExprs = AtomicExpr::getNumSubExprs(E->Op);
   for (unsigned I = 0; I != E->NumSubExprs; ++I)
-    E->SubExprs[I] = Reader.ReadSubExpr();
-  E->BuiltinLoc = ReadSourceLocation(Record, Idx);
-  E->RParenLoc = ReadSourceLocation(Record, Idx);
+    E->SubExprs[I] = Record.readSubExpr();
+  E->BuiltinLoc = ReadSourceLocation();
+  E->RParenLoc = ReadSourceLocation();
 }
 
 //===----------------------------------------------------------------------===//
@@ -961,142 +948,141 @@
 
 void ASTStmtReader::VisitObjCStringLiteral(ObjCStringLiteral *E) {
   VisitExpr(E);
-  E->setString(cast<StringLiteral>(Reader.ReadSubStmt()));
-  E->setAtLoc(ReadSourceLocation(Record, Idx));
+  E->setString(cast<StringLiteral>(Record.readSubStmt()));
+  E->setAtLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
   VisitExpr(E);
   // could be one of several IntegerLiteral, FloatLiteral, etc.
-  E->SubExpr = Reader.ReadSubStmt();
-  E->BoxingMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
-  E->Range = ReadSourceRange(Record, Idx);
+  E->SubExpr = Record.readSubStmt();
+  E->BoxingMethod = ReadDeclAs<ObjCMethodDecl>();
+  E->Range = ReadSourceRange();
 }
 
 void ASTStmtReader::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
   VisitExpr(E);
-  unsigned NumElements = Record[Idx++];
+  unsigned NumElements = Record.readInt();
   assert(NumElements == E->getNumElements() && "Wrong number of elements");
   Expr **Elements = E->getElements();
   for (unsigned I = 0, N = NumElements; I != N; ++I)
-    Elements[I] = Reader.ReadSubExpr();
-  E->ArrayWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
-  E->Range = ReadSourceRange(Record, Idx);
+    Elements[I] = Record.readSubExpr();
+  E->ArrayWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>();
+  E->Range = ReadSourceRange();
 }
 
 void ASTStmtReader::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
   VisitExpr(E);
-  unsigned NumElements = Record[Idx++];
+  unsigned NumElements = Record.readInt();
   assert(NumElements == E->getNumElements() && "Wrong number of elements");
-  bool HasPackExpansions = Record[Idx++];
+  bool HasPackExpansions = Record.readInt();
   assert(HasPackExpansions == E->HasPackExpansions &&"Pack expansion mismatch");
   ObjCDictionaryLiteral::KeyValuePair *KeyValues =
       E->getTrailingObjects<ObjCDictionaryLiteral::KeyValuePair>();
   ObjCDictionaryLiteral::ExpansionData *Expansions =
       E->getTrailingObjects<ObjCDictionaryLiteral::ExpansionData>();
   for (unsigned I = 0; I != NumElements; ++I) {
-    KeyValues[I].Key = Reader.ReadSubExpr();
-    KeyValues[I].Value = Reader.ReadSubExpr();
+    KeyValues[I].Key = Record.readSubExpr();
+    KeyValues[I].Value = Record.readSubExpr();
     if (HasPackExpansions) {
-      Expansions[I].EllipsisLoc = ReadSourceLocation(Record, Idx);
-      Expansions[I].NumExpansionsPlusOne = Record[Idx++];
+      Expansions[I].EllipsisLoc = ReadSourceLocation();
+      Expansions[I].NumExpansionsPlusOne = Record.readInt();
     }
   }
-  E->DictWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
-  E->Range = ReadSourceRange(Record, Idx);
+  E->DictWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>();
+  E->Range = ReadSourceRange();
 }
 
 void ASTStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
   VisitExpr(E);
-  E->setEncodedTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
-  E->setAtLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
+  E->setEncodedTypeSourceInfo(GetTypeSourceInfo());
+  E->setAtLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
   VisitExpr(E);
-  E->setSelector(Reader.ReadSelector(F, Record, Idx));
-  E->setAtLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
+  E->setSelector(Record.readSelector());
+  E->setAtLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
   VisitExpr(E);
-  E->setProtocol(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
-  E->setAtLoc(ReadSourceLocation(Record, Idx));
-  E->ProtoLoc = ReadSourceLocation(Record, Idx);
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
+  E->setProtocol(ReadDeclAs<ObjCProtocolDecl>());
+  E->setAtLoc(ReadSourceLocation());
+  E->ProtoLoc = ReadSourceLocation();
+  E->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
   VisitExpr(E);
-  E->setDecl(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
-  E->setLocation(ReadSourceLocation(Record, Idx));
-  E->setOpLoc(ReadSourceLocation(Record, Idx));
-  E->setBase(Reader.ReadSubExpr());
-  E->setIsArrow(Record[Idx++]);
-  E->setIsFreeIvar(Record[Idx++]);
+  E->setDecl(ReadDeclAs<ObjCIvarDecl>());
+  E->setLocation(ReadSourceLocation());
+  E->setOpLoc(ReadSourceLocation());
+  E->setBase(Record.readSubExpr());
+  E->setIsArrow(Record.readInt());
+  E->setIsFreeIvar(Record.readInt());
 }
 
 void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
   VisitExpr(E);
-  unsigned MethodRefFlags = Record[Idx++];
-  bool Implicit = Record[Idx++] != 0;
+  unsigned MethodRefFlags = Record.readInt();
+  bool Implicit = Record.readInt() != 0;
   if (Implicit) {
-    ObjCMethodDecl *Getter = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
-    ObjCMethodDecl *Setter = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
+    ObjCMethodDecl *Getter = ReadDeclAs<ObjCMethodDecl>();
+    ObjCMethodDecl *Setter = ReadDeclAs<ObjCMethodDecl>();
     E->setImplicitProperty(Getter, Setter, MethodRefFlags);
   } else {
-    E->setExplicitProperty(ReadDeclAs<ObjCPropertyDecl>(Record, Idx),
-                           MethodRefFlags);
+    E->setExplicitProperty(ReadDeclAs<ObjCPropertyDecl>(), MethodRefFlags);
   }
-  E->setLocation(ReadSourceLocation(Record, Idx));
-  E->setReceiverLocation(ReadSourceLocation(Record, Idx));
-  switch (Record[Idx++]) {
+  E->setLocation(ReadSourceLocation());
+  E->setReceiverLocation(ReadSourceLocation());
+  switch (Record.readInt()) {
   case 0:
-    E->setBase(Reader.ReadSubExpr());
+    E->setBase(Record.readSubExpr());
     break;
   case 1:
-    E->setSuperReceiver(Reader.readType(F, Record, Idx));
+    E->setSuperReceiver(Record.readType());
     break;
   case 2:
-    E->setClassReceiver(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
+    E->setClassReceiver(ReadDeclAs<ObjCInterfaceDecl>());
     break;
   }
 }
 
 void ASTStmtReader::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
   VisitExpr(E);
-  E->setRBracket(ReadSourceLocation(Record, Idx));
-  E->setBaseExpr(Reader.ReadSubExpr());
-  E->setKeyExpr(Reader.ReadSubExpr());
-  E->GetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
-  E->SetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
+  E->setRBracket(ReadSourceLocation());
+  E->setBaseExpr(Record.readSubExpr());
+  E->setKeyExpr(Record.readSubExpr());
+  E->GetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>();
+  E->SetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>();
 }
 
 void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
   VisitExpr(E);
-  assert(Record[Idx] == E->getNumArgs());
-  ++Idx;
-  unsigned NumStoredSelLocs = Record[Idx++];
-  E->SelLocsKind = Record[Idx++]; 
-  E->setDelegateInitCall(Record[Idx++]);
-  E->IsImplicit = Record[Idx++];
+  assert(Record.peekInt() == E->getNumArgs());
+  Record.skipInts(1);
+  unsigned NumStoredSelLocs = Record.readInt();
+  E->SelLocsKind = Record.readInt();
+  E->setDelegateInitCall(Record.readInt());
+  E->IsImplicit = Record.readInt();
   ObjCMessageExpr::ReceiverKind Kind
-    = static_cast<ObjCMessageExpr::ReceiverKind>(Record[Idx++]);
+    = static_cast<ObjCMessageExpr::ReceiverKind>(Record.readInt());
   switch (Kind) {
   case ObjCMessageExpr::Instance:
-    E->setInstanceReceiver(Reader.ReadSubExpr());
+    E->setInstanceReceiver(Record.readSubExpr());
     break;
 
   case ObjCMessageExpr::Class:
-    E->setClassReceiver(GetTypeSourceInfo(Record, Idx));
+    E->setClassReceiver(GetTypeSourceInfo());
     break;
 
   case ObjCMessageExpr::SuperClass:
   case ObjCMessageExpr::SuperInstance: {
-    QualType T = Reader.readType(F, Record, Idx);
-    SourceLocation SuperLoc = ReadSourceLocation(Record, Idx);
+    QualType T = Record.readType();
+    SourceLocation SuperLoc = ReadSourceLocation();
     E->setSuper(SuperLoc, T, Kind == ObjCMessageExpr::SuperInstance);
     break;
   }
@@ -1104,90 +1090,90 @@
 
   assert(Kind == E->getReceiverKind());
 
-  if (Record[Idx++])
-    E->setMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
+  if (Record.readInt())
+    E->setMethodDecl(ReadDeclAs<ObjCMethodDecl>());
   else
-    E->setSelector(Reader.ReadSelector(F, Record, Idx));
+    E->setSelector(Record.readSelector());
 
-  E->LBracLoc = ReadSourceLocation(Record, Idx);
-  E->RBracLoc = ReadSourceLocation(Record, Idx);
+  E->LBracLoc = ReadSourceLocation();
+  E->RBracLoc = ReadSourceLocation();
 
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
-    E->setArg(I, Reader.ReadSubExpr());
+    E->setArg(I, Record.readSubExpr());
 
   SourceLocation *Locs = E->getStoredSelLocs();
   for (unsigned I = 0; I != NumStoredSelLocs; ++I)
-    Locs[I] = ReadSourceLocation(Record, Idx);
+    Locs[I] = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
   VisitStmt(S);
-  S->setElement(Reader.ReadSubStmt());
-  S->setCollection(Reader.ReadSubExpr());
-  S->setBody(Reader.ReadSubStmt());
-  S->setForLoc(ReadSourceLocation(Record, Idx));
-  S->setRParenLoc(ReadSourceLocation(Record, Idx));
+  S->setElement(Record.readSubStmt());
+  S->setCollection(Record.readSubExpr());
+  S->setBody(Record.readSubStmt());
+  S->setForLoc(ReadSourceLocation());
+  S->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
   VisitStmt(S);
-  S->setCatchBody(Reader.ReadSubStmt());
-  S->setCatchParamDecl(ReadDeclAs<VarDecl>(Record, Idx));
-  S->setAtCatchLoc(ReadSourceLocation(Record, Idx));
-  S->setRParenLoc(ReadSourceLocation(Record, Idx));
+  S->setCatchBody(Record.readSubStmt());
+  S->setCatchParamDecl(ReadDeclAs<VarDecl>());
+  S->setAtCatchLoc(ReadSourceLocation());
+  S->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
   VisitStmt(S);
-  S->setFinallyBody(Reader.ReadSubStmt());
-  S->setAtFinallyLoc(ReadSourceLocation(Record, Idx));
+  S->setFinallyBody(Record.readSubStmt());
+  S->setAtFinallyLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
   VisitStmt(S);
-  S->setSubStmt(Reader.ReadSubStmt());
-  S->setAtLoc(ReadSourceLocation(Record, Idx));
+  S->setSubStmt(Record.readSubStmt());
+  S->setAtLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
   VisitStmt(S);
-  assert(Record[Idx] == S->getNumCatchStmts());
-  ++Idx;
-  bool HasFinally = Record[Idx++];
-  S->setTryBody(Reader.ReadSubStmt());
+  assert(Record.peekInt() == S->getNumCatchStmts());
+  Record.skipInts(1);
+  bool HasFinally = Record.readInt();
+  S->setTryBody(Record.readSubStmt());
   for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
-    S->setCatchStmt(I, cast_or_null<ObjCAtCatchStmt>(Reader.ReadSubStmt()));
+    S->setCatchStmt(I, cast_or_null<ObjCAtCatchStmt>(Record.readSubStmt()));
 
   if (HasFinally)
-    S->setFinallyStmt(Reader.ReadSubStmt());
-  S->setAtTryLoc(ReadSourceLocation(Record, Idx));
+    S->setFinallyStmt(Record.readSubStmt());
+  S->setAtTryLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
   VisitStmt(S);
-  S->setSynchExpr(Reader.ReadSubStmt());
-  S->setSynchBody(Reader.ReadSubStmt());
-  S->setAtSynchronizedLoc(ReadSourceLocation(Record, Idx));
+  S->setSynchExpr(Record.readSubStmt());
+  S->setSynchBody(Record.readSubStmt());
+  S->setAtSynchronizedLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
   VisitStmt(S);
-  S->setThrowExpr(Reader.ReadSubStmt());
-  S->setThrowLoc(ReadSourceLocation(Record, Idx));
+  S->setThrowExpr(Record.readSubStmt());
+  S->setThrowLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
   VisitExpr(E);
-  E->setValue(Record[Idx++]);
-  E->setLocation(ReadSourceLocation(Record, Idx));
+  E->setValue(Record.readInt());
+  E->setLocation(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
   VisitExpr(E);
-  SourceRange R = Reader.ReadSourceRange(F, Record, Idx);
+  SourceRange R = Record.readSourceRange();
   E->AtLoc = R.getBegin();
   E->RParen = R.getEnd();
-  E->VersionToCheck = Reader.ReadVersionTuple(Record, Idx);
+  E->VersionToCheck = Record.readVersionTuple();
 }
 
 //===----------------------------------------------------------------------===//
@@ -1196,125 +1182,113 @@
 
 void ASTStmtReader::VisitCXXCatchStmt(CXXCatchStmt *S) {
   VisitStmt(S);
-  S->CatchLoc = ReadSourceLocation(Record, Idx);
-  S->ExceptionDecl = ReadDeclAs<VarDecl>(Record, Idx);
-  S->HandlerBlock = Reader.ReadSubStmt();
+  S->CatchLoc = ReadSourceLocation();
+  S->ExceptionDecl = ReadDeclAs<VarDecl>();
+  S->HandlerBlock = Record.readSubStmt();
 }
 
 void ASTStmtReader::VisitCXXTryStmt(CXXTryStmt *S) {
   VisitStmt(S);
-  assert(Record[Idx] == S->getNumHandlers() && "NumStmtFields is wrong ?");
-  ++Idx;
-  S->TryLoc = ReadSourceLocation(Record, Idx);
-  S->getStmts()[0] = Reader.ReadSubStmt();
+  assert(Record.peekInt() == S->getNumHandlers() && "NumStmtFields is wrong ?");
+  Record.skipInts(1);
+  S->TryLoc = ReadSourceLocation();
+  S->getStmts()[0] = Record.readSubStmt();
   for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
-    S->getStmts()[i + 1] = Reader.ReadSubStmt();
+    S->getStmts()[i + 1] = Record.readSubStmt();
 }
 
 void ASTStmtReader::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
   VisitStmt(S);
-  S->ForLoc = ReadSourceLocation(Record, Idx);
-  S->CoawaitLoc = ReadSourceLocation(Record, Idx);
-  S->ColonLoc = ReadSourceLocation(Record, Idx);
-  S->RParenLoc = ReadSourceLocation(Record, Idx);
-  S->setRangeStmt(Reader.ReadSubStmt());
-  S->setBeginStmt(Reader.ReadSubStmt());
-  S->setEndStmt(Reader.ReadSubStmt());
-  S->setCond(Reader.ReadSubExpr());
-  S->setInc(Reader.ReadSubExpr());
-  S->setLoopVarStmt(Reader.ReadSubStmt());
-  S->setBody(Reader.ReadSubStmt());
+  S->ForLoc = ReadSourceLocation();
+  S->CoawaitLoc = ReadSourceLocation();
+  S->ColonLoc = ReadSourceLocation();
+  S->RParenLoc = ReadSourceLocation();
+  S->setRangeStmt(Record.readSubStmt());
+  S->setBeginStmt(Record.readSubStmt());
+  S->setEndStmt(Record.readSubStmt());
+  S->setCond(Record.readSubExpr());
+  S->setInc(Record.readSubExpr());
+  S->setLoopVarStmt(Record.readSubStmt());
+  S->setBody(Record.readSubStmt());
 }
 
 void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
   VisitStmt(S);
-  S->KeywordLoc = ReadSourceLocation(Record, Idx);
-  S->IsIfExists = Record[Idx++];
-  S->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
-  ReadDeclarationNameInfo(S->NameInfo, Record, Idx);
-  S->SubStmt = Reader.ReadSubStmt();
+  S->KeywordLoc = ReadSourceLocation();
+  S->IsIfExists = Record.readInt();
+  S->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  ReadDeclarationNameInfo(S->NameInfo);
+  S->SubStmt = Record.readSubStmt();
 }
 
 void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   VisitCallExpr(E);
-  E->Operator = (OverloadedOperatorKind)Record[Idx++];
-  E->Range = Reader.ReadSourceRange(F, Record, Idx);
-  E->setFPContractable((bool)Record[Idx++]);
+  E->Operator = (OverloadedOperatorKind)Record.readInt();
+  E->Range = Record.readSourceRange();
+  E->setFPContractable((bool)Record.readInt());
 }
 
 void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
   VisitExpr(E);
-  E->NumArgs = Record[Idx++];
+  E->NumArgs = Record.readInt();
   if (E->NumArgs)
-    E->Args = new (Reader.getContext()) Stmt*[E->NumArgs];
+    E->Args = new (Record.getContext()) Stmt*[E->NumArgs];
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
-    E->setArg(I, Reader.ReadSubExpr());
-  E->setConstructor(ReadDeclAs<CXXConstructorDecl>(Record, Idx));
-  E->setLocation(ReadSourceLocation(Record, Idx));
-  E->setElidable(Record[Idx++]);
-  E->setHadMultipleCandidates(Record[Idx++]);
-  E->setListInitialization(Record[Idx++]);
-  E->setStdInitListInitialization(Record[Idx++]);
-  E->setRequiresZeroInitialization(Record[Idx++]);
-  E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]);
-  E->ParenOrBraceRange = ReadSourceRange(Record, Idx);
+    E->setArg(I, Record.readSubExpr());
+  E->setConstructor(ReadDeclAs<CXXConstructorDecl>());
+  E->setLocation(ReadSourceLocation());
+  E->setElidable(Record.readInt());
+  E->setHadMultipleCandidates(Record.readInt());
+  E->setListInitialization(Record.readInt());
+  E->setStdInitListInitialization(Record.readInt());
+  E->setRequiresZeroInitialization(Record.readInt());
+  E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record.readInt());
+  E->ParenOrBraceRange = ReadSourceRange();
 }
 
 void ASTStmtReader::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
   VisitExpr(E);
-  E->Constructor = ReadDeclAs<CXXConstructorDecl>(Record, Idx);
-  E->Loc = ReadSourceLocation(Record, Idx);
-  E->ConstructsVirtualBase = Record[Idx++];
-  E->InheritedFromVirtualBase = Record[Idx++];
+  E->Constructor = ReadDeclAs<CXXConstructorDecl>();
+  E->Loc = ReadSourceLocation();
+  E->ConstructsVirtualBase = Record.readInt();
+  E->InheritedFromVirtualBase = Record.readInt();
 }
 
 void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
   VisitCXXConstructExpr(E);
-  E->Type = GetTypeSourceInfo(Record, Idx);
+  E->Type = GetTypeSourceInfo();
 }
 
 void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) {
   VisitExpr(E);
-  unsigned NumCaptures = Record[Idx++];
+  unsigned NumCaptures = Record.readInt();
   assert(NumCaptures == E->NumCaptures);(void)NumCaptures;
-  unsigned NumArrayIndexVars = Record[Idx++];
-  E->IntroducerRange = ReadSourceRange(Record, Idx);
-  E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record[Idx++]);
-  E->CaptureDefaultLoc = ReadSourceLocation(Record, Idx);
-  E->ExplicitParams = Record[Idx++];
-  E->ExplicitResultType = Record[Idx++];
-  E->ClosingBrace = ReadSourceLocation(Record, Idx);
-  
+  E->IntroducerRange = ReadSourceRange();
+  E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record.readInt());
+  E->CaptureDefaultLoc = ReadSourceLocation();
+  E->ExplicitParams = Record.readInt();
+  E->ExplicitResultType = Record.readInt();
+  E->ClosingBrace = ReadSourceLocation();
+
   // Read capture initializers.
   for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
                                       CEnd = E->capture_init_end();
        C != CEnd; ++C)
-    *C = Reader.ReadSubExpr();
-  
-  // Read array capture index variables.
-  if (NumArrayIndexVars > 0) {
-    unsigned *ArrayIndexStarts = E->getArrayIndexStarts();
-    for (unsigned I = 0; I != NumCaptures + 1; ++I)
-      ArrayIndexStarts[I] = Record[Idx++];
-    
-    VarDecl **ArrayIndexVars = E->getArrayIndexVars();
-    for (unsigned I = 0; I != NumArrayIndexVars; ++I)
-      ArrayIndexVars[I] = ReadDeclAs<VarDecl>(Record, Idx);
-  }
+    *C = Record.readSubExpr();
 }
 
 void
 ASTStmtReader::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
   VisitExpr(E);
-  E->SubExpr = Reader.ReadSubExpr();
+  E->SubExpr = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
   VisitExplicitCastExpr(E);
-  SourceRange R = ReadSourceRange(Record, Idx);
+  SourceRange R = ReadSourceRange();
   E->Loc = R.getBegin();
   E->RParenLoc = R.getEnd();
-  R = ReadSourceRange(Record, Idx);
+  R = ReadSourceRange();
   E->AngleBrackets = R;
 }
 
@@ -1336,344 +1310,345 @@
 
 void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
   VisitExplicitCastExpr(E);
-  E->setLParenLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
+  E->setLParenLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
   VisitCallExpr(E);
-  E->UDSuffixLoc = ReadSourceLocation(Record, Idx);
+  E->UDSuffixLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
   VisitExpr(E);
-  E->setValue(Record[Idx++]);
-  E->setLocation(ReadSourceLocation(Record, Idx));
+  E->setValue(Record.readInt());
+  E->setLocation(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
   VisitExpr(E);
-  E->setLocation(ReadSourceLocation(Record, Idx));
+  E->setLocation(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
   VisitExpr(E);
-  E->setSourceRange(ReadSourceRange(Record, Idx));
+  E->setSourceRange(ReadSourceRange());
   if (E->isTypeOperand()) { // typeid(int)
     E->setTypeOperandSourceInfo(
-        GetTypeSourceInfo(Record, Idx));
+        GetTypeSourceInfo());
     return;
   }
-  
+
   // typeid(42+2)
-  E->setExprOperand(Reader.ReadSubExpr());
+  E->setExprOperand(Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
   VisitExpr(E);
-  E->setLocation(ReadSourceLocation(Record, Idx));
-  E->setImplicit(Record[Idx++]);
+  E->setLocation(ReadSourceLocation());
+  E->setImplicit(Record.readInt());
 }
 
 void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
   VisitExpr(E);
-  E->ThrowLoc = ReadSourceLocation(Record, Idx);
-  E->Op = Reader.ReadSubExpr();
-  E->IsThrownVariableInScope = Record[Idx++];
+  E->ThrowLoc = ReadSourceLocation();
+  E->Op = Record.readSubExpr();
+  E->IsThrownVariableInScope = Record.readInt();
 }
 
 void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   VisitExpr(E);
-  E->Param = ReadDeclAs<ParmVarDecl>(Record, Idx);
-  E->Loc = ReadSourceLocation(Record, Idx);
+  E->Param = ReadDeclAs<ParmVarDecl>();
+  E->Loc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
   VisitExpr(E);
-  E->Field = ReadDeclAs<FieldDecl>(Record, Idx);
-  E->Loc = ReadSourceLocation(Record, Idx);
+  E->Field = ReadDeclAs<FieldDecl>();
+  E->Loc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
   VisitExpr(E);
-  E->setTemporary(Reader.ReadCXXTemporary(F, Record, Idx));
-  E->setSubExpr(Reader.ReadSubExpr());
+  E->setTemporary(Record.readCXXTemporary());
+  E->setSubExpr(Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   VisitExpr(E);
-  E->TypeInfo = GetTypeSourceInfo(Record, Idx);
-  E->RParenLoc = ReadSourceLocation(Record, Idx);
+  E->TypeInfo = GetTypeSourceInfo();
+  E->RParenLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
   VisitExpr(E);
-  E->GlobalNew = Record[Idx++];
-  bool isArray = Record[Idx++];
-  E->PassAlignment = Record[Idx++];
-  E->UsualArrayDeleteWantsSize = Record[Idx++];
-  unsigned NumPlacementArgs = Record[Idx++];
-  E->StoredInitializationStyle = Record[Idx++];
-  E->setOperatorNew(ReadDeclAs<FunctionDecl>(Record, Idx));
-  E->setOperatorDelete(ReadDeclAs<FunctionDecl>(Record, Idx));
-  E->AllocatedTypeInfo = GetTypeSourceInfo(Record, Idx);
-  E->TypeIdParens = ReadSourceRange(Record, Idx);
-  E->Range = ReadSourceRange(Record, Idx);
-  E->DirectInitRange = ReadSourceRange(Record, Idx);
+  E->GlobalNew = Record.readInt();
+  bool isArray = Record.readInt();
+  E->PassAlignment = Record.readInt();
+  E->UsualArrayDeleteWantsSize = Record.readInt();
+  unsigned NumPlacementArgs = Record.readInt();
+  E->StoredInitializationStyle = Record.readInt();
+  E->setOperatorNew(ReadDeclAs<FunctionDecl>());
+  E->setOperatorDelete(ReadDeclAs<FunctionDecl>());
+  E->AllocatedTypeInfo = GetTypeSourceInfo();
+  E->TypeIdParens = ReadSourceRange();
+  E->Range = ReadSourceRange();
+  E->DirectInitRange = ReadSourceRange();
 
-  E->AllocateArgsArray(Reader.getContext(), isArray, NumPlacementArgs,
+  E->AllocateArgsArray(Record.getContext(), isArray, NumPlacementArgs,
                        E->StoredInitializationStyle != 0);
 
   // Install all the subexpressions.
   for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),e = E->raw_arg_end();
        I != e; ++I)
-    *I = Reader.ReadSubStmt();
+    *I = Record.readSubStmt();
 }
 
 void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
   VisitExpr(E);
-  E->GlobalDelete = Record[Idx++];
-  E->ArrayForm = Record[Idx++];
-  E->ArrayFormAsWritten = Record[Idx++];
-  E->UsualArrayDeleteWantsSize = Record[Idx++];
-  E->OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx);
-  E->Argument = Reader.ReadSubExpr();
-  E->Loc = ReadSourceLocation(Record, Idx);
+  E->GlobalDelete = Record.readInt();
+  E->ArrayForm = Record.readInt();
+  E->ArrayFormAsWritten = Record.readInt();
+  E->UsualArrayDeleteWantsSize = Record.readInt();
+  E->OperatorDelete = ReadDeclAs<FunctionDecl>();
+  E->Argument = Record.readSubExpr();
+  E->Loc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
   VisitExpr(E);
 
-  E->Base = Reader.ReadSubExpr();
-  E->IsArrow = Record[Idx++];
-  E->OperatorLoc = ReadSourceLocation(Record, Idx);
-  E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
-  E->ScopeType = GetTypeSourceInfo(Record, Idx);
-  E->ColonColonLoc = ReadSourceLocation(Record, Idx);
-  E->TildeLoc = ReadSourceLocation(Record, Idx);
-  
-  IdentifierInfo *II = Reader.GetIdentifierInfo(F, Record, Idx);
+  E->Base = Record.readSubExpr();
+  E->IsArrow = Record.readInt();
+  E->OperatorLoc = ReadSourceLocation();
+  E->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  E->ScopeType = GetTypeSourceInfo();
+  E->ColonColonLoc = ReadSourceLocation();
+  E->TildeLoc = ReadSourceLocation();
+
+  IdentifierInfo *II = Record.getIdentifierInfo();
   if (II)
-    E->setDestroyedType(II, ReadSourceLocation(Record, Idx));
+    E->setDestroyedType(II, ReadSourceLocation());
   else
-    E->setDestroyedType(GetTypeSourceInfo(Record, Idx));
+    E->setDestroyedType(GetTypeSourceInfo());
 }
 
 void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) {
   VisitExpr(E);
 
-  unsigned NumObjects = Record[Idx++];
+  unsigned NumObjects = Record.readInt();
   assert(NumObjects == E->getNumObjects());
   for (unsigned i = 0; i != NumObjects; ++i)
     E->getTrailingObjects<BlockDecl *>()[i] =
-        ReadDeclAs<BlockDecl>(Record, Idx);
+        ReadDeclAs<BlockDecl>();
 
-  E->ExprWithCleanupsBits.CleanupsHaveSideEffects = Record[Idx++];
-  E->SubExpr = Reader.ReadSubExpr();
+  E->ExprWithCleanupsBits.CleanupsHaveSideEffects = Record.readInt();
+  E->SubExpr = Record.readSubExpr();
 }
 
 void
 ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
   VisitExpr(E);
 
-  if (Record[Idx++]) // HasTemplateKWAndArgsInfo
+  if (Record.readInt()) // HasTemplateKWAndArgsInfo
     ReadTemplateKWAndArgsInfo(
         *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
         E->getTrailingObjects<TemplateArgumentLoc>(),
-        /*NumTemplateArgs=*/Record[Idx++]);
+        /*NumTemplateArgs=*/Record.readInt());
 
-  E->Base = Reader.ReadSubExpr();
-  E->BaseType = Reader.readType(F, Record, Idx);
-  E->IsArrow = Record[Idx++];
-  E->OperatorLoc = ReadSourceLocation(Record, Idx);
-  E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
-  E->FirstQualifierFoundInScope = ReadDeclAs<NamedDecl>(Record, Idx);
-  ReadDeclarationNameInfo(E->MemberNameInfo, Record, Idx);
+  E->Base = Record.readSubExpr();
+  E->BaseType = Record.readType();
+  E->IsArrow = Record.readInt();
+  E->OperatorLoc = ReadSourceLocation();
+  E->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  E->FirstQualifierFoundInScope = ReadDeclAs<NamedDecl>();
+  ReadDeclarationNameInfo(E->MemberNameInfo);
 }
 
 void
 ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
   VisitExpr(E);
 
-  if (Record[Idx++]) // HasTemplateKWAndArgsInfo
+  if (Record.readInt()) // HasTemplateKWAndArgsInfo
     ReadTemplateKWAndArgsInfo(
         *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
         E->getTrailingObjects<TemplateArgumentLoc>(),
-        /*NumTemplateArgs=*/Record[Idx++]);
+        /*NumTemplateArgs=*/Record.readInt());
 
-  E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
-  ReadDeclarationNameInfo(E->NameInfo, Record, Idx);
+  E->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  ReadDeclarationNameInfo(E->NameInfo);
 }
 
 void
 ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
   VisitExpr(E);
-  assert(Record[Idx] == E->arg_size() && "Read wrong record during creation ?");
-  ++Idx; // NumArgs;
+  assert(Record.peekInt() == E->arg_size() &&
+         "Read wrong record during creation ?");
+  Record.skipInts(1);
   for (unsigned I = 0, N = E->arg_size(); I != N; ++I)
-    E->setArg(I, Reader.ReadSubExpr());
-  E->Type = GetTypeSourceInfo(Record, Idx);
-  E->setLParenLoc(ReadSourceLocation(Record, Idx));
-  E->setRParenLoc(ReadSourceLocation(Record, Idx));
+    E->setArg(I, Record.readSubExpr());
+  E->Type = GetTypeSourceInfo();
+  E->setLParenLoc(ReadSourceLocation());
+  E->setRParenLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
   VisitExpr(E);
 
-  if (Record[Idx++]) // HasTemplateKWAndArgsInfo
+  if (Record.readInt()) // HasTemplateKWAndArgsInfo
     ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(),
                               E->getTrailingTemplateArgumentLoc(),
-                              /*NumTemplateArgs=*/Record[Idx++]);
+                              /*NumTemplateArgs=*/Record.readInt());
 
-  unsigned NumDecls = Record[Idx++];
+  unsigned NumDecls = Record.readInt();
   UnresolvedSet<8> Decls;
   for (unsigned i = 0; i != NumDecls; ++i) {
-    NamedDecl *D = ReadDeclAs<NamedDecl>(Record, Idx);
-    AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
+    NamedDecl *D = ReadDeclAs<NamedDecl>();
+    AccessSpecifier AS = (AccessSpecifier)Record.readInt();
     Decls.addDecl(D, AS);
   }
-  E->initializeResults(Reader.getContext(), Decls.begin(), Decls.end());
+  E->initializeResults(Record.getContext(), Decls.begin(), Decls.end());
 
-  ReadDeclarationNameInfo(E->NameInfo, Record, Idx);
-  E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
+  ReadDeclarationNameInfo(E->NameInfo);
+  E->QualifierLoc = Record.readNestedNameSpecifierLoc();
 }
 
 void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
   VisitOverloadExpr(E);
-  E->IsArrow = Record[Idx++];
-  E->HasUnresolvedUsing = Record[Idx++];
-  E->Base = Reader.ReadSubExpr();
-  E->BaseType = Reader.readType(F, Record, Idx);
-  E->OperatorLoc = ReadSourceLocation(Record, Idx);
+  E->IsArrow = Record.readInt();
+  E->HasUnresolvedUsing = Record.readInt();
+  E->Base = Record.readSubExpr();
+  E->BaseType = Record.readType();
+  E->OperatorLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
   VisitOverloadExpr(E);
-  E->RequiresADL = Record[Idx++];
-  E->Overloaded = Record[Idx++];
-  E->NamingClass = ReadDeclAs<CXXRecordDecl>(Record, Idx);
+  E->RequiresADL = Record.readInt();
+  E->Overloaded = Record.readInt();
+  E->NamingClass = ReadDeclAs<CXXRecordDecl>();
 }
 
 void ASTStmtReader::VisitTypeTraitExpr(TypeTraitExpr *E) {
   VisitExpr(E);
-  E->TypeTraitExprBits.NumArgs = Record[Idx++];
-  E->TypeTraitExprBits.Kind = Record[Idx++];
-  E->TypeTraitExprBits.Value = Record[Idx++];
-  SourceRange Range = ReadSourceRange(Record, Idx);
+  E->TypeTraitExprBits.NumArgs = Record.readInt();
+  E->TypeTraitExprBits.Kind = Record.readInt();
+  E->TypeTraitExprBits.Value = Record.readInt();
+  SourceRange Range = ReadSourceRange();
   E->Loc = Range.getBegin();
   E->RParenLoc = Range.getEnd();
 
   TypeSourceInfo **Args = E->getTrailingObjects<TypeSourceInfo *>();
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
-    Args[I] = GetTypeSourceInfo(Record, Idx);
+    Args[I] = GetTypeSourceInfo();
 }
 
 void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
   VisitExpr(E);
-  E->ATT = (ArrayTypeTrait)Record[Idx++];
-  E->Value = (unsigned int)Record[Idx++];
-  SourceRange Range = ReadSourceRange(Record, Idx);
+  E->ATT = (ArrayTypeTrait)Record.readInt();
+  E->Value = (unsigned int)Record.readInt();
+  SourceRange Range = ReadSourceRange();
   E->Loc = Range.getBegin();
   E->RParen = Range.getEnd();
-  E->QueriedType = GetTypeSourceInfo(Record, Idx);
-  E->Dimension = Reader.ReadSubExpr();
+  E->QueriedType = GetTypeSourceInfo();
+  E->Dimension = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
   VisitExpr(E);
-  E->ET = (ExpressionTrait)Record[Idx++];
-  E->Value = (bool)Record[Idx++];
-  SourceRange Range = ReadSourceRange(Record, Idx);
-  E->QueriedExpression = Reader.ReadSubExpr();
+  E->ET = (ExpressionTrait)Record.readInt();
+  E->Value = (bool)Record.readInt();
+  SourceRange Range = ReadSourceRange();
+  E->QueriedExpression = Record.readSubExpr();
   E->Loc = Range.getBegin();
   E->RParen = Range.getEnd();
 }
 
 void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
   VisitExpr(E);
-  E->Value = (bool)Record[Idx++];
-  E->Range = ReadSourceRange(Record, Idx);
-  E->Operand = Reader.ReadSubExpr();
+  E->Value = (bool)Record.readInt();
+  E->Range = ReadSourceRange();
+  E->Operand = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitPackExpansionExpr(PackExpansionExpr *E) {
   VisitExpr(E);
-  E->EllipsisLoc = ReadSourceLocation(Record, Idx);
-  E->NumExpansions = Record[Idx++];
-  E->Pattern = Reader.ReadSubExpr();  
+  E->EllipsisLoc = ReadSourceLocation();
+  E->NumExpansions = Record.readInt();
+  E->Pattern = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
   VisitExpr(E);
-  unsigned NumPartialArgs = Record[Idx++];
-  E->OperatorLoc = ReadSourceLocation(Record, Idx);
-  E->PackLoc = ReadSourceLocation(Record, Idx);
-  E->RParenLoc = ReadSourceLocation(Record, Idx);
-  E->Pack = Reader.ReadDeclAs<NamedDecl>(F, Record, Idx);
+  unsigned NumPartialArgs = Record.readInt();
+  E->OperatorLoc = ReadSourceLocation();
+  E->PackLoc = ReadSourceLocation();
+  E->RParenLoc = ReadSourceLocation();
+  E->Pack = Record.readDeclAs<NamedDecl>();
   if (E->isPartiallySubstituted()) {
     assert(E->Length == NumPartialArgs);
     for (auto *I = E->getTrailingObjects<TemplateArgument>(),
               *E = I + NumPartialArgs;
          I != E; ++I)
-      new (I) TemplateArgument(Reader.ReadTemplateArgument(F, Record, Idx));
+      new (I) TemplateArgument(Record.readTemplateArgument());
   } else if (!E->isValueDependent()) {
-    E->Length = Record[Idx++];
+    E->Length = Record.readInt();
   }
 }
 
 void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
                                               SubstNonTypeTemplateParmExpr *E) {
   VisitExpr(E);
-  E->Param = ReadDeclAs<NonTypeTemplateParmDecl>(Record, Idx);
-  E->NameLoc = ReadSourceLocation(Record, Idx);
-  E->Replacement = Reader.ReadSubExpr();
+  E->Param = ReadDeclAs<NonTypeTemplateParmDecl>();
+  E->NameLoc = ReadSourceLocation();
+  E->Replacement = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitSubstNonTypeTemplateParmPackExpr(
                                           SubstNonTypeTemplateParmPackExpr *E) {
   VisitExpr(E);
-  E->Param = ReadDeclAs<NonTypeTemplateParmDecl>(Record, Idx);
-  TemplateArgument ArgPack = Reader.ReadTemplateArgument(F, Record, Idx);
+  E->Param = ReadDeclAs<NonTypeTemplateParmDecl>();
+  TemplateArgument ArgPack = Record.readTemplateArgument();
   if (ArgPack.getKind() != TemplateArgument::Pack)
     return;
-  
+
   E->Arguments = ArgPack.pack_begin();
   E->NumArguments = ArgPack.pack_size();
-  E->NameLoc = ReadSourceLocation(Record, Idx);
+  E->NameLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
   VisitExpr(E);
-  E->NumParameters = Record[Idx++];
-  E->ParamPack = ReadDeclAs<ParmVarDecl>(Record, Idx);
-  E->NameLoc = ReadSourceLocation(Record, Idx);
+  E->NumParameters = Record.readInt();
+  E->ParamPack = ReadDeclAs<ParmVarDecl>();
+  E->NameLoc = ReadSourceLocation();
   ParmVarDecl **Parms = E->getTrailingObjects<ParmVarDecl *>();
   for (unsigned i = 0, n = E->NumParameters; i != n; ++i)
-    Parms[i] = ReadDeclAs<ParmVarDecl>(Record, Idx);
+    Parms[i] = ReadDeclAs<ParmVarDecl>();
 }
 
 void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
   VisitExpr(E);
-  E->State = Reader.ReadSubExpr();
-  auto VD = ReadDeclAs<ValueDecl>(Record, Idx);
-  unsigned ManglingNumber = Record[Idx++];
+  E->State = Record.readSubExpr();
+  auto VD = ReadDeclAs<ValueDecl>();
+  unsigned ManglingNumber = Record.readInt();
   E->setExtendingDecl(VD, ManglingNumber);
 }
 
 void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) {
   VisitExpr(E);
-  E->LParenLoc = ReadSourceLocation(Record, Idx);
-  E->EllipsisLoc = ReadSourceLocation(Record, Idx);
-  E->RParenLoc = ReadSourceLocation(Record, Idx);
-  E->SubExprs[0] = Reader.ReadSubExpr();
-  E->SubExprs[1] = Reader.ReadSubExpr();
-  E->Opcode = (BinaryOperatorKind)Record[Idx++];
+  E->LParenLoc = ReadSourceLocation();
+  E->EllipsisLoc = ReadSourceLocation();
+  E->RParenLoc = ReadSourceLocation();
+  E->SubExprs[0] = Record.readSubExpr();
+  E->SubExprs[1] = Record.readSubExpr();
+  E->Opcode = (BinaryOperatorKind)Record.readInt();
 }
 
 void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
   VisitExpr(E);
-  E->SourceExpr = Reader.ReadSubExpr();
-  E->Loc = ReadSourceLocation(Record, Idx);
+  E->SourceExpr = Record.readSubExpr();
+  E->Loc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitTypoExpr(TypoExpr *E) {
@@ -1685,59 +1660,59 @@
 //===----------------------------------------------------------------------===//
 void ASTStmtReader::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
   VisitExpr(E);
-  E->IsArrow = (Record[Idx++] != 0);
-  E->BaseExpr = Reader.ReadSubExpr();
-  E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
-  E->MemberLoc = ReadSourceLocation(Record, Idx);
-  E->TheDecl = ReadDeclAs<MSPropertyDecl>(Record, Idx);
+  E->IsArrow = (Record.readInt() != 0);
+  E->BaseExpr = Record.readSubExpr();
+  E->QualifierLoc = Record.readNestedNameSpecifierLoc();
+  E->MemberLoc = ReadSourceLocation();
+  E->TheDecl = ReadDeclAs<MSPropertyDecl>();
 }
 
 void ASTStmtReader::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
   VisitExpr(E);
-  E->setBase(Reader.ReadSubExpr());
-  E->setIdx(Reader.ReadSubExpr());
-  E->setRBracketLoc(ReadSourceLocation(Record, Idx));
+  E->setBase(Record.readSubExpr());
+  E->setIdx(Record.readSubExpr());
+  E->setRBracketLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
   VisitExpr(E);
-  E->setSourceRange(ReadSourceRange(Record, Idx));
-  std::string UuidStr = ReadString(Record, Idx);
-  E->setUuidStr(StringRef(UuidStr).copy(Reader.getContext()));
+  E->setSourceRange(ReadSourceRange());
+  std::string UuidStr = ReadString();
+  E->setUuidStr(StringRef(UuidStr).copy(Record.getContext()));
   if (E->isTypeOperand()) { // __uuidof(ComType)
     E->setTypeOperandSourceInfo(
-        GetTypeSourceInfo(Record, Idx));
+        GetTypeSourceInfo());
     return;
   }
-  
+
   // __uuidof(expr)
-  E->setExprOperand(Reader.ReadSubExpr());
+  E->setExprOperand(Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
   VisitStmt(S);
-  S->setLeaveLoc(ReadSourceLocation(Record, Idx));
+  S->setLeaveLoc(ReadSourceLocation());
 }
 
 void ASTStmtReader::VisitSEHExceptStmt(SEHExceptStmt *S) {
   VisitStmt(S);
-  S->Loc = ReadSourceLocation(Record, Idx);
-  S->Children[SEHExceptStmt::FILTER_EXPR] = Reader.ReadSubStmt();
-  S->Children[SEHExceptStmt::BLOCK] = Reader.ReadSubStmt();
+  S->Loc = ReadSourceLocation();
+  S->Children[SEHExceptStmt::FILTER_EXPR] = Record.readSubStmt();
+  S->Children[SEHExceptStmt::BLOCK] = Record.readSubStmt();
 }
 
 void ASTStmtReader::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
   VisitStmt(S);
-  S->Loc = ReadSourceLocation(Record, Idx);
-  S->Block = Reader.ReadSubStmt();
+  S->Loc = ReadSourceLocation();
+  S->Block = Record.readSubStmt();
 }
 
 void ASTStmtReader::VisitSEHTryStmt(SEHTryStmt *S) {
   VisitStmt(S);
-  S->IsCXXTry = Record[Idx++];
-  S->TryLoc = ReadSourceLocation(Record, Idx);
-  S->Children[SEHTryStmt::TRY] = Reader.ReadSubStmt();
-  S->Children[SEHTryStmt::HANDLER] = Reader.ReadSubStmt();
+  S->IsCXXTry = Record.readInt();
+  S->TryLoc = ReadSourceLocation();
+  S->Children[SEHTryStmt::TRY] = Record.readSubStmt();
+  S->Children[SEHTryStmt::HANDLER] = Record.readSubStmt();
 }
 
 //===----------------------------------------------------------------------===//
@@ -1746,7 +1721,7 @@
 
 void ASTStmtReader::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
   VisitCallExpr(E);
-  E->setConfig(cast<CallExpr>(Reader.ReadSubExpr()));
+  E->setConfig(cast<CallExpr>(Record.readSubExpr()));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1754,9 +1729,9 @@
 //===----------------------------------------------------------------------===//
 void ASTStmtReader::VisitAsTypeExpr(AsTypeExpr *E) {
   VisitExpr(E);
-  E->BuiltinLoc = ReadSourceLocation(Record, Idx);
-  E->RParenLoc = ReadSourceLocation(Record, Idx);
-  E->SrcExpr = Reader.ReadSubExpr();
+  E->BuiltinLoc = ReadSourceLocation();
+  E->RParenLoc = ReadSourceLocation();
+  E->SrcExpr = Record.readSubExpr();
 }
 
 //===----------------------------------------------------------------------===//
@@ -1767,12 +1742,9 @@
 class OMPClauseReader : public OMPClauseVisitor<OMPClauseReader> {
   ASTStmtReader *Reader;
   ASTContext &Context;
-  const ASTReader::RecordData &Record;
-  unsigned &Idx;
 public:
-  OMPClauseReader(ASTStmtReader *R, ASTContext &C,
-                  const ASTReader::RecordData &Record, unsigned &Idx)
-    : Reader(R), Context(C), Record(Record), Idx(Idx) { }
+  OMPClauseReader(ASTStmtReader *R, ASTRecordReader &Record)
+      : Reader(R), Context(Record.getContext()) {}
 #define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *C);
 #include "clang/Basic/OpenMPKinds.def"
   OMPClause *readClause();
@@ -1783,7 +1755,7 @@
 
 OMPClause *OMPClauseReader::readClause() {
   OMPClause *C;
-  switch (Record[Idx++]) {
+  switch (Reader->Record.readInt()) {
   case OMPC_if:
     C = new (Context) OMPIfClause();
     break;
@@ -1848,46 +1820,46 @@
     C = new (Context) OMPNogroupClause();
     break;
   case OMPC_private:
-    C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPPrivateClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_firstprivate:
-    C = OMPFirstprivateClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPFirstprivateClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_lastprivate:
-    C = OMPLastprivateClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPLastprivateClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_shared:
-    C = OMPSharedClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPSharedClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_reduction:
-    C = OMPReductionClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPReductionClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_linear:
-    C = OMPLinearClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPLinearClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_aligned:
-    C = OMPAlignedClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPAlignedClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_copyin:
-    C = OMPCopyinClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPCopyinClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_copyprivate:
-    C = OMPCopyprivateClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPCopyprivateClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_flush:
-    C = OMPFlushClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPFlushClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_depend:
-    C = OMPDependClause::CreateEmpty(Context, Record[Idx++]);
+    C = OMPDependClause::CreateEmpty(Context, Reader->Record.readInt());
     break;
   case OMPC_device:
     C = new (Context) OMPDeviceClause();
     break;
   case OMPC_map: {
-    unsigned NumVars = Record[Idx++];
-    unsigned NumDeclarations = Record[Idx++];
-    unsigned NumLists = Record[Idx++];
-    unsigned NumComponents = Record[Idx++];
+    unsigned NumVars = Reader->Record.readInt();
+    unsigned NumDeclarations = Reader->Record.readInt();
+    unsigned NumLists = Reader->Record.readInt();
+    unsigned NumComponents = Reader->Record.readInt();
     C = OMPMapClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
                                   NumComponents);
     break;
@@ -1917,124 +1889,127 @@
     C = new (Context) OMPDefaultmapClause();
     break;
   case OMPC_to: {
-    unsigned NumVars = Record[Idx++];
-    unsigned NumDeclarations = Record[Idx++];
-    unsigned NumLists = Record[Idx++];
-    unsigned NumComponents = Record[Idx++];
+    unsigned NumVars = Reader->Record.readInt();
+    unsigned NumDeclarations = Reader->Record.readInt();
+    unsigned NumLists = Reader->Record.readInt();
+    unsigned NumComponents = Reader->Record.readInt();
     C = OMPToClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
                                  NumComponents);
     break;
   }
   case OMPC_from: {
-    unsigned NumVars = Record[Idx++];
-    unsigned NumDeclarations = Record[Idx++];
-    unsigned NumLists = Record[Idx++];
-    unsigned NumComponents = Record[Idx++];
+    unsigned NumVars = Reader->Record.readInt();
+    unsigned NumDeclarations = Reader->Record.readInt();
+    unsigned NumLists = Reader->Record.readInt();
+    unsigned NumComponents = Reader->Record.readInt();
     C = OMPFromClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
                                    NumComponents);
     break;
   }
   case OMPC_use_device_ptr: {
-    unsigned NumVars = Record[Idx++];
-    unsigned NumDeclarations = Record[Idx++];
-    unsigned NumLists = Record[Idx++];
-    unsigned NumComponents = Record[Idx++];
+    unsigned NumVars = Reader->Record.readInt();
+    unsigned NumDeclarations = Reader->Record.readInt();
+    unsigned NumLists = Reader->Record.readInt();
+    unsigned NumComponents = Reader->Record.readInt();
     C = OMPUseDevicePtrClause::CreateEmpty(Context, NumVars, NumDeclarations,
                                            NumLists, NumComponents);
     break;
   }
   case OMPC_is_device_ptr: {
-    unsigned NumVars = Record[Idx++];
-    unsigned NumDeclarations = Record[Idx++];
-    unsigned NumLists = Record[Idx++];
-    unsigned NumComponents = Record[Idx++];
+    unsigned NumVars = Reader->Record.readInt();
+    unsigned NumDeclarations = Reader->Record.readInt();
+    unsigned NumLists = Reader->Record.readInt();
+    unsigned NumComponents = Reader->Record.readInt();
     C = OMPIsDevicePtrClause::CreateEmpty(Context, NumVars, NumDeclarations,
                                           NumLists, NumComponents);
     break;
   }
   }
   Visit(C);
-  C->setLocStart(Reader->ReadSourceLocation(Record, Idx));
-  C->setLocEnd(Reader->ReadSourceLocation(Record, Idx));
+  C->setLocStart(Reader->ReadSourceLocation());
+  C->setLocEnd(Reader->ReadSourceLocation());
 
   return C;
 }
 
 void OMPClauseReader::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) {
-  C->setPreInitStmt(Reader->Reader.ReadSubStmt());
+  C->setPreInitStmt(Reader->Record.readSubStmt(),
+                    static_cast<OpenMPDirectiveKind>(Reader->Record.readInt()));
 }
 
 void OMPClauseReader::VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C) {
   VisitOMPClauseWithPreInit(C);
-  C->setPostUpdateExpr(Reader->Reader.ReadSubExpr());
+  C->setPostUpdateExpr(Reader->Record.readSubExpr());
 }
 
 void OMPClauseReader::VisitOMPIfClause(OMPIfClause *C) {
-  C->setNameModifier(static_cast<OpenMPDirectiveKind>(Record[Idx++]));
-  C->setNameModifierLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setCondition(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  VisitOMPClauseWithPreInit(C);
+  C->setNameModifier(static_cast<OpenMPDirectiveKind>(Reader->Record.readInt()));
+  C->setNameModifierLoc(Reader->ReadSourceLocation());
+  C->setColonLoc(Reader->ReadSourceLocation());
+  C->setCondition(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPFinalClause(OMPFinalClause *C) {
-  C->setCondition(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setCondition(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
-  C->setNumThreads(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  VisitOMPClauseWithPreInit(C);
+  C->setNumThreads(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPSafelenClause(OMPSafelenClause *C) {
-  C->setSafelen(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setSafelen(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
-  C->setSimdlen(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setSimdlen(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPCollapseClause(OMPCollapseClause *C) {
-  C->setNumForLoops(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setNumForLoops(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPDefaultClause(OMPDefaultClause *C) {
   C->setDefaultKind(
-       static_cast<OpenMPDefaultClauseKind>(Record[Idx++]));
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setDefaultKindKwLoc(Reader->ReadSourceLocation(Record, Idx));
+       static_cast<OpenMPDefaultClauseKind>(Reader->Record.readInt()));
+  C->setLParenLoc(Reader->ReadSourceLocation());
+  C->setDefaultKindKwLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPProcBindClause(OMPProcBindClause *C) {
   C->setProcBindKind(
-       static_cast<OpenMPProcBindClauseKind>(Record[Idx++]));
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setProcBindKindKwLoc(Reader->ReadSourceLocation(Record, Idx));
+       static_cast<OpenMPProcBindClauseKind>(Reader->Record.readInt()));
+  C->setLParenLoc(Reader->ReadSourceLocation());
+  C->setProcBindKindKwLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPScheduleClause(OMPScheduleClause *C) {
   VisitOMPClauseWithPreInit(C);
   C->setScheduleKind(
-       static_cast<OpenMPScheduleClauseKind>(Record[Idx++]));
+       static_cast<OpenMPScheduleClauseKind>(Reader->Record.readInt()));
   C->setFirstScheduleModifier(
-      static_cast<OpenMPScheduleClauseModifier>(Record[Idx++]));
+      static_cast<OpenMPScheduleClauseModifier>(Reader->Record.readInt()));
   C->setSecondScheduleModifier(
-      static_cast<OpenMPScheduleClauseModifier>(Record[Idx++]));
-  C->setChunkSize(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setFirstScheduleModifierLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setSecondScheduleModifierLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setScheduleKindLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setCommaLoc(Reader->ReadSourceLocation(Record, Idx));
+      static_cast<OpenMPScheduleClauseModifier>(Reader->Record.readInt()));
+  C->setChunkSize(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
+  C->setFirstScheduleModifierLoc(Reader->ReadSourceLocation());
+  C->setSecondScheduleModifierLoc(Reader->ReadSourceLocation());
+  C->setScheduleKindLoc(Reader->ReadSourceLocation());
+  C->setCommaLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPOrderedClause(OMPOrderedClause *C) {
-  C->setNumForLoops(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setNumForLoops(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPNowaitClause(OMPNowaitClause *) {}
@@ -2060,83 +2035,82 @@
 void OMPClauseReader::VisitOMPNogroupClause(OMPNogroupClause *) {}
 
 void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   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());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setPrivateCopies(Vars);
 }
 
 void OMPClauseReader::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
   VisitOMPClauseWithPreInit(C);
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   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());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setPrivateCopies(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setInits(Vars);
 }
 
 void OMPClauseReader::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
   VisitOMPClauseWithPostUpdate(C);
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   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());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setPrivateCopies(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setSourceExprs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setDestinationExprs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setAssignmentOps(Vars);
 }
 
 void OMPClauseReader::VisitOMPSharedClause(OMPSharedClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   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());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
 }
 
 void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) {
   VisitOMPClauseWithPostUpdate(C);
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
-  NestedNameSpecifierLoc NNSL =
-    Reader->Reader.ReadNestedNameSpecifierLoc(Reader->F, Record, Idx);
+  C->setLParenLoc(Reader->ReadSourceLocation());
+  C->setColonLoc(Reader->ReadSourceLocation());
+  NestedNameSpecifierLoc NNSL = Reader->Record.readNestedNameSpecifierLoc();
   DeclarationNameInfo DNI;
-  Reader->ReadDeclarationNameInfo(DNI, Record, Idx);
+  Reader->ReadDeclarationNameInfo(DNI);
   C->setQualifierLoc(NNSL);
   C->setNameInfo(DNI);
 
@@ -2144,151 +2118,152 @@
   SmallVector<Expr *, 16> Vars;
   Vars.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setPrivates(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setLHSExprs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setRHSExprs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setReductionOps(Vars);
 }
 
 void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) {
   VisitOMPClauseWithPostUpdate(C);
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setModifier(static_cast<OpenMPLinearClauseKind>(Record[Idx++]));
-  C->setModifierLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
+  C->setColonLoc(Reader->ReadSourceLocation());
+  C->setModifier(static_cast<OpenMPLinearClauseKind>(Reader->Record.readInt()));
+  C->setModifierLoc(Reader->ReadSourceLocation());
   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());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setPrivates(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setInits(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setUpdates(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setFinals(Vars);
-  C->setStep(Reader->Reader.ReadSubExpr());
-  C->setCalcStep(Reader->Reader.ReadSubExpr());
+  C->setStep(Reader->Record.readSubExpr());
+  C->setCalcStep(Reader->Record.readSubExpr());
 }
 
 void OMPClauseReader::VisitOMPAlignedClause(OMPAlignedClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
+  C->setColonLoc(Reader->ReadSourceLocation());
   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());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
-  C->setAlignment(Reader->Reader.ReadSubExpr());
+  C->setAlignment(Reader->Record.readSubExpr());
 }
 
 void OMPClauseReader::VisitOMPCopyinClause(OMPCopyinClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   unsigned NumVars = C->varlist_size();
   SmallVector<Expr *, 16> Exprs;
   Exprs.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i)
-    Exprs.push_back(Reader->Reader.ReadSubExpr());
+    Exprs.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Exprs);
   Exprs.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Exprs.push_back(Reader->Reader.ReadSubExpr());
+    Exprs.push_back(Reader->Record.readSubExpr());
   C->setSourceExprs(Exprs);
   Exprs.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Exprs.push_back(Reader->Reader.ReadSubExpr());
+    Exprs.push_back(Reader->Record.readSubExpr());
   C->setDestinationExprs(Exprs);
   Exprs.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Exprs.push_back(Reader->Reader.ReadSubExpr());
+    Exprs.push_back(Reader->Record.readSubExpr());
   C->setAssignmentOps(Exprs);
 }
 
 void OMPClauseReader::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   unsigned NumVars = C->varlist_size();
   SmallVector<Expr *, 16> Exprs;
   Exprs.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i)
-    Exprs.push_back(Reader->Reader.ReadSubExpr());
+    Exprs.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Exprs);
   Exprs.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Exprs.push_back(Reader->Reader.ReadSubExpr());
+    Exprs.push_back(Reader->Record.readSubExpr());
   C->setSourceExprs(Exprs);
   Exprs.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Exprs.push_back(Reader->Reader.ReadSubExpr());
+    Exprs.push_back(Reader->Record.readSubExpr());
   C->setDestinationExprs(Exprs);
   Exprs.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Exprs.push_back(Reader->Reader.ReadSubExpr());
+    Exprs.push_back(Reader->Record.readSubExpr());
   C->setAssignmentOps(Exprs);
 }
 
 void OMPClauseReader::VisitOMPFlushClause(OMPFlushClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   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());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
 }
 
 void OMPClauseReader::VisitOMPDependClause(OMPDependClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setDependencyKind(static_cast<OpenMPDependClauseKind>(Record[Idx++]));
-  C->setDependencyLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
+  C->setDependencyKind(
+      static_cast<OpenMPDependClauseKind>(Reader->Record.readInt()));
+  C->setDependencyLoc(Reader->ReadSourceLocation());
+  C->setColonLoc(Reader->ReadSourceLocation());
   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());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
-  C->setCounterValue(Reader->Reader.ReadSubExpr());
+  C->setCounterValue(Reader->Record.readSubExpr());
 }
 
 void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) {
-  C->setDevice(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setDevice(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   C->setMapTypeModifier(
-     static_cast<OpenMPMapClauseKind>(Record[Idx++]));
+     static_cast<OpenMPMapClauseKind>(Reader->Record.readInt()));
   C->setMapType(
-     static_cast<OpenMPMapClauseKind>(Record[Idx++]));
-  C->setMapLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+     static_cast<OpenMPMapClauseKind>(Reader->Record.readInt()));
+  C->setMapLoc(Reader->ReadSourceLocation());
+  C->setColonLoc(Reader->ReadSourceLocation());
   auto NumVars = C->varlist_size();
   auto UniqueDecls = C->getUniqueDeclarationsNum();
   auto TotalLists = C->getTotalComponentListNum();
@@ -2297,34 +2272,32 @@
   SmallVector<Expr *, 16> Vars;
   Vars.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
 
   SmallVector<ValueDecl *, 16> Decls;
   Decls.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    Decls.push_back(
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx));
+    Decls.push_back(Reader->Record.readDeclAs<ValueDecl>());
   C->setUniqueDecls(Decls);
 
   SmallVector<unsigned, 16> ListsPerDecl;
   ListsPerDecl.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    ListsPerDecl.push_back(Record[Idx++]);
+    ListsPerDecl.push_back(Reader->Record.readInt());
   C->setDeclNumLists(ListsPerDecl);
 
   SmallVector<unsigned, 32> ListSizes;
   ListSizes.reserve(TotalLists);
   for (unsigned i = 0; i < TotalLists; ++i)
-    ListSizes.push_back(Record[Idx++]);
+    ListSizes.push_back(Reader->Record.readInt());
   C->setComponentListSizes(ListSizes);
 
   SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
   Components.reserve(TotalComponents);
   for (unsigned i = 0; i < TotalComponents; ++i) {
-    Expr *AssociatedExpr = Reader->Reader.ReadSubExpr();
-    ValueDecl *AssociatedDecl =
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx);
+    Expr *AssociatedExpr = Reader->Record.readSubExpr();
+    ValueDecl *AssociatedDecl = Reader->Record.readDeclAs<ValueDecl>();
     Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
         AssociatedExpr, AssociatedDecl));
   }
@@ -2332,57 +2305,59 @@
 }
 
 void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
-  C->setNumTeams(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  VisitOMPClauseWithPreInit(C);
+  C->setNumTeams(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) {
-  C->setThreadLimit(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  VisitOMPClauseWithPreInit(C);
+  C->setThreadLimit(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPPriorityClause(OMPPriorityClause *C) {
-  C->setPriority(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setPriority(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
-  C->setGrainsize(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setGrainsize(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
-  C->setNumTasks(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setNumTasks(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPHintClause(OMPHintClause *C) {
-  C->setHint(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setHint(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPDistScheduleClause(OMPDistScheduleClause *C) {
   VisitOMPClauseWithPreInit(C);
   C->setDistScheduleKind(
-      static_cast<OpenMPDistScheduleClauseKind>(Record[Idx++]));
-  C->setChunkSize(Reader->Reader.ReadSubExpr());
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setDistScheduleKindLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setCommaLoc(Reader->ReadSourceLocation(Record, Idx));
+      static_cast<OpenMPDistScheduleClauseKind>(Reader->Record.readInt()));
+  C->setChunkSize(Reader->Record.readSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation());
+  C->setDistScheduleKindLoc(Reader->ReadSourceLocation());
+  C->setCommaLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
   C->setDefaultmapKind(
-       static_cast<OpenMPDefaultmapClauseKind>(Record[Idx++]));
+       static_cast<OpenMPDefaultmapClauseKind>(Reader->Record.readInt()));
   C->setDefaultmapModifier(
-      static_cast<OpenMPDefaultmapClauseModifier>(Record[Idx++]));
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setDefaultmapModifierLoc(Reader->ReadSourceLocation(Record, Idx));
-  C->setDefaultmapKindLoc(Reader->ReadSourceLocation(Record, Idx));
+      static_cast<OpenMPDefaultmapClauseModifier>(Reader->Record.readInt()));
+  C->setLParenLoc(Reader->ReadSourceLocation());
+  C->setDefaultmapModifierLoc(Reader->ReadSourceLocation());
+  C->setDefaultmapKindLoc(Reader->ReadSourceLocation());
 }
 
 void OMPClauseReader::VisitOMPToClause(OMPToClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   auto NumVars = C->varlist_size();
   auto UniqueDecls = C->getUniqueDeclarationsNum();
   auto TotalLists = C->getTotalComponentListNum();
@@ -2391,34 +2366,32 @@
   SmallVector<Expr *, 16> Vars;
   Vars.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
 
   SmallVector<ValueDecl *, 16> Decls;
   Decls.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    Decls.push_back(
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx));
+    Decls.push_back(Reader->Record.readDeclAs<ValueDecl>());
   C->setUniqueDecls(Decls);
 
   SmallVector<unsigned, 16> ListsPerDecl;
   ListsPerDecl.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    ListsPerDecl.push_back(Record[Idx++]);
+    ListsPerDecl.push_back(Reader->Record.readInt());
   C->setDeclNumLists(ListsPerDecl);
 
   SmallVector<unsigned, 32> ListSizes;
   ListSizes.reserve(TotalLists);
   for (unsigned i = 0; i < TotalLists; ++i)
-    ListSizes.push_back(Record[Idx++]);
+    ListSizes.push_back(Reader->Record.readInt());
   C->setComponentListSizes(ListSizes);
 
   SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
   Components.reserve(TotalComponents);
   for (unsigned i = 0; i < TotalComponents; ++i) {
-    Expr *AssociatedExpr = Reader->Reader.ReadSubExpr();
-    ValueDecl *AssociatedDecl =
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx);
+    Expr *AssociatedExpr = Reader->Record.readSubExpr();
+    ValueDecl *AssociatedDecl = Reader->Record.readDeclAs<ValueDecl>();
     Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
         AssociatedExpr, AssociatedDecl));
   }
@@ -2426,7 +2399,7 @@
 }
 
 void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   auto NumVars = C->varlist_size();
   auto UniqueDecls = C->getUniqueDeclarationsNum();
   auto TotalLists = C->getTotalComponentListNum();
@@ -2435,34 +2408,32 @@
   SmallVector<Expr *, 16> Vars;
   Vars.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
 
   SmallVector<ValueDecl *, 16> Decls;
   Decls.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    Decls.push_back(
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx));
+    Decls.push_back(Reader->Record.readDeclAs<ValueDecl>());
   C->setUniqueDecls(Decls);
 
   SmallVector<unsigned, 16> ListsPerDecl;
   ListsPerDecl.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    ListsPerDecl.push_back(Record[Idx++]);
+    ListsPerDecl.push_back(Reader->Record.readInt());
   C->setDeclNumLists(ListsPerDecl);
 
   SmallVector<unsigned, 32> ListSizes;
   ListSizes.reserve(TotalLists);
   for (unsigned i = 0; i < TotalLists; ++i)
-    ListSizes.push_back(Record[Idx++]);
+    ListSizes.push_back(Reader->Record.readInt());
   C->setComponentListSizes(ListSizes);
 
   SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
   Components.reserve(TotalComponents);
   for (unsigned i = 0; i < TotalComponents; ++i) {
-    Expr *AssociatedExpr = Reader->Reader.ReadSubExpr();
-    ValueDecl *AssociatedDecl =
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx);
+    Expr *AssociatedExpr = Reader->Record.readSubExpr();
+    ValueDecl *AssociatedDecl = Reader->Record.readDeclAs<ValueDecl>();
     Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
         AssociatedExpr, AssociatedDecl));
   }
@@ -2470,7 +2441,7 @@
 }
 
 void OMPClauseReader::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   auto NumVars = C->varlist_size();
   auto UniqueDecls = C->getUniqueDeclarationsNum();
   auto TotalLists = C->getTotalComponentListNum();
@@ -2479,42 +2450,40 @@
   SmallVector<Expr *, 16> Vars;
   Vars.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setPrivateCopies(Vars);
   Vars.clear();
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setInits(Vars);
 
   SmallVector<ValueDecl *, 16> Decls;
   Decls.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    Decls.push_back(
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx));
+    Decls.push_back(Reader->Record.readDeclAs<ValueDecl>());
   C->setUniqueDecls(Decls);
 
   SmallVector<unsigned, 16> ListsPerDecl;
   ListsPerDecl.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    ListsPerDecl.push_back(Record[Idx++]);
+    ListsPerDecl.push_back(Reader->Record.readInt());
   C->setDeclNumLists(ListsPerDecl);
 
   SmallVector<unsigned, 32> ListSizes;
   ListSizes.reserve(TotalLists);
   for (unsigned i = 0; i < TotalLists; ++i)
-    ListSizes.push_back(Record[Idx++]);
+    ListSizes.push_back(Reader->Record.readInt());
   C->setComponentListSizes(ListSizes);
 
   SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
   Components.reserve(TotalComponents);
   for (unsigned i = 0; i < TotalComponents; ++i) {
-    Expr *AssociatedExpr = Reader->Reader.ReadSubExpr();
-    ValueDecl *AssociatedDecl =
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx);
+    Expr *AssociatedExpr = Reader->Record.readSubExpr();
+    ValueDecl *AssociatedDecl = Reader->Record.readDeclAs<ValueDecl>();
     Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
         AssociatedExpr, AssociatedDecl));
   }
@@ -2522,7 +2491,7 @@
 }
 
 void OMPClauseReader::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
-  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setLParenLoc(Reader->ReadSourceLocation());
   auto NumVars = C->varlist_size();
   auto UniqueDecls = C->getUniqueDeclarationsNum();
   auto TotalLists = C->getTotalComponentListNum();
@@ -2531,35 +2500,33 @@
   SmallVector<Expr *, 16> Vars;
   Vars.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i)
-    Vars.push_back(Reader->Reader.ReadSubExpr());
+    Vars.push_back(Reader->Record.readSubExpr());
   C->setVarRefs(Vars);
   Vars.clear();
 
   SmallVector<ValueDecl *, 16> Decls;
   Decls.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    Decls.push_back(
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx));
+    Decls.push_back(Reader->Record.readDeclAs<ValueDecl>());
   C->setUniqueDecls(Decls);
 
   SmallVector<unsigned, 16> ListsPerDecl;
   ListsPerDecl.reserve(UniqueDecls);
   for (unsigned i = 0; i < UniqueDecls; ++i)
-    ListsPerDecl.push_back(Record[Idx++]);
+    ListsPerDecl.push_back(Reader->Record.readInt());
   C->setDeclNumLists(ListsPerDecl);
 
   SmallVector<unsigned, 32> ListSizes;
   ListSizes.reserve(TotalLists);
   for (unsigned i = 0; i < TotalLists; ++i)
-    ListSizes.push_back(Record[Idx++]);
+    ListSizes.push_back(Reader->Record.readInt());
   C->setComponentListSizes(ListSizes);
 
   SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
   Components.reserve(TotalComponents);
   for (unsigned i = 0; i < TotalComponents; ++i) {
-    Expr *AssociatedExpr = Reader->Reader.ReadSubExpr();
-    ValueDecl *AssociatedDecl =
-        Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx);
+    Expr *AssociatedExpr = Reader->Record.readSubExpr();
+    ValueDecl *AssociatedDecl = Reader->Record.readDeclAs<ValueDecl>();
     Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
         AssociatedExpr, AssociatedDecl));
   }
@@ -2570,76 +2537,78 @@
 // OpenMP Directives.
 //===----------------------------------------------------------------------===//
 void ASTStmtReader::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
-  E->setLocStart(ReadSourceLocation(Record, Idx));
-  E->setLocEnd(ReadSourceLocation(Record, Idx));
-  OMPClauseReader ClauseReader(this, Reader.getContext(), Record, Idx);
+  E->setLocStart(ReadSourceLocation());
+  E->setLocEnd(ReadSourceLocation());
+  OMPClauseReader ClauseReader(this, Record);
   SmallVector<OMPClause *, 5> Clauses;
   for (unsigned i = 0; i < E->getNumClauses(); ++i)
     Clauses.push_back(ClauseReader.readClause());
   E->setClauses(Clauses);
   if (E->hasAssociatedStmt())
-    E->setAssociatedStmt(Reader.ReadSubStmt());
+    E->setAssociatedStmt(Record.readSubStmt());
 }
 
 void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) {
   VisitStmt(D);
   // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream.
-  Idx += 2;
+  Record.skipInts(2);
   VisitOMPExecutableDirective(D);
-  D->setIterationVariable(Reader.ReadSubExpr());
-  D->setLastIteration(Reader.ReadSubExpr());
-  D->setCalcLastIteration(Reader.ReadSubExpr());
-  D->setPreCond(Reader.ReadSubExpr());
-  D->setCond(Reader.ReadSubExpr());
-  D->setInit(Reader.ReadSubExpr());
-  D->setInc(Reader.ReadSubExpr());
-  D->setPreInits(Reader.ReadSubStmt());
+  D->setIterationVariable(Record.readSubExpr());
+  D->setLastIteration(Record.readSubExpr());
+  D->setCalcLastIteration(Record.readSubExpr());
+  D->setPreCond(Record.readSubExpr());
+  D->setCond(Record.readSubExpr());
+  D->setInit(Record.readSubExpr());
+  D->setInc(Record.readSubExpr());
+  D->setPreInits(Record.readSubStmt());
   if (isOpenMPWorksharingDirective(D->getDirectiveKind()) ||
       isOpenMPTaskLoopDirective(D->getDirectiveKind()) ||
       isOpenMPDistributeDirective(D->getDirectiveKind())) {
-    D->setIsLastIterVariable(Reader.ReadSubExpr());
-    D->setLowerBoundVariable(Reader.ReadSubExpr());
-    D->setUpperBoundVariable(Reader.ReadSubExpr());
-    D->setStrideVariable(Reader.ReadSubExpr());
-    D->setEnsureUpperBound(Reader.ReadSubExpr());
-    D->setNextLowerBound(Reader.ReadSubExpr());
-    D->setNextUpperBound(Reader.ReadSubExpr());
-    D->setNumIterations(Reader.ReadSubExpr());
+    D->setIsLastIterVariable(Record.readSubExpr());
+    D->setLowerBoundVariable(Record.readSubExpr());
+    D->setUpperBoundVariable(Record.readSubExpr());
+    D->setStrideVariable(Record.readSubExpr());
+    D->setEnsureUpperBound(Record.readSubExpr());
+    D->setNextLowerBound(Record.readSubExpr());
+    D->setNextUpperBound(Record.readSubExpr());
+    D->setNumIterations(Record.readSubExpr());
   }
   if (isOpenMPLoopBoundSharingDirective(D->getDirectiveKind())) {
-    D->setPrevLowerBoundVariable(Reader.ReadSubExpr());
-    D->setPrevUpperBoundVariable(Reader.ReadSubExpr());
+    D->setPrevLowerBoundVariable(Record.readSubExpr());
+    D->setPrevUpperBoundVariable(Record.readSubExpr());
+    D->setDistInc(Record.readSubExpr());
+    D->setPrevEnsureUpperBound(Record.readSubExpr());
   }
   SmallVector<Expr *, 4> Sub;
   unsigned CollapsedNum = D->getCollapsedNumber();
   Sub.reserve(CollapsedNum);
   for (unsigned i = 0; i < CollapsedNum; ++i)
-    Sub.push_back(Reader.ReadSubExpr());
+    Sub.push_back(Record.readSubExpr());
   D->setCounters(Sub);
   Sub.clear();
   for (unsigned i = 0; i < CollapsedNum; ++i)
-    Sub.push_back(Reader.ReadSubExpr());
+    Sub.push_back(Record.readSubExpr());
   D->setPrivateCounters(Sub);
   Sub.clear();
   for (unsigned i = 0; i < CollapsedNum; ++i)
-    Sub.push_back(Reader.ReadSubExpr());
+    Sub.push_back(Record.readSubExpr());
   D->setInits(Sub);
   Sub.clear();
   for (unsigned i = 0; i < CollapsedNum; ++i)
-    Sub.push_back(Reader.ReadSubExpr());
+    Sub.push_back(Record.readSubExpr());
   D->setUpdates(Sub);
   Sub.clear();
   for (unsigned i = 0; i < CollapsedNum; ++i)
-    Sub.push_back(Reader.ReadSubExpr());
+    Sub.push_back(Record.readSubExpr());
   D->setFinals(Sub);
 }
 
 void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
-  D->setHasCancel(Record[Idx++]);
+  D->setHasCancel(Record.readInt());
 }
 
 void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) {
@@ -2648,7 +2617,7 @@
 
 void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) {
   VisitOMPLoopDirective(D);
-  D->setHasCancel(Record[Idx++]);
+  D->setHasCancel(Record.readInt());
 }
 
 void ASTStmtReader::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
@@ -2658,21 +2627,21 @@
 void ASTStmtReader::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
-  D->setHasCancel(Record[Idx++]);
+  D->setHasCancel(Record.readInt());
 }
 
 void ASTStmtReader::VisitOMPSectionDirective(OMPSectionDirective *D) {
   VisitStmt(D);
   VisitOMPExecutableDirective(D);
-  D->setHasCancel(Record[Idx++]);
+  D->setHasCancel(Record.readInt());
 }
 
 void ASTStmtReader::VisitOMPSingleDirective(OMPSingleDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 
@@ -2684,14 +2653,14 @@
 void ASTStmtReader::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
-  ReadDeclarationNameInfo(D->DirName, Record, Idx);
+  ReadDeclarationNameInfo(D->DirName);
 }
 
 void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
   VisitOMPLoopDirective(D);
-  D->setHasCancel(Record[Idx++]);
+  D->setHasCancel(Record.readInt());
 }
 
 void ASTStmtReader::VisitOMPParallelForSimdDirective(
@@ -2703,17 +2672,17 @@
     OMPParallelSectionsDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
-  D->setHasCancel(Record[Idx++]);
+  D->setHasCancel(Record.readInt());
 }
 
 void ASTStmtReader::VisitOMPTaskDirective(OMPTaskDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
-  D->setHasCancel(Record[Idx++]);
+  D->setHasCancel(Record.readInt());
 }
 
 void ASTStmtReader::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
@@ -2739,74 +2708,74 @@
 void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 
 void ASTStmtReader::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 
 void ASTStmtReader::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
-  D->setX(Reader.ReadSubExpr());
-  D->setV(Reader.ReadSubExpr());
-  D->setExpr(Reader.ReadSubExpr());
-  D->setUpdateExpr(Reader.ReadSubExpr());
-  D->IsXLHSInRHSPart = Record[Idx++] != 0;
-  D->IsPostfixUpdate = Record[Idx++] != 0;
+  D->setX(Record.readSubExpr());
+  D->setV(Record.readSubExpr());
+  D->setExpr(Record.readSubExpr());
+  D->setUpdateExpr(Record.readSubExpr());
+  D->IsXLHSInRHSPart = Record.readInt() != 0;
+  D->IsPostfixUpdate = Record.readInt() != 0;
 }
 
 void ASTStmtReader::VisitOMPTargetDirective(OMPTargetDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 
 void ASTStmtReader::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
   VisitStmt(D);
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 
 void ASTStmtReader::VisitOMPTargetEnterDataDirective(
     OMPTargetEnterDataDirective *D) {
   VisitStmt(D);
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 
 void ASTStmtReader::VisitOMPTargetExitDataDirective(
     OMPTargetExitDataDirective *D) {
   VisitStmt(D);
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 
 void ASTStmtReader::VisitOMPTargetParallelDirective(
     OMPTargetParallelDirective *D) {
   VisitStmt(D);
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 
 void ASTStmtReader::VisitOMPTargetParallelForDirective(
     OMPTargetParallelForDirective *D) {
   VisitOMPLoopDirective(D);
-  D->setHasCancel(Record[Idx++]);
+  D->setHasCancel(Record.readInt());
 }
 
 void ASTStmtReader::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 
@@ -2814,15 +2783,15 @@
     OMPCancellationPointDirective *D) {
   VisitStmt(D);
   VisitOMPExecutableDirective(D);
-  D->setCancelRegion(static_cast<OpenMPDirectiveKind>(Record[Idx++]));
+  D->setCancelRegion(static_cast<OpenMPDirectiveKind>(Record.readInt()));
 }
 
 void ASTStmtReader::VisitOMPCancelDirective(OMPCancelDirective *D) {
   VisitStmt(D);
   // The NumClauses field was read in ReadStmtFromStream.
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
-  D->setCancelRegion(static_cast<OpenMPDirectiveKind>(Record[Idx++]));
+  D->setCancelRegion(static_cast<OpenMPDirectiveKind>(Record.readInt()));
 }
 
 void ASTStmtReader::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
@@ -2839,7 +2808,7 @@
 
 void ASTStmtReader::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
   VisitStmt(D);
-  ++Idx;
+  Record.skipInts(1);
   VisitOMPExecutableDirective(D);
 }
 void ASTStmtReader::VisitOMPDistributeParallelForDirective(
@@ -2886,6 +2855,33 @@
   VisitOMPLoopDirective(D);
 }
 
+void ASTStmtReader::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  Record.skipInts(1);
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPTargetTeamsDistributeDirective(
+    OMPTargetTeamsDistributeDirective *D) {
+  VisitOMPLoopDirective(D);
+}
+
+void ASTStmtReader::VisitOMPTargetTeamsDistributeParallelForDirective(
+    OMPTargetTeamsDistributeParallelForDirective *D) {
+  VisitOMPLoopDirective(D);
+}
+
+void ASTStmtReader::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
+    OMPTargetTeamsDistributeParallelForSimdDirective *D) {
+  VisitOMPLoopDirective(D);
+}
+
+void ASTStmtReader::VisitOMPTargetTeamsDistributeSimdDirective(
+    OMPTargetTeamsDistributeSimdDirective *D) {
+  VisitOMPLoopDirective(D);
+}
+
 //===----------------------------------------------------------------------===//
 // ASTReader Implementation
 //===----------------------------------------------------------------------===//
@@ -2923,23 +2919,22 @@
 
   ReadingKindTracker ReadingKind(Read_Stmt, *this);
   llvm::BitstreamCursor &Cursor = F.DeclsCursor;
-  
+
   // Map of offset to previously deserialized stmt. The offset points
-  /// just after the stmt record.
+  // just after the stmt record.
   llvm::DenseMap<uint64_t, Stmt *> StmtEntries;
 
 #ifndef NDEBUG
   unsigned PrevNumStmts = StmtStack.size();
 #endif
 
-  RecordData Record;
-  unsigned Idx;
-  ASTStmtReader Reader(*this, F, Cursor, Record, Idx);
+  ASTRecordReader Record(*this, F);
+  ASTStmtReader Reader(Record, Cursor);
   Stmt::EmptyShell Empty;
 
   while (true) {
     llvm::BitstreamEntry Entry = Cursor.advanceSkippingSubblocks();
-    
+
     switch (Entry.Kind) {
     case llvm::BitstreamEntry::SubBlock: // Handled for us already.
     case llvm::BitstreamEntry::Error:
@@ -2953,11 +2948,9 @@
     }
 
     Stmt *S = nullptr;
-    Idx = 0;
-    Record.clear();
     bool Finished = false;
     bool IsStmtReference = false;
-    switch ((StmtCode)Cursor.readRecord(Entry.ID, Record)) {
+    switch ((StmtCode)Record.readRecord(Cursor, Entry.ID)) {
     case STMT_STOP:
       Finished = true;
       break;
@@ -2966,7 +2959,7 @@
       IsStmtReference = true;
       assert(StmtEntries.find(Record[0]) != StmtEntries.end() &&
              "No stmt was recorded for this offset reference!");
-      S = StmtEntries[Record[Idx++]];
+      S = StmtEntries[Record.readInt()];
       break;
 
     case STMT_NULL_PTR:
@@ -3104,11 +3097,11 @@
       break;
 
     case EXPR_OFFSETOF:
-      S = OffsetOfExpr::CreateEmpty(Context, 
+      S = OffsetOfExpr::CreateEmpty(Context,
                                     Record[ASTStmtReader::NumExprFields],
                                     Record[ASTStmtReader::NumExprFields + 1]);
       break;
-        
+
     case EXPR_SIZEOF_ALIGN_OF:
       S = new (Context) UnaryExprOrTypeTraitExpr(Empty);
       break;
@@ -3130,46 +3123,46 @@
       // That way we can use MemberExpr::Create and don't have to duplicate its
       // logic with a MemberExpr::CreateEmpty.
 
-      assert(Idx == 0);
+      assert(Record.getIdx() == 0);
       NestedNameSpecifierLoc QualifierLoc;
-      if (Record[Idx++]) { // HasQualifier.
-        QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx);
+      if (Record.readInt()) { // HasQualifier.
+        QualifierLoc = Record.readNestedNameSpecifierLoc();
       }
 
       SourceLocation TemplateKWLoc;
       TemplateArgumentListInfo ArgInfo;
-      bool HasTemplateKWAndArgsInfo = Record[Idx++];
+      bool HasTemplateKWAndArgsInfo = Record.readInt();
       if (HasTemplateKWAndArgsInfo) {
-        TemplateKWLoc = ReadSourceLocation(F, Record, Idx);
-        unsigned NumTemplateArgs = Record[Idx++];
-        ArgInfo.setLAngleLoc(ReadSourceLocation(F, Record, Idx));
-        ArgInfo.setRAngleLoc(ReadSourceLocation(F, Record, Idx));
+        TemplateKWLoc = Record.readSourceLocation();
+        unsigned NumTemplateArgs = Record.readInt();
+        ArgInfo.setLAngleLoc(Record.readSourceLocation());
+        ArgInfo.setRAngleLoc(Record.readSourceLocation());
         for (unsigned i = 0; i != NumTemplateArgs; ++i)
-          ArgInfo.addArgument(ReadTemplateArgumentLoc(F, Record, Idx));
+          ArgInfo.addArgument(Record.readTemplateArgumentLoc());
       }
 
-      bool HadMultipleCandidates = Record[Idx++];
+      bool HadMultipleCandidates = Record.readInt();
 
-      NamedDecl *FoundD = ReadDeclAs<NamedDecl>(F, Record, Idx);
-      AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
+      NamedDecl *FoundD = Record.readDeclAs<NamedDecl>();
+      AccessSpecifier AS = (AccessSpecifier)Record.readInt();
       DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS);
 
-      QualType T = readType(F, Record, Idx);
-      ExprValueKind VK = static_cast<ExprValueKind>(Record[Idx++]);
-      ExprObjectKind OK = static_cast<ExprObjectKind>(Record[Idx++]);
+      QualType T = Record.readType();
+      ExprValueKind VK = static_cast<ExprValueKind>(Record.readInt());
+      ExprObjectKind OK = static_cast<ExprObjectKind>(Record.readInt());
       Expr *Base = ReadSubExpr();
-      ValueDecl *MemberD = ReadDeclAs<ValueDecl>(F, Record, Idx);
-      SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx);
+      ValueDecl *MemberD = Record.readDeclAs<ValueDecl>();
+      SourceLocation MemberLoc = Record.readSourceLocation();
       DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc);
-      bool IsArrow = Record[Idx++];
-      SourceLocation OperatorLoc = ReadSourceLocation(F, Record, Idx);
+      bool IsArrow = Record.readInt();
+      SourceLocation OperatorLoc = Record.readSourceLocation();
 
       S = MemberExpr::Create(Context, Base, IsArrow, OperatorLoc, QualifierLoc,
                              TemplateKWLoc, MemberD, FoundDecl, MemberNameInfo,
                              HasTemplateKWAndArgsInfo ? &ArgInfo : nullptr, T,
                              VK, OK);
-      ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc,
-                             MemberD->getDeclName(), Record, Idx);
+      Record.readDeclarationNameLoc(cast<MemberExpr>(S)->MemberDNLoc,
+                                    MemberD->getDeclName());
       if (HadMultipleCandidates)
         cast<MemberExpr>(S)->setHadMultipleCandidates(true);
       break;
@@ -3231,6 +3224,14 @@
       S = new (Context) NoInitExpr(Empty);
       break;
 
+    case EXPR_ARRAY_INIT_LOOP:
+      S = new (Context) ArrayInitLoopExpr(Empty);
+      break;
+
+    case EXPR_ARRAY_INIT_INDEX:
+      S = new (Context) ArrayInitIndexExpr(Empty);
+      break;
+
     case EXPR_VA_ARG:
       S = new (Context) VAArgExpr(Empty);
       break;
@@ -3326,7 +3327,7 @@
       S = new (Context) ObjCAtFinallyStmt(Empty);
       break;
     case STMT_OBJC_AT_TRY:
-      S = ObjCAtTryStmt::CreateEmpty(Context, 
+      S = ObjCAtTryStmt::CreateEmpty(Context,
                                      Record[ASTStmtReader::NumStmtFields],
                                      Record[ASTStmtReader::NumStmtFields + 1]);
       break;
@@ -3605,7 +3606,7 @@
       break;
     }
 
-    case STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE: {
+     case STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE: {
       auto NumClauses = Record[ASTStmtReader::NumStmtFields];
       auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
       S = OMPTeamsDistributeDirective::CreateEmpty(Context, NumClauses,
@@ -3637,6 +3638,44 @@
       break;
     }
 
+    case STMT_OMP_TARGET_TEAMS_DIRECTIVE: {
+      S = OMPTargetTeamsDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+    }
+
+    case STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE: {
+      auto NumClauses = Record[ASTStmtReader::NumStmtFields];
+      auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+      S = OMPTargetTeamsDistributeDirective::CreateEmpty(Context, NumClauses,
+                                                         CollapsedNum, Empty);
+      break;
+    }
+
+    case STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE: {
+      auto NumClauses = Record[ASTStmtReader::NumStmtFields];
+      auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+      S = OMPTargetTeamsDistributeParallelForDirective::CreateEmpty(
+          Context, NumClauses, CollapsedNum, Empty);
+      break;
+    }
+
+    case STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE: {
+      auto NumClauses = Record[ASTStmtReader::NumStmtFields];
+      auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+      S = OMPTargetTeamsDistributeParallelForSimdDirective::CreateEmpty(
+          Context, NumClauses, CollapsedNum, Empty);
+      break;
+    }
+
+    case STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE: {
+      auto NumClauses = Record[ASTStmtReader::NumStmtFields];
+      auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+      S = OMPTargetTeamsDistributeSimdDirective::CreateEmpty(
+          Context, NumClauses, CollapsedNum, Empty);
+      break;
+    }
+
     case EXPR_CXX_OPERATOR_CALL:
       S = new (Context) CXXOperatorCallExpr(Context, Empty);
       break;
@@ -3729,7 +3768,7 @@
     case EXPR_CXX_BIND_TEMPORARY:
       S = new (Context) CXXBindTemporaryExpr(Empty);
       break;
-        
+
     case EXPR_CXX_SCALAR_VALUE_INIT:
       S = new (Context) CXXScalarValueInitExpr(Empty);
       break;
@@ -3742,54 +3781,54 @@
     case EXPR_CXX_PSEUDO_DESTRUCTOR:
       S = new (Context) CXXPseudoDestructorExpr(Empty);
       break;
-        
+
     case EXPR_EXPR_WITH_CLEANUPS:
       S = ExprWithCleanups::Create(Context, Empty,
                                    Record[ASTStmtReader::NumExprFields]);
       break;
-      
+
     case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
       S = CXXDependentScopeMemberExpr::CreateEmpty(Context,
          /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
                   /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
-                                   ? Record[ASTStmtReader::NumExprFields + 1] 
+                                   ? Record[ASTStmtReader::NumExprFields + 1]
                                    : 0);
       break;
-      
+
     case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
       S = DependentScopeDeclRefExpr::CreateEmpty(Context,
          /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
                   /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
-                                   ? Record[ASTStmtReader::NumExprFields + 1] 
+                                   ? Record[ASTStmtReader::NumExprFields + 1]
                                    : 0);
       break;
-      
+
     case EXPR_CXX_UNRESOLVED_CONSTRUCT:
       S = CXXUnresolvedConstructExpr::CreateEmpty(Context,
                               /*NumArgs=*/Record[ASTStmtReader::NumExprFields]);
       break;
-      
+
     case EXPR_CXX_UNRESOLVED_MEMBER:
       S = UnresolvedMemberExpr::CreateEmpty(Context,
          /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
                   /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
-                                   ? Record[ASTStmtReader::NumExprFields + 1] 
+                                   ? Record[ASTStmtReader::NumExprFields + 1]
                                    : 0);
       break;
-      
+
     case EXPR_CXX_UNRESOLVED_LOOKUP:
       S = UnresolvedLookupExpr::CreateEmpty(Context,
          /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
                   /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
-                                   ? Record[ASTStmtReader::NumExprFields + 1] 
+                                   ? Record[ASTStmtReader::NumExprFields + 1]
                                    : 0);
       break;
 
     case EXPR_TYPE_TRAIT:
-      S = TypeTraitExpr::CreateDeserialized(Context, 
+      S = TypeTraitExpr::CreateDeserialized(Context,
             Record[ASTStmtReader::NumExprFields]);
       break;
-        
+
     case EXPR_ARRAY_TYPE_TRAIT:
       S = new (Context) ArrayTypeTraitExpr(Empty);
       break;
@@ -3805,17 +3844,17 @@
     case EXPR_PACK_EXPANSION:
       S = new (Context) PackExpansionExpr(Empty);
       break;
-        
+
     case EXPR_SIZEOF_PACK:
       S = SizeOfPackExpr::CreateDeserialized(
               Context,
               /*NumPartialArgs=*/Record[ASTStmtReader::NumExprFields]);
       break;
-        
+
     case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM:
       S = new (Context) SubstNonTypeTemplateParmExpr(Empty);
       break;
-        
+
     case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK:
       S = new (Context) SubstNonTypeTemplateParmPackExpr(Empty);
       break;
@@ -3824,7 +3863,7 @@
       S = FunctionParmPackExpr::CreateEmpty(Context,
                                           Record[ASTStmtReader::NumExprFields]);
       break;
-        
+
     case EXPR_MATERIALIZE_TEMPORARY:
       S = new (Context) MaterializeTemporaryExpr(Empty);
       break;
@@ -3840,7 +3879,7 @@
     case EXPR_CUDA_KERNEL_CALL:
       S = new (Context) CUDAKernelCallExpr(Context, Empty);
       break;
-        
+
     case EXPR_ASTYPE:
       S = new (Context) AsTypeExpr(Empty);
       break;
@@ -3854,16 +3893,14 @@
     case EXPR_ATOMIC:
       S = new (Context) AtomicExpr(Empty);
       break;
-        
+
     case EXPR_LAMBDA: {
       unsigned NumCaptures = Record[ASTStmtReader::NumExprFields];
-      unsigned NumArrayIndexVars = Record[ASTStmtReader::NumExprFields + 1];
-      S = LambdaExpr::CreateDeserialized(Context, NumCaptures, 
-                                         NumArrayIndexVars);
+      S = LambdaExpr::CreateDeserialized(Context, NumCaptures);
       break;
     }
     }
-    
+
     // We hit a STMT_STOP, so we're done with this expression.
     if (Finished)
       break;
@@ -3875,8 +3912,8 @@
       StmtEntries[Cursor.GetCurrentBitNo()] = S;
     }
 
-
-    assert(Idx == Record.size() && "Invalid deserialization of statement");
+    assert(Record.getIdx() == Record.size() &&
+           "Invalid deserialization of statement");
     StmtStack.push_back(S);
   }
 Done:
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 9c906e4..b13a4e1 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -18,8 +18,8 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTUnresolvedSet.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/DeclContextInternals.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclContextInternals.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
@@ -33,8 +33,8 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/SourceManager.h"
@@ -64,20 +64,22 @@
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Bitcode/BitCodes.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/EndianStream.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/OnDiskHashTable.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/SHA1.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cassert>
@@ -348,6 +350,15 @@
   Code = TYPE_AUTO;
 }
 
+void ASTTypeWriter::VisitDeducedTemplateSpecializationType(
+    const DeducedTemplateSpecializationType *T) {
+  Record.AddTemplateName(T->getTemplateName());
+  Record.AddTypeRef(T->getDeducedType());
+  if (T->getDeducedType().isNull())
+    Record.push_back(T->isDependentType());
+  Code = TYPE_DEDUCED_TEMPLATE_SPECIALIZATION;
+}
+
 void ASTTypeWriter::VisitTagType(const TagType *T) {
   Record.push_back(T->isDependentType());
   Record.AddDeclRef(T->getDecl()->getCanonicalDecl());
@@ -629,6 +640,7 @@
   Record.AddSourceLocation(TL.getLocalRangeBegin());
   Record.AddSourceLocation(TL.getLParenLoc());
   Record.AddSourceLocation(TL.getRParenLoc());
+  Record.AddSourceRange(TL.getExceptionSpecRange());
   Record.AddSourceLocation(TL.getLocalRangeEnd());
   for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i)
     Record.AddDeclRef(TL.getParam(i));
@@ -681,6 +693,11 @@
   Record.AddSourceLocation(TL.getNameLoc());
 }
 
+void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc(
+    DeducedTemplateSpecializationTypeLoc TL) {
+  Record.AddSourceLocation(TL.getTemplateNameLoc());
+}
+
 void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
   Record.AddSourceLocation(TL.getNameLoc());
 }
@@ -800,17 +817,17 @@
 void ASTWriter::WriteTypeAbbrevs() {
   using namespace llvm;
 
-  BitCodeAbbrev *Abv;
+  std::shared_ptr<BitCodeAbbrev> Abv;
 
   // Abbreviation for TYPE_EXT_QUAL
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::TYPE_EXT_QUAL));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Type
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3));   // Quals
-  TypeExtQualAbbrev = Stream.EmitAbbrev(Abv);
+  TypeExtQualAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for TYPE_FUNCTION_PROTO
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::TYPE_FUNCTION_PROTO));
   // FunctionType
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // ReturnType
@@ -828,7 +845,7 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // NumParams
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Params
-  TypeFunctionProtoAbbrev = Stream.EmitAbbrev(Abv);
+  TypeFunctionProtoAbbrev = Stream.EmitAbbrev(std::move(Abv));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1000,7 +1017,6 @@
   // Control Block.
   BLOCK(CONTROL_BLOCK);
   RECORD(METADATA);
-  RECORD(SIGNATURE);
   RECORD(MODULE_NAME);
   RECORD(MODULE_DIRECTORY);
   RECORD(MODULE_MAP_FILE);
@@ -1013,7 +1029,6 @@
   BLOCK(OPTIONS_BLOCK);
   RECORD(LANGUAGE_OPTIONS);
   RECORD(TARGET_OPTIONS);
-  RECORD(DIAGNOSTIC_OPTIONS);
   RECORD(FILE_SYSTEM_OPTIONS);
   RECORD(HEADER_SEARCH_OPTIONS);
   RECORD(PREPROCESSOR_OPTIONS);
@@ -1028,6 +1043,7 @@
   RECORD(IDENTIFIER_OFFSET);
   RECORD(IDENTIFIER_TABLE);
   RECORD(EAGERLY_DESERIALIZED_DECLS);
+  RECORD(MODULAR_CODEGEN_DECLS);
   RECORD(SPECIAL_TYPES);
   RECORD(STATISTICS);
   RECORD(TENTATIVE_DEFINITIONS);
@@ -1048,11 +1064,12 @@
   RECORD(UPDATE_VISIBLE);
   RECORD(DECL_UPDATE_OFFSETS);
   RECORD(DECL_UPDATES);
-  RECORD(DIAG_PRAGMA_MAPPINGS);
   RECORD(CUDA_SPECIAL_DECL_REFS);
   RECORD(HEADER_SEARCH_TABLE);
   RECORD(FP_PRAGMA_OPTIONS);
   RECORD(OPENCL_EXTENSIONS);
+  RECORD(OPENCL_EXTENSION_TYPES);
+  RECORD(OPENCL_EXTENSION_DECLS);
   RECORD(DELEGATING_CTORS);
   RECORD(KNOWN_NAMESPACES);
   RECORD(MODULE_OFFSET_MAP);
@@ -1239,6 +1256,11 @@
   BLOCK(EXTENSION_BLOCK);
   RECORD(EXTENSION_METADATA);
 
+  BLOCK(UNHASHED_CONTROL_BLOCK);
+  RECORD(SIGNATURE);
+  RECORD(DIAGNOSTIC_OPTIONS);
+  RECORD(DIAG_PRAGMA_MAPPINGS);
+
 #undef RECORD
 #undef BLOCK
   Stream.ExitBlock();
@@ -1301,27 +1323,79 @@
   return Filename + Pos;
 }
 
-static ASTFileSignature getSignature() {
-  while (true) {
-    if (ASTFileSignature S = llvm::sys::Process::GetRandomNumber())
-      return S;
-    // Rely on GetRandomNumber to eventually return non-zero...
+ASTFileSignature ASTWriter::createSignature(StringRef Bytes) {
+  // Calculate the hash till start of UNHASHED_CONTROL_BLOCK.
+  llvm::SHA1 Hasher;
+  Hasher.update(ArrayRef<uint8_t>(Bytes.bytes_begin(), Bytes.size()));
+  auto Hash = Hasher.result();
+
+  // Convert to an array [5*i32].
+  ASTFileSignature Signature;
+  auto LShift = [&](unsigned char Val, unsigned Shift) {
+    return (uint32_t)Val << Shift;
+  };
+  for (int I = 0; I != 5; ++I)
+    Signature[I] = LShift(Hash[I * 4 + 0], 24) | LShift(Hash[I * 4 + 1], 16) |
+                   LShift(Hash[I * 4 + 2], 8) | LShift(Hash[I * 4 + 3], 0);
+
+  return Signature;
+}
+
+ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
+                                                      ASTContext &Context) {
+  // Flush first to prepare the PCM hash (signature).
+  Stream.FlushToWord();
+  auto StartOfUnhashedControl = Stream.GetCurrentBitNo() >> 3;
+
+  // Enter the block and prepare to write records.
+  RecordData Record;
+  Stream.EnterSubblock(UNHASHED_CONTROL_BLOCK_ID, 5);
+
+  // For implicit modules, write the hash of the PCM as its signature.
+  ASTFileSignature Signature;
+  if (WritingModule &&
+      PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent) {
+    Signature = createSignature(StringRef(Buffer.begin(), StartOfUnhashedControl));
+    Record.append(Signature.begin(), Signature.end());
+    Stream.EmitRecord(SIGNATURE, Record);
+    Record.clear();
   }
+
+  // Diagnostic options.
+  const auto &Diags = Context.getDiagnostics();
+  const DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions();
+#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
+#define ENUM_DIAGOPT(Name, Type, Bits, Default)                                \
+  Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
+#include "clang/Basic/DiagnosticOptions.def"
+  Record.push_back(DiagOpts.Warnings.size());
+  for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I)
+    AddString(DiagOpts.Warnings[I], Record);
+  Record.push_back(DiagOpts.Remarks.size());
+  for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I)
+    AddString(DiagOpts.Remarks[I], Record);
+  // Note: we don't serialize the log or serialization file names, because they
+  // are generally transient files and will almost always be overridden.
+  Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
+
+  // Write out the diagnostic/pragma mappings.
+  WritePragmaDiagnosticMappings(Diags, /* IsModule = */ WritingModule);
+
+  // Leave the options block.
+  Stream.ExitBlock();
+  return Signature;
 }
 
 /// \brief Write the control block.
-uint64_t ASTWriter::WriteControlBlock(Preprocessor &PP,
-                                      ASTContext &Context,
-                                      StringRef isysroot,
-                                      const std::string &OutputFile) {
-  ASTFileSignature Signature = 0;
-
+void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+                                  StringRef isysroot,
+                                  const std::string &OutputFile) {
   using namespace llvm;
   Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
   RecordData Record;
   
   // Metadata
-  auto *MetadataAbbrev = new BitCodeAbbrev();
+  auto MetadataAbbrev = std::make_shared<BitCodeAbbrev>();
   MetadataAbbrev->Add(BitCodeAbbrevOp(METADATA));
   MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Major
   MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Minor
@@ -1331,7 +1405,7 @@
   MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Timestamps
   MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Errors
   MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag
-  unsigned MetadataAbbrevCode = Stream.EmitAbbrev(MetadataAbbrev);
+  unsigned MetadataAbbrevCode = Stream.EmitAbbrev(std::move(MetadataAbbrev));
   assert((!WritingModule || isysroot.empty()) &&
          "writing module as a relocatable PCH?");
   {
@@ -1343,21 +1417,12 @@
                               getClangFullRepositoryVersion());
   }
   if (WritingModule) {
-    // For implicit modules we output a signature that we can use to ensure
-    // duplicate module builds don't collide in the cache as their output order
-    // is non-deterministic.
-    // FIXME: Remove this when output is deterministic.
-    if (Context.getLangOpts().ImplicitModules) {
-      Signature = getSignature();
-      RecordData::value_type Record[] = {Signature};
-      Stream.EmitRecord(SIGNATURE, Record);
-    }
 
     // Module name
-    auto *Abbrev = new BitCodeAbbrev();
+    auto Abbrev = std::make_shared<BitCodeAbbrev>();
     Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+    unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
     RecordData::value_type Record[] = {MODULE_NAME};
     Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name);
   }
@@ -1374,10 +1439,10 @@
              .ModuleMapFileHomeIsCwd ||
         WritingModule->Directory->getName() != StringRef(".")) {
       // Module directory.
-      auto *Abbrev = new BitCodeAbbrev();
+      auto Abbrev = std::make_shared<BitCodeAbbrev>();
       Abbrev->Add(BitCodeAbbrevOp(MODULE_DIRECTORY));
       Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Directory
-      unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+      unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
 
       RecordData::value_type Record[] = {MODULE_DIRECTORY};
       Stream.EmitRecordWithBlob(AbbrevCode, Record, BaseDir);
@@ -1417,17 +1482,23 @@
     serialization::ModuleManager &Mgr = Chain->getModuleManager();
     Record.clear();
 
-    for (auto *M : Mgr) {
+    for (ModuleFile &M : Mgr) {
       // Skip modules that weren't directly imported.
-      if (!M->isDirectlyImported())
+      if (!M.isDirectlyImported())
         continue;
 
-      Record.push_back((unsigned)M->Kind); // FIXME: Stable encoding
-      AddSourceLocation(M->ImportLoc, Record);
-      Record.push_back(M->File->getSize());
-      Record.push_back(getTimestampForOutput(M->File));
-      Record.push_back(M->Signature);
-      AddPath(M->FileName, Record);
+      Record.push_back((unsigned)M.Kind); // FIXME: Stable encoding
+      AddSourceLocation(M.ImportLoc, Record);
+
+      // If we have calculated signature, there is no need to store
+      // the size or timestamp.
+      Record.push_back(M.Signature ? 0 : M.File->getSize());
+      Record.push_back(M.Signature ? 0 : getTimestampForOutput(M.File));
+
+      for (auto I : M.Signature)
+        Record.push_back(I);
+
+      AddPath(M.FileName, Record);
     }
     Stream.EmitRecord(IMPORTS, Record);
   }
@@ -1489,24 +1560,6 @@
   }
   Stream.EmitRecord(TARGET_OPTIONS, Record);
 
-  // Diagnostic options.
-  Record.clear();
-  const DiagnosticOptions &DiagOpts
-    = Context.getDiagnostics().getDiagnosticOptions();
-#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-  Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
-#include "clang/Basic/DiagnosticOptions.def"
-  Record.push_back(DiagOpts.Warnings.size());
-  for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I)
-    AddString(DiagOpts.Warnings[I], Record);
-  Record.push_back(DiagOpts.Remarks.size());
-  for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I)
-    AddString(DiagOpts.Remarks[I], Record);
-  // Note: we don't serialize the log or serialization file names, because they
-  // are generally transient files and will almost always be overridden.
-  Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
-
   // File system options.
   Record.clear();
   const FileSystemOptions &FSOpts =
@@ -1584,11 +1637,11 @@
   // Original file name and file ID
   SourceManager &SM = Context.getSourceManager();
   if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
-    auto *FileAbbrev = new BitCodeAbbrev();
+    auto FileAbbrev = std::make_shared<BitCodeAbbrev>();
     FileAbbrev->Add(BitCodeAbbrevOp(ORIGINAL_FILE));
     FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // File ID
     FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
-    unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev);
+    unsigned FileAbbrevCode = Stream.EmitAbbrev(std::move(FileAbbrev));
 
     Record.clear();
     Record.push_back(ORIGINAL_FILE);
@@ -1602,10 +1655,10 @@
 
   // Original PCH directory
   if (!OutputFile.empty() && OutputFile != "-") {
-    auto *Abbrev = new BitCodeAbbrev();
+    auto Abbrev = std::make_shared<BitCodeAbbrev>();
     Abbrev->Add(BitCodeAbbrevOp(ORIGINAL_PCH_DIR));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
-    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+    unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
 
     SmallString<128> OutputPath(OutputFile);
 
@@ -1620,7 +1673,6 @@
                   PP.getHeaderSearchInfo().getHeaderSearchOpts(),
                   PP.getLangOpts().Modules);
   Stream.ExitBlock();
-  return Signature;
 }
 
 namespace  {
@@ -1642,7 +1694,7 @@
   Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4);
 
   // Create input-file abbreviation.
-  auto *IFAbbrev = new BitCodeAbbrev();
+  auto IFAbbrev = std::make_shared<BitCodeAbbrev>();
   IFAbbrev->Add(BitCodeAbbrevOp(INPUT_FILE));
   IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
   IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size
@@ -1650,7 +1702,7 @@
   IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Overridden
   IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Transient
   IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
-  unsigned IFAbbrevCode = Stream.EmitAbbrev(IFAbbrev);
+  unsigned IFAbbrevCode = Stream.EmitAbbrev(std::move(IFAbbrev));
 
   // Get all ContentCache objects for files, sorted by whether the file is a
   // system one or not. System files go at the back, users files at the front.
@@ -1710,13 +1762,13 @@
   Stream.ExitBlock();
 
   // Create input file offsets abbreviation.
-  auto *OffsetsAbbrev = new BitCodeAbbrev();
+  auto OffsetsAbbrev = std::make_shared<BitCodeAbbrev>();
   OffsetsAbbrev->Add(BitCodeAbbrevOp(INPUT_FILE_OFFSETS));
   OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # input files
   OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # non-system
                                                                 //   input files
   OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));   // Array
-  unsigned OffsetsAbbrevCode = Stream.EmitAbbrev(OffsetsAbbrev);
+  unsigned OffsetsAbbrevCode = Stream.EmitAbbrev(std::move(OffsetsAbbrev));
 
   // Write input file offsets.
   RecordData::value_type Record[] = {INPUT_FILE_OFFSETS,
@@ -1733,7 +1785,7 @@
 static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) {
   using namespace llvm;
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
@@ -1744,7 +1796,7 @@
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumCreatedFIDs
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 24)); // FirstDeclIndex
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumDecls
-  return Stream.EmitAbbrev(Abbrev);
+  return Stream.EmitAbbrev(std::move(Abbrev));
 }
 
 /// \brief Create an abbreviation for the SLocEntry that refers to a
@@ -1752,14 +1804,14 @@
 static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) {
   using namespace llvm;
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
-  return Stream.EmitAbbrev(Abbrev);
+  return Stream.EmitAbbrev(std::move(Abbrev));
 }
 
 /// \brief Create an abbreviation for the SLocEntry that refers to a
@@ -1768,13 +1820,13 @@
                                            bool Compressed) {
   using namespace llvm;
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(Compressed ? SM_SLOC_BUFFER_BLOB_COMPRESSED
                                          : SM_SLOC_BUFFER_BLOB));
   if (Compressed)
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Uncompressed size
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
-  return Stream.EmitAbbrev(Abbrev);
+  return Stream.EmitAbbrev(std::move(Abbrev));
 }
 
 /// \brief Create an abbreviation for the SLocEntry that refers to a macro
@@ -1782,14 +1834,14 @@
 static unsigned CreateSLocExpansionAbbrev(llvm::BitstreamWriter &Stream) {
   using namespace llvm;
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_EXPANSION_ENTRY));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length
-  return Stream.EmitAbbrev(Abbrev);
+  return Stream.EmitAbbrev(std::move(Abbrev));
 }
 
 namespace {
@@ -1964,13 +2016,13 @@
   // Create a blob abbreviation
   using namespace llvm;
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_TABLE));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-  unsigned TableAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned TableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
   
   // Write the header search table
   RecordData::value_type Record[] = {HEADER_SEARCH_TABLE, BucketOffset,
@@ -1983,6 +2035,30 @@
     free(const_cast<char *>(SavedStrings[I]));
 }
 
+static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
+                     unsigned SLocBufferBlobCompressedAbbrv,
+                     unsigned SLocBufferBlobAbbrv) {
+  typedef ASTWriter::RecordData::value_type RecordDataType;
+
+  // Compress the buffer if possible. We expect that almost all PCM
+  // consumers will not want its contents.
+  SmallString<0> CompressedBuffer;
+  if (llvm::zlib::isAvailable()) {
+    llvm::Error E = llvm::zlib::compress(Blob.drop_back(1), CompressedBuffer);
+    if (!E) {
+      RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED,
+                                 Blob.size() - 1};
+      Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record,
+                                CompressedBuffer);
+      return;
+    }
+    llvm::consumeError(std::move(E));
+  }
+
+  RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB};
+  Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, Blob);
+}
+
 /// \brief Writes the block containing the serialized form of the
 /// source manager.
 ///
@@ -2091,20 +2167,8 @@
         const llvm::MemoryBuffer *Buffer =
             Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
         StringRef Blob(Buffer->getBufferStart(), Buffer->getBufferSize() + 1);
-
-        // Compress the buffer if possible. We expect that almost all PCM
-        // consumers will not want its contents.
-        SmallString<0> CompressedBuffer;
-        if (llvm::zlib::compress(Blob.drop_back(1), CompressedBuffer) ==
-            llvm::zlib::StatusOK) {
-          RecordData::value_type Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED,
-                                             Blob.size() - 1};
-          Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record,
-                                    CompressedBuffer);
-        } else {
-          RecordData::value_type Record[] = {SM_SLOC_BUFFER_BLOB};
-          Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, Blob);
-        }
+        emitBlob(Stream, Blob, SLocBufferBlobCompressedAbbrv,
+                 SLocBufferBlobAbbrv);
       }
     } else {
       // The source location entry is a macro expansion.
@@ -2134,12 +2198,12 @@
   // table is used for lazily loading source-location information.
   using namespace llvm;
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // total size
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets
-  unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
   {
     RecordData::value_type Record[] = {
         SOURCE_LOCATION_OFFSETS, SLocEntryOffsets.size(),
@@ -2389,13 +2453,13 @@
   // Write the offsets table for macro IDs.
   using namespace llvm;
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(MACRO_OFFSET));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macros
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
 
-  unsigned MacroOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned MacroOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
   {
     RecordData::value_type Record[] = {MACRO_OFFSET, MacroOffsets.size(),
                                        FirstMacroID - NUM_PREDEF_MACRO_IDS};
@@ -2419,14 +2483,14 @@
   // Set up the abbreviation for 
   unsigned InclusionAbbrev = 0;
   {
-    auto *Abbrev = new BitCodeAbbrev();
+    auto Abbrev = std::make_shared<BitCodeAbbrev>();
     Abbrev->Add(BitCodeAbbrevOp(PPD_INCLUSION_DIRECTIVE));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // imported module
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-    InclusionAbbrev = Stream.EmitAbbrev(Abbrev);
+    InclusionAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
   }
   
   unsigned FirstPreprocessorEntityID 
@@ -2489,11 +2553,11 @@
     // Write the offsets table for identifier IDs.
     using namespace llvm;
 
-    auto *Abbrev = new BitCodeAbbrev();
+    auto Abbrev = std::make_shared<BitCodeAbbrev>();
     Abbrev->Add(BitCodeAbbrevOp(PPD_ENTITIES_OFFSETS));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first pp entity
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-    unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+    unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
     RecordData::value_type Record[] = {PPD_ENTITIES_OFFSETS,
                                        FirstPreprocessorEntityID -
@@ -2513,7 +2577,8 @@
 
   auto *Top = Mod->getTopLevelModule();
   if (Top != WritingModule &&
-      !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule)))
+      (getLangOpts().CompilingPCH ||
+       !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule))))
     return 0;
 
   return SubmoduleIDs[Mod] = NextSubmoduleID++;
@@ -2547,7 +2612,7 @@
   // Write the abbreviations needed for the submodules block.
   using namespace llvm;
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
@@ -2559,71 +2624,72 @@
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ConfigMacrosExh...
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // WithCodegen
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-  unsigned DefinitionAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned DefinitionAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_HEADER));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-  unsigned UmbrellaAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned UmbrellaAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_HEADER));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-  unsigned HeaderAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned HeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_TOPHEADER));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-  unsigned TopHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned TopHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_DIR));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-  unsigned UmbrellaDirAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned UmbrellaDirAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_REQUIRES));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // State
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));     // Feature
-  unsigned RequiresAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned RequiresAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_EXCLUDED_HEADER));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-  unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_TEXTUAL_HEADER));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-  unsigned TextualHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned TextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_HEADER));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-  unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_TEXTUAL_HEADER));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
-  unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_LINK_LIBRARY));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));     // Name
-  unsigned LinkLibraryAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned LinkLibraryAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_CONFIG_MACRO));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));    // Macro name
-  unsigned ConfigMacroAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned ConfigMacroAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_CONFLICT));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));  // Other module
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));    // Message
-  unsigned ConflictAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
   // Write the submodule metadata block.
   RecordData::value_type Record[] = {getNumberOfModules(WritingModule),
@@ -2647,11 +2713,18 @@
 
     // Emit the definition of the block.
     {
-      RecordData::value_type Record[] = {
-          SUBMODULE_DEFINITION, ID, ParentID, Mod->IsFramework, Mod->IsExplicit,
-          Mod->IsSystem, Mod->IsExternC, Mod->InferSubmodules,
-          Mod->InferExplicitSubmodules, Mod->InferExportWildcard,
-          Mod->ConfigMacrosExhaustive};
+      RecordData::value_type Record[] = {SUBMODULE_DEFINITION,
+                                         ID,
+                                         ParentID,
+                                         Mod->IsFramework,
+                                         Mod->IsExplicit,
+                                         Mod->IsSystem,
+                                         Mod->IsExternC,
+                                         Mod->InferSubmodules,
+                                         Mod->InferExplicitSubmodules,
+                                         Mod->InferExportWildcard,
+                                         Mod->ConfigMacrosExhaustive,
+                                         Context->getLangOpts().ModularCodegen && WritingModule};
       Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name);
     }
 
@@ -2786,38 +2859,43 @@
 
 void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
                                               bool isModule) {
-  // Make sure set diagnostic pragmas don't affect the translation unit that
-  // imports the module.
-  // FIXME: Make diagnostic pragma sections work properly with modules.
-  if (isModule)
-    return;
-
   llvm::SmallDenseMap<const DiagnosticsEngine::DiagState *, unsigned, 64>
       DiagStateIDMap;
   unsigned CurrID = 0;
-  DiagStateIDMap[&Diag.DiagStates.front()] = ++CurrID; // the command-line one.
   RecordData Record;
-  for (DiagnosticsEngine::DiagStatePointsTy::const_iterator
-         I = Diag.DiagStatePoints.begin(), E = Diag.DiagStatePoints.end();
-         I != E; ++I) {
-    const DiagnosticsEngine::DiagStatePoint &point = *I;
-    if (point.Loc.isInvalid())
-      continue;
 
-    AddSourceLocation(point.Loc, Record);
-    unsigned &DiagStateID = DiagStateIDMap[point.State];
+  auto AddDiagState = [&](const DiagnosticsEngine::DiagState *State,
+                          bool IncludeNonPragmaStates) {
+    unsigned &DiagStateID = DiagStateIDMap[State];
     Record.push_back(DiagStateID);
-    
+  
     if (DiagStateID == 0) {
       DiagStateID = ++CurrID;
-      for (const auto &I : *(point.State)) {
-        if (I.second.isPragma()) {
+      for (const auto &I : *State) {
+        if (I.second.isPragma() || IncludeNonPragmaStates) {
           Record.push_back(I.first);
           Record.push_back((unsigned)I.second.getSeverity());
         }
       }
-      Record.push_back(-1); // mark the end of the diag/map pairs for this
-                            // location.
+      // Add a sentinel to mark the end of the diag IDs.
+      Record.push_back(unsigned(-1));
+    }
+  };
+
+  AddDiagState(Diag.DiagStatesByLoc.FirstDiagState, isModule);
+  AddSourceLocation(Diag.DiagStatesByLoc.CurDiagStateLoc, Record);
+  AddDiagState(Diag.DiagStatesByLoc.CurDiagState, false);
+
+  for (auto &FileIDAndFile : Diag.DiagStatesByLoc.Files) {
+    if (!FileIDAndFile.first.isValid() ||
+        !FileIDAndFile.second.HasLocalTransitions)
+      continue;
+    AddSourceLocation(Diag.SourceMgr->getLocForStartOfFile(FileIDAndFile.first),
+                      Record);
+    Record.push_back(FileIDAndFile.second.StateTransitions.size());
+    for (auto &StatePoint : FileIDAndFile.second.StateTransitions) {
+      Record.push_back(StatePoint.Offset);
+      AddDiagState(StatePoint.State, false);
     }
   }
 
@@ -2889,12 +2967,12 @@
   using namespace llvm;
 
   // Write the type offsets array
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base type index
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block
-  unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
   {
     RecordData::value_type Record[] = {TYPE_OFFSET, TypeOffsets.size(),
                                        FirstTypeID - NUM_PREDEF_TYPE_IDS};
@@ -2902,12 +2980,12 @@
   }
 
   // Write the declaration offsets array
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base decl ID
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block
-  unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
   {
     RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(),
                                        FirstDeclID - NUM_PREDEF_DECL_IDS};
@@ -2932,11 +3010,11 @@
       FileGroupedDeclIDs.push_back(LocDeclEntry.second);
   }
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(FILE_SORTED_DECLS));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-  unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+  unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
   RecordData::value_type Record[] = {FILE_SORTED_DECLS,
                                      FileGroupedDeclIDs.size()};
   Stream.EmitRecordWithBlob(AbbrevCode, Record, bytes(FileGroupedDeclIDs));
@@ -3140,12 +3218,12 @@
     }
 
     // Create a blob abbreviation
-    auto *Abbrev = new BitCodeAbbrev();
+    auto Abbrev = std::make_shared<BitCodeAbbrev>();
     Abbrev->Add(BitCodeAbbrevOp(METHOD_POOL));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-    unsigned MethodPoolAbbrev = Stream.EmitAbbrev(Abbrev);
+    unsigned MethodPoolAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
     // Write the method pool
     {
@@ -3155,12 +3233,12 @@
     }
 
     // Create a blob abbreviation for the selector table offsets.
-    Abbrev = new BitCodeAbbrev();
+    Abbrev = std::make_shared<BitCodeAbbrev>();
     Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-    unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+    unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
     // Write the selector offsets table.
     {
@@ -3450,11 +3528,11 @@
     }
 
     // Create a blob abbreviation
-    auto *Abbrev = new BitCodeAbbrev();
+    auto Abbrev = std::make_shared<BitCodeAbbrev>();
     Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_TABLE));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-    unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev);
+    unsigned IDTableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
     // Write the identifier table
     RecordData::value_type Record[] = {IDENTIFIER_TABLE, BucketOffset};
@@ -3462,12 +3540,12 @@
   }
 
   // Write the offsets table for identifier IDs.
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-  unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+  unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
 #ifndef NDEBUG
   for (unsigned I = 0, N = IdentifierOffsets.size(); I != N; ++I)
@@ -3556,6 +3634,7 @@
     case DeclarationName::ObjCOneArgSelector:
     case DeclarationName::ObjCMultiArgSelector:
     case DeclarationName::CXXLiteralOperatorName:
+    case DeclarationName::CXXDeductionGuideName:
       KeyLen += 4;
       break;
     case DeclarationName::CXXOperatorName:
@@ -3585,6 +3664,7 @@
     switch (Name.getKind()) {
     case DeclarationName::Identifier:
     case DeclarationName::CXXLiteralOperatorName:
+    case DeclarationName::CXXDeductionGuideName:
       LE.write<uint32_t>(Writer.getIdentifierRef(Name.getIdentifier()));
       return;
     case DeclarationName::ObjCZeroArgSelector:
@@ -3939,11 +4019,46 @@
 
   const OpenCLOptions &Opts = SemaRef.getOpenCLOptions();
   RecordData Record;
-#define OPENCLEXT(nm)  Record.push_back(Opts.nm);
-#include "clang/Basic/OpenCLExtensions.def"
+  for (const auto &I:Opts.OptMap) {
+    AddString(I.getKey(), Record);
+    auto V = I.getValue();
+    Record.push_back(V.Supported ? 1 : 0);
+    Record.push_back(V.Enabled ? 1 : 0);
+    Record.push_back(V.Avail);
+    Record.push_back(V.Core);
+  }
   Stream.EmitRecord(OPENCL_EXTENSIONS, Record);
 }
 
+void ASTWriter::WriteOpenCLExtensionTypes(Sema &SemaRef) {
+  if (!SemaRef.Context.getLangOpts().OpenCL)
+    return;
+
+  RecordData Record;
+  for (const auto &I : SemaRef.OpenCLTypeExtMap) {
+    Record.push_back(
+        static_cast<unsigned>(getTypeID(I.first->getCanonicalTypeInternal())));
+    Record.push_back(I.second.size());
+    for (auto Ext : I.second)
+      AddString(Ext, Record);
+  }
+  Stream.EmitRecord(OPENCL_EXTENSION_TYPES, Record);
+}
+
+void ASTWriter::WriteOpenCLExtensionDecls(Sema &SemaRef) {
+  if (!SemaRef.Context.getLangOpts().OpenCL)
+    return;
+
+  RecordData Record;
+  for (const auto &I : SemaRef.OpenCLDeclExtMap) {
+    Record.push_back(getDeclID(I.first));
+    Record.push_back(static_cast<unsigned>(I.second.size()));
+    for (auto Ext : I.second)
+      AddString(Ext, Record);
+  }
+  Stream.EmitRecord(OPENCL_EXTENSION_DECLS, Record);
+}
+
 void ASTWriter::WriteCUDAPragmas(Sema &SemaRef) {
   if (SemaRef.ForceCUDAHostDeviceDepth > 0) {
     RecordData::value_type Record[] = {SemaRef.ForceCUDAHostDeviceDepth};
@@ -3988,11 +4103,11 @@
   // Emit the categories map.
   using namespace llvm;
 
-  auto *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(OBJC_CATEGORIES_MAP));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of entries
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-  unsigned AbbrevID = Stream.EmitAbbrev(Abbrev);
+  unsigned AbbrevID = Stream.EmitAbbrev(std::move(Abbrev));
 
   RecordData::value_type Record[] = {OBJC_CATEGORIES_MAP, CategoriesMap.size()};
   Stream.EmitRecordWithBlob(AbbrevID, Record,
@@ -4054,14 +4169,14 @@
   Stream.EnterSubblock(EXTENSION_BLOCK_ID, 4);
 
   // Emit the metadata record abbreviation.
-  auto *Abv = new llvm::BitCodeAbbrev();
+  auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
   Abv->Add(llvm::BitCodeAbbrevOp(EXTENSION_METADATA));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
-  unsigned Abbrev = Stream.EmitAbbrev(Abv);
+  unsigned Abbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Emit the metadata record.
   RecordData Record;
@@ -4184,29 +4299,11 @@
   SelectorOffsets[ID - FirstSelectorID] = Offset;
 }
 
-ASTWriter::ASTWriter(
-  llvm::BitstreamWriter &Stream,
-  ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
-  bool IncludeTimestamps)
-    : Stream(Stream), Context(nullptr), PP(nullptr), Chain(nullptr),
-      WritingModule(nullptr), IncludeTimestamps(IncludeTimestamps),
-      WritingAST(false), DoneWritingDeclsAndTypes(false),
-      ASTHasCompilerErrors(false), FirstDeclID(NUM_PREDEF_DECL_IDS),
-      NextDeclID(FirstDeclID), FirstTypeID(NUM_PREDEF_TYPE_IDS),
-      NextTypeID(FirstTypeID), FirstIdentID(NUM_PREDEF_IDENT_IDS),
-      NextIdentID(FirstIdentID), FirstMacroID(NUM_PREDEF_MACRO_IDS),
-      NextMacroID(FirstMacroID), FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS),
-      NextSubmoduleID(FirstSubmoduleID),
-      FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
-      NumStatements(0), NumMacros(0),
-      NumLexicalDeclContexts(0), NumVisibleDeclContexts(0),
-      TypeExtQualAbbrev(0), TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0),
-      DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0),
-      UpdateVisibleAbbrev(0), DeclRecordAbbrev(0), DeclTypedefAbbrev(0),
-      DeclVarAbbrev(0), DeclFieldAbbrev(0), DeclEnumAbbrev(0),
-      DeclObjCIvarAbbrev(0), DeclCXXMethodAbbrev(0), DeclRefExprAbbrev(0),
-      CharacterLiteralAbbrev(0), IntegerLiteralAbbrev(0),
-      ExprImplicitCastAbbrev(0) {
+ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
+                     SmallVectorImpl<char> &Buffer,
+                     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
+                     bool IncludeTimestamps)
+    : Stream(Stream), Buffer(Buffer), IncludeTimestamps(IncludeTimestamps) {
   for (const auto &Ext : Extensions) {
     if (auto Writer = Ext->createExtensionWriter(*this))
       ModuleFileExtensionWriters.push_back(std::move(Writer));
@@ -4226,9 +4323,10 @@
   return IncludeTimestamps ? E->getModificationTime() : 0;
 }
 
-uint64_t ASTWriter::WriteAST(Sema &SemaRef, const std::string &OutputFile,
-                             Module *WritingModule, StringRef isysroot,
-                             bool hasErrors) {
+ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
+                                     const std::string &OutputFile,
+                                     Module *WritingModule, StringRef isysroot,
+                                     bool hasErrors) {
   WritingAST = true;
 
   ASTHasCompilerErrors = hasErrors;
@@ -4264,9 +4362,9 @@
   }
 }
 
-uint64_t ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
-                                 const std::string &OutputFile,
-                                 Module *WritingModule) {
+ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
+                                         const std::string &OutputFile,
+                                         Module *WritingModule) {
   using namespace llvm;
 
   bool isModule = WritingModule != nullptr;
@@ -4414,7 +4512,7 @@
   }
 
   // Write the control block
-  uint64_t Signature = WriteControlBlock(PP, Context, isysroot, OutputFile);
+  WriteControlBlock(PP, Context, isysroot, OutputFile);
 
   // Write the remaining AST contents.
   Stream.EnterSubblock(AST_BLOCK_ID, 5);
@@ -4437,10 +4535,10 @@
     }
   }
   
-  auto *Abv = new llvm::BitCodeAbbrev();
+  auto Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
-  unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(Abv);
+  unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
   {
     RecordData::value_type Record[] = {TU_UPDATE_LEXICAL};
     Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
@@ -4448,11 +4546,11 @@
   }
 
   // And a visible updates block for the translation unit.
-  Abv = new llvm::BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
-  UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv);
+  UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
   WriteDeclContextVisibleUpdate(TU);
 
   // If we have any extern "C" names, write out a visible update for them.
@@ -4547,17 +4645,17 @@
     //   c++-base-specifiers-id:i32
     //   type-id:i32)
     // 
-    auto *Abbrev = new BitCodeAbbrev();
+    auto Abbrev = std::make_shared<BitCodeAbbrev>();
     Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-    unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(Abbrev);
+    unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
     SmallString<2048> Buffer;
     {
       llvm::raw_svector_ostream Out(Buffer);
-      for (ModuleFile *M : Chain->ModuleMgr) {
+      for (ModuleFile &M : Chain->ModuleMgr) {
         using namespace llvm::support;
         endian::Writer<little> LE(Out);
-        StringRef FileName = M->FileName;
+        StringRef FileName = M.FileName;
         LE.write<uint16_t>(FileName.size());
         Out.write(FileName.data(), FileName.size());
 
@@ -4575,15 +4673,15 @@
 
         // These values should be unique within a chain, since they will be read
         // as keys into ContinuousRangeMaps.
-        writeBaseIDOrNone(M->SLocEntryBaseOffset, M->LocalNumSLocEntries);
-        writeBaseIDOrNone(M->BaseIdentifierID, M->LocalNumIdentifiers);
-        writeBaseIDOrNone(M->BaseMacroID, M->LocalNumMacros);
-        writeBaseIDOrNone(M->BasePreprocessedEntityID,
-                          M->NumPreprocessedEntities);
-        writeBaseIDOrNone(M->BaseSubmoduleID, M->LocalNumSubmodules);
-        writeBaseIDOrNone(M->BaseSelectorID, M->LocalNumSelectors);
-        writeBaseIDOrNone(M->BaseDeclID, M->LocalNumDecls);
-        writeBaseIDOrNone(M->BaseTypeIndex, M->LocalNumTypes);
+        writeBaseIDOrNone(M.SLocEntryBaseOffset, M.LocalNumSLocEntries);
+        writeBaseIDOrNone(M.BaseIdentifierID, M.LocalNumIdentifiers);
+        writeBaseIDOrNone(M.BaseMacroID, M.LocalNumMacros);
+        writeBaseIDOrNone(M.BasePreprocessedEntityID,
+                          M.NumPreprocessedEntities);
+        writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules);
+        writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors);
+        writeBaseIDOrNone(M.BaseDeclID, M.LocalNumDecls);
+        writeBaseIDOrNone(M.BaseTypeIndex, M.LocalNumTypes);
       }
     }
     RecordData::value_type Record[] = {MODULE_OFFSET_MAP};
@@ -4628,23 +4726,13 @@
   WriteIdentifierTable(PP, SemaRef.IdResolver, isModule);
   WriteFPPragmaOptions(SemaRef.getFPOptions());
   WriteOpenCLExtensions(SemaRef);
+  WriteOpenCLExtensionTypes(SemaRef);
+  WriteOpenCLExtensionDecls(SemaRef);
   WriteCUDAPragmas(SemaRef);
-  WritePragmaDiagnosticMappings(Context.getDiagnostics(), isModule);
 
   // If we're emitting a module, write out the submodule information.  
   if (WritingModule)
     WriteSubmodules(WritingModule);
-  else if (!getLangOpts().CurrentModule.empty()) {
-    // If we're building a PCH in the implementation of a module, we may need
-    // the description of the current module.
-    //
-    // FIXME: We may need other modules that we did not load from an AST file,
-    // such as if a module declares a 'conflicts' on a different module.
-    Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule(
-        getLangOpts().CurrentModule);
-    if (M && !M->IsFromModuleFile)
-      WriteSubmodules(M);
-  }
 
   Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
 
@@ -4652,6 +4740,9 @@
   if (!EagerlyDeserializedDecls.empty())
     Stream.EmitRecord(EAGERLY_DESERIALIZED_DECLS, EagerlyDeserializedDecls);
 
+  if (Context.getLangOpts().ModularCodegen)
+    Stream.EmitRecord(MODULAR_CODEGEN_DECLS, ModularCodegenDecls);
+
   // Write the record containing tentative definitions.
   if (!TentativeDefinitions.empty())
     Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
@@ -4766,7 +4857,7 @@
   for (const auto &ExtWriter : ModuleFileExtensionWriters)
     WriteModuleFileExtension(SemaRef, *ExtWriter);
 
-  return Signature;
+  return writeUnhashedControlBlock(PP, Context);
 }
 
 void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
@@ -5219,6 +5310,10 @@
     AddTypeRef(Name.getCXXNameType());
     break;
 
+  case DeclarationName::CXXDeductionGuideName:
+    AddDeclRef(Name.getCXXDeductionGuideTemplate());
+    break;
+
   case DeclarationName::CXXOperatorName:
     Record->push_back(Name.getCXXOverloadedOperator());
     break;
@@ -5280,6 +5375,7 @@
   case DeclarationName::ObjCOneArgSelector:
   case DeclarationName::ObjCMultiArgSelector:
   case DeclarationName::CXXUsingDirective:
+  case DeclarationName::CXXDeductionGuideName:
     break;
   }
 }
@@ -5588,13 +5684,8 @@
     Writer.AddSourceLocation(Init->getLParenLoc());
     Writer.AddSourceLocation(Init->getRParenLoc());
     Writer.push_back(Init->isWritten());
-    if (Init->isWritten()) {
+    if (Init->isWritten())
       Writer.push_back(Init->getSourceOrder());
-    } else {
-      Writer.push_back(Init->getNumArrayIndices());
-      for (auto *VD : Init->getArrayIndices())
-        Writer.AddDeclRef(VD);
-    }
   }
 
   return Writer.Emit(serialization::DECL_CXX_CTOR_INITIALIZERS);
@@ -5646,10 +5737,12 @@
   Record->push_back(Data.ComputedVisibleConversions);
   Record->push_back(Data.UserProvidedDefaultConstructor);
   Record->push_back(Data.DeclaredSpecialMembers);
-  Record->push_back(Data.ImplicitCopyConstructorHasConstParam);
+  Record->push_back(Data.ImplicitCopyConstructorCanHaveConstParamForVBase);
+  Record->push_back(Data.ImplicitCopyConstructorCanHaveConstParamForNonVBase);
   Record->push_back(Data.ImplicitCopyAssignmentHasConstParam);
   Record->push_back(Data.HasDeclaredCopyConstructorWithConstParam);
   Record->push_back(Data.HasDeclaredCopyAssignmentWithConstParam);
+  Record->push_back(Data.ODRHash);
   // IsLambda bit is already saved.
 
   Record->push_back(Data.NumBases);
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 2146861..190d397 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -86,6 +86,7 @@
     void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
     void VisitDeclaratorDecl(DeclaratorDecl *D);
     void VisitFunctionDecl(FunctionDecl *D);
+    void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D);
     void VisitCXXMethodDecl(CXXMethodDecl *D);
     void VisitCXXConstructorDecl(CXXConstructorDecl *D);
     void VisitCXXDestructorDecl(CXXDestructorDecl *D);
@@ -107,6 +108,7 @@
     void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
     void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
     void VisitUsingDecl(UsingDecl *D);
+    void VisitUsingPackDecl(UsingPackDecl *D);
     void VisitUsingShadowDecl(UsingShadowDecl *D);
     void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
     void VisitLinkageSpecDecl(LinkageSpecDecl *D);
@@ -367,6 +369,7 @@
   Record.push_back(D->isModed());
   if (D->isModed())
     Record.AddTypeRef(D->getUnderlyingType());
+  Record.AddDeclRef(D->getAnonDeclWithTypedefName(false));
 }
 
 void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
@@ -518,6 +521,7 @@
   Record.push_back((int)D->SClass); // FIXME: stable encoding
   Record.push_back(D->IsInline);
   Record.push_back(D->IsInlineSpecified);
+  Record.push_back(D->IsExplicitSpecified);
   Record.push_back(D->IsVirtualAsWritten);
   Record.push_back(D->IsPure);
   Record.push_back(D->HasInheritedPrototype);
@@ -528,6 +532,7 @@
   Record.push_back(D->IsExplicitlyDefaulted);
   Record.push_back(D->HasImplicitReturnZero);
   Record.push_back(D->IsConstexpr);
+  Record.push_back(D->UsesSEHTry);
   Record.push_back(D->HasSkippedBody);
   Record.push_back(D->IsLateTemplateParsed);
   Record.push_back(D->getLinkageInternal());
@@ -605,6 +610,11 @@
   Code = serialization::DECL_FUNCTION;
 }
 
+void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
+  VisitFunctionDecl(D);
+  Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
+}
+
 void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
   VisitNamedDecl(D);
   // FIXME: convert to LazyStmtPtr?
@@ -804,7 +814,6 @@
 
 void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
   VisitObjCImplDecl(D);
-  Record.AddIdentifierRef(D->getIdentifier());
   Record.AddSourceLocation(D->getCategoryNameLoc());
   Code = serialization::DECL_OBJC_CATEGORY_IMPL;
 }
@@ -1142,6 +1151,15 @@
   Code = serialization::DECL_USING;
 }
 
+void ASTDeclWriter::VisitUsingPackDecl(UsingPackDecl *D) {
+  Record.push_back(D->NumExpansions);
+  VisitNamedDecl(D);
+  Record.AddDeclRef(D->getInstantiatedFromUsingDecl());
+  for (auto *E : D->expansions())
+    Record.AddDeclRef(E);
+  Code = serialization::DECL_USING_PACK;
+}
+
 void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
   VisitRedeclarable(D);
   VisitNamedDecl(D);
@@ -1175,6 +1193,7 @@
   Record.AddSourceLocation(D->getUsingLoc());
   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
   Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
+  Record.AddSourceLocation(D->getEllipsisLoc());
   Code = serialization::DECL_UNRESOLVED_USING_VALUE;
 }
 
@@ -1183,6 +1202,7 @@
   VisitTypeDecl(D);
   Record.AddSourceLocation(D->getTypenameLoc());
   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
+  Record.AddSourceLocation(D->getEllipsisLoc());
   Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
 }
 
@@ -1255,8 +1275,6 @@
 
   VisitCXXMethodDecl(D);
 
-  Record.push_back(D->IsExplicitSpecified);
-
   Code = D->isInheritingConstructor()
              ? serialization::DECL_CXX_INHERITED_CONSTRUCTOR
              : serialization::DECL_CXX_CONSTRUCTOR;
@@ -1272,7 +1290,6 @@
 
 void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
   VisitCXXMethodDecl(D);
-  Record.push_back(D->IsExplicitSpecified);
   Code = serialization::DECL_CXX_CONVERSION;
 }
 
@@ -1690,10 +1707,10 @@
 void ASTWriter::WriteDeclAbbrevs() {
   using namespace llvm;
 
-  BitCodeAbbrev *Abv;
+  std::shared_ptr<BitCodeAbbrev> Abv;
 
   // Abbreviation for DECL_FIELD
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD));
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
@@ -1723,10 +1740,10 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
-  DeclFieldAbbrev = Stream.EmitAbbrev(Abv);
+  DeclFieldAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for DECL_OBJC_IVAR
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_OBJC_IVAR));
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
@@ -1759,10 +1776,10 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
-  DeclObjCIvarAbbrev = Stream.EmitAbbrev(Abv);
+  DeclObjCIvarAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for DECL_ENUM
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
   // Redeclarable
   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
@@ -1808,10 +1825,10 @@
   // DC
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
-  DeclEnumAbbrev = Stream.EmitAbbrev(Abv);
+  DeclEnumAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for DECL_RECORD
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
   // Redeclarable
   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
@@ -1852,10 +1869,10 @@
   // DC
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
-  DeclRecordAbbrev = Stream.EmitAbbrev(Abv);
+  DeclRecordAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for DECL_PARM_VAR
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
   // Redeclarable
   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
@@ -1899,10 +1916,10 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
-  DeclParmVarAbbrev = Stream.EmitAbbrev(Abv);
+  DeclParmVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for DECL_TYPEDEF
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
   // Redeclarable
   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
@@ -1928,10 +1945,10 @@
   // TypedefDecl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
-  DeclTypedefAbbrev = Stream.EmitAbbrev(Abv);
+  DeclTypedefAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for DECL_VAR
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
   // Redeclarable
   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
@@ -1977,10 +1994,10 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
-  DeclVarAbbrev = Stream.EmitAbbrev(Abv);
+  DeclVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for DECL_CXX_METHOD
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
   // RedeclarableDecl
   Abv->Add(BitCodeAbbrevOp(0));                         // CanonicalDecl
@@ -2010,6 +2027,7 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitSpecified
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
   Abv->Add(BitCodeAbbrevOp(0));                         // HasInheritedProto
@@ -2020,6 +2038,7 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constexpr
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // UsesSEHTry
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
@@ -2035,10 +2054,10 @@
   //  Add an AbbrevOp for 'size then elements' and use it here.
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
-  DeclCXXMethodAbbrev = Stream.EmitAbbrev(Abv);
+  DeclCXXMethodAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for EXPR_DECL_REF
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
   //Stmt
   //Expr
@@ -2058,10 +2077,10 @@
                            1)); // RefersToEnclosingVariableOrCapture
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
-  DeclRefExprAbbrev = Stream.EmitAbbrev(Abv);
+  DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for EXPR_INTEGER_LITERAL
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
   //Stmt
   //Expr
@@ -2076,10 +2095,10 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
   Abv->Add(BitCodeAbbrevOp(32));                      // Bit Width
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
-  IntegerLiteralAbbrev = Stream.EmitAbbrev(Abv);
+  IntegerLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for EXPR_CHARACTER_LITERAL
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
   //Stmt
   //Expr
@@ -2094,10 +2113,10 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind
-  CharacterLiteralAbbrev = Stream.EmitAbbrev(Abv);
+  CharacterLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for EXPR_IMPLICIT_CAST
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST));
   // Stmt
   // Expr
@@ -2112,17 +2131,17 @@
   Abv->Add(BitCodeAbbrevOp(0)); // PathSize
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind
   // ImplicitCastExpr
-  ExprImplicitCastAbbrev = Stream.EmitAbbrev(Abv);
+  ExprImplicitCastAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-  DeclContextLexicalAbbrev = Stream.EmitAbbrev(Abv);
+  DeclContextLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
-  Abv = new BitCodeAbbrev();
+  Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-  DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv);
+  DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(std::move(Abv));
 }
 
 /// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
@@ -2138,7 +2157,7 @@
 /// relatively painless since they would presumably only do it for top-level
 /// decls.
 static bool isRequiredDecl(const Decl *D, ASTContext &Context,
-                           bool WritingModule) {
+                           bool WritingModule, bool ModularCode) {
   // An ObjCMethodDecl is never considered as "required" because its
   // implementation container always is.
 
@@ -2154,7 +2173,7 @@
     return false;
   }
 
-  return Context.DeclMustBeEmitted(D);
+  return Context.DeclMustBeEmitted(D, ModularCode);
 }
 
 void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
@@ -2198,8 +2217,11 @@
 
   // Note declarations that should be deserialized eagerly so that we can add
   // them to a record in the AST file later.
-  if (isRequiredDecl(D, Context, WritingModule))
+  if (isRequiredDecl(D, Context, WritingModule, false))
     EagerlyDeserializedDecls.push_back(ID);
+  else if (Context.getLangOpts().ModularCodegen && WritingModule &&
+           isRequiredDecl(D, Context, true, true))
+    ModularCodegenDecls.push_back(ID);
 }
 
 void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 46acfad..bade553 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -315,6 +315,11 @@
   llvm_unreachable("unimplemented");
 }
 
+void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
+  // FIXME: Implement coroutine serialization.
+  llvm_unreachable("unimplemented");
+}
+
 void ASTStmtWriter::VisitCoyieldExpr(CoyieldExpr *S) {
   // FIXME: Implement coroutine serialization.
   llvm_unreachable("unimplemented");
@@ -792,6 +797,18 @@
   Code = serialization::EXPR_NO_INIT;
 }
 
+void ASTStmtWriter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
+  VisitExpr(E);
+  Record.AddStmt(E->SubExprs[0]);
+  Record.AddStmt(E->SubExprs[1]);
+  Code = serialization::EXPR_ARRAY_INIT_LOOP;
+}
+
+void ASTStmtWriter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
+  VisitExpr(E);
+  Code = serialization::EXPR_ARRAY_INIT_INDEX;
+}
+
 void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
   VisitExpr(E);
   Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
@@ -1245,10 +1262,6 @@
 void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
   VisitExpr(E);
   Record.push_back(E->NumCaptures);
-  unsigned NumArrayIndexVars = 0;
-  if (E->HasArrayIndexVars)
-    NumArrayIndexVars = E->getArrayIndexStarts()[E->NumCaptures];
-  Record.push_back(NumArrayIndexVars);
   Record.AddSourceRange(E->IntroducerRange);
   Record.push_back(E->CaptureDefault); // FIXME: stable encoding
   Record.AddSourceLocation(E->CaptureDefaultLoc);
@@ -1263,15 +1276,6 @@
     Record.AddStmt(*C);
   }
   
-  // Add array index variables, if any.
-  if (NumArrayIndexVars) {
-    Record.append(E->getArrayIndexStarts(), 
-                  E->getArrayIndexStarts() + E->NumCaptures + 1);
-    VarDecl **ArrayIndexVars = E->getArrayIndexVars();
-    for (unsigned I = 0; I != NumArrayIndexVars; ++I)
-      Record.AddDeclRef(ArrayIndexVars[I]);
-  }
-  
   Code = serialization::EXPR_LAMBDA;
 }
 
@@ -1795,6 +1799,7 @@
 }
 
 void OMPClauseWriter::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) {
+  Record.push_back(C->getCaptureRegion());
   Record.AddStmt(C->getPreInitStmt());
 }
 
@@ -1804,6 +1809,7 @@
 }
 
 void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
+  VisitOMPClauseWithPreInit(C);
   Record.push_back(C->getNameModifier());
   Record.AddSourceLocation(C->getNameModifierLoc());
   Record.AddSourceLocation(C->getColonLoc());
@@ -1817,6 +1823,7 @@
 }
 
 void OMPClauseWriter::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
+  VisitOMPClauseWithPreInit(C);
   Record.AddStmt(C->getNumThreads());
   Record.AddSourceLocation(C->getLParenLoc());
 }
@@ -2065,11 +2072,13 @@
 }
 
 void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
+  VisitOMPClauseWithPreInit(C);
   Record.AddStmt(C->getNumTeams());
   Record.AddSourceLocation(C->getLParenLoc());
 }
 
 void OMPClauseWriter::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) {
+  VisitOMPClauseWithPreInit(C);
   Record.AddStmt(C->getThreadLimit());
   Record.AddSourceLocation(C->getLParenLoc());
 }
@@ -2237,6 +2246,8 @@
   if (isOpenMPLoopBoundSharingDirective(D->getDirectiveKind())) {
     Record.AddStmt(D->getPrevLowerBoundVariable());
     Record.AddStmt(D->getPrevUpperBoundVariable());
+    Record.AddStmt(D->getDistInc());
+    Record.AddStmt(D->getPrevEnsureUpperBound());
   }
   for (auto I : D->counters()) {
     Record.AddStmt(I);
@@ -2538,6 +2549,38 @@
   Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
 }
 
+void ASTStmtWriter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_TARGET_TEAMS_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective(
+    OMPTargetTeamsDistributeDirective *D) {
+  VisitOMPLoopDirective(D);
+  Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForDirective(
+    OMPTargetTeamsDistributeParallelForDirective *D) {
+  VisitOMPLoopDirective(D);
+  Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
+    OMPTargetTeamsDistributeParallelForSimdDirective *D) {
+  VisitOMPLoopDirective(D);
+  Code = serialization::
+      STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective(
+    OMPTargetTeamsDistributeSimdDirective *D) {
+  VisitOMPLoopDirective(D);
+  Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
+}
+
 //===----------------------------------------------------------------------===//
 // ASTWriter Implementation
 //===----------------------------------------------------------------------===//
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index e1765da..141a559 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -24,11 +24,11 @@
 PCHGenerator::PCHGenerator(
     const Preprocessor &PP, StringRef OutputFile, StringRef isysroot,
     std::shared_ptr<PCHBuffer> Buffer,
-    ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
+    ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
     bool AllowASTWithErrors, bool IncludeTimestamps)
     : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
       SemaPtr(nullptr), Buffer(Buffer), Stream(Buffer->Data),
-      Writer(Stream, Extensions, IncludeTimestamps),
+      Writer(Stream, Buffer->Data, Extensions, IncludeTimestamps),
       AllowASTWithErrors(AllowASTWithErrors) {
   Buffer->IsComplete = false;
 }
diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index 9f986d5..6978e7e 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/lib/Serialization/GlobalModuleIndex.cpp
@@ -376,6 +376,15 @@
     /// \brief The set of modules on which this module depends. Each entry is
     /// a module ID.
     SmallVector<unsigned, 4> Dependencies;
+    ASTFileSignature Signature;
+  };
+
+  struct ImportedModuleFileInfo {
+    off_t StoredSize;
+    time_t StoredModTime;
+    ASTFileSignature StoredSignature;
+    ImportedModuleFileInfo(off_t Size, time_t ModTime, ASTFileSignature Sig)
+        : StoredSize(Size), StoredModTime(ModTime), StoredSignature(Sig) {}
   };
 
   /// \brief Builder that generates the global module index file.
@@ -383,12 +392,20 @@
     FileManager &FileMgr;
     const PCHContainerReader &PCHContainerRdr;
 
-    /// \brief Mapping from files to module file information.
+    /// Mapping from files to module file information.
     typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap;
 
-    /// \brief Information about each of the known module files.
+    /// Information about each of the known module files.
     ModuleFilesMap ModuleFiles;
 
+    /// \brief Mapping from the imported module file to the imported
+    /// information.
+    typedef std::multimap<const FileEntry *, ImportedModuleFileInfo>
+        ImportedModuleFilesMap;
+
+    /// \brief Information about each importing of a module file.
+    ImportedModuleFilesMap ImportedModuleFiles;
+
     /// \brief Mapping from identifiers to the list of module file IDs that
     /// consider this identifier to be interesting.
     typedef llvm::StringMap<SmallVector<unsigned, 2> > InterestingIdentifierMap;
@@ -424,7 +441,8 @@
     bool loadModuleFile(const FileEntry *File);
 
     /// \brief Write the index to the given bitstream.
-    void writeIndex(llvm::BitstreamWriter &Stream);
+    /// \returns true if an error occurred, false otherwise.
+    bool writeIndex(llvm::BitstreamWriter &Stream);
   };
 }
 
@@ -515,7 +533,7 @@
   unsigned ID = getModuleFileInfo(File).ID;
 
   // Search for the blocks and records we care about.
-  enum { Other, ControlBlock, ASTBlock } State = Other;
+  enum { Other, ControlBlock, ASTBlock, DiagnosticOptionsBlock } State = Other;
   bool Done = false;
   while (!Done) {
     llvm::BitstreamEntry Entry = InStream.advance();
@@ -553,6 +571,15 @@
         continue;
       }
 
+      if (Entry.ID == UNHASHED_CONTROL_BLOCK_ID) {
+        if (InStream.EnterSubBlock(UNHASHED_CONTROL_BLOCK_ID))
+          return true;
+
+        // Found the Diagnostic Options block.
+        State = DiagnosticOptionsBlock;
+        continue;
+      }
+
       if (InStream.SkipBlock())
         return true;
 
@@ -587,7 +614,10 @@
 
         // Skip the stored signature.
         // FIXME: we could read the signature out of the import and validate it.
-        Idx++;
+        ASTFileSignature StoredSignature = {
+            {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++]}}};
 
         // Retrieve the imported file name.
         unsigned Length = Record[Idx++];
@@ -599,11 +629,16 @@
         const FileEntry *DependsOnFile
           = FileMgr.getFile(ImportedFile, /*openFile=*/false,
                             /*cacheFailure=*/false);
-        if (!DependsOnFile ||
-            (StoredSize != DependsOnFile->getSize()) ||
-            (StoredModTime != DependsOnFile->getModificationTime()))
+
+        if (!DependsOnFile)
           return true;
 
+        // Save the information in ImportedModuleFileInfo so we can verify after
+        // loading all pcms.
+        ImportedModuleFiles.insert(std::make_pair(
+            DependsOnFile, ImportedModuleFileInfo(StoredSize, StoredModTime,
+                                                  StoredSignature)));
+
         // Record the dependency.
         unsigned DependsOnID = getModuleFileInfo(DependsOnFile).ID;
         getModuleFileInfo(File).Dependencies.push_back(DependsOnID);
@@ -632,6 +667,12 @@
       }
     }
 
+    // Get Signature.
+    if (State == DiagnosticOptionsBlock && Code == SIGNATURE)
+      getModuleFileInfo(File).Signature = {
+          {{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2],
+            (uint32_t)Record[3], (uint32_t)Record[4]}}};
+
     // We don't care about this record.
   }
 
@@ -680,7 +721,20 @@
 
 }
 
-void GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
+bool GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
+  for (auto MapEntry : ImportedModuleFiles) {
+    auto *File = MapEntry.first;
+    ImportedModuleFileInfo &Info = MapEntry.second;
+    if (getModuleFileInfo(File).Signature) {
+      if (getModuleFileInfo(File).Signature != Info.StoredSignature)
+        // Verify Signature.
+        return true;
+    } else if (Info.StoredSize != File->getSize() ||
+               Info.StoredModTime != File->getModificationTime())
+      // Verify Size and ModTime.
+      return true;
+  }
+
   using namespace llvm;
   
   // Emit the file header.
@@ -744,11 +798,11 @@
     }
 
     // Create a blob abbreviation
-    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+    auto Abbrev = std::make_shared<BitCodeAbbrev>();
     Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_INDEX));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-    unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev);
+    unsigned IDTableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
     // Write the identifier table
     uint64_t Record[] = {IDENTIFIER_INDEX, BucketOffset};
@@ -756,6 +810,7 @@
   }
 
   Stream.ExitBlock();
+  return false;
 }
 
 GlobalModuleIndex::ErrorCode
@@ -816,7 +871,8 @@
   SmallVector<char, 16> OutputBuffer;
   {
     llvm::BitstreamWriter OutputStream(OutputBuffer);
-    Builder.writeIndex(OutputStream);
+    if (Builder.writeIndex(OutputStream))
+      return EC_IOError;
   }
 
   // Write the global index file to a temporary file.
diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp
index 72b0861..5a44d26 100644
--- a/lib/Serialization/Module.cpp
+++ b/lib/Serialization/Module.cpp
@@ -19,28 +19,6 @@
 using namespace serialization;
 using namespace reader;
 
-ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation)
-  : Kind(Kind), File(nullptr), Signature(0), DirectlyImported(false),
-    Generation(Generation), SizeInBits(0),
-    LocalNumSLocEntries(0), SLocEntryBaseID(0),
-    SLocEntryBaseOffset(0), SLocEntryOffsets(nullptr),
-    LocalNumIdentifiers(0),
-    IdentifierOffsets(nullptr), BaseIdentifierID(0),
-    IdentifierTableData(nullptr), IdentifierLookupTable(nullptr),
-    LocalNumMacros(0), MacroOffsets(nullptr),
-    BasePreprocessedEntityID(0),
-    PreprocessedEntityOffsets(nullptr), NumPreprocessedEntities(0),
-    LocalNumHeaderFileInfos(0), 
-    HeaderFileInfoTableData(nullptr), HeaderFileInfoTable(nullptr),
-    LocalNumSubmodules(0), BaseSubmoduleID(0),
-    LocalNumSelectors(0), SelectorOffsets(nullptr), BaseSelectorID(0),
-    SelectorLookupTableData(nullptr), SelectorLookupTable(nullptr),
-    LocalNumDecls(0), DeclOffsets(nullptr), BaseDeclID(0),
-    FileSortedDecls(nullptr), NumFileSortedDecls(0),
-    ObjCCategoriesMap(nullptr), LocalNumObjCCategoriesInMap(0),
-    LocalNumTypes(0), TypeOffsets(nullptr), BaseTypeIndex(0)
-{}
-
 ModuleFile::~ModuleFile() {
   delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
   delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index 722b547..f0654fc 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/lib/Serialization/ModuleManager.cpp
@@ -27,7 +27,7 @@
 using namespace clang;
 using namespace serialization;
 
-ModuleFile *ModuleManager::lookup(StringRef Name) {
+ModuleFile *ModuleManager::lookup(StringRef Name) const {
   const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,
                                            /*cacheFailure=*/false);
   if (Entry)
@@ -36,9 +36,8 @@
   return nullptr;
 }
 
-ModuleFile *ModuleManager::lookup(const FileEntry *File) {
-  llvm::DenseMap<const FileEntry *, ModuleFile *>::iterator Known
-    = Modules.find(File);
+ModuleFile *ModuleManager::lookup(const FileEntry *File) const {
+  auto Known = Modules.find(File);
   if (Known == Modules.end())
     return nullptr;
 
@@ -52,6 +51,30 @@
   return std::move(InMemoryBuffers[Entry]);
 }
 
+static bool checkSignature(ASTFileSignature Signature,
+                           ASTFileSignature ExpectedSignature,
+                           std::string &ErrorStr) {
+  if (!ExpectedSignature || Signature == ExpectedSignature)
+    return false;
+
+  ErrorStr =
+      Signature ? "signature mismatch" : "could not read module signature";
+  return true;
+}
+
+static void updateModuleImports(ModuleFile &MF, ModuleFile *ImportedBy,
+                                SourceLocation ImportLoc) {
+  if (ImportedBy) {
+    MF.ImportedBy.insert(ImportedBy);
+    ImportedBy->Imports.insert(&MF);
+  } else {
+    if (!MF.DirectlyImported)
+      MF.ImportLoc = ImportLoc;
+
+    MF.DirectlyImported = true;
+  }
+}
+
 ModuleManager::AddModuleResult
 ModuleManager::addModule(StringRef FileName, ModuleKind Type,
                          SourceLocation ImportLoc, ModuleFile *ImportedBy,
@@ -84,141 +107,126 @@
   }
 
   // Check whether we already loaded this module, before
-  ModuleFile *ModuleEntry = Modules[Entry];
-  bool NewModule = false;
-  if (!ModuleEntry) {
-    // Allocate a new module.
-    NewModule = true;
-    ModuleEntry = new ModuleFile(Type, Generation);
-    ModuleEntry->Index = Chain.size();
-    ModuleEntry->FileName = FileName.str();
-    ModuleEntry->File = Entry;
-    ModuleEntry->ImportLoc = ImportLoc;
-    ModuleEntry->InputFilesValidationTimestamp = 0;
-
-    if (ModuleEntry->Kind == MK_ImplicitModule) {
-      std::string TimestampFilename = ModuleEntry->getTimestampFilename();
-      vfs::Status Status;
-      // A cached stat value would be fine as well.
-      if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
-        ModuleEntry->InputFilesValidationTimestamp =
-            llvm::sys::toTimeT(Status.getLastModificationTime());
-    }
-
-    // Load the contents of the module
-    if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
-      // The buffer was already provided for us.
-      ModuleEntry->Buffer = std::move(Buffer);
-    } else {
-      // Open the AST file.
-      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf(
-          (std::error_code()));
-      if (FileName == "-") {
-        Buf = llvm::MemoryBuffer::getSTDIN();
-      } else {
-        // Leave the FileEntry open so if it gets read again by another
-        // ModuleManager it must be the same underlying file.
-        // FIXME: Because FileManager::getFile() doesn't guarantee that it will
-        // give us an open file, this may not be 100% reliable.
-        Buf = FileMgr.getBufferForFile(ModuleEntry->File,
-                                       /*IsVolatile=*/false,
-                                       /*ShouldClose=*/false);
-      }
-
-      if (!Buf) {
-        ErrorStr = Buf.getError().message();
-        delete ModuleEntry;
-        return Missing;
-      }
-
-      ModuleEntry->Buffer = std::move(*Buf);
-    }
-
-    // Initialize the stream.
-    ModuleEntry->Data = PCHContainerRdr.ExtractPCH(*ModuleEntry->Buffer);
-  }
-
-  if (ExpectedSignature) {
-    // If we've not read the control block yet, read the signature eagerly now
-    // so that we can check it.
-    if (!ModuleEntry->Signature)
-      ModuleEntry->Signature = ReadSignature(ModuleEntry->Data);
-
-    if (ModuleEntry->Signature != ExpectedSignature) {
-      ErrorStr = ModuleEntry->Signature ? "signature mismatch"
-                                        : "could not read module signature";
-
-      if (NewModule)
-        delete ModuleEntry;
+  if (ModuleFile *ModuleEntry = Modules.lookup(Entry)) {
+    // Check the stored signature.
+    if (checkSignature(ModuleEntry->Signature, ExpectedSignature, ErrorStr))
       return OutOfDate;
-    }
-  }
 
-  if (ImportedBy) {
-    ModuleEntry->ImportedBy.insert(ImportedBy);
-    ImportedBy->Imports.insert(ModuleEntry);
-  } else {
-    if (!ModuleEntry->DirectlyImported)
-      ModuleEntry->ImportLoc = ImportLoc;
-    
-    ModuleEntry->DirectlyImported = true;
-  }
-
-  Module = ModuleEntry;
-
-  if (!NewModule)
+    Module = ModuleEntry;
+    updateModuleImports(*ModuleEntry, ImportedBy, ImportLoc);
     return AlreadyLoaded;
+  }
 
-  assert(!Modules[Entry] && "module loaded twice");
-  Modules[Entry] = ModuleEntry;
+  // Allocate a new module.
+  auto NewModule = llvm::make_unique<ModuleFile>(Type, Generation);
+  NewModule->Index = Chain.size();
+  NewModule->FileName = FileName.str();
+  NewModule->File = Entry;
+  NewModule->ImportLoc = ImportLoc;
+  NewModule->InputFilesValidationTimestamp = 0;
 
-  Chain.push_back(ModuleEntry);
-  if (!ModuleEntry->isModule())
-    PCHChain.push_back(ModuleEntry);
+  if (NewModule->Kind == MK_ImplicitModule) {
+    std::string TimestampFilename = NewModule->getTimestampFilename();
+    vfs::Status Status;
+    // A cached stat value would be fine as well.
+    if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
+      NewModule->InputFilesValidationTimestamp =
+          llvm::sys::toTimeT(Status.getLastModificationTime());
+  }
+
+  // Load the contents of the module
+  if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
+    // The buffer was already provided for us.
+    NewModule->Buffer = std::move(Buffer);
+  } else {
+    // Open the AST file.
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code()));
+    if (FileName == "-") {
+      Buf = llvm::MemoryBuffer::getSTDIN();
+    } else {
+      // Leave the FileEntry open so if it gets read again by another
+      // ModuleManager it must be the same underlying file.
+      // FIXME: Because FileManager::getFile() doesn't guarantee that it will
+      // give us an open file, this may not be 100% reliable.
+      Buf = FileMgr.getBufferForFile(NewModule->File,
+                                     /*IsVolatile=*/false,
+                                     /*ShouldClose=*/false);
+    }
+
+    if (!Buf) {
+      ErrorStr = Buf.getError().message();
+      return Missing;
+    }
+
+    NewModule->Buffer = std::move(*Buf);
+  }
+
+  // Initialize the stream.
+  NewModule->Data = PCHContainerRdr.ExtractPCH(*NewModule->Buffer);
+
+  // Read the signature eagerly now so that we can check it.  Avoid calling
+  // ReadSignature unless there's something to check though.
+  if (ExpectedSignature && checkSignature(ReadSignature(NewModule->Data),
+                                          ExpectedSignature, ErrorStr))
+    return OutOfDate;
+
+  // We're keeping this module.  Store it everywhere.
+  Module = Modules[Entry] = NewModule.get();
+
+  updateModuleImports(*NewModule, ImportedBy, ImportLoc);
+
+  if (!NewModule->isModule())
+    PCHChain.push_back(NewModule.get());
   if (!ImportedBy)
-    Roots.push_back(ModuleEntry);
+    Roots.push_back(NewModule.get());
 
+  Chain.push_back(std::move(NewModule));
   return NewlyLoaded;
 }
 
 void ModuleManager::removeModules(
-    ModuleIterator first, ModuleIterator last,
+    ModuleIterator First,
     llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
     ModuleMap *modMap) {
-  if (first == last)
+  auto Last = end();
+  if (First == Last)
     return;
 
+
   // Explicitly clear VisitOrder since we might not notice it is stale.
   VisitOrder.clear();
 
   // Collect the set of module file pointers that we'll be removing.
-  llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last);
+  llvm::SmallPtrSet<ModuleFile *, 4> victimSet(
+      (llvm::pointer_iterator<ModuleIterator>(First)),
+      (llvm::pointer_iterator<ModuleIterator>(Last)));
 
   auto IsVictim = [&](ModuleFile *MF) {
     return victimSet.count(MF);
   };
   // Remove any references to the now-destroyed modules.
-  for (unsigned i = 0, n = Chain.size(); i != n; ++i) {
-    Chain[i]->ImportedBy.remove_if(IsVictim);
+  for (auto I = begin(); I != First; ++I) {
+    I->Imports.remove_if(IsVictim);
+    I->ImportedBy.remove_if(IsVictim);
   }
   Roots.erase(std::remove_if(Roots.begin(), Roots.end(), IsVictim),
               Roots.end());
 
   // Remove the modules from the PCH chain.
-  for (auto I = first; I != last; ++I) {
-    if (!(*I)->isModule()) {
-      PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), *I),
+  for (auto I = First; I != Last; ++I) {
+    if (!I->isModule()) {
+      PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), &*I),
                      PCHChain.end());
       break;
     }
   }
 
   // Delete the modules and erase them from the various structures.
-  for (ModuleIterator victim = first; victim != last; ++victim) {
-    Modules.erase((*victim)->File);
+  for (ModuleIterator victim = First; victim != Last; ++victim) {
+    Modules.erase(victim->File);
 
     if (modMap) {
-      StringRef ModuleName = (*victim)->ModuleName;
+      StringRef ModuleName = victim->ModuleName;
       if (Module *mod = modMap->findModule(ModuleName)) {
         mod->setASTFile(nullptr);
       }
@@ -227,14 +235,12 @@
     // 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;
+    if (LoadedSuccessfully.count(&*victim) == 0)
+      FileMgr.invalidateCache(victim->File);
   }
 
-  // Remove the modules from the chain.
-  Chain.erase(first, last);
+  // Delete the modules.
+  Chain.erase(Chain.begin() + (First - begin()), Chain.end());
 }
 
 void
@@ -274,11 +280,9 @@
 
   // Notify the global module index about all of the modules we've already
   // loaded.
-  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
-    if (!GlobalIndex->loadedModuleFile(Chain[I])) {
-      ModulesInCommonWithGlobalIndex.push_back(Chain[I]);
-    }
-  }
+  for (ModuleFile &M : *this)
+    if (!GlobalIndex->loadedModuleFile(&M))
+      ModulesInCommonWithGlobalIndex.push_back(&M);
 }
 
 void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
@@ -293,11 +297,7 @@
     : FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr), GlobalIndex(),
       FirstVisitState(nullptr) {}
 
-ModuleManager::~ModuleManager() {
-  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
-    delete Chain[e - i - 1];
-  delete FirstVisitState;
-}
+ModuleManager::~ModuleManager() { delete FirstVisitState; }
 
 void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
                           llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {
@@ -314,11 +314,11 @@
     Queue.reserve(N);
     llvm::SmallVector<unsigned, 4> UnusedIncomingEdges;
     UnusedIncomingEdges.resize(size());
-    for (ModuleFile *M : llvm::reverse(*this)) {
-      unsigned Size = M->ImportedBy.size();
-      UnusedIncomingEdges[M->Index] = Size;
+    for (ModuleFile &M : llvm::reverse(*this)) {
+      unsigned Size = M.ImportedBy.size();
+      UnusedIncomingEdges[M.Index] = Size;
       if (!Size)
-        Queue.push_back(M);
+        Queue.push_back(&M);
     }
 
     // Traverse the graph, making sure to visit a module before visiting any
@@ -433,7 +433,7 @@
   struct GraphTraits<ModuleManager> {
     typedef ModuleFile *NodeRef;
     typedef llvm::SetVector<ModuleFile *>::const_iterator ChildIteratorType;
-    typedef ModuleManager::ModuleConstIterator nodes_iterator;
+    typedef pointer_iterator<ModuleManager::ModuleConstIterator> nodes_iterator;
 
     static ChildIteratorType child_begin(NodeRef Node) {
       return Node->Imports.begin();
@@ -444,11 +444,11 @@
     }
     
     static nodes_iterator nodes_begin(const ModuleManager &Manager) {
-      return Manager.begin();
+      return nodes_iterator(Manager.begin());
     }
     
     static nodes_iterator nodes_end(const ModuleManager &Manager) {
-      return Manager.end();
+      return nodes_iterator(Manager.end());
     }
   };
   
diff --git a/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
index 082a487..d19630e 100644
--- a/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
@@ -29,7 +29,9 @@
 class BlockInCriticalSectionChecker : public Checker<check::PostCall,
                                                      check::PreCall> {
 
-  CallDescription LockFn, UnlockFn, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn;
+  CallDescription LockFn, UnlockFn, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn,
+                  PthreadLockFn, PthreadTryLockFn, PthreadUnlockFn,
+                  MtxLock, MtxTimedLock, MtxTryLock, MtxUnlock;
 
   std::unique_ptr<BugType> BlockInCritSectionBugType;
 
@@ -40,6 +42,10 @@
 public:
   BlockInCriticalSectionChecker();
 
+  bool isBlockingFunction(const CallEvent &Call) const;
+  bool isLockFunction(const CallEvent &Call) const;
+  bool isUnlockFunction(const CallEvent &Call) const;
+
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
 
   /// Process unlock.
@@ -55,34 +61,69 @@
 
 BlockInCriticalSectionChecker::BlockInCriticalSectionChecker()
     : LockFn("lock"), UnlockFn("unlock"), SleepFn("sleep"), GetcFn("getc"),
-      FgetsFn("fgets"), ReadFn("read"), RecvFn("recv") {
+      FgetsFn("fgets"), ReadFn("read"), RecvFn("recv"),
+      PthreadLockFn("pthread_mutex_lock"),
+      PthreadTryLockFn("pthread_mutex_trylock"),
+      PthreadUnlockFn("pthread_mutex_unlock"),
+      MtxLock("mtx_lock"),
+      MtxTimedLock("mtx_timedlock"),
+      MtxTryLock("mtx_trylock"),
+      MtxUnlock("mtx_unlock") {
   // Initialize the bug type.
   BlockInCritSectionBugType.reset(
       new BugType(this, "Call to blocking function in critical section",
                         "Blocking Error"));
 }
 
+bool BlockInCriticalSectionChecker::isBlockingFunction(const CallEvent &Call) const {
+  if (Call.isCalled(SleepFn)
+      || Call.isCalled(GetcFn)
+      || Call.isCalled(FgetsFn)
+      || Call.isCalled(ReadFn)
+      || Call.isCalled(RecvFn)) {
+    return true;
+  }
+  return false;
+}
+
+bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) const {
+  if (Call.isCalled(LockFn)
+      || Call.isCalled(PthreadLockFn)
+      || Call.isCalled(PthreadTryLockFn)
+      || Call.isCalled(MtxLock)
+      || Call.isCalled(MtxTimedLock)
+      || Call.isCalled(MtxTryLock)) {
+    return true;
+  }
+  return false;
+}
+
+bool BlockInCriticalSectionChecker::isUnlockFunction(const CallEvent &Call) const {
+  if (Call.isCalled(UnlockFn)
+       || Call.isCalled(PthreadUnlockFn)
+       || Call.isCalled(MtxUnlock)) {
+    return true;
+  }
+  return false;
+}
+
 void BlockInCriticalSectionChecker::checkPreCall(const CallEvent &Call,
                                                  CheckerContext &C) const {
 }
 
 void BlockInCriticalSectionChecker::checkPostCall(const CallEvent &Call,
                                                   CheckerContext &C) const {
-  if (!Call.isCalled(LockFn)
-      && !Call.isCalled(SleepFn)
-      && !Call.isCalled(GetcFn)
-      && !Call.isCalled(FgetsFn)
-      && !Call.isCalled(ReadFn)
-      && !Call.isCalled(RecvFn)
-      && !Call.isCalled(UnlockFn))
+  if (!isBlockingFunction(Call)
+      && !isLockFunction(Call)
+      && !isUnlockFunction(Call))
     return;
 
   ProgramStateRef State = C.getState();
   unsigned mutexCount = State->get<MutexCounter>();
-  if (Call.isCalled(UnlockFn) && mutexCount > 0) {
+  if (isUnlockFunction(Call) && mutexCount > 0) {
     State = State->set<MutexCounter>(--mutexCount);
     C.addTransition(State);
-  } else if (Call.isCalled(LockFn)) {
+  } else if (isLockFunction(Call)) {
     State = State->set<MutexCounter>(++mutexCount);
     C.addTransition(State);
   } else if (mutexCount > 0) {
@@ -97,8 +138,11 @@
   if (!ErrNode)
     return;
 
-  auto R = llvm::make_unique<BugReport>(*BlockInCritSectionBugType,
-      "A blocking function %s is called inside a critical section.", ErrNode);
+  std::string msg;
+  llvm::raw_string_ostream os(msg);
+  os << "Call to blocking function '" << Call.getCalleeIdentifier()->getName()
+     << "' inside of critical section";
+  auto R = llvm::make_unique<BugReport>(*BlockInCritSectionBugType, os.str(), ErrNode);
   R->addRange(Call.getSourceRange());
   R->markInteresting(BlockDescSym);
   C.emitReport(std::move(R));
diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 6996cdb..05505ec 100644
--- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -37,7 +37,9 @@
   ExprInspectionChecker.cpp
   FixedAddressChecker.cpp
   GenericTaintChecker.cpp
+  GTestChecker.cpp
   IdenticalExprChecker.cpp
+  IteratorPastEndChecker.cpp
   IvarInvalidationChecker.cpp
   LLVMConventionsChecker.cpp
   LocalizationChecker.cpp
@@ -59,6 +61,7 @@
   ObjCContainersASTChecker.cpp
   ObjCContainersChecker.cpp
   ObjCMissingSuperCallChecker.cpp
+  ObjCPropertyChecker.cpp
   ObjCSelfInitChecker.cpp
   ObjCSuperDeallocChecker.cpp
   ObjCUnusedIVarsChecker.cpp
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 238032c8..32e3ce9 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -68,6 +68,7 @@
                        const InvalidatedSymbols *,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) const;
 
   typedef void (CStringChecker::*FnCheck)(CheckerContext &,
@@ -1943,8 +1944,12 @@
     // Overwrite the search string pointer. The new value is either an address
     // further along in the same string, or NULL if there are no more tokens.
     State = State->bindLoc(*SearchStrLoc,
-                           SVB.conjureSymbolVal(getTag(), CE, LCtx, CharPtrTy,
-                                                C.blockCount()));
+                           SVB.conjureSymbolVal(getTag(),
+                                                CE,
+                                                LCtx,
+                                                CharPtrTy,
+                                                C.blockCount()),
+                           LCtx);
   } else {
     assert(SearchStrVal.isUnknown());
     // Conjure a symbolic value. It's the best we can do.
@@ -2116,6 +2121,7 @@
                                    const InvalidatedSymbols *,
                                    ArrayRef<const MemRegion *> ExplicitRegions,
                                    ArrayRef<const MemRegion *> Regions,
+                                   const LocationContext *LCtx,
                                    const CallEvent *Call) const {
   CStringLengthTy Entries = state->get<CStringLength>();
   if (Entries.isEmpty())
diff --git a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
index 3db1994..391b843 100644
--- a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
@@ -36,25 +36,24 @@
   AnalysisDeclContext* AC;
 
   /// Check if two expressions refer to the same declaration.
-  inline bool sameDecl(const Expr *A1, const Expr *A2) {
-    if (const DeclRefExpr *D1 = dyn_cast<DeclRefExpr>(A1->IgnoreParenCasts()))
-      if (const DeclRefExpr *D2 = dyn_cast<DeclRefExpr>(A2->IgnoreParenCasts()))
+  bool sameDecl(const Expr *A1, const Expr *A2) {
+    if (const auto *D1 = dyn_cast<DeclRefExpr>(A1->IgnoreParenCasts()))
+      if (const auto *D2 = dyn_cast<DeclRefExpr>(A2->IgnoreParenCasts()))
         return D1->getDecl() == D2->getDecl();
     return false;
   }
 
   /// Check if the expression E is a sizeof(WithArg).
-  inline bool isSizeof(const Expr *E, const Expr *WithArg) {
-    if (const UnaryExprOrTypeTraitExpr *UE =
-    dyn_cast<UnaryExprOrTypeTraitExpr>(E))
-      if (UE->getKind() == UETT_SizeOf)
+  bool isSizeof(const Expr *E, const Expr *WithArg) {
+    if (const auto *UE = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
+      if (UE->getKind() == UETT_SizeOf && !UE->isArgumentType())
         return sameDecl(UE->getArgumentExpr(), WithArg);
     return false;
   }
 
   /// Check if the expression E is a strlen(WithArg).
-  inline bool isStrlen(const Expr *E, const Expr *WithArg) {
-    if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+  bool isStrlen(const Expr *E, const Expr *WithArg) {
+    if (const auto *CE = dyn_cast<CallExpr>(E)) {
       const FunctionDecl *FD = CE->getDirectCallee();
       if (!FD)
         return false;
@@ -65,14 +64,14 @@
   }
 
   /// Check if the expression is an integer literal with value 1.
-  inline bool isOne(const Expr *E) {
-    if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E))
+  bool isOne(const Expr *E) {
+    if (const auto *IL = dyn_cast<IntegerLiteral>(E))
       return (IL->getValue().isIntN(1));
     return false;
   }
 
-  inline StringRef getPrintableName(const Expr *E) {
-    if (const DeclRefExpr *D = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
+  StringRef getPrintableName(const Expr *E) {
+    if (const auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
       return D->getDecl()->getName();
     return StringRef();
   }
@@ -82,8 +81,8 @@
   bool containsBadStrncatPattern(const CallExpr *CE);
 
 public:
-  WalkAST(const CheckerBase *checker, BugReporter &br, AnalysisDeclContext *ac)
-      : Checker(checker), BR(br), AC(ac) {}
+  WalkAST(const CheckerBase *Checker, BugReporter &BR, AnalysisDeclContext *AC)
+      : Checker(Checker), BR(BR), AC(AC) {}
 
   // Statement visitor methods.
   void VisitChildren(Stmt *S);
@@ -108,8 +107,7 @@
   const Expr *LenArg = CE->getArg(2);
 
   // Identify wrong size expressions, which are commonly used instead.
-  if (const BinaryOperator *BE =
-              dyn_cast<BinaryOperator>(LenArg->IgnoreParenCasts())) {
+  if (const auto *BE = dyn_cast<BinaryOperator>(LenArg->IgnoreParenCasts())) {
     // - sizeof(dst) - strlen(dst)
     if (BE->getOpcode() == BO_Sub) {
       const Expr *L = BE->getLHS();
diff --git a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
index 7631322..668e772 100644
--- a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
@@ -51,9 +51,9 @@
       State->getSVal(SVB.getCXXThis(MD, LCtx->getCurrentStackFrame()));
   auto Param = SVB.makeLoc(State->getRegion(MD->getParamDecl(0), LCtx));
   auto ParamVal = State->getSVal(Param);
-  ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal);
+  ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal, LCtx);
   C.addTransition(SelfAssignState);
-  ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal);
+  ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal, LCtx);
   C.addTransition(NonSelfAssignState);
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index f474857..07285d2 100644
--- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -21,6 +21,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -71,7 +72,7 @@
 
 private:
   bool PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange ArgRange,
-                          const Expr *ArgEx, bool IsFirstArgument,
+                          const Expr *ArgEx, int ArgumentNumber,
                           bool CheckUninitFields, const CallEvent &Call,
                           std::unique_ptr<BugType> &BT,
                           const ParmVarDecl *ParamDecl) const;
@@ -89,9 +90,10 @@
       BT.reset(new BuiltinBug(this, desc));
   }
   bool uninitRefOrPointer(CheckerContext &C, const SVal &V,
-                          SourceRange ArgRange,
-                          const Expr *ArgEx, std::unique_ptr<BugType> &BT,
-                          const ParmVarDecl *ParamDecl, const char *BD) const;
+                          SourceRange ArgRange, const Expr *ArgEx,
+                          std::unique_ptr<BugType> &BT,
+                          const ParmVarDecl *ParamDecl, const char *BD,
+                          int ArgumentNumber) const;
 };
 } // end anonymous namespace
 
@@ -111,38 +113,45 @@
   C.emitReport(std::move(R));
 }
 
-static StringRef describeUninitializedArgumentInCall(const CallEvent &Call,
-                                                     bool IsFirstArgument) {
+static void describeUninitializedArgumentInCall(const CallEvent &Call,
+                                                int ArgumentNumber,
+                                                llvm::raw_svector_ostream &Os) {
   switch (Call.getKind()) {
   case CE_ObjCMessage: {
     const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
     switch (Msg.getMessageKind()) {
     case OCM_Message:
-      return "Argument in message expression is an uninitialized value";
+      Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+         << " argument in message expression is an uninitialized value";
+      return;
     case OCM_PropertyAccess:
       assert(Msg.isSetter() && "Getters have no args");
-      return "Argument for property setter is an uninitialized value";
+      Os << "Argument for property setter is an uninitialized value";
+      return;
     case OCM_Subscript:
-      if (Msg.isSetter() && IsFirstArgument)
-        return "Argument for subscript setter is an uninitialized value";
-      return "Subscript index is an uninitialized value";
+      if (Msg.isSetter() && (ArgumentNumber == 0))
+        Os << "Argument for subscript setter is an uninitialized value";
+      else
+        Os << "Subscript index is an uninitialized value";
+      return;
     }
     llvm_unreachable("Unknown message kind.");
   }
   case CE_Block:
-    return "Block call argument is an uninitialized value";
+    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+       << " block call argument is an uninitialized value";
+    return;
   default:
-    return "Function call argument is an uninitialized value";
+    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+       << " function call argument is an uninitialized value";
+    return;
   }
 }
 
-bool CallAndMessageChecker::uninitRefOrPointer(CheckerContext &C,
-                                               const SVal &V,
-                                               SourceRange ArgRange,
-                                               const Expr *ArgEx,
-                                               std::unique_ptr<BugType> &BT,
-                                               const ParmVarDecl *ParamDecl,
-                                               const char *BD) const {
+bool CallAndMessageChecker::uninitRefOrPointer(
+    CheckerContext &C, const SVal &V, SourceRange ArgRange, const Expr *ArgEx,
+    std::unique_ptr<BugType> &BT, const ParmVarDecl *ParamDecl, const char *BD,
+    int ArgumentNumber) const {
   if (!Filter.Check_CallAndMessageUnInitRefArg)
     return false;
 
@@ -153,12 +162,15 @@
   // If parameter is declared as pointer to const in function declaration,
   // then check if corresponding argument in function call is
   // pointing to undefined symbol value (uninitialized memory).
-  StringRef Message;
+  SmallString<200> Buf;
+  llvm::raw_svector_ostream Os(Buf);
 
   if (ParamDecl->getType()->isPointerType()) {
-    Message = "Function call argument is a pointer to uninitialized value";
+    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+       << " function call argument is a pointer to uninitialized value";
   } else if (ParamDecl->getType()->isReferenceType()) {
-    Message = "Function call argument is an uninitialized value";
+    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+       << " function call argument is an uninitialized value";
   } else
     return false;
 
@@ -171,7 +183,7 @@
     if (PSV.isUndef()) {
       if (ExplodedNode *N = C.generateErrorNode()) {
         LazyInit_BT(BD, BT);
-        auto R = llvm::make_unique<BugReport>(*BT, Message, N);
+        auto R = llvm::make_unique<BugReport>(*BT, Os.str(), N);
         R->addRange(ArgRange);
         if (ArgEx) {
           bugreporter::trackNullOrUndefValue(N, ArgEx, *R);
@@ -188,7 +200,7 @@
                                                SVal V,
                                                SourceRange ArgRange,
                                                const Expr *ArgEx,
-                                               bool IsFirstArgument,
+                                               int ArgumentNumber,
                                                bool CheckUninitFields,
                                                const CallEvent &Call,
                                                std::unique_ptr<BugType> &BT,
@@ -196,17 +208,19 @@
                                                ) const {
   const char *BD = "Uninitialized argument value";
 
-  if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD))
+  if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD,
+                         ArgumentNumber))
     return true;
 
   if (V.isUndef()) {
     if (ExplodedNode *N = C.generateErrorNode()) {
       LazyInit_BT(BD, BT);
-
       // Generate a report for this bug.
-      StringRef Desc =
-          describeUninitializedArgumentInCall(Call, IsFirstArgument);
-      auto R = llvm::make_unique<BugReport>(*BT, Desc, N);
+      SmallString<200> Buf;
+      llvm::raw_svector_ostream Os(Buf);
+      describeUninitializedArgumentInCall(Call, ArgumentNumber, Os);
+      auto R = llvm::make_unique<BugReport>(*BT, Os.str(), N);
+
       R->addRange(ArgRange);
       if (ArgEx)
         bugreporter::trackNullOrUndefValue(N, ArgEx, *R);
@@ -435,7 +449,7 @@
     if(FD && i < FD->getNumParams())
       ParamDecl = FD->getParamDecl(i);
     if (PreVisitProcessArg(C, Call.getArgSVal(i), Call.getArgSourceRange(i),
-                           Call.getArgExpr(i), /*IsFirstArgument=*/i == 0,
+                           Call.getArgExpr(i), i,
                            checkUninitFields, Call, *BT, ParamDecl))
       return;
   }
diff --git a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
index 16a475a..65e8131 100644
--- a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
@@ -84,6 +84,10 @@
     if (!VD || VD->getType()->isReferenceType())
       return true;
 
+    if (ToPointeeTy->isIncompleteType() ||
+        OrigPointeeTy->isIncompleteType())
+      return true;
+
     // Warn when there is widening cast.
     unsigned ToWidth = Ctx.getTypeInfo(ToPointeeTy).Width;
     unsigned OrigWidth = Ctx.getTypeInfo(OrigPointeeTy).Width;
diff --git a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
index 86764c9..95b6c4d 100644
--- a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
@@ -231,14 +231,6 @@
   /// check::LiveSymbols
   void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const {}
 
-  /// \brief Called to determine if the checker currently needs to know if when
-  /// contents of any regions change.
-  ///
-  /// Since it is not necessarily cheap to compute which regions are being
-  /// changed, this allows the analyzer core to skip the more expensive
-  /// #checkRegionChanges when no checkers are tracking any state.
-  bool wantsRegionChangeUpdate(ProgramStateRef St) const { return true; }
-
   /// \brief Called when the contents of one or more regions change.
   ///
   /// This can occur in many different ways: an explicit bind, a blanket
@@ -255,18 +247,18 @@
   ///        by this change. For a simple bind, this list will be the same as
   ///        \p ExplicitRegions, since a bind does not affect the contents of
   ///        anything accessible through the base region.
+  /// \param LCtx LocationContext that is useful for getting various contextual
+  ///        info, like callstack, CFG etc.
   /// \param Call The opaque call triggering this invalidation. Will be 0 if the
   ///        change was not triggered by a call.
   ///
-  /// Note that this callback will not be invoked unless
-  /// #wantsRegionChangeUpdate returns \c true.
-  ///
   /// check::RegionChanges
   ProgramStateRef
     checkRegionChanges(ProgramStateRef State,
                        const InvalidatedSymbols *Invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) const {
     return State;
   }
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
index a37ebc5..109897b 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
@@ -49,10 +49,10 @@
       ID.AddPointer(Reg);
     }
 
-    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                   const ExplodedNode *PrevN,
-                                   BugReporterContext &BRC,
-                                   BugReport &BR) override;
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
 
   private:
     // The tracked region.
@@ -91,9 +91,11 @@
   C.emitReport(std::move(R));
 }
 
-PathDiagnosticPiece *DynamicTypeChecker::DynamicTypeBugVisitor::VisitNode(
-    const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
-    BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+DynamicTypeChecker::DynamicTypeBugVisitor::VisitNode(const ExplodedNode *N,
+                                                     const ExplodedNode *PrevN,
+                                                     BugReporterContext &BRC,
+                                                     BugReport &BR) {
   ProgramStateRef State = N->getState();
   ProgramStateRef StatePrev = PrevN->getState();
 
@@ -143,7 +145,8 @@
   // Generate the extra diagnostic.
   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
                              N->getLocationContext());
-  return new PathDiagnosticEventPiece(Pos, OS.str(), true, nullptr);
+  return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(), true,
+                                                    nullptr);
 }
 
 static bool hasDefinition(const ObjCObjectPointerType *ObjPtr) {
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index a418c82..0891ea8 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -83,10 +83,10 @@
       ID.AddPointer(Sym);
     }
 
-    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                   const ExplodedNode *PrevN,
-                                   BugReporterContext &BRC,
-                                   BugReport &BR) override;
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
 
   private:
     // The tracked symbol.
@@ -923,9 +923,11 @@
   C.emitReport(std::move(R));
 }
 
-PathDiagnosticPiece *DynamicTypePropagation::GenericsBugVisitor::VisitNode(
-    const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
-    BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+DynamicTypePropagation::GenericsBugVisitor::VisitNode(const ExplodedNode *N,
+                                                      const ExplodedNode *PrevN,
+                                                      BugReporterContext &BRC,
+                                                      BugReport &BR) {
   ProgramStateRef state = N->getState();
   ProgramStateRef statePrev = PrevN->getState();
 
@@ -975,7 +977,8 @@
   // Generate the extra diagnostic.
   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
                              N->getLocationContext());
-  return new PathDiagnosticEventPiece(Pos, OS.str(), true, nullptr);
+  return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(), true,
+                                                    nullptr);
 }
 
 /// Register checkers.
diff --git a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
index 2d5cb60..32040e7 100644
--- a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -13,6 +13,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Checkers/SValExplainer.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ScopedPrinter.h"
 
 using namespace clang;
 using namespace ento;
@@ -71,8 +72,8 @@
           &ExprInspectionChecker::analyzerWarnIfReached)
     .Case("clang_analyzer_warnOnDeadSymbol",
           &ExprInspectionChecker::analyzerWarnOnDeadSymbol)
-    .Case("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain)
-    .Case("clang_analyzer_dump", &ExprInspectionChecker::analyzerDump)
+    .StartsWith("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain)
+    .StartsWith("clang_analyzer_dump", &ExprInspectionChecker::analyzerDump)
     .Case("clang_analyzer_getExtent", &ExprInspectionChecker::analyzerGetExtent)
     .Case("clang_analyzer_printState",
           &ExprInspectionChecker::analyzerPrintState)
@@ -269,7 +270,7 @@
     unsigned NumTimesReached = Item.second.NumTimesReached;
     ExplodedNode *N = Item.second.ExampleNode;
 
-    reportBug(std::to_string(NumTimesReached), BR, N);
+    reportBug(llvm::to_string(NumTimesReached), BR, N);
   }
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/GTestChecker.cpp b/lib/StaticAnalyzer/Checkers/GTestChecker.cpp
new file mode 100644
index 0000000..f0be41b
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/GTestChecker.cpp
@@ -0,0 +1,299 @@
+//==- GTestChecker.cpp - Model gtest API --*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker models the behavior of un-inlined APIs from the gtest
+// unit-testing library to avoid false positives when using assertions from
+// that library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace ento;
+
+// Modeling of un-inlined AssertionResult constructors
+//
+// The gtest unit testing API provides macros for assertions that expand
+// into an if statement that calls a series of constructors and returns
+// when the "assertion" is false.
+//
+// For example,
+//
+//   ASSERT_TRUE(a == b)
+//
+// expands into:
+//
+//   switch (0)
+//   case 0:
+//   default:
+//     if (const ::testing::AssertionResult gtest_ar_ =
+//             ::testing::AssertionResult((a == b)))
+//       ;
+//     else
+//       return ::testing::internal::AssertHelper(
+//                  ::testing::TestPartResult::kFatalFailure,
+//                  "<path to project>",
+//                  <line number>,
+//                  ::testing::internal::GetBoolAssertionFailureMessage(
+//                      gtest_ar_, "a == b", "false", "true")
+//                      .c_str()) = ::testing::Message();
+//
+// where AssertionResult is defined similarly to
+//
+//   class AssertionResult {
+//   public:
+//     AssertionResult(const AssertionResult& other);
+//     explicit AssertionResult(bool success) : success_(success) {}
+//     operator bool() const { return success_; }
+//     ...
+//     private:
+//     bool success_;
+//   };
+//
+// In order for the analyzer to correctly handle this assertion, it needs to
+// know that the boolean value of the expression "a == b" is stored the
+// 'success_' field of the original AssertionResult temporary and propagated
+// (via the copy constructor) into the 'success_' field of the object stored
+// in 'gtest_ar_'.  That boolean value will then be returned from the bool
+// conversion method in the if statement. This guarantees that the assertion
+// holds when the return path is not taken.
+//
+// If the success value is not properly propagated, then the eager case split
+// on evaluating the expression can cause pernicious false positives
+// on the non-return path:
+//
+//   ASSERT(ptr != NULL)
+//   *ptr = 7; // False positive null pointer dereference here
+//
+// Unfortunately, the bool constructor cannot be inlined (because its
+// implementation is not present in the headers) and the copy constructor is
+// not inlined (because it is constructed into a temporary and the analyzer
+// does not inline these since it does not yet reliably call temporary
+// destructors).
+//
+// This checker compensates for the missing inlining by propagating the
+// _success value across the bool and copy constructors so the assertion behaves
+// as expected.
+
+namespace {
+class GTestChecker : public Checker<check::PostCall> {
+
+  mutable IdentifierInfo *AssertionResultII;
+  mutable IdentifierInfo *SuccessII;
+
+public:
+  GTestChecker();
+
+  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
+
+private:
+  void modelAssertionResultBoolConstructor(const CXXConstructorCall *Call,
+                                           bool IsRef, CheckerContext &C) const;
+
+  void modelAssertionResultCopyConstructor(const CXXConstructorCall *Call,
+                                           CheckerContext &C) const;
+
+  void initIdentifierInfo(ASTContext &Ctx) const;
+
+  SVal
+  getAssertionResultSuccessFieldValue(const CXXRecordDecl *AssertionResultDecl,
+                                      SVal Instance,
+                                      ProgramStateRef State) const;
+
+  static ProgramStateRef assumeValuesEqual(SVal Val1, SVal Val2,
+                                           ProgramStateRef State,
+                                           CheckerContext &C);
+};
+} // End anonymous namespace.
+
+GTestChecker::GTestChecker() : AssertionResultII(nullptr), SuccessII(nullptr) {}
+
+/// Model a call to an un-inlined AssertionResult(bool) or
+/// AssertionResult(bool &, ...).
+/// To do so, constrain the value of the newly-constructed instance's 'success_'
+/// field to be equal to the passed-in boolean value.
+///
+/// \param IsRef Whether the boolean parameter is a reference or not.
+void GTestChecker::modelAssertionResultBoolConstructor(
+    const CXXConstructorCall *Call, bool IsRef, CheckerContext &C) const {
+  assert(Call->getNumArgs() >= 1 && Call->getNumArgs() <= 2);
+
+  ProgramStateRef State = C.getState();
+  SVal BooleanArgVal = Call->getArgSVal(0);
+  if (IsRef) {
+    // The argument is a reference, so load from it to get the boolean value.
+    if (!BooleanArgVal.getAs<Loc>())
+      return;
+    BooleanArgVal = C.getState()->getSVal(BooleanArgVal.castAs<Loc>());
+  }
+
+  SVal ThisVal = Call->getCXXThisVal();
+
+  SVal ThisSuccess = getAssertionResultSuccessFieldValue(
+      Call->getDecl()->getParent(), ThisVal, State);
+
+  State = assumeValuesEqual(ThisSuccess, BooleanArgVal, State, C);
+  C.addTransition(State);
+}
+
+/// Model a call to an un-inlined AssertionResult copy constructor:
+///
+///   AssertionResult(const &AssertionResult other)
+///
+/// To do so, constrain the value of the newly-constructed instance's
+/// 'success_' field to be equal to the value of the pass-in instance's
+/// 'success_' field.
+void GTestChecker::modelAssertionResultCopyConstructor(
+    const CXXConstructorCall *Call, CheckerContext &C) const {
+  assert(Call->getNumArgs() == 1);
+
+  // The first parameter of the the copy constructor must be the other
+  // instance to initialize this instances fields from.
+  SVal OtherVal = Call->getArgSVal(0);
+  SVal ThisVal = Call->getCXXThisVal();
+
+  const CXXRecordDecl *AssertResultClassDecl = Call->getDecl()->getParent();
+  ProgramStateRef State = C.getState();
+
+  SVal ThisSuccess = getAssertionResultSuccessFieldValue(AssertResultClassDecl,
+                                                         ThisVal, State);
+  SVal OtherSuccess = getAssertionResultSuccessFieldValue(AssertResultClassDecl,
+                                                          OtherVal, State);
+
+  State = assumeValuesEqual(ThisSuccess, OtherSuccess, State, C);
+  C.addTransition(State);
+}
+
+/// Model calls to AssertionResult constructors that are not inlined.
+void GTestChecker::checkPostCall(const CallEvent &Call,
+                                 CheckerContext &C) const {
+  /// If the constructor was inlined, there is no need model it.
+  if (C.wasInlined)
+    return;
+
+  initIdentifierInfo(C.getASTContext());
+
+  auto *CtorCall = dyn_cast<CXXConstructorCall>(&Call);
+  if (!CtorCall)
+    return;
+
+  const CXXConstructorDecl *CtorDecl = CtorCall->getDecl();
+  const CXXRecordDecl *CtorParent = CtorDecl->getParent();
+  if (CtorParent->getIdentifier() != AssertionResultII)
+    return;
+
+  unsigned ParamCount = CtorDecl->getNumParams();
+
+  // Call the appropriate modeling method based the parameters and their
+  // types.
+
+  // We have AssertionResult(const &AssertionResult)
+  if (CtorDecl->isCopyConstructor() && ParamCount == 1) {
+    modelAssertionResultCopyConstructor(CtorCall, C);
+    return;
+  }
+
+  // There are two possible boolean constructors, depending on which
+  // version of gtest is being used:
+  //
+  // v1.7 and earlier:
+  //      AssertionResult(bool success)
+  //
+  // v1.8 and greater:
+  //      template <typename T>
+  //      AssertionResult(const T& success,
+  //                      typename internal::EnableIf<
+  //                          !internal::ImplicitlyConvertible<T,
+  //                              AssertionResult>::value>::type*)
+  //
+  CanQualType BoolTy = C.getASTContext().BoolTy;
+  if (ParamCount == 1 && CtorDecl->getParamDecl(0)->getType() == BoolTy) {
+    // We have AssertionResult(bool)
+    modelAssertionResultBoolConstructor(CtorCall, /*IsRef=*/false, C);
+    return;
+  }
+  if (ParamCount == 2){
+    auto *RefTy = CtorDecl->getParamDecl(0)->getType()->getAs<ReferenceType>();
+    if (RefTy &&
+        RefTy->getPointeeType()->getCanonicalTypeUnqualified() == BoolTy) {
+      // We have AssertionResult(bool &, ...)
+      modelAssertionResultBoolConstructor(CtorCall, /*IsRef=*/true, C);
+      return;
+    }
+  }
+}
+
+void GTestChecker::initIdentifierInfo(ASTContext &Ctx) const {
+  if (AssertionResultII)
+    return;
+
+  AssertionResultII = &Ctx.Idents.get("AssertionResult");
+  SuccessII = &Ctx.Idents.get("success_");
+}
+
+/// Returns the value stored in the 'success_' field of the passed-in
+/// AssertionResult instance.
+SVal GTestChecker::getAssertionResultSuccessFieldValue(
+    const CXXRecordDecl *AssertionResultDecl, SVal Instance,
+    ProgramStateRef State) const {
+
+  DeclContext::lookup_result Result = AssertionResultDecl->lookup(SuccessII);
+  if (Result.empty())
+    return UnknownVal();
+
+  auto *SuccessField = dyn_cast<FieldDecl>(Result.front());
+  if (!SuccessField)
+    return UnknownVal();
+
+  Optional<Loc> FieldLoc =
+      State->getLValue(SuccessField, Instance).getAs<Loc>();
+  if (!FieldLoc.hasValue())
+    return UnknownVal();
+
+  return State->getSVal(*FieldLoc);
+}
+
+/// Constrain the passed-in state to assume two values are equal.
+ProgramStateRef GTestChecker::assumeValuesEqual(SVal Val1, SVal Val2,
+                                                ProgramStateRef State,
+                                                CheckerContext &C) {
+  if (!Val1.getAs<DefinedOrUnknownSVal>() ||
+      !Val2.getAs<DefinedOrUnknownSVal>())
+    return State;
+
+  auto ValuesEqual =
+      C.getSValBuilder().evalEQ(State, Val1.castAs<DefinedOrUnknownSVal>(),
+                                Val2.castAs<DefinedOrUnknownSVal>());
+
+  if (!ValuesEqual.getAs<DefinedSVal>())
+    return State;
+
+  State = C.getConstraintManager().assume(
+      State, ValuesEqual.castAs<DefinedSVal>(), true);
+
+  return State;
+}
+
+void ento::registerGTestChecker(CheckerManager &Mgr) {
+  const LangOptions &LangOpts = Mgr.getLangOpts();
+  // gtest is a C++ API so there is no sense running the checker
+  // if not compiling for C++.
+  if (!LangOpts.CPlusPlus)
+    return;
+
+  Mgr.registerChecker<GTestChecker>();
+}
diff --git a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index 8c8acc6..b1a54e7 100644
--- a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -65,6 +65,18 @@
   /// and thus, is tainted.
   static bool isStdin(const Expr *E, CheckerContext &C);
 
+  /// This is called from getPointedToSymbol() to resolve symbol references for
+  /// the region underlying a LazyCompoundVal. This is the default binding
+  /// for the LCV, which could be a conjured symbol from a function call that
+  /// initialized the region. It only returns the conjured symbol if the LCV
+  /// covers the entire region, e.g. we avoid false positives by not returning
+  /// a default bindingc for an entire struct if the symbol for only a single
+  /// field or element within it is requested.
+  // TODO: Return an appropriate symbol for sub-fields/elements of an LCV so
+  // that they are also appropriately tainted.
+  static SymbolRef getLCVSymbol(CheckerContext &C,
+                                nonloc::LazyCompoundVal &LCV);
+
   /// \brief Given a pointer argument, get the symbol of the value it contains
   /// (points to).
   static SymbolRef getPointedToSymbol(CheckerContext &C, const Expr *Arg);
@@ -101,6 +113,22 @@
   bool generateReportIfTainted(const Expr *E, const char Msg[],
                                CheckerContext &C) const;
 
+  /// The bug visitor prints a diagnostic message at the location where a given
+  /// variable was tainted.
+  class TaintBugVisitor
+      : public BugReporterVisitorImpl<TaintBugVisitor> {
+  private:
+    const SVal V;
+
+  public:
+    TaintBugVisitor(const SVal V) : V(V) {}
+    void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); }
+
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
+  };
 
   typedef SmallVector<unsigned, 2> ArgVector;
 
@@ -194,6 +222,28 @@
 /// points to data, which should be tainted on return.
 REGISTER_SET_WITH_PROGRAMSTATE(TaintArgsOnPostVisit, unsigned)
 
+std::shared_ptr<PathDiagnosticPiece>
+GenericTaintChecker::TaintBugVisitor::VisitNode(const ExplodedNode *N,
+    const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) {
+
+  // Find the ExplodedNode where the taint was first introduced
+  if (!N->getState()->isTainted(V) || PrevN->getState()->isTainted(V))
+    return nullptr;
+
+  const Stmt *S = PathDiagnosticLocation::getStmt(N);
+  if (!S)
+    return nullptr;
+
+  const LocationContext *NCtx = N->getLocationContext();
+  PathDiagnosticLocation L =
+      PathDiagnosticLocation::createBegin(S, BRC.getSourceManager(), NCtx);
+  if (!L.isValid() || !L.asLocation().isValid())
+    return nullptr;
+
+  return std::make_shared<PathDiagnosticEventPiece>(
+      L, "Taint originated here");
+}
+
 GenericTaintChecker::TaintPropagationRule
 GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
                                                      const FunctionDecl *FDecl,
@@ -423,6 +473,27 @@
   return false;
 }
 
+SymbolRef GenericTaintChecker::getLCVSymbol(CheckerContext &C,
+                                            nonloc::LazyCompoundVal &LCV) {
+  StoreManager &StoreMgr = C.getStoreManager();
+
+  // getLCVSymbol() is reached in a PostStmt so we can always expect a default
+  // binding to exist if one is present.
+  if (Optional<SVal> binding = StoreMgr.getDefaultBinding(LCV)) {
+    SymbolRef Sym = binding->getAsSymbol();
+    if (!Sym)
+      return nullptr;
+
+    // If the LCV covers an entire base region return the default conjured symbol.
+    if (LCV.getRegion() == LCV.getRegion()->getBaseRegion())
+      return Sym;
+  }
+
+  // Otherwise, return a nullptr as there's not yet a functional way to taint
+  // sub-regions of LCVs.
+  return nullptr;
+}
+
 SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
                                                   const Expr* Arg) {
   ProgramStateRef State = C.getState();
@@ -438,6 +509,10 @@
     dyn_cast<PointerType>(Arg->getType().getCanonicalType().getTypePtr());
   SVal Val = State->getSVal(*AddrLoc,
                             ArgTy ? ArgTy->getPointeeType(): QualType());
+
+  if (auto LCV = Val.getAs<nonloc::LazyCompoundVal>())
+    return getLCVSymbol(C, *LCV);
+
   return Val.getAsSymbol();
 }
 
@@ -635,8 +710,13 @@
 
   // Check for taint.
   ProgramStateRef State = C.getState();
-  if (!State->isTainted(getPointedToSymbol(C, E)) &&
-      !State->isTainted(E, C.getLocationContext()))
+  const SymbolRef PointedToSym = getPointedToSymbol(C, E);
+  SVal TaintedSVal;
+  if (State->isTainted(PointedToSym))
+    TaintedSVal = nonloc::SymbolVal(PointedToSym);
+  else if (State->isTainted(E, C.getLocationContext()))
+    TaintedSVal = C.getSVal(E);
+  else
     return false;
 
   // Generate diagnostic.
@@ -644,6 +724,7 @@
     initBugType();
     auto report = llvm::make_unique<BugReport>(*BT, Msg, N);
     report->addRange(E->getSourceRange());
+    report->addVisitor(llvm::make_unique<TaintBugVisitor>(TaintedSVal));
     C.emitReport(std::move(report));
     return true;
   }
diff --git a/lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp b/lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp
new file mode 100644
index 0000000..531054a
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp
@@ -0,0 +1,842 @@
+//===-- IteratorPastEndChecker.cpp --------------------------------*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a checker for using iterators outside their range (past end). Usage
+// means here dereferencing, incrementing etc.
+//
+//===----------------------------------------------------------------------===//
+
+#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 <utility>
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+struct IteratorPosition {
+private:
+  enum Kind { InRange, OutofRange } K;
+  IteratorPosition(Kind InK) : K(InK) {}
+
+public:
+  bool isInRange() const { return K == InRange; }
+  bool isOutofRange() const { return K == OutofRange; }
+
+  static IteratorPosition getInRange() { return IteratorPosition(InRange); }
+  static IteratorPosition getOutofRange() {
+    return IteratorPosition(OutofRange);
+  }
+
+  bool operator==(const IteratorPosition &X) const { return K == X.K; }
+  bool operator!=(const IteratorPosition &X) const { return K != X.K; }
+  void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(K); }
+};
+
+typedef llvm::PointerUnion<const MemRegion *, SymbolRef> RegionOrSymbol;
+
+struct IteratorComparison {
+private:
+  RegionOrSymbol Left, Right;
+  bool Equality;
+
+public:
+  IteratorComparison(RegionOrSymbol L, RegionOrSymbol R, bool Eq)
+      : Left(L), Right(R), Equality(Eq) {}
+
+  RegionOrSymbol getLeft() const { return Left; }
+  RegionOrSymbol getRight() const { return Right; }
+  bool isEquality() const { return Equality; }
+  bool operator==(const IteratorComparison &X) const {
+    return Left == X.Left && Right == X.Right && Equality == X.Equality;
+  }
+  bool operator!=(const IteratorComparison &X) const {
+    return Left != X.Left || Right != X.Right || Equality != X.Equality;
+  }
+  void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Equality); }
+};
+
+class IteratorPastEndChecker
+    : public Checker<
+          check::PreCall, check::PostCall, check::PreStmt<CXXOperatorCallExpr>,
+          check::PostStmt<CXXConstructExpr>, check::PostStmt<DeclStmt>,
+          check::PostStmt<MaterializeTemporaryExpr>, check::BeginFunction,
+          check::DeadSymbols, eval::Assume, eval::Call> {
+  mutable IdentifierInfo *II_find = nullptr,
+                         *II_find_end = nullptr, *II_find_first_of = nullptr,
+                         *II_find_if = nullptr, *II_find_if_not = nullptr,
+                         *II_lower_bound = nullptr, *II_upper_bound = nullptr,
+                         *II_search = nullptr, *II_search_n = nullptr;
+
+  std::unique_ptr<BugType> PastEndBugType;
+
+  void handleComparison(CheckerContext &C, const SVal &RetVal, const SVal &LVal,
+                        const SVal &RVal, OverloadedOperatorKind Op) const;
+  void handleAccess(CheckerContext &C, const SVal &Val) const;
+  void handleDecrement(CheckerContext &C, const SVal &Val) const;
+  void handleEnd(CheckerContext &C, const SVal &RetVal) const;
+
+  bool evalFind(CheckerContext &C, const CallExpr *CE) const;
+  bool evalFindEnd(CheckerContext &C, const CallExpr *CE) const;
+  bool evalFindFirstOf(CheckerContext &C, const CallExpr *CE) const;
+  bool evalFindIf(CheckerContext &C, const CallExpr *CE) const;
+  bool evalFindIfNot(CheckerContext &C, const CallExpr *CE) const;
+  bool evalLowerBound(CheckerContext &C, const CallExpr *CE) const;
+  bool evalUpperBound(CheckerContext &C, const CallExpr *CE) const;
+  bool evalSearch(CheckerContext &C, const CallExpr *CE) const;
+  bool evalSearchN(CheckerContext &C, const CallExpr *CE) const;
+  void Find(CheckerContext &C, const CallExpr *CE) const;
+
+  void reportPastEndBug(const StringRef &Message, const SVal &Val,
+                        CheckerContext &C, ExplodedNode *ErrNode) const;
+  void initIdentifiers(ASTContext &Ctx) const;
+
+public:
+  IteratorPastEndChecker();
+
+  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
+  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
+  void checkPreStmt(const CXXOperatorCallExpr *COCE, CheckerContext &C) const;
+  void checkBeginFunction(CheckerContext &C) const;
+  void checkPostStmt(const CXXConstructExpr *CCE, CheckerContext &C) const;
+  void checkPostStmt(const DeclStmt *DS, CheckerContext &C) const;
+  void checkPostStmt(const MaterializeTemporaryExpr *MTE,
+                     CheckerContext &C) const;
+  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
+  ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond,
+                             bool Assumption) const;
+  bool evalCall(const CallExpr *CE, CheckerContext &C) const;
+};
+}
+
+REGISTER_MAP_WITH_PROGRAMSTATE(IteratorSymbolMap, SymbolRef, IteratorPosition)
+REGISTER_MAP_WITH_PROGRAMSTATE(IteratorRegionMap, const MemRegion *,
+                               IteratorPosition)
+
+REGISTER_MAP_WITH_PROGRAMSTATE(IteratorComparisonMap, const SymExpr *,
+                               IteratorComparison)
+
+#define INIT_ID(Id)                                                            \
+  if (!II_##Id)                                                                \
+  II_##Id = &Ctx.Idents.get(#Id)
+
+namespace {
+
+bool isIteratorType(const QualType &Type);
+bool isIterator(const CXXRecordDecl *CRD);
+bool isEndCall(const FunctionDecl *Func);
+bool isSimpleComparisonOperator(OverloadedOperatorKind OK);
+bool isAccessOperator(OverloadedOperatorKind OK);
+bool isDecrementOperator(OverloadedOperatorKind OK);
+BinaryOperator::Opcode getOpcode(const SymExpr *SE);
+const RegionOrSymbol getRegionOrSymbol(const SVal &Val);
+const ProgramStateRef processComparison(ProgramStateRef State,
+                                        RegionOrSymbol LVal,
+                                        RegionOrSymbol RVal, bool Equal);
+const ProgramStateRef saveComparison(ProgramStateRef State,
+                                     const SymExpr *Condition, const SVal &LVal,
+                                     const SVal &RVal, bool Eq);
+const IteratorComparison *loadComparison(ProgramStateRef State,
+                                         const SymExpr *Condition);
+const IteratorPosition *getIteratorPosition(ProgramStateRef State,
+                                            const SVal &Val);
+const IteratorPosition *getIteratorPosition(ProgramStateRef State,
+                                            RegionOrSymbol RegOrSym);
+ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val,
+                                    IteratorPosition Pos);
+ProgramStateRef setIteratorPosition(ProgramStateRef State,
+                                    RegionOrSymbol RegOrSym,
+                                    IteratorPosition Pos);
+ProgramStateRef adjustIteratorPosition(ProgramStateRef State,
+                                       RegionOrSymbol RegOrSym,
+                                       IteratorPosition Pos, bool Equal);
+bool contradictingIteratorPositions(IteratorPosition Pos1,
+                                    IteratorPosition Pos2, bool Equal);
+}
+
+IteratorPastEndChecker::IteratorPastEndChecker() {
+  PastEndBugType.reset(
+      new BugType(this, "Iterator Past End", "Misuse of STL APIs"));
+  PastEndBugType->setSuppressOnSink(true);
+}
+
+void IteratorPastEndChecker::checkPreCall(const CallEvent &Call,
+                                          CheckerContext &C) const {
+  // Check for access past end
+  const auto *Func = Call.getDecl()->getAsFunction();
+  if (!Func)
+    return;
+  if (Func->isOverloadedOperator()) {
+    if (isAccessOperator(Func->getOverloadedOperator())) {
+      if (const auto *InstCall = dyn_cast<CXXInstanceCall>(&Call)) {
+        handleAccess(C, InstCall->getCXXThisVal());
+      } else {
+        handleAccess(C, Call.getArgSVal(0));
+      }
+    }
+  }
+}
+
+void IteratorPastEndChecker::checkPostCall(const CallEvent &Call,
+                                           CheckerContext &C) const {
+  // Record end() iterators, iterator decrementation and comparison
+  const auto *Func = Call.getDecl()->getAsFunction();
+  if (!Func)
+    return;
+  if (Func->isOverloadedOperator()) {
+    const auto Op = Func->getOverloadedOperator();
+    if (isSimpleComparisonOperator(Op)) {
+      if (Func->isCXXInstanceMember()) {
+        const auto &InstCall = static_cast<const CXXInstanceCall &>(Call);
+        handleComparison(C, InstCall.getReturnValue(), InstCall.getCXXThisVal(),
+                         InstCall.getArgSVal(0), Op);
+      } else {
+        handleComparison(C, Call.getReturnValue(), Call.getArgSVal(0),
+                         Call.getArgSVal(1), Op);
+      }
+    } else if (isDecrementOperator(Func->getOverloadedOperator())) {
+      if (Func->isCXXInstanceMember()) {
+        const auto &InstCall = static_cast<const CXXInstanceCall &>(Call);
+        handleDecrement(C, InstCall.getCXXThisVal());
+      } else {
+        handleDecrement(C, Call.getArgSVal(0));
+      }
+    }
+  } else if (Func->isCXXInstanceMember()) {
+    if (!isEndCall(Func))
+      return;
+    if (!isIteratorType(Call.getResultType()))
+      return;
+    handleEnd(C, Call.getReturnValue());
+  }
+}
+
+void IteratorPastEndChecker::checkPreStmt(const CXXOperatorCallExpr *COCE,
+                                          CheckerContext &C) const {
+  const auto *ThisExpr = COCE->getArg(0);
+
+  auto State = C.getState();
+  const auto *LCtx = C.getPredecessor()->getLocationContext();
+
+  const auto CurrentThis = State->getSVal(ThisExpr, LCtx);
+  if (const auto *Reg = CurrentThis.getAsRegion()) {
+    if (!Reg->getAs<CXXTempObjectRegion>())
+      return;
+    const auto OldState = C.getPredecessor()->getFirstPred()->getState();
+    const auto OldThis = OldState->getSVal(ThisExpr, LCtx);
+    const auto *Pos = getIteratorPosition(OldState, OldThis);
+    if (!Pos)
+      return;
+    State = setIteratorPosition(State, CurrentThis, *Pos);
+    C.addTransition(State);
+  }
+}
+
+void IteratorPastEndChecker::checkBeginFunction(CheckerContext &C) const {
+  // Copy state of iterator arguments to iterator parameters
+  auto State = C.getState();
+  const auto *LCtx = C.getLocationContext();
+
+  const auto *Site = cast<StackFrameContext>(LCtx)->getCallSite();
+  if (!Site)
+    return;
+
+  const auto *FD = dyn_cast<FunctionDecl>(LCtx->getDecl());
+  if (!FD)
+    return;
+
+  const auto *CE = dyn_cast<CallExpr>(Site);
+  if (!CE)
+    return;
+
+  bool Change = false;
+  int idx = 0;
+  for (const auto P : FD->parameters()) {
+    auto Param = State->getLValue(P, LCtx);
+    auto Arg = State->getSVal(CE->getArg(idx++), LCtx->getParent());
+    const auto *Pos = getIteratorPosition(State, Arg);
+    if (!Pos)
+      continue;
+    State = setIteratorPosition(State, Param, *Pos);
+    Change = true;
+  }
+  if (Change) {
+    C.addTransition(State);
+  }
+}
+
+void IteratorPastEndChecker::checkPostStmt(const CXXConstructExpr *CCE,
+                                           CheckerContext &C) const {
+  // Transfer iterator state in case of copy or move by constructor
+  const auto *ctr = CCE->getConstructor();
+  if (!ctr->isCopyOrMoveConstructor())
+    return;
+  const auto *RHSExpr = CCE->getArg(0);
+
+  auto State = C.getState();
+  const auto *LCtx = C.getLocationContext();
+
+  const auto RetVal = State->getSVal(CCE, LCtx);
+
+  const auto RHSVal = State->getSVal(RHSExpr, LCtx);
+  const auto *RHSPos = getIteratorPosition(State, RHSVal);
+  if (!RHSPos)
+    return;
+  State = setIteratorPosition(State, RetVal, *RHSPos);
+  C.addTransition(State);
+}
+
+void IteratorPastEndChecker::checkPostStmt(const DeclStmt *DS,
+                                           CheckerContext &C) const {
+  // Transfer iterator state to new variable declaration
+  for (const auto *D : DS->decls()) {
+    const auto *VD = dyn_cast<VarDecl>(D);
+    if (!VD || !VD->hasInit())
+      continue;
+
+    auto State = C.getState();
+    const auto *LCtx = C.getPredecessor()->getLocationContext();
+    const auto *Pos =
+        getIteratorPosition(State, State->getSVal(VD->getInit(), LCtx));
+    if (!Pos)
+      continue;
+    State = setIteratorPosition(State, State->getLValue(VD, LCtx), *Pos);
+    C.addTransition(State);
+  }
+}
+
+void IteratorPastEndChecker::checkPostStmt(const MaterializeTemporaryExpr *MTE,
+                                           CheckerContext &C) const {
+  /* Transfer iterator state for to temporary objects */
+  auto State = C.getState();
+  const auto *LCtx = C.getPredecessor()->getLocationContext();
+  const auto *Pos =
+      getIteratorPosition(State, State->getSVal(MTE->GetTemporaryExpr(), LCtx));
+  if (!Pos)
+    return;
+  State = setIteratorPosition(State, State->getSVal(MTE, LCtx), *Pos);
+  C.addTransition(State);
+}
+
+void IteratorPastEndChecker::checkDeadSymbols(SymbolReaper &SR,
+                                              CheckerContext &C) const {
+  auto State = C.getState();
+
+  auto RegionMap = State->get<IteratorRegionMap>();
+  for (const auto Reg : RegionMap) {
+    if (!SR.isLiveRegion(Reg.first)) {
+      State = State->remove<IteratorRegionMap>(Reg.first);
+    }
+  }
+
+  auto SymbolMap = State->get<IteratorSymbolMap>();
+  for (const auto Sym : SymbolMap) {
+    if (SR.isDead(Sym.first)) {
+      State = State->remove<IteratorSymbolMap>(Sym.first);
+    }
+  }
+
+  auto ComparisonMap = State->get<IteratorComparisonMap>();
+  for (const auto Comp : ComparisonMap) {
+    if (SR.isDead(Comp.first)) {
+      State = State->remove<IteratorComparisonMap>(Comp.first);
+    }
+  }
+}
+
+ProgramStateRef IteratorPastEndChecker::evalAssume(ProgramStateRef State,
+                                                   SVal Cond,
+                                                   bool Assumption) const {
+  // Load recorded comparison and transfer iterator state between sides
+  // according to comparison operator and assumption
+  const auto *SE = Cond.getAsSymExpr();
+  if (!SE)
+    return State;
+
+  auto Opc = getOpcode(SE);
+  if (Opc != BO_EQ && Opc != BO_NE)
+    return State;
+
+  bool Negated = false;
+  const auto *Comp = loadComparison(State, SE);
+  if (!Comp) {
+    // Try negated comparison, which is a SymExpr to 0 integer comparison
+    const auto *SIE = dyn_cast<SymIntExpr>(SE);
+    if (!SIE)
+      return State;
+
+    if (SIE->getRHS() != 0)
+      return State;
+
+    SE = SIE->getLHS();
+    Negated = SIE->getOpcode() == BO_EQ; // Equal to zero means negation
+    Opc = getOpcode(SE);
+    if (Opc != BO_EQ && Opc != BO_NE)
+      return State;
+
+    Comp = loadComparison(State, SE);
+    if (!Comp)
+      return State;
+  }
+
+  return processComparison(State, Comp->getLeft(), Comp->getRight(),
+                           (Comp->isEquality() == Assumption) != Negated);
+}
+
+// FIXME: Evaluation of these STL calls should be moved to StdCLibraryFunctions
+//       checker (see patch r284960) or another similar checker for C++ STL
+//       functions (e.g. StdCXXLibraryFunctions or StdCppLibraryFunctions).
+bool IteratorPastEndChecker::evalCall(const CallExpr *CE,
+                                      CheckerContext &C) const {
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
+  if (!FD)
+    return false;
+
+  ASTContext &Ctx = C.getASTContext();
+  initIdentifiers(Ctx);
+
+  if (FD->getKind() == Decl::Function) {
+    if (FD->isInStdNamespace()) {
+      if (FD->getIdentifier() == II_find) {
+        return evalFind(C, CE);
+      } else if (FD->getIdentifier() == II_find_end) {
+        return evalFindEnd(C, CE);
+      } else if (FD->getIdentifier() == II_find_first_of) {
+        return evalFindFirstOf(C, CE);
+      } else if (FD->getIdentifier() == II_find_if) {
+        return evalFindIf(C, CE);
+      } else if (FD->getIdentifier() == II_find_if) {
+        return evalFindIf(C, CE);
+      } else if (FD->getIdentifier() == II_find_if_not) {
+        return evalFindIfNot(C, CE);
+      } else if (FD->getIdentifier() == II_upper_bound) {
+        return evalUpperBound(C, CE);
+      } else if (FD->getIdentifier() == II_lower_bound) {
+        return evalLowerBound(C, CE);
+      } else if (FD->getIdentifier() == II_search) {
+        return evalSearch(C, CE);
+      } else if (FD->getIdentifier() == II_search_n) {
+        return evalSearchN(C, CE);
+      }
+    }
+  }
+
+  return false;
+}
+
+void IteratorPastEndChecker::handleComparison(CheckerContext &C,
+                                              const SVal &RetVal,
+                                              const SVal &LVal,
+                                              const SVal &RVal,
+                                              OverloadedOperatorKind Op) const {
+  // Record the operands and the operator of the comparison for the next
+  // evalAssume, if the result is a symbolic expression. If it is a concrete
+  // value (only one branch is possible), then transfer the state between
+  // the operands according to the operator and the result
+  auto State = C.getState();
+  if (const auto *Condition = RetVal.getAsSymbolicExpression()) {
+    const auto *LPos = getIteratorPosition(State, LVal);
+    const auto *RPos = getIteratorPosition(State, RVal);
+    if (!LPos && !RPos)
+      return;
+    State = saveComparison(State, Condition, LVal, RVal, Op == OO_EqualEqual);
+    C.addTransition(State);
+  } else if (const auto TruthVal = RetVal.getAs<nonloc::ConcreteInt>()) {
+    if ((State = processComparison(
+             State, getRegionOrSymbol(LVal), getRegionOrSymbol(RVal),
+             (Op == OO_EqualEqual) == (TruthVal->getValue() != 0)))) {
+      C.addTransition(State);
+    } else {
+      C.generateSink(State, C.getPredecessor());
+    }
+  }
+}
+
+void IteratorPastEndChecker::handleAccess(CheckerContext &C,
+                                          const SVal &Val) const {
+  auto State = C.getState();
+  const auto *Pos = getIteratorPosition(State, Val);
+  if (Pos && Pos->isOutofRange()) {
+    auto *N = C.generateNonFatalErrorNode(State);
+    if (!N) {
+      return;
+    }
+    reportPastEndBug("Iterator accessed past its end.", Val, C, N);
+  }
+}
+
+void IteratorPastEndChecker::handleDecrement(CheckerContext &C,
+                                             const SVal &Val) const {
+  auto State = C.getState();
+  const auto *Pos = getIteratorPosition(State, Val);
+  if (Pos && Pos->isOutofRange()) {
+    State = setIteratorPosition(State, Val, IteratorPosition::getInRange());
+    // FIXME: We could also check for iterators ahead of their beginnig in the
+    //       future, but currently we do not care for such errors. We also
+    //       assume that the iterator is not past its end by more then one
+    //       position.
+    C.addTransition(State);
+  }
+}
+
+void IteratorPastEndChecker::handleEnd(CheckerContext &C,
+                                       const SVal &RetVal) const {
+  auto State = C.getState();
+  State = setIteratorPosition(State, RetVal, IteratorPosition::getOutofRange());
+  C.addTransition(State);
+}
+
+bool IteratorPastEndChecker::evalFind(CheckerContext &C,
+                                      const CallExpr *CE) const {
+  if (CE->getNumArgs() == 3 && isIteratorType(CE->getArg(0)->getType()) &&
+      isIteratorType(CE->getArg(1)->getType())) {
+    Find(C, CE);
+    return true;
+  }
+  return false;
+}
+
+bool IteratorPastEndChecker::evalFindEnd(CheckerContext &C,
+                                         const CallExpr *CE) const {
+  if ((CE->getNumArgs() == 4 || CE->getNumArgs() == 5) &&
+      isIteratorType(CE->getArg(0)->getType()) &&
+      isIteratorType(CE->getArg(1)->getType()) &&
+      isIteratorType(CE->getArg(2)->getType()) &&
+      isIteratorType(CE->getArg(3)->getType())) {
+    Find(C, CE);
+    return true;
+  }
+  return false;
+}
+
+bool IteratorPastEndChecker::evalFindFirstOf(CheckerContext &C,
+                                             const CallExpr *CE) const {
+  if ((CE->getNumArgs() == 4 || CE->getNumArgs() == 5) &&
+      isIteratorType(CE->getArg(0)->getType()) &&
+      isIteratorType(CE->getArg(1)->getType()) &&
+      isIteratorType(CE->getArg(2)->getType()) &&
+      isIteratorType(CE->getArg(3)->getType())) {
+    Find(C, CE);
+    return true;
+  }
+  return false;
+}
+
+bool IteratorPastEndChecker::evalFindIf(CheckerContext &C,
+                                        const CallExpr *CE) const {
+  if (CE->getNumArgs() == 3 && isIteratorType(CE->getArg(0)->getType()) &&
+      isIteratorType(CE->getArg(1)->getType())) {
+    Find(C, CE);
+    return true;
+  }
+  return false;
+}
+
+bool IteratorPastEndChecker::evalFindIfNot(CheckerContext &C,
+                                           const CallExpr *CE) const {
+  if (CE->getNumArgs() == 3 && isIteratorType(CE->getArg(0)->getType()) &&
+      isIteratorType(CE->getArg(1)->getType())) {
+    Find(C, CE);
+    return true;
+  }
+  return false;
+}
+
+bool IteratorPastEndChecker::evalLowerBound(CheckerContext &C,
+                                            const CallExpr *CE) const {
+  if ((CE->getNumArgs() == 3 || CE->getNumArgs() == 4) &&
+      isIteratorType(CE->getArg(0)->getType()) &&
+      isIteratorType(CE->getArg(1)->getType())) {
+    Find(C, CE);
+    return true;
+  }
+  return false;
+}
+
+bool IteratorPastEndChecker::evalUpperBound(CheckerContext &C,
+                                            const CallExpr *CE) const {
+  if ((CE->getNumArgs() == 3 || CE->getNumArgs() == 4) &&
+      isIteratorType(CE->getArg(0)->getType()) &&
+      isIteratorType(CE->getArg(1)->getType())) {
+    Find(C, CE);
+    return true;
+  }
+  return false;
+}
+
+bool IteratorPastEndChecker::evalSearch(CheckerContext &C,
+                                        const CallExpr *CE) const {
+  if ((CE->getNumArgs() == 4 || CE->getNumArgs() == 5) &&
+      isIteratorType(CE->getArg(0)->getType()) &&
+      isIteratorType(CE->getArg(1)->getType()) &&
+      isIteratorType(CE->getArg(2)->getType()) &&
+      isIteratorType(CE->getArg(3)->getType())) {
+    Find(C, CE);
+    return true;
+  }
+  return false;
+}
+
+bool IteratorPastEndChecker::evalSearchN(CheckerContext &C,
+                                         const CallExpr *CE) const {
+  if ((CE->getNumArgs() == 4 || CE->getNumArgs() == 5) &&
+      isIteratorType(CE->getArg(0)->getType()) &&
+      isIteratorType(CE->getArg(1)->getType())) {
+    Find(C, CE);
+    return true;
+  }
+  return false;
+}
+
+void IteratorPastEndChecker::Find(CheckerContext &C, const CallExpr *CE) const {
+  auto state = C.getState();
+  auto &svalBuilder = C.getSValBuilder();
+  const auto *LCtx = C.getLocationContext();
+
+  auto RetVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
+  auto SecondParam = state->getSVal(CE->getArg(1), LCtx);
+
+  auto stateFound = state->BindExpr(CE, LCtx, RetVal);
+  auto stateNotFound = state->BindExpr(CE, LCtx, SecondParam);
+
+  C.addTransition(stateFound);
+  C.addTransition(stateNotFound);
+}
+
+void IteratorPastEndChecker::reportPastEndBug(const StringRef &Message,
+                                              const SVal &Val,
+                                              CheckerContext &C,
+                                              ExplodedNode *ErrNode) const {
+  auto R = llvm::make_unique<BugReport>(*PastEndBugType, Message, ErrNode);
+  R->markInteresting(Val);
+  C.emitReport(std::move(R));
+}
+
+void IteratorPastEndChecker::initIdentifiers(ASTContext &Ctx) const {
+  INIT_ID(find);
+  INIT_ID(find_end);
+  INIT_ID(find_first_of);
+  INIT_ID(find_if);
+  INIT_ID(find_if_not);
+  INIT_ID(lower_bound);
+  INIT_ID(upper_bound);
+  INIT_ID(search);
+  INIT_ID(search_n);
+}
+
+namespace {
+
+bool isIteratorType(const QualType &Type) {
+  if (Type->isPointerType())
+    return true;
+
+  const auto *CRD = Type->getUnqualifiedDesugaredType()->getAsCXXRecordDecl();
+  return isIterator(CRD);
+}
+
+bool isIterator(const CXXRecordDecl *CRD) {
+  if (!CRD)
+    return false;
+
+  const auto Name = CRD->getName();
+  if (!(Name.endswith_lower("iterator") || Name.endswith_lower("iter") ||
+        Name.endswith_lower("it")))
+    return false;
+
+  bool HasCopyCtor = false, HasCopyAssign = true, HasDtor = false,
+       HasPreIncrOp = false, HasPostIncrOp = false, HasDerefOp = false;
+  for (const auto *Method : CRD->methods()) {
+    if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(Method)) {
+      if (Ctor->isCopyConstructor()) {
+        HasCopyCtor = !Ctor->isDeleted() && Ctor->getAccess() == AS_public;
+      }
+      continue;
+    }
+    if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(Method)) {
+      HasDtor = !Dtor->isDeleted() && Dtor->getAccess() == AS_public;
+      continue;
+    }
+    if (Method->isCopyAssignmentOperator()) {
+      HasCopyAssign = !Method->isDeleted() && Method->getAccess() == AS_public;
+      continue;
+    }
+    if (!Method->isOverloadedOperator())
+      continue;
+    const auto OPK = Method->getOverloadedOperator();
+    if (OPK == OO_PlusPlus) {
+      HasPreIncrOp = HasPreIncrOp || (Method->getNumParams() == 0);
+      HasPostIncrOp = HasPostIncrOp || (Method->getNumParams() == 1);
+      continue;
+    }
+    if (OPK == OO_Star) {
+      HasDerefOp = (Method->getNumParams() == 0);
+      continue;
+    }
+  }
+
+  return HasCopyCtor && HasCopyAssign && HasDtor && HasPreIncrOp &&
+         HasPostIncrOp && HasDerefOp;
+}
+
+bool isEndCall(const FunctionDecl *Func) {
+  const auto *IdInfo = Func->getIdentifier();
+  if (!IdInfo)
+    return false;
+  return IdInfo->getName().endswith_lower("end");
+}
+
+bool isSimpleComparisonOperator(OverloadedOperatorKind OK) {
+  return OK == OO_EqualEqual || OK == OO_ExclaimEqual;
+}
+
+bool isAccessOperator(OverloadedOperatorKind OK) {
+  return OK == OO_Star || OK == OO_Arrow || OK == OO_ArrowStar ||
+         OK == OO_Plus || OK == OO_PlusEqual || OK == OO_PlusPlus ||
+         OK == OO_Subscript;
+}
+
+bool isDecrementOperator(OverloadedOperatorKind OK) {
+  return OK == OO_MinusEqual || OK == OO_MinusMinus;
+}
+
+BinaryOperator::Opcode getOpcode(const SymExpr *SE) {
+  if (const auto *BSE = dyn_cast<BinarySymExpr>(SE)) {
+    return BSE->getOpcode();
+  } else if (const auto *SC = dyn_cast<SymbolConjured>(SE)) {
+    const auto *COE = dyn_cast<CXXOperatorCallExpr>(SC->getStmt());
+    if (!COE)
+      return BO_Comma; // Extremal value, neither EQ nor NE
+    if (COE->getOperator() == OO_EqualEqual) {
+      return BO_EQ;
+    } else if (COE->getOperator() == OO_ExclaimEqual) {
+      return BO_NE;
+    }
+    return BO_Comma; // Extremal value, neither EQ nor NE
+  }
+  return BO_Comma; // Extremal value, neither EQ nor NE
+}
+
+const RegionOrSymbol getRegionOrSymbol(const SVal &Val) {
+  if (const auto Reg = Val.getAsRegion()) {
+    return Reg;
+  } else if (const auto Sym = Val.getAsSymbol()) {
+    return Sym;
+  } else if (const auto LCVal = Val.getAs<nonloc::LazyCompoundVal>()) {
+    return LCVal->getRegion();
+  }
+  return RegionOrSymbol();
+}
+
+const ProgramStateRef processComparison(ProgramStateRef State,
+                                        RegionOrSymbol LVal,
+                                        RegionOrSymbol RVal, bool Equal) {
+  const auto *LPos = getIteratorPosition(State, LVal);
+  const auto *RPos = getIteratorPosition(State, RVal);
+  if (LPos && !RPos) {
+    State = adjustIteratorPosition(State, RVal, *LPos, Equal);
+  } else if (!LPos && RPos) {
+    State = adjustIteratorPosition(State, LVal, *RPos, Equal);
+  } else if (LPos && RPos) {
+    if (contradictingIteratorPositions(*LPos, *RPos, Equal)) {
+      return nullptr;
+    }
+  }
+  return State;
+}
+
+const ProgramStateRef saveComparison(ProgramStateRef State,
+                                     const SymExpr *Condition, const SVal &LVal,
+                                     const SVal &RVal, bool Eq) {
+  const auto Left = getRegionOrSymbol(LVal);
+  const auto Right = getRegionOrSymbol(RVal);
+  if (!Left || !Right)
+    return State;
+  return State->set<IteratorComparisonMap>(Condition,
+                                           IteratorComparison(Left, Right, Eq));
+}
+
+const IteratorComparison *loadComparison(ProgramStateRef State,
+                                         const SymExpr *Condition) {
+  return State->get<IteratorComparisonMap>(Condition);
+}
+
+const IteratorPosition *getIteratorPosition(ProgramStateRef State,
+                                            const SVal &Val) {
+  if (const auto Reg = Val.getAsRegion()) {
+    return State->get<IteratorRegionMap>(Reg);
+  } else if (const auto Sym = Val.getAsSymbol()) {
+    return State->get<IteratorSymbolMap>(Sym);
+  } else if (const auto LCVal = Val.getAs<nonloc::LazyCompoundVal>()) {
+    return State->get<IteratorRegionMap>(LCVal->getRegion());
+  }
+  return nullptr;
+}
+
+const IteratorPosition *getIteratorPosition(ProgramStateRef State,
+                                            RegionOrSymbol RegOrSym) {
+  if (RegOrSym.is<const MemRegion *>()) {
+    return State->get<IteratorRegionMap>(RegOrSym.get<const MemRegion *>());
+  } else if (RegOrSym.is<SymbolRef>()) {
+    return State->get<IteratorSymbolMap>(RegOrSym.get<SymbolRef>());
+  }
+  return nullptr;
+}
+
+ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val,
+                                    IteratorPosition Pos) {
+  if (const auto Reg = Val.getAsRegion()) {
+    return State->set<IteratorRegionMap>(Reg, Pos);
+  } else if (const auto Sym = Val.getAsSymbol()) {
+    return State->set<IteratorSymbolMap>(Sym, Pos);
+  } else if (const auto LCVal = Val.getAs<nonloc::LazyCompoundVal>()) {
+    return State->set<IteratorRegionMap>(LCVal->getRegion(), Pos);
+  }
+  return nullptr;
+}
+
+ProgramStateRef setIteratorPosition(ProgramStateRef State,
+                                    RegionOrSymbol RegOrSym,
+                                    IteratorPosition Pos) {
+  if (RegOrSym.is<const MemRegion *>()) {
+    return State->set<IteratorRegionMap>(RegOrSym.get<const MemRegion *>(),
+                                         Pos);
+  } else if (RegOrSym.is<SymbolRef>()) {
+    return State->set<IteratorSymbolMap>(RegOrSym.get<SymbolRef>(), Pos);
+  }
+  return nullptr;
+}
+
+ProgramStateRef adjustIteratorPosition(ProgramStateRef State,
+                                       RegionOrSymbol RegOrSym,
+                                       IteratorPosition Pos, bool Equal) {
+
+  if ((Pos.isInRange() && Equal) || (Pos.isOutofRange() && !Equal)) {
+    return setIteratorPosition(State, RegOrSym, IteratorPosition::getInRange());
+  } else if (Pos.isOutofRange() && Equal) {
+    return setIteratorPosition(State, RegOrSym,
+                               IteratorPosition::getOutofRange());
+  } else {
+    return State;
+  }
+}
+
+bool contradictingIteratorPositions(IteratorPosition Pos1,
+                                    IteratorPosition Pos2, bool Equal) {
+  return ((Pos1 != Pos2) && Equal) ||
+         ((Pos1.isOutofRange() && Pos2.isOutofRange()) && !Equal);
+}
+}
+
+void ento::registerIteratorPastEndChecker(CheckerManager &Mgr) {
+  Mgr.registerChecker<IteratorPastEndChecker>();
+}
diff --git a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
index d1dab6d..af35c2b 100644
--- a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
@@ -123,10 +123,10 @@
         assert(NonLocalizedString);
   }
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
-                                 const ExplodedNode *Pred,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+                                                 const ExplodedNode *Pred,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 
   void Profile(llvm::FoldingSetNodeID &ID) const override {
     ID.Add(NonLocalizedString);
@@ -910,7 +910,7 @@
   setNonLocalizedState(sv, C);
 }
 
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
 NonLocalizedStringBRVisitor::VisitNode(const ExplodedNode *Succ,
                                        const ExplodedNode *Pred,
                                        BugReporterContext &BRC, BugReport &BR) {
@@ -938,11 +938,11 @@
   if (!L.isValid() || !L.asLocation().isValid())
     return nullptr;
 
-  auto *Piece = new PathDiagnosticEventPiece(L,
-      "Non-localized string literal here");
+  auto Piece = std::make_shared<PathDiagnosticEventPiece>(
+      L, "Non-localized string literal here");
   Piece->addRange(LiteralExpr->getSourceRange());
 
-  return Piece;
+  return std::move(Piece);
 }
 
 namespace {
diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
index d56ea6d..e9ec7a0 100644
--- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
+++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
@@ -85,9 +85,11 @@
   BReporter.emitReport(std::move(Report));
 }
 
-PathDiagnosticPiece *MPIBugReporter::RequestNodeVisitor::VisitNode(
-    const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
-    BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+MPIBugReporter::RequestNodeVisitor::VisitNode(const ExplodedNode *N,
+                                              const ExplodedNode *PrevN,
+                                              BugReporterContext &BRC,
+                                              BugReport &BR) {
 
   if (IsNodeFound)
     return nullptr;
@@ -104,7 +106,7 @@
     PathDiagnosticLocation L =
         PathDiagnosticLocation::create(P, BRC.getSourceManager());
 
-    return new PathDiagnosticEventPiece(L, ErrorText);
+    return std::make_shared<PathDiagnosticEventPiece>(L, ErrorText);
   }
 
   return nullptr;
diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
index 8474d2d..0ee91cc 100644
--- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
+++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
@@ -90,10 +90,10 @@
       ID.AddPointer(RequestRegion);
     }
 
-    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                   const ExplodedNode *PrevN,
-                                   BugReporterContext &BRC,
-                                   BugReport &BR) override;
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
 
   private:
     const MemRegion *const RequestRegion;
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
index 86c8270..f8473db 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -28,7 +28,8 @@
 namespace {
 class MacOSKeychainAPIChecker : public Checker<check::PreStmt<CallExpr>,
                                                check::PostStmt<CallExpr>,
-                                               check::DeadSymbols> {
+                                               check::DeadSymbols,
+                                               eval::Assume> {
   mutable std::unique_ptr<BugType> BT;
 
 public:
@@ -57,6 +58,10 @@
   void checkPreStmt(const CallExpr *S, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *S, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
+  ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
+                             bool Assumption) const;
+  void printState(raw_ostream &Out, ProgramStateRef State,
+                  const char *NL, const char *Sep) const;
 
 private:
   typedef std::pair<SymbolRef, const AllocationState*> AllocationPair;
@@ -106,19 +111,6 @@
   std::unique_ptr<BugReport> generateAllocatedDataNotReleasedReport(
       const AllocationPair &AP, ExplodedNode *N, CheckerContext &C) const;
 
-  /// Check if RetSym evaluates to an error value in the current state.
-  bool definitelyReturnedError(SymbolRef RetSym,
-                               ProgramStateRef State,
-                               SValBuilder &Builder,
-                               bool noError = false) const;
-
-  /// Check if RetSym evaluates to a NoErr value in the current state.
-  bool definitelyDidnotReturnError(SymbolRef RetSym,
-                                   ProgramStateRef State,
-                                   SValBuilder &Builder) const {
-    return definitelyReturnedError(RetSym, State, Builder, true);
-  }
-
   /// Mark an AllocationPair interesting for diagnostic reporting.
   void markInteresting(BugReport *R, const AllocationPair &AP) const {
     R->markInteresting(AP.first);
@@ -143,10 +135,10 @@
       ID.AddPointer(Sym);
     }
 
-    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                   const ExplodedNode *PrevN,
-                                   BugReporterContext &BRC,
-                                   BugReport &BR) override;
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
   };
 };
 }
@@ -221,24 +213,6 @@
   return nullptr;
 }
 
-// When checking for error code, we need to consider the following cases:
-// 1) noErr / [0]
-// 2) someErr / [1, inf]
-// 3) unknown
-// If noError, returns true iff (1).
-// If !noError, returns true iff (2).
-bool MacOSKeychainAPIChecker::definitelyReturnedError(SymbolRef RetSym,
-                                                      ProgramStateRef State,
-                                                      SValBuilder &Builder,
-                                                      bool noError) const {
-  DefinedOrUnknownSVal NoErrVal = Builder.makeIntVal(NoErr,
-    Builder.getSymbolManager().getType(RetSym));
-  DefinedOrUnknownSVal NoErr = Builder.evalEQ(State, NoErrVal,
-                                                     nonloc::SymbolVal(RetSym));
-  ProgramStateRef ErrState = State->assume(NoErr, noError);
-  return ErrState == State;
-}
-
 // Report deallocator mismatch. Remove the region from tracking - reporting a
 // missing free error after this one is redundant.
 void MacOSKeychainAPIChecker::
@@ -289,27 +263,25 @@
     const Expr *ArgExpr = CE->getArg(paramIdx);
     if (SymbolRef V = getAsPointeeSymbol(ArgExpr, C))
       if (const AllocationState *AS = State->get<AllocatedData>(V)) {
-        if (!definitelyReturnedError(AS->Region, State, C.getSValBuilder())) {
-          // Remove the value from the state. The new symbol will be added for
-          // tracking when the second allocator is processed in checkPostStmt().
-          State = State->remove<AllocatedData>(V);
-          ExplodedNode *N = C.generateNonFatalErrorNode(State);
-          if (!N)
-            return;
-          initBugType();
-          SmallString<128> sbuf;
-          llvm::raw_svector_ostream os(sbuf);
-          unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx;
-          os << "Allocated data should be released before another call to "
-              << "the allocator: missing a call to '"
-              << FunctionsToTrack[DIdx].Name
-              << "'.";
-          auto Report = llvm::make_unique<BugReport>(*BT, os.str(), N);
-          Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(V));
-          Report->addRange(ArgExpr->getSourceRange());
-          Report->markInteresting(AS->Region);
-          C.emitReport(std::move(Report));
-        }
+        // Remove the value from the state. The new symbol will be added for
+        // tracking when the second allocator is processed in checkPostStmt().
+        State = State->remove<AllocatedData>(V);
+        ExplodedNode *N = C.generateNonFatalErrorNode(State);
+        if (!N)
+          return;
+        initBugType();
+        SmallString<128> sbuf;
+        llvm::raw_svector_ostream os(sbuf);
+        unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx;
+        os << "Allocated data should be released before another call to "
+            << "the allocator: missing a call to '"
+            << FunctionsToTrack[DIdx].Name
+            << "'.";
+        auto Report = llvm::make_unique<BugReport>(*BT, os.str(), N);
+        Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(V));
+        Report->addRange(ArgExpr->getSourceRange());
+        Report->markInteresting(AS->Region);
+        C.emitReport(std::move(Report));
       }
     return;
   }
@@ -344,13 +316,12 @@
 
   // Is the argument to the call being tracked?
   const AllocationState *AS = State->get<AllocatedData>(ArgSM);
-  if (!AS && FunctionsToTrack[idx].Kind != ValidAPI) {
+  if (!AS)
     return;
-  }
-  // If trying to free data which has not been allocated yet, report as a bug.
-  // TODO: We might want a more precise diagnostic for double free
+
+  // TODO: We might want to report double free here.
   // (that would involve tracking all the freed symbols in the checker state).
-  if (!AS || RegionArgIsBad) {
+  if (RegionArgIsBad) {
     // It is possible that this is a false positive - the argument might
     // have entered as an enclosing function parameter.
     if (isEnclosingFunctionParam(ArgExpr))
@@ -418,23 +389,6 @@
     return;
   }
 
-  // If the buffer can be null and the return status can be an error,
-  // report a bad call to free.
-  if (State->assume(ArgSVal.castAs<DefinedSVal>(), false) &&
-      !definitelyDidnotReturnError(AS->Region, State, C.getSValBuilder())) {
-    ExplodedNode *N = C.generateNonFatalErrorNode(State);
-    if (!N)
-      return;
-    initBugType();
-    auto Report = llvm::make_unique<BugReport>(
-        *BT, "Only call free if a valid (non-NULL) buffer was returned.", N);
-    Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(ArgSM));
-    Report->addRange(ArgExpr->getSourceRange());
-    Report->markInteresting(AS->Region);
-    C.emitReport(std::move(Report));
-    return;
-  }
-
   C.addTransition(State);
 }
 
@@ -540,27 +494,63 @@
   return Report;
 }
 
+/// If the return symbol is assumed to be error, remove the allocated info
+/// from consideration.
+ProgramStateRef MacOSKeychainAPIChecker::evalAssume(ProgramStateRef State,
+                                                    SVal Cond,
+                                                    bool Assumption) const {
+  AllocatedDataTy AMap = State->get<AllocatedData>();
+  if (AMap.isEmpty())
+    return State;
+
+  auto *CondBSE = dyn_cast_or_null<BinarySymExpr>(Cond.getAsSymExpr());
+  if (!CondBSE)
+    return State;
+  BinaryOperator::Opcode OpCode = CondBSE->getOpcode();
+  if (OpCode != BO_EQ && OpCode != BO_NE)
+    return State;
+
+  // Match for a restricted set of patterns for cmparison of error codes.
+  // Note, the comparisons of type '0 == st' are transformed into SymIntExpr.
+  SymbolRef ReturnSymbol = nullptr;
+  if (auto *SIE = dyn_cast<SymIntExpr>(CondBSE)) {
+    const llvm::APInt &RHS = SIE->getRHS();
+    bool ErrorIsReturned = (OpCode == BO_EQ && RHS != NoErr) ||
+                           (OpCode == BO_NE && RHS == NoErr);
+    if (!Assumption)
+      ErrorIsReturned = !ErrorIsReturned;
+    if (ErrorIsReturned)
+      ReturnSymbol = SIE->getLHS();
+  }
+
+  if (ReturnSymbol)
+    for (auto I = AMap.begin(), E = AMap.end(); I != E; ++I) {
+      if (ReturnSymbol == I->second.Region)
+        State = State->remove<AllocatedData>(I->first);
+    }
+
+  return State;
+}
+
 void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
                                                CheckerContext &C) const {
   ProgramStateRef State = C.getState();
-  AllocatedDataTy ASet = State->get<AllocatedData>();
-  if (ASet.isEmpty())
+  AllocatedDataTy AMap = State->get<AllocatedData>();
+  if (AMap.isEmpty())
     return;
 
   bool Changed = false;
   AllocationPairVec Errors;
-  for (AllocatedDataTy::iterator I = ASet.begin(), E = ASet.end(); I != E; ++I) {
-    if (SR.isLive(I->first))
+  for (auto I = AMap.begin(), E = AMap.end(); I != E; ++I) {
+    if (!SR.isDead(I->first))
       continue;
 
     Changed = true;
     State = State->remove<AllocatedData>(I->first);
-    // If the allocated symbol is null or if the allocation call might have
-    // returned an error, do not report.
+    // If the allocated symbol is null do not report.
     ConstraintManager &CMgr = State->getConstraintManager();
     ConditionTruthVal AllocFailed = CMgr.isNull(State, I.getKey());
-    if (AllocFailed.isConstrainedTrue() ||
-        definitelyReturnedError(I->second.Region, State, C.getSValBuilder()))
+    if (AllocFailed.isConstrainedTrue())
       continue;
     Errors.push_back(std::make_pair(I->first, &I->second));
   }
@@ -583,12 +573,10 @@
   C.addTransition(State, N);
 }
 
-
-PathDiagnosticPiece *MacOSKeychainAPIChecker::SecKeychainBugVisitor::VisitNode(
-                                                      const ExplodedNode *N,
-                                                      const ExplodedNode *PrevN,
-                                                      BugReporterContext &BRC,
-                                                      BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+MacOSKeychainAPIChecker::SecKeychainBugVisitor::VisitNode(
+    const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
+    BugReport &BR) {
   const AllocationState *AS = N->getState()->get<AllocatedData>(Sym);
   if (!AS)
     return nullptr;
@@ -610,9 +598,26 @@
   const Expr *ArgExpr = CE->getArg(FunctionsToTrack[Idx].Param);
   PathDiagnosticLocation Pos(ArgExpr, BRC.getSourceManager(),
                              N->getLocationContext());
-  return new PathDiagnosticEventPiece(Pos, "Data is allocated here.");
+  return std::make_shared<PathDiagnosticEventPiece>(Pos,
+                                                    "Data is allocated here.");
 }
 
+void MacOSKeychainAPIChecker::printState(raw_ostream &Out,
+                                         ProgramStateRef State,
+                                         const char *NL,
+                                         const char *Sep) const {
+
+  AllocatedDataTy AMap = State->get<AllocatedData>();
+
+  if (!AMap.isEmpty()) {
+    Out << Sep << "KeychainAPIChecker :" << NL;
+    for (auto I = AMap.begin(), E = AMap.end(); I != E; ++I) {
+      I.getKey()->dumpToStream(Out);
+    }
+  }
+}
+
+
 void ento::registerMacOSKeychainAPIChecker(CheckerManager &mgr) {
   mgr.registerChecker<MacOSKeychainAPIChecker>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
index 0e0f52a..437378e 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
@@ -94,11 +94,18 @@
   bool SuggestStatic = false;
   os << "Call to '" << FName << "' uses";
   if (const VarRegion *VR = dyn_cast<VarRegion>(RB)) {
+    const VarDecl *VD = VR->getDecl();
+    // FIXME: These should have correct memory space and thus should be filtered
+    // out earlier. This branch only fires when we're looking from a block,
+    // which we analyze as a top-level declaration, onto a static local
+    // in a function that contains the block.
+    if (VD->isStaticLocal())
+      return;
     // We filtered out globals earlier, so it must be a local variable
     // or a block variable which is under UnknownSpaceRegion.
     if (VR != R)
       os << " memory within";
-    if (VR->getDecl()->hasAttr<BlocksAttr>())
+    if (VD->hasAttr<BlocksAttr>())
       os << " the block variable '";
     else
       os << " the local variable '";
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index a00fd1d..6e9b7fe 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -174,7 +174,10 @@
         II_valloc(nullptr), II_reallocf(nullptr), II_strndup(nullptr),
         II_strdup(nullptr), II_win_strdup(nullptr), II_kmalloc(nullptr),
         II_if_nameindex(nullptr), II_if_freenameindex(nullptr),
-        II_wcsdup(nullptr), II_win_wcsdup(nullptr) {}
+        II_wcsdup(nullptr), II_win_wcsdup(nullptr), II_g_malloc(nullptr),
+        II_g_malloc0(nullptr), II_g_realloc(nullptr), II_g_try_malloc(nullptr), 
+        II_g_try_malloc0(nullptr), II_g_try_realloc(nullptr), 
+        II_g_free(nullptr), II_g_memdup(nullptr) {}
 
   /// In pessimistic mode, the checker assumes that it does not know which
   /// functions might free the memory.
@@ -236,7 +239,9 @@
                          *II_realloc, *II_calloc, *II_valloc, *II_reallocf,
                          *II_strndup, *II_strdup, *II_win_strdup, *II_kmalloc,
                          *II_if_nameindex, *II_if_freenameindex, *II_wcsdup,
-                         *II_win_wcsdup;
+                         *II_win_wcsdup, *II_g_malloc, *II_g_malloc0, 
+                         *II_g_realloc, *II_g_try_malloc, *II_g_try_malloc0, 
+                         *II_g_try_realloc, *II_g_free, *II_g_memdup;
   mutable Optional<uint64_t> KernelZeroFlagVal;
 
   void initIdentifierInfo(ASTContext &C) const;
@@ -463,10 +468,10 @@
                           SPrev->isAllocatedOfSizeZero())));
     }
 
-    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                   const ExplodedNode *PrevN,
-                                   BugReporterContext &BRC,
-                                   BugReport &BR) override;
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
 
     std::unique_ptr<PathDiagnosticPiece>
     getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
@@ -554,6 +559,16 @@
   II_win_strdup = &Ctx.Idents.get("_strdup");
   II_win_wcsdup = &Ctx.Idents.get("_wcsdup");
   II_win_alloca = &Ctx.Idents.get("_alloca");
+
+  // Glib
+  II_g_malloc = &Ctx.Idents.get("g_malloc");
+  II_g_malloc0 = &Ctx.Idents.get("g_malloc0");
+  II_g_realloc = &Ctx.Idents.get("g_realloc");
+  II_g_try_malloc = &Ctx.Idents.get("g_try_malloc");
+  II_g_try_malloc0 = &Ctx.Idents.get("g_try_malloc0");
+  II_g_try_realloc = &Ctx.Idents.get("g_try_realloc");
+  II_g_free = &Ctx.Idents.get("g_free");
+  II_g_memdup = &Ctx.Idents.get("g_memdup");
 }
 
 bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
@@ -589,7 +604,8 @@
     initIdentifierInfo(C);
 
     if (Family == AF_Malloc && CheckFree) {
-      if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf)
+      if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf || 
+          FunI == II_g_free)
         return true;
     }
 
@@ -597,7 +613,11 @@
       if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf ||
           FunI == II_calloc || FunI == II_valloc || FunI == II_strdup ||
           FunI == II_win_strdup || FunI == II_strndup || FunI == II_wcsdup ||
-          FunI == II_win_wcsdup || FunI == II_kmalloc)
+          FunI == II_win_wcsdup || FunI == II_kmalloc ||
+          FunI == II_g_malloc || FunI == II_g_malloc0 || 
+          FunI == II_g_realloc || FunI == II_g_try_malloc || 
+          FunI == II_g_try_malloc0 || FunI == II_g_try_realloc ||
+          FunI == II_g_memdup)
         return true;
     }
 
@@ -762,7 +782,7 @@
     initIdentifierInfo(C.getASTContext());
     IdentifierInfo *FunI = FD->getIdentifier();
 
-    if (FunI == II_malloc) {
+    if (FunI == II_malloc || FunI == II_g_malloc || FunI == II_g_try_malloc) {
       if (CE->getNumArgs() < 1)
         return;
       if (CE->getNumArgs() < 3) {
@@ -791,7 +811,8 @@
         return;
       State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
       State = ProcessZeroAllocation(C, CE, 0, State);
-    } else if (FunI == II_realloc) {
+    } else if (FunI == II_realloc || FunI == II_g_realloc || 
+               FunI == II_g_try_realloc) {
       State = ReallocMem(C, CE, false, State);
       State = ProcessZeroAllocation(C, CE, 1, State);
     } else if (FunI == II_reallocf) {
@@ -801,7 +822,7 @@
       State = CallocMem(C, CE, State);
       State = ProcessZeroAllocation(C, CE, 0, State);
       State = ProcessZeroAllocation(C, CE, 1, State);
-    } else if (FunI == II_free) {
+    } else if (FunI == II_free || FunI == II_g_free) {
       State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
     } else if (FunI == II_strdup || FunI == II_win_strdup ||
                FunI == II_wcsdup || FunI == II_win_wcsdup) {
@@ -841,6 +862,18 @@
                            AF_IfNameIndex);
     } else if (FunI == II_if_freenameindex) {
       State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
+    } else if (FunI == II_g_malloc0 || FunI == II_g_try_malloc0) {
+      if (CE->getNumArgs() < 1)
+        return;
+      SValBuilder &svalBuilder = C.getSValBuilder();
+      SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
+      State = MallocMemAux(C, CE, CE->getArg(0), zeroVal, State);
+      State = ProcessZeroAllocation(C, CE, 0, State);
+    } else if (FunI == II_g_memdup) {
+      if (CE->getNumArgs() < 2)
+        return;
+      State = MallocMemAux(C, CE, CE->getArg(1), UndefinedVal(), State);
+      State = ProcessZeroAllocation(C, CE, 1, State);
     }
   }
 
@@ -1026,8 +1059,7 @@
   ASTContext &AstContext = C.getASTContext();
   CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType);
 
-  if (Optional<DefinedOrUnknownSVal> DefinedSize =
-          ElementCount.getAs<DefinedOrUnknownSVal>()) {
+  if (ElementCount.getAs<NonLoc>()) {
     DefinedOrUnknownSVal Extent = Region->getExtent(svalBuilder);
     // size in Bytes = ElementCount*TypeSize
     SVal SizeInBytes = svalBuilder.evalBinOpNN(
@@ -1155,7 +1187,7 @@
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
 
   // Fill the region with the initialization value.
-  State = State->bindDefault(RetVal, Init);
+  State = State->bindDefault(RetVal, Init, LCtx);
 
   // Set the region's extent equal to the Size parameter.
   const SymbolicRegion *R =
@@ -2579,6 +2611,11 @@
     return true;
   }
 
+  if (FName == "connectImpl" &&
+      FD->getQualifiedNameAsString() == "QObject::connectImpl") {
+    return true;
+  }
+
   // Handle cases where we know a buffer's /address/ can escape.
   // Note that the above checks handle some special cases where we know that
   // even though the address escapes, it's still our responsibility to free the
@@ -2664,11 +2701,9 @@
   return nullptr;
 }
 
-PathDiagnosticPiece *
-MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
-                                           const ExplodedNode *PrevN,
-                                           BugReporterContext &BRC,
-                                           BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece> MallocChecker::MallocBugVisitor::VisitNode(
+    const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
+    BugReport &BR) {
   ProgramStateRef state = N->getState();
   ProgramStateRef statePrev = PrevN->getState();
 
@@ -2736,7 +2771,7 @@
   // Generate the extra diagnostic.
   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
                              N->getLocationContext());
-  return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint);
+  return std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true, StackHint);
 }
 
 void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
diff --git a/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
index 4e2aace..c14a87c 100644
--- a/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
@@ -153,10 +153,10 @@
       ID.AddPointer(Region);
     }
 
-    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                   const ExplodedNode *PrevN,
-                                   BugReporterContext &BRC,
-                                   BugReport &BR) override;
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
 
   private:
     // The tracked region.
@@ -306,9 +306,11 @@
   return dyn_cast<SymbolicRegion>(Region);
 }
 
-PathDiagnosticPiece *NullabilityChecker::NullabilityBugVisitor::VisitNode(
-    const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
-    BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+NullabilityChecker::NullabilityBugVisitor::VisitNode(const ExplodedNode *N,
+                                                     const ExplodedNode *PrevN,
+                                                     BugReporterContext &BRC,
+                                                     BugReport &BR) {
   ProgramStateRef State = N->getState();
   ProgramStateRef StatePrev = PrevN->getState();
 
@@ -339,7 +341,8 @@
   // Generate the extra diagnostic.
   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
                              N->getLocationContext());
-  return new PathDiagnosticEventPiece(Pos, InfoText, true, nullptr);
+  return std::make_shared<PathDiagnosticEventPiece>(Pos, InfoText, true,
+                                                    nullptr);
 }
 
 static Nullability getNullabilityAnnotation(QualType Type) {
@@ -610,9 +613,9 @@
 
     SmallString<256> SBuf;
     llvm::raw_svector_ostream OS(SBuf);
-    OS << "Null is returned from a " << C.getDeclDescription(D) <<
+    OS << (RetExpr->getType()->isObjCObjectPointerType() ? "nil" : "Null");
+    OS << " returned from a " << C.getDeclDescription(D) <<
           " that is expected to return a non-null value";
-
     reportBugIfInvariantHolds(OS.str(),
                               ErrorKind::NilReturnedToNonnull, N, nullptr, C,
                               RetExpr);
@@ -707,9 +710,11 @@
       ExplodedNode *N = C.generateErrorNode(State);
       if (!N)
         return;
+
       SmallString<256> SBuf;
       llvm::raw_svector_ostream OS(SBuf);
-      OS << "Null passed to a callee that requires a non-null " << ParamIdx
+      OS << (Param->getType()->isObjCObjectPointerType() ? "nil" : "Null");
+      OS << " passed to a callee that requires a non-null " << ParamIdx
          << llvm::getOrdinalSuffix(ParamIdx) << " parameter";
       reportBugIfInvariantHolds(OS.str(), ErrorKind::NilPassedToNonnull, N,
                                 nullptr, C,
@@ -1128,8 +1133,11 @@
     if (ValueExpr)
       ValueStmt = ValueExpr;
 
-    reportBugIfInvariantHolds("Null is assigned to a pointer which is "
-                              "expected to have non-null value",
+    SmallString<256> SBuf;
+    llvm::raw_svector_ostream OS(SBuf);
+    OS << (LocType->isObjCObjectPointerType() ? "nil" : "Null");
+    OS << " assigned to a pointer which is expected to have non-null value";
+    reportBugIfInvariantHolds(OS.str(),
                               ErrorKind::NilAssignedToNonnull, N, nullptr, C,
                               ValueStmt);
     return;
diff --git a/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp
new file mode 100644
index 0000000..dfd2c9a
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp
@@ -0,0 +1,81 @@
+//==- ObjCPropertyChecker.cpp - Check ObjC properties ------------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This checker finds issues with Objective-C properties.
+//  Currently finds only one kind of issue:
+//  - Find synthesized properties with copy attribute of mutable NS collection
+//    types. Calling -copy on such collections produces an immutable copy,
+//    which contradicts the type of the property.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class ObjCPropertyChecker
+    : public Checker<check::ASTDecl<ObjCPropertyDecl>> {
+  void checkCopyMutable(const ObjCPropertyDecl *D, BugReporter &BR) const;
+
+public:
+  void checkASTDecl(const ObjCPropertyDecl *D, AnalysisManager &Mgr,
+                    BugReporter &BR) const;
+};
+} // end anonymous namespace.
+
+void ObjCPropertyChecker::checkASTDecl(const ObjCPropertyDecl *D,
+                                       AnalysisManager &Mgr,
+                                       BugReporter &BR) const {
+  checkCopyMutable(D, BR);
+}
+
+void ObjCPropertyChecker::checkCopyMutable(const ObjCPropertyDecl *D,
+                                           BugReporter &BR) const {
+  if (D->isReadOnly() || D->getSetterKind() != ObjCPropertyDecl::Copy)
+    return;
+
+  QualType T = D->getType();
+  if (!T->isObjCObjectPointerType())
+    return;
+
+  const std::string &PropTypeName(T->getPointeeType().getCanonicalType()
+                                                     .getUnqualifiedType()
+                                                     .getAsString());
+  if (!StringRef(PropTypeName).startswith("NSMutable"))
+    return;
+
+  const ObjCImplDecl *ImplD = nullptr;
+  if (const ObjCInterfaceDecl *IntD =
+          dyn_cast<ObjCInterfaceDecl>(D->getDeclContext())) {
+    ImplD = IntD->getImplementation();
+  } else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext())) {
+    ImplD = CatD->getClassInterface()->getImplementation();
+  }
+
+  if (!ImplD || ImplD->HasUserDeclaredSetterMethod(D))
+    return;
+
+  SmallString<128> Str;
+  llvm::raw_svector_ostream OS(Str);
+  OS << "Property of mutable type '" << PropTypeName
+     << "' has 'copy' attribute; an immutable object will be stored instead";
+
+  BR.EmitBasicReport(
+      D, this, "Objective-C property misuse", "Logic error", OS.str(),
+      PathDiagnosticLocation::createBegin(D, BR.getSourceManager()),
+      D->getSourceRange());
+}
+
+void ento::registerObjCPropertyChecker(CheckerManager &Mgr) {
+  Mgr.registerChecker<ObjCPropertyChecker>();
+}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
index e75d208..075ff09 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
@@ -73,10 +73,10 @@
       : ReceiverSymbol(ReceiverSymbol),
         Satisfied(false) {}
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
-                                 const ExplodedNode *Pred,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+                                                 const ExplodedNode *Pred,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 
   void Profile(llvm::FoldingSetNodeID &ID) const override {
     ID.Add(ReceiverSymbol);
@@ -249,10 +249,10 @@
   return M.getSelector() == SELdealloc;
 }
 
-PathDiagnosticPiece *SuperDeallocBRVisitor::VisitNode(const ExplodedNode *Succ,
-                                                      const ExplodedNode *Pred,
-                                                      BugReporterContext &BRC,
-                                                      BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+SuperDeallocBRVisitor::VisitNode(const ExplodedNode *Succ,
+                                 const ExplodedNode *Pred,
+                                 BugReporterContext &BRC, BugReport &BR) {
   if (Satisfied)
     return nullptr;
 
@@ -275,7 +275,7 @@
     if (!L.isValid() || !L.asLocation().isValid())
       return nullptr;
 
-    return new PathDiagnosticEventPiece(
+    return std::make_shared<PathDiagnosticEventPiece>(
         L, "[super dealloc] called here");
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index b7d1670..3f6ae62 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1773,10 +1773,10 @@
       ID.AddPointer(Sym);
     }
 
-    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                   const ExplodedNode *PrevN,
-                                   BugReporterContext &BRC,
-                                   BugReport &BR) override;
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
 
     std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
                                                     const ExplodedNode *N,
@@ -1899,10 +1899,9 @@
   return SFC->getAnalysisDeclContext()->isBodyAutosynthesized();
 }
 
-PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
-                                                   const ExplodedNode *PrevN,
-                                                   BugReporterContext &BRC,
-                                                   BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN,
+                              BugReporterContext &BRC, BugReport &BR) {
   // FIXME: We will eventually need to handle non-statement-based events
   // (__attribute__((cleanup))).
   if (!N->getLocation().getAs<StmtPoint>())
@@ -1990,11 +1989,23 @@
       }
 
       if (CurrV.getObjKind() == RetEffect::CF) {
-        os << " returns a Core Foundation object with a ";
+        if (Sym->getType().isNull()) {
+          os << " returns a Core Foundation object with a ";
+        } else {
+          os << " returns a Core Foundation object of type "
+             << Sym->getType().getAsString() << " with a ";
+        }
       }
       else {
         assert (CurrV.getObjKind() == RetEffect::ObjC);
-        os << " returns an Objective-C object with a ";
+        QualType T = Sym->getType();
+        if (T.isNull() || !isa<ObjCObjectPointerType>(T)) {
+          os << " returns an Objective-C object with a ";
+        } else {
+          const ObjCObjectPointerType *PT = cast<ObjCObjectPointerType>(T);
+          os << " returns an instance of "
+             << PT->getPointeeType().getAsString() << " with a ";
+        }
       }
 
       if (CurrV.isOwned()) {
@@ -2014,7 +2025,7 @@
 
     PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
                                   N->getLocationContext());
-    return new PathDiagnosticEventPiece(Pos, os.str());
+    return std::make_shared<PathDiagnosticEventPiece>(Pos, os.str());
   }
 
   // Gather up the effects that were performed on the object at this
@@ -2191,7 +2202,7 @@
   const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
                                 N->getLocationContext());
-  PathDiagnosticPiece *P = new PathDiagnosticEventPiece(Pos, os.str());
+  auto P = std::make_shared<PathDiagnosticEventPiece>(Pos, os.str());
 
   // Add the range by scanning the children of the statement for any bindings
   // to Sym.
@@ -2202,7 +2213,7 @@
         break;
       }
 
-  return P;
+  return std::move(P);
 }
 
 namespace {
@@ -2650,6 +2661,7 @@
                      const InvalidatedSymbols *invalidated,
                      ArrayRef<const MemRegion *> ExplicitRegions,
                      ArrayRef<const MemRegion *> Regions,
+                     const LocationContext* LCtx,
                      const CallEvent *Call) const;
 
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
@@ -3636,7 +3648,7 @@
       // same state.
       SVal StoredVal = state->getSVal(regionLoc->getRegion());
       if (StoredVal != val)
-        escapes = (state == (state->bindLoc(*regionLoc, val)));
+        escapes = (state == (state->bindLoc(*regionLoc, val, C.getLocationContext())));
     }
     if (!escapes) {
       // Case 4: We do not currently model what happens when a symbol is
@@ -3703,10 +3715,11 @@
 
 ProgramStateRef
 RetainCountChecker::checkRegionChanges(ProgramStateRef state,
-                                    const InvalidatedSymbols *invalidated,
-                                    ArrayRef<const MemRegion *> ExplicitRegions,
-                                    ArrayRef<const MemRegion *> Regions,
-                                    const CallEvent *Call) const {
+                                       const InvalidatedSymbols *invalidated,
+                                       ArrayRef<const MemRegion *> ExplicitRegions,
+                                       ArrayRef<const MemRegion *> Regions,
+                                       const LocationContext *LCtx,
+                                       const CallEvent *Call) const {
   if (!invalidated)
     return state;
 
diff --git a/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
index b794d2f..5268bbf 100644
--- a/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
@@ -70,10 +70,10 @@
     ID.Add(SFC);
   }
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
-                                 const ExplodedNode *Pred,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override;
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+                                                 const ExplodedNode *Pred,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
 };
 
 class TestAfterDivZeroChecker
@@ -94,10 +94,9 @@
 
 REGISTER_SET_WITH_PROGRAMSTATE(DivZeroMap, ZeroState)
 
-PathDiagnosticPiece *DivisionBRVisitor::VisitNode(const ExplodedNode *Succ,
-                                                  const ExplodedNode *Pred,
-                                                  BugReporterContext &BRC,
-                                                  BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+DivisionBRVisitor::VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred,
+                             BugReporterContext &BRC, BugReport &BR) {
   if (Satisfied)
     return nullptr;
 
@@ -128,7 +127,7 @@
     if (!L.isValid() || !L.asLocation().isValid())
       return nullptr;
 
-    return new PathDiagnosticEventPiece(
+    return std::make_shared<PathDiagnosticEventPiece>(
         L, "Division with compared value made here");
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
index 38d2aa6..f3c2ffc 100644
--- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -35,6 +35,30 @@
 };
 } // end anonymous namespace
 
+static bool isArrayIndexOutOfBounds(CheckerContext &C, const Expr *Ex) {
+  ProgramStateRef state = C.getState();
+  const LocationContext *LCtx = C.getLocationContext();
+
+  if (!isa<ArraySubscriptExpr>(Ex))
+    return false;
+
+  SVal Loc = state->getSVal(Ex, LCtx);
+  if (!Loc.isValid())
+    return false;
+
+  const MemRegion *MR = Loc.castAs<loc::MemRegionVal>().getRegion();
+  const ElementRegion *ER = dyn_cast<ElementRegion>(MR);
+  if (!ER)
+    return false;
+
+  DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
+  DefinedOrUnknownSVal NumElements = C.getStoreManager().getSizeInElements(
+      state, ER->getSuperRegion(), ER->getValueType());
+  ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
+  ProgramStateRef StOutBound = state->assumeInBound(Idx, NumElements, false);
+  return StOutBound && !StInBound;
+}
+
 void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
                                        CheckerContext &C) const {
   ProgramStateRef state = C.getState();
@@ -77,6 +101,8 @@
          << " operand of '"
          << BinaryOperator::getOpcodeStr(B->getOpcode())
          << "' is a garbage value";
+      if (isArrayIndexOutOfBounds(C, Ex))
+        OS << " due to array index out of bounds";
     }
     else {
       // Neither operand was undefined, but the result is undefined.
diff --git a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index c9dafb5..26bf597 100644
--- a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -21,6 +21,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/raw_ostream.h"
 #include <fcntl.h>
@@ -28,6 +29,16 @@
 using namespace clang;
 using namespace ento;
 
+enum class OpenVariant {
+  /// The standard open() call:
+  ///    int open(const char *path, int oflag, ...);
+  Open,
+
+  /// The variant taking a directory file descriptor and a relative path:
+  ///    int openat(int fd, const char *path, int oflag, ...);
+  OpenAt
+};
+
 namespace {
 class UnixAPIChecker : public Checker< check::PreStmt<CallExpr> > {
   mutable std::unique_ptr<BugType> BT_open, BT_pthreadOnce, BT_mallocZero;
@@ -37,6 +48,8 @@
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
 
   void CheckOpen(CheckerContext &C, const CallExpr *CE) const;
+  void CheckOpenAt(CheckerContext &C, const CallExpr *CE) const;
+
   void CheckPthreadOnce(CheckerContext &C, const CallExpr *CE) const;
   void CheckCallocZero(CheckerContext &C, const CallExpr *CE) const;
   void CheckMallocZero(CheckerContext &C, const CallExpr *CE) const;
@@ -49,6 +62,10 @@
   typedef void (UnixAPIChecker::*SubChecker)(CheckerContext &,
                                              const CallExpr *) const;
 private:
+
+  void CheckOpenVariant(CheckerContext &C,
+                        const CallExpr *CE, OpenVariant Variant) const;
+
   bool ReportZeroByteAllocation(CheckerContext &C,
                                 ProgramStateRef falseState,
                                 const Expr *arg,
@@ -90,25 +107,71 @@
 }
 
 void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
+  CheckOpenVariant(C, CE, OpenVariant::Open);
+}
+
+void UnixAPIChecker::CheckOpenAt(CheckerContext &C, const CallExpr *CE) const {
+  CheckOpenVariant(C, CE, OpenVariant::OpenAt);
+}
+
+void UnixAPIChecker::CheckOpenVariant(CheckerContext &C,
+                                      const CallExpr *CE,
+                                      OpenVariant Variant) const {
+  // The index of the argument taking the flags open flags (O_RDONLY,
+  // O_WRONLY, O_CREAT, etc.),
+  unsigned int FlagsArgIndex;
+  const char *VariantName;
+  switch (Variant) {
+  case OpenVariant::Open:
+    FlagsArgIndex = 1;
+    VariantName = "open";
+    break;
+  case OpenVariant::OpenAt:
+    FlagsArgIndex = 2;
+    VariantName = "openat";
+    break;
+  };
+
+  // All calls should at least provide arguments up to the 'flags' parameter.
+  unsigned int MinArgCount = FlagsArgIndex + 1;
+
+  // If the flags has O_CREAT set then open/openat() require an additional
+  // argument specifying the file mode (permission bits) for the created file.
+  unsigned int CreateModeArgIndex = FlagsArgIndex + 1;
+
+  // The create mode argument should be the last argument.
+  unsigned int MaxArgCount = CreateModeArgIndex + 1;
+
   ProgramStateRef state = C.getState();
 
-  if (CE->getNumArgs() < 2) {
+  if (CE->getNumArgs() < MinArgCount) {
     // The frontend should issue a warning for this case, so this is a sanity
     // check.
     return;
-  } else if (CE->getNumArgs() == 3) {
-    const Expr *Arg = CE->getArg(2);
+  } else if (CE->getNumArgs() == MaxArgCount) {
+    const Expr *Arg = CE->getArg(CreateModeArgIndex);
     QualType QT = Arg->getType();
     if (!QT->isIntegerType()) {
+      SmallString<256> SBuf;
+      llvm::raw_svector_ostream OS(SBuf);
+      OS << "The " << CreateModeArgIndex + 1
+         << llvm::getOrdinalSuffix(CreateModeArgIndex + 1)
+         << " argument to '" << VariantName << "' is not an integer";
+
       ReportOpenBug(C, state,
-                    "Third argument to 'open' is not an integer",
+                    SBuf.c_str(),
                     Arg->getSourceRange());
       return;
     }
-  } else if (CE->getNumArgs() > 3) {
+  } else if (CE->getNumArgs() > MaxArgCount) {
+    SmallString<256> SBuf;
+    llvm::raw_svector_ostream OS(SBuf);
+    OS << "Call to '" << VariantName << "' with more than " << MaxArgCount
+       << " arguments";
+
     ReportOpenBug(C, state,
-                  "Call to 'open' with more than three arguments",
-                  CE->getArg(3)->getSourceRange());
+                  SBuf.c_str(),
+                  CE->getArg(MaxArgCount)->getSourceRange());
     return;
   }
 
@@ -128,7 +191,7 @@
   }
 
   // Now check if oflags has O_CREAT set.
-  const Expr *oflagsEx = CE->getArg(1);
+  const Expr *oflagsEx = CE->getArg(FlagsArgIndex);
   const SVal V = state->getSVal(oflagsEx, C.getLocationContext());
   if (!V.getAs<NonLoc>()) {
     // The case where 'V' can be a location can only be due to a bad header,
@@ -154,10 +217,15 @@
   if (!(trueState && !falseState))
     return;
 
-  if (CE->getNumArgs() < 3) {
+  if (CE->getNumArgs() < MaxArgCount) {
+    SmallString<256> SBuf;
+    llvm::raw_svector_ostream OS(SBuf);
+    OS << "Call to '" << VariantName << "' requires a "
+       << CreateModeArgIndex + 1
+       << llvm::getOrdinalSuffix(CreateModeArgIndex + 1)
+       << " argument when the 'O_CREAT' flag is set";
     ReportOpenBug(C, trueState,
-                  "Call to 'open' requires a third argument when "
-                  "the 'O_CREAT' flag is set",
+                  SBuf.c_str(),
                   oflagsEx->getSourceRange());
   }
 }
@@ -359,6 +427,12 @@
   if (!FD || FD->getKind() != Decl::Function)
     return;
 
+  // Don't treat functions in namespaces with the same name a Unix function
+  // as a call to the Unix function.
+  const DeclContext *NamespaceCtx = FD->getEnclosingNamespaceContext();
+  if (NamespaceCtx && isa<NamespaceDecl>(NamespaceCtx))
+    return;
+
   StringRef FName = C.getCalleeName(FD);
   if (FName.empty())
     return;
@@ -366,6 +440,7 @@
   SubChecker SC =
     llvm::StringSwitch<SubChecker>(FName)
       .Case("open", &UnixAPIChecker::CheckOpen)
+      .Case("openat", &UnixAPIChecker::CheckOpenAt)
       .Case("pthread_once", &UnixAPIChecker::CheckPthreadOnce)
       .Case("calloc", &UnixAPIChecker::CheckCallocZero)
       .Case("malloc", &UnixAPIChecker::CheckMallocZero)
diff --git a/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
index b4bfa0c..d12ba62 100644
--- a/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
@@ -54,11 +54,11 @@
   void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
 
 private:
-  const MemRegion *getVAListAsRegion(SVal SV, CheckerContext &C) const;
+  const MemRegion *getVAListAsRegion(SVal SV, const Expr *VAExpr,
+                                     bool &IsSymbolic, CheckerContext &C) const;
   StringRef getVariableNameFromRegion(const MemRegion *Reg) const;
   const ExplodedNode *getStartCallSite(const ExplodedNode *N,
-                                       const MemRegion *Reg,
-                                       CheckerContext &C) const;
+                                       const MemRegion *Reg) const;
 
   void reportUninitializedAccess(const MemRegion *VAList, StringRef Msg,
                                  CheckerContext &C) const;
@@ -91,10 +91,10 @@
       return llvm::make_unique<PathDiagnosticEventPiece>(L, BR.getDescription(),
                                                          false);
     }
-    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                   const ExplodedNode *PrevN,
-                                   BugReporterContext &BRC,
-                                   BugReport &BR) override;
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
 
   private:
     const MemRegion *Reg;
@@ -138,14 +138,21 @@
     for (auto FuncInfo : VAListAccepters) {
       if (!Call.isCalled(FuncInfo.Func))
         continue;
+      bool Symbolic;
       const MemRegion *VAList =
-          getVAListAsRegion(Call.getArgSVal(FuncInfo.VAListPos), C);
+          getVAListAsRegion(Call.getArgSVal(FuncInfo.VAListPos),
+                            Call.getArgExpr(FuncInfo.VAListPos), Symbolic, C);
       if (!VAList)
         return;
 
       if (C.getState()->contains<InitializedVALists>(VAList))
         return;
 
+      // We did not see va_start call, but the source of the region is unknown.
+      // Be conservative and assume the best.
+      if (Symbolic)
+        return;
+
       SmallString<80> Errmsg("Function '");
       Errmsg += FuncInfo.Func.getFunctionName();
       Errmsg += "' is called with an uninitialized va_list argument";
@@ -155,13 +162,41 @@
   }
 }
 
+const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E,
+                                                  bool &IsSymbolic,
+                                                  CheckerContext &C) const {
+  const MemRegion *Reg = SV.getAsRegion();
+  if (!Reg)
+    return nullptr;
+  // TODO: In the future this should be abstracted away by the analyzer.
+  bool VaListModelledAsArray = false;
+  if (const auto *Cast = dyn_cast<CastExpr>(E)) {
+    QualType Ty = Cast->getType();
+    VaListModelledAsArray =
+        Ty->isPointerType() && Ty->getPointeeType()->isRecordType();
+  }
+  if (const auto *DeclReg = Reg->getAs<DeclRegion>()) {
+    if (isa<ParmVarDecl>(DeclReg->getDecl()))
+      Reg = C.getState()->getSVal(SV.castAs<Loc>()).getAsRegion();
+  }
+  IsSymbolic = Reg && Reg->getAs<SymbolicRegion>();
+  // Some VarRegion based VA lists reach here as ElementRegions.
+  const auto *EReg = dyn_cast_or_null<ElementRegion>(Reg);
+  return (EReg && VaListModelledAsArray) ? EReg->getSuperRegion() : Reg;
+}
+
 void ValistChecker::checkPreStmt(const VAArgExpr *VAA,
                                  CheckerContext &C) const {
   ProgramStateRef State = C.getState();
-  SVal VAListSVal = State->getSVal(VAA->getSubExpr(), C.getLocationContext());
-  const MemRegion *VAList = getVAListAsRegion(VAListSVal, C);
+  const Expr *VASubExpr = VAA->getSubExpr();
+  SVal VAListSVal = State->getSVal(VASubExpr, C.getLocationContext());
+  bool Symbolic;
+  const MemRegion *VAList =
+      getVAListAsRegion(VAListSVal, VASubExpr, Symbolic, C);
   if (!VAList)
     return;
+  if (Symbolic)
+    return;
   if (!State->contains<InitializedVALists>(VAList))
     reportUninitializedAccess(
         VAList, "va_arg() is called on an uninitialized va_list", C);
@@ -183,22 +218,13 @@
                         N);
 }
 
-const MemRegion *ValistChecker::getVAListAsRegion(SVal SV,
-                                                  CheckerContext &C) const {
-  const MemRegion *Reg = SV.getAsRegion();
-  const auto *TReg = dyn_cast_or_null<TypedValueRegion>(Reg);
-  // Some VarRegion based VLAs reach here as ElementRegions.
-  const auto *EReg = dyn_cast_or_null<ElementRegion>(TReg);
-  return EReg ? EReg->getSuperRegion() : TReg;
-}
-
 // This function traverses the exploded graph backwards and finds the node where
 // the va_list is initialized. That node is used for uniquing the bug paths.
 // It is not likely that there are several different va_lists that belongs to
 // different stack frames, so that case is not yet handled.
-const ExplodedNode *ValistChecker::getStartCallSite(const ExplodedNode *N,
-                                                    const MemRegion *Reg,
-                                                    CheckerContext &C) const {
+const ExplodedNode *
+ValistChecker::getStartCallSite(const ExplodedNode *N,
+                                const MemRegion *Reg) const {
   const LocationContext *LeakContext = N->getLocationContext();
   const ExplodedNode *StartCallNode = N;
 
@@ -252,7 +278,7 @@
       BT_leakedvalist->setSuppressOnSink(true);
     }
 
-    const ExplodedNode *StartNode = getStartCallSite(N, Reg, C);
+    const ExplodedNode *StartNode = getStartCallSite(N, Reg);
     PathDiagnosticLocation LocUsedForUniqueing;
 
     if (const Stmt *StartCallStmt = PathDiagnosticLocation::getStmt(StartNode))
@@ -278,13 +304,17 @@
 
 void ValistChecker::checkVAListStartCall(const CallEvent &Call,
                                          CheckerContext &C, bool IsCopy) const {
-  const MemRegion *VAList = getVAListAsRegion(Call.getArgSVal(0), C);
-  ProgramStateRef State = C.getState();
+  bool Symbolic;
+  const MemRegion *VAList =
+      getVAListAsRegion(Call.getArgSVal(0), Call.getArgExpr(0), Symbolic, C);
   if (!VAList)
     return;
 
+  ProgramStateRef State = C.getState();
+
   if (IsCopy) {
-    const MemRegion *Arg2 = getVAListAsRegion(Call.getArgSVal(1), C);
+    const MemRegion *Arg2 =
+        getVAListAsRegion(Call.getArgSVal(1), Call.getArgExpr(1), Symbolic, C);
     if (Arg2) {
       if (ChecksEnabled[CK_CopyToSelf] && VAList == Arg2) {
         RegionVector LeakedVALists{VAList};
@@ -292,7 +322,7 @@
           reportLeakedVALists(LeakedVALists, "va_list",
                               " is copied onto itself", C, N, true);
         return;
-      } else if (!State->contains<InitializedVALists>(Arg2)) {
+      } else if (!State->contains<InitializedVALists>(Arg2) && !Symbolic) {
         if (State->contains<InitializedVALists>(VAList)) {
           State = State->remove<InitializedVALists>(VAList);
           RegionVector LeakedVALists{VAList};
@@ -321,10 +351,17 @@
 
 void ValistChecker::checkVAListEndCall(const CallEvent &Call,
                                        CheckerContext &C) const {
-  const MemRegion *VAList = getVAListAsRegion(Call.getArgSVal(0), C);
+  bool Symbolic;
+  const MemRegion *VAList =
+      getVAListAsRegion(Call.getArgSVal(0), Call.getArgExpr(0), Symbolic, C);
   if (!VAList)
     return;
 
+  // We did not see va_start call, but the source of the region is unknown.
+  // Be conservative and assume the best.
+  if (Symbolic)
+    return;
+
   if (!C.getState()->contains<InitializedVALists>(VAList)) {
     reportUninitializedAccess(
         VAList, "va_end() is called on an uninitialized va_list", C);
@@ -335,7 +372,7 @@
   C.addTransition(State);
 }
 
-PathDiagnosticPiece *ValistChecker::ValistBugVisitor::VisitNode(
+std::shared_ptr<PathDiagnosticPiece> ValistChecker::ValistBugVisitor::VisitNode(
     const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
     BugReport &BR) {
   ProgramStateRef State = N->getState();
@@ -358,7 +395,7 @@
 
   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
                              N->getLocationContext());
-  return new PathDiagnosticEventPiece(Pos, Msg, true);
+  return std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true);
 }
 
 #define REGISTER_CHECKER(name)                                                 \
diff --git a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
index 5502503..b47762b 100644
--- a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
@@ -32,6 +32,18 @@
   BugReporter &BR;
   AnalysisDeclContext *AC;
 
+  /// The root constructor or destructor whose callees are being analyzed.
+  const CXXMethodDecl *RootMethod = nullptr;
+
+  /// Whether the checker should walk into bodies of called functions.
+  /// Controlled by the "Interprocedural" analyzer-config option.
+  bool IsInterprocedural = false;
+
+  /// Whether the checker should only warn for calls to pure virtual functions
+  /// (which is undefined behavior) or for all virtual functions (which may
+  /// may result in unexpected behavior).
+  bool ReportPureOnly = false;
+
   typedef const CallExpr * WorkListUnit;
   typedef SmallVector<WorkListUnit, 20> DFSWorkList;
 
@@ -59,9 +71,16 @@
   const CallExpr *visitingCallExpr;
 
 public:
-  WalkAST(const CheckerBase *checker, BugReporter &br,
-          AnalysisDeclContext *ac)
-      : Checker(checker), BR(br), AC(ac), visitingCallExpr(nullptr) {}
+  WalkAST(const CheckerBase *checker, BugReporter &br, AnalysisDeclContext *ac,
+          const CXXMethodDecl *rootMethod, bool isInterprocedural,
+          bool reportPureOnly)
+      : Checker(checker), BR(br), AC(ac), RootMethod(rootMethod),
+        IsInterprocedural(isInterprocedural), ReportPureOnly(reportPureOnly),
+        visitingCallExpr(nullptr) {
+    // Walking should always start from either a constructor or a destructor.
+    assert(isa<CXXConstructorDecl>(rootMethod) ||
+           isa<CXXDestructorDecl>(rootMethod));
+  }
 
   bool hasWork() const { return !WList.empty(); }
 
@@ -132,7 +151,8 @@
 
 void WalkAST::VisitCallExpr(CallExpr *CE) {
   VisitChildren(CE);
-  Enqueue(CE);
+  if (IsInterprocedural)
+    Enqueue(CE);
 }
 
 void WalkAST::VisitCXXMemberCallExpr(CallExpr *CE) {
@@ -159,56 +179,70 @@
   }
 
   // Get the callee.
-  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CE->getDirectCallee());
+  const CXXMethodDecl *MD =
+      dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee());
   if (MD && MD->isVirtual() && !callIsNonVirtual && !MD->hasAttr<FinalAttr>() &&
       !MD->getParent()->hasAttr<FinalAttr>())
     ReportVirtualCall(CE, MD->isPure());
 
-  Enqueue(CE);
+  if (IsInterprocedural)
+    Enqueue(CE);
 }
 
 void WalkAST::ReportVirtualCall(const CallExpr *CE, bool isPure) {
+  if (ReportPureOnly && !isPure)
+    return;
+
   SmallString<100> buf;
   llvm::raw_svector_ostream os(buf);
 
-  os << "Call Path : ";
-  // Name of current visiting CallExpr.
-  os << *CE->getDirectCallee();
+  // FIXME: The interprocedural diagnostic experience here is not good.
+  // Ultimately this checker should be re-written to be path sensitive.
+  // For now, only diagnose intraprocedurally, by default.
+  if (IsInterprocedural) {
+    os << "Call Path : ";
+    // Name of current visiting CallExpr.
+    os << *CE->getDirectCallee();
 
-  // Name of the CallExpr whose body is current walking.
-  if (visitingCallExpr)
-    os << " <-- " << *visitingCallExpr->getDirectCallee();
-  // Names of FunctionDecls in worklist with state PostVisited.
-  for (SmallVectorImpl<const CallExpr *>::iterator I = WList.end(),
+    // Name of the CallExpr whose body is current being walked.
+    if (visitingCallExpr)
+      os << " <-- " << *visitingCallExpr->getDirectCallee();
+    // Names of FunctionDecls in worklist with state PostVisited.
+    for (SmallVectorImpl<const CallExpr *>::iterator I = WList.end(),
          E = WList.begin(); I != E; --I) {
-    const FunctionDecl *FD = (*(I-1))->getDirectCallee();
-    assert(FD);
-    if (VisitedFunctions[FD] == PostVisited)
-      os << " <-- " << *FD;
+      const FunctionDecl *FD = (*(I-1))->getDirectCallee();
+      assert(FD);
+      if (VisitedFunctions[FD] == PostVisited)
+        os << " <-- " << *FD;
+    }
+
+    os << "\n";
   }
 
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
   SourceRange R = CE->getCallee()->getSourceRange();
 
-  if (isPure) {
-    os << "\n" <<  "Call pure virtual functions during construction or "
-       << "destruction may leads undefined behaviour";
-    BR.EmitBasicReport(AC->getDecl(), Checker,
-                       "Call pure virtual function during construction or "
-                       "Destruction",
-                       "Cplusplus", os.str(), CELoc, R);
-    return;
-  }
-  else {
-    os << "\n" << "Call virtual functions during construction or "
-       << "destruction will never go to a more derived class";
-    BR.EmitBasicReport(AC->getDecl(), Checker,
-                       "Call virtual function during construction or "
-                       "Destruction",
-                       "Cplusplus", os.str(), CELoc, R);
-    return;
-  }
+  os << "Call to ";
+  if (isPure)
+    os << "pure ";
+
+  os << "virtual function during ";
+
+  if (isa<CXXConstructorDecl>(RootMethod))
+    os << "construction ";
+  else
+    os << "destruction ";
+
+  if (isPure)
+    os << "has undefined behavior";
+  else
+    os << "will not dispatch to derived class";
+
+  BR.EmitBasicReport(AC->getDecl(), Checker,
+                     "Call to virtual function during construction or "
+                     "destruction",
+                     "C++ Object Lifecycle", os.str(), CELoc, R);
 }
 
 //===----------------------------------------------------------------------===//
@@ -218,14 +252,18 @@
 namespace {
 class VirtualCallChecker : public Checker<check::ASTDecl<CXXRecordDecl> > {
 public:
+  DefaultBool isInterprocedural;
+  DefaultBool isPureOnly;
+
   void checkASTDecl(const CXXRecordDecl *RD, AnalysisManager& mgr,
                     BugReporter &BR) const {
-    WalkAST walker(this, BR, mgr.getAnalysisDeclContext(RD));
+    AnalysisDeclContext *ADC = mgr.getAnalysisDeclContext(RD);
 
     // Check the constructors.
     for (const auto *I : RD->ctors()) {
       if (!I->isCopyOrMoveConstructor())
         if (Stmt *Body = I->getBody()) {
+          WalkAST walker(this, BR, ADC, I, isInterprocedural, isPureOnly);
           walker.Visit(Body);
           walker.Execute();
         }
@@ -234,6 +272,7 @@
     // Check the destructor.
     if (CXXDestructorDecl *DD = RD->getDestructor())
       if (Stmt *Body = DD->getBody()) {
+        WalkAST walker(this, BR, ADC, DD, isInterprocedural, isPureOnly);
         walker.Visit(Body);
         walker.Execute();
       }
@@ -242,5 +281,12 @@
 }
 
 void ento::registerVirtualCallChecker(CheckerManager &mgr) {
-  mgr.registerChecker<VirtualCallChecker>();
+  VirtualCallChecker *checker = mgr.registerChecker<VirtualCallChecker>();
+  checker->isInterprocedural =
+      mgr.getAnalyzerOptions().getBooleanOption("Interprocedural", false,
+                                                checker);
+
+  checker->isPureOnly =
+      mgr.getAnalyzerOptions().getBooleanOption("PureOnly", false,
+                                                checker);
 }
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index 1542263..45ef612 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -230,7 +230,7 @@
 bool AnalyzerOptions::shouldSuppressFromCXXStandardLibrary() {
   return getBooleanOption(SuppressFromCXXStandardLibrary,
                           "suppress-c++-stdlib",
-                          /* Default = */ false);
+                          /* Default = */ true);
 }
 
 bool AnalyzerOptions::shouldReportIssuesInMainSourceFile() {
diff --git a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index 3c3f41a..ebbace4 100644
--- a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -33,6 +33,13 @@
   ID.AddPointer(region);
 }
 
+void PointerToMemberData::Profile(
+    llvm::FoldingSetNodeID& ID, const DeclaratorDecl *D,
+    llvm::ImmutableList<const CXXBaseSpecifier *> L) {
+  ID.AddPointer(D);
+  ID.AddPointer(L.getInternalPointer());
+}
+
 typedef std::pair<SVal, uintptr_t> SValData;
 typedef std::pair<SVal, SVal> SValPair;
 
@@ -142,6 +149,49 @@
   return D;
 }
 
+const PointerToMemberData *BasicValueFactory::getPointerToMemberData(
+    const DeclaratorDecl *DD, llvm::ImmutableList<const CXXBaseSpecifier*> L) {
+  llvm::FoldingSetNodeID ID;
+  PointerToMemberData::Profile(ID, DD, L);
+  void *InsertPos;
+
+  PointerToMemberData *D =
+      PointerToMemberDataSet.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!D) {
+    D = (PointerToMemberData*) BPAlloc.Allocate<PointerToMemberData>();
+    new (D) PointerToMemberData(DD, L);
+    PointerToMemberDataSet.InsertNode(D, InsertPos);
+  }
+
+  return D;
+}
+
+const clang::ento::PointerToMemberData *BasicValueFactory::accumCXXBase(
+    llvm::iterator_range<CastExpr::path_const_iterator> PathRange,
+    const nonloc::PointerToMember &PTM) {
+  nonloc::PointerToMember::PTMDataType PTMDT = PTM.getPTMData();
+  const DeclaratorDecl *DD = nullptr;
+  llvm::ImmutableList<const CXXBaseSpecifier *> PathList;
+
+  if (PTMDT.isNull() || PTMDT.is<const DeclaratorDecl *>()) {
+    if (PTMDT.is<const DeclaratorDecl *>())
+      DD = PTMDT.get<const DeclaratorDecl *>();
+
+    PathList = CXXBaseListFactory.getEmptyList();
+  } else { // const PointerToMemberData *
+    const PointerToMemberData *PTMD =
+        PTMDT.get<const PointerToMemberData *>();
+    DD = PTMD->getDeclaratorDecl();
+
+    PathList = PTMD->getCXXBaseList();
+  }
+
+  for (const auto &I : llvm::reverse(PathRange))
+    PathList = prependCXXBase(I, PathList);
+  return getPointerToMemberData(DD, PathList);
+}
+
 const llvm::APSInt*
 BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
                              const llvm::APSInt& V1, const llvm::APSInt& V2) {
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 24dc887..2114033 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Analysis/CFG.h"
+#include "clang/Analysis/CFGStmtMap.h"
 #include "clang/Analysis/ProgramPoint.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -110,15 +111,15 @@
   // grabbing the front, processing it, and if we decide to keep it append
   // it to the end of the path.  The entire path is processed in this way.
   for (unsigned i = 0; i < N; ++i) {
-    IntrusiveRefCntPtr<PathDiagnosticPiece> piece(path.front());
+    auto piece = std::move(path.front());
     path.pop_front();
 
     switch (piece->getKind()) {
       case PathDiagnosticPiece::Call:
-        removeRedundantMsgs(cast<PathDiagnosticCallPiece>(piece)->path);
+        removeRedundantMsgs(cast<PathDiagnosticCallPiece>(*piece).path);
         break;
       case PathDiagnosticPiece::Macro:
-        removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(piece)->subPieces);
+        removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(*piece).subPieces);
         break;
       case PathDiagnosticPiece::ControlFlow:
         break;
@@ -129,13 +130,13 @@
         if (PathDiagnosticEventPiece *nextEvent =
             dyn_cast<PathDiagnosticEventPiece>(path.front().get())) {
           PathDiagnosticEventPiece *event =
-            cast<PathDiagnosticEventPiece>(piece);
+              cast<PathDiagnosticEventPiece>(piece.get());
           // Check to see if we should keep one of the two pieces.  If we
           // come up with a preference, record which piece to keep, and consume
           // another piece from the path.
-          if (PathDiagnosticEventPiece *pieceToKeep =
-              eventsDescribeSameCondition(event, nextEvent)) {
-            piece = pieceToKeep;
+          if (auto *pieceToKeep =
+                  eventsDescribeSameCondition(event, nextEvent)) {
+            piece = std::move(pieceToKeep == event ? piece : path.front());
             path.pop_front();
             ++i;
           }
@@ -145,7 +146,7 @@
       case PathDiagnosticPiece::Note:
         break;
     }
-    path.push_back(piece);
+    path.push_back(std::move(piece));
   }
 }
 
@@ -165,38 +166,38 @@
   for (unsigned i = 0 ; i < N ; ++i) {
     // Remove the front piece from the path.  If it is still something we
     // want to keep once we are done, we will push it back on the end.
-    IntrusiveRefCntPtr<PathDiagnosticPiece> piece(pieces.front());
+    auto piece = std::move(pieces.front());
     pieces.pop_front();
 
     switch (piece->getKind()) {
       case PathDiagnosticPiece::Call: {
-        PathDiagnosticCallPiece *call = cast<PathDiagnosticCallPiece>(piece);
+        auto &call = cast<PathDiagnosticCallPiece>(*piece);
         // Check if the location context is interesting.
-        assert(LCM.count(&call->path));
-        if (R->isInteresting(LCM[&call->path])) {
+        assert(LCM.count(&call.path));
+        if (R->isInteresting(LCM[&call.path])) {
           containsSomethingInteresting = true;
           break;
         }
 
-        if (!removeUnneededCalls(call->path, R, LCM))
+        if (!removeUnneededCalls(call.path, R, LCM))
           continue;
 
         containsSomethingInteresting = true;
         break;
       }
       case PathDiagnosticPiece::Macro: {
-        PathDiagnosticMacroPiece *macro = cast<PathDiagnosticMacroPiece>(piece);
-        if (!removeUnneededCalls(macro->subPieces, R, LCM))
+        auto &macro = cast<PathDiagnosticMacroPiece>(*piece);
+        if (!removeUnneededCalls(macro.subPieces, R, LCM))
           continue;
         containsSomethingInteresting = true;
         break;
       }
       case PathDiagnosticPiece::Event: {
-        PathDiagnosticEventPiece *event = cast<PathDiagnosticEventPiece>(piece);
+        auto &event = cast<PathDiagnosticEventPiece>(*piece);
 
         // We never throw away an event, but we do throw it away wholesale
         // as part of a path if we throw the entire path away.
-        containsSomethingInteresting |= !event->isPrunable();
+        containsSomethingInteresting |= !event.isPrunable();
         break;
       }
       case PathDiagnosticPiece::ControlFlow:
@@ -206,7 +207,7 @@
         break;
     }
 
-    pieces.push_back(piece);
+    pieces.push_back(std::move(piece));
   }
 
   return containsSomethingInteresting;
@@ -225,7 +226,7 @@
 adjustCallLocations(PathPieces &Pieces,
                     PathDiagnosticLocation *LastCallLocation = nullptr) {
   for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E; ++I) {
-    PathDiagnosticCallPiece *Call = dyn_cast<PathDiagnosticCallPiece>(*I);
+    PathDiagnosticCallPiece *Call = dyn_cast<PathDiagnosticCallPiece>(I->get());
 
     if (!Call) {
       assert((*I)->getLocation().asLocation().isValid());
@@ -259,14 +260,13 @@
 /// explicitly in a constructor or braced list.
 static void removeEdgesToDefaultInitializers(PathPieces &Pieces) {
   for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E;) {
-    if (PathDiagnosticCallPiece *C = dyn_cast<PathDiagnosticCallPiece>(*I))
+    if (auto *C = dyn_cast<PathDiagnosticCallPiece>(I->get()))
       removeEdgesToDefaultInitializers(C->path);
 
-    if (PathDiagnosticMacroPiece *M = dyn_cast<PathDiagnosticMacroPiece>(*I))
+    if (auto *M = dyn_cast<PathDiagnosticMacroPiece>(I->get()))
       removeEdgesToDefaultInitializers(M->subPieces);
 
-    if (PathDiagnosticControlFlowPiece *CF =
-          dyn_cast<PathDiagnosticControlFlowPiece>(*I)) {
+    if (auto *CF = dyn_cast<PathDiagnosticControlFlowPiece>(I->get())) {
       const Stmt *Start = CF->getStartLocation().asStmt();
       const Stmt *End = CF->getEndLocation().asStmt();
       if (Start && isa<CXXDefaultInitExpr>(Start)) {
@@ -275,8 +275,8 @@
       } else if (End && isa<CXXDefaultInitExpr>(End)) {
         PathPieces::iterator Next = std::next(I);
         if (Next != E) {
-          if (PathDiagnosticControlFlowPiece *NextCF =
-                dyn_cast<PathDiagnosticControlFlowPiece>(*Next)) {
+          if (auto *NextCF =
+                  dyn_cast<PathDiagnosticControlFlowPiece>(Next->get())) {
             NextCF->setStartLocation(CF->getStartLocation());
           }
         }
@@ -294,10 +294,10 @@
 /// Farm generated functions.
 static void removePiecesWithInvalidLocations(PathPieces &Pieces) {
   for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E;) {
-    if (PathDiagnosticCallPiece *C = dyn_cast<PathDiagnosticCallPiece>(*I))
+    if (auto *C = dyn_cast<PathDiagnosticCallPiece>(I->get()))
       removePiecesWithInvalidLocations(C->path);
 
-    if (PathDiagnosticMacroPiece *M = dyn_cast<PathDiagnosticMacroPiece>(*I))
+    if (auto *M = dyn_cast<PathDiagnosticMacroPiece>(I->get()))
       removePiecesWithInvalidLocations(M->subPieces);
 
     if (!(*I)->getLocation().isValid() ||
@@ -517,11 +517,9 @@
 
   BugReport *R = PDB.getBugReport();
   while (const ExplodedNode *Pred = N->getFirstPred()) {
-    for (auto &V : visitors) {
+    for (auto &V : visitors)
       // Visit all the node pairs, but throw the path pieces away.
-      PathDiagnosticPiece *Piece = V->VisitNode(N, Pred, PDB, *R);
-      delete Piece;
-    }
+      V->VisitNode(N, Pred, PDB, *R);
 
     N = Pred;
   }
@@ -535,12 +533,11 @@
 typedef std::pair<PathDiagnosticCallPiece*, const ExplodedNode*> StackDiagPair;
 typedef SmallVector<StackDiagPair, 6> StackDiagVector;
 
-static void updateStackPiecesWithMessage(PathDiagnosticPiece *P,
+static void updateStackPiecesWithMessage(PathDiagnosticPiece &P,
                                          StackDiagVector &CallStack) {
   // If the piece contains a special message, add it to all the call
   // pieces on the active stack.
-  if (PathDiagnosticEventPiece *ep =
-        dyn_cast<PathDiagnosticEventPiece>(P)) {
+  if (PathDiagnosticEventPiece *ep = dyn_cast<PathDiagnosticEventPiece>(&P)) {
 
     if (ep->hasCallStackHint())
       for (StackDiagVector::iterator I = CallStack.begin(),
@@ -581,13 +578,13 @@
 
     do {
       if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) {
-        PathDiagnosticCallPiece *C =
-            PathDiagnosticCallPiece::construct(N, *CE, SMgr);
+        auto C = PathDiagnosticCallPiece::construct(N, *CE, SMgr);
         // Record the mapping from call piece to LocationContext.
         LCM[&C->path] = CE->getCalleeContext();
-        PD.getActivePath().push_front(C);
-        PD.pushActivePath(&C->path);
-        CallStack.push_back(StackDiagPair(C, N));
+        auto *P = C.get();
+        PD.getActivePath().push_front(std::move(C));
+        PD.pushActivePath(&P->path);
+        CallStack.push_back(StackDiagPair(P, N));
         break;
       }
 
@@ -603,7 +600,7 @@
         // a new PathDiagnosticCallPiece.
         PathDiagnosticCallPiece *C;
         if (VisitedEntireCall) {
-          C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
+          C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front().get());
         } else {
           const Decl *Caller = CE->getLocationContext()->getDecl();
           C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
@@ -648,8 +645,9 @@
 
           os << "Control jumps to line "
               << End.asLocation().getExpansionLineNumber();
-          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-              Start, End, os.str()));
+          PD.getActivePath().push_front(
+              std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                               os.str()));
           break;
         }
 
@@ -700,14 +698,16 @@
               break;
             }
             }
-            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                Start, End, os.str()));
+            PD.getActivePath().push_front(
+                std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                                 os.str()));
           }
           else {
             os << "'Default' branch taken. ";
             const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
-            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                Start, End, os.str()));
+            PD.getActivePath().push_front(
+                std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                                 os.str()));
           }
 
           break;
@@ -718,8 +718,9 @@
           std::string sbuf;
           llvm::raw_string_ostream os(sbuf);
           PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
-          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-              Start, End, os.str()));
+          PD.getActivePath().push_front(
+              std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                               os.str()));
           break;
         }
 
@@ -740,8 +741,9 @@
           if (const Stmt *S = End.asStmt())
             End = PDB.getEnclosingStmtLocation(S);
 
-          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-              Start, End, os.str()));
+          PD.getActivePath().push_front(
+              std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                               os.str()));
           break;
         }
 
@@ -763,15 +765,17 @@
               PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
               PathDiagnosticLocation Start =
                   PathDiagnosticLocation::createOperatorLoc(B, SMgr);
-              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                  Start, End, os.str()));
+              PD.getActivePath().push_front(
+                  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                                   os.str()));
             }
             else {
               os << "true";
               PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
               PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                  Start, End, os.str()));
+              PD.getActivePath().push_front(
+                  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                                   os.str()));
             }
           }
           else {
@@ -782,16 +786,18 @@
               os << "false";
               PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
               PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                  Start, End, os.str()));
+              PD.getActivePath().push_front(
+                  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                                   os.str()));
             }
             else {
               os << "true";
               PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
               PathDiagnosticLocation Start =
                   PathDiagnosticLocation::createOperatorLoc(B, SMgr);
-              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                  Start, End, os.str()));
+              PD.getActivePath().push_front(
+                  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                                   os.str()));
             }
           }
 
@@ -809,8 +815,9 @@
             if (const Stmt *S = End.asStmt())
               End = PDB.getEnclosingStmtLocation(S);
 
-            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                Start, End, os.str()));
+            PD.getActivePath().push_front(
+                std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                                 os.str()));
           }
           else {
             PathDiagnosticLocation End = PDB.ExecutionContinues(N);
@@ -818,8 +825,9 @@
             if (const Stmt *S = End.asStmt())
               End = PDB.getEnclosingStmtLocation(S);
 
-            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                Start, End, "Loop condition is false.  Exiting loop"));
+            PD.getActivePath().push_front(
+                std::make_shared<PathDiagnosticControlFlowPiece>(
+                    Start, End, "Loop condition is false.  Exiting loop"));
           }
 
           break;
@@ -836,16 +844,18 @@
             if (const Stmt *S = End.asStmt())
               End = PDB.getEnclosingStmtLocation(S);
 
-            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                Start, End, os.str()));
+            PD.getActivePath().push_front(
+                std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+                                                                 os.str()));
           }
           else {
             PathDiagnosticLocation End = PDB.ExecutionContinues(N);
             if (const Stmt *S = End.asStmt())
               End = PDB.getEnclosingStmtLocation(S);
 
-            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                Start, End, "Loop condition is true.  Entering loop body"));
+            PD.getActivePath().push_front(
+                std::make_shared<PathDiagnosticControlFlowPiece>(
+                    Start, End, "Loop condition is true.  Entering loop body"));
           }
 
           break;
@@ -858,11 +868,13 @@
             End = PDB.getEnclosingStmtLocation(S);
 
           if (*(Src->succ_begin()+1) == Dst)
-            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                Start, End, "Taking false branch"));
+            PD.getActivePath().push_front(
+                std::make_shared<PathDiagnosticControlFlowPiece>(
+                    Start, End, "Taking false branch"));
           else
-            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
-                Start, End, "Taking true branch"));
+            PD.getActivePath().push_front(
+                std::make_shared<PathDiagnosticControlFlowPiece>(
+                    Start, End, "Taking true branch"));
 
           break;
         }
@@ -874,9 +886,9 @@
       // Add diagnostic pieces from custom visitors.
       BugReport *R = PDB.getBugReport();
       for (auto &V : visitors) {
-        if (PathDiagnosticPiece *p = V->VisitNode(N, NextNode, PDB, *R)) {
-          PD.getActivePath().push_front(p);
-          updateStackPiecesWithMessage(p, CallStack);
+        if (auto p = V->VisitNode(N, NextNode, PDB, *R)) {
+          updateStackPiecesWithMessage(*p, CallStack);
+          PD.getActivePath().push_front(std::move(p));
         }
       }
     }
@@ -1117,7 +1129,9 @@
       PrevLocClean.asLocation().getExpansionLoc())
     return;
 
-  PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
+  PD.getActivePath().push_front(
+      std::make_shared<PathDiagnosticControlFlowPiece>(NewLocClean,
+                                                       PrevLocClean));
   PrevLoc = NewLoc;
 }
 
@@ -1422,16 +1436,16 @@
                                                 N->getLocationContext());
         }
 
-        PathDiagnosticCallPiece *C =
-          PathDiagnosticCallPiece::construct(N, *CE, SM);
+        auto C = PathDiagnosticCallPiece::construct(N, *CE, SM);
         LCM[&C->path] = CE->getCalleeContext();
 
         EB.addEdge(C->callReturn, /*AlwaysAdd=*/true, /*IsPostJump=*/true);
         EB.flushLocations();
 
-        PD.getActivePath().push_front(C);
-        PD.pushActivePath(&C->path);
-        CallStack.push_back(StackDiagPair(C, N));
+        auto *P = C.get();
+        PD.getActivePath().push_front(std::move(C));
+        PD.pushActivePath(&P->path);
+        CallStack.push_back(StackDiagPair(P, N));
         break;
       }
 
@@ -1457,7 +1471,7 @@
         // a new PathDiagnosticCallPiece.
         PathDiagnosticCallPiece *C;
         if (VisitedEntireCall) {
-          C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
+          C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front().get());
         } else {
           const Decl *Caller = CE->getLocationContext()->getDecl();
           C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
@@ -1504,13 +1518,12 @@
           else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop))
             CS = dyn_cast<CompoundStmt>(WS->getBody());
 
-          PathDiagnosticEventPiece *p =
-            new PathDiagnosticEventPiece(L,
-                                        "Looping back to the head of the loop");
+          auto p = std::make_shared<PathDiagnosticEventPiece>(
+              L, "Looping back to the head of the loop");
           p->setPrunable(true);
 
           EB.addEdge(p->getLocation(), true);
-          PD.getActivePath().push_front(p);
+          PD.getActivePath().push_front(std::move(p));
 
           if (CS) {
             PathDiagnosticLocation BL =
@@ -1532,12 +1545,12 @@
                                               N),
                             Term)) {
             PathDiagnosticLocation L(Term, SM, PDB.LC);
-            PathDiagnosticEventPiece *PE =
-                new PathDiagnosticEventPiece(L, "Loop body executed 0 times");
+            auto PE = std::make_shared<PathDiagnosticEventPiece>(
+                L, "Loop body executed 0 times");
             PE->setPrunable(true);
 
             EB.addEdge(PE->getLocation(), true);
-            PD.getActivePath().push_front(PE);
+            PD.getActivePath().push_front(std::move(PE));
           }
 
           // In any case, add the terminator as the current statement
@@ -1572,11 +1585,11 @@
     // Add pieces from custom visitors.
     BugReport *R = PDB.getBugReport();
     for (auto &V : visitors) {
-      if (PathDiagnosticPiece *p = V->VisitNode(N, NextNode, PDB, *R)) {
+      if (auto p = V->VisitNode(N, NextNode, PDB, *R)) {
         const PathDiagnosticLocation &Loc = p->getLocation();
         EB.addEdge(Loc, true);
-        PD.getActivePath().push_front(p);
-        updateStackPiecesWithMessage(p, CallStack);
+        updateStackPiecesWithMessage(*p, CallStack);
+        PD.getActivePath().push_front(std::move(p));
 
         if (const Stmt *S = Loc.asStmt())
           EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
@@ -1609,8 +1622,8 @@
   if (NewLoc.asStmt() && NewLoc.asStmt() == PrevLoc.asStmt())
     return;
 
-  path.push_front(new PathDiagnosticControlFlowPiece(NewLoc,
-                                                     PrevLoc));
+  path.push_front(
+      std::make_shared<PathDiagnosticControlFlowPiece>(NewLoc, PrevLoc));
   PrevLoc = NewLoc;
 }
 
@@ -1677,7 +1690,7 @@
           // Since we just transferred the path over to the call piece,
           // reset the mapping from active to location context.
           assert(PD.getActivePath().size() == 1 &&
-                 PD.getActivePath().front() == C);
+                 PD.getActivePath().front().get() == C);
           LCM[&PD.getActivePath()] = nullptr;
 
           // Record the location context mapping for the path within
@@ -1728,20 +1741,20 @@
 
         // We are descending into a call (backwards).  Construct
         // a new call piece to contain the path pieces for that call.
-        PathDiagnosticCallPiece *C =
-          PathDiagnosticCallPiece::construct(N, *CE, SM);
+        auto C = PathDiagnosticCallPiece::construct(N, *CE, SM);
 
         // Record the location context for this call piece.
         LCM[&C->path] = CE->getCalleeContext();
 
         // Add the edge to the return site.
         addEdgeToPath(PD.getActivePath(), PrevLoc, C->callReturn, PDB.LC);
-        PD.getActivePath().push_front(C);
+        auto *P = C.get();
+        PD.getActivePath().push_front(std::move(C));
         PrevLoc.invalidate();
 
         // Make the contents of the call the active path for now.
-        PD.pushActivePath(&C->path);
-        CallStack.push_back(StackDiagPair(C, N));
+        PD.pushActivePath(&P->path);
+        CallStack.push_back(StackDiagPair(P, N));
         break;
       }
 
@@ -1796,13 +1809,13 @@
           }
           // do-while statements are explicitly excluded here
 
-          PathDiagnosticEventPiece *p =
-            new PathDiagnosticEventPiece(L, "Looping back to the head "
-                                            "of the loop");
+          auto p = std::make_shared<PathDiagnosticEventPiece>(
+              L, "Looping back to the head "
+                 "of the loop");
           p->setPrunable(true);
 
           addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC);
-          PD.getActivePath().push_front(p);
+          PD.getActivePath().push_front(std::move(p));
 
           if (const CompoundStmt *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
             addEdgeToPath(PD.getActivePath(), PrevLoc,
@@ -1840,12 +1853,11 @@
 
             if (str) {
               PathDiagnosticLocation L(TermCond ? TermCond : Term, SM, PDB.LC);
-              PathDiagnosticEventPiece *PE =
-                new PathDiagnosticEventPiece(L, str);
+              auto PE = std::make_shared<PathDiagnosticEventPiece>(L, str);
               PE->setPrunable(true);
               addEdgeToPath(PD.getActivePath(), PrevLoc,
                             PE->getLocation(), PDB.LC);
-              PD.getActivePath().push_front(PE);
+              PD.getActivePath().push_front(std::move(PE));
             }
           } else if (isa<BreakStmt>(Term) || isa<ContinueStmt>(Term) ||
                      isa<GotoStmt>(Term)) {
@@ -1862,10 +1874,10 @@
 
     // Add pieces from custom visitors.
     for (auto &V : visitors) {
-      if (PathDiagnosticPiece *p = V->VisitNode(N, NextNode, PDB, *report)) {
+      if (auto p = V->VisitNode(N, NextNode, PDB, *report)) {
         addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC);
-        PD.getActivePath().push_front(p);
-        updateStackPiecesWithMessage(p, CallStack);
+        updateStackPiecesWithMessage(*p, CallStack);
+        PD.getActivePath().push_front(std::move(p));
       }
     }
   }
@@ -1972,7 +1984,7 @@
   for (PathPieces::iterator I = pieces.begin(), E = Prev; I != E;
        Prev = I, ++I) {
     PathDiagnosticControlFlowPiece *Piece =
-      dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+        dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
 
     if (!Piece)
       continue;
@@ -2013,8 +2025,7 @@
       // Try to extend the previous edge if it's at the same level as the source
       // context.
       if (Prev != E) {
-        PathDiagnosticControlFlowPiece *PrevPiece =
-          dyn_cast<PathDiagnosticControlFlowPiece>(*Prev);
+        auto *PrevPiece = dyn_cast<PathDiagnosticControlFlowPiece>(Prev->get());
 
         if (PrevPiece) {
           if (const Stmt *PrevSrc = getLocStmt(PrevPiece->getStartLocation())) {
@@ -2030,8 +2041,10 @@
       // Otherwise, split the current edge into a context edge and a
       // subexpression edge. Note that the context statement may itself have
       // context.
-      Piece = new PathDiagnosticControlFlowPiece(SrcLoc, DstContext);
-      I = pieces.insert(I, Piece);
+      auto P =
+          std::make_shared<PathDiagnosticControlFlowPiece>(SrcLoc, DstContext);
+      Piece = P.get();
+      I = pieces.insert(I, std::move(P));
     }
   }
 }
@@ -2050,8 +2063,7 @@
 static void simplifySimpleBranches(PathPieces &pieces) {
   for (PathPieces::iterator I = pieces.begin(), E = pieces.end(); I != E; ++I) {
 
-    PathDiagnosticControlFlowPiece *PieceI =
-      dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+    auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
 
     if (!PieceI)
       continue;
@@ -2072,7 +2084,7 @@
       if (NextI == E)
         break;
 
-      PathDiagnosticEventPiece *EV = dyn_cast<PathDiagnosticEventPiece>(*NextI);
+      auto *EV = dyn_cast<PathDiagnosticEventPiece>(NextI->get());
       if (EV) {
         StringRef S = EV->getString();
         if (S == StrEnteringLoop || S == StrLoopBodyZero ||
@@ -2083,7 +2095,7 @@
         break;
       }
 
-      PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
+      PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
       break;
     }
 
@@ -2175,7 +2187,7 @@
   for (PathPieces::iterator I = Path.begin(), E = Path.end(); I != E; ) {
     // Pattern match the current piece and its successor.
     PathDiagnosticControlFlowPiece *PieceI =
-      dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+        dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
 
     if (!PieceI) {
       ++I;
@@ -2190,14 +2202,14 @@
       break;
 
     PathDiagnosticControlFlowPiece *PieceNextI =
-      dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
+        dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
 
     if (!PieceNextI) {
-      if (isa<PathDiagnosticEventPiece>(*NextI)) {
+      if (isa<PathDiagnosticEventPiece>(NextI->get())) {
         ++NextI;
         if (NextI == E)
           break;
-        PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
+        PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
       }
 
       if (!PieceNextI) {
@@ -2250,8 +2262,7 @@
 
     erased = false;
 
-    PathDiagnosticControlFlowPiece *PieceI =
-      dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+    auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
 
     if (!PieceI)
       continue;
@@ -2298,8 +2309,7 @@
 
 static void removeIdenticalEvents(PathPieces &path) {
   for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ++I) {
-    PathDiagnosticEventPiece *PieceI =
-      dyn_cast<PathDiagnosticEventPiece>(*I);
+    auto *PieceI = dyn_cast<PathDiagnosticEventPiece>(I->get());
 
     if (!PieceI)
       continue;
@@ -2308,8 +2318,7 @@
     if (NextI == E)
       return;
 
-    PathDiagnosticEventPiece *PieceNextI =
-      dyn_cast<PathDiagnosticEventPiece>(*NextI);
+    auto *PieceNextI = dyn_cast<PathDiagnosticEventPiece>(NextI->get());
 
     if (!PieceNextI)
       continue;
@@ -2331,7 +2340,7 @@
 
   for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ) {
     // Optimize subpaths.
-    if (PathDiagnosticCallPiece *CallI = dyn_cast<PathDiagnosticCallPiece>(*I)){
+    if (auto *CallI = dyn_cast<PathDiagnosticCallPiece>(I->get())) {
       // Record the fact that a call has been optimized so we only do the
       // effort once.
       if (!OCS.count(CallI)) {
@@ -2343,8 +2352,7 @@
     }
 
     // Pattern match the current piece and its successor.
-    PathDiagnosticControlFlowPiece *PieceI =
-      dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+    auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
 
     if (!PieceI) {
       ++I;
@@ -2360,8 +2368,7 @@
     if (NextI == E)
       break;
 
-    PathDiagnosticControlFlowPiece *PieceNextI =
-      dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
+    auto *PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
 
     if (!PieceNextI) {
       ++I;
@@ -2510,8 +2517,8 @@
 static void dropFunctionEntryEdge(PathPieces &Path,
                                   LocationContextMap &LCM,
                                   SourceManager &SM) {
-  const PathDiagnosticControlFlowPiece *FirstEdge =
-    dyn_cast<PathDiagnosticControlFlowPiece>(Path.front());
+  const auto *FirstEdge =
+      dyn_cast<PathDiagnosticControlFlowPiece>(Path.front().get());
   if (!FirstEdge)
     return;
 
@@ -2966,11 +2973,11 @@
 /// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
 ///  and collapses PathDiagosticPieces that are expanded by macros.
 static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
-  typedef std::vector<std::pair<IntrusiveRefCntPtr<PathDiagnosticMacroPiece>,
-                                SourceLocation> > MacroStackTy;
+  typedef std::vector<
+      std::pair<std::shared_ptr<PathDiagnosticMacroPiece>, SourceLocation>>
+      MacroStackTy;
 
-  typedef std::vector<IntrusiveRefCntPtr<PathDiagnosticPiece> >
-          PiecesTy;
+  typedef std::vector<std::shared_ptr<PathDiagnosticPiece>> PiecesTy;
 
   MacroStackTy MacroStack;
   PiecesTy Pieces;
@@ -2978,10 +2985,10 @@
   for (PathPieces::const_iterator I = path.begin(), E = path.end();
        I!=E; ++I) {
 
-    PathDiagnosticPiece *piece = I->get();
+    auto &piece = *I;
 
     // Recursively compact calls.
-    if (PathDiagnosticCallPiece *call=dyn_cast<PathDiagnosticCallPiece>(piece)){
+    if (auto *call = dyn_cast<PathDiagnosticCallPiece>(&*piece)) {
       CompactPathDiagnostic(call->path, SM);
     }
 
@@ -3010,7 +3017,7 @@
 
     // We aren't in the same group.  Are we descending into a new macro
     // or are part of an old one?
-    IntrusiveRefCntPtr<PathDiagnosticMacroPiece> MacroGroup;
+    std::shared_ptr<PathDiagnosticMacroPiece> MacroGroup;
 
     SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
                                           SM.getExpansionLoc(Loc) :
@@ -3033,8 +3040,7 @@
 
     if (!MacroGroup || ParentInstantiationLoc == MacroStack.back().second) {
       // Create a new macro group and add it to the stack.
-      PathDiagnosticMacroPiece *NewGroup =
-        new PathDiagnosticMacroPiece(
+      auto NewGroup = std::make_shared<PathDiagnosticMacroPiece>(
           PathDiagnosticLocation::createSingleLocation(piece->getLocation()));
 
       if (MacroGroup)
@@ -3285,6 +3291,19 @@
 };
 }
 
+static const CFGBlock *findBlockForNode(const ExplodedNode *N) {
+  ProgramPoint P = N->getLocation();
+  if (auto BEP = P.getAs<BlockEntrance>())
+    return BEP->getBlock();
+
+  // Find the node's current statement in the CFG.
+  if (const Stmt *S = PathDiagnosticLocation::getStmt(N))
+    return N->getLocationContext()->getAnalysisDeclContext()
+                                  ->getCFGStmtMap()->getBlock(S);
+
+  return nullptr;
+}
+
 static BugReport *
 FindReportInEquivalenceClass(BugReportEquivClass& EQ,
                              SmallVectorImpl<BugReport*> &bugReports) {
@@ -3333,6 +3352,18 @@
       continue;
     }
 
+    // See if we are in a no-return CFG block. If so, treat this similarly
+    // to being post-dominated by a sink. This works better when the analysis
+    // is incomplete and we have never reached a no-return function
+    // we're post-dominated by.
+    // This is not quite enough to handle the incomplete analysis case.
+    // We may be post-dominated in subsequent blocks, or even
+    // inter-procedurally. However, it is not clear if more complicated
+    // cases are generally worth suppressing.
+    if (const CFGBlock *B = findBlockForNode(errorNode))
+      if (B->hasNoReturnElement())
+        continue;
+
     // At this point we know that 'N' is not a sink and it has at least one
     // successor.  Use a DFS worklist to find a non-sink end-of-path node.
     typedef FRIEC_WLItem WLItem;
@@ -3451,13 +3482,12 @@
     for (auto I = exampleReport->getNotes().rbegin(),
               E = exampleReport->getNotes().rend(); I != E; ++I) {
       PathDiagnosticNotePiece *Piece = I->get();
-      PathDiagnosticEventPiece *ConvertedPiece =
-          new PathDiagnosticEventPiece(Piece->getLocation(),
-                                       Piece->getString());
+      auto ConvertedPiece = std::make_shared<PathDiagnosticEventPiece>(
+          Piece->getLocation(), Piece->getString());
       for (const auto &R: Piece->getRanges())
         ConvertedPiece->addRange(R);
 
-      Pieces.push_front(ConvertedPiece);
+      Pieces.push_front(std::move(ConvertedPiece));
     }
   } else {
     for (auto I = exampleReport->getNotes().rbegin(),
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 7045d8b..c3c3f2f 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/Analysis/CFGStmtMap.h"
+#include "clang/Lex/Lexer.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
@@ -228,10 +229,9 @@
     return Options.shouldAvoidSuppressingNullArgumentPaths();
   }
 
-  PathDiagnosticPiece *visitNodeInitial(const ExplodedNode *N,
-                                        const ExplodedNode *PrevN,
-                                        BugReporterContext &BRC,
-                                        BugReport &BR) {
+  std::shared_ptr<PathDiagnosticPiece>
+  visitNodeInitial(const ExplodedNode *N, const ExplodedNode *PrevN,
+                   BugReporterContext &BRC, BugReport &BR) {
     // Only print a message at the interesting return statement.
     if (N->getLocationContext() != StackFrame)
       return nullptr;
@@ -327,13 +327,12 @@
     if (!L.isValid() || !L.asLocation().isValid())
       return nullptr;
 
-    return new PathDiagnosticEventPiece(L, Out.str());
+    return std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
   }
 
-  PathDiagnosticPiece *visitNodeMaybeUnsuppress(const ExplodedNode *N,
-                                                const ExplodedNode *PrevN,
-                                                BugReporterContext &BRC,
-                                                BugReport &BR) {
+  std::shared_ptr<PathDiagnosticPiece>
+  visitNodeMaybeUnsuppress(const ExplodedNode *N, const ExplodedNode *PrevN,
+                           BugReporterContext &BRC, BugReport &BR) {
 #ifndef NDEBUG
     ExprEngine &Eng = BRC.getBugReporter().getEngine();
     AnalyzerOptions &Options = Eng.getAnalysisManager().options;
@@ -383,10 +382,10 @@
     return nullptr;
   }
 
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *PrevN,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) override {
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override {
     switch (Mode) {
     case Initial:
       return visitNodeInitial(N, PrevN, BRC, BR);
@@ -447,10 +446,10 @@
   return FrameSpace->getStackFrame() == LCtx->getCurrentStackFrame();
 }
 
-PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
-                                                       const ExplodedNode *Pred,
-                                                       BugReporterContext &BRC,
-                                                       BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
+                                  const ExplodedNode *Pred,
+                                  BugReporterContext &BRC, BugReport &BR) {
 
   if (Satisfied)
     return nullptr;
@@ -705,7 +704,7 @@
   if (!L.isValid() || !L.asLocation().isValid())
     return nullptr;
 
-  return new PathDiagnosticEventPiece(L, os.str());
+  return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
 }
 
 void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
@@ -727,11 +726,10 @@
   return (bool)N->getState()->assume(Constraint, !Assumption);
 }
 
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
 TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
                                     const ExplodedNode *PrevN,
-                                    BugReporterContext &BRC,
-                                    BugReport &BR) {
+                                    BugReporterContext &BRC, BugReport &BR) {
   if (IsSatisfied)
     return nullptr;
 
@@ -774,9 +772,9 @@
     if (!L.isValid())
       return nullptr;
 
-    PathDiagnosticEventPiece *X = new PathDiagnosticEventPiece(L, os.str());
+    auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str());
     X->setTag(getTag());
-    return X;
+    return std::move(X);
   }
 
   return nullptr;
@@ -807,7 +805,7 @@
   return "IDCVisitor";
 }
 
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
 SuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
                                                 const ExplodedNode *Pred,
                                                 BugReporterContext &BRC,
@@ -1120,10 +1118,10 @@
   return nullptr;
 }
 
-PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
-                                                     const ExplodedNode *PrevN,
-                                                     BugReporterContext &BRC,
-                                                     BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
+                                const ExplodedNode *PrevN,
+                                BugReporterContext &BRC, BugReport &BR) {
   Optional<PreStmt> P = N->getLocationAs<PreStmt>();
   if (!P)
     return nullptr;
@@ -1154,7 +1152,7 @@
   // Issue a message saying that the method was skipped.
   PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
                                      N->getLocationContext());
-  return new PathDiagnosticEventPiece(L, OS.str());
+  return std::make_shared<PathDiagnosticEventPiece>(L, OS.str());
 }
 
 // Registers every VarDecl inside a Stmt with a last store visitor.
@@ -1203,23 +1201,22 @@
   return "ConditionBRVisitor";
 }
 
-PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
-                                                   const ExplodedNode *Prev,
-                                                   BugReporterContext &BRC,
-                                                   BugReport &BR) {
-  PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *Prev,
+                              BugReporterContext &BRC, BugReport &BR) {
+  auto piece = VisitNodeImpl(N, Prev, BRC, BR);
   if (piece) {
     piece->setTag(getTag());
-    if (PathDiagnosticEventPiece *ev=dyn_cast<PathDiagnosticEventPiece>(piece))
+    if (auto *ev = dyn_cast<PathDiagnosticEventPiece>(piece.get()))
       ev->setPrunable(true, /* override */ false);
   }
   return piece;
 }
 
-PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
-                                                       const ExplodedNode *Prev,
-                                                       BugReporterContext &BRC,
-                                                       BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
+                                  const ExplodedNode *Prev,
+                                  BugReporterContext &BRC, BugReport &BR) {
 
   ProgramPoint progPoint = N->getLocation();
   ProgramStateRef CurrentState = N->getState();
@@ -1262,13 +1259,9 @@
   return nullptr;
 }
 
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitTerminator(const Stmt *Term,
-                                    const ExplodedNode *N,
-                                    const CFGBlock *srcBlk,
-                                    const CFGBlock *dstBlk,
-                                    BugReport &R,
-                                    BugReporterContext &BRC) {
+std::shared_ptr<PathDiagnosticPiece> ConditionBRVisitor::VisitTerminator(
+    const Stmt *Term, const ExplodedNode *N, const CFGBlock *srcBlk,
+    const CFGBlock *dstBlk, BugReport &R, BugReporterContext &BRC) {
   const Expr *Cond = nullptr;
 
   // In the code below, Term is a CFG terminator and Cond is a branch condition
@@ -1321,11 +1314,9 @@
   return VisitTrueTest(Cond, tookTrue, BRC, R, N);
 }
 
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
-                                  bool tookTrue,
-                                  BugReporterContext &BRC,
-                                  BugReport &R,
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitTrueTest(const Expr *Cond, bool tookTrue,
+                                  BugReporterContext &BRC, BugReport &R,
                                   const ExplodedNode *N) {
   // These will be modified in code below, but we need to preserve the original
   //  values in case we want to throw the generic message.
@@ -1338,13 +1329,13 @@
       default:
         break;
       case Stmt::BinaryOperatorClass:
-        if (PathDiagnosticPiece *P = VisitTrueTest(
-                Cond, cast<BinaryOperator>(CondTmp), tookTrueTmp, BRC, R, N))
+        if (auto P = VisitTrueTest(Cond, cast<BinaryOperator>(CondTmp),
+                                   tookTrueTmp, BRC, R, N))
           return P;
         break;
       case Stmt::DeclRefExprClass:
-        if (PathDiagnosticPiece *P = VisitTrueTest(
-                Cond, cast<DeclRefExpr>(CondTmp), tookTrueTmp, BRC, R, N))
+        if (auto P = VisitTrueTest(Cond, cast<DeclRefExpr>(CondTmp),
+                                   tookTrueTmp, BRC, R, N))
           return P;
         break;
       case Stmt::UnaryOperatorClass: {
@@ -1367,12 +1358,13 @@
   if (!Loc.isValid() || !Loc.asLocation().isValid())
     return nullptr;
 
-  PathDiagnosticEventPiece *Event = new PathDiagnosticEventPiece(
+  return std::make_shared<PathDiagnosticEventPiece>(
       Loc, tookTrue ? GenericTrueMessage : GenericFalseMessage);
-  return Event;
 }
 
-bool ConditionBRVisitor::patternMatch(const Expr *Ex, raw_ostream &Out,
+bool ConditionBRVisitor::patternMatch(const Expr *Ex,
+                                      const Expr *ParentEx,
+                                      raw_ostream &Out,
                                       BugReporterContext &BRC,
                                       BugReport &report,
                                       const ExplodedNode *N,
@@ -1380,6 +1372,47 @@
   const Expr *OriginalExpr = Ex;
   Ex = Ex->IgnoreParenCasts();
 
+  // Use heuristics to determine if Ex is a macro expending to a literal and
+  // if so, use the macro's name.
+  SourceLocation LocStart = Ex->getLocStart();
+  SourceLocation LocEnd = Ex->getLocEnd();
+  if (LocStart.isMacroID() && LocEnd.isMacroID() &&
+      (isa<GNUNullExpr>(Ex) ||
+       isa<ObjCBoolLiteralExpr>(Ex) ||
+       isa<CXXBoolLiteralExpr>(Ex) ||
+       isa<IntegerLiteral>(Ex) ||
+       isa<FloatingLiteral>(Ex))) {
+
+    StringRef StartName = Lexer::getImmediateMacroNameForDiagnostics(LocStart,
+      BRC.getSourceManager(), BRC.getASTContext().getLangOpts());
+    StringRef EndName = Lexer::getImmediateMacroNameForDiagnostics(LocEnd,
+      BRC.getSourceManager(), BRC.getASTContext().getLangOpts());
+    bool beginAndEndAreTheSameMacro = StartName.equals(EndName);
+
+    bool partOfParentMacro = false;
+    if (ParentEx->getLocStart().isMacroID()) {
+      StringRef PName = Lexer::getImmediateMacroNameForDiagnostics(
+        ParentEx->getLocStart(), BRC.getSourceManager(),
+        BRC.getASTContext().getLangOpts());
+      partOfParentMacro = PName.equals(StartName);
+    }
+
+    if (beginAndEndAreTheSameMacro && !partOfParentMacro ) {
+      // Get the location of the macro name as written by the caller.
+      SourceLocation Loc = LocStart;
+      while (LocStart.isMacroID()) {
+        Loc = LocStart;
+        LocStart = BRC.getSourceManager().getImmediateMacroCallerLoc(LocStart);
+      }
+      StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
+        Loc, BRC.getSourceManager(), BRC.getASTContext().getLangOpts());
+
+      // Return the macro name.
+      Out << MacroName;
+      return false;
+    }
+  }
+
   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
     const bool quotes = isa<VarDecl>(DR->getDecl());
     if (quotes) {
@@ -1426,13 +1459,10 @@
   return false;
 }
 
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
-                                  const BinaryOperator *BExpr,
-                                  const bool tookTrue,
-                                  BugReporterContext &BRC,
-                                  BugReport &R,
-                                  const ExplodedNode *N) {
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitTrueTest(const Expr *Cond, const BinaryOperator *BExpr,
+                                  const bool tookTrue, BugReporterContext &BRC,
+                                  BugReport &R, const ExplodedNode *N) {
 
   bool shouldInvert = false;
   Optional<bool> shouldPrune;
@@ -1440,10 +1470,10 @@
   SmallString<128> LhsString, RhsString;
   {
     llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
-    const bool isVarLHS = patternMatch(BExpr->getLHS(), OutLHS, BRC, R, N,
-                                       shouldPrune);
-    const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC, R, N,
-                                       shouldPrune);
+    const bool isVarLHS = patternMatch(BExpr->getLHS(), BExpr, OutLHS,
+                                       BRC, R, N, shouldPrune);
+    const bool isVarRHS = patternMatch(BExpr->getRHS(), BExpr, OutRHS,
+                                       BRC, R, N, shouldPrune);
 
     shouldInvert = !isVarLHS && isVarRHS;
   }
@@ -1505,20 +1535,15 @@
   Out << (shouldInvert ? LhsString : RhsString);
   const LocationContext *LCtx = N->getLocationContext();
   PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
-  PathDiagnosticEventPiece *event =
-    new PathDiagnosticEventPiece(Loc, Out.str());
+  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
   if (shouldPrune.hasValue())
     event->setPrunable(shouldPrune.getValue());
   return event;
 }
 
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
-                                           const Expr *CondVarExpr,
-                                           const bool tookTrue,
-                                           BugReporterContext &BRC,
-                                           BugReport &report,
-                                           const ExplodedNode *N) {
+std::shared_ptr<PathDiagnosticPiece> ConditionBRVisitor::VisitConditionVariable(
+    StringRef LhsString, const Expr *CondVarExpr, const bool tookTrue,
+    BugReporterContext &BRC, BugReport &report, const ExplodedNode *N) {
   // FIXME: If there's already a constraint tracker for this variable,
   // we shouldn't emit anything here (c.f. the double note in
   // test/Analysis/inlining/path-notes.c)
@@ -1541,8 +1566,7 @@
 
   const LocationContext *LCtx = N->getLocationContext();
   PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
-  PathDiagnosticEventPiece *event =
-    new PathDiagnosticEventPiece(Loc, Out.str());
+  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
 
   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
     if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
@@ -1557,13 +1581,10 @@
   return event;
 }
 
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
-                                  const DeclRefExpr *DR,
-                                  const bool tookTrue,
-                                  BugReporterContext &BRC,
-                                  BugReport &report,
-                                  const ExplodedNode *N) {
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitTrueTest(const Expr *Cond, const DeclRefExpr *DR,
+                                  const bool tookTrue, BugReporterContext &BRC,
+                                  BugReport &report, const ExplodedNode *N) {
 
   const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
   if (!VD)
@@ -1587,8 +1608,7 @@
 
   const LocationContext *LCtx = N->getLocationContext();
   PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
-  PathDiagnosticEventPiece *event =
-    new PathDiagnosticEventPiece(Loc, Out.str());
+  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
 
   const ProgramState *state = N->getState().get();
   if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
@@ -1600,7 +1620,7 @@
         event->setPrunable(false);
     }
   }
-  return event;
+  return std::move(event);
 }
 
 const char *const ConditionBRVisitor::GenericTrueMessage =
@@ -1702,11 +1722,10 @@
   return nullptr;
 }
 
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
 UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
-                                  const ExplodedNode *PrevN,
-                                  BugReporterContext &BRC,
-                                  BugReport &BR) {
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext &BRC, BugReport &BR) {
 
   ProgramStateRef State = N->getState();
   ProgramPoint ProgLoc = N->getLocation();
@@ -1756,7 +1775,7 @@
   return nullptr;
 }
 
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
 CXXSelfAssignmentBRVisitor::VisitNode(const ExplodedNode *Succ,
                                       const ExplodedNode *Pred,
                                       BugReporterContext &BRC, BugReport &BR) {
@@ -1803,8 +1822,8 @@
   Out << "Assuming " << Met->getParamDecl(0)->getName() <<
     ((Param == This) ? " == " : " != ") << "*this";
 
-  auto *Piece = new PathDiagnosticEventPiece(L, Out.str());
+  auto Piece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
   Piece->addRange(Met->getSourceRange());
 
-  return Piece;
+  return std::move(Piece);
 }
diff --git a/lib/StaticAnalyzer/Core/CMakeLists.txt b/lib/StaticAnalyzer/Core/CMakeLists.txt
index aaffb0b..0b4606b 100644
--- a/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -34,6 +34,7 @@
   PlistDiagnostics.cpp
   ProgramState.cpp
   RangeConstraintManager.cpp
+  RangedConstraintManager.cpp
   RegionStore.cpp
   SValBuilder.cpp
   SVals.cpp
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index bd47e89..ef824b8 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -212,9 +212,12 @@
 
 bool CallEvent::isCalled(const CallDescription &CD) const {
   assert(getKind() != CE_ObjCMessage && "Obj-C methods are not supported");
-  if (!CD.II)
+  if (!CD.IsLookupDone) {
+    CD.IsLookupDone = true;
     CD.II = &getState()->getStateManager().getContext().Idents.get(CD.FuncName);
-  if (getCalleeIdentifier() != CD.II)
+  }
+  const IdentifierInfo *II = getCalleeIdentifier();
+  if (!II || II != CD.II)
     return false;
   return (CD.RequiredArgs == CallDescription::NoArgRequirement ||
           CD.RequiredArgs == getNumArgs());
@@ -382,6 +385,11 @@
   if (II->isStr("funopen"))
     return true;
 
+  // - __cxa_demangle - can reallocate memory and can return the pointer to
+  // the input buffer.
+  if (II->isStr("__cxa_demangle"))
+    return true;
+
   StringRef FName = II->getName();
 
   // - CoreFoundation functions that end with "NoCopy" can free a passed-in
@@ -891,6 +899,38 @@
   llvm_unreachable("The while loop should always terminate.");
 }
 
+static const ObjCMethodDecl *findDefiningRedecl(const ObjCMethodDecl *MD) {
+  if (!MD)
+    return MD;
+
+  // Find the redeclaration that defines the method.
+  if (!MD->hasBody()) {
+    for (auto I : MD->redecls())
+      if (I->hasBody())
+        MD = cast<ObjCMethodDecl>(I);
+  }
+  return MD;
+}
+
+static bool isCallToSelfClass(const ObjCMessageExpr *ME) {
+  const Expr* InstRec = ME->getInstanceReceiver();
+  if (!InstRec)
+    return false;
+  const auto *InstRecIg = dyn_cast<DeclRefExpr>(InstRec->IgnoreParenImpCasts());
+
+  // Check that receiver is called 'self'.
+  if (!InstRecIg || !InstRecIg->getFoundDecl() ||
+      !InstRecIg->getFoundDecl()->getName().equals("self"))
+    return false;
+
+  // Check that the method name is 'class'.
+  if (ME->getSelector().getNumArgs() != 0 ||
+      !ME->getSelector().getNameForSlot(0).equals("class"))
+    return false;
+
+  return true;
+}
+
 RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
   const ObjCMessageExpr *E = getOriginExpr();
   assert(E);
@@ -905,6 +945,7 @@
     const MemRegion *Receiver = nullptr;
 
     if (!SupersType.isNull()) {
+      // The receiver is guaranteed to be 'super' in this case.
       // Super always means the type of immediate predecessor to the method
       // where the call occurs.
       ReceiverT = cast<ObjCObjectPointerType>(SupersType);
@@ -916,7 +957,7 @@
       DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
       QualType DynType = DTI.getType();
       CanBeSubClassed = DTI.canBeASubClass();
-      ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType);
+      ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
 
       if (ReceiverT && CanBeSubClassed)
         if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl())
@@ -924,7 +965,32 @@
             CanBeSubClassed = false;
     }
 
-    // Lookup the method implementation.
+    // Handle special cases of '[self classMethod]' and
+    // '[[self class] classMethod]', which are treated by the compiler as
+    // instance (not class) messages. We will statically dispatch to those.
+    if (auto *PT = dyn_cast_or_null<ObjCObjectPointerType>(ReceiverT)) {
+      // For [self classMethod], return the compiler visible declaration.
+      if (PT->getObjectType()->isObjCClass() &&
+          Receiver == getSelfSVal().getAsRegion())
+        return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
+
+      // Similarly, handle [[self class] classMethod].
+      // TODO: We are currently doing a syntactic match for this pattern with is
+      // limiting as the test cases in Analysis/inlining/InlineObjCClassMethod.m
+      // shows. A better way would be to associate the meta type with the symbol
+      // using the dynamic type info tracking and use it here. We can add a new
+      // SVal for ObjC 'Class' values that know what interface declaration they
+      // come from. Then 'self' in a class method would be filled in with
+      // something meaningful in ObjCMethodCall::getReceiverSVal() and we could
+      // do proper dynamic dispatch for class methods just like we do for
+      // instance methods now.
+      if (E->getInstanceReceiver())
+        if (const auto *M = dyn_cast<ObjCMessageExpr>(E->getInstanceReceiver()))
+          if (isCallToSelfClass(M))
+            return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
+    }
+
+    // Lookup the instance method implementation.
     if (ReceiverT)
       if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl()) {
         // Repeatedly calling lookupPrivateMethod() is expensive, especially
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 79e204c..49f3ede 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -521,17 +521,19 @@
 /// \brief Run checkers for region changes.
 ProgramStateRef
 CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
-                                    const InvalidatedSymbols *invalidated,
-                                    ArrayRef<const MemRegion *> ExplicitRegions,
-                                    ArrayRef<const MemRegion *> Regions,
-                                    const CallEvent *Call) {
+                                            const InvalidatedSymbols *invalidated,
+                                            ArrayRef<const MemRegion *> ExplicitRegions,
+                                            ArrayRef<const MemRegion *> Regions,
+                                            const LocationContext *LCtx,
+                                            const CallEvent *Call) {
   for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
     // If any checker declares the state infeasible (or if it starts that way),
     // bail out.
     if (!state)
       return nullptr;
     state = RegionChangesCheckers[i](state, invalidated,
-                                     ExplicitRegions, Regions, Call);
+                                     ExplicitRegions, Regions,
+                                     LCtx, Call);
   }
   return state;
 }
diff --git a/lib/StaticAnalyzer/Core/ConstraintManager.cpp b/lib/StaticAnalyzer/Core/ConstraintManager.cpp
index b7db833..8de2b0e 100644
--- a/lib/StaticAnalyzer/Core/ConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/ConstraintManager.cpp
@@ -20,8 +20,8 @@
 
 static DefinedSVal getLocFromSymbol(const ProgramStateRef &State,
                                     SymbolRef Sym) {
-  const MemRegion *R = State->getStateManager().getRegionManager()
-                                               .getSymbolicRegion(Sym);
+  const MemRegion *R =
+      State->getStateManager().getRegionManager().getSymbolicRegion(Sym);
   return loc::MemRegionVal(R);
 }
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 91946b8..a5d8fb7 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -254,7 +254,7 @@
       break;
     case SubobjectAdjustment::MemberPointerAdjustment:
       // FIXME: Unimplemented.
-      State->bindDefault(Reg, UnknownVal());
+      State->bindDefault(Reg, UnknownVal(), LC);
       return State;
     }
   }
@@ -265,7 +265,7 @@
                                           currBldrCtx->blockCount());
   // Bind the value of the expression to the sub-object region, and then bind
   // the sub-object region to our expression.
-  State = State->bindLoc(Reg, V);
+  State = State->bindLoc(Reg, V, LC);
   State = State->BindExpr(Result, LC, Reg);
   return State;
 }
@@ -286,9 +286,11 @@
                                  const InvalidatedSymbols *invalidated,
                                  ArrayRef<const MemRegion *> Explicits,
                                  ArrayRef<const MemRegion *> Regions,
+                                 const LocationContext *LCtx,
                                  const CallEvent *Call) {
   return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
-                                                      Explicits, Regions, Call);
+                                                         Explicits, Regions,
+                                                         LCtx, Call);
 }
 
 void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
@@ -507,7 +509,7 @@
       }
 
       SVal InitVal;
-      if (BMI->getNumArrayIndices() > 0) {
+      if (Init->getType()->isArrayType()) {
         // Handle arrays of trivial type. We can represent this with a
         // primitive load/copy from the base array region.
         const ArraySubscriptExpr *ASE;
@@ -515,8 +517,9 @@
           Init = ASE->getBase()->IgnoreImplicit();
 
         SVal LValue = State->getSVal(Init, stackFrame);
-        if (Optional<Loc> LValueLoc = LValue.getAs<Loc>())
-          InitVal = State->getSVal(*LValueLoc);
+        if (!Field->getType()->isReferenceType())
+          if (Optional<Loc> LValueLoc = LValue.getAs<Loc>())
+            InitVal = State->getSVal(*LValueLoc);
 
         // If we fail to get the value for some reason, use a symbolic value.
         if (InitVal.isUnknownOrUndef()) {
@@ -612,7 +615,15 @@
   const MemRegion *Region = dest.castAs<loc::MemRegionVal>().getRegion();
 
   if (varType->isReferenceType()) {
-    Region = state->getSVal(Region).getAsRegion()->getBaseRegion();
+    const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
+    if (!ValueRegion) {
+      // FIXME: This should not happen. The language guarantees a presence
+      // of a valid initializer here, so the reference shall not be undefined.
+      // It seems that we're calling destructors over variables that
+      // were not initialized yet.
+      return;
+    }
+    Region = ValueRegion->getBaseRegion();
     varType = cast<TypedValueRegion>(Region)->getValueType();
   }
 
@@ -766,7 +777,7 @@
   assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
 
   switch (S->getStmtClass()) {
-    // C++ and ARC stuff we don't support yet.
+    // C++, OpenMP and ARC stuff we don't support yet.
     case Expr::ObjCIndirectCopyRestoreExprClass:
     case Stmt::CXXDependentScopeMemberExprClass:
     case Stmt::CXXInheritedCtorInitExprClass:
@@ -789,41 +800,13 @@
     case Stmt::FunctionParmPackExprClass:
     case Stmt::CoroutineBodyStmtClass:
     case Stmt::CoawaitExprClass:
+    case Stmt::DependentCoawaitExprClass:
     case Stmt::CoreturnStmtClass:
     case Stmt::CoyieldExprClass:
     case Stmt::SEHTryStmtClass:
     case Stmt::SEHExceptStmtClass:
     case Stmt::SEHLeaveStmtClass:
-    case Stmt::SEHFinallyStmtClass: {
-      const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
-      Engine.addAbortedBlock(node, currBldrCtx->getBlock());
-      break;
-    }
-
-    case Stmt::ParenExprClass:
-      llvm_unreachable("ParenExprs already handled.");
-    case Stmt::GenericSelectionExprClass:
-      llvm_unreachable("GenericSelectionExprs already handled.");
-    // Cases that should never be evaluated simply because they shouldn't
-    // appear in the CFG.
-    case Stmt::BreakStmtClass:
-    case Stmt::CaseStmtClass:
-    case Stmt::CompoundStmtClass:
-    case Stmt::ContinueStmtClass:
-    case Stmt::CXXForRangeStmtClass:
-    case Stmt::DefaultStmtClass:
-    case Stmt::DoStmtClass:
-    case Stmt::ForStmtClass:
-    case Stmt::GotoStmtClass:
-    case Stmt::IfStmtClass:
-    case Stmt::IndirectGotoStmtClass:
-    case Stmt::LabelStmtClass:
-    case Stmt::NoStmtClass:
-    case Stmt::NullStmtClass:
-    case Stmt::SwitchStmtClass:
-    case Stmt::WhileStmtClass:
-    case Expr::MSDependentExistsStmtClass:
-    case Stmt::CapturedStmtClass:
+    case Stmt::SEHFinallyStmtClass:
     case Stmt::OMPParallelDirectiveClass:
     case Stmt::OMPSimdDirectiveClass:
     case Stmt::OMPForDirectiveClass:
@@ -866,6 +849,41 @@
     case Stmt::OMPTeamsDistributeSimdDirectiveClass:
     case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
     case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
+    case Stmt::OMPTargetTeamsDirectiveClass:
+    case Stmt::OMPTargetTeamsDistributeDirectiveClass:
+    case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
+    case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
+    case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
+    case Stmt::CapturedStmtClass:
+    {
+      const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
+      Engine.addAbortedBlock(node, currBldrCtx->getBlock());
+      break;
+    }
+
+    case Stmt::ParenExprClass:
+      llvm_unreachable("ParenExprs already handled.");
+    case Stmt::GenericSelectionExprClass:
+      llvm_unreachable("GenericSelectionExprs already handled.");
+    // Cases that should never be evaluated simply because they shouldn't
+    // appear in the CFG.
+    case Stmt::BreakStmtClass:
+    case Stmt::CaseStmtClass:
+    case Stmt::CompoundStmtClass:
+    case Stmt::ContinueStmtClass:
+    case Stmt::CXXForRangeStmtClass:
+    case Stmt::DefaultStmtClass:
+    case Stmt::DoStmtClass:
+    case Stmt::ForStmtClass:
+    case Stmt::GotoStmtClass:
+    case Stmt::IfStmtClass:
+    case Stmt::IndirectGotoStmtClass:
+    case Stmt::LabelStmtClass:
+    case Stmt::NoStmtClass:
+    case Stmt::NullStmtClass:
+    case Stmt::SwitchStmtClass:
+    case Stmt::WhileStmtClass:
+    case Expr::MSDependentExistsStmtClass:
       llvm_unreachable("Stmt should not be in analyzer evaluation loop");
 
     case Stmt::ObjCSubscriptRefExprClass:
@@ -905,6 +923,8 @@
     // Cases not handled yet; but will handle some day.
     case Stmt::DesignatedInitExprClass:
     case Stmt::DesignatedInitUpdateExprClass:
+    case Stmt::ArrayInitLoopExprClass:
+    case Stmt::ArrayInitIndexExprClass:
     case Stmt::ExtVectorElementExprClass:
     case Stmt::ImaginaryLiteralClass:
     case Stmt::ObjCAtCatchStmtClass:
@@ -1242,7 +1262,14 @@
     case Expr::MaterializeTemporaryExprClass: {
       Bldr.takeNodes(Pred);
       const MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(S);
-      CreateCXXTemporaryObject(MTE, Pred, Dst);
+      ExplodedNodeSet dstPrevisit;
+      getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this);
+      ExplodedNodeSet dstExpr;
+      for (ExplodedNodeSet::iterator i = dstPrevisit.begin(),
+                                     e = dstPrevisit.end(); i != e ; ++i) {
+        CreateCXXTemporaryObject(MTE, *i, dstExpr);
+      }
+      getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this);
       Bldr.addNodes(Dst);
       break;
     }
@@ -2150,7 +2177,9 @@
 // (3) We are binding to a MemRegion with stack storage that the store
 //     does not understand.
 ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
-                                                        SVal Loc, SVal Val) {
+                                                        SVal Loc,
+                                                        SVal Val,
+                                                        const LocationContext *LCtx) {
   // Are we storing to something that causes the value to "escape"?
   bool escapes = true;
 
@@ -2166,7 +2195,7 @@
       // same state.
       SVal StoredVal = State->getSVal(regionLoc->getRegion());
       if (StoredVal != Val)
-        escapes = (State == (State->bindLoc(*regionLoc, Val)));
+        escapes = (State == (State->bindLoc(*regionLoc, Val, LCtx)));
     }
   }
 
@@ -2263,7 +2292,7 @@
     const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr,
                                      /*tag*/nullptr);
     ProgramStateRef state = Pred->getState();
-    state = processPointerEscapedOnBind(state, location, Val);
+    state = processPointerEscapedOnBind(state, location, Val, LC);
     Bldr.generateNode(L, state, Pred);
     return;
   }
@@ -2273,13 +2302,13 @@
     ExplodedNode *PredI = *I;
     ProgramStateRef state = PredI->getState();
 
-    state = processPointerEscapedOnBind(state, location, Val);
+    state = processPointerEscapedOnBind(state, location, Val, LC);
 
     // When binding the value, pass on the hint that this is a initialization.
     // For initializations, we do not need to inform clients of region
     // changes.
     state = state->bindLoc(location.castAs<Loc>(),
-                           Val, /* notifyChanges = */ !atDeclInit);
+                           Val, LC, /* notifyChanges = */ !atDeclInit);
 
     const MemRegion *LocReg = nullptr;
     if (Optional<loc::MemRegionVal> LocRegVal =
@@ -2505,7 +2534,7 @@
     assert (!X.getAs<NonLoc>());  // Should be an Lval, or unknown, undef.
 
     if (Optional<Loc> LV = X.getAs<Loc>())
-      state = state->bindLoc(*LV, UnknownVal());
+      state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
   }
 
   Bldr.generateNode(A, Pred, state);
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index cae6ea0..ea4ff91 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 
@@ -226,12 +227,13 @@
 
       if (capturedR != originalR) {
         SVal originalV;
+        const LocationContext *LCtx = Pred->getLocationContext();
         if (copyExpr) {
-          originalV = State->getSVal(copyExpr, Pred->getLocationContext());
+          originalV = State->getSVal(copyExpr, LCtx);
         } else {
           originalV = State->getSVal(loc::MemRegionVal(originalR));
         }
-        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV);
+        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
       }
     }
   }
@@ -246,6 +248,38 @@
   getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
 }
 
+ProgramStateRef ExprEngine::handleLValueBitCast(
+    ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx,
+    QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr,
+    ExplodedNode* Pred) {
+  // Delegate to SValBuilder to process.
+  SVal V = state->getSVal(Ex, LCtx);
+  V = svalBuilder.evalCast(V, T, ExTy);
+  // Negate the result if we're treating the boolean as a signed i1
+  if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
+    V = evalMinus(V);
+  state = state->BindExpr(CastE, LCtx, V);
+  Bldr.generateNode(CastE, Pred, state);
+
+  return state;
+}
+
+ProgramStateRef ExprEngine::handleLVectorSplat(
+    ProgramStateRef state, const LocationContext* LCtx, const CastExpr* CastE,
+    StmtNodeBuilder &Bldr, ExplodedNode* Pred) {
+  // Recover some path sensitivity by conjuring a new value.
+  QualType resultType = CastE->getType();
+  if (CastE->isGLValue())
+    resultType = getContext().getPointerType(resultType);
+  SVal result = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx,
+                                             resultType,
+                                             currBldrCtx->blockCount());
+  state = state->BindExpr(CastE, LCtx, result);
+  Bldr.generateNode(CastE, Pred, state);
+
+  return state;
+}
+
 void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
                            ExplodedNode *Pred, ExplodedNodeSet &Dst) {
 
@@ -310,8 +344,21 @@
         continue;
       }
       case CK_MemberPointerToBoolean:
-        // FIXME: For now, member pointers are represented by void *.
-        // FALLTHROUGH
+      case CK_PointerToBoolean: {
+        SVal V = state->getSVal(Ex, LCtx);
+        auto PTMSV = V.getAs<nonloc::PointerToMember>();
+        if (PTMSV)
+          V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
+        if (V.isUndef() || PTMSV) {
+          state = state->BindExpr(CastE, LCtx, V);
+          Bldr.generateNode(CastE, Pred, state);
+          continue;
+        }
+        // Explicitly proceed with default handler for this case cascade.
+        state =
+            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
+        continue;
+      }
       case CK_Dependent:
       case CK_ArrayToPointerDecay:
       case CK_BitCast:
@@ -319,8 +366,18 @@
       case CK_BooleanToSignedIntegral:
       case CK_NullToPointer:
       case CK_IntegralToPointer:
-      case CK_PointerToIntegral:
-      case CK_PointerToBoolean:
+      case CK_PointerToIntegral: {
+        SVal V = state->getSVal(Ex, LCtx);
+        if (V.getAs<nonloc::PointerToMember>()) {
+          state = state->BindExpr(CastE, LCtx, UnknownVal());
+          Bldr.generateNode(CastE, Pred, state);
+          continue;
+        }
+        // Explicitly proceed with default handler for this case cascade.
+        state =
+            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
+        continue;
+      }
       case CK_IntegralToBoolean:
       case CK_IntegralToFloating:
       case CK_FloatingToIntegral:
@@ -341,16 +398,11 @@
       case CK_AnyPointerToBlockPointerCast:
       case CK_ObjCObjectLValueCast:
       case CK_ZeroToOCLEvent:
+      case CK_ZeroToOCLQueue:
       case CK_IntToOCLSampler:
       case CK_LValueBitCast: {
-        // Delegate to SValBuilder to process.
-        SVal V = state->getSVal(Ex, LCtx);
-        V = svalBuilder.evalCast(V, T, ExTy);
-        // Negate the result if we're treating the boolean as a signed i1
-        if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
-          V = evalMinus(V);
-        state = state->BindExpr(CastE, LCtx, V);
-        Bldr.generateNode(CastE, Pred, state);
+        state =
+            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
         continue;
       }
       case CK_IntegralCast: {
@@ -435,27 +487,32 @@
         continue;
       }
       case CK_NullToMemberPointer: {
-        // FIXME: For now, member pointers are represented by void *.
-        SVal V = svalBuilder.makeNull();
+        SVal V = svalBuilder.getMemberPointer(nullptr);
         state = state->BindExpr(CastE, LCtx, V);
         Bldr.generateNode(CastE, Pred, state);
         continue;
       }
+      case CK_DerivedToBaseMemberPointer:
+      case CK_BaseToDerivedMemberPointer:
+      case CK_ReinterpretMemberPointer: {
+        SVal V = state->getSVal(Ex, LCtx);
+        if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
+          SVal CastedPTMSV = svalBuilder.makePointerToMember(
+              getBasicVals().accumCXXBase(
+                  llvm::make_range<CastExpr::path_const_iterator>(
+                      CastE->path_begin(), CastE->path_end()), *PTMSV));
+          state = state->BindExpr(CastE, LCtx, CastedPTMSV);
+          Bldr.generateNode(CastE, Pred, state);
+          continue;
+        }
+        // Explicitly proceed with default handler for this case cascade.
+        state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
+        continue;
+      }
       // Various C++ casts that are not handled yet.
       case CK_ToUnion:
-      case CK_BaseToDerivedMemberPointer:
-      case CK_DerivedToBaseMemberPointer:
-      case CK_ReinterpretMemberPointer:
       case CK_VectorSplat: {
-        // Recover some path-sensitivty by conjuring a new value.
-        QualType resultType = CastE->getType();
-        if (CastE->isGLValue())
-          resultType = getContext().getPointerType(resultType);
-        SVal result = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx,
-                                                   resultType,
-                                                   currBldrCtx->blockCount());
-        state = state->BindExpr(CastE, LCtx, result);
-        Bldr.generateNode(CastE, Pred, state);
+        state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
         continue;
       }
     }
@@ -478,7 +535,7 @@
   } else {
     assert(isa<InitListExpr>(Init));
     Loc CLLoc = State->getLValue(CL, LCtx);
-    State = State->bindLoc(CLLoc, V);
+    State = State->bindLoc(CLLoc, V, LCtx);
 
     if (CL->isGLValue())
       V = CLLoc;
@@ -610,23 +667,13 @@
     if (RHSVal.isUndef()) {
       X = RHSVal;
     } else {
-      DefinedOrUnknownSVal DefinedRHS = RHSVal.castAs<DefinedOrUnknownSVal>();
-      ProgramStateRef StTrue, StFalse;
-      std::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
-      if (StTrue) {
-        if (StFalse) {
-          // We can't constrain the value to 0 or 1.
-          // The best we can do is a cast.
-          X = getSValBuilder().evalCast(RHSVal, B->getType(), RHS->getType());
-        } else {
-          // The value is known to be true.
-          X = getSValBuilder().makeIntVal(1, B->getType());
-        }
-      } else {
-        // The value is known to be false.
-        assert(StFalse && "Infeasible path!");
-        X = getSValBuilder().makeIntVal(0, B->getType());
-      }
+      // We evaluate "RHSVal != 0" expression which result in 0 if the value is
+      // known to be false, 1 if the value is known to be true and a new symbol
+      // when the assumption is unknown.
+      nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType()));
+      X = evalBinOp(N->getState(), BO_NE, 
+                    svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
+                    Zero, B->getType());
     }
   }
   Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
@@ -658,7 +705,7 @@
     for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
          ei = IE->rend(); it != ei; ++it) {
       SVal V = state->getSVal(cast<Expr>(*it), LCtx);
-      vals = getBasicVals().consVals(V, vals);
+      vals = getBasicVals().prependSVal(V, vals);
     }
 
     B.generateNode(IE, Pred,
@@ -803,8 +850,24 @@
   getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
 }
 
-void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
-                                    ExplodedNode *Pred,
+void ExprEngine::handleUOExtension(ExplodedNodeSet::iterator I,
+                                   const UnaryOperator *U,
+                                   StmtNodeBuilder &Bldr) {
+  // FIXME: We can probably just have some magic in Environment::getSVal()
+  // that propagates values, instead of creating a new node here.
+  //
+  // Unary "+" is a no-op, similar to a parentheses.  We still have places
+  // where it may be a block-level expression, so we need to
+  // generate an extra node that just propagates the value of the
+  // subexpression.
+  const Expr *Ex = U->getSubExpr()->IgnoreParens();
+  ProgramStateRef state = (*I)->getState();
+  const LocationContext *LCtx = (*I)->getLocationContext();
+  Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
+                                           state->getSVal(Ex, LCtx)));
+}
+
+void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
                                     ExplodedNodeSet &Dst) {
   // FIXME: Prechecks eventually go in ::Visit().
   ExplodedNodeSet CheckedSet;
@@ -856,24 +919,30 @@
       break;
     }
 
+    case UO_AddrOf: {
+      // Process pointer-to-member address operation.
+      const Expr *Ex = U->getSubExpr()->IgnoreParens();
+      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
+        const ValueDecl *VD = DRE->getDecl();
+
+        if (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD)) {
+          ProgramStateRef State = (*I)->getState();
+          const LocationContext *LCtx = (*I)->getLocationContext();
+          SVal SV = svalBuilder.getMemberPointer(cast<DeclaratorDecl>(VD));
+          Bldr.generateNode(U, *I, State->BindExpr(U, LCtx, SV));
+          break;
+        }
+      }
+      // Explicitly proceed with default handler for this case cascade.
+      handleUOExtension(I, U, Bldr);
+      break;
+    }
     case UO_Plus:
       assert(!U->isGLValue());
       // FALL-THROUGH.
     case UO_Deref:
-    case UO_AddrOf:
     case UO_Extension: {
-      // FIXME: We can probably just have some magic in Environment::getSVal()
-      // that propagates values, instead of creating a new node here.
-      //
-      // Unary "+" is a no-op, similar to a parentheses.  We still have places
-      // where it may be a block-level expression, so we need to
-      // generate an extra node that just propagates the value of the
-      // subexpression.
-      const Expr *Ex = U->getSubExpr()->IgnoreParens();
-      ProgramStateRef state = (*I)->getState();
-      const LocationContext *LCtx = (*I)->getLocationContext();
-      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
-                                               state->getSVal(Ex, LCtx)));
+      handleUOExtension(I, U, Bldr);
       break;
     }
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 011f776..ca2e242 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -317,7 +317,7 @@
         // actually make things worse. Placement new makes this tricky as well,
         // since it's then possible to be initializing one part of a multi-
         // dimensional array.
-        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
+        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal, LCtx);
         Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
                           ProgramPoint::PreStmtKind);
       }
@@ -346,6 +346,30 @@
       defaultEvalCall(Bldr, *I, *Call);
   }
 
+  // If the CFG was contructed without elements for temporary destructors
+  // and the just-called constructor created a temporary object then
+  // stop exploration if the temporary object has a noreturn constructor.
+  // This can lose coverage because the destructor, if it were present
+  // in the CFG, would be called at the end of the full expression or
+  // later (for life-time extended temporaries) -- but avoids infeasible
+  // paths when no-return temporary destructors are used for assertions.
+  const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
+  if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
+      const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
+      if (Target && isa<CXXTempObjectRegion>(Target) &&
+          Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+
+      for (ExplodedNode *N : DstEvaluated) {
+        Bldr.generateSink(CE, N, N->getState());
+      }
+
+      // There is no need to run the PostCall and PostStmtchecker
+      // callbacks because we just generated sinks on all nodes in th
+      // frontier.
+      return;
+    }
+ }
+
   ExplodedNodeSet DstPostCall;
   getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
                                              *Call, *this);
@@ -548,7 +572,7 @@
   SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
                                         currBldrCtx->blockCount());
   ProgramStateRef state = Pred->getState();
-  state = state->bindLoc(state->getLValue(VD, LCtx), V);
+  state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
 
   StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   Bldr.generateNode(CS, Pred, state);
@@ -603,7 +627,7 @@
       InitVal = State->getSVal(SizeExpr, LocCtxt);
     }
 
-    State = State->bindLoc(FieldLoc, InitVal);
+    State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
   }
 
   // Decay the Loc into an RValue, because there might be a
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index 92c5fe6..f5e64f4 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -115,11 +115,11 @@
         SymbolRef Sym = SymMgr.conjureSymbol(elem, LCtx, T,
                                              currBldrCtx->blockCount());
         SVal V = svalBuilder.makeLoc(Sym);
-        hasElems = hasElems->bindLoc(elementV, V);
+        hasElems = hasElems->bindLoc(elementV, V, LCtx);
 
         // Bind the location to 'nil' on the false branch.
         SVal nilV = svalBuilder.makeIntVal(0, T);
-        noElems = noElems->bindLoc(elementV, nilV);
+        noElems = noElems->bindLoc(elementV, nilV, LCtx);
       }
 
     // Create the new nodes.
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index f157c3d..f0f6dd2 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -156,8 +156,8 @@
   unsigned TotalPieces = path.size();
   unsigned TotalNotePieces =
       std::count_if(path.begin(), path.end(),
-                    [](const IntrusiveRefCntPtr<PathDiagnosticPiece> &p) {
-                      return isa<PathDiagnosticNotePiece>(p.get());
+                    [](const std::shared_ptr<PathDiagnosticPiece> &p) {
+                      return isa<PathDiagnosticNotePiece>(*p);
                     });
 
   unsigned TotalRegularPieces = TotalPieces - TotalNotePieces;
@@ -615,12 +615,13 @@
         I!=E; ++I) {
 
     if (const PathDiagnosticMacroPiece *MP =
-          dyn_cast<PathDiagnosticMacroPiece>(*I)) {
+            dyn_cast<PathDiagnosticMacroPiece>(I->get())) {
       num = ProcessMacroPiece(os, *MP, num);
       continue;
     }
 
-    if (PathDiagnosticEventPiece *EP = dyn_cast<PathDiagnosticEventPiece>(*I)) {
+    if (PathDiagnosticEventPiece *EP =
+            dyn_cast<PathDiagnosticEventPiece>(I->get())) {
       os << "<div class=\"msg msgEvent\" style=\"width:94%; "
             "margin-left:5px\">"
             "<table class=\"msgT\"><tr>"
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index c4ba2ae..d6e8fe5 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -816,9 +816,11 @@
 
     const StackFrameContext *STC = V.get<const StackFrameContext*>();
 
-    if (!STC)
+    if (!STC) {
+      // FIXME: Assign a more sensible memory space to static locals
+      // we see from within blocks that we analyze as top-level declarations.
       sReg = getUnknownRegion();
-    else {
+    } else {
       if (D->hasLocalStorage()) {
         sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
                ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 5675cb2..7c5ee3b 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -29,11 +29,10 @@
 using namespace ento;
 
 bool PathDiagnosticMacroPiece::containsEvent() const {
-  for (PathPieces::const_iterator I = subPieces.begin(), E = subPieces.end();
-       I!=E; ++I) {
-    if (isa<PathDiagnosticEventPiece>(*I))
+  for (auto &P : subPieces) {
+    if (isa<PathDiagnosticEventPiece>(*P))
       return true;
-    if (PathDiagnosticMacroPiece *MP = dyn_cast<PathDiagnosticMacroPiece>(*I))
+    if (auto *MP = dyn_cast<PathDiagnosticMacroPiece>(P.get()))
       if (MP->containsEvent())
         return true;
   }
@@ -64,33 +63,27 @@
 
 void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current,
                            bool ShouldFlattenMacros) const {
-  for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
-    PathDiagnosticPiece *Piece = I->get();
-
+  for (auto &Piece : *this) {
     switch (Piece->getKind()) {
     case PathDiagnosticPiece::Call: {
-      PathDiagnosticCallPiece *Call = cast<PathDiagnosticCallPiece>(Piece);
-      IntrusiveRefCntPtr<PathDiagnosticEventPiece> CallEnter =
-        Call->getCallEnterEvent();
-      if (CallEnter)
-        Current.push_back(CallEnter);
-      Call->path.flattenTo(Primary, Primary, ShouldFlattenMacros);
-      IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
-        Call->getCallExitEvent();
-      if (callExit)
-        Current.push_back(callExit);
+      auto &Call = cast<PathDiagnosticCallPiece>(*Piece);
+      if (auto CallEnter = Call.getCallEnterEvent())
+        Current.push_back(std::move(CallEnter));
+      Call.path.flattenTo(Primary, Primary, ShouldFlattenMacros);
+      if (auto callExit = Call.getCallExitEvent())
+        Current.push_back(std::move(callExit));
       break;
     }
     case PathDiagnosticPiece::Macro: {
-      PathDiagnosticMacroPiece *Macro = cast<PathDiagnosticMacroPiece>(Piece);
+      auto &Macro = cast<PathDiagnosticMacroPiece>(*Piece);
       if (ShouldFlattenMacros) {
-        Macro->subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros);
+        Macro.subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros);
       } else {
         Current.push_back(Piece);
         PathPieces NewPath;
-        Macro->subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros);
+        Macro.subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros);
         // FIXME: This probably shouldn't mutate the original path piece.
-        Macro->subPieces = NewPath;
+        Macro.subPieces = NewPath;
       }
       break;
     }
@@ -143,7 +136,7 @@
   // Check if the last piece in the callee path is a call to a function outside
   // of the main file.
   if (PathDiagnosticCallPiece *CPInner =
-      dyn_cast<PathDiagnosticCallPiece>(Path.back())) {
+          dyn_cast<PathDiagnosticCallPiece>(Path.back().get())) {
     return getFirstStackedCallToHeaderFile(CPInner, SMgr);
   }
 
@@ -890,24 +883,26 @@
 // Manipulation of PathDiagnosticCallPieces.
 //===----------------------------------------------------------------------===//
 
-PathDiagnosticCallPiece *
-PathDiagnosticCallPiece::construct(const ExplodedNode *N,
-                                   const CallExitEnd &CE,
+std::shared_ptr<PathDiagnosticCallPiece>
+PathDiagnosticCallPiece::construct(const ExplodedNode *N, const CallExitEnd &CE,
                                    const SourceManager &SM) {
   const Decl *caller = CE.getLocationContext()->getDecl();
   PathDiagnosticLocation pos = getLocationForCaller(CE.getCalleeContext(),
                                                     CE.getLocationContext(),
                                                     SM);
-  return new PathDiagnosticCallPiece(caller, pos);
+  return std::shared_ptr<PathDiagnosticCallPiece>(
+      new PathDiagnosticCallPiece(caller, pos));
 }
 
 PathDiagnosticCallPiece *
 PathDiagnosticCallPiece::construct(PathPieces &path,
                                    const Decl *caller) {
-  PathDiagnosticCallPiece *C = new PathDiagnosticCallPiece(path, caller);
+  std::shared_ptr<PathDiagnosticCallPiece> C(
+      new PathDiagnosticCallPiece(path, caller));
   path.clear();
-  path.push_front(C);
-  return C;
+  auto *R = C.get();
+  path.push_front(std::move(C));
+  return R;
 }
 
 void PathDiagnosticCallPiece::setCallee(const CallEnter &CE,
@@ -989,7 +984,7 @@
   return true;
 }
 
-IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+std::shared_ptr<PathDiagnosticEventPiece>
 PathDiagnosticCallPiece::getCallEnterEvent() const {
   if (!Callee)
     return nullptr;
@@ -1001,10 +996,10 @@
   describeCodeDecl(Out, Callee, /*ExtendedDescription=*/true);
 
   assert(callEnter.asLocation().isValid());
-  return new PathDiagnosticEventPiece(callEnter, Out.str());
+  return std::make_shared<PathDiagnosticEventPiece>(callEnter, Out.str());
 }
 
-IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+std::shared_ptr<PathDiagnosticEventPiece>
 PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const {
   if (!callEnterWithin.asLocation().isValid())
     return nullptr;
@@ -1020,10 +1015,10 @@
   Out << "Entered call";
   describeCodeDecl(Out, Caller, /*ExtendedDescription=*/false, " from ");
 
-  return new PathDiagnosticEventPiece(callEnterWithin, Out.str());
+  return std::make_shared<PathDiagnosticEventPiece>(callEnterWithin, Out.str());
 }
 
-IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+std::shared_ptr<PathDiagnosticEventPiece>
 PathDiagnosticCallPiece::getCallExitEvent() const {
   if (NoExit)
     return nullptr;
@@ -1042,7 +1037,7 @@
   }
 
   assert(callReturn.asLocation().isValid());
-  return new PathDiagnosticEventPiece(callReturn, Out.str());
+  return std::make_shared<PathDiagnosticEventPiece>(callReturn, Out.str());
 }
 
 static void compute_path_size(const PathPieces &pieces, unsigned &size) {
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index c5263ee..66812ed 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -208,19 +208,14 @@
                        unsigned indent,
                        unsigned depth) {
 
-  IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnter =
-    P.getCallEnterEvent();
-
-  if (callEnter)
+  if (auto callEnter = P.getCallEnterEvent())
     ReportPiece(o, *callEnter, FM, SM, LangOpts, indent, depth, true,
                 P.isLastInMainSourceFile());
 
-  IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnterWithinCaller =
-    P.getCallEnterWithinCallerEvent();
 
   ++depth;
 
-  if (callEnterWithinCaller)
+  if (auto callEnterWithinCaller = P.getCallEnterWithinCallerEvent())
     ReportPiece(o, *callEnterWithinCaller, FM, SM, LangOpts,
                 indent, depth, true);
 
@@ -229,10 +224,7 @@
 
   --depth;
 
-  IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
-    P.getCallExitEvent();
-
-  if (callExit)
+  if (auto callExit = P.getCallExitEvent())
     ReportPiece(o, *callExit, FM, SM, LangOpts, indent, depth, true);
 }
 
@@ -299,10 +291,9 @@
   if (!Diags.empty())
     SM = &Diags.front()->path.front()->getLocation().getManager();
 
-
-  auto AddPieceFID = [&FM, &Fids, SM](const PathDiagnosticPiece *Piece)->void {
-    AddFID(FM, Fids, *SM, Piece->getLocation().asLocation());
-    ArrayRef<SourceRange> Ranges = Piece->getRanges();
+  auto AddPieceFID = [&FM, &Fids, SM](const PathDiagnosticPiece &Piece) {
+    AddFID(FM, Fids, *SM, Piece.getLocation().asLocation());
+    ArrayRef<SourceRange> Ranges = Piece.getRanges();
     for (const SourceRange &Range : Ranges) {
       AddFID(FM, Fids, *SM, Range.getBegin());
       AddFID(FM, Fids, *SM, Range.getEnd());
@@ -318,23 +309,20 @@
       const PathPieces &Path = *WorkList.pop_back_val();
 
       for (const auto &Iter : Path) {
-        const PathDiagnosticPiece *Piece = Iter.get();
+        const PathDiagnosticPiece &Piece = *Iter;
         AddPieceFID(Piece);
 
         if (const PathDiagnosticCallPiece *Call =
-            dyn_cast<PathDiagnosticCallPiece>(Piece)) {
-          if (IntrusiveRefCntPtr<PathDiagnosticEventPiece>
-              CallEnterWithin = Call->getCallEnterWithinCallerEvent())
-            AddPieceFID(CallEnterWithin.get());
+                dyn_cast<PathDiagnosticCallPiece>(&Piece)) {
+          if (auto CallEnterWithin = Call->getCallEnterWithinCallerEvent())
+            AddPieceFID(*CallEnterWithin);
 
-          if (IntrusiveRefCntPtr<PathDiagnosticEventPiece>
-              CallEnterEvent = Call->getCallEnterEvent())
-            AddPieceFID(CallEnterEvent.get());
+          if (auto CallEnterEvent = Call->getCallEnterEvent())
+            AddPieceFID(*CallEnterEvent);
 
           WorkList.push_back(&Call->path);
-        }
-        else if (const PathDiagnosticMacroPiece *Macro =
-                 dyn_cast<PathDiagnosticMacroPiece>(Piece)) {
+        } else if (const PathDiagnosticMacroPiece *Macro =
+                       dyn_cast<PathDiagnosticMacroPiece>(&Piece)) {
           WorkList.push_back(&Macro->subPieces);
         }
       }
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 03ace35..31556c7 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -111,24 +111,29 @@
   return ConstraintMgr->removeDeadBindings(Result, SymReaper);
 }
 
-ProgramStateRef ProgramState::bindLoc(Loc LV, SVal V, bool notifyChanges) const {
+ProgramStateRef ProgramState::bindLoc(Loc LV,
+                                      SVal V,
+                                      const LocationContext *LCtx,
+                                      bool notifyChanges) const {
   ProgramStateManager &Mgr = getStateManager();
   ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
                                                              LV, V));
   const MemRegion *MR = LV.getAsRegion();
   if (MR && Mgr.getOwningEngine() && notifyChanges)
-    return Mgr.getOwningEngine()->processRegionChange(newState, MR);
+    return Mgr.getOwningEngine()->processRegionChange(newState, MR, LCtx);
 
   return newState;
 }
 
-ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
+ProgramStateRef ProgramState::bindDefault(SVal loc,
+                                          SVal V,
+                                          const LocationContext *LCtx) const {
   ProgramStateManager &Mgr = getStateManager();
   const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
   const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
   ProgramStateRef new_state = makeWithStore(newStore);
   return Mgr.getOwningEngine() ?
-           Mgr.getOwningEngine()->processRegionChange(new_state, R) :
+           Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) :
            new_state;
 }
 
@@ -202,7 +207,7 @@
     }
 
     return Eng->processRegionChanges(newState, IS, TopLevelInvalidated,
-                                     Invalidated, Call);
+                                     Invalidated, LCtx, Call);
   }
 
   const StoreRef &newStore =
diff --git a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index a312350..e0ad2d8 100644
--- a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -12,7 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "SimpleConstraintManager.h"
+#include "RangedConstraintManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
@@ -27,22 +27,17 @@
 /// guarantee that from <= to.  Note that Range is immutable, so as not
 /// to subvert RangeSet's immutability.
 namespace {
-class Range : public std::pair<const llvm::APSInt*,
-                                                const llvm::APSInt*> {
+class Range : public std::pair<const llvm::APSInt *, const llvm::APSInt *> {
 public:
   Range(const llvm::APSInt &from, const llvm::APSInt &to)
-    : std::pair<const llvm::APSInt*, const llvm::APSInt*>(&from, &to) {
+      : std::pair<const llvm::APSInt *, const llvm::APSInt *>(&from, &to) {
     assert(from <= to);
   }
   bool Includes(const llvm::APSInt &v) const {
     return *first <= v && v <= *second;
   }
-  const llvm::APSInt &From() const {
-    return *first;
-  }
-  const llvm::APSInt &To() const {
-    return *second;
-  }
+  const llvm::APSInt &From() const { return *first; }
+  const llvm::APSInt &To() const { return *second; }
   const llvm::APSInt *getConcreteValue() const {
     return &From() == &To() ? &From() : nullptr;
   }
@@ -53,7 +48,6 @@
   }
 };
 
-
 class RangeTrait : public llvm::ImutContainerInfo<Range> {
 public:
   // When comparing if one Range is less than another, we should compare
@@ -61,8 +55,8 @@
   // consistent (instead of comparing by pointer values) and can potentially
   // be used to speed up some of the operations in RangeSet.
   static inline bool isLess(key_type_ref lhs, key_type_ref rhs) {
-    return *lhs.first < *rhs.first || (!(*rhs.first < *lhs.first) &&
-                                       *lhs.second < *rhs.second);
+    return *lhs.first < *rhs.first ||
+           (!(*rhs.first < *lhs.first) && *lhs.second < *rhs.second);
   }
 };
 
@@ -96,7 +90,7 @@
 
   /// Construct a new RangeSet representing '{ [from, to] }'.
   RangeSet(Factory &F, const llvm::APSInt &from, const llvm::APSInt &to)
-    : ranges(F.add(F.getEmptySet(), Range(from, to))) {}
+      : ranges(F.add(F.getEmptySet(), Range(from, to))) {}
 
   /// Profile - Generates a hash profile of this RangeSet for use
   ///  by FoldingSet.
@@ -105,16 +99,14 @@
   /// getConcreteValue - If a symbol is contrained to equal a specific integer
   ///  constant then this method returns that value.  Otherwise, it returns
   ///  NULL.
-  const llvm::APSInt* getConcreteValue() const {
+  const llvm::APSInt *getConcreteValue() const {
     return ranges.isSingleton() ? ranges.begin()->getConcreteValue() : nullptr;
   }
 
 private:
   void IntersectInRange(BasicValueFactory &BV, Factory &F,
-                        const llvm::APSInt &Lower,
-                        const llvm::APSInt &Upper,
-                        PrimRangeSet &newRanges,
-                        PrimRangeSet::iterator &i,
+                        const llvm::APSInt &Lower, const llvm::APSInt &Upper,
+                        PrimRangeSet &newRanges, PrimRangeSet::iterator &i,
                         PrimRangeSet::iterator &e) const {
     // There are six cases for each range R in the set:
     //   1. R is entirely before the intersection range.
@@ -134,8 +126,8 @@
 
       if (i->Includes(Lower)) {
         if (i->Includes(Upper)) {
-          newRanges = F.add(newRanges, Range(BV.getValue(Lower),
-                                             BV.getValue(Upper)));
+          newRanges =
+              F.add(newRanges, Range(BV.getValue(Lower), BV.getValue(Upper)));
           break;
         } else
           newRanges = F.add(newRanges, Range(BV.getValue(Lower), i->To()));
@@ -243,8 +235,8 @@
   // range is taken to wrap around. This is equivalent to taking the
   // intersection with the two ranges [Min, Upper] and [Lower, Max],
   // or, alternatively, /removing/ all integers between Upper and Lower.
-  RangeSet Intersect(BasicValueFactory &BV, Factory &F,
-                     llvm::APSInt Lower, llvm::APSInt Upper) const {
+  RangeSet Intersect(BasicValueFactory &BV, Factory &F, llvm::APSInt Lower,
+                     llvm::APSInt Upper) const {
     if (!pin(Lower, Upper))
       return F.getEmptySet();
 
@@ -290,56 +282,69 @@
                                                              RangeSet))
 
 namespace {
-class RangeConstraintManager : public SimpleConstraintManager{
-  RangeSet GetRange(ProgramStateRef state, SymbolRef sym);
+class RangeConstraintManager : public RangedConstraintManager {
 public:
-  RangeConstraintManager(SubEngine *subengine, SValBuilder &SVB)
-    : SimpleConstraintManager(subengine, SVB) {}
+  RangeConstraintManager(SubEngine *SE, SValBuilder &SVB)
+      : RangedConstraintManager(SE, SVB) {}
 
-  ProgramStateRef assumeSymNE(ProgramStateRef state, SymbolRef sym,
-                             const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment) override;
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from ConstraintManager.
+  //===------------------------------------------------------------------===//
 
-  ProgramStateRef assumeSymEQ(ProgramStateRef state, SymbolRef sym,
-                             const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment) override;
+  bool canReasonAbout(SVal X) const override;
 
-  ProgramStateRef assumeSymLT(ProgramStateRef state, SymbolRef sym,
-                             const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment) override;
-
-  ProgramStateRef assumeSymGT(ProgramStateRef state, SymbolRef sym,
-                             const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment) override;
-
-  ProgramStateRef assumeSymGE(ProgramStateRef state, SymbolRef sym,
-                             const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment) override;
-
-  ProgramStateRef assumeSymLE(ProgramStateRef state, SymbolRef sym,
-                             const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment) override;
-
-  ProgramStateRef assumeSymbolWithinInclusiveRange(
-        ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
-        const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
-
-  ProgramStateRef assumeSymbolOutOfInclusiveRange(
-        ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
-        const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
-
-  const llvm::APSInt* getSymVal(ProgramStateRef St,
-                                SymbolRef sym) const override;
   ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
 
-  ProgramStateRef removeDeadBindings(ProgramStateRef St,
-                                     SymbolReaper& SymReaper) override;
+  const llvm::APSInt *getSymVal(ProgramStateRef State,
+                                SymbolRef Sym) const override;
 
-  void print(ProgramStateRef St, raw_ostream &Out,
-             const char* nl, const char *sep) override;
+  ProgramStateRef removeDeadBindings(ProgramStateRef State,
+                                     SymbolReaper &SymReaper) override;
+
+  void print(ProgramStateRef State, raw_ostream &Out, const char *nl,
+             const char *sep) override;
+
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from RangedConstraintManager.
+  //===------------------------------------------------------------------===//
+
+  ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
+                              const llvm::APSInt &V,
+                              const llvm::APSInt &Adjustment) override;
+
+  ProgramStateRef assumeSymEQ(ProgramStateRef State, SymbolRef Sym,
+                              const llvm::APSInt &V,
+                              const llvm::APSInt &Adjustment) override;
+
+  ProgramStateRef assumeSymLT(ProgramStateRef State, SymbolRef Sym,
+                              const llvm::APSInt &V,
+                              const llvm::APSInt &Adjustment) override;
+
+  ProgramStateRef assumeSymGT(ProgramStateRef State, SymbolRef Sym,
+                              const llvm::APSInt &V,
+                              const llvm::APSInt &Adjustment) override;
+
+  ProgramStateRef assumeSymLE(ProgramStateRef State, SymbolRef Sym,
+                              const llvm::APSInt &V,
+                              const llvm::APSInt &Adjustment) override;
+
+  ProgramStateRef assumeSymGE(ProgramStateRef State, SymbolRef Sym,
+                              const llvm::APSInt &V,
+                              const llvm::APSInt &Adjustment) override;
+
+  ProgramStateRef assumeSymWithinInclusiveRange(
+      ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+      const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
+
+  ProgramStateRef assumeSymOutsideInclusiveRange(
+      ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+      const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
 
 private:
   RangeSet::Factory F;
+
+  RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
+
   RangeSet getSymLTRange(ProgramStateRef St, SymbolRef Sym,
                          const llvm::APSInt &Int,
                          const llvm::APSInt &Adjustment);
@@ -363,10 +368,46 @@
   return llvm::make_unique<RangeConstraintManager>(Eng, StMgr.getSValBuilder());
 }
 
-const llvm::APSInt* RangeConstraintManager::getSymVal(ProgramStateRef St,
-                                                      SymbolRef sym) const {
-  const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(sym);
-  return T ? T->getConcreteValue() : nullptr;
+bool RangeConstraintManager::canReasonAbout(SVal X) const {
+  Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
+  if (SymVal && SymVal->isExpression()) {
+    const SymExpr *SE = SymVal->getSymbol();
+
+    if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
+      switch (SIE->getOpcode()) {
+      // We don't reason yet about bitwise-constraints on symbolic values.
+      case BO_And:
+      case BO_Or:
+      case BO_Xor:
+        return false;
+      // We don't reason yet about these arithmetic constraints on
+      // symbolic values.
+      case BO_Mul:
+      case BO_Div:
+      case BO_Rem:
+      case BO_Shl:
+      case BO_Shr:
+        return false;
+      // All other cases.
+      default:
+        return true;
+      }
+    }
+
+    if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
+      if (BinaryOperator::isComparisonOp(SSE->getOpcode())) {
+        // We handle Loc <> Loc comparisons, but not (yet) NonLoc <> NonLoc.
+        if (Loc::isLocType(SSE->getLHS()->getType())) {
+          assert(Loc::isLocType(SSE->getRHS()->getType()));
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
+  return true;
 }
 
 ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
@@ -393,35 +434,41 @@
   return ConditionTruthVal();
 }
 
+const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
+                                                      SymbolRef Sym) const {
+  const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(Sym);
+  return T ? T->getConcreteValue() : nullptr;
+}
+
 /// Scan all symbols referenced by the constraints. If the symbol is not alive
 /// as marked in LSymbols, mark it as dead in DSymbols.
 ProgramStateRef
-RangeConstraintManager::removeDeadBindings(ProgramStateRef state,
-                                           SymbolReaper& SymReaper) {
+RangeConstraintManager::removeDeadBindings(ProgramStateRef State,
+                                           SymbolReaper &SymReaper) {
   bool Changed = false;
-  ConstraintRangeTy CR = state->get<ConstraintRange>();
-  ConstraintRangeTy::Factory &CRFactory = state->get_context<ConstraintRange>();
+  ConstraintRangeTy CR = State->get<ConstraintRange>();
+  ConstraintRangeTy::Factory &CRFactory = State->get_context<ConstraintRange>();
 
   for (ConstraintRangeTy::iterator I = CR.begin(), E = CR.end(); I != E; ++I) {
-    SymbolRef sym = I.getKey();
-    if (SymReaper.maybeDead(sym)) {
+    SymbolRef Sym = I.getKey();
+    if (SymReaper.maybeDead(Sym)) {
       Changed = true;
-      CR = CRFactory.remove(CR, sym);
+      CR = CRFactory.remove(CR, Sym);
     }
   }
 
-  return Changed ? state->set<ConstraintRange>(CR) : state;
+  return Changed ? State->set<ConstraintRange>(CR) : State;
 }
 
-RangeSet
-RangeConstraintManager::GetRange(ProgramStateRef state, SymbolRef sym) {
-  if (ConstraintRangeTy::data_type* V = state->get<ConstraintRange>(sym))
+RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
+                                          SymbolRef Sym) {
+  if (ConstraintRangeTy::data_type *V = State->get<ConstraintRange>(Sym))
     return *V;
 
   // Lazily generate a new RangeSet representing all possible values for the
   // given symbol type.
   BasicValueFactory &BV = getBasicVals();
-  QualType T = sym->getType();
+  QualType T = Sym->getType();
 
   RangeSet Result(F, BV.getMinValue(T), BV.getMaxValue(T));
 
@@ -429,14 +476,14 @@
   if (T->isReferenceType()) {
     APSIntType IntType = BV.getAPSIntType(T);
     Result = Result.Intersect(BV, F, ++IntType.getZeroValue(),
-                                     --IntType.getZeroValue());
+                              --IntType.getZeroValue());
   }
 
   return Result;
 }
 
 //===------------------------------------------------------------------------===
-// assumeSymX methods: public interface for RangeConstraintManager.
+// assumeSymX methods: protected interface for RangeConstraintManager.
 //===------------------------------------------------------------------------===/
 
 // The syntax for ranges below is mathematical, using [x, y] for closed ranges
@@ -463,7 +510,7 @@
 
   // [Int-Adjustment+1, Int-Adjustment-1]
   // Notice that the lower bound is greater than the upper bound.
-  RangeSet New = GetRange(St, Sym).Intersect(getBasicVals(), F, Upper, Lower);
+  RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, Upper, Lower);
   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
@@ -478,7 +525,7 @@
 
   // [Int-Adjustment, Int-Adjustment]
   llvm::APSInt AdjInt = AdjustmentType.convert(Int) - Adjustment;
-  RangeSet New = GetRange(St, Sym).Intersect(getBasicVals(), F, AdjInt, AdjInt);
+  RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, AdjInt, AdjInt);
   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
@@ -494,7 +541,7 @@
   case APSIntType::RTR_Within:
     break;
   case APSIntType::RTR_Above:
-    return GetRange(St, Sym);
+    return getRange(St, Sym);
   }
 
   // Special case for Int == Min. This is always false.
@@ -507,7 +554,7 @@
   llvm::APSInt Upper = ComparisonVal - Adjustment;
   --Upper;
 
-  return GetRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
+  return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
 }
 
 ProgramStateRef
@@ -518,15 +565,15 @@
   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
-RangeSet
-RangeConstraintManager::getSymGTRange(ProgramStateRef St, SymbolRef Sym,
-                                      const llvm::APSInt &Int,
-                                      const llvm::APSInt &Adjustment) {
+RangeSet RangeConstraintManager::getSymGTRange(ProgramStateRef St,
+                                               SymbolRef Sym,
+                                               const llvm::APSInt &Int,
+                                               const llvm::APSInt &Adjustment) {
   // Before we do any real work, see if the value can even show up.
   APSIntType AdjustmentType(Adjustment);
   switch (AdjustmentType.testInRange(Int, true)) {
   case APSIntType::RTR_Below:
-    return GetRange(St, Sym);
+    return getRange(St, Sym);
   case APSIntType::RTR_Within:
     break;
   case APSIntType::RTR_Above:
@@ -543,7 +590,7 @@
   llvm::APSInt Upper = Max - Adjustment;
   ++Lower;
 
-  return GetRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
+  return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
 }
 
 ProgramStateRef
@@ -554,15 +601,15 @@
   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
-RangeSet
-RangeConstraintManager::getSymGERange(ProgramStateRef St, SymbolRef Sym,
-                                      const llvm::APSInt &Int,
-                                      const llvm::APSInt &Adjustment) {
+RangeSet RangeConstraintManager::getSymGERange(ProgramStateRef St,
+                                               SymbolRef Sym,
+                                               const llvm::APSInt &Int,
+                                               const llvm::APSInt &Adjustment) {
   // Before we do any real work, see if the value can even show up.
   APSIntType AdjustmentType(Adjustment);
   switch (AdjustmentType.testInRange(Int, true)) {
   case APSIntType::RTR_Below:
-    return GetRange(St, Sym);
+    return getRange(St, Sym);
   case APSIntType::RTR_Within:
     break;
   case APSIntType::RTR_Above:
@@ -573,13 +620,13 @@
   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
   llvm::APSInt Min = AdjustmentType.getMinValue();
   if (ComparisonVal == Min)
-    return GetRange(St, Sym);
+    return getRange(St, Sym);
 
   llvm::APSInt Max = AdjustmentType.getMaxValue();
   llvm::APSInt Lower = ComparisonVal - Adjustment;
   llvm::APSInt Upper = Max - Adjustment;
 
-  return GetRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
+  return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
 }
 
 ProgramStateRef
@@ -590,10 +637,9 @@
   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
-RangeSet
-RangeConstraintManager::getSymLERange(const RangeSet &RS,
-                                      const llvm::APSInt &Int,
-                                      const llvm::APSInt &Adjustment) {
+RangeSet RangeConstraintManager::getSymLERange(const RangeSet &RS,
+                                               const llvm::APSInt &Int,
+                                               const llvm::APSInt &Adjustment) {
   // Before we do any real work, see if the value can even show up.
   APSIntType AdjustmentType(Adjustment);
   switch (AdjustmentType.testInRange(Int, true)) {
@@ -618,10 +664,10 @@
   return RS.Intersect(getBasicVals(), F, Lower, Upper);
 }
 
-RangeSet
-RangeConstraintManager::getSymLERange(ProgramStateRef St, SymbolRef Sym,
-                                      const llvm::APSInt &Int,
-                                      const llvm::APSInt &Adjustment) {
+RangeSet RangeConstraintManager::getSymLERange(ProgramStateRef St,
+                                               SymbolRef Sym,
+                                               const llvm::APSInt &Int,
+                                               const llvm::APSInt &Adjustment) {
   // Before we do any real work, see if the value can even show up.
   APSIntType AdjustmentType(Adjustment);
   switch (AdjustmentType.testInRange(Int, true)) {
@@ -630,20 +676,20 @@
   case APSIntType::RTR_Within:
     break;
   case APSIntType::RTR_Above:
-    return GetRange(St, Sym);
+    return getRange(St, Sym);
   }
 
   // Special case for Int == Max. This is always feasible.
   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
   llvm::APSInt Max = AdjustmentType.getMaxValue();
   if (ComparisonVal == Max)
-    return GetRange(St, Sym);
+    return getRange(St, Sym);
 
   llvm::APSInt Min = AdjustmentType.getMinValue();
   llvm::APSInt Lower = Min - Adjustment;
   llvm::APSInt Upper = ComparisonVal - Adjustment;
 
-  return GetRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
+  return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
 }
 
 ProgramStateRef
@@ -654,8 +700,7 @@
   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
-ProgramStateRef
-RangeConstraintManager::assumeSymbolWithinInclusiveRange(
+ProgramStateRef RangeConstraintManager::assumeSymWithinInclusiveRange(
     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
   RangeSet New = getSymGERange(State, Sym, From, Adjustment);
@@ -665,8 +710,7 @@
   return New.isEmpty() ? nullptr : State->set<ConstraintRange>(Sym, New);
 }
 
-ProgramStateRef
-RangeConstraintManager::assumeSymbolOutOfInclusiveRange(
+ProgramStateRef RangeConstraintManager::assumeSymOutsideInclusiveRange(
     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
   RangeSet RangeLT = getSymLTRange(State, Sym, From, Adjustment);
@@ -680,7 +724,7 @@
 //===------------------------------------------------------------------------===/
 
 void RangeConstraintManager::print(ProgramStateRef St, raw_ostream &Out,
-                                   const char* nl, const char *sep) {
+                                   const char *nl, const char *sep) {
 
   ConstraintRangeTy Ranges = St->get<ConstraintRange>();
 
@@ -690,7 +734,8 @@
   }
 
   Out << nl << sep << "Ranges of symbol values:";
-  for (ConstraintRangeTy::iterator I=Ranges.begin(), E=Ranges.end(); I!=E; ++I){
+  for (ConstraintRangeTy::iterator I = Ranges.begin(), E = Ranges.end(); I != E;
+       ++I) {
     Out << nl << ' ' << I.getKey() << " : ";
     I.getData().print(Out);
   }
diff --git a/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
new file mode 100644
index 0000000..1304116
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
@@ -0,0 +1,204 @@
+//== RangedConstraintManager.cpp --------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines RangedConstraintManager, a class that provides a
+//  range-based constraint manager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RangedConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+
+namespace clang {
+
+namespace ento {
+
+RangedConstraintManager::~RangedConstraintManager() {}
+
+ProgramStateRef RangedConstraintManager::assumeSym(ProgramStateRef State,
+                                                   SymbolRef Sym,
+                                                   bool Assumption) {
+  // Handle SymbolData.
+  if (isa<SymbolData>(Sym)) {
+    return assumeSymUnsupported(State, Sym, Assumption);
+
+    // Handle symbolic expression.
+  } else if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(Sym)) {
+    // We can only simplify expressions whose RHS is an integer.
+
+    BinaryOperator::Opcode op = SIE->getOpcode();
+    if (BinaryOperator::isComparisonOp(op)) {
+      if (!Assumption)
+        op = BinaryOperator::negateComparisonOp(op);
+
+      return assumeSymRel(State, SIE->getLHS(), op, SIE->getRHS());
+    }
+
+  } else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
+    // Translate "a != b" to "(b - a) != 0".
+    // We invert the order of the operands as a heuristic for how loop
+    // conditions are usually written ("begin != end") as compared to length
+    // calculations ("end - begin"). The more correct thing to do would be to
+    // canonicalize "a - b" and "b - a", which would allow us to treat
+    // "a != b" and "b != a" the same.
+    SymbolManager &SymMgr = getSymbolManager();
+    BinaryOperator::Opcode Op = SSE->getOpcode();
+    assert(BinaryOperator::isComparisonOp(Op));
+
+    // For now, we only support comparing pointers.
+    assert(Loc::isLocType(SSE->getLHS()->getType()));
+    assert(Loc::isLocType(SSE->getRHS()->getType()));
+    QualType DiffTy = SymMgr.getContext().getPointerDiffType();
+    SymbolRef Subtraction =
+        SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub, SSE->getLHS(), DiffTy);
+
+    const llvm::APSInt &Zero = getBasicVals().getValue(0, DiffTy);
+    Op = BinaryOperator::reverseComparisonOp(Op);
+    if (!Assumption)
+      Op = BinaryOperator::negateComparisonOp(Op);
+    return assumeSymRel(State, Subtraction, Op, Zero);
+  }
+
+  // If we get here, there's nothing else we can do but treat the symbol as
+  // opaque.
+  return assumeSymUnsupported(State, Sym, Assumption);
+}
+
+ProgramStateRef RangedConstraintManager::assumeSymInclusiveRange(
+    ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+    const llvm::APSInt &To, bool InRange) {
+  // Get the type used for calculating wraparound.
+  BasicValueFactory &BVF = getBasicVals();
+  APSIntType WraparoundType = BVF.getAPSIntType(Sym->getType());
+
+  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
+  SymbolRef AdjustedSym = Sym;
+  computeAdjustment(AdjustedSym, Adjustment);
+
+  // Convert the right-hand side integer as necessary.
+  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(From));
+  llvm::APSInt ConvertedFrom = ComparisonType.convert(From);
+  llvm::APSInt ConvertedTo = ComparisonType.convert(To);
+
+  // Prefer unsigned comparisons.
+  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
+      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
+    Adjustment.setIsSigned(false);
+
+  if (InRange)
+    return assumeSymWithinInclusiveRange(State, AdjustedSym, ConvertedFrom,
+                                         ConvertedTo, Adjustment);
+  return assumeSymOutsideInclusiveRange(State, AdjustedSym, ConvertedFrom,
+                                        ConvertedTo, Adjustment);
+}
+
+ProgramStateRef
+RangedConstraintManager::assumeSymUnsupported(ProgramStateRef State,
+                                              SymbolRef Sym, bool Assumption) {
+  BasicValueFactory &BVF = getBasicVals();
+  QualType T = Sym->getType();
+
+  // Non-integer types are not supported.
+  if (!T->isIntegralOrEnumerationType())
+    return State;
+
+  // Reverse the operation and add directly to state.
+  const llvm::APSInt &Zero = BVF.getValue(0, T);
+  if (Assumption)
+    return assumeSymNE(State, Sym, Zero, Zero);
+  else
+    return assumeSymEQ(State, Sym, Zero, Zero);
+}
+
+ProgramStateRef RangedConstraintManager::assumeSymRel(ProgramStateRef State,
+                                                      SymbolRef Sym,
+                                                      BinaryOperator::Opcode Op,
+                                                      const llvm::APSInt &Int) {
+  assert(BinaryOperator::isComparisonOp(Op) &&
+         "Non-comparison ops should be rewritten as comparisons to zero.");
+
+  // Simplification: translate an assume of a constraint of the form
+  // "(exp comparison_op expr) != 0" to true into an assume of
+  // "exp comparison_op expr" to true. (And similarly, an assume of the form
+  // "(exp comparison_op expr) == 0" to true into an assume of
+  // "exp comparison_op expr" to false.)
+  if (Int == 0 && (Op == BO_EQ || Op == BO_NE)) {
+    if (const BinarySymExpr *SE = dyn_cast<BinarySymExpr>(Sym))
+      if (BinaryOperator::isComparisonOp(SE->getOpcode()))
+        return assumeSym(State, Sym, (Op == BO_NE ? true : false));
+  }
+
+  // Get the type used for calculating wraparound.
+  BasicValueFactory &BVF = getBasicVals();
+  APSIntType WraparoundType = BVF.getAPSIntType(Sym->getType());
+
+  // We only handle simple comparisons of the form "$sym == constant"
+  // or "($sym+constant1) == constant2".
+  // The adjustment is "constant1" in the above expression. It's used to
+  // "slide" the solution range around for modular arithmetic. For example,
+  // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
+  // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
+  // the subclasses of SimpleConstraintManager to handle the adjustment.
+  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
+  computeAdjustment(Sym, Adjustment);
+
+  // Convert the right-hand side integer as necessary.
+  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(Int));
+  llvm::APSInt ConvertedInt = ComparisonType.convert(Int);
+
+  // Prefer unsigned comparisons.
+  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
+      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
+    Adjustment.setIsSigned(false);
+
+  switch (Op) {
+  default:
+    llvm_unreachable("invalid operation not caught by assertion above");
+
+  case BO_EQ:
+    return assumeSymEQ(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_NE:
+    return assumeSymNE(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_GT:
+    return assumeSymGT(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_GE:
+    return assumeSymGE(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_LT:
+    return assumeSymLT(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_LE:
+    return assumeSymLE(State, Sym, ConvertedInt, Adjustment);
+  } // end switch
+}
+
+void RangedConstraintManager::computeAdjustment(SymbolRef &Sym,
+                                                llvm::APSInt &Adjustment) {
+  // Is it a "($sym+constant1)" expression?
+  if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(Sym)) {
+    BinaryOperator::Opcode Op = SE->getOpcode();
+    if (Op == BO_Add || Op == BO_Sub) {
+      Sym = SE->getLHS();
+      Adjustment = APSIntType(Adjustment).convert(SE->getRHS());
+
+      // Don't forget to negate the adjustment if it's being subtracted.
+      // This should happen /after/ promotion, in case the value being
+      // subtracted is, say, CHAR_MIN, and the promoted type is 'int'.
+      if (Op == BO_Sub)
+        Adjustment = -Adjustment;
+    }
+  }
+}
+
+} // end of namespace ento
+
+} // end of namespace clang
diff --git a/lib/StaticAnalyzer/Core/RangedConstraintManager.h b/lib/StaticAnalyzer/Core/RangedConstraintManager.h
new file mode 100644
index 0000000..a4e6062
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/RangedConstraintManager.h
@@ -0,0 +1,102 @@
+//== RangedConstraintManager.h ----------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Ranged constraint manager, built on SimpleConstraintManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CORE_RANGEDCONSTRAINTMANAGER_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CORE_RANGEDCONSTRAINTMANAGER_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h"
+
+namespace clang {
+
+namespace ento {
+
+class RangedConstraintManager : public SimpleConstraintManager {
+public:
+  RangedConstraintManager(SubEngine *SE, SValBuilder &SB)
+      : SimpleConstraintManager(SE, SB) {}
+
+  ~RangedConstraintManager() override;
+
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from SimpleConstraintManager.
+  //===------------------------------------------------------------------===//
+
+  ProgramStateRef assumeSym(ProgramStateRef State, SymbolRef Sym,
+                            bool Assumption) override;
+
+  ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State, SymbolRef Sym,
+                                          const llvm::APSInt &From,
+                                          const llvm::APSInt &To,
+                                          bool InRange) override;
+
+  ProgramStateRef assumeSymUnsupported(ProgramStateRef State, SymbolRef Sym,
+                                       bool Assumption) override;
+
+protected:
+  /// Assume a constraint between a symbolic expression and a concrete integer.
+  virtual ProgramStateRef assumeSymRel(ProgramStateRef State, SymbolRef Sym,
+                               BinaryOperator::Opcode op,
+                               const llvm::APSInt &Int);
+
+  //===------------------------------------------------------------------===//
+  // Interface that subclasses must implement.
+  //===------------------------------------------------------------------===//
+
+  // Each of these is of the form "$Sym+Adj <> V", where "<>" is the comparison
+  // operation for the method being invoked.
+
+  virtual ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymEQ(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymLT(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymGT(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymLE(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymGE(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymWithinInclusiveRange(
+      ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+      const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymOutsideInclusiveRange(
+      ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+      const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
+
+  //===------------------------------------------------------------------===//
+  // Internal implementation.
+  //===------------------------------------------------------------------===//
+private:
+  static void computeAdjustment(SymbolRef &Sym, llvm::APSInt &Adjustment);
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index a19869d9..f0c2df4 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -494,6 +494,11 @@
     return getBinding(getRegionBindings(S), L, T);
   }
 
+  Optional<SVal> getDefaultBinding(Store S, const MemRegion *R) override {
+    RegionBindingsRef B = getRegionBindings(S);
+    return B.getDefaultBinding(R);
+  }
+
   SVal getBinding(RegionBindingsConstRef B, Loc L, QualType T = QualType());
 
   SVal getBindingForElement(RegionBindingsConstRef B, const ElementRegion *R);
@@ -1849,6 +1854,8 @@
 
     // Function-scoped static variables are default-initialized to 0; if they
     // have an initializer, it would have been processed by now.
+    // FIXME: This is only true when we're starting analysis from main().
+    // We're losing a lot of coverage here.
     if (isa<StaticGlobalSpaceRegion>(MS))
       return svalBuilder.makeZeroVal(T);
 
@@ -2073,11 +2080,10 @@
   if (Init.getAs<nonloc::LazyCompoundVal>())
     return bindAggregate(B, R, Init);
 
-  // Remaining case: explicit compound values.
-
   if (Init.isUnknown())
-    return setImplicitDefaultValue(B, R, ElementTy);
+    return bindAggregate(B, R, UnknownVal());
 
+  // Remaining case: explicit compound values.
   const nonloc::CompoundVal& CV = Init.castAs<nonloc::CompoundVal>();
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
   uint64_t i = 0;
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp
index fe9a683..ffaa0ed 100644
--- a/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -36,8 +36,11 @@
   if (type->isIntegralOrEnumerationType())
     return makeIntVal(0, type);
 
+  if (type->isArrayType() || type->isRecordType() || type->isVectorType() ||
+      type->isAnyComplexType())
+    return makeCompoundVal(type, BasicVals.getEmptySValList());
+
   // FIXME: Handle floats.
-  // FIXME: Handle structs.
   return UnknownVal();
 }
 
@@ -214,6 +217,22 @@
   return nonloc::SymbolVal(sym);
 }
 
+DefinedSVal SValBuilder::getMemberPointer(const DeclaratorDecl* DD) {
+  assert(!DD || isa<CXXMethodDecl>(DD) || isa<FieldDecl>(DD));
+
+  if (auto *MD = dyn_cast_or_null<CXXMethodDecl>(DD)) {
+    // Sema treats pointers to static member functions as have function pointer
+    // type, so return a function pointer for the method.
+    // We don't need to play a similar trick for static member fields
+    // because these are represented as plain VarDecls and not FieldDecls
+    // in the AST.
+    if (MD->isStatic())
+      return getFunctionPointer(MD);
+  }
+
+  return nonloc::PointerToMember(DD);
+}
+
 DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) {
   return loc::MemRegionVal(MemMgr.getFunctionCodeRegion(func));
 }
diff --git a/lib/StaticAnalyzer/Core/SVals.cpp b/lib/StaticAnalyzer/Core/SVals.cpp
index a30beed..9f2af3f 100644
--- a/lib/StaticAnalyzer/Core/SVals.cpp
+++ b/lib/StaticAnalyzer/Core/SVals.cpp
@@ -16,6 +16,7 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "llvm/Support/raw_ostream.h"
+#include "clang/AST/DeclCXX.h"
 using namespace clang;
 using namespace ento;
 using llvm::APSInt;
@@ -56,6 +57,10 @@
         return FD;
   }
 
+  if (auto X = getAs<nonloc::PointerToMember>()) {
+    if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(X->getDecl()))
+      return MD;
+  }
   return nullptr;
 }
 
@@ -155,6 +160,20 @@
   return static_cast<const LazyCompoundValData*>(Data)->getRegion();
 }
 
+const DeclaratorDecl *nonloc::PointerToMember::getDecl() const {
+  const auto PTMD = this->getPTMData();
+  if (PTMD.isNull())
+    return nullptr;
+
+  const DeclaratorDecl *DD = nullptr;
+  if (PTMD.is<const DeclaratorDecl *>())
+    DD = PTMD.get<const DeclaratorDecl *>();
+  else
+    DD = PTMD.get<const PointerToMemberData *>()->getDeclaratorDecl();
+
+  return DD;
+}
+
 //===----------------------------------------------------------------------===//
 // Other Iterators.
 //===----------------------------------------------------------------------===//
@@ -167,6 +186,20 @@
   return getValue()->end();
 }
 
+nonloc::PointerToMember::iterator nonloc::PointerToMember::begin() const {
+  const PTMDataType PTMD = getPTMData();
+  if (PTMD.is<const DeclaratorDecl *>())
+    return nonloc::PointerToMember::iterator();
+  return PTMD.get<const PointerToMemberData *>()->begin();
+}
+
+nonloc::PointerToMember::iterator nonloc::PointerToMember::end() const {
+  const PTMDataType PTMD = getPTMData();
+  if (PTMD.is<const DeclaratorDecl *>())
+    return nonloc::PointerToMember::iterator();
+  return PTMD.get<const PointerToMemberData *>()->end();
+}
+
 //===----------------------------------------------------------------------===//
 // Useful predicates.
 //===----------------------------------------------------------------------===//
@@ -299,6 +332,26 @@
          << '}';
       break;
     }
+    case nonloc::PointerToMemberKind: {
+      os << "pointerToMember{";
+      const nonloc::PointerToMember &CastRes =
+          castAs<nonloc::PointerToMember>();
+      if (CastRes.getDecl())
+        os << "|" << CastRes.getDecl()->getQualifiedNameAsString() << "|";
+      bool first = true;
+      for (const auto &I : CastRes) {
+        if (first) {
+          os << ' '; first = false;
+        }
+        else
+          os << ", ";
+
+        os << (*I).getType().getAsString();
+      }
+
+      os << '}';
+      break;
+    }
     default:
       assert (false && "Pretty-printed not implemented for this NonLoc.");
       break;
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index 9cb344e..adb4017 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -7,12 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 //
-//  This file defines SimpleConstraintManager, a class that holds code shared
-//  between BasicConstraintManager and RangeConstraintManager.
+//  This file defines SimpleConstraintManager, a class that provides a
+//  simplified constraint manager interface, compared to ConstraintManager.
 //
 //===----------------------------------------------------------------------===//
 
-#include "SimpleConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
@@ -23,54 +23,12 @@
 
 SimpleConstraintManager::~SimpleConstraintManager() {}
 
-bool SimpleConstraintManager::canReasonAbout(SVal X) const {
-  Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
-  if (SymVal && SymVal->isExpression()) {
-    const SymExpr *SE = SymVal->getSymbol();
-
-    if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
-      switch (SIE->getOpcode()) {
-          // We don't reason yet about bitwise-constraints on symbolic values.
-        case BO_And:
-        case BO_Or:
-        case BO_Xor:
-          return false;
-        // We don't reason yet about these arithmetic constraints on
-        // symbolic values.
-        case BO_Mul:
-        case BO_Div:
-        case BO_Rem:
-        case BO_Shl:
-        case BO_Shr:
-          return false;
-        // All other cases.
-        default:
-          return true;
-      }
-    }
-
-    if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
-      if (BinaryOperator::isComparisonOp(SSE->getOpcode())) {
-        // We handle Loc <> Loc comparisons, but not (yet) NonLoc <> NonLoc.
-        if (Loc::isLocType(SSE->getLHS()->getType())) {
-          assert(Loc::isLocType(SSE->getRHS()->getType()));
-          return true;
-        }
-      }
-    }
-
-    return false;
-  }
-
-  return true;
-}
-
-ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
-                                               DefinedSVal Cond,
-                                               bool Assumption) {
+ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State,
+                                                DefinedSVal Cond,
+                                                bool Assumption) {
   // If we have a Loc value, cast it to a bool NonLoc first.
   if (Optional<Loc> LV = Cond.getAs<Loc>()) {
-    SValBuilder &SVB = state->getStateManager().getSValBuilder();
+    SValBuilder &SVB = State->getStateManager().getSValBuilder();
     QualType T;
     const MemRegion *MR = LV->getAsRegion();
     if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR))
@@ -81,46 +39,28 @@
     Cond = SVB.evalCast(*LV, SVB.getContext().BoolTy, T).castAs<DefinedSVal>();
   }
 
-  return assume(state, Cond.castAs<NonLoc>(), Assumption);
+  return assume(State, Cond.castAs<NonLoc>(), Assumption);
 }
 
-ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
-                                               NonLoc cond,
-                                               bool assumption) {
-  state = assumeAux(state, cond, assumption);
+ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State,
+                                                NonLoc Cond, bool Assumption) {
+  State = assumeAux(State, Cond, Assumption);
   if (NotifyAssumeClients && SU)
-    return SU->processAssume(state, cond, assumption);
-  return state;
+    return SU->processAssume(State, Cond, Assumption);
+  return State;
 }
 
-
-ProgramStateRef
-SimpleConstraintManager::assumeAuxForSymbol(ProgramStateRef State,
-                                            SymbolRef Sym, bool Assumption) {
-  BasicValueFactory &BVF = getBasicVals();
-  QualType T = Sym->getType();
-
-  // None of the constraint solvers currently support non-integer types.
-  if (!T->isIntegralOrEnumerationType())
-    return State;
-
-  const llvm::APSInt &zero = BVF.getValue(0, T);
-  if (Assumption)
-    return assumeSymNE(State, Sym, zero, zero);
-  else
-    return assumeSymEQ(State, Sym, zero, zero);
-}
-
-ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
-                                                  NonLoc Cond,
-                                                  bool Assumption) {
+ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State,
+                                                   NonLoc Cond,
+                                                   bool Assumption) {
 
   // We cannot reason about SymSymExprs, and can only reason about some
   // SymIntExprs.
   if (!canReasonAbout(Cond)) {
     // Just add the constraint to the expression without trying to simplify.
-    SymbolRef sym = Cond.getAsSymExpr();
-    return assumeAuxForSymbol(state, sym, Assumption);
+    SymbolRef Sym = Cond.getAsSymExpr();
+    assert(Sym);
+    return assumeSymUnsupported(State, Sym, Assumption);
   }
 
   switch (Cond.getSubKind()) {
@@ -129,63 +69,25 @@
 
   case nonloc::SymbolValKind: {
     nonloc::SymbolVal SV = Cond.castAs<nonloc::SymbolVal>();
-    SymbolRef sym = SV.getSymbol();
-    assert(sym);
-
-    // Handle SymbolData.
-    if (!SV.isExpression()) {
-      return assumeAuxForSymbol(state, sym, Assumption);
-
-    // Handle symbolic expression.
-    } else if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(sym)) {
-      // We can only simplify expressions whose RHS is an integer.
-
-      BinaryOperator::Opcode op = SE->getOpcode();
-      if (BinaryOperator::isComparisonOp(op)) {
-        if (!Assumption)
-          op = BinaryOperator::negateComparisonOp(op);
-
-        return assumeSymRel(state, SE->getLHS(), op, SE->getRHS());
-      }
-
-    } else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(sym)) {
-      // Translate "a != b" to "(b - a) != 0".
-      // We invert the order of the operands as a heuristic for how loop
-      // conditions are usually written ("begin != end") as compared to length
-      // calculations ("end - begin"). The more correct thing to do would be to
-      // canonicalize "a - b" and "b - a", which would allow us to treat
-      // "a != b" and "b != a" the same.
-      SymbolManager &SymMgr = getSymbolManager();
-      BinaryOperator::Opcode Op = SSE->getOpcode();
-      assert(BinaryOperator::isComparisonOp(Op));
-
-      // For now, we only support comparing pointers.
-      assert(Loc::isLocType(SSE->getLHS()->getType()));
-      assert(Loc::isLocType(SSE->getRHS()->getType()));
-      QualType DiffTy = SymMgr.getContext().getPointerDiffType();
-      SymbolRef Subtraction = SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub,
-                                                   SSE->getLHS(), DiffTy);
-
-      const llvm::APSInt &Zero = getBasicVals().getValue(0, DiffTy);
-      Op = BinaryOperator::reverseComparisonOp(Op);
-      if (!Assumption)
-        Op = BinaryOperator::negateComparisonOp(Op);
-      return assumeSymRel(state, Subtraction, Op, Zero);
-    }
-
-    // If we get here, there's nothing else we can do but treat the symbol as
-    // opaque.
-    return assumeAuxForSymbol(state, sym, Assumption);
+    SymbolRef Sym = SV.getSymbol();
+    assert(Sym);
+    return assumeSym(State, Sym, Assumption);
   }
 
   case nonloc::ConcreteIntKind: {
     bool b = Cond.castAs<nonloc::ConcreteInt>().getValue() != 0;
     bool isFeasible = b ? Assumption : !Assumption;
-    return isFeasible ? state : nullptr;
+    return isFeasible ? State : nullptr;
+  }
+
+  case nonloc::PointerToMemberKind: {
+    bool IsNull = !Cond.castAs<nonloc::PointerToMember>().isNullMemberPointer();
+    bool IsFeasible = IsNull ? Assumption : !Assumption;
+    return IsFeasible ? State : nullptr;
   }
 
   case nonloc::LocAsIntegerKind:
-    return assume(state, Cond.castAs<nonloc::LocAsInteger>().getLoc(),
+    return assume(State, Cond.castAs<nonloc::LocAsInteger>().getLoc(),
                   Assumption);
   } // end switch
 }
@@ -202,7 +104,7 @@
     // Just add the constraint to the expression without trying to simplify.
     SymbolRef Sym = Value.getAsSymExpr();
     assert(Sym);
-    return assumeSymWithinInclusiveRange(State, Sym, From, To, InRange);
+    return assumeSymInclusiveRange(State, Sym, From, To, InRange);
   }
 
   switch (Value.getSubKind()) {
@@ -213,7 +115,7 @@
   case nonloc::LocAsIntegerKind:
   case nonloc::SymbolValKind: {
     if (SymbolRef Sym = Value.getAsSymbol())
-      return assumeSymWithinInclusiveRange(State, Sym, From, To, InRange);
+      return assumeSymInclusiveRange(State, Sym, From, To, InRange);
     return State;
   } // end switch
 
@@ -226,109 +128,6 @@
   } // end switch
 }
 
-static void computeAdjustment(SymbolRef &Sym, llvm::APSInt &Adjustment) {
-  // Is it a "($sym+constant1)" expression?
-  if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(Sym)) {
-    BinaryOperator::Opcode Op = SE->getOpcode();
-    if (Op == BO_Add || Op == BO_Sub) {
-      Sym = SE->getLHS();
-      Adjustment = APSIntType(Adjustment).convert(SE->getRHS());
-
-      // Don't forget to negate the adjustment if it's being subtracted.
-      // This should happen /after/ promotion, in case the value being
-      // subtracted is, say, CHAR_MIN, and the promoted type is 'int'.
-      if (Op == BO_Sub)
-        Adjustment = -Adjustment;
-    }
-  }
-}
-
-ProgramStateRef SimpleConstraintManager::assumeSymRel(ProgramStateRef state,
-                                                     const SymExpr *LHS,
-                                                     BinaryOperator::Opcode op,
-                                                     const llvm::APSInt& Int) {
-  assert(BinaryOperator::isComparisonOp(op) &&
-         "Non-comparison ops should be rewritten as comparisons to zero.");
-
-  // Get the type used for calculating wraparound.
-  BasicValueFactory &BVF = getBasicVals();
-  APSIntType WraparoundType = BVF.getAPSIntType(LHS->getType());
-
-  // We only handle simple comparisons of the form "$sym == constant"
-  // or "($sym+constant1) == constant2".
-  // The adjustment is "constant1" in the above expression. It's used to
-  // "slide" the solution range around for modular arithmetic. For example,
-  // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
-  // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
-  // the subclasses of SimpleConstraintManager to handle the adjustment.
-  SymbolRef Sym = LHS;
-  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
-  computeAdjustment(Sym, Adjustment);
-
-  // Convert the right-hand side integer as necessary.
-  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(Int));
-  llvm::APSInt ConvertedInt = ComparisonType.convert(Int);
-
-  // Prefer unsigned comparisons.
-  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
-      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
-    Adjustment.setIsSigned(false);
-
-  switch (op) {
-  default:
-    llvm_unreachable("invalid operation not caught by assertion above");
-
-  case BO_EQ:
-    return assumeSymEQ(state, Sym, ConvertedInt, Adjustment);
-
-  case BO_NE:
-    return assumeSymNE(state, Sym, ConvertedInt, Adjustment);
-
-  case BO_GT:
-    return assumeSymGT(state, Sym, ConvertedInt, Adjustment);
-
-  case BO_GE:
-    return assumeSymGE(state, Sym, ConvertedInt, Adjustment);
-
-  case BO_LT:
-    return assumeSymLT(state, Sym, ConvertedInt, Adjustment);
-
-  case BO_LE:
-    return assumeSymLE(state, Sym, ConvertedInt, Adjustment);
-  } // end switch
-}
-
-ProgramStateRef
-SimpleConstraintManager::assumeSymWithinInclusiveRange(ProgramStateRef State,
-                                                       SymbolRef Sym,
-                                                       const llvm::APSInt &From,
-                                                       const llvm::APSInt &To,
-                                                       bool InRange) {
-  // Get the type used for calculating wraparound.
-  BasicValueFactory &BVF = getBasicVals();
-  APSIntType WraparoundType = BVF.getAPSIntType(Sym->getType());
-
-  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
-  SymbolRef AdjustedSym = Sym;
-  computeAdjustment(AdjustedSym, Adjustment);
-
-  // Convert the right-hand side integer as necessary.
-  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(From));
-  llvm::APSInt ConvertedFrom = ComparisonType.convert(From);
-  llvm::APSInt ConvertedTo = ComparisonType.convert(To);
-
-  // Prefer unsigned comparisons.
-  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
-      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
-    Adjustment.setIsSigned(false);
-
-  if (InRange)
-    return assumeSymbolWithinInclusiveRange(State, AdjustedSym, ConvertedFrom,
-                                            ConvertedTo, Adjustment);
-  return assumeSymbolOutOfInclusiveRange(State, AdjustedSym, ConvertedFrom,
-                                         ConvertedTo, Adjustment);
-}
-
 } // end of namespace ento
 
 } // end of namespace clang
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.h b/lib/StaticAnalyzer/Core/SimpleConstraintManager.h
deleted file mode 100644
index f436639..0000000
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.h
+++ /dev/null
@@ -1,121 +0,0 @@
-//== SimpleConstraintManager.h ----------------------------------*- C++ -*--==//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  Code shared between BasicConstraintManager and RangeConstraintManager.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_STATICANALYZER_CORE_SIMPLECONSTRAINTMANAGER_H
-#define LLVM_CLANG_LIB_STATICANALYZER_CORE_SIMPLECONSTRAINTMANAGER_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-
-namespace clang {
-
-namespace ento {
-
-class SimpleConstraintManager : public ConstraintManager {
-  SubEngine *SU;
-  SValBuilder &SVB;
-public:
-  SimpleConstraintManager(SubEngine *subengine, SValBuilder &SB)
-    : SU(subengine), SVB(SB) {}
-  ~SimpleConstraintManager() override;
-
-  //===------------------------------------------------------------------===//
-  // Common implementation for the interface provided by ConstraintManager.
-  //===------------------------------------------------------------------===//
-
-  ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond,
-                        bool Assumption) override;
-
-  ProgramStateRef assume(ProgramStateRef state, NonLoc Cond, bool Assumption);
-
-  ProgramStateRef assumeInclusiveRange(ProgramStateRef State,
-                                             NonLoc Value,
-                                             const llvm::APSInt &From,
-                                             const llvm::APSInt &To,
-                                             bool InRange) override;
-
-  ProgramStateRef assumeSymRel(ProgramStateRef state,
-                              const SymExpr *LHS,
-                              BinaryOperator::Opcode op,
-                              const llvm::APSInt& Int);
-
-  ProgramStateRef assumeSymWithinInclusiveRange(ProgramStateRef State,
-                                                SymbolRef Sym,
-                                                const llvm::APSInt &From,
-                                                const llvm::APSInt &To,
-                                                bool InRange);
-
-
-protected:
-
-  //===------------------------------------------------------------------===//
-  // Interface that subclasses must implement.
-  //===------------------------------------------------------------------===//
-
-  // Each of these is of the form "$sym+Adj <> V", where "<>" is the comparison
-  // operation for the method being invoked.
-  virtual ProgramStateRef assumeSymNE(ProgramStateRef state, SymbolRef sym,
-                                     const llvm::APSInt& V,
-                                     const llvm::APSInt& Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymEQ(ProgramStateRef state, SymbolRef sym,
-                                     const llvm::APSInt& V,
-                                     const llvm::APSInt& Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymLT(ProgramStateRef state, SymbolRef sym,
-                                     const llvm::APSInt& V,
-                                     const llvm::APSInt& Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymGT(ProgramStateRef state, SymbolRef sym,
-                                     const llvm::APSInt& V,
-                                     const llvm::APSInt& Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymLE(ProgramStateRef state, SymbolRef sym,
-                                     const llvm::APSInt& V,
-                                     const llvm::APSInt& Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymGE(ProgramStateRef state, SymbolRef sym,
-                                     const llvm::APSInt& V,
-                                     const llvm::APSInt& Adjustment) = 0;
-
-
-  virtual ProgramStateRef assumeSymbolWithinInclusiveRange(
-      ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
-      const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymbolOutOfInclusiveRange(
-      ProgramStateRef state, SymbolRef Sym, const llvm::APSInt &From,
-      const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
-  //===------------------------------------------------------------------===//
-  // Internal implementation.
-  //===------------------------------------------------------------------===//
-
-  BasicValueFactory &getBasicVals() const { return SVB.getBasicValueFactory(); }
-  SymbolManager &getSymbolManager() const { return SVB.getSymbolManager(); }
-
-  bool canReasonAbout(SVal X) const override;
-
-  ProgramStateRef assumeAux(ProgramStateRef state,
-                                NonLoc Cond,
-                                bool Assumption);
-
-  ProgramStateRef assumeAuxForSymbol(ProgramStateRef State,
-                                         SymbolRef Sym,
-                                         bool Assumption);
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index edcf2aa..28b43dd 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -69,6 +69,9 @@
 
   bool isLocType = Loc::isLocType(castTy);
 
+  if (val.getAs<nonloc::PointerToMember>())
+    return val;
+
   if (Optional<nonloc::LocAsInteger> LI = val.getAs<nonloc::LocAsInteger>()) {
     if (isLocType)
       return LI->getLoc();
@@ -335,6 +338,21 @@
     switch (lhs.getSubKind()) {
     default:
       return makeSymExprValNN(state, op, lhs, rhs, resultTy);
+    case nonloc::PointerToMemberKind: {
+      assert(rhs.getSubKind() == nonloc::PointerToMemberKind &&
+             "Both SVals should have pointer-to-member-type");
+      auto LPTM = lhs.castAs<nonloc::PointerToMember>(),
+           RPTM = rhs.castAs<nonloc::PointerToMember>();
+      auto LPTMD = LPTM.getPTMData(), RPTMD = RPTM.getPTMData();
+      switch (op) {
+        case BO_EQ:
+          return makeTruthVal(LPTMD == RPTMD, resultTy);
+        case BO_NE:
+          return makeTruthVal(LPTMD != RPTMD, resultTy);
+        default:
+          return UnknownVal();
+      }
+    }
     case nonloc::LocAsIntegerKind: {
       Loc lhsL = lhs.castAs<nonloc::LocAsInteger>().getLoc();
       switch (rhs.getSubKind()) {
@@ -863,6 +881,23 @@
 SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
                                   BinaryOperator::Opcode op,
                                   Loc lhs, NonLoc rhs, QualType resultTy) {
+  if (op >= BO_PtrMemD && op <= BO_PtrMemI) {
+    if (auto PTMSV = rhs.getAs<nonloc::PointerToMember>()) {
+      if (PTMSV->isNullMemberPointer())
+        return UndefinedVal();
+      if (const FieldDecl *FD = PTMSV->getDeclAs<FieldDecl>()) {
+        SVal Result = lhs;
+
+        for (const auto &I : *PTMSV)
+          Result = StateMgr.getStoreManager().evalDerivedToBase(
+              Result, I->getType(),I->isVirtual());
+        return state->getLValue(FD, Result);
+      }
+    }
+
+    return rhs;
+  }
+
   assert(!BinaryOperator::isComparisonOp(op) &&
          "arguments to comparison ops must be of the same type");
 
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index b3e287e..0fe0f3a 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -615,8 +615,8 @@
            << OC->getIdentifier()->getNameStart() << ')';
       }
     } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
-      OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '('
-         << OCD->getIdentifier()->getNameStart() << ')';
+      OS << OCD->getClassInterface()->getName() << '('
+         << OCD->getName() << ')';
     } else if (isa<ObjCProtocolDecl>(DC)) {
       // We can extract the type of the class from the self pointer.
       if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
index 31b6638..6792f89 100644
--- a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
+++ b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
@@ -116,7 +116,7 @@
                            ArrayRef<std::string> plugins,
                            DiagnosticsEngine &diags) {
   std::unique_ptr<CheckerManager> checkerMgr(
-      new CheckerManager(langOpts, &opts));
+      new CheckerManager(langOpts, opts));
 
   SmallVector<CheckerOptInfo, 8> checkerOpts = getCheckerOptList(opts);
 
diff --git a/lib/StaticAnalyzer/Frontend/ModelInjector.cpp b/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
index 0a28485..c6f3baa 100644
--- a/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
+++ b/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
@@ -62,8 +62,7 @@
     return;
   }
 
-  IntrusiveRefCntPtr<CompilerInvocation> Invocation(
-      new CompilerInvocation(CI.getInvocation()));
+  auto Invocation = std::make_shared<CompilerInvocation>(CI.getInvocation());
 
   FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
   InputKind IK = IK_CXX; // FIXME
@@ -76,7 +75,7 @@
   // Modules are parsed by a separate CompilerInstance, so this code mimics that
   // behavior for models
   CompilerInstance Instance(CI.getPCHContainerOperations());
-  Instance.setInvocation(&*Invocation);
+  Instance.setInvocation(std::move(Invocation));
   Instance.createDiagnostics(
       new ForwardingDiagnosticConsumer(CI.getDiagnosticClient()),
       /*ShouldOwnClient=*/true);
@@ -89,7 +88,7 @@
   // is set to true to avoid double free issues
   Instance.setFileManager(&CI.getFileManager());
   Instance.setSourceManager(&SM);
-  Instance.setPreprocessor(&CI.getPreprocessor());
+  Instance.setPreprocessor(CI.getPreprocessorPtr());
   Instance.setASTContext(&CI.getASTContext());
 
   Instance.getPreprocessor().InitializeForModelFile();
diff --git a/lib/Tooling/CMakeLists.txt b/lib/Tooling/CMakeLists.txt
index 2eec1db..7b0c58e 100644
--- a/lib/Tooling/CMakeLists.txt
+++ b/lib/Tooling/CMakeLists.txt
@@ -4,6 +4,7 @@
   )
 
 add_subdirectory(Core)
+add_subdirectory(Refactoring)
 
 add_clang_library(clangTooling
   ArgumentsAdjusters.cpp
diff --git a/lib/Tooling/Core/CMakeLists.txt b/lib/Tooling/Core/CMakeLists.txt
index f6348cb..e2b0dd4 100644
--- a/lib/Tooling/Core/CMakeLists.txt
+++ b/lib/Tooling/Core/CMakeLists.txt
@@ -4,6 +4,7 @@
   Lookup.cpp
   Replacement.cpp
   QualTypeNames.cpp
+  Diagnostic.cpp
 
   LINK_LIBS
   clangAST
diff --git a/lib/Tooling/Core/Diagnostic.cpp b/lib/Tooling/Core/Diagnostic.cpp
new file mode 100644
index 0000000..3bbc2b9
--- /dev/null
+++ b/lib/Tooling/Core/Diagnostic.cpp
@@ -0,0 +1,46 @@
+//===--- Diagnostic.cpp - Framework for clang diagnostics tools ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Implements classes to support/store diagnostics refactoring.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Core/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+
+namespace clang {
+namespace tooling {
+
+DiagnosticMessage::DiagnosticMessage(llvm::StringRef Message)
+    : Message(Message), FileOffset(0) {}
+
+DiagnosticMessage::DiagnosticMessage(llvm::StringRef Message,
+                                     const SourceManager &Sources,
+                                     SourceLocation Loc)
+    : Message(Message) {
+  assert(Loc.isValid() && Loc.isFileID());
+  FilePath = Sources.getFilename(Loc);
+  FileOffset = Sources.getFileOffset(Loc);
+}
+
+Diagnostic::Diagnostic(llvm::StringRef DiagnosticName,
+                       Diagnostic::Level DiagLevel, StringRef BuildDirectory)
+    : DiagnosticName(DiagnosticName), DiagLevel(DiagLevel),
+      BuildDirectory(BuildDirectory) {}
+
+Diagnostic::Diagnostic(llvm::StringRef DiagnosticName,
+                       DiagnosticMessage &Message,
+                       llvm::StringMap<Replacements> &Fix,
+                       SmallVector<DiagnosticMessage, 1> &Notes,
+                       Level DiagLevel, llvm::StringRef BuildDirectory)
+    : DiagnosticName(DiagnosticName), Message(Message), Fix(Fix), Notes(Notes),
+      DiagLevel(DiagLevel), BuildDirectory(BuildDirectory) {}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactoring.cpp b/lib/Tooling/Refactoring.cpp
index 308c1ac..954a473 100644
--- a/lib/Tooling/Refactoring.cpp
+++ b/lib/Tooling/Refactoring.cpp
@@ -68,8 +68,8 @@
 }
 
 bool formatAndApplyAllReplacements(
-    const std::map<std::string, Replacements> &FileToReplaces, Rewriter &Rewrite,
-    StringRef Style) {
+    const std::map<std::string, Replacements> &FileToReplaces,
+    Rewriter &Rewrite, StringRef Style) {
   SourceManager &SM = Rewrite.getSourceMgr();
   FileManager &Files = SM.getFileManager();
 
@@ -83,9 +83,14 @@
     FileID ID = SM.getOrCreateFileID(Entry, SrcMgr::C_User);
     StringRef Code = SM.getBufferData(ID);
 
-    format::FormatStyle CurStyle = format::getStyle(Style, FilePath, "LLVM");
+    auto CurStyle = format::getStyle(Style, FilePath, "LLVM");
+    if (!CurStyle) {
+      llvm::errs() << llvm::toString(CurStyle.takeError()) << "\n";
+      return false;
+    }
+
     auto NewReplacements =
-        format::formatReplacements(Code, CurReplaces, CurStyle);
+        format::formatReplacements(Code, CurReplaces, *CurStyle);
     if (!NewReplacements) {
       llvm::errs() << llvm::toString(NewReplacements.takeError()) << "\n";
       return false;
diff --git a/lib/Tooling/Refactoring/AtomicChange.cpp b/lib/Tooling/Refactoring/AtomicChange.cpp
new file mode 100644
index 0000000..02c5510
--- /dev/null
+++ b/lib/Tooling/Refactoring/AtomicChange.cpp
@@ -0,0 +1,172 @@
+//===--- AtomicChange.cpp - AtomicChange implementation -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "clang/Tooling/ReplacementsYaml.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <string>
+
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::AtomicChange)
+
+namespace {
+/// \brief Helper to (de)serialize an AtomicChange since we don't have direct
+/// access to its data members.
+/// Data members of a normalized AtomicChange can be directly mapped from/to
+/// YAML string.
+struct NormalizedAtomicChange {
+  NormalizedAtomicChange() = default;
+
+  NormalizedAtomicChange(const llvm::yaml::IO &) {}
+
+  // This converts AtomicChange's internal implementation of the replacements
+  // set to a vector of replacements.
+  NormalizedAtomicChange(const llvm::yaml::IO &,
+                         const clang::tooling::AtomicChange &E)
+      : Key(E.getKey()), FilePath(E.getFilePath()), Error(E.getError()),
+        InsertedHeaders(E.getInsertedHeaders()),
+        RemovedHeaders(E.getRemovedHeaders()),
+        Replaces(E.getReplacements().begin(), E.getReplacements().end()) {}
+
+  // This is not expected to be called but needed for template instantiation.
+  clang::tooling::AtomicChange denormalize(const llvm::yaml::IO &) {
+    llvm_unreachable("Do not convert YAML to AtomicChange directly with '>>'. "
+                     "Use AtomicChange::convertFromYAML instead.");
+  }
+  std::string Key;
+  std::string FilePath;
+  std::string Error;
+  std::vector<std::string> InsertedHeaders;
+  std::vector<std::string> RemovedHeaders;
+  std::vector<clang::tooling::Replacement> Replaces;
+};
+} // anonymous namespace
+
+namespace llvm {
+namespace yaml {
+
+/// \brief Specialized MappingTraits to describe how an AtomicChange is
+/// (de)serialized.
+template <> struct MappingTraits<NormalizedAtomicChange> {
+  static void mapping(IO &Io, NormalizedAtomicChange &Doc) {
+    Io.mapRequired("Key", Doc.Key);
+    Io.mapRequired("FilePath", Doc.FilePath);
+    Io.mapRequired("Error", Doc.Error);
+    Io.mapRequired("InsertedHeaders", Doc.InsertedHeaders);
+    Io.mapRequired("RemovedHeaders", Doc.RemovedHeaders);
+    Io.mapRequired("Replacements", Doc.Replaces);
+  }
+};
+
+/// \brief Specialized MappingTraits to describe how an AtomicChange is
+/// (de)serialized.
+template <> struct MappingTraits<clang::tooling::AtomicChange> {
+  static void mapping(IO &Io, clang::tooling::AtomicChange &Doc) {
+    MappingNormalization<NormalizedAtomicChange, clang::tooling::AtomicChange>
+        Keys(Io, Doc);
+    Io.mapRequired("Key", Keys->Key);
+    Io.mapRequired("FilePath", Keys->FilePath);
+    Io.mapRequired("Error", Keys->Error);
+    Io.mapRequired("InsertedHeaders", Keys->InsertedHeaders);
+    Io.mapRequired("RemovedHeaders", Keys->RemovedHeaders);
+    Io.mapRequired("Replacements", Keys->Replaces);
+  }
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+namespace clang {
+namespace tooling {
+
+AtomicChange::AtomicChange(const SourceManager &SM,
+                           SourceLocation KeyPosition) {
+  const FullSourceLoc FullKeyPosition(KeyPosition, SM);
+  std::pair<FileID, unsigned> FileIDAndOffset =
+      FullKeyPosition.getSpellingLoc().getDecomposedLoc();
+  const FileEntry *FE = SM.getFileEntryForID(FileIDAndOffset.first);
+  assert(FE && "Cannot create AtomicChange with invalid location.");
+  FilePath = FE->getName();
+  Key = FilePath + ":" + std::to_string(FileIDAndOffset.second);
+}
+
+AtomicChange::AtomicChange(std::string Key, std::string FilePath,
+                           std::string Error,
+                           std::vector<std::string> InsertedHeaders,
+                           std::vector<std::string> RemovedHeaders,
+                           clang::tooling::Replacements Replaces)
+    : Key(std::move(Key)), FilePath(std::move(FilePath)),
+      Error(std::move(Error)), InsertedHeaders(std::move(InsertedHeaders)),
+      RemovedHeaders(std::move(RemovedHeaders)), Replaces(std::move(Replaces)) {
+}
+
+std::string AtomicChange::toYAMLString() {
+  std::string YamlContent;
+  llvm::raw_string_ostream YamlContentStream(YamlContent);
+
+  llvm::yaml::Output YAML(YamlContentStream);
+  YAML << *this;
+  YamlContentStream.flush();
+  return YamlContent;
+}
+
+AtomicChange AtomicChange::convertFromYAML(llvm::StringRef YAMLContent) {
+  NormalizedAtomicChange NE;
+  llvm::yaml::Input YAML(YAMLContent);
+  YAML >> NE;
+  AtomicChange E(NE.Key, NE.FilePath, NE.Error, NE.InsertedHeaders,
+                 NE.RemovedHeaders, tooling::Replacements());
+  for (const auto &R : NE.Replaces) {
+    llvm::Error Err = E.Replaces.add(R);
+    if (Err)
+      llvm_unreachable(
+          "Failed to add replacement when Converting YAML to AtomicChange.");
+    llvm::consumeError(std::move(Err));
+  }
+  return E;
+}
+
+llvm::Error AtomicChange::replace(const SourceManager &SM, SourceLocation Loc,
+                                  unsigned Length, llvm::StringRef Text) {
+  return Replaces.add(Replacement(SM, Loc, Length, Text));
+}
+
+llvm::Error AtomicChange::insert(const SourceManager &SM, SourceLocation Loc,
+                                 llvm::StringRef Text, bool InsertAfter) {
+  if (Text.empty())
+    return llvm::Error::success();
+  Replacement R(SM, Loc, 0, Text);
+  llvm::Error Err = Replaces.add(R);
+  if (Err) {
+    return llvm::handleErrors(
+        std::move(Err), [&](const ReplacementError &RE) -> llvm::Error {
+          if (RE.get() != replacement_error::insert_conflict)
+            return llvm::make_error<ReplacementError>(RE);
+          unsigned NewOffset = Replaces.getShiftedCodePosition(R.getOffset());
+          if (!InsertAfter)
+            NewOffset -=
+                RE.getExistingReplacement()->getReplacementText().size();
+          Replacement NewR(R.getFilePath(), NewOffset, 0, Text);
+          Replaces = Replaces.merge(Replacements(NewR));
+          return llvm::Error::success();
+        });
+  }
+  return llvm::Error::success();
+}
+
+void AtomicChange::addHeader(llvm::StringRef Header) {
+  InsertedHeaders.push_back(Header);
+}
+
+void AtomicChange::removeHeader(llvm::StringRef Header) {
+  RemovedHeaders.push_back(Header);
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactoring/CMakeLists.txt b/lib/Tooling/Refactoring/CMakeLists.txt
new file mode 100644
index 0000000..b2f9b4f
--- /dev/null
+++ b/lib/Tooling/Refactoring/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(LLVM_LINK_COMPONENTS
+  Option
+  Support
+  )
+
+add_clang_library(clangToolingRefactor
+  AtomicChange.cpp
+
+  LINK_LIBS
+  clangBasic
+  clangToolingCore
+  )
diff --git a/lib/Tooling/RefactoringCallbacks.cpp b/lib/Tooling/RefactoringCallbacks.cpp
index af25fd8..e900c23 100644
--- a/lib/Tooling/RefactoringCallbacks.cpp
+++ b/lib/Tooling/RefactoringCallbacks.cpp
@@ -39,15 +39,16 @@
 
 void ReplaceStmtWithText::run(
     const ast_matchers::MatchFinder::MatchResult &Result) {
-  if (const Stmt *FromMatch = Result.Nodes.getStmtAs<Stmt>(FromId)) {
+  if (const Stmt *FromMatch = Result.Nodes.getNodeAs<Stmt>(FromId)) {
     auto Err = Replace.add(tooling::Replacement(
         *Result.SourceManager,
         CharSourceRange::getTokenRange(FromMatch->getSourceRange()), ToText));
     // FIXME: better error handling. For now, just print error message in the
     // release version.
-    if (Err)
+    if (Err) {
       llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-    assert(!Err);
+      assert(false);
+    }
   }
 }
 
@@ -56,16 +57,17 @@
 
 void ReplaceStmtWithStmt::run(
     const ast_matchers::MatchFinder::MatchResult &Result) {
-  const Stmt *FromMatch = Result.Nodes.getStmtAs<Stmt>(FromId);
-  const Stmt *ToMatch = Result.Nodes.getStmtAs<Stmt>(ToId);
+  const Stmt *FromMatch = Result.Nodes.getNodeAs<Stmt>(FromId);
+  const Stmt *ToMatch = Result.Nodes.getNodeAs<Stmt>(ToId);
   if (FromMatch && ToMatch) {
     auto Err = Replace.add(
         replaceStmtWithStmt(*Result.SourceManager, *FromMatch, *ToMatch));
     // FIXME: better error handling. For now, just print error message in the
     // release version.
-    if (Err)
+    if (Err) {
       llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-    assert(!Err);
+      assert(false);
+    }
   }
 }
 
@@ -75,16 +77,17 @@
 
 void ReplaceIfStmtWithItsBody::run(
     const ast_matchers::MatchFinder::MatchResult &Result) {
-  if (const IfStmt *Node = Result.Nodes.getStmtAs<IfStmt>(Id)) {
+  if (const IfStmt *Node = Result.Nodes.getNodeAs<IfStmt>(Id)) {
     const Stmt *Body = PickTrueBranch ? Node->getThen() : Node->getElse();
     if (Body) {
       auto Err =
           Replace.add(replaceStmtWithStmt(*Result.SourceManager, *Node, *Body));
       // FIXME: better error handling. For now, just print error message in the
       // release version.
-      if (Err)
+      if (Err) {
         llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-      assert(!Err);
+        assert(false);
+      }
     } else if (!PickTrueBranch) {
       // If we want to use the 'else'-branch, but it doesn't exist, delete
       // the whole 'if'.
@@ -92,9 +95,10 @@
           Replace.add(replaceStmtWithText(*Result.SourceManager, *Node, ""));
       // FIXME: better error handling. For now, just print error message in the
       // release version.
-      if (Err)
+      if (Err) {
         llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-      assert(!Err);
+        assert(false);
+      }
     }
   }
 }
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
index 529c47e..9e11812 100644
--- a/lib/Tooling/Tooling.cpp
+++ b/lib/Tooling/Tooling.cpp
@@ -244,7 +244,7 @@
   const char *const BinaryName = Argv[0];
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   unsigned MissingArgIndex, MissingArgCount;
-  std::unique_ptr<llvm::opt::OptTable> Opts(driver::createDriverOptTable());
+  std::unique_ptr<llvm::opt::OptTable> Opts = driver::createDriverOptTable();
   llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs(
       ArrayRef<const char *>(Argv).slice(1), MissingArgIndex, MissingArgCount);
   ParseDiagnosticArgs(*DiagOpts, ParsedArgs);
@@ -275,13 +275,13 @@
     Invocation->getPreprocessorOpts().addRemappedFile(It.getKey(),
                                                       Input.release());
   }
-  return runInvocation(BinaryName, Compilation.get(), Invocation.release(),
+  return runInvocation(BinaryName, Compilation.get(), std::move(Invocation),
                        std::move(PCHContainerOps));
 }
 
 bool ToolInvocation::runInvocation(
     const char *BinaryName, clang::driver::Compilation *Compilation,
-    clang::CompilerInvocation *Invocation,
+    std::shared_ptr<clang::CompilerInvocation> Invocation,
     std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
   // Show the invocation, with -v.
   if (Invocation->getHeaderSearchOpts().Verbose) {
@@ -290,17 +290,17 @@
     llvm::errs() << "\n";
   }
 
-  return Action->runInvocation(Invocation, Files, std::move(PCHContainerOps),
-                               DiagConsumer);
+  return Action->runInvocation(std::move(Invocation), Files,
+                               std::move(PCHContainerOps), DiagConsumer);
 }
 
 bool FrontendActionFactory::runInvocation(
-    CompilerInvocation *Invocation, FileManager *Files,
+    std::shared_ptr<CompilerInvocation> Invocation, FileManager *Files,
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     DiagnosticConsumer *DiagConsumer) {
   // Create a compiler instance to handle the actual work.
   clang::CompilerInstance Compiler(std::move(PCHContainerOps));
-  Compiler.setInvocation(Invocation);
+  Compiler.setInvocation(std::move(Invocation));
   Compiler.setFileManager(Files);
 
   // The FrontendAction can have lifetime requirements for Compiler or its
@@ -474,7 +474,8 @@
 public:
   ASTBuilderAction(std::vector<std::unique_ptr<ASTUnit>> &ASTs) : ASTs(ASTs) {}
 
-  bool runInvocation(CompilerInvocation *Invocation, FileManager *Files,
+  bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
+                     FileManager *Files,
                      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
                      DiagnosticConsumer *DiagConsumer) override {
     std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt
index 896a3ab..27cb83a 100644
--- a/runtime/CMakeLists.txt
+++ b/runtime/CMakeLists.txt
@@ -78,6 +78,7 @@
                -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
                -DLLVM_LIBDIR_SUFFIX=${LLVM_LIBDIR_SUFFIX}
                -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}
+               -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT}
                ${COMPILER_RT_PASSTHROUGH_VARIABLES}
     INSTALL_COMMAND ""
     STEP_TARGETS configure build
diff --git a/test/ARCMT/lit.local.cfg b/test/ARCMT/lit.local.cfg
index 4b28d6d..e9b0416 100644
--- a/test/ARCMT/lit.local.cfg
+++ b/test/ARCMT/lit.local.cfg
@@ -1,2 +1,2 @@
-if config.root.clang_arcmt == 0:
+if not config.root.clang_arcmt:
     config.unsupported = True
diff --git a/test/ASTMerge/asm/Inputs/asm-function.cpp b/test/ASTMerge/asm/Inputs/asm-function.cpp
index 59c4edf..1b87833 100644
--- a/test/ASTMerge/asm/Inputs/asm-function.cpp
+++ b/test/ASTMerge/asm/Inputs/asm-function.cpp
@@ -9,3 +9,13 @@
   res = bigres;
   return res;
 }
+
+int asmFunc2(int i) {
+  int res;
+  asm ("mov %1, %0 \t\n"
+       "inc %0 "
+      : "=r" (res)
+      : "r" (i)
+      : "cc");
+  return res;
+}
diff --git a/test/ASTMerge/asm/test.cpp b/test/ASTMerge/asm/test.cpp
index 3a0a205..8c3bdfe 100644
--- a/test/ASTMerge/asm/test.cpp
+++ b/test/ASTMerge/asm/test.cpp
@@ -4,4 +4,5 @@
 
 void testAsmImport() {
   asmFunc(12, 42);
+  asmFunc2(42);
 }
diff --git a/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp b/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp
new file mode 100644
index 0000000..43606d4
--- /dev/null
+++ b/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp
@@ -0,0 +1,118 @@
+template<typename T, class P>
+struct TwoOptionTemplate {};
+
+template<typename T>
+struct TwoOptionTemplate<T, char> {
+  int member;
+};
+
+
+template<typename T>
+struct TwoOptionTemplate<T, double> {
+  float member;
+};
+
+template<typename T>
+struct TwoOptionTemplate<T, T> {
+  T** member;
+};
+
+TwoOptionTemplate<int, char> X0;
+TwoOptionTemplate<int, float> X1;
+TwoOptionTemplate<void *, wchar_t> X2;
+TwoOptionTemplate<long, long> X3;
+TwoOptionTemplate<float, float> X4;
+TwoOptionTemplate<long, long> SingleSource;
+TwoOptionTemplate<char, double> SecondDoubleSource;
+
+
+template<int I, class C>
+struct IntTemplateSpec {};
+
+template<class C>
+struct IntTemplateSpec<4, C> {
+  C member;
+};
+
+template<int I>
+struct IntTemplateSpec<I, void *> {
+  int member;
+  static constexpr int val = I;
+};
+
+template<int I>
+struct IntTemplateSpec<I, double> {
+  char member;
+  static constexpr int val = I;
+};
+
+IntTemplateSpec<4, wchar_t> Y0;
+IntTemplateSpec<5, void *> Y1;
+IntTemplateSpec<1, long> Y2;
+IntTemplateSpec<3, int> Y3;
+//template<int I> constexpr int IntTemplateSpec<I, double>::val;
+IntTemplateSpec<42, double> NumberSource;
+static_assert(NumberSource.val == 42);
+
+namespace One {
+namespace Two {
+  // Just an empty namespace to ensure we can deal with multiple namespace decls.
+}
+}
+
+
+namespace One {
+namespace Two {
+namespace Three {
+
+template<class T>
+class Parent {};
+
+} // namespace Three
+
+} // namespace Two
+
+template<typename T, typename X>
+struct Child1: public Two::Three::Parent<unsigned> {
+  char member;
+};
+
+template<class T>
+struct Child1<T, One::Two::Three::Parent<T>> {
+  T member;
+};
+
+} // namespace One
+
+One::Child1<int, double> Z0Source;
+
+// Test import of nested namespace specifiers
+template<typename T>
+struct Outer {
+  template<typename U> class Inner0;
+};
+
+template<typename X>
+template<typename Y>
+class Outer<X>::Inner0 {
+public:
+  void f(X, Y);
+  template<typename Z> struct Inner1;
+};
+
+template<typename X>
+template<typename Y>
+void Outer<X>::Inner0<Y>::f(X, Y) {}
+
+template<typename X>
+template<typename Y>
+template<typename Z>
+class Outer<X>::Inner0<Y>::Inner1 {
+public:
+  void f(Y, Z);
+};
+
+template<typename X>
+template<typename Y>
+template<typename Z>
+void Outer<X>::Inner0<Y>::Inner1<Z>::f(Y, Z) {}
diff --git a/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp b/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp
new file mode 100644
index 0000000..2f3f0c6
--- /dev/null
+++ b/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp
@@ -0,0 +1,79 @@
+template<typename T, typename P>
+struct TwoOptionTemplate {};
+
+template<typename T>
+struct TwoOptionTemplate<T, char> {
+  int member;
+};
+
+
+template<typename T>
+struct TwoOptionTemplate<T, double> {
+  float member;
+};
+
+template<typename T>
+struct TwoOptionTemplate<T, T> {
+  T** member;
+};
+
+TwoOptionTemplate<int, char> X0;
+TwoOptionTemplate<int, double> X1;
+TwoOptionTemplate<void *, wchar_t> X2;
+TwoOptionTemplate<long, long> X3;
+TwoOptionTemplate<int, int> X4;
+TwoOptionTemplate<long, long> SingleDest;
+TwoOptionTemplate<int, double> SecondDoubleDest;
+
+
+template<int I, class C>
+struct IntTemplateSpec {};
+
+template<class C>
+struct IntTemplateSpec<4, C> {
+  C member;
+};
+
+template<int I>
+struct IntTemplateSpec<I, void *> {
+  double member;
+  static constexpr int val = I;
+};
+
+template<int I>
+struct IntTemplateSpec<I, double> {
+  char member;
+  static constexpr int val = I;
+};
+
+IntTemplateSpec<4, wchar_t>Y0;
+IntTemplateSpec<5, void *> Y1;
+IntTemplateSpec<1, int> Y2;
+IntTemplateSpec<2, int> Y3;
+IntTemplateSpec<43, double> NumberDest;
+
+namespace One {
+namespace Two {
+namespace Three {
+
+template<class T>
+class Parent {};
+
+} // namespace Three
+
+} // namespace Two
+
+template<typename T, typename X>
+struct Child1: public Two::Three::Parent<unsigned> {
+  char member;
+};
+
+template<class T>
+struct Child1<T, One::Two::Three::Parent<T>> {
+  T member;
+};
+
+} // namespace One
+
+namespace Dst { One::Child1<double, One::Two::Three::Parent<double>> Z0Dst; }
+One::Child1<int, float> Z1;
diff --git a/test/ASTMerge/class-template-partial-spec/test.cpp b/test/ASTMerge/class-template-partial-spec/test.cpp
new file mode 100644
index 0000000..cfa6052
--- /dev/null
+++ b/test/ASTMerge/class-template-partial-spec/test.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/class-template-partial-spec1.cpp
+// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/class-template-partial-spec2.cpp
+// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+static_assert(sizeof(**SingleSource.member) == sizeof(**SingleDest.member));
+static_assert(sizeof(SecondDoubleSource.member) == sizeof(SecondDoubleDest.member));
+static_assert(NumberSource.val == 42);
+static_assert(sizeof(Z0Source.member) == sizeof(char));
+static_assert(sizeof(Dst::Z0Dst.member) == sizeof(double));
+static_assert(sizeof(One::Child1<double, One::Two::Three::Parent<double>>::member) == sizeof(double));
+
+// CHECK: class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate<int, double>' vs. 'TwoOptionTemplate<int, float>')
+// CHECK: class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate<int, float>'
+
+// CHECK: class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate<int, int>' vs. 'TwoOptionTemplate<float, float>')
+// CHECK: class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate<float, float>'
+
+// CHECK: class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units
+// CHECK: class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here
+// CHECK: class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here
+
+// CHECK: class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>')
+// CHECK: class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>'
+
+// CHECK-NOT: static_assert
diff --git a/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp b/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp
index 7ed8e33..2a33c35 100644
--- a/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp
+++ b/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp
@@ -108,6 +108,10 @@
   return a;
 }
 
+int testDefaultArgExpr() {
+  return testDefaultArg();
+}
+
 template <typename T> // T has TemplateTypeParmType
 void testTemplateTypeParmType(int i);
 
diff --git a/test/ASTMerge/exprs-cpp/test.cpp b/test/ASTMerge/exprs-cpp/test.cpp
index ba1f18b..0535aa8 100644
--- a/test/ASTMerge/exprs-cpp/test.cpp
+++ b/test/ASTMerge/exprs-cpp/test.cpp
@@ -41,5 +41,7 @@
   testScalarInit(42);
   testOffsetOf();
   testDefaultArg(12);
+  testDefaultArg();
+  testDefaultArgExpr();
   useTemplateType();
 }
diff --git a/test/Analysis/CFContainers-invalid.c b/test/Analysis/CFContainers-invalid.c
index 3268e1e..ce1284f 100644
--- a/test/Analysis/CFContainers-invalid.c
+++ b/test/Analysis/CFContainers-invalid.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues -triple x86_64-apple-darwin -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues -triple x86_64-apple-darwin -verify %s
 // expected-no-diagnostics
 
 typedef const struct __CFAllocator * CFAllocatorRef;
diff --git a/test/Analysis/CFContainers.mm b/test/Analysis/CFContainers.mm
index f315bc9..0a45bff 100644
--- a/test/Analysis/CFContainers.mm
+++ b/test/Analysis/CFContainers.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues,osx.coreFoundation.containers.OutOfBounds -analyzer-store=region -triple x86_64-apple-darwin -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues,osx.coreFoundation.containers.OutOfBounds -analyzer-store=region -triple x86_64-apple-darwin -verify %s
 
 typedef const struct __CFAllocator * CFAllocatorRef;
 typedef const struct __CFString * CFStringRef;
diff --git a/test/Analysis/CFDateGC.m b/test/Analysis/CFDateGC.m
index fae144f..714e213 100644
--- a/test/Analysis/CFDateGC.m
+++ b/test/Analysis/CFDateGC.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -fobjc-gc %s  -Wno-implicit-function-declaration
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -fobjc-gc %s  -Wno-implicit-function-declaration
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
diff --git a/test/Analysis/CFNumber.c b/test/Analysis/CFNumber.c
index d7dd951..7ac65cc 100644
--- a/test/Analysis/CFNumber.c
+++ b/test/Analysis/CFNumber.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber,osx.cocoa.RetainCount -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.coreFoundation.CFNumber,osx.cocoa.RetainCount -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
 
 typedef signed long CFIndex;
 typedef const struct __CFAllocator * CFAllocatorRef;
diff --git a/test/Analysis/CFRetainRelease_NSAssertionHandler.m b/test/Analysis/CFRetainRelease_NSAssertionHandler.m
index be1f20d..f358ee6 100644
--- a/test/Analysis/CFRetainRelease_NSAssertionHandler.m
+++ b/test/Analysis/CFRetainRelease_NSAssertionHandler.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -verify %s -analyzer-store=region
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -verify %s -analyzer-store=region
 // expected-no-diagnostics
 
 typedef struct objc_selector *SEL;
diff --git a/test/Analysis/CGColorSpace.c b/test/Analysis/CGColorSpace.c
index 8681e15..38f0512 100644
--- a/test/Analysis/CGColorSpace.c
+++ b/test/Analysis/CGColorSpace.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
 
 typedef struct CGColorSpace *CGColorSpaceRef;
 extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
diff --git a/test/Analysis/CheckNSError.m b/test/Analysis/CheckNSError.m
index d126d29..6de98e8 100644
--- a/test/Analysis/CheckNSError.m
+++ b/test/Analysis/CheckNSError.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NSError,osx.coreFoundation.CFError -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NSError,osx.coreFoundation.CFError -analyzer-store=region -verify -Wno-objc-root-class %s
 
 
 typedef signed char BOOL;
diff --git a/test/Analysis/DeallocMissingRelease.m b/test/Analysis/DeallocMissingRelease.m
index 651f20a..91af2bd 100644
--- a/test/Analysis/DeallocMissingRelease.m
+++ b/test/Analysis/DeallocMissingRelease.m
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-ios4.0 -DMACOS=0 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-macosx10.6.0 -DMACOS=1 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-darwin10 -fobjc-arc -fobjc-runtime-has-weak -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-ios4.0 -DMACOS=0 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-macosx10.6.0 -DMACOS=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-darwin10 -fobjc-arc -fobjc-runtime-has-weak -verify %s
 
 #include "Inputs/system-header-simulator-for-objc-dealloc.h"
 
diff --git a/test/Analysis/DeallocUseAfterFreeErrors.m b/test/Analysis/DeallocUseAfterFreeErrors.m
index c131e71..2e1bdc4 100644
--- a/test/Analysis/DeallocUseAfterFreeErrors.m
+++ b/test/Analysis/DeallocUseAfterFreeErrors.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.SuperDealloc,debug.ExprInspection -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.SuperDealloc,debug.ExprInspection -analyzer-output=text -verify %s
 
 void clang_analyzer_warnIfReached();
 
diff --git a/test/Analysis/DynamicTypePropagation.m b/test/Analysis/DynamicTypePropagation.m
index 79ef37c..25a0ae3 100644
--- a/test/Analysis/DynamicTypePropagation.m
+++ b/test/Analysis/DynamicTypePropagation.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.ObjCGenerics -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.ObjCGenerics -verify %s
 
 #if !__has_feature(objc_generics)
 #  error Compiler does not support Objective-C generics?
diff --git a/test/Analysis/Inputs/qt-simulator.h b/test/Analysis/Inputs/qt-simulator.h
index d1d6c03..a3c7387 100644
--- a/test/Analysis/Inputs/qt-simulator.h
+++ b/test/Analysis/Inputs/qt-simulator.h
@@ -1,6 +1,23 @@
 #pragma clang system_header
 
+namespace QtPrivate {
+struct QSlotObjectBase {};
+}
+
+namespace Qt {
+enum ConnectionType {};
+}
+
+struct QMetaObject {
+  struct Connection {};
+};
+
 struct QObject {
+  static QMetaObject::Connection connectImpl(const QObject *, void **,
+                                             const QObject *, void **,
+                                             QtPrivate::QSlotObjectBase *,
+                                             Qt::ConnectionType,
+                                             const int *, const QMetaObject *);
 };
 
 struct QEvent {
diff --git a/test/Analysis/Inputs/system-header-simulator-cxx.h b/test/Analysis/Inputs/system-header-simulator-cxx.h
index b32d200..005e7f5 100644
--- a/test/Analysis/Inputs/system-header-simulator-cxx.h
+++ b/test/Analysis/Inputs/system-header-simulator-cxx.h
@@ -10,6 +10,29 @@
 typedef __typeof__(sizeof(int)) size_t;
 void *memmove(void *s1, const void *s2, size_t n);
 
+template <typename T, typename Ptr, typename Ref> struct __iterator {
+  typedef __iterator<T, T *, T &> iterator;
+  typedef __iterator<T, const T *, const T &> const_iterator;
+
+  __iterator(const Ptr p) : ptr(p) {}
+
+  __iterator<T, Ptr, Ref> operator++() { return *this; }
+  __iterator<T, Ptr, Ref> operator++(int) { return *this; }
+  __iterator<T, Ptr, Ref> operator--() { return *this; }
+  __iterator<T, Ptr, Ref> operator--(int) { return *this; }
+  Ref operator*() const { return *ptr; }
+  Ptr operator->() const { return *ptr; }
+
+  bool operator==(const iterator &rhs) const { return ptr == rhs.ptr; }
+  bool operator==(const const_iterator &rhs) const { return ptr == rhs.ptr; }
+
+  bool operator!=(const iterator &rhs) const { return ptr != rhs.ptr; }
+  bool operator!=(const const_iterator &rhs) const { return ptr != rhs.ptr; }
+
+private:
+  Ptr ptr;
+};
+
 namespace std {
   template <class T1, class T2>
   struct pair {
@@ -27,6 +50,9 @@
   
   template<typename T>
   class vector {
+    typedef __iterator<T, T *, T &> iterator;
+    typedef __iterator<T, const T *, const T &> const_iterator;
+
     T *_start;
     T *_finish;
     T *_end_of_storage;
@@ -49,11 +75,10 @@
       return _start[n];
     }
     
-    T *begin() { return _start; }
-    const T *begin() const { return _start; }
-
-    T *end() { return _finish; }
-    const T *end() const { return _finish; }
+    iterator begin() { return iterator(_start); }
+    const_iterator begin() const { return const_iterator(_start); }
+    iterator end() { return iterator(_finish); }
+    const_iterator end() const { return const_iterator(_finish); }
   };
   
   class exception {
@@ -223,6 +248,35 @@
     return __copy_backward(II, IE, OI);
   }
 
+  template <class InputIterator, class T>
+  InputIterator find(InputIterator first, InputIterator last, const T &val);
+  template <class ForwardIterator1, class ForwardIterator2>
+  ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1,
+                            ForwardIterator2 first2, ForwardIterator2 last2);
+  template <class ForwardIterator1, class ForwardIterator2>
+  ForwardIterator1 find_first_of(ForwardIterator1 first1,
+                                 ForwardIterator1 last1,
+                                 ForwardIterator2 first2,
+                                 ForwardIterator2 last2);
+  template <class InputIterator, class UnaryPredicate>
+  InputIterator find_if(InputIterator first, InputIterator last,
+                        UnaryPredicate pred);
+  template <class InputIterator, class UnaryPredicate>
+  InputIterator find_if_not(InputIterator first, InputIterator last,
+                            UnaryPredicate pred);
+  template <class InputIterator, class T>
+  InputIterator lower_bound(InputIterator first, InputIterator last,
+                            const T &val);
+  template <class InputIterator, class T>
+  InputIterator upper_bound(InputIterator first, InputIterator last,
+                            const T &val);
+  template <class ForwardIterator1, class ForwardIterator2>
+  ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
+                          ForwardIterator2 first2, ForwardIterator2 last2);
+  template <class ForwardIterator1, class ForwardIterator2>
+  ForwardIterator1 search_n(ForwardIterator1 first1, ForwardIterator1 last1,
+                            ForwardIterator2 first2, ForwardIterator2 last2);
+
   struct input_iterator_tag { };
   struct output_iterator_tag { };
   struct forward_iterator_tag : public input_iterator_tag { };
@@ -240,3 +294,12 @@
 void* operator new[] (std::size_t size, void* ptr) throw() { return ptr; };
 void operator delete (void* ptr, void*) throw() {};
 void operator delete[] (void* ptr, void*) throw() {};
+
+namespace __cxxabiv1 {
+extern "C" {
+extern char *__cxa_demangle(const char *mangled_name,
+                            char *output_buffer,
+                            size_t *length,
+                            int *status);
+}}
+namespace abi = __cxxabiv1;
diff --git a/test/Analysis/Inputs/system-header-simulator-objc.h b/test/Analysis/Inputs/system-header-simulator-objc.h
index 9563fb1..df751d0 100644
--- a/test/Analysis/Inputs/system-header-simulator-objc.h
+++ b/test/Analysis/Inputs/system-header-simulator-objc.h
@@ -17,7 +17,11 @@
 typedef unsigned short unichar;
 typedef UInt16 UniChar;
 
-#define NULL ((void *)0)
+#ifndef NULL
+#define __DARWIN_NULL ((void *)0)
+#define NULL __DARWIN_NULL
+#endif
+
 #define nil ((id)0)
 
 enum {
@@ -54,6 +58,7 @@
 - (oneway void)release;
 - (id)autorelease;
 - (id)init;
+@property (readonly, copy) NSString *description;
 @end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
 @end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
 @end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
diff --git a/test/Analysis/Inputs/system-header-simulator.h b/test/Analysis/Inputs/system-header-simulator.h
index 889e233..2e6f1e7 100644
--- a/test/Analysis/Inputs/system-header-simulator.h
+++ b/test/Analysis/Inputs/system-header-simulator.h
@@ -102,3 +102,11 @@
 void _exit(int status) __attribute__ ((__noreturn__));
 void _Exit(int status) __attribute__ ((__noreturn__));
 
+#define UINT32_MAX        4294967295U
+#define INT64_MIN        (-INT64_MAX-1)
+#define __DBL_MAX__ 1.7976931348623157e+308
+#define DBL_MAX __DBL_MAX__
+#ifndef NULL
+#define __DARWIN_NULL 0
+#define NULL __DARWIN_NULL
+#endif
\ No newline at end of file
diff --git a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
index 6fab8bb..b5e47b3 100644
--- a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
+++ b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
 
 #include "Inputs/system-header-simulator-for-malloc.h"
 
diff --git a/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
index bca223b..88435b8 100644
--- a/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
+++ b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator -analyzer-store region -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator -analyzer-store region -std=c++11 -verify %s
 // expected-no-diagnostics
 
 typedef __typeof(sizeof(int)) size_t;
diff --git a/test/Analysis/Malloc+NewDelete_intersections.cpp b/test/Analysis/Malloc+NewDelete_intersections.cpp
index d10020d..9140e1f 100644
--- a/test/Analysis/Malloc+NewDelete_intersections.cpp
+++ b/test/Analysis/Malloc+NewDelete_intersections.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -std=c++11 -verify %s
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
diff --git a/test/Analysis/MemRegion.cpp b/test/Analysis/MemRegion.cpp
index 992b7f1..b8f079a 100644
--- a/test/Analysis/MemRegion.cpp
+++ b/test/Analysis/MemRegion.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.mpi.MPI-Checker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.mpi.MPI-Checker -verify %s
 
 #include "MPIMock.h"
 
diff --git a/test/Analysis/MismatchedDeallocator-checker-test.mm b/test/Analysis/MismatchedDeallocator-checker-test.mm
index 3cc3e18..b80f7df 100644
--- a/test/Analysis/MismatchedDeallocator-checker-test.mm
+++ b/test/Analysis/MismatchedDeallocator-checker-test.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
 
 #include "Inputs/system-header-simulator-objc.h"
 #include "Inputs/system-header-simulator-cxx.h"
diff --git a/test/Analysis/MismatchedDeallocator-path-notes.cpp b/test/Analysis/MismatchedDeallocator-path-notes.cpp
index 1c8c80c..118f23b 100644
--- a/test/Analysis/MismatchedDeallocator-path-notes.cpp
+++ b/test/Analysis/MismatchedDeallocator-path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void changePointee(int *p);
diff --git a/test/Analysis/MissingDealloc.m b/test/Analysis/MissingDealloc.m
index 248dc51..bedd1e7 100644
--- a/test/Analysis/MissingDealloc.m
+++ b/test/Analysis/MissingDealloc.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify -triple x86_64-apple-darwin10 -fobjc-arc %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify -triple x86_64-apple-darwin10 -fobjc-arc %s
 
 #define NON_ARC !__has_feature(objc_arc)
 
diff --git a/test/Analysis/NSContainers.m b/test/Analysis/NSContainers.m
index c868459..ac33efc 100644
--- a/test/Analysis/NSContainers.m
+++ b/test/Analysis/NSContainers.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -Wno-objc-literal-conversion -analyze -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops,debug.ExprInspection -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1  -Wno-objc-literal-conversion -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops,debug.ExprInspection -verify -Wno-objc-root-class %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/NSPanel.m b/test/Analysis/NSPanel.m
index 53b18c2..e65b071 100644
--- a/test/Analysis/NSPanel.m
+++ b/test/Analysis/NSPanel.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 // BEGIN delta-debugging reduced header stuff
diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m
index 1123d80..a53fc1e 100644
--- a/test/Analysis/NSString.m
+++ b/test/Analysis/NSString.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -analyzer-config mode=shallow -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -DOSATOMIC_USE_INLINED -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -analyzer-config mode=shallow -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -DOSATOMIC_USE_INLINED -triple i386-apple-darwin10 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
diff --git a/test/Analysis/NSWindow.m b/test/Analysis/NSWindow.m
index 44a97e4..e247ff1 100644
--- a/test/Analysis/NSWindow.m
+++ b/test/Analysis/NSWindow.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core,deadcode.DeadStores -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core,deadcode.DeadStores -analyzer-store=region -verify %s
 
 // These declarations were reduced using Delta-Debugging from Foundation.h
 // on Mac OS X.  The test cases are below.
diff --git a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
index 49358f6..987ed6a 100644
--- a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
+++ b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,unix.MismatchedDeallocator -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.MismatchedDeallocator -DLEAKS -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.MismatchedDeallocator -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.MismatchedDeallocator -DLEAKS -std=c++11 -verify %s
 // expected-no-diagnostics
 
 typedef __typeof(sizeof(int)) size_t;
diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp
index 78a0015..66e8375 100644
--- a/test/Analysis/NewDelete-checker-test.cpp
+++ b/test/Analysis/NewDelete-checker-test.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
 #include "Inputs/system-header-simulator-cxx.h"
 
 typedef __typeof__(sizeof(int)) size_t;
@@ -244,7 +244,7 @@
 
 void testUninitFree() {
   int *x;
-  free(x); // expected-warning{{Function call argument is an uninitialized value}}
+  free(x); // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 void testUninitDeleteSink() {
diff --git a/test/Analysis/NewDelete-custom.cpp b/test/Analysis/NewDelete-custom.cpp
index d368889..f06ff4a 100644
--- a/test/Analysis/NewDelete-custom.cpp
+++ b/test/Analysis/NewDelete-custom.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -DLEAKS -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -DLEAKS -fblocks -verify %s
 #include "Inputs/system-header-simulator-cxx.h"
 
 #ifndef LEAKS
diff --git a/test/Analysis/NewDelete-intersections.mm b/test/Analysis/NewDelete-intersections.mm
index cde8122..aa52c79 100644
--- a/test/Analysis/NewDelete-intersections.mm
+++ b/test/Analysis/NewDelete-intersections.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -std=c++11 -DLEAKS -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -std=c++11 -DLEAKS -fblocks -verify %s
 #include "Inputs/system-header-simulator-cxx.h"
 #include "Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/NewDelete-path-notes.cpp b/test/Analysis/NewDelete-path-notes.cpp
index 64b15b8..115a4ad 100644
--- a/test/Analysis/NewDelete-path-notes.cpp
+++ b/test/Analysis/NewDelete-path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void test() {
diff --git a/test/Analysis/NewDelete-variadic.cpp b/test/Analysis/NewDelete-variadic.cpp
index f9ef079b..523785a 100644
--- a/test/Analysis/NewDelete-variadic.cpp
+++ b/test/Analysis/NewDelete-variadic.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -fblocks -verify %s
 // expected-no-diagnostics
 
 namespace std {
diff --git a/test/Analysis/NewDeleteLeaks-PR18394.cpp b/test/Analysis/NewDeleteLeaks-PR18394.cpp
index d0d7037..5a5b82c 100644
--- a/test/Analysis/NewDeleteLeaks-PR18394.cpp
+++ b/test/Analysis/NewDeleteLeaks-PR18394.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyzer-config graph-trim-interval=1 -analyzer-max-loop 1 -analyze -analyzer-checker=core,cplusplus.NewDeleteLeaks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-config graph-trim-interval=1 -analyzer-max-loop 1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -verify %s
 // expected-no-diagnostics
 
 class A {
diff --git a/test/Analysis/NewDeleteLeaks-PR19102.cpp b/test/Analysis/NewDeleteLeaks-PR19102.cpp
index b141301..502db61 100644
--- a/test/Analysis/NewDeleteLeaks-PR19102.cpp
+++ b/test/Analysis/NewDeleteLeaks-PR19102.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDeleteLeaks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -verify %s
 
 class A0 {};
 
diff --git a/test/Analysis/NoReturn.m b/test/Analysis/NoReturn.m
index 5ed92df..c08fd0d 100644
--- a/test/Analysis/NoReturn.m
+++ b/test/Analysis/NoReturn.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 #include <stdarg.h>
 
diff --git a/test/Analysis/OSAtomic_mac.cpp b/test/Analysis/OSAtomic_mac.cpp
index f938958..e45f236 100644
--- a/test/Analysis/OSAtomic_mac.cpp
+++ b/test/Analysis/OSAtomic_mac.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,osx -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,osx -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
 // expected-no-diagnostics
 
 // Test handling of OSAtomicCompareAndSwap when C++ inserts "no-op" casts and we
diff --git a/test/Analysis/ObjCProperties.m b/test/Analysis/ObjCProperties.m
index 201e3e1..1a112ec 100644
--- a/test/Analysis/ObjCProperties.m
+++ b/test/Analysis/ObjCProperties.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s -verify
 // expected-no-diagnostics
 
 // The point of this test cases is to exercise properties in the static
diff --git a/test/Analysis/ObjCPropertiesSyntaxChecks.m b/test/Analysis/ObjCPropertiesSyntaxChecks.m
new file mode 100644
index 0000000..5a25896
--- /dev/null
+++ b/test/Analysis/ObjCPropertiesSyntaxChecks.m
@@ -0,0 +1,68 @@
+// RUN: %clang_analyze_cc1 -w -fblocks -analyzer-checker=osx.ObjCProperty %s -verify
+
+#include "Inputs/system-header-simulator-objc.h"
+
+@interface I : NSObject {
+  NSMutableString *_mutableExplicitStr;
+  NSMutableString *_trulyMutableStr;
+  NSMutableString *_trulyMutableExplicitStr;
+}
+@property(copy) NSString *str; // no-warning
+@property(copy) NSMutableString *mutableStr; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@property(copy) NSMutableString *mutableExplicitStr; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@property(copy, readonly) NSMutableString *mutableReadonlyStr; // no-warning
+@property(copy, readonly) NSMutableString *mutableReadonlyStrOverriddenInChild; // no-warning
+@property(copy, readonly) NSMutableString *mutableReadonlyStrOverriddenInCategory; // no-warning
+@property(copy) NSMutableString *trulyMutableStr; // no-warning
+@property(copy) NSMutableString *trulyMutableExplicitStr; // no-warning
+@property(copy) NSMutableString *trulyMutableStrWithSynthesizedStorage; // no-warning
+@end
+
+@interface I () {}
+@property(copy) NSMutableString *mutableStrInCategory; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@property (copy, readwrite) NSMutableString *mutableReadonlyStrOverriddenInCategory; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@end
+
+@implementation I
+@synthesize mutableExplicitStr = _mutableExplicitStr;
+- (NSMutableString *)trulyMutableStr {
+  return _trulyMutableStr;
+}
+- (void)setTrulyMutableStr: (NSMutableString *) S {
+  _trulyMutableStr = [S mutableCopy];
+}
+@dynamic trulyMutableExplicitStr;
+- (NSMutableString *)trulyMutableExplicitStr {
+  return _trulyMutableExplicitStr;
+}
+- (void)setTrulyMutableExplicitStr: (NSMutableString *) S {
+  _trulyMutableExplicitStr = [S mutableCopy];
+}
+@synthesize trulyMutableStrWithSynthesizedStorage;
+- (NSMutableString *)trulyMutableStrWithSynthesizedStorage {
+  return trulyMutableStrWithSynthesizedStorage;
+}
+- (void)setTrulyMutableStrWithSynthesizedStorage: (NSMutableString *) S {
+  trulyMutableStrWithSynthesizedStorage = [S mutableCopy];
+}
+@end
+
+@interface J : I {}
+@property (copy, readwrite) NSMutableString *mutableReadonlyStrOverriddenInChild; // expected-warning{{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}}
+@end
+
+@implementation J
+@end
+
+// If we do not see the implementation then we do not want to warn,
+// because we may miss a user-defined setter that works correctly.
+@interface IWithoutImpl : NSObject {}
+@property(copy) NSMutableString *mutableStr; // no-warning
+@end
+
+@protocol SomeProtocol
+// Don't warn on protocol properties because it is possible to
+// conform to them correctly; it is only synthesized setters that
+// that are definitely incorrect.
+@property (copy) NSMutableString *myProp; // no-crash // no-warning
+@end
diff --git a/test/Analysis/ObjCRetSigs.m b/test/Analysis/ObjCRetSigs.m
index 6ee83ec..97d33f9 100644
--- a/test/Analysis/ObjCRetSigs.m
+++ b/test/Analysis/ObjCRetSigs.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-checker=osx.cocoa.IncompatibleMethodTypes -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-checker=osx.cocoa.IncompatibleMethodTypes -verify -Wno-objc-root-class %s
 
 int printf(const char *, ...);
 
diff --git a/test/Analysis/PR12905.c b/test/Analysis/PR12905.c
index 8f678d1..f36b93a 100644
--- a/test/Analysis/PR12905.c
+++ b/test/Analysis/PR12905.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core %s
 // PR12905
 
 void C(void);
diff --git a/test/Analysis/PR24184.cpp b/test/Analysis/PR24184.cpp
index 54eae56..1280334 100644
--- a/test/Analysis/PR24184.cpp
+++ b/test/Analysis/PR24184.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -w -analyze -analyzer-eagerly-assume -fcxx-exceptions -analyzer-checker=core -analyzer-checker=alpha.core.PointerArithm,alpha.core.CastToStruct -analyzer-max-loop 64 -verify %s
-// RUN: %clang_cc1 -w -analyze -analyzer-checker=core -analyzer-checker=cplusplus -fcxx-exceptions -analyzer-checker alpha.core.PointerArithm,alpha.core.CastToStruct -analyzer-max-loop 63 -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-eagerly-assume -fcxx-exceptions -analyzer-checker=core -analyzer-checker=alpha.core.PointerArithm,alpha.core.CastToStruct -analyzer-max-loop 64 -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core -analyzer-checker=cplusplus -fcxx-exceptions -analyzer-checker alpha.core.PointerArithm,alpha.core.CastToStruct -analyzer-max-loop 63 -verify %s
 
 // These tests used to hit an assertion in the bug report. Test case from http://llvm.org/PR24184.
 typedef struct {
diff --git a/test/Analysis/PR2599.m b/test/Analysis/PR2599.m
index ac552ee..1c2270e 100644
--- a/test/Analysis/PR2599.m
+++ b/test/Analysis/PR2599.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -fobjc-gc -verify %s
+// RUN: %clang_analyze_cc1 -triple %itanium_abi_triple -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -fobjc-gc -verify %s
 
 typedef const void * CFTypeRef;
 typedef const struct __CFString * CFStringRef;
diff --git a/test/Analysis/PR2978.m b/test/Analysis/PR2978.m
index b609da5..8b7effc 100644
--- a/test/Analysis/PR2978.m
+++ b/test/Analysis/PR2978.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,osx.cocoa.Dealloc %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,osx.cocoa.Dealloc %s -verify
 
 // Tests for the checker which checks missing/extra ivar 'release' calls 
 // in dealloc.
diff --git a/test/Analysis/PR3991.m b/test/Analysis/PR3991.m
index 68d5660..ffdb7b4 100644
--- a/test/Analysis/PR3991.m
+++ b/test/Analysis/PR3991.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-incomplete-implementation %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-incomplete-implementation %s
 // expected-no-diagnostics
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Analysis/PR7218.c b/test/Analysis/PR7218.c
index 1775e05..10a75c9 100644
--- a/test/Analysis/PR7218.c
+++ b/test/Analysis/PR7218.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store region -verify %s
 char PR7218(char a) {
     char buf[2];
     buf[0] = a;
diff --git a/test/Analysis/additive-folding-range-constraints.c b/test/Analysis/additive-folding-range-constraints.c
index 4baada8..87d1b1c 100644
--- a/test/Analysis/additive-folding-range-constraints.c
+++ b/test/Analysis/additive-folding-range-constraints.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/additive-folding.cpp b/test/Analysis/additive-folding.cpp
index 6ae025b..52056d4 100644
--- a/test/Analysis/additive-folding.cpp
+++ b/test/Analysis/additive-folding.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -Wno-tautological-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -Wno-tautological-compare %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/analyzeOneFunction.m b/test/Analysis/analyzeOneFunction.m
index e70b2d7..a77abe1 100644
--- a/test/Analysis/analyzeOneFunction.m
+++ b/test/Analysis/analyzeOneFunction.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyze-function="-[Test1 myMethodWithY:withX:]" -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyze-function="-[Test1 myMethodWithY:withX:]" -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
 
 typedef signed char BOOL;
 typedef unsigned int NSUInteger;
diff --git a/test/Analysis/analyzer-checker-config.c b/test/Analysis/analyzer-checker-config.c
index 642c96c..34e3399 100644
--- a/test/Analysis/analyzer-checker-config.c
+++ b/test/Analysis/analyzer-checker-config.c
@@ -1,10 +1,10 @@
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config unix.mallo:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config uni:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config uni.:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config ..:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config unix.:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config unrelated:Optimistic=true 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config unix.Malloc:Optimistic=true
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.mallo:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config uni:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config uni.:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config ..:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unrelated:Optimistic=true 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.Malloc:Optimistic=true
 
 // Just to test clang is working.
 # foo
diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c
index 6faeeb3..c0153a5 100644
--- a/test/Analysis/analyzer-config.c
+++ b/test/Analysis/analyzer-config.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper -Xclang -analyzer-max-loop -Xclang 34 > %t 2>&1
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core,osx.cocoa,debug.ConfigDumper -analyzer-max-loop 34 > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 void bar() {}
diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp
index 23f0828..f84be17 100644
--- a/test/Analysis/analyzer-config.cpp
+++ b/test/Analysis/analyzer-config.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper -Xclang -analyzer-max-loop -Xclang 34 > %t 2>&1
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core,osx.cocoa,debug.ConfigDumper -analyzer-max-loop 34 > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 void bar() {}
diff --git a/test/Analysis/analyzer-display-progress.cpp b/test/Analysis/analyzer-display-progress.cpp
index 5d9f5e5..b54044a 100644
--- a/test/Analysis/analyzer-display-progress.cpp
+++ b/test/Analysis/analyzer-display-progress.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-display-progress %s 2>&1 | FileCheck %s
 
 void f() {};
 void g() {};
diff --git a/test/Analysis/analyzer-display-progress.m b/test/Analysis/analyzer-display-progress.m
index cc43cf3..8d0b3d6 100644
--- a/test/Analysis/analyzer-display-progress.m
+++ b/test/Analysis/analyzer-display-progress.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-display-progress %s 2>&1 | FileCheck %s
 
 #include "Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/analyzer-enabled-checkers.c b/test/Analysis/analyzer-enabled-checkers.c
index e60de05..0ea01a0 100644
--- a/test/Analysis/analyzer-enabled-checkers.c
+++ b/test/Analysis/analyzer-enabled-checkers.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=core -Xclang -analyzer-list-enabled-checkers > %t 2>&1
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core -analyzer-list-enabled-checkers > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 // CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List
diff --git a/test/Analysis/analyzer-stats.c b/test/Analysis/analyzer-stats.c
index a0a50cb..5a40d19 100644
--- a/test/Analysis/analyzer-stats.c
+++ b/test/Analysis/analyzer-stats.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,debug.Stats -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,deadcode.DeadStores,debug.Stats -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
 
 int foo();
 
diff --git a/test/Analysis/array-struct-region.c b/test/Analysis/array-struct-region.c
index a41d040..cdfec45 100644
--- a/test/Analysis/array-struct-region.c
+++ b/test/Analysis/array-struct-region.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/array-struct-region.cpp b/test/Analysis/array-struct-region.cpp
index 4777686..48a05fd 100644
--- a/test/Analysis/array-struct-region.cpp
+++ b/test/Analysis/array-struct-region.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c
index 34bdc58..45c4c9d 100644
--- a/test/Analysis/array-struct.c
+++ b/test/Analysis/array-struct.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.CastToStruct -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.CastToStruct -analyzer-store=region -verify %s
 
 struct s {
   int data;
diff --git a/test/Analysis/atomics.c b/test/Analysis/atomics.c
index f0f5ff0..6fe4ec5 100644
--- a/test/Analysis/atomics.c
+++ b/test/Analysis/atomics.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 // Tests for c11 atomics. Many of these tests currently yield unknown
 // because we don't fully model the atomics and instead imprecisely
diff --git a/test/Analysis/auto-obj-dtors-cfg-output.cpp b/test/Analysis/auto-obj-dtors-cfg-output.cpp
index 0b4454f..cc47c92 100644
--- a/test/Analysis/auto-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/auto-obj-dtors-cfg-output.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -fexceptions -analyzer-checker=debug.DumpCFG %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 class A {
diff --git a/test/Analysis/base-init.cpp b/test/Analysis/base-init.cpp
index 3c870e1..1f59303 100644
--- a/test/Analysis/base-init.cpp
+++ b/test/Analysis/base-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/bitwise-ops.c b/test/Analysis/bitwise-ops.c
index 01daf42..407aa19 100644
--- a/test/Analysis/bitwise-ops.c
+++ b/test/Analysis/bitwise-ops.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -triple x86_64-apple-darwin13 -Wno-shift-count-overflow -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -triple x86_64-apple-darwin13 -Wno-shift-count-overflow -verify %s
 
 void clang_analyzer_eval(int);
 #define CHECK(expr) if (!(expr)) return; clang_analyzer_eval(expr)
diff --git a/test/Analysis/block-in-critical-section.cpp b/test/Analysis/block-in-critical-section.cpp
index 93c0b6d..c65cc61 100644
--- a/test/Analysis/block-in-critical-section.cpp
+++ b/test/Analysis/block-in-critical-section.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.BlockInCriticalSection -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.BlockInCriticalSection -std=c++11 -verify %s
 
 void sleep(int x) {}
 
@@ -9,29 +9,91 @@
 };
 }
 
-void testBlockInCriticalSection() {
+void getc() {}
+void fgets() {}
+void read() {}
+void recv() {}
+
+void pthread_mutex_lock() {}
+void pthread_mutex_trylock() {}
+void pthread_mutex_unlock() {}
+
+void mtx_lock() {}
+void mtx_timedlock() {}
+void mtx_trylock() {}
+void mtx_unlock() {}
+
+void testBlockInCriticalSectionWithStdMutex() {
   std::mutex m;
   m.lock();
-  sleep(3); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
   m.unlock();
 }
 
+void testBlockInCriticalSectionWithPthreadMutex() {
+  pthread_mutex_lock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  pthread_mutex_unlock();
+
+  pthread_mutex_trylock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  pthread_mutex_unlock();
+}
+
+void testBlockInCriticalSectionC11Locks() {
+  mtx_lock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  mtx_unlock();
+
+  mtx_timedlock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  mtx_unlock();
+
+  mtx_trylock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  mtx_unlock();
+}
+
 void testBlockInCriticalSectionWithNestedMutexes() {
   std::mutex m, n, k;
   m.lock();
   n.lock();
   k.lock();
-  sleep(3); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
   k.unlock();
-  sleep(5); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(5); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
   n.unlock();
-  sleep(3); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
   m.unlock();
   sleep(3); // no-warning
 }
 
 void f() {
-  sleep(1000); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(1000); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
 }
 
 void testBlockInCriticalSectionInterProcedural() {
@@ -46,5 +108,5 @@
   m.unlock();
   sleep(1); // no-warning
   m.lock();
-  sleep(1); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
 }
diff --git a/test/Analysis/blocks-no-inline.c b/test/Analysis/blocks-no-inline.c
index de6f959..859eedf 100644
--- a/test/Analysis/blocks-no-inline.c
+++ b/test/Analysis/blocks-no-inline.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -fblocks -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -fblocks -verify -x c++ %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -fblocks -verify -x c++ %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/blocks.m b/test/Analysis/blocks.m
index bf10c61..98d0f8a 100644
--- a/test/Analysis/blocks.m
+++ b/test/Analysis/blocks.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -analyzer-opt-analyze-nested-blocks -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -analyzer-opt-analyze-nested-blocks -verify -x objective-c++ %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -analyzer-store=region -fblocks -analyzer-opt-analyze-nested-blocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -analyzer-store=region -fblocks -analyzer-opt-analyze-nested-blocks -verify -x objective-c++ %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from Mac OS X headers:
diff --git a/test/Analysis/blocks.mm b/test/Analysis/blocks.mm
index 5f93888..6cff9b4 100644
--- a/test/Analysis/blocks.mm
+++ b/test/Analysis/blocks.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -fblocks -analyzer-opt-analyze-nested-blocks -verify -x objective-c++ %s
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core,debug.DumpCFG -fblocks -analyzer-opt-analyze-nested-blocks  %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -fblocks -analyzer-opt-analyze-nested-blocks -verify -x objective-c++ %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.DumpCFG -fblocks -analyzer-opt-analyze-nested-blocks %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 // expected-no-diagnostics
diff --git a/test/Analysis/bool-assignment.c b/test/Analysis/bool-assignment.c
index 285569e..57a7f0b 100644
--- a/test/Analysis/bool-assignment.c
+++ b/test/Analysis/bool-assignment.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -std=c99 -Dbool=_Bool %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -x c++ %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -std=c99 -Dbool=_Bool %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -x c++ %s
 
 // Test C++'s bool and C's _Bool.
 // FIXME: We stopped warning on these when SValBuilder got smarter about
@@ -43,8 +43,11 @@
     return;
   }
   if (y > 200 && y < 250) {
-    // FIXME: Currently we are loosing this warning due to a SymbolCast in RHS.
+#ifdef ANALYZER_CM_Z3
+    BOOL x = y; // expected-warning {{Assignment of a non-Boolean value}}
+#else
     BOOL x = y; // no-warning
+#endif
     return;
   }
   if (y >= 127 && y < 150) {
diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c
index 824aa7c..a671d9e 100644
--- a/test/Analysis/bstring.c
+++ b/test/Analysis/bstring.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
 
 //===----------------------------------------------------------------------===
 // Declarations
diff --git a/test/Analysis/bstring.cpp b/test/Analysis/bstring.cpp
index 0b4e7e9..a6d7b40 100644
--- a/test/Analysis/bstring.cpp
+++ b/test/Analysis/bstring.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator-cxx.h"
 #include "Inputs/system-header-simulator-for-malloc.h"
diff --git a/test/Analysis/bug_hash_test.cpp b/test/Analysis/bug_hash_test.cpp
index b73528e..0efcb5f 100644
--- a/test/Analysis/bug_hash_test.cpp
+++ b/test/Analysis/bug_hash_test.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 int function(int p) {
diff --git a/test/Analysis/bug_hash_test.m b/test/Analysis/bug_hash_test.m
index debed32..1e99d3c 100644
--- a/test/Analysis/bug_hash_test.m
+++ b/test/Analysis/bug_hash_test.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 @protocol NSObject
diff --git a/test/Analysis/builtin-functions.cpp b/test/Analysis/builtin-functions.cpp
index d3afab5..4e98597 100644
--- a/test/Analysis/builtin-functions.cpp
+++ b/test/Analysis/builtin-functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection %s -std=c++11 -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,debug.ExprInspection %s -std=c++11 -verify
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/call-invalidation.cpp b/test/Analysis/call-invalidation.cpp
index 80323ff..d3b5fca 100644
--- a/test/Analysis/call-invalidation.cpp
+++ b/test/Analysis/call-invalidation.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/cast-to-struct.cpp b/test/Analysis/cast-to-struct.cpp
index 45d5594..c3aba02 100644
--- a/test/Analysis/cast-to-struct.cpp
+++ b/test/Analysis/cast-to-struct.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.CastToStruct,core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.CastToStruct,core -verify %s
 
 struct AB {
   int A;
@@ -65,3 +65,17 @@
   void *VP = P;
   Abc = (struct ABC *)VP;
 }
+
+// https://llvm.org/bugs/show_bug.cgi?id=31173
+void dontCrash1(struct AB X) {
+  struct UndefS *S = (struct UndefS *)&X;
+}
+
+struct S;
+struct T {
+  struct S *P;
+};
+extern struct S Var1, Var2;
+void dontCrash2() {
+  ((struct T *) &Var1)->P = &Var2;
+}
diff --git a/test/Analysis/castexpr-callback.c b/test/Analysis/castexpr-callback.c
index 73fa17a..3b46093 100644
--- a/test/Analysis/castexpr-callback.c
+++ b/test/Analysis/castexpr-callback.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PreStmtCastExpr=true,debug.AnalysisOrder:PostStmtCastExpr=true %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PreStmtCastExpr=true,debug.AnalysisOrder:PostStmtCastExpr=true %s 2>&1 | FileCheck %s
 
 void test(char c) {
   int i = (int)c;
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
index b5e6e27..92082fe 100644
--- a/test/Analysis/casts.c
+++ b/test/Analysis/casts.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
 
 extern void clang_analyzer_eval(_Bool);
 
diff --git a/test/Analysis/casts.cpp b/test/Analysis/casts.cpp
index 53e1cd0..f96f19b 100644
--- a/test/Analysis/casts.cpp
+++ b/test/Analysis/casts.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify %s
 
 bool PR14634(int x) {
   double y = (double)x;
diff --git a/test/Analysis/casts.m b/test/Analysis/casts.m
index 895c811..5c81ae6 100644
--- a/test/Analysis/casts.m
+++ b/test/Analysis/casts.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 // Test function pointer casts.
diff --git a/test/Analysis/cfg.cpp b/test/Analysis/cfg.cpp
index 3e34a0f..2082773 100644
--- a/test/Analysis/cfg.cpp
+++ b/test/Analysis/cfg.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 // CHECK-LABEL: void checkWrap(int i)
diff --git a/test/Analysis/cfref_PR2519.c b/test/Analysis/cfref_PR2519.c
index d9642e5..5636737 100644
--- a/test/Analysis/cfref_PR2519.c
+++ b/test/Analysis/cfref_PR2519.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 typedef unsigned char Boolean;
diff --git a/test/Analysis/cfref_rdar6080742.c b/test/Analysis/cfref_rdar6080742.c
index 7094660..2f74036 100644
--- a/test/Analysis/cfref_rdar6080742.c
+++ b/test/Analysis/cfref_rdar6080742.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 // This test case was reported in <rdar:problem/6080742>.
diff --git a/test/Analysis/check-deserialization.cpp b/test/Analysis/check-deserialization.cpp
index 2b0bce2..9e4e471 100644
--- a/test/Analysis/check-deserialization.cpp
+++ b/test/Analysis/check-deserialization.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-pch -o %t %s
-// RUN: %clang_cc1 -error-on-deserialized-decl S1_method -include-pch %t -analyze -analyzer-checker=core %s
-// RUN: %clang_cc1 -include-pch %t -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -error-on-deserialized-decl S1_method -include-pch %t -analyzer-checker=core %s
+// RUN: %clang_analyze_cc1 -include-pch %t -analyzer-checker=core -verify %s
 
 #ifndef HEADER
 #define HEADER
diff --git a/test/Analysis/checker-plugins.c b/test/Analysis/checker-plugins.c
index 3882ba6..ee60ec6 100644
--- a/test/Analysis/checker-plugins.c
+++ b/test/Analysis/checker-plugins.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -load %llvmshlibdir/SampleAnalyzerPlugin%pluginext -analyze -analyzer-checker='example.MainCallChecker' -verify %s
+// RUN: %clang_analyze_cc1 -load %llvmshlibdir/SampleAnalyzerPlugin%pluginext -analyzer-checker='example.MainCallChecker' -verify %s
 // REQUIRES: plugins, examples
 
 // Test that the MainCallChecker example analyzer plugin loads and runs.
diff --git a/test/Analysis/chroot.c b/test/Analysis/chroot.c
index 1b818a8..7e514f7 100644
--- a/test/Analysis/chroot.c
+++ b/test/Analysis/chroot.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.Chroot -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.Chroot -analyzer-store region -verify %s
 
 extern int chroot(const char* path);
 extern int chdir(const char* path);
diff --git a/test/Analysis/comparison-implicit-casts.cpp b/test/Analysis/comparison-implicit-casts.cpp
index a991d43..fe5254c 100644
--- a/test/Analysis/comparison-implicit-casts.cpp
+++ b/test/Analysis/comparison-implicit-casts.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple i386-apple-darwin9 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple x86_64-apple-darwin9 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple i386-apple-darwin9 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple x86_64-apple-darwin9 -verify %s
 
 // This file runs in C++ mode so that the comparison type is 'bool', not 'int'.
 void clang_analyzer_eval(int);
diff --git a/test/Analysis/complex-init-list.cpp b/test/Analysis/complex-init-list.cpp
index bbff64b..299f362 100644
--- a/test/Analysis/complex-init-list.cpp
+++ b/test/Analysis/complex-init-list.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
 // expected-no-diagnostics
 
 // Do not crash on initialization to complex numbers.
diff --git a/test/Analysis/complex.c b/test/Analysis/complex.c
index 6aca589..1f61b14 100644
--- a/test/Analysis/complex.c
+++ b/test/Analysis/complex.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify -Wno-unreachable-code -ffreestanding %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify -Wno-unreachable-code -ffreestanding %s
 
 #include <stdint.h>
 
diff --git a/test/Analysis/concrete-address.c b/test/Analysis/concrete-address.c
index 819afca..f1608f8 100644
--- a/test/Analysis/concrete-address.c
+++ b/test/Analysis/concrete-address.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 void foo() {
diff --git a/test/Analysis/conditional-operator.cpp b/test/Analysis/conditional-operator.cpp
index 137dc39..32978c6 100644
--- a/test/Analysis/conditional-operator.cpp
+++ b/test/Analysis/conditional-operator.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection %s -analyzer-output=text -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %s -analyzer-output=text -verify
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/conditional-path-notes.c b/test/Analysis/conditional-path-notes.c
index 448af7f..d842b7f 100644
--- a/test/Analysis/conditional-path-notes.c
+++ b/test/Analysis/conditional-path-notes.c
@@ -1,5 +1,5 @@
-// RUN: %clang --analyze %s -Xanalyzer -analyzer-output=text -Xclang -verify
-// RUN: %clang --analyze %s -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -o %t
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=text -verify
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t
 // RUN: FileCheck --input-file=%t %s
 
 void testCondOp(int *p) {
diff --git a/test/Analysis/const-method-call.cpp b/test/Analysis/const-method-call.cpp
index b8aaeea..17df2a0 100644
--- a/test/Analysis/const-method-call.cpp
+++ b/test/Analysis/const-method-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/constant-folding.c b/test/Analysis/constant-folding.c
index 81d1193..a6d2b74 100644
--- a/test/Analysis/constant-folding.c
+++ b/test/Analysis/constant-folding.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/conversion.c b/test/Analysis/conversion.c
index f202696..5827794 100644
--- a/test/Analysis/conversion.c
+++ b/test/Analysis/conversion.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-conversion -analyze -analyzer-checker=core,alpha.core.Conversion -verify %s
+// RUN: %clang_analyze_cc1 -Wno-conversion -analyzer-checker=core,alpha.core.Conversion -verify %s
 
 unsigned char U8;
 signed char S8;
diff --git a/test/Analysis/copypaste/asm.cpp b/test/Analysis/copypaste/asm.cpp
index e93f119..2e3613d 100644
--- a/test/Analysis/copypaste/asm.cpp
+++ b/test/Analysis/copypaste/asm.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -analyze -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/attributes.cpp b/test/Analysis/copypaste/attributes.cpp
index 72d654c..083be74 100644
--- a/test/Analysis/copypaste/attributes.cpp
+++ b/test/Analysis/copypaste/attributes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/blocks.cpp b/test/Analysis/copypaste/blocks.cpp
index 133b5cb..10467b7 100644
--- a/test/Analysis/copypaste/blocks.cpp
+++ b/test/Analysis/copypaste/blocks.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fblocks -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // This tests if we search for clones in blocks.
 
diff --git a/test/Analysis/copypaste/call.cpp b/test/Analysis/copypaste/call.cpp
index 8e95f7c..046229a 100644
--- a/test/Analysis/copypaste/call.cpp
+++ b/test/Analysis/copypaste/call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/catch.cpp b/test/Analysis/copypaste/catch.cpp
index 590ce8f..cf3e807 100644
--- a/test/Analysis/copypaste/catch.cpp
+++ b/test/Analysis/copypaste/catch.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/delete.cpp b/test/Analysis/copypaste/delete.cpp
index dc42c9c..394226b 100644
--- a/test/Analysis/copypaste/delete.cpp
+++ b/test/Analysis/copypaste/delete.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/dependent-exist.cpp b/test/Analysis/copypaste/dependent-exist.cpp
index 5182ba6..9046353 100644
--- a/test/Analysis/copypaste/dependent-exist.cpp
+++ b/test/Analysis/copypaste/dependent-exist.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fms-extensions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fms-extensions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/expr-types.cpp b/test/Analysis/copypaste/expr-types.cpp
index 14eef6e..601f0b1 100644
--- a/test/Analysis/copypaste/expr-types.cpp
+++ b/test/Analysis/copypaste/expr-types.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/fold.cpp b/test/Analysis/copypaste/fold.cpp
index 548dfb1..0aed11b 100644
--- a/test/Analysis/copypaste/fold.cpp
+++ b/test/Analysis/copypaste/fold.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/function-try-block.cpp b/test/Analysis/copypaste/function-try-block.cpp
index 7a69097..d777145 100644
--- a/test/Analysis/copypaste/function-try-block.cpp
+++ b/test/Analysis/copypaste/function-try-block.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // Tests if function try blocks are correctly handled.
 
diff --git a/test/Analysis/copypaste/functions.cpp b/test/Analysis/copypaste/functions.cpp
index c95443d..d2c607b 100644
--- a/test/Analysis/copypaste/functions.cpp
+++ b/test/Analysis/copypaste/functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // This tests if we search for clones in functions.
 
diff --git a/test/Analysis/copypaste/generic.c b/test/Analysis/copypaste/generic.c
index 9d83921..d4d4564 100644
--- a/test/Analysis/copypaste/generic.c
+++ b/test/Analysis/copypaste/generic.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/labels.cpp b/test/Analysis/copypaste/labels.cpp
index 26318ac..eff3330 100644
--- a/test/Analysis/copypaste/labels.cpp
+++ b/test/Analysis/copypaste/labels.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=gnu++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=gnu++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/lambda.cpp b/test/Analysis/copypaste/lambda.cpp
index c13c56f..17c8748 100644
--- a/test/Analysis/copypaste/lambda.cpp
+++ b/test/Analysis/copypaste/lambda.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/macro-complexity.cpp b/test/Analysis/copypaste/macro-complexity.cpp
index aca4df1..70d3f0c 100644
--- a/test/Analysis/copypaste/macro-complexity.cpp
+++ b/test/Analysis/copypaste/macro-complexity.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // Tests that the complexity value of a macro expansion is about the same as
 // the complexity value of a normal function call and the the macro body doesn't
diff --git a/test/Analysis/copypaste/macros.cpp b/test/Analysis/copypaste/macros.cpp
index db9b4c6..bdacd48 100644
--- a/test/Analysis/copypaste/macros.cpp
+++ b/test/Analysis/copypaste/macros.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // Tests that macros and non-macro clones aren't mixed into the same hash
 // group. This is currently necessary as all clones in a hash group need
diff --git a/test/Analysis/copypaste/objc-methods.m b/test/Analysis/copypaste/objc-methods.m
index 9b8002c..e63c7f6 100644
--- a/test/Analysis/copypaste/objc-methods.m
+++ b/test/Analysis/copypaste/objc-methods.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -Wno-objc-root-class -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -Wno-objc-root-class -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // This tests if we search for clones in Objective-C methods.
 
diff --git a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
index 1180d44..7c4f355 100644
--- a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-output=plist -analyzer-config notes-as-events=true -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=plist -analyzer-config notes-as-events=true -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 void log();
diff --git a/test/Analysis/copypaste/plist-diagnostics.cpp b/test/Analysis/copypaste/plist-diagnostics.cpp
index 109d8e4..e2fa759 100644
--- a/test/Analysis/copypaste/plist-diagnostics.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 void log();
diff --git a/test/Analysis/copypaste/sub-sequences.cpp b/test/Analysis/copypaste/sub-sequences.cpp
index ff73632..798662d 100644
--- a/test/Analysis/copypaste/sub-sequences.cpp
+++ b/test/Analysis/copypaste/sub-sequences.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // This tests if sub-sequences can match with normal sequences.
 
diff --git a/test/Analysis/copypaste/suspicious-clones.cpp b/test/Analysis/copypaste/suspicious-clones.cpp
index c64a1dc..3a760e2 100644
--- a/test/Analysis/copypaste/suspicious-clones.cpp
+++ b/test/Analysis/copypaste/suspicious-clones.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true  -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true  -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -verify %s
 
 // Tests finding a suspicious clone that references local variables.
 
diff --git a/test/Analysis/copypaste/text-diagnostics.cpp b/test/Analysis/copypaste/text-diagnostics.cpp
index a80afdb..a6e358c 100644
--- a/test/Analysis/copypaste/text-diagnostics.cpp
+++ b/test/Analysis/copypaste/text-diagnostics.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-output=text -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=text -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 void log();
 
diff --git a/test/Analysis/coverage.c b/test/Analysis/coverage.c
index 9e437d2..b819f10 100644
--- a/test/Analysis/coverage.c
+++ b/test/Analysis/coverage.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -analyzer-max-loop 4 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-store=region -analyzer-max-loop 4 -verify %s
 #include "Inputs/system-header-simulator.h"
 
 typedef __typeof(sizeof(int)) size_t;
diff --git a/test/Analysis/crash-trace.c b/test/Analysis/crash-trace.c
index bac7447..b79dd02 100644
--- a/test/Analysis/crash-trace.c
+++ b/test/Analysis/crash-trace.c
@@ -1,4 +1,4 @@
-// RUN: not --crash %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+// RUN: not --crash %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
 // REQUIRES: crash-recovery
 
 // FIXME: CHECKs might be incompatible to win32.
diff --git a/test/Analysis/cstring-syntax-cxx.cpp b/test/Analysis/cstring-syntax-cxx.cpp
index 39c978a..b2adef8 100644
--- a/test/Analysis/cstring-syntax-cxx.cpp
+++ b/test/Analysis/cstring-syntax-cxx.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 // Ensure we don't crash on C++ declarations with special names.
diff --git a/test/Analysis/cstring-syntax.c b/test/Analysis/cstring-syntax.c
index 4aa88ed..313ac54 100644
--- a/test/Analysis/cstring-syntax.c
+++ b/test/Analysis/cstring-syntax.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -Wno-strncat-size -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument -Wno-sizeof-pointer-memaccess -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -Wno-strncat-size -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument -Wno-sizeof-pointer-memaccess -verify %s
 
 typedef __SIZE_TYPE__ size_t;
 char  *strncat(char *, const char *, size_t);
@@ -10,4 +10,6 @@
   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest)); // expected-warning {{Potential buffer overflow. Replace with}}
   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest) - strlen(dest)); // expected-warning {{Potential buffer overflow. Replace with}}
   strncat(dest, src, sizeof(src)); // expected-warning {{Potential buffer overflow. Replace with}}
+  // Should not crash when sizeof has a type argument.
+  strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(char));
 }
diff --git a/test/Analysis/ctor.mm b/test/Analysis/ctor.mm
index e7c0c6c..646229a 100644
--- a/test/Analysis/ctor.mm
+++ b/test/Analysis/ctor.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify %s
 
 #include "Inputs/system-header-simulator-cxx.h"
 
diff --git a/test/Analysis/cxx-crashes.cpp b/test/Analysis/cxx-crashes.cpp
index e3f8125..f8234c9 100644
--- a/test/Analysis/cxx-crashes.cpp
+++ b/test/Analysis/cxx-crashes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
 // REQUIRES: LP64
 
 void clang_analyzer_eval(bool);
diff --git a/test/Analysis/cxx-for-range.cpp b/test/Analysis/cxx-for-range.cpp
index 6be8b78..bf3cfbf 100644
--- a/test/Analysis/cxx-for-range.cpp
+++ b/test/Analysis/cxx-for-range.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist-multi-file -o %t.plist -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist-multi-file -o %t.plist -verify %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 extern void work();
diff --git a/test/Analysis/cxx-method-names.cpp b/test/Analysis/cxx-method-names.cpp
index 21be5e4..e57e72d 100644
--- a/test/Analysis/cxx-method-names.cpp
+++ b/test/Analysis/cxx-method-names.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,osx,alpha.unix,alpha.security.taint -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,osx,alpha.unix,alpha.security.taint -analyzer-store region -verify %s
 // expected-no-diagnostics
 
 class Evil {
diff --git a/test/Analysis/cxx11-crashes.cpp b/test/Analysis/cxx11-crashes.cpp
index c6034e6..8905d1c 100644
--- a/test/Analysis/cxx11-crashes.cpp
+++ b/test/Analysis/cxx11-crashes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++11 -verify %s
 
 // radar://11485149, PR12871
 class PlotPoint {
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index c55b34f..05bc64a 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
-// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores -analyzer-store=region -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -Wunused-variable -analyzer-checker=core,deadcode.DeadStores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -Wunused-variable -analyzer-checker=core,deadcode.DeadStores -analyzer-store=region -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
 
 void f1() {
   int k, y; // expected-warning{{unused variable 'k'}} expected-warning{{unused variable 'y'}}
diff --git a/test/Analysis/dead-stores.cpp b/test/Analysis/dead-stores.cpp
index 77b349e..d926ccf 100644
--- a/test/Analysis/dead-stores.cpp
+++ b/test/Analysis/dead-stores.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyze -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyze -analyzer-store=region -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyzer-store=region -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
 
 //===----------------------------------------------------------------------===//
 // Basic dead store checking (but in C++ mode).
diff --git a/test/Analysis/dead-stores.m b/test/Analysis/dead-stores.m
index 8bc6b2e..9f91f39 100644
--- a/test/Analysis/dead-stores.m
+++ b/test/Analysis/dead-stores.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-checker=deadcode.DeadStores,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-checker=deadcode.DeadStores,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 typedef signed char BOOL;
diff --git a/test/Analysis/debug-CallGraph.c b/test/Analysis/debug-CallGraph.c
index 64259e2..9f3865b 100644
--- a/test/Analysis/debug-CallGraph.c
+++ b/test/Analysis/debug-CallGraph.c
@@ -1,4 +1,16 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCallGraph %s -fblocks 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCallGraph %s -fblocks 2>&1 | FileCheck %s
+
+int get5() {
+  return 5;
+}
+
+int add(int val1, int val2) {
+  return val1 + val2;
+}
+
+int test_add() {
+  return add(10, get5());
+}
 
 static void mmm(int y) {
   if (y != 0)
@@ -31,8 +43,18 @@
 void eee() {}
 void fff() { eee(); }
 
+// This test case tests that forward declaration for the top-level function
+// does not affect call graph construction.
+void do_nothing() {}
+void test_single_call();
+void test_single_call() {
+  do_nothing();
+}
+
 // CHECK:--- Call graph Dump ---
-// CHECK-NEXT: {{Function: < root > calls: mmm foo aaa < > bbb ccc ddd eee fff $}}
+// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call $}}
+// CHECK-NEXT: {{Function: test_single_call calls: do_nothing $}}
+// CHECK-NEXT: {{Function: do_nothing calls: $}}
 // CHECK-NEXT: {{Function: fff calls: eee $}}
 // CHECK-NEXT: {{Function: eee calls: $}}
 // CHECK-NEXT: {{Function: ddd calls: ccc $}}
@@ -42,3 +64,6 @@
 // CHECK-NEXT: {{Function: aaa calls: foo $}}
 // CHECK-NEXT: {{Function: foo calls: mmm $}}
 // CHECK-NEXT: {{Function: mmm calls: $}}
+// CHECK-NEXT: {{Function: test_add calls: add get5 $}}
+// CHECK-NEXT: {{Function: add calls: $}}
+// CHECK-NEXT: {{Function: get5 calls: $}}
diff --git a/test/Analysis/default-analyze.m b/test/Analysis/default-analyze.m
index 5fbaa2f..e2f7297 100644
--- a/test/Analysis/default-analyze.m
+++ b/test/Analysis/default-analyze.m
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -o %t
+// RUN: %clang_analyze_cc1 %s -o %t
 
 // Tests that some specific checkers are enabled by default.
 
diff --git a/test/Analysis/default-diagnostic-visitors.c b/test/Analysis/default-diagnostic-visitors.c
index 0bc6a03..c8f64bc 100644
--- a/test/Analysis/default-diagnostic-visitors.c
+++ b/test/Analysis/default-diagnostic-visitors.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -analyzer-store=region -analyzer-output=text -verify %s
 
 // This file is for testing enhanced diagnostics produced by the default BugReporterVisitors.
 
diff --git a/test/Analysis/delayed-template-parsing-crash.cpp b/test/Analysis/delayed-template-parsing-crash.cpp
index 94a143b..6d189af 100644
--- a/test/Analysis/delayed-template-parsing-crash.cpp
+++ b/test/Analysis/delayed-template-parsing-crash.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -std=c++11 -fdelayed-template-parsing -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++11 -fdelayed-template-parsing -verify %s
 // expected-no-diagnostics
 
 template <class T> struct remove_reference      {typedef T type;};
diff --git a/test/Analysis/delegates.m b/test/Analysis/delegates.m
index 28e9006..2302805 100644
--- a/test/Analysis/delegates.m
+++ b/test/Analysis/delegates.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -Wno-objc-root-class -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -Wno-objc-root-class -verify %s
 // expected-no-diagnostics
 
 
diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp
index e9c7ca8..b9851fd 100644
--- a/test/Analysis/derived-to-base.cpp
+++ b/test/Analysis/derived-to-base.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DCONSTRUCTORS=1 -analyzer-config c++-inlining=constructors -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DCONSTRUCTORS=1 -analyzer-config c++-inlining=constructors -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
diff --git a/test/Analysis/designated-initializer.c b/test/Analysis/designated-initializer.c
index b601f87..920b2f0 100644
--- a/test/Analysis/designated-initializer.c
+++ b/test/Analysis/designated-initializer.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 \
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 \
 // RUN:   | FileCheck %s
 
 struct Q { int a, b, c; };
diff --git a/test/Analysis/diagnostics/deref-track-symbolic-region.c b/test/Analysis/diagnostics/deref-track-symbolic-region.c
index 42060cc..179e736 100644
--- a/test/Analysis/diagnostics/deref-track-symbolic-region.c
+++ b/test/Analysis/diagnostics/deref-track-symbolic-region.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 struct S {
diff --git a/test/Analysis/diagnostics/deref-track-symbolic-region.cpp b/test/Analysis/diagnostics/deref-track-symbolic-region.cpp
index 6d34841..61993f0 100644
--- a/test/Analysis/diagnostics/deref-track-symbolic-region.cpp
+++ b/test/Analysis/diagnostics/deref-track-symbolic-region.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
 
 struct S {
   int *x;
diff --git a/test/Analysis/diagnostics/diag-cross-file-boundaries.c b/test/Analysis/diagnostics/diag-cross-file-boundaries.c
index 270163e..b975af3 100644
--- a/test/Analysis/diagnostics/diag-cross-file-boundaries.c
+++ b/test/Analysis/diagnostics/diag-cross-file-boundaries.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=html -o PR12421.html %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o PR12421.html %s 2>&1 | FileCheck %s
 
 // Test for PR12421
 #include "diag-cross-file-boundaries.h"
diff --git a/test/Analysis/diagnostics/explicit-suppression.cpp b/test/Analysis/diagnostics/explicit-suppression.cpp
index 67a47d0..193846c 100644
--- a/test/Analysis/diagnostics/explicit-suppression.cpp
+++ b/test/Analysis/diagnostics/explicit-suppression.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=true -DSUPPRESSED=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=true -DSUPPRESSED=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DSUPPRESSED=1 -verify %s
 
 #ifdef SUPPRESSED
 // expected-no-diagnostics
@@ -18,6 +19,6 @@
 void testCopyNull(C *I, C *E) {
   std::copy(I, E, (C *)0);
 #ifndef SUPPRESSED
-  // expected-warning@../Inputs/system-header-simulator-cxx.h:166 {{Called C++ object pointer is null}}
+  // expected-warning@../Inputs/system-header-simulator-cxx.h:191 {{Called C++ object pointer is null}}
 #endif
 }
diff --git a/test/Analysis/diagnostics/false-positive-suppression.c b/test/Analysis/diagnostics/false-positive-suppression.c
index cdcd7cc..87c04cb 100644
--- a/test/Analysis/diagnostics/false-positive-suppression.c
+++ b/test/Analysis/diagnostics/false-positive-suppression.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -I %S/Inputs -analyze -analyzer-checker=core,unix -verify %s
+// RUN: %clang_analyze_cc1 -I %S/Inputs -analyzer-checker=core,unix -verify %s
 // expected-no-diagnostics
 
 #include "include/sys/queue.h"
diff --git a/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp b/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp
index 143cbbe..197fad5 100644
--- a/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp
+++ b/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -std=c++11 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/diagnostics/macros.cpp b/test/Analysis/diagnostics/macros.cpp
new file mode 100644
index 0000000..5aa2c03
--- /dev/null
+++ b/test/Analysis/diagnostics/macros.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,osx -analyzer-output=text -verify %s
+
+#include "../Inputs/system-header-simulator.h"
+#include "../Inputs/system-header-simulator-cxx.h"
+
+void testIntMacro(unsigned int i) {
+  if (i == UINT32_MAX) { // expected-note {{Assuming 'i' is equal to UINT32_MAX}}
+                         // expected-note@-1 {{Taking true branch}}
+    char *p = NULL; // expected-note {{'p' initialized to a null pointer value}}
+    *p = 7;  // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+             // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
+  }
+}
+
+void testNULLMacro(int *p) {
+  if (p == NULL) { // expected-note {{Assuming 'p' is equal to NULL}}
+                   // expected-note@-1 {{Taking true branch}}
+    *p = 7;  // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+             // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
+  }
+}
+
+void testnullptrMacro(int *p) {
+  if (p == nullptr) { // expected-note {{Assuming pointer value is null}}
+                      // expected-note@-1 {{Taking true branch}}
+    *p = 7;  // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+             // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
+  }
+}
+
+// There are no path notes on the comparison to float types.
+void testDoubleMacro(double d) {
+  if (d == DBL_MAX) { // expected-note {{Taking true branch}}
+
+    char *p = NULL; // expected-note {{'p' initialized to a null pointer value}}
+    *p = 7;         // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+                    // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
+  }
+}
+
+void testboolMacro(bool b, int *p) {
+  p = nullptr;      // expected-note {{Null pointer value stored to 'p'}}
+  if (b == false) { // expected-note {{Assuming the condition is true}}
+                    // expected-note@-1 {{Taking true branch}}
+    *p = 7;         // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+                    // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
+  }
+}
diff --git a/test/Analysis/diagnostics/macros.m b/test/Analysis/diagnostics/macros.m
new file mode 100644
index 0000000..b459974
--- /dev/null
+++ b/test/Analysis/diagnostics/macros.m
@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -fblocks -analyzer-output=text -verify %s
+
+#include "../Inputs/system-header-simulator-objc.h"
+
+@interface NSDictionary : NSObject
+- (NSUInteger)count;
+- (id)objectForKey:(id)aKey;
+- (NSEnumerator *)keyEnumerator;
+@end
+@interface NSMutableDictionary : NSDictionary
+- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
+@end
+
+void testBOOLMacro(BOOL b) {
+  if (b == YES) { // expected-note {{Assuming 'b' is equal to YES}}
+                  // expected-note@-1 {{Taking true branch}}
+    char *p = NULL;// expected-note {{'p' initialized to a null pointer value}}
+    *p = 7;  // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+             // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
+  }
+}
+
+void testNilMacro(NSMutableDictionary *d, NSObject *o) {
+  if (o == nil) // expected-note {{Assuming 'o' is equal to nil}}
+                // expected-note@-1 {{Taking true branch}}
+    [d setObject:o forKey:[o description]]; // expected-warning {{Key argument to 'setObject:forKey:' cannot be nil}}
+                                            // expected-note@-1 {{'description' not called because the receiver is nil}}
+                                            // expected-note@-2 {{Key argument to 'setObject:forKey:' cannot be nil}}
+
+  return;
+}
diff --git a/test/Analysis/diagnostics/no-prune-paths.c b/test/Analysis/diagnostics/no-prune-paths.c
index fab5cf8..6e9e457 100644
--- a/test/Analysis/diagnostics/no-prune-paths.c
+++ b/test/Analysis/diagnostics/no-prune-paths.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config prune-paths=false -DNPRUNE=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config prune-paths=false -DNPRUNE=1 -verify %s
 
 // "prune-paths" is a debug option only; this is just a simple test to see that
 // it's being honored.
diff --git a/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp b/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
index 6ed3945..8c66b96 100644
--- a/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
+++ b/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -analyzer-output=plist-multi-file %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -analyzer-output=plist-multi-file %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 #include "Inputs/include/plist-diagnostics-include-check-macro.h"
diff --git a/test/Analysis/diagnostics/report-issues-within-main-file.cpp b/test/Analysis/diagnostics/report-issues-within-main-file.cpp
index 5fd7abd..784fdba 100644
--- a/test/Analysis/diagnostics/report-issues-within-main-file.cpp
+++ b/test/Analysis/diagnostics/report-issues-within-main-file.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -analyzer-output=plist-multi-file -analyzer-config report-in-main-source-file=true -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-output=plist-multi-file -analyzer-config report-in-main-source-file=true -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 #include "Inputs/include/report-issues-within-main-file.h"
 
diff --git a/test/Analysis/diagnostics/shortest-path-suppression.c b/test/Analysis/diagnostics/shortest-path-suppression.c
index 4f648b9..d0fa4b5 100644
--- a/test/Analysis/diagnostics/shortest-path-suppression.c
+++ b/test/Analysis/diagnostics/shortest-path-suppression.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=true -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-null-return-paths=true -analyzer-output=text -verify %s
 // expected-no-diagnostics
 
 int *returnNull() { return 0; }
diff --git a/test/Analysis/diagnostics/text-diagnostics.c b/test/Analysis/diagnostics/text-diagnostics.c
index 5925216..0194647 100644
--- a/test/Analysis/diagnostics/text-diagnostics.c
+++ b/test/Analysis/diagnostics/text-diagnostics.c
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze -Xanalyzer -analyzer-output=text -fno-caret-diagnostics %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.NullDereference -analyzer-output=text -fno-caret-diagnostics %s 2>&1 | FileCheck %s
 
 void testA() {
   int *p = 0;
diff --git a/test/Analysis/diagnostics/undef-value-caller.c b/test/Analysis/diagnostics/undef-value-caller.c
index dc19e0a..4f273bd 100644
--- a/test/Analysis/diagnostics/undef-value-caller.c
+++ b/test/Analysis/diagnostics/undef-value-caller.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
 // RUN: FileCheck --input-file %t %s
 
 #include "undef-value-callee.h"
diff --git a/test/Analysis/diagnostics/undef-value-param.c b/test/Analysis/diagnostics/undef-value-param.c
index 8ebf0da..837b041 100644
--- a/test/Analysis/diagnostics/undef-value-param.c
+++ b/test/Analysis/diagnostics/undef-value-param.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void foo_irrelevant(int c) {
diff --git a/test/Analysis/diagnostics/undef-value-param.m b/test/Analysis/diagnostics/undef-value-param.m
index b9947d8..f8212e0 100644
--- a/test/Analysis/diagnostics/undef-value-param.m
+++ b/test/Analysis/diagnostics/undef-value-param.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 typedef signed char BOOL;
@@ -45,8 +45,8 @@
     CreateRefUndef(&storeRef, 4);
                              //expected-note@-1{{Calling 'CreateRefUndef'}}
                              //expected-note@-2{{Returning from 'CreateRefUndef'}}
-    CFRelease(storeRef); //expected-warning {{Function call argument is an uninitialized value}}
-                         //expected-note@-1{{Function call argument is an uninitialized value}}
+    CFRelease(storeRef); //expected-warning {{1st function call argument is an uninitialized value}}
+                         //expected-note@-1{{1st function call argument is an uninitialized value}}
 }
 @end
 
@@ -918,12 +918,12 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Function call argument is an uninitialized value</string>
+// CHECK-NEXT:      <string>1st function call argument is an uninitialized value</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Function call argument is an uninitialized value</string>
+// CHECK-NEXT:      <string>1st function call argument is an uninitialized value</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Function call argument is an uninitialized value</string>
+// CHECK-NEXT:    <key>description</key><string>1st function call argument is an uninitialized value</string>
 // CHECK-NEXT:    <key>category</key><string>Logic error</string>
 // CHECK-NEXT:    <key>type</key><string>Uninitialized argument value</string>
 // CHECK-NEXT:    <key>check_name</key><string>core.CallAndMessage</string>
diff --git a/test/Analysis/disable-all-checks.c b/test/Analysis/disable-all-checks.c
index 461e6d9..eb55799 100644
--- a/test/Analysis/disable-all-checks.c
+++ b/test/Analysis/disable-all-checks.c
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-disable-all-checks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-disable-all-checks -analyzer-checker=core -analyzer-store=region -verify %s
-// RUN: %clang --analyze -Xanalyzer -analyzer-disable-all-checks -Xclang -verify %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-disable-checker -verify %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-disable-all-checks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-disable-all-checks -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-disable-all-checks -verify %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-disable-checker -verify %s 2>&1 | FileCheck %s
 // expected-no-diagnostics
 
 // CHECK: use -analyzer-disable-all-checks to disable all static analyzer checkers
 int buggy() {
   int x = 0;
   return 5/x; // no warning
-}
\ No newline at end of file
+}
diff --git a/test/Analysis/dispatch-once.m b/test/Analysis/dispatch-once.m
index 7d54147..7314dc9 100644
--- a/test/Analysis/dispatch-once.m
+++ b/test/Analysis/dispatch-once.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -w -fblocks -analyze -analyzer-checker=core,osx.API,unix.Malloc -verify %s
-// RUN: %clang_cc1 -w -fblocks -fobjc-arc -analyze -analyzer-checker=core,osx.API,unix.Malloc -verify %s
+// RUN: %clang_analyze_cc1 -w -fblocks -analyzer-checker=core,osx.API,unix.Malloc -verify %s
+// RUN: %clang_analyze_cc1 -w -fblocks -fobjc-arc -analyzer-checker=core,osx.API,unix.Malloc -verify %s
 
 #include "Inputs/system-header-simulator-objc.h"
 
@@ -107,3 +107,10 @@
   };
   dispatch_once(&once, ^{}); // expected-warning{{Call to 'dispatch_once' uses the block variable 'once' for the predicate value.}}
 }
+
+void test_static_var_from_outside_block() {
+  static dispatch_once_t once;
+  ^{
+    dispatch_once(&once, ^{}); // no-warning
+  };
+}
diff --git a/test/Analysis/div-zero.cpp b/test/Analysis/div-zero.cpp
index d1261dc..063450d 100644
--- a/test/Analysis/div-zero.cpp
+++ b/test/Analysis/div-zero.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core.DivideZero -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.DivideZero -verify %s
 
 int fooPR10616 (int qX ) {
   int a, c, d;
diff --git a/test/Analysis/division-by-zero.c b/test/Analysis/division-by-zero.c
index d3c228e..33bb6fa 100644
--- a/test/Analysis/division-by-zero.c
+++ b/test/Analysis/division-by-zero.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.Malloc %s
 // Do not crash due to division by zero
 
 int f(unsigned int a) {
diff --git a/test/Analysis/domtest.c b/test/Analysis/domtest.c
index dd72117..e957c8d 100644
--- a/test/Analysis/domtest.c
+++ b/test/Analysis/domtest.c
@@ -1,5 +1,5 @@
 // RUN: rm -f %t
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpDominators %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpDominators %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 // Test the DominatorsTree implementation with various control flows
diff --git a/test/Analysis/dtor-cxx11.cpp b/test/Analysis/dtor-cxx11.cpp
index 7d2e87e..76d5e6c 100644
--- a/test/Analysis/dtor-cxx11.cpp
+++ b/test/Analysis/dtor-cxx11.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config cfg-temporary-dtors=true -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config cfg-temporary-dtors=true -Wno-null-dereference -verify %s
 // expected-no-diagnostics
 
 #include "Inputs/system-header-simulator-cxx.h"
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index c677222..bc74130 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
diff --git a/test/Analysis/dtors-in-dtor-cfg-output.cpp b/test/Analysis/dtors-in-dtor-cfg-output.cpp
index ceda58c..4c1c8dd 100644
--- a/test/Analysis/dtors-in-dtor-cfg-output.cpp
+++ b/test/Analysis/dtors-in-dtor-cfg-output.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
 
 class A {
 public:
diff --git a/test/Analysis/dynamic-cast.cpp b/test/Analysis/dynamic-cast.cpp
index b48ee5b..0c86f81 100644
--- a/test/Analysis/dynamic-cast.cpp
+++ b/test/Analysis/dynamic-cast.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/dynamic_type_check.m b/test/Analysis/dynamic_type_check.m
index f9b181e..3dc9465 100644
--- a/test/Analysis/dynamic_type_check.m
+++ b/test/Analysis/dynamic_type_check.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.DynamicTypeChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.DynamicTypeChecker -verify %s
 
 
 #define nil 0
diff --git a/test/Analysis/edges-new.mm b/test/Analysis/edges-new.mm
index 775b1ce..217cd4a 100644
--- a/test/Analysis/edges-new.mm
+++ b/test/Analysis/edges-new.mm
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-apple-darwin10 --analyze -Xclang -analyzer-config -Xclang path-diagnostics-alternate=true -Xclang -analyzer-output=plist -o %t %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,deadcode.DeadStores,osx.cocoa.RetainCount,unix.Malloc,unix.MismatchedDeallocator -analyzer-eagerly-assume -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist -o %t -w %s
 // RUN: FileCheck --input-file %t %s
 
 //===----------------------------------------------------------------------===//
@@ -230,7 +230,7 @@
     p = 0;
 
   } while (i< 2);
-  
+
   *p = 0xDEADBEEF;
 }
 
@@ -2438,9 +2438,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFNumberCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFNumberCreate&apos; returns a Core Foundation object of type CFNumberRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFNumberCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFNumberCreate&apos; returns a Core Foundation object of type CFNumberRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -11355,9 +11355,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of RDar10797980 with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of RDar10797980 with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -20325,9 +20325,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
diff --git a/test/Analysis/elementtype.c b/test/Analysis/elementtype.c
index 1b26811..7eba8e1 100644
--- a/test/Analysis/elementtype.c
+++ b/test/Analysis/elementtype.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region %s
 
 typedef struct added_obj_st {
   int type;
diff --git a/test/Analysis/engine/replay-without-inlining.c b/test/Analysis/engine/replay-without-inlining.c
index 14b2b81..0b9820e 100644
--- a/test/Analysis/engine/replay-without-inlining.c
+++ b/test/Analysis/engine/replay-without-inlining.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -verify %s
 // expected-no-diagnostics
 
 typedef struct {
diff --git a/test/Analysis/enum.cpp b/test/Analysis/enum.cpp
index 571fa7b..e26b8f0 100644
--- a/test/Analysis/enum.cpp
+++ b/test/Analysis/enum.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=debug.ExprInspection %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=debug.ExprInspection %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/exceptions.mm b/test/Analysis/exceptions.mm
index dab1b5e..0e77637 100644
--- a/test/Analysis/exceptions.mm
+++ b/test/Analysis/exceptions.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fexceptions -fobjc-exceptions -fcxx-exceptions -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -fexceptions -fobjc-exceptions -fcxx-exceptions -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
 
 void clang_analyzer_checkInlined(bool);
 
diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c
index 03b6874..577b88b 100644
--- a/test/Analysis/exercise-ps.c
+++ b/test/Analysis/exercise-ps.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 //
 // Just exercise the analyzer on code that has at one point caused issues
 // (i.e., no assertions or crashes).
diff --git a/test/Analysis/explain-svals.c b/test/Analysis/explain-svals.c
new file mode 100644
index 0000000..f1540bb
--- /dev/null
+++ b/test/Analysis/explain-svals.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin,debug.ExprInspection,unix.cstring -verify %s
+
+struct S {
+  int z;
+};
+
+void clang_analyzer_explain_int(int);
+void clang_analyzer_explain_voidp(void *);
+void clang_analyzer_explain_S(struct S);
+
+int glob;
+
+void test_1(int param, void *ptr) {
+  clang_analyzer_explain_voidp(&glob); // expected-warning-re{{{{^pointer to global variable 'glob'$}}}}
+  clang_analyzer_explain_int(param);   // expected-warning-re{{{{^argument 'param'$}}}}
+  clang_analyzer_explain_voidp(ptr);   // expected-warning-re{{{{^argument 'ptr'$}}}}
+  if (param == 42)
+    clang_analyzer_explain_int(param); // expected-warning-re{{{{^signed 32-bit integer '42'$}}}}
+}
+
+void test_2(struct S s) {
+  clang_analyzer_explain_S(s);      //expected-warning-re{{{{^lazily frozen compound value of parameter 's'$}}}}
+  clang_analyzer_explain_voidp(&s); // expected-warning-re{{{{^pointer to parameter 's'$}}}}
+  clang_analyzer_explain_int(s.z);  // expected-warning-re{{{{^initial value of field 'z' of parameter 's'$}}}}
+}
diff --git a/test/Analysis/explain-svals.cpp b/test/Analysis/explain-svals.cpp
index be2f830..d4b56a3 100644
--- a/test/Analysis/explain-svals.cpp
+++ b/test/Analysis/explain-svals.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin,debug.ExprInspection,unix.cstring -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core.builtin,debug.ExprInspection,unix.cstring -verify %s
 
 typedef unsigned long size_t;
 
diff --git a/test/Analysis/explain-svals.m b/test/Analysis/explain-svals.m
index 34cdacf..dd40946 100644
--- a/test/Analysis/explain-svals.m
+++ b/test/Analysis/explain-svals.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -triple i386-apple-darwin10 -fblocks -analyze -analyzer-checker=core.builtin,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -w -triple i386-apple-darwin10 -fblocks -analyzer-checker=core.builtin,debug.ExprInspection -verify %s
 
 #include "Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/expr-inspection.c b/test/Analysis/expr-inspection.c
index 69e18cb..1e21efb 100644
--- a/test/Analysis/expr-inspection.c
+++ b/test/Analysis/expr-inspection.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -verify %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -verify %s 2>&1 | FileCheck %s
 
 // Self-tests for the debug.ExprInspection checker.
 
diff --git a/test/Analysis/fields.c b/test/Analysis/fields.c
index a670c50..1aa4840 100644
--- a/test/Analysis/fields.c
+++ b/test/Analysis/fields.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection %s -analyzer-store=region -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection %s -analyzer-store=region -verify
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/free.c b/test/Analysis/free.c
index 3746bf1..acdb282 100644
--- a/test/Analysis/free.c
+++ b/test/Analysis/free.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify -analyzer-config unix.Malloc:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify -analyzer-config unix.Malloc:Optimistic=true %s
 typedef __typeof(sizeof(int)) size_t;
 void free(void *);
 void *alloca(size_t);
diff --git a/test/Analysis/func.c b/test/Analysis/func.c
index 78afb45..58d4f45 100644
--- a/test/Analysis/func.c
+++ b/test/Analysis/func.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_warnIfReached();
diff --git a/test/Analysis/generics.m b/test/Analysis/generics.m
index da5c512..dac148d 100644
--- a/test/Analysis/generics.m
+++ b/test/Analysis/generics.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s -analyzer-output=plist -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s -analyzer-output=plist -o %t.plist
 // RUN: FileCheck --input-file %t.plist %s
 
 #if !__has_feature(objc_generics)
diff --git a/test/Analysis/global-region-invalidation.c b/test/Analysis/global-region-invalidation.c
index bff2201..83df292 100644
--- a/test/Analysis/global-region-invalidation.c
+++ b/test/Analysis/global-region-invalidation.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,alpha.security.taint,debug.TaintTest,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,alpha.security.taint,debug.TaintTest,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/global_region_invalidation.mm b/test/Analysis/global_region_invalidation.mm
index 2369c09..aee3b66 100644
--- a/test/Analysis/global_region_invalidation.mm
+++ b/test/Analysis/global_region_invalidation.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/gmalloc.c b/test/Analysis/gmalloc.c
new file mode 100644
index 0000000..10c4fe2
--- /dev/null
+++ b/test/Analysis/gmalloc.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify %s
+
+#include "Inputs/system-header-simulator.h"
+
+typedef void* gpointer;
+typedef const void* gconstpointer;
+typedef unsigned long gsize;
+typedef unsigned int guint;
+
+gpointer g_malloc(gsize n_bytes);
+gpointer g_malloc0(gsize n_bytes);
+gpointer g_realloc(gpointer mem, gsize n_bytes);
+gpointer g_try_malloc(gsize n_bytes);
+gpointer g_try_malloc0(gsize n_bytes);
+gpointer g_try_realloc(gpointer mem, gsize n_bytes);
+void g_free(gpointer mem);
+gpointer g_memdup(gconstpointer mem, guint byte_size);
+
+static const gsize n_bytes = 1024;
+
+void f1() {
+  gpointer g1 = g_malloc(n_bytes);
+  gpointer g2 = g_malloc0(n_bytes);
+  g1 = g_realloc(g1, n_bytes * 2);
+  gpointer g3 = g_try_malloc(n_bytes);
+  gpointer g4 = g_try_malloc0(n_bytes);
+  g3 = g_try_realloc(g3, n_bytes * 2);
+
+  g_free(g1);
+  g_free(g2);
+  g_free(g2); // expected-warning{{Attempt to free released memory}}
+}
+
+void f2() {
+  gpointer g1 = g_malloc(n_bytes);
+  gpointer g2 = g_malloc0(n_bytes);
+  g1 = g_realloc(g1, n_bytes * 2);
+  gpointer g3 = g_try_malloc(n_bytes);
+  gpointer g4 = g_try_malloc0(n_bytes);
+  g3 = g_try_realloc(g3, n_bytes * 2);
+
+  g_free(g1);
+  g_free(g2);
+  g_free(g3);
+  g3 = g_memdup(g3, n_bytes); // expected-warning{{Use of memory after it is freed}}
+}
+
+void f3() {
+  gpointer g1 = g_malloc(n_bytes);
+  gpointer g2 = g_malloc0(n_bytes);
+  g1 = g_realloc(g1, n_bytes * 2);
+  gpointer g3 = g_try_malloc(n_bytes);
+  gpointer g4 = g_try_malloc0(n_bytes);
+  g3 = g_try_realloc(g3, n_bytes * 2); // expected-warning{{Potential leak of memory pointed to by 'g4'}}
+
+  g_free(g1);
+  g_free(g2);
+  g_free(g3);
+}
diff --git a/test/Analysis/gtest.cpp b/test/Analysis/gtest.cpp
new file mode 100644
index 0000000..5797a77
--- /dev/null
+++ b/test/Analysis/gtest.cpp
@@ -0,0 +1,153 @@
+//RUN: %clang_analyze_cc1 -cc1 -std=c++11  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -analyzer-eagerly-assume %s -verify
+//RUN: %clang_analyze_cc1 -cc1 -std=c++11  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -analyzer-eagerly-assume -DGTEST_VERSION_1_8_AND_LATER=1 %s -verify
+//RUN: %clang_analyze_cc1 -cc1 -std=c++11  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -analyzer-eagerly-assume -analyzer-config cfg-temporary-dtors=true %s -verify
+
+void clang_analyzer_eval(int);
+void clang_analyzer_warnIfReached();
+
+namespace std {
+  class string {
+    public:
+    ~string();
+    const char *c_str();
+  };
+}
+
+namespace testing {
+
+class Message { };
+class TestPartResult {
+ public:
+  enum Type {
+    kSuccess,
+    kNonFatalFailure,
+    kFatalFailure
+  };
+};
+
+namespace internal {
+
+class AssertHelper {
+ public:
+  AssertHelper(TestPartResult::Type type, const char* file, int line,
+               const char* message);
+  ~AssertHelper();
+  void operator=(const Message& message) const;
+};
+
+
+template <typename T>
+struct AddReference { typedef T& type; };
+template <typename T>
+struct AddReference<T&> { typedef T& type; };
+template <typename From, typename To>
+class ImplicitlyConvertible {
+ private:
+  static typename AddReference<From>::type MakeFrom();
+  static char Helper(To);
+  static char (&Helper(...))[2];
+ public:
+  static const bool value =
+      sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
+};
+template <typename From, typename To>
+const bool ImplicitlyConvertible<From, To>::value;
+template<bool> struct EnableIf;
+template<> struct EnableIf<true> { typedef void type; };
+
+} // end internal
+
+
+class AssertionResult {
+public:
+
+  // The implementation for the copy constructor is not exposed in the
+  // interface.
+  AssertionResult(const AssertionResult& other);
+
+#if defined(GTEST_VERSION_1_8_AND_LATER)
+  template <typename T>
+  explicit AssertionResult(
+      const T& success,
+      typename internal::EnableIf<
+          !internal::ImplicitlyConvertible<T, AssertionResult>::value>::type*
+          /*enabler*/ = 0)
+      : success_(success) {}
+#else
+  explicit AssertionResult(bool success) : success_(success) {}
+#endif
+
+  operator bool() const { return success_; }
+
+  // The actual AssertionResult does not have an explicit destructor, but
+  // it does have a non-trivial member veriable, so we add a destructor here
+  // to force temporary cleanups.
+  ~AssertionResult();
+private:
+
+  bool success_;
+};
+
+namespace internal {
+std::string GetBoolAssertionFailureMessage(
+    const AssertionResult& assertion_result,
+    const char* expression_text,
+    const char* actual_predicate_value,
+    const char* expected_predicate_value);
+} // end internal
+
+} // end testing
+
+#define GTEST_MESSAGE_AT_(file, line, message, result_type) \
+  ::testing::internal::AssertHelper(result_type, file, line, message) \
+    = ::testing::Message()
+
+#define GTEST_MESSAGE_(message, result_type) \
+  GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
+
+#define GTEST_FATAL_FAILURE_(message) \
+  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
+
+#define GTEST_NONFATAL_FAILURE_(message) \
+  GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
+
+# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default:
+
+#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const ::testing::AssertionResult gtest_ar_ = \
+      ::testing::AssertionResult(expression)) \
+    ; \
+  else \
+    fail(::testing::internal::GetBoolAssertionFailureMessage(\
+        gtest_ar_, text, #actual, #expected).c_str())
+
+#define EXPECT_TRUE(condition) \
+  GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
+                      GTEST_NONFATAL_FAILURE_)
+#define ASSERT_TRUE(condition) \
+  GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
+                      GTEST_FATAL_FAILURE_)
+
+#define ASSERT_FALSE(condition) \
+  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
+                      GTEST_FATAL_FAILURE_)
+
+void testAssertTrue(int *p) {
+  ASSERT_TRUE(p != nullptr);
+  EXPECT_TRUE(1 == *p); // no-warning
+}
+
+void testAssertFalse(int *p) {
+  ASSERT_FALSE(p == nullptr);
+  EXPECT_TRUE(1 == *p); // no-warning
+}
+
+void testConstrainState(int p) {
+  ASSERT_TRUE(p == 7);
+
+  clang_analyzer_eval(p == 7); // expected-warning {{TRUE}}
+
+  ASSERT_TRUE(false);
+  clang_analyzer_warnIfReached(); // no-warning
+}
diff --git a/test/Analysis/html-diags-multifile.c b/test/Analysis/html-diags-multifile.c
index bb76928..ce1f72b 100644
--- a/test/Analysis/html-diags-multifile.c
+++ b/test/Analysis/html-diags-multifile.c
@@ -1,5 +1,5 @@
 // RUN: mkdir -p %t.dir
-// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %t.dir %s
+// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o %t.dir %s
 // RUN: ls %t.dir | not grep report
 // RUN: rm -fR %t.dir
 
diff --git a/test/Analysis/html-diags.c b/test/Analysis/html-diags.c
index e998020..182bcfb 100644
--- a/test/Analysis/html-diags.c
+++ b/test/Analysis/html-diags.c
@@ -1,11 +1,11 @@
 // RUN: rm -fR %T/dir
 // RUN: mkdir %T/dir
-// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %T/dir %s
+// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o %T/dir %s
 // RUN: ls %T/dir | grep report
 
 // PR16547: Test relative paths
 // RUN: cd %T/dir
-// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o testrelative %s
+// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o testrelative %s
 // RUN: ls %T/dir/testrelative | grep report
 
 // Currently this test mainly checks that the HTML diagnostics doesn't crash
diff --git a/test/Analysis/identical-expressions.cpp b/test/Analysis/identical-expressions.cpp
index 138cd7c..8bb8237 100644
--- a/test/Analysis/identical-expressions.cpp
+++ b/test/Analysis/identical-expressions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.IdenticalExpr -w -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.IdenticalExpr -w -verify %s
 
 /* Only one expected warning per function allowed at the very end. */
 
diff --git a/test/Analysis/index-type.c b/test/Analysis/index-type.c
index fc638df..b86913b 100644
--- a/test/Analysis/index-type.c
+++ b/test/Analysis/index-type.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2 -verify %s
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2 -DM32 -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -DM32 -verify %s
 // expected-no-diagnostics
 
 #define UINT_MAX (~0u)
diff --git a/test/Analysis/initializer.cpp b/test/Analysis/initializer.cpp
index b31c315..c736356 100644
--- a/test/Analysis/initializer.cpp
+++ b/test/Analysis/initializer.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
 
 void clang_analyzer_eval(bool);
 
@@ -197,3 +197,10 @@
   }
 
 };
+
+namespace PR31592 {
+struct C {
+   C() : f("}") { } // no-crash
+   const char(&f)[2];
+};
+}
diff --git a/test/Analysis/initializers-cfg-output.cpp b/test/Analysis/initializers-cfg-output.cpp
index deefbef..ccf4db5 100644
--- a/test/Analysis/initializers-cfg-output.cpp
+++ b/test/Analysis/initializers-cfg-output.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
 
 class A {
 public:
diff --git a/test/Analysis/inline-not-supported.c b/test/Analysis/inline-not-supported.c
index 756d5d8..c5f4c74 100644
--- a/test/Analysis/inline-not-supported.c
+++ b/test/Analysis/inline-not-supported.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core -verify %s
 
 // For now, don't inline varargs.
 void foo(int *x, ...) {
diff --git a/test/Analysis/inline-plist.c b/test/Analysis/inline-plist.c
index bccf219..441bb48 100644
--- a/test/Analysis/inline-plist.c
+++ b/test/Analysis/inline-plist.c
@@ -1,5 +1,5 @@
-// RUN: %clang --analyze %s -fblocks -Xanalyzer -analyzer-output=text -Xanalyzer -analyzer-config -Xanalyzer suppress-null-return-paths=false -Xclang -verify %s
-// RUN: %clang --analyze %s -fblocks -Xanalyzer -analyzer-config -Xanalyzer suppress-null-return-paths=false -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -o %t
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference,core.DivideZero -fblocks -analyzer-output=text -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference,core.DivideZero -fblocks -analyzer-output=plist -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false -o %t
 // RUN: FileCheck -input-file %t %s
 
 // <rdar://problem/10967815>
@@ -41,7 +41,7 @@
     // expected-note@-2 {{Taking false branch}}
     return;
   }
-  
+
   if (p == 0) {
     // expected-note@-1 {{Taking true branch}}
     triggers_bug(p);
@@ -59,7 +59,7 @@
   ^(){ // expected-note {{Calling anonymous block}}
     *p = 1; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}} expected-note{{Dereference of null pointer (loaded from variable 'p')}}
   }();
-  
+
 }
 
 void test_block_ret() {
@@ -550,12 +550,12 @@
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>39</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>39</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -567,7 +567,7 @@
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
 // CHECK-NEXT:       <key>line</key><integer>39</integer>
-// CHECK-NEXT:       <key>col</key><integer>8</integer>
+// CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:      <key>ranges</key>
@@ -575,7 +575,7 @@
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>39</integer>
-// CHECK-NEXT:          <key>col</key><integer>8</integer>
+// CHECK-NEXT:          <key>col</key><integer>7</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
@@ -600,12 +600,12 @@
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>39</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>39</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
diff --git a/test/Analysis/inline-unique-reports.c b/test/Analysis/inline-unique-reports.c
index 4b3c2fe..f827f88 100644
--- a/test/Analysis/inline-unique-reports.c
+++ b/test/Analysis/inline-unique-reports.c
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -o %t > /dev/null 2>&1
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t > /dev/null 2>&1
 // RUN: FileCheck -input-file %t %s
 
 static inline bug(int *p) {
diff --git a/test/Analysis/inline.c b/test/Analysis/inline.c
index 03c4ea8..8fce0fb 100644
--- a/test/Analysis/inline.c
+++ b/test/Analysis/inline.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_checkInlined(int);
diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp
index 9fc4f81..76eee5b 100644
--- a/test/Analysis/inline.cpp
+++ b/test/Analysis/inline.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
diff --git a/test/Analysis/inline2.c b/test/Analysis/inline2.c
index bae7434..39e6d16 100644
--- a/test/Analysis/inline2.c
+++ b/test/Analysis/inline2.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 
 // Test parameter 'a' is registered to LiveVariables analysis data although it
diff --git a/test/Analysis/inline3.c b/test/Analysis/inline3.c
index e7f4775..2c70fb2 100644
--- a/test/Analysis/inline3.c
+++ b/test/Analysis/inline3.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 
 // Test when entering f1(), we set the right AnalysisDeclContext to Environment.
diff --git a/test/Analysis/inline4.c b/test/Analysis/inline4.c
index 71a379a..a1aac1d 100644
--- a/test/Analysis/inline4.c
+++ b/test/Analysis/inline4.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 
 int g(int a) {    
diff --git a/test/Analysis/inlining/DynDispatchBifurcate.m b/test/Analysis/inlining/DynDispatchBifurcate.m
index 0ce0796..a41a5e3 100644
--- a/test/Analysis/inlining/DynDispatchBifurcate.m
+++ b/test/Analysis/inlining/DynDispatchBifurcate.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 #include "InlineObjCInstanceMethod.h"
 
diff --git a/test/Analysis/inlining/InlineObjCClassMethod.m b/test/Analysis/inlining/InlineObjCClassMethod.m
index c9cc90b..bb869c5 100644
--- a/test/Analysis/inlining/InlineObjCClassMethod.m
+++ b/test/Analysis/inlining/InlineObjCClassMethod.m
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 void clang_analyzer_checkInlined(int);
+void clang_analyzer_eval(int);
 
 // Test inlining of ObjC class methods.
 
@@ -194,7 +195,9 @@
 @implementation SelfUsedInParent
 + (int)getNum {return 5;}
 + (int)foo {
-  return [self getNum];
+  int r = [self getNum];
+  clang_analyzer_eval(r == 5); // expected-warning{{TRUE}}
+  return r;
 }
 @end
 @interface SelfUsedInParentChild : SelfUsedInParent
@@ -229,8 +232,80 @@
 + (void)forwardDeclaredVariadicMethod:(int)x, ... {
   clang_analyzer_checkInlined(0); // no-warning
 }
-
 @end
 
+@interface SelfClassTestParent : NSObject
+-(unsigned)returns10;
++(unsigned)returns20;
++(unsigned)returns30;
+@end
 
+@implementation SelfClassTestParent
+-(unsigned)returns10 { return 100; }
++(unsigned)returns20 { return 100; }
++(unsigned)returns30 { return 100; }
+@end
 
+@interface SelfClassTest : SelfClassTestParent
+-(unsigned)returns10;
++(unsigned)returns20;
++(unsigned)returns30;
+@end
+
+@implementation SelfClassTest
+-(unsigned)returns10 { return 10; }
++(unsigned)returns20 { return 20; }
++(unsigned)returns30 { return 30; }
++(void)classMethod {
+  unsigned result1 = [self returns20];
+  clang_analyzer_eval(result1 == 20); // expected-warning{{TRUE}}
+  unsigned result2 = [[self class] returns30];
+  clang_analyzer_eval(result2 == 30); // expected-warning{{TRUE}}
+  unsigned result3 = [[super class] returns30];
+  clang_analyzer_eval(result3 == 100); // expected-warning{{UNKNOWN}}
+}
+-(void)instanceMethod {
+  unsigned result0 = [self returns10];
+  clang_analyzer_eval(result0 == 10); // expected-warning{{TRUE}}
+  unsigned result2 = [[self class] returns30];
+  clang_analyzer_eval(result2 == 30); // expected-warning{{TRUE}}
+  unsigned result3 = [[super class] returns30];
+  clang_analyzer_eval(result3 == 100); // expected-warning{{UNKNOWN}}
+}
+@end
+
+@interface Parent : NSObject
++ (int)a;
++ (int)b;
+@end
+@interface Child : Parent
+@end
+@interface Other : NSObject
++(void)run;
+@end
+int main(int argc, const char * argv[]) {
+  @autoreleasepool {
+    [Other run];
+  }
+  return 0;
+}
+@implementation Other
++(void)run {
+  int result = [Child a];
+  // TODO: This should return 100.
+  clang_analyzer_eval(result == 12); // expected-warning{{TRUE}}
+}
+@end
+@implementation Parent
++ (int)a; {
+  return [self b];
+}
++ (int)b; {
+  return 12;
+}
+@end
+@implementation Child
++ (int)b; {
+  return 100;
+}
+@end
diff --git a/test/Analysis/inlining/InlineObjCInstanceMethod.m b/test/Analysis/inlining/InlineObjCInstanceMethod.m
index f6aa50a..4578a55 100644
--- a/test/Analysis/inlining/InlineObjCInstanceMethod.m
+++ b/test/Analysis/inlining/InlineObjCInstanceMethod.m
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze -Xanalyzer -analyzer-checker=osx.cocoa.IncompatibleMethodTypes,osx.coreFoundation.CFRetainRelease -Xclang -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.DivideZero,core.DynamicTypePropagation,osx.cocoa.IncompatibleMethodTypes -w -verify %s
 
 #include "InlineObjCInstanceMethod.h"
 
diff --git a/test/Analysis/inlining/ObjCDynTypePopagation.m b/test/Analysis/inlining/ObjCDynTypePopagation.m
index ccc2471..0c1d4f2 100644
--- a/test/Analysis/inlining/ObjCDynTypePopagation.m
+++ b/test/Analysis/inlining/ObjCDynTypePopagation.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 #include "InlineObjCInstanceMethod.h"
 
diff --git a/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m b/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m
index 06b271a..d787c7e 100644
--- a/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m
+++ b/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 typedef signed char BOOL;
 @protocol NSObject  - (BOOL)isEqual:(id)object; @end
diff --git a/test/Analysis/inlining/RetainCountExamples.m b/test/Analysis/inlining/RetainCountExamples.m
index 41479af..938d3e2 100644
--- a/test/Analysis/inlining/RetainCountExamples.m
+++ b/test/Analysis/inlining/RetainCountExamples.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 typedef signed char BOOL;
 typedef struct objc_class *Class;
diff --git a/test/Analysis/inlining/analysis-order.c b/test/Analysis/inlining/analysis-order.c
index 5149818..620732c 100644
--- a/test/Analysis/inlining/analysis-order.c
+++ b/test/Analysis/inlining/analysis-order.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core.builtin.NoReturnFunctions -analyzer-display-progress %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.builtin.NoReturnFunctions -analyzer-display-progress %s 2>&1 | FileCheck %s
 
 // Do not analyze test1() again because it was inlined
 void test1();
diff --git a/test/Analysis/inlining/assume-super-init-does-not-return-nil.m b/test/Analysis/inlining/assume-super-init-does-not-return-nil.m
index fba3e2d..be46776 100644
--- a/test/Analysis/inlining/assume-super-init-does-not-return-nil.m
+++ b/test/Analysis/inlining/assume-super-init-does-not-return-nil.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -verify %s
 
 typedef signed char BOOL;
 
diff --git a/test/Analysis/inlining/containers.cpp b/test/Analysis/inlining/containers.cpp
index c757da6..16e006b 100644
--- a/test/Analysis/inlining/containers.cpp
+++ b/test/Analysis/inlining/containers.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=false -verify %s
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=true -DINLINE=1 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=false -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=true -DINLINE=1 -verify %s
 
 #ifndef HEADER
 
diff --git a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
index e23d4e2..0208483 100644
--- a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
+++ b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify -Wno-reinterpret-base-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify -Wno-reinterpret-base-class %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.c b/test/Analysis/inlining/eager-reclamation-path-notes.c
index cd16eb3..7c0f0ec 100644
--- a/test/Analysis/inlining/eager-reclamation-path-notes.c
+++ b/test/Analysis/inlining/eager-reclamation-path-notes.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void use(int *ptr, int val) {
diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.cpp b/test/Analysis/inlining/eager-reclamation-path-notes.cpp
index 8d5e85a..f77a19f 100644
--- a/test/Analysis/inlining/eager-reclamation-path-notes.cpp
+++ b/test/Analysis/inlining/eager-reclamation-path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 typedef struct {
diff --git a/test/Analysis/inlining/false-positive-suppression.c b/test/Analysis/inlining/false-positive-suppression.c
index a0bc361..4931695 100644
--- a/test/Analysis/inlining/false-positive-suppression.c
+++ b/test/Analysis/inlining/false-positive-suppression.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-eagerly-assume -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-eagerly-assume -analyzer-checker=core -verify -DSUPPRESSED=1 %s
-// RUN: %clang_cc1 -analyze -analyzer-eagerly-assume -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-eagerly-assume -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-eagerly-assume -analyzer-checker=core -verify -DSUPPRESSED=1 %s
+// RUN: %clang_analyze_cc1 -analyzer-eagerly-assume -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
 
 int opaquePropertyCheck(void *object);
 int coin();
diff --git a/test/Analysis/inlining/false-positive-suppression.cpp b/test/Analysis/inlining/false-positive-suppression.cpp
index bff6907..56659b4 100644
--- a/test/Analysis/inlining/false-positive-suppression.cpp
+++ b/test/Analysis/inlining/false-positive-suppression.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -DSUPPRESSED=1 %s
 
 namespace rdar12676053 {
   // Delta-reduced from a preprocessed file.
diff --git a/test/Analysis/inlining/false-positive-suppression.m b/test/Analysis/inlining/false-positive-suppression.m
index 685e29e..f3532e5 100644
--- a/test/Analysis/inlining/false-positive-suppression.m
+++ b/test/Analysis/inlining/false-positive-suppression.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -fobjc-arc -verify -DSUPPRESSED=1 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -DSUPPRESSED=1 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -fobjc-arc -verify -DSUPPRESSED=1 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
 
 #define ARC __has_feature(objc_arc)
 
diff --git a/test/Analysis/inlining/inline-defensive-checks.c b/test/Analysis/inlining/inline-defensive-checks.c
index 4ce783c..4029da6 100644
--- a/test/Analysis/inlining/inline-defensive-checks.c
+++ b/test/Analysis/inlining/inline-defensive-checks.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
 
 // Perform inline defensive checks.
 void idc(int *p) {
diff --git a/test/Analysis/inlining/inline-defensive-checks.cpp b/test/Analysis/inlining/inline-defensive-checks.cpp
index b69c535..6a803fa 100644
--- a/test/Analysis/inlining/inline-defensive-checks.cpp
+++ b/test/Analysis/inlining/inline-defensive-checks.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 
 extern void __assert_fail (__const char *__assertion, __const char *__file,
diff --git a/test/Analysis/inlining/inline-defensive-checks.m b/test/Analysis/inlining/inline-defensive-checks.m
index 0404ee6..38e5446 100644
--- a/test/Analysis/inlining/inline-defensive-checks.m
+++ b/test/Analysis/inlining/inline-defensive-checks.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
 
 typedef signed char BOOL;
 typedef struct objc_class *Class;
diff --git a/test/Analysis/inlining/path-notes.c b/test/Analysis/inlining/path-notes.c
index 403d33d..95adee3 100644
--- a/test/Analysis/inlining/path-notes.c
+++ b/test/Analysis/inlining/path-notes.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void zero(int **p) {
diff --git a/test/Analysis/inlining/path-notes.cpp b/test/Analysis/inlining/path-notes.cpp
index 2d6886f..4d0b899 100644
--- a/test/Analysis/inlining/path-notes.cpp
+++ b/test/Analysis/inlining/path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-tautological-undefined-compare %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist -Wno-tautological-undefined-compare
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-tautological-undefined-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist -Wno-tautological-undefined-compare
 // RUN: FileCheck --input-file=%t.plist %s
 
 class Foo {
diff --git a/test/Analysis/inlining/path-notes.m b/test/Analysis/inlining/path-notes.m
index 264f0db..7f60ff8 100644
--- a/test/Analysis/inlining/path-notes.m
+++ b/test/Analysis/inlining/path-notes.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=text -analyzer-config suppress-null-return-paths=false -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false -fblocks %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=text -analyzer-config suppress-null-return-paths=false -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false -fblocks %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 typedef struct dispatch_queue_s *dispatch_queue_t;
@@ -160,7 +160,7 @@
   dispatch_once(&token, ^{});
 
   id x = [[[[NSObject alloc] init] autorelease] autorelease];
-  // expected-note@-1 {{Method returns an Objective-C object with a +1 retain count}}
+  // expected-note@-1 {{Method returns an instance of NSObject with a +1 retain count}}
   // expected-note@-2 {{Object autoreleased}}
   // expected-note@-3 {{Object autoreleased}}
 
@@ -1840,9 +1840,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
diff --git a/test/Analysis/inlining/retain-count-self-init.m b/test/Analysis/inlining/retain-count-self-init.m
index 97379db..2081973 100644
--- a/test/Analysis/inlining/retain-count-self-init.m
+++ b/test/Analysis/inlining/retain-count-self-init.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.SelfInit -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.SelfInit -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 typedef signed char BOOL;
 typedef struct objc_class *Class;
diff --git a/test/Analysis/inlining/stl.cpp b/test/Analysis/inlining/stl.cpp
index 95ac3f8..b672be2 100644
--- a/test/Analysis/inlining/stl.cpp
+++ b/test/Analysis/inlining/stl.cpp
@@ -1,13 +1,12 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -std=c++11 -DINLINE=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -std=c++11 -DINLINE=1 -verify %s
 
 #include "../Inputs/system-header-simulator-cxx.h"
 
 void clang_analyzer_eval(bool);
 
 void testVector(std::vector<int> &nums) {
-  if (nums.begin()) return;
-  if (nums.end()) return;
+  if (nums.begin() != nums.end()) return;
   
   clang_analyzer_eval(nums.size() == 0);
 #if INLINE
diff --git a/test/Analysis/inlining/test-always-inline-size-option.c b/test/Analysis/inlining/test-always-inline-size-option.c
index 6b3c13d..85fc8a1 100644
--- a/test/Analysis/inlining/test-always-inline-size-option.c
+++ b/test/Analysis/inlining/test-always-inline-size-option.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-inline-max-stack-depth=3 -analyzer-config ipa-always-inline-size=3 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-inline-max-stack-depth=3 -analyzer-config ipa-always-inline-size=3 -verify %s
 
 void clang_analyzer_eval(int);
 int nested5() {
diff --git a/test/Analysis/inlining/test_objc_inlining_option.m b/test/Analysis/inlining/test_objc_inlining_option.m
index 61408c1..f3a9417 100644
--- a/test/Analysis/inlining/test_objc_inlining_option.m
+++ b/test/Analysis/inlining/test_objc_inlining_option.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config ipa=dynamic-bifurcate -analyzer-config objc-inlining=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config ipa=dynamic-bifurcate -analyzer-config objc-inlining=false -verify %s
 // expected-no-diagnostics
 
 typedef signed char BOOL;
diff --git a/test/Analysis/iterator-past-end.cpp b/test/Analysis/iterator-past-end.cpp
new file mode 100644
index 0000000..252d104
--- /dev/null
+++ b/test/Analysis/iterator-past-end.cpp
@@ -0,0 +1,205 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorPastEnd -analyzer-eagerly-assume -analyzer-config c++-container-inlining=false %s -verify
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorPastEnd -analyzer-eagerly-assume -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+void simple_good(const std::vector<int> &v) {
+  auto i = v.end();
+  if (i != v.end())
+    *i; // no-warning
+}
+
+void simple_good_negated(const std::vector<int> &v) {
+  auto i = v.end();
+  if (!(i == v.end()))
+    *i; // no-warning
+}
+
+void simple_bad(const std::vector<int> &v) {
+  auto i = v.end();
+  *i; // expected-warning{{Iterator accessed past its end}}
+}
+
+void copy(const std::vector<int> &v) {
+  auto i1 = v.end();
+  auto i2 = i1;
+  *i2; // expected-warning{{Iterator accessed past its end}}
+}
+
+void decrease(const std::vector<int> &v) {
+  auto i = v.end();
+  --i;
+  *i; // no-warning
+}
+
+void copy_and_decrease1(const std::vector<int> &v) {
+  auto i1 = v.end();
+  auto i2 = i1;
+  --i1;
+  *i1; // no-warning
+}
+
+void copy_and_decrease2(const std::vector<int> &v) {
+  auto i1 = v.end();
+  auto i2 = i1;
+  --i1;
+  *i2; // expected-warning{{Iterator accessed past its end}}
+}
+
+void copy_and_increase1(const std::vector<int> &v) {
+  auto i1 = v.begin();
+  auto i2 = i1;
+  ++i1;
+  if (i1 == v.end())
+    *i2; // no-warning
+}
+
+void copy_and_increase2(const std::vector<int> &v) {
+  auto i1 = v.begin();
+  auto i2 = i1;
+  ++i1;
+  if (i2 == v.end())
+    *i2; // expected-warning{{Iterator accessed past its end}}
+}
+
+void good_find(std::vector<int> &vec, int e) {
+  auto first = std::find(vec.begin(), vec.end(), e);
+  if (vec.end() != first)
+    *first; // no-warning
+}
+
+void bad_find(std::vector<int> &vec, int e) {
+  auto first = std::find(vec.begin(), vec.end(), e);
+  *first; // expected-warning{{Iterator accessed past its end}}
+}
+
+void good_find_end(std::vector<int> &vec, std::vector<int> &seq) {
+  auto last = std::find_end(vec.begin(), vec.end(), seq.begin(), seq.end());
+  if (vec.end() != last)
+    *last; // no-warning
+}
+
+void bad_find_end(std::vector<int> &vec, std::vector<int> &seq) {
+  auto last = std::find_end(vec.begin(), vec.end(), seq.begin(), seq.end());
+  *last; // expected-warning{{Iterator accessed past its end}}
+}
+
+void good_find_first_of(std::vector<int> &vec, std::vector<int> &seq) {
+  auto first =
+      std::find_first_of(vec.begin(), vec.end(), seq.begin(), seq.end());
+  if (vec.end() != first)
+    *first; // no-warning
+}
+
+void bad_find_first_of(std::vector<int> &vec, std::vector<int> &seq) {
+  auto first = std::find_end(vec.begin(), vec.end(), seq.begin(), seq.end());
+  *first; // expected-warning{{Iterator accessed past its end}}
+}
+
+bool odd(int i) { return i % 2; }
+
+void good_find_if(std::vector<int> &vec) {
+  auto first = std::find_if(vec.begin(), vec.end(), odd);
+  if (vec.end() != first)
+    *first; // no-warning
+}
+
+void bad_find_if(std::vector<int> &vec, int e) {
+  auto first = std::find_if(vec.begin(), vec.end(), odd);
+  *first; // expected-warning{{Iterator accessed past its end}}
+}
+
+void good_find_if_not(std::vector<int> &vec) {
+  auto first = std::find_if_not(vec.begin(), vec.end(), odd);
+  if (vec.end() != first)
+    *first; // no-warning
+}
+
+void bad_find_if_not(std::vector<int> &vec, int e) {
+  auto first = std::find_if_not(vec.begin(), vec.end(), odd);
+  *first; // expected-warning{{Iterator accessed past its end}}
+}
+
+void good_lower_bound(std::vector<int> &vec, int e) {
+  auto first = std::lower_bound(vec.begin(), vec.end(), e);
+  if (vec.end() != first)
+    *first; // no-warning
+}
+
+void bad_lower_bound(std::vector<int> &vec, int e) {
+  auto first = std::lower_bound(vec.begin(), vec.end(), e);
+  *first; // expected-warning{{Iterator accessed past its end}}
+}
+
+void good_upper_bound(std::vector<int> &vec, int e) {
+  auto last = std::lower_bound(vec.begin(), vec.end(), e);
+  if (vec.end() != last)
+    *last; // no-warning
+}
+
+void bad_upper_bound(std::vector<int> &vec, int e) {
+  auto last = std::lower_bound(vec.begin(), vec.end(), e);
+  *last; // expected-warning{{Iterator accessed past its end}}
+}
+
+void good_search(std::vector<int> &vec, std::vector<int> &seq) {
+  auto first = std::search(vec.begin(), vec.end(), seq.begin(), seq.end());
+  if (vec.end() != first)
+    *first; // no-warning
+}
+
+void bad_search(std::vector<int> &vec, std::vector<int> &seq) {
+  auto first = std::search(vec.begin(), vec.end(), seq.begin(), seq.end());
+  *first; // expected-warning{{Iterator accessed past its end}}
+}
+
+void good_search_n(std::vector<int> &vec, std::vector<int> &seq) {
+  auto nth = std::search_n(vec.begin(), vec.end(), seq.begin(), seq.end());
+  if (vec.end() != nth)
+    *nth; // no-warning
+}
+
+void bad_search_n(std::vector<int> &vec, std::vector<int> &seq) {
+  auto nth = std::search_n(vec.begin(), vec.end(), seq.begin(), seq.end());
+  *nth; // expected-warning{{Iterator accessed past its end}}
+}
+
+template <class InputIterator, class T>
+InputIterator nonStdFind(InputIterator first, InputIterator last,
+                         const T &val) {
+  for (auto i = first; i != last; ++i) {
+    if (*i == val) {
+      return i;
+    }
+  }
+  return last;
+}
+
+void good_non_std_find(std::vector<int> &vec, int e) {
+  auto first = nonStdFind(vec.begin(), vec.end(), e);
+  if (vec.end() != first)
+    *first; // no-warning
+}
+
+void bad_non_std_find(std::vector<int> &vec, int e) {
+  auto first = nonStdFind(vec.begin(), vec.end(), e);
+  *first; // expected-warning{{Iterator accessed past its end}}
+}
+
+void tricky(std::vector<int> &vec, int e) {
+  const auto first = vec.begin();
+  const auto comp1 = (first != vec.end()), comp2 = (first == vec.end());
+  if (comp1)
+    *first;
+}
+
+void loop(std::vector<int> &vec, int e) {
+  auto start = vec.begin();
+  while (true) {
+    auto item = std::find(start, vec.end(), e);
+    if (item == vec.end())
+      break;
+    *item;          // no-warning
+    start = ++item; // no-warning
+  }
+}
diff --git a/test/Analysis/ivars.m b/test/Analysis/ivars.m
index c717da6..11514d2 100644
--- a/test/Analysis/ivars.m
+++ b/test/Analysis/ivars.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/keychainAPI-diagnostic-visitor.m b/test/Analysis/keychainAPI-diagnostic-visitor.m
index a78b114..d8da697 100644
--- a/test/Analysis/keychainAPI-diagnostic-visitor.m
+++ b/test/Analysis/keychainAPI-diagnostic-visitor.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=osx.SecKeychainAPI -analyzer-store=region -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=osx.SecKeychainAPI -analyzer-store=region -analyzer-output=text -verify %s
 
 // This file is for testing enhanced diagnostics produced by the default SecKeychainAPI checker.
 
diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m
index 4fc48c0..1725ce1 100644
--- a/test/Analysis/keychainAPI.m
+++ b/test/Analysis/keychainAPI.m
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.SecKeychainAPI -fblocks %s -verify
+
+#include "Inputs/system-header-simulator-objc.h"
 
 // Fake typedefs.
 typedef unsigned int OSStatus;
@@ -6,8 +8,6 @@
 typedef unsigned int SecKeychainItemRef;
 typedef unsigned int SecItemClass;
 typedef unsigned int UInt32;
-typedef unsigned int CFTypeRef;
-typedef unsigned int UInt16;
 typedef unsigned int SecProtocolType;
 typedef unsigned int SecAuthenticationType;
 typedef unsigned int SecKeychainAttributeInfo;
@@ -77,7 +77,7 @@
   void *outData;
   st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
   if (st == GenericError)
-    SecKeychainItemFreeContent(ptr, outData); // expected-warning{{Only call free if a valid (non-NULL) buffer was returned}}
+    SecKeychainItemFreeContent(ptr, outData);
 } // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
 
 // If null is passed in, the data is not allocated, so no need for the matching free.
@@ -101,14 +101,6 @@
       SecKeychainItemFreeContent(ptr, outData);
 }
 
-void fooOnlyFree() {
-  unsigned int *ptr = 0;
-  OSStatus st = 0;
-  UInt32 length;
-  void *outData = &length;
-  SecKeychainItemFreeContent(ptr, outData);// expected-warning{{Trying to free data which has not been allocated}}
-}
-
 // Do not warn if undefined value is passed to a function.
 void fooOnlyFreeUndef() {
   unsigned int *ptr = 0;
@@ -220,11 +212,27 @@
     if (st == noErr)
       SecKeychainItemFreeContent(ptr, outData[3]);
   }
-  if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
+  if (length) { // TODO: We do not report a warning here since the symbol is no longer live, but it's not marked as dead.
     length++;
   }
   return 0;
-}// no-warning
+}
+
+int testErrorCodeAsLHS(CFTypeRef keychainOrArray, SecProtocolType protocol,
+        SecAuthenticationType authenticationType, SecKeychainItemRef *itemRef) {
+  unsigned int *ptr = 0;
+  OSStatus st = 0;
+  UInt32 length;
+  void *outData;
+  st = SecKeychainFindInternetPassword(keychainOrArray,
+                                       16, "server", 16, "domain", 16, "account",
+                                       16, "path", 222, protocol, authenticationType,
+                                       &length, &outData, itemRef);
+  if (noErr == st)
+    SecKeychainItemFreeContent(ptr, outData);
+
+  return 0;
+}
 
 void free(void *ptr);
 void deallocateWithFree() {
@@ -251,7 +259,6 @@
 extern const CFAllocatorRef kCFAllocatorNull;
 extern const CFAllocatorRef kCFAllocatorUseContext;
 CFStringRef CFStringCreateWithBytesNoCopy(CFAllocatorRef alloc, const uint8_t *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean externalFormat, CFAllocatorRef contentsDeallocator);
-extern void CFRelease(CFStringRef cf);
 
 void DellocWithCFStringCreate1(CFAllocatorRef alloc) {
   unsigned int *ptr = 0;
@@ -333,11 +340,11 @@
     SecKeychainItemFreeContent(0, pwdBytes);
 }
 
-void radar10508828_2() {
+void radar10508828_20092614() {
   UInt32 pwdLen = 0;
   void*  pwdBytes = 0;
   OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0);
-  SecKeychainItemFreeContent(0, pwdBytes); // expected-warning {{Only call free if a valid (non-NULL) buffer was returned}}
+  SecKeychainItemFreeContent(0, pwdBytes);
 }
 
 //Example from bug 10797.
@@ -426,3 +433,24 @@
       SecKeychainItemFreeContent(attrList, outData);
 }
 
+typedef struct AuthorizationValue {
+    int length;
+    void *data;
+} AuthorizationValue;
+typedef struct AuthorizationCallback {
+    OSStatus (*SetContextVal)(AuthorizationValue *inValue);
+} AuthorizationCallback;
+static AuthorizationCallback cb;
+int radar_19196494() {
+  @autoreleasepool {
+    AuthorizationValue login_password = {};
+    UInt32 passwordLength;
+    void *passwordData = 0;
+    OSStatus err = SecKeychainFindGenericPassword(0, 0, "", 0, "", (UInt32 *)&login_password.length, (void**)&login_password.data, 0);
+    cb.SetContextVal(&login_password);
+    if (err == noErr) {
+      SecKeychainItemFreeContent(0, login_password.data);
+    }
+  }
+  return 0;
+}
diff --git a/test/Analysis/kmalloc-linux.c b/test/Analysis/kmalloc-linux.c
index 87c1107..bac7138 100644
--- a/test/Analysis/kmalloc-linux.c
+++ b/test/Analysis/kmalloc-linux.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-unknown-linux --analyze %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux %s
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/lambda-notes.cpp b/test/Analysis/lambda-notes.cpp
index 661fd05..7abff35 100644
--- a/test/Analysis/lambda-notes.cpp
+++ b/test/Analysis/lambda-notes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core -analyzer-config inline-lambdas=true -analyzer-output plist -verify %s -o %t
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core.DivideZero -analyzer-config inline-lambdas=true -analyzer-output plist -verify %s -o %t
 // RUN: FileCheck --input-file=%t %s
 
 
diff --git a/test/Analysis/lambdas-generalized-capture.cpp b/test/Analysis/lambdas-generalized-capture.cpp
index 790e15e..feaf55d 100644
--- a/test/Analysis/lambdas-generalized-capture.cpp
+++ b/test/Analysis/lambdas-generalized-capture.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -fsyntax-only -analyze -analyzer-checker=core,deadcode,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,deadcode,debug.ExprInspection -verify %s
 
 int clang_analyzer_eval(int);
 
diff --git a/test/Analysis/lambdas.cpp b/test/Analysis/lambdas.cpp
index 0b66e6b..f3ff9b9 100644
--- a/test/Analysis/lambdas.cpp
+++ b/test/Analysis/lambdas.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core,deadcode,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core,debug.DumpCFG -analyzer-config inline-lambdas=true %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,deadcode,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.DumpCFG -analyzer-config inline-lambdas=true %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 void clang_analyzer_warnIfReached();
@@ -212,7 +212,7 @@
     callLambda([&](){ ++x; });
     callLambdaFromStatic([&](){ ++x; });
   }
-  
+
   template<typename T>
   static void callLambdaFromStatic(T t) {
     t();
diff --git a/test/Analysis/lambdas.mm b/test/Analysis/lambdas.mm
index dc1a13e..d2b8e7b 100644
--- a/test/Analysis/lambdas.mm
+++ b/test/Analysis/lambdas.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fblocks -Wno-objc-root-class -analyze -analyzer-checker=core,deadcode,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -Wno-objc-root-class -analyzer-checker=core,deadcode,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s
 
 int clang_analyzer_eval(int);
 
diff --git a/test/Analysis/lifetime-extension.cpp b/test/Analysis/lifetime-extension.cpp
index 124eef3..5e3c5dd 100644
--- a/test/Analysis/lifetime-extension.cpp
+++ b/test/Analysis/lifetime-extension.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-unused -std=c++11 -analyze -analyzer-checker=debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -Wno-unused -std=c++11 -analyzer-checker=debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/lit.local.cfg b/test/Analysis/lit.local.cfg
index da2a68b..acae2bd 100644
--- a/test/Analysis/lit.local.cfg
+++ b/test/Analysis/lit.local.cfg
@@ -1,2 +1,30 @@
-if config.root.clang_staticanalyzer == 0:
+import lit.TestRunner
+import sys
+
+# Custom format class for static analyzer tests
+class AnalyzerTest(lit.formats.ShTest, object):
+
+    def execute(self, test, litConfig):
+        result = self.executeWithAnalyzeSubstitution(test, litConfig, '-analyzer-constraints=range')
+
+        if result.code == lit.Test.FAIL:
+            return result
+
+        return result
+
+    def executeWithAnalyzeSubstitution(self, test, litConfig, substitution):
+        saved_substitutions = list(test.config.substitutions)
+        test.config.substitutions.append(('%analyze', substitution))
+        result = lit.TestRunner.executeShTest(test, litConfig, self.execute_external)
+        test.config.substitutions = saved_substitutions
+
+        return result
+
+# This results in a pickling-related failure on Windows
+if (not sys.platform in ['win32']):
+    config.test_format = AnalyzerTest(config.test_format.execute_external)
+else:
+    config.substitutions.append(('%analyze', '-analyzer-constraints=range'))
+
+if not config.root.clang_staticanalyzer:
     config.unsupported = True
diff --git a/test/Analysis/live-variables.cpp b/test/Analysis/live-variables.cpp
index 0cfaa1b..2c38b8b 100644
--- a/test/Analysis/live-variables.cpp
+++ b/test/Analysis/live-variables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 class B {
 public:
diff --git a/test/Analysis/live-variables.m b/test/Analysis/live-variables.m
index eefd292..d2390f3 100644
--- a/test/Analysis/live-variables.m
+++ b/test/Analysis/live-variables.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -fobjc-arc -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -fobjc-arc -verify %s
 // expected-no-diagnostics
 @interface NSObject
 @end
diff --git a/test/Analysis/localization-aggressive.m b/test/Analysis/localization-aggressive.m
index 89950d4..346cf3e 100644
--- a/test/Analysis/localization-aggressive.m
+++ b/test/Analysis/localization-aggressive.m
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fblocks -x objective-c-header -emit-pch -o %t.pch %S/Inputs/localization-pch.h
 
-// RUN: %clang_cc1 -analyze -fblocks -analyzer-store=region  -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=optin.osx.cocoa.localizability.EmptyLocalizationContextChecker -include-pch %t.pch -verify  -analyzer-config AggressiveReport=true %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-store=region  -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=optin.osx.cocoa.localizability.EmptyLocalizationContextChecker -include-pch %t.pch -verify  -analyzer-config AggressiveReport=true %s
 
 // These declarations were reduced using Delta-Debugging from Foundation.h
 // on Mac OS X.
diff --git a/test/Analysis/localization.m b/test/Analysis/localization.m
index 200eac3..3a6a0d7 100644
--- a/test/Analysis/localization.m
+++ b/test/Analysis/localization.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fblocks -analyzer-store=region -analyzer-output=text -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=alpha.osx.cocoa.localizability.PluralMisuseChecker -verify  %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-store=region -analyzer-output=text -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=alpha.osx.cocoa.localizability.PluralMisuseChecker -verify  %s
 
 // The larger set of tests in located in localization.m. These are tests
 // specific for non-aggressive reporting.
diff --git a/test/Analysis/logical-ops.c b/test/Analysis/logical-ops.c
index 0b63bc9..5530501 100644
--- a/test/Analysis/logical-ops.c
+++ b/test/Analysis/logical-ops.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-pointer-bool-conversion -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -Wno-pointer-bool-conversion -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/loop-widening.c b/test/Analysis/loop-widening.c
index 0b9bf70..de17951 100644
--- a/test/Analysis/loop-widening.c
+++ b/test/Analysis/loop-widening.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_warnIfReached();
diff --git a/test/Analysis/lvalue.cpp b/test/Analysis/lvalue.cpp
index 9a6bd59..7621139 100644
--- a/test/Analysis/lvalue.cpp
+++ b/test/Analysis/lvalue.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 int f1() {
diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c
index 3119cb7..21eaab7 100644
--- a/test/Analysis/malloc-annotations.c
+++ b/test/Analysis/malloc-annotations.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc -analyzer-store=region -verify -analyzer-config unix.Malloc:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc -analyzer-store=region -verify -analyzer-config unix.Malloc:Optimistic=true %s
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
 void free(void *);
diff --git a/test/Analysis/malloc-custom.c b/test/Analysis/malloc-custom.c
index 3c16bbd..f33b150 100644
--- a/test/Analysis/malloc-custom.c
+++ b/test/Analysis/malloc-custom.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -Wno-incompatible-library-redeclaration -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -Wno-incompatible-library-redeclaration -verify %s
 
 // Various tests to make the the analyzer is robust against custom
 // redeclarations of memory routines.
diff --git a/test/Analysis/malloc-interprocedural.c b/test/Analysis/malloc-interprocedural.c
index c78cc6c..4f7daec 100644
--- a/test/Analysis/malloc-interprocedural.c
+++ b/test/Analysis/malloc-interprocedural.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -verify %s
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/malloc-overflow.c b/test/Analysis/malloc-overflow.c
index 99e05ad..d8ad062 100644
--- a/test/Analysis/malloc-overflow.c
+++ b/test/Analysis/malloc-overflow.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.MallocOverflow -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.MallocOverflow -verify %s
 
 #define NULL ((void *) 0)
 typedef __typeof__(sizeof(int)) size_t;
diff --git a/test/Analysis/malloc-overflow.cpp b/test/Analysis/malloc-overflow.cpp
index e3a0408..e070217 100644
--- a/test/Analysis/malloc-overflow.cpp
+++ b/test/Analysis/malloc-overflow.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.MallocOverflow -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.MallocOverflow -verify %s
 // expected-no-diagnostics
 
 class A {
diff --git a/test/Analysis/malloc-overflow2.c b/test/Analysis/malloc-overflow2.c
index 83a2c02..2e1b1d4 100644
--- a/test/Analysis/malloc-overflow2.c
+++ b/test/Analysis/malloc-overflow2.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -analyze -analyzer-checker=alpha.security.MallocOverflow,unix -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -analyzer-checker=alpha.security.MallocOverflow,unix -verify %s
 
 typedef __typeof__(sizeof(int)) size_t;
 extern void *malloc(size_t);
diff --git a/test/Analysis/malloc-plist.c b/test/Analysis/malloc-plist.c
index d6c4f39..26aea16 100644
--- a/test/Analysis/malloc-plist.c
+++ b/test/Analysis/malloc-plist.c
@@ -1,5 +1,5 @@
 // RUN: rm -f %t
-// RUN: %clang_cc1 -analyze -fblocks -analyzer-checker=core,unix.Malloc -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,unix.Malloc -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
 // RUN: FileCheck -input-file %t %s
 
 typedef __typeof(sizeof(int)) size_t;
diff --git a/test/Analysis/malloc-protoype.c b/test/Analysis/malloc-protoype.c
index f056f0f..0b8c0f9 100644
--- a/test/Analysis/malloc-protoype.c
+++ b/test/Analysis/malloc-protoype.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -analyze -analyzer-checker=core,unix.Malloc -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,unix.Malloc -verify %s
 // expected-no-diagnostics
 
 // Test that strange prototypes doesn't crash the analyzer
diff --git a/test/Analysis/malloc-sizeof.c b/test/Analysis/malloc-sizeof.c
index 7a8585f..ee10424 100644
--- a/test/Analysis/malloc-sizeof.c
+++ b/test/Analysis/malloc-sizeof.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.MallocSizeof -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.MallocSizeof -verify %s
 
 #include <stddef.h>
 
diff --git a/test/Analysis/malloc-sizeof.cpp b/test/Analysis/malloc-sizeof.cpp
index 8589975..30227a9 100644
--- a/test/Analysis/malloc-sizeof.cpp
+++ b/test/Analysis/malloc-sizeof.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.MallocSizeof -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.MallocSizeof -verify %s
 
 #include <stddef.h>
 
diff --git a/test/Analysis/malloc-three-arg.c b/test/Analysis/malloc-three-arg.c
index 01b08ae..a210337 100644
--- a/test/Analysis/malloc-three-arg.c
+++ b/test/Analysis/malloc-three-arg.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-unknown-freebsd --analyze %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-freebsd %s
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 51e2cd6..d5f2cfe 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator.h"
 
@@ -1763,6 +1763,17 @@
   constEscape(&(s.x)); // could free s->p!
 } // no-warning
 
+// PR15623
+int testNoCheckerDataPropogationFromLogicalOpOperandToOpResult(void) {
+   char *param = malloc(10);
+   char *value = malloc(10);
+   int ok = (param && value);
+   free(param);
+   free(value);
+   // Previously we ended up with 'Use of memory after it is freed' on return.
+   return ok; // no warning
+}
+
 // ----------------------------------------------------------------------------
 // False negatives.
 
diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp
index f24ccf5..c323754 100644
--- a/test/Analysis/malloc.cpp
+++ b/test/Analysis/malloc.cpp
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -w -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus.NewDelete -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -w -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus.NewDelete -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus.NewDelete -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-unknown-linux-gnu -w -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus.NewDelete -analyzer-store=region -verify %s
+
+#include "Inputs/system-header-simulator-cxx.h"
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
@@ -125,3 +127,15 @@
     p->m(); // no-crash // no-warning
   }
 }
+
+// Allow __cxa_demangle to escape.
+char* test_cxa_demangle(const char* sym) {
+  size_t funcnamesize = 256;
+  char* funcname = (char*)malloc(funcnamesize);
+  int status;
+  char* ret = abi::__cxa_demangle(sym, funcname, &funcnamesize, &status);
+  if (status == 0) {
+    funcname = ret;
+  }
+  return funcname; // no-warning
+}
diff --git a/test/Analysis/malloc.m b/test/Analysis/malloc.m
index 9201c2b..1f67dab 100644
--- a/test/Analysis/malloc.m
+++ b/test/Analysis/malloc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -Wno-objc-root-class -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -Wno-objc-root-class -fblocks %s
 #include "Inputs/system-header-simulator-objc.h"
 
 @class NSString;
@@ -29,7 +29,7 @@
     if (error != ((void*)0))
         return error;
 
-    rdar10579586(buffer->str_c); // expected-warning {{Function call argument is an uninitialized value}}
+    rdar10579586(buffer->str_c); // expected-warning {{1st function call argument is an uninitialized value}}
     free(buffer);
     return ((void*)0);
 }
diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm
index c7fe86b..f8a43b3 100644
--- a/test/Analysis/malloc.mm
+++ b/test/Analysis/malloc.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -fblocks %s
 #import "Inputs/system-header-simulator-objc.h"
 #import "Inputs/system-header-simulator-for-malloc.h"
 
diff --git a/test/Analysis/max-nodes-suppress-on-sink.c b/test/Analysis/max-nodes-suppress-on-sink.c
new file mode 100644
index 0000000..8d955b9
--- /dev/null
+++ b/test/Analysis/max-nodes-suppress-on-sink.c
@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config max-nodes=12 -verify %s
+
+// Here we test how "suppress on sink" feature of certain bugtypes interacts
+// with reaching analysis limits.
+
+// If we report a warning of a bug-type with "suppress on sink" attribute set
+// (such as MallocChecker's memory leak warning), then failing to reach the
+// reason for the sink (eg. no-return function such as "exit()") due to analysis
+// limits (eg. max-nodes option), we may produce a false positive.
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+
+extern void exit(int) __attribute__ ((__noreturn__));
+
+void clang_analyzer_warnIfReached(void);
+
+void test_single_cfg_block_sink() {
+  void *p = malloc(1); // no-warning (wherever the leak warning may occur here)
+
+  // Due to max-nodes option in the run line, we should reach the first call
+  // but bail out before the second call.
+  // If the test on these two lines starts failing, see if modifying
+  // the max-nodes run-line helps.
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+  clang_analyzer_warnIfReached(); // no-warning
+
+  // Even though we do not reach this line, we should still suppress
+  // the leak report.
+  exit(0);
+}
diff --git a/test/Analysis/member-expr.cpp b/test/Analysis/member-expr.cpp
index f8dd324..9951943 100644
--- a/test/Analysis/member-expr.cpp
+++ b/test/Analysis/member-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %s -verify
 
 void clang_analyzer_checkInlined(bool);
 void clang_analyzer_eval(int);
diff --git a/test/Analysis/method-call-intra-p.cpp b/test/Analysis/method-call-intra-p.cpp
index a170942..bead20f 100644
--- a/test/Analysis/method-call-intra-p.cpp
+++ b/test/Analysis/method-call-intra-p.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store region -verify %s
 // expected-no-diagnostics
 
 // Intra-procedural C++ tests.
diff --git a/test/Analysis/method-call-path-notes.cpp b/test/Analysis/method-call-path-notes.cpp
index 8eb07d5..e6253d4 100644
--- a/test/Analysis/method-call-path-notes.cpp
+++ b/test/Analysis/method-call-path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 // Test warning about null or uninitialized pointer values used as instance member
diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp
index 95db452..4f6a9a4 100644
--- a/test/Analysis/method-call.cpp
+++ b/test/Analysis/method-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/misc-ps-64.m b/test/Analysis/misc-ps-64.m
index be50d46..50c0e97 100644
--- a/test/Analysis/misc-ps-64.m
+++ b/test/Analysis/misc-ps-64.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
 // expected-no-diagnostics
 
 // <rdar://problem/6440393> - A bunch of misc. failures involving evaluating
diff --git a/test/Analysis/misc-ps-arm.m b/test/Analysis/misc-ps-arm.m
index a9ea327..9cb7bb2 100644
--- a/test/Analysis/misc-ps-arm.m
+++ b/test/Analysis/misc-ps-arm.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple thumbv7-apple-ios0.0.0 -target-feature +neon -analyze -analyzer-checker=core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple thumbv7-apple-ios0.0.0 -target-feature +neon -analyzer-checker=core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 // <rdar://problem/11405978> - Handle casts of vectors to structs, and loading
diff --git a/test/Analysis/misc-ps-cxx0x.cpp b/test/Analysis/misc-ps-cxx0x.cpp
index 164af5d..1b4516a 100644
--- a/test/Analysis/misc-ps-cxx0x.cpp
+++ b/test/Analysis/misc-ps-cxx0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze -std=c++11 %s -Xclang -verify -o /dev/null
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.NullDereference,core.uninitialized.UndefReturn -std=c++11 %s -verify -o /dev/null
 
 void test_static_assert() {
   static_assert(sizeof(void *) == sizeof(void*), "test_static_assert");
diff --git a/test/Analysis/misc-ps-eager-assume.m b/test/Analysis/misc-ps-eager-assume.m
index ca056d8..dbeecf2 100644
--- a/test/Analysis/misc-ps-eager-assume.m
+++ b/test/Analysis/misc-ps-eager-assume.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s -analyzer-eagerly-assume
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s -analyzer-eagerly-assume
 // expected-no-diagnostics
 
 // Delta-reduced header stuff (needed for test cases).
diff --git a/test/Analysis/misc-ps-ranges.m b/test/Analysis/misc-ps-ranges.m
index d8720e9..161d981 100644
--- a/test/Analysis/misc-ps-ranges.m
+++ b/test/Analysis/misc-ps-ranges.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
 
 // <rdar://problem/6776949>
 // main's 'argc' argument is always > 0
diff --git a/test/Analysis/misc-ps-region-store-i386.m b/test/Analysis/misc-ps-region-store-i386.m
index bed6fc3..269a815 100644
--- a/test/Analysis/misc-ps-region-store-i386.m
+++ b/test/Analysis/misc-ps-region-store-i386.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
 // expected-no-diagnostics
 
 // Here is a case where a pointer is treated as integer, invalidated as an
diff --git a/test/Analysis/misc-ps-region-store-x86_64.m b/test/Analysis/misc-ps-region-store-x86_64.m
index 4575ad4..0bdc5a2 100644
--- a/test/Analysis/misc-ps-region-store-x86_64.m
+++ b/test/Analysis/misc-ps-region-store-x86_64.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
 // expected-no-diagnostics
 
 // Here is a case where a pointer is treated as integer, invalidated as an
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index daa6d64..c6dad5d 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
 
 void clang_analyzer_warnIfReached();
 
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index 5816648..9bd2073 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyze -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
 
 typedef long unsigned int size_t;
 void *memcpy(void *, const void *, size_t);
@@ -396,7 +396,7 @@
 int rdar_7332673_test2_aux(char *x);
 void rdar_7332673_test2() {
     char *value;
-    if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{Function call argument is an uninitialized value}}
+    if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 //===----------------------------------------------------------------------===//
@@ -673,7 +673,7 @@
   builder = ^(id object) {
     id x;
     if (object) {
-      builder(x); // expected-warning{{Block call argument is an uninitialized value}}
+      builder(x); // expected-warning{{1st block call argument is an uninitialized value}}
     }
   };
   builder(target);
diff --git a/test/Analysis/misc-ps-region-store.mm b/test/Analysis/misc-ps-region-store.mm
index c19a90f..4b271c4 100644
--- a/test/Analysis/misc-ps-region-store.mm
+++ b/test/Analysis/misc-ps-region-store.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
 // expected-no-diagnostics
 
 //===------------------------------------------------------------------------------------------===//
diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c
index 01cad15..3044dc9 100644
--- a/test/Analysis/misc-ps.c
+++ b/test/Analysis/misc-ps.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
@@ -191,3 +191,13 @@
   clang_analyzer_eval(*ip == 42); // expected-warning{{TRUE}}
   clang_analyzer_eval(*(int *)&v == 42); // expected-warning{{TRUE}}
 }
+
+// PR15623: Currently the analyzer doesn't handle symbolic expressions of the
+// form "(exp comparison_op expr) != 0" very well. We perform a simplification
+// translating an assume of a constraint of the form "(exp comparison_op expr)
+// != 0" to true into an assume of "exp comparison_op expr" to true.
+void PR15623(int n) {
+  if ((n == 0) != 0) {
+    clang_analyzer_eval(n == 0); // expected-warning{{TRUE}}
+  }
+}
diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
index f979cf3..9a75cfd 100644
--- a/test/Analysis/misc-ps.m
+++ b/test/Analysis/misc-ps.m
@@ -1,6 +1,6 @@
 // NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued.
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
 
 #ifndef __clang_analyzer__
 #error __clang_analyzer__ not defined
@@ -796,7 +796,7 @@
 void test_bad_call_aux(int x);
 void test_bad_call(void) {
   int y;
-  test_bad_call_aux(y); // expected-warning{{Function call argument is an uninitialized value}}
+  test_bad_call_aux(y); // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 @interface TestBadArg {}
@@ -805,7 +805,7 @@
 
 void test_bad_msg(TestBadArg *p) {
   int y;
-  [p testBadArg:y]; // expected-warning{{Argument in message expression is an uninitialized value}}
+  [p testBadArg:y]; // expected-warning{{1st argument in message expression is an uninitialized value}}
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Analysis/model-file.cpp b/test/Analysis/model-file.cpp
index 41cdf7f..de5a888 100644
--- a/test/Analysis/model-file.cpp
+++ b/test/Analysis/model-file.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config faux-bodies=true,model-path=%S/Inputs/Models -analyzer-output=plist-multi-file -verify %s -o %t
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config faux-bodies=true,model-path=%S/Inputs/Models -analyzer-output=plist-multi-file -verify %s -o %t
 // RUN: FileCheck --input-file=%t %s
 
 typedef int* intptr;
diff --git a/test/Analysis/mpichecker.cpp b/test/Analysis/mpichecker.cpp
index b7a1e00..f764452 100644
--- a/test/Analysis/mpichecker.cpp
+++ b/test/Analysis/mpichecker.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.mpi.MPI-Checker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.mpi.MPI-Checker -verify %s
 
 #include "MPIMock.h"
 
diff --git a/test/Analysis/mpicheckernotes.cpp b/test/Analysis/mpicheckernotes.cpp
index be312fd..994ce8e 100644
--- a/test/Analysis/mpicheckernotes.cpp
+++ b/test/Analysis/mpicheckernotes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.mpi.MPI-Checker -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.mpi.MPI-Checker -analyzer-output=text -verify %s
 
 // MPI-Checker test file to test note diagnostics.
 
diff --git a/test/Analysis/new-with-exceptions.cpp b/test/Analysis/new-with-exceptions.cpp
index 84d77c2..9d02574 100644
--- a/test/Analysis/new-with-exceptions.cpp
+++ b/test/Analysis/new-with-exceptions.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -std=c++11 -fexceptions -fcxx-exceptions -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-store region -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp
index e262aa7..6cfcb1d 100644
--- a/test/Analysis/new.cpp
+++ b/test/Analysis/new.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
 #include "Inputs/system-header-simulator-cxx.h"
 
 void clang_analyzer_eval(bool);
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret-region.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret-region.m
index e63e2ca..cbfc266 100644
--- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret-region.m
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret-region.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin8 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin8 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
 
 // <rdar://problem/6888289> - This test case shows that a nil instance
 // variable can possibly be initialized by a method.
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
index 4f99390..d4a478d 100644
--- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin8 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.1 2>&1
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin8 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.1 2>&1
 // RUN: FileCheck -input-file=%t.1 -check-prefix=CHECK-darwin8 %s
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.2 2>&1
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.2 2>&1
 // RUN: FileCheck -input-file=%t.2 -check-prefix=CHECK-darwin9 %s
-// RUN: %clang_cc1 -triple thumbv6-apple-ios4.0 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.3 2>&1
+// RUN: %clang_analyze_cc1 -triple thumbv6-apple-ios4.0 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.3 2>&1
 // RUN: FileCheck -input-file=%t.3 -check-prefix=CHECK-darwin9 %s
 
 @interface MyClass {}
diff --git a/test/Analysis/no-exit-cfg.c b/test/Analysis/no-exit-cfg.c
index b3c3fbc..7575152 100644
--- a/test/Analysis/no-exit-cfg.c
+++ b/test/Analysis/no-exit-cfg.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s 
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s 
 // expected-no-diagnostics
 
 // This is a test case for the issue reported in PR 2819:
diff --git a/test/Analysis/no-outofbounds.c b/test/Analysis/no-outofbounds.c
index d401279..ae534a9 100644
--- a/test/Analysis/no-outofbounds.c
+++ b/test/Analysis/no-outofbounds.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,alpha.unix,alpha.security.ArrayBound -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,alpha.unix,alpha.security.ArrayBound -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Analysis/no-unreachable-dtors.cpp b/test/Analysis/no-unreachable-dtors.cpp
index e0893b3..1675542 100644
--- a/test/Analysis/no-unreachable-dtors.cpp
+++ b/test/Analysis/no-unreachable-dtors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.Stats -verify -Wno-unreachable-code %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.Stats -verify -Wno-unreachable-code %s
 
 struct S {
   ~S();
diff --git a/test/Analysis/non-diagnosable-assumptions.c b/test/Analysis/non-diagnosable-assumptions.c
index 50cc8d6..44b69be 100644
--- a/test/Analysis/non-diagnosable-assumptions.c
+++ b/test/Analysis/non-diagnosable-assumptions.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -analyze -analyzer-checker=core.DivideZero -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core.DivideZero -analyzer-output=text -verify %s
 
 // This test file verifies the "Assuming..." diagnostic pieces that are being
 // reported when the branch condition was too complicated to explain.
diff --git a/test/Analysis/nonnull.m b/test/Analysis/nonnull.m
index c21360d..6db7cfa 100644
--- a/test/Analysis/nonnull.m
+++ b/test/Analysis/nonnull.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -w -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -w -verify %s
 
 @interface MyObject
 - (void)takePointer:(void *)ptr __attribute__((nonnull(1)));
diff --git a/test/Analysis/null-deref-path-notes.m b/test/Analysis/null-deref-path-notes.m
index 9e5cab6..242b5da 100644
--- a/test/Analysis/null-deref-path-notes.m
+++ b/test/Analysis/null-deref-path-notes.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-output=text -fblocks -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false -fblocks -Wno-objc-root-class %s -o %t
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-output=text -fblocks -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false -fblocks -Wno-objc-root-class %s -o %t
 // RUN: FileCheck --input-file=%t %s
 
 @interface Root {
diff --git a/test/Analysis/null-deref-ps-region.c b/test/Analysis/null-deref-ps-region.c
index 5bb9454..6ef99ae 100644
--- a/test/Analysis/null-deref-ps-region.c
+++ b/test/Analysis/null-deref-ps-region.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -std=gnu99 -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -std=gnu99 -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index b0d2292..5dee308 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -analyzer-purge=none -verify %s -Wno-error=return-type
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -verify %s -Wno-error=return-type
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -analyzer-purge=none -verify %s -Wno-error=return-type
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -verify %s -Wno-error=return-type
 
 typedef unsigned uintptr_t;
 
@@ -286,7 +286,7 @@
 
 void pr4759() {
   int *p;
-  pr4759_aux(p); // expected-warning{{Function call argument is an uninitialized value}}
+  pr4759_aux(p); // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 // Relax function call arguments invalidation to be aware of const
diff --git a/test/Analysis/null-deref-static.m b/test/Analysis/null-deref-static.m
new file mode 100644
index 0000000..887bea2
--- /dev/null
+++ b/test/Analysis/null-deref-static.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -w -fblocks -analyze -analyzer-checker=core,deadcode,alpha.core,debug.ExprInspection -verify %s
+
+void *malloc(unsigned long);
+void clang_analyzer_warnIfReached();
+
+void test_static_from_block() {
+  static int *x;
+  ^{
+    *x; // no-warning
+  };
+}
+
+void test_static_within_block() {
+  ^{
+    static int *x;
+    *x; // expected-warning{{Dereference of null pointer}}
+  };
+}
+
+void test_static_control_flow(int y) {
+  static int *x;
+  if (x) {
+    // FIXME: Should be reachable.
+    clang_analyzer_warnIfReached(); // no-warning
+  }
+  if (y) {
+    // We are not sure if this branch is possible, because the developer
+    // may argue that function is always called with y == 1 for the first time.
+    // In this case, we can only advise the developer to add assertions
+    // for suppressing such path.
+    *x; // expected-warning{{Dereference of null pointer}}
+  } else {
+    x = malloc(1);
+  }
+}
diff --git a/test/Analysis/nullability-no-arc.mm b/test/Analysis/nullability-no-arc.mm
index 37d29b7..0760186 100644
--- a/test/Analysis/nullability-no-arc.mm
+++ b/test/Analysis/nullability-no-arc.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,nullability -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,nullability -verify %s
 
 #define nil 0
 
@@ -17,20 +17,20 @@
 @interface TestObject : NSObject
 @end
 
-TestObject * _Nonnull returnsNilObjCInstanceIndirectly() {
-  TestObject *local = 0;
-  return local; // expected-warning {{Null is returned from a function that is expected to return a non-null value}}
+TestObject *_Nonnull returnsNilObjCInstanceIndirectly() {
+  TestObject *local = nil;
+  return local; // expected-warning {{nil returned from a function that is expected to return a non-null value}}
 }
 
 TestObject * _Nonnull returnsNilObjCInstanceIndirectlyWithSupressingCast() {
-  TestObject *local = 0;
+  TestObject *local = nil;
   return (TestObject * _Nonnull)local; // no-warning
 }
 
 TestObject * _Nonnull returnsNilObjCInstanceDirectly() {
   // The first warning is from Sema. The second is from the static analyzer.
   return nil; // expected-warning {{null returned from function that requires a non-null return value}}
-              // expected-warning@-1 {{Null is returned from a function that is expected to return a non-null value}}
+              // expected-warning@-1 {{nil returned from a function that is expected to return a non-null value}}
 }
 
 TestObject * _Nonnull returnsNilObjCInstanceDirectlyWithSuppressingCast() {
@@ -43,7 +43,7 @@
 }
 
 void testObjCNonARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{Null is assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}}
 }
 
 @interface ClassWithInitializers : NSObject
diff --git a/test/Analysis/nullability.c b/test/Analysis/nullability.c
index a282969..e0836c6 100644
--- a/test/Analysis/nullability.c
+++ b/test/Analysis/nullability.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability -verify %s
 
 void it_takes_two(int a, int b);
 void function_pointer_arity_mismatch() {
diff --git a/test/Analysis/nullability.mm b/test/Analysis/nullability.mm
index ac2a839..ddfede5 100644
--- a/test/Analysis/nullability.mm
+++ b/test/Analysis/nullability.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -DNOSYSTEMHEADERS=0 -verify %s
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -DNOSYSTEMHEADERS=0 -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
 
 #include "Inputs/system-header-simulator-for-nullability.h"
 
@@ -75,7 +75,7 @@
   }
   Dummy a;
   Dummy *_Nonnull nonnull = &a;
-  nonnull = q; // expected-warning {{Null is assigned to a pointer which is expected to have non-null value}}
+  nonnull = q; // expected-warning {{Null assigned to a pointer which is expected to have non-null value}}
   q = &a;
   takesNullable(q);
   takesNonnull(q);
@@ -107,7 +107,7 @@
 
 Dummy *_Nonnull testNullReturn() {
   Dummy *p = 0;
-  return p; // expected-warning {{Null is returned from a function that is expected to return a non-null value}}
+  return p; // expected-warning {{Null returned from a function that is expected to return a non-null value}}
 }
 
 void testObjCMessageResultNullability() {
@@ -229,7 +229,7 @@
 Dummy * _Nonnull testIndirectCastNilToNonnullAndReturn() {
   Dummy *p = (Dummy * _Nonnull)0;
   // FIXME: Ideally the cast above would suppress this warning.
-  return p; // expected-warning {{Null is returned from a function that is expected to return a non-null value}}
+  return p; // expected-warning {{Null returned from a function that is expected to return a non-null value}}
 }
 
 void testInvalidPropagation() {
diff --git a/test/Analysis/nullability_nullonly.mm b/test/Analysis/nullability_nullonly.mm
index 9671877..1822539 100644
--- a/test/Analysis/nullability_nullonly.mm
+++ b/test/Analysis/nullability_nullonly.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -DNOSYSTEMHEADERS=0 -verify %s
-// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
+// RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -DNOSYSTEMHEADERS=0 -verify %s
+// RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
 
 #include "Inputs/system-header-simulator-for-nullability.h"
 
@@ -24,7 +24,7 @@
 
 Dummy *_Nonnull testNullReturn() {
   Dummy *p = 0;
-  return p; // expected-warning {{Null is returned from a function that is expected to return a non-null value}}
+  return p; // expected-warning {{Null returned from a function that is expected to return a non-null value}}
 }
 
 void onlyReportFirstPreconditionViolationOnPath() {
@@ -100,24 +100,24 @@
 }
 
 void testObjCARCExplicitZeroInitialization() {
-  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{Null is assigned to a pointer which is expected to have non-null value}}
+  TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}}
 }
 
 // Under ARC, returned expressions of ObjC objects types are are implicitly
 // cast to _Nonnull when the functions return type is _Nonnull, so make
 // sure this doesn't implicit cast doesn't suppress a legitimate warning.
 TestObject * _Nonnull returnsNilObjCInstanceIndirectly() {
-  TestObject *local = 0;
-  return local; // expected-warning {{Null is returned from a function that is expected to return a non-null value}}
+  TestObject *local = nil;
+  return local; // expected-warning {{nil returned from a function that is expected to return a non-null value}}
 }
 
 TestObject * _Nonnull returnsNilObjCInstanceIndirectlyWithSupressingCast() {
-  TestObject *local = 0;
+  TestObject *local = nil;
   return (TestObject * _Nonnull)local; // no-warning
 }
 
 TestObject * _Nonnull returnsNilObjCInstanceDirectly() {
-  return nil; // expected-warning {{Null is returned from a function that is expected to return a non-null value}}
+  return nil; // expected-warning {{nil returned from a function that is expected to return a non-null value}}
 }
 
 TestObject * _Nonnull returnsNilObjCInstanceDirectlyWithSuppressingCast() {
@@ -130,7 +130,7 @@
 @implementation SomeClass (MethodReturn)
 - (SomeClass * _Nonnull)testReturnsNilInNonnull {
   SomeClass *local = nil;
-  return local; // expected-warning {{Null is returned from a method that is expected to return a non-null value}}
+  return local; // expected-warning {{nil returned from a method that is expected to return a non-null value}}
 }
 
 - (SomeClass * _Nonnull)testReturnsCastSuppressedNilInNonnull {
@@ -154,7 +154,7 @@
 
   NSSystemFunctionTakingNonnull(s);
   #if !NOSYSTEMHEADERS
-  // expected-warning@-2{{Null passed to a callee that requires a non-null 1st parameter}}
+  // expected-warning@-2{{nil passed to a callee that requires a non-null 1st parameter}}
   #endif
 }
 
@@ -165,6 +165,6 @@
   NSSystemClass *sc = [[NSSystemClass alloc] init];
   [sc takesNonnull:s];
   #if !NOSYSTEMHEADERS
-  // expected-warning@-2{{Null passed to a callee that requires a non-null 1st parameter}}
+  // expected-warning@-2{{nil passed to a callee that requires a non-null 1st parameter}}
   #endif
 }
diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp
index acc525e..229ad7b 100644
--- a/test/Analysis/nullptr.cpp
+++ b/test/Analysis/nullptr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -Wno-conversion-null -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
 
 void clang_analyzer_eval(int);
 
@@ -107,7 +107,7 @@
 void shouldNotCrash() {
   decltype(nullptr) p;
   if (getSymbol())
-    invokeF(p); // expected-warning{{Function call argument is an uninit}}
+    invokeF(p); // expected-warning{{1st function call argument is an uninit}}
   if (getSymbol())
     invokeF(nullptr);
   if (getSymbol()) {
diff --git a/test/Analysis/number-object-conversion.c b/test/Analysis/number-object-conversion.c
index c4ffaaf..8f1e672 100644
--- a/test/Analysis/number-object-conversion.c
+++ b/test/Analysis/number-object-conversion.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -analyzer-checker=osx.NumberObjectConversion %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
 
 #define NULL ((void *)0)
 
diff --git a/test/Analysis/number-object-conversion.cpp b/test/Analysis/number-object-conversion.cpp
index 9dea7b0..7e46a2b 100644
--- a/test/Analysis/number-object-conversion.cpp
+++ b/test/Analysis/number-object-conversion.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyzer-checker=osx.NumberObjectConversion %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
 
 #define NULL ((void *)0)
 #include "Inputs/system-header-simulator-cxx.h" // for nullptr
diff --git a/test/Analysis/number-object-conversion.m b/test/Analysis/number-object-conversion.m
index 08d4a19..8bc0332 100644
--- a/test/Analysis/number-object-conversion.m
+++ b/test/Analysis/number-object-conversion.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -w -analyzer-checker=osx.NumberObjectConversion %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -w -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyzer-checker=osx.NumberObjectConversion %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
 
 #include "Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/objc-arc.m b/test/Analysis/objc-arc.m
index e9ef459..4b446ab 100644
--- a/test/Analysis/objc-arc.m
+++ b/test/Analysis/objc-arc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-arc -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist-multi-file -o %t.plist %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-arc -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist-multi-file -o %t.plist %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 typedef signed char BOOL;
@@ -441,9 +441,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object of type CFDateRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object of type CFDateRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -911,9 +911,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1091,9 +1091,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateString&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateString&apos; returns a Core Foundation object of type CFStringRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateString&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateString&apos; returns a Core Foundation object of type CFStringRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1466,9 +1466,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object of type CFDateRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object of type CFDateRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1782,9 +1782,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateString&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateString&apos; returns a Core Foundation object of type CFStringRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateString&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateString&apos; returns a Core Foundation object of type CFStringRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1879,9 +1879,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +0 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +0 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
diff --git a/test/Analysis/objc-bool.m b/test/Analysis/objc-bool.m
index a2d10cc..98d0cb2 100644
--- a/test/Analysis/objc-bool.m
+++ b/test/Analysis/objc-bool.m
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -o %t -Xclang -verify
+// RUN: %clang_analyze_cc1 %s -o %t -verify
 // expected-no-diagnostics
 
 // Test handling of ObjC bool literals.
diff --git a/test/Analysis/objc-boxing.m b/test/Analysis/objc-boxing.m
index 73386f4..963374b 100644
--- a/test/Analysis/objc-boxing.m
+++ b/test/Analysis/objc-boxing.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-objc-literal-conversion -analyze -analyzer-checker=core,unix.Malloc,osx.cocoa.NonNilReturnValue,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -Wno-objc-literal-conversion -analyzer-checker=core,unix.Malloc,osx.cocoa.NonNilReturnValue,debug.ExprInspection -analyzer-store=region -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/objc-for.m b/test/Analysis/objc-for.m
index d1e044a..41709be 100644
--- a/test/Analysis/objc-for.m
+++ b/test/Analysis/objc-for.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/objc-message.m b/test/Analysis/objc-message.m
index dc0fd1f..f525ce7 100644
--- a/test/Analysis/objc-message.m
+++ b/test/Analysis/objc-message.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
 
 extern void clang_analyzer_warnIfReached();
 void clang_analyzer_eval(int);
diff --git a/test/Analysis/objc-method-coverage.m b/test/Analysis/objc-method-coverage.m
index 489c19b..1915586 100644
--- a/test/Analysis/objc-method-coverage.m
+++ b/test/Analysis/objc-method-coverage.m
@@ -1,5 +1,5 @@
 // REQUIRES: asserts
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-stats -fblocks %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-stats -fblocks %s 2>&1 | FileCheck %s
 @interface I
 int f() {
   return 0;
diff --git a/test/Analysis/objc-properties.m b/test/Analysis/objc-properties.m
index f6ed3e5..88a19a1 100644
--- a/test/Analysis/objc-properties.m
+++ b/test/Analysis/objc-properties.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignment -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignment -verify -fblocks %s
 
 typedef signed char BOOL;
 @protocol NSObject  - (BOOL)isEqual:(id)object; @end
diff --git a/test/Analysis/objc-radar17039661.m b/test/Analysis/objc-radar17039661.m
index fc55ab1..bfb8ef0 100644
--- a/test/Analysis/objc-radar17039661.m
+++ b/test/Analysis/objc-radar17039661.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t
 // RUN: FileCheck --input-file=%t %s
 @class NSString;
 typedef long NSInteger;
diff --git a/test/Analysis/objc-string.mm b/test/Analysis/objc-string.mm
index a32b740..53f3c37 100644
--- a/test/Analysis/objc-string.mm
+++ b/test/Analysis/objc-string.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -Wno-objc-literal-conversion %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -Wno-objc-literal-conversion %s
 
 void clang_analyzer_eval(bool);
 @class NSString;
diff --git a/test/Analysis/objc-subscript.m b/test/Analysis/objc-subscript.m
index ae621c9..155fbb7 100644
--- a/test/Analysis/objc-subscript.m
+++ b/test/Analysis/objc-subscript.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -Wno-objc-root-class %s
 
 typedef signed char BOOL;
 typedef unsigned int NSUInteger;
diff --git a/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m b/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m
index 4777aed..1603a57 100644
--- a/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m
+++ b/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions -verify -fblocks %s
 
 typedef signed char BOOL;
 @protocol NSObject  - (BOOL)isEqual:(id)object; @end
diff --git a/test/Analysis/objc_invalidation.m b/test/Analysis/objc_invalidation.m
index cd66444..52a79d8 100644
--- a/test/Analysis/objc_invalidation.m
+++ b/test/Analysis/objc_invalidation.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.osx.cocoa.InstanceVariableInvalidation -DRUN_IVAR_INVALIDATION -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.osx.cocoa.MissingInvalidationMethod -DRUN_MISSING_INVALIDATION_METHOD -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.osx.cocoa.InstanceVariableInvalidation -DRUN_IVAR_INVALIDATION -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.osx.cocoa.MissingInvalidationMethod -DRUN_MISSING_INVALIDATION_METHOD -verify %s
 extern void __assert_fail (__const char *__assertion, __const char *__file,
     unsigned int __line, __const char *__function)
      __attribute__ ((__noreturn__));
diff --git a/test/Analysis/openmp-unsupported.c b/test/Analysis/openmp-unsupported.c
new file mode 100644
index 0000000..7e363ee
--- /dev/null
+++ b/test/Analysis/openmp-unsupported.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin -fopenmp -verify %s
+// expected-no-diagnostics
+
+void openmp_parallel_crash_test() {
+#pragma omp parallel
+  ;
+}
diff --git a/test/Analysis/operator-calls.cpp b/test/Analysis/operator-calls.cpp
index 4bd7c12..3107229 100644
--- a/test/Analysis/operator-calls.cpp
+++ b/test/Analysis/operator-calls.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
 void clang_analyzer_eval(bool);
 
 struct X0 { };
diff --git a/test/Analysis/out-of-bounds-new.cpp b/test/Analysis/out-of-bounds-new.cpp
index 41ecbee..b7ceea7 100644
--- a/test/Analysis/out-of-bounds-new.cpp
+++ b/test/Analysis/out-of-bounds-new.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -Wno-array-bounds -analyze -analyzer-checker=unix,core,alpha.security.ArrayBoundV2 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,alpha.security.ArrayBoundV2 -verify %s
 
 // Tests doing an out-of-bounds access after the end of an array using:
 // - constant integer index
@@ -148,3 +148,9 @@
   int *buf = new int[s];
   buf[0] = 1; // no-warning
 }
+//Tests complex arithmetic
+//in new expression
+void test_dynamic_size2(unsigned m,unsigned n){
+  unsigned *U = nullptr;
+  U = new unsigned[m + n + 1];
+}
diff --git a/test/Analysis/out-of-bounds.c b/test/Analysis/out-of-bounds.c
index ca1e0d0..1970cd6 100644
--- a/test/Analysis/out-of-bounds.c
+++ b/test/Analysis/out-of-bounds.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,alpha.security.ArrayBoundV2,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/outofbound-notwork.c b/test/Analysis/outofbound-notwork.c
index 68b01e0..22ccd9e 100644
--- a/test/Analysis/outofbound-notwork.c
+++ b/test/Analysis/outofbound-notwork.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,alpha.security.ArrayBound -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,alpha.security.ArrayBound -analyzer-store=region -verify %s
 // XFAIL: *
 
 // Once we better handle modeling of sizes of VLAs, we can pull this back
diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c
index 81ed7ac..35672c0 100644
--- a/test/Analysis/outofbound.c
+++ b/test/Analysis/outofbound.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,unix,alpha.security.ArrayBound -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,unix,alpha.security.ArrayBound -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
diff --git a/test/Analysis/override-werror.c b/test/Analysis/override-werror.c
index a68ee1e..7dc09f5 100644
--- a/test/Analysis/override-werror.c
+++ b/test/Analysis/override-werror.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -Werror %s -analyzer-store=region -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -Werror %s -analyzer-store=region -verify
 
 // This test case illustrates that using '-analyze' overrides the effect of
 // -Werror.  This allows basic warnings not to interfere with producing
diff --git a/test/Analysis/padding_c.c b/test/Analysis/padding_c.c
index 93cefca..f4178f5 100644
--- a/test/Analysis/padding_c.c
+++ b/test/Analysis/padding_c.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
 
 #if __has_include(<stdalign.h>)
 #include <stdalign.h>
diff --git a/test/Analysis/padding_cpp.cpp b/test/Analysis/padding_cpp.cpp
index df2f2a8..ee49aea 100644
--- a/test/Analysis/padding_cpp.cpp
+++ b/test/Analysis/padding_cpp.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
 
 // Make sure that the C cases still work fine, even when compiled as C++.
 #include "padding_c.c"
diff --git a/test/Analysis/padding_message.cpp b/test/Analysis/padding_message.cpp
index bbfa453..4c7e061 100644
--- a/test/Analysis/padding_message.cpp
+++ b/test/Analysis/padding_message.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++14 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
 
 // expected-warning@+7{{\
 Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal). \
diff --git a/test/Analysis/plist-html-macros.c b/test/Analysis/plist-html-macros.c
index dbdbb30..c25346d 100644
--- a/test/Analysis/plist-html-macros.c
+++ b/test/Analysis/plist-html-macros.c
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // (sanity check)
 
 // RUN: rm -rf %t.dir
 // RUN: mkdir -p %t.dir
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-html -o %t.dir/index.plist %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-html -o %t.dir/index.plist %s
 // RUN: ls %t.dir | grep '\.html' | count 1
 // RUN: grep '\.html' %t.dir/index.plist | count 1
 
diff --git a/test/Analysis/plist-macros.cpp b/test/Analysis/plist-macros.cpp
index 09ad15e..594cfdc 100644
--- a/test/Analysis/plist-macros.cpp
+++ b/test/Analysis/plist-macros.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -analyzer-eagerly-assume -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -analyzer-eagerly-assume -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=ture %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-eagerly-assume -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-eagerly-assume -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=ture %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 
diff --git a/test/Analysis/plist-output-alternate.m b/test/Analysis/plist-output-alternate.m
index 164f1c5..03f3393 100644
--- a/test/Analysis/plist-output-alternate.m
+++ b/test/Analysis/plist-output-alternate.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -fblocks -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -fblocks -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
 // RUN: FileCheck --input-file %t %s
 
 void test_null_init(void) {
@@ -1191,9 +1191,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFNumberCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFNumberCreate&apos; returns a Core Foundation object of type CFNumberRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFNumberCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFNumberCreate&apos; returns a Core Foundation object of type CFNumberRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m
index affbb5d..a80ab5c 100644
--- a/test/Analysis/plist-output.m
+++ b/test/Analysis/plist-output.m
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -Xanalyzer -analyzer-checker=osx.cocoa.RetainCount -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -o %t.plist
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=osx.cocoa.RetainCount,deadcode.DeadStores,core -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void test_null_init(void) {
@@ -24,7 +24,7 @@
     *p = 0xDEADBEEF;
   }
 }
-  
+
 void test_null_cond_transitive(int *q) {
   if (!q) {
     int *p = q;
@@ -51,7 +51,7 @@
 }
 
 int *bar_cond_assign();
-int test_cond_assign() { 
+int test_cond_assign() {
   int *p;
   if (p = bar_cond_assign())
     return 1;
@@ -138,7 +138,7 @@
 
 void test_loop_diagnostics_2() {
   int *p = 0;
-  for (int i = 0; i < 2; ) { 
+  for (int i = 0; i < 2; ) {
     ++i;
     p = 0;
   }
@@ -166,9 +166,9 @@
 @interface RDar12114812 { char *p; }
 @end
 
-@implementation RDar12114812 
+@implementation RDar12114812
 - (void)test {
-  p = 0;        
+  p = 0;
   *p = 1;
 }
 @end
@@ -2686,103 +2686,6 @@
 // CHECK-NEXT:       </array>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>108</integer>
-// CHECK-NEXT:       <key>col</key><integer>24</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>108</integer>
-// CHECK-NEXT:          <key>col</key><integer>24</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>108</integer>
-// CHECK-NEXT:          <key>col</key><integer>28</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;i&apos; is &gt;= &apos;x&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;i&apos; is &gt;= &apos;x&apos;</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
@@ -2992,103 +2895,6 @@
 // CHECK-NEXT:       </array>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>11</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>11</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>117</integer>
-// CHECK-NEXT:       <key>col</key><integer>11</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>117</integer>
-// CHECK-NEXT:          <key>col</key><integer>11</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>117</integer>
-// CHECK-NEXT:          <key>col</key><integer>15</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;i&apos; is &gt;= &apos;x&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;i&apos; is &gt;= &apos;x&apos;</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>11</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>11</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
diff --git a/test/Analysis/pointer-to-member.cpp b/test/Analysis/pointer-to-member.cpp
index 37d0439..0fbb992 100644
--- a/test/Analysis/pointer-to-member.cpp
+++ b/test/Analysis/pointer-to-member.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
@@ -35,8 +35,7 @@
   clang_analyzer_eval(&A::getPtr == &A::getPtr); // expected-warning{{TRUE}}
   clang_analyzer_eval(&A::getPtr == 0); // expected-warning{{FALSE}}
 
-  // FIXME: Should be TRUE.
-  clang_analyzer_eval(&A::m_ptr == &A::m_ptr); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(&A::m_ptr == &A::m_ptr); // expected-warning{{TRUE}}
 }
 
 namespace PR15742 {
@@ -62,21 +61,172 @@
   }
 }
 
-// ---------------
-// FALSE NEGATIVES
-// ---------------
-
 bool testDereferencing() {
   A obj;
   obj.m_ptr = 0;
 
   A::MemberPointer member = &A::m_ptr;
 
-  // FIXME: Should be TRUE.
-  clang_analyzer_eval(obj.*member == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(obj.*member == 0); // expected-warning{{TRUE}}
 
   member = 0;
 
-  // FIXME: Should emit a null dereference.
-  return obj.*member; // no-warning
+  return obj.*member; // expected-warning{{The result of the '.*' expression is undefined}}
 }
+
+namespace testPointerToMemberFunction {
+  struct A {
+    virtual int foo() { return 1; }
+    int bar() { return 2; }
+    int static staticMemberFunction(int p) { return p + 1; };
+  };
+
+  struct B : public A {
+    virtual int foo() { return 3; }
+  };
+
+  typedef int (A::*AFnPointer)();
+  typedef int (B::*BFnPointer)();
+
+  void testPointerToMemberCasts() {
+    AFnPointer AFP = &A::bar;
+    BFnPointer StaticCastedBase2Derived = static_cast<BFnPointer>(&A::bar),
+               CCastedBase2Derived = (BFnPointer) (&A::bar);
+    A a;
+    B b;
+
+    clang_analyzer_eval((a.*AFP)() == 2); // expected-warning{{TRUE}}
+    clang_analyzer_eval((b.*StaticCastedBase2Derived)() == 2); // expected-warning{{TRUE}}
+    clang_analyzer_eval(((b.*CCastedBase2Derived)() == 2)); // expected-warning{{TRUE}}
+  }
+
+  void testPointerToMemberVirtualCall() {
+    A a;
+    B b;
+    A *APtr = &a;
+    AFnPointer AFP = &A::foo;
+
+    clang_analyzer_eval((APtr->*AFP)() == 1); // expected-warning{{TRUE}}
+
+    APtr = &b;
+
+    clang_analyzer_eval((APtr->*AFP)() == 3); // expected-warning{{TRUE}}
+  }
+
+  void testPointerToStaticMemberCall() {
+    int (*fPtr)(int) = &A::staticMemberFunction;
+    if (fPtr != 0) { // no-crash
+      clang_analyzer_eval(fPtr(2) == 3); // expected-warning{{TRUE}}
+    }
+  }
+} // end of testPointerToMemberFunction namespace
+
+namespace testPointerToMemberData {
+  struct A {
+    int i;
+    static int j;
+  };
+
+  void testPointerToMemberData() {
+    int A::*AMdPointer = &A::i;
+    A a;
+
+    a.i = 42;
+    a.*AMdPointer += 1;
+
+    clang_analyzer_eval(a.i == 43); // expected-warning{{TRUE}}
+
+    int *ptrToStaticField = &A::j;
+    if (ptrToStaticField != 0) {
+      *ptrToStaticField = 7;
+      clang_analyzer_eval(*ptrToStaticField == 7); // expected-warning{{TRUE}}
+      clang_analyzer_eval(A::j == 7); // expected-warning{{TRUE}}
+    }
+  }
+} // end of testPointerToMemberData namespace
+
+namespace testPointerToMemberMiscCasts {
+struct B {
+  int f;
+};
+
+struct D : public B {
+  int g;
+};
+
+void foo() {
+  D d;
+  d.f = 7;
+
+  int B::* pfb = &B::f;
+  int D::* pfd = pfb;
+  int v = d.*pfd;
+
+  clang_analyzer_eval(v == 7); // expected-warning{{TRUE}}
+}
+} // end of testPointerToMemberMiscCasts namespace
+
+namespace testPointerToMemberMiscCasts2 {
+struct B {
+  int f;
+};
+struct L : public B { };
+struct R : public B { };
+struct D : public L, R { };
+
+void foo() {
+  D d;
+
+  int B::* pb = &B::f;
+  int L::* pl = pb;
+  int R::* pr = pb;
+
+  int D::* pdl = pl;
+  int D::* pdr = pr;
+
+  clang_analyzer_eval(pdl == pdr); // expected-warning{{FALSE}}
+  clang_analyzer_eval(pb == pl); // expected-warning{{TRUE}}
+}
+} // end of testPointerToMemberMiscCasts2 namespace
+
+namespace testPointerToMemberDiamond {
+struct B {
+  int f;
+};
+struct L1 : public B { };
+struct R1 : public B { };
+struct M : public L1, R1 { };
+struct L2 : public M { };
+struct R2 : public M { };
+struct D2 : public L2, R2 { };
+
+void diamond() {
+  M m;
+
+  static_cast<L1 *>(&m)->f = 7;
+  static_cast<R1 *>(&m)->f = 16;
+
+  int L1::* pl1 = &B::f;
+  int M::* pm_via_l1 = pl1;
+
+  int R1::* pr1 = &B::f;
+  int M::* pm_via_r1 = pr1;
+
+  clang_analyzer_eval(m.*(pm_via_l1) == 7); // expected-warning {{TRUE}}
+  clang_analyzer_eval(m.*(pm_via_r1) == 16); // expected-warning {{TRUE}}
+}
+
+void double_diamond() {
+  D2 d2;
+
+  static_cast<L1 *>(static_cast<L2 *>(&d2))->f = 1;
+  static_cast<L1 *>(static_cast<R2 *>(&d2))->f = 2;
+  static_cast<R1 *>(static_cast<L2 *>(&d2))->f = 3;
+  static_cast<R1 *>(static_cast<R2 *>(&d2))->f = 4;
+
+  clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int L2::*>(static_cast<int L1::*>(&B::f)))) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int R2::*>(static_cast<int L1::*>(&B::f)))) == 2); // expected-warning {{TRUE}}
+  clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int L2::*>(static_cast<int R1::*>(&B::f)))) == 3); // expected-warning {{TRUE}}
+  clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int R2::*>(static_cast<int R1::*>(&B::f)))) == 4); // expected-warning {{TRUE}}
+}
+} // end of testPointerToMemberDiamond namespace
diff --git a/test/Analysis/pr22954.c b/test/Analysis/pr22954.c
index 01aa5b3..64a00c5 100644
--- a/test/Analysis/pr22954.c
+++ b/test/Analysis/pr22954.c
@@ -3,7 +3,7 @@
 // At the moment the whole of the destination array content is invalidated.
 // If a.s1 region has a symbolic offset, the whole region of 'a' is invalidated.
 // Specific triple set to test structures of size 0.
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
 
 typedef __typeof(sizeof(int)) size_t;
 
diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m
index 29abe94..8b0eaca 100644
--- a/test/Analysis/pr4209.m
+++ b/test/Analysis/pr4209.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-incomplete-implementation -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-incomplete-implementation -verify %s
 
 // This test case was crashing due to how CFRefCount.cpp resolved the
 // ObjCInterfaceDecl* and ClassName in EvalObjCMessageExpr.
diff --git a/test/Analysis/pr_2542_rdar_6793404.m b/test/Analysis/pr_2542_rdar_6793404.m
index 6f1ebf9..5df40e8 100644
--- a/test/Analysis/pr_2542_rdar_6793404.m
+++ b/test/Analysis/pr_2542_rdar_6793404.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -pedantic -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -pedantic -analyzer-store=region -verify -Wno-objc-root-class %s
 
 // BEGIN delta-debugging reduced header stuff
 
diff --git a/test/Analysis/pr_4164.c b/test/Analysis/pr_4164.c
index 0d2ca41..02c1f41 100644
--- a/test/Analysis/pr_4164.c
+++ b/test/Analysis/pr_4164.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 // PR 4164: http://llvm.org/bugs/show_bug.cgi?id=4164
diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m
index b130534..542a339 100644
--- a/test/Analysis/properties.m
+++ b/test/Analysis/properties.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
 
 void clang_analyzer_eval(int);
 
@@ -315,6 +315,32 @@
 }
 @end
 
+__attribute__((objc_root_class))
+@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
+@end
+
+@protocol HasStuff
+@property (nonatomic, readonly) int stuffProperty;
+@end
+
+@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Private)
+@property (nonatomic, readonly) int stuffProperty;
+@end
+
+@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Internal) <HasStuff>
+@end
+
+@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory() <HasStuff>
+@end
+
+@implementation ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
+@synthesize stuffProperty = _stuffProperty;
+
+-(void)foo {
+  (void)self.stuffProperty;
+}
+@end
+
 //------
 // Setter ivar invalidation.
 //------
diff --git a/test/Analysis/properties.mm b/test/Analysis/properties.mm
index e49d034..2d93d6d 100644
--- a/test/Analysis/properties.mm
+++ b/test/Analysis/properties.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
diff --git a/test/Analysis/pthreadlock.c b/test/Analysis/pthreadlock.c
index a6e29e7..9886817 100644
--- a/test/Analysis/pthreadlock.c
+++ b/test/Analysis/pthreadlock.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.PthreadLock -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.PthreadLock -verify %s
 
 // Tests performing normal locking patterns and wrong locking orders
 
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
index 2b15bad..b78ec50 100644
--- a/test/Analysis/ptr-arith.c
+++ b/test/Analysis/ptr-arith.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare %s
 
 void clang_analyzer_eval(int);
 
@@ -213,7 +213,12 @@
   }
 
   clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}}
+// FIXME: In Z3ConstraintManager, ptrdiff_t is mapped to signed bitvector. However, this does not directly imply the unsigned comparison.
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}}
+#endif
   clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}
 
   if (lhs >= rhs) {
@@ -223,7 +228,11 @@
 
   clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
   clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}}
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}}
+#endif
 }
 
 void size_implies_comparison(int *lhs, int *rhs) {
@@ -234,7 +243,11 @@
     return;
   }
 
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(lhs <= rhs); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}}
+#endif
   clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}}
   clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}
 
@@ -244,7 +257,11 @@
   }
 
   clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(lhs < rhs); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}}
+#endif
   clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}}
 }
 
@@ -255,30 +272,42 @@
 void zero_implies_reversed_equal(int *lhs, int *rhs) {
   clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{UNKNOWN}}
   if ((rhs - lhs) == 0) {
-    // FIXME: Should be FALSE.
+#ifdef ANALYZER_CM_Z3
+    clang_analyzer_eval(rhs != lhs); // expected-warning{{FALSE}}
+    clang_analyzer_eval(rhs == lhs); // expected-warning{{TRUE}}
+#else
     clang_analyzer_eval(rhs != lhs); // expected-warning{{UNKNOWN}}
-    // FIXME: Should be TRUE.
     clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+#endif
     return;
   }
   clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}
-  // FIXME: Should be FALSE.
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(rhs == lhs); // expected-warning{{FALSE}}
+  clang_analyzer_eval(rhs != lhs); // expected-warning{{TRUE}}
+#else
   clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
-  // FIXME: Should be TRUE.
   clang_analyzer_eval(rhs != lhs); // expected-warning{{UNKNOWN}}
+#endif
 }
 
 void canonical_equal(int *lhs, int *rhs) {
   clang_analyzer_eval(lhs == rhs); // expected-warning{{UNKNOWN}}
   if (lhs == rhs) {
-    // FIXME: Should be TRUE.
+#ifdef ANALYZER_CM_Z3
+    clang_analyzer_eval(rhs == lhs); // expected-warning{{TRUE}}
+#else
     clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+#endif
     return;
   }
   clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
 
-  // FIXME: Should be FALSE.
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(rhs == lhs); // expected-warning{{FALSE}}
+#else
   clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+#endif
 }
 
 void compare_element_region_and_base(int *p) {
diff --git a/test/Analysis/ptr-arith.cpp b/test/Analysis/ptr-arith.cpp
index 07ddec3..e1860f4 100644
--- a/test/Analysis/ptr-arith.cpp
+++ b/test/Analysis/ptr-arith.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-unused-value -std=c++14 -analyze -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
+// RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14 -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
 struct X {
   int *p;
   int zero;
diff --git a/test/Analysis/qt_malloc.cpp b/test/Analysis/qt_malloc.cpp
index d29835f..ad25634 100644
--- a/test/Analysis/qt_malloc.cpp
+++ b/test/Analysis/qt_malloc.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus -analyzer-store=region -verify %s
 // expected-no-diagnostics
 #include "Inputs/qt-simulator.h"
 
@@ -13,3 +13,9 @@
   QEvent *e4 = new QEvent(QEvent::None);
   QApplication::postEvent(obj, e4);
 }
+
+void connect(QObject *obj) {
+  obj->connectImpl(nullptr, nullptr, nullptr, nullptr,
+                   new QtPrivate::QSlotObjectBase(), (Qt::ConnectionType)0,
+                   nullptr, nullptr);
+}
diff --git a/test/Analysis/range_casts.c b/test/Analysis/range_casts.c
index 682369c..a01ab5d 100644
--- a/test/Analysis/range_casts.c
+++ b/test/Analysis/range_casts.c
@@ -1,5 +1,5 @@
 // This test checks that intersecting ranges does not cause 'system is over constrained' assertions in the case of eg: 32 bits unsigned integers getting their range from 64 bits signed integers.
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s
 
 void clang_analyzer_warnIfReached();
 
diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m
index 31a300c..d840000 100644
--- a/test/Analysis/rdar-6442306-1.m
+++ b/test/Analysis/rdar-6442306-1.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-disable-checker=alpha.core.PointerArithm %s -analyzer-store=region -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-disable-checker=alpha.core.PointerArithm %s -analyzer-store=region -verify
 // expected-no-diagnostics
 
 typedef int bar_return_t;
diff --git a/test/Analysis/rdar-6540084.m b/test/Analysis/rdar-6540084.m
index 2119df5..da7d42c 100644
--- a/test/Analysis/rdar-6540084.m
+++ b/test/Analysis/rdar-6540084.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-checker=deadcode.DeadStores -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-checker=deadcode.DeadStores -verify %s
 //
 // This test exercises the live variables analysis (LiveVariables.cpp).
 // The case originally identified a non-termination bug.
diff --git a/test/Analysis/rdar-6541136-region.c b/test/Analysis/rdar-6541136-region.c
index 83b7605..dc75af4 100644
--- a/test/Analysis/rdar-6541136-region.c
+++ b/test/Analysis/rdar-6541136-region.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -analyze -analyzer-checker=core,alpha.security.ArrayBound -analyzer-store=region %s
+// RUN: %clang_analyze_cc1 -verify -analyzer-checker=core,alpha.security.ArrayBound -analyzer-store=region %s
 
 struct tea_cheese { unsigned magic; };
 typedef struct tea_cheese kernel_tea_cheese_t;
diff --git a/test/Analysis/rdar-6562655.m b/test/Analysis/rdar-6562655.m
index 9591f55..8794cac 100644
--- a/test/Analysis/rdar-6562655.m
+++ b/test/Analysis/rdar-6562655.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 //
 // This test case mainly checks that the retain/release checker doesn't crash
diff --git a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
index e9809db..72dbe42 100644
--- a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
+++ b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 typedef struct Foo { int x; } Bar;
diff --git a/test/Analysis/rdar-7168531.m b/test/Analysis/rdar-7168531.m
index b128d32..b2b1511 100644
--- a/test/Analysis/rdar-7168531.m
+++ b/test/Analysis/rdar-7168531.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -analyzer-store=region %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -analyzer-store=region %s
 
 // Note that the target triple is important for this test case.  It specifies that we use the
 // fragile Objective-C ABI.
diff --git a/test/Analysis/redefined_system.c b/test/Analysis/redefined_system.c
index 16f03ab..4901b3a 100644
--- a/test/Analysis/redefined_system.c
+++ b/test/Analysis/redefined_system.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx,unix,core,alpha.security.taint -w -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx,unix,core,alpha.security.taint -w -verify %s
 // expected-no-diagnostics
 
 // Make sure we don't crash when someone redefines a system function we reason about.
diff --git a/test/Analysis/refcnt_naming.m b/test/Analysis/refcnt_naming.m
index cff5970..c77909a 100644
--- a/test/Analysis/refcnt_naming.m
+++ b/test/Analysis/refcnt_naming.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-config ipa=none -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-config ipa=none -analyzer-store=region -verify %s
 
 typedef const struct __CFString * CFStringRef;
 typedef const struct __CFAllocator * CFAllocatorRef;
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index 951079d..b323b96 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -Wno-null-dereference -Wno-tautological-undefined-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -Wno-null-dereference -Wno-tautological-undefined-compare %s
 
 void clang_analyzer_eval(bool);
 
@@ -118,16 +118,30 @@
 }
 
 void testReferenceAddress(int &x) {
+// FIXME: Move non-zero reference assumption out of RangeConstraintManager.cpp:422
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(&x != 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(&ref() != 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(&x != 0); // expected-warning{{TRUE}}
   clang_analyzer_eval(&ref() != 0); // expected-warning{{TRUE}}
+#endif
 
   struct S { int &x; };
 
   extern S getS();
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(&getS().x != 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(&getS().x != 0); // expected-warning{{TRUE}}
+#endif
 
   extern S *getSP();
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{TRUE}}
+#endif
 }
 
 
diff --git a/test/Analysis/reference.mm b/test/Analysis/reference.mm
index c5546aa..1d73ccd 100644
--- a/test/Analysis/reference.mm
+++ b/test/Analysis/reference.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -Wno-null-dereference %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -Wno-null-dereference %s
 
 @interface Foo
 - (int &)ref;
diff --git a/test/Analysis/region-1.m b/test/Analysis/region-1.m
index 6940c69..3245bd4 100644
--- a/test/Analysis/region-1.m
+++ b/test/Analysis/region-1.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 //
 // This test case simply should not crash.  It evaluates the logic of not
diff --git a/test/Analysis/region-store.c b/test/Analysis/region-store.c
index 70bda11..673baaf 100644
--- a/test/Analysis/region-store.c
+++ b/test/Analysis/region-store.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,debug.ExprInspection -verify %s
 
 int printf(const char *restrict,...);
 
diff --git a/test/Analysis/region-store.cpp b/test/Analysis/region-store.cpp
index 5ea5c3f..cb49f48 100644
--- a/test/Analysis/region-store.cpp
+++ b/test/Analysis/region-store.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s
 // expected-no-diagnostics
 
 class Loc {
diff --git a/test/Analysis/reinterpret-cast.cpp b/test/Analysis/reinterpret-cast.cpp
index f3b0a7b..7b8c2f3 100644
--- a/test/Analysis/reinterpret-cast.cpp
+++ b/test/Analysis/reinterpret-cast.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/retain-release-arc.m b/test/Analysis/retain-release-arc.m
index 616e009..78115ac 100644
--- a/test/Analysis/retain-release-arc.m
+++ b/test/Analysis/retain-release-arc.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fobjc-arc -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fobjc-arc -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
 
 typedef __typeof(sizeof(int)) size_t;
 
@@ -90,7 +90,7 @@
   CFErrorRef error;
   CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error);
 #if HAS_ARC
-      // expected-note@-2 {{Call to function 'CFPropertyListCreateWithData' returns a Core Foundation object with a +1 retain count}}
+      // expected-note@-2 {{Call to function 'CFPropertyListCreateWithData' returns a Core Foundation object of type CFPropertyListRef with a +1 retain count}}
 #endif
   return (__bridge NSDictionary *)testDict;
 #if HAS_ARC
diff --git a/test/Analysis/retain-release-cache-out.m b/test/Analysis/retain-release-cache-out.m
index 54573a4..5e9ebc4 100644
--- a/test/Analysis/retain-release-cache-out.m
+++ b/test/Analysis/retain-release-cache-out.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze %s -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify
 
 // This test is checking behavior when a single checker runs only with the core
 // checkers, testing that the traversal order in the CFG does not affect the
diff --git a/test/Analysis/retain-release-cf-audited.m b/test/Analysis/retain-release-cf-audited.m
index c89172f..414ccd5 100644
--- a/test/Analysis/retain-release-cf-audited.m
+++ b/test/Analysis/retain-release-cf-audited.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -verify %s -x objective-c++
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.RetainCount -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.RetainCount -verify %s -x objective-c++
 
 // The special thing about this file is that CFRetain and CFRelease are marked
 // as cf_audited_transfer.
diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m
index 26eb6e1..6305942 100644
--- a/test/Analysis/retain-release-gc-only.m
+++ b/test/Analysis/retain-release-gc-only.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.NSAutoreleasePool -analyzer-store=region -fobjc-gc-only -fblocks -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple %itanium_abi_triple -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.NSAutoreleasePool -analyzer-store=region -fobjc-gc-only -fblocks -verify -Wno-objc-root-class %s
 
 //===----------------------------------------------------------------------===//
 // Header stuff.
diff --git a/test/Analysis/retain-release-inline.m b/test/Analysis/retain-release-inline.m
index 8809c8c..0cde2c1 100644
--- a/test/Analysis/retain-release-inline.m
+++ b/test/Analysis/retain-release-inline.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from Mac OS X headers:
diff --git a/test/Analysis/retain-release-path-notes-gc.m b/test/Analysis/retain-release-path-notes-gc.m
index 08e4151..04f9912 100644
--- a/test/Analysis/retain-release-path-notes-gc.m
+++ b/test/Analysis/retain-release-path-notes-gc.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 /***
@@ -40,12 +40,12 @@
 
 
 void creationViaCFCreate () {
-  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
   return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void makeCollectable () {
-  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
   CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
   CFMakeCollectable(leaked); // expected-note{{In GC mode a call to 'CFMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1}}
   NSMakeCollectable(leaked); // expected-note{{In GC mode a call to 'NSMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector}}
@@ -54,7 +54,7 @@
 }
 
 void retainReleaseIgnored () {
-  id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +0 retain count}}
+  id object = [[NSObject alloc] init]; // expected-note{{Method returns an instance of NSObject with a +0 retain count}}
   [object retain]; // expected-note{{In GC mode the 'retain' message has no effect}}
   [object release]; // expected-note{{In GC mode the 'release' message has no effect}}
   [object autorelease]; // expected-note{{In GC mode an 'autorelease' has no effect}}
@@ -63,12 +63,12 @@
 
 @implementation Foo (FundamentalRuleUnderGC)
 - (id)getViolation {
-  id object = (id) CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
+  id object = (id) CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
   return object; // expected-warning{{leak}} expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' and returned from method 'getViolation' is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector}}
 }
 
 - (id)copyViolation {
-  id object = (id) CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
+  id object = (id) CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
   return object; // expected-warning{{leak}} expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' and returned from method 'copyViolation' is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector}}
 }
 @end
@@ -137,9 +137,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -283,9 +283,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -729,9 +729,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +0 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +0 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1100,9 +1100,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1287,9 +1287,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m
index 51104fb..f44d40f 100644
--- a/test/Analysis/retain-release-path-notes.m
+++ b/test/Analysis/retain-release-path-notes.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t
 // RUN: FileCheck --input-file=%t %s
 
 /***
@@ -44,12 +44,12 @@
 
 
 void creationViaAlloc () {
-  id leaked = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
+  id leaked = [[NSObject alloc] init]; // expected-note{{Method returns an instance of NSObject with a +1 retain count}}
   return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void creationViaCFCreate () {
-  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count}}
   return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
@@ -68,25 +68,25 @@
 }
 
 void acquisitionViaCFFunction () {
-  CFTypeRef leaked = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count}}
+  CFTypeRef leaked = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count}}
   CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +1 retain count}}
   return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void explicitDealloc () {
-  id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
+  id object = [[NSObject alloc] init]; // expected-note{{Method returns an instance of NSObject with a +1 retain count}}
   [object dealloc]; // expected-note{{Object released by directly sending the '-dealloc' message}}
   [object class]; // expected-warning{{Reference-counted object is used after it is released}} // expected-note{{Reference-counted object is used after it is released}}
 }
 
 void implicitDealloc () {
-  id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
+  id object = [[NSObject alloc] init]; // expected-note{{Method returns an instance of NSObject with a +1 retain count}}
   [object release]; // expected-note{{Object released}}
   [object class]; // expected-warning{{Reference-counted object is used after it is released}} // expected-note{{Reference-counted object is used after it is released}}
 }
 
 void overAutorelease () {
-  id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
+  id object = [[NSObject alloc] init]; // expected-note{{Method returns an instance of NSObject with a +1 retain count}}
   [object autorelease]; // expected-note{{Object autoreleased}}
   [object autorelease]; // expected-note{{Object autoreleased}} 
   return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased 2 times but the object has a +1 retain count}} 
@@ -99,19 +99,19 @@
 }
 
 void makeCollectableIgnored () {
-  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count}}
   CFMakeCollectable(leaked); // expected-note{{When GC is not enabled a call to 'CFMakeCollectable' has no effect on its argument}}
   NSMakeCollectable(leaked); // expected-note{{When GC is not enabled a call to 'NSMakeCollectable' has no effect on its argument}}
   return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 CFTypeRef CFCopyRuleViolation () {
-  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count}}
+  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count}}
   return object; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object returned to caller with a +0 retain count}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
 }
 
 CFTypeRef CFGetRuleViolation () {
-  CFTypeRef object = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
+  CFTypeRef object = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count}}
   return object; // expected-warning{{leak}} expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' is returned from a function whose name ('CFGetRuleViolation') does not contain 'Copy' or 'Create'.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation}}
 }
 
@@ -132,12 +132,12 @@
 }
 
 - (id)getViolation {
-  id result = [[Foo alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
+  id result = [[Foo alloc] init]; // expected-note{{Method returns an instance of Foo with a +1 retain count}}
   return result; // expected-warning{{leak}} expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'result' is returned from a method whose name ('getViolation') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'.  This violates the naming convention rules given in the Memory Management Guide for Cocoa}}
 }
 
 - (id)copyAutorelease {
-  id result = [[Foo alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
+  id result = [[Foo alloc] init]; // expected-note{{Method returns an instance of Foo with a +1 retain count}}
   [result autorelease]; // expected-note{{Object autoreleased}}
   return result; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
 }
@@ -212,7 +212,7 @@
 }
 
 -(id)initY {
-  self = [super init]; //expected-note {{Method returns an Objective-C object with a +1 retain count}}
+  self = [super init]; //expected-note {{Method returns an instance of MyObj with a +1 retain count}}
   return self;
 }
 
@@ -224,7 +224,7 @@
 +(void)test {
   // initX is inlined since we explicitely mark it as interesting
   id x = [[MyObj alloc] initX]; // expected-warning {{Potential leak of an object}}
-                                // expected-note@-1 {{Method returns an Objective-C object with a +1 retain count}}
+                                // expected-note@-1 {{Method returns an instance of MyObj with a +1 retain count}}
                                 // expected-note@-2 {{Calling 'initX'}}
                                 // expected-note@-3 {{Returning from 'initX'}}
                                 // expected-note@-4 {{Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1}}
@@ -244,20 +244,20 @@
 
 
 void CFOverAutorelease() {
-  CFTypeRef object = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
+  CFTypeRef object = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object of type CFTypeRef with a +1 retain count}}
   CFAutorelease(object); // expected-note{{Object autoreleased}}
   CFAutorelease(object); // expected-note{{Object autoreleased}}
   return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased 2 times but the object has a +1 retain count}}
 }
 
 void CFAutoreleaseUnowned() {
-  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count}}
+  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count}}
   CFAutorelease(object); // expected-note{{Object autoreleased}}
   return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased but has a +0 retain count}}
 }
 
 void CFAutoreleaseUnownedMixed() {
-  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count}}
+  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object of type CFTypeRef with a +0 retain count}}
   CFAutorelease(object); // expected-note{{Object autoreleased}}
   [(id)object autorelease]; // expected-note{{Object autoreleased}}
   return; // expected-warning{{Object autoreleased too many times}} expected-note{{Object was autoreleased 2 times but the object has a +0 retain count}}
@@ -393,9 +393,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -539,9 +539,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1277,9 +1277,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object of type CFTypeRef with a +0 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object of type CFTypeRef with a +0 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1498,9 +1498,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1719,9 +1719,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -1940,9 +1940,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of NSObject with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -2457,9 +2457,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -2753,9 +2753,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object of type CFTypeRef with a +0 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object of type CFTypeRef with a +0 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -2940,9 +2940,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -3688,9 +3688,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of Foo with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of Foo with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -3875,9 +3875,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of Foo with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of Foo with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -4826,9 +4826,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of MyObj with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of MyObj with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -5354,9 +5354,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>1</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of MyObj with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns an instance of MyObj with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
@@ -5563,9 +5563,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object of type CFTypeRef with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -5859,9 +5859,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object of type CFTypeRef with a +0 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object of type CFTypeRef with a +0 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -6080,9 +6080,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object of type CFTypeRef with a +0 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object of type CFTypeRef with a +0 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m
index 3f83fb5..65a31cc 100644
--- a/test/Analysis/retain-release-region-store.m
+++ b/test/Analysis/retain-release-region-store.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-max-loop 6 -verify %s
+// RUN: %clang_analyze_cc1 -triple %itanium_abi_triple -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-max-loop 6 -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index b883a86..39a3baa 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1,6 +1,6 @@
 // RUN: rm -f %t.objc.plist %t.objcpp.plist
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s -analyzer-output=plist -o %t.objc.plist
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ -std=gnu++98 -Wno-objc-root-class %s -analyzer-output=plist -o %t.objcpp.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s -analyzer-output=plist -o %t.objc.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ -std=gnu++98 -Wno-objc-root-class %s -analyzer-output=plist -o %t.objcpp.plist
 // FIXLATER: cat %t.objc.plist ; FileCheck --input-file=%t.objc.plist %s
 // FIXLATER: cat %t.objcpp.plist ; FileCheck --input-file=%t.objcpp.plist %s
 
diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm
index 3650d88..c981700 100644
--- a/test/Analysis/retain-release.mm
+++ b/test/Analysis/retain-release.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify %s
 
 #if __has_feature(attribute_ns_returns_retained)
 #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
diff --git a/test/Analysis/return-ptr-range.cpp b/test/Analysis/return-ptr-range.cpp
index 0cc17b0..dd5dcd5 100644
--- a/test/Analysis/return-ptr-range.cpp
+++ b/test/Analysis/return-ptr-range.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.ReturnPtrRange -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.ReturnPtrRange -verify %s
 
 int arr[10];
 int *ptr;
diff --git a/test/Analysis/security-syntax-checks-no-emit.c b/test/Analysis/security-syntax-checks-no-emit.c
index 7759aa7..29dd201 100644
--- a/test/Analysis/security-syntax-checks-no-emit.c
+++ b/test/Analysis/security-syntax-checks-no-emit.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i686-pc-linux-gnu -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
 // expected-no-diagnostics
 
 // This file complements 'security-syntax-checks.m', but tests that we omit
diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m
index 9b7fb25..04a4c7d8 100644
--- a/test/Analysis/security-syntax-checks.m
+++ b/test/Analysis/security-syntax-checks.m
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
 
 #ifdef USE_BUILTINS
 # define BUILTIN(f) __builtin_ ## f
diff --git a/test/Analysis/self-assign.cpp b/test/Analysis/self-assign.cpp
index 74fb0fe..580a3ab 100644
--- a/test/Analysis/self-assign.cpp
+++ b/test/Analysis/self-assign.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,cplusplus,unix.Malloc,debug.ExprInspection %s -verify -analyzer-output=text
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,unix.Malloc,debug.ExprInspection %s -verify -analyzer-output=text
 
 extern "C" char *strdup(const char* s);
 extern "C" void free(void* ptr);
diff --git a/test/Analysis/self-init.m b/test/Analysis/self-init.m
index d1fb88d..cb1a321 100644
--- a/test/Analysis/self-init.m
+++ b/test/Analysis/self-init.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -analyzer-config ipa=dynamic -fno-builtin %s -verify
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fno-builtin %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.SelfInit -analyzer-config ipa=dynamic -fno-builtin %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.SelfInit -fno-builtin %s -verify
 
 @class NSZone, NSCoder;
 @protocol NSObject
diff --git a/test/Analysis/shallow-mode.m b/test/Analysis/shallow-mode.m
index 23df699..1c71e1b 100644
--- a/test/Analysis/shallow-mode.m
+++ b/test/Analysis/shallow-mode.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config mode=shallow -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config mode=shallow -verify %s
 // expected-no-diagnostics
 
 void clang_analyzer_checkInlined(unsigned);
diff --git a/test/Analysis/simple-stream-checks.c b/test/Analysis/simple-stream-checks.c
index 2f72574..f47e488 100644
--- a/test/Analysis/simple-stream-checks.c
+++ b/test/Analysis/simple-stream-checks.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.unix.SimpleStream -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.SimpleStream -verify %s
 
 #include "Inputs/system-header-simulator-for-simple-stream.h"
 
diff --git a/test/Analysis/sizeofpointer.c b/test/Analysis/sizeofpointer.c
index a9e045b..14ddbd1 100644
--- a/test/Analysis/sizeofpointer.c
+++ b/test/Analysis/sizeofpointer.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.SizeofPtr -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.SizeofPtr -verify %s
 
 struct s {
 };
diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c
index d668f8f..4026cee 100644
--- a/test/Analysis/stack-addr-ps.c
+++ b/test/Analysis/stack-addr-ps.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
 
 int* f1() {
   int x = 0;
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
index a4ab2f3..79afd18 100644
--- a/test/Analysis/stack-addr-ps.cpp
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s -Wno-undefined-bool-conversion
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify %s -Wno-undefined-bool-conversion
 
 typedef __INTPTR_TYPE__ intptr_t;
 
diff --git a/test/Analysis/stack-block-returned.cpp b/test/Analysis/stack-block-returned.cpp
index af2cec7..b45cf63 100644
--- a/test/Analysis/stack-block-returned.cpp
+++ b/test/Analysis/stack-block-returned.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
 
 typedef void (^bptr)(void);
 
diff --git a/test/Analysis/stackaddrleak.c b/test/Analysis/stackaddrleak.c
index 717f309..a037d12 100644
--- a/test/Analysis/stackaddrleak.c
+++ b/test/Analysis/stackaddrleak.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool -Wno-bool-conversion %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ -Wno-bool-conversion %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -std=c99 -Dbool=_Bool -Wno-bool-conversion %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -x c++ -Wno-bool-conversion %s
 
 typedef __INTPTR_TYPE__ intptr_t;
 char const *p;
diff --git a/test/Analysis/static_local.m b/test/Analysis/static_local.m
index dcd49e1..daa7ef5 100644
--- a/test/Analysis/static_local.m
+++ b/test/Analysis/static_local.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 // Test reasoning about static locals in ObjCMethods. 
diff --git a/test/Analysis/stats.c b/test/Analysis/stats.c
index 5701dc7..eca83c0 100644
--- a/test/Analysis/stats.c
+++ b/test/Analysis/stats.c
@@ -1,5 +1,5 @@
 // REQUIRES: asserts
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-stats %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-stats %s 2>&1 | FileCheck %s
 
 void foo() {
   int x;
diff --git a/test/Analysis/std-c-library-functions.c b/test/Analysis/std-c-library-functions.c
index 6b78a26..042b035 100644
--- a/test/Analysis/std-c-library-functions.c
+++ b/test/Analysis/std-c-library-functions.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -triple i686-unknown-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -triple armv7-a15-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -triple thumbv7-a15-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple armv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple thumbv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/std-c-library-functions.cpp b/test/Analysis/std-c-library-functions.cpp
index e6ac66b..00b341a 100644
--- a/test/Analysis/std-c-library-functions.cpp
+++ b/test/Analysis/std-c-library-functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
 
 // Test that we don't model functions with broken prototypes.
 // Because they probably work differently as well.
diff --git a/test/Analysis/stream.c b/test/Analysis/stream.c
index 329a782..7adf14b 100644
--- a/test/Analysis/stream.c
+++ b/test/Analysis/stream.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.Stream -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.Stream -analyzer-store region -verify %s
 
 typedef __typeof__(sizeof(int)) size_t;
 typedef struct _IO_FILE FILE;
diff --git a/test/Analysis/string-fail.c b/test/Analysis/string-fail.c
index ac5c6d0..ff95ea9 100644
--- a/test/Analysis/string-fail.c
+++ b/test/Analysis/string-fail.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
 // XFAIL: *
 
 // This file is for tests that may eventually go into string.c, or may be
diff --git a/test/Analysis/string.c b/test/Analysis/string.c
index e541219..8ea2068 100644
--- a/test/Analysis/string.c
+++ b/test/Analysis/string.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
 
 //===----------------------------------------------------------------------===
 // Declarations
diff --git a/test/Analysis/superclass.m b/test/Analysis/superclass.m
index 3102d1f..1729359 100644
--- a/test/Analysis/superclass.m
+++ b/test/Analysis/superclass.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=osx.cocoa.MissingSuperCall -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=osx.cocoa.MissingSuperCall -verify -Wno-objc-root-class %s
 
 // Define used Classes
 @protocol NSObject
diff --git a/test/Analysis/svalbuilder-logic.c b/test/Analysis/svalbuilder-logic.c
index 9cf3f96..1595acb 100644
--- a/test/Analysis/svalbuilder-logic.c
+++ b/test/Analysis/svalbuilder-logic.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s
 // expected-no-diagnostics
 
 // Testing core functionality of the SValBuilder.
diff --git a/test/Analysis/switch-case.c b/test/Analysis/switch-case.c
index 08a61a0..0840393 100644
--- a/test/Analysis/switch-case.c
+++ b/test/Analysis/switch-case.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_warnIfReached();
diff --git a/test/Analysis/symbol-reaper.c b/test/Analysis/symbol-reaper.c
index 362a22d..72fcc7e 100644
--- a/test/Analysis/symbol-reaper.c
+++ b/test/Analysis/symbol-reaper.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_warnOnDeadSymbol(int);
diff --git a/test/Analysis/taint-diagnostic-visitor.c b/test/Analysis/taint-diagnostic-visitor.c
new file mode 100644
index 0000000..50fc0b6
--- /dev/null
+++ b/test/Analysis/taint-diagnostic-visitor.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.taint,core -analyzer-output=text -verify %s
+
+// This file is for testing enhanced diagnostics produced by the GenericTaintChecker
+
+int scanf(const char *restrict format, ...);
+int system(const char *command);
+
+void taintDiagnostic()
+{
+  char buf[128];
+  scanf("%s", buf); // expected-note {{Taint originated here}}
+  system(buf); // expected-warning {{Untrusted data is passed to a system call}} // expected-note {{Untrusted data is passed to a system call (CERT/STR02-C. Sanitize data passed to complex subsystems)}}
+}
diff --git a/test/Analysis/taint-generic.c b/test/Analysis/taint-generic.c
index fe27070..8efed66 100644
--- a/test/Analysis/taint-generic.c
+++ b/test/Analysis/taint-generic.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -analyze -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -Wno-format-security -verify %s
+// RUN: %clang_analyze_cc1  -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -Wno-format-security -verify %s
 
 int scanf(const char *restrict format, ...);
 int getchar(void);
@@ -169,6 +169,43 @@
   sock = socket(AF_LOCAL, SOCK_STREAM, 0);
   read(sock, buffer, 100);
   execl(buffer, "filename", 0); // no-warning
+
+  sock = socket(AF_INET, SOCK_STREAM, 0);
+  // References to both buffer and &buffer as an argument should taint the argument
+  read(sock, &buffer, 100);
+  execl(buffer, "filename", 0); // expected-warning {{Untrusted data is passed to a system call}}
+}
+
+void testStruct() {
+  struct {
+    char buf[16];
+    int length;
+  } tainted;
+
+  char buffer[16];
+  int sock;
+
+  sock = socket(AF_INET, SOCK_STREAM, 0);
+  read(sock, &tainted, sizeof(tainted));
+  __builtin_memcpy(buffer, tainted.buf, tainted.length); // expected-warning {{Untrusted data is used to specify the buffer size}}
+}
+
+void testStructArray() {
+  struct {
+    char buf[16];
+    struct {
+      int length;
+    } st[1];
+  } tainted;
+
+  char buffer[16];
+  int sock;
+
+  sock = socket(AF_INET, SOCK_STREAM, 0);
+  read(sock, &tainted.buf[0], sizeof(tainted.buf));
+  read(sock, &tainted.st[0], sizeof(tainted.st));
+  // FIXME: tainted.st[0].length should be marked tainted
+  __builtin_memcpy(buffer, tainted.buf, tainted.st[0].length); // no-warning
 }
 
 int testDivByZero() {
diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c
index 6287198..1b59e7b 100644
--- a/test/Analysis/taint-tester.c
+++ b/test/Analysis/taint-tester.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
+// RUN: %clang_analyze_cc1 -Wno-int-to-pointer-cast -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/taint-tester.cpp b/test/Analysis/taint-tester.cpp
index ca7b729..23a92cc 100644
--- a/test/Analysis/taint-tester.cpp
+++ b/test/Analysis/taint-tester.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
+// RUN: %clang_analyze_cc1  -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
 // expected-no-diagnostics
 
 typedef struct _FILE FILE;
diff --git a/test/Analysis/taint-tester.m b/test/Analysis/taint-tester.m
index b5663ca..531c21b 100644
--- a/test/Analysis/taint-tester.m
+++ b/test/Analysis/taint-tester.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
+// RUN: %clang_analyze_cc1  -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
 // expected-no-diagnostics
 
 #import <stdarg.h>
diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp
index a9e4556..372443b 100644
--- a/test/Analysis/temp-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp
@@ -1,7 +1,7 @@
 // RUN: rm -f %t
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true -std=c++98 %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true -std=c++98 %s > %t 2>&1
 // RUN: FileCheck --input-file=%t -check-prefix=CXX98 -check-prefix=CHECK %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1
 // RUN: FileCheck --input-file=%t -check-prefix=CXX11 -check-prefix=CHECK %s
 
 class A {
diff --git a/test/Analysis/templates.cpp b/test/Analysis/templates.cpp
index 131794a..c1631e0 100644
--- a/test/Analysis/templates.cpp
+++ b/test/Analysis/templates.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fblocks -analyzer-config c++-template-inlining=false -DNO_INLINE -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -fblocks -analyzer-config c++-template-inlining=false -DNO_INLINE -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp
index e96e9b0..2c052f8 100644
--- a/test/Analysis/temporaries.cpp
+++ b/test/Analysis/temporaries.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++03 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++11 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true %s -std=c++11
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++03 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true %s -std=c++11
 
 extern bool clang_analyzer_eval(bool);
 extern bool clang_analyzer_warnIfReached();
@@ -413,6 +413,32 @@
       value ? DefaultParam(42) : DefaultParam(42);
     }
   }
+#else // !TEMPORARY_DTORS
+
+// Test for fallback logic that conservatively stops exploration after
+// executing a temporary constructor for a class with a no-return destructor
+// when temporary destructors are not enabled in the CFG.
+
+  struct CtorWithNoReturnDtor {
+    CtorWithNoReturnDtor() = default;
+
+    ~CtorWithNoReturnDtor() __attribute__((noreturn));
+  };
+
+  void testDefaultContructorWithNoReturnDtor() {
+    CtorWithNoReturnDtor();
+    clang_analyzer_warnIfReached();  // no-warning
+  }
+
+  void testLifeExtensionWithNoReturnDtor() {
+    const CtorWithNoReturnDtor &c = CtorWithNoReturnDtor();
+
+    // This represents an (expected) loss of coverage, since the destructor
+    // of the lifetime-exended temporary is executed at at the end of
+    // scope.
+    clang_analyzer_warnIfReached();  // no-warning
+  }
+
 #endif // TEMPORARY_DTORS
 }
 
@@ -467,3 +493,13 @@
     clang_analyzer_eval(x == 47); // expected-warning{{TRUE}}
   }
 }
+
+namespace PR32088 {
+  void testReturnFromStmtExprInitializer() {
+    // We shouldn't try to destroy the object pointed to by `obj' upon return.
+    const NonTrivial &obj = ({
+      return; // no-crash
+      NonTrivial(42);
+    });
+  }
+}
diff --git a/test/Analysis/test-after-div-zero.c b/test/Analysis/test-after-div-zero.c
index f34c4f7..159c80c 100644
--- a/test/Analysis/test-after-div-zero.c
+++ b/test/Analysis/test-after-div-zero.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c99 -Dbool=_Bool -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -x c++ -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -std=c99 -Dbool=_Bool -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -x c++ -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
 
 int var;
 
diff --git a/test/Analysis/test-include-cpp.cpp b/test/Analysis/test-include-cpp.cpp
index 2ac5e11..6998e3c 100644
--- a/test/Analysis/test-include-cpp.cpp
+++ b/test/Analysis/test-include-cpp.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 #include "test-include-cpp.h"
 
diff --git a/test/Analysis/test-include.c b/test/Analysis/test-include.c
index 6aa80b9..20aa244 100644
--- a/test/Analysis/test-include.c
+++ b/test/Analysis/test-include.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 #include "test-include.h"
 #define DIVYX(X,Y) Y/X
diff --git a/test/Analysis/test-objc-non-nil-return-value-checker.m b/test/Analysis/test-objc-non-nil-return-value-checker.m
index 8b1e6a5..2a90636 100644
--- a/test/Analysis/test-objc-non-nil-return-value-checker.m
+++ b/test/Analysis/test-objc-non-nil-return-value-checker.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.NonNilReturnValue,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.NonNilReturnValue,debug.ExprInspection -verify %s
 
 typedef unsigned int NSUInteger;
 typedef signed char BOOL;
diff --git a/test/Analysis/test-variably-modified-types.c b/test/Analysis/test-variably-modified-types.c
index a833434..1df57af 100644
--- a/test/Analysis/test-variably-modified-types.c
+++ b/test/Analysis/test-variably-modified-types.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyze-function=testVariablyModifiedTypes -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyze-function=testVariablyModifiedTypes -verify %s
 
 // Test that we process variably modified type correctly - the call graph construction should pick up function_with_bug while recursively visiting test_variably_modifiable_types.
 unsigned getArraySize(int *x) {
diff --git a/test/Analysis/traversal-algorithm.mm b/test/Analysis/traversal-algorithm.mm
index 8a3dc8b..bdf5760 100644
--- a/test/Analysis/traversal-algorithm.mm
+++ b/test/Analysis/traversal-algorithm.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpTraversal -analyzer-max-loop 4 -std=c++11 %s | FileCheck -check-prefix=DFS %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpTraversal -analyzer-max-loop 4 -std=c++11 %s | FileCheck -check-prefix=DFS %s
 
 int a();
 int b();
diff --git a/test/Analysis/traversal-begin-end-function.c b/test/Analysis/traversal-begin-end-function.c
index 810ce1d..9d46f26 100644
--- a/test/Analysis/traversal-begin-end-function.c
+++ b/test/Analysis/traversal-begin-end-function.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.DumpTraversal %s | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.DumpTraversal %s | FileCheck %s
 
 void inline_callee(int i);
 
diff --git a/test/Analysis/traversal-path-unification.c b/test/Analysis/traversal-path-unification.c
index 3bf6df7..28a1511 100644
--- a/test/Analysis/traversal-path-unification.c
+++ b/test/Analysis/traversal-path-unification.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.DumpTraversal %s | FileCheck %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.DumpTraversal -DUSE_EXPR %s | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.DumpTraversal %s | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.DumpTraversal -DUSE_EXPR %s | FileCheck %s
 
 int a();
 int b();
diff --git a/test/Analysis/ubigraph-viz.cpp b/test/Analysis/ubigraph-viz.cpp
index 0cb9bd6..228dd66 100644
--- a/test/Analysis/ubigraph-viz.cpp
+++ b/test/Analysis/ubigraph-viz.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -analyzer-viz-egraph-ubigraph -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API -analyzer-viz-egraph-ubigraph -verify %s
 // expected-no-diagnostics
 
 int f(int x) {
diff --git a/test/Analysis/undef-buffers.c b/test/Analysis/undef-buffers.c
index 1581b2b..d5802fb 100644
--- a/test/Analysis/undef-buffers.c
+++ b/test/Analysis/undef-buffers.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,core.uninitialized -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,core.uninitialized -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
 void free(void *);
diff --git a/test/Analysis/uninit-const.c b/test/Analysis/uninit-const.c
index 9e42d23..9a6529a 100644
--- a/test/Analysis/uninit-const.c
+++ b/test/Analysis/uninit-const.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc,core,alpha.core.CallAndMessageUnInitRefArg -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.Malloc,core,alpha.core.CallAndMessageUnInitRefArg -analyzer-output=text -verify %s
 
 // Passing uninitialized const data to function
 #include "Inputs/system-header-simulator.h"
@@ -24,16 +24,16 @@
 void f_1(void) {
   int t;
   int* tp = &t;        // expected-note {{'tp' initialized here}}
-  doStuff_pointerToConstInt(tp);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(tp);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_1_1(void) {
   int t;
   int* tp1 = &t;
   int* tp2 = tp1;        // expected-note {{'tp2' initialized here}}
-  doStuff_pointerToConstInt(tp2);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(tp2);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 
@@ -45,8 +45,8 @@
   int t;
   int* p = f_2_sub(&t);
   int* tp = p; // expected-note {{'tp' initialized here}}
-  doStuff_pointerToConstInt(tp); // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                      // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                      // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 int z;
@@ -62,14 +62,14 @@
 void f_5(void) {
   int ta[5];
   int* tp = ta;        // expected-note {{'tp' initialized here}}
-  doStuff_pointerToConstInt(tp);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(tp);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_5_1(void) {
   int ta[5];        // expected-note {{'ta' initialized here}}
-  doStuff_pointerToConstInt(ta);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(ta);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_6(void) {
@@ -92,27 +92,27 @@
 
 void f_8(void) {
       int g;       // expected-note {{'g' declared without an initial value}}
-      doStuff2(g); // expected-warning {{Function call argument is an uninitialized value}}
-                   // expected-note@-1 {{Function call argument is an uninitialized value}}
+      doStuff2(g); // expected-warning {{1st function call argument is an uninitialized value}}
+                   // expected-note@-1 {{1st function call argument is an uninitialized value}}
 }
 
 void f_9(void) {
   int  a[6];
   int const *ptau = a;             // expected-note {{'ptau' initialized here}}
-  doStuff_arrayOfConstInt(ptau);    // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                                   // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_arrayOfConstInt(ptau);    // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                                   // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_10(void) {
   int  a[6];                     // expected-note {{'a' initialized here}}
-  doStuff_arrayOfConstInt(a);    // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                                 // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_arrayOfConstInt(a);    // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                                 // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_11(void) {
   int t[10];                    //expected-note {{'t' initialized here}}
-  doStuff_constStaticSizedArray(t);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                                // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_constStaticSizedArray(t);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                                // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_12(void) {
@@ -126,8 +126,8 @@
 
   ptr = (int *)malloc(sizeof(int)); // expected-note {{Value assigned to 'ptr'}}
 
-  doStuff_pointerToConstInt(ptr); // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(ptr); // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
   free(ptr);
   return 0;
 }
@@ -148,16 +148,16 @@
   int t;
   int v;
   int* tp = &t;           // expected-note {{'tp' initialized here}}
-  doStuff_variadic(tp,v);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                          // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_variadic(tp,v);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                          // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 // uninit pointer, init val
 void f_variadic_unp_inv(void) {
   int t;
   int v = 3;
   int* tp = &t;           // expected-note {{'tp' initialized here}}
-  doStuff_variadic(tp,v);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                          // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_variadic(tp,v);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                          // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 // init pointer, uninit val
@@ -165,8 +165,8 @@
   int t=5;
   int v;                  // expected-note {{'v' declared without an initial value}}
   int* tp = &t;
-  doStuff_variadic(tp,v);// expected-warning {{Function call argument is an uninitialized value}}
-                          // expected-note@-1 {{Function call argument is an uninitialized value}}
+  doStuff_variadic(tp,v);// expected-warning {{2nd function call argument is an uninitialized value}}
+                          // expected-note@-1 {{2nd function call argument is an uninitialized value}}
 }
 
 // init pointer, init val
@@ -192,8 +192,8 @@
   int u=3;
   int *vp = &u ;
   int *tp = &t;             // expected-note {{'tp' initialized here}}
-  doStuff_variadic(tp,vp); // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                            // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_variadic(tp,vp); // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                            // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 //init pointer, uninit pointer
@@ -211,6 +211,6 @@
   int u;
   int *vp = &u ;
   int *tp = &t;             // expected-note {{'tp' initialized here}}
-  doStuff_variadic(tp,vp); // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                            // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_variadic(tp,vp); // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                            // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
diff --git a/test/Analysis/uninit-const.cpp b/test/Analysis/uninit-const.cpp
index 56bfa08..75e932a 100644
--- a/test/Analysis/uninit-const.cpp
+++ b/test/Analysis/uninit-const.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,core,alpha.core.CallAndMessageUnInitRefArg -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,core,alpha.core.CallAndMessageUnInitRefArg -analyzer-output=text -verify %s
 // Passing uninitialized const data to unknown function
 
 #include "Inputs/system-header-simulator-cxx.h"
@@ -66,8 +66,8 @@
   int &p = t;
   int &s = p;
   int &q = s;  //expected-note {{'q' initialized here}}
-  doStuff6(q); //expected-warning {{Function call argument is an uninitialized value}}
-               //expected-note@-1 {{Function call argument is an uninitialized value}}
+  doStuff6(q); //expected-warning {{1st function call argument is an uninitialized value}}
+               //expected-note@-1 {{1st function call argument is an uninitialized value}}
 }
 
 void doStuff6_3(int& q_, int *ptr_) {}
@@ -78,15 +78,15 @@
   int &p = t;
   int &s = p;
   int &q = s;
-  doStuff6_3(q,ptr); //expected-warning {{Function call argument is an uninitialized value}}
-               //expected-note@-1 {{Function call argument is an uninitialized value}}
+  doStuff6_3(q,ptr); //expected-warning {{2nd function call argument is an uninitialized value}}
+               //expected-note@-1 {{2nd function call argument is an uninitialized value}}
 
 }
 
 void f6(void) {
   int k;       // expected-note {{'k' declared without an initial value}}
-  doStuff6(k); // expected-warning {{Function call argument is an uninitialized value}}
-               // expected-note@-1 {{Function call argument is an uninitialized value}}
+  doStuff6(k); // expected-warning {{1st function call argument is an uninitialized value}}
+               // expected-note@-1 {{1st function call argument is an uninitialized value}}
 
 }
 
@@ -95,15 +95,15 @@
 void f5(void) {
   int t;
   int* tp = &t;        // expected-note {{'tp' initialized here}}
-  doStuff_uninit(tp);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_uninit(tp);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 
 void f4(void) {
       int y;        // expected-note {{'y' declared without an initial value}}
-      doStuff4(y);  // expected-warning {{Function call argument is an uninitialized value}}
-                    // expected-note@-1 {{Function call argument is an uninitialized value}}
+      doStuff4(y);  // expected-warning {{1st function call argument is an uninitialized value}}
+                    // expected-note@-1 {{1st function call argument is an uninitialized value}}
 }
 
 void f3(void) {
@@ -123,6 +123,6 @@
 
 void f_uninit(void) {
       int x;
-      doStuff_uninit(&x);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                           // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+      doStuff_uninit(&x);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                           // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
diff --git a/test/Analysis/uninit-msg-expr.m b/test/Analysis/uninit-msg-expr.m
index 19fdf61..8454137 100644
--- a/test/Analysis/uninit-msg-expr.m
+++ b/test/Analysis/uninit-msg-expr.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
@@ -52,5 +52,5 @@
 void f3() {
   NSMutableArray *aArray = [NSArray array];
   NSString *aString;
-  [aArray addObject:aString]; // expected-warning {{Argument in message expression is an uninitialized value}}
+  [aArray addObject:aString]; // expected-warning {{1st argument in message expression is an uninitialized value}}
 }
diff --git a/test/Analysis/uninit-ps-rdar6145427.m b/test/Analysis/uninit-ps-rdar6145427.m
index c18116f..d735f17 100644
--- a/test/Analysis/uninit-ps-rdar6145427.m
+++ b/test/Analysis/uninit-ps-rdar6145427.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -analyzer-store=region %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -analyzer-store=region %s
 
 // Delta-Debugging reduced preamble.
 typedef signed char BOOL;
diff --git a/test/Analysis/uninit-vals-ps-region.m b/test/Analysis/uninit-vals-ps-region.m
index 87256b3..18010f2 100644
--- a/test/Analysis/uninit-vals-ps-region.m
+++ b/test/Analysis/uninit-vals-ps-region.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core -verify %s
 
 struct s {
   int data;
diff --git a/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c
index ad40b15..ee25d9d 100644
--- a/test/Analysis/uninit-vals-ps.c
+++ b/test/Analysis/uninit-vals-ps.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
 
 struct FPRec {
   void (*my_func)(int * x);  
@@ -14,7 +14,7 @@
 
 int f1_b() {
   int x;
-  return bar(x)+1;  // expected-warning{{Function call argument is an uninitialized value}}
+  return bar(x)+1;  // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 int f2() {
@@ -57,6 +57,12 @@
   return s.x; // no-warning
 }
 
+void f6(int x) {
+  int a[20];
+  if (x == 25) {}
+  if (a[x] == 123) {} // expected-warning{{The left operand of '==' is a garbage value due to array index out of bounds}}
+}
+
 int ret_uninit() {
   int i;
   int *p = &i;
diff --git a/test/Analysis/uninit-vals-union.c b/test/Analysis/uninit-vals-union.c
index 927dfa2..b433e7b 100644
--- a/test/Analysis/uninit-vals-union.c
+++ b/test/Analysis/uninit-vals-union.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core.builtin -analyzer-store=region -verify -Wno-unused %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.builtin -analyzer-store=region -verify -Wno-unused %s
 
 typedef union {
   int y;
diff --git a/test/Analysis/uninit-vals.cpp b/test/Analysis/uninit-vals.cpp
index 387c375..5ab1348 100644
--- a/test/Analysis/uninit-vals.cpp
+++ b/test/Analysis/uninit-vals.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core.builtin -verify -DCHECK_FOR_CRASH %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.builtin -verify -DCHECK_FOR_CRASH %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 #ifdef CHECK_FOR_CRASH
 // expected-no-diagnostics
@@ -27,7 +27,7 @@
   // case with undefined values, too.
   c1.b.a = c2->b.a;
 #else
-  c1.b.a = c2->b.a; // expected-warning{{Function call argument is an uninitialized value}}
+  c1.b.a = c2->b.a; // expected-warning{{1st function call argument is an uninitialized value}}
 #endif
 }
 }
diff --git a/test/Analysis/uninit-vals.m b/test/Analysis/uninit-vals.m
index 72b6739..7c18dee 100644
--- a/test/Analysis/uninit-vals.m
+++ b/test/Analysis/uninit-vals.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
 
 typedef unsigned int NSUInteger;
 typedef __typeof__(sizeof(int)) size_t;
diff --git a/test/Analysis/unions-region.m b/test/Analysis/unions-region.m
index 636198a..bad159f 100644
--- a/test/Analysis/unions-region.m
+++ b/test/Analysis/unions-region.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region %s -verify
 // expected-no-diagnostics
 
 //===-- unions-region.m ---------------------------------------------------===//
diff --git a/test/Analysis/unions.cpp b/test/Analysis/unions.cpp
index f363ab8..2758cda 100644
--- a/test/Analysis/unions.cpp
+++ b/test/Analysis/unions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -verify
 
 extern void clang_analyzer_eval(bool);
 extern "C" char *strdup(const char *s);
diff --git a/test/Analysis/unix-api.c b/test/Analysis/unix-api.c
index 86c702d..64ff3c0 100644
--- a/test/Analysis/unix-api.c
+++ b/test/Analysis/unix-api.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API -verify %s
 
 #ifndef O_RDONLY
 #define O_RDONLY 0
@@ -9,6 +9,7 @@
 #endif
 
 int open(const char *, int, ...);
+int openat(int, const char *, int, ...);
 int close(int fildes);
 
 void open_1(const char *path) {
@@ -21,21 +22,37 @@
 void open_2(const char *path) {
   int fd;
   int mode = 0x0;
-  fd = open(path, O_RDONLY, mode, NULL); // expected-warning{{Call to 'open' with more than three arguments}}
+  fd = open(path, O_RDONLY, mode, NULL); // expected-warning{{Call to 'open' with more than 3 arguments}}
+  if (fd > -1)
+    close(fd);
+}
+
+void openat_2(int base_fd, const char *path) {
+  int fd;
+  int mode = 0x0;
+  fd = openat(base_fd, path, O_RDONLY, mode, NULL); // expected-warning{{Call to 'openat' with more than 4 arguments}}
   if (fd > -1)
     close(fd);
 }
 
 void open_3(const char *path) {
   int fd;
-  fd = open(path, O_RDONLY, NULL); // expected-warning{{Third argument to 'open' is not an integer}}
+  fd = open(path, O_RDONLY, NULL); // expected-warning{{The 3rd argument to 'open' is not an integer}}
   if (fd > -1)
     close(fd);
 }
 
+void openat_3(int base_fd, const char *path) {
+  int fd;
+  fd = openat(base_fd, path, O_RDONLY, NULL); // expected-warning{{The 4th argument to 'openat' is not an integer}}
+  if (fd > -1)
+    close(fd);
+}
+
+
 void open_4(const char *path) {
   int fd;
-  fd = open(path, O_RDONLY, ""); // expected-warning{{Third argument to 'open' is not an integer}}
+  fd = open(path, O_RDONLY, ""); // expected-warning{{The 3rd argument to 'open' is not an integer}}
   if (fd > -1)
     close(fd);
 }
@@ -45,7 +62,7 @@
   struct {
     int val;
   } st = {0};
-  fd = open(path, O_RDONLY, st); // expected-warning{{Third argument to 'open' is not an integer}}
+  fd = open(path, O_RDONLY, st); // expected-warning{{The 3rd argument to 'open' is not an integer}}
   if (fd > -1)
     close(fd);
 }
@@ -62,14 +79,14 @@
 
 void open_7(const char *path) {
   int fd;
-  fd = open(path, O_RDONLY, &open); // expected-warning{{Third argument to 'open' is not an integer}}
+  fd = open(path, O_RDONLY, &open); // expected-warning{{The 3rd argument to 'open' is not an integer}}
   if (fd > -1)
     close(fd);
 }
 
 void open_8(const char *path) {
   int fd;
-  fd = open(path, O_RDONLY, 0.0f); // expected-warning{{Third argument to 'open' is not an integer}}
+  fd = open(path, O_RDONLY, 0.0f); // expected-warning{{The 3rd argument to 'open' is not an integer}}
   if (fd > -1)
     close(fd);
 }
diff --git a/test/Analysis/unix-api.cpp b/test/Analysis/unix-api.cpp
new file mode 100644
index 0000000..2b07d88
--- /dev/null
+++ b/test/Analysis/unix-api.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API -verify %s
+extern "C" {
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif
+
+int open(const char *, int, ...);
+int close(int fildes);
+
+} // extern "C"
+
+namespace MyNameSpace {
+int open(const char *a, int b, int c, int d);
+}
+
+void unix_open(const char *path) {
+  int fd;
+  fd = open(path, O_RDONLY); // no-warning
+  if (fd > -1)
+    close(fd);
+}
+
+void unix_open_misuse(const char *path) {
+  int fd;
+  int mode = 0x0;
+  fd = open(path, O_RDONLY, mode, NULL); // expected-warning{{Call to 'open' with more than 3 arguments}}
+  if (fd > -1)
+    close(fd);
+}
+
+// Don't treat open() in namespaces as the POSIX open()
+void namespaced_open(const char *path) {
+  MyNameSpace::open("Hi", 2, 3, 4); // no-warning
+
+  using namespace MyNameSpace;
+
+  open("Hi", 2, 3, 4); // no-warning
+
+  int fd;
+  int mode = 0x0;
+  fd = ::open(path, O_RDONLY, mode, NULL); // expected-warning{{Call to 'open' with more than 3 arguments}}
+  if (fd > -1)
+    close(fd);
+}
+
+class MyClass {
+public:
+  static int open(const char *a, int b, int c, int d);
+
+  int open(int a, int, int c, int d);
+};
+
+void class_qualified_open() {
+  MyClass::open("Hi", 2, 3, 4); // no-warning
+
+  MyClass mc;
+  mc.open(1, 2, 3, 4); // no-warning
+}
diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c
index df9edc4..3eccd51 100644
--- a/test/Analysis/unix-fns.c
+++ b/test/Analysis/unix-fns.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,unix.API,osx.API %s -analyzer-store=region -analyzer-output=plist -analyzer-eagerly-assume -analyzer-config faux-bodies=true -analyzer-config path-diagnostics-alternate=false -fblocks -verify -o %t.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,unix.API,osx.API %s -analyzer-store=region -analyzer-output=plist -analyzer-eagerly-assume -analyzer-config faux-bodies=true -analyzer-config path-diagnostics-alternate=false -fblocks -verify -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 // RUN: mkdir -p %t.dir
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API,osx.API -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %t.dir %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API,osx.API -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %t.dir %s
 // RUN: rm -fR %t.dir
 struct _opaque_pthread_once_t {
   long __sig;
@@ -44,6 +44,7 @@
 #define O_RDONLY 0x0000
 #endif
 int open(const char *, int, ...);
+int openat(int, const char *, int, ...);
 int close(int fildes);
 
 void test_open(const char *path) {
@@ -52,11 +53,22 @@
   if (!fd)
     close(fd);
 
-  fd = open(path, O_CREAT); // expected-warning{{Call to 'open' requires a third argument when the 'O_CREAT' flag is set}}
+  fd = open(path, O_CREAT); // expected-warning{{Call to 'open' requires a 3rd argument when the 'O_CREAT' flag is set}}
   if (!fd)
     close(fd);
 } 
 
+void test_open_at(int directory_fd, const char *relative_path) {
+  int fd;
+  fd = openat(directory_fd, relative_path, O_RDONLY); // no-warning
+  if (!fd)
+    close(fd);
+
+  fd = openat(directory_fd, relative_path, O_CREAT); // expected-warning{{Call to 'openat' requires a 4th argument when the 'O_CREAT' flag is set}}
+  if (!fd)
+    close(fd);
+}
+
 void test_dispatch_once() {
   dispatch_once_t pred = 0;
   do { if (__builtin_expect(*(&pred), ~0l) != ~0l) dispatch_once((&pred), (^() {})); } while (0); // expected-warning{{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}}
@@ -203,1999 +215,2213 @@
   });
 }
 
-// CHECK:  <key>diagnostics</key>
-// CHECK-NEXT:  <array>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>50</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>50</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>52</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>52</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>52</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>52</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>52</integer>
-// CHECK-NEXT:            <key>col</key><integer>7</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>52</integer>
-// CHECK-NEXT:            <key>col</key><integer>7</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>52</integer>
-// CHECK-NEXT:       <key>col</key><integer>7</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK: <key>diagnostics</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>52</integer>
-// CHECK-NEXT:          <key>col</key><integer>7</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>52</integer>
-// CHECK-NEXT:          <key>col</key><integer>9</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>51</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>51</integer>
+// CHECK-NEXT:           <key>col</key><integer>5</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;fd&apos; is not equal to 0</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;fd&apos; is not equal to 0</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>52</integer>
-// CHECK-NEXT:            <key>col</key><integer>7</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>52</integer>
-// CHECK-NEXT:            <key>col</key><integer>7</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>55</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>55</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>55</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>55</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>55</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>55</integer>
-// CHECK-NEXT:            <key>col</key><integer>11</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>55</integer>
-// CHECK-NEXT:       <key>col</key><integer>8</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>55</integer>
-// CHECK-NEXT:          <key>col</key><integer>19</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>55</integer>
-// CHECK-NEXT:          <key>col</key><integer>25</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;open&apos; requires a third argument when the &apos;O_CREAT&apos; flag is set</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;open&apos; requires a third argument when the &apos;O_CREAT&apos; flag is set</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;open&apos; requires a third argument when the &apos;O_CREAT&apos; flag is set</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Improper use of &apos;open&apos;</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>5ef25c5c47db3dbfb329901d426452e7</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_open</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>6</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>55</integer>
-// CHECK-NEXT:    <key>col</key><integer>8</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>53</integer>
+// CHECK-NEXT:      <key>col</key><integer>7</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>61</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>61</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>53</integer>
+// CHECK-NEXT:         <key>col</key><integer>7</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>53</integer>
+// CHECK-NEXT:         <key>col</key><integer>9</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>52</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>62</integer>
-// CHECK-NEXT:            <key>col</key><integer>64</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>62</integer>
-// CHECK-NEXT:       <key>col</key><integer>52</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Assuming &apos;fd&apos; is not equal to 0</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Assuming &apos;fd&apos; is not equal to 0</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>62</integer>
-// CHECK-NEXT:          <key>col</key><integer>66</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>62</integer>
-// CHECK-NEXT:          <key>col</key><integer>72</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>Improper use of &apos;dispatch_once&apos;</string>
-// CHECK-NEXT:    <key>check_name</key><string>osx.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>173fbcac3fc64dbaec32768d4cfda250</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_dispatch_once</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>2</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>62</integer>
-// CHECK-NEXT:    <key>col</key><integer>52</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>col</key><integer>8</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>col</key><integer>11</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>56</integer>
+// CHECK-NEXT:      <key>col</key><integer>8</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>72</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>72</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>73</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>73</integer>
-// CHECK-NEXT:            <key>col</key><integer>14</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>56</integer>
+// CHECK-NEXT:         <key>col</key><integer>19</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>56</integer>
+// CHECK-NEXT:         <key>col</key><integer>25</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>73</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;open&apos; requires a 3rd argument when the &apos;O_CREAT&apos; flag is set</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;open&apos; requires a 3rd argument when the &apos;O_CREAT&apos; flag is set</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;open&apos; requires a 3rd argument when the &apos;O_CREAT&apos; flag is set</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Improper use of &apos;open&apos;</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>5ef25c5c47db3dbfb329901d426452e7</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_open</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>6</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>56</integer>
+// CHECK-NEXT:   <key>col</key><integer>8</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>73</integer>
-// CHECK-NEXT:          <key>col</key><integer>16</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>73</integer>
-// CHECK-NEXT:          <key>col</key><integer>20</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>62</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>62</integer>
+// CHECK-NEXT:           <key>col</key><integer>5</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;pthread_once&apos; uses the local variable &apos;pred&apos; for the &quot;control&quot; value.  Using such transient memory for the control value is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;pthread_once&apos; uses the local variable &apos;pred&apos; for the &quot;control&quot; value.  Using such transient memory for the control value is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;pthread_once&apos; uses the local variable &apos;pred&apos; for the &quot;control&quot; value.  Using such transient memory for the control value is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Improper use of &apos;pthread_once&apos;</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>1e2f657a65cf8ee3c3ac2227de05ade4</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_pthread_once</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>2</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>73</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>64</integer>
+// CHECK-NEXT:      <key>col</key><integer>7</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>82</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>82</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>82</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>82</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>64</integer>
+// CHECK-NEXT:         <key>col</key><integer>7</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>64</integer>
+// CHECK-NEXT:         <key>col</key><integer>9</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>82</integer>
-// CHECK-NEXT:       <key>col</key><integer>15</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Assuming &apos;fd&apos; is not equal to 0</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Assuming &apos;fd&apos; is not equal to 0</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>82</integer>
-// CHECK-NEXT:          <key>col</key><integer>22</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>82</integer>
-// CHECK-NEXT:          <key>col</key><integer>22</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;malloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;malloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;malloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>0e841458f0cb7cf161d35f9db5862dcf</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>pr2899</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>82</integer>
-// CHECK-NEXT:    <key>col</key><integer>15</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>col</key><integer>8</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>col</key><integer>13</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>67</integer>
+// CHECK-NEXT:      <key>col</key><integer>8</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>94</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>94</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>94</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>94</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>67</integer>
+// CHECK-NEXT:         <key>col</key><integer>44</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>67</integer>
+// CHECK-NEXT:         <key>col</key><integer>50</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>94</integer>
-// CHECK-NEXT:       <key>col</key><integer>15</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;openat&apos; requires a 4th argument when the &apos;O_CREAT&apos; flag is set</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;openat&apos; requires a 4th argument when the &apos;O_CREAT&apos; flag is set</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;openat&apos; requires a 4th argument when the &apos;O_CREAT&apos; flag is set</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Improper use of &apos;open&apos;</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>433b17840bb989e7a13dc6337c1ed220</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_open_at</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>6</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>67</integer>
+// CHECK-NEXT:   <key>col</key><integer>8</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>94</integer>
-// CHECK-NEXT:          <key>col</key><integer>22</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>94</integer>
-// CHECK-NEXT:          <key>col</key><integer>22</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>73</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>73</integer>
+// CHECK-NEXT:           <key>col</key><integer>17</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>a267ff573c7e8b959a3f886677893eb0</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_calloc</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>94</integer>
-// CHECK-NEXT:    <key>col</key><integer>15</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>8</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>9</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>8</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>9</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>52</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>col</key><integer>64</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>74</integer>
+// CHECK-NEXT:      <key>col</key><integer>52</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>100</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>100</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>100</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>100</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>74</integer>
+// CHECK-NEXT:         <key>col</key><integer>66</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>74</integer>
+// CHECK-NEXT:         <key>col</key><integer>72</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>100</integer>
-// CHECK-NEXT:       <key>col</key><integer>15</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
+// CHECK-NEXT:   <key>category</key><string>API Misuse (Apple)</string>
+// CHECK-NEXT:   <key>type</key><string>Improper use of &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:   <key>check_name</key><string>osx.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>173fbcac3fc64dbaec32768d4cfda250</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_dispatch_once</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>2</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>74</integer>
+// CHECK-NEXT:   <key>col</key><integer>52</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>100</integer>
-// CHECK-NEXT:          <key>col</key><integer>26</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>100</integer>
-// CHECK-NEXT:          <key>col</key><integer>26</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>84</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>84</integer>
+// CHECK-NEXT:           <key>col</key><integer>16</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>85</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>85</integer>
+// CHECK-NEXT:           <key>col</key><integer>14</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>14eb72957baab3c63bac610a10e6f48b</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_calloc2</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>100</integer>
-// CHECK-NEXT:    <key>col</key><integer>15</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>85</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>112</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>112</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>112</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>112</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>85</integer>
+// CHECK-NEXT:         <key>col</key><integer>16</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>85</integer>
+// CHECK-NEXT:         <key>col</key><integer>20</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>112</integer>
-// CHECK-NEXT:       <key>col</key><integer>15</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;pthread_once&apos; uses the local variable &apos;pred&apos; for the &quot;control&quot; value.  Using such transient memory for the control value is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;pthread_once&apos; uses the local variable &apos;pred&apos; for the &quot;control&quot; value.  Using such transient memory for the control value is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;pthread_once&apos; uses the local variable &apos;pred&apos; for the &quot;control&quot; value.  Using such transient memory for the control value is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Improper use of &apos;pthread_once&apos;</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>1e2f657a65cf8ee3c3ac2227de05ade4</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_pthread_once</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>2</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>85</integer>
+// CHECK-NEXT:   <key>col</key><integer>3</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>112</integer>
-// CHECK-NEXT:          <key>col</key><integer>28</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>112</integer>
-// CHECK-NEXT:          <key>col</key><integer>28</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>94</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>94</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>94</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>94</integer>
+// CHECK-NEXT:           <key>col</key><integer>20</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;realloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;realloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;realloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>7f6f67ebe3d481aed7750005bea7e371</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_realloc</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>112</integer>
-// CHECK-NEXT:    <key>col</key><integer>15</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>94</integer>
+// CHECK-NEXT:      <key>col</key><integer>15</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>118</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>118</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>118</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>118</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>94</integer>
+// CHECK-NEXT:         <key>col</key><integer>22</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>94</integer>
+// CHECK-NEXT:         <key>col</key><integer>22</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>118</integer>
-// CHECK-NEXT:       <key>col</key><integer>15</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;malloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;malloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;malloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>0e841458f0cb7cf161d35f9db5862dcf</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>pr2899</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>94</integer>
+// CHECK-NEXT:   <key>col</key><integer>15</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>118</integer>
-// CHECK-NEXT:          <key>col</key><integer>29</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>118</integer>
-// CHECK-NEXT:          <key>col</key><integer>29</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>106</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>106</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>106</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>106</integer>
+// CHECK-NEXT:           <key>col</key><integer>20</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;reallocf&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;reallocf&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;reallocf&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>4941698efbd81601653dff10ef9c645b</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_reallocf</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>118</integer>
-// CHECK-NEXT:    <key>col</key><integer>15</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>106</integer>
+// CHECK-NEXT:      <key>col</key><integer>15</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>136</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>136</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>136</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>136</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>106</integer>
+// CHECK-NEXT:         <key>col</key><integer>22</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>106</integer>
+// CHECK-NEXT:         <key>col</key><integer>22</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>136</integer>
-// CHECK-NEXT:       <key>col</key><integer>15</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>a267ff573c7e8b959a3f886677893eb0</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_calloc</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>106</integer>
+// CHECK-NEXT:   <key>col</key><integer>15</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>136</integer>
-// CHECK-NEXT:          <key>col</key><integer>22</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>136</integer>
-// CHECK-NEXT:          <key>col</key><integer>22</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>112</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>112</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>112</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>112</integer>
+// CHECK-NEXT:           <key>col</key><integer>20</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>b7ca3488e81d9d9d4b8dc545258ce97c</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_alloca</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>136</integer>
-// CHECK-NEXT:    <key>col</key><integer>15</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>112</integer>
+// CHECK-NEXT:      <key>col</key><integer>15</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>148</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>148</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>148</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>148</integer>
-// CHECK-NEXT:            <key>col</key><integer>31</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>112</integer>
+// CHECK-NEXT:         <key>col</key><integer>26</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>112</integer>
+// CHECK-NEXT:         <key>col</key><integer>26</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>148</integer>
-// CHECK-NEXT:       <key>col</key><integer>16</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>14eb72957baab3c63bac610a10e6f48b</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_calloc2</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>112</integer>
+// CHECK-NEXT:   <key>col</key><integer>15</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>148</integer>
-// CHECK-NEXT:          <key>col</key><integer>33</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>148</integer>
-// CHECK-NEXT:          <key>col</key><integer>33</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>124</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>124</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>124</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>124</integer>
+// CHECK-NEXT:           <key>col</key><integer>21</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>1ec52551362b070237f47f6bb6c3847d</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_builtin_alloca</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>148</integer>
-// CHECK-NEXT:    <key>col</key><integer>16</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>124</integer>
+// CHECK-NEXT:      <key>col</key><integer>15</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>160</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>160</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>160</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>160</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>124</integer>
+// CHECK-NEXT:         <key>col</key><integer>28</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>124</integer>
+// CHECK-NEXT:         <key>col</key><integer>28</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>160</integer>
-// CHECK-NEXT:       <key>col</key><integer>15</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;realloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;realloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;realloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>7f6f67ebe3d481aed7750005bea7e371</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_realloc</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>124</integer>
+// CHECK-NEXT:   <key>col</key><integer>15</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>160</integer>
-// CHECK-NEXT:          <key>col</key><integer>22</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>160</integer>
-// CHECK-NEXT:          <key>col</key><integer>22</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>130</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>130</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>130</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>130</integer>
+// CHECK-NEXT:           <key>col</key><integer>22</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;valloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;valloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;valloc&apos; has an allocation size of 0 bytes</string>
-// CHECK-NEXT:    <key>category</key><string>Unix API</string>
-// CHECK-NEXT:    <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
-// CHECK-NEXT:    <key>check_name</key><string>unix.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>675741e04c8d0071d280324e23f41d35</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_valloc</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>160</integer>
-// CHECK-NEXT:    <key>col</key><integer>15</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>130</integer>
+// CHECK-NEXT:      <key>col</key><integer>15</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>183</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>183</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>184</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>184</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>130</integer>
+// CHECK-NEXT:         <key>col</key><integer>29</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>130</integer>
+// CHECK-NEXT:         <key>col</key><integer>29</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>184</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;reallocf&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;reallocf&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;reallocf&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>4941698efbd81601653dff10ef9c645b</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_reallocf</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>130</integer>
+// CHECK-NEXT:   <key>col</key><integer>15</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>184</integer>
-// CHECK-NEXT:          <key>col</key><integer>17</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>184</integer>
-// CHECK-NEXT:          <key>col</key><integer>21</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>148</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>148</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>148</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>148</integer>
+// CHECK-NEXT:           <key>col</key><integer>20</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
-// CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>Improper use of &apos;dispatch_once&apos;</string>
-// CHECK-NEXT:    <key>check_name</key><string>osx.API</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>8ded1f2025c1e4a4bcd5302dc97006d9</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_dispatch_once_in_macro</string>
-// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>2</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>184</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>189</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>189</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>189</integer>
-// CHECK-NEXT:          <key>col</key><integer>8</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>&apos;p&apos; initialized to a null pointer value</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT:      <key>line</key><integer>148</integer>
+// CHECK-NEXT:      <key>col</key><integer>15</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>189</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>189</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>190</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>190</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>148</integer>
+// CHECK-NEXT:         <key>col</key><integer>22</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>148</integer>
+// CHECK-NEXT:         <key>col</key><integer>22</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>b7ca3488e81d9d9d4b8dc545258ce97c</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_alloca</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>148</integer>
+// CHECK-NEXT:   <key>col</key><integer>15</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>160</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>160</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>160</integer>
+// CHECK-NEXT:           <key>col</key><integer>16</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>160</integer>
+// CHECK-NEXT:           <key>col</key><integer>31</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>160</integer>
+// CHECK-NEXT:      <key>col</key><integer>16</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>190</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>190</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>190</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>190</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>160</integer>
+// CHECK-NEXT:         <key>col</key><integer>33</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>160</integer>
+// CHECK-NEXT:         <key>col</key><integer>33</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>190</integer>
-// CHECK-NEXT:       <key>col</key><integer>24</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>1ec52551362b070237f47f6bb6c3847d</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_builtin_alloca</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>160</integer>
+// CHECK-NEXT:   <key>col</key><integer>16</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>190</integer>
-// CHECK-NEXT:          <key>col</key><integer>24</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>194</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>172</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>172</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>172</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>172</integer>
+// CHECK-NEXT:           <key>col</key><integer>20</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>&apos;p&apos; captured by block as a null pointer value</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>&apos;p&apos; captured by block as a null pointer value</string>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>190</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>190</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>194</integer>
-// CHECK-NEXT:          <key>col</key><integer>4</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Calling &apos;dispatch_sync&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Calling &apos;dispatch_sync&apos;</string>
+// CHECK-NEXT:      <key>line</key><integer>172</integer>
+// CHECK-NEXT:      <key>col</key><integer>15</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>190</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>190</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>194</integer>
-// CHECK-NEXT:          <key>col</key><integer>4</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>1</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Calling anonymous block</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Calling anonymous block</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>190</integer>
-// CHECK-NEXT:       <key>col</key><integer>24</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>depth</key><integer>2</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Entered call from &apos;dispatch_sync&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Entered call from &apos;dispatch_sync&apos;</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>190</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>190</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>191</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>191</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>172</integer>
+// CHECK-NEXT:         <key>col</key><integer>22</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>172</integer>
+// CHECK-NEXT:         <key>col</key><integer>22</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;valloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;valloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;valloc&apos; has an allocation size of 0 bytes</string>
+// CHECK-NEXT:   <key>category</key><string>Unix API</string>
+// CHECK-NEXT:   <key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
+// CHECK-NEXT:   <key>check_name</key><string>unix.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>675741e04c8d0071d280324e23f41d35</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_valloc</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>172</integer>
+// CHECK-NEXT:   <key>col</key><integer>15</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>195</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>195</integer>
+// CHECK-NEXT:           <key>col</key><integer>17</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>196</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>196</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>196</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>191</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>191</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>191</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>191</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>196</integer>
+// CHECK-NEXT:         <key>col</key><integer>17</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>196</integer>
+// CHECK-NEXT:         <key>col</key><integer>21</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Call to &apos;dispatch_once&apos; uses the local variable &apos;pred&apos; for the predicate value.  Using such transient memory for the predicate is potentially dangerous.  Perhaps you intended to declare the variable as &apos;static&apos;?</string>
+// CHECK-NEXT:   <key>category</key><string>API Misuse (Apple)</string>
+// CHECK-NEXT:   <key>type</key><string>Improper use of &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:   <key>check_name</key><string>osx.API</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>8ded1f2025c1e4a4bcd5302dc97006d9</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_dispatch_once_in_macro</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>2</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>196</integer>
+// CHECK-NEXT:   <key>col</key><integer>3</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>191</integer>
-// CHECK-NEXT:       <key>col</key><integer>8</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>191</integer>
-// CHECK-NEXT:          <key>col</key><integer>8</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>191</integer>
-// CHECK-NEXT:          <key>col</key><integer>8</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>2</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;q&apos; is non-null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;q&apos; is non-null</string>
+// CHECK-NEXT:      <key>line</key><integer>201</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>191</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>191</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>192</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>192</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>201</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>201</integer>
+// CHECK-NEXT:         <key>col</key><integer>8</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>201</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>201</integer>
+// CHECK-NEXT:           <key>col</key><integer>5</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>202</integer>
+// CHECK-NEXT:      <key>col</key><integer>24</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>192</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>192</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>192</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>192</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>202</integer>
+// CHECK-NEXT:         <key>col</key><integer>24</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>206</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>&apos;p&apos; captured by block as a null pointer value</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>&apos;p&apos; captured by block as a null pointer value</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>192</integer>
-// CHECK-NEXT:       <key>col</key><integer>6</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>192</integer>
-// CHECK-NEXT:          <key>col</key><integer>4</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>192</integer>
-// CHECK-NEXT:          <key>col</key><integer>4</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>2</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:      <key>line</key><integer>202</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
-// CHECK-NEXT:    <key>category</key><string>Logic error</string>
-// CHECK-NEXT:    <key>type</key><string>Dereference of null pointer</string>
-// CHECK-NEXT:    <key>check_name</key><string>core.NullDereference</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>5d3f4c433004c7a6d4a06aa30cc3ea85</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>192</integer>
-// CHECK-NEXT:    <key>col</key><integer>6</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>199</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>199</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>200</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>200</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>202</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>206</integer>
+// CHECK-NEXT:         <key>col</key><integer>4</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Calling &apos;dispatch_sync&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Calling &apos;dispatch_sync&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>200</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>200</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>200</integer>
-// CHECK-NEXT:          <key>col</key><integer>8</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>&apos;p&apos; initialized to a null pointer value</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT:      <key>line</key><integer>202</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>200</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>200</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>201</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>201</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>202</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>206</integer>
+// CHECK-NEXT:         <key>col</key><integer>4</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>1</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Calling anonymous block</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Calling anonymous block</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>201</integer>
-// CHECK-NEXT:       <key>col</key><integer>24</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <key>line</key><integer>202</integer>
+// CHECK-NEXT:      <key>col</key><integer>24</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>depth</key><integer>2</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;dispatch_sync&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;dispatch_sync&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>201</integer>
-// CHECK-NEXT:          <key>col</key><integer>24</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>203</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>col</key><integer>5</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>&apos;p&apos; captured by block as a null pointer value</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>&apos;p&apos; captured by block as a null pointer value</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>201</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>201</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>203</integer>
-// CHECK-NEXT:          <key>col</key><integer>4</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>col</key><integer>5</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>col</key><integer>8</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>col</key><integer>8</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Calling &apos;_dispatch_once&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Calling &apos;_dispatch_once&apos;</string>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>175</integer>
-// CHECK-NEXT:       <key>col</key><integer>1</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>depth</key><integer>1</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Entered call from &apos;test_inline_dispatch_once&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Entered call from &apos;test_inline_dispatch_once&apos;</string>
+// CHECK-NEXT:      <key>line</key><integer>203</integer>
+// CHECK-NEXT:      <key>col</key><integer>8</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>175</integer>
-// CHECK-NEXT:            <key>col</key><integer>1</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>175</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>177</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>177</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>203</integer>
+// CHECK-NEXT:         <key>col</key><integer>8</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>203</integer>
+// CHECK-NEXT:         <key>col</key><integer>8</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>177</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>2</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Assuming &apos;q&apos; is non-null</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Assuming &apos;q&apos; is non-null</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>177</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>177</integer>
-// CHECK-NEXT:          <key>col</key><integer>33</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>col</key><integer>8</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>col</key><integer>8</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>1</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Calling &apos;dispatch_once&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Calling &apos;dispatch_once&apos;</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>177</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>177</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>177</integer>
-// CHECK-NEXT:          <key>col</key><integer>33</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>2</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Calling anonymous block</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Calling anonymous block</string>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>201</integer>
-// CHECK-NEXT:       <key>col</key><integer>24</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>depth</key><integer>3</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Entered call from &apos;dispatch_once&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Entered call from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:      <key>line</key><integer>204</integer>
+// CHECK-NEXT:      <key>col</key><integer>6</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>201</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>201</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>202</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>202</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>204</integer>
+// CHECK-NEXT:         <key>col</key><integer>4</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>204</integer>
+// CHECK-NEXT:         <key>col</key><integer>4</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>2</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:   <key>category</key><string>Logic error</string>
+// CHECK-NEXT:   <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT:   <key>check_name</key><string>core.NullDereference</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>5d3f4c433004c7a6d4a06aa30cc3ea85</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>204</integer>
+// CHECK-NEXT:   <key>col</key><integer>6</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>211</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>211</integer>
+// CHECK-NEXT:           <key>col</key><integer>8</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>212</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>212</integer>
+// CHECK-NEXT:           <key>col</key><integer>5</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:      <key>line</key><integer>212</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>202</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>202</integer>
-// CHECK-NEXT:            <key>col</key><integer>4</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>202</integer>
-// CHECK-NEXT:            <key>col</key><integer>7</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>202</integer>
-// CHECK-NEXT:            <key>col</key><integer>7</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>line</key><integer>212</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>212</integer>
+// CHECK-NEXT:         <key>col</key><integer>8</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>202</integer>
-// CHECK-NEXT:       <key>col</key><integer>7</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>&apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
 // CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>202</integer>
-// CHECK-NEXT:          <key>col</key><integer>5</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>202</integer>
-// CHECK-NEXT:          <key>col</key><integer>5</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>212</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>212</integer>
+// CHECK-NEXT:           <key>col</key><integer>5</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>213</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>213</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>3</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>213</integer>
+// CHECK-NEXT:      <key>col</key><integer>24</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
-// CHECK-NEXT:    <key>category</key><string>Logic error</string>
-// CHECK-NEXT:    <key>type</key><string>Dereference of null pointer</string>
-// CHECK-NEXT:    <key>check_name</key><string>core.NullDereference</string>
-// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>265c4fd608dafee211bfa93d21c28866</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>202</integer>
-// CHECK-NEXT:    <key>col</key><integer>7</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:  </array>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>213</integer>
+// CHECK-NEXT:         <key>col</key><integer>24</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>215</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>&apos;p&apos; captured by block as a null pointer value</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>&apos;p&apos; captured by block as a null pointer value</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>213</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>213</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>215</integer>
+// CHECK-NEXT:         <key>col</key><integer>4</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Calling &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Calling &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>187</integer>
+// CHECK-NEXT:      <key>col</key><integer>1</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>depth</key><integer>1</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;test_inline_dispatch_once&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;test_inline_dispatch_once&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>187</integer>
+// CHECK-NEXT:           <key>col</key><integer>1</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>187</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>189</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>189</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>189</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>189</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>189</integer>
+// CHECK-NEXT:         <key>col</key><integer>33</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>1</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Calling &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Calling &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>189</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>189</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>189</integer>
+// CHECK-NEXT:         <key>col</key><integer>33</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>2</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Calling anonymous block</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Calling anonymous block</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>213</integer>
+// CHECK-NEXT:      <key>col</key><integer>24</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>depth</key><integer>3</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>213</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>213</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>col</key><integer>4</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>214</integer>
+// CHECK-NEXT:      <key>col</key><integer>7</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>214</integer>
+// CHECK-NEXT:         <key>col</key><integer>5</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>214</integer>
+// CHECK-NEXT:         <key>col</key><integer>5</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>3</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:   <key>category</key><string>Logic error</string>
+// CHECK-NEXT:   <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT:   <key>check_name</key><string>core.NullDereference</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>265c4fd608dafee211bfa93d21c28866</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>214</integer>
+// CHECK-NEXT:   <key>col</key><integer>7</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT: </array>
diff --git a/test/Analysis/unreachable-code-path.c b/test/Analysis/unreachable-code-path.c
index 4ddfb21..ff58587 100644
--- a/test/Analysis/unreachable-code-path.c
+++ b/test/Analysis/unreachable-code-path.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,alpha.deadcode.UnreachableCode -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,deadcode.DeadStores,alpha.deadcode.UnreachableCode -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s
 
 extern void foo(int a);
 
diff --git a/test/Analysis/unused-ivars.m b/test/Analysis/unused-ivars.m
index f04132b..8f12d9b 100644
--- a/test/Analysis/unused-ivars.m
+++ b/test/Analysis/unused-ivars.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=osx.cocoa.UnusedIvars -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=osx.cocoa.UnusedIvars -verify -Wno-objc-root-class %s
 
 //===--- BEGIN: Delta-debugging reduced headers. --------------------------===//
 
diff --git a/test/Analysis/valist-as-lazycompound.c b/test/Analysis/valist-as-lazycompound.c
new file mode 100644
index 0000000..2fbd4cb
--- /dev/null
+++ b/test/Analysis/valist-as-lazycompound.c
@@ -0,0 +1,21 @@
+// RUN: %clang_analyze_cc1 -triple gcc-linaro-arm-linux-gnueabihf -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// expected-no-diagnostics
+
+typedef unsigned int size_t;
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+
+extern int vsprintf(char *__restrict __s,
+                    const char *__restrict __format, __gnuc_va_list
+                                                         __arg);
+
+void _dprintf(const char *function, int flen, int line, int level,
+             const char *prefix, const char *fmt, ...) {
+  char raw[10];
+  int err;
+  va_list ap;
+
+  __builtin_va_start(ap, fmt);
+  err = vsprintf(raw, fmt, ap);
+  __builtin_va_end(ap);
+}
diff --git a/test/Analysis/valist-uninitialized-no-undef.c b/test/Analysis/valist-uninitialized-no-undef.c
new file mode 100644
index 0000000..528ac86
--- /dev/null
+++ b/test/Analysis/valist-uninitialized-no-undef.c
@@ -0,0 +1,40 @@
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+
+#include "Inputs/system-header-simulator-for-valist.h"
+
+// This is called in call_inlined_uses_arg(),
+// and the warning is generated during the analysis of call_inlined_uses_arg().
+void inlined_uses_arg(va_list arg) {
+  (void)va_arg(arg, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
+}
+
+void call_inlined_uses_arg(int fst, ...) {
+  va_list va;
+  inlined_uses_arg(va); // expected-note{{Calling 'inlined_uses_arg'}}
+}
+
+void f6(va_list *fst, ...) {
+  va_start(*fst, fst);
+  // FIXME: There should be no warning for this.
+  (void)va_arg(*fst, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
+  va_end(*fst);
+} 
+
+void call_vprintf_bad(int isstring, ...) {
+  va_list va;
+  vprintf(isstring ? "%s" : "%d", va); // expected-warning{{Function 'vprintf' is called with an uninitialized va_list argument}}
+  // expected-note@-1{{Function 'vprintf' is called with an uninitialized va_list argument}}
+  // expected-note@-2{{Assuming 'isstring' is 0}}
+  // expected-note@-3{{'?' condition is false}}
+}
+
+void call_vsprintf_bad(char *buffer, ...) {
+  va_list va;
+  va_start(va, buffer); // expected-note{{Initialized va_list}}
+  va_end(va); // expected-note{{Ended va_list}}
+  vsprintf(buffer, "%s %d %d %lf %03d", va); // expected-warning{{Function 'vsprintf' is called with an uninitialized va_list argument}}
+  // expected-note@-1{{Function 'vsprintf' is called with an uninitialized va_list argument}}
+}
+
diff --git a/test/Analysis/valist-uninitialized.c b/test/Analysis/valist-uninitialized.c
index b1f11d1..1930853 100644
--- a/test/Analysis/valist-uninitialized.c
+++ b/test/Analysis/valist-uninitialized.c
@@ -1,17 +1,20 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,alpha.valist.Uninitialized,alpha.valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-disable-checker=core.CallAndMessage -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-disable-checker=core.CallAndMessage -analyzer-output=text -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator-for-valist.h"
 
 void f1(int fst, ...) {
   va_list va;
-  (void)va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
+  (void)va_arg(va, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
 }
 
 int f2(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
   va_end(va); // expected-note{{Ended va_list}}
-  return va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
+  return va_arg(va, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
 }
 
 void f3(int fst, ...) {
@@ -25,11 +28,13 @@
 
 void f4(int cond, ...) {
   va_list va;
-  if (cond) { // expected-note{{Assuming 'cond' is 0}} expected-note{{Taking false branch}}
+  if (cond) { // expected-note{{Assuming 'cond' is 0}}
+    // expected-note@-1{{Taking false branch}}
     va_start(va, cond);
     (void)va_arg(va,int);
   }
-  va_end(va); //expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
+  va_end(va); //expected-warning{{va_end() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_end() is called on an uninitialized va_list}}
 }
 
 void f5(va_list fst, ...) {
@@ -38,13 +43,6 @@
   va_end(fst);
 } // no-warning
 
-//FIXME: this should not cause a warning
-void f6(va_list *fst, ...) {
-  va_start(*fst, fst);
-  (void)va_arg(*fst, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-  va_end(*fst);
-}
-
 void f7(int *fst, ...) {
   va_list x;
   va_list *y = &x;
@@ -58,8 +56,9 @@
   va_list *y = &x;
   va_start(*y,fst); // expected-note{{Initialized va_list}}
   va_end(x); // expected-note{{Ended va_list}}
-  (void)va_arg(*y, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-} // no-warning
+  (void)va_arg(*y, int); //expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
+}
 
 // This only contains problems which are handled by varargs.Unterminated.
 void reinit(int *fst, ...) {
@@ -87,48 +86,56 @@
   va_start(va, fst); // expected-note{{Initialized va_list}}
   (void)va_arg(va, int);
   va_end(va); // expected-note{{Ended va_list}}
-  (void)va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
+  (void)va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
 }
 
 void copyself(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}}
+  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
+  // expected-note@-1{{va_list 'va' is copied onto itself}}
   va_end(va);
-} // no-warning
+}
 
 void copyselfUninit(int fst, ...) {
   va_list va;
-  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}}
-} // no-warning
+  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
+  // expected-note@-1{{va_list 'va' is copied onto itself}}
+}
 
 void copyOverwrite(int fst, ...) {
   va_list va, va2;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}} expected-note{{Initialized va_list 'va' is overwritten by an uninitialized one}}
-} // no-warning
+  va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}}
+  // expected-note@-1{{Initialized va_list 'va' is overwritten by an uninitialized one}}
+}
 
 void copyUnint(int fst, ...) {
   va_list va, va2;
-  va_copy(va, va2); // expected-warning{{Uninitialized va_list is copied}} expected-note{{Uninitialized va_list is copied}}
+  va_copy(va, va2); // expected-warning{{Uninitialized va_list is copied}}
+  // expected-note@-1{{Uninitialized va_list is copied}}
 }
 
 void g1(int fst, ...) {
   va_list va;
-  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
+  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_end() is called on an uninitialized va_list}}
 }
 
 void g2(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
   va_end(va); // expected-note{{Ended va_list}}
-  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
+  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_end() is called on an uninitialized va_list}}
 }
 
 void is_sink(int fst, ...) {
   va_list va;
-  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
-  *((volatile int *)0) = 1; //no-warning
+  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_end() is called on an uninitialized va_list}}
+  *((volatile int *)0) = 1;
 }
 
 // NOTE: this is invalid, as the man page of va_end requires that "Each invocation of va_start()
@@ -141,17 +148,6 @@
   (void)va_arg(arg, int);
 } //no-warning
 
-// This is the same function as the previous one, but it is called in call_uses_arg2(),
-// and the warning is generated during the analysis of call_uses_arg2().
-void inlined_uses_arg(va_list arg) {
-  (void)va_arg(arg, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-}
-
-void call_inlined_uses_arg(int fst, ...) {
-  va_list va;
-  inlined_uses_arg(va); // expected-note{{Calling 'inlined_uses_arg'}}
-}
-
 void call_vprintf_ok(int isstring, ...) {
   va_list va;
   va_start(va, isstring);
@@ -159,20 +155,24 @@
   va_end(va);
 } //no-warning
 
-void call_vprintf_bad(int isstring, ...) {
-  va_list va;
-  vprintf(isstring ? "%s" : "%d", va); //expected-warning{{Function 'vprintf' is called with an uninitialized va_list argument}} expected-note{{Function 'vprintf' is called with an uninitialized va_list argument}} expected-note{{Assuming 'isstring' is 0}} expected-note{{'?' condition is false}}
-}
-
-void call_vsprintf_bad(char *buffer, ...) {
-  va_list va;
-  va_start(va, buffer); // expected-note{{Initialized va_list}}
-  va_end(va); // expected-note{{Ended va_list}}
-  vsprintf(buffer, "%s %d %d %lf %03d", va); //expected-warning{{Function 'vsprintf' is called with an uninitialized va_list argument}} expected-note{{Function 'vsprintf' is called with an uninitialized va_list argument}}
-}
-
 void call_some_other_func(int n, ...) {
   va_list va;
   some_library_function(n, va);
 } //no-warning
 
+void inlined_uses_arg_good(va_list arg) {
+  (void)va_arg(arg, int);
+}
+
+void call_inlined_uses_arg_good(int fst, ...) {
+  va_list va;
+  va_start(va, fst);
+  inlined_uses_arg_good(va);
+  va_end(va);
+}
+
+void va_copy_test(va_list arg) {
+  va_list dst;
+  va_copy(dst, arg);
+  va_end(dst);
+}
diff --git a/test/Analysis/valist-unterminated.c b/test/Analysis/valist-unterminated.c
index 63ee992..e19c676 100644
--- a/test/Analysis/valist-unterminated.c
+++ b/test/Analysis/valist-unterminated.c
@@ -1,11 +1,13 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,alpha.valist.Unterminated,alpha.valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -analyzer-checker=core,valist.Unterminated,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Unterminated,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator-for-valist.h"
 
 void f1(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  return; // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}
+  return; // expected-warning{{Initialized va_list 'va' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va' is leaked}}
 }
 
 void f2(int fst, ...) {
@@ -13,37 +15,42 @@
   va_start(va, fst); // expected-note{{Initialized va_list}}
   va_end(va); // expected-note{{Ended va_list}}
   va_start(va, fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}}
+} // expected-warning{{Initialized va_list 'va' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va' is leaked}}
 
 void f3(int fst, ...) {
   va_list va, va2;
   va_start(va, fst);
   va_copy(va2, va); // expected-note{{Initialized va_list}}
-  va_end(va); // expected-warning{{Initialized va_list 'va2' is leaked}} expected-note{{Initialized va_list 'va2' is leaked}}
+  va_end(va); // expected-warning{{Initialized va_list 'va2' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va2' is leaked}}
 }
 
 void f4(va_list *fst, ...) {
   va_start(*fst, fst); // expected-note{{Initialized va_list}}
-  return; // expected-warning{{Initialized va_list is leaked}} expected-note{{Initialized va_list is leaked}}
+  return; // expected-warning{{Initialized va_list is leaked}}
+  // expected-note@-1{{Initialized va_list is leaked}}
 }
 
 void f5(va_list fst, ...) {
-  va_start(fst, fst);
-  //FIXME: this should cause a warning
-} // no-warning
+  va_start(fst, fst); // expected-note{{Initialized va_list}}
+} // expected-warning{{Initialized va_list}}
+  // expected-note@-1{{Initialized va_list}}
 
 void f6(va_list *fst, ...) {
   va_start(*fst, fst); // expected-note{{Initialized va_list}}
   (void)va_arg(*fst, int);
   //FIXME: this should NOT cause a warning
-  va_end(*fst); // expected-warning{{Initialized va_list is leaked}} expected-note{{Initialized va_list is leaked}}
+  va_end(*fst); // expected-warning{{Initialized va_list is leaked}}
+  // expected-note@-1{{Initialized va_list is leaked}}
 }
 
 void f7(int *fst, ...) {
   va_list x;
   va_list *y = &x;
   va_start(*y,fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'x' is leaked}} expected-note{{Initialized va_list 'x' is leaked}}
+} // expected-warning{{Initialized va_list 'x' is leaked}}
+  // expected-note@-1{{Initialized va_list 'x' is leaked}}
 
 void f8(int *fst, ...) {
   va_list x;
@@ -54,9 +61,12 @@
 
 void reinit(int *fst, ...) {
   va_list va;
-  va_start(va, fst); // expected-note{{Initialized va_list}} expected-note{{Initialized va_list}}
-  va_start(va, fst); // expected-warning{{Initialized va_list 'va' is initialized again}} expected-note{{Initialized va_list 'va' is initialized again}}
-} // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}
+  va_start(va, fst); // expected-note{{Initialized va_list}}
+                     // expected-note@-1{{Initialized va_list}}
+  va_start(va, fst); // expected-warning{{Initialized va_list 'va' is initialized again}}
+  // expected-note@-1{{Initialized va_list 'va' is initialized again}}
+} // expected-warning{{Initialized va_list 'va' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va' is leaked}}
 
 void reinitOk(int *fst, ...) {
   va_list va;
@@ -69,20 +79,23 @@
 void copyself(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}}
+  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
+                   // expected-note@-1{{va_list 'va' is copied onto itself}}
   va_end(va);
-} // no-warning
+}
 
 void copyselfUninit(int fst, ...) {
   va_list va;
-  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}} 
-} // no-warning
+  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
+  // expected-note@-1{{va_list 'va' is copied onto itself}}
+}
 
 void copyOverwrite(int fst, ...) {
   va_list va, va2;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}} expected-note{{Initialized va_list 'va' is overwritten by an uninitialized one}}
-} // no-warning
+  va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}}
+  // expected-note@-1{{Initialized va_list 'va' is overwritten by an uninitialized one}}
+}
 
 //This only generates a warning for the valist.Uninitialized checker
 void copyUnint(int fst, ...) {
@@ -94,20 +107,27 @@
   va_list va, va2;
   va_start(va, fst);
   va_copy(va2, va); // expected-note{{Initialized va_list}}
-  va_copy(va2, va); // expected-warning{{Initialized va_list 'va2' is initialized again}} expected-note{{Initialized va_list 'va2' is initialized again}}
+  va_copy(va2, va); // expected-warning{{Initialized va_list 'va2' is initialized again}}
+  // expected-note@-1{{Initialized va_list 'va2' is initialized again}}
   va_end(va);
   va_end(va2);
-} //no-warning
+}
 
 void doublemsg(int fst, ...) {
   va_list va, va2;
-  va_start(va, fst), va_start(va2, fst); // expected-warning{{Initialized va_list 'va' is leaked}} expected-warning{{Initialized va_list 'va2' is leaked}} expected-note{{Initialized va_list}} expected-note{{Initialized va_list}} expected-note{{Initialized va_list}} expected-note{{Initialized va_list 'va' is leaked}} 
+  va_start(va, fst), va_start(va2, fst); // expected-warning{{Initialized va_list 'va' is leaked}}
+  // expected-warning@-1{{Initialized va_list 'va2' is leaked}}
+  // expected-note@-2{{Initialized va_list}}
+  // expected-note@-3{{Initialized va_list}}
+  // expected-note@-4{{Initialized va_list}}
+  // expected-note@-5{{Initialized va_list 'va' is leaked}} 
 } 
 
 void in_array(int fst, ...) {
   va_list va_array[8];
   va_start(va_array[3], fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'va_array[3]' is leaked}} expected-note{{Initialized va_list 'va_array[3]' is leaked}}
+} // expected-warning{{Initialized va_list 'va_array[3]' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va_array[3]' is leaked}}
 
 struct containing_a_valist {
   va_list vafield;
@@ -117,12 +137,14 @@
 void in_struct(int fst, ...) {
   struct containing_a_valist s;
   va_start(s.vafield, fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 's.vafield' is leaked}} expected-note{{Initialized va_list 's.vafield' is leaked}}
+} // expected-warning{{Initialized va_list 's.vafield' is leaked}}
+  // expected-note@-1{{Initialized va_list 's.vafield' is leaked}}
 
 void casting(int fst, ...) {
   char mem[sizeof(va_list)];
   va_start(*(va_list *) mem, fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'mem[0]' is leaked}} expected-note{{Initialized va_list 'mem[0]' is leaked}}
+} // expected-warning{{Initialized va_list 'mem[0]' is leaked}}
+  // expected-note@-1{{Initialized va_list 'mem[0]' is leaked}}
 
 
 void castingOk(int fst, ...) {
diff --git a/test/Analysis/variadic-method-types.m b/test/Analysis/variadic-method-types.m
index 9f90e5f..6db93ac 100644
--- a/test/Analysis/variadic-method-types.m
+++ b/test/Analysis/variadic-method-types.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.VariadicMethodTypes -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.VariadicMethodTypes -analyzer-store=region -fblocks -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
diff --git a/test/Analysis/vfork.c b/test/Analysis/vfork.c
index c7a02fa..da1b5da 100644
--- a/test/Analysis/vfork.c
+++ b/test/Analysis/vfork.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify -x c++ %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify -x c++ %s
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/virtualcall.cpp b/test/Analysis/virtualcall.cpp
index 8ce1d41..56bd324 100644
--- a/test/Analysis/virtualcall.cpp
+++ b/test/Analysis/virtualcall.cpp
@@ -1,36 +1,79 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.VirtualCall -analyzer-store region -verify -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -verify -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:Interprocedural=true -DINTERPROCEDURAL=1 -verify -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -verify -std=c++11 %s
+
+/* When INTERPROCEDURAL is set, we expect diagnostics in all functions reachable
+   from a constructor or destructor. If it is not set, we expect diagnostics
+   only in the constructor or destructor.
+
+   When PUREONLY is set, we expect diagnostics only for calls to pure virtual
+   functions not to non-pure virtual functions.
+*/
 
 class A {
 public:
   A();
+  A(int i);
+
   ~A() {};
   
-  virtual int foo() = 0;
+  virtual int foo() = 0; // from Sema: expected-note {{'foo' declared here}}
   virtual void bar() = 0;
   void f() {
-    foo(); // expected-warning{{Call pure virtual functions during construction or destruction may leads undefined behaviour}}
+    foo();
+#if INTERPROCEDURAL
+        // expected-warning-re@-2 {{{{^}}Call Path : foo <-- fCall to pure virtual function during construction has undefined behavior}}
+#endif
   }
 };
 
 class B : public A {
 public:
   B() {
-    foo(); // expected-warning{{Call virtual functions during construction or destruction will never go to a more derived class}}
+    foo();
+#if !PUREONLY
+#if INTERPROCEDURAL
+        // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
+#else
+        // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}}
+#endif
+#endif
+
   }
   ~B();
   
   virtual int foo();
-  virtual void bar() { foo(); }  // expected-warning{{Call virtual functions during construction or destruction will never go to a more derived class}}
+  virtual void bar() { foo(); }
+#if INTERPROCEDURAL
+      // expected-warning-re@-2 {{{{^}}Call Path : foo <-- barCall to virtual function during destruction will not dispatch to derived class}}
+#endif
 };
 
 A::A() {
   f();
 }
 
+A::A(int i) {
+  foo(); // From Sema: expected-warning {{call to pure virtual member function 'foo' has undefined behavior}}
+#if INTERPROCEDURAL
+      // expected-warning-re@-2 {{{{^}}Call Path : fooCall to pure virtual function during construction has undefined behavior}}
+#else
+      // expected-warning-re@-4 {{{{^}}Call to pure virtual function during construction has undefined behavior}}
+#endif
+}
+
 B::~B() {
   this->B::foo(); // no-warning
   this->B::bar();
-  this->foo(); // expected-warning{{Call virtual functions during construction or destruction will never go to a more derived class}}
+  this->foo();
+#if !PUREONLY
+#if INTERPROCEDURAL
+      // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during destruction will not dispatch to derived class}}
+#else
+      // expected-warning-re@-5 {{{{^}}Call to virtual function during destruction will not dispatch to derived class}}
+#endif
+#endif
+
 }
 
 class C : public B {
@@ -43,7 +86,14 @@
 };
 
 C::C() {
-  f(foo()); // expected-warning{{Call virtual functions during construction or destruction will never go to a more derived class}}
+  f(foo());
+#if !PUREONLY
+#if INTERPROCEDURAL
+      // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
+#else
+      // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}}
+#endif
+#endif
 }
 
 class D : public B {
@@ -65,12 +115,23 @@
   int foo() override;
 };
 
+// Regression test: don't crash when there's no direct callee.
+class F {
+public:
+  F() {
+    void (F::* ptr)() = &F::foo;
+    (this->*ptr)();
+  }
+  void foo();
+};
+
 int main() {
   A *a;
   B *b;
   C *c;
   D *d;
   E *e;
+  F *f;
 }
 
 #include "virtualcall.h"
diff --git a/test/Analysis/virtualcall.h b/test/Analysis/virtualcall.h
index 9f7094d..c2ad8a6 100644
--- a/test/Analysis/virtualcall.h
+++ b/test/Analysis/virtualcall.h
@@ -18,7 +18,15 @@
   class A {
   public:
     A() {
-      foo(); // expected-warning{{Call virtual functions during construction or destruction will never go to a more derived class}}
+      foo();
+#if !PUREONLY
+#if INTERPROCEDURAL
+          // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
+#else
+          // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}}
+#endif
+#endif
+
     }
 
     virtual int foo();
diff --git a/test/Analysis/vla.c b/test/Analysis/vla.c
index f94bea9..eb06c24 100644
--- a/test/Analysis/vla.c
+++ b/test/Analysis/vla.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 // Zero-sized VLAs.
 void check_zero_sized_VLA(int x) {
diff --git a/test/Analysis/weak-functions.c b/test/Analysis/weak-functions.c
index a983f92..514a943 100644
--- a/test/Analysis/weak-functions.c
+++ b/test/Analysis/weak-functions.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection,unix.Malloc,unix.cstring,alpha.unix.cstring,unix.API,osx.API,osx.cocoa.RetainCount -Wno-null-dereference -Wno-tautological-compare -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection,unix.Malloc,unix.cstring,alpha.unix.cstring,unix.API,osx.API,osx.cocoa.RetainCount -Wno-null-dereference -Wno-tautological-compare -analyzer-store=region -fblocks -verify %s
 #define NULL 0
 void clang_analyzer_eval(int);
 void myFunc();
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 8ba9040..23d23bc 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -18,6 +18,13 @@
   endif()
 endif()
 
+llvm_canonicalize_cmake_booleans(
+  CLANG_BUILD_EXAMPLES
+  CLANG_ENABLE_ARCMT
+  CLANG_ENABLE_STATIC_ANALYZER
+  ENABLE_BACKTRACES
+  HAVE_LIBZ)
+
 configure_lit_site_cfg(
   ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
   ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
@@ -39,6 +46,7 @@
   c-index-test diagtool
   clang-tblgen
   clang-offload-bundler
+  clang-import-test
   )
   
 if(CLANG_ENABLE_STATIC_ANALYZER)
@@ -54,7 +62,7 @@
   )
 endif ()
 
-if (ENABLE_CLANG_EXAMPLES)
+if (CLANG_BUILD_EXAMPLES)
   list(APPEND CLANG_TEST_DEPS
     AnnotateFunctions
     clang-interpreter
@@ -62,7 +70,7 @@
     )
 endif ()
 
-if (ENABLE_CLANG_STATIC_ANALYZER AND ENABLE_CLANG_EXAMPLES)
+if (CLANG_ENABLE_STATIC_ANALYZER AND CLANG_BUILD_EXAMPLES)
   list(APPEND CLANG_TEST_DEPS
     SampleAnalyzerPlugin
     )
@@ -78,6 +86,9 @@
     FileCheck count not
     llc
     llvm-bcanalyzer
+    llvm-cat
+    llvm-dis
+    llvm-modextract
     llvm-nm
     llvm-objdump
     llvm-profdata
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
index 004d1e4..ca17ba5 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
@@ -9,7 +9,7 @@
     typedef int A; // expected-note {{declared here}}
 
     int test() {
-      struct A a; // expected-error {{elaborated type refers to a typedef}}
+      struct A a; // expected-error {{typedef 'A' cannot be referenced with a struct specifier}}
       return a.foo;
     }
   }
@@ -18,7 +18,7 @@
     template <class> class A; // expected-note {{declared here}}
 
     int test() {
-      struct A a; // expected-error {{elaborated type refers to a template}}
+      struct A a; // expected-error {{template 'A' cannot be referenced with a struct specifier}}
       return a.foo;
     }
   }
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
index f32b239..18b1883 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
@@ -1,17 +1,25 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 struct X0 {
+  X0();
+  X0(int);
   X0 f1();
   X0 f2();
+  typedef int A;
+  typedef X0 B;
 };
 
 template<typename T>
-struct X1 {
+struct X1 : X0 {
+  X1();
   X1<T>(int);
   (X1<T>)(float);
   X1 f2();
   X1 f2(int);
   X1 f2(float);
+  X1 f2(double);
+  X1 f2(short);
+  X1 f2(long);
 };
 
 // Error recovery: out-of-line constructors whose names have template arguments.
@@ -19,13 +27,88 @@
 template<typename T> (X1<T>::X1<T>)(float) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}}
 
 // Error recovery: out-of-line constructor names intended to be types
-X0::X0 X0::f1() { return X0(); } // expected-error{{qualified reference to 'X0' is a constructor name rather than a type wherever a constructor can be declared}}
+X0::X0 X0::f1() { return X0(); } // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
 
 struct X0::X0 X0::f2() { return X0(); }
 
-template<typename T> X1<T>::X1<T> X1<T>::f2() { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}}
-template<typename T> X1<T>::X1<T> (X1<T>::f2)(int) { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}}
+template<typename T> X1<T>::X1<T> X1<T>::f2() { } // expected-error{{missing 'typename'}}
+template<typename T> X1<T>::X1<T> (X1<T>::f2)(int) { } // expected-error{{missing 'typename'}}
 template<typename T> struct X1<T>::X1<T> (X1<T>::f2)(float) { }
+template<typename T> struct X1<T>::X1 (X1<T>::f2)(double) { }
+template<typename T> typename X1<T>::template X1<T> X1<T>::f2(short) { } // expected-warning {{qualified reference to 'X1' is a constructor name rather than a template name in this context}}
+template<typename T> typename X1<T>::template X1<T> (X1<T>::f2)(long) { } // expected-warning {{qualified reference to 'X1' is a constructor name rather than a template name in this context}}
+
+void x1test(X1<int> x1i) {
+  x1i.f2();
+  x1i.f2(0);
+  x1i.f2(0.f);
+  x1i.f2(0.);
+}
+
+void other_contexts() {
+  X0::X0 x0; // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+  X1<int>::X1 x1a; // expected-error{{qualified reference to 'X1' is a constructor name rather than a type in this context}}
+  X1<int>::X1<float> x1b; // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name in this context}}
+
+  X0::B ok1;
+  X0::X0::A ok2;
+  X0::X0::X0 x0b; // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+  X1<int>::X0 ok3;
+  X1<int>::X0::X0 x0c; // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+  X1<int>::X1<float>::X0 ok4;
+
+  {
+    typename X0::X0 tn1; // expected-warning{{qualified reference to 'X0' is a constructor name rather than a type in this context}} expected-warning 0-1{{typename}}
+    typename X1<int>::X1<float> tn2; // expected-warning{{qualified reference to 'X1' is a constructor name rather than a template name in this context}} expected-warning 0-1{{typename}}
+    typename X0::B ok1; // expected-warning 0-1{{typename}}
+    typename X1<int>::X0 ok2; // expected-warning 0-1{{typename}}
+  }
+
+  {
+    struct X0::X0 tag1;
+    struct X1<int>::X1 tag2;
+    struct X1<int>::X1<int> tag3;
+  }
+
+  int a;
+  {
+    X0::X0(a); // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+  }
+}
+
+template<typename T> void in_instantiation_x0() {
+  typename T::X0 x0; // expected-warning{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+  typename T::A a;
+  typename T::B b;
+}
+template void in_instantiation_x0<X0>(); // expected-note {{instantiation of}}
+
+template<typename T> void in_instantiation_x1() {
+  typename T::X1 x1; // expected-warning{{qualified reference to 'X1' is a constructor name rather than a type in this context}}
+  typename T::template X1<int> x1i; // expected-warning{{qualified reference to 'X1' is a constructor name rather than a template name in this context}}
+  typename T::X0 x0;
+}
+template void in_instantiation_x1<X1<int> >(); // expected-note {{instantiation of}}
+
+namespace sfinae {
+  template<typename T> void f(typename T::X0 *) = delete; // expected-warning 0-1{{extension}}
+  template<typename T> void f(...);
+  void g() { f<X0>(0); }
+}
+
+namespace versus_injected_class_name {
+  template <typename T> struct A : T::B {
+    struct T::B *p;
+    typename T::B::type a;
+    A() : T::B() {}
+
+    typename T::B b; // expected-warning {{qualified reference to 'B' is a constructor name rather than a type in this context}}
+  };
+  struct B {
+    typedef int type;
+  };
+  template struct A<B>; // expected-note {{in instantiation of}}
+}
 
 // We have a special case for lookup within using-declarations that are
 // member-declarations: foo::bar::baz::baz always names baz's constructor
@@ -109,7 +192,7 @@
   // FIXME: Consider reusing the same diagnostic between dependent and non-dependent contexts
   typedef int I;
   struct UsingInt {
-    using I::I; // expected-error {{'I' (aka 'int') is not a class, namespace, or enumeration}}
+    using I::I; // expected-error {{'InhCtor::I' (aka 'int') is not a class, namespace, or enumeration}}
   };
   template<typename T> struct UsingIntTemplate {
     using T::T; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
diff --git a/test/CXX/basic/basic.start/basic.start.init/p2.cpp b/test/CXX/basic/basic.start/basic.start.init/p2.cpp
new file mode 100644
index 0000000..3615821
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.init/p2.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -verify %s -pedantic-errors -std=c++11
+// RUN: %clang_cc1 -verify %s -pedantic-errors -std=c++14
+// expected-no-diagnostics
+
+struct foo_t {
+  union {
+    int i;
+    volatile int j;
+  } u;
+};
+
+__attribute__((__require_constant_initialization__))
+static const foo_t x = {{0}};
+
+union foo_u {
+  int i;
+  volatile int j;
+};
+
+__attribute__((__require_constant_initialization__))
+static const foo_u y = {0};
diff --git a/test/CXX/class.derived/class.abstract/p16.cpp b/test/CXX/class.derived/class.abstract/p16.cpp
index 29adbcc..80396a9 100644
--- a/test/CXX/class.derived/class.abstract/p16.cpp
+++ b/test/CXX/class.derived/class.abstract/p16.cpp
@@ -35,13 +35,15 @@
 // expected-error@-1 {{deleted function '~E' cannot override a non-deleted function}}
 // expected-note@-2 {{destructor of 'E' is implicitly deleted because base class 'D' has an inaccessible destructor}}
 // expected-error@-3 {{deleted function 'operator=' cannot override a non-deleted function}}
-// expected-note@-4 {{copy assignment operator of 'E' is implicitly deleted because base class 'D' has an inaccessible copy assignment operator}}
+// expected-note@-4 {{while declaring the implicit copy assignment operator for 'E'}}
+// expected-note@-5 {{copy assignment operator of 'E' is implicitly deleted because base class 'D' has an inaccessible copy assignment operator}}
 struct F : D {};
 struct G : D {};
 // expected-error@-1 {{deleted function '~G' cannot override a non-deleted function}}
-// expected-note@-2 {{move assignment operator of 'G' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}}
+// expected-note@-2 {{destructor of 'G' is implicitly deleted because base class 'D' has an inaccessible destructor}}
 // expected-error@-3 {{deleted function 'operator=' cannot override a non-deleted function}}
-// expected-note@-4 {{destructor of 'G' is implicitly deleted because base class 'D' has an inaccessible destructor}}
+// expected-note@-4 {{while declaring the implicit move assignment operator for 'G'}}
+// expected-note@-5 {{move assignment operator of 'G' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}}
 struct H : D {
   H &operator=(H&&) = default;
   // expected-error@-1 {{deleted function 'operator=' cannot override a non-deleted function}}
diff --git a/test/CXX/class.derived/class.abstract/p2.cpp b/test/CXX/class.derived/class.abstract/p2.cpp
new file mode 100644
index 0000000..713a526
--- /dev/null
+++ b/test/CXX/class.derived/class.abstract/p2.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+// no objects of an abstract class can be created except as subobjects of a
+// class derived from it
+
+struct A {
+  A() {}
+  A(int) : A() {} // ok
+
+  virtual void f() = 0; // expected-note 1+{{unimplemented}}
+};
+
+void f(A &&a);
+
+void g() {
+  f({}); // expected-error {{abstract class}}
+  f({0}); // expected-error {{abstract class}}
+  f(0); // expected-error {{abstract class}}
+}
+
+struct B : A {
+  B() : A() {} // ok
+};
diff --git a/test/CXX/class.derived/class.abstract/p3.cpp b/test/CXX/class.derived/class.abstract/p3.cpp
new file mode 100644
index 0000000..ad5b874
--- /dev/null
+++ b/test/CXX/class.derived/class.abstract/p3.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+struct A {
+  A() {}
+  A(int) : A() {} // ok
+
+  virtual void f() = 0; // expected-note 1+{{unimplemented}}
+};
+
+template<typename> struct SecretlyAbstract {
+  SecretlyAbstract();
+  SecretlyAbstract(int);
+  virtual void f() = 0; // expected-note 1+{{unimplemented}}
+};
+using B = SecretlyAbstract<int>;
+using C = SecretlyAbstract<float>;
+using D = SecretlyAbstract<char>[1];
+
+B b; // expected-error {{abstract class}}
+D d; // expected-error {{abstract class}}
+
+template<int> struct N;
+
+// Note: C is not instantiated anywhere in this file, so we never discover that
+// it is in fact abstract. The C++ standard suggests that we need to
+// instantiate in all cases where abstractness could affect the validity of a
+// program, but that breaks a *lot* of code, so we don't do that.
+//
+// FIXME: Once DR1640 is resolved, remove the check on forming an abstract
+// array type entirely. The only restriction we need is that you can't create
+// an object of abstract (most-derived) type.
+
+
+// An abstract class shall not be used
+
+//  - as a parameter type
+void f(A&);
+void f(A); // expected-error {{abstract class}}
+void f(A[1]); // expected-error {{abstract class}}
+void f(B); // expected-error {{abstract class}}
+void f(B[1]); // expected-error {{abstract class}}
+void f(C);
+void f(C[1]);
+void f(D); // expected-error {{abstract class}}
+void f(D[1]); // expected-error {{abstract class}}
+
+//  - as a function return type
+A &f(N<0>);
+A *f(N<1>);
+A f(N<2>); // expected-error {{abstract class}}
+A (&f(N<3>))[2]; // expected-error {{abstract class}}
+B f(N<4>); // expected-error {{abstract class}}
+B (&f(N<5>))[2]; // expected-error {{abstract class}}
+C f(N<6>);
+C (&f(N<7>))[2];
+
+//  - as the type of an explicit conversion
+void g(A&&);
+void h() {
+  A(); // expected-error {{abstract class}}
+  A(0); // expected-error {{abstract class}}
+  A{}; // expected-error {{abstract class}}
+  A{0}; // expected-error {{abstract class}}
+  (A)(0); // expected-error {{abstract class}}
+  (A){}; // expected-error {{abstract class}}
+  (A){0}; // expected-error {{abstract class}}
+
+  D(); // expected-error {{array type}}
+  D{}; // expected-error {{abstract class}}
+  D{0}; // expected-error {{abstract class}}
+  (D){}; // expected-error {{abstract class}}
+  (D){0}; // expected-error {{abstract class}}
+}
+
+template<typename T> void t(T); // expected-note 2{{abstract class}}
+void i(A &a, B &b, C &c, D &d) {
+  // FIXME: These should be handled consistently. We currently reject the first
+  // two early because we (probably incorrectly, depending on dr1640) take
+  // abstractness into account in forming implicit conversion sequences.
+  t(a); // expected-error {{no matching function}}
+  t(b); // expected-error {{no matching function}}
+  t(c); // expected-error {{allocating an object of abstract class type}}
+  t(d); // ok, decays to pointer
+}
+
+struct E : A {
+  E() : A() {} // ok
+  E(int n) : A( A(n) ) {} // expected-error {{abstract class}}
+};
+
+namespace std {
+  template<typename T> struct initializer_list {
+    const T *begin, *end;
+    initializer_list();
+  };
+}
+std::initializer_list<A> ila = {1, 2, 3, 4}; // expected-error {{abstract class}}
diff --git a/test/CXX/class.derived/class.member.lookup/p10.cpp b/test/CXX/class.derived/class.member.lookup/p10.cpp
new file mode 100644
index 0000000..afd8752
--- /dev/null
+++ b/test/CXX/class.derived/class.member.lookup/p10.cpp
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wshadow-all
+
+// Basic cases, ambiguous paths, and fields with different access
+class A {
+public:
+  int x;  // expected-note 2{{declared here}}
+protected:
+  int y;  // expected-note 2{{declared here}}
+private:
+  int z;
+};
+
+struct B : A {
+};
+
+struct C : A {
+};
+
+struct W {
+  int w;  // expected-note {{declared here}}
+};
+
+struct U : W {
+};
+
+struct V : W {
+};
+
+class D {
+public:
+  char w; // expected-note {{declared here}}
+private:
+  char x;
+};
+
+// Check direct inheritance and multiple paths to the same base.
+class E : B, C, D, U, V
+{
+  unsigned x;  // expected-warning {{non-static data member 'x' of 'E' shadows member inherited from type 'A'}}
+  char y;  // expected-warning {{non-static data member 'y' of 'E' shadows member inherited from type 'A'}}
+  double z;
+  char w;  // expected-warning {{non-static data member 'w' of 'E' shadows member inherited from type 'D'}}  expected-warning {{non-static data member 'w' of 'E' shadows member inherited from type 'W'}}
+};
+
+// Virtual inheritance
+struct F : virtual A {
+};
+
+struct G : virtual A {
+};
+
+class H : F, G {
+  int x;  // expected-warning {{non-static data member 'x' of 'H' shadows member inherited from type 'A'}}
+  int y;  // expected-warning {{non-static data member 'y' of 'H' shadows member inherited from type 'A'}}
+  int z;
+};
+
+// Indirect inheritance
+struct I {
+  union {
+    int x;  // expected-note {{declared here}}
+    int y;
+  };
+};
+
+struct J : I {
+  int x;  // expected-warning {{non-static data member 'x' of 'J' shadows member inherited from type 'I'}}
+};
+
+// non-access paths
+class N : W {
+};
+
+struct K {
+  int y;
+};
+
+struct L : private K {
+};
+
+struct M : L {
+  int y;
+  int w;
+};
+
+// Multiple ambiguous paths with different accesses
+struct A1 {
+  int x;  // expected-note {{declared here}}
+};
+
+class B1 : A1 {
+};
+
+struct B2 : A1 {
+};
+
+struct C1 : B1, B2 {
+};
+
+class D1 : C1 {
+};
+
+struct D2 : C1 {
+};
+
+class D3 : C1 {
+};
+
+struct E1 : D1, D2, D3{
+  int x;  // expected-warning {{non-static data member 'x' of 'E1' shadows member inherited from type 'A1'}}
+};
+
+
+
diff --git a/test/CXX/class.derived/class.member.lookup/p6.cpp b/test/CXX/class.derived/class.member.lookup/p6.cpp
index 7239881..0a400a2 100644
--- a/test/CXX/class.derived/class.member.lookup/p6.cpp
+++ b/test/CXX/class.derived/class.member.lookup/p6.cpp
@@ -1,24 +1,24 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wshadow-field
 
 class V { 
 public: 
   int f(); 
-  int x; 
+  int x; // expected-note {{declared here}}
 };
 
 class W { 
 public: 
   int g(); // expected-note{{member found by ambiguous name lookup}}
-  int y; // expected-note{{member found by ambiguous name lookup}}
+  int y; // expected-note{{member found by ambiguous name lookup}} expected-note {{declared here}}
 };
 
 class B : public virtual V, public W
 {
 public:
   int f(); 
-  int x;
+  int x;  // expected-warning {{non-static data member 'x' of 'B' shadows member inherited from type 'V'}}
   int g();  // expected-note{{member found by ambiguous name lookup}}
-  int y; // expected-note{{member found by ambiguous name lookup}}
+  int y; // expected-note{{member found by ambiguous name lookup}} expected-warning {{non-static data member 'y' of 'B' shadows member inherited from type 'W'}}
 };
 
 class C : public virtual V, public W { };
diff --git a/test/CXX/class.derived/class.member.lookup/p7.cpp b/test/CXX/class.derived/class.member.lookup/p7.cpp
index a785e0f..7750577 100644
--- a/test/CXX/class.derived/class.member.lookup/p7.cpp
+++ b/test/CXX/class.derived/class.member.lookup/p7.cpp
@@ -1,11 +1,9 @@
-// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify %s -Wshadow-field
 
-// expected-no-diagnostics
-
-struct A { int n; };
-struct B { float n; };
+struct A { int n; };  // expected-note {{declared here}}
+struct B { float n; };  // expected-note {{declared here}}
 struct C : A, B {};
 struct D : virtual C {};
-struct E : virtual C { char n; };
+struct E : virtual C { char n; }; // expected-warning {{non-static data member 'n' of 'E' shadows member inherited from type 'A'}} expected-warning {{non-static data member 'n' of 'E' shadows member inherited from type 'B'}}
 struct F : D, E {} f;
 char &k = f.n;
diff --git a/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp b/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
new file mode 100644
index 0000000..d1ad040
--- /dev/null
+++ b/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+
+namespace nodiag {
+
+template <typename T> requires bool(T())
+struct A;
+template <typename U> requires bool(U())
+struct A;
+
+} // end namespace nodiag
+
+namespace diag {
+
+template <typename T> requires true // expected-note{{previous template declaration is here}}
+struct A;
+template <typename T> struct A; // expected-error{{associated constraints differ in template redeclaration}}
+
+template <typename T> struct B; // expected-note{{previous template declaration is here}}
+template <typename T> requires true // expected-error{{associated constraints differ in template redeclaration}}
+struct B;
+
+template <typename T> requires true // expected-note{{previous template declaration is here}}
+struct C;
+template <typename T> requires !0 // expected-error{{associated constraints differ in template redeclaration}}
+struct C;
+
+} // end namespace diag
+
+namespace nodiag {
+
+struct AA {
+  template <typename T> requires someFunc(T())
+  struct A;
+};
+
+template <typename T> requires someFunc(T())
+struct AA::A { };
+
+struct AAF {
+  template <typename T> requires someFunc(T())
+  friend struct AA::A;
+};
+
+} // end namespace nodiag
+
+namespace diag {
+
+template <unsigned N>
+struct TA {
+  template <template <unsigned> class TT> requires TT<N>::happy // expected-note 2{{previous template declaration is here}}
+  struct A;
+
+  struct AF;
+};
+
+template <unsigned N>
+template <template <unsigned> class TT> struct TA<N>::A { }; // expected-error{{associated constraints differ in template redeclaration}}
+
+template <unsigned N>
+struct TA<N>::AF {
+  template <template <unsigned> class TT> requires TT<N + 0>::happy // expected-error{{associated constraints differ in template redeclaration}}
+  friend struct TA::A;
+};
+
+} // end namespace diag
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
index 3e04d50..0c58da0 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
@@ -1,16 +1,16 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
-struct B1 { // expected-note 2{{candidate}}
+struct B1 {
   B1(int); // expected-note {{candidate}}
 };
 
-struct B2 { // expected-note 2{{candidate}}
+struct B2 {
   B2(int); // expected-note {{candidate}}
 };
 
 struct D1 : B1, B2 { // expected-note 2{{candidate}}
-  using B1::B1; // expected-note 3{{inherited here}}
-  using B2::B2; // expected-note 3{{inherited here}}
+  using B1::B1; // expected-note {{inherited here}}
+  using B2::B2; // expected-note {{inherited here}}
 };
 D1 d1(0); // expected-error {{ambiguous}}
 
@@ -28,24 +28,35 @@
   struct C;
   struct D;
 
-  struct A { // expected-note 4{{candidate}}
+  struct convert_to_D1 {
+    operator D&&();
+  };
+  struct convert_to_D2 {
+    operator D&&();
+  };
+
+  struct A { // expected-note 2{{candidate}}
     A(); // expected-note {{candidate}}
 
     A(C &&); // expected-note {{candidate}}
     C &operator=(C&&); // expected-note {{candidate}}
 
-    A(D &&); // expected-note {{candidate}}
+    A(D &&);
     D &operator=(D&&); // expected-note {{candidate}}
+
+    A(convert_to_D2); // expected-note {{candidate}}
   };
 
-  struct B { // expected-note 4{{candidate}}
+  struct B { // expected-note 2{{candidate}}
     B(); // expected-note {{candidate}}
 
     B(C &&); // expected-note {{candidate}}
     C &operator=(C&&); // expected-note {{candidate}}
 
-    B(D &&); // expected-note {{candidate}}
+    B(D &&);
     D &operator=(D&&); // expected-note {{candidate}}
+
+    B(convert_to_D2); // expected-note {{candidate}}
   };
 
   struct C : A, B {
@@ -55,9 +66,9 @@
     using B::operator=;
   };
   struct D : A, B {
-    using A::A; // expected-note 5{{inherited here}}
+    using A::A; // expected-note 3{{inherited here}}
     using A::operator=;
-    using B::B; // expected-note 5{{inherited here}}
+    using B::B; // expected-note 3{{inherited here}}
     using B::operator=;
 
     D(int);
@@ -75,7 +86,20 @@
   // versions are inherited.
   D d; // expected-error {{ambiguous}}
   void f(D d) {
-    D d2(static_cast<D&&>(d)); // expected-error {{ambiguous}}
+    D d2(static_cast<D&&>(d)); // ok, ignores inherited constructors
+    D d3(convert_to_D1{}); // ok, ignores inherited constructors
+    D d4(convert_to_D2{}); // expected-error {{ambiguous}}
     d = static_cast<D&&>(d); // expected-error {{ambiguous}}
   }
+
+  struct Y;
+  struct X {
+    X();
+    X(volatile Y &); // expected-note 3{{inherited constructor cannot be used to copy object}}
+  } x;
+  struct Y : X { using X::X; } volatile y;
+  struct Z : Y { using Y::Y; } volatile z; // expected-note 4{{no known conversion}} expected-note 2{{would lose volatile}} expected-note 3{{requires 0}} expected-note 3{{inherited here}}
+  Z z1(x); // expected-error {{no match}}
+  Z z2(y); // expected-error {{no match}}
+  Z z3(z); // expected-error {{no match}}
 }
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
index 6c63f06..0ea4eeb 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
 // RUN: not %clang_cc1 -fsyntax-only -std=c++98 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX98 %s
 // RUN: not %clang_cc1 -fsyntax-only -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX11 %s
 // C++0x N2914.
@@ -44,10 +45,158 @@
 #endif
 }
 
-template <typename T>
-struct PR21933 : T {
-  static void StaticFun() { using T::member; } // expected-error{{using declaration cannot refer to class member}}
-};
+namespace PR21933 {
+  struct A { int member; };
+  struct B { static int member; };
+  enum C { member };
+
+  template <typename T>
+  struct X {
+    static void StaticFun() {
+      using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}}
+#if __cplusplus < 201103L
+    // expected-error@-2 {{cannot be used prior to '::'}}
+#endif
+      (void)member;
+    }
+  };
+  template<typename T>
+  struct Y : T { 
+    static void StaticFun() {
+      using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}}
+      (void)member;
+    }
+  };
+
+  void f() { 
+    X<A>::StaticFun(); // expected-note {{instantiation of}}
+    X<B>::StaticFun(); // expected-note {{instantiation of}}
+    X<C>::StaticFun();
+#if __cplusplus < 201103L
+    // expected-note@-2 {{instantiation of}}
+#endif
+    Y<A>::StaticFun(); // expected-note {{instantiation of}}
+    Y<B>::StaticFun(); // expected-note {{instantiation of}}
+  }
+
+  template<typename T, typename U> void value_vs_value() {
+    using T::a; // expected-note {{previous}}
+#if __cplusplus < 201103L
+    // expected-error@-2 {{cannot be used prior to '::'}}
+#endif
+    extern int a(); // expected-error {{different kind of symbol}}
+    a();
+
+    extern int b(); // expected-note {{previous}}
+    using T::b; // expected-error {{different kind of symbol}}
+    b();
+
+    using T::c; // expected-note {{previous}}
+    using U::c; // expected-error-re {{redefinition of 'c'{{$}}}}
+    c();
+  }
+
+  template<typename T, typename U> void value_vs_type() {
+    using T::Xt; // expected-note {{previous}}
+    typedef struct {} Xt; // expected-error {{different kind of symbol}}
+    (void)Xt;
+
+    using T::Xs; // expected-note {{hidden by}}
+    struct Xs {};
+    (void)Xs;
+    Xs xs; // expected-error {{must use 'struct'}}
+
+    using T::Xe; // expected-note {{hidden by}}
+    enum Xe {};
+    (void)Xe;
+    Xe xe; // expected-error {{must use 'enum'}}
+
+    typedef struct {} Yt; // expected-note {{candidate}}
+    using T::Yt; // eypected-error {{different kind of symbol}} expected-note {{candidate}}
+    Yt yt; // expected-error {{ambiguous}}
+
+    struct Ys {};
+    using T::Ys; // expected-note {{hidden by}}
+    (void)Ys;
+    Ys ys; // expected-error {{must use 'struct'}}
+
+    enum Ye {};
+    using T::Ye; // expected-note {{hidden by}}
+    Ye ye; // expected-error {{must use 'enum'}}
+  }
+
+  template<typename T> void type() {
+    // Must be a class member because T:: can only name a class or enum,
+    // and an enum cannot have a type member.
+    using typename T::X; // expected-error {{cannot refer to class member}}
+  }
+
+  namespace N1 { enum E { a, b, c }; }
+  namespace N2 { enum E { a, b, c }; }
+  void g() { value_vs_value<N1::E, N2::E>(); }
+#if __cplusplus < 201103L
+    // expected-note@-2 {{in instantiation of}}
+#endif
+
+#if __cplusplus >= 201402L
+  namespace partial_substitute {
+    template<typename T> auto f() {
+      return [](auto x) {
+        using A = typename T::template U<decltype(x)>;
+        using A::E::e;
+        struct S : A {
+          using A::f;
+          using typename A::type;
+          type f(int) { return e; }
+        };
+        return S();
+      };
+    }
+    enum Enum { e };
+    struct X {
+      template<typename T> struct U {
+        int f(int, int);
+        using type = int;
+        using E = Enum;
+      };
+    };
+    int test() {
+      auto s = f<X>()(0);
+      return s.f(0) + s.f(0, 0);
+    }
+
+    template<typename T, typename U> auto g() {
+      return [](auto x) {
+        using X = decltype(x);
+        struct S : T::template Q<X>, U::template Q<X> {
+          using T::template Q<X>::f;
+          using U::template Q<X>::f;
+          void h() { f(); }
+          void h(int n) { f(n); }
+        };
+        return S();
+      };
+    }
+    struct A { template<typename> struct Q { int f(); }; };
+    struct B { template<typename> struct Q { int f(int); }; };
+    int test2() {
+      auto s = g<A, B>()(0);
+      s.f();
+      s.f(0);
+      s.h();
+      s.h(0);
+    }
+  }
+#endif
+
+  template<typename T, typename U> struct RepeatedMember : T, U {
+    // FIXME: This is the wrong error: we should complain that a member type
+    // cannot be redeclared at class scope.
+    using typename T::type; // expected-note {{candidate}}
+    using typename U::type; // expected-note {{candidate}}
+    type x; // expected-error {{ambiguous}}
+  };
+}
 
 struct S {
   static int n;
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
index eb75151..e8f1215 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
@@ -3,15 +3,15 @@
 
 // FIXME: This is in p11 (?) in C++1y.
 void f() {
-  decltype(auto) a = a; // expected-error{{variable 'a' declared with 'decltype(auto)' type cannot appear in its own initializer}}
-  if (decltype(auto) b = b) {} // expected-error {{variable 'b' declared with 'decltype(auto)' type cannot appear in its own initializer}}
-  decltype(auto) c = ({ decltype(auto) d = c; 0; }); // expected-error {{variable 'c' declared with 'decltype(auto)' type cannot appear in its own initializer}}
+  decltype(auto) a = a; // expected-error{{variable 'a' declared with deduced type 'decltype(auto)' cannot appear in its own initializer}}
+  if (decltype(auto) b = b) {} // expected-error {{variable 'b' declared with deduced type 'decltype(auto)' cannot appear in its own initializer}}
+  decltype(auto) c = ({ decltype(auto) d = c; 0; }); // expected-error {{variable 'c' declared with deduced type 'decltype(auto)' cannot appear in its own initializer}}
 }
 
 void g() {
-  decltype(auto) a; // expected-error{{declaration of variable 'a' with type 'decltype(auto)' requires an initializer}}
+  decltype(auto) a; // expected-error{{declaration of variable 'a' with deduced type 'decltype(auto)' requires an initializer}}
   
-  decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with type 'decltype(auto) *' requires an initializer}}
+  decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with deduced type 'decltype(auto) *' requires an initializer}}
 
   if (decltype(auto) b) {} // expected-error {{must have an initializer}}
   for (;decltype(auto) b;) {} // expected-error {{must have an initializer}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1z.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1z.cpp
new file mode 100644
index 0000000..73caa2d
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1z.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1z
+
+// FIXME: This is in p10 (?) in C++1z.
+template<typename T> struct A {
+  A(T);
+};
+template<typename T> A(T) -> A<T>;
+A a = a; // expected-error{{variable 'a' declared with deduced type 'A' cannot appear in its own initializer}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
index e91cacf..440c782 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
@@ -1,17 +1,17 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions -Wc++11-compat 
 void f() {
-  auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
-  auto *b = b; // expected-error{{variable 'b' declared with 'auto' type cannot appear in its own initializer}}
-  const auto c = c; // expected-error{{variable 'c' declared with 'auto' type cannot appear in its own initializer}}
-  if (auto d = d) {} // expected-error {{variable 'd' declared with 'auto' type cannot appear in its own initializer}}
-  auto e = ({ auto f = e; 0; }); // expected-error {{variable 'e' declared with 'auto' type cannot appear in its own initializer}}
+  auto a = a; // expected-error{{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
+  auto *b = b; // expected-error{{variable 'b' declared with deduced type 'auto *' cannot appear in its own initializer}}
+  const auto c = c; // expected-error{{variable 'c' declared with deduced type 'const auto' cannot appear in its own initializer}}
+  if (auto d = d) {} // expected-error {{variable 'd' declared with deduced type 'auto' cannot appear in its own initializer}}
+  auto e = ({ auto f = e; 0; }); // expected-error {{variable 'e' declared with deduced type 'auto' cannot appear in its own initializer}}
 }
 
 void g() {
-  auto a; // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}}
+  auto a; // expected-error{{declaration of variable 'a' with deduced type 'auto' requires an initializer}}
   
-  auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}}
+  auto *b; // expected-error{{declaration of variable 'b' with deduced type 'auto *' requires an initializer}}
 
   if (auto b) {} // expected-error {{must have an initializer}}
   for (;auto b;) {} // expected-error {{must have an initializer}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
index 46c874f..bf1b309 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
@@ -36,7 +36,7 @@
 };
 
 struct S {
-  static const auto a; // expected-error {{declaration of variable 'a' with type 'const auto' requires an initializer}}
+  static const auto a; // expected-error {{declaration of variable 'a' with deduced type 'const auto' requires an initializer}}
   static const auto b = 0;
   static const int c;
 };
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
index 0cdf3c6..a260f99 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
@@ -9,7 +9,7 @@
 
   void f() throw (auto); // expected-error{{'auto' not allowed here}}
 
-  friend auto; // expected-error{{'auto' not allowed in non-static struct member}}
+  friend auto; // expected-error{{'auto' not allowed in friend declaration}}
 
   operator auto(); // expected-error{{'auto' not allowed in conversion function type}}
 };
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp
index 06bd72e..60ddabe 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp
@@ -51,7 +51,7 @@
 const decltype(auto) f4(); // expected-error {{'decltype(auto)' cannot be combined with other type specifiers}}
 typedef decltype(auto) f5(); // expected-error {{'decltype(auto)' not allowed in typedef}}
 decltype(auto) ((((((f6))))())); // ok
-decltype(auto) f7()(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{function cannot return function type}}
+decltype(auto) f7()(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}}
 decltype(auto) (S::*f8)(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{requires an initializer}}
 decltype(auto) &f9(); // expected-error {{cannot form reference to 'decltype(auto)'}}
 decltype(auto) (&f10())[10]; // expected-error {{cannot form array of 'decltype(auto)'}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
index 8d789bd..e9294d7 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions
 void f() {
@@ -19,22 +20,42 @@
 }
 
 void g() {
+#if __has_feature(cxx_trailing_return)
   auto a = 0,
-#if __has_feature(cxx_trailing_return)
-       (*b)() -> void,
-#endif
+       (*b)() -> void, // expected-error {{declaration with trailing return type must be the only declaration in its group}}
        c = 0;
-  auto d = 0, // expected-error {{'auto' deduced as 'int' in declaration of 'd' and deduced as 'double' in declaration of 'f'}}
-#if __has_feature(cxx_trailing_return)
-       (*e)() -> void,
-#endif
+  auto d = 0,
+       e() -> void, // expected-error {{declaration with trailing return type must be the only declaration in its group}}
        f = 0.0;
+  auto x() -> void, // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+       y() -> void;
+#endif
 
 #if __has_feature(cxx_decltype)
   auto g = 0ull, h = decltype(g)(0);
 #endif
 }
 
+#if __has_feature(cxx_trailing_return)
+int F();
+auto p = 0, (*q)() -> auto = F; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+  #if __cplusplus < 201402L
+  // expected-error@-2 {{'auto' not allowed in function return type}}
+  #endif
+#endif
+
+#if __cplusplus >= 201402L
+namespace DeducedReturnType {
+  auto a = 0,
+       b(), // expected-error {{function with deduced return type must be the only declaration in its group}}
+       c = 0.0;
+  auto d(), // expected-error {{function with deduced return type must be the only declaration in its group}}
+       e = 1;
+  auto f(), // expected-error {{function with deduced return type must be the only declaration in its group}}
+       g();
+}
+#endif
+
 template<typename T> void h() {
   auto a = T(), *b = &a;
 #if __has_feature(cxx_decltype)
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
new file mode 100644
index 0000000..cfb9a61
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+template<typename T> struct A { constexpr A(int = 0) {} };
+A() -> A<int>;
+A(int) -> A<char>;
+
+static constexpr inline const volatile A a = {}; // ok, specifiers are permitted
+// FIXME: There isn't really a good reason to reject this.
+A b; // expected-error {{requires an initializer}}
+A c [[]] {};
+
+A d = {}, e = {};
+A f(0), g{}; // expected-error {{template arguments deduced as 'A<char>' in declaration of 'f' and deduced as 'A<int>' in declaration of 'g'}}
+
+struct B {
+  static A a; // expected-error {{requires an initializer}}
+};
+extern A x; // expected-error {{requires an initializer}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
index 0271041..f3e79c0 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
@@ -2,18 +2,18 @@
 
 struct A { typedef int type; };
 template<typename T> using X = A; // expected-note {{declared here}}
-struct X<int>* p2; // expected-error {{elaborated type refers to a type alias template}}
+struct X<int>* p2; // expected-error {{type alias template 'X' cannot be referenced with a struct specifier}}
 
 
 template<typename T> using Id = T; // expected-note {{declared here}}
 template<template<typename> class F>
 struct Y {
-  struct F<int> i; // expected-error {{elaborated type refers to a type alias template}}
+  struct F<int> i; // expected-error {{type alias template 'Id' cannot be referenced with a struct specifier}}
   typename F<A>::type j; // ok
 
   // FIXME: don't produce the diagnostic both for the definition and the instantiation.
   template<typename T> using U = F<char>; // expected-note 2{{declared here}}
-  struct Y<F>::template U<char> k; // expected-error 2{{elaborated type refers to a type alias template}}
+  struct Y<F>::template U<char> k; // expected-error 2{{type alias template 'U' cannot be referenced with a struct specifier}}
   typename Y<F>::template U<char> l; // ok
 };
 template struct Y<Id>; // expected-note {{requested here}}
diff --git a/test/CXX/dcl.decl/dcl.decomp/p2.cpp b/test/CXX/dcl.decl/dcl.decomp/p2.cpp
index 639aff6..211719a 100644
--- a/test/CXX/dcl.decl/dcl.decomp/p2.cpp
+++ b/test/CXX/dcl.decl/dcl.decomp/p2.cpp
@@ -1,9 +1,20 @@
-// RUN: %clang_cc1 -std=c++1z -verify %s
+// RUN: %clang_cc1 -std=c++1z -verify %s -Wpedantic
+
+struct X {
+  X(int);
+  X(const X&) = delete;
+};
 
 int array() {
   static int arr[3] = {};
-  // FIXME: We are supposed to create an array object here and perform elementwise initialization.
-  auto [a, b, c] = arr; // expected-error {{cannot decompose non-class, non-array}}
+  auto [a, b, c] = arr;
+  static_assert(&a != &arr[0]);
+
+  using I3 = int[3];
+  auto [a2, b2, c2] = I3{1, 2, 3};
+
+  using X3 = X[3];
+  auto [a3, b3, c3] = X3{1, 2, 3};
 
   auto &[d, e] = arr; // expected-error {{type 'int [3]' decomposes into 3 elements, but only 2 names were provided}}
   auto &[f, g, h, i] = arr; // expected-error {{type 'int [3]' decomposes into 3 elements, but 4 names were provided}}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp
index 7a92e7a..f4f73a5 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp
@@ -134,13 +134,13 @@
 
 struct DefaultedBase {
   int n;
-  DefaultedBase() = default; // expected-note 0+ {{candidate}}
-  DefaultedBase(DefaultedBase const&) = default; // expected-note 0+ {{candidate}}
-  DefaultedBase(DefaultedBase &&) = default; // expected-note 0+ {{candidate}}
+  DefaultedBase() = default;
+  DefaultedBase(DefaultedBase const&) = default;
+  DefaultedBase(DefaultedBase &&) = default;
 };
 
 struct InheritingConstructors : DefaultedBase { // expected-note 3 {{candidate}}
-  using DefaultedBase::DefaultedBase; // expected-note 2 {{inherited here}}
+  using DefaultedBase::DefaultedBase;
 };
 InheritingConstructors ic = { 42 }; // expected-error {{no matching constructor}}
 
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
index f381ed7..ade3274 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
@@ -150,35 +150,44 @@
 
     void f(T);
     f(T{0});
+
+    char c;
+    auto t3 = T{c};
   }
 #if __cplusplus <= 201402L
-  // expected-error@-15 5{{cannot initialize}}
-  // expected-error@-15 5{{cannot initialize}}
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
+  //
+  //
+  // expected-error@-18 5{{cannot initialize}}
 #else
-  // expected-error@-29 {{cannot initialize}}
-  // expected-error@-29 {{cannot initialize}}
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
+  //
+  //
+  // expected-error@-35 {{cannot initialize}}
 #endif
 
   template<typename T> void bad() {
@@ -252,4 +261,12 @@
     (void)B{0.0}; // expected-error {{type 'double' cannot be narrowed}}
 #endif
   }
+
+#if __cplusplus > 201402L
+  enum class F : unsigned {};
+  F f1(unsigned x) { return F{x}; }
+  F f2(const unsigned x) { return F{x}; }
+  F f3(bool x) { return F{x}; }
+  F f4(const bool x) { return F{x}; }
+#endif
 }
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
index be1113d..052349c 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s
 
-// CHECK: example0
+// CHECK-LABEL: example0
 void example0() {
   double d = 2.0;
   // CHECK: VarDecl{{.*}}rd 'double &'
@@ -14,14 +14,15 @@
 struct A { };
 struct B : A { } b;
 
-// CHECK: example1
+// CHECK-LABEL: example1
 void example1() {
   // CHECK: VarDecl{{.*}}ra 'struct A &'
   // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
   A &ra = b;
   // CHECK: VarDecl{{.*}}rca 'const struct A &'
-  // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <NoOp>
-  // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
+  // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)>
+  // CHECK-NOT: MaterializeTemporaryExpr
+  // CHECK: ImplicitCastExpr{{.*}}'const struct B' lvalue <NoOp>
   const A& rca = b;
 }
 
@@ -31,21 +32,23 @@
   operator B();
 } x;
 
-// CHECK: example2
+// CHECK-LABEL: example2
 void example2() {
   // CHECK: VarDecl{{.*}}rca 'const struct A &'
-  // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
-  // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+  // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)>
+  // CHECK: MaterializeTemporaryExpr{{.*}}'const struct B'
+  // CHECK: ImplicitCastExpr{{.*}}'const struct B' <NoOp>
   // CHECK: CallExpr{{.*}}B
   const A &rca = f(); 
   // CHECK: VarDecl{{.*}}r 'const struct A &'
-  // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
-  // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+  // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)>
+  // CHECK: MaterializeTemporaryExpr{{.*}}'const struct B'
+  // CHECK: ImplicitCastExpr{{.*}}'const struct B' <NoOp>
   // CHECK: CXXMemberCallExpr{{.*}}'struct B'
   const A& r = x;
 }
 
-// CHECK: example3
+// CHECK-LABEL: example3
 void example3() {
   // CHECK: VarDecl{{.*}}rcd2 'const double &'
   // CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating>
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
index 263f661..e775e8f 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
@@ -41,7 +41,7 @@
 
 namespace test3 {
   struct A {
-    unsigned bitX : 4; // expected-note 4 {{bit-field is declared here}}
+    unsigned bitX : 4; // expected-note 3 {{bit-field is declared here}}
     unsigned bitY : 4; // expected-note {{bit-field is declared here}}
     unsigned var;
 
@@ -50,7 +50,7 @@
 
   void test(A *a) {
     unsigned &t0 = a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
-    unsigned &t1 = (unsigned&) a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
+    unsigned &t1 = (unsigned&) a->bitX; // expected-error {{C-style cast from bit-field lvalue to reference type 'unsigned int &'}}
     unsigned &t2 = const_cast<unsigned&>(a->bitX); // expected-error {{const_cast from bit-field lvalue to reference type 'unsigned int &'}}
     unsigned &t3 = (a->foo(), a->bitX); // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
     unsigned &t4 = (a->var ? a->bitX : a->bitY); // expected-error {{non-const reference cannot bind to bit-field}}
diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp
index 82f71af..055f40f 100644
--- a/test/CXX/drs/dr0xx.cpp
+++ b/test/CXX/drs/dr0xx.cpp
@@ -333,7 +333,7 @@
   E &m = true ? n : n;
 }
 
-// dr28: na
+// dr28: na lib
 
 namespace dr29 { // dr29: 3.4
   void dr29_f0(); // expected-note {{here}}
@@ -1032,7 +1032,7 @@
   int k = f(U());
 }
 
-namespace dr92 { // dr92: 4.0 c++17
+namespace dr92 { // dr92: 4 c++17
   void f() throw(int, float); // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
   void (*p)() throw(int) = &f; // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
 #if __cplusplus <= 201402L
diff --git a/test/CXX/drs/dr10xx.cpp b/test/CXX/drs/dr10xx.cpp
index e11e796..e1db9ef 100644
--- a/test/CXX/drs/dr10xx.cpp
+++ b/test/CXX/drs/dr10xx.cpp
@@ -12,6 +12,30 @@
   };
 }
 
+namespace dr1004 { // dr1004: 5
+  template<typename> struct A {};
+  template<typename> struct B1 {};
+  template<template<typename> class> struct B2 {};
+  template<typename X> void f(); // expected-note {{[with X = dr1004::A<int>]}}
+  template<template<typename> class X> void f(); // expected-note {{[with X = A]}}
+  template<template<typename> class X> void g(); // expected-note {{[with X = A]}}
+  template<typename X> void g(); // expected-note {{[with X = dr1004::A<int>]}}
+  struct C : A<int> {
+    B1<A> b1a;
+    B2<A> b2a;
+    void h() {
+      f<A>(); // expected-error {{ambiguous}}
+      g<A>(); // expected-error {{ambiguous}}
+    }
+  };
+
+  // This example (from the standard) is actually ill-formed, because
+  // name lookup of "T::template A" names the constructor.
+  // FIXME: Only issue one diagnostic for this case.
+  template<class T, template<class> class U = T::template A> struct Third { }; // expected-error 2{{is a constructor name}}
+  Third<A<int> > t; // expected-note {{in instantiation of}} expected-note {{while substituting}} expected-note {{while checking}}
+}
+
 namespace dr1048 { // dr1048: 3.6
   struct A {};
   const A f();
diff --git a/test/CXX/drs/dr118.cpp b/test/CXX/drs/dr118.cpp
new file mode 100644
index 0000000..58aa391
--- /dev/null
+++ b/test/CXX/drs/dr118.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++98 %s -pedantic-errors -emit-llvm -o - | FileCheck %s --implicit-check-not " call "
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++11 %s -pedantic-errors -emit-llvm -o - | FileCheck %s --implicit-check-not " call "
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++14 %s -pedantic-errors -emit-llvm -o - | FileCheck %s --implicit-check-not " call "
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++1z %s -pedantic-errors -emit-llvm -o - | FileCheck %s --implicit-check-not " call "
+
+// dr118: yes
+
+struct S {
+  virtual void f();
+};
+void (S::*pmf)();
+
+// CHECK-LABEL: define {{.*}} @_Z1g
+void g(S *sp) {
+  // CHECK: call void %
+  sp->f();        // 1: polymorphic
+  // CHECK: call void @
+  sp->S::f();     // 2: non-polymorphic
+  // CHECK: call void @
+  (sp->S::f)();   // 3: non-polymorphic
+  // CHECK: call void %
+  (sp->*pmf)();   // 4: polymorphic
+  // CHECK: call void %
+  (sp->*&S::f)(); // 5: polymorphic
+}
+
diff --git a/test/CXX/drs/dr12xx.cpp b/test/CXX/drs/dr12xx.cpp
index c4f980a..24039a1 100644
--- a/test/CXX/drs/dr12xx.cpp
+++ b/test/CXX/drs/dr12xx.cpp
@@ -3,9 +3,7 @@
 // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 
-// expected-no-diagnostics
-
-namespace dr1213 { // dr1213: 4.0
+namespace dr1213 { // dr1213: 4
 #if __cplusplus >= 201103L
   using T = int[3];
   int &&r = T{}[1];
@@ -16,7 +14,7 @@
 #endif
 }
 
-namespace dr1250 {  // dr1250: 3.9
+namespace dr1250 { // dr1250: 3.9
 struct Incomplete;
 
 struct Base {
@@ -26,4 +24,44 @@
 struct Derived : Base {
   virtual Incomplete *meow();
 };
-} // dr1250
+}
+
+namespace dr1265 { // dr1265: 5
+#if __cplusplus >= 201103L
+  auto a = 0, b() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+  auto b() -> int, d = 0; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+  auto e() -> int, f() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+#endif
+
+#if __cplusplus >= 201402L
+  auto g(), h = 0; // expected-error {{function with deduced return type must be the only declaration in its group}}
+  auto i = 0, j(); // expected-error {{function with deduced return type must be the only declaration in its group}}
+  auto k(), l(); // expected-error {{function with deduced return type must be the only declaration in its group}}
+#endif
+}
+
+namespace dr1295 { // dr1295: 4
+  struct X {
+    unsigned bitfield : 4;
+  };
+
+  X x = {1};
+
+  unsigned const &r1 = static_cast<X &&>(x).bitfield; // expected-error 0-1{{C++11}}
+  unsigned const &r2 = static_cast<unsigned &&>(x.bitfield); // expected-error 0-1{{C++11}}
+
+  template<unsigned &r> struct Y {};
+  Y<x.bitfield> y;
+#if __cplusplus <= 201402L
+  // expected-error@-2 {{does not refer to any declaration}} expected-note@-3 {{here}}
+#else
+  // expected-error@-4 {{refers to subobject}}
+#endif
+
+#if __cplusplus >= 201103L
+  const unsigned other = 0;
+  using T = decltype(true ? other : x.bitfield);
+  using T = unsigned;
+#endif
+}
+
diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp
index 3bfbfd6..56ff123 100644
--- a/test/CXX/drs/dr13xx.cpp
+++ b/test/CXX/drs/dr13xx.cpp
@@ -3,7 +3,125 @@
 // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 
-namespace dr1330 { // dr1330: 4.0 c++11
+__extension__ typedef __SIZE_TYPE__ size_t;
+
+namespace std {
+  template<typename T> struct initializer_list {
+    const T *ptr;
+    size_t n;
+    initializer_list(const T*, size_t);
+  };
+}
+
+namespace dr1310 { // dr1310: 5
+  struct S {} * sp = new S::S; // expected-error {{qualified reference to 'S' is a constructor name}}
+  void f() {
+    S::S(a); // expected-error {{qualified reference to 'S' is a constructor name}}
+  }
+  struct T { int n; typedef int U; typedef T V; };
+  int k = T().T::T::n;
+  T::V v;
+
+  struct U { int U; };
+  int u = U().U::U;
+  struct U::U w;
+
+  struct V : T::T {
+    // FIXME: This is technically ill-formed, but we consider that to be a defect.
+    V() : T::T() {}
+  };
+  template<typename T> struct VT : T::T {
+    VT() : T::T() {}
+  };
+  template struct VT<T>;
+
+  template<template<typename> class> class TT {};
+  template<typename> class TTy {};
+
+  template<typename T> struct WBase {};
+  template<typename T> struct W : WBase<T> { typedef int X; int n; };
+
+  void w_test() {
+    W<int>::W w1a; // expected-error {{qualified reference to 'W' is a constructor name}}
+    W<int>::W::X w1ax;
+    W<int>::W<int> w1b; // expected-error {{qualified reference to 'W' is a constructor name}}
+    W<int>::W<int>::X w1bx;
+    typename W<int>::W w2a; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
+    typename W<int>::W::X w2ax; // expected-error 0-1{{outside of a template}}
+    typename W<int>::W<int> w2b; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
+    typename W<int>::W<int>::X w2bx; // expected-error 0-1{{outside of a template}}
+    W<int>::template W<int> w3; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
+    W<int>::template W<int>::X w3x; // expected-error 0-1{{outside of a template}}
+    typename W<int>::template W<int> w4; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-2{{outside of a template}}
+    typename W<int>::template W<int>::X w4x; // expected-error 0-2{{outside of a template}}
+
+    TT<W<int>::W> tt1; // expected-error {{qualified reference to 'W' is a constructor name}}
+    TTy<W<int>::W> tt1a; // expected-error {{qualified reference to 'W' is a constructor name}}
+    TT<W<int>::template W> tt2; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
+    TT<W<int>::WBase> tt3;
+    TTy<W<int>::WBase> tt3a;
+    TT<W<int>::template WBase> tt4; // expected-error 0-1{{outside of a template}}
+
+    W<int> w;
+    (void)w.W::W::n;
+    (void)w.W<int>::W::n;
+    (void)w.W<int>::W<int>::n;
+    (void)w.W<int>::template W<int>::n; // expected-error 0-1{{outside of a template}}
+  }
+
+  template<typename W>
+  void wt_test() {
+    typename W::W w2a; // expected-error {{qualified reference to 'W' is a constructor name}}
+    typename W::template W<int> w4; // expected-error {{qualified reference to 'W' is a constructor name}}
+    TTy<typename W::W> tt2; // expected-error {{qualified reference to 'W' is a constructor name}}
+    TT<W::template W> tt3; // expected-error {{qualified reference to 'W' is a constructor name}}
+  }
+  template<typename W>
+  void wt_test_good() {
+    typename W::W::X w2ax;
+    typename W::template W<int>::X w4x;
+    TTy<typename W::WBase> tt4;
+    TT<W::template WBase> tt5;
+
+    W w;
+    (void)w.W::W::n;
+    (void)w.W::template W<int>::n;
+    (void)w.template W<int>::W::n;
+    (void)w.template W<int>::template W<int>::n;
+  }
+  template void wt_test<W<int> >(); // expected-note {{instantiation of}}
+  template void wt_test_good<W<int> >();
+}
+
+namespace dr1315 { // dr1315: partial
+  template <int I, int J> struct A {};
+  template <int I> // expected-note {{non-deducible template parameter 'I'}}
+    struct A<I + 5, I * 2> {}; // expected-error {{contains a template parameter that cannot be deduced}}
+  template <int I> struct A<I, I> {};
+
+  template <int I, int J, int K> struct B;
+  template <int I, int K> struct B<I, I * 2, K> {}; // expected-note {{matches}}
+  B<1, 2, 3> b1;
+
+  // Multiple declarations with the same dependent expression are equivalent
+  // for partial ordering purposes.
+  template <int I> struct B<I, I * 2, 2> { typedef int type; };
+  B<1, 2, 2>::type b2;
+
+  // Multiple declarations with differing dependent expressions are unordered.
+  template <int I, int K> struct B<I, I + 1, K> {}; // expected-note {{matches}}
+  B<1, 2, 4> b3; // expected-error {{ambiguous}}
+
+  // FIXME: Under dr1315, this is perhaps valid, but that is not clear: this
+  // fails the "more specialized than the primary template" test because the
+  // dependent type of T::value is not the same as 'int'.
+  // A core issue will be opened to decide what is supposed to happen here.
+  template <typename T, int I> struct C;
+  template <typename T> struct C<T, T::value>;
+  // expected-error@-1 {{type of specialized non-type template argument depends on a template parameter of the partial specialization}}
+}
+
+namespace dr1330 { // dr1330: 4 c++11
   // exception-specifications are parsed in a context where the class is complete.
   struct A {
     void f() throw(T) {} // expected-error 0-1{{C++1z}} expected-note 0-1{{noexcept}}
@@ -131,6 +249,15 @@
 #endif
 }
 
+namespace dr1347 { // dr1347: yes
+  auto x = 5, *y = &x; // expected-error 0-1{{extension}}
+  auto z = y, *q = y; // expected-error {{'auto' deduced as 'int *' in declaration of 'z' and deduced as 'int' in declaration of 'q'}} expected-error 0-1{{extension}}
+#if __cplusplus >= 201103L
+  auto a = 5, b = {1, 2}; // expected-error {{'auto' deduced as 'int' in declaration of 'a' and deduced as 'std::initializer_list<int>' in declaration of 'b'}}
+  auto (*fp)(int) -> int, i = 0; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+#endif
+}
+
 namespace dr1359 { // dr1359: 3.5
 #if __cplusplus >= 201103L
   union A { constexpr A() = default; };
@@ -146,3 +273,133 @@
   constexpr Y y = Y(); // expected-error {{no matching}}
 #endif
 }
+
+namespace dr1388 { // dr1388: 4
+  template<typename A, typename ...T> void f(T..., A); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}}
+  template<typename ...T> void g(T..., int); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}}
+  template<typename ...T, typename A> void h(T..., A); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}}
+
+  void test_f() { 
+    f(0); // ok, trailing parameter pack deduced to empty
+    f(0, 0); // expected-error {{no matching}}
+    f<int>(0);
+    f<int>(0, 0); // expected-error {{no matching}}
+    f<int, int>(0, 0);
+    f<int, int, int>(0, 0); // expected-error {{no matching}}
+
+    g(0);
+    g(0, 0); // expected-error {{no matching}}
+    g<>(0);
+    g<int>(0); // expected-error {{no matching}}
+    g<int>(0, 0);
+
+    h(0);
+    h(0, 0); // expected-error {{no matching}}
+    h<int>(0, 0);
+    h<int, int>(0, 0); // expected-error {{no matching}}
+  }
+
+  // A non-trailing parameter pack is still a non-deduced context, even though
+  // we know exactly how many arguments correspond to it.
+  template<typename T, typename U> struct pair {};
+  template<typename ...T> struct tuple { typedef char type; }; // expected-error 0-2{{C++11}}
+  template<typename ...T, typename ...U> void f_pair_1(pair<T, U>..., int); // expected-error 0-2{{C++11}} expected-note {{different lengths (2 vs. 0)}}
+  template<typename ...T, typename U> void f_pair_2(pair<T, char>..., U); // expected-error 0-2{{C++11}}
+  template<typename ...T, typename ...U> void f_pair_3(pair<T, U>..., tuple<U...>); // expected-error 0-2{{C++11}} expected-note {{different lengths (2 vs. 1)}}
+  template<typename ...T> void f_pair_4(pair<T, char>..., T...); // expected-error 0-2{{C++11}} expected-note {{<int, long> vs. <int, long, const char *>}}
+  void g(pair<int, char> a, pair<long, char> b, tuple<char, char> c) {
+    f_pair_1<int, long>(a, b, 0); // expected-error {{no match}}
+    f_pair_2<int, long>(a, b, 0);
+    f_pair_3<int, long>(a, b, c);
+    f_pair_3<int, long>(a, b, tuple<char>()); // expected-error {{no match}}
+    f_pair_4<int, long>(a, b, 0, 0L);
+    f_pair_4<int, long>(a, b, 0, 0L, "foo"); // expected-error {{no match}}
+  }
+}
+
+namespace dr1391 { // dr1391: partial
+  struct A {}; struct B : A {};
+  template<typename T> struct C { C(int); typename T::error error; }; // expected-error 2{{'::'}}
+  template<typename T> struct D {};
+
+  // No deduction is performed for parameters with no deducible template-parameters, therefore types do not need to match.
+  template<typename T> void a(T, int T::*);
+  void test_a(int A::*p) { a(A(), p); } // ok, type of second parameter does not need to match
+
+  namespace dr_example_1 {
+    template<typename T, typename U> void f(C<T>);
+    template<typename T> void f(D<T>);
+
+    void g(D<int> d) {
+      f(d); // ok, first 'f' eliminated by deduction failure
+      f<int>(d); // ok, first 'f' eliminated because 'U' cannot be deduced
+    }
+  }
+
+  namespace dr_example_2 {
+    template<typename T> typename C<T>::error f(int, T);
+    template<typename T> T f(T, T);
+
+    void g(A a) {
+      f(a, a); // ok, no conversion from A to int for first parameter of first candidate
+    }
+  }
+
+  namespace std_example {
+    template<typename T> struct Z {
+      typedef typename T::x xx;
+    };
+    template<typename T> typename Z<T>::xx f(void *, T);
+    template<typename T> void f(int, T);
+    struct A {} a;
+    void g() { f(1, a); }
+  }
+
+  template<typename T> void b(C<int> ci, T *p);
+  void b(...);
+  void test_b() {
+    b(0, 0); // ok, deduction fails prior to forming a conversion sequence and instantiating C<int>
+    // FIXME: The "while substituting" note should point at the overload candidate.
+    b<int>(0, 0); // expected-note {{instantiation of}} expected-note {{while substituting}}
+  }
+
+  template<typename T> struct Id { typedef T type; };
+  template<typename T> void c(T, typename Id<C<T> >::type);
+  void test_c() {
+    // Implicit conversion sequences for dependent types are checked later.
+    c(0.0, 0); // expected-note {{instantiation of}}
+  }
+
+  namespace partial_ordering {
+    // FIXME: Second template should be considered more specialized because non-dependent parameter is ignored.
+    template<typename T> int a(T, short) = delete; // expected-error 0-1{{extension}} expected-note {{candidate}}
+    template<typename T> int a(T*, char); // expected-note {{candidate}}
+    int test_a = a((int*)0, 0); // FIXME: expected-error {{ambiguous}}
+
+    // FIXME: Second template should be considered more specialized:
+    // deducing #1 from #2 ignores the second P/A pair, so deduction succeeds,
+    // deducing #2 from #1 fails to deduce T, so deduction fails.
+    template<typename T> int b(T, int) = delete; // expected-error 0-1{{extension}} expected-note {{candidate}}
+    template<typename T, typename U> int b(T*, U); // expected-note {{candidate}}
+    int test_b = b((int*)0, 0); // FIXME: expected-error {{ambiguous}}
+
+    // Unintended consequences: because partial ordering does not consider
+    // explicit template arguments, and deduction from a non-dependent type
+    // vacuously succeeds, a non-dependent template is less specialized than
+    // anything else!
+    // According to DR1391, this is ambiguous!
+    template<typename T> int c(int);
+    template<typename T> int c(T);
+    int test_c1 = c(0); // ok
+    int test_c2 = c<int>(0); // FIXME: apparently ambiguous
+  }
+}
+
+namespace dr1399 { // dr1399: dup 1388
+  template<typename ...T> void f(T..., int, T...) {} // expected-note {{candidate}} expected-error 0-1{{C++11}}
+  void g() {
+    f(0);
+    f<int>(0, 0, 0);
+    f(0, 0, 0); // expected-error {{no match}}
+  }
+}
diff --git a/test/CXX/drs/dr14xx.cpp b/test/CXX/drs/dr14xx.cpp
index 9491f7d..116437b 100644
--- a/test/CXX/drs/dr14xx.cpp
+++ b/test/CXX/drs/dr14xx.cpp
@@ -342,4 +342,32 @@
   char s[4]{"abc"};                   // Ok
   std::initializer_list<char>{"abc"}; // expected-error {{expected unqualified-id}}}
 } // dr190
+
+namespace dr1495 { // dr1495: 4
+  // Deduction succeeds in both directions.
+  template<typename T, typename U> struct A {}; // expected-note {{template is declared here}}
+  template<typename T, typename U> struct A<U, T> {}; // expected-error {{class template partial specialization is not more specialized}}
+
+  // Primary template is more specialized.
+  template<typename, typename...> struct B {}; // expected-note {{template is declared here}}
+  template<typename ...Ts> struct B<Ts...> {}; // expected-error {{not more specialized}}
+
+  // Deduction fails in both directions.
+  template<int, typename, typename ...> struct C {}; // expected-note {{template is declared here}}
+  template<typename ...Ts> struct C<0, Ts...> {}; // expected-error {{not more specialized}}
+
+#if __cplusplus >= 201402L
+  // Deduction succeeds in both directions.
+  template<typename T, typename U> int a; // expected-note {{template is declared here}}
+  template<typename T, typename U> int a<U, T>; // expected-error {{variable template partial specialization is not more specialized}}
+
+  // Primary template is more specialized.
+  template<typename, typename...> int b; // expected-note {{template is declared here}}
+  template<typename ...Ts> int b<Ts...>; // expected-error {{not more specialized}}
+
+  // Deduction fails in both directions.
+  template<int, typename, typename ...> int c; // expected-note {{template is declared here}}
+  template<typename ...Ts> int c<0, Ts...>; // expected-error {{not more specialized}}
+#endif
+}
 #endif
diff --git a/test/CXX/drs/dr158.cpp b/test/CXX/drs/dr158.cpp
new file mode 100644
index 0000000..33f837c
--- /dev/null
+++ b/test/CXX/drs/dr158.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++98 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++11 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++14 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++1z %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
+
+// dr158: yes
+
+// CHECK-LABEL: define {{.*}} @_Z1f
+const int *f(const int * const *p, int **q) {
+  // CHECK: load i32**, {{.*}}, !tbaa ![[INTPTR_TBAA:[^,]*]]
+  const int *x = *p;
+  // CHECK: store i32* null, {{.*}}, !tbaa ![[INTPTR_TBAA]]
+  *q = 0;
+  return x;
+}
+
+struct A {};
+
+// CHECK-LABEL: define {{.*}} @_Z1g
+const int *(A::*const *g(const int *(A::* const **p)[3], int *(A::***q)[3]))[3] {
+  // CHECK: load i64**, {{.*}}, !tbaa ![[MEMPTR_TBAA:[^,]*]]
+  const int *(A::*const *x)[3] = *p;
+  // CHECK: store i64* null, {{.*}}, !tbaa ![[MEMPTR_TBAA]]
+  *q = 0;
+  return x;
+}
+
diff --git a/test/CXX/drs/dr15xx.cpp b/test/CXX/drs/dr15xx.cpp
index 5c4ea2d..a68928f 100644
--- a/test/CXX/drs/dr15xx.cpp
+++ b/test/CXX/drs/dr15xx.cpp
@@ -3,7 +3,7 @@
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 
-namespace dr1512 { // dr1512: 4.0
+namespace dr1512 { // dr1512: 4
   void f(char *p) {
     if (p > 0) {} // expected-error {{ordered comparison between pointer and zero}}
 #if __cplusplus >= 201103L
@@ -135,7 +135,7 @@
   }
 }
 
-namespace dr1518 { // dr1518: 4.0
+namespace dr1518 { // dr1518: 4
 #if __cplusplus >= 201103L
 struct Z0 { // expected-note 0+ {{candidate}}
   explicit Z0() = default; // expected-note 0+ {{here}}
@@ -179,6 +179,45 @@
 };
 InheritsCtor II = {{}, 42}; // expected-error {{no matching constructor}}
 
+namespace std_example {
+  struct A {
+    explicit A() = default; // expected-note 2{{declared here}}
+  };
+
+  struct B : A {
+    explicit B() = default; // expected-note 2{{declared here}}
+  };
+
+  struct C {
+    explicit C(); // expected-note 2{{declared here}}
+  };
+
+  struct D : A {
+    C c;
+    explicit D() = default; // expected-note 2{{declared here}}
+  };
+
+  template <typename T> void f() {
+    T t; // ok
+    T u{}; // ok
+    T v = {}; // expected-error 4{{explicit}}
+  }
+  template <typename T> void g() {
+    void x(T t); // expected-note 4{{parameter}}
+    x({}); // expected-error 4{{explicit}}
+  }
+
+  void test() {
+    f<A>(); // expected-note {{instantiation of}}
+    f<B>(); // expected-note {{instantiation of}}
+    f<C>(); // expected-note {{instantiation of}}
+    f<D>(); // expected-note {{instantiation of}}
+    g<A>(); // expected-note {{instantiation of}}
+    g<B>(); // expected-note {{instantiation of}}
+    g<C>(); // expected-note {{instantiation of}}
+    g<D>(); // expected-note {{instantiation of}}
+  }
+}
 #endif                      // __cplusplus >= 201103L
 }
 
diff --git a/test/CXX/drs/dr16xx.cpp b/test/CXX/drs/dr16xx.cpp
index 65467e3..08ae925 100644
--- a/test/CXX/drs/dr16xx.cpp
+++ b/test/CXX/drs/dr16xx.cpp
@@ -3,9 +3,12 @@
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 
-#if __cplusplus < 201103L
-// expected-no-diagnostics
-#endif
+namespace dr1611 { // dr1611: dup 1658
+  struct A { A(int); };
+  struct B : virtual A { virtual void f() = 0; };
+  struct C : B { C() : A(0) {} void f(); };
+  C c;
+}
 
 namespace dr1684 { // dr1684: 3.6
 #if __cplusplus >= 201103L
@@ -44,19 +47,175 @@
 #endif
 }
 
+namespace dr1638 { // dr1638: yes
+#if __cplusplus >= 201103L
+  template<typename T> struct A {
+    enum class E; // expected-note {{previous}}
+    enum class F : T; // expected-note 2{{previous}}
+  };
+
+  template<> enum class A<int>::E;
+  template<> enum class A<int>::E {};
+  template<> enum class A<int>::F : int;
+  template<> enum class A<int>::F : int {};
+
+  template<> enum class A<short>::E : int;
+  template<> enum class A<short>::E : int {};
+
+  template<> enum class A<short>::F; // expected-error {{different underlying type}}
+  template<> enum class A<char>::E : char; // expected-error {{different underlying type}}
+  template<> enum class A<char>::F : int; // expected-error {{different underlying type}}
+
+  enum class A<unsigned>::E; // expected-error {{template specialization requires 'template<>'}} expected-error {{nested name specifier}}
+  template enum class A<unsigned>::E; // expected-error {{enumerations cannot be explicitly instantiated}}
+  enum class A<unsigned>::E *e; // expected-error {{must use 'enum' not 'enum class'}}
+
+  struct B {
+    friend enum class A<unsigned>::E; // expected-error {{must use 'enum' not 'enum class'}}
+  };
+#endif
+}
+
 namespace dr1645 { // dr1645: 3.9
 #if __cplusplus >= 201103L
-  struct A { // expected-note 2{{candidate}}
+  struct A {
     constexpr A(int, float = 0); // expected-note 2{{candidate}}
     explicit A(int, int = 0); // expected-note 2{{candidate}}
     A(int, int, int = 0) = delete; // expected-note {{candidate}}
   };
 
   struct B : A { // expected-note 2{{candidate}}
-    using A::A; // expected-note 7{{inherited here}}
+    using A::A; // expected-note 5{{inherited here}}
   };
 
   constexpr B a(0); // expected-error {{ambiguous}}
   constexpr B b(0, 0); // expected-error {{ambiguous}}
 #endif
 }
+
+namespace dr1653 { // dr1653: 4 c++17
+  void f(bool b) {
+    ++b;
+    b++;
+#if __cplusplus <= 201402L
+    // expected-warning@-3 {{deprecated}} expected-warning@-2 {{deprecated}}
+#else
+    // expected-error@-5 {{incrementing expression of type bool}} expected-error@-4 {{incrementing expression of type bool}}
+#endif
+    --b; // expected-error {{cannot decrement expression of type bool}}
+    b--; // expected-error {{cannot decrement expression of type bool}}
+    b += 1; // ok
+    b -= 1; // ok
+  }
+}
+
+namespace dr1658 { // dr1658: 5
+  namespace DefCtor {
+    class A { A(); }; // expected-note 0-2{{here}}
+    class B { ~B(); }; // expected-note 0-2{{here}}
+
+    // The stars align! An abstract class does not construct its virtual bases.
+    struct C : virtual A { C(); virtual void foo() = 0; };
+    C::C() = default; // ok, not deleted, expected-error 0-1{{extension}}
+    struct D : virtual B { D(); virtual void foo() = 0; };
+    D::D() = default; // ok, not deleted, expected-error 0-1{{extension}}
+
+    // In all other cases, we are not so lucky.
+    struct E : A { E(); virtual void foo() = 0; };
+#if __cplusplus < 201103L
+    E::E() = default; // expected-error {{private default constructor}} expected-error {{extension}} expected-note {{here}}
+#else
+    E::E() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible default constructor}}
+#endif
+    struct F : virtual A { F(); };
+#if __cplusplus < 201103L
+    F::F() = default; // expected-error {{private default constructor}} expected-error {{extension}} expected-note {{here}}
+#else
+    F::F() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible default constructor}}
+#endif
+
+    struct G : B { G(); virtual void foo() = 0; };
+#if __cplusplus < 201103L
+    G::G() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}
+#else
+    G::G() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}
+#endif
+    struct H : virtual B { H(); };
+#if __cplusplus < 201103L
+    H::H() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}
+#else
+    H::H() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}
+#endif
+  }
+
+  namespace Dtor {
+    class B { ~B(); }; // expected-note 0-2{{here}}
+
+    struct D : virtual B { ~D(); virtual void foo() = 0; };
+    D::~D() = default; // ok, not deleted, expected-error 0-1{{extension}}
+
+    struct G : B { ~G(); virtual void foo() = 0; };
+#if __cplusplus < 201103L
+    G::~G() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}
+#else
+    G::~G() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}
+#endif
+    struct H : virtual B { ~H(); };
+#if __cplusplus < 201103L
+    H::~H() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}
+#else
+    H::~H() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}
+#endif
+  }
+
+  namespace MemInit {
+    struct A { A(int); }; // expected-note {{here}}
+    struct B : virtual A {
+      B() {}
+      virtual void f() = 0;
+    };
+    struct C : virtual A {
+      C() {} // expected-error {{must explicitly initialize}}
+    };
+  }
+
+  namespace CopyCtorParamType {
+    struct A { A(A&); };
+    struct B : virtual A { virtual void f() = 0; };
+    struct C : virtual A { virtual void f(); };
+    struct D : A { virtual void f() = 0; };
+
+    struct X {
+      friend B::B(const B&) throw();
+      friend C::C(C&);
+      friend D::D(D&);
+    };
+  }
+
+  namespace CopyCtor {
+    class A { A(const A&); A(A&&); }; // expected-note 0-4{{here}} expected-error 0-1{{extension}}
+
+    struct C : virtual A { C(const C&); C(C&&); virtual void foo() = 0; }; // expected-error 0-1{{extension}}
+    C::C(const C&) = default; // expected-error 0-1{{extension}}
+    C::C(C&&) = default; // expected-error 0-2{{extension}}
+
+    struct E : A { E(const E&); E(E&&); virtual void foo() = 0; }; // expected-error 0-1{{extension}}
+#if __cplusplus < 201103L
+    E::E(const E&) = default; // expected-error {{private copy constructor}} expected-error {{extension}} expected-note {{here}}
+    E::E(E&&) = default; // expected-error {{private move constructor}} expected-error 2{{extension}} expected-note {{here}}
+#else
+    E::E(const E&) = default; // expected-error {{would delete}} expected-note@-5{{inaccessible copy constructor}}
+    E::E(E&&) = default; // expected-error {{would delete}} expected-note@-6{{inaccessible move constructor}}
+#endif
+    struct F : virtual A { F(const F&); F(F&&); }; // expected-error 0-1{{extension}}
+#if __cplusplus < 201103L
+    F::F(const F&) = default; // expected-error {{private copy constructor}} expected-error {{extension}} expected-note {{here}}
+    F::F(F&&) = default; // expected-error {{private move constructor}} expected-error 2{{extension}} expected-note {{here}}
+#else
+    F::F(const F&) = default; // expected-error {{would delete}} expected-note@-5{{inaccessible copy constructor}}
+    F::F(F&&) = default; // expected-error {{would delete}} expected-note@-6{{inaccessible move constructor}}
+#endif
+  }
+
+  // assignment case is superseded by dr2180
+}
diff --git a/test/CXX/drs/dr18xx.cpp b/test/CXX/drs/dr18xx.cpp
index 436bccc..e4ec199 100644
--- a/test/CXX/drs/dr18xx.cpp
+++ b/test/CXX/drs/dr18xx.cpp
@@ -7,7 +7,7 @@
 // expected-no-diagnostics
 #endif
 
-void dr1891() { // dr1891: 4.0
+void dr1891() { // dr1891: 4
 #if __cplusplus >= 201103L
   int n;
   auto a = []{}; // expected-note 2{{candidate}} expected-note 2{{here}}
diff --git a/test/CXX/drs/dr19xx.cpp b/test/CXX/drs/dr19xx.cpp
index 5b626dd..e6cf337 100644
--- a/test/CXX/drs/dr19xx.cpp
+++ b/test/CXX/drs/dr19xx.cpp
@@ -138,27 +138,31 @@
   struct c;
   struct a {
     a() = default;
-    a(const a &) = delete; // expected-note 2{{deleted}}
+    a(const a &) = delete; // expected-note {{deleted}}
     a(const b &) = delete; // not inherited
-    a(c &&) = delete; // expected-note {{deleted}}
-    template<typename T> a(T) = delete;
+    a(c &&) = delete; // expected-note {{not viable}}
+    template<typename T> a(T) = delete; // expected-note {{would take its own class type by value}}
   };
 
-  struct b : a { // expected-note {{copy constructor of 'b' is implicitly deleted because base class 'dr1959::a' has a deleted copy constructor}}
-    using a::a;
+  struct b : a { // expected-note {{cannot bind}} expected-note {{deleted because}}
+    using a::a; // expected-note 2{{inherited here}}
   };
 
   a x;
-  b y = x; // expected-error {{deleted}}
+  // FIXME: As a resolution to an open DR against P0136R0, we disallow
+  // use of inherited constructors to construct from a single argument
+  // where the base class is reference-related to the argument type.
+  b y = x; // expected-error {{no viable conversion}}
   b z = z; // expected-error {{deleted}}
 
-  // FIXME: It's not really clear that this matches the intent, but it's
-  // consistent with the behavior for assignment operators.
   struct c : a {
     using a::a;
     c(const c &);
   };
-  c q(static_cast<c&&>(q)); // expected-error {{call to deleted}}
+  // FIXME: As a resolution to an open DR against P0136R0, we disallow
+  // use of inherited constructors to construct from a single argument
+  // where the base class is reference-related to the argument type.
+  c q(static_cast<c&&>(q));
 #endif
 }
 
diff --git a/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp
index dbd1599..f5395cf 100644
--- a/test/CXX/drs/dr1xx.cpp
+++ b/test/CXX/drs/dr1xx.cpp
@@ -35,7 +35,7 @@
 }
 
 // dr103: na
-// dr104 FIXME: add codegen test
+// dr104: na lib
 // dr105: na
 
 namespace dr106 { // dr106: sup 540
@@ -202,7 +202,7 @@
 }
 
 // dr117: na
-// dr118 FIXME: add codegen test
+// dr118 is in its own file.
 // dr119: na
 // dr120: na
 
@@ -535,13 +535,15 @@
   }
 }
 
-namespace dr147 { // dr147: no
+namespace dr147 { // dr147: yes
   namespace example1 {
     template<typename> struct A {
       template<typename T> A(T);
     };
-    // FIXME: This appears to be valid, and EDG and G++ accept.
+    // Per core issue 1435, this is ill-formed because A<int>::A<int> does not
+    // name the injected-class-name. (A<int>::A does, though.)
     template<> template<> A<int>::A<int>(int) {} // expected-error {{out-of-line constructor for 'A' cannot have template arguments}}
+    template<> template<> A<float>::A(float) {}
   }
   namespace example2 {
     struct A { A(); };
@@ -608,7 +610,7 @@
   struct S { int n; } s = { { 1 } }; // expected-warning {{braces around scalar initializer}}
 }
 
-// dr158 FIXME write codegen test
+// dr158 is in its own file.
 
 namespace dr159 { // dr159: 3.5
   namespace X { void f(); }
diff --git a/test/CXX/drs/dr21xx.cpp b/test/CXX/drs/dr21xx.cpp
new file mode 100644
index 0000000..78fc0be
--- /dev/null
+++ b/test/CXX/drs/dr21xx.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr2180 { // dr2180: yes
+  class A {
+    A &operator=(const A &); // expected-note 0-2{{here}}
+    A &operator=(A &&); // expected-note 0-2{{here}} expected-error 0-1{{extension}}
+  };
+
+  struct B : virtual A {
+    B &operator=(const B &);
+    B &operator=(B &&); // expected-error 0-1{{extension}}
+    virtual void foo() = 0;
+  };
+#if __cplusplus < 201103L
+  B &B::operator=(const B&) = default; // expected-error {{private member}} expected-error {{extension}} expected-note {{here}}
+  B &B::operator=(B&&) = default; // expected-error {{private member}} expected-error 2{{extension}} expected-note {{here}}
+#else
+  B &B::operator=(const B&) = default; // expected-error {{would delete}} expected-note@-9{{inaccessible copy assignment}}
+  B &B::operator=(B&&) = default; // expected-error {{would delete}} expected-note@-10{{inaccessible move assignment}}
+#endif
+}
diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp
index fa9d677..a5677a1 100644
--- a/test/CXX/drs/dr2xx.cpp
+++ b/test/CXX/drs/dr2xx.cpp
@@ -620,7 +620,7 @@
   template<typename T> struct A {
     typedef typename T::type type; // ok even if this is a typedef-name, because
                                    // it's not an elaborated-type-specifier
-    typedef struct T::type foo; // expected-error {{elaborated type refers to a typedef}}
+    typedef struct T::type foo; // expected-error {{typedef 'type' cannot be referenced with a struct specifier}}
   };
   struct B { struct type {}; };
   struct C { typedef struct {} type; }; // expected-note {{here}}
@@ -679,7 +679,7 @@
   } f; // expected-error {{abstract}}
 }
 
-namespace dr259 { // dr259: 4.0
+namespace dr259 { // dr259: 4
   template<typename T> struct A {};
   template struct A<int>; // expected-note {{previous}}
   template struct A<int>; // expected-error {{duplicate explicit instantiation}}
@@ -1014,7 +1014,7 @@
 
 namespace dr295 { // dr295: 3.7
   typedef int f();
-  const f g; // expected-warning {{'const' qualifier on function type 'f' (aka 'int ()') has no effect}}
+  const f g; // expected-warning {{'const' qualifier on function type 'dr295::f' (aka 'int ()') has no effect}}
   f &r = g;
   template<typename T> struct X {
     const T &f;
@@ -1022,10 +1022,10 @@
   X<f> x = {g};
 
   typedef int U();
-  typedef const U U; // expected-warning {{'const' qualifier on function type 'U' (aka 'int ()') has no effect}}
+  typedef const U U; // expected-warning {{'const' qualifier on function type 'dr295::U' (aka 'int ()') has no effect}}
 
   typedef int (*V)();
-  typedef volatile U *V; // expected-warning {{'volatile' qualifier on function type 'U' (aka 'int ()') has no effect}}
+  typedef volatile U *V; // expected-warning {{'volatile' qualifier on function type 'dr295::U' (aka 'int ()') has no effect}}
 }
 
 namespace dr296 { // dr296: yes
@@ -1048,12 +1048,12 @@
   C::type i3;
 
   struct A a;
-  struct B b; // expected-error {{refers to a typedef}}
-  struct C c; // expected-error {{refers to a typedef}}
+  struct B b; // expected-error {{typedef 'B' cannot be referenced with a struct specifier}}
+  struct C c; // expected-error {{typedef 'C' cannot be referenced with a struct specifier}}
 
   B::B() {} // expected-error {{requires a type specifier}}
   B::A() {} // ok
-  C::~C() {} // expected-error {{destructor cannot be declared using a typedef 'C' (aka 'const dr298::A') of the class name}}
+  C::~C() {} // expected-error {{destructor cannot be declared using a typedef 'dr298::C' (aka 'const dr298::A') of the class name}}
 
   typedef struct D E; // expected-note {{here}}
   struct E {}; // expected-error {{conflicts with typedef}}
diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp
index 4be3a58..3ea226a 100644
--- a/test/CXX/drs/dr4xx.cpp
+++ b/test/CXX/drs/dr4xx.cpp
@@ -35,9 +35,7 @@
   };
 
   A<B> *b; // expected-note {{default argument}}
-  // FIXME: We're missing the "in instantiation of" note for the default
-  // argument here.
-  A<D> *d;
+  A<D> *d; // expected-note {{in instantiation of default argument}}
 
   struct E {
     template<class T, class U = typename T::type> class A : public T {};
@@ -90,7 +88,7 @@
     struct S *p;
     {
       typedef struct S S; // expected-note {{here}}
-      struct S *p; // expected-error {{refers to a typedef}}
+      struct S *p; // expected-error {{typedef 'S' cannot be referenced with a struct specifier}}
     }
   }
   struct S {};
diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp
index f065128..97b40b8 100644
--- a/test/CXX/drs/dr5xx.cpp
+++ b/test/CXX/drs/dr5xx.cpp
@@ -863,7 +863,7 @@
 
 // dr582: na
 
-namespace dr583 { // dr583: 4.0
+namespace dr583 { // dr583: 4
   // see n3624
   int *p;
   bool b1 = p < 0; // expected-error {{ordered comparison between pointer and zero}}
@@ -877,13 +877,25 @@
 namespace dr585 { // dr585: yes
   template<typename> struct T;
   struct A {
-    friend T; // expected-error {{requires a type specifier}} expected-error {{can only be classes or functions}}
+    friend T;
+#if __cplusplus <= 201402L
+    // expected-error@-2 {{requires a type specifier}} expected-error@-2 {{can only be classes or functions}}
+#else
+    // expected-error@-4 {{use of class template 'T' requires template arguments; argument deduction not allowed in friend declaration}}
+    // expected-note@-7 {{here}}
+#endif
     // FIXME: It's not clear whether the standard allows this or what it means,
     // but the DR585 writeup suggests it as an alternative.
     template<typename U> friend T<U>; // expected-error {{must use an elaborated type}}
   };
   template<template<typename> class T> struct B {
-    friend T; // expected-error {{requires a type specifier}} expected-error {{can only be classes or functions}}
+    friend T;
+#if __cplusplus <= 201402L
+    // expected-error@-2 {{requires a type specifier}} expected-error@-2 {{can only be classes or functions}}
+#else
+    // expected-error@-4 {{use of template template parameter 'T' requires template arguments; argument deduction not allowed in friend declaration}}
+    // expected-note@-6 {{here}}
+#endif
     template<typename U> friend T<U>; // expected-error {{must use an elaborated type}}
   };
 }
@@ -942,7 +954,7 @@
 
   template<typename T> struct A<T>::B::C : A<T> {
     // FIXME: Should find member of non-dependent base class A<T>.
-    M m; // expected-error {{incomplete type 'M' (aka 'void'}}
+    M m; // expected-error {{incomplete type 'dr591::A::B::M' (aka 'void'}}
   };
 }
 
diff --git a/test/CXX/drs/dr6xx.cpp b/test/CXX/drs/dr6xx.cpp
index 74b9a54..8b9a699 100644
--- a/test/CXX/drs/dr6xx.cpp
+++ b/test/CXX/drs/dr6xx.cpp
@@ -142,7 +142,7 @@
   static int n = f();
 }
 
-namespace dr616 { // dr616: 4.0
+namespace dr616 { // dr616: 4
 #if __cplusplus >= 201103L
   struct S { int n; } s;
   S f();
@@ -353,3 +353,66 @@
     void((i = 0) + (i = 0)); // expected-warning {{unsequenced}}
   }
 }
+
+namespace dr692 { // dr692: no
+  namespace temp_func_order_example2 {
+    template <typename T, typename U> struct A {};
+    template <typename T, typename U> void f(U, A<U, T> *p = 0); // expected-note {{candidate}}
+    template <typename U> int &f(U, A<U, U> *p = 0); // expected-note {{candidate}}
+    template <typename T> void g(T, T = T());
+    template <typename T, typename... U> void g(T, U...); // expected-error 0-1{{C++11}}
+    void h() {
+      int &r = f<int>(42, (A<int, int> *)0);
+      f<int>(42); // expected-error {{ambiguous}}
+      // FIXME: We should reject this due to ambiguity between the pack and the
+      // default argument. Only parameters with arguments are considered during
+      // partial ordering of function templates.
+      g(42);
+    }
+  }
+
+  namespace temp_func_order_example3 {
+    template <typename T, typename... U> void f(T, U...); // expected-error 0-1{{C++11}}
+    template <typename T> void f(T);
+    template <typename T, typename... U> int &g(T *, U...); // expected-error 0-1{{C++11}}
+    template <typename T> void g(T);
+    void h(int i) {
+      // This is made ambiguous by dr692, but made valid again by dr1395.
+      f(&i);
+      int &r = g(&i);
+    }
+  }
+
+  namespace temp_deduct_partial_example {
+    template <typename... Args> char &f(Args... args); // expected-error 0-1{{C++11}}
+    template <typename T1, typename... Args> short &f(T1 a1, Args... args); // expected-error 0-1{{C++11}}
+    template <typename T1, typename T2> int &f(T1 a1, T2 a2);
+    void g() {
+      char &a = f();
+      short &b = f(1, 2, 3);
+      int &c = f(1, 2);
+    }
+  }
+
+  namespace temp_deduct_type_example1 {
+    template <class T1, class ...Z> class S; // expected-error 0-1{{C++11}}
+    template <class T1, class ...Z> class S<T1, const Z&...>; // expected-error 0-1{{C++11}}
+    template <class T1, class T2> class S<T1, const T2&> {};
+    S<int, const int&> s;
+
+    // FIXME: This should select the first partial specialization. Deduction of
+    // the second from the first should succeed, because we should ignore the
+    // trailing pack in A with no corresponding P.
+    template<class T, class... U> struct A; // expected-error 0-1{{C++11}}
+    template<class T1, class T2, class... U> struct A<T1,T2*,U...>; // expected-note {{matches}} expected-error 0-1{{C++11}}
+    template<class T1, class T2> struct A<T1,T2> {}; // expected-note {{matches}}
+    template struct A<int, int*>; // expected-error {{ambiguous}}
+  }
+
+  namespace temp_deduct_type_example3 {
+    // FIXME: This should select the first template, as in the case above.
+    template<class T, class... U> void f(T*, U...){} // expected-note {{candidate}} expected-error 0-1{{C++11}}
+    template<class T> void f(T){} // expected-note {{candidate}}
+    template void f(int*); // expected-error {{ambiguous}}
+  }
+}
diff --git a/test/CXX/expr/expr.cond/p4.cpp b/test/CXX/expr/expr.cond/p4.cpp
new file mode 100644
index 0000000..4d0cf35
--- /dev/null
+++ b/test/CXX/expr/expr.cond/p4.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++98 -verify %s
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+// expected-no-diagnostics
+
+struct A { A(); A(int); };
+void f() {
+  const A a;
+  true ? a : 0;
+}
diff --git a/test/CXX/expr/expr.post/expr.type.conv/p1.cpp b/test/CXX/expr/expr.post/expr.type.conv/p1.cpp
new file mode 100644
index 0000000..f3608bc
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.type.conv/p1.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+template<typename T> struct A { // expected-note 2{{candidate}}
+  T t, u;
+};
+template<typename T> A(T, T) -> A<T>; // expected-note {{deduced conflicting types for parameter 'T'}}
+template<typename T> A(A<T>) -> A<T>; // expected-note {{requires 1 argument, but 2 were provided}}
+
+A a = A{1, 2};
+A b = A{3, 4.0}; // expected-error {{no viable constructor or deduction guide}}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
index 4a2a4f3..e7fce11 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
 
 void odr_used() {
   int i = 17;
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
index 8bb707e..b55beb7 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
 
 void f2() {
   int i = 1;
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp
index 94f8111..905192f 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
 
 
 struct X {
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp
index 93c2805..72cf93b 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
 // expected-no-diagnostics
 
 template<typename T, typename U>
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
index 1dbcbf4..a8b4024 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
 
 struct MoveOnly {
   MoveOnly(MoveOnly&&);
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
index e407617..31213c9 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
@@ -139,11 +139,11 @@
   }
 
   template<typename T>
-  struct X2 { // expected-note{{in instantiation of default member initializer 'NonLocalLambdaInstantation::X2<int *>::x' requested here}}
+  struct X2 {
     int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}}
   };
 
   X2<int> x2i;
   X2<float> x2f;
-  X2<int*> x2ip; // expected-note{{implicit default constructor for 'NonLocalLambdaInstantation::X2<int *>' first required here}}
+  X2<int*> x2ip; // expected-note{{in instantiation of default member initializer 'NonLocalLambdaInstantation::X2<int *>::x'}}
 }
diff --git a/test/CXX/over/over.match/over.match.best/p1.cpp b/test/CXX/over/over.match/over.match.best/p1.cpp
index 59e3dac..fad5bf9 100644
--- a/test/CXX/over/over.match/over.match.best/p1.cpp
+++ b/test/CXX/over/over.match/over.match.best/p1.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
 // expected-no-diagnostics
 
 template<typename T> int &f0(T*, int);
@@ -12,6 +12,28 @@
   float &fr = f0(vp, 0);
 }
 
+namespace deduction_guide_example {
+  template<typename T> struct A {
+    A(T, int*);
+    A(A<T>&, int*);
+    enum { value };
+  };
+
+  template<typename T> struct remove_ref_impl;
+  template<typename T> struct remove_ref_impl<T&> { using type = T; };
+  template<typename T> using remove_ref = typename remove_ref_impl<T>::type;
+
+  // FIXME: The standard's example is wrong; we add a remove_ref<...> here to
+  // fix it.
+  template<typename T, int N = remove_ref<T>::value> A(T&&, int*) -> A<T>;
+  A a{1, 0};
+  extern A<int> a;
+  A b{a, 0};
+
+  A<int> *pa = &a;
+  A<A<int>&> *pb = &b;
+}
+
 // Partial ordering of function template specializations will be tested 
 // elsewhere
 // FIXME: Initialization by user-defined conversion is tested elsewhere
diff --git a/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
new file mode 100644
index 0000000..fe1b6a6
--- /dev/null
+++ b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -verify -std=c++1z %s
+
+namespace Explicit {
+  // Each notional constructor is explicit if the function or function template
+  // was generated from a constructor or deduction-guide that was declared explicit.
+  template<typename T> struct A {
+    A(T);
+    A(T*);
+  };
+  template<typename T> A(T) -> A<T>;
+  template<typename T> explicit A(T*) -> A<T>; // expected-note {{explicit}}
+
+  int *p;
+  A a(p);
+  A b = p;
+  A c{p};
+  A d = {p}; // expected-error {{selected an explicit deduction guide}}
+
+  using X = A<int>;
+  using Y = A<int*>;
+
+  using X = decltype(a);
+  using Y = decltype(b);
+  using X = decltype(c);
+}
diff --git a/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp
new file mode 100644
index 0000000..4ed1d30
--- /dev/null
+++ b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+namespace std_example {
+  template <class T> struct A {
+    explicit A(const T &, ...) noexcept; // expected-note {{explicit}} expected-note 2{{candidate}}
+    A(T &&, ...); // expected-note 2{{candidate}}
+  };
+
+  int i;
+  A a1 = {i, i}; // expected-error {{class template argument deduction for 'A' selected an explicit constructor for copy-list-initialization}}
+  A a2{i, i};
+  A a3{0, i};
+  A a4 = {0, i};
+
+  template <class T> A(const T &, const T &) -> A<T &>; // expected-note 2{{candidate}}
+  template <class T> explicit A(T &&, T &&) -> A<T>; // expected-note {{explicit deduction guide declared here}}
+
+  // FIXME: The standard gives an incorrect explanation for why a5, a7, and a8 are ill-formed.
+  A a5 = {0, 1}; // expected-error {{class template argument deduction for 'A' selected an explicit deduction guide}}
+  A a6{0, 1};
+  A a7 = {0, i}; // expected-error {{ambiguous deduction}}
+  A a8{0, i}; // expected-error {{ambiguous deduction}}
+
+  template <class T> struct B {
+    template <class U> using TA = T;
+    template <class U> B(U, TA<U>);
+  };
+  B b{(int *)0, (char *)0};
+}
+
+namespace check {
+  using namespace std_example;
+  template<typename T, typename U> constexpr bool same = false;
+  template<typename T> constexpr bool same<T, T> = true;
+
+  static_assert(same<decltype(a2), A<int>>);
+  static_assert(same<decltype(a3), A<int>>);
+  static_assert(same<decltype(a4), A<int>>);
+  static_assert(same<decltype(a6), A<int>>);
+  static_assert(same<decltype(b), B<char*>>);
+}
diff --git a/test/CXX/special/class.copy/implicit-move-def.cpp b/test/CXX/special/class.copy/implicit-move-def.cpp
index f344b0c..7a6a1ee 100644
--- a/test/CXX/special/class.copy/implicit-move-def.cpp
+++ b/test/CXX/special/class.copy/implicit-move-def.cpp
@@ -110,8 +110,8 @@
 // CHECK-CTOR: call {{.*}} @_ZN1FC1EOS_
 // CHECK-CTOR: call {{.*}} @_ZN1EC1EOS_
 // array loop
-// CHECK-CTOR: br i1
 // CHECK-CTOR: call {{.*}} @_ZN1FC1EOS_
+// CHECK-CTOR: br i1
 
 // CHECK-CTOR: define linkonce_odr {{.*}} @_ZN1GC2EOS_
 // CHECK-CTOR: call {{.*}} @_ZN1EC1EOS_
diff --git a/test/CXX/special/class.dtor/p10-0x.cpp b/test/CXX/special/class.dtor/p10-0x.cpp
index 3b8a0ad..3be0a98 100644
--- a/test/CXX/special/class.dtor/p10-0x.cpp
+++ b/test/CXX/special/class.dtor/p10-0x.cpp
@@ -33,7 +33,7 @@
                              expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
   i.~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
   pi->~decltype(int())();
-  pi.~decltype(int())(); // expected-error{{the type of object expression ('int *') does not match the type being destroyed ('decltype(int())' (aka 'int')) in pseudo-destructor expression}}
+  pi.~decltype(int())(); // expected-error{{member reference type 'int *' is a pointer; did you mean to use '->'?}}
   pi.~decltype(intp())();
   pi->~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
 }
diff --git a/test/CXX/special/class.dtor/p3-0x.cpp b/test/CXX/special/class.dtor/p3-0x.cpp
index 2d7eba4..f6a6426 100644
--- a/test/CXX/special/class.dtor/p3-0x.cpp
+++ b/test/CXX/special/class.dtor/p3-0x.cpp
@@ -176,4 +176,4 @@
 template <typename T>
 TVC<T>::~TVC() {}
 
-// CHECK: attributes [[ATTRGRP]] = { nounwind{{.*}} }
+// CHECK: attributes [[ATTRGRP]] = { noinline nounwind{{.*}} }
diff --git a/test/CXX/special/class.inhctor/p1.cpp b/test/CXX/special/class.inhctor/p1.cpp
index c006abe..45f6049 100644
--- a/test/CXX/special/class.inhctor/p1.cpp
+++ b/test/CXX/special/class.inhctor/p1.cpp
@@ -3,7 +3,7 @@
 // Note: [class.inhctor] was removed by P0136R1. This tests the new behavior
 // for the wording that used to be there.
 
-struct A { // expected-note 8{{candidate is the implicit}}
+struct A { // expected-note 4{{candidate is the implicit}}
   A(...); // expected-note 4{{candidate constructor}} expected-note 4{{candidate inherited constructor}}
   A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 3{{candidate constructor}} expected-note 3{{candidate inherited constructor}}
   A(int = 0, int = 0, ...); // expected-note 3{{candidate constructor}} expected-note 3{{candidate inherited constructor}}
@@ -15,7 +15,7 @@
 };
 
 struct B : A { // expected-note 4{{candidate is the implicit}}
-  using A::A; // expected-note 19{{inherited here}}
+  using A::A; // expected-note 15{{inherited here}}
   B(void*);
 };
 
diff --git a/test/CXX/special/class.inhctor/p3.cpp b/test/CXX/special/class.inhctor/p3.cpp
index 7f05487..19f15eb 100644
--- a/test/CXX/special/class.inhctor/p3.cpp
+++ b/test/CXX/special/class.inhctor/p3.cpp
@@ -14,21 +14,21 @@
 
 D1 fd1() { return 1; }
 
-struct B2 { // expected-note 2{{candidate}}
+struct B2 {
   explicit B2(int, int = 0, int = 0);
 };
 struct D2 : B2 { // expected-note 2{{candidate constructor}}
-  using B2::B2; // expected-note 2{{inherited here}}
+  using B2::B2;
 };
 D2 d2a(1), d2b(1, 1), d2c(1, 1, 1);
 
 D2 fd2() { return 1; } // expected-error {{no viable conversion}}
 
-struct B3 { // expected-note 2{{candidate}}
+struct B3 {
   B3(void*); // expected-note {{candidate}}
 };
 struct D3 : B3 { // expected-note 2{{candidate constructor}}
-  using B3::B3; // expected-note 3{{inherited here}}
+  using B3::B3; // expected-note {{inherited here}}
 };
 D3 fd3() { return 1; } // expected-error {{no viable conversion}}
 
diff --git a/test/CXX/special/class.inhctor/p7.cpp b/test/CXX/special/class.inhctor/p7.cpp
index c22a43a..2d7acdc 100644
--- a/test/CXX/special/class.inhctor/p7.cpp
+++ b/test/CXX/special/class.inhctor/p7.cpp
@@ -3,15 +3,15 @@
 // Note: [class.inhctor] was removed by P0136R1. This tests the new behavior
 // for the wording that used to be there.
 
-struct B1 { // expected-note 2{{candidate}}
+struct B1 {
   B1(int); // expected-note {{candidate}}
 };
-struct B2 { // expected-note 2{{candidate}}
+struct B2 {
   B2(int); // expected-note {{candidate}}
 };
 struct D1 : B1, B2 { // expected-note 2{{candidate}}
-  using B1::B1; // expected-note 3{{inherited here}}
-  using B2::B2; // expected-note 3{{inherited here}}
+  using B1::B1; // expected-note {{inherited here}}
+  using B2::B2; // expected-note {{inherited here}}
 };
 struct D2 : B1, B2 {
   using B1::B1;
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
index aa1e2d4..52fbd94 100644
--- a/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
@@ -2,7 +2,10 @@
 
 template<int ...Values> struct X1;
 
-template<int ...Values> 
-struct X1<0, Values+1 ...>; // expected-error{{non-type template argument depends on a template parameter of the partial specialization}}
+template<int ...Values>  // expected-note {{non-deducible}}
+struct X1<0, Values+1 ...>; // expected-error{{contains a template parameter that cannot be deduced}}
 
-
+template<typename T, int ...Values> struct X2; // expected-note {{here}}
+template<int ...Values> struct X2<X1<Values...>, Values+1 ...> {}; // ok (DR1315)
+X2<X1<1, 2, 3>, 2, 3, 4> x2; // ok
+X2<X1<1, 2, 3>, 2, 3, 4, 5> x3; // expected-error {{undefined template}}
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
index 2651f99..388a80e 100644
--- a/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
@@ -21,15 +21,16 @@
 
 template<typename Outer> struct X {
   template<typename Inner> static int y;
-  template<typename Inner> static int y<Outer>; // expected-warning {{cannot be deduced}} expected-note {{'Inner'}}
+  // FIXME: It would be preferable to only diagnose this once.
+  template<typename Inner> static int y<Outer>; // expected-error 3{{cannot be deduced}} expected-note 3{{'Inner'}}
   template<typename Inner> static int y<Inner>; // expected-error {{does not specialize}}
-};
-template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-warning {{cannot be deduced}} expected-note {{'Inner'}}
-template<typename Outer> template<typename Inner> int X<Outer>::y<Inner>; // expected-error {{does not specialize}}
 
-// FIXME: Merging this with the above class causes an assertion failure when
-// instantiating one of the bogus partial specializations.
-template<typename Outer> struct Y {
-  template<typename Inner> static int y;
+  template<typename, int> static int z;
+  template<Outer N> static int z<int, N>; // expected-error {{not implicitly convertible}}
 };
-template<> template<typename Inner> int Y<int>::y<Inner>; // expected-error {{does not specialize}}
+template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-error {{cannot be deduced}} expected-note {{'Inner'}}
+template<typename Outer> template<typename Inner> int X<Outer>::y<Inner>; // expected-error {{does not specialize}}
+template<> template<typename Inner> int X<int>::y<Inner>; // expected-error {{does not specialize}} expected-note {{instantiation of}}
+
+X<int> xi;
+X<int*> xf; // expected-note {{instantiation of}}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
index 640d03d..f1f3f70 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -174,7 +174,7 @@
 
   // This shouldn't crash.
   template <class T> class D {
-    friend class A; // expected-error {{elaborated type refers to a template}}
+    friend class A; // expected-error {{template 'A' cannot be referenced with a class specifier}}
   };
   template class D<int>;
 }
diff --git a/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp b/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
index a466be0..a990c82 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
@@ -108,10 +108,10 @@
 
 namespace PartialSpecialization {
   template<typename T, typename U, typename V = U>
-  struct X0; // expected-note{{template is declared here}}
+  struct X0; // expected-note 2{{template is declared here}}
 
   template<typename ...Ts>
-  struct X0<Ts...> {
+  struct X0<Ts...> { // expected-error {{class template partial specialization is not more specialized than the primary template}}
   };
 
   X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp b/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
index 4960a2b..87c22a0 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
@@ -61,7 +61,7 @@
 
 template<class... Members>
 template<int i>
-X<Members...>::get_t<i> X<Members...>::get()
+typename X<Members...>::template get_t<i> X<Members...>::get()
 {
   return 0;
 }
diff --git a/test/CXX/temp/temp.deduct.guide/p1.cpp b/test/CXX/temp/temp.deduct.guide/p1.cpp
new file mode 100644
index 0000000..c0a2ba1
--- /dev/null
+++ b/test/CXX/temp/temp.deduct.guide/p1.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
+// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s -DCLASS
+
+#ifdef CLASS
+struct Outer {
+#endif
+
+template<typename> struct A {};
+
+// Valid forms.
+A(int(&)[1]) -> A<int>;
+explicit A(int(&)[2]) -> A<int>;
+
+// Declarator pieces are not OK.
+*A(int(&)[3]) -> A<int>; // expected-error {{cannot specify any part of a return type in the declaration of a deduction guide}}
+&A(int(&)[4]) -> A<int>; // expected-error {{cannot specify any part of a return type in the declaration of a deduction guide}}
+A(int(&)[5])[3] -> A<int>;
+#ifdef CLASS // FIXME: These diagnostics are both pretty bad.
+// expected-error@-2 {{function cannot return array type}} expected-error@-2 {{';'}}
+#else
+// expected-error@-4 {{expected function body after function declarator}}
+#endif
+
+(A[3])(int(&)[5][1]) -> A<int>; // expected-error {{'<deduction guide for A>' cannot be the name of a variable}}
+#ifndef CLASS
+// expected-error@-2 {{declared as array of functions}}
+#endif
+(*A)(int(&)[5][2]) -> A<int>; // expected-error {{'<deduction guide for A>' cannot be the name of a variable}}
+(&A)(int(&)[5][3]) -> A<int>; // expected-error {{'<deduction guide for A>' cannot be the name of a variable}}
+(*A(int))(int(&)[5][4]) -> A<int>; // expected-error {{cannot specify any part of a return type in the declaration of a deduction guide}}
+
+// (Pending DR) attributes and parens around the declarator-id are OK.
+[[deprecated]] A(int(&)[6]) [[]] -> A<int> [[]];
+A [[]] (int(&)[7]) -> A<int>;
+(A)(int(&)[8]) -> A<int>;
+
+// ... but the trailing-return-type is part of the function-declarator as normal
+(A(int(&)[9])) -> A<int>;
+#ifdef CLASS // FIXME: These diagnostics are both pretty bad.
+// expected-error@-2 {{deduction guide declaration without trailing return type}} expected-error@-2 {{';'}}
+#else
+// expected-error@-4 {{expected function body after function declarator}}
+#endif
+(A(int(&)[10]) -> A<int>); // expected-error {{trailing return type may not be nested within parentheses}}
+
+// A trailing-return-type is mandatory.
+A(int(&)[11]); // expected-error {{deduction guide declaration without trailing return type}}
+
+// No type specifier is permitted; we don't even parse such cases as a deduction-guide.
+int A(int) -> A<int>; // expected-error {{function with trailing return type must specify return type 'auto', not 'int'}}
+template<typename T> struct B {}; // expected-note {{here}}
+auto B(int) -> B<int>; // expected-error {{redefinition of 'B' as different kind of symbol}}
+
+// No storage class specifier, function specifier, ...
+friend A(int(&)[20]) -> A<int>;
+#ifdef CLASS
+// expected-error@-2 {{cannot declare a deduction guide as a friend}}
+#else
+// expected-error@-4 {{'friend' used outside of class}}
+#endif
+typedef A(int(&)[21]) -> A<int>; // expected-error {{deduction guide cannot be declared 'typedef'}}
+constexpr A(int(&)[22]) -> A<int>; // expected-error {{deduction guide cannot be declared 'constexpr'}}
+inline A(int(&)[23]) -> A<int>; // expected-error {{deduction guide cannot be declared 'inline'}}
+static A(int(&)[24]) -> A<int>; // expected-error {{deduction guide cannot be declared 'static'}}
+thread_local A(int(&)[25]) -> A<int>; // expected-error {{'thread_local' is only allowed on variable declarations}}
+extern A(int(&)[26]) -> A<int>;
+#ifdef CLASS
+// expected-error@-2 {{storage class specified for a member}}
+#else
+// expected-error@-4 {{deduction guide cannot be declared 'extern'}}
+#endif
+mutable A(int(&)[27]) -> A<int>; // expected-error-re {{{{'mutable' cannot be applied to|illegal storage class on}} function}}
+virtual A(int(&)[28]) -> A<int>; // expected-error {{'virtual' can only appear on non-static member functions}}
+const A(int(&)[28]) -> A<int>; // expected-error {{deduction guide cannot be declared 'const'}}
+
+const volatile static constexpr inline A(int(&)[29]) -> A<int>; // expected-error {{deduction guide cannot be declared 'static inline constexpr const volatile'}}
+
+A(int(&)[30]) const -> A<int>; // expected-error {{deduction guide cannot have 'const' qualifier}}
+
+// No definition is allowed.
+A(int(&)[40]) -> A<int> {} // expected-error {{deduction guide cannot have a function definition}}
+A(int(&)[41]) -> A<int> = default; // expected-error {{deduction guide cannot have a function definition}} expected-error {{only special member functions may be defaulted}}
+A(int(&)[42]) -> A<int> = delete; // expected-error {{deduction guide cannot have a function definition}}
+A(int(&)[43]) -> A<int> try {} catch (...) {} // expected-error {{deduction guide cannot have a function definition}}
+
+#ifdef CLASS
+};
+#endif
+
+namespace ExplicitInst {
+  // Explicit instantiation / specialization is not permitted.
+  template<typename T> struct B {};
+  template<typename T> B(T) -> B<T>;
+  template<> B(int) -> B<int>; // expected-error {{deduction guide cannot be explicitly specialized}}
+  extern template B(float) -> B<float>; // expected-error {{deduction guide cannot be explicitly instantiated}}
+  template B(char) -> B<char>; // expected-error {{deduction guide cannot be explicitly instantiated}}
+
+  // An attempt at partial specialization doesn't even parse as a deduction-guide.
+  template<typename T> B<T*>(T*) -> B<T*>; // expected-error 1+{{}} expected-note 0+{{}}
+
+  struct X {
+    template<typename T> struct C {};
+    template<typename T> C(T) -> C<T>;
+    template<> C(int) -> C<int>; // expected-error {{explicit specialization of '<deduction guide for C>' in class scope}}
+    extern template C(float) -> C<float>; // expected-error {{expected member name or ';'}}
+    template C(char) -> C<char>; // expected-error {{expected '<' after 'template'}}
+  };
+}
diff --git a/test/CXX/temp/temp.deduct.guide/p2.cpp b/test/CXX/temp/temp.deduct.guide/p2.cpp
new file mode 100644
index 0000000..3549755
--- /dev/null
+++ b/test/CXX/temp/temp.deduct.guide/p2.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+// expected-no-diagnostics
+
+namespace std_example {
+  template<typename T, typename U = int> struct S {
+    T data;
+  };
+  template<typename U> S(U) -> S<typename U::type>;
+
+  struct A {
+    using type = short;
+    operator type();
+  };
+  S x{A()};
+}
diff --git a/test/CXX/temp/temp.deduct.guide/p3.cpp b/test/CXX/temp/temp.deduct.guide/p3.cpp
new file mode 100644
index 0000000..e12f7b6
--- /dev/null
+++ b/test/CXX/temp/temp.deduct.guide/p3.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+
+// The same restrictions apply to the parameter-declaration-clause of a
+// deduction guide as in a function declaration.
+template<typename T> struct A {};
+A(void) -> A<int>; // ok
+A(void, int) -> A<int>; // expected-error {{'void' must be the first and only parameter if specified}}
+
+// We interpret this as also extending to the validity of redeclarations. It's
+// a bit of a stretch (OK, a lot of a stretch) but it gives desirable answers.
+A() -> A<int>; // ok, redeclaration
+
+A() -> A<int>; // expected-note {{previous}}
+A() -> A<float>; // FIXME: "functions" is a poor term. expected-error {{functions that differ only in their return type cannot be overloaded}}
+
+template<typename T> A(T) -> A<typename T::foo>;
+template<typename T> A(T) -> A<typename T::bar>; // ok, can overload on return type (SFINAE applies)
+
+A(long) -> A<int>;
+template<typename T = int> A(long) -> A<char>; // ok, non-template beats template as usual
+
+// (Pending DR) The template-name shall name a class template.
+template<typename T> using B = A<T>; // expected-note {{template}}
+B() -> B<int>; // expected-error {{cannot specify deduction guide for alias template 'B'}}
+// FIXME: expected-error@-1 {{declarator requires an identifier}}
+template<typename T> int C;
+C() -> int; // expected-error {{requires a type specifier}}
+template<typename T> void D();
+D() -> int; // expected-error {{requires a type specifier}}
+template<template<typename> typename TT> struct E { // expected-note 2{{template}}
+  // FIXME: Should only diagnose this once!
+  TT(int) -> TT<int>; // expected-error 2{{cannot specify deduction guide for template template parameter 'TT'}} expected-error {{requires an identifier}}
+};
+
+A(int) -> int; // expected-error {{deduced type 'int' of deduction guide is not a specialization of template 'A'}}
+template<typename T> A(T) -> B<T>; // expected-error {{deduced type 'B<T>' (aka 'A<type-parameter-0-0>') of deduction guide is not written as a specialization of template 'A'}}
+template<typename T> A(T*) -> const A<T>; // expected-error {{deduced type 'const A<T>' of deduction guide is not a specialization of template 'A'}}
+
+// A deduction-guide shall be declared in the same scope as the corresponding
+// class template.
+namespace WrongScope {
+  namespace {
+    template<typename T> struct AnonNS1 {}; // expected-note {{here}}
+    AnonNS1(float) -> AnonNS1<float>; // ok
+  }
+  AnonNS1(int) -> AnonNS1<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::}}
+  template<typename T> struct AnonNS2 {}; // expected-note {{here}}
+  namespace {
+    AnonNS1(char) -> AnonNS1<char>; // ok
+    AnonNS2(int) -> AnonNS2<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::AnonNS2'}}
+  }
+  namespace N {
+    template<typename T> struct NamedNS1 {}; // expected-note {{here}}
+    template<typename T> struct NamedNS2 {}; // expected-note {{here}}
+  }
+  using N::NamedNS1;
+  NamedNS1(int) -> NamedNS1<int>; // expected-error {{deduction guide must be declared in the same scope as template}}
+  using namespace N;
+  NamedNS2(int) -> NamedNS2<int>; // expected-error {{deduction guide must be declared in the same scope as template}}
+  struct ClassMemberA {
+    template<typename T> struct X {}; // expected-note {{here}}
+  };
+  struct ClassMemberB : ClassMemberA {
+    X(int) -> X<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::ClassMemberA::X'}}
+  };
+  template<typename T> struct Local {};
+  void f() {
+    Local(int) -> Local<int>; // expected-error 2{{expected}} expected-note {{to match}}
+    using WrongScope::Local;
+    Local(int) -> Local<int>; // expected-error 2{{expected}} expected-note {{to match}}
+  }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
index 9fd3df5..f7103a3 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
@@ -32,8 +32,11 @@
   static const unsigned char ten = 10;
   template<typename T, T Value, typename U>
   void f2(X<T, Value>, X<U, Value>);
+  // expected-note@-1 {{candidate template ignored: deduced values of conflicting types for parameter 'Value' (10 of type 'int' vs. 10 of type 'char')}}
+  // expected-note@-2 {{candidate template ignored: deduced values of conflicting types for parameter 'Value' (10 of type 'char' vs. 10 of type 'int')}}
 
   void g2() {
-    f2(X<int, 10>(), X<char, ten>());
+    f2(X<int, 10>(), X<char, ten>()); // expected-error {{no matching}}
+    f2(X<char, 10>(), X<int, ten>()); // expected-error {{no matching}}
   }
 }
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
index cd1d9f1..081bba2 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
@@ -76,14 +76,17 @@
   first_arg_pair(make_pair(ip, 17), 16); // expected-error{{no matching function for call to 'first_arg_pair'}}
 }
 
-// For a function parameter pack that does not occur at the end of the
-// parameter-declaration-list, the type of the parameter pack is a
-// non-deduced context.
+// A function parameter pack not at the end of the parameter list is never
+// deduced. We interpret this as meaning the types within it are never
+// deduced, and thus must match explicitly-specified values.
 template<typename ...Types> struct tuple { };
 
 template<typename ...Types>
-void pack_not_at_end(tuple<Types...>, Types... values, int);
+void pack_not_at_end(tuple<Types...>, Types... values, int); // expected-note {{<int *, double *> vs. <>}}
 
 void test_pack_not_at_end(tuple<int*, double*> t2) {
-  pack_not_at_end(t2, 0, 0, 0);
+  pack_not_at_end(t2, 0, 0, 0); // expected-error {{no match}}
+  // FIXME: Should the "original argument type must match deduced parameter
+  // type" rule apply here?
+  pack_not_at_end<int*, double*>(t2, 0, 0, 0); // ok
 }
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
index e470dd0..ebff0a1 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
@@ -1,9 +1,39 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++1z -fsyntax-only -verify %s
 
+// A forwarding reference is an rvalue reference to a cv-unqualified template
+// parameter that does not represent a template parameter of a class template.
+#if __cplusplus > 201402L
+namespace ClassTemplateParamNotForwardingRef {
+  // This is not a forwarding reference.
+  template<typename T> struct A { // expected-note {{candidate}}
+    A(T&&); // expected-note {{no known conversion from 'int' to 'int &&'}}
+  };
+  int n;
+  A a = n; // expected-error {{no viable constructor or deduction guide}}
 
-// If P is an rvalue reference to a cv-unqualified template parameter
-// and the argument is an lvalue, the type "lvalue reference to A" is
-// used in place of A for type deduction.
+  A b = 0;
+  A<int> *pb = &b;
+
+  // This is a forwarding reference.
+  template<typename T> A(T&&) -> A<T>;
+  A c = n;
+  A<int&> *pc = &c;
+
+  A d = 0;
+  A<int> *pd = &d;
+
+  template<typename T = void> struct B {
+    // This is a forwarding reference.
+    template<typename U> B(U &&);
+  };
+  B e = n;
+  B<void> *pe = &e;
+}
+#endif
+
+// If P is a forwarding reference and the argument is an lvalue, the type
+// "lvalue reference to A" is used in place of A for type deduction.
 template<typename T> struct X { };
 
 template<typename T> X<T> f0(T&&);
@@ -43,4 +73,21 @@
   int n1 = f(i);
   int n2 = f(0);
   int n3 = g(i); // expected-error{{no matching function for call to 'g'}}
+
+#if __cplusplus > 201402L
+  template<class T> struct A { // expected-note {{candidate}}
+    template<class U>
+    A(T &&, U &&, int *); // expected-note {{[with T = int, U = int] not viable: no known conversion from 'int' to 'int &&'}}
+    A(T &&, int *);       // expected-note {{requires 2}}
+  };
+  template<class T> A(T &&, int *) -> A<T>; // expected-note {{requires 2}}
+
+  int *ip;
+  A a{i, 0, ip};  // expected-error {{no viable constructor or deduction guide}}
+  A a0{0, 0, ip};
+  A a2{i, ip};
+
+  A<int> &a0r = a0;
+  A<int&> &a2r = a2;
+#endif
 }
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
index b807a0f..54a54b0 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
@@ -32,7 +32,7 @@
 
   template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}}
            typename Tail> // expected-note{{non-deducible template parameter 'Tail'}}
-  struct UselessPartialSpec<Types..., Tail>; // expected-warning{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}}
+  struct UselessPartialSpec<Types..., Tail>; // expected-error{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}}
 }
 
 namespace DeduceNonTypeTemplateArgsInArray {
diff --git a/test/CXX/temp/temp.param/p5.cpp b/test/CXX/temp/temp.param/p5.cpp
index ab430fb..aa0d7e9 100644
--- a/test/CXX/temp/temp.param/p5.cpp
+++ b/test/CXX/temp/temp.param/p5.cpp
@@ -1,13 +1,13 @@
-// RUN: %clang_cc1 -verify %s -std=c++11
+// RUN: %clang_cc1 -verify %s -std=c++14
 
-template<const int I> struct S { // expected-note {{instantiation}}
+template<const int I> struct S {
   decltype(I) n;
   int &&r = I; // expected-warning 2{{binding reference member 'r' to a temporary value}} expected-note 2{{declared here}}
 };
-S<5> s;
+S<5> s; // expected-note {{instantiation}}
 
-template<typename T, T v> struct U { // expected-note {{instantiation}}
+template<typename T, T v> struct U {
   decltype(v) n;
   int &&r = v; // expected-warning {{binding reference member 'r' to a temporary value}} expected-note {{declared here}}
 };
-U<const int, 6> u;
+U<const int, 6> u; // expected-note {{instantiation}}
diff --git a/test/CXX/temp/temp.res/p3.cpp b/test/CXX/temp/temp.res/p3.cpp
new file mode 100644
index 0000000..ea87b8d
--- /dev/null
+++ b/test/CXX/temp/temp.res/p3.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -verify %s -std=c++11
+
+template<typename T> struct A {
+  template<typename U> struct B;
+  template<typename U> using C = U; // expected-note {{here}}
+};
+
+struct X {
+  template<typename T> X(T);
+  struct Y {
+    template<typename T> Y(T);
+  };
+};
+
+template<typename T> A // expected-error {{missing 'typename' prior to dependent type template name 'A<T>::B'}}
+                      <T>::B<T> f1();
+template<typename T> A<T>::C<T> f2(); // expected-error {{missing 'typename' prior to dependent type template name 'A<T>::C'}}
+
+// FIXME: Should these cases really be valid? There doesn't appear to be a rule prohibiting them...
+template<typename T> A<T>::C<X>::X(T) {}
+template<typename T> A<T>::C<X>::X::Y::Y(T) {}
+
+// FIXME: This is ill-formed
+template<typename T> int A<T>::B<T>::*f3() {}
+template<typename T> int A<T>::C<X>::*f4() {}
+
+// FIXME: This is valid
+template<typename T> int A<T>::template C<int>::*f5() {} // expected-error {{has no members}}
+
+template<typename T> template<typename U> struct A<T>::B {
+  friend A<T>::C<T> f6(); // ok, same as 'friend T f6();'
+
+  // FIXME: Error recovery here is awful; we decide that the template-id names
+  // a type, and then complain about the rest of the tokens, and then complain
+  // that we didn't get a function declaration.
+  friend A<U>::C<T> f7(); // expected-error {{use 'template' keyword to treat 'C' as a dependent template name}} expected-error 3{{}}
+  friend A<U>::template C<T> f8(); // expected-error 3{{}}
+};
diff --git a/test/CXX/temp/temp.res/temp.local/p1.cpp b/test/CXX/temp/temp.res/temp.local/p1.cpp
index f6ef636..faa85cb 100644
--- a/test/CXX/temp/temp.res/temp.local/p1.cpp
+++ b/test/CXX/temp/temp.res/temp.local/p1.cpp
@@ -1,12 +1,55 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
 
-// C++0x [temp.local]p1:
+// C++1z [temp.local]p1:
 //   Like normal (non-template) classes, class templates have an
-//   injected-class-name (Clause 9). The injected-class-name can be used with
-//   or without a template-argument-list. When it is used without
-//   a template-argument-list, it is equivalent to the injected-class-name
-//   followed by the template-parameters of the class template enclosed in <>.
+//   injected-class-name (Clause 9). The injected-class-name can
+//   be used as a template-name or a type-name.
+
+template<typename> char id;
+
+template<typename> struct TempType {};
+template<template<typename> class> struct TempTemp {};
+
+template<typename> void use(int&); // expected-note {{invalid explicitly-specified argument}} expected-note {{no known conversion}}
+template<template<typename> class> void use(float&); // expected-note 2{{no known conversion}}
+template<int> void use(char&); // expected-note 2{{invalid explicitly-specified argument}}
+
+template<typename T> struct A {
+  template<typename> struct C {};
+  struct B : C<T> {
+    //   When it is used with a template-argument-list,
+    A<int> *aint;
+    typename B::template C<int> *cint;
+
+    //   as a template-argument for a template template-parameter,
+    TempTemp<A> a_as_temp;
+    TempTemp<B::template C> c_as_temp;
+
+    //   or as the final identifier in the elaborated-type-specifier of a friend
+    //   class template declaration,
+    template<typename U> friend struct A;
+    // it refers to the class template itself.
+
+    // Otherwise, it is equivalent to the template-name followed by the
+    // template-parameters of the class template enclosed in <>.
+    A *aT;
+    typename B::C *cT;
+    TempType<A> a_as_type;
+    TempType<typename B::C> c_as_type;
+    friend struct A;
+    friend struct B::C;
+
+    void f(T &t) {
+      use<A>(t); // expected-error {{no matching function}}
+      if constexpr (&id<T> != &id<int>)
+        use<B::template C>(t); // expected-error {{no matching function}}
+    }
+  };
+};
+
+template struct A<int>;
+template struct A<float>;
+template struct A<char>; // expected-note {{instantiation of}}
 
 template <typename T> struct X0 {
   X0();
diff --git a/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp b/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
index 7eb5e37..425d527 100644
--- a/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
+++ b/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
@@ -9,7 +9,7 @@
 template int pi<int>;
 
 #ifndef FIXING
-template float pi<>; // expected-error {{too few template arguments for template 'pi'}}
+template float pi<>; // expected-error {{too few template arguments for variable template 'pi'}}
 template double pi_var0; // expected-error {{explicit instantiation of 'pi_var0' does not refer to a function template, variable template, member function, member class, or static data member}}
 #endif
 
diff --git a/test/CXX/temp/temp.spec/no-body.cpp b/test/CXX/temp/temp.spec/no-body.cpp
index 4ec18fd..6d1b82f 100644
--- a/test/CXX/temp/temp.spec/no-body.cpp
+++ b/test/CXX/temp/temp.spec/no-body.cpp
@@ -43,7 +43,7 @@
 
 namespace unsupported {
 #ifndef FIXING
- template struct y;     // expected-error {{elaborated type refers to a template}}
+ template struct y;     // expected-error {{template 'y' cannot be referenced with a struct specifier}}
 #endif
 }
 
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
index 1af47a0..ec2e380 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
@@ -283,7 +283,7 @@
     template <typename STRING_TYPE> class BasicStringPiece {};
     template class BasicStringPiece<int>;  // expected-note {{explicit instantiation definition is here}} expected-note {{previous definition is here}}
     extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
-    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::IDS_WithDefinedTemplate::BasicStringPiece<int>'}}
+    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'BasicStringPiece<int>'}}
   }
 
   namespace DIS_WithDefinedTemplate {
@@ -313,14 +313,14 @@
     template <typename STRING_TYPE> class BasicStringPiece;
     template <> class BasicStringPiece<int> { };  // expected-note {{previous definition is here}} expected-note {{previous}}
     template class BasicStringPiece<int>; // expected-warning {{has no effect}}
-    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}}
+    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'BasicStringPiece<int>'}}
   }
 
   namespace SDS {
     template <typename STRING_TYPE> class BasicStringPiece;
     template <> class BasicStringPiece<int> { };  // expected-note {{previous definition is here}}
     extern template class BasicStringPiece<int>;
-    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::SDS::BasicStringPiece<int>'}}
+    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'BasicStringPiece<int>'}}
   }
 
   namespace SDIS {
@@ -328,7 +328,7 @@
     template <> class BasicStringPiece<int> { };  // expected-note {{previous definition is here}}
     extern template class BasicStringPiece<int>;
     template class BasicStringPiece<int>;
-    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::SDIS::BasicStringPiece<int>'}}
+    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'BasicStringPiece<int>'}}
   }
 
 }
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
index 38dc367..9bdccc8 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns -emit-llvm -std=c++11 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes -emit-llvm -std=c++11 -o - %s | FileCheck %s
 
 template<typename T>
 struct X0 {
diff --git a/test/CodeCompletion/auto_type.c b/test/CodeCompletion/auto_type.c
new file mode 100644
index 0000000..3fcfff0
--- /dev/null
+++ b/test/CodeCompletion/auto_type.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -code-completion-at=%s:3:1 %s | FileCheck %s
+void func() {
+
+}
+// CHECK: COMPLETION: __auto_type
diff --git a/test/CodeCompletion/keywords.cpp b/test/CodeCompletion/keywords.cpp
new file mode 100644
index 0000000..6e5824c
--- /dev/null
+++ b/test/CodeCompletion/keywords.cpp
@@ -0,0 +1,79 @@
+int function(int x) {
+  return x + 1;
+}
+
+int variable = 0;
+
+class Class {
+public:
+  Class() { }
+
+  int method(int x) {
+    return x + 1;
+  }
+
+  virtual void virtualMethod() {
+  }
+
+  static void staticMethod() {
+  }
+
+  static int staticVar;
+};
+
+class SubClass : public Class {
+  void virtualMethod() override final {
+  }
+};
+
+struct Struct {
+};
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:1:1 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:5:1 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:11:1 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s
+// CHECK-TOP-LEVEL: alignas(<#expression#>)
+// CHECK-TOP-LEVEL: constexpr
+// CHECK-TOP-LEVEL: static_assert(<#expression#>, <#message#>)
+// CHECK-TOP-LEVEL: thread_local
+// CHECK-TOP-LEVEL-NOT: final
+// CHECK-TOP-LEVEL-NOT: noexcept
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:1:14 %s | FileCheck --check-prefix=CHECK-PARAM %s
+// CHECK-PARAM-NOT: alignas
+// CHECK-PARAM-NOT: constexpr
+// CHECK-PARAM-NOT: final
+// CHECK-PARAM-NOT: thread_local
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:21:10 %s | FileCheck --check-prefix=CHECK-STATICVAR1 %s
+// CHECK-STATICVAR1: constexpr
+// CHECK-STATICVAR1: thread_local
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:7:13 %s | FileCheck --check-prefix=CHECK-CLASS-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:24:16 %s | FileCheck --check-prefix=CHECK-CLASS-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:29:15 %s | FileCheck --check-prefix=CHECK-CLASS-QUALIFIER %s
+// CHECK-CLASS-QUALIFIER: final
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:1:21 %s | FileCheck --check-prefix=CHECK-FUNCTION-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:9:11 %s | FileCheck --check-prefix=CHECK-FUNCTION-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:18:30 %s | FileCheck --check-prefix=CHECK-FUNCTION-QUALIFIER %s
+// CHECK-FUNCTION-QUALIFIER: noexcept
+// CHECK-FUNCTION-QUALIFIER-NOT: final
+// CHECK-FUNCTION-QUALIFIER-NOT: override
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:11:21 %s | FileCheck --check-prefix=CHECK-METHOD-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:15:32 %s | FileCheck --check-prefix=CHECK-METHOD-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:25:24 %s | FileCheck --check-prefix=CHECK-METHOD-QUALIFIER %s
+// CHECK-METHOD-QUALIFIER: final
+// CHECK-METHOD-QUALIFIER: noexcept
+// CHECK-METHOD-QUALIFIER: override
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:25:33 %s | FileCheck --check-prefix=CHECK-OVERRIDE-SPECIFIED %s
+// CHECK-OVERRIDE-SPECIFIED: final
+// CHECK-OVERRIDE-SPECIFIED: noexcept
+// CHECK-OVERRIDE-SPECIFIED-NOT: override
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:25:39 %s | FileCheck --check-prefix=CHECK-OVERRIDE-FINAL-SPECIFIED %s
+// CHECK-OVERRIDE-FINAL-SPECIFIED: noexcept
+// CHECK-OVERRIDE-FINAL-SPECIFIED-NOT: final
+// CHECK-OVERRIDE-FINAL-SPECIFIED-NOT: override
diff --git a/test/CodeCompletion/member-access.cpp b/test/CodeCompletion/member-access.cpp
index 8f772c0..8195f76 100644
--- a/test/CodeCompletion/member-access.cpp
+++ b/test/CodeCompletion/member-access.cpp
@@ -27,6 +27,16 @@
 
 void test(const Proxy &p) {
   p->
+}
+
+struct Test1 {
+  Base1 b;
+
+  static void sfunc() {
+    b. // expected-error {{invalid use of member 'b' in static member function}}
+  }
+};
+
   // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:29:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
   // CHECK-CC1: Base1 : Base1::
   // CHECK-CC1: member1 : [#int#][#Base1::#]member1
@@ -39,4 +49,6 @@
   // CHECK-CC1: memfun1 (Hidden) : [#void#]Base2::memfun1(<#int#>)
   // CHECK-CC1: memfun2 : [#void#][#Base3::#]memfun2(<#int#>)
   // CHECK-CC1: memfun3 : [#int#]memfun3(<#int#>)
-  
+
+// Make sure this doesn't crash
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:36:7 %s -verify
diff --git a/test/CodeCompletion/ordinary-name-cxx11.cpp b/test/CodeCompletion/ordinary-name-cxx11.cpp
index 8e6f383..34c3bf9 100644
--- a/test/CodeCompletion/ordinary-name-cxx11.cpp
+++ b/test/CodeCompletion/ordinary-name-cxx11.cpp
@@ -39,10 +39,12 @@
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof...(<#parameter-pack#>)
   // CHECK-CC1-NEXT: COMPLETION: static
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-CC1-NEXT: COMPLETION: Pattern : static_cast<<#type#>>(<#expression#>)
   // CHECK-CC1-NEXT: COMPLETION: struct
   // CHECK-CC1-NEXT: COMPLETION: Pattern : switch(<#condition#>){
   // CHECK-CC1: COMPLETION: t : t
+  // CHECK-CC1-NEXT: COMPLETION: thread_local
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#void#]throw <#expression#>
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#bool#]true
   // CHECK-CC1-NEXT: COMPLETION: Pattern : try{<#statements#>
@@ -72,6 +74,7 @@
   // CHECK-CC2-NEXT: COMPLETION: char32
   // CHECK-CC2-NEXT: COMPLETION: class
   // CHECK-CC2-NEXT: COMPLETION: const
+  // CHECK-CC2-NEXT: COMPLETION: constexpr
   // CHECK-CC2-NEXT: COMPLETION: Pattern : decltype(<#expression#>)
   // CHECK-CC2-NEXT: COMPLETION: double
   // CHECK-CC2-NEXT: COMPLETION: enum
@@ -86,10 +89,12 @@
   // CHECK-CC2-NEXT: COMPLETION: short
   // CHECK-CC2-NEXT: COMPLETION: signed
   // CHECK-CC2-NEXT: COMPLETION: static
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-CC2-NEXT: COMPLETION: struct
   // CHECK-CC2-NEXT: COMPLETION: t : t
   // CHECK-CC2-NEXT: COMPLETION: Pattern : template <#declaration#>
   // CHECK-CC2-NEXT: COMPLETION: Pattern : template<<#parameters#>>
+  // CHECK-CC2-NEXT: COMPLETION: thread_local
   // CHECK-CC2-NEXT: COMPLETION: TYPEDEF : TYPEDEF
   // CHECK-CC2-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>
   // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#>
@@ -111,6 +116,7 @@
   // CHECK-CC3-NEXT: COMPLETION: char32_t
   // CHECK-CC3-NEXT: COMPLETION: class
   // CHECK-CC3-NEXT: COMPLETION: const
+  // CHECK-CC3-NEXT: COMPLETION: constexpr
   // CHECK-CC3-NEXT: COMPLETION: Pattern : decltype(<#expression#>)
   // CHECK-CC3-NEXT: COMPLETION: double
   // CHECK-CC3-NEXT: COMPLETION: enum
@@ -129,8 +135,10 @@
   // CHECK-CC3-NEXT: COMPLETION: short
   // CHECK-CC3-NEXT: COMPLETION: signed
   // CHECK-CC3-NEXT: COMPLETION: static
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-CC3-NEXT: COMPLETION: struct
   // CHECK-CC3-NEXT: COMPLETION: Pattern : template<<#parameters#>>
+  // CHECK-CC3-NEXT: COMPLETION: thread_local
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#>
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof <#expression#>
@@ -227,6 +235,7 @@
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof...(<#parameter-pack#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: static
+  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : static_cast<<#type#>>(<#expression#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: struct
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : switch(<#condition#>){
diff --git a/test/CodeCompletion/pragma-macro-token-caching.c b/test/CodeCompletion/pragma-macro-token-caching.c
new file mode 100644
index 0000000..432706e
--- /dev/null
+++ b/test/CodeCompletion/pragma-macro-token-caching.c
@@ -0,0 +1,18 @@
+
+#define Outer(action) action
+
+void completeParam(int param) {
+    ;
+    Outer(__extension__({ _Pragma("clang diagnostic push") }));
+    param;
+}
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:7:1 %s | FileCheck %s
+// CHECK: param : [#int#]param
+
+void completeParamPragmaError(int param) {
+    Outer(__extension__({ _Pragma(2) })); // expected-error {{_Pragma takes a parenthesized string literal}}
+    param;
+}
+
+// RUN: %clang_cc1 -fsyntax-only -verify -code-completion-at=%s:16:1 %s | FileCheck %s
diff --git a/test/CodeGen/2008-04-08-NoExceptions.c b/test/CodeGen/2008-04-08-NoExceptions.c
index 1213492..6528c35 100644
--- a/test/CodeGen/2008-04-08-NoExceptions.c
+++ b/test/CodeGen/2008-04-08-NoExceptions.c
@@ -9,4 +9,4 @@
 
 // CHECK-NOT: declare void @f() [[NUW]]
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGen/2009-10-20-GlobalDebug.c b/test/CodeGen/2009-10-20-GlobalDebug.c
index 38f20cd..0d7c759 100644
--- a/test/CodeGen/2009-10-20-GlobalDebug.c
+++ b/test/CodeGen/2009-10-20-GlobalDebug.c
@@ -10,9 +10,11 @@
   return 0;
 }
 
-// CHECK: [[L]] = distinct !DIGlobalVariable(name: "localstatic"
-// CHECK-NOT:               linkageName:
-// CHECK-SAME:              line: 9,
-// CHECK: [[G]] = distinct !DIGlobalVariable(name: "global"
-// CHECK-NOT:               linkageName:
-// CHECK-SAME:              line: 7,
+// CHECK: [[L]] = !DIGlobalVariableExpression(var: [[LV:.*]])
+// CHECK: [[LV]] = distinct !DIGlobalVariable(name: "localstatic"
+// CHECK-NOT:                                 linkageName:
+// CHECK-SAME:                                line: 9,
+// CHECK: [[G]] = !DIGlobalVariableExpression(var: [[GV:.*]])
+// CHECK: [[GV]] = distinct !DIGlobalVariable(name: "global"
+// CHECK-NOT:                                 linkageName:
+// CHECK-SAME:                                line: 7,
diff --git a/test/CodeGen/2010-08-10-DbgConstant.c b/test/CodeGen/2010-08-10-DbgConstant.c
index 3a40c24..68947ed 100644
--- a/test/CodeGen/2010-08-10-DbgConstant.c
+++ b/test/CodeGen/2010-08-10-DbgConstant.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -S -emit-llvm -debug-info-kind=limited  %s -o - | FileCheck %s
-// CHECK: !DIGlobalVariable({{.*}}, expr: [[EXPR:![0-9]+]])
+// CHECK: !DIGlobalVariableExpression(var: [[VAR:.*]], expr: [[EXPR:![0-9]+]])
 // CHECK: [[EXPR]] = !DIExpression(DW_OP_constu, 201, DW_OP_stack_value)
 
 static const unsigned int ro = 201;
diff --git a/test/CodeGen/Inputs/debug-info-file-checksum.c b/test/CodeGen/Inputs/debug-info-file-checksum.c
new file mode 100644
index 0000000..081f6f0
--- /dev/null
+++ b/test/CodeGen/Inputs/debug-info-file-checksum.c
@@ -0,0 +1,3 @@
+int foo(int x) {
+  return x+1;
+}
diff --git a/test/CodeGen/Inputs/debug-info-macro.h b/test/CodeGen/Inputs/debug-info-macro.h
new file mode 100644
index 0000000..f71d5c3
--- /dev/null
+++ b/test/CodeGen/Inputs/debug-info-macro.h
@@ -0,0 +1,12 @@
+
+#ifdef D1
+/*Line 3*/ #define A(x, y, z) (x)
+#endif
+
+#ifdef D2
+/*Line 7*/ #define A(x, y, z) (y)
+#endif
+
+#ifdef A
+/*Line 11*/ #undef A
+#endif
diff --git a/test/CodeGen/address-safety-attr-kasan.cpp b/test/CodeGen/address-safety-attr-kasan.cpp
index c84ba88..4d8333d 100644
--- a/test/CodeGen/address-safety-attr-kasan.cpp
+++ b/test/CodeGen/address-safety-attr-kasan.cpp
@@ -8,31 +8,31 @@
 int HasSanitizeAddress() {
   return 1;
 }
-// CHECK-NOASAN: {{Function Attrs: nounwind$}}
-// CHECK-ASAN: Function Attrs: nounwind sanitize_address
-// CHECK-KASAN: Function Attrs: nounwind sanitize_address
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-ASAN: Function Attrs: noinline nounwind sanitize_address
+// CHECK-KASAN: Function Attrs: noinline nounwind sanitize_address
 
 __attribute__((no_sanitize("address")))
 int NoSanitizeQuoteAddress() {
   return 0;
 }
-// CHECK-NOASAN: {{Function Attrs: nounwind$}}
-// CHECK-ASAN: {{Function Attrs: nounwind$}}
-// CHECK-KASAN: {{Function Attrs: nounwind sanitize_address$}}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
 
 __attribute__((no_sanitize_address))
 int NoSanitizeAddress() {
   return 0;
 }
-// CHECK-NOASAN: {{Function Attrs: nounwind$}}
-// CHECK-ASAN: {{Function Attrs: nounwind$}}
-// CHECK-KASAN: {{Function Attrs: nounwind sanitize_address$}}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
 
 __attribute__((no_sanitize("kernel-address")))
 int NoSanitizeKernelAddress() {
   return 0;
 }
 
-// CHECK-NOASAN: {{Function Attrs: nounwind$}}
-// CHECK-ASAN: {{Function Attrs: nounwind sanitize_address$}}
-// CHECK-KASAN: {{Function Attrs: nounwind$}}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind$}}
diff --git a/test/CodeGen/address-safety-attr.cpp b/test/CodeGen/address-safety-attr.cpp
index 0038b34..60faedd 100644
--- a/test/CodeGen/address-safety-attr.cpp
+++ b/test/CodeGen/address-safety-attr.cpp
@@ -143,13 +143,13 @@
 // BLFUNC: @__cxx_global_var_init{{.*}}[[WITH]]
 // ASAN: @__cxx_global_var_init{{.*}}[[WITH]]
 
-// WITHOUT: attributes [[NOATTR]] = { nounwind{{.*}} }
+// WITHOUT: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 
-// BLFILE: attributes [[WITH]] = { nounwind sanitize_address{{.*}} }
-// BLFILE: attributes [[NOATTR]] = { nounwind{{.*}} }
+// BLFILE: attributes [[WITH]] = { noinline nounwind sanitize_address{{.*}} }
+// BLFILE: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 
-// BLFUNC: attributes [[WITH]] = { nounwind sanitize_address{{.*}} }
-// BLFUNC: attributes [[NOATTR]] = { nounwind{{.*}} }
+// BLFUNC: attributes [[WITH]] = { noinline nounwind sanitize_address{{.*}} }
+// BLFUNC: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 
-// ASAN: attributes [[WITH]] = { nounwind sanitize_address{{.*}} }
-// ASAN: attributes [[NOATTR]] = { nounwind{{.*}} }
+// ASAN: attributes [[WITH]] = { noinline nounwind sanitize_address{{.*}} }
+// ASAN: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGen/address-space-field1.c b/test/CodeGen/address-space-field1.c
index 109c692..64b51ae 100644
--- a/test/CodeGen/address-space-field1.c
+++ b/test/CodeGen/address-space-field1.c
@@ -37,4 +37,4 @@
   p1->b = p2->a;
 }
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c
index c34dcf5..6ec1270 100644
--- a/test/CodeGen/alias.c
+++ b/test/CodeGen/alias.c
@@ -77,9 +77,9 @@
 // CHECKCC: call arm_aapcs_vfpcc  i32 @inner_weak(i32 %{{.*}})
 // CHECKCC: define internal arm_aapcs_vfpcc i32 @inner_weak(i32 %a) [[NUW]] {
 
-// CHECKBASIC: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECKBASIC: attributes [[NUW]] = { noinline nounwind{{.*}} }
 
-// CHECKCC: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECKCC: attributes [[NUW]] = { noinline nounwind{{.*}} }
 
 void test8_bar() {}
 void test8_foo() __attribute__((weak, alias("test8_bar")));
diff --git a/test/CodeGen/alloc-size.c b/test/CodeGen/alloc-size.c
new file mode 100644
index 0000000..1e503f0
--- /dev/null
+++ b/test/CodeGen/alloc-size.c
@@ -0,0 +1,352 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+
+#define NULL ((void *)0)
+
+int gi;
+
+typedef unsigned long size_t;
+
+// CHECK-DAG-RE: define void @my_malloc({{.*}}) #[[MALLOC_ATTR_NUMBER:[0-9]+]]
+// N.B. LLVM's allocsize arguments are base-0, whereas ours are base-1 (for
+// compat with GCC)
+// CHECK-DAG-RE: attributes #[[MALLOC_ATTR_NUMBER]] = {.*allocsize(0).*}
+void *my_malloc(size_t) __attribute__((alloc_size(1)));
+
+// CHECK-DAG-RE: define void @my_calloc({{.*}}) #[[CALLOC_ATTR_NUMBER:[0-9]+]]
+// CHECK-DAG-RE: attributes #[[CALLOC_ATTR_NUMBER]] = {.*allocsize(0, 1).*}
+void *my_calloc(size_t, size_t) __attribute__((alloc_size(1, 2)));
+
+// CHECK-LABEL: @test1
+void test1() {
+  void *const vp = my_malloc(100);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(vp, 0);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(vp, 1);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(vp, 2);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(vp, 3);
+
+  void *const arr = my_calloc(100, 5);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(arr, 0);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(arr, 1);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(arr, 2);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(arr, 3);
+
+  // CHECK: store i32 100
+  gi = __builtin_object_size(my_malloc(100), 0);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(my_malloc(100), 1);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(my_malloc(100), 2);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(my_malloc(100), 3);
+
+  // CHECK: store i32 500
+  gi = __builtin_object_size(my_calloc(100, 5), 0);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(my_calloc(100, 5), 1);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(my_calloc(100, 5), 2);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(my_calloc(100, 5), 3);
+
+  void *const zeroPtr = my_malloc(0);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(zeroPtr, 0);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(my_malloc(0), 0);
+
+  void *const zeroArr1 = my_calloc(0, 1);
+  void *const zeroArr2 = my_calloc(1, 0);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(zeroArr1, 0);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(zeroArr2, 0);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(my_calloc(1, 0), 0);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(my_calloc(0, 1), 0);
+}
+
+// CHECK-LABEL: @test2
+void test2() {
+  void *const vp = my_malloc(gi);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(vp, 0);
+
+  void *const arr1 = my_calloc(gi, 1);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr1, 0);
+
+  void *const arr2 = my_calloc(1, gi);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr2, 0);
+}
+
+// CHECK-LABEL: @test3
+void test3() {
+  char *const buf = (char *)my_calloc(100, 5);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(buf, 0);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(buf, 1);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(buf, 2);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(buf, 3);
+}
+
+struct Data {
+  int a;
+  int t[10];
+  char pad[3];
+  char end[1];
+};
+
+// CHECK-LABEL: @test5
+void test5() {
+  struct Data *const data = my_malloc(sizeof(*data));
+  // CHECK: store i32 48
+  gi = __builtin_object_size(data, 0);
+  // CHECK: store i32 48
+  gi = __builtin_object_size(data, 1);
+  // CHECK: store i32 48
+  gi = __builtin_object_size(data, 2);
+  // CHECK: store i32 48
+  gi = __builtin_object_size(data, 3);
+
+  // CHECK: store i32 40
+  gi = __builtin_object_size(&data->t[1], 0);
+  // CHECK: store i32 36
+  gi = __builtin_object_size(&data->t[1], 1);
+  // CHECK: store i32 40
+  gi = __builtin_object_size(&data->t[1], 2);
+  // CHECK: store i32 36
+  gi = __builtin_object_size(&data->t[1], 3);
+
+  struct Data *const arr = my_calloc(sizeof(*data), 2);
+  // CHECK: store i32 96
+  gi = __builtin_object_size(arr, 0);
+  // CHECK: store i32 96
+  gi = __builtin_object_size(arr, 1);
+  // CHECK: store i32 96
+  gi = __builtin_object_size(arr, 2);
+  // CHECK: store i32 96
+  gi = __builtin_object_size(arr, 3);
+
+  // CHECK: store i32 88
+  gi = __builtin_object_size(&arr->t[1], 0);
+  // CHECK: store i32 36
+  gi = __builtin_object_size(&arr->t[1], 1);
+  // CHECK: store i32 88
+  gi = __builtin_object_size(&arr->t[1], 2);
+  // CHECK: store i32 36
+  gi = __builtin_object_size(&arr->t[1], 3);
+}
+
+// CHECK-LABEL: @test6
+void test6() {
+  // Things that would normally trigger conservative estimates don't need to do
+  // so when we know the source of the allocation.
+  struct Data *const data = my_malloc(sizeof(*data) + 10);
+  // CHECK: store i32 11
+  gi = __builtin_object_size(data->end, 0);
+  // CHECK: store i32 11
+  gi = __builtin_object_size(data->end, 1);
+  // CHECK: store i32 11
+  gi = __builtin_object_size(data->end, 2);
+  // CHECK: store i32 11
+  gi = __builtin_object_size(data->end, 3);
+
+  struct Data *const arr = my_calloc(sizeof(*arr) + 5, 3);
+  // AFAICT, GCC treats malloc and calloc identically. So, we should do the
+  // same.
+  //
+  // Additionally, GCC ignores the initial array index when determining whether
+  // we're writing off the end of an alloc_size base. e.g.
+  //   arr[0].end
+  //   arr[1].end
+  //   arr[2].end
+  // ...Are all considered "writing off the end", because there's no way to tell
+  // with high accuracy if the user meant "allocate a single N-byte `Data`",
+  // or "allocate M smaller `Data`s with extra padding".
+
+  // CHECK: store i32 112
+  gi = __builtin_object_size(arr->end, 0);
+  // CHECK: store i32 112
+  gi = __builtin_object_size(arr->end, 1);
+  // CHECK: store i32 112
+  gi = __builtin_object_size(arr->end, 2);
+  // CHECK: store i32 112
+  gi = __builtin_object_size(arr->end, 3);
+
+  // CHECK: store i32 112
+  gi = __builtin_object_size(arr[0].end, 0);
+  // CHECK: store i32 112
+  gi = __builtin_object_size(arr[0].end, 1);
+  // CHECK: store i32 112
+  gi = __builtin_object_size(arr[0].end, 2);
+  // CHECK: store i32 112
+  gi = __builtin_object_size(arr[0].end, 3);
+
+  // CHECK: store i32 64
+  gi = __builtin_object_size(arr[1].end, 0);
+  // CHECK: store i32 64
+  gi = __builtin_object_size(arr[1].end, 1);
+  // CHECK: store i32 64
+  gi = __builtin_object_size(arr[1].end, 2);
+  // CHECK: store i32 64
+  gi = __builtin_object_size(arr[1].end, 3);
+
+  // CHECK: store i32 16
+  gi = __builtin_object_size(arr[2].end, 0);
+  // CHECK: store i32 16
+  gi = __builtin_object_size(arr[2].end, 1);
+  // CHECK: store i32 16
+  gi = __builtin_object_size(arr[2].end, 2);
+  // CHECK: store i32 16
+  gi = __builtin_object_size(arr[2].end, 3);
+}
+
+// CHECK-LABEL: @test7
+void test7() {
+  struct Data *const data = my_malloc(sizeof(*data) + 5);
+  // CHECK: store i32 9
+  gi = __builtin_object_size(data->pad, 0);
+  // CHECK: store i32 3
+  gi = __builtin_object_size(data->pad, 1);
+  // CHECK: store i32 9
+  gi = __builtin_object_size(data->pad, 2);
+  // CHECK: store i32 3
+  gi = __builtin_object_size(data->pad, 3);
+}
+
+// CHECK-LABEL: @test8
+void test8() {
+  // Non-const pointers aren't currently supported.
+  void *buf = my_calloc(100, 5);
+  // CHECK: @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
+  gi = __builtin_object_size(buf, 0);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(buf, 1);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(buf, 2);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(buf, 3);
+}
+
+// CHECK-LABEL: @test9
+void test9() {
+  // Check to be sure that we unwrap things correctly.
+  short *const buf0 = (my_malloc(100));
+  short *const buf1 = (short*)(my_malloc(100));
+  short *const buf2 = ((short*)(my_malloc(100)));
+
+  // CHECK: store i32 100
+  gi = __builtin_object_size(buf0, 0);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(buf1, 0);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(buf2, 0);
+}
+
+// CHECK-LABEL: @test10
+void test10() {
+  // Yay overflow
+  short *const arr = my_calloc((size_t)-1 / 2 + 1, 2);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr, 0);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr, 1);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr, 2);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(arr, 3);
+
+  // As an implementation detail, CharUnits can't handle numbers greater than or
+  // equal to 2**63. Realistically, this shouldn't be a problem, but we should
+  // be sure we don't emit crazy results for this case.
+  short *const buf = my_malloc((size_t)-1);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(buf, 0);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(buf, 1);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(buf, 2);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(buf, 3);
+
+  short *const arr_big = my_calloc((size_t)-1 / 2 - 1, 2);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr_big, 0);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr_big, 1);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr_big, 2);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(arr_big, 3);
+}
+
+void *my_tiny_malloc(char) __attribute__((alloc_size(1)));
+void *my_tiny_calloc(char, char) __attribute__((alloc_size(1, 2)));
+
+// CHECK-LABEL: @test11
+void test11() {
+  void *const vp = my_tiny_malloc(100);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(vp, 0);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(vp, 1);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(vp, 2);
+  // CHECK: store i32 100
+  gi = __builtin_object_size(vp, 3);
+
+  // N.B. This causes char overflow, but not size_t overflow, so it should be
+  // supported.
+  void *const arr = my_tiny_calloc(100, 5);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(arr, 0);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(arr, 1);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(arr, 2);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(arr, 3);
+}
+
+void *my_signed_malloc(long) __attribute__((alloc_size(1)));
+void *my_signed_calloc(long, long) __attribute__((alloc_size(1, 2)));
+
+// CHECK-LABEL: @test12
+void test12() {
+  // CHECK: store i32 100
+  gi = __builtin_object_size(my_signed_malloc(100), 0);
+  // CHECK: store i32 500
+  gi = __builtin_object_size(my_signed_calloc(100, 5), 0);
+
+  void *const vp = my_signed_malloc(-2);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(vp, 0);
+  // N.B. These get lowered to -1 because the function calls may have
+  // side-effects, and we can't determine the objectsize.
+  // CHECK: store i32 -1
+  gi = __builtin_object_size(my_signed_malloc(-2), 0);
+
+  void *const arr1 = my_signed_calloc(-2, 1);
+  void *const arr2 = my_signed_calloc(1, -2);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr1, 0);
+  // CHECK: @llvm.objectsize
+  gi = __builtin_object_size(arr2, 0);
+  // CHECK: store i32 -1
+  gi = __builtin_object_size(my_signed_calloc(1, -2), 0);
+  // CHECK: store i32 -1
+  gi = __builtin_object_size(my_signed_calloc(-2, 1), 0);
+}
diff --git a/test/CodeGen/always_inline.c b/test/CodeGen/always_inline.c
index c91fd43..8e4a7c7 100644
--- a/test/CodeGen/always_inline.c
+++ b/test/CodeGen/always_inline.c
@@ -1,7 +1,7 @@
 // RUN: %clang -emit-llvm -S -o %t %s
 // RUN: not grep '@f0' %t
 // RUN: not grep 'call ' %t
-// RUN: %clang -mllvm -disable-llvm-optzns -emit-llvm -S -o %t %s
+// RUN: %clang -Xclang -disable-llvm-passes -emit-llvm -S -o %t %s
 // RUN: grep '@f0' %t | count 2
 
 //static int f0() { 
diff --git a/test/CodeGen/arm-target-features.c b/test/CodeGen/arm-target-features.c
index 2670dfe..7437fb0 100644
--- a/test/CodeGen/arm-target-features.c
+++ b/test/CodeGen/arm-target-features.c
@@ -30,6 +30,7 @@
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a73 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m2 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
+// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // CHECK-BASIC-V8: "target-features"="+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon"
 
 
diff --git a/test/CodeGen/arm64_crypto.c b/test/CodeGen/arm64_crypto.c
index e63009a..c8bd4f9 100644
--- a/test/CodeGen/arm64_crypto.c
+++ b/test/CodeGen/arm64_crypto.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +crypto -ffreestanding -Os -S -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +crypto -ffreestanding -fexperimental-new-pass-manager -Os -S -o - %s | FileCheck %s
 // REQUIRES: aarch64-registered-target
 
 #include <arm_neon.h>
diff --git a/test/CodeGen/arm_acle.c b/test/CodeGen/arm_acle.c
index 0884394..b4f39be 100644
--- a/test/CodeGen/arm_acle.c
+++ b/test/CodeGen/arm_acle.c
@@ -244,23 +244,23 @@
 }
 
 // ARM-LABEL: test_rbit
-// AArch32: call i32 @llvm.arm.rbit
-// AArch64: call i32 @llvm.aarch64.rbit.i32
+// AArch32: call i32 @llvm.bitreverse.i32
+// AArch64: call i32 @llvm.bitreverse.i32
 uint32_t test_rbit(uint32_t t) {
   return __rbit(t);
 }
 
 // ARM-LABEL: test_rbitl
-// AArch32: call i32 @llvm.arm.rbit
-// AArch64: call i64 @llvm.aarch64.rbit.i64
+// AArch32: call i32 @llvm.bitreverse.i32
+// AArch64: call i64 @llvm.bitreverse.i64
 long test_rbitl(long t) {
   return __rbitl(t);
 }
 
 // ARM-LABEL: test_rbitll
-// AArch32: call i32 @llvm.arm.rbit
-// AArch32: call i32 @llvm.arm.rbit
-// AArch64: call i64 @llvm.aarch64.rbit.i64
+// AArch32: call i32 @llvm.bitreverse.i32
+// AArch32: call i32 @llvm.bitreverse.i32
+// AArch64: call i64 @llvm.bitreverse.i64
 uint64_t test_rbitll(uint64_t t) {
   return __rbitll(t);
 }
diff --git a/test/CodeGen/attr-minsize.cpp b/test/CodeGen/attr-minsize.cpp
index 1e5c634..4a26e85 100644
--- a/test/CodeGen/attr-minsize.cpp
+++ b/test/CodeGen/attr-minsize.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -Oz -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s -check-prefix=Oz
-// RUN: %clang_cc1     -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
-// RUN: %clang_cc1 -O1 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
-// RUN: %clang_cc1 -O2 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
-// RUN: %clang_cc1 -O3 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
-// RUN: %clang_cc1 -Os -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
+// RUN: %clang_cc1 -Oz -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefix=Oz
+// RUN: %clang_cc1     -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
+// RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
+// RUN: %clang_cc1 -O2 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
+// RUN: %clang_cc1 -O3 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
+// RUN: %clang_cc1 -Os -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER
 // Check that we set the minsize attribute on each function
 // when Oz optimization level is set.
 
@@ -76,4 +76,4 @@
 
 // Oz: attributes [[MINSIZE]] = { minsize{{.*}} }
 
-// OTHER: attributes [[MS]] = { minsize nounwind{{.*}} }
+// OTHER: attributes [[MS]] = { minsize{{.*}} }
diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c
index 7bfc392..9e5fa9f 100644
--- a/test/CodeGen/attributes.c
+++ b/test/CodeGen/attributes.c
@@ -90,5 +90,5 @@
 
 // CHECK: define void @t22() [[NUW]] section ".bar"
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
-// CHECK: attributes [[NR]] = { noreturn nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
+// CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} }
diff --git a/test/CodeGen/avr-inline-asm-constraints.c b/test/CodeGen/avr-inline-asm-constraints.c
new file mode 100644
index 0000000..f1bfbac
--- /dev/null
+++ b/test/CodeGen/avr-inline-asm-constraints.c
@@ -0,0 +1,124 @@
+// REQUIRES: avr-registered-target
+// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+int data;
+
+void a() {
+  // CHECK: call void asm sideeffect "add r5, $0", "a"(i16 %0)
+  asm("add r5, %0" :: "a"(data));
+}
+
+void b() {
+  // CHECK: call void asm sideeffect "add r5, $0", "b"(i16 %0)
+  asm("add r5, %0" :: "b"(data));
+}
+
+void d() {
+  // CHECK: call void asm sideeffect "add r5, $0", "d"(i16 %0)
+  asm("add r5, %0" :: "d"(data));
+}
+
+void l() {
+  // CHECK: call void asm sideeffect "add r5, $0", "l"(i16 %0)
+  asm("add r5, %0" :: "l"(data));
+}
+
+void e() {
+  // CHECK: call void asm sideeffect "add r5, $0", "e"(i16 %0)
+  asm("add r5, %0" :: "e"(data));
+}
+
+void q() {
+  // CHECK: call void asm sideeffect "add r5, $0", "q"(i16 %0)
+  asm("add r5, %0" :: "q"(data));
+}
+
+void r() {
+  // CHECK: call void asm sideeffect "add r5, $0", "r"(i16 %0)
+  asm("add r5, %0" :: "r"(data));
+}
+
+void w() {
+  // CHECK: call void asm sideeffect "add r5, $0", "w"(i16 %0)
+  asm("add r5, %0" :: "w"(data));
+}
+
+void t() {
+  // CHECK: call void asm sideeffect "add r5, $0", "t"(i16 %0)
+  asm("add r5, %0" :: "t"(data));
+}
+
+void x() {
+  // CHECK: call void asm sideeffect "add r5, $0", "x"(i16 %0)
+  asm("add r5, %0" :: "x"(data));
+}
+
+void y() {
+  // CHECK: call void asm sideeffect "add r5, $0", "y"(i16 %0)
+  asm("add r5, %0" :: "y"(data));
+}
+
+void z() {
+  // CHECK: call void asm sideeffect "add r5, $0", "z"(i16 %0)
+  asm("add r5, %0" :: "z"(data));
+}
+
+void I() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "I"(i16 50)
+  asm("subi r30, %0" :: "I"(50));
+}
+
+void J() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "J"(i16 -50)
+  asm("subi r30, %0" :: "J"(-50));
+}
+
+void K() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "K"(i16 2)
+  asm("subi r30, %0" :: "K"(2));
+}
+
+void L() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "L"(i16 0)
+  asm("subi r30, %0" :: "L"(0));
+}
+
+void M() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "M"(i16 255)
+  asm("subi r30, %0" :: "M"(255));
+}
+
+void O() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "O"(i16 16)
+  asm("subi r30, %0" :: "O"(16));
+}
+
+void P() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "P"(i16 1)
+  asm("subi r30, %0" :: "P"(1));
+}
+
+void R() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "R"(i16 -3)
+  asm("subi r30, %0" :: "R"(-3));
+}
+
+void G() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "G"(i16 50)
+  asm("subi r30, %0" :: "G"(50));
+}
+
+void Q() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "Q"(i16 50)
+  asm("subi r30, %0" :: "Q"(50));
+}
+
+void ra() {
+  // CHECK: call void asm sideeffect "subi r30, $0", "ra"(i16 50)
+  asm("subi r30, %0" :: "ra"(50));
+}
+
+void ora() {
+  // CHECK: call i16 asm "subi r30, $0", "=ra"()
+  asm("subi r30, %0" : "=ra"(data));
+}
diff --git a/test/CodeGen/avr-unsupported-inline-asm-constraints.c b/test/CodeGen/avr-unsupported-inline-asm-constraints.c
new file mode 100644
index 0000000..5a87597
--- /dev/null
+++ b/test/CodeGen/avr-unsupported-inline-asm-constraints.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple avr-unknown-unknown -verify %s
+
+const unsigned char val = 0;
+
+int foo() {
+  __asm__ volatile("foo %0, 1" : : "fo" (val)); // expected-error {{invalid input constraint 'fo' in asm}}
+  __asm__ volatile("foo %0, 1" : : "Nd" (val)); // expected-error {{invalid input constraint 'Nd' in asm}}
+}
diff --git a/test/CodeGen/avr/attributes/interrupt.c b/test/CodeGen/avr/attributes/interrupt.c
new file mode 100644
index 0000000..31b7ebb
--- /dev/null
+++ b/test/CodeGen/avr/attributes/interrupt.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: define void @foo() #0
+__attribute__((interrupt)) void foo(void) { }
+
+// CHECK: attributes #0 = {{{.*interrupt.*}}}
diff --git a/test/CodeGen/avr/attributes/signal.c b/test/CodeGen/avr/attributes/signal.c
new file mode 100644
index 0000000..8285900
--- /dev/null
+++ b/test/CodeGen/avr/attributes/signal.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: define void @foo() #0
+__attribute__((signal)) void foo(void) { }
+
+// CHECK: attributes #0 = {{{.*signal.*}}}
diff --git a/test/CodeGen/avr/target-cpu-defines/atmega328p.c b/test/CodeGen/avr/target-cpu-defines/atmega328p.c
new file mode 100644
index 0000000..83b0acc
--- /dev/null
+++ b/test/CodeGen/avr/target-cpu-defines/atmega328p.c
@@ -0,0 +1,7 @@
+// REQUIRES: avr-registered-target
+// RUN: %clang_cc1 -E -dM -triple avr-unknown-unknown -target-cpu atmega328p /dev/null | FileCheck -match-full-lines %s
+
+// CHECK: #define AVR 1
+// CHECK: #define __AVR 1
+// CHECK: #define __AVR_ATmega328P__ 1
+// CHECK: #define __AVR__ 1
diff --git a/test/CodeGen/avr/target-cpu-defines/attiny104.c b/test/CodeGen/avr/target-cpu-defines/attiny104.c
new file mode 100644
index 0000000..7de65bf
--- /dev/null
+++ b/test/CodeGen/avr/target-cpu-defines/attiny104.c
@@ -0,0 +1,7 @@
+// REQUIRES: avr-registered-target
+// RUN: %clang_cc1 -E -dM -triple avr-unknown-unknown -target-cpu attiny104 /dev/null | FileCheck -match-full-lines %s
+
+// CHECK: #define AVR 1
+// CHECK: #define __AVR 1
+// CHECK: #define __AVR_ATtiny104__ 1
+// CHECK: #define __AVR__ 1
diff --git a/test/CodeGen/avr/target-cpu-defines/common.c b/test/CodeGen/avr/target-cpu-defines/common.c
new file mode 100644
index 0000000..0b11f5d
--- /dev/null
+++ b/test/CodeGen/avr/target-cpu-defines/common.c
@@ -0,0 +1,6 @@
+// REQUIRES: avr-registered-target
+// RUN: %clang_cc1 -E -dM -triple avr-unknown-unknown /dev/null | FileCheck -match-full-lines %s
+
+// CHECK: #define AVR 1
+// CHECK: #define __AVR 1
+// CHECK: #define __AVR__ 1
diff --git a/test/CodeGen/avx-builtins.c b/test/CodeGen/avx-builtins.c
index 6a9f7c0..4832664 100644
--- a/test/CodeGen/avx-builtins.c
+++ b/test/CodeGen/avx-builtins.c
@@ -346,19 +346,19 @@
 
 __m128d test_mm256_extractf128_pd(__m256d A) {
   // CHECK-LABEL: test_mm256_extractf128_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <2 x i32> <i32 2, i32 3>
   return _mm256_extractf128_pd(A, 1);
 }
 
 __m128 test_mm256_extractf128_ps(__m256 A) {
   // CHECK-LABEL: test_mm256_extractf128_ps
-  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   return _mm256_extractf128_ps(A, 1);
 }
 
 __m128i test_mm256_extractf128_si256(__m256i A) {
   // CHECK-LABEL: test_mm256_extractf128_si256
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <2 x i32> <i32 2, i32 3>
   return _mm256_extractf128_si256(A, 1);
 }
 
@@ -647,32 +647,32 @@
 
 __m128d test_mm_permute_pd(__m128d A) {
   // CHECK-LABEL: test_mm_permute_pd
-  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> <i32 1, i32 0>
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> zeroinitializer, <2 x i32> <i32 1, i32 0>
   return _mm_permute_pd(A, 1);
 }
 
 __m256d test_mm256_permute_pd(__m256d A) {
   // CHECK-LABEL: test_mm256_permute_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
   return _mm256_permute_pd(A, 5);
 }
 
 __m128 test_mm_permute_ps(__m128 A) {
   // CHECK-LABEL: test_mm_permute_ps
-  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
   return _mm_permute_ps(A, 0x1b);
 }
 
 // Test case for PR12401
 __m128 test2_mm_permute_ps(__m128 a) {
   // CHECK-LABEL: test2_mm_permute_ps
-  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> <i32 2, i32 1, i32 2, i32 3>
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <4 x i32> <i32 2, i32 1, i32 2, i32 3>
   return _mm_permute_ps(a, 0xe6);
 }
 
 __m256 test_mm256_permute_ps(__m256 A) {
   // CHECK-LABEL: test_mm256_permute_ps
-  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> undef, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> zeroinitializer, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
   return _mm256_permute_ps(A, 0x1b);
 }
 
@@ -1177,7 +1177,7 @@
   // CHECK-LABEL: test_mm256_storeu2_m128
   // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
   // CHECK: store <4 x float> %{{.*}}, <4 x float>* %{{.*}}, align 1{{$}}
-  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   // CHECK: store <4 x float> %{{.*}}, <4 x float>* %{{.*}}, align 1{{$}}
   _mm256_storeu2_m128(A, B, C);
 }
@@ -1186,7 +1186,7 @@
   // CHECK-LABEL: test_mm256_storeu2_m128d
   // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <2 x i32> <i32 0, i32 1>
   // CHECK: store <2 x double> %{{.*}}, <2 x double>* %{{.*}}, align 1{{$}}
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <2 x i32> <i32 2, i32 3>
   // CHECK: store <2 x double> %{{.*}}, <2 x double>* %{{.*}}, align 1{{$}}
   _mm256_storeu2_m128d(A, B, C);
 }
@@ -1195,7 +1195,7 @@
   // CHECK-LABEL: test_mm256_storeu2_m128i
   // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <2 x i32> <i32 0, i32 1>
   // CHECK: store <2 x i64> %{{.*}}, <2 x i64>* %{{.*}}, align 1{{$}}
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <2 x i32> <i32 2, i32 3>
   // CHECK: store <2 x i64> %{{.*}}, <2 x i64>* %{{.*}}, align 1{{$}}
   _mm256_storeu2_m128i(A, B, C);
 }
@@ -1322,19 +1322,19 @@
 
 __m256 test_mm256_undefined_ps() {
   // CHECK-LABEL: @test_mm256_undefined_ps
-  // CHECK: ret <8 x float> undef
+  // CHECK: ret <8 x float> zeroinitializer
   return _mm256_undefined_ps();
 }
 
 __m256d test_mm256_undefined_pd() {
   // CHECK-LABEL: @test_mm256_undefined_pd
-  // CHECK: ret <4 x double> undef
+  // CHECK: ret <4 x double> zeroinitializer
   return _mm256_undefined_pd();
 }
 
 __m256i test_mm256_undefined_si256() {
   // CHECK-LABEL: @test_mm256_undefined_si256
-  // CHECK: ret <4 x i64> undef
+  // CHECK: ret <4 x i64> zeroinitializer
   return _mm256_undefined_si256();
 }
 
diff --git a/test/CodeGen/avx-shuffle-builtins.c b/test/CodeGen/avx-shuffle-builtins.c
index 3d6c46d..b5bac89 100644
--- a/test/CodeGen/avx-shuffle-builtins.c
+++ b/test/CodeGen/avx-shuffle-builtins.c
@@ -67,9 +67,7 @@
 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
+  // CHECK: shufflevector <4 x float> {{.*}}, <4 x float> undef, <4 x i32> zeroinitializer
   return _mm_broadcast_ss(__a);
 }
 
@@ -77,9 +75,7 @@
 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
+  // CHECK: shufflevector <4 x double> {{.*}}, <4 x double> undef, <4 x i32> zeroinitializer
   return _mm256_broadcast_sd(__a);
 }
 
@@ -87,13 +83,7 @@
 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
+  // CHECK: shufflevector <8 x float> {{.*}}, <8 x float> undef, <8 x i32> zeroinitializer
   return _mm256_broadcast_ss(__a);
 }
 
diff --git a/test/CodeGen/avx2-builtins.c b/test/CodeGen/avx2-builtins.c
index 4ccf6e6..31b02ac 100644
--- a/test/CodeGen/avx2-builtins.c
+++ b/test/CodeGen/avx2-builtins.c
@@ -368,20 +368,20 @@
 
 __m128i test0_mm256_extracti128_si256_0(__m256i a) {
   // CHECK-LABEL: test0_mm256_extracti128_si256
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <2 x i32> <i32 0, i32 1>
   return _mm256_extracti128_si256(a, 0);
 }
 
 __m128i test1_mm256_extracti128_si256_1(__m256i a) {
   // CHECK-LABEL: test1_mm256_extracti128_si256
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <2 x i32> <i32 2, i32 3>
   return _mm256_extracti128_si256(a, 1);
 }
 
 // Immediate should be truncated to one bit.
 __m128i test2_mm256_extracti128_si256(__m256i a) {
   // CHECK-LABEL: test2_mm256_extracti128_si256
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <2 x i32> <i32 0, i32 1>
   return _mm256_extracti128_si256(a, 2);
 }
 
@@ -447,7 +447,7 @@
 
 __m128i test_mm_i32gather_epi64(long long const *b, __m128i c) {
   // CHECK-LABEL: test_mm_i32gather_epi64
-  // CHECK: call <2 x i64> @llvm.x86.avx2.gather.d.q(<2 x i64> undef, i8* %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}}, i8 2)
+  // CHECK: call <2 x i64> @llvm.x86.avx2.gather.d.q(<2 x i64> zeroinitializer, i8* %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}}, i8 2)
   return _mm_i32gather_epi64(b, c, 2);
 }
 
@@ -459,7 +459,7 @@
 
 __m256i test_mm256_i32gather_epi64(long long const *b, __m128i c) {
   // CHECK-LABEL: test_mm256_i32gather_epi64
-  // CHECK: call <4 x i64> @llvm.x86.avx2.gather.d.q.256(<4 x i64> undef, i8* %{{.*}}, <4 x i32> %{{.*}}, <4 x i64> %{{.*}}, i8 2)
+  // CHECK: call <4 x i64> @llvm.x86.avx2.gather.d.q.256(<4 x i64> zeroinitializer, i8* %{{.*}}, <4 x i32> %{{.*}}, <4 x i64> %{{.*}}, i8 2)
   return _mm256_i32gather_epi64(b, c, 2);
 }
 
@@ -474,7 +474,7 @@
   // CHECK:         [[CMP:%.*]] = fcmp oeq <2 x double>
   // CHECK-NEXT:    [[SEXT:%.*]] = sext <2 x i1> [[CMP]] to <2 x i64>
   // CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x i64> [[SEXT]] to <2 x double>
-  // CHECK: call <2 x double> @llvm.x86.avx2.gather.d.pd(<2 x double> undef, i8* %{{.*}}, <4 x i32> %{{.*}}, <2 x double> %{{.*}}, i8 2)
+  // CHECK: call <2 x double> @llvm.x86.avx2.gather.d.pd(<2 x double> zeroinitializer, i8* %{{.*}}, <4 x i32> %{{.*}}, <2 x double> %{{.*}}, i8 2)
   return _mm_i32gather_pd(b, c, 2);
 }
 
@@ -489,7 +489,7 @@
   // CHECK:         [[CMP:%.*]] = fcmp oeq <4 x double>
   // CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[CMP]] to <4 x i64>
   // CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x i64> [[SEXT]] to <4 x double>
-  // CHECK: call <4 x double> @llvm.x86.avx2.gather.d.pd.256(<4 x double> undef, i8* %{{.*}}, <4 x i32> %{{.*}}, <4 x double> %{{.*}}, i8 2)
+  // CHECK: call <4 x double> @llvm.x86.avx2.gather.d.pd.256(<4 x double> zeroinitializer, i8* %{{.*}}, <4 x i32> %{{.*}}, <4 x double> %{{.*}}, i8 2)
   return _mm256_i32gather_pd(b, c, 2);
 }
 
@@ -504,7 +504,7 @@
   // CHECK:         [[CMP:%.*]] = fcmp oeq <4 x float>
   // CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[CMP]] to <4 x i32>
   // CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x i32> [[SEXT]] to <4 x float>
-  // CHECK: call <4 x float> @llvm.x86.avx2.gather.d.ps(<4 x float> undef, i8* %{{.*}}, <4 x i32> %{{.*}}, <4 x float> %{{.*}}, i8 2)
+  // CHECK: call <4 x float> @llvm.x86.avx2.gather.d.ps(<4 x float> zeroinitializer, i8* %{{.*}}, <4 x i32> %{{.*}}, <4 x float> %{{.*}}, i8 2)
   return _mm_i32gather_ps(b, c, 2);
 }
 
@@ -519,7 +519,7 @@
   // CHECK:         [[CMP:%.*]] = fcmp oeq <8 x float>
   // CHECK-NEXT:    [[SEXT:%.*]] = sext <8 x i1> [[CMP]] to <8 x i32>
   // CHECK-NEXT:    [[BC:%.*]] = bitcast <8 x i32> [[SEXT]] to <8 x float>
-  // CHECK: call <8 x float> @llvm.x86.avx2.gather.d.ps.256(<8 x float> undef, i8* %{{.*}}, <8 x i32> %{{.*}}, <8 x float> %{{.*}}, i8 2)
+  // CHECK: call <8 x float> @llvm.x86.avx2.gather.d.ps.256(<8 x float> zeroinitializer, i8* %{{.*}}, <8 x i32> %{{.*}}, <8 x float> %{{.*}}, i8 2)
   return _mm256_i32gather_ps(b, c, 2);
 }
 
@@ -555,7 +555,7 @@
 
 __m128i test_mm_i64gather_epi64(long long const *b, __m128i c) {
   // CHECK-LABEL: test_mm_i64gather_epi64
-  // CHECK: call <2 x i64> @llvm.x86.avx2.gather.q.q(<2 x i64> undef, i8* %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 2)
+  // CHECK: call <2 x i64> @llvm.x86.avx2.gather.q.q(<2 x i64> zeroinitializer, i8* %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 2)
   return _mm_i64gather_epi64(b, c, 2);
 }
 
@@ -567,7 +567,7 @@
 
 __m256i test_mm256_i64gather_epi64(long long const *b, __m256i c) {
   // CHECK-LABEL: test_mm256_i64gather_epi64
-  // CHECK: call <4 x i64> @llvm.x86.avx2.gather.q.q.256(<4 x i64> undef, i8* %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, i8 2)
+  // CHECK: call <4 x i64> @llvm.x86.avx2.gather.q.q.256(<4 x i64> zeroinitializer, i8* %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, i8 2)
   return _mm256_i64gather_epi64(b, c, 2);
 }
 
@@ -582,7 +582,7 @@
   // CHECK:         [[CMP:%.*]] = fcmp oeq <2 x double>
   // CHECK-NEXT:    [[SEXT:%.*]] = sext <2 x i1> [[CMP]] to <2 x i64>
   // CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x i64> [[SEXT]] to <2 x double>
-  // CHECK: call <2 x double> @llvm.x86.avx2.gather.q.pd(<2 x double> undef, i8* %{{.*}}, <2 x i64> %{{.*}}, <2 x double> %{{.*}}, i8 2)
+  // CHECK: call <2 x double> @llvm.x86.avx2.gather.q.pd(<2 x double> zeroinitializer, i8* %{{.*}}, <2 x i64> %{{.*}}, <2 x double> %{{.*}}, i8 2)
   return _mm_i64gather_pd(b, c, 2);
 }
 
@@ -597,7 +597,7 @@
   // CHECK:         [[CMP:%.*]] = fcmp oeq <4 x double>
   // CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[CMP]] to <4 x i64>
   // CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x i64> [[SEXT]] to <4 x double>
-  // CHECK: call <4 x double> @llvm.x86.avx2.gather.q.pd.256(<4 x double> undef, i8* %{{.*}}, <4 x i64> %{{.*}}, <4 x double> %{{.*}}, i8 2)
+  // CHECK: call <4 x double> @llvm.x86.avx2.gather.q.pd.256(<4 x double> zeroinitializer, i8* %{{.*}}, <4 x i64> %{{.*}}, <4 x double> %{{.*}}, i8 2)
   return _mm256_i64gather_pd(b, c, 2);
 }
 
@@ -612,7 +612,7 @@
   // CHECK:         [[CMP:%.*]] = fcmp oeq <4 x float>
   // CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[CMP]] to <4 x i32>
   // CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x i32> [[SEXT]] to <4 x float>
-  // CHECK: call <4 x float> @llvm.x86.avx2.gather.q.ps(<4 x float> undef, i8* %{{.*}}, <2 x i64> %{{.*}}, <4 x float> %{{.*}}, i8 2)
+  // CHECK: call <4 x float> @llvm.x86.avx2.gather.q.ps(<4 x float> zeroinitializer, i8* %{{.*}}, <2 x i64> %{{.*}}, <4 x float> %{{.*}}, i8 2)
   return _mm_i64gather_ps(b, c, 2);
 }
 
@@ -627,7 +627,7 @@
   // CHECK:         [[CMP:%.*]] = fcmp oeq <4 x float>
   // CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[CMP]] to <4 x i32>
   // CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x i32> [[SEXT]] to <4 x float>
-  // CHECK: call <4 x float> @llvm.x86.avx2.gather.q.ps.256(<4 x float> undef, i8* %{{.*}}, <4 x i64> %{{.*}}, <4 x float> %{{.*}}, i8 2)
+  // CHECK: call <4 x float> @llvm.x86.avx2.gather.q.ps.256(<4 x float> zeroinitializer, i8* %{{.*}}, <4 x i64> %{{.*}}, <4 x float> %{{.*}}, i8 2)
   return _mm256_i64gather_ps(b, c, 2);
 }
 
@@ -895,13 +895,13 @@
 
 __m256i test_mm256_permute4x64_epi64(__m256i a) {
   // CHECK-LABEL: test_mm256_permute4x64_epi64
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <4 x i32> <i32 3, i32 0, i32 2, i32 0>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 2, i32 0>
   return _mm256_permute4x64_epi64(a, 35);
 }
 
 __m256d test_mm256_permute4x64_pd(__m256d a) {
   // CHECK-LABEL: test_mm256_permute4x64_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <4 x i32> <i32 1, i32 2, i32 1, i32 0>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 1, i32 0>
   return _mm256_permute4x64_pd(a, 25);
 }
 
diff --git a/test/CodeGen/avx512-reduceMinMaxIntrin.c b/test/CodeGen/avx512-reduceMinMaxIntrin.c
index 8249b22..993e296 100644
--- a/test/CodeGen/avx512-reduceMinMaxIntrin.c
+++ b/test/CodeGen/avx512-reduceMinMaxIntrin.c
@@ -1,3 +1,5 @@
+// FIXME: We should not be testing with -O2 (ie, a dependency on the entire IR optimizer).
+
 // RUN: %clang_cc1 -ffreestanding %s -O2 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -emit-llvm -o - -Wall -Werror |opt -instnamer -S |FileCheck %s
 
 #include <immintrin.h>
@@ -202,7 +204,7 @@
 int test_mm512_reduce_max_epi32(__m512i __W){
   // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
   // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  // CHECK: %tmp1 = icmp sgt <16 x i32> %tmp, %shuffle1.i
+  // CHECK: %tmp1 = icmp slt <16 x i32> %shuffle1.i, %tmp
   // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> %shuffle1.i
   // CHECK: %shuffle3.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
   // CHECK: %tmp3 = icmp sgt <16 x i32> %tmp2, %shuffle3.i
@@ -223,7 +225,7 @@
 unsigned int test_mm512_reduce_max_epu32(__m512i __W){
   // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
   // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  // CHECK: %tmp1 = icmp ugt <16 x i32> %tmp, %shuffle1.i
+  // CHECK: %tmp1 = icmp ult <16 x i32> %shuffle1.i, %tmp
   // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> %shuffle1.i
   // CHECK: %shuffle3.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
   // CHECK: %tmp3 = icmp ugt <16 x i32> %tmp2, %shuffle3.i
@@ -258,7 +260,7 @@
 int test_mm512_reduce_min_epi32(__m512i __W){
   // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
   // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  // CHECK: %tmp1 = icmp slt <16 x i32> %tmp, %shuffle1.i
+  // CHECK: %tmp1 = icmp sgt <16 x i32> %shuffle1.i, %tmp
   // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> %shuffle1.i
   // CHECK: %shuffle3.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
   // CHECK: %tmp3 = icmp slt <16 x i32> %tmp2, %shuffle3.i
@@ -279,7 +281,7 @@
 unsigned int test_mm512_reduce_min_epu32(__m512i __W){
   // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
   // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  // CHECK: %tmp1 = icmp ult <16 x i32> %tmp, %shuffle1.i
+  // CHECK: %tmp1 = icmp ugt <16 x i32> %shuffle1.i, %tmp
   // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> %shuffle1.i
   // CHECK: %shuffle3.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
   // CHECK: %tmp3 = icmp ult <16 x i32> %tmp2, %shuffle3.i
diff --git a/test/CodeGen/avx512bw-builtins.c b/test/CodeGen/avx512bw-builtins.c
index ed1957b..4d45f29 100644
--- a/test/CodeGen/avx512bw-builtins.c
+++ b/test/CodeGen/avx512bw-builtins.c
@@ -510,62 +510,70 @@
 }
 __m512i test_mm512_packs_epi32(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_packs_epi32
-  // CHECK: @llvm.x86.avx512.mask.packssdw.512
+  // CHECK: @llvm.x86.avx512.packssdw.512
   return _mm512_packs_epi32(__A,__B); 
 }
 __m512i test_mm512_maskz_packs_epi32(__mmask32 __M, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_packs_epi32
-  // CHECK: @llvm.x86.avx512.mask.packssdw.512
+  // CHECK: @llvm.x86.avx512.packssdw.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_packs_epi32(__M,__A,__B); 
 }
 __m512i test_mm512_mask_packs_epi32(__m512i __W, __mmask32 __M, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_packs_epi32
-  // CHECK: @llvm.x86.avx512.mask.packssdw.512
+  // CHECK: @llvm.x86.avx512.packssdw.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_packs_epi32(__W,__M,__A,__B); 
 }
 __m512i test_mm512_packs_epi16(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_packs_epi16
-  // CHECK: @llvm.x86.avx512.mask.packsswb.512
+  // CHECK: @llvm.x86.avx512.packsswb.512
   return _mm512_packs_epi16(__A,__B); 
 }
 __m512i test_mm512_mask_packs_epi16(__m512i __W, __mmask64 __M, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_packs_epi16
-  // CHECK: @llvm.x86.avx512.mask.packsswb.512
+  // CHECK: @llvm.x86.avx512.packsswb.512
+  // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
   return _mm512_mask_packs_epi16(__W,__M,__A,__B); 
 }
 __m512i test_mm512_maskz_packs_epi16(__mmask64 __M, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_packs_epi16
-  // CHECK: @llvm.x86.avx512.mask.packsswb.512
+  // CHECK: @llvm.x86.avx512.packsswb.512
+  // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
   return _mm512_maskz_packs_epi16(__M,__A,__B); 
 }
 __m512i test_mm512_packus_epi32(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_packus_epi32
-  // CHECK: @llvm.x86.avx512.mask.packusdw.512
+  // CHECK: @llvm.x86.avx512.packusdw.512
   return _mm512_packus_epi32(__A,__B); 
 }
 __m512i test_mm512_maskz_packus_epi32(__mmask32 __M, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_packus_epi32
-  // CHECK: @llvm.x86.avx512.mask.packusdw.512
+  // CHECK: @llvm.x86.avx512.packusdw.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_packus_epi32(__M,__A,__B); 
 }
 __m512i test_mm512_mask_packus_epi32(__m512i __W, __mmask32 __M, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_packus_epi32
-  // CHECK: @llvm.x86.avx512.mask.packusdw.512
+  // CHECK: @llvm.x86.avx512.packusdw.512
+  // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_packus_epi32(__W,__M,__A,__B); 
 }
 __m512i test_mm512_packus_epi16(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_packus_epi16
-  // CHECK: @llvm.x86.avx512.mask.packuswb.512
+  // CHECK: @llvm.x86.avx512.packuswb.512
   return _mm512_packus_epi16(__A,__B); 
 }
 __m512i test_mm512_mask_packus_epi16(__m512i __W, __mmask64 __M, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_packus_epi16
-  // CHECK: @llvm.x86.avx512.mask.packuswb.512
+  // CHECK: @llvm.x86.avx512.packuswb.512
+  // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
   return _mm512_mask_packus_epi16(__W,__M,__A,__B); 
 }
 __m512i test_mm512_maskz_packus_epi16(__mmask64 __M, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_packus_epi16
-  // CHECK: @llvm.x86.avx512.mask.packuswb.512
+  // CHECK: @llvm.x86.avx512.packuswb.512
+  // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
   return _mm512_maskz_packus_epi16(__M,__A,__B); 
 }
 __m512i test_mm512_adds_epi8(__m512i __A, __m512i __B) {
@@ -820,17 +828,19 @@
 }
 __m512i test_mm512_shuffle_epi8(__m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_shuffle_epi8
-  // CHECK: @llvm.x86.avx512.mask.pshuf.b.512
+  // CHECK: @llvm.x86.avx512.pshuf.b.512
   return _mm512_shuffle_epi8(__A,__B); 
 }
 __m512i test_mm512_mask_shuffle_epi8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_mask_shuffle_epi8
-  // CHECK: @llvm.x86.avx512.mask.pshuf.b.512
+  // CHECK: @llvm.x86.avx512.pshuf.b.512
+  // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
   return _mm512_mask_shuffle_epi8(__W,__U,__A,__B); 
 }
 __m512i test_mm512_maskz_shuffle_epi8(__mmask64 __U, __m512i __A, __m512i __B) {
   // CHECK-LABEL: @test_mm512_maskz_shuffle_epi8
-  // CHECK: @llvm.x86.avx512.mask.pshuf.b.512
+  // CHECK: @llvm.x86.avx512.pshuf.b.512
+  // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
   return _mm512_maskz_shuffle_epi8(__U,__A,__B); 
 }
 __m512i test_mm512_subs_epi8(__m512i __A, __m512i __B) {
@@ -1545,40 +1555,40 @@
 
 __m512i test_mm512_broadcastb_epi8(__m128i __A) {
   // CHECK-LABEL: @test_mm512_broadcastb_epi8
-  // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <64 x i32> zeroinitializer
+  // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> zeroinitializer, <64 x i32> zeroinitializer
   return _mm512_broadcastb_epi8(__A);
 }
 
 __m512i test_mm512_mask_broadcastb_epi8(__m512i __O, __mmask64 __M, __m128i __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcastb_epi8
-  // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <64 x i32> zeroinitializer
+  // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> zeroinitializer, <64 x i32> zeroinitializer
   // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
   return _mm512_mask_broadcastb_epi8(__O, __M, __A);
 }
 
 __m512i test_mm512_maskz_broadcastb_epi8(__mmask64 __M, __m128i __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcastb_epi8
-  // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <64 x i32> zeroinitializer
+  // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> zeroinitializer, <64 x i32> zeroinitializer
   // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
   return _mm512_maskz_broadcastb_epi8(__M, __A);
 }
 
 __m512i test_mm512_broadcastw_epi16(__m128i __A) {
   // CHECK-LABEL: @test_mm512_broadcastw_epi16
-  // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <32 x i32> zeroinitializer
+  // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> zeroinitializer, <32 x i32> zeroinitializer
   return _mm512_broadcastw_epi16(__A);
 }
 
 __m512i test_mm512_mask_broadcastw_epi16(__m512i __O, __mmask32 __M, __m128i __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcastw_epi16
-  // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <32 x i32> zeroinitializer
+  // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> zeroinitializer, <32 x i32> zeroinitializer
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_mask_broadcastw_epi16(__O, __M, __A);
 }
 
 __m512i test_mm512_maskz_broadcastw_epi16(__mmask32 __M, __m128i __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcastw_epi16
-  // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <32 x i32> zeroinitializer
+  // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> zeroinitializer, <32 x i32> zeroinitializer
   // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
   return _mm512_maskz_broadcastw_epi16(__M, __A);
 }
diff --git a/test/CodeGen/avx512dq-builtins.c b/test/CodeGen/avx512dq-builtins.c
index f57433a..b4166ad 100644
--- a/test/CodeGen/avx512dq-builtins.c
+++ b/test/CodeGen/avx512dq-builtins.c
@@ -963,40 +963,44 @@
   return _mm512_maskz_broadcast_f32x2(__M, __A); 
 }
 
-__m512 test_mm512_broadcast_f32x8(__m256 __A) {
+__m512 test_mm512_broadcast_f32x8(float const* __A) {
   // CHECK-LABEL: @test_mm512_broadcast_f32x8
-  // CHECK: @llvm.x86.avx512.mask.broadcastf32x8
-  return _mm512_broadcast_f32x8(__A); 
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+  return _mm512_broadcast_f32x8(_mm256_loadu_ps(__A)); 
 }
 
-__m512 test_mm512_mask_broadcast_f32x8(__m512 __O, __mmask16 __M, __m256 __A) {
+__m512 test_mm512_mask_broadcast_f32x8(__m512 __O, __mmask16 __M, float const* __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcast_f32x8
-  // CHECK: @llvm.x86.avx512.mask.broadcastf32x8
-  return _mm512_mask_broadcast_f32x8(__O, __M, __A); 
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+  // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+  return _mm512_mask_broadcast_f32x8(__O, __M, _mm256_loadu_ps(__A)); 
 }
 
-__m512 test_mm512_maskz_broadcast_f32x8(__mmask16 __M, __m256 __A) {
+__m512 test_mm512_maskz_broadcast_f32x8(__mmask16 __M, float const* __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcast_f32x8
-  // CHECK: @llvm.x86.avx512.mask.broadcastf32x8
-  return _mm512_maskz_broadcast_f32x8(__M, __A); 
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+  // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+  return _mm512_maskz_broadcast_f32x8(__M, _mm256_loadu_ps(__A)); 
 }
 
-__m512d test_mm512_broadcast_f64x2(__m128d __A) {
+__m512d test_mm512_broadcast_f64x2(double const* __A) {
   // CHECK-LABEL: @test_mm512_broadcast_f64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcastf64x2
-  return _mm512_broadcast_f64x2(__A); 
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+  return _mm512_broadcast_f64x2(_mm_loadu_pd(__A)); 
 }
 
-__m512d test_mm512_mask_broadcast_f64x2(__m512d __O, __mmask8 __M, __m128d __A) {
+__m512d test_mm512_mask_broadcast_f64x2(__m512d __O, __mmask8 __M, double const* __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcast_f64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcastf64x2
-  return _mm512_mask_broadcast_f64x2(__O, __M, __A); 
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
+  return _mm512_mask_broadcast_f64x2(__O, __M, _mm_loadu_pd(__A)); 
 }
 
-__m512d test_mm512_maskz_broadcast_f64x2(__mmask8 __M, __m128d __A) {
+__m512d test_mm512_maskz_broadcast_f64x2(__mmask8 __M, double const* __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcast_f64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcastf64x2
-  return _mm512_maskz_broadcast_f64x2(__M, __A); 
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
+  return _mm512_maskz_broadcast_f64x2(__M, _mm_loadu_pd(__A)); 
 }
 
 __m512i test_mm512_broadcast_i32x2(__m128i __A) {
@@ -1017,77 +1021,82 @@
   return _mm512_maskz_broadcast_i32x2(__M, __A); 
 }
 
-__m512i test_mm512_broadcast_i32x8(__m256i __A) {
+__m512i test_mm512_broadcast_i32x8(__m256i const* __A) {
   // CHECK-LABEL: @test_mm512_broadcast_i32x8
-  // CHECK: @llvm.x86.avx512.mask.broadcasti32x8
-  return _mm512_broadcast_i32x8(__A); 
+  // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+  return _mm512_broadcast_i32x8(_mm256_loadu_si256(__A)); 
 }
 
-__m512i test_mm512_mask_broadcast_i32x8(__m512i __O, __mmask16 __M, __m256i __A) {
+__m512i test_mm512_mask_broadcast_i32x8(__m512i __O, __mmask16 __M, __m256i const* __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcast_i32x8
-  // CHECK: @llvm.x86.avx512.mask.broadcasti32x8
-  return _mm512_mask_broadcast_i32x8(__O, __M, __A); 
+  // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_mask_broadcast_i32x8(__O, __M, _mm256_loadu_si256(__A)); 
 }
 
-__m512i test_mm512_maskz_broadcast_i32x8(__mmask16 __M, __m256i __A) {
+__m512i test_mm512_maskz_broadcast_i32x8(__mmask16 __M, __m256i const* __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcast_i32x8
-  // CHECK: @llvm.x86.avx512.mask.broadcasti32x8
-  return _mm512_maskz_broadcast_i32x8(__M, __A); 
+  // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_maskz_broadcast_i32x8(__M, _mm256_loadu_si256(__A)); 
 }
 
-__m512i test_mm512_broadcast_i64x2(__m128i __A) {
+__m512i test_mm512_broadcast_i64x2(__m128i const* __A) {
   // CHECK-LABEL: @test_mm512_broadcast_i64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcasti64x2
-  return _mm512_broadcast_i64x2(__A); 
+  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+  return _mm512_broadcast_i64x2(_mm_loadu_si128(__A)); 
 }
 
-__m512i test_mm512_mask_broadcast_i64x2(__m512i __O, __mmask8 __M, __m128i __A) {
+__m512i test_mm512_mask_broadcast_i64x2(__m512i __O, __mmask8 __M, __m128i const* __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcast_i64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcasti64x2
-  return _mm512_mask_broadcast_i64x2(__O, __M, __A); 
+  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_mask_broadcast_i64x2(__O, __M, _mm_loadu_si128(__A)); 
 }
 
-__m512i test_mm512_maskz_broadcast_i64x2(__mmask8 __M, __m128i __A) {
+__m512i test_mm512_maskz_broadcast_i64x2(__mmask8 __M, __m128i const* __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcast_i64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcasti64x2
-  return _mm512_maskz_broadcast_i64x2(__M, __A); 
+  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_maskz_broadcast_i64x2(__M, _mm_loadu_si128(__A)); 
 }
+
 __m256 test_mm512_extractf32x8_ps(__m512 __A) {
   // CHECK-LABEL: @test_mm512_extractf32x8_ps
-  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
   return _mm512_extractf32x8_ps(__A, 1); 
 }
 
 __m256 test_mm512_mask_extractf32x8_ps(__m256 __W, __mmask8 __U, __m512 __A) {
   // CHECK-LABEL: @test_mm512_mask_extractf32x8_ps
-  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
   // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
   return _mm512_mask_extractf32x8_ps(__W, __U, __A, 1); 
 }
 
 __m256 test_mm512_maskz_extractf32x8_ps(__mmask8 __U, __m512 __A) {
   // CHECK-LABEL: @test_mm512_maskz_extractf32x8_ps
-  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
   // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
   return _mm512_maskz_extractf32x8_ps(__U, __A, 1); 
 }
 
 __m128d test_mm512_extractf64x2_pd(__m512d __A) {
   // CHECK-LABEL: @test_mm512_extractf64x2_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <2 x i32> <i32 6, i32 7>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <2 x i32> <i32 6, i32 7>
   return _mm512_extractf64x2_pd(__A, 3); 
 }
 
 __m128d test_mm512_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m512d __A) {
   // CHECK-LABEL: @test_mm512_mask_extractf64x2_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <2 x i32> <i32 6, i32 7>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <2 x i32> <i32 6, i32 7>
   // CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
   return _mm512_mask_extractf64x2_pd(__W, __U, __A, 3); 
 }
 
 __m128d test_mm512_maskz_extractf64x2_pd(__mmask8 __U, __m512d __A) {
   // CHECK-LABEL: @test_mm512_maskz_extractf64x2_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <2 x i32> <i32 6, i32 7>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <2 x i32> <i32 6, i32 7>
   // CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
   return _mm512_maskz_extractf64x2_pd(__U, __A, 3); 
 }
@@ -1114,20 +1123,20 @@
 
 __m128i test_mm512_extracti64x2_epi64(__m512i __A) {
   // CHECK-LABEL: @test_mm512_extracti64x2_epi64
-  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <2 x i32> <i32 6, i32 7>
+  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <2 x i32> <i32 6, i32 7>
   return _mm512_extracti64x2_epi64(__A, 3); 
 }
 
 __m128i test_mm512_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_extracti64x2_epi64
-  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <2 x i32> <i32 6, i32 7>
+  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <2 x i32> <i32 6, i32 7>
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm512_mask_extracti64x2_epi64(__W, __U, __A, 3); 
 }
 
 __m128i test_mm512_maskz_extracti64x2_epi64(__mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_extracti64x2_epi64
-  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <2 x i32> <i32 6, i32 7>
+  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <2 x i32> <i32 6, i32 7>
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm512_maskz_extracti64x2_epi64(__U, __A, 3); 
 }
diff --git a/test/CodeGen/avx512f-builtins.c b/test/CodeGen/avx512f-builtins.c
index b5a69dd..67e2d43 100644
--- a/test/CodeGen/avx512f-builtins.c
+++ b/test/CodeGen/avx512f-builtins.c
@@ -1241,20 +1241,20 @@
 __m256d test_mm512_extractf64x4_pd(__m512d a)
 {
   // CHECK-LABEL: @test_mm512_extractf64x4_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   return _mm512_extractf64x4_pd(a, 1);
 }
 
 __m256d test_mm512_mask_extractf64x4_pd(__m256d  __W,__mmask8  __U,__m512d __A){
   // CHECK-LABEL:@test_mm512_mask_extractf64x4_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
   return _mm512_mask_extractf64x4_pd( __W, __U, __A, 1);
 }
 
 __m256d test_mm512_maskz_extractf64x4_pd(__mmask8  __U,__m512d __A){
   // CHECK-LABEL:@test_mm512_maskz_extractf64x4_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
   return _mm512_maskz_extractf64x4_pd( __U, __A, 1);
 }
@@ -1262,20 +1262,20 @@
 __m128 test_mm512_extractf32x4_ps(__m512 a)
 {
   // CHECK-LABEL: @test_mm512_extractf32x4_ps
-  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   return _mm512_extractf32x4_ps(a, 1);
 }
 
 __m128 test_mm512_mask_extractf32x4_ps(__m128 __W, __mmask8  __U,__m512d __A){
   // CHECK-LABEL:@test_mm512_mask_extractf32x4_ps
-  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
   return _mm512_mask_extractf32x4_ps( __W, __U, __A, 1);
 }
 
 __m128 test_mm512_maskz_extractf32x4_ps( __mmask8  __U,__m512d __A){
   // CHECK-LABEL:@test_mm512_maskz_extractf32x4_ps
-  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
  return _mm512_maskz_extractf32x4_ps(  __U, __A, 1);
 }
@@ -1867,29 +1867,45 @@
   return _mm512_add_epi64(__A,__B);
 }
 
+__m512i test_mm512_mul_epi32(__m512i __A, __m512i __B) {
+  //CHECK-LABEL: @test_mm512_mul_epi32
+  //CHECK: @llvm.x86.avx512.pmul.dq.512
+  return _mm512_mul_epi32(__A,__B);
+}
+
 __m512i test_mm512_maskz_mul_epi32 (__mmask16 __k,__m512i __A, __m512i __B) {
   //CHECK-LABEL: @test_mm512_maskz_mul_epi32
-  //CHECK: @llvm.x86.avx512.mask.pmul.dq.512
+  //CHECK: @llvm.x86.avx512.pmul.dq.512
+  //CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_mul_epi32(__k,__A,__B);
 }
 
 __m512i test_mm512_mask_mul_epi32 (__mmask16 __k,__m512i __A, __m512i __B,
                                    __m512i __src) {
   //CHECK-LABEL: @test_mm512_mask_mul_epi32
-  //CHECK: @llvm.x86.avx512.mask.pmul.dq.512
+  //CHECK: @llvm.x86.avx512.pmul.dq.512
+  //CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_mul_epi32(__src,__k,__A,__B);
 }
 
+__m512i test_mm512_mul_epu32 (__m512i __A, __m512i __B) {
+  //CHECK-LABEL: @test_mm512_mul_epu32
+  //CHECK: @llvm.x86.avx512.pmulu.dq.512
+  return _mm512_mul_epu32(__A,__B);
+}
+
 __m512i test_mm512_maskz_mul_epu32 (__mmask16 __k,__m512i __A, __m512i __B) {
   //CHECK-LABEL: @test_mm512_maskz_mul_epu32
-  //CHECK: @llvm.x86.avx512.mask.pmulu.dq.512
+  //CHECK: @llvm.x86.avx512.pmulu.dq.512
+  //CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_mul_epu32(__k,__A,__B);
 }
 
 __m512i test_mm512_mask_mul_epu32 (__mmask16 __k,__m512i __A, __m512i __B, 
                                    __m512i __src) {
   //CHECK-LABEL: @test_mm512_mask_mul_epu32
-  //CHECK: @llvm.x86.avx512.mask.pmulu.dq.512
+  //CHECK: @llvm.x86.avx512.pmulu.dq.512
+  //CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_mul_epu32(__src,__k,__A,__B);
 }
 
@@ -2442,25 +2458,25 @@
 
 __m512 test_mm512_undefined() {
   // CHECK-LABEL: @test_mm512_undefined
-  // CHECK: ret <16 x float> undef
+  // CHECK: ret <16 x float> zeroinitializer
   return _mm512_undefined();
 }
 
 __m512 test_mm512_undefined_ps() {
   // CHECK-LABEL: @test_mm512_undefined_ps
-  // CHECK: ret <16 x float> undef
+  // CHECK: ret <16 x float> zeroinitializer
   return _mm512_undefined_ps();
 }
 
 __m512d test_mm512_undefined_pd() {
   // CHECK-LABEL: @test_mm512_undefined_pd
-  // CHECK: ret <8 x double> undef
+  // CHECK: ret <8 x double> zeroinitializer
   return _mm512_undefined_pd();
 }
 
 __m512i test_mm512_undefined_epi32() {
   // CHECK-LABEL: @test_mm512_undefined_epi32
-  // CHECK: ret <8 x i64> undef
+  // CHECK: ret <8 x i64> zeroinitializer
   return _mm512_undefined_epi32();
 }
 
@@ -3698,77 +3714,81 @@
 
 __m512d test_mm512_permute_pd(__m512d __X) {
   // CHECK-LABEL: @test_mm512_permute_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 2, i32 4, i32 4, i32 6, i32 6>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 2, i32 4, i32 4, i32 6, i32 6>
   return _mm512_permute_pd(__X, 2);
 }
 
 __m512d test_mm512_mask_permute_pd(__m512d __W, __mmask8 __U, __m512d __X) {
   // CHECK-LABEL: @test_mm512_mask_permute_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 2, i32 4, i32 4, i32 6, i32 6>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 2, i32 4, i32 4, i32 6, i32 6>
   // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
   return _mm512_mask_permute_pd(__W, __U, __X, 2);
 }
 
 __m512d test_mm512_maskz_permute_pd(__mmask8 __U, __m512d __X) {
   // CHECK-LABEL: @test_mm512_maskz_permute_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 2, i32 4, i32 4, i32 6, i32 6>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 2, i32 4, i32 4, i32 6, i32 6>
   // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
   return _mm512_maskz_permute_pd(__U, __X, 2);
 }
 
 __m512 test_mm512_permute_ps(__m512 __X) {
   // CHECK-LABEL: @test_mm512_permute_ps
-  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> undef, <16 x i32> <i32 2, i32 0, i32 0, i32 0, i32 6, i32 4, i32 4, i32 4, i32 10, i32 8, i32 8, i32 8, i32 14, i32 12, i32 12, i32 12>
+  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, <16 x i32> <i32 2, i32 0, i32 0, i32 0, i32 6, i32 4, i32 4, i32 4, i32 10, i32 8, i32 8, i32 8, i32 14, i32 12, i32 12, i32 12>
   return _mm512_permute_ps(__X, 2);
 }
 
 __m512 test_mm512_mask_permute_ps(__m512 __W, __mmask16 __U, __m512 __X) {
   // CHECK-LABEL: @test_mm512_mask_permute_ps
-  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> undef, <16 x i32> <i32 2, i32 0, i32 0, i32 0, i32 6, i32 4, i32 4, i32 4, i32 10, i32 8, i32 8, i32 8, i32 14, i32 12, i32 12, i32 12>
+  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, <16 x i32> <i32 2, i32 0, i32 0, i32 0, i32 6, i32 4, i32 4, i32 4, i32 10, i32 8, i32 8, i32 8, i32 14, i32 12, i32 12, i32 12>
   // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
   return _mm512_mask_permute_ps(__W, __U, __X, 2);
 }
 
 __m512 test_mm512_maskz_permute_ps(__mmask16 __U, __m512 __X) {
   // CHECK-LABEL: @test_mm512_maskz_permute_ps
-  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> undef, <16 x i32> <i32 2, i32 0, i32 0, i32 0, i32 6, i32 4, i32 4, i32 4, i32 10, i32 8, i32 8, i32 8, i32 14, i32 12, i32 12, i32 12>
+  // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, <16 x i32> <i32 2, i32 0, i32 0, i32 0, i32 6, i32 4, i32 4, i32 4, i32 10, i32 8, i32 8, i32 8, i32 14, i32 12, i32 12, i32 12>
   // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
   return _mm512_maskz_permute_ps(__U, __X, 2);
 }
 
 __m512d test_mm512_permutevar_pd(__m512d __A, __m512i __C) {
   // CHECK-LABEL: @test_mm512_permutevar_pd
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.pd.512
+  // CHECK: @llvm.x86.avx512.vpermilvar.pd.512
   return _mm512_permutevar_pd(__A, __C); 
 }
 
 __m512d test_mm512_mask_permutevar_pd(__m512d __W, __mmask8 __U, __m512d __A, __m512i __C) {
   // CHECK-LABEL: @test_mm512_mask_permutevar_pd
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.pd.512
+  // CHECK: @llvm.x86.avx512.vpermilvar.pd.512
+  // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
   return _mm512_mask_permutevar_pd(__W, __U, __A, __C); 
 }
 
 __m512d test_mm512_maskz_permutevar_pd(__mmask8 __U, __m512d __A, __m512i __C) {
   // CHECK-LABEL: @test_mm512_maskz_permutevar_pd
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.pd.512
+  // CHECK: @llvm.x86.avx512.vpermilvar.pd.512
+  // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
   return _mm512_maskz_permutevar_pd(__U, __A, __C); 
 }
 
 __m512 test_mm512_permutevar_ps(__m512 __A, __m512i __C) {
   // CHECK-LABEL: @test_mm512_permutevar_ps
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.ps.512
+  // CHECK: @llvm.x86.avx512.vpermilvar.ps.512
   return _mm512_permutevar_ps(__A, __C); 
 }
 
 __m512 test_mm512_mask_permutevar_ps(__m512 __W, __mmask16 __U, __m512 __A, __m512i __C) {
   // CHECK-LABEL: @test_mm512_mask_permutevar_ps
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.ps.512
+  // CHECK: @llvm.x86.avx512.vpermilvar.ps.512
+  // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
   return _mm512_mask_permutevar_ps(__W, __U, __A, __C); 
 }
 
 __m512 test_mm512_maskz_permutevar_ps(__mmask16 __U, __m512 __A, __m512i __C) {
   // CHECK-LABEL: @test_mm512_maskz_permutevar_ps
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.ps.512
+  // CHECK: @llvm.x86.avx512.vpermilvar.ps.512
+  // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
   return _mm512_maskz_permutevar_ps(__U, __A, __C); 
 }
 
@@ -4627,154 +4647,162 @@
     return _mm_maskz_sqrt_round_ss(__U,__A,__B,_MM_FROUND_CUR_DIRECTION);
 }
 
-__m512 test_mm512_broadcast_f32x4(__m128 __A) {
+__m512 test_mm512_broadcast_f32x4(float const* __A) {
   // CHECK-LABEL: @test_mm512_broadcast_f32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcastf32x4
-  return _mm512_broadcast_f32x4(__A); 
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  return _mm512_broadcast_f32x4(_mm_loadu_ps(__A)); 
 }
 
-__m512 test_mm512_mask_broadcast_f32x4(__m512 __O, __mmask16 __M, __m128 __A) {
+__m512 test_mm512_mask_broadcast_f32x4(__m512 __O, __mmask16 __M, float const* __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcast_f32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcastf32x4
-  return _mm512_mask_broadcast_f32x4(__O, __M, __A); 
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+  return _mm512_mask_broadcast_f32x4(__O, __M, _mm_loadu_ps(__A)); 
 }
 
-__m512 test_mm512_maskz_broadcast_f32x4(__mmask16 __M, __m128 __A) {
+__m512 test_mm512_maskz_broadcast_f32x4(__mmask16 __M, float const* __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcast_f32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcastf32x4
-  return _mm512_maskz_broadcast_f32x4(__M, __A); 
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+  return _mm512_maskz_broadcast_f32x4(__M, _mm_loadu_ps(__A)); 
 }
 
-__m512d test_mm512_broadcast_f64x4(__m256d __A) {
+__m512d test_mm512_broadcast_f64x4(float const* __A) {
   // CHECK-LABEL: @test_mm512_broadcast_f64x4
-  // CHECK: @llvm.x86.avx512.mask.broadcastf64x4
-  return _mm512_broadcast_f64x4(__A); 
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  return _mm512_broadcast_f64x4(_mm256_loadu_ps(__A)); 
 }
 
-__m512d test_mm512_mask_broadcast_f64x4(__m512d __O, __mmask8 __M, __m256d __A) {
+__m512d test_mm512_mask_broadcast_f64x4(__m512d __O, __mmask8 __M, float const* __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcast_f64x4
-  // CHECK: @llvm.x86.avx512.mask.broadcastf64x4
-  return _mm512_mask_broadcast_f64x4(__O, __M, __A); 
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
+  return _mm512_mask_broadcast_f64x4(__O, __M, _mm256_loadu_ps(__A)); 
 }
 
-__m512d test_mm512_maskz_broadcast_f64x4(__mmask8 __M, __m256d __A) {
+__m512d test_mm512_maskz_broadcast_f64x4(__mmask8 __M, float const* __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcast_f64x4
-  // CHECK: @llvm.x86.avx512.mask.broadcastf64x4
-  return _mm512_maskz_broadcast_f64x4(__M, __A); 
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
+  return _mm512_maskz_broadcast_f64x4(__M, _mm256_loadu_ps(__A)); 
 }
 
-__m512i test_mm512_broadcast_i32x4(__m128i __A) {
+__m512i test_mm512_broadcast_i32x4(__m128i const* __A) {
   // CHECK-LABEL: @test_mm512_broadcast_i32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcasti32x4
-  return _mm512_broadcast_i32x4(__A); 
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  return _mm512_broadcast_i32x4(_mm_loadu_si128(__A)); 
 }
 
-__m512i test_mm512_mask_broadcast_i32x4(__m512i __O, __mmask16 __M, __m128i __A) {
+__m512i test_mm512_mask_broadcast_i32x4(__m512i __O, __mmask16 __M, __m128i const* __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcast_i32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcasti32x4
-  return _mm512_mask_broadcast_i32x4(__O, __M, __A); 
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_mask_broadcast_i32x4(__O, __M, _mm_loadu_si128(__A)); 
 }
 
-__m512i test_mm512_maskz_broadcast_i32x4(__mmask16 __M, __m128i __A) {
+__m512i test_mm512_maskz_broadcast_i32x4(__mmask16 __M, __m128i const* __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcast_i32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcasti32x4
-  return _mm512_maskz_broadcast_i32x4(__M, __A); 
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_maskz_broadcast_i32x4(__M, _mm_loadu_si128(__A)); 
 }
 
-__m512i test_mm512_broadcast_i64x4(__m256i __A) {
+__m512i test_mm512_broadcast_i64x4(__m256i const* __A) {
   // CHECK-LABEL: @test_mm512_broadcast_i64x4
-  // CHECK: @llvm.x86.avx512.mask.broadcasti64x4
-  return _mm512_broadcast_i64x4(__A); 
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  return _mm512_broadcast_i64x4(_mm256_loadu_si256(__A)); 
 }
 
-__m512i test_mm512_mask_broadcast_i64x4(__m512i __O, __mmask8 __M, __m256i __A) {
+__m512i test_mm512_mask_broadcast_i64x4(__m512i __O, __mmask8 __M, __m256i const* __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcast_i64x4
-  // CHECK: @llvm.x86.avx512.mask.broadcasti64x4
-  return _mm512_mask_broadcast_i64x4(__O, __M, __A); 
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_mask_broadcast_i64x4(__O, __M, _mm256_loadu_si256(__A)); 
 }
 
-__m512i test_mm512_maskz_broadcast_i64x4(__mmask8 __M, __m256i __A) {
+__m512i test_mm512_maskz_broadcast_i64x4(__mmask8 __M, __m256i const* __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcast_i64x4
-  // CHECK: @llvm.x86.avx512.mask.broadcasti64x4
-  return _mm512_maskz_broadcast_i64x4(__M, __A); 
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_maskz_broadcast_i64x4(__M, _mm256_loadu_si256(__A)); 
 }
 
 __m512d test_mm512_broadcastsd_pd(__m128d __A) {
   // CHECK-LABEL: @test_mm512_broadcastsd_pd
-  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <8 x i32> zeroinitializer
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> zeroinitializer, <8 x i32> zeroinitializer
   return _mm512_broadcastsd_pd(__A);
 }
 
 __m512d test_mm512_mask_broadcastsd_pd(__m512d __O, __mmask8 __M, __m128d __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcastsd_pd
-  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <8 x i32> zeroinitializer
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> zeroinitializer, <8 x i32> zeroinitializer
   // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
   return _mm512_mask_broadcastsd_pd(__O, __M, __A);
 }
 
 __m512d test_mm512_maskz_broadcastsd_pd(__mmask8 __M, __m128d __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcastsd_pd
-  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <8 x i32> zeroinitializer
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> zeroinitializer, <8 x i32> zeroinitializer
   // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
   return _mm512_maskz_broadcastsd_pd(__M, __A);
 }
 
 __m512 test_mm512_broadcastss_ps(__m128 __A) {
   // CHECK-LABEL: @test_mm512_broadcastss_ps
-  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <16 x i32> zeroinitializer
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <16 x i32> zeroinitializer
   return _mm512_broadcastss_ps(__A);
 }
 
 __m512 test_mm512_mask_broadcastss_ps(__m512 __O, __mmask16 __M, __m128 __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcastss_ps
-  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <16 x i32> zeroinitializer
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <16 x i32> zeroinitializer
   // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
   return _mm512_mask_broadcastss_ps(__O, __M, __A);
 }
 
 __m512 test_mm512_maskz_broadcastss_ps(__mmask16 __M, __m128 __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcastss_ps
-  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <16 x i32> zeroinitializer
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <16 x i32> zeroinitializer
   // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
   return _mm512_maskz_broadcastss_ps(__M, __A);
 }
 
 __m512i test_mm512_broadcastd_epi32(__m128i __A) {
   // CHECK-LABEL: @test_mm512_broadcastd_epi32
-  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <16 x i32> zeroinitializer
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <16 x i32> zeroinitializer
   return _mm512_broadcastd_epi32(__A);
 }
 
 __m512i test_mm512_mask_broadcastd_epi32(__m512i __O, __mmask16 __M, __m128i __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcastd_epi32
-  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <16 x i32> zeroinitializer
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <16 x i32> zeroinitializer
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_mask_broadcastd_epi32(__O, __M, __A);
 }
 
 __m512i test_mm512_maskz_broadcastd_epi32(__mmask16 __M, __m128i __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcastd_epi32
-  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <16 x i32> zeroinitializer
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <16 x i32> zeroinitializer
   // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
   return _mm512_maskz_broadcastd_epi32(__M, __A);
 }
 
 __m512i test_mm512_broadcastq_epi64(__m128i __A) {
   // CHECK-LABEL: @test_mm512_broadcastq_epi64
-  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <8 x i32> zeroinitializer
+  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> zeroinitializer, <8 x i32> zeroinitializer
   return _mm512_broadcastq_epi64(__A);
 }
 
 __m512i test_mm512_mask_broadcastq_epi64(__m512i __O, __mmask8 __M, __m128i __A) {
   // CHECK-LABEL: @test_mm512_mask_broadcastq_epi64
-  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <8 x i32> zeroinitializer
+  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> zeroinitializer, <8 x i32> zeroinitializer
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_broadcastq_epi64(__O, __M, __A);
 }
 
 __m512i test_mm512_maskz_broadcastq_epi64(__mmask8 __M, __m128i __A) {
   // CHECK-LABEL: @test_mm512_maskz_broadcastq_epi64
-  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <8 x i32> zeroinitializer
+  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> zeroinitializer, <8 x i32> zeroinitializer
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_broadcastq_epi64(__M, __A);
 }
@@ -5161,20 +5189,20 @@
 
 __m256i test_mm512_extracti64x4_epi64(__m512i __A) {
   // CHECK-LABEL: @test_mm512_extracti64x4_epi64
-  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   return _mm512_extracti64x4_epi64(__A, 1); 
 }
 
 __m256i test_mm512_mask_extracti64x4_epi64(__m256i __W, __mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_mask_extracti64x4_epi64
-  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm512_mask_extracti64x4_epi64(__W, __U, __A, 1); 
 }
 
 __m256i test_mm512_maskz_extracti64x4_epi64(__mmask8 __U, __m512i __A) {
   // CHECK-LABEL: @test_mm512_maskz_extracti64x4_epi64
-  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm512_maskz_extracti64x4_epi64(__U, __A, 1); 
 }
@@ -6057,40 +6085,40 @@
 
 __m512d test_mm512_permutex_pd(__m512d __X) {
   // CHECK-LABEL: @test_mm512_permutex_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
   return _mm512_permutex_pd(__X, 0);
 }
 
 __m512d test_mm512_mask_permutex_pd(__m512d __W, __mmask8 __U, __m512d __X) {
   // CHECK-LABEL: @test_mm512_mask_permutex_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
   // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
   return _mm512_mask_permutex_pd(__W, __U, __X, 0);
 }
 
 __m512d test_mm512_maskz_permutex_pd(__mmask8 __U, __m512d __X) {
   // CHECK-LABEL: @test_mm512_maskz_permutex_pd
-  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
+  // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
   // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
   return _mm512_maskz_permutex_pd(__U, __X, 0);
 }
 
 __m512i test_mm512_permutex_epi64(__m512i __X) {
   // CHECK-LABEL: @test_mm512_permutex_epi64
-  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
+  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
   return _mm512_permutex_epi64(__X, 0);
 }
 
 __m512i test_mm512_mask_permutex_epi64(__m512i __W, __mmask8 __M, __m512i __X) {
   // CHECK-LABEL: @test_mm512_mask_permutex_epi64
-  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
+  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_mask_permutex_epi64(__W, __M, __X, 0);
 }
 
 __m512i test_mm512_maskz_permutex_epi64(__mmask8 __M, __m512i __X) {
   // CHECK-LABEL: @test_mm512_maskz_permutex_epi64
-  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
+  // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
   // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
   return _mm512_maskz_permutex_epi64(__M, __X, 0);
 }
diff --git a/test/CodeGen/avx512vl-builtins.c b/test/CodeGen/avx512vl-builtins.c
index c4ae3a0..c64b7bc 100644
--- a/test/CodeGen/avx512vl-builtins.c
+++ b/test/CodeGen/avx512vl-builtins.c
@@ -5008,105 +5008,113 @@
 
 __m128d test_mm_mask_permute_pd(__m128d __W, __mmask8 __U, __m128d __X) {
   // CHECK-LABEL: @test_mm_mask_permute_pd
-  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> <i32 1, i32 0>
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> zeroinitializer, <2 x i32> <i32 1, i32 0>
   // CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
   return _mm_mask_permute_pd(__W, __U, __X, 1); 
 }
 
 __m128d test_mm_maskz_permute_pd(__mmask8 __U, __m128d __X) {
   // CHECK-LABEL: @test_mm_maskz_permute_pd
-  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> <i32 1, i32 0>
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> zeroinitializer, <2 x i32> <i32 1, i32 0>
   // CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
   return _mm_maskz_permute_pd(__U, __X, 1); 
 }
 
 __m256d test_mm256_mask_permute_pd(__m256d __W, __mmask8 __U, __m256d __X) {
   // CHECK-LABEL: @test_mm256_mask_permute_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
   // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
   return _mm256_mask_permute_pd(__W, __U, __X, 5); 
 }
 
 __m256d test_mm256_maskz_permute_pd(__mmask8 __U, __m256d __X) {
   // CHECK-LABEL: @test_mm256_maskz_permute_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
   // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
   return _mm256_maskz_permute_pd(__U, __X, 5); 
 }
 
 __m128 test_mm_mask_permute_ps(__m128 __W, __mmask8 __U, __m128 __X) {
   // CHECK-LABEL: @test_mm_mask_permute_ps
-  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
   // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
   return _mm_mask_permute_ps(__W, __U, __X, 0x1b); 
 }
 
 __m128 test_mm_maskz_permute_ps(__mmask8 __U, __m128 __X) {
   // CHECK-LABEL: @test_mm_maskz_permute_ps
-  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
   // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
   return _mm_maskz_permute_ps(__U, __X, 0x1b); 
 }
 
 __m256 test_mm256_mask_permute_ps(__m256 __W, __mmask8 __U, __m256 __X) {
   // CHECK-LABEL: @test_mm256_mask_permute_ps
-  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> undef, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> zeroinitializer, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
   // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
   return _mm256_mask_permute_ps(__W, __U, __X, 0x1b); 
 }
 
 __m256 test_mm256_maskz_permute_ps(__mmask8 __U, __m256 __X) {
   // CHECK-LABEL: @test_mm256_maskz_permute_ps
-  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> undef, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> zeroinitializer, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
   // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
   return _mm256_maskz_permute_ps(__U, __X, 0x1b); 
 }
 
 __m128d test_mm_mask_permutevar_pd(__m128d __W, __mmask8 __U, __m128d __A, __m128i __C) {
   // CHECK-LABEL: @test_mm_mask_permutevar_pd
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.pd
+  // CHECK: @llvm.x86.avx.vpermilvar.pd
+  // CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
   return _mm_mask_permutevar_pd(__W, __U, __A, __C); 
 }
 
 __m128d test_mm_maskz_permutevar_pd(__mmask8 __U, __m128d __A, __m128i __C) {
   // CHECK-LABEL: @test_mm_maskz_permutevar_pd
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.pd
+  // CHECK: @llvm.x86.avx.vpermilvar.pd
+  // CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
   return _mm_maskz_permutevar_pd(__U, __A, __C); 
 }
 
 __m256d test_mm256_mask_permutevar_pd(__m256d __W, __mmask8 __U, __m256d __A, __m256i __C) {
   // CHECK-LABEL: @test_mm256_mask_permutevar_pd
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.pd.256
+  // CHECK: @llvm.x86.avx.vpermilvar.pd.256
+  // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
   return _mm256_mask_permutevar_pd(__W, __U, __A, __C); 
 }
 
 __m256d test_mm256_maskz_permutevar_pd(__mmask8 __U, __m256d __A, __m256i __C) {
   // CHECK-LABEL: @test_mm256_maskz_permutevar_pd
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.pd.256
+  // CHECK: @llvm.x86.avx.vpermilvar.pd.256
+  // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
   return _mm256_maskz_permutevar_pd(__U, __A, __C); 
 }
 
 __m128 test_mm_mask_permutevar_ps(__m128 __W, __mmask8 __U, __m128 __A, __m128i __C) {
   // CHECK-LABEL: @test_mm_mask_permutevar_ps
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.ps
+  // CHECK: @llvm.x86.avx.vpermilvar.ps
+  // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
   return _mm_mask_permutevar_ps(__W, __U, __A, __C); 
 }
 
 __m128 test_mm_maskz_permutevar_ps(__mmask8 __U, __m128 __A, __m128i __C) {
   // CHECK-LABEL: @test_mm_maskz_permutevar_ps
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.ps
+  // CHECK: @llvm.x86.avx.vpermilvar.ps
+  // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
   return _mm_maskz_permutevar_ps(__U, __A, __C); 
 }
 
 __m256 test_mm256_mask_permutevar_ps(__m256 __W, __mmask8 __U, __m256 __A, __m256i __C) {
   // CHECK-LABEL: @test_mm256_mask_permutevar_ps
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.ps.256
+  // CHECK: @llvm.x86.avx.vpermilvar.ps.256
+  // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
   return _mm256_mask_permutevar_ps(__W, __U, __A, __C); 
 }
 
 __m256 test_mm256_maskz_permutevar_ps(__mmask8 __U, __m256 __A, __m256i __C) {
   // CHECK-LABEL: @test_mm256_maskz_permutevar_ps
-  // CHECK: @llvm.x86.avx512.mask.vpermilvar.ps.256
+  // CHECK: @llvm.x86.avx.vpermilvar.ps.256
+  // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
   return _mm256_maskz_permutevar_ps(__U, __A, __C); 
 }
 
@@ -5726,38 +5734,42 @@
 
 __m256 test_mm256_broadcast_f32x4(__m128 __A) {
   // CHECK-LABEL: @test_mm256_broadcast_f32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcastf32x4
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
   return _mm256_broadcast_f32x4(__A); 
 }
 
 __m256 test_mm256_mask_broadcast_f32x4(__m256 __O, __mmask8 __M, __m128 __A) {
   // CHECK-LABEL: @test_mm256_mask_broadcast_f32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcastf32x4
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
   return _mm256_mask_broadcast_f32x4(__O, __M, __A); 
 }
 
 __m256 test_mm256_maskz_broadcast_f32x4(__mmask8 __M, __m128 __A) {
   // CHECK-LABEL: @test_mm256_maskz_broadcast_f32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcastf32x4
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
   return _mm256_maskz_broadcast_f32x4(__M, __A); 
 }
 
-__m256i test_mm256_broadcast_i32x4(__m128i __A) {
+__m256i test_mm256_broadcast_i32x4(__m128i const* __A) {
   // CHECK-LABEL: @test_mm256_broadcast_i32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcasti32x4
-  return _mm256_broadcast_i32x4(__A); 
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  return _mm256_broadcast_i32x4(_mm_loadu_si128(__A)); 
 }
 
-__m256i test_mm256_mask_broadcast_i32x4(__m256i __O, __mmask8 __M, __m128i __A) {
+__m256i test_mm256_mask_broadcast_i32x4(__m256i __O, __mmask8 __M, __m128i const* __A) {
   // CHECK-LABEL: @test_mm256_mask_broadcast_i32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcasti32x4
-  return _mm256_mask_broadcast_i32x4(__O, __M, __A); 
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  return _mm256_mask_broadcast_i32x4(__O, __M, _mm_loadu_si128(__A)); 
 }
 
-__m256i test_mm256_maskz_broadcast_i32x4(__mmask8 __M, __m128i __A) {
+__m256i test_mm256_maskz_broadcast_i32x4(__mmask8 __M, __m128i const* __A) {
   // CHECK-LABEL: @test_mm256_maskz_broadcast_i32x4
-  // CHECK: @llvm.x86.avx512.mask.broadcasti32x4
-  return _mm256_maskz_broadcast_i32x4(__M, __A); 
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+  return _mm256_maskz_broadcast_i32x4(__M, _mm_loadu_si128(__A)); 
 }
 
 __m256d test_mm256_mask_broadcastsd_pd(__m256d __O, __mmask8 __M, __m128d __A) {
@@ -6580,20 +6592,20 @@
 
 __m128 test_mm256_extractf32x4_ps(__m256 __A) {
   // CHECK-LABEL: @test_mm256_extractf32x4_ps
-  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   return _mm256_extractf32x4_ps(__A, 1); 
 }
 
 __m128 test_mm256_mask_extractf32x4_ps(__m128 __W, __mmask8 __U, __m256 __A) {
   // CHECK-LABEL: @test_mm256_mask_extractf32x4_ps
-  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
   return _mm256_mask_extractf32x4_ps(__W, __U, __A, 1); 
 }
 
 __m128 test_mm256_maskz_extractf32x4_ps(__mmask8 __U, __m256 __A) {
   // CHECK-LABEL: @test_mm256_maskz_extractf32x4_ps
-  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> zeroinitializer, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
   // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
   return _mm256_maskz_extractf32x4_ps(__U, __A, 1); 
 }
@@ -6828,40 +6840,40 @@
 
 __m256d test_mm256_permutex_pd(__m256d __X) {
   // CHECK-LABEL: @test_mm256_permutex_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <4 x i32> <i32 3, i32 0, i32 0, i32 0>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 0, i32 0>
   return _mm256_permutex_pd(__X, 3);
 }
 
 __m256d test_mm256_mask_permutex_pd(__m256d __W, __mmask8 __U, __m256d __X) {
   // CHECK-LABEL: @test_mm256_mask_permutex_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <4 x i32> <i32 1, i32 0, i32 0, i32 0>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <4 x i32> <i32 1, i32 0, i32 0, i32 0>
   // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
   return _mm256_mask_permutex_pd(__W, __U, __X, 1);
 }
 
 __m256d test_mm256_maskz_permutex_pd(__mmask8 __U, __m256d __X) {
   // CHECK-LABEL: @test_mm256_maskz_permutex_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <4 x i32> <i32 1, i32 0, i32 0, i32 0>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <4 x i32> <i32 1, i32 0, i32 0, i32 0>
   // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
   return _mm256_maskz_permutex_pd(__U, __X, 1);
 }
 
 __m256i test_mm256_permutex_epi64(__m256i __X) {
   // CHECK-LABEL: @test_mm256_permutex_epi64
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <4 x i32> <i32 3, i32 0, i32 0, i32 0>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 0, i32 0>
   return _mm256_permutex_epi64(__X, 3);
 }
 
 __m256i test_mm256_mask_permutex_epi64(__m256i __W, __mmask8 __M, __m256i __X) {
   // CHECK-LABEL: @test_mm256_mask_permutex_epi64
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <4 x i32> <i32 3, i32 0, i32 0, i32 0>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 0, i32 0>
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_mask_permutex_epi64(__W, __M, __X, 3);
 }
 
 __m256i test_mm256_maskz_permutex_epi64(__mmask8 __M, __m256i __X) {
   // CHECK-LABEL: @test_mm256_maskz_permutex_epi64
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <4 x i32> <i32 3, i32 0, i32 0, i32 0>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 0, i32 0>
   // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
   return _mm256_maskz_permutex_epi64(__M, __X, 3);
 }
diff --git a/test/CodeGen/avx512vldq-builtins.c b/test/CodeGen/avx512vldq-builtins.c
index 6834b6f..a368924 100644
--- a/test/CodeGen/avx512vldq-builtins.c
+++ b/test/CodeGen/avx512vldq-builtins.c
@@ -918,22 +918,24 @@
   return _mm256_maskz_broadcast_f32x2(__M, __A); 
 }
 
-__m256d test_mm256_broadcast_f64x2(__m128d __A) {
+__m256d test_mm256_broadcast_f64x2(double const* __A) {
   // CHECK-LABEL: @test_mm256_broadcast_f64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcastf64x2
-  return _mm256_broadcast_f64x2(__A); 
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+  return _mm256_broadcast_f64x2(_mm_loadu_pd(__A)); 
 }
 
-__m256d test_mm256_mask_broadcast_f64x2(__m256d __O, __mmask8 __M, __m128d __A) {
+__m256d test_mm256_mask_broadcast_f64x2(__m256d __O, __mmask8 __M, double const* __A) {
   // CHECK-LABEL: @test_mm256_mask_broadcast_f64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcastf64x2
-  return _mm256_mask_broadcast_f64x2(__O, __M, __A); 
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+  // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
+  return _mm256_mask_broadcast_f64x2(__O, __M, _mm_loadu_pd(__A)); 
 }
 
-__m256d test_mm256_maskz_broadcast_f64x2(__mmask8 __M, __m128d __A) {
+__m256d test_mm256_maskz_broadcast_f64x2(__mmask8 __M, double const* __A) {
   // CHECK-LABEL: @test_mm256_maskz_broadcast_f64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcastf64x2
-  return _mm256_maskz_broadcast_f64x2(__M, __A); 
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+  // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
+  return _mm256_maskz_broadcast_f64x2(__M, _mm_loadu_pd(__A)); 
 }
 
 __m128i test_mm_broadcast_i32x2(__m128i __A) {
@@ -972,60 +974,62 @@
   return _mm256_maskz_broadcast_i32x2(__M, __A); 
 }
 
-__m256i test_mm256_broadcast_i64x2(__m128i __A) {
+__m256i test_mm256_broadcast_i64x2(__m128i const* __A) {
   // CHECK-LABEL: @test_mm256_broadcast_i64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcasti64x2
-  return _mm256_broadcast_i64x2(__A); 
+  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+  return _mm256_broadcast_i64x2(_mm_loadu_si128(__A)); 
 }
 
-__m256i test_mm256_mask_broadcast_i64x2(__m256i __O, __mmask8 __M, __m128i __A) {
+__m256i test_mm256_mask_broadcast_i64x2(__m256i __O, __mmask8 __M, __m128i const* __A) {
   // CHECK-LABEL: @test_mm256_mask_broadcast_i64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcasti64x2
-  return _mm256_mask_broadcast_i64x2(__O, __M, __A); 
+  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm256_mask_broadcast_i64x2(__O, __M, _mm_loadu_si128(__A)); 
 }
 
-__m256i test_mm256_maskz_broadcast_i64x2(__mmask8 __M, __m128i __A) {
+__m256i test_mm256_maskz_broadcast_i64x2(__mmask8 __M, __m128i const* __A) {
   // CHECK-LABEL: @test_mm256_maskz_broadcast_i64x2
-  // CHECK: @llvm.x86.avx512.mask.broadcasti64x2
-  return _mm256_maskz_broadcast_i64x2(__M, __A); 
+  // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+  // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm256_maskz_broadcast_i64x2(__M, _mm_loadu_si128(__A)); 
 }
 
 __m128d test_mm256_extractf64x2_pd(__m256d __A) {
   // CHECK-LABEL: @test_mm256_extractf64x2_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <2 x i32> <i32 2, i32 3>
   return _mm256_extractf64x2_pd(__A, 1); 
 }
 
 __m128d test_mm256_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m256d __A) {
   // CHECK-LABEL: @test_mm256_mask_extractf64x2_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <2 x i32> <i32 2, i32 3>
   // CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
   return _mm256_mask_extractf64x2_pd(__W, __U, __A, 1); 
 }
 
 __m128d test_mm256_maskz_extractf64x2_pd(__mmask8 __U, __m256d __A) {
   // CHECK-LABEL: @test_mm256_maskz_extractf64x2_pd
-  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> zeroinitializer, <2 x i32> <i32 2, i32 3>
   // CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
   return _mm256_maskz_extractf64x2_pd(__U, __A, 1); 
 }
 
 __m128i test_mm256_extracti64x2_epi64(__m256i __A) {
   // CHECK-LABEL: @test_mm256_extracti64x2_epi64
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <2 x i32> <i32 2, i32 3>
   return _mm256_extracti64x2_epi64(__A, 1); 
 }
 
 __m128i test_mm256_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_mask_extracti64x2_epi64
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <2 x i32> <i32 2, i32 3>
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm256_mask_extracti64x2_epi64(__W, __U, __A, 1); 
 }
 
 __m128i test_mm256_maskz_extracti64x2_epi64(__mmask8 __U, __m256i __A) {
   // CHECK-LABEL: @test_mm256_maskz_extracti64x2_epi64
-  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> zeroinitializer, <2 x i32> <i32 2, i32 3>
   // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
   return _mm256_maskz_extracti64x2_epi64(__U, __A, 1); 
 }
diff --git a/test/CodeGen/blocks-opencl.cl b/test/CodeGen/blocks-opencl.cl
index 61c479b..1251333 100644
--- a/test/CodeGen/blocks-opencl.cl
+++ b/test/CodeGen/blocks-opencl.cl
@@ -5,7 +5,7 @@
 void dummy(float (^const op)(float)) {
 }
 
-// CHECK: i8 addrspace(3)* getelementptr inbounds ([9 x i8], [9 x i8] addrspace(3)* @.str, i32 0, i32 0)
+// CHECK: i8 addrspace(2)* getelementptr inbounds ([9 x i8], [9 x i8] addrspace(2)* @.str, i32 0, i32 0)
 
 kernel void test_block()
 {
diff --git a/test/CodeGen/blocks.c b/test/CodeGen/blocks.c
index 2a81826..911c63e 100644
--- a/test/CodeGen/blocks.c
+++ b/test/CodeGen/blocks.c
@@ -78,3 +78,37 @@
 // CHECK: [[ONE:%.*]] = bitcast void (...)* [[ZERO]] to void ()*
 // CHECK-NEXT:   br label [[CE:%.*]]
 
+// Ensure that we don't emit helper code in copy/dispose routines for variables
+// that are const-captured.
+void testConstCaptureInCopyAndDestroyHelpers() {
+  const int x = 0;
+  __block int i;
+  (^ { i = x; })();
+}
+// CHECK-LABEL: testConstCaptureInCopyAndDestroyHelpers_block_invoke
+
+// CHECK: @__copy_helper_block
+// CHECK: alloca
+// CHECK-NEXT: alloca
+// CHECK-NEXT: store
+// CHECK-NEXT: store
+// CHECK-NEXT: load
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: load
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: getelementptr
+// CHECK-NEXT: getelementptr
+// CHECK-NEXT: load
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @_Block_object_assign
+// CHECK-NEXT: ret
+
+// CHECK: @__destroy_helper_block
+// CHECK: alloca
+// CHECK-NEXT: store
+// CHECK-NEXT: load
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: getelementptr
+// CHECK-NEXT: load
+// CHECK-NEXT: call void @_Block_object_dispose
+// CHECK-NEXT: ret
diff --git a/test/CodeGen/bool_test.c b/test/CodeGen/bool_test.c
index b48da37..ead8854 100644
--- a/test/CodeGen/bool_test.c
+++ b/test/CodeGen/bool_test.c
@@ -1,5 +1,5 @@
 // REQUIRES: powerpc-registered-target
-// RUN: %clang_cc1 -triple powerpc-apple-macosx10.4.0 -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-apple-macosx10.4.0 -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s
 
 int boolsize = sizeof(_Bool);
 // CHECK: boolsize = global i32 4, align 4
diff --git a/test/CodeGen/builtin-clflushopt.c b/test/CodeGen/builtin-clflushopt.c
index e98c2aa..9386116 100644
--- a/test/CodeGen/builtin-clflushopt.c
+++ b/test/CodeGen/builtin-clflushopt.c
@@ -3,7 +3,7 @@
 
 #include <immintrin.h>
 void test_mm_clflushopt(char * __m) {
-  //CHECK-LABLE: @test_mm_clflushopt
+  //CHECK-LABEL: @test_mm_clflushopt
   //CHECK: @llvm.x86.clflushopt
   _mm_clflushopt(__m);
 }
diff --git a/test/CodeGen/builtin-clzero.c b/test/CodeGen/builtin-clzero.c
new file mode 100644
index 0000000..c9960ce
--- /dev/null
+++ b/test/CodeGen/builtin-clzero.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin -target-feature +clzero  -emit-llvm -o - -Wall -Werror | FileCheck %s
+#define __MM_MALLOC_H
+
+#include <x86intrin.h>
+void test_mm_clzero(void * __m) {
+  //CHECK-LABEL: @test_mm_clzero
+  //CHECK: @llvm.x86.clzero
+  _mm_clzero(__m);
+}
diff --git a/test/CodeGen/builtin-expect.c b/test/CodeGen/builtin-expect.c
index 560625e..2d49700 100644
--- a/test/CodeGen/builtin-expect.c
+++ b/test/CodeGen/builtin-expect.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O1 -disable-llvm-optzns | FileCheck %s --check-prefix=ALL --check-prefix=O1
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O1 -disable-llvm-passes | FileCheck %s --check-prefix=ALL --check-prefix=O1
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck %s --check-prefix=ALL --check-prefix=O0
 
 // In all tests, make sure that no expect is generated if optimizations are off.
diff --git a/test/CodeGen/builtin-unpredictable.c b/test/CodeGen/builtin-unpredictable.c
index 653f231..30709b0 100644
--- a/test/CodeGen/builtin-unpredictable.c
+++ b/test/CodeGen/builtin-unpredictable.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-optzns -o - %s -O1 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - %s -O1 | FileCheck %s
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck %s --check-prefix=CHECK_O0
 
 // When optimizing, the builtin should be converted to metadata.
diff --git a/test/CodeGen/builtins-arm.c b/test/CodeGen/builtins-arm.c
index a385bd2..0dc4c7d 100644
--- a/test/CodeGen/builtins-arm.c
+++ b/test/CodeGen/builtins-arm.c
@@ -68,7 +68,7 @@
   __builtin_arm_isb(3); //CHECK: call {{.*}} @llvm.arm.isb(i32 3)
 }
 
-// CHECK: call {{.*}} @llvm.arm.rbit(i32 %a)
+// CHECK: call {{.*}} @llvm.bitreverse.i32(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 20eb2ab..dc5fb6f 100644
--- a/test/CodeGen/builtins-arm64.c
+++ b/test/CodeGen/builtins-arm64.c
@@ -10,12 +10,12 @@
 // CHECK: call {{.*}} @llvm.thread.pointer()
 }
 
-// CHECK: call {{.*}} @llvm.aarch64.rbit.i32(i32 %a)
+// CHECK: call {{.*}} @llvm.bitreverse.i32(i32 %a)
 unsigned rbit(unsigned a) {
   return __builtin_arm_rbit(a);
 }
 
-// CHECK: call {{.*}} @llvm.aarch64.rbit.i64(i64 %a)
+// CHECK: call {{.*}} @llvm.bitreverse.i64(i64 %a)
 unsigned long long rbit64(unsigned long long a) {
   return __builtin_arm_rbit64(a);
 }
diff --git a/test/CodeGen/builtins-mips-msa-error.c b/test/CodeGen/builtins-mips-msa-error.c
index fcdf6f0..7aba8ff 100644
--- a/test/CodeGen/builtins-mips-msa-error.c
+++ b/test/CodeGen/builtins-mips-msa-error.c
@@ -162,11 +162,6 @@
   v8i16_r = __msa_shf_h(v8i16_a, 256);               // CHECK: warning: argument should be a value from 0 to 255}}
   v4i32_r = __msa_shf_w(v4i32_a, 256);               // CHECK: warning: argument should be a value from 0 to 255}}
 
-  v16i8_r = __msa_sld_b(v16i8_r, v16i8_a, 16);      // expected-error {{argument should be a value from 0 to 15}}
-  v8i16_r = __msa_sld_h(v8i16_r, v8i16_a, 8);       // expected-error {{argument should be a value from 0 to 7}}
-  v4i32_r = __msa_sld_w(v4i32_r, v4i32_a, 4);       // expected-error {{argument should be a value from 0 to 3}}
-  v2i64_r = __msa_sld_d(v2i64_r, v2i64_a, 2);       // expected-error {{argument should be a value from 0 to 1}}
-
   v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, 16);      // expected-error {{argument should be a value from 0 to 15}}
   v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, 8);       // expected-error {{argument should be a value from 0 to 7}}
   v4i32_r = __msa_sldi_w(v4i32_r, v4i32_a, 4);       // expected-error {{argument should be a value from 0 to 3}}
@@ -358,11 +353,6 @@
   v8i16_r = __msa_shf_h(v8i16_a, -1);                // CHECK: warning: argument should be a value from 0 to 255}}
   v4i32_r = __msa_shf_w(v4i32_a, -1);                // CHECK: warning: argument should be a value from 0 to 255}}
 
-  v16i8_r = __msa_sld_b(v16i8_r, v16i8_a, -17);      // expected-error {{argument should be a value from 0 to 15}}
-  v8i16_r = __msa_sld_h(v8i16_r, v8i16_a, -8);       // expected-error {{argument should be a value from 0 to 7}}
-  v4i32_r = __msa_sld_w(v4i32_r, v4i32_a, -4);       // expected-error {{argument should be a value from 0 to 3}}
-  v2i64_r = __msa_sld_d(v2i64_r, v2i64_a, -2);       // expected-error {{argument should be a value from 0 to 1}}
-
   v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, -17);     // expected-error {{argument should be a value from 0 to 15}}
   v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, -8);      // expected-error {{argument should be a value from 0 to 7}}
   v4i32_r = __msa_sldi_w(v4i32_r, v4i32_a, -4);      // expected-error {{argument should be a value from 0 to 3}}
diff --git a/test/CodeGen/builtins-mips-msa.c b/test/CodeGen/builtins-mips-msa.c
index 1256795..2e46bfd 100644
--- a/test/CodeGen/builtins-mips-msa.c
+++ b/test/CodeGen/builtins-mips-msa.c
@@ -699,6 +699,11 @@
   v4i32_r = __msa_sld_w(v4i32_r, v4i32_a, 3); // CHECK: call <4  x i32> @llvm.mips.sld.w(
   v2i64_r = __msa_sld_d(v2i64_r, v2i64_a, 1); // CHECK: call <2  x i64> @llvm.mips.sld.d(
 
+  v16i8_r = __msa_sld_b(v16i8_r, v16i8_a, 16); // CHECK: call <16 x i8>  @llvm.mips.sld.b(
+  v8i16_r = __msa_sld_h(v8i16_r, v8i16_a, 8); // CHECK: call <8  x i16> @llvm.mips.sld.h(
+  v4i32_r = __msa_sld_w(v4i32_r, v4i32_a, 4); // CHECK: call <4  x i32> @llvm.mips.sld.w(
+  v2i64_r = __msa_sld_d(v2i64_r, v2i64_a, 2); // CHECK: call <2  x i64> @llvm.mips.sld.d(
+
   v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, 7); // CHECK: call <16 x i8>  @llvm.mips.sldi.b(
   v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, 3); // CHECK: call <8  x i16> @llvm.mips.sldi.h(
   v4i32_r = __msa_sldi_w(v4i32_r, v4i32_a, 2); // CHECK: call <4  x i32> @llvm.mips.sldi.w(
diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c
index 3b75cb4..d54a698 100644
--- a/test/CodeGen/builtins-ppc-altivec.c
+++ b/test/CodeGen/builtins-ppc-altivec.c
@@ -3419,28 +3419,40 @@
 
   /* vec_sl */
   res_vsc = vec_sl(vsc, vuc);
-// CHECK: shl <16 x i8>
-// CHECK-LE: shl <16 x i8>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK: shl <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK-LE: shl <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
 
   res_vuc = vec_sl(vuc, vuc);
-// CHECK: shl <16 x i8>
-// CHECK-LE: shl <16 x i8>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK: shl <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <16 x i8> {{[0-9a-zA-Z%.]+}}, <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>
+// CHECK-LE: shl <16 x i8> {{[0-9a-zA-Z%.]+}}, [[UREM]]
 
   res_vs  = vec_sl(vs, vus);
-// CHECK: shl <8 x i16>
-// CHECK-LE: shl <8 x i16>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK: shl <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK-LE: shl <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
 
   res_vus = vec_sl(vus, vus);
-// CHECK: shl <8 x i16>
-// CHECK-LE: shl <8 x i16>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK: shl <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <8 x i16> {{[0-9a-zA-Z%.]+}}, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
+// CHECK-LE: shl <8 x i16> {{[0-9a-zA-Z%.]+}}, [[UREM]]
 
   res_vi  = vec_sl(vi, vui);
-// CHECK: shl <4 x i32>
-// CHECK-LE: shl <4 x i32>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK: shl <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK-LE: shl <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
 
   res_vui = vec_sl(vui, vui);
-// CHECK: shl <4 x i32>
-// CHECK-LE: shl <4 x i32>
+// CHECK: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK: shl <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
+// CHECK-LE: [[UREM:[0-9a-zA-Z%.]+]] = urem <4 x i32> {{[0-9a-zA-Z%.]+}}, <i32 32, i32 32, i32 32, i32 32>
+// CHECK-LE: shl <4 x i32> {{[0-9a-zA-Z%.]+}}, [[UREM]]
 
   res_vsc = vec_vslb(vsc, vuc);
 // CHECK: shl <16 x i8>
diff --git a/test/CodeGen/builtins-ppc-error.c b/test/CodeGen/builtins-ppc-error.c
new file mode 100644
index 0000000..5860c4f
--- /dev/null
+++ b/test/CodeGen/builtins-ppc-error.c
@@ -0,0 +1,20 @@
+// REQUIRES: powerpc-registered-target
+
+// RUN: %clang_cc1 -faltivec -target-feature +power9-vector \
+// RUN:   -triple powerpc64-unknown-unknown -fsyntax-only   \
+// RUN: -Wall -Werror -verify %s
+
+// RUN: %clang_cc1 -faltivec -target-feature +power9-vector  \
+// RUN: -triple powerpc64le-unknown-unknown -fsyntax-only    \
+// RUN: -Wall -Werror -verify %s
+
+#include <altivec.h>
+
+extern vector signed int vsi;
+extern vector unsigned char vuc;
+
+void testInsertWord1(void) {
+  int index = 5;
+  vector unsigned char v1 = vec_insert4b(vsi, vuc, index); // expected-error {{argument to '__builtin_vsx_insertword' must be a constant integer}}
+  vector unsigned long long v2 = vec_extract4b(vuc, index);   // expected-error {{argument to '__builtin_vsx_extractuword' must be a constant integer}}
+}
diff --git a/test/CodeGen/builtins-ppc-p9vector.c b/test/CodeGen/builtins-ppc-p9vector.c
index f70d2f9..4231697 100644
--- a/test/CodeGen/builtins-ppc-p9vector.c
+++ b/test/CodeGen/builtins-ppc-p9vector.c
@@ -868,20 +868,24 @@
   return vec_rlmi(vula, vula, vula);
 }
 vector unsigned int test77(void) {
+// CHECK-BE: %[[RES1:.+]] = shl <4 x i32
+// CHECK-BE: %[[RES2:.+]] = or <4 x i32> %[[RES1]]
 // CHECK-BE: @llvm.ppc.altivec.vrlwnm(<4 x i32
-// CHECK-BE: and <4 x i32
 // CHECK-BE: ret <4 x i32>
+// CHECK: %[[RES1:.+]] = shl <4 x i32
+// CHECK: %[[RES2:.+]] = or <4 x i32> %[[RES1]]
 // CHECK: @llvm.ppc.altivec.vrlwnm(<4 x i32
-// CHECK: and <4 x i32
 // CHECK: ret <4 x i32>
   return vec_rlnm(vuia, vuia, vuia);
 }
 vector unsigned long long test78(void) {
+// CHECK-BE: %[[RES1:.+]] = shl <2 x i64
+// CHECK-BE: %[[RES2:.+]] = or <2 x i64> %[[RES1]]
 // CHECK-BE: @llvm.ppc.altivec.vrldnm(<2 x i64
-// CHECK-BE: and <2 x i64
 // CHECK-BE-NEXT: ret <2 x i64>
+// CHECK: %[[RES1:.+]] = shl <2 x i64
+// CHECK: %[[RES2:.+]] = or <2 x i64> %[[RES1]]
 // CHECK: @llvm.ppc.altivec.vrldnm(<2 x i64
-// CHECK: and <2 x i64
 // CHECK-NEXT: ret <2 x i64>
   return vec_rlnm(vula, vula, vula);
 }
@@ -1166,17 +1170,52 @@
 // CHECK-BE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 undef, i32 0, i32 undef, i32 1, i32 undef, i32 2, i32 undef, i32 3>
 // CHECK-BE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
 // CHECK-BE-NEXT: ret <4 x float>
-// CHECK-LE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 0, i32 undef, i32 1, i32 undef, i32 2, i32 undef, i32 3, i32 undef>
-// CHECK-LE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
-// CHECK-LE-NEXT: ret <4 x float>
+// CHECK: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 0, i32 undef, i32 1, i32 undef, i32 2, i32 undef, i32 3, i32 undef>
+// CHECK: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
+// CHECK-NEXT: ret <4 x float>
   return vec_extract_fp32_from_shorth(vusa);
 }
 vector float test115(void) {
 // CHECK-BE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 undef, i32 4, i32 undef, i32 5, i32 undef, i32 6, i32 undef, i32 7>
 // CHECK-BE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
 // CHECK-BE-NEXT: ret <4 x float>
-// CHECK-LE: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 4, i32 undef, i32 5, i32 undef, i32 6, i32 undef, i32 7, i32 undef>
-// CHECK-LE: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
-// CHECK-LE-NEXT: ret <4 x float>
+// CHECK: shufflevector <8 x i16> {{.+}}, <8 x i16> {{.+}}, <8 x i32> <i32 4, i32 undef, i32 5, i32 undef, i32 6, i32 undef, i32 7, i32 undef>
+// CHECK: @llvm.ppc.vsx.xvcvhpsp(<8 x i16> {{.+}})
+// CHECK-NEXT: ret <4 x float>
   return vec_extract_fp32_from_shortl(vusa);
 }
+vector unsigned char test116(void) {
+// CHECK-BE: [[T1:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxinsertw(<4 x i32> {{.+}}, <2 x i64> {{.+}}, i32 7)
+// CHECK-BE-NEXT: bitcast <4 x i32> [[T1]] to <16 x i8>
+// CHECK: [[T1:%.+]] = shufflevector <2 x i64> {{.+}}, <2 x i64> {{.+}}, <2 x i32> <i32 1, i32 0>
+// CHECK-NEXT: [[T2:%.+]] =  bitcast <2 x i64> [[T1]] to <4 x i32>
+// CHECK-NEXT: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxinsertw(<4 x i32> [[T2]], <2 x i64> {{.+}}, i32 5)
+// CHECK-NEXT: bitcast <4 x i32> [[T3]] to <16 x i8>
+  return vec_insert4b(vuia, vuca, 7);
+}
+vector unsigned char test117(void) {
+// CHECK-BE: [[T1:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxinsertw(<4 x i32> {{.+}}, <2 x i64> {{.+}}, i32 12)
+// CHECK-BE-NEXT: bitcast <4 x i32> [[T1]] to <16 x i8>
+// CHECK: [[T1:%.+]] = shufflevector <2 x i64> {{.+}}, <2 x i64> {{.+}}, <2 x i32> <i32 1, i32 0>
+// CHECK-NEXT: [[T2:%.+]] =  bitcast <2 x i64> [[T1]] to <4 x i32>
+// CHECK-NEXT: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxinsertw(<4 x i32> [[T2]], <2 x i64> {{.+}}, i32 0)
+// CHECK-NEXT: bitcast <4 x i32> [[T3]] to <16 x i8>
+  return vec_insert4b(vuia, vuca, 13);
+}
+vector unsigned long long test118(void) {
+// CHECK-BE: call <2 x i64> @llvm.ppc.vsx.xxextractuw(<2 x i64> {{.+}}, i32 11)
+// CHECK-BE-NEXT: ret <2 x i64>
+// CHECK: [[T1:%.+]] = call <2 x i64> @llvm.ppc.vsx.xxextractuw(<2 x i64> {{.+}}, i32 1)
+// CHECK-NEXT: shufflevector <2 x i64> [[T1]], <2 x i64> [[T1]], <2 x i32> <i32 1, i32 0>
+// CHECK-NEXT: ret <2 x i64>
+  return vec_extract4b(vuca, 11);
+}
+vector unsigned long long test119(void) {
+// CHECK-BE: call <2 x i64> @llvm.ppc.vsx.xxextractuw(<2 x i64> {{.+}}, i32 0)
+// CHECK-BE-NEXT: ret <2 x i64>
+// CHECK: [[T1:%.+]] = call <2 x i64> @llvm.ppc.vsx.xxextractuw(<2 x i64> {{.+}}, i32 12)
+// CHECK-NEXT: shufflevector <2 x i64> [[T1]], <2 x i64> [[T1]], <2 x i32> <i32 1, i32 0>
+// CHECK-NEXT: ret <2 x i64>
+  return vec_extract4b(vuca, -5);
+}
+
diff --git a/test/CodeGen/builtins-wasm.c b/test/CodeGen/builtins-wasm.c
index 135e329..0c0b879 100644
--- a/test/CodeGen/builtins-wasm.c
+++ b/test/CodeGen/builtins-wasm.c
@@ -9,8 +9,8 @@
 // WEBASSEMBLY64: call {{i.*}} @llvm.wasm.current.memory.i64()
 }
 
-void f2(long delta) {
-  __builtin_wasm_grow_memory(delta);
-// WEBASSEMBLY32: call void @llvm.wasm.grow.memory.i32(i32 %{{.*}})
-// WEBASSEMBLY64: call void @llvm.wasm.grow.memory.i64(i64 %{{.*}})
+__SIZE_TYPE__ f2(__SIZE_TYPE__ delta) {
+  return __builtin_wasm_grow_memory(delta);
+// WEBASSEMBLY32: call i32 @llvm.wasm.grow.memory.i32(i32 %{{.*}})
+// WEBASSEMBLY64: call i64 @llvm.wasm.grow.memory.i64(i64 %{{.*}})
 }
diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c
index ec8a8bf..0086f70 100644
--- a/test/CodeGen/builtins-x86.c
+++ b/test/CodeGen/builtins-x86.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -DUSE_64 -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -emit-llvm -o %t %s
-// RUN: %clang_cc1 -DUSE_ALL -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -fsyntax-only -o %t %s
+// RUN: %clang_cc1 -DUSE_64 -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +clzero -emit-llvm -o %t %s
+// RUN: %clang_cc1 -DUSE_ALL -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +clzero -fsyntax-only -o %t %s
 
 #ifdef USE_ALL
 #define USE_3DNOW
@@ -285,6 +285,7 @@
 
   (void) __builtin_ia32_monitorx(tmp_vp, tmp_Ui, tmp_Ui);
   (void) __builtin_ia32_mwaitx(tmp_Ui, tmp_Ui, tmp_Ui);
+  (void) __builtin_ia32_clzero(tmp_vp);
 
   tmp_V4f = __builtin_ia32_cvtpi2ps(tmp_V4f, tmp_V2i);
   tmp_V2i = __builtin_ia32_cvtps2pi(tmp_V4f);
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index c604ee5..390c2e3 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -489,6 +489,83 @@
   __builtin_os_log_format(buf, "%S", str);
 }
 
+// CHECK-LABEL: define void @test_builtin_os_log_precision_width
+// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]], i32 [[PRECISION:%.*]], i32 [[WIDTH:%.*]])
+void test_builtin_os_log_precision_width(void *buf, const char *data,
+                                         int precision, int width) {
+  volatile int len;
+  // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
+  // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
+  // CHECK: store i32 [[PRECISION]], i32* [[PRECISION_ADDR:%.*]], align 4
+  // CHECK: store i32 [[WIDTH]], i32* [[WIDTH_ADDR:%.*]], align 4
+
+  // CHECK: store volatile i32 24,
+  len = __builtin_os_log_format_buffer_size("Hello %*.*s World", precision, width, data);
+
+  // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
+  // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
+  // CHECK: store i8 2, i8* [[SUMMARY]]
+  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
+  // CHECK: store i8 3, i8* [[NUM_ARGS]]
+
+  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
+  // CHECK: store i8 0, i8* [[ARG1_DESC]]
+  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
+  // CHECK: store i8 4, i8* [[ARG1_SIZE]]
+  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
+  // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
+  // CHECK: [[ARG1_VAL:%.*]] = load i32, i32* [[PRECISION_ADDR]]
+  // CHECK: store i32 [[ARG1_VAL]], i32* [[ARG1_INT]]
+
+  // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 8
+  // CHECK: store i8 16, i8* [[ARG2_DESC]]
+  // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 9
+  // CHECK: store i8 4, i8* [[ARG2_SIZE]]
+  // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 10
+  // CHECK: [[ARG2_INT:%.*]] = bitcast i8* [[ARG2]] to i32*
+  // CHECK: [[ARG2_VAL:%.*]] = load i32, i32* [[WIDTH_ADDR]]
+  // CHECK: store i32 [[ARG2_VAL]], i32* [[ARG2_INT]]
+
+  // CHECK: [[ARG3_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 14
+  // CHECK: store i8 32, i8* [[ARG3_DESC]]
+  // CHECK: [[ARG3_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 15
+  // CHECK: store i8 8, i8* [[ARG3_SIZE]]
+  // CHECK: [[ARG3:%.*]] = getelementptr i8, i8* [[BUF2]], i64 16
+  // CHECK: [[ARG3_PTR:%.*]] = bitcast i8* [[ARG3]] to i8**
+  // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]]
+  // CHECK: store i8* [[DATA2]], i8** [[ARG3_PTR]]
+
+  __builtin_os_log_format(buf, "Hello %*.*s World", precision, width, data);
+}
+
+// CHECK-LABEL: define void @test_builtin_os_log_invalid
+// CHECK: (i8* [[BUF:%.*]], i32 [[DATA:%.*]])
+void test_builtin_os_log_invalid(void *buf, int data) {
+  volatile int len;
+  // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
+  // CHECK: store i32 [[DATA]], i32* [[DATA_ADDR:%.*]]
+
+  // CHECK: store volatile i32 8,
+  len = __builtin_os_log_format_buffer_size("invalid specifier %: %d even a trailing one%", data);
+
+  // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
+  // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
+  // CHECK: store i8 0, i8* [[SUMMARY]]
+  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
+  // CHECK: store i8 1, i8* [[NUM_ARGS]]
+
+  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
+  // CHECK: store i8 0, i8* [[ARG1_DESC]]
+  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
+  // CHECK: store i8 4, i8* [[ARG1_SIZE]]
+  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
+  // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
+  // CHECK: [[ARG1_VAL:%.*]] = load i32, i32* [[DATA_ADDR]]
+  // CHECK: store i32 [[ARG1_VAL]], i32* [[ARG1_INT]]
+
+  __builtin_os_log_format(buf, "invalid specifier %: %d even a trailing one%", data);
+}
+
 // CHECK-LABEL: define void @test_builtin_os_log_percent
 // CHECK: (i8* [[BUF:%.*]], i8* [[DATA1:%.*]], i8* [[DATA2:%.*]])
 // Check that the %% which does not consume any argument is correctly handled
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
index c2f01ae..d3fc176 100644
--- a/test/CodeGen/catch-undef-behavior.c
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -1,21 +1,20 @@
 // RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift-base,shift-exponent,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize-recover=alignment,null,object-size,shift-base,shift-exponent,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-UBSAN
 // RUN: %clang_cc1 -fsanitize-trap=alignment,null,object-size,shift-base,shift-exponent,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize-recover=alignment,null,object-size,shift-base,shift-exponent,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize=alignment,null,object-size,shift-base,shift-exponent,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize-recover=alignment,null,object-size,shift-base,shift-exponent,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-TRAP
-// RUN: %clang_cc1 -fsanitize=null -fsanitize-recover=null -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-NULL
 // RUN: %clang_cc1 -fsanitize=signed-integer-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-OVERFLOW
 
 // CHECK-UBSAN: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" }
 
 // FIXME: When we only emit each type once, use [[INT]] more below.
-// CHECK-UBSAN: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]], i64 4, i8 1
-// CHECK-UBSAN: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i64 4, i8 0
+// CHECK-UBSAN: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]], i8 2, i8 1
+// CHECK-UBSAN: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i8 2, i8 0
 // CHECK-UBSAN: @[[LINE_300:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}}
 // CHECK-UBSAN: @[[LINE_400:.*]] = {{.*}}, i32 400, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}}
-// CHECK-UBSAN: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 {{.*}} @{{.*}}, i64 4, i8 0 }
-// CHECK-UBSAN: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 3 {{.*}} @{{.*}}, i64 4, i8 1 }
+// CHECK-UBSAN: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 {{.*}} @{{.*}}, i8 2, i8 0 }
+// CHECK-UBSAN: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 3 {{.*}} @{{.*}}, i8 2, i8 1 }
 
 // CHECK-UBSAN: @[[STRUCT_S:.*]] = private unnamed_addr constant { i16, i16, [11 x i8] } { i16 -1, i16 0, [11 x i8] c"'struct S'\00" }
 
-// CHECK-UBSAN: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 14 {{.*}} @[[STRUCT_S]], i64 4, i8 3 }
+// CHECK-UBSAN: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 14 {{.*}} @[[STRUCT_S]], i8 2, i8 3 }
 // CHECK-UBSAN: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 12 {{.*}} @{{.*}} }
 // CHECK-UBSAN: @[[LINE_900:.*]] = {{.*}}, i32 900, i32 11 {{.*}} @{{.*}} }
 // CHECK-UBSAN: @[[LINE_1000:.*]] = {{.*}}, i32 1000, i32 10 {{.*}} @{{.*}} }
@@ -30,39 +29,29 @@
 // CHECK-UBSAN: @[[LINE_1500:.*]] = {{.*}}, i32 1500, i32 10 {{.*}} @[[FP16]], {{.*}} }
 // CHECK-UBSAN: @[[LINE_1600:.*]] = {{.*}}, i32 1600, i32 10 {{.*}} @{{.*}} }
 
-// CHECK-NULL: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}}
-
 // PR6805
 // CHECK-COMMON-LABEL: @foo
-// CHECK-NULL-LABEL: @foo
 void foo() {
   union { int i; } u;
-  // CHECK-COMMON:      %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null
 
-  // CHECK-COMMON:      %[[I8PTR:.*]] = bitcast i32* %[[PTR]] to i8*
+  // CHECK-COMMON:      %[[I8PTR:.*]] = bitcast i32* %[[PTR:.*]] to i8*
   // CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false)
-  // CHECK-COMMON-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4
+  // CHECK-COMMON-NEXT: %[[CHECK0:.*]] = icmp uge i64 %[[SIZE]], 4
 
   // CHECK-COMMON:      %[[PTRTOINT:.*]] = ptrtoint {{.*}}* %[[PTR]] to i64
   // CHECK-COMMON-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRTOINT]], 3
-  // CHECK-COMMON-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0
+  // CHECK-COMMON-NEXT: %[[CHECK1:.*]] = icmp eq i64 %[[MISALIGN]], 0
 
-  // CHECK-COMMON:       %[[CHECK01:.*]] = and i1 %[[CHECK0]], %[[CHECK1]]
-  // CHECK-COMMON-NEXT:  %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]]
+  // CHECK-COMMON:       %[[OK:.*]] = and i1 %[[CHECK0]], %[[CHECK1]]
 
   // CHECK-UBSAN: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
   // CHECK-TRAP:  br i1 %[[OK]], {{.*}}
 
   // CHECK-UBSAN:      %[[ARG:.*]] = ptrtoint {{.*}} %[[PTR]] to i64
-  // CHECK-UBSAN-NEXT: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %[[ARG]])
+  // CHECK-UBSAN-NEXT: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %[[ARG]])
 
   // CHECK-TRAP:      call void @llvm.trap() [[NR_NUW:#[0-9]+]]
   // CHECK-TRAP-NEXT: unreachable
-
-  // With -fsanitize=null, only perform the null check.
-  // CHECK-NULL: %[[NULL:.*]] = icmp ne {{.*}}, null
-  // CHECK-NULL: br i1 %[[NULL]]
-  // CHECK-NULL: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %{{.*}})
 #line 100
   u.i=1;
 }
@@ -77,7 +66,7 @@
   // CHECK-COMMON-NEXT: icmp eq i64 %[[MISALIGN]], 0
 
   // CHECK-UBSAN:      %[[ARG:.*]] = ptrtoint
-  // CHECK-UBSAN-NEXT: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[ARG]])
+  // CHECK-UBSAN-NEXT: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[ARG]])
 
   // CHECK-TRAP:      call void @llvm.trap() [[NR_NUW]]
   // CHECK-TRAP-NEXT: unreachable
@@ -145,7 +134,7 @@
 
 // CHECK-COMMON-LABEL: @load
 int load(int *p) {
-  // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_500]] to i8*), i64 %{{.*}})
+  // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_500]] to i8*), i64 %{{.*}})
 
   // CHECK-TRAP:      call void @llvm.trap() [[NR_NUW]]
   // CHECK-TRAP-NEXT: unreachable
@@ -155,7 +144,7 @@
 
 // CHECK-COMMON-LABEL: @store
 void store(int *p, int q) {
-  // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_600]] to i8*), i64 %{{.*}})
+  // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_600]] to i8*), i64 %{{.*}})
 
   // CHECK-TRAP:      call void @llvm.trap() [[NR_NUW]]
   // CHECK-TRAP-NEXT: unreachable
@@ -167,7 +156,7 @@
 
 // CHECK-COMMON-LABEL: @member_access
 int *member_access(struct S *p) {
-  // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_700]] to i8*), i64 %{{.*}})
+  // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_700]] to i8*), i64 %{{.*}})
 
   // CHECK-TRAP:      call void @llvm.trap() [[NR_NUW]]
   // CHECK-TRAP-NEXT: unreachable
diff --git a/test/CodeGen/compound-assign-overflow.c b/test/CodeGen/compound-assign-overflow.c
index f126bb0..92ae249 100644
--- a/test/CodeGen/compound-assign-overflow.c
+++ b/test/CodeGen/compound-assign-overflow.c
@@ -25,11 +25,9 @@
   // CHECK: @__ubsan_handle_add_overflow(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), {{.*}})
 }
 
-int8_t a, b;
-
 // CHECK: @compdiv
 void compdiv() {
 #line 300
-  a /= b;
+  x /= x;
   // CHECK: @__ubsan_handle_divrem_overflow(i8* bitcast ({{.*}} @[[LINE_300]] to i8*), {{.*}})
 }
diff --git a/test/CodeGen/compound-literal.c b/test/CodeGen/compound-literal.c
index 85138bf..6507341 100644
--- a/test/CodeGen/compound-literal.c
+++ b/test/CodeGen/compound-literal.c
@@ -1,5 +1,10 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s
 
+// Capture the type and name so matching later is cleaner.
+struct CompoundTy { int a; };
+// CHECK: @MyCLH = constant [[MY_CLH:[^,]+]]
+const struct CompoundTy *const MyCLH = &(struct CompoundTy){3};
+
 int* a = &(int){1};
 struct s {int a, b, c;} * b = &(struct s) {1, 2, 3};
 _Complex double * x = &(_Complex double){1.0f};
@@ -66,3 +71,14 @@
   // CHECK-NEXT: [[T0:%.*]] = load i48, i48* [[COERCE_TEMP]]
   // CHECK-NEXT: ret i48 [[T0]]
 }
+
+// We had a bug where we'd emit a new GlobalVariable for each time we used a
+// const pointer to a variable initialized by a compound literal.
+// CHECK-LABEL: define i32 @compareMyCLH() #0
+int compareMyCLH() {
+  // CHECK: store i8* bitcast ([[MY_CLH]] to i8*)
+  const void *a = MyCLH;
+  // CHECK: store i8* bitcast ([[MY_CLH]] to i8*)
+  const void *b = MyCLH;
+  return a == b;
+}
diff --git a/test/CodeGen/dbg-const-int128.c b/test/CodeGen/dbg-const-int128.c
new file mode 100644
index 0000000..966c227
--- /dev/null
+++ b/test/CodeGen/dbg-const-int128.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -S -emit-llvm -debug-info-kind=limited  %s -o - | FileCheck %s
+// CHECK: !DIGlobalVariable({{.*}}
+// CHECK-NOT: expr:
+
+static const __uint128_t ro = 18446744073709551615;
+
+void bar(__uint128_t);
+void foo() { bar(ro); }
diff --git a/test/CodeGen/debug-info-atomic.c b/test/CodeGen/debug-info-atomic.c
index 06b9546..3de0d35 100644
--- a/test/CodeGen/debug-info-atomic.c
+++ b/test/CodeGen/debug-info-atomic.c
@@ -1,7 +1,8 @@
 // RUN: %clang -g -c -std=c11 -S -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: !DIGlobalVariable(name: "i"{{.*}}type: !5, isLocal: false, isDefinition: true)
-// CHECK: !5 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !6)
-// CHECK: !6 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !7)
-// CHECK: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK: !DIGlobalVariable(name: "i"
+// CHECK-SAME: type: ![[T:.*]], isLocal: false, isDefinition: true)
+// CHECK: ![[T]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[BT:.*]])
+// CHECK: ![[BT]] = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: ![[BTT:.*]])
+// CHECK: ![[BTT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
 _Atomic const int i;
diff --git a/test/CodeGen/debug-info-file-checksum.c b/test/CodeGen/debug-info-file-checksum.c
new file mode 100644
index 0000000..2750800
--- /dev/null
+++ b/test/CodeGen/debug-info-file-checksum.c
@@ -0,0 +1,5 @@
+// RUN: %clang -emit-llvm -S -g -gcodeview -x c %S/Inputs/debug-info-file-checksum.c -o - | FileCheck %s
+
+// Check that "checksum" is created correctly for the compiled file.
+
+// CHECK: !DIFile(filename:{{.*}}, directory:{{.*}}, checksumkind: CSK_MD5, checksum: "a3b7d27af071accdeccaa933fc603608")
diff --git a/test/CodeGen/debug-info-global-constant.c b/test/CodeGen/debug-info-global-constant.c
index f214fdc..4175f24 100644
--- a/test/CodeGen/debug-info-global-constant.c
+++ b/test/CodeGen/debug-info-global-constant.c
@@ -5,8 +5,8 @@
 // exactly once.
 
 // CHECK: @i = internal constant i32 1, align 4, !dbg ![[I:[0-9]+]]
-// CHECK: ![[I]] = distinct !DIGlobalVariable(name: "i",
-// CHECK-SAME:                                expr: ![[EXPR:[0-9]+]]
+// CHECK: ![[I]] = !DIGlobalVariableExpression(var: ![[VAR:.*]], expr: ![[EXPR:[0-9]+]])
+// CHECK: ![[VAR]] = distinct !DIGlobalVariable(name: "i",
 // CHECK: !DICompileUnit({{.*}}globals: ![[GLOBALS:[0-9]+]])
 // CHECK: ![[GLOBALS]] = !{![[I]]}
 // CHECK: ![[EXPR]] = !DIExpression(DW_OP_constu, 1, DW_OP_stack_value)
diff --git a/test/CodeGen/debug-info-macro.c b/test/CodeGen/debug-info-macro.c
new file mode 100644
index 0000000..889c7ff
--- /dev/null
+++ b/test/CodeGen/debug-info-macro.c
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=line-tables-only -debug-info-macro %s -o - "-DC1(x)=( x  + 5 )" -DA -include %S/Inputs/debug-info-macro.h -UC1 | FileCheck -check-prefixes=CHECK,NO_PCH %s 
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited          -debug-info-macro %s -o - "-DC1(x)=( x  + 5 )" -DA -include %S/Inputs/debug-info-macro.h -UC1 | FileCheck -check-prefixes=CHECK,NO_PCH %s 
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone       -debug-info-macro %s -o - "-DC1(x)=( x  + 5 )" -DA -include %S/Inputs/debug-info-macro.h -UC1 | FileCheck -check-prefixes=CHECK,NO_PCH %s 
+// RUN: %clang_cc1 -emit-llvm                                   -debug-info-macro %s -o - "-DC1(x)=( x  + 5 )" -DA -include %S/Inputs/debug-info-macro.h -UC1 | FileCheck -check-prefixes=NO_MACRO %s 
+
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -debug-info-macro %S/Inputs/debug-info-macro.h -emit-pch -o %t.pch -DC3
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -debug-info-macro %s -o - -include-pch %t.pch "-DC1(x)=( x  + 5 )" -DA -include %S/Inputs/debug-info-macro.h -UC1 | FileCheck -check-prefixes=CHECK,PCH %s 
+
+// This test checks that macro Debug info is correctly generated.
+
+// TODO: Check for an following entry once support macros defined in pch files.
+// -PCH: !DIMacro(type: DW_MACINFO_define, name: "C3", value: "1")>
+
+#line 15
+/*Line 15*/ #define D1 1
+/*Line 16*/ #include  "Inputs/debug-info-macro.h"
+/*Line 17*/ #undef D1
+/*Line 18*/ #define D2 2
+/*Line 19*/ #include  "Inputs/debug-info-macro.h"
+/*Line 20*/ #undef D2
+
+// NO_MACRO-NOT: macros
+// NO_MACRO-NOT: DIMacro
+// NO_MACRO-NOT: DIMacroFile
+
+// CHECK:  !DICompileUnit({{.*}} macros: [[Macros:![0-9]+]])
+// CHECK:  [[EmptyMD:![0-9]+]] = !{}
+
+// NO_PCH: [[Macros]] = !{[[MainMacroFile:![0-9]+]], [[BuiltinMacro:![0-9]+]], {{.*}}, [[DefineC1:![0-9]+]], [[DefineA:![0-9]+]], [[UndefC1:![0-9]+]]}
+// PCH:    [[Macros]] = !{[[MainMacroFile:![0-9]+]], [[DefineC1:![0-9]+]], [[DefineA:![0-9]+]], [[UndefC1:![0-9]+]]}
+
+// CHECK:  [[MainMacroFile]] = !DIMacroFile(file: [[MainFile:![0-9]+]], nodes: [[N1:![0-9]+]])
+// CHECK:  [[MainFile]] = !DIFile(filename: "{{.*}}debug-info-macro.c"
+// CHECK:  [[N1]] = !{[[CommandLineInclude:![0-9]+]], [[DefineD1:![0-9]+]], [[FileInclude1:![0-9]+]], [[UndefD1:![0-9]+]], [[DefineD2:![0-9]+]], [[FileInclude2:![0-9]+]], [[UndefD2:![0-9]+]]}
+
+// CHECK:  [[CommandLineInclude]] = !DIMacroFile(file: [[HeaderFile:![0-9]+]], nodes: [[N2:![0-9]+]])
+// CHECK:  [[HeaderFile]] = !DIFile(filename: "{{.*}}debug-info-macro.h"
+// CHECK:  [[N2]] = !{[[UndefA:![0-9]+]]}
+// CHECK:  [[UndefA]] = !DIMacro(type: DW_MACINFO_undef, line: 11, name: "A")
+
+// CHECK:  [[DefineD1]] = !DIMacro(type: DW_MACINFO_define, line: 15, name: "D1", value: "1")
+// CHECK:  [[FileInclude1]] = !DIMacroFile(line: 16, file: [[HeaderFile]], nodes: [[N3:![0-9]+]])
+// CHECK:  [[N3]] = !{[[DefineAx:![0-9]+]], [[UndefA]]}
+// CHECK:  [[DefineAx]] = !DIMacro(type: DW_MACINFO_define, line: 3, name: "A(x,y,z)", value: "(x)")
+// CHECK:  [[UndefD1]] = !DIMacro(type: DW_MACINFO_undef, line: 17, name: "D1") 
+
+// CHECK:  [[DefineD2]] = !DIMacro(type: DW_MACINFO_define, line: 18, name: "D2", value: "2")
+// CHECK:  [[FileInclude2]] = !DIMacroFile(line: 19, file: [[HeaderFile]], nodes: [[N4:![0-9]+]])
+// CHECK:  [[N4]] = !{[[DefineAy:![0-9]+]], [[UndefA]]}
+// CHECK:  [[DefineAy]] = !DIMacro(type: DW_MACINFO_define, line: 7, name: "A(x,y,z)", value: "(y)")
+// CHECK:  [[UndefD2]] = !DIMacro(type: DW_MACINFO_undef, line: 20, name: "D2")
+
+// NO_PCH: [[BuiltinMacro]] = !DIMacro(type: DW_MACINFO_define, name: "__llvm__", value: "1")
+
+// CHECK:  [[DefineC1]] = !DIMacro(type: DW_MACINFO_define, name: "C1(x)", value: "( x + 5 )")
+// CHECK:  [[DefineA]] = !DIMacro(type: DW_MACINFO_define, name: "A", value: "1")
+// CHECK:  [[UndefC1]] = !DIMacro(type: DW_MACINFO_undef, name: "C1")
diff --git a/test/CodeGen/debug-info-static-const-fp.c b/test/CodeGen/debug-info-static-const-fp.c
index 6ca2d5d..4dfe057 100644
--- a/test/CodeGen/debug-info-static-const-fp.c
+++ b/test/CodeGen/debug-info-static-const-fp.c
@@ -1,7 +1,25 @@
-// RUN: %clang -emit-llvm -O0 -S -g %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -O0 -debug-info-kind=limited %s -o - | \
+// RUN:   FileCheck --check-prefixes CHECK %s
+
+// RUN: %clang_cc1 -triple hexagon-unknown--elf -emit-llvm -O0 -debug-info-kind=limited %s -o - | \
+// RUN:   FileCheck --check-prefixes CHECK,CHECK-LDsm %s
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -O0 -debug-info-kind=limited %s -o - | \
+// RUN:   FileCheck --check-prefixes CHECK,CHECK-LDlg %s
 
 // Per PR26619, check that for referenced static const of floating-point type,
-// we emit its constant value in debug info.  NOTE that PR26619 is not yet fixed for long double.
+// we emit its constant value in debug info.
+//
+// NOTE that __fp16 is assumed to be 16 bits, float is assumed to be
+// 32 bits, and double is assumed to be 64 bits.  Size of long double
+// is not known (for example, it is 64 bits for hexagon-unknown--elf,
+// but 128 bits for x86_64-unknown-linux-gnu).  Therefore, we specify
+// target triples where it has a known size, and check accordingly:
+// for the absence of a constant (CHECK-LDlg) when the size exceeds 64
+// bits, and for the presence of a constant (CHECK-LDsm) but not its
+// value when the size does not exceed 64 bits.
+//
+// NOTE that PR26619 is not yet fixed for types greater than 64 bits.
 
 static const __fp16 hVal = 29/13.0f;            //    2.2307692307692307692     (2.23046875)
 
@@ -9,23 +27,28 @@
 
 static const double dVal = 19637/7.0;           // 2805.2857142857142857        (2805.2857142857142)
 
-static const long double ldVal = 3/1234567.0L;  //    2.4300017739012949479e-06 (<optimized out>)
+static const long double ldVal = 3/1234567.0L;  //    2.4300017739012949479e-06 (<depends on size of long double>)
 
 int main() {
   return hVal + fVal + dVal + ldVal;
 }
 
-// CHECK: !DIGlobalVariable(name: "hVal", {{.*}}, isLocal: true, isDefinition: true, expr: ![[HEXPR:[0-9]+]]
-// CHECK: ![[HEXPR]] = !DIExpression(DW_OP_constu, 16502, DW_OP_stack_value)
+// CHECK: !DIGlobalVariableExpression(var: [[HVAL:.*]], expr: [[HEXPR:.*]])
+// CHECK: [[HVAL]] = distinct !DIGlobalVariable(name: "hVal",
+// CHECK-SAME:                                  isLocal: true, isDefinition: true
+// CHECK: [[HEXPR]] = !DIExpression(DW_OP_constu, 16502, DW_OP_stack_value)
 
-// CHECK: !DIGlobalVariable(name: "fVal", {{.*}}, isLocal: true, isDefinition: true, expr: ![[FEXPR:[0-9]+]]
-// CHECK: ![[FEXPR]] = !DIExpression(DW_OP_constu, 3238681178, DW_OP_stack_value)
+// CHECK: !DIGlobalVariableExpression(var: [[FVAL:.*]], expr: [[FEXPR:.*]])
+// CHECK: [[FVAL]] = distinct !DIGlobalVariable(name: "fVal",
+// CHECK-SAME:                                  isLocal: true, isDefinition: true
+// CHECK: [[FEXPR]] = !DIExpression(DW_OP_constu, 3238681178, DW_OP_stack_value)
 
-// CHECK: !DIGlobalVariable(name: "dVal", {{.*}}, isLocal: true, isDefinition: true, expr: ![[DEXPR:[0-9]+]]
-// CHECK: ![[DEXPR]] = !DIExpression(DW_OP_constu, 4658387303597904457, DW_OP_stack_value)
+// CHECK: !DIGlobalVariableExpression(var: [[DVAL:.*]], expr: [[DEXPR:.*]])
+// CHECK: [[DVAL]] = distinct !DIGlobalVariable(name: "dVal",
+// CHECK-SAME:                                  isLocal: true, isDefinition: true
+// CHECK: [[DEXPR]] = !DIExpression(DW_OP_constu, 4658387303597904457, DW_OP_stack_value)
 
-// Temporarily removing this check -- for some targets (such as
-// "--target=hexagon-unknown-elf"), long double does not exceed 64
-// bits, and so we actually do get the constant value (expr) emitted.
-//
-// DO-NOT-CHECK: !DIGlobalVariable(name: "ldVal", {{.*}}, isLocal: true, isDefinition: true)
+// CHECK-LDlg-DAG: [[LDVAL:.*]] = distinct !DIGlobalVariable(name: "ldVal", {{.*}}, isLocal: true, isDefinition: true)
+// CHECK-LDlg-DAG: !DIGlobalVariableExpression(var: [[LDVAL]])
+// CHECK-LDsm-DAG: [[LDVAL:.*]] = distinct !DIGlobalVariable(name: "ldVal", {{.*}}, isLocal: true, isDefinition: true)
+// CHECK-LDsm-DAG: !DIGlobalVariableExpression(var: [[LDVAL]], expr:
diff --git a/test/CodeGen/debug-info-static.c b/test/CodeGen/debug-info-static.c
index 0ebd6a6..016f1e6 100644
--- a/test/CodeGen/debug-info-static.c
+++ b/test/CodeGen/debug-info-static.c
@@ -2,7 +2,8 @@
 
 // CHECK: @f.xyzzy = internal global i32 0, align 4, !dbg [[XYZZY:![0-9]+]]
 
-// CHECK: [[XYZZY]] = distinct !DIGlobalVariable
+// CHECK: [[XYZZY]] = !DIGlobalVariableExpression(var: [[VAR:.*]])
+// CHECK: [[VAR]] = distinct !DIGlobalVariable
 void f(void)
 {
    static int xyzzy;
diff --git a/test/CodeGen/decl-in-prototype.c b/test/CodeGen/decl-in-prototype.c
index 15efa65..426adf4 100644
--- a/test/CodeGen/decl-in-prototype.c
+++ b/test/CodeGen/decl-in-prototype.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target i386-unknown-unknown -emit-llvm -S -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-linux -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
 
 const int AA = 5;
 
@@ -19,3 +19,8 @@
     // CHECK: ret i32 0
     return AA;
 }
+
+// This used to crash with debug info enabled.
+int pr31366(struct { enum { a = 1 } b; } c) {
+  return a;
+}
diff --git a/test/CodeGen/fentry.c b/test/CodeGen/fentry.c
new file mode 100644
index 0000000..b913318
--- /dev/null
+++ b/test/CodeGen/fentry.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -pg -mfentry -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck  %s
+// RUN: %clang_cc1 -pg -mfentry -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -mfentry -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix=NOPG %s
+// RUN: %clang_cc1 -mfentry -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=NOPG %s
+
+int foo(void) {
+  return 0;
+}
+
+//CHECK: attributes #{{[0-9]+}} = { {{.*}}"fentry-call"="true"{{.*}} }
+//NOPG-NOT: attributes #{{[0-9]+}} = { {{.*}}"fentry-call"{{.*}} }
diff --git a/test/CodeGen/fixup-depth-overflow.c b/test/CodeGen/fixup-depth-overflow.c
index be8f542..af452d0 100644
--- a/test/CodeGen/fixup-depth-overflow.c
+++ b/test/CodeGen/fixup-depth-overflow.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -O1 -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
 
 #define M if (x) goto L1;
 #define M10 M M M M M M M M M M
diff --git a/test/CodeGen/function-attributes.c b/test/CodeGen/function-attributes.c
index 8f682a7..2139f6f 100644
--- a/test/CodeGen/function-attributes.c
+++ b/test/CodeGen/function-attributes.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -disable-llvm-optzns -Os -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -disable-llvm-optzns -Os -std=c99 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -disable-llvm-passes -Os -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -disable-llvm-passes -Os -std=c99 -o - %s | FileCheck %s
 // CHECK: define signext i8 @f0(i32 %x) [[NUW:#[0-9]+]]
 // CHECK: define zeroext i8 @f1(i32 %x) [[NUW]]
 // CHECK: define void @f2(i8 signext %x) [[NUW]]
diff --git a/test/CodeGen/incomplete-function-type-2.c b/test/CodeGen/incomplete-function-type-2.c
index 41dd5fe..4ed065a 100644
--- a/test/CodeGen/incomplete-function-type-2.c
+++ b/test/CodeGen/incomplete-function-type-2.c
@@ -16,4 +16,4 @@
   p1(0.0);
 }
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGen/inline-optim.c b/test/CodeGen/inline-optim.c
index f8b355a..c6038de 100644
--- a/test/CodeGen/inline-optim.c
+++ b/test/CodeGen/inline-optim.c
@@ -1,9 +1,15 @@
 // Make sure -finline-functions family flags are behaving correctly.
-
+//
+// REQUIRES: x86-registered-target
+//
 // RUN: %clang_cc1 -triple i686-pc-win32 -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fexperimental-new-pass-manager -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
 // RUN: %clang_cc1 -triple i686-pc-win32 -O3 -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
-// RUN: %clang_cc1 -triple i686-pc-win32 -finline-hint-functions -emit-llvm %s -o - | FileCheck -check-prefix=HINT %s
-// RUN: %clang_cc1 -triple i686-pc-win32 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fexperimental-new-pass-manager -O3 -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -O3 -finline-hint-functions -emit-llvm %s -o - | FileCheck -check-prefix=HINT %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fexperimental-new-pass-manager -O3 -finline-hint-functions -emit-llvm %s -o - | FileCheck -check-prefix=HINT %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -O3 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fexperimental-new-pass-manager -O3 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s
 
 inline int inline_hint(int a, int b) { return(a+b); }
 
diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c
index fe7efe3..e17b251 100644
--- a/test/CodeGen/inline.c
+++ b/test/CodeGen/inline.c
@@ -1,5 +1,8 @@
+// REQUIRES: x86-registered-target
+//
 // RUN: echo "GNU89 tests:"
-// RUN: %clang_cc1 %s -triple i386-unknown-unknown -O1 -disable-llvm-optzns -emit-llvm -o - -std=gnu89 | FileCheck %s --check-prefix=CHECK1
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -O1 -disable-llvm-passes -emit-llvm -o - -std=gnu89 | FileCheck %s --check-prefix=CHECK1
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fexperimental-new-pass-manager -O1 -disable-llvm-passes -emit-llvm -o - -std=gnu89 | FileCheck %s --check-prefix=CHECK1
 // CHECK1-LABEL: define i32 @foo()
 // CHECK1-LABEL: define i32 @bar()
 // CHECK1-LABEL: define void @unreferenced1()
@@ -21,7 +24,8 @@
 // CHECK1-LABEL: define available_externally void @gnu_ei_inline()
 
 // RUN: echo "C99 tests:"
-// RUN: %clang_cc1 %s -triple i386-unknown-unknown -O1 -disable-llvm-optzns -emit-llvm -o - -std=gnu99 | FileCheck %s --check-prefix=CHECK2
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -O1 -disable-llvm-passes -emit-llvm -o - -std=gnu99 | FileCheck %s --check-prefix=CHECK2
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fexperimental-new-pass-manager -O1 -disable-llvm-passes -emit-llvm -o - -std=gnu99 | FileCheck %s --check-prefix=CHECK2
 // CHECK2-LABEL: define i32 @ei()
 // CHECK2-LABEL: define i32 @bar()
 // CHECK2-NOT: unreferenced1
@@ -43,7 +47,8 @@
 // CHECK2-LABEL: define available_externally void @gnu_ei_inline()
 
 // RUN: echo "C++ tests:"
-// RUN: %clang_cc1 -x c++ %s -triple i386-unknown-unknown -O1 -disable-llvm-optzns -emit-llvm -o - -std=c++98 | FileCheck %s --check-prefix=CHECK3
+// RUN: %clang_cc1 -x c++ %s -triple i386-unknown-unknown -O1 -disable-llvm-passes -emit-llvm -o - -std=c++98 | FileCheck %s --check-prefix=CHECK3
+// RUN: %clang_cc1 -x c++ %s -triple i386-unknown-unknown -fexperimental-new-pass-manager -O1 -disable-llvm-passes -emit-llvm -o - -std=c++98 | FileCheck %s --check-prefix=CHECK3
 // CHECK3-LABEL: define i32 @_Z3barv()
 // CHECK3-LABEL: define linkonce_odr i32 @_Z3foov()
 // CHECK3-NOT: unreferenced
@@ -53,7 +58,8 @@
 // CHECK3-LABEL: define linkonce_odr i32 @_Z2eiv()
 
 // RUN: echo "MS C Mode tests:"
-// RUN: %clang_cc1 %s -triple i386-pc-win32 -O1 -disable-llvm-optzns -emit-llvm -o - -std=c99 | FileCheck %s --check-prefix=CHECK4
+// RUN: %clang_cc1 %s -triple i386-pc-win32 -O1 -disable-llvm-passes -emit-llvm -o - -std=c99 | FileCheck %s --check-prefix=CHECK4
+// RUN: %clang_cc1 %s -triple i386-pc-win32 -fexperimental-new-pass-manager -O1 -disable-llvm-passes -emit-llvm -o - -std=c99 | FileCheck %s --check-prefix=CHECK4
 // CHECK4-NOT: define weak_odr void @_Exit(
 // CHECK4-LABEL: define weak_odr i32 @ei()
 // CHECK4-LABEL: define i32 @bar()
diff --git a/test/CodeGen/integer-overflow.c b/test/CodeGen/integer-overflow.c
index 6a7c3e5..0b28bc5 100644
--- a/test/CodeGen/integer-overflow.c
+++ b/test/CodeGen/integer-overflow.c
@@ -65,13 +65,37 @@
   // TRAPV: getelementptr inbounds i32, i32*
   // CATCH_UB: getelementptr inbounds i32, i32*
 
-  // PR9350: char increment never overflows.
-  extern volatile signed char PR9350;
+  // PR9350: char pre-increment never overflows.
+  extern volatile signed char PR9350_char_inc;
   // DEFAULT: add i8 {{.*}}, 1
   // WRAPV: add i8 {{.*}}, 1
   // TRAPV: add i8 {{.*}}, 1
   // CATCH_UB: add i8 {{.*}}, 1
-  ++PR9350;
+  ++PR9350_char_inc;
+
+  // PR9350: char pre-decrement never overflows.
+  extern volatile signed char PR9350_char_dec;
+  // DEFAULT: add i8 {{.*}}, -1
+  // WRAPV: add i8 {{.*}}, -1
+  // TRAPV: add i8 {{.*}}, -1
+  // CATCH_UB: add i8 {{.*}}, -1
+  --PR9350_char_dec;
+
+  // PR9350: short pre-increment never overflows.
+  extern volatile signed short PR9350_short_inc;
+  // DEFAULT: add i16 {{.*}}, 1
+  // WRAPV: add i16 {{.*}}, 1
+  // TRAPV: add i16 {{.*}}, 1
+  // CATCH_UB: add i16 {{.*}}, 1
+  ++PR9350_short_inc;
+
+  // PR9350: short pre-decrement never overflows.
+  extern volatile signed short PR9350_short_dec;
+  // DEFAULT: add i16 {{.*}}, -1
+  // WRAPV: add i16 {{.*}}, -1
+  // TRAPV: add i16 {{.*}}, -1
+  // CATCH_UB: add i16 {{.*}}, -1
+  --PR9350_short_dec;
 
   // PR24256: don't instrument __builtin_frame_address.
   __builtin_frame_address(0 + 0);
diff --git a/test/CodeGen/libcall-declarations.c b/test/CodeGen/libcall-declarations.c
index 345b74f..5a0b2ba 100644
--- a/test/CodeGen/libcall-declarations.c
+++ b/test/CodeGen/libcall-declarations.c
@@ -402,9 +402,9 @@
 // CHECK-NOERRNO: declare i32 @ilogb(double) [[NUW]]
 // CHECK-NOERRNO: declare i32 @ilogbf(float) [[NUW]]
 // CHECK-NOERRNO: declare i32 @ilogbl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @lgamma(double) [[NUW]]
-// CHECK-NOERRNO: declare float @lgammaf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare double @lgamma(double) [[NONCONST:#[0-9]+]]
+// CHECK-NOERRNO: declare float @lgammaf(float) [[NONCONST]]
+// CHECK-NOERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NONCONST]]
 // CHECK-NOERRNO: declare i64 @llrint(double) [[NUW]]
 // CHECK-NOERRNO: declare i64 @llrintf(float) [[NUW]]
 // CHECK-NOERRNO: declare i64 @llrintl(x86_fp80) [[NUW]]
@@ -554,6 +554,9 @@
 // CHECK-ERRNO: declare double @fmin(double, double) [[NUW]]
 // CHECK-ERRNO: declare float @fminf(float, float) [[NUW]]
 // CHECK-ERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare double @lgamma(double) [[NONCONST:#[0-9]+]]
+// CHECK-ERRNO: declare float @lgammaf(float) [[NONCONST]]
+// CHECK-ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NONCONST]]
 // CHECK-ERRNO: declare double @nearbyint(double) [[NUW]]
 // CHECK-ERRNO: declare float @nearbyintf(float) [[NUW]]
 // CHECK-ERRNO: declare x86_fp80 @nearbyintl(x86_fp80) [[NUW]]
@@ -612,5 +615,11 @@
 // CHECK-ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[NUW]]
 
 // CHECK-NOERRNO: attributes [[NUW]] = { nounwind readnone{{.*}} }
+// CHECK-NOERRNO: attributes [[NONCONST]] = {
+// CHECK-NOERRNO-NOT: readnone
+// CHECK-NOERRNO-SAME: nounwind{{.*}} }
 
+// CHECK-ERRNO: attributes [[NONCONST]] = {
+// CHECK-ERRNO-NOT: readnone
+// CHECK-ERRNO-SAME: nounwind{{.*}} }
 // CHECK-ERRNO: attributes [[NUW]] = { nounwind readnone{{.*}} }
diff --git a/test/CodeGen/lifetime2.c b/test/CodeGen/lifetime2.c
index 0d22282..55c6d91 100644
--- a/test/CodeGen/lifetime2.c
+++ b/test/CodeGen/lifetime2.c
@@ -1,5 +1,7 @@
-// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefixes=CHECK,O2
-// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
+// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s -check-prefixes=CHECK,O2
+// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-lifetime-markers %s \
+// RUN:       | FileCheck %s -check-prefixes=CHECK,O0
+// RUN: %clang_cc1 -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
 
 extern int bar(char *A, int n);
 
@@ -23,13 +25,11 @@
   char x;
 l1:
   bar(&x, 1);
-  // O2: @llvm.lifetime.start(i64 5
-  // O2: @llvm.lifetime.end(i64 5
   char y[5];
   bar(y, 5);
   goto l1;
   // Infinite loop
-  // O2-NOT: @llvm.lifetime.end(i64 1
+  // O2-NOT: @llvm.lifetime.end(
 }
 
 // CHECK-LABEL: @goto_bypass
@@ -89,3 +89,27 @@
 L:
   bar(&x, 1);
 }
+
+// O2-LABEL: @jump_backward_over_declaration(
+// O2: %[[p:.*]] = alloca i32*
+// O2: %[[v0:.*]] = bitcast i32** %[[p]] to i8*
+// O2: call void @llvm.lifetime.start(i64 {{.*}}, i8* %[[v0]])
+// O2-NOT: call void @llvm.lifetime.start(
+
+extern void foo2(int p);
+
+int jump_backward_over_declaration(int a) {
+  int *p = 0;
+label1:
+  if (p) {
+    foo2(*p);
+    return 0;
+  }
+
+  int i = 999;
+  if (a != 2) {
+    p = &i;
+    goto label1;
+  }
+  return -1;
+}
diff --git a/test/CodeGen/may-alias.c b/test/CodeGen/may-alias.c
index 520b7ab..41eda85 100644
--- a/test/CodeGen/may-alias.c
+++ b/test/CodeGen/may-alias.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -no-struct-path-tbaa -disable-llvm-optzns -o - %s | FileCheck %s
-// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-optzns -o - %s | FileCheck %s -check-prefix=PATH
+// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -no-struct-path-tbaa -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-passes -o - %s | FileCheck %s -check-prefix=PATH
 
 // Types with the may_alias attribute should be considered equivalent
 // to char for aliasing.
diff --git a/test/CodeGen/mips16-attr.c b/test/CodeGen/mips16-attr.c
index 18799be..128a1bd 100644
--- a/test/CodeGen/mips16-attr.c
+++ b/test/CodeGen/mips16-attr.c
@@ -11,7 +11,7 @@
 
 // CHECK: define void @nofoo() [[NOMIPS16:#[0-9]+]]
 
-// CHECK: attributes [[MIPS16]] = { nounwind {{.*}} "mips16" {{.*}} }
+// CHECK: attributes [[MIPS16]] = { noinline nounwind {{.*}} "mips16" {{.*}} }
 
-// CHECK: attributes [[NOMIPS16]]  = { nounwind {{.*}} "nomips16" {{.*}} }
+// CHECK: attributes [[NOMIPS16]]  = { noinline nounwind {{.*}} "nomips16" {{.*}} }
 
diff --git a/test/CodeGen/mrtd.c b/test/CodeGen/mrtd.c
index 8d2aeee..e526e0b 100644
--- a/test/CodeGen/mrtd.c
+++ b/test/CodeGen/mrtd.c
@@ -25,4 +25,4 @@
 // CHECK-LABEL: define x86_stdcallcc void @quux
 // CHECK: call void (i32, ...) @qux
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGen/ms-declspecs.c b/test/CodeGen/ms-declspecs.c
index 91f5aa2..05810bb 100644
--- a/test/CodeGen/ms-declspecs.c
+++ b/test/CodeGen/ms-declspecs.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -O2 -disable-llvm-passes -o - | FileCheck %s
 
 __declspec(selectany) int x1 = 1;
 const __declspec(selectany) int x2 = 2;
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index 6efc09a..69b732c 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -55,9 +55,15 @@
     }
   }
   __asm {}
+  __asm {
+    ;
+    ; label
+    mov eax, ebx
+  }
 // CHECK: t7
 // CHECK: call void asm sideeffect inteldialect "int $$0x2cU", "~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, ebx", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 }
 
 int t8() {
@@ -643,6 +649,14 @@
   // CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:", "~{dirflag},~{fpsr},~{flags}"()
 }
 
+// Don't include mxcsr in the clobber list.
+void mxcsr() {
+  char buf[4096];
+  __asm fxrstor buf
+}
+// CHECK-LABEL: define void @mxcsr
+// CHECK: call void asm sideeffect inteldialect "fxrstor byte ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"
+
 typedef union _LARGE_INTEGER {
   struct {
     unsigned int LowPart;
diff --git a/test/CodeGen/ms-intrinsics.c b/test/CodeGen/ms-intrinsics.c
index 25eae44..2d4ca5c 100644
--- a/test/CodeGen/ms-intrinsics.c
+++ b/test/CodeGen/ms-intrinsics.c
@@ -3,7 +3,7 @@
 // RUN:         | FileCheck %s -check-prefixes CHECK,CHECK-I386,CHECK-INTEL
 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
 // RUN:         -triple thumbv7--windows -Oz -emit-llvm %s -o - \
-// RUN:         | FileCheck %s --check-prefixes CHECK,CHECK-ARM-X64
+// RUN:         | FileCheck %s --check-prefixes CHECK,CHECK-ARM,CHECK-ARM-X64
 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
 // RUN:         -triple x86_64--windows -Oz -emit-llvm %s -o - \
 // RUN:         | FileCheck %s --check-prefixes CHECK,CHECK-X64,CHECK-ARM-X64,CHECK-INTEL
@@ -28,6 +28,20 @@
 // CHECK-X64:   tail call void @llvm.memset.p0i8.i64(i8* %Dest, i8 %Data, i64 %Count, i32 1, i1 true)
 // CHECK-X64:   ret void
 // CHECK-X64: }
+
+void test__ud2(void) {
+  __ud2();
+}
+// CHECK-INTEL-LABEL: define{{.*}} void @test__ud2()
+// CHECK-INTEL: call void @llvm.trap()
+
+void test__int2c(void) {
+  __int2c();
+}
+// CHECK-INTEL-LABEL: define{{.*}} void @test__int2c()
+// CHECK-INTEL: call void asm sideeffect "int $$0x2c", ""() #[[NORETURN:[0-9]+]]
+
+
 #endif
 
 void *test_ReturnAddress() {
@@ -419,3 +433,15 @@
 // CHECK-ARM-X64: }
 
 #endif
+
+void test__fastfail() {
+  __fastfail(42);
+}
+// CHECK-LABEL: define{{.*}} void @test__fastfail()
+// CHECK-ARM: call void asm sideeffect "udf #251", "{r0}"(i32 42) #[[NORETURN:[0-9]+]]
+// CHECK-INTEL: call void asm sideeffect "int $$0x29", "{cx}"(i32 42) #[[NORETURN]]
+
+// Attributes come last.
+
+// CHECK: attributes #[[NORETURN]] = { noreturn{{.*}} }
+
diff --git a/test/CodeGen/object-size.c b/test/CodeGen/object-size.c
index a3f3bce..a824f55 100644
--- a/test/CodeGen/object-size.c
+++ b/test/CodeGen/object-size.c
@@ -536,3 +536,35 @@
   // CHECK: store i32 14
   gi = __builtin_object_size(sa->sa_data, 3);
 }
+
+extern char incomplete_char_array[];
+// CHECK-LABEL: @incomplete_and_function_types
+int incomplete_and_function_types() {
+  // CHECK: call i64 @llvm.objectsize.i64.p0i8
+  gi = __builtin_object_size(incomplete_char_array, 0);
+  // CHECK: call i64 @llvm.objectsize.i64.p0i8
+  gi = __builtin_object_size(incomplete_char_array, 1);
+  // CHECK: call i64 @llvm.objectsize.i64.p0i8
+  gi = __builtin_object_size(incomplete_char_array, 2);
+  // CHECK: store i32 0
+  gi = __builtin_object_size(incomplete_char_array, 3);
+}
+
+// Flips between the pointer and lvalue evaluator a lot.
+void deeply_nested() {
+  struct {
+    struct {
+      struct {
+        struct {
+          int e[2];
+          char f; // Inhibit our writing-off-the-end check
+        } d[2];
+      } c[2];
+    } b[2];
+  } *a;
+
+  // CHECK: store i32 4
+  gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 1);
+  // CHECK: store i32 4
+  gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 3);
+}
diff --git a/test/CodeGen/opt-record-MIR.c b/test/CodeGen/opt-record-MIR.c
new file mode 100644
index 0000000..00b91ff
--- /dev/null
+++ b/test/CodeGen/opt-record-MIR.c
@@ -0,0 +1,33 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -Rpass-missed=regalloc 2>&1 | FileCheck -check-prefix=REMARK %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info 2>&1 | FileCheck -allow-empty -check-prefix=NO_REMARK %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -opt-record-file %t.yaml
+// RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s
+
+void bar(float);
+
+void foo(float *p, int i) {
+  while (i--)  {
+    float f = *p;
+    asm("" ::
+        : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp", "memory");
+    bar(f);
+  }
+}
+
+// REMARK: opt-record-MIR.c:10:11: remark: {{.}} spills {{.}} reloads generated in loop
+// NO_REMARK-NOT: remark:
+
+// YAML: --- !Missed
+// YAML: Pass:            regalloc
+// YAML: Name:            LoopSpillReload
+// YAML: DebugLoc:        { File: {{.*}},
+// YAML:                    Line: 10, Column: 11 }
+// YAML: Function:        foo
+// YAML: Args:
+// YAML:   - NumSpills:       '{{.}}'
+// YAML:   - String:          ' spills '
+// YAML:   - NumReloads:      '{{.}}'
+// YAML:   - String:          ' reloads '
+// YAML:   - String:          generated
+// YAML: ...
diff --git a/test/CodeGen/pass-object-size.c b/test/CodeGen/pass-object-size.c
index 6f5827b..f5c1231 100644
--- a/test/CodeGen/pass-object-size.c
+++ b/test/CodeGen/pass-object-size.c
@@ -343,16 +343,26 @@
 
 // CHECK-LABEL: define void @test13
 void test13() {
-  // Ensuring that we don't lower objectsize if the expression has side-effects
   char c[10];
+  unsigned i = 0;
   char *p = c;
 
   // CHECK: @llvm.objectsize
   ObjectSize0(p);
 
-  // CHECK-NOT: @llvm.objectsize
-  ObjectSize0(++p);
-  ObjectSize0(p++);
+  // Allow side-effects, since they always need to happen anyway. Just make sure
+  // we don't perform them twice.
+  // CHECK: = add
+  // CHECK-NOT: = add
+  // CHECK: @llvm.objectsize
+  // CHECK: call i32 @ObjectSize0
+  ObjectSize0(p + ++i);
+
+  // CHECK: = add
+  // CHECK: @llvm.objectsize
+  // CHECK-NOT: = add
+  // CHECK: call i32 @ObjectSize0
+  ObjectSize0(p + i++);
 }
 
 // There was a bug where variadic functions with pass_object_size would cause
@@ -369,3 +379,42 @@
   // CHECK: call void (i8*, i64, ...) @my_sprintf
   my_sprintf(c, 1, 2, 3);
 }
+
+void pass_size_unsigned(unsigned *const PS(0));
+
+// Bug: we weren't lowering to the proper @llvm.objectsize for pointers that
+// don't turn into i8*s, which caused crashes.
+// CHECK-LABEL: define void @test15
+void test15(unsigned *I) {
+  // CHECK: @llvm.objectsize.i64.p0i32
+  // CHECK: call void @pass_size_unsigned
+  pass_size_unsigned(I);
+}
+
+void pass_size_as1(__attribute__((address_space(1))) void *const PS(0));
+
+void pass_size_unsigned_as1(
+    __attribute__((address_space(1))) unsigned *const PS(0));
+
+// CHECK-LABEL: define void @test16
+void test16(__attribute__((address_space(1))) unsigned *I) {
+  // CHECK: call i64 @llvm.objectsize.i64.p1i8
+  // CHECK: call void @pass_size_as1
+  pass_size_as1(I);
+  // CHECK: call i64 @llvm.objectsize.i64.p1i32
+  // CHECK: call void @pass_size_unsigned_as1
+  pass_size_unsigned_as1(I);
+}
+
+// This used to cause assertion failures, since we'd try to emit the statement
+// expression (and definitions for `a`) twice.
+// CHECK-LABEL: define void @test17
+void test17(char *C) {
+  // Check for 65535 to see if we're emitting this pointer twice.
+  // CHECK: 65535
+  // CHECK-NOT: 65535
+  // CHECK: @llvm.objectsize.i64.p0i8(i8* [[PTR:%[^,]+]],
+  // CHECK-NOT: 65535
+  // CHECK: call i32 @ObjectSize0(i8* [[PTR]]
+  ObjectSize0(C + ({ int a = 65535; a; }));
+}
diff --git a/test/CodeGen/ppc64-complex-parms.c b/test/CodeGen/ppc64-complex-parms.c
index 3f2a0c2..c0e1794 100644
--- a/test/CodeGen/ppc64-complex-parms.c
+++ b/test/CodeGen/ppc64-complex-parms.c
@@ -93,7 +93,7 @@
 // CHECK: %[[VAR22:[A-Za-z0-9.]+]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, { ppc_fp128, ppc_fp128 }* %[[VAR21]], i32 0, i32 0
 // CHECK: %[[VAR23:[A-Za-z0-9.]+]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, { ppc_fp128, ppc_fp128 }* %[[VAR21]], i32 0, i32 1
 // CHECK: store ppc_fp128 0xM40000000000000000000000000000000, ppc_fp128* %[[VAR22]]
-// CHECK: store ppc_fp128 0xMC0040000000000000000000000000000, ppc_fp128* %[[VAR23]]
+// CHECK: store ppc_fp128 0xMC0040000000000008000000000000000, ppc_fp128* %[[VAR23]]
 // CHECK: %[[VAR24:[A-Za-z0-9.]+]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, { ppc_fp128, ppc_fp128 }* %[[VAR21]], i32 0, i32 0
 // CHECK: %[[VAR25:[A-Za-z0-9.]+]] = load ppc_fp128, ppc_fp128* %[[VAR24]], align 16
 // CHECK: %[[VAR26:[A-Za-z0-9.]+]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, { ppc_fp128, ppc_fp128 }* %[[VAR21]], i32 0, i32 1
@@ -180,4 +180,4 @@
 // CHECK: %[[VAR77:[A-Za-z0-9.]+]] = load i64, i64* %[[VAR76]], align 8
 // CHECK: %{{[A-Za-z0-9.]+}} = call i64 @foo_long_long(i64 %[[VAR75]], i64 %[[VAR77]])
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGen/ppc64-complex-return.c b/test/CodeGen/ppc64-complex-return.c
index cdb0ed6..02bfe82 100644
--- a/test/CodeGen/ppc64-complex-return.c
+++ b/test/CodeGen/ppc64-complex-return.c
@@ -126,4 +126,4 @@
 // CHECK: extractvalue { i64, i64 } [[VAR8]], 1
 
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGen/ppc64-extend.c b/test/CodeGen/ppc64-extend.c
index 52e5f13..6b596b4 100644
--- a/test/CodeGen/ppc64-extend.c
+++ b/test/CodeGen/ppc64-extend.c
@@ -13,4 +13,4 @@
 unsigned int f4(void) { return 0; }
 // CHECK: define zeroext i32 @f4() [[NUW]]
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGen/sanitize-init-order.cpp b/test/CodeGen/sanitize-init-order.cpp
index 894f75e..f6a4140 100644
--- a/test/CodeGen/sanitize-init-order.cpp
+++ b/test/CodeGen/sanitize-init-order.cpp
@@ -36,13 +36,13 @@
 
 // Check that ASan init-order checking ignores structs with trivial default
 // constructor.
-// CHECK: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]], ![[GLOB_4:[0-9]]]}
+// CHECK: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]+]], ![[GLOB_4:[0-9]+]]
 // CHECK: ![[GLOB_1]] = !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
 // CHECK: ![[GLOB_2]] = !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
 // CHECK: ![[GLOB_3]] = !{%struct.PODWithCtorAndDtor* {{.*}}, i1 true, i1 false}
 // CHECK: ![[GLOB_4]] = !{{{.*}}class.NS::PODWithCtor{{.*}}, i1 true, i1 false}
 
-// BLACKLIST: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]], ![[GLOB_4:[0-9]]]}
+// BLACKLIST: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]+]], ![[GLOB_4:[0-9]+]]}
 // BLACKLIST: ![[GLOB_1]] = !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
 // BLACKLIST: ![[GLOB_2]] = !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
 // BLACKLIST: ![[GLOB_3]] = !{%struct.PODWithCtorAndDtor* {{.*}}, i1 false, i1 false}
diff --git a/test/CodeGen/sanitize-recover.c b/test/CodeGen/sanitize-recover.c
index b263f51..6cf7af8 100644
--- a/test/CodeGen/sanitize-recover.c
+++ b/test/CodeGen/sanitize-recover.c
@@ -19,21 +19,18 @@
 void foo() {
   union { int i; } u;
   u.i=1;
-  // PARTIAL:      %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null
-
   // PARTIAL:      %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
-  // PARTIAL-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4
+  // PARTIAL-NEXT: %[[CHECK0:.*]] = icmp uge i64 %[[SIZE]], 4
 
   // PARTIAL:      %[[MISALIGN:.*]] = and i64 {{.*}}, 3
-  // PARTIAL-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0
+  // PARTIAL-NEXT: %[[CHECK1:.*]] = icmp eq i64 %[[MISALIGN]], 0
 
-  // PARTIAL:      %[[CHECK02:.*]] = and i1 %[[CHECK0]], %[[CHECK2]]
-  // PARTIAL-NEXT: %[[CHECK012:.*]] = and i1 %[[CHECK02]], %[[CHECK1]]
+  // PARTIAL:      %[[CHECK01:.*]] = and i1 %[[CHECK1]], %[[CHECK0]]
 
-  // PARTIAL:      br i1 %[[CHECK012]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
+  // PARTIAL:      br i1 %[[CHECK01]], {{.*}} !nosanitize
+  // PARTIAL:      br i1 %[[CHECK1]], {{.*}} !nosanitize
 
-  // PARTIAL:      br i1 %[[CHECK02]], {{.*}}
-  // PARTIAL:      call void @__ubsan_handle_type_mismatch_abort(
+  // PARTIAL:      call void @__ubsan_handle_type_mismatch_v1_abort(
   // PARTIAL-NEXT: unreachable
-  // PARTIAL:      call void @__ubsan_handle_type_mismatch(
+  // PARTIAL:      call void @__ubsan_handle_type_mismatch_v1(
 }
diff --git a/test/CodeGen/sanitize-thread-attr.cpp b/test/CodeGen/sanitize-thread-attr.cpp
index cffe70a..4e0e28e 100644
--- a/test/CodeGen/sanitize-thread-attr.cpp
+++ b/test/CodeGen/sanitize-thread-attr.cpp
@@ -54,9 +54,9 @@
 // BL: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
 // TSAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
 
-// WITHOUT: attributes [[NOATTR]] = { nounwind{{.*}} }
+// WITHOUT: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 
-// BL: attributes [[NOATTR]] = { nounwind{{.*}} }
+// BL: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 
-// TSAN: attributes [[NOATTR]] = { nounwind{{.*}} }
-// TSAN: attributes [[WITH]] = { nounwind sanitize_thread{{.*}} }
+// TSAN: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
+// TSAN: attributes [[WITH]] = { noinline nounwind sanitize_thread{{.*}} }
diff --git a/test/CodeGen/sanitize-thread-no-checking-at-run-time.m b/test/CodeGen/sanitize-thread-no-checking-at-run-time.m
index fade1e3..3d862c0 100644
--- a/test/CodeGen/sanitize-thread-no-checking-at-run-time.m
+++ b/test/CodeGen/sanitize-thread-no-checking-at-run-time.m
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefix=TSAN %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -fblocks -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -fblocks -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefix=TSAN %s
+
+// WITHOUT-NOT: "sanitize_thread_no_checking_at_run_time"
 
 __attribute__((objc_root_class))
 @interface NSObject
@@ -26,9 +28,14 @@
 }
 @end
 
-// WITHOUT-NOT: "sanitize_thread_no_checking_at_run_time"
-
 // TSAN: initialize{{.*}}) [[ATTR:#[0-9]+]]
 // TSAN: dealloc{{.*}}) [[ATTR:#[0-9]+]]
 // TSAN: cxx_destruct{{.*}}) [[ATTR:#[0-9]+]]
-// TSAN: attributes [[ATTR]] = { nounwind {{.*}} "sanitize_thread_no_checking_at_run_time" {{.*}} }
+
+void test2(id x) {
+  extern void test2_helper(id (^)(void));
+  test2_helper(^{ return x; });
+// TSAN: define internal void @__destroy_helper_block_(i8*) [[ATTR:#[0-9]+]]
+}
+
+// TSAN: attributes [[ATTR]] = { noinline nounwind {{.*}} "sanitize_thread_no_checking_at_run_time" {{.*}} }
diff --git a/test/CodeGen/sse-builtins.c b/test/CodeGen/sse-builtins.c
index 27b016f..28b4f2c 100644
--- a/test/CodeGen/sse-builtins.c
+++ b/test/CodeGen/sse-builtins.c
@@ -802,7 +802,7 @@
 
 __m128 test_mm_undefined_ps() {
   // CHECK-LABEL: @test_mm_undefined_ps
-  // CHECK: ret <4 x float> undef
+  // CHECK: ret <4 x float> zeroinitializer
   return _mm_undefined_ps();
 }
 
diff --git a/test/CodeGen/sse2-builtins.c b/test/CodeGen/sse2-builtins.c
index 48c7036..a140a6c 100644
--- a/test/CodeGen/sse2-builtins.c
+++ b/test/CodeGen/sse2-builtins.c
@@ -1455,13 +1455,13 @@
 
 __m128d test_mm_undefined_pd() {
   // CHECK-LABEL: @test_mm_undefined_pd
-  // CHECK: ret <2 x double> undef
+  // CHECK: ret <2 x double> zeroinitializer
   return _mm_undefined_pd();
 }
 
 __m128i test_mm_undefined_si128() {
   // CHECK-LABEL: @test_mm_undefined_si128
-  // CHECK: ret <2 x i64> undef
+  // CHECK: ret <2 x i64> zeroinitializer
   return _mm_undefined_si128();
 }
 
diff --git a/test/CodeGen/tbaa-class.cpp b/test/CodeGen/tbaa-class.cpp
index 7172e05..9b614a1 100644
--- a/test/CodeGen/tbaa-class.cpp
+++ b/test/CodeGen/tbaa-class.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
 // Test TBAA metadata generated by front-end.
 
 typedef unsigned char uint8_t;
diff --git a/test/CodeGen/tbaa-ms-abi.cpp b/test/CodeGen/tbaa-ms-abi.cpp
index 878e1b6..51100b1 100644
--- a/test/CodeGen/tbaa-ms-abi.cpp
+++ b/test/CodeGen/tbaa-ms-abi.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -disable-llvm-optzns -emit-llvm -o - -O1 %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -disable-llvm-passes -emit-llvm -o - -O1 %s | FileCheck %s
 //
 // Test that TBAA works in the Microsoft C++ ABI.  We used to error out while
 // attempting to mangle RTTI.
diff --git a/test/CodeGen/tbaa.cpp b/test/CodeGen/tbaa.cpp
index 432c41e..10e6487 100644
--- a/test/CodeGen/tbaa.cpp
+++ b/test/CodeGen/tbaa.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA
 // Test TBAA metadata generated by front-end.
 //
 // NO-TBAA-NOT: !tbaa
diff --git a/test/CodeGen/thinlto-multi-module.ll b/test/CodeGen/thinlto-multi-module.ll
new file mode 100644
index 0000000..21d28cf
--- /dev/null
+++ b/test/CodeGen/thinlto-multi-module.ll
@@ -0,0 +1,22 @@
+; REQUIRES: x86-registered-target
+
+; RUN: opt -module-summary -o %t1.o %s
+; RUN: llvm-lto -thinlto -o %t %t1.o
+
+; RUN: opt -o %t2.o %S/Inputs/thinlto_backend.ll
+; RUN: llvm-cat -b -o %t1cat.o %t1.o %t2.o
+; RUN: cp %t1cat.o %t1.o
+; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=%t.thinlto.bc
+; RUN: llvm-nm %t3.o | FileCheck --check-prefix=CHECK-OBJ %s
+; CHECK-OBJ: T f1
+; CHECK-OBJ: U f2
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @f2()
+
+define void @f1() {
+  call void @f2()
+  ret void
+}
diff --git a/test/CodeGen/thinlto_backend.ll b/test/CodeGen/thinlto_backend.ll
index 0fb2643..ac0b3b7 100644
--- a/test/CodeGen/thinlto_backend.ll
+++ b/test/CodeGen/thinlto_backend.ll
@@ -9,8 +9,16 @@
 ; CHECK-WARNING: error: invalid argument '-fthinlto-index={{.*}}' only allowed with '-x ir'
 
 ; Ensure we get expected error for missing index file
-; RUN: %clang -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=bad.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR
-; CHECK-ERROR: Error loading index file 'bad.thinlto.bc'
+; RUN: %clang -O2 -o %t4.o -x ir %t1.o -c -fthinlto-index=bad.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR1
+; CHECK-ERROR1: Error loading index file 'bad.thinlto.bc'
+
+; Ensure we ignore empty index file under -ignore-empty-index-file, and run
+; non-ThinLTO compilation which would not import f2
+; RUN: touch %t4.thinlto.bc
+; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t4.o -x ir %t1.o -c -fthinlto-index=%t4.thinlto.bc -mllvm -ignore-empty-index-file
+; RUN: llvm-nm %t4.o | FileCheck --check-prefix=CHECK-OBJ-IGNORE-EMPTY %s
+; CHECK-OBJ-IGNORE-EMPTY: T f1
+; CHECK-OBJ-IGNORE-EMPTY: U f2
 
 ; Ensure f2 was imported
 ; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=%t.thinlto.bc
@@ -18,6 +26,11 @@
 ; CHECK-OBJ: T f1
 ; CHECK-OBJ-NOT: U f2
 
+; Ensure we get expected error for input files without summaries
+; RUN: opt -o %t2.o %s
+; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=%t.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR2
+; CHECK-ERROR2: Error loading imported file '{{.*}}': Could not find module summary
+
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
diff --git a/test/CodeGen/transparent-union.c b/test/CodeGen/transparent-union.c
index 2f00c2d..efaef1b 100644
--- a/test/CodeGen/transparent-union.c
+++ b/test/CodeGen/transparent-union.c
@@ -3,10 +3,21 @@
 // RUN: %clang_cc1 -Werror -triple armv7-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM
 // RUN: %clang_cc1 -Werror -triple powerpc64le-linux -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -Werror -triple aarch64-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -DINFRONT -Werror -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -DINFRONT -Werror -triple i386-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -DINFRONT -Werror -triple armv7-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM
+// RUN: %clang_cc1 -DINFRONT -Werror -triple powerpc64le-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -DINFRONT -Werror -triple aarch64-linux -emit-llvm -o - %s | FileCheck %s
 
+#ifdef INFRONT
+typedef union __attribute__((transparent_union)) {
+  void *f0;
+} transp_t0;
+#else
 typedef union {
   void *f0;
 } transp_t0 __attribute__((transparent_union));
+#endif
 
 void f0(transp_t0 obj);
 
diff --git a/test/CodeGen/ubsan-promoted-arith.cpp b/test/CodeGen/ubsan-promoted-arith.cpp
new file mode 100644
index 0000000..5a2898b
--- /dev/null
+++ b/test/CodeGen/ubsan-promoted-arith.cpp
@@ -0,0 +1,131 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=signed-integer-overflow,unsigned-integer-overflow | FileCheck %s
+
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+typedef int int4 __attribute__((ext_vector_type(4)));
+
+enum E1 : int {
+  a
+};
+
+enum E2 : char {
+  b
+};
+
+// CHECK-LABEL: define signext i8 @_Z4add1
+// CHECK-NOT: sadd.with.overflow
+char add1(char c) { return c + c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4add2
+// CHECK-NOT: uadd.with.overflow
+uchar add2(uchar uc) { return uc + uc; }
+
+// CHECK-LABEL: define i32 @_Z4add3
+// CHECK: sadd.with.overflow
+int add3(E1 e) { return e + a; }
+
+// CHECK-LABEL: define signext i8 @_Z4add4
+// CHECK-NOT: sadd.with.overflow
+char add4(E2 e) { return e + b; }
+
+// CHECK-LABEL: define signext i8 @_Z4sub1
+// CHECK-NOT: ssub.with.overflow
+char sub1(char c) { return c - c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4sub2
+// CHECK-NOT: usub.with.overflow
+uchar sub2(uchar uc) { return uc - uc; }
+
+// CHECK-LABEL: define signext i8 @_Z4sub3
+// CHECK-NOT: ssub.with.overflow
+char sub3(char c) { return -c; }
+
+// Note: -INT_MIN can overflow.
+//
+// CHECK-LABEL: define i32 @_Z4sub4
+// CHECK: ssub.with.overflow
+int sub4(int i) { return -i; }
+
+// CHECK-LABEL: define signext i8 @_Z4mul1
+// CHECK-NOT: smul.with.overflow
+char mul1(char c) { return c * c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4mul2
+// CHECK-NOT: smul.with.overflow
+uchar mul2(uchar uc) { return uc * uc; }
+
+// Note: USHRT_MAX * USHRT_MAX can overflow.
+//
+// CHECK-LABEL: define zeroext i16 @_Z4mul3
+// CHECK: smul.with.overflow
+ushort mul3(ushort us) { return us * us; }
+
+// CHECK-LABEL: define i32 @_Z4mul4
+// CHECK: smul.with.overflow
+int mul4(int i, char c) { return i * c; }
+
+// CHECK-LABEL: define i32 @_Z4mul5
+// CHECK: smul.with.overflow
+int mul5(int i, char c) { return c * i; }
+
+// CHECK-LABEL: define signext i16 @_Z4mul6
+// CHECK-NOT: smul.with.overflow
+short mul6(short s) { return s * s; }
+
+// CHECK-LABEL: define signext i8 @_Z4div1
+// CHECK-NOT: ubsan_handle_divrem_overflow
+char div1(char c) { return c / c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4div2
+// CHECK-NOT: ubsan_handle_divrem_overflow
+uchar div2(uchar uc) { return uc / uc; }
+
+// CHECK-LABEL: define signext i8 @_Z4div3
+// CHECK-NOT: ubsan_handle_divrem_overflow
+char div3(char c, int i) { return c / i; }
+
+// CHECK-LABEL: define signext i8 @_Z4div4
+// CHECK: ubsan_handle_divrem_overflow
+char div4(int i, char c) { return i / c; }
+
+// Note: INT_MIN / -1 can overflow.
+//
+// CHECK-LABEL: define signext i8 @_Z4div5
+// CHECK: ubsan_handle_divrem_overflow
+char div5(int i, char c) { return i / c; }
+
+// CHECK-LABEL: define signext i8 @_Z4rem1
+// CHECK-NOT: ubsan_handle_divrem_overflow
+char rem1(char c) { return c % c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4rem2
+// CHECK-NOT: ubsan_handle_divrem_overflow
+uchar rem2(uchar uc) { return uc % uc; }
+
+// CHECK-LABEL: define signext i8 @_Z4rem3
+// CHECK: ubsan_handle_divrem_overflow
+char rem3(int i, char c) { return i % c; }
+
+// CHECK-LABEL: define signext i8 @_Z4rem4
+// CHECK-NOT: ubsan_handle_divrem_overflow
+char rem4(char c, int i) { return c % i; }
+
+// CHECK-LABEL: define signext i8 @_Z4inc1
+// CHECK-NOT: sadd.with.overflow
+char inc1(char c) { return c++ + (char)0; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4inc2
+// CHECK-NOT: uadd.with.overflow
+uchar inc2(uchar uc) { return uc++ + (uchar)0; }
+
+// CHECK-LABEL: define void @_Z4inc3
+// CHECK-NOT: sadd.with.overflow
+void inc3(char c) { c++; }
+
+// CHECK-LABEL: define void @_Z4inc4
+// CHECK-NOT: uadd.with.overflow
+void inc4(uchar uc) { uc++; }
+
+// CHECK-LABEL: define <4 x i32> @_Z4vremDv4_iS_
+// CHECK-NOT: ubsan_handle_divrem_overflow
+int4 vrem(int4 a, int4 b) { return a % b; }
diff --git a/test/CodeGen/ubsan-shift.c b/test/CodeGen/ubsan-shift.c
new file mode 100644
index 0000000..90c15d8
--- /dev/null
+++ b/test/CodeGen/ubsan-shift.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fsanitize=shift-exponent,shift-base -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: define i32 @f1
+int f1(int c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+  return 1 << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f2
+int f2(long c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 63, !nosanitize
+// CHECK: icmp ule i64 %{{.*}}, 31, !nosanitize
+  return 1 << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f3
+unsigned f3(unsigned c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+  return 1U << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f4
+unsigned f4(unsigned long c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 63, !nosanitize
+// CHECK: icmp ule i64 %{{.*}}, 31, !nosanitize
+  return 1U << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f5
+int f5(int c, long long shamt) {
+// CHECK: icmp ule i64 %{{[0-9]+}}, 31, !nosanitize
+//
+// CHECK: sub nuw nsw i32 31, %sh_prom, !nosanitize
+// CHECK: lshr i32 %{{.*}}, %shl.zeros, !nosanitize
+  return c << shamt;
+}
+
+// CHECK-LABEL: define i32 @f6
+int f6(int c, int shamt) {
+// CHECK: icmp ule i32 %[[WIDTH:.*]], 31, !nosanitize
+//
+// CHECK: sub nuw nsw i32 31, %[[WIDTH]], !nosanitize
+// CHECK: lshr i32 %{{.*}}, %shl.zeros, !nosanitize
+  return c << shamt;
+}
diff --git a/test/CodeGen/unaligned-decl.c b/test/CodeGen/unaligned-decl.c
new file mode 100644
index 0000000..d5d32bd
--- /dev/null
+++ b/test/CodeGen/unaligned-decl.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s
+
+// CHECK: @a1 = global i32 1, align 1
+__unaligned int a1 = 1;
+
+// CHECK: @a2 = global i32 1, align 1
+int __unaligned a2 = 1;
+
+// CHECK: @a3 = {{.*}} align 1
+__unaligned int a3[10];
+
+// CHECK: @a4 = {{.*}} align 1
+int __unaligned a4[10];
+
+// CHECK: @p1 = {{.*}} align 1
+int *__unaligned p1;
+
+// CHECK: @p2 = {{.*}} align 8
+int __unaligned *p2;
+
+// CHECK: @p3 = {{.*}} align 1
+int __unaligned *__unaligned p3;
diff --git a/test/CodeGen/unaligned-expr.c b/test/CodeGen/unaligned-expr.c
new file mode 100644
index 0000000..6e23cbc
--- /dev/null
+++ b/test/CodeGen/unaligned-expr.c
@@ -0,0 +1,217 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s
+
+// -------------
+// Scalar integer
+// -------------
+__unaligned int x;
+void test1(void) {
+  // CHECK: {{%.*}} = load i32, i32* @x, align 1
+  // CHECK: store i32 {{%.*}}, i32* @x, align 1
+  x++;
+}
+
+void test2(void) {
+  // CHECK: %y = alloca i32, align 1
+  // CHECK: {{%.*}} = load i32, i32* %y, align 1
+  // CHECK: store i32 {{%.*}}, i32* %y, align 1
+  __unaligned int y;
+  y++;
+}
+
+void test2_1(void) {
+  // CHECK: %y = alloca i32, align 1
+  // CHECK: store i32 1, i32* %y, align 1
+  __unaligned int y = 1;
+}
+
+// -------------
+// Global pointer
+// -------------
+int *__unaligned p1;
+void test3(void) {
+
+  // CHECK: {{%.*}} = load i32*, i32** @p1, align 1
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 4
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 4
+  (*p1)++;
+}
+
+int __unaligned *p2;
+void test4(void) {
+  // CHECK: {{%.*}} = load i32*, i32** @p2, align 8
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
+  (*p2)++;
+}
+
+int __unaligned *__unaligned p3;
+void test5(void) {
+  // CHECK: {{%.*}} = load i32*, i32** @p3, align 1
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
+  (*p3)++;
+}
+
+// -------------
+// Local pointer
+// -------------
+void test6(void) {
+  // CHECK: %lp1 = alloca i32*, align 1
+  // CHECK: {{%.*}} = load i32*, i32** %lp1, align 1
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 4
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 4
+  int *__unaligned lp1;
+  (*lp1)++;
+}
+
+void test7(void) {
+  // CHECK: %lp2 = alloca i32*, align 8
+  // CHECK: {{%.*}} = load i32*, i32** %lp2, align 8
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
+  int __unaligned *lp2;
+  (*lp2)++;
+}
+
+void test8(void) {
+  // CHECK: %lp3 = alloca i32*, align 1
+  // CHECK: {{%.*}} = load i32*, i32** %lp3, align 1
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
+  int __unaligned *__unaligned lp3;
+  (*lp3)++;
+}
+
+// -------------
+// Global array
+// -------------
+__unaligned int a[10];
+void test9(void) {
+  // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @a, i64 0, i64 3), align 1
+  // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @a, i64 0, i64 3), align 1
+  (a[3])++;
+}
+
+// -------------
+// Local array
+// -------------
+void test10(void) {
+  // CHECK: %la = alloca [10 x i32], align 1
+  // CHECK: {{%.*}} = getelementptr inbounds [10 x i32], [10 x i32]* %la, i64 0, i64 3
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
+  __unaligned int la[10];
+  (la[3])++;
+}
+
+// --------
+// Typedefs
+// --------
+
+typedef __unaligned int UnalignedInt;
+void test13() {
+  // CHECK: %i = alloca i32, align 1
+  // CHECK: {{%.*}} = load i32, i32* %i, align 1
+  // CHECK: store i32 {{%.*}}, i32* %i, align 1
+  UnalignedInt i;
+  i++;
+}
+
+typedef int Aligned;
+typedef __unaligned Aligned UnalignedInt2;
+void test14() {
+  // CHECK: %i = alloca i32, align 1
+  // CHECK: {{%.*}} = load i32, i32* %i, align 1
+  // CHECK: store i32 {{%.*}}, i32* %i, align 1
+  UnalignedInt2 i;
+  i++;
+}
+
+typedef UnalignedInt UnalignedInt3;
+void test15() {
+  // CHECK: %i = alloca i32, align 1
+  // CHECK: {{%.*}} = load i32, i32* %i, align 1
+  // CHECK: store i32 {{%.*}}, i32* %i, align 1
+  UnalignedInt3 i;
+  i++;
+}
+
+// -------------
+// Decayed types
+// -------------
+void test16(__unaligned int c[10]) {
+  // CHECK: {{%.*}} = alloca i32*, align 8
+  // CHECK: store i32* %c, i32** {{%.*}}, align 8
+  // CHECK: {{%.*}} = load i32*, i32** {{%.*}}, align 8
+  // CHECK: {{%.*}} = getelementptr inbounds i32, i32* {{%.*}}, i64 3
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
+  c[3]++;
+}
+
+// -----------
+// __alignof__
+// -----------
+int test17(void) {
+  // CHECK: ret i32 1
+  return __alignof__(__unaligned int);
+}
+
+int test18(void) {
+  // CHECK: ret i32 1
+  __unaligned int a;
+  return __alignof__(a);
+}
+
+int test19(void) {
+  // CHECK: ret i32 1
+  __unaligned int a[10];
+  return __alignof__(a);
+}
+
+// -----------
+// structs
+// -----------
+typedef
+struct S1 {
+    char c;
+    int x;
+} S1;
+
+__unaligned S1 s1;
+void test20(void) {
+    // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds (%struct.S1, %struct.S1* @s1, i32 0, i32 1), align 1
+    // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds (%struct.S1, %struct.S1* @s1, i32 0, i32 1), align 1
+    s1.x++;
+}
+
+void test21(void) {
+  // CHECK: {{%.*}} = alloca %struct.S1, align 1
+  // CHECK: {{%.*}} = getelementptr inbounds %struct.S1, %struct.S1* {{%.*}}, i32 0, i32 1
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
+  __unaligned S1 s1_2;
+  s1_2.x++;
+}
+
+typedef
+struct __attribute__((packed)) S2 {
+    char c;
+    int x;
+} S2;
+
+__unaligned S2 s2;
+void test22(void) {
+    // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds (%struct.S2, %struct.S2* @s2, i32 0, i32 1), align 1
+    // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds (%struct.S2, %struct.S2* @s2, i32 0, i32 1), align 1
+    s2.x++;
+}
+
+void test23(void) {
+  // CHECK: {{%.*}} = alloca %struct.S2, align 1
+  // CHECK: {{%.*}} = getelementptr inbounds %struct.S2, %struct.S2* {{%.*}}, i32 0, i32 1
+  // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
+  // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
+  __unaligned S2 s2_2;
+  s2_2.x++;
+}
diff --git a/test/CodeGen/unaligned-field.c b/test/CodeGen/unaligned-field.c
new file mode 100644
index 0000000..5aa59c2
--- /dev/null
+++ b/test/CodeGen/unaligned-field.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s
+// Test that __unaligned does not impact the layout of the fields.
+
+struct A
+{
+    char a;
+    __unaligned int b;
+} a;
+// CHECK: %struct.A = type { i8, i32 }
+
+struct A2
+{
+    int b;
+    char a;
+    __unaligned int c;
+} a2;
+// CHECK: %struct.A2 = type { i32, i8, i32 }
diff --git a/test/CodeGen/unsigned-promotion.c b/test/CodeGen/unsigned-promotion.c
index 4e7a442..4b13f68 100644
--- a/test/CodeGen/unsigned-promotion.c
+++ b/test/CodeGen/unsigned-promotion.c
@@ -7,53 +7,6 @@
 // RUN:   -fsanitize=unsigned-integer-overflow | FileCheck %s --check-prefix=CHECKU
 
 unsigned short si, sj, sk;
-unsigned char ci, cj, ck;
-
-extern void opaqueshort(unsigned short);
-extern void opaquechar(unsigned char);
-
-// CHECKS-LABEL:   define void @testshortadd()
-// CHECKU-LABEL: define void @testshortadd()
-void testshortadd() {
-  // CHECKS:        load i16, i16* @sj
-  // CHECKS:        load i16, i16* @sk
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_add_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i16, i16* @sj
-  // CHECKU:      [[T2:%.*]] = zext i16 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i16, i16* @sk
-  // CHECKU:      [[T4:%.*]] = zext i16 [[T3]]
-  // CHECKU-NOT:  llvm.sadd
-  // CHECKU-NOT:  llvm.uadd
-  // CHECKU:      [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
-
-  si = sj + sk;
-}
-
-// CHECKS-LABEL:   define void @testshortsub()
-// CHECKU-LABEL: define void @testshortsub()
-void testshortsub() {
-
-  // CHECKS:        load i16, i16* @sj
-  // CHECKS:        load i16, i16* @sk
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_sub_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i16, i16* @sj
-  // CHECKU:      [[T2:%.*]] = zext i16 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i16, i16* @sk
-  // CHECKU:      [[T4:%.*]] = zext i16 [[T3]]
-  // CHECKU-NOT:  llvm.ssub
-  // CHECKU-NOT:  llvm.usub
-  // CHECKU:      [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
-
-  si = sj - sk;
-}
 
 // CHECKS-LABEL:   define void @testshortmul()
 // CHECKU-LABEL: define void @testshortmul()
@@ -75,69 +28,3 @@
   // CHECKU:      [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
   si = sj * sk;
 }
-
-// CHECKS-LABEL:   define void @testcharadd()
-// CHECKU-LABEL: define void @testcharadd()
-void testcharadd() {
-
-  // CHECKS:        load i8, i8* @cj
-  // CHECKS:        load i8, i8* @ck
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_add_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i8, i8* @cj
-  // CHECKU:      [[T2:%.*]] = zext i8 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i8, i8* @ck
-  // CHECKU:      [[T4:%.*]] = zext i8 [[T3]]
-  // CHECKU-NOT:  llvm.sadd
-  // CHECKU-NOT:  llvm.uadd
-  // CHECKU:      [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
-
-  ci = cj + ck;
-}
-
-// CHECKS-LABEL:   define void @testcharsub()
-// CHECKU-LABEL: define void @testcharsub()
-void testcharsub() {
-
-  // CHECKS:        load i8, i8* @cj
-  // CHECKS:        load i8, i8* @ck
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_sub_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i8, i8* @cj
-  // CHECKU:      [[T2:%.*]] = zext i8 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i8, i8* @ck
-  // CHECKU:      [[T4:%.*]] = zext i8 [[T3]]
-  // CHECKU-NOT:  llvm.ssub
-  // CHECKU-NOT:  llvm.usub
-  // CHECKU:      [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
-
-  ci = cj - ck;
-}
-
-// CHECKS-LABEL:   define void @testcharmul()
-// CHECKU-LABEL: define void @testcharmul()
-void testcharmul() {
-
-  // CHECKS:        load i8, i8* @cj
-  // CHECKS:        load i8, i8* @ck
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_mul_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i8, i8* @cj
-  // CHECKU:      [[T2:%.*]] = zext i8 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i8, i8* @ck
-  // CHECKU:      [[T4:%.*]] = zext i8 [[T3]]
-  // CHECKU-NOT:  llvm.smul
-  // CHECKU-NOT:  llvm.umul
-  // CHECKU:      [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
-
-  ci = cj * ck;
-}
diff --git a/test/CodeGen/unwind-attr.c b/test/CodeGen/unwind-attr.c
index 5272375..2065653 100644
--- a/test/CodeGen/unwind-attr.c
+++ b/test/CodeGen/unwind-attr.c
@@ -23,7 +23,7 @@
   return 0;
 }
 
-// CHECK: attributes [[TF]] = { "{{.*}} }
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[TF]] = { noinline "{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
 
-// CHECK-NOEXC: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK-NOEXC: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGen/variadic-null-win64.c b/test/CodeGen/variadic-null-win64.c
index 3e079cb..23c85b8 100644
--- a/test/CodeGen/variadic-null-win64.c
+++ b/test/CodeGen/variadic-null-win64.c
@@ -3,15 +3,21 @@
 
 // Make it possible to pass NULL through variadic functions on platforms where
 // NULL has an integer type that is more narrow than a pointer. On such
-// platforms we widen null pointer constants to a pointer-sized integer.
+// platforms we widen null pointer constants passed to variadic functions to a
+// pointer-sized integer. We don't apply this special case to K&R-style
+// unprototyped functions, because MSVC doesn't either.
 
 #define NULL 0
 
 void v(const char *f, ...);
+void kr();
 void f(const char *f) {
   v(f, 1, 2, 3, NULL);
+  kr(f, 1, 2, 3, 0);
 }
 // WINDOWS: define void @f(i8* %f)
 // WINDOWS: call void (i8*, ...) @v(i8* {{.*}}, i32 1, i32 2, i32 3, i64 0)
+// WINDOWS: call void bitcast (void (...)* @kr to void (i8*, i32, i32, i32, i32)*)(i8* {{.*}}, i32 1, i32 2, i32 3, i32 0)
 // LINUX: define void @f(i8* %f)
 // LINUX: call void (i8*, ...) @v(i8* {{.*}}, i32 1, i32 2, i32 3, i32 0)
+// LINUX: call void (i8*, i32, i32, i32, i32, ...) bitcast (void (...)* @kr to void (i8*, i32, i32, i32, i32, ...)*)(i8* {{.*}}, i32 1, i32 2, i32 3, i32 0)
diff --git a/test/CodeGen/vectorcall.c b/test/CodeGen/vectorcall.c
index b38d5e5..167f72c 100644
--- a/test/CodeGen/vectorcall.c
+++ b/test/CodeGen/vectorcall.c
@@ -1,22 +1,22 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s --check-prefix=X64
+// RUN: %clang_cc1 -emit-llvm %s -o - -ffreestanding -triple=i386-pc-win32       | FileCheck %s --check-prefix=X32
+// RUN: %clang_cc1 -emit-llvm %s -o - -ffreestanding -triple=x86_64-pc-win32     | FileCheck %s --check-prefix=X64
 
 void __vectorcall v1(int a, int b) {}
-// CHECK: define x86_vectorcallcc void @"\01v1@@8"(i32 inreg %a, i32 inreg %b)
+// X32: define x86_vectorcallcc void @"\01v1@@8"(i32 inreg %a, i32 inreg %b)
 // X64: define x86_vectorcallcc void @"\01v1@@16"(i32 %a, i32 %b)
 
 void __vectorcall v2(char a, char b) {}
-// CHECK: define x86_vectorcallcc void @"\01v2@@8"(i8 inreg signext %a, i8 inreg signext %b)
+// X32: define x86_vectorcallcc void @"\01v2@@8"(i8 inreg signext %a, i8 inreg signext %b)
 // X64: define x86_vectorcallcc void @"\01v2@@16"(i8 %a, i8 %b)
 
 struct Small { int x; };
 void __vectorcall v3(int a, struct Small b, int c) {}
-// CHECK: define x86_vectorcallcc void @"\01v3@@12"(i32 inreg %a, i32 %b.0, i32 inreg %c)
+// X32: define x86_vectorcallcc void @"\01v3@@12"(i32 inreg %a, i32 %b.0, i32 inreg %c)
 // X64: define x86_vectorcallcc void @"\01v3@@24"(i32 %a, i32 %b.coerce, i32 %c)
 
 struct Large { int a[5]; };
 void __vectorcall v4(int a, struct Large b, int c) {}
-// CHECK: define x86_vectorcallcc void @"\01v4@@28"(i32 inreg %a, %struct.Large* byval align 4 %b, i32 inreg %c)
+// X32: define x86_vectorcallcc void @"\01v4@@28"(i32 inreg %a, %struct.Large* byval align 4 %b, i32 inreg %c)
 // X64: define x86_vectorcallcc void @"\01v4@@40"(i32 %a, %struct.Large* %b, i32 %c)
 
 struct HFA2 { double x, y; };
@@ -24,54 +24,84 @@
 struct HFA5 { double v, w, x, y, z; };
 
 void __vectorcall hfa1(int a, struct HFA4 b, int c) {}
-// CHECK: define x86_vectorcallcc void @"\01hfa1@@40"(i32 inreg %a, double %b.0, double %b.1, double %b.2, double %b.3, i32 inreg %c)
-// X64: define x86_vectorcallcc void @"\01hfa1@@48"(i32 %a, double %b.0, double %b.1, double %b.2, double %b.3, i32 %c)
+// X32: define x86_vectorcallcc void @"\01hfa1@@40"(i32 inreg %a, %struct.HFA4 inreg %b.coerce, i32 inreg %c)
+// X64: define x86_vectorcallcc void @"\01hfa1@@48"(i32 %a, %struct.HFA4 inreg %b.coerce, i32 %c)
 
 // HFAs that would require more than six total SSE registers are passed
 // indirectly. Additional vector arguments can consume the rest of the SSE
 // registers.
 void __vectorcall hfa2(struct HFA4 a, struct HFA4 b, double c) {}
-// CHECK: define x86_vectorcallcc void @"\01hfa2@@72"(double %a.0, double %a.1, double %a.2, double %a.3, %struct.HFA4* inreg %b, double %c)
-// X64: define x86_vectorcallcc void @"\01hfa2@@72"(double %a.0, double %a.1, double %a.2, double %a.3, %struct.HFA4* %b, double %c)
+// X32: define x86_vectorcallcc void @"\01hfa2@@72"(%struct.HFA4 inreg %a.coerce, %struct.HFA4* inreg %b, double %c)
+// X64: define x86_vectorcallcc void @"\01hfa2@@72"(%struct.HFA4 inreg %a.coerce, %struct.HFA4* %b, double %c)
 
 // Ensure that we pass builtin types directly while counting them against the
 // SSE register usage.
 void __vectorcall hfa3(double a, double b, double c, double d, double e, struct HFA2 f) {}
-// CHECK: define x86_vectorcallcc void @"\01hfa3@@56"(double %a, double %b, double %c, double %d, double %e, %struct.HFA2* inreg %f)
+// X32: define x86_vectorcallcc void @"\01hfa3@@56"(double %a, double %b, double %c, double %d, double %e, %struct.HFA2* inreg %f)
 // X64: define x86_vectorcallcc void @"\01hfa3@@56"(double %a, double %b, double %c, double %d, double %e, %struct.HFA2* %f)
 
 // Aggregates with more than four elements are not HFAs and are passed byval.
 // Because they are not classified as homogeneous, they don't get special
 // handling to ensure alignment.
 void __vectorcall hfa4(struct HFA5 a) {}
-// CHECK: define x86_vectorcallcc void @"\01hfa4@@40"(%struct.HFA5* byval align 4)
+// X32: define x86_vectorcallcc void @"\01hfa4@@40"(%struct.HFA5* byval align 4)
 // X64: define x86_vectorcallcc void @"\01hfa4@@40"(%struct.HFA5* %a)
 
 // Return HFAs of 4 or fewer elements in registers.
 static struct HFA2 g_hfa2;
 struct HFA2 __vectorcall hfa5(void) { return g_hfa2; }
-// CHECK: define x86_vectorcallcc %struct.HFA2 @"\01hfa5@@0"()
+// X32: define x86_vectorcallcc %struct.HFA2 @"\01hfa5@@0"()
 // X64: define x86_vectorcallcc %struct.HFA2 @"\01hfa5@@0"()
 
 typedef float __attribute__((vector_size(16))) v4f32;
 struct HVA2 { v4f32 x, y; };
+struct HVA3 { v4f32 w, x, y; };
 struct HVA4 { v4f32 w, x, y, z; };
+struct HVA5 { v4f32 w, x, y, z, p; };
 
-void __vectorcall hva1(int a, struct HVA4 b, int c) {}
-// CHECK: define x86_vectorcallcc void @"\01hva1@@72"(i32 inreg %a, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, i32 inreg %c)
-// X64: define x86_vectorcallcc void @"\01hva1@@80"(i32 %a, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, i32 %c)
+v4f32 __vectorcall hva1(int a, struct HVA4 b, int c) {return b.w;}
+// X32: define x86_vectorcallcc <4 x float> @"\01hva1@@72"(i32 inreg %a, %struct.HVA4 inreg %b.coerce, i32 inreg %c)
+// X64: define x86_vectorcallcc <4 x float> @"\01hva1@@80"(i32 %a, %struct.HVA4 inreg %b.coerce, i32 %c)
 
-void __vectorcall hva2(struct HVA4 a, struct HVA4 b, v4f32 c) {}
-// CHECK: define x86_vectorcallcc void @"\01hva2@@144"(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, %struct.HVA4* inreg %b, <4 x float> %c)
-// X64: define x86_vectorcallcc void @"\01hva2@@144"(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, %struct.HVA4* %b, <4 x float> %c)
+v4f32 __vectorcall hva2(struct HVA4 a, struct HVA4 b, v4f32 c) {return c;}
+// X32: define x86_vectorcallcc <4 x float> @"\01hva2@@144"(%struct.HVA4 inreg %a.coerce, %struct.HVA4* inreg %b, <4 x float> %c)
+// X64: define x86_vectorcallcc <4 x float> @"\01hva2@@144"(%struct.HVA4 inreg %a.coerce, %struct.HVA4* %b, <4 x float> %c)
 
-void __vectorcall hva3(v4f32 a, v4f32 b, v4f32 c, v4f32 d, v4f32 e, struct HVA2 f) {}
-// CHECK: define x86_vectorcallcc void @"\01hva3@@112"(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d, <4 x float> %e, %struct.HVA2* inreg %f)
-// X64: define x86_vectorcallcc void @"\01hva3@@112"(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d, <4 x float> %e, %struct.HVA2* %f)
+v4f32 __vectorcall hva3(v4f32 a, v4f32 b, v4f32 c, v4f32 d, v4f32 e, struct HVA2 f) {return f.x;}
+// X32: define x86_vectorcallcc <4 x float> @"\01hva3@@112"(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d, <4 x float> %e, %struct.HVA2* inreg %f)
+// X64: define x86_vectorcallcc <4 x float> @"\01hva3@@112"(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d, <4 x float> %e, %struct.HVA2* %f)
+
+// vector types have higher priority then HVA structures, So vector types are allocated first
+// and HVAs are allocated if enough registers are available
+v4f32 __vectorcall hva4(struct HVA4 a, struct HVA2 b, v4f32 c) {return b.y;}
+// X32: define x86_vectorcallcc <4 x float> @"\01hva4@@112"(%struct.HVA4 inreg %a.coerce, %struct.HVA2* inreg %b, <4 x float> %c)
+// X64: define x86_vectorcallcc <4 x float> @"\01hva4@@112"(%struct.HVA4 inreg %a.coerce, %struct.HVA2* %b, <4 x float> %c)
+
+v4f32 __vectorcall hva5(struct HVA3 a, struct HVA3 b, v4f32 c, struct HVA2 d) {return d.y;}
+// X32: define x86_vectorcallcc <4 x float> @"\01hva5@@144"(%struct.HVA3 inreg %a.coerce, %struct.HVA3* inreg %b, <4 x float> %c, %struct.HVA2 inreg %d.coerce)
+// X64: define x86_vectorcallcc <4 x float> @"\01hva5@@144"(%struct.HVA3 inreg %a.coerce, %struct.HVA3* %b, <4 x float> %c, %struct.HVA2 inreg %d.coerce)
+
+struct HVA4 __vectorcall hva6(struct HVA4 a, struct HVA4 b) { return b;}
+// X32: define x86_vectorcallcc %struct.HVA4 @"\01hva6@@128"(%struct.HVA4 inreg %a.coerce, %struct.HVA4* inreg %b)
+// X64: define x86_vectorcallcc %struct.HVA4 @"\01hva6@@128"(%struct.HVA4 inreg %a.coerce, %struct.HVA4* %b)
+
+struct HVA5 __vectorcall hva7() {struct HVA5 a = {}; return a;}
+// X32: define x86_vectorcallcc void @"\01hva7@@0"(%struct.HVA5* inreg noalias sret %agg.result)
+// X64: define x86_vectorcallcc void @"\01hva7@@0"(%struct.HVA5* noalias sret %agg.result)
+
+v4f32 __vectorcall hva8(v4f32 a, v4f32 b, v4f32 c, v4f32 d, int e, v4f32 f) {return f;}
+// X32: define x86_vectorcallcc <4 x float> @"\01hva8@@84"(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d, i32 inreg %e, <4 x float> %f)
+// X64: define x86_vectorcallcc <4 x float> @"\01hva8@@88"(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d, i32 %e, <4 x float> %f)
 
 typedef float __attribute__((ext_vector_type(3))) v3f32;
 struct OddSizeHVA { v3f32 x, y; };
 
 void __vectorcall odd_size_hva(struct OddSizeHVA a) {}
-// CHECK: define x86_vectorcallcc void @"\01odd_size_hva@@32"(<3 x float> %a.0, <3 x float> %a.1)
-// X64: define x86_vectorcallcc void @"\01odd_size_hva@@32"(<3 x float> %a.0, <3 x float> %a.1)
+// X32: define x86_vectorcallcc void @"\01odd_size_hva@@32"(%struct.OddSizeHVA inreg %a.coerce)
+// X64: define x86_vectorcallcc void @"\01odd_size_hva@@32"(%struct.OddSizeHVA inreg %a.coerce)
+
+// The Vectorcall ABI only allows passing the first 6 items in registers, so this shouldn't 
+// consider 'p7' as a register.  Instead p5 gets put into the register on the second pass.
+struct HFA2 __vectorcall AddParticles(struct HFA2 p1, float p2, struct HFA4 p3, int p4, struct HFA2 p5, float p6, float p7){ return p1;}
+// X32: define x86_vectorcallcc %struct.HFA2 @"\01AddParticles@@80"(%struct.HFA2 inreg %p1.coerce, float %p2, %struct.HFA4* inreg %p3, i32 inreg %p4, %struct.HFA2 inreg %p5.coerce, float %p6, float %p7)
+// X64: define x86_vectorcallcc %struct.HFA2 @"\01AddParticles@@96"(%struct.HFA2 inreg %p1.coerce, float %p2, %struct.HFA4* %p3, i32 %p4, %struct.HFA2 inreg %p5.coerce, float %p6, float %p7)
diff --git a/test/CodeGen/xop-builtins.c b/test/CodeGen/xop-builtins.c
index da9a3b9..5302b9a 100644
--- a/test/CodeGen/xop-builtins.c
+++ b/test/CodeGen/xop-builtins.c
@@ -170,13 +170,19 @@
 
 __m128i test_mm_cmov_si128(__m128i a, __m128i b, __m128i c) {
   // CHECK-LABEL: test_mm_cmov_si128
-  // CHECK: call <2 x i64> @llvm.x86.xop.vpcmov(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+  // CHECK: [[AND:%.*]] = and <2 x i64> %{{.*}}, %{{.*}}
+  // CHECK: [[NEG:%.*]] = xor <2 x i64> %{{.*}}, <i64 -1, i64 -1>
+  // CHECK-NEXT: [[ANDN:%.*]] = and <2 x i64> %{{.*}}, [[NEG]]
+  // CHECK-NEXT: %{{.*}} = or <2 x i64> [[AND]], [[ANDN]]
   return _mm_cmov_si128(a, b, c);
 }
 
 __m256i test_mm256_cmov_si256(__m256i a, __m256i b, __m256i c) {
   // CHECK-LABEL: test_mm256_cmov_si256
-  // CHECK: call <4 x i64> @llvm.x86.xop.vpcmov.256(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}})
+  // CHECK: [[AND:%.*]] = and <4 x i64> %{{.*}}, %{{.*}}
+  // CHECK: [[NEG:%.*]] = xor <4 x i64> %{{.*}}, <i64 -1, i64 -1, i64 -1, i64 -1>
+  // CHECK-NEXT: [[ANDN:%.*]] = and <4 x i64> %{{.*}}, [[NEG]]
+  // CHECK-NEXT: %{{.*}} = or <4 x i64> [[AND]], [[ANDN]]
   return _mm256_cmov_si256(a, b, c);
 }
 
diff --git a/test/CodeGen/xray-attributes-supported-arm.cpp b/test/CodeGen/xray-attributes-supported-arm.cpp
deleted file mode 100644
index 3104f28..0000000
--- a/test/CodeGen/xray-attributes-supported-arm.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple arm-unknown-linux-gnu | FileCheck %s
-
-// Make sure that the LLVM attribute for XRay-annotated functions do show up.
-[[clang::xray_always_instrument]] void foo() {
-// CHECK: define void @_Z3foov() #0
-};
-
-[[clang::xray_never_instrument]] void bar() {
-// CHECK: define void @_Z3barv() #1
-};
-
-// CHECK: #0 = {{.*}}"function-instrument"="xray-always"
-// CHECK: #1 = {{.*}}"function-instrument"="xray-never"
diff --git a/test/CodeGen/xray-attributes-supported.cpp b/test/CodeGen/xray-attributes-supported.cpp
index d70b3aa..860efb2 100644
--- a/test/CodeGen/xray-attributes-supported.cpp
+++ b/test/CodeGen/xray-attributes-supported.cpp
@@ -1,4 +1,10 @@
 // RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple x86_64-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple arm-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple mips-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple mipsel-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple mips64-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple mips64el-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu | FileCheck %s
 
 // Make sure that the LLVM attribute for XRay-annotated functions do show up.
 [[clang::xray_always_instrument]] void foo() {
diff --git a/test/CodeGen/xray-log-args.cpp b/test/CodeGen/xray-log-args.cpp
new file mode 100644
index 0000000..d4f4a1b
--- /dev/null
+++ b/test/CodeGen/xray-log-args.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple x86_64-unknown-linux-gnu | FileCheck %s
+
+// Make sure that the LLVM attribute for XRay-annotated functions do show up.
+[[clang::xray_always_instrument,clang::xray_log_args(1)]] void foo(int a) {
+// CHECK: define void @_Z3fooi(i32 %a) #0
+};
+
+[[clang::xray_log_args(1)]] void bar(int a) {
+// CHECK: define void @_Z3bari(i32 %a) #1
+};
+
+// CHECK: #0 = {{.*}}"function-instrument"="xray-always"{{.*}}"xray-log-args"="1"
+// CHECK-NOT: #1 = {{.*}}"xray-log-args"="1"
diff --git a/test/CodeGen/zvector.c b/test/CodeGen/zvector.c
index ebe7e41..a8405a7 100644
--- a/test/CodeGen/zvector.c
+++ b/test/CodeGen/zvector.c
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu z13 -fzvector \
-// RUN:  -O -emit-llvm -o - -W -Wall -Werror %s | FileCheck %s
+// RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu z13 -fzvector -emit-llvm -o - -W -Wall -Werror %s | opt -S -mem2reg | FileCheck %s
 
 volatile vector signed char sc, sc2;
 volatile vector unsigned char uc, uc2;
@@ -21,2778 +20,3349 @@
 
 volatile int cnt;
 
-void test_assign (void)
-{
-// CHECK-LABEL: test_assign
+// CHECK-LABEL: define void @test_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   store volatile <16 x i8> [[TMP0]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   store volatile <16 x i8> [[TMP1]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   store volatile <8 x i16> [[TMP2]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   store volatile <8 x i16> [[TMP3]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   store volatile <4 x i32> [[TMP4]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   store volatile <4 x i32> [[TMP5]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   store volatile <2 x i64> [[TMP6]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   store volatile <2 x i64> [[TMP7]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   store volatile <2 x double> [[TMP8]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_assign(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: store volatile <16 x i8> [[VAL]], <16 x i8>* @sc
   sc = sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: store volatile <16 x i8> [[VAL]], <16 x i8>* @uc
   uc = uc2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: store volatile <8 x i16> [[VAL]], <8 x i16>* @ss
   ss = ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: store volatile <8 x i16> [[VAL]], <8 x i16>* @us
   us = us2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: store volatile <4 x i32> [[VAL]], <4 x i32>* @si
   si = si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: store volatile <4 x i32> [[VAL]], <4 x i32>* @ui
   ui = ui2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: store volatile <2 x i64> [[VAL]], <2 x i64>* @sl
   sl = sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: store volatile <2 x i64> [[VAL]], <2 x i64>* @ul
   ul = ul2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: store volatile <2 x double> [[VAL]], <2 x double>* @fd
   fd = fd2;
 }
 
-void test_pos (void)
-{
-// CHECK-LABEL: test_pos
+// CHECK-LABEL: define void @test_pos() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   store volatile <16 x i8> [[TMP0]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   store volatile <16 x i8> [[TMP1]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   store volatile <8 x i16> [[TMP2]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   store volatile <8 x i16> [[TMP3]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   store volatile <4 x i32> [[TMP4]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   store volatile <4 x i32> [[TMP5]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   store volatile <2 x i64> [[TMP6]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   store volatile <2 x i64> [[TMP7]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   store volatile <2 x double> [[TMP8]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_pos(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: store volatile <16 x i8> [[VAL]], <16 x i8>* @sc
   sc = +sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: store volatile <16 x i8> [[VAL]], <16 x i8>* @uc
   uc = +uc2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: store volatile <8 x i16> [[VAL]], <8 x i16>* @ss
   ss = +ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: store volatile <8 x i16> [[VAL]], <8 x i16>* @us
   us = +us2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: store volatile <4 x i32> [[VAL]], <4 x i32>* @si
   si = +si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: store volatile <4 x i32> [[VAL]], <4 x i32>* @ui
   ui = +ui2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: store volatile <2 x i64> [[VAL]], <2 x i64>* @sl
   sl = +sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: store volatile <2 x i64> [[VAL]], <2 x i64>* @ul
   ul = +ul2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: store volatile <2 x double> [[VAL]], <2 x double>* @fd
   fd = +fd2;
 }
 
-void test_neg (void)
-{
-// CHECK-LABEL: test_neg
+// CHECK-LABEL: define void @test_neg() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[SUB:%.*]] = sub <16 x i8> zeroinitializer, [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[SUB]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[SUB1:%.*]] = sub <8 x i16> zeroinitializer, [[TMP1]]
+// CHECK:   store volatile <8 x i16> [[SUB1]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[SUB2:%.*]] = sub <4 x i32> zeroinitializer, [[TMP2]]
+// CHECK:   store volatile <4 x i32> [[SUB2]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[SUB3:%.*]] = sub <2 x i64> zeroinitializer, [[TMP3]]
+// CHECK:   store volatile <2 x i64> [[SUB3]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[SUB4:%.*]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, [[TMP4]]
+// CHECK:   store volatile <2 x double> [[SUB4]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_neg(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = sub <16 x i8> zeroinitializer, [[VAL]]
   sc = -sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = sub <8 x i16> zeroinitializer, [[VAL]]
   ss = -ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = sub <4 x i32> zeroinitializer, [[VAL]]
   si = -si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = sub <2 x i64> zeroinitializer, [[VAL]]
   sl = -sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: %{{.*}} = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, [[VAL]]
   fd = -fd2;
 }
 
-void test_preinc (void)
-{
-// CHECK-LABEL: test_preinc
+// CHECK-LABEL: define void @test_preinc() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[INC:%.*]] = add <16 x i8> [[TMP0]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
+// CHECK:   store volatile <16 x i8> [[INC]], <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[INC1:%.*]] = add <16 x i8> [[TMP1]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
+// CHECK:   store volatile <16 x i8> [[INC1]], <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[INC2:%.*]] = add <8 x i16> [[TMP2]], <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+// CHECK:   store volatile <8 x i16> [[INC2]], <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[INC3:%.*]] = add <8 x i16> [[TMP3]], <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+// CHECK:   store volatile <8 x i16> [[INC3]], <8 x i16>* @us2, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[INC4:%.*]] = add <4 x i32> [[TMP4]], <i32 1, i32 1, i32 1, i32 1>
+// CHECK:   store volatile <4 x i32> [[INC4]], <4 x i32>* @si2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[INC5:%.*]] = add <4 x i32> [[TMP5]], <i32 1, i32 1, i32 1, i32 1>
+// CHECK:   store volatile <4 x i32> [[INC5]], <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[INC6:%.*]] = add <2 x i64> [[TMP6]], <i64 1, i64 1>
+// CHECK:   store volatile <2 x i64> [[INC6]], <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[INC7:%.*]] = add <2 x i64> [[TMP7]], <i64 1, i64 1>
+// CHECK:   store volatile <2 x i64> [[INC7]], <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[INC8:%.*]] = fadd <2 x double> [[TMP8]], <double 1.000000e+00, double 1.000000e+00>
+// CHECK:   store volatile <2 x double> [[INC8]], <2 x double>* @fd2, align 8
+// CHECK:   ret void
+void test_preinc(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
   ++sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
   ++uc2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL]], <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
   ++ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL]], <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
   ++us2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL]], <i32 1, i32 1, i32 1, i32 1>
   ++si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL]], <i32 1, i32 1, i32 1, i32 1>
   ++ui2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL]], <i64 1, i64 1>
   ++sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL]], <i64 1, i64 1>
   ++ul2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: %{{.*}} = fadd <2 x double> [[VAL]], <double 1.000000e+00, double 1.000000e+00>
   ++fd2;
 }
 
-void test_postinc (void)
-{
-// CHECK-LABEL: test_postinc
+// CHECK-LABEL: define void @test_postinc() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[INC:%.*]] = add <16 x i8> [[TMP0]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
+// CHECK:   store volatile <16 x i8> [[INC]], <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[INC1:%.*]] = add <16 x i8> [[TMP1]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
+// CHECK:   store volatile <16 x i8> [[INC1]], <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[INC2:%.*]] = add <8 x i16> [[TMP2]], <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+// CHECK:   store volatile <8 x i16> [[INC2]], <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[INC3:%.*]] = add <8 x i16> [[TMP3]], <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+// CHECK:   store volatile <8 x i16> [[INC3]], <8 x i16>* @us2, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[INC4:%.*]] = add <4 x i32> [[TMP4]], <i32 1, i32 1, i32 1, i32 1>
+// CHECK:   store volatile <4 x i32> [[INC4]], <4 x i32>* @si2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[INC5:%.*]] = add <4 x i32> [[TMP5]], <i32 1, i32 1, i32 1, i32 1>
+// CHECK:   store volatile <4 x i32> [[INC5]], <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[INC6:%.*]] = add <2 x i64> [[TMP6]], <i64 1, i64 1>
+// CHECK:   store volatile <2 x i64> [[INC6]], <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[INC7:%.*]] = add <2 x i64> [[TMP7]], <i64 1, i64 1>
+// CHECK:   store volatile <2 x i64> [[INC7]], <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[INC8:%.*]] = fadd <2 x double> [[TMP8]], <double 1.000000e+00, double 1.000000e+00>
+// CHECK:   store volatile <2 x double> [[INC8]], <2 x double>* @fd2, align 8
+// CHECK:   ret void
+void test_postinc(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
   sc2++;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
   uc2++;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL]], <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
   ss2++;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL]], <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
   us2++;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL]], <i32 1, i32 1, i32 1, i32 1>
   si2++;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL]], <i32 1, i32 1, i32 1, i32 1>
   ui2++;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL]], <i64 1, i64 1>
   sl2++;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL]], <i64 1, i64 1>
   ul2++;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: %{{.*}} = fadd <2 x double> [[VAL]], <double 1.000000e+00, double 1.000000e+00>
   fd2++;
 }
 
-void test_predec (void)
-{
-// CHECK-LABEL: test_predec
+// CHECK-LABEL: define void @test_predec() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[DEC:%.*]] = add <16 x i8> [[TMP0]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
+// CHECK:   store volatile <16 x i8> [[DEC]], <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[DEC1:%.*]] = add <16 x i8> [[TMP1]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
+// CHECK:   store volatile <16 x i8> [[DEC1]], <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[DEC2:%.*]] = add <8 x i16> [[TMP2]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+// CHECK:   store volatile <8 x i16> [[DEC2]], <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[DEC3:%.*]] = add <8 x i16> [[TMP3]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+// CHECK:   store volatile <8 x i16> [[DEC3]], <8 x i16>* @us2, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[DEC4:%.*]] = add <4 x i32> [[TMP4]], <i32 -1, i32 -1, i32 -1, i32 -1>
+// CHECK:   store volatile <4 x i32> [[DEC4]], <4 x i32>* @si2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[DEC5:%.*]] = add <4 x i32> [[TMP5]], <i32 -1, i32 -1, i32 -1, i32 -1>
+// CHECK:   store volatile <4 x i32> [[DEC5]], <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[DEC6:%.*]] = add <2 x i64> [[TMP6]], <i64 -1, i64 -1>
+// CHECK:   store volatile <2 x i64> [[DEC6]], <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[DEC7:%.*]] = add <2 x i64> [[TMP7]], <i64 -1, i64 -1>
+// CHECK:   store volatile <2 x i64> [[DEC7]], <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[DEC8:%.*]] = fadd <2 x double> [[TMP8]], <double -1.000000e+00, double -1.000000e+00>
+// CHECK:   store volatile <2 x double> [[DEC8]], <2 x double>* @fd2, align 8
+// CHECK:   ret void
+void test_predec(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
   --sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
   --uc2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
   --ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
   --us2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL]], <i32 -1, i32 -1, i32 -1, i32 -1>
   --si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL]], <i32 -1, i32 -1, i32 -1, i32 -1>
   --ui2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL]], <i64 -1, i64 -1>
   --sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL]], <i64 -1, i64 -1>
   --ul2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: %{{.*}} = fadd <2 x double> [[VAL]], <double -1.000000e+00, double -1.000000e+00>
   --fd2;
 }
 
-void test_postdec (void)
-{
-// CHECK-LABEL: test_postdec
+// CHECK-LABEL: define void @test_postdec() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[DEC:%.*]] = add <16 x i8> [[TMP0]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
+// CHECK:   store volatile <16 x i8> [[DEC]], <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[DEC1:%.*]] = add <16 x i8> [[TMP1]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
+// CHECK:   store volatile <16 x i8> [[DEC1]], <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[DEC2:%.*]] = add <8 x i16> [[TMP2]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+// CHECK:   store volatile <8 x i16> [[DEC2]], <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[DEC3:%.*]] = add <8 x i16> [[TMP3]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+// CHECK:   store volatile <8 x i16> [[DEC3]], <8 x i16>* @us2, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[DEC4:%.*]] = add <4 x i32> [[TMP4]], <i32 -1, i32 -1, i32 -1, i32 -1>
+// CHECK:   store volatile <4 x i32> [[DEC4]], <4 x i32>* @si2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[DEC5:%.*]] = add <4 x i32> [[TMP5]], <i32 -1, i32 -1, i32 -1, i32 -1>
+// CHECK:   store volatile <4 x i32> [[DEC5]], <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[DEC6:%.*]] = add <2 x i64> [[TMP6]], <i64 -1, i64 -1>
+// CHECK:   store volatile <2 x i64> [[DEC6]], <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[DEC7:%.*]] = add <2 x i64> [[TMP7]], <i64 -1, i64 -1>
+// CHECK:   store volatile <2 x i64> [[DEC7]], <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[DEC8:%.*]] = fadd <2 x double> [[TMP8]], <double -1.000000e+00, double -1.000000e+00>
+// CHECK:   store volatile <2 x double> [[DEC8]], <2 x double>* @fd2, align 8
+// CHECK:   ret void
+void test_postdec(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
   sc2--;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
   uc2--;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
   ss2--;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
   us2--;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL]], <i32 -1, i32 -1, i32 -1, i32 -1>
   si2--;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL]], <i32 -1, i32 -1, i32 -1, i32 -1>
   ui2--;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL]], <i64 -1, i64 -1>
   sl2--;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL]], <i64 -1, i64 -1>
   ul2--;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: %{{.*}} = fadd <2 x double> [[VAL]], <double -1.000000e+00, double -1.000000e+00>
   fd2--;
 }
 
-void test_add (void)
-{
-// CHECK-LABEL: test_add
+// CHECK-LABEL: define void @test_add() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[ADD:%.*]] = add <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[ADD]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[ADD1:%.*]] = add <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[ADD1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[ADD2:%.*]] = add <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   store volatile <16 x i8> [[ADD2]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[ADD3:%.*]] = add <16 x i8> [[TMP6]], [[TMP7]]
+// CHECK:   store volatile <16 x i8> [[ADD3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[ADD4:%.*]] = add <16 x i8> [[TMP8]], [[TMP9]]
+// CHECK:   store volatile <16 x i8> [[ADD4]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[ADD5:%.*]] = add <16 x i8> [[TMP10]], [[TMP11]]
+// CHECK:   store volatile <16 x i8> [[ADD5]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[ADD6:%.*]] = add <8 x i16> [[TMP12]], [[TMP13]]
+// CHECK:   store volatile <8 x i16> [[ADD6]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[ADD7:%.*]] = add <8 x i16> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <8 x i16> [[ADD7]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[ADD8:%.*]] = add <8 x i16> [[TMP16]], [[TMP17]]
+// CHECK:   store volatile <8 x i16> [[ADD8]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[ADD9:%.*]] = add <8 x i16> [[TMP18]], [[TMP19]]
+// CHECK:   store volatile <8 x i16> [[ADD9]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[ADD10:%.*]] = add <8 x i16> [[TMP20]], [[TMP21]]
+// CHECK:   store volatile <8 x i16> [[ADD10]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[ADD11:%.*]] = add <8 x i16> [[TMP22]], [[TMP23]]
+// CHECK:   store volatile <8 x i16> [[ADD11]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[ADD12:%.*]] = add <4 x i32> [[TMP24]], [[TMP25]]
+// CHECK:   store volatile <4 x i32> [[ADD12]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[ADD13:%.*]] = add <4 x i32> [[TMP26]], [[TMP27]]
+// CHECK:   store volatile <4 x i32> [[ADD13]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[ADD14:%.*]] = add <4 x i32> [[TMP28]], [[TMP29]]
+// CHECK:   store volatile <4 x i32> [[ADD14]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[ADD15:%.*]] = add <4 x i32> [[TMP30]], [[TMP31]]
+// CHECK:   store volatile <4 x i32> [[ADD15]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[ADD16:%.*]] = add <4 x i32> [[TMP32]], [[TMP33]]
+// CHECK:   store volatile <4 x i32> [[ADD16]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[ADD17:%.*]] = add <4 x i32> [[TMP34]], [[TMP35]]
+// CHECK:   store volatile <4 x i32> [[ADD17]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[ADD18:%.*]] = add <2 x i64> [[TMP36]], [[TMP37]]
+// CHECK:   store volatile <2 x i64> [[ADD18]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[ADD19:%.*]] = add <2 x i64> [[TMP38]], [[TMP39]]
+// CHECK:   store volatile <2 x i64> [[ADD19]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP40:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[ADD20:%.*]] = add <2 x i64> [[TMP40]], [[TMP41]]
+// CHECK:   store volatile <2 x i64> [[ADD20]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[ADD21:%.*]] = add <2 x i64> [[TMP42]], [[TMP43]]
+// CHECK:   store volatile <2 x i64> [[ADD21]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[ADD22:%.*]] = add <2 x i64> [[TMP44]], [[TMP45]]
+// CHECK:   store volatile <2 x i64> [[ADD22]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP47:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[ADD23:%.*]] = add <2 x i64> [[TMP46]], [[TMP47]]
+// CHECK:   store volatile <2 x i64> [[ADD23]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[ADD24:%.*]] = fadd <2 x double> [[TMP48]], [[TMP49]]
+// CHECK:   store volatile <2 x double> [[ADD24]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_add(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL2]], [[VAL1]]
   sc = sc + sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL2]], [[VAL1]]
   sc = sc + bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL2]], [[VAL1]]
   sc = bc + sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL2]], [[VAL1]]
   uc = uc + uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL2]], [[VAL1]]
   uc = uc + bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = add <16 x i8> [[VAL2]], [[VAL1]]
   uc = bc + uc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL2]], [[VAL1]]
   ss = ss + ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL2]], [[VAL1]]
   ss = ss + bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL2]], [[VAL1]]
   ss = bs + ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL2]], [[VAL1]]
   us = us + us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL2]], [[VAL1]]
   us = us + bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = add <8 x i16> [[VAL2]], [[VAL1]]
   us = bs + us2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL2]], [[VAL1]]
   si = si + si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL2]], [[VAL1]]
   si = si + bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL2]], [[VAL1]]
   si = bi + si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL2]], [[VAL1]]
   ui = ui + ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL2]], [[VAL1]]
   ui = ui + bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = add <4 x i32> [[VAL2]], [[VAL1]]
   ui = bi + ui2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL2]], [[VAL1]]
   sl = sl + sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL2]], [[VAL1]]
   sl = sl + bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL2]], [[VAL1]]
   sl = bl + sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL2]], [[VAL1]]
   ul = ul + ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL2]], [[VAL1]]
   ul = ul + bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = add <2 x i64> [[VAL2]], [[VAL1]]
   ul = bl + ul2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: %{{.*}} = fadd <2 x double> [[VAL1]], [[VAL2]]
   fd = fd + fd2;
 }
 
-void test_add_assign (void)
-{
-// CHECK-LABEL: test_add_assign
+// CHECK-LABEL: define void @test_add_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[ADD:%.*]] = add <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[ADD]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[ADD1:%.*]] = add <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[ADD1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[ADD2:%.*]] = add <16 x i8> [[TMP5]], [[TMP4]]
+// CHECK:   store volatile <16 x i8> [[ADD2]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[ADD3:%.*]] = add <16 x i8> [[TMP7]], [[TMP6]]
+// CHECK:   store volatile <16 x i8> [[ADD3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[ADD4:%.*]] = add <8 x i16> [[TMP9]], [[TMP8]]
+// CHECK:   store volatile <8 x i16> [[ADD4]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[ADD5:%.*]] = add <8 x i16> [[TMP11]], [[TMP10]]
+// CHECK:   store volatile <8 x i16> [[ADD5]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[ADD6:%.*]] = add <8 x i16> [[TMP13]], [[TMP12]]
+// CHECK:   store volatile <8 x i16> [[ADD6]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[ADD7:%.*]] = add <8 x i16> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <8 x i16> [[ADD7]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[ADD8:%.*]] = add <4 x i32> [[TMP17]], [[TMP16]]
+// CHECK:   store volatile <4 x i32> [[ADD8]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[ADD9:%.*]] = add <4 x i32> [[TMP19]], [[TMP18]]
+// CHECK:   store volatile <4 x i32> [[ADD9]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[ADD10:%.*]] = add <4 x i32> [[TMP21]], [[TMP20]]
+// CHECK:   store volatile <4 x i32> [[ADD10]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[ADD11:%.*]] = add <4 x i32> [[TMP23]], [[TMP22]]
+// CHECK:   store volatile <4 x i32> [[ADD11]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[ADD12:%.*]] = add <2 x i64> [[TMP25]], [[TMP24]]
+// CHECK:   store volatile <2 x i64> [[ADD12]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[ADD13:%.*]] = add <2 x i64> [[TMP27]], [[TMP26]]
+// CHECK:   store volatile <2 x i64> [[ADD13]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[ADD14:%.*]] = add <2 x i64> [[TMP29]], [[TMP28]]
+// CHECK:   store volatile <2 x i64> [[ADD14]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[ADD15:%.*]] = add <2 x i64> [[TMP31]], [[TMP30]]
+// CHECK:   store volatile <2 x i64> [[ADD15]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[ADD16:%.*]] = fadd <2 x double> [[TMP33]], [[TMP32]]
+// CHECK:   store volatile <2 x double> [[ADD16]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_add_assign(void) {
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = add <16 x i8> [[VAL1]], [[VAL2]]
   sc += sc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = add <16 x i8> [[VAL1]], [[VAL2]]
   sc += bc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = add <16 x i8> [[VAL1]], [[VAL2]]
   uc += uc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = add <16 x i8> [[VAL1]], [[VAL2]]
   uc += bc2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = add <8 x i16> [[VAL1]], [[VAL2]]
   ss += ss2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = add <8 x i16> [[VAL1]], [[VAL2]]
   ss += bs2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = add <8 x i16> [[VAL1]], [[VAL2]]
   us += us2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = add <8 x i16> [[VAL1]], [[VAL2]]
   us += bs2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = add <4 x i32> [[VAL1]], [[VAL2]]
   si += si2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = add <4 x i32> [[VAL1]], [[VAL2]]
   si += bi2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = add <4 x i32> [[VAL1]], [[VAL2]]
   ui += ui2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = add <4 x i32> [[VAL1]], [[VAL2]]
   ui += bi2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = add <2 x i64> [[VAL1]], [[VAL2]]
   sl += sl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = add <2 x i64> [[VAL1]], [[VAL2]]
   sl += bl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = add <2 x i64> [[VAL1]], [[VAL2]]
   ul += ul2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = add <2 x i64> [[VAL1]], [[VAL2]]
   ul += bl2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: %{{.*}} = fadd <2 x double> [[VAL2]], [[VAL1]]
   fd += fd2;
 }
 
-void test_sub (void)
-{
-// CHECK-LABEL: test_sub
+// CHECK-LABEL: define void @test_sub() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[SUB:%.*]] = sub <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[SUB]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[SUB1:%.*]] = sub <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[SUB1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[SUB2:%.*]] = sub <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   store volatile <16 x i8> [[SUB2]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[SUB3:%.*]] = sub <16 x i8> [[TMP6]], [[TMP7]]
+// CHECK:   store volatile <16 x i8> [[SUB3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[SUB4:%.*]] = sub <16 x i8> [[TMP8]], [[TMP9]]
+// CHECK:   store volatile <16 x i8> [[SUB4]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[SUB5:%.*]] = sub <16 x i8> [[TMP10]], [[TMP11]]
+// CHECK:   store volatile <16 x i8> [[SUB5]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[SUB6:%.*]] = sub <8 x i16> [[TMP12]], [[TMP13]]
+// CHECK:   store volatile <8 x i16> [[SUB6]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[SUB7:%.*]] = sub <8 x i16> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <8 x i16> [[SUB7]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[SUB8:%.*]] = sub <8 x i16> [[TMP16]], [[TMP17]]
+// CHECK:   store volatile <8 x i16> [[SUB8]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[SUB9:%.*]] = sub <8 x i16> [[TMP18]], [[TMP19]]
+// CHECK:   store volatile <8 x i16> [[SUB9]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[SUB10:%.*]] = sub <8 x i16> [[TMP20]], [[TMP21]]
+// CHECK:   store volatile <8 x i16> [[SUB10]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[SUB11:%.*]] = sub <8 x i16> [[TMP22]], [[TMP23]]
+// CHECK:   store volatile <8 x i16> [[SUB11]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[SUB12:%.*]] = sub <4 x i32> [[TMP24]], [[TMP25]]
+// CHECK:   store volatile <4 x i32> [[SUB12]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[SUB13:%.*]] = sub <4 x i32> [[TMP26]], [[TMP27]]
+// CHECK:   store volatile <4 x i32> [[SUB13]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[SUB14:%.*]] = sub <4 x i32> [[TMP28]], [[TMP29]]
+// CHECK:   store volatile <4 x i32> [[SUB14]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[SUB15:%.*]] = sub <4 x i32> [[TMP30]], [[TMP31]]
+// CHECK:   store volatile <4 x i32> [[SUB15]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[SUB16:%.*]] = sub <4 x i32> [[TMP32]], [[TMP33]]
+// CHECK:   store volatile <4 x i32> [[SUB16]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[SUB17:%.*]] = sub <4 x i32> [[TMP34]], [[TMP35]]
+// CHECK:   store volatile <4 x i32> [[SUB17]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[SUB18:%.*]] = sub <2 x i64> [[TMP36]], [[TMP37]]
+// CHECK:   store volatile <2 x i64> [[SUB18]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[SUB19:%.*]] = sub <2 x i64> [[TMP38]], [[TMP39]]
+// CHECK:   store volatile <2 x i64> [[SUB19]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP40:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[SUB20:%.*]] = sub <2 x i64> [[TMP40]], [[TMP41]]
+// CHECK:   store volatile <2 x i64> [[SUB20]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[SUB21:%.*]] = sub <2 x i64> [[TMP42]], [[TMP43]]
+// CHECK:   store volatile <2 x i64> [[SUB21]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[SUB22:%.*]] = sub <2 x i64> [[TMP44]], [[TMP45]]
+// CHECK:   store volatile <2 x i64> [[SUB22]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP47:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[SUB23:%.*]] = sub <2 x i64> [[TMP46]], [[TMP47]]
+// CHECK:   store volatile <2 x i64> [[SUB23]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[SUB24:%.*]] = fsub <2 x double> [[TMP48]], [[TMP49]]
+// CHECK:   store volatile <2 x double> [[SUB24]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_sub(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   sc = sc - sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   sc = sc - bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   sc = bc - sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   uc = uc - uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   uc = uc - bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   uc = bc - uc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   ss = ss - ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   ss = ss - bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   ss = bs - ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   us = us - us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   us = us - bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   us = bs - us2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   si = si - si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   si = si - bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   si = bi - si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   ui = ui - ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   ui = ui - bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   ui = bi - ui2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   sl = sl - sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   sl = sl - bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   sl = bl - sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   ul = ul - ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   ul = ul - bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   ul = bl - ul2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: %{{.*}} = fsub <2 x double> [[VAL1]], [[VAL2]]
   fd = fd - fd2;
 }
 
-void test_sub_assign (void)
-{
-// CHECK-LABEL: test_sub_assign
+// CHECK-LABEL: define void @test_sub_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SUB:%.*]] = sub <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[SUB]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SUB1:%.*]] = sub <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[SUB1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SUB2:%.*]] = sub <16 x i8> [[TMP5]], [[TMP4]]
+// CHECK:   store volatile <16 x i8> [[SUB2]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SUB3:%.*]] = sub <16 x i8> [[TMP7]], [[TMP6]]
+// CHECK:   store volatile <16 x i8> [[SUB3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SUB4:%.*]] = sub <8 x i16> [[TMP9]], [[TMP8]]
+// CHECK:   store volatile <8 x i16> [[SUB4]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SUB5:%.*]] = sub <8 x i16> [[TMP11]], [[TMP10]]
+// CHECK:   store volatile <8 x i16> [[SUB5]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SUB6:%.*]] = sub <8 x i16> [[TMP13]], [[TMP12]]
+// CHECK:   store volatile <8 x i16> [[SUB6]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SUB7:%.*]] = sub <8 x i16> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <8 x i16> [[SUB7]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SUB8:%.*]] = sub <4 x i32> [[TMP17]], [[TMP16]]
+// CHECK:   store volatile <4 x i32> [[SUB8]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SUB9:%.*]] = sub <4 x i32> [[TMP19]], [[TMP18]]
+// CHECK:   store volatile <4 x i32> [[SUB9]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SUB10:%.*]] = sub <4 x i32> [[TMP21]], [[TMP20]]
+// CHECK:   store volatile <4 x i32> [[SUB10]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SUB11:%.*]] = sub <4 x i32> [[TMP23]], [[TMP22]]
+// CHECK:   store volatile <4 x i32> [[SUB11]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SUB12:%.*]] = sub <2 x i64> [[TMP25]], [[TMP24]]
+// CHECK:   store volatile <2 x i64> [[SUB12]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SUB13:%.*]] = sub <2 x i64> [[TMP27]], [[TMP26]]
+// CHECK:   store volatile <2 x i64> [[SUB13]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SUB14:%.*]] = sub <2 x i64> [[TMP29]], [[TMP28]]
+// CHECK:   store volatile <2 x i64> [[SUB14]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SUB15:%.*]] = sub <2 x i64> [[TMP31]], [[TMP30]]
+// CHECK:   store volatile <2 x i64> [[SUB15]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[SUB16:%.*]] = fsub <2 x double> [[TMP33]], [[TMP32]]
+// CHECK:   store volatile <2 x double> [[SUB16]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_sub_assign(void) {
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   sc -= sc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   sc -= bc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   uc -= uc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = sub <16 x i8> [[VAL1]], [[VAL2]]
   uc -= bc2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   ss -= ss2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   ss -= bs2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   us -= us2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = sub <8 x i16> [[VAL1]], [[VAL2]]
   us -= bs2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   si -= si2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   si -= bi2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   ui -= ui2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = sub <4 x i32> [[VAL1]], [[VAL2]]
   ui -= bi2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   sl -= sl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   sl -= bl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   ul -= ul2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = sub <2 x i64> [[VAL1]], [[VAL2]]
   ul -= bl2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: %{{.*}} = fsub <2 x double> [[VAL1]], [[VAL2]]
   fd -= fd2;
 }
 
-void test_mul (void)
-{
-// CHECK-LABEL: test_mul
+// CHECK-LABEL: define void @test_mul() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[MUL:%.*]] = mul <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[MUL]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[MUL1:%.*]] = mul <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[MUL1]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[MUL2:%.*]] = mul <8 x i16> [[TMP4]], [[TMP5]]
+// CHECK:   store volatile <8 x i16> [[MUL2]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[MUL3:%.*]] = mul <8 x i16> [[TMP6]], [[TMP7]]
+// CHECK:   store volatile <8 x i16> [[MUL3]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[MUL4:%.*]] = mul <4 x i32> [[TMP8]], [[TMP9]]
+// CHECK:   store volatile <4 x i32> [[MUL4]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[MUL5:%.*]] = mul <4 x i32> [[TMP10]], [[TMP11]]
+// CHECK:   store volatile <4 x i32> [[MUL5]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[MUL6:%.*]] = mul <2 x i64> [[TMP12]], [[TMP13]]
+// CHECK:   store volatile <2 x i64> [[MUL6]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[MUL7:%.*]] = mul <2 x i64> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <2 x i64> [[MUL7]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[MUL8:%.*]] = fmul <2 x double> [[TMP16]], [[TMP17]]
+// CHECK:   store volatile <2 x double> [[MUL8]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_mul(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = mul <16 x i8> [[VAL2]], [[VAL1]]
   sc = sc * sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = mul <16 x i8> [[VAL2]], [[VAL1]]
   uc = uc * uc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = mul <8 x i16> [[VAL2]], [[VAL1]]
   ss = ss * ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = mul <8 x i16> [[VAL2]], [[VAL1]]
   us = us * us2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = mul <4 x i32> [[VAL2]], [[VAL1]]
   si = si * si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = mul <4 x i32> [[VAL2]], [[VAL1]]
   ui = ui * ui2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = mul <2 x i64> [[VAL2]], [[VAL1]]
   sl = sl * sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = mul <2 x i64> [[VAL2]], [[VAL1]]
   ul = ul * ul2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: %{{.*}} = fmul <2 x double> [[VAL1]], [[VAL2]]
   fd = fd * fd2;
 }
 
-void test_mul_assign (void)
-{
-// CHECK-LABEL: test_mul_assign
+// CHECK-LABEL: define void @test_mul_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[MUL:%.*]] = mul <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[MUL]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[MUL1:%.*]] = mul <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[MUL1]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[MUL2:%.*]] = mul <8 x i16> [[TMP5]], [[TMP4]]
+// CHECK:   store volatile <8 x i16> [[MUL2]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[MUL3:%.*]] = mul <8 x i16> [[TMP7]], [[TMP6]]
+// CHECK:   store volatile <8 x i16> [[MUL3]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[MUL4:%.*]] = mul <4 x i32> [[TMP9]], [[TMP8]]
+// CHECK:   store volatile <4 x i32> [[MUL4]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[MUL5:%.*]] = mul <4 x i32> [[TMP11]], [[TMP10]]
+// CHECK:   store volatile <4 x i32> [[MUL5]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[MUL6:%.*]] = mul <2 x i64> [[TMP13]], [[TMP12]]
+// CHECK:   store volatile <2 x i64> [[MUL6]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[MUL7:%.*]] = mul <2 x i64> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <2 x i64> [[MUL7]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[MUL8:%.*]] = fmul <2 x double> [[TMP17]], [[TMP16]]
+// CHECK:   store volatile <2 x double> [[MUL8]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_mul_assign(void) {
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = mul <16 x i8> [[VAL1]], [[VAL2]]
   sc *= sc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = mul <16 x i8> [[VAL1]], [[VAL2]]
   uc *= uc2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = mul <8 x i16> [[VAL1]], [[VAL2]]
   ss *= ss2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = mul <8 x i16> [[VAL1]], [[VAL2]]
   us *= us2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = mul <4 x i32> [[VAL1]], [[VAL2]]
   si *= si2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = mul <4 x i32> [[VAL1]], [[VAL2]]
   ui *= ui2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = mul <2 x i64> [[VAL1]], [[VAL2]]
   sl *= sl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = mul <2 x i64> [[VAL1]], [[VAL2]]
   ul *= ul2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: %{{.*}} = fmul <2 x double> [[VAL2]], [[VAL1]]
   fd *= fd2;
 }
 
-void test_div (void)
-{
-// CHECK-LABEL: test_div
+// CHECK-LABEL: define void @test_div() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[DIV:%.*]] = sdiv <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[DIV]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[DIV1:%.*]] = udiv <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[DIV1]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[DIV2:%.*]] = sdiv <8 x i16> [[TMP4]], [[TMP5]]
+// CHECK:   store volatile <8 x i16> [[DIV2]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[DIV3:%.*]] = udiv <8 x i16> [[TMP6]], [[TMP7]]
+// CHECK:   store volatile <8 x i16> [[DIV3]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[DIV4:%.*]] = sdiv <4 x i32> [[TMP8]], [[TMP9]]
+// CHECK:   store volatile <4 x i32> [[DIV4]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[DIV5:%.*]] = udiv <4 x i32> [[TMP10]], [[TMP11]]
+// CHECK:   store volatile <4 x i32> [[DIV5]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[DIV6:%.*]] = sdiv <2 x i64> [[TMP12]], [[TMP13]]
+// CHECK:   store volatile <2 x i64> [[DIV6]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[DIV7:%.*]] = udiv <2 x i64> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <2 x i64> [[DIV7]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[DIV8:%.*]] = fdiv <2 x double> [[TMP16]], [[TMP17]]
+// CHECK:   store volatile <2 x double> [[DIV8]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_div(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = sdiv <16 x i8> [[VAL1]], [[VAL2]]
   sc = sc / sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = udiv <16 x i8> [[VAL1]], [[VAL2]]
   uc = uc / uc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = sdiv <8 x i16> [[VAL1]], [[VAL2]]
   ss = ss / ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = udiv <8 x i16> [[VAL1]], [[VAL2]]
   us = us / us2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = sdiv <4 x i32> [[VAL1]], [[VAL2]]
   si = si / si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = udiv <4 x i32> [[VAL1]], [[VAL2]]
   ui = ui / ui2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = sdiv <2 x i64> [[VAL1]], [[VAL2]]
   sl = sl / sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = udiv <2 x i64> [[VAL1]], [[VAL2]]
   ul = ul / ul2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: %{{.*}} = fdiv <2 x double> [[VAL1]], [[VAL2]]
   fd = fd / fd2;
 }
 
-void test_div_assign (void)
-{
-// CHECK-LABEL: test_div_assign
+// CHECK-LABEL: define void @test_div_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[DIV:%.*]] = sdiv <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[DIV]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[DIV1:%.*]] = udiv <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[DIV1]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[DIV2:%.*]] = sdiv <8 x i16> [[TMP5]], [[TMP4]]
+// CHECK:   store volatile <8 x i16> [[DIV2]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[DIV3:%.*]] = udiv <8 x i16> [[TMP7]], [[TMP6]]
+// CHECK:   store volatile <8 x i16> [[DIV3]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[DIV4:%.*]] = sdiv <4 x i32> [[TMP9]], [[TMP8]]
+// CHECK:   store volatile <4 x i32> [[DIV4]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[DIV5:%.*]] = udiv <4 x i32> [[TMP11]], [[TMP10]]
+// CHECK:   store volatile <4 x i32> [[DIV5]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[DIV6:%.*]] = sdiv <2 x i64> [[TMP13]], [[TMP12]]
+// CHECK:   store volatile <2 x i64> [[DIV6]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[DIV7:%.*]] = udiv <2 x i64> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <2 x i64> [[DIV7]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[DIV8:%.*]] = fdiv <2 x double> [[TMP17]], [[TMP16]]
+// CHECK:   store volatile <2 x double> [[DIV8]], <2 x double>* @fd, align 8
+// CHECK:   ret void
+void test_div_assign(void) {
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = sdiv <16 x i8> [[VAL1]], [[VAL2]]
   sc /= sc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = udiv <16 x i8> [[VAL1]], [[VAL2]]
   uc /= uc2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = sdiv <8 x i16> [[VAL1]], [[VAL2]]
   ss /= ss2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = udiv <8 x i16> [[VAL1]], [[VAL2]]
   us /= us2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = sdiv <4 x i32> [[VAL1]], [[VAL2]]
   si /= si2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = udiv <4 x i32> [[VAL1]], [[VAL2]]
   ui /= ui2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = sdiv <2 x i64> [[VAL1]], [[VAL2]]
   sl /= sl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = udiv <2 x i64> [[VAL1]], [[VAL2]]
   ul /= ul2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: %{{.*}} = fdiv <2 x double> [[VAL1]], [[VAL2]]
   fd /= fd2;
 }
 
-void test_rem (void)
-{
-// CHECK-LABEL: test_rem
+// CHECK-LABEL: define void @test_rem() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[REM:%.*]] = srem <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[REM]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[REM1:%.*]] = urem <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[REM1]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[REM2:%.*]] = srem <8 x i16> [[TMP4]], [[TMP5]]
+// CHECK:   store volatile <8 x i16> [[REM2]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[REM3:%.*]] = urem <8 x i16> [[TMP6]], [[TMP7]]
+// CHECK:   store volatile <8 x i16> [[REM3]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[REM4:%.*]] = srem <4 x i32> [[TMP8]], [[TMP9]]
+// CHECK:   store volatile <4 x i32> [[REM4]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[REM5:%.*]] = urem <4 x i32> [[TMP10]], [[TMP11]]
+// CHECK:   store volatile <4 x i32> [[REM5]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[REM6:%.*]] = srem <2 x i64> [[TMP12]], [[TMP13]]
+// CHECK:   store volatile <2 x i64> [[REM6]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[REM7:%.*]] = urem <2 x i64> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <2 x i64> [[REM7]], <2 x i64>* @ul, align 8
+// CHECK:   ret void
+void test_rem(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = srem <16 x i8> [[VAL1]], [[VAL2]]
   sc = sc % sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = urem <16 x i8> [[VAL1]], [[VAL2]]
   uc = uc % uc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = srem <8 x i16> [[VAL1]], [[VAL2]]
   ss = ss % ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = urem <8 x i16> [[VAL1]], [[VAL2]]
   us = us % us2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = srem <4 x i32> [[VAL1]], [[VAL2]]
   si = si % si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = urem <4 x i32> [[VAL1]], [[VAL2]]
   ui = ui % ui2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = srem <2 x i64> [[VAL1]], [[VAL2]]
   sl = sl % sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = urem <2 x i64> [[VAL1]], [[VAL2]]
   ul = ul % ul2;
 }
 
-void test_rem_assign (void)
-{
-// CHECK-LABEL: test_rem_assign
+// CHECK-LABEL: define void @test_rem_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[REM:%.*]] = srem <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[REM]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[REM1:%.*]] = urem <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[REM1]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[REM2:%.*]] = srem <8 x i16> [[TMP5]], [[TMP4]]
+// CHECK:   store volatile <8 x i16> [[REM2]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[REM3:%.*]] = urem <8 x i16> [[TMP7]], [[TMP6]]
+// CHECK:   store volatile <8 x i16> [[REM3]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[REM4:%.*]] = srem <4 x i32> [[TMP9]], [[TMP8]]
+// CHECK:   store volatile <4 x i32> [[REM4]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[REM5:%.*]] = urem <4 x i32> [[TMP11]], [[TMP10]]
+// CHECK:   store volatile <4 x i32> [[REM5]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[REM6:%.*]] = srem <2 x i64> [[TMP13]], [[TMP12]]
+// CHECK:   store volatile <2 x i64> [[REM6]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[REM7:%.*]] = urem <2 x i64> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <2 x i64> [[REM7]], <2 x i64>* @ul, align 8
+// CHECK:   ret void
+void test_rem_assign(void) {
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = srem <16 x i8> [[VAL1]], [[VAL2]]
   sc %= sc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = urem <16 x i8> [[VAL1]], [[VAL2]]
   uc %= uc2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = srem <8 x i16> [[VAL1]], [[VAL2]]
   ss %= ss2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = urem <8 x i16> [[VAL1]], [[VAL2]]
   us %= us2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = srem <4 x i32> [[VAL1]], [[VAL2]]
   si %= si2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = urem <4 x i32> [[VAL1]], [[VAL2]]
   ui %= ui2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = srem <2 x i64> [[VAL1]], [[VAL2]]
   sl %= sl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = urem <2 x i64> [[VAL1]], [[VAL2]]
   ul %= ul2;
 }
 
-void test_not (void)
-{
-// CHECK-LABEL: test_not
+// CHECK-LABEL: define void @test_not() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[NEG:%.*]] = xor <16 x i8> [[TMP0]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
+// CHECK:   store volatile <16 x i8> [[NEG]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[NEG1:%.*]] = xor <16 x i8> [[TMP1]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
+// CHECK:   store volatile <16 x i8> [[NEG1]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[NEG2:%.*]] = xor <16 x i8> [[TMP2]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
+// CHECK:   store volatile <16 x i8> [[NEG2]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[NEG3:%.*]] = xor <8 x i16> [[TMP3]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+// CHECK:   store volatile <8 x i16> [[NEG3]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[NEG4:%.*]] = xor <8 x i16> [[TMP4]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+// CHECK:   store volatile <8 x i16> [[NEG4]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[NEG5:%.*]] = xor <8 x i16> [[TMP5]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+// CHECK:   store volatile <8 x i16> [[NEG5]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[NEG6:%.*]] = xor <4 x i32> [[TMP6]], <i32 -1, i32 -1, i32 -1, i32 -1>
+// CHECK:   store volatile <4 x i32> [[NEG6]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[NEG7:%.*]] = xor <4 x i32> [[TMP7]], <i32 -1, i32 -1, i32 -1, i32 -1>
+// CHECK:   store volatile <4 x i32> [[NEG7]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[NEG8:%.*]] = xor <4 x i32> [[TMP8]], <i32 -1, i32 -1, i32 -1, i32 -1>
+// CHECK:   store volatile <4 x i32> [[NEG8]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[NEG9:%.*]] = xor <2 x i64> [[TMP9]], <i64 -1, i64 -1>
+// CHECK:   store volatile <2 x i64> [[NEG9]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[NEG10:%.*]] = xor <2 x i64> [[TMP10]], <i64 -1, i64 -1>
+// CHECK:   store volatile <2 x i64> [[NEG10]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[NEG11:%.*]] = xor <2 x i64> [[TMP11]], <i64 -1, i64 -1>
+// CHECK:   store volatile <2 x i64> [[NEG11]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_not(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
   sc = ~sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
   uc = ~uc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
   bc = ~bc2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
   ss = ~ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
   us = ~us2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
   bs = ~bs2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL]], <i32 -1, i32 -1, i32 -1, i32 -1>
   si = ~si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL]], <i32 -1, i32 -1, i32 -1, i32 -1>
   ui = ~ui2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL]], <i32 -1, i32 -1, i32 -1, i32 -1>
   bi = ~bi2;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL]], <i64 -1, i64 -1>
   sl = ~sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL]], <i64 -1, i64 -1>
   ul = ~ul2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL]], <i64 -1, i64 -1>
   bl = ~bl2;
 }
 
-void test_and (void)
-{
-// CHECK-LABEL: test_and
+// CHECK-LABEL: define void @test_and() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[AND:%.*]] = and <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[AND]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[AND1:%.*]] = and <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[AND1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[AND2:%.*]] = and <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   store volatile <16 x i8> [[AND2]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[AND3:%.*]] = and <16 x i8> [[TMP6]], [[TMP7]]
+// CHECK:   store volatile <16 x i8> [[AND3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[AND4:%.*]] = and <16 x i8> [[TMP8]], [[TMP9]]
+// CHECK:   store volatile <16 x i8> [[AND4]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[AND5:%.*]] = and <16 x i8> [[TMP10]], [[TMP11]]
+// CHECK:   store volatile <16 x i8> [[AND5]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[AND6:%.*]] = and <16 x i8> [[TMP12]], [[TMP13]]
+// CHECK:   store volatile <16 x i8> [[AND6]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[AND7:%.*]] = and <8 x i16> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <8 x i16> [[AND7]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[AND8:%.*]] = and <8 x i16> [[TMP16]], [[TMP17]]
+// CHECK:   store volatile <8 x i16> [[AND8]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[AND9:%.*]] = and <8 x i16> [[TMP18]], [[TMP19]]
+// CHECK:   store volatile <8 x i16> [[AND9]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[AND10:%.*]] = and <8 x i16> [[TMP20]], [[TMP21]]
+// CHECK:   store volatile <8 x i16> [[AND10]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[AND11:%.*]] = and <8 x i16> [[TMP22]], [[TMP23]]
+// CHECK:   store volatile <8 x i16> [[AND11]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[AND12:%.*]] = and <8 x i16> [[TMP24]], [[TMP25]]
+// CHECK:   store volatile <8 x i16> [[AND12]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[AND13:%.*]] = and <8 x i16> [[TMP26]], [[TMP27]]
+// CHECK:   store volatile <8 x i16> [[AND13]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[AND14:%.*]] = and <4 x i32> [[TMP28]], [[TMP29]]
+// CHECK:   store volatile <4 x i32> [[AND14]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[AND15:%.*]] = and <4 x i32> [[TMP30]], [[TMP31]]
+// CHECK:   store volatile <4 x i32> [[AND15]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[AND16:%.*]] = and <4 x i32> [[TMP32]], [[TMP33]]
+// CHECK:   store volatile <4 x i32> [[AND16]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[AND17:%.*]] = and <4 x i32> [[TMP34]], [[TMP35]]
+// CHECK:   store volatile <4 x i32> [[AND17]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[AND18:%.*]] = and <4 x i32> [[TMP36]], [[TMP37]]
+// CHECK:   store volatile <4 x i32> [[AND18]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[AND19:%.*]] = and <4 x i32> [[TMP38]], [[TMP39]]
+// CHECK:   store volatile <4 x i32> [[AND19]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP40:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[AND20:%.*]] = and <4 x i32> [[TMP40]], [[TMP41]]
+// CHECK:   store volatile <4 x i32> [[AND20]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[AND21:%.*]] = and <2 x i64> [[TMP42]], [[TMP43]]
+// CHECK:   store volatile <2 x i64> [[AND21]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[AND22:%.*]] = and <2 x i64> [[TMP44]], [[TMP45]]
+// CHECK:   store volatile <2 x i64> [[AND22]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP47:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[AND23:%.*]] = and <2 x i64> [[TMP46]], [[TMP47]]
+// CHECK:   store volatile <2 x i64> [[AND23]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[AND24:%.*]] = and <2 x i64> [[TMP48]], [[TMP49]]
+// CHECK:   store volatile <2 x i64> [[AND24]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP50:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP51:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[AND25:%.*]] = and <2 x i64> [[TMP50]], [[TMP51]]
+// CHECK:   store volatile <2 x i64> [[AND25]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP52:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP53:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[AND26:%.*]] = and <2 x i64> [[TMP52]], [[TMP53]]
+// CHECK:   store volatile <2 x i64> [[AND26]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP54:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP55:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[AND27:%.*]] = and <2 x i64> [[TMP54]], [[TMP55]]
+// CHECK:   store volatile <2 x i64> [[AND27]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_and(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = and <16 x i8> [[VAL2]], [[VAL1]]
   sc = sc & sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = and <16 x i8> [[VAL2]], [[VAL1]]
   sc = sc & bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = and <16 x i8> [[VAL2]], [[VAL1]]
   sc = bc & sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = and <16 x i8> [[VAL2]], [[VAL1]]
   uc = uc & uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = and <16 x i8> [[VAL2]], [[VAL1]]
   uc = uc & bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = and <16 x i8> [[VAL2]], [[VAL1]]
   uc = bc & uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = and <16 x i8> [[VAL2]], [[VAL1]]
   bc = bc & bc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = and <8 x i16> [[VAL2]], [[VAL1]]
   ss = ss & ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = and <8 x i16> [[VAL2]], [[VAL1]]
   ss = ss & bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = and <8 x i16> [[VAL2]], [[VAL1]]
   ss = bs & ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = and <8 x i16> [[VAL2]], [[VAL1]]
   us = us & us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = and <8 x i16> [[VAL2]], [[VAL1]]
   us = us & bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = and <8 x i16> [[VAL2]], [[VAL1]]
   us = bs & us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = and <8 x i16> [[VAL2]], [[VAL1]]
   bs = bs & bs2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = and <4 x i32> [[VAL2]], [[VAL1]]
   si = si & si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = and <4 x i32> [[VAL2]], [[VAL1]]
   si = si & bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = and <4 x i32> [[VAL2]], [[VAL1]]
   si = bi & si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = and <4 x i32> [[VAL2]], [[VAL1]]
   ui = ui & ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = and <4 x i32> [[VAL2]], [[VAL1]]
   ui = ui & bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = and <4 x i32> [[VAL2]], [[VAL1]]
   ui = bi & ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = and <4 x i32> [[VAL2]], [[VAL1]]
   bi = bi & bi2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = and <2 x i64> [[VAL2]], [[VAL1]]
   sl = sl & sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = and <2 x i64> [[VAL2]], [[VAL1]]
   sl = sl & bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = and <2 x i64> [[VAL2]], [[VAL1]]
   sl = bl & sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = and <2 x i64> [[VAL2]], [[VAL1]]
   ul = ul & ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = and <2 x i64> [[VAL2]], [[VAL1]]
   ul = ul & bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = and <2 x i64> [[VAL2]], [[VAL1]]
   ul = bl & ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = and <2 x i64> [[VAL2]], [[VAL1]]
   bl = bl & bl2;
 }
 
-void test_and_assign (void)
-{
-// CHECK-LABEL: test_and_assign
+// CHECK-LABEL: define void @test_and_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[AND:%.*]] = and <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[AND]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[AND1:%.*]] = and <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[AND1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[AND2:%.*]] = and <16 x i8> [[TMP5]], [[TMP4]]
+// CHECK:   store volatile <16 x i8> [[AND2]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[AND3:%.*]] = and <16 x i8> [[TMP7]], [[TMP6]]
+// CHECK:   store volatile <16 x i8> [[AND3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[AND4:%.*]] = and <16 x i8> [[TMP9]], [[TMP8]]
+// CHECK:   store volatile <16 x i8> [[AND4]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[AND5:%.*]] = and <8 x i16> [[TMP11]], [[TMP10]]
+// CHECK:   store volatile <8 x i16> [[AND5]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[AND6:%.*]] = and <8 x i16> [[TMP13]], [[TMP12]]
+// CHECK:   store volatile <8 x i16> [[AND6]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[AND7:%.*]] = and <8 x i16> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <8 x i16> [[AND7]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[AND8:%.*]] = and <8 x i16> [[TMP17]], [[TMP16]]
+// CHECK:   store volatile <8 x i16> [[AND8]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[AND9:%.*]] = and <8 x i16> [[TMP19]], [[TMP18]]
+// CHECK:   store volatile <8 x i16> [[AND9]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[AND10:%.*]] = and <4 x i32> [[TMP21]], [[TMP20]]
+// CHECK:   store volatile <4 x i32> [[AND10]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[AND11:%.*]] = and <4 x i32> [[TMP23]], [[TMP22]]
+// CHECK:   store volatile <4 x i32> [[AND11]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[AND12:%.*]] = and <4 x i32> [[TMP25]], [[TMP24]]
+// CHECK:   store volatile <4 x i32> [[AND12]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[AND13:%.*]] = and <4 x i32> [[TMP27]], [[TMP26]]
+// CHECK:   store volatile <4 x i32> [[AND13]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[AND14:%.*]] = and <4 x i32> [[TMP29]], [[TMP28]]
+// CHECK:   store volatile <4 x i32> [[AND14]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[AND15:%.*]] = and <2 x i64> [[TMP31]], [[TMP30]]
+// CHECK:   store volatile <2 x i64> [[AND15]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[AND16:%.*]] = and <2 x i64> [[TMP33]], [[TMP32]]
+// CHECK:   store volatile <2 x i64> [[AND16]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[AND17:%.*]] = and <2 x i64> [[TMP35]], [[TMP34]]
+// CHECK:   store volatile <2 x i64> [[AND17]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[AND18:%.*]] = and <2 x i64> [[TMP37]], [[TMP36]]
+// CHECK:   store volatile <2 x i64> [[AND18]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[AND19:%.*]] = and <2 x i64> [[TMP39]], [[TMP38]]
+// CHECK:   store volatile <2 x i64> [[AND19]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_and_assign(void) {
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = and <16 x i8> [[VAL1]], [[VAL2]]
   sc &= sc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = and <16 x i8> [[VAL1]], [[VAL2]]
   sc &= bc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = and <16 x i8> [[VAL1]], [[VAL2]]
   uc &= uc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = and <16 x i8> [[VAL1]], [[VAL2]]
   uc &= bc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: %{{.*}} = and <16 x i8> [[VAL1]], [[VAL2]]
   bc &= bc2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = and <8 x i16> [[VAL1]], [[VAL2]]
   ss &= ss2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = and <8 x i16> [[VAL1]], [[VAL2]]
   ss &= bs2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = and <8 x i16> [[VAL1]], [[VAL2]]
   us &= us2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = and <8 x i16> [[VAL1]], [[VAL2]]
   us &= bs2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: %{{.*}} = and <8 x i16> [[VAL1]], [[VAL2]]
   bs &= bs2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = and <4 x i32> [[VAL1]], [[VAL2]]
   si &= si2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = and <4 x i32> [[VAL1]], [[VAL2]]
   si &= bi2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = and <4 x i32> [[VAL1]], [[VAL2]]
   ui &= ui2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = and <4 x i32> [[VAL1]], [[VAL2]]
   ui &= bi2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: %{{.*}} = and <4 x i32> [[VAL1]], [[VAL2]]
   bi &= bi2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = and <2 x i64> [[VAL1]], [[VAL2]]
   sl &= sl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = and <2 x i64> [[VAL1]], [[VAL2]]
   sl &= bl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = and <2 x i64> [[VAL1]], [[VAL2]]
   ul &= ul2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = and <2 x i64> [[VAL1]], [[VAL2]]
   ul &= bl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: %{{.*}} = and <2 x i64> [[VAL1]], [[VAL2]]
   bl &= bl2;
 }
 
-void test_or (void)
-{
-// CHECK-LABEL: test_or
+// CHECK-LABEL: define void @test_or() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[OR:%.*]] = or <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[OR]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[OR1:%.*]] = or <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[OR1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[OR2:%.*]] = or <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   store volatile <16 x i8> [[OR2]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[OR3:%.*]] = or <16 x i8> [[TMP6]], [[TMP7]]
+// CHECK:   store volatile <16 x i8> [[OR3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[OR4:%.*]] = or <16 x i8> [[TMP8]], [[TMP9]]
+// CHECK:   store volatile <16 x i8> [[OR4]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[OR5:%.*]] = or <16 x i8> [[TMP10]], [[TMP11]]
+// CHECK:   store volatile <16 x i8> [[OR5]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[OR6:%.*]] = or <16 x i8> [[TMP12]], [[TMP13]]
+// CHECK:   store volatile <16 x i8> [[OR6]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[OR7:%.*]] = or <8 x i16> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <8 x i16> [[OR7]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[OR8:%.*]] = or <8 x i16> [[TMP16]], [[TMP17]]
+// CHECK:   store volatile <8 x i16> [[OR8]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[OR9:%.*]] = or <8 x i16> [[TMP18]], [[TMP19]]
+// CHECK:   store volatile <8 x i16> [[OR9]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[OR10:%.*]] = or <8 x i16> [[TMP20]], [[TMP21]]
+// CHECK:   store volatile <8 x i16> [[OR10]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[OR11:%.*]] = or <8 x i16> [[TMP22]], [[TMP23]]
+// CHECK:   store volatile <8 x i16> [[OR11]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[OR12:%.*]] = or <8 x i16> [[TMP24]], [[TMP25]]
+// CHECK:   store volatile <8 x i16> [[OR12]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[OR13:%.*]] = or <8 x i16> [[TMP26]], [[TMP27]]
+// CHECK:   store volatile <8 x i16> [[OR13]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[OR14:%.*]] = or <4 x i32> [[TMP28]], [[TMP29]]
+// CHECK:   store volatile <4 x i32> [[OR14]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[OR15:%.*]] = or <4 x i32> [[TMP30]], [[TMP31]]
+// CHECK:   store volatile <4 x i32> [[OR15]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[OR16:%.*]] = or <4 x i32> [[TMP32]], [[TMP33]]
+// CHECK:   store volatile <4 x i32> [[OR16]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[OR17:%.*]] = or <4 x i32> [[TMP34]], [[TMP35]]
+// CHECK:   store volatile <4 x i32> [[OR17]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[OR18:%.*]] = or <4 x i32> [[TMP36]], [[TMP37]]
+// CHECK:   store volatile <4 x i32> [[OR18]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[OR19:%.*]] = or <4 x i32> [[TMP38]], [[TMP39]]
+// CHECK:   store volatile <4 x i32> [[OR19]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP40:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[OR20:%.*]] = or <4 x i32> [[TMP40]], [[TMP41]]
+// CHECK:   store volatile <4 x i32> [[OR20]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[OR21:%.*]] = or <2 x i64> [[TMP42]], [[TMP43]]
+// CHECK:   store volatile <2 x i64> [[OR21]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[OR22:%.*]] = or <2 x i64> [[TMP44]], [[TMP45]]
+// CHECK:   store volatile <2 x i64> [[OR22]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP47:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[OR23:%.*]] = or <2 x i64> [[TMP46]], [[TMP47]]
+// CHECK:   store volatile <2 x i64> [[OR23]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[OR24:%.*]] = or <2 x i64> [[TMP48]], [[TMP49]]
+// CHECK:   store volatile <2 x i64> [[OR24]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP50:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP51:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[OR25:%.*]] = or <2 x i64> [[TMP50]], [[TMP51]]
+// CHECK:   store volatile <2 x i64> [[OR25]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP52:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP53:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[OR26:%.*]] = or <2 x i64> [[TMP52]], [[TMP53]]
+// CHECK:   store volatile <2 x i64> [[OR26]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP54:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP55:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[OR27:%.*]] = or <2 x i64> [[TMP54]], [[TMP55]]
+// CHECK:   store volatile <2 x i64> [[OR27]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_or(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = or <16 x i8> [[VAL2]], [[VAL1]]
   sc = sc | sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = or <16 x i8> [[VAL2]], [[VAL1]]
   sc = sc | bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = or <16 x i8> [[VAL2]], [[VAL1]]
   sc = bc | sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = or <16 x i8> [[VAL2]], [[VAL1]]
   uc = uc | uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = or <16 x i8> [[VAL2]], [[VAL1]]
   uc = uc | bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = or <16 x i8> [[VAL2]], [[VAL1]]
   uc = bc | uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = or <16 x i8> [[VAL2]], [[VAL1]]
   bc = bc | bc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = or <8 x i16> [[VAL2]], [[VAL1]]
   ss = ss | ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = or <8 x i16> [[VAL2]], [[VAL1]]
   ss = ss | bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = or <8 x i16> [[VAL2]], [[VAL1]]
   ss = bs | ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = or <8 x i16> [[VAL2]], [[VAL1]]
   us = us | us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = or <8 x i16> [[VAL2]], [[VAL1]]
   us = us | bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = or <8 x i16> [[VAL2]], [[VAL1]]
   us = bs | us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = or <8 x i16> [[VAL2]], [[VAL1]]
   bs = bs | bs2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = or <4 x i32> [[VAL2]], [[VAL1]]
   si = si | si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = or <4 x i32> [[VAL2]], [[VAL1]]
   si = si | bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = or <4 x i32> [[VAL2]], [[VAL1]]
   si = bi | si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = or <4 x i32> [[VAL2]], [[VAL1]]
   ui = ui | ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = or <4 x i32> [[VAL2]], [[VAL1]]
   ui = ui | bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = or <4 x i32> [[VAL2]], [[VAL1]]
   ui = bi | ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = or <4 x i32> [[VAL2]], [[VAL1]]
   bi = bi | bi2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = or <2 x i64> [[VAL2]], [[VAL1]]
   sl = sl | sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = or <2 x i64> [[VAL2]], [[VAL1]]
   sl = sl | bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = or <2 x i64> [[VAL2]], [[VAL1]]
   sl = bl | sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = or <2 x i64> [[VAL2]], [[VAL1]]
   ul = ul | ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = or <2 x i64> [[VAL2]], [[VAL1]]
   ul = ul | bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = or <2 x i64> [[VAL2]], [[VAL1]]
   ul = bl | ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = or <2 x i64> [[VAL2]], [[VAL1]]
   bl = bl | bl2;
 }
 
-void test_or_assign (void)
-{
-// CHECK-LABEL: test_or_assign
+// CHECK-LABEL: define void @test_or_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[OR:%.*]] = or <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[OR]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[OR1:%.*]] = or <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[OR1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[OR2:%.*]] = or <16 x i8> [[TMP5]], [[TMP4]]
+// CHECK:   store volatile <16 x i8> [[OR2]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[OR3:%.*]] = or <16 x i8> [[TMP7]], [[TMP6]]
+// CHECK:   store volatile <16 x i8> [[OR3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[OR4:%.*]] = or <16 x i8> [[TMP9]], [[TMP8]]
+// CHECK:   store volatile <16 x i8> [[OR4]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[OR5:%.*]] = or <8 x i16> [[TMP11]], [[TMP10]]
+// CHECK:   store volatile <8 x i16> [[OR5]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[OR6:%.*]] = or <8 x i16> [[TMP13]], [[TMP12]]
+// CHECK:   store volatile <8 x i16> [[OR6]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[OR7:%.*]] = or <8 x i16> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <8 x i16> [[OR7]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[OR8:%.*]] = or <8 x i16> [[TMP17]], [[TMP16]]
+// CHECK:   store volatile <8 x i16> [[OR8]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[OR9:%.*]] = or <8 x i16> [[TMP19]], [[TMP18]]
+// CHECK:   store volatile <8 x i16> [[OR9]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[OR10:%.*]] = or <4 x i32> [[TMP21]], [[TMP20]]
+// CHECK:   store volatile <4 x i32> [[OR10]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[OR11:%.*]] = or <4 x i32> [[TMP23]], [[TMP22]]
+// CHECK:   store volatile <4 x i32> [[OR11]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[OR12:%.*]] = or <4 x i32> [[TMP25]], [[TMP24]]
+// CHECK:   store volatile <4 x i32> [[OR12]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[OR13:%.*]] = or <4 x i32> [[TMP27]], [[TMP26]]
+// CHECK:   store volatile <4 x i32> [[OR13]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[OR14:%.*]] = or <4 x i32> [[TMP29]], [[TMP28]]
+// CHECK:   store volatile <4 x i32> [[OR14]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[OR15:%.*]] = or <2 x i64> [[TMP31]], [[TMP30]]
+// CHECK:   store volatile <2 x i64> [[OR15]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[OR16:%.*]] = or <2 x i64> [[TMP33]], [[TMP32]]
+// CHECK:   store volatile <2 x i64> [[OR16]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[OR17:%.*]] = or <2 x i64> [[TMP35]], [[TMP34]]
+// CHECK:   store volatile <2 x i64> [[OR17]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[OR18:%.*]] = or <2 x i64> [[TMP37]], [[TMP36]]
+// CHECK:   store volatile <2 x i64> [[OR18]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[OR19:%.*]] = or <2 x i64> [[TMP39]], [[TMP38]]
+// CHECK:   store volatile <2 x i64> [[OR19]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_or_assign(void) {
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = or <16 x i8> [[VAL1]], [[VAL2]]
   sc |= sc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = or <16 x i8> [[VAL1]], [[VAL2]]
   sc |= bc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = or <16 x i8> [[VAL1]], [[VAL2]]
   uc |= uc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = or <16 x i8> [[VAL1]], [[VAL2]]
   uc |= bc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: %{{.*}} = or <16 x i8> [[VAL1]], [[VAL2]]
   bc |= bc2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = or <8 x i16> [[VAL1]], [[VAL2]]
   ss |= ss2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = or <8 x i16> [[VAL1]], [[VAL2]]
   ss |= bs2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = or <8 x i16> [[VAL1]], [[VAL2]]
   us |= us2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = or <8 x i16> [[VAL1]], [[VAL2]]
   us |= bs2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: %{{.*}} = or <8 x i16> [[VAL1]], [[VAL2]]
   bs |= bs2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = or <4 x i32> [[VAL1]], [[VAL2]]
   si |= si2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = or <4 x i32> [[VAL1]], [[VAL2]]
   si |= bi2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = or <4 x i32> [[VAL1]], [[VAL2]]
   ui |= ui2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = or <4 x i32> [[VAL1]], [[VAL2]]
   ui |= bi2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: %{{.*}} = or <4 x i32> [[VAL1]], [[VAL2]]
   bi |= bi2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = or <2 x i64> [[VAL1]], [[VAL2]]
   sl |= sl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = or <2 x i64> [[VAL1]], [[VAL2]]
   sl |= bl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = or <2 x i64> [[VAL1]], [[VAL2]]
   ul |= ul2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = or <2 x i64> [[VAL1]], [[VAL2]]
   ul |= bl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: %{{.*}} = or <2 x i64> [[VAL1]], [[VAL2]]
   bl |= bl2;
 }
 
-void test_xor (void)
-{
-// CHECK-LABEL: test_xor
+// CHECK-LABEL: define void @test_xor() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[XOR:%.*]] = xor <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[XOR]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[XOR1:%.*]] = xor <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[XOR1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[XOR2:%.*]] = xor <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   store volatile <16 x i8> [[XOR2]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[XOR3:%.*]] = xor <16 x i8> [[TMP6]], [[TMP7]]
+// CHECK:   store volatile <16 x i8> [[XOR3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[XOR4:%.*]] = xor <16 x i8> [[TMP8]], [[TMP9]]
+// CHECK:   store volatile <16 x i8> [[XOR4]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[XOR5:%.*]] = xor <16 x i8> [[TMP10]], [[TMP11]]
+// CHECK:   store volatile <16 x i8> [[XOR5]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[XOR6:%.*]] = xor <16 x i8> [[TMP12]], [[TMP13]]
+// CHECK:   store volatile <16 x i8> [[XOR6]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[XOR7:%.*]] = xor <8 x i16> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <8 x i16> [[XOR7]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[XOR8:%.*]] = xor <8 x i16> [[TMP16]], [[TMP17]]
+// CHECK:   store volatile <8 x i16> [[XOR8]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[XOR9:%.*]] = xor <8 x i16> [[TMP18]], [[TMP19]]
+// CHECK:   store volatile <8 x i16> [[XOR9]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[XOR10:%.*]] = xor <8 x i16> [[TMP20]], [[TMP21]]
+// CHECK:   store volatile <8 x i16> [[XOR10]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[XOR11:%.*]] = xor <8 x i16> [[TMP22]], [[TMP23]]
+// CHECK:   store volatile <8 x i16> [[XOR11]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[XOR12:%.*]] = xor <8 x i16> [[TMP24]], [[TMP25]]
+// CHECK:   store volatile <8 x i16> [[XOR12]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[XOR13:%.*]] = xor <8 x i16> [[TMP26]], [[TMP27]]
+// CHECK:   store volatile <8 x i16> [[XOR13]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[XOR14:%.*]] = xor <4 x i32> [[TMP28]], [[TMP29]]
+// CHECK:   store volatile <4 x i32> [[XOR14]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[XOR15:%.*]] = xor <4 x i32> [[TMP30]], [[TMP31]]
+// CHECK:   store volatile <4 x i32> [[XOR15]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[XOR16:%.*]] = xor <4 x i32> [[TMP32]], [[TMP33]]
+// CHECK:   store volatile <4 x i32> [[XOR16]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[XOR17:%.*]] = xor <4 x i32> [[TMP34]], [[TMP35]]
+// CHECK:   store volatile <4 x i32> [[XOR17]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[XOR18:%.*]] = xor <4 x i32> [[TMP36]], [[TMP37]]
+// CHECK:   store volatile <4 x i32> [[XOR18]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[XOR19:%.*]] = xor <4 x i32> [[TMP38]], [[TMP39]]
+// CHECK:   store volatile <4 x i32> [[XOR19]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP40:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[XOR20:%.*]] = xor <4 x i32> [[TMP40]], [[TMP41]]
+// CHECK:   store volatile <4 x i32> [[XOR20]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[XOR21:%.*]] = xor <2 x i64> [[TMP42]], [[TMP43]]
+// CHECK:   store volatile <2 x i64> [[XOR21]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[XOR22:%.*]] = xor <2 x i64> [[TMP44]], [[TMP45]]
+// CHECK:   store volatile <2 x i64> [[XOR22]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP47:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[XOR23:%.*]] = xor <2 x i64> [[TMP46]], [[TMP47]]
+// CHECK:   store volatile <2 x i64> [[XOR23]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[XOR24:%.*]] = xor <2 x i64> [[TMP48]], [[TMP49]]
+// CHECK:   store volatile <2 x i64> [[XOR24]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP50:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP51:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[XOR25:%.*]] = xor <2 x i64> [[TMP50]], [[TMP51]]
+// CHECK:   store volatile <2 x i64> [[XOR25]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP52:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP53:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[XOR26:%.*]] = xor <2 x i64> [[TMP52]], [[TMP53]]
+// CHECK:   store volatile <2 x i64> [[XOR26]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP54:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP55:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[XOR27:%.*]] = xor <2 x i64> [[TMP54]], [[TMP55]]
+// CHECK:   store volatile <2 x i64> [[XOR27]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_xor(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL1]], [[VAL2]]
   sc = sc ^ sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL1]], [[VAL2]]
   sc = sc ^ bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL1]], [[VAL2]]
   sc = bc ^ sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL1]], [[VAL2]]
   uc = uc ^ uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL1]], [[VAL2]]
   uc = uc ^ bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL1]], [[VAL2]]
   uc = bc ^ uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL1]], [[VAL2]]
   bc = bc ^ bc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL1]], [[VAL2]]
   ss = ss ^ ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL1]], [[VAL2]]
   ss = ss ^ bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL1]], [[VAL2]]
   ss = bs ^ ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL1]], [[VAL2]]
   us = us ^ us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL1]], [[VAL2]]
   us = us ^ bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL1]], [[VAL2]]
   us = bs ^ us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL1]], [[VAL2]]
   bs = bs ^ bs2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL1]], [[VAL2]]
   si = si ^ si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL1]], [[VAL2]]
   si = si ^ bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL1]], [[VAL2]]
   si = bi ^ si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL1]], [[VAL2]]
   ui = ui ^ ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL1]], [[VAL2]]
   ui = ui ^ bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL1]], [[VAL2]]
   ui = bi ^ ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL1]], [[VAL2]]
   bi = bi ^ bi2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL1]], [[VAL2]]
   sl = sl ^ sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL1]], [[VAL2]]
   sl = sl ^ bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL1]], [[VAL2]]
   sl = bl ^ sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL1]], [[VAL2]]
   ul = ul ^ ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL1]], [[VAL2]]
   ul = ul ^ bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL1]], [[VAL2]]
   ul = bl ^ ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL1]], [[VAL2]]
   bl = bl ^ bl2;
 }
 
-void test_xor_assign (void)
-{
-// CHECK-LABEL: test_xor_assign
+// CHECK-LABEL: define void @test_xor_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[XOR:%.*]] = xor <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[XOR]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[XOR1:%.*]] = xor <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[XOR1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[XOR2:%.*]] = xor <16 x i8> [[TMP5]], [[TMP4]]
+// CHECK:   store volatile <16 x i8> [[XOR2]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[XOR3:%.*]] = xor <16 x i8> [[TMP7]], [[TMP6]]
+// CHECK:   store volatile <16 x i8> [[XOR3]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[XOR4:%.*]] = xor <16 x i8> [[TMP9]], [[TMP8]]
+// CHECK:   store volatile <16 x i8> [[XOR4]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[XOR5:%.*]] = xor <8 x i16> [[TMP11]], [[TMP10]]
+// CHECK:   store volatile <8 x i16> [[XOR5]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[XOR6:%.*]] = xor <8 x i16> [[TMP13]], [[TMP12]]
+// CHECK:   store volatile <8 x i16> [[XOR6]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[XOR7:%.*]] = xor <8 x i16> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <8 x i16> [[XOR7]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[XOR8:%.*]] = xor <8 x i16> [[TMP17]], [[TMP16]]
+// CHECK:   store volatile <8 x i16> [[XOR8]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[XOR9:%.*]] = xor <8 x i16> [[TMP19]], [[TMP18]]
+// CHECK:   store volatile <8 x i16> [[XOR9]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[XOR10:%.*]] = xor <4 x i32> [[TMP21]], [[TMP20]]
+// CHECK:   store volatile <4 x i32> [[XOR10]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[XOR11:%.*]] = xor <4 x i32> [[TMP23]], [[TMP22]]
+// CHECK:   store volatile <4 x i32> [[XOR11]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[XOR12:%.*]] = xor <4 x i32> [[TMP25]], [[TMP24]]
+// CHECK:   store volatile <4 x i32> [[XOR12]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[XOR13:%.*]] = xor <4 x i32> [[TMP27]], [[TMP26]]
+// CHECK:   store volatile <4 x i32> [[XOR13]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[XOR14:%.*]] = xor <4 x i32> [[TMP29]], [[TMP28]]
+// CHECK:   store volatile <4 x i32> [[XOR14]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[XOR15:%.*]] = xor <2 x i64> [[TMP31]], [[TMP30]]
+// CHECK:   store volatile <2 x i64> [[XOR15]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[XOR16:%.*]] = xor <2 x i64> [[TMP33]], [[TMP32]]
+// CHECK:   store volatile <2 x i64> [[XOR16]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[XOR17:%.*]] = xor <2 x i64> [[TMP35]], [[TMP34]]
+// CHECK:   store volatile <2 x i64> [[XOR17]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[XOR18:%.*]] = xor <2 x i64> [[TMP37]], [[TMP36]]
+// CHECK:   store volatile <2 x i64> [[XOR18]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[XOR19:%.*]] = xor <2 x i64> [[TMP39]], [[TMP38]]
+// CHECK:   store volatile <2 x i64> [[XOR19]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_xor_assign(void) {
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL2]], [[VAL1]]
   sc ^= sc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL2]], [[VAL1]]
   sc ^= bc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL2]], [[VAL1]]
   uc ^= uc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL2]], [[VAL1]]
   uc ^= bc2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: %{{.*}} = xor <16 x i8> [[VAL2]], [[VAL1]]
   bc ^= bc2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL2]], [[VAL1]]
   ss ^= ss2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL2]], [[VAL1]]
   ss ^= bs2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL2]], [[VAL1]]
   us ^= us2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL2]], [[VAL1]]
   us ^= bs2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: %{{.*}} = xor <8 x i16> [[VAL2]], [[VAL1]]
   bs ^= bs2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL2]], [[VAL1]]
   si ^= si2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL2]], [[VAL1]]
   si ^= bi2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL2]], [[VAL1]]
   ui ^= ui2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL2]], [[VAL1]]
   ui ^= bi2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: %{{.*}} = xor <4 x i32> [[VAL2]], [[VAL1]]
   bi ^= bi2;
 
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL2]], [[VAL1]]
   sl ^= sl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL2]], [[VAL1]]
   sl ^= bl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL2]], [[VAL1]]
   ul ^= ul2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL2]], [[VAL1]]
   ul ^= bl2;
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: %{{.*}} = xor <2 x i64> [[VAL2]], [[VAL1]]
   bl ^= bl2;
 }
 
-void test_sl (void)
-{
-// CHECK-LABEL: test_sl
+// CHECK-LABEL: define void @test_sl() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[SHL:%.*]] = shl <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[SHL]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[SHL1:%.*]] = shl <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[SHL1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT:%.*]] = insertelement <16 x i32> undef, i32 [[TMP5]], i32 0
+// CHECK:   [[SPLAT_SPLAT:%.*]] = shufflevector <16 x i32> [[SPLAT_SPLAT:%.*]]insert, <16 x i32> undef, <16 x i32> zeroinitializer
+// CHECK:   [[SH_PROM:%.*]] = trunc <16 x i32> [[SPLAT_SPLAT]] to <16 x i8>
+// CHECK:   [[SHL2:%.*]] = shl <16 x i8> [[TMP4]], [[SH_PROM]]
+// CHECK:   store volatile <16 x i8> [[SHL2]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SHL3:%.*]] = shl <16 x i8> [[TMP6]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+// CHECK:   store volatile <16 x i8> [[SHL3]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[SHL4:%.*]] = shl <16 x i8> [[TMP7]], [[TMP8]]
+// CHECK:   store volatile <16 x i8> [[SHL4]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[SHL5:%.*]] = shl <16 x i8> [[TMP9]], [[TMP10]]
+// CHECK:   store volatile <16 x i8> [[SHL5]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT6:%.*]] = insertelement <16 x i32> undef, i32 [[TMP12]], i32 0
+// CHECK:   [[SPLAT_SPLAT7:%.*]] = shufflevector <16 x i32> [[SPLAT_SPLATINSERT6]], <16 x i32> undef, <16 x i32> zeroinitializer
+// CHECK:   [[SH_PROM8:%.*]] = trunc <16 x i32> [[SPLAT_SPLAT7]] to <16 x i8>
+// CHECK:   [[SHL9:%.*]] = shl <16 x i8> [[TMP11]], [[SH_PROM8]]
+// CHECK:   store volatile <16 x i8> [[SHL9]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SHL10:%.*]] = shl <16 x i8> [[TMP13]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+// CHECK:   store volatile <16 x i8> [[SHL10]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[SHL11:%.*]] = shl <8 x i16> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <8 x i16> [[SHL11]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[SHL12:%.*]] = shl <8 x i16> [[TMP16]], [[TMP17]]
+// CHECK:   store volatile <8 x i16> [[SHL12]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT13:%.*]] = insertelement <8 x i32> undef, i32 [[TMP19]], i32 0
+// CHECK:   [[SPLAT_SPLAT14:%.*]] = shufflevector <8 x i32> [[SPLAT_SPLATINSERT13]], <8 x i32> undef, <8 x i32> zeroinitializer
+// CHECK:   [[SH_PROM15:%.*]] = trunc <8 x i32> [[SPLAT_SPLAT14]] to <8 x i16>
+// CHECK:   [[SHL16:%.*]] = shl <8 x i16> [[TMP18]], [[SH_PROM15]]
+// CHECK:   store volatile <8 x i16> [[SHL16]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SHL17:%.*]] = shl <8 x i16> [[TMP20]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+// CHECK:   store volatile <8 x i16> [[SHL17]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[SHL18:%.*]] = shl <8 x i16> [[TMP21]], [[TMP22]]
+// CHECK:   store volatile <8 x i16> [[SHL18]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[SHL19:%.*]] = shl <8 x i16> [[TMP23]], [[TMP24]]
+// CHECK:   store volatile <8 x i16> [[SHL19]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT20:%.*]] = insertelement <8 x i32> undef, i32 [[TMP26]], i32 0
+// CHECK:   [[SPLAT_SPLAT21:%.*]] = shufflevector <8 x i32> [[SPLAT_SPLATINSERT20]], <8 x i32> undef, <8 x i32> zeroinitializer
+// CHECK:   [[SH_PROM22:%.*]] = trunc <8 x i32> [[SPLAT_SPLAT21]] to <8 x i16>
+// CHECK:   [[SHL23:%.*]] = shl <8 x i16> [[TMP25]], [[SH_PROM22]]
+// CHECK:   store volatile <8 x i16> [[SHL23]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SHL24:%.*]] = shl <8 x i16> [[TMP27]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+// CHECK:   store volatile <8 x i16> [[SHL24]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[SHL25:%.*]] = shl <4 x i32> [[TMP28]], [[TMP29]]
+// CHECK:   store volatile <4 x i32> [[SHL25]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[SHL26:%.*]] = shl <4 x i32> [[TMP30]], [[TMP31]]
+// CHECK:   store volatile <4 x i32> [[SHL26]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT27:%.*]] = insertelement <4 x i32> undef, i32 [[TMP33]], i32 0
+// CHECK:   [[SPLAT_SPLAT28:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT27]], <4 x i32> undef, <4 x i32> zeroinitializer
+// CHECK:   [[SHL29:%.*]] = shl <4 x i32> [[TMP32]], [[SPLAT_SPLAT28]]
+// CHECK:   store volatile <4 x i32> [[SHL29]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHL30:%.*]] = shl <4 x i32> [[TMP34]], <i32 5, i32 5, i32 5, i32 5>
+// CHECK:   store volatile <4 x i32> [[SHL30]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[SHL31:%.*]] = shl <4 x i32> [[TMP35]], [[TMP36]]
+// CHECK:   store volatile <4 x i32> [[SHL31]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[SHL32:%.*]] = shl <4 x i32> [[TMP37]], [[TMP38]]
+// CHECK:   store volatile <4 x i32> [[SHL32]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP40:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT33:%.*]] = insertelement <4 x i32> undef, i32 [[TMP40]], i32 0
+// CHECK:   [[SPLAT_SPLAT34:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT33]], <4 x i32> undef, <4 x i32> zeroinitializer
+// CHECK:   [[SHL35:%.*]] = shl <4 x i32> [[TMP39]], [[SPLAT_SPLAT34]]
+// CHECK:   store volatile <4 x i32> [[SHL35]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHL36:%.*]] = shl <4 x i32> [[TMP41]], <i32 5, i32 5, i32 5, i32 5>
+// CHECK:   store volatile <4 x i32> [[SHL36]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[SHL37:%.*]] = shl <2 x i64> [[TMP42]], [[TMP43]]
+// CHECK:   store volatile <2 x i64> [[SHL37]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[SHL38:%.*]] = shl <2 x i64> [[TMP44]], [[TMP45]]
+// CHECK:   store volatile <2 x i64> [[SHL38]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP47:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT39:%.*]] = insertelement <2 x i32> undef, i32 [[TMP47]], i32 0
+// CHECK:   [[SPLAT_SPLAT40:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT39]], <2 x i32> undef, <2 x i32> zeroinitializer
+// CHECK:   [[SH_PROM41:%.*]] = zext <2 x i32> [[SPLAT_SPLAT40]] to <2 x i64>
+// CHECK:   [[SHL42:%.*]] = shl <2 x i64> [[TMP46]], [[SH_PROM41]]
+// CHECK:   store volatile <2 x i64> [[SHL42]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SHL43:%.*]] = shl <2 x i64> [[TMP48]], <i64 5, i64 5>
+// CHECK:   store volatile <2 x i64> [[SHL43]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP50:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[SHL44:%.*]] = shl <2 x i64> [[TMP49]], [[TMP50]]
+// CHECK:   store volatile <2 x i64> [[SHL44]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP51:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP52:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[SHL45:%.*]] = shl <2 x i64> [[TMP51]], [[TMP52]]
+// CHECK:   store volatile <2 x i64> [[SHL45]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP53:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP54:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT46:%.*]] = insertelement <2 x i32> undef, i32 [[TMP54]], i32 0
+// CHECK:   [[SPLAT_SPLAT47:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT46]], <2 x i32> undef, <2 x i32> zeroinitializer
+// CHECK:   [[SH_PROM48:%.*]] = zext <2 x i32> [[SPLAT_SPLAT47]] to <2 x i64>
+// CHECK:   [[SHL49:%.*]] = shl <2 x i64> [[TMP53]], [[SH_PROM48]]
+// CHECK:   store volatile <2 x i64> [[SHL49]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP55:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SHL50:%.*]] = shl <2 x i64> [[TMP55]], <i64 5, i64 5>
+// CHECK:   store volatile <2 x i64> [[SHL50]], <2 x i64>* @ul, align 8
+// CHECK:   ret void
+void test_sl(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   sc = sc << sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   sc = sc << uc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <16 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <16 x i32> [[T2]], <16 x i32> undef, <16 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = trunc <16 x i32> [[T3]] to <16 x i8>
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   sc = sc << cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
   sc = sc << 5;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   uc = uc << sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   uc = uc << uc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <16 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <16 x i32> [[T2]], <16 x i32> undef, <16 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = trunc <16 x i32> [[T3]] to <16 x i8>
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   uc = uc << cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
   uc = uc << 5;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   ss = ss << ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   ss = ss << us2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <8 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <8 x i32> [[T2]], <8 x i32> undef, <8 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = trunc <8 x i32> [[T3]] to <8 x i16>
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   ss = ss << cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
   ss = ss << 5;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   us = us << ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   us = us << us2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <8 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <8 x i32> [[T2]], <8 x i32> undef, <8 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = trunc <8 x i32> [[T3]] to <8 x i16>
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   us = us << cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
   us = us << 5;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   si = si << si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   si = si << ui2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T3:%[^ ]+]] = insertelement <4 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[CNT:%[^ ]+]] = shufflevector <4 x i32> [[T3]], <4 x i32> undef, <4 x i32> zeroinitializer
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   si = si << cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], <i32 5, i32 5, i32 5, i32 5>
   si = si << 5;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   ui = ui << si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   ui = ui << ui2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T3:%[^ ]+]] = insertelement <4 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[CNT:%[^ ]+]] = shufflevector <4 x i32> [[T3]], <4 x i32> undef, <4 x i32> zeroinitializer
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   ui = ui << cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], <i32 5, i32 5, i32 5, i32 5>
   ui = ui << 5;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   sl = sl << sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   sl = sl << ul2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <2 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <2 x i32> [[T2]], <2 x i32> undef, <2 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = zext <2 x i32> [[T3]] to <2 x i64>
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   sl = sl << cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], <i64 5, i64 5>
   sl = sl << 5;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   ul = ul << sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   ul = ul << ul2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <2 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <2 x i32> [[T2]], <2 x i32> undef, <2 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = zext <2 x i32> [[T3]] to <2 x i64>
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   ul = ul << cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], <i64 5, i64 5>
   ul = ul << 5;
 }
 
-void test_sl_assign (void)
-{
-// CHECK-LABEL: test_sl_assign
+// CHECK-LABEL: define void @test_sl_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SHL:%.*]] = shl <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[SHL]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SHL1:%.*]] = shl <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[SHL1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT:%.*]] = insertelement <16 x i32> undef, i32 [[TMP4]], i32 0
+// CHECK:   [[SPLAT_SPLAT:%.*]] = shufflevector <16 x i32> [[SPLAT_SPLAT:%.*]]insert, <16 x i32> undef, <16 x i32> zeroinitializer
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SH_PROM:%.*]] = trunc <16 x i32> [[SPLAT_SPLAT]] to <16 x i8>
+// CHECK:   [[SHL2:%.*]] = shl <16 x i8> [[TMP5]], [[SH_PROM]]
+// CHECK:   store volatile <16 x i8> [[SHL2]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SHL3:%.*]] = shl <16 x i8> [[TMP6]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+// CHECK:   store volatile <16 x i8> [[SHL3]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SHL4:%.*]] = shl <16 x i8> [[TMP8]], [[TMP7]]
+// CHECK:   store volatile <16 x i8> [[SHL4]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SHL5:%.*]] = shl <16 x i8> [[TMP10]], [[TMP9]]
+// CHECK:   store volatile <16 x i8> [[SHL5]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT6:%.*]] = insertelement <16 x i32> undef, i32 [[TMP11]], i32 0
+// CHECK:   [[SPLAT_SPLAT7:%.*]] = shufflevector <16 x i32> [[SPLAT_SPLATINSERT6]], <16 x i32> undef, <16 x i32> zeroinitializer
+// CHECK:   [[TMP12:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SH_PROM8:%.*]] = trunc <16 x i32> [[SPLAT_SPLAT7]] to <16 x i8>
+// CHECK:   [[SHL9:%.*]] = shl <16 x i8> [[TMP12]], [[SH_PROM8]]
+// CHECK:   store volatile <16 x i8> [[SHL9]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SHL10:%.*]] = shl <16 x i8> [[TMP13]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+// CHECK:   store volatile <16 x i8> [[SHL10]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SHL11:%.*]] = shl <8 x i16> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <8 x i16> [[SHL11]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SHL12:%.*]] = shl <8 x i16> [[TMP17]], [[TMP16]]
+// CHECK:   store volatile <8 x i16> [[SHL12]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT13:%.*]] = insertelement <8 x i32> undef, i32 [[TMP18]], i32 0
+// CHECK:   [[SPLAT_SPLAT14:%.*]] = shufflevector <8 x i32> [[SPLAT_SPLATINSERT13]], <8 x i32> undef, <8 x i32> zeroinitializer
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SH_PROM15:%.*]] = trunc <8 x i32> [[SPLAT_SPLAT14]] to <8 x i16>
+// CHECK:   [[SHL16:%.*]] = shl <8 x i16> [[TMP19]], [[SH_PROM15]]
+// CHECK:   store volatile <8 x i16> [[SHL16]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SHL17:%.*]] = shl <8 x i16> [[TMP20]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+// CHECK:   store volatile <8 x i16> [[SHL17]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SHL18:%.*]] = shl <8 x i16> [[TMP22]], [[TMP21]]
+// CHECK:   store volatile <8 x i16> [[SHL18]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SHL19:%.*]] = shl <8 x i16> [[TMP24]], [[TMP23]]
+// CHECK:   store volatile <8 x i16> [[SHL19]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT20:%.*]] = insertelement <8 x i32> undef, i32 [[TMP25]], i32 0
+// CHECK:   [[SPLAT_SPLAT21:%.*]] = shufflevector <8 x i32> [[SPLAT_SPLATINSERT20]], <8 x i32> undef, <8 x i32> zeroinitializer
+// CHECK:   [[TMP26:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SH_PROM22:%.*]] = trunc <8 x i32> [[SPLAT_SPLAT21]] to <8 x i16>
+// CHECK:   [[SHL23:%.*]] = shl <8 x i16> [[TMP26]], [[SH_PROM22]]
+// CHECK:   store volatile <8 x i16> [[SHL23]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SHL24:%.*]] = shl <8 x i16> [[TMP27]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+// CHECK:   store volatile <8 x i16> [[SHL24]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHL25:%.*]] = shl <4 x i32> [[TMP29]], [[TMP28]]
+// CHECK:   store volatile <4 x i32> [[SHL25]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHL26:%.*]] = shl <4 x i32> [[TMP31]], [[TMP30]]
+// CHECK:   store volatile <4 x i32> [[SHL26]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT27:%.*]] = insertelement <4 x i32> undef, i32 [[TMP32]], i32 0
+// CHECK:   [[SPLAT_SPLAT28:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT27]], <4 x i32> undef, <4 x i32> zeroinitializer
+// CHECK:   [[TMP33:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHL29:%.*]] = shl <4 x i32> [[TMP33]], [[SPLAT_SPLAT28]]
+// CHECK:   store volatile <4 x i32> [[SHL29]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHL30:%.*]] = shl <4 x i32> [[TMP34]], <i32 5, i32 5, i32 5, i32 5>
+// CHECK:   store volatile <4 x i32> [[SHL30]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHL31:%.*]] = shl <4 x i32> [[TMP36]], [[TMP35]]
+// CHECK:   store volatile <4 x i32> [[SHL31]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHL32:%.*]] = shl <4 x i32> [[TMP38]], [[TMP37]]
+// CHECK:   store volatile <4 x i32> [[SHL32]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT33:%.*]] = insertelement <4 x i32> undef, i32 [[TMP39]], i32 0
+// CHECK:   [[SPLAT_SPLAT34:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT33]], <4 x i32> undef, <4 x i32> zeroinitializer
+// CHECK:   [[TMP40:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHL35:%.*]] = shl <4 x i32> [[TMP40]], [[SPLAT_SPLAT34]]
+// CHECK:   store volatile <4 x i32> [[SHL35]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHL36:%.*]] = shl <4 x i32> [[TMP41]], <i32 5, i32 5, i32 5, i32 5>
+// CHECK:   store volatile <4 x i32> [[SHL36]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SHL37:%.*]] = shl <2 x i64> [[TMP43]], [[TMP42]]
+// CHECK:   store volatile <2 x i64> [[SHL37]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SHL38:%.*]] = shl <2 x i64> [[TMP45]], [[TMP44]]
+// CHECK:   store volatile <2 x i64> [[SHL38]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT39:%.*]] = insertelement <2 x i32> undef, i32 [[TMP46]], i32 0
+// CHECK:   [[SPLAT_SPLAT40:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT39]], <2 x i32> undef, <2 x i32> zeroinitializer
+// CHECK:   [[TMP47:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SH_PROM41:%.*]] = zext <2 x i32> [[SPLAT_SPLAT40]] to <2 x i64>
+// CHECK:   [[SHL42:%.*]] = shl <2 x i64> [[TMP47]], [[SH_PROM41]]
+// CHECK:   store volatile <2 x i64> [[SHL42]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SHL43:%.*]] = shl <2 x i64> [[TMP48]], <i64 5, i64 5>
+// CHECK:   store volatile <2 x i64> [[SHL43]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP50:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SHL44:%.*]] = shl <2 x i64> [[TMP50]], [[TMP49]]
+// CHECK:   store volatile <2 x i64> [[SHL44]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP51:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP52:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SHL45:%.*]] = shl <2 x i64> [[TMP52]], [[TMP51]]
+// CHECK:   store volatile <2 x i64> [[SHL45]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP53:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT46:%.*]] = insertelement <2 x i32> undef, i32 [[TMP53]], i32 0
+// CHECK:   [[SPLAT_SPLAT47:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT46]], <2 x i32> undef, <2 x i32> zeroinitializer
+// CHECK:   [[TMP54:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SH_PROM48:%.*]] = zext <2 x i32> [[SPLAT_SPLAT47]] to <2 x i64>
+// CHECK:   [[SHL49:%.*]] = shl <2 x i64> [[TMP54]], [[SH_PROM48]]
+// CHECK:   store volatile <2 x i64> [[SHL49]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP55:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SHL50:%.*]] = shl <2 x i64> [[TMP55]], <i64 5, i64 5>
+// CHECK:   store volatile <2 x i64> [[SHL50]], <2 x i64>* @ul, align 8
+// CHECK:   ret void
+void test_sl_assign(void) {
 
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   sc <<= sc2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   sc <<= uc2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <16 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <16 x i32> [[T2]], <16 x i32> undef, <16 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[CNT:%[^ ]+]] = trunc <16 x i32> [[T3]] to <16 x i8>
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   sc <<= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
   sc <<= 5;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   uc <<= sc2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   uc <<= uc2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <16 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <16 x i32> [[T2]], <16 x i32> undef, <16 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[CNT:%[^ ]+]] = trunc <16 x i32> [[T3]] to <16 x i8>
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], [[CNT]]
   uc <<= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = shl <16 x i8> [[VAL]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
   uc <<= 5;
 
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   ss <<= ss2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   ss <<= us2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <8 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <8 x i32> [[T2]], <8 x i32> undef, <8 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[CNT:%[^ ]+]] = trunc <8 x i32> [[T3]] to <8 x i16>
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   ss <<= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
   ss <<= 5;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   us <<= ss2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   us <<= us2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <8 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <8 x i32> [[T2]], <8 x i32> undef, <8 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[CNT:%[^ ]+]] = trunc <8 x i32> [[T3]] to <8 x i16>
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], [[CNT]]
   us <<= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = shl <8 x i16> [[VAL]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
   us <<= 5;
 
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   si <<= si2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   si <<= ui2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T3:%[^ ]+]] = insertelement <4 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[CNT:%[^ ]+]] = shufflevector <4 x i32> [[T3]], <4 x i32> undef, <4 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   si <<= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], <i32 5, i32 5, i32 5, i32 5>
   si <<= 5;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   ui <<= si2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   ui <<= ui2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T3:%[^ ]+]] = insertelement <4 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[CNT:%[^ ]+]] = shufflevector <4 x i32> [[T3]], <4 x i32> undef, <4 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], [[CNT]]
   ui <<= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = shl <4 x i32> [[VAL]], <i32 5, i32 5, i32 5, i32 5>
   ui <<= 5;
 
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   sl <<= sl2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   sl <<= ul2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <2 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <2 x i32> [[T2]], <2 x i32> undef, <2 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[CNT:%[^ ]+]] = zext <2 x i32> [[T3]] to <2 x i64>
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   sl <<= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], <i64 5, i64 5>
   sl <<= 5;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   ul <<= sl2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   ul <<= ul2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <2 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <2 x i32> [[T2]], <2 x i32> undef, <2 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[CNT:%[^ ]+]] = zext <2 x i32> [[T3]] to <2 x i64>
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], [[CNT]]
   ul <<= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = shl <2 x i64> [[VAL]], <i64 5, i64 5>
   ul <<= 5;
 }
 
-void test_sr (void)
-{
-// CHECK-LABEL: test_sr
+// CHECK-LABEL: define void @test_sr() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[SHR:%.*]] = ashr <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   store volatile <16 x i8> [[SHR]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[SHR1:%.*]] = ashr <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   store volatile <16 x i8> [[SHR1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT:%.*]] = insertelement <16 x i32> undef, i32 [[TMP5]], i32 0
+// CHECK:   [[SPLAT_SPLAT:%.*]] = shufflevector <16 x i32> [[SPLAT_SPLAT:%.*]]insert, <16 x i32> undef, <16 x i32> zeroinitializer
+// CHECK:   [[SH_PROM:%.*]] = trunc <16 x i32> [[SPLAT_SPLAT]] to <16 x i8>
+// CHECK:   [[SHR2:%.*]] = ashr <16 x i8> [[TMP4]], [[SH_PROM]]
+// CHECK:   store volatile <16 x i8> [[SHR2]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SHR3:%.*]] = ashr <16 x i8> [[TMP6]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+// CHECK:   store volatile <16 x i8> [[SHR3]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[SHR4:%.*]] = lshr <16 x i8> [[TMP7]], [[TMP8]]
+// CHECK:   store volatile <16 x i8> [[SHR4]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[SHR5:%.*]] = lshr <16 x i8> [[TMP9]], [[TMP10]]
+// CHECK:   store volatile <16 x i8> [[SHR5]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT6:%.*]] = insertelement <16 x i32> undef, i32 [[TMP12]], i32 0
+// CHECK:   [[SPLAT_SPLAT7:%.*]] = shufflevector <16 x i32> [[SPLAT_SPLATINSERT6]], <16 x i32> undef, <16 x i32> zeroinitializer
+// CHECK:   [[SH_PROM8:%.*]] = trunc <16 x i32> [[SPLAT_SPLAT7]] to <16 x i8>
+// CHECK:   [[SHR9:%.*]] = lshr <16 x i8> [[TMP11]], [[SH_PROM8]]
+// CHECK:   store volatile <16 x i8> [[SHR9]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SHR10:%.*]] = lshr <16 x i8> [[TMP13]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+// CHECK:   store volatile <16 x i8> [[SHR10]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[SHR11:%.*]] = ashr <8 x i16> [[TMP14]], [[TMP15]]
+// CHECK:   store volatile <8 x i16> [[SHR11]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[SHR12:%.*]] = ashr <8 x i16> [[TMP16]], [[TMP17]]
+// CHECK:   store volatile <8 x i16> [[SHR12]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT13:%.*]] = insertelement <8 x i32> undef, i32 [[TMP19]], i32 0
+// CHECK:   [[SPLAT_SPLAT14:%.*]] = shufflevector <8 x i32> [[SPLAT_SPLATINSERT13]], <8 x i32> undef, <8 x i32> zeroinitializer
+// CHECK:   [[SH_PROM15:%.*]] = trunc <8 x i32> [[SPLAT_SPLAT14]] to <8 x i16>
+// CHECK:   [[SHR16:%.*]] = ashr <8 x i16> [[TMP18]], [[SH_PROM15]]
+// CHECK:   store volatile <8 x i16> [[SHR16]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SHR17:%.*]] = ashr <8 x i16> [[TMP20]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+// CHECK:   store volatile <8 x i16> [[SHR17]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[SHR18:%.*]] = lshr <8 x i16> [[TMP21]], [[TMP22]]
+// CHECK:   store volatile <8 x i16> [[SHR18]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[SHR19:%.*]] = lshr <8 x i16> [[TMP23]], [[TMP24]]
+// CHECK:   store volatile <8 x i16> [[SHR19]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT20:%.*]] = insertelement <8 x i32> undef, i32 [[TMP26]], i32 0
+// CHECK:   [[SPLAT_SPLAT21:%.*]] = shufflevector <8 x i32> [[SPLAT_SPLATINSERT20]], <8 x i32> undef, <8 x i32> zeroinitializer
+// CHECK:   [[SH_PROM22:%.*]] = trunc <8 x i32> [[SPLAT_SPLAT21]] to <8 x i16>
+// CHECK:   [[SHR23:%.*]] = lshr <8 x i16> [[TMP25]], [[SH_PROM22]]
+// CHECK:   store volatile <8 x i16> [[SHR23]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SHR24:%.*]] = lshr <8 x i16> [[TMP27]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+// CHECK:   store volatile <8 x i16> [[SHR24]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[SHR25:%.*]] = ashr <4 x i32> [[TMP28]], [[TMP29]]
+// CHECK:   store volatile <4 x i32> [[SHR25]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[SHR26:%.*]] = ashr <4 x i32> [[TMP30]], [[TMP31]]
+// CHECK:   store volatile <4 x i32> [[SHR26]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT27:%.*]] = insertelement <4 x i32> undef, i32 [[TMP33]], i32 0
+// CHECK:   [[SPLAT_SPLAT28:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT27]], <4 x i32> undef, <4 x i32> zeroinitializer
+// CHECK:   [[SHR29:%.*]] = ashr <4 x i32> [[TMP32]], [[SPLAT_SPLAT28]]
+// CHECK:   store volatile <4 x i32> [[SHR29]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHR30:%.*]] = ashr <4 x i32> [[TMP34]], <i32 5, i32 5, i32 5, i32 5>
+// CHECK:   store volatile <4 x i32> [[SHR30]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[SHR31:%.*]] = lshr <4 x i32> [[TMP35]], [[TMP36]]
+// CHECK:   store volatile <4 x i32> [[SHR31]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[SHR32:%.*]] = lshr <4 x i32> [[TMP37]], [[TMP38]]
+// CHECK:   store volatile <4 x i32> [[SHR32]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP40:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT33:%.*]] = insertelement <4 x i32> undef, i32 [[TMP40]], i32 0
+// CHECK:   [[SPLAT_SPLAT34:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT33]], <4 x i32> undef, <4 x i32> zeroinitializer
+// CHECK:   [[SHR35:%.*]] = lshr <4 x i32> [[TMP39]], [[SPLAT_SPLAT34]]
+// CHECK:   store volatile <4 x i32> [[SHR35]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHR36:%.*]] = lshr <4 x i32> [[TMP41]], <i32 5, i32 5, i32 5, i32 5>
+// CHECK:   store volatile <4 x i32> [[SHR36]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[SHR37:%.*]] = ashr <2 x i64> [[TMP42]], [[TMP43]]
+// CHECK:   store volatile <2 x i64> [[SHR37]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[SHR38:%.*]] = ashr <2 x i64> [[TMP44]], [[TMP45]]
+// CHECK:   store volatile <2 x i64> [[SHR38]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP47:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT39:%.*]] = insertelement <2 x i32> undef, i32 [[TMP47]], i32 0
+// CHECK:   [[SPLAT_SPLAT40:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT39]], <2 x i32> undef, <2 x i32> zeroinitializer
+// CHECK:   [[SH_PROM41:%.*]] = zext <2 x i32> [[SPLAT_SPLAT40]] to <2 x i64>
+// CHECK:   [[SHR42:%.*]] = ashr <2 x i64> [[TMP46]], [[SH_PROM41]]
+// CHECK:   store volatile <2 x i64> [[SHR42]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SHR43:%.*]] = ashr <2 x i64> [[TMP48]], <i64 5, i64 5>
+// CHECK:   store volatile <2 x i64> [[SHR43]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP50:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[SHR44:%.*]] = lshr <2 x i64> [[TMP49]], [[TMP50]]
+// CHECK:   store volatile <2 x i64> [[SHR44]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP51:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP52:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[SHR45:%.*]] = lshr <2 x i64> [[TMP51]], [[TMP52]]
+// CHECK:   store volatile <2 x i64> [[SHR45]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP53:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP54:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT46:%.*]] = insertelement <2 x i32> undef, i32 [[TMP54]], i32 0
+// CHECK:   [[SPLAT_SPLAT47:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT46]], <2 x i32> undef, <2 x i32> zeroinitializer
+// CHECK:   [[SH_PROM48:%.*]] = zext <2 x i32> [[SPLAT_SPLAT47]] to <2 x i64>
+// CHECK:   [[SHR49:%.*]] = lshr <2 x i64> [[TMP53]], [[SH_PROM48]]
+// CHECK:   store volatile <2 x i64> [[SHR49]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP55:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SHR50:%.*]] = lshr <2 x i64> [[TMP55]], <i64 5, i64 5>
+// CHECK:   store volatile <2 x i64> [[SHR50]], <2 x i64>* @ul, align 8
+// CHECK:   ret void
+void test_sr(void) {
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = ashr <16 x i8> [[VAL]], [[CNT]]
   sc = sc >> sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = ashr <16 x i8> [[VAL]], [[CNT]]
   sc = sc >> uc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <16 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <16 x i32> [[T2]], <16 x i32> undef, <16 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = trunc <16 x i32> [[T3]] to <16 x i8>
-// CHECK: %{{.*}} = ashr <16 x i8> [[VAL]], [[CNT]]
   sc = sc >> cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = ashr <16 x i8> [[VAL]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
   sc = sc >> 5;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: %{{.*}} = lshr <16 x i8> [[VAL]], [[CNT]]
   uc = uc >> sc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: %{{.*}} = lshr <16 x i8> [[VAL]], [[CNT]]
   uc = uc >> uc2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <16 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <16 x i32> [[T2]], <16 x i32> undef, <16 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = trunc <16 x i32> [[T3]] to <16 x i8>
-// CHECK: %{{.*}} = lshr <16 x i8> [[VAL]], [[CNT]]
   uc = uc >> cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = lshr <16 x i8> [[VAL]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
   uc = uc >> 5;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = ashr <8 x i16> [[VAL]], [[CNT]]
   ss = ss >> ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = ashr <8 x i16> [[VAL]], [[CNT]]
   ss = ss >> us2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <8 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <8 x i32> [[T2]], <8 x i32> undef, <8 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = trunc <8 x i32> [[T3]] to <8 x i16>
-// CHECK: %{{.*}} = ashr <8 x i16> [[VAL]], [[CNT]]
   ss = ss >> cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = ashr <8 x i16> [[VAL]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
   ss = ss >> 5;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: %{{.*}} = lshr <8 x i16> [[VAL]], [[CNT]]
   us = us >> ss2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: %{{.*}} = lshr <8 x i16> [[VAL]], [[CNT]]
   us = us >> us2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <8 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <8 x i32> [[T2]], <8 x i32> undef, <8 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = trunc <8 x i32> [[T3]] to <8 x i16>
-// CHECK: %{{.*}} = lshr <8 x i16> [[VAL]], [[CNT]]
   us = us >> cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = lshr <8 x i16> [[VAL]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
   us = us >> 5;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = ashr <4 x i32> [[VAL]], [[CNT]]
   si = si >> si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = ashr <4 x i32> [[VAL]], [[CNT]]
   si = si >> ui2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T3:%[^ ]+]] = insertelement <4 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[CNT:%[^ ]+]] = shufflevector <4 x i32> [[T3]], <4 x i32> undef, <4 x i32> zeroinitializer
-// CHECK: %{{.*}} = ashr <4 x i32> [[VAL]], [[CNT]]
   si = si >> cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = ashr <4 x i32> [[VAL]], <i32 5, i32 5, i32 5, i32 5>
   si = si >> 5;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: %{{.*}} = lshr <4 x i32> [[VAL]], [[CNT]]
   ui = ui >> si2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: %{{.*}} = lshr <4 x i32> [[VAL]], [[CNT]]
   ui = ui >> ui2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T3:%[^ ]+]] = insertelement <4 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[CNT:%[^ ]+]] = shufflevector <4 x i32> [[T3]], <4 x i32> undef, <4 x i32> zeroinitializer
-// CHECK: %{{.*}} = lshr <4 x i32> [[VAL]], [[CNT]]
   ui = ui >> cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = lshr <4 x i32> [[VAL]], <i32 5, i32 5, i32 5, i32 5>
   ui = ui >> 5;
 
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = ashr <2 x i64> [[VAL]], [[CNT]]
   sl = sl >> sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = ashr <2 x i64> [[VAL]], [[CNT]]
   sl = sl >> ul2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <2 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <2 x i32> [[T2]], <2 x i32> undef, <2 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = zext <2 x i32> [[T3]] to <2 x i64>
-// CHECK: %{{.*}} = ashr <2 x i64> [[VAL]], [[CNT]]
   sl = sl >> cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = ashr <2 x i64> [[VAL]], <i64 5, i64 5>
   sl = sl >> 5;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: %{{.*}} = lshr <2 x i64> [[VAL]], [[CNT]]
   ul = ul >> sl2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: %{{.*}} = lshr <2 x i64> [[VAL]], [[CNT]]
   ul = ul >> ul2;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <2 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <2 x i32> [[T2]], <2 x i32> undef, <2 x i32> zeroinitializer
-// CHECK: [[CNT:%[^ ]+]] = zext <2 x i32> [[T3]] to <2 x i64>
-// CHECK: %{{.*}} = lshr <2 x i64> [[VAL]], [[CNT]]
   ul = ul >> cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = lshr <2 x i64> [[VAL]], <i64 5, i64 5>
   ul = ul >> 5;
 }
 
-void test_sr_assign (void)
-{
-// CHECK-LABEL: test_sr_assign
+// CHECK-LABEL: define void @test_sr_assign() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SHR:%.*]] = ashr <16 x i8> [[TMP1]], [[TMP0]]
+// CHECK:   store volatile <16 x i8> [[SHR]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SHR1:%.*]] = ashr <16 x i8> [[TMP3]], [[TMP2]]
+// CHECK:   store volatile <16 x i8> [[SHR1]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT:%.*]] = insertelement <16 x i32> undef, i32 [[TMP4]], i32 0
+// CHECK:   [[SPLAT_SPLAT:%.*]] = shufflevector <16 x i32> [[SPLAT_SPLAT:%.*]]insert, <16 x i32> undef, <16 x i32> zeroinitializer
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SH_PROM:%.*]] = trunc <16 x i32> [[SPLAT_SPLAT]] to <16 x i8>
+// CHECK:   [[SHR2:%.*]] = ashr <16 x i8> [[TMP5]], [[SH_PROM]]
+// CHECK:   store volatile <16 x i8> [[SHR2]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[SHR3:%.*]] = ashr <16 x i8> [[TMP6]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+// CHECK:   store volatile <16 x i8> [[SHR3]], <16 x i8>* @sc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SHR4:%.*]] = lshr <16 x i8> [[TMP8]], [[TMP7]]
+// CHECK:   store volatile <16 x i8> [[SHR4]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SHR5:%.*]] = lshr <16 x i8> [[TMP10]], [[TMP9]]
+// CHECK:   store volatile <16 x i8> [[SHR5]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT6:%.*]] = insertelement <16 x i32> undef, i32 [[TMP11]], i32 0
+// CHECK:   [[SPLAT_SPLAT7:%.*]] = shufflevector <16 x i32> [[SPLAT_SPLATINSERT6]], <16 x i32> undef, <16 x i32> zeroinitializer
+// CHECK:   [[TMP12:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SH_PROM8:%.*]] = trunc <16 x i32> [[SPLAT_SPLAT7]] to <16 x i8>
+// CHECK:   [[SHR9:%.*]] = lshr <16 x i8> [[TMP12]], [[SH_PROM8]]
+// CHECK:   store volatile <16 x i8> [[SHR9]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[SHR10:%.*]] = lshr <16 x i8> [[TMP13]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
+// CHECK:   store volatile <16 x i8> [[SHR10]], <16 x i8>* @uc, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SHR11:%.*]] = ashr <8 x i16> [[TMP15]], [[TMP14]]
+// CHECK:   store volatile <8 x i16> [[SHR11]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SHR12:%.*]] = ashr <8 x i16> [[TMP17]], [[TMP16]]
+// CHECK:   store volatile <8 x i16> [[SHR12]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT13:%.*]] = insertelement <8 x i32> undef, i32 [[TMP18]], i32 0
+// CHECK:   [[SPLAT_SPLAT14:%.*]] = shufflevector <8 x i32> [[SPLAT_SPLATINSERT13]], <8 x i32> undef, <8 x i32> zeroinitializer
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SH_PROM15:%.*]] = trunc <8 x i32> [[SPLAT_SPLAT14]] to <8 x i16>
+// CHECK:   [[SHR16:%.*]] = ashr <8 x i16> [[TMP19]], [[SH_PROM15]]
+// CHECK:   store volatile <8 x i16> [[SHR16]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[SHR17:%.*]] = ashr <8 x i16> [[TMP20]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+// CHECK:   store volatile <8 x i16> [[SHR17]], <8 x i16>* @ss, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SHR18:%.*]] = lshr <8 x i16> [[TMP22]], [[TMP21]]
+// CHECK:   store volatile <8 x i16> [[SHR18]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SHR19:%.*]] = lshr <8 x i16> [[TMP24]], [[TMP23]]
+// CHECK:   store volatile <8 x i16> [[SHR19]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT20:%.*]] = insertelement <8 x i32> undef, i32 [[TMP25]], i32 0
+// CHECK:   [[SPLAT_SPLAT21:%.*]] = shufflevector <8 x i32> [[SPLAT_SPLATINSERT20]], <8 x i32> undef, <8 x i32> zeroinitializer
+// CHECK:   [[TMP26:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SH_PROM22:%.*]] = trunc <8 x i32> [[SPLAT_SPLAT21]] to <8 x i16>
+// CHECK:   [[SHR23:%.*]] = lshr <8 x i16> [[TMP26]], [[SH_PROM22]]
+// CHECK:   store volatile <8 x i16> [[SHR23]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[SHR24:%.*]] = lshr <8 x i16> [[TMP27]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+// CHECK:   store volatile <8 x i16> [[SHR24]], <8 x i16>* @us, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHR25:%.*]] = ashr <4 x i32> [[TMP29]], [[TMP28]]
+// CHECK:   store volatile <4 x i32> [[SHR25]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHR26:%.*]] = ashr <4 x i32> [[TMP31]], [[TMP30]]
+// CHECK:   store volatile <4 x i32> [[SHR26]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT27:%.*]] = insertelement <4 x i32> undef, i32 [[TMP32]], i32 0
+// CHECK:   [[SPLAT_SPLAT28:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT27]], <4 x i32> undef, <4 x i32> zeroinitializer
+// CHECK:   [[TMP33:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHR29:%.*]] = ashr <4 x i32> [[TMP33]], [[SPLAT_SPLAT28]]
+// CHECK:   store volatile <4 x i32> [[SHR29]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[SHR30:%.*]] = ashr <4 x i32> [[TMP34]], <i32 5, i32 5, i32 5, i32 5>
+// CHECK:   store volatile <4 x i32> [[SHR30]], <4 x i32>* @si, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHR31:%.*]] = lshr <4 x i32> [[TMP36]], [[TMP35]]
+// CHECK:   store volatile <4 x i32> [[SHR31]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHR32:%.*]] = lshr <4 x i32> [[TMP38]], [[TMP37]]
+// CHECK:   store volatile <4 x i32> [[SHR32]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT33:%.*]] = insertelement <4 x i32> undef, i32 [[TMP39]], i32 0
+// CHECK:   [[SPLAT_SPLAT34:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT33]], <4 x i32> undef, <4 x i32> zeroinitializer
+// CHECK:   [[TMP40:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHR35:%.*]] = lshr <4 x i32> [[TMP40]], [[SPLAT_SPLAT34]]
+// CHECK:   store volatile <4 x i32> [[SHR35]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[SHR36:%.*]] = lshr <4 x i32> [[TMP41]], <i32 5, i32 5, i32 5, i32 5>
+// CHECK:   store volatile <4 x i32> [[SHR36]], <4 x i32>* @ui, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SHR37:%.*]] = ashr <2 x i64> [[TMP43]], [[TMP42]]
+// CHECK:   store volatile <2 x i64> [[SHR37]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SHR38:%.*]] = ashr <2 x i64> [[TMP45]], [[TMP44]]
+// CHECK:   store volatile <2 x i64> [[SHR38]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT39:%.*]] = insertelement <2 x i32> undef, i32 [[TMP46]], i32 0
+// CHECK:   [[SPLAT_SPLAT40:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT39]], <2 x i32> undef, <2 x i32> zeroinitializer
+// CHECK:   [[TMP47:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SH_PROM41:%.*]] = zext <2 x i32> [[SPLAT_SPLAT40]] to <2 x i64>
+// CHECK:   [[SHR42:%.*]] = ashr <2 x i64> [[TMP47]], [[SH_PROM41]]
+// CHECK:   store volatile <2 x i64> [[SHR42]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[SHR43:%.*]] = ashr <2 x i64> [[TMP48]], <i64 5, i64 5>
+// CHECK:   store volatile <2 x i64> [[SHR43]], <2 x i64>* @sl, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[TMP50:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SHR44:%.*]] = lshr <2 x i64> [[TMP50]], [[TMP49]]
+// CHECK:   store volatile <2 x i64> [[SHR44]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP51:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[TMP52:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SHR45:%.*]] = lshr <2 x i64> [[TMP52]], [[TMP51]]
+// CHECK:   store volatile <2 x i64> [[SHR45]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP53:%.*]] = load volatile i32, i32* @cnt, align 4
+// CHECK:   [[SPLAT_SPLATINSERT46:%.*]] = insertelement <2 x i32> undef, i32 [[TMP53]], i32 0
+// CHECK:   [[SPLAT_SPLAT47:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT46]], <2 x i32> undef, <2 x i32> zeroinitializer
+// CHECK:   [[TMP54:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SH_PROM48:%.*]] = zext <2 x i32> [[SPLAT_SPLAT47]] to <2 x i64>
+// CHECK:   [[SHR49:%.*]] = lshr <2 x i64> [[TMP54]], [[SH_PROM48]]
+// CHECK:   store volatile <2 x i64> [[SHR49]], <2 x i64>* @ul, align 8
+// CHECK:   [[TMP55:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[SHR50:%.*]] = lshr <2 x i64> [[TMP55]], <i64 5, i64 5>
+// CHECK:   store volatile <2 x i64> [[SHR50]], <2 x i64>* @ul, align 8
+// CHECK:   ret void
+void test_sr_assign(void) {
 
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = ashr <16 x i8> [[VAL]], [[CNT]]
   sc >>= sc2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = ashr <16 x i8> [[VAL]], [[CNT]]
   sc >>= uc2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <16 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <16 x i32> [[T2]], <16 x i32> undef, <16 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[CNT:%[^ ]+]] = trunc <16 x i32> [[T3]] to <16 x i8>
-// CHECK: %{{.*}} = ashr <16 x i8> [[VAL]], [[CNT]]
   sc >>= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: %{{.*}} = ashr <16 x i8> [[VAL]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
   sc >>= 5;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = lshr <16 x i8> [[VAL]], [[CNT]]
   uc >>= sc2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = lshr <16 x i8> [[VAL]], [[CNT]]
   uc >>= uc2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <16 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <16 x i32> [[T2]], <16 x i32> undef, <16 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[CNT:%[^ ]+]] = trunc <16 x i32> [[T3]] to <16 x i8>
-// CHECK: %{{.*}} = lshr <16 x i8> [[VAL]], [[CNT]]
   uc >>= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: %{{.*}} = lshr <16 x i8> [[VAL]], <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
   uc >>= 5;
 
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = ashr <8 x i16> [[VAL]], [[CNT]]
   ss >>= ss2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = ashr <8 x i16> [[VAL]], [[CNT]]
   ss >>= us2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <8 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <8 x i32> [[T2]], <8 x i32> undef, <8 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[CNT:%[^ ]+]] = trunc <8 x i32> [[T3]] to <8 x i16>
-// CHECK: %{{.*}} = ashr <8 x i16> [[VAL]], [[CNT]]
   ss >>= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: %{{.*}} = ashr <8 x i16> [[VAL]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
   ss >>= 5;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = lshr <8 x i16> [[VAL]], [[CNT]]
   us >>= ss2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = lshr <8 x i16> [[VAL]], [[CNT]]
   us >>= us2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <8 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <8 x i32> [[T2]], <8 x i32> undef, <8 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[CNT:%[^ ]+]] = trunc <8 x i32> [[T3]] to <8 x i16>
-// CHECK: %{{.*}} = lshr <8 x i16> [[VAL]], [[CNT]]
   us >>= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: %{{.*}} = lshr <8 x i16> [[VAL]], <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
   us >>= 5;
 
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = ashr <4 x i32> [[VAL]], [[CNT]]
   si >>= si2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = ashr <4 x i32> [[VAL]], [[CNT]]
   si >>= ui2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T3:%[^ ]+]] = insertelement <4 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[CNT:%[^ ]+]] = shufflevector <4 x i32> [[T3]], <4 x i32> undef, <4 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = ashr <4 x i32> [[VAL]], [[CNT]]
   si >>= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: %{{.*}} = ashr <4 x i32> [[VAL]], <i32 5, i32 5, i32 5, i32 5>
   si >>= 5;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = lshr <4 x i32> [[VAL]], [[CNT]]
   ui >>= si2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = lshr <4 x i32> [[VAL]], [[CNT]]
   ui >>= ui2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T3:%[^ ]+]] = insertelement <4 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[CNT:%[^ ]+]] = shufflevector <4 x i32> [[T3]], <4 x i32> undef, <4 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = lshr <4 x i32> [[VAL]], [[CNT]]
   ui >>= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: %{{.*}} = lshr <4 x i32> [[VAL]], <i32 5, i32 5, i32 5, i32 5>
   ui >>= 5;
 
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = ashr <2 x i64> [[VAL]], [[CNT]]
   sl >>= sl2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = ashr <2 x i64> [[VAL]], [[CNT]]
   sl >>= ul2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <2 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <2 x i32> [[T2]], <2 x i32> undef, <2 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[CNT:%[^ ]+]] = zext <2 x i32> [[T3]] to <2 x i64>
-// CHECK: %{{.*}} = ashr <2 x i64> [[VAL]], [[CNT]]
   sl >>= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: %{{.*}} = ashr <2 x i64> [[VAL]], <i64 5, i64 5>
   sl >>= 5;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = lshr <2 x i64> [[VAL]], [[CNT]]
   ul >>= sl2;
-// CHECK: [[CNT:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = lshr <2 x i64> [[VAL]], [[CNT]]
   ul >>= ul2;
-// CHECK: [[T1:%[^ ]+]] = load volatile i32, i32* @cnt
-// CHECK: [[T2:%[^ ]+]] = insertelement <2 x i32> undef, i32 [[T1]], i32 0
-// CHECK: [[T3:%[^ ]+]] = shufflevector <2 x i32> [[T2]], <2 x i32> undef, <2 x i32> zeroinitializer
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[CNT:%[^ ]+]] = zext <2 x i32> [[T3]] to <2 x i64>
-// CHECK: %{{.*}} = lshr <2 x i64> [[VAL]], [[CNT]]
   ul >>= cnt;
-// CHECK: [[VAL:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: %{{.*}} = lshr <2 x i64> [[VAL]], <i64 5, i64 5>
   ul >>= 5;
 }
 
 
-void test_cmpeq (void)
-{
-// CHECK-LABEL: test_cmpeq
+// CHECK-LABEL: define void @test_cmpeq() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[CMP:%.*]] = icmp eq <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   [[SEXT:%.*]] = sext <16 x i1> [[CMP]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP1:%.*]] = icmp eq <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   [[SEXT2:%.*]] = sext <16 x i1> [[CMP1]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT2]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[CMP3:%.*]] = icmp eq <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   [[SEXT4:%.*]] = sext <16 x i1> [[CMP3]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT4]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[CMP5:%.*]] = icmp eq <16 x i8> [[TMP6]], [[TMP7]]
+// CHECK:   [[SEXT6:%.*]] = sext <16 x i1> [[CMP5]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT6]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP7:%.*]] = icmp eq <16 x i8> [[TMP8]], [[TMP9]]
+// CHECK:   [[SEXT8:%.*]] = sext <16 x i1> [[CMP7]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT8]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[CMP9:%.*]] = icmp eq <16 x i8> [[TMP10]], [[TMP11]]
+// CHECK:   [[SEXT10:%.*]] = sext <16 x i1> [[CMP9]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT10]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP11:%.*]] = icmp eq <16 x i8> [[TMP12]], [[TMP13]]
+// CHECK:   [[SEXT12:%.*]] = sext <16 x i1> [[CMP11]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT12]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[CMP13:%.*]] = icmp eq <8 x i16> [[TMP14]], [[TMP15]]
+// CHECK:   [[SEXT14:%.*]] = sext <8 x i1> [[CMP13]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT14]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP15:%.*]] = icmp eq <8 x i16> [[TMP16]], [[TMP17]]
+// CHECK:   [[SEXT16:%.*]] = sext <8 x i1> [[CMP15]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT16]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[CMP17:%.*]] = icmp eq <8 x i16> [[TMP18]], [[TMP19]]
+// CHECK:   [[SEXT18:%.*]] = sext <8 x i1> [[CMP17]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT18]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[CMP19:%.*]] = icmp eq <8 x i16> [[TMP20]], [[TMP21]]
+// CHECK:   [[SEXT20:%.*]] = sext <8 x i1> [[CMP19]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT20]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP21:%.*]] = icmp eq <8 x i16> [[TMP22]], [[TMP23]]
+// CHECK:   [[SEXT22:%.*]] = sext <8 x i1> [[CMP21]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT22]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[CMP23:%.*]] = icmp eq <8 x i16> [[TMP24]], [[TMP25]]
+// CHECK:   [[SEXT24:%.*]] = sext <8 x i1> [[CMP23]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT24]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP25:%.*]] = icmp eq <8 x i16> [[TMP26]], [[TMP27]]
+// CHECK:   [[SEXT26:%.*]] = sext <8 x i1> [[CMP25]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT26]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[CMP27:%.*]] = icmp eq <4 x i32> [[TMP28]], [[TMP29]]
+// CHECK:   [[SEXT28:%.*]] = sext <4 x i1> [[CMP27]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT28]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP29:%.*]] = icmp eq <4 x i32> [[TMP30]], [[TMP31]]
+// CHECK:   [[SEXT30:%.*]] = sext <4 x i1> [[CMP29]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT30]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[CMP31:%.*]] = icmp eq <4 x i32> [[TMP32]], [[TMP33]]
+// CHECK:   [[SEXT32:%.*]] = sext <4 x i1> [[CMP31]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT32]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[CMP33:%.*]] = icmp eq <4 x i32> [[TMP34]], [[TMP35]]
+// CHECK:   [[SEXT34:%.*]] = sext <4 x i1> [[CMP33]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT34]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP35:%.*]] = icmp eq <4 x i32> [[TMP36]], [[TMP37]]
+// CHECK:   [[SEXT36:%.*]] = sext <4 x i1> [[CMP35]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT36]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[CMP37:%.*]] = icmp eq <4 x i32> [[TMP38]], [[TMP39]]
+// CHECK:   [[SEXT38:%.*]] = sext <4 x i1> [[CMP37]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT38]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP40:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP39:%.*]] = icmp eq <4 x i32> [[TMP40]], [[TMP41]]
+// CHECK:   [[SEXT40:%.*]] = sext <4 x i1> [[CMP39]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT40]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[CMP41:%.*]] = icmp eq <2 x i64> [[TMP42]], [[TMP43]]
+// CHECK:   [[SEXT42:%.*]] = sext <2 x i1> [[CMP41]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT42]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP43:%.*]] = icmp eq <2 x i64> [[TMP44]], [[TMP45]]
+// CHECK:   [[SEXT44:%.*]] = sext <2 x i1> [[CMP43]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT44]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP47:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[CMP45:%.*]] = icmp eq <2 x i64> [[TMP46]], [[TMP47]]
+// CHECK:   [[SEXT46:%.*]] = sext <2 x i1> [[CMP45]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT46]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[CMP47:%.*]] = icmp eq <2 x i64> [[TMP48]], [[TMP49]]
+// CHECK:   [[SEXT48:%.*]] = sext <2 x i1> [[CMP47]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT48]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP50:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP51:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP49:%.*]] = icmp eq <2 x i64> [[TMP50]], [[TMP51]]
+// CHECK:   [[SEXT50:%.*]] = sext <2 x i1> [[CMP49]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT50]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP52:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP53:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[CMP51:%.*]] = icmp eq <2 x i64> [[TMP52]], [[TMP53]]
+// CHECK:   [[SEXT52:%.*]] = sext <2 x i1> [[CMP51]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT52]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP54:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP55:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP53:%.*]] = icmp eq <2 x i64> [[TMP54]], [[TMP55]]
+// CHECK:   [[SEXT54:%.*]] = sext <2 x i1> [[CMP53]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT54]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP56:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP57:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[CMP55:%.*]] = fcmp oeq <2 x double> [[TMP56]], [[TMP57]]
+// CHECK:   [[SEXT56:%.*]] = sext <2 x i1> [[CMP55]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT56]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_cmpeq(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = sc == sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = sc == bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc == sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = uc == uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = uc == bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc == uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc == bc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = ss == ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = ss == bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs == ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = us == us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = us == bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs == us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs == bs2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = si == si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = si == bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi == si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = ui == ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = ui == bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi == ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi == bi2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = sl == sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = sl == bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl == sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = ul == ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = ul == bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl == ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp eq <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl == bl2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[CMP:%[^ ]+]] = fcmp oeq <2 x double> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = fd == fd2;
 }
 
-void test_cmpne (void)
-{
-// CHECK-LABEL: test_cmpne
+// CHECK-LABEL: define void @test_cmpne() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[CMP:%.*]] = icmp ne <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   [[SEXT:%.*]] = sext <16 x i1> [[CMP]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP1:%.*]] = icmp ne <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   [[SEXT2:%.*]] = sext <16 x i1> [[CMP1]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT2]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[CMP3:%.*]] = icmp ne <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   [[SEXT4:%.*]] = sext <16 x i1> [[CMP3]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT4]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[CMP5:%.*]] = icmp ne <16 x i8> [[TMP6]], [[TMP7]]
+// CHECK:   [[SEXT6:%.*]] = sext <16 x i1> [[CMP5]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT6]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP7:%.*]] = icmp ne <16 x i8> [[TMP8]], [[TMP9]]
+// CHECK:   [[SEXT8:%.*]] = sext <16 x i1> [[CMP7]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT8]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[CMP9:%.*]] = icmp ne <16 x i8> [[TMP10]], [[TMP11]]
+// CHECK:   [[SEXT10:%.*]] = sext <16 x i1> [[CMP9]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT10]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP11:%.*]] = icmp ne <16 x i8> [[TMP12]], [[TMP13]]
+// CHECK:   [[SEXT12:%.*]] = sext <16 x i1> [[CMP11]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT12]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[CMP13:%.*]] = icmp ne <8 x i16> [[TMP14]], [[TMP15]]
+// CHECK:   [[SEXT14:%.*]] = sext <8 x i1> [[CMP13]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT14]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP15:%.*]] = icmp ne <8 x i16> [[TMP16]], [[TMP17]]
+// CHECK:   [[SEXT16:%.*]] = sext <8 x i1> [[CMP15]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT16]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[CMP17:%.*]] = icmp ne <8 x i16> [[TMP18]], [[TMP19]]
+// CHECK:   [[SEXT18:%.*]] = sext <8 x i1> [[CMP17]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT18]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[CMP19:%.*]] = icmp ne <8 x i16> [[TMP20]], [[TMP21]]
+// CHECK:   [[SEXT20:%.*]] = sext <8 x i1> [[CMP19]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT20]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP21:%.*]] = icmp ne <8 x i16> [[TMP22]], [[TMP23]]
+// CHECK:   [[SEXT22:%.*]] = sext <8 x i1> [[CMP21]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT22]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[CMP23:%.*]] = icmp ne <8 x i16> [[TMP24]], [[TMP25]]
+// CHECK:   [[SEXT24:%.*]] = sext <8 x i1> [[CMP23]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT24]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP26:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP27:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP25:%.*]] = icmp ne <8 x i16> [[TMP26]], [[TMP27]]
+// CHECK:   [[SEXT26:%.*]] = sext <8 x i1> [[CMP25]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT26]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP28:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP29:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[CMP27:%.*]] = icmp ne <4 x i32> [[TMP28]], [[TMP29]]
+// CHECK:   [[SEXT28:%.*]] = sext <4 x i1> [[CMP27]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT28]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP30:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP31:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP29:%.*]] = icmp ne <4 x i32> [[TMP30]], [[TMP31]]
+// CHECK:   [[SEXT30:%.*]] = sext <4 x i1> [[CMP29]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT30]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP32:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP33:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[CMP31:%.*]] = icmp ne <4 x i32> [[TMP32]], [[TMP33]]
+// CHECK:   [[SEXT32:%.*]] = sext <4 x i1> [[CMP31]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT32]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP34:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP35:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[CMP33:%.*]] = icmp ne <4 x i32> [[TMP34]], [[TMP35]]
+// CHECK:   [[SEXT34:%.*]] = sext <4 x i1> [[CMP33]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT34]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP36:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP37:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP35:%.*]] = icmp ne <4 x i32> [[TMP36]], [[TMP37]]
+// CHECK:   [[SEXT36:%.*]] = sext <4 x i1> [[CMP35]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT36]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP38:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP39:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[CMP37:%.*]] = icmp ne <4 x i32> [[TMP38]], [[TMP39]]
+// CHECK:   [[SEXT38:%.*]] = sext <4 x i1> [[CMP37]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT38]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP40:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP41:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP39:%.*]] = icmp ne <4 x i32> [[TMP40]], [[TMP41]]
+// CHECK:   [[SEXT40:%.*]] = sext <4 x i1> [[CMP39]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT40]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP42:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP43:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[CMP41:%.*]] = icmp ne <2 x i64> [[TMP42]], [[TMP43]]
+// CHECK:   [[SEXT42:%.*]] = sext <2 x i1> [[CMP41]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT42]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP44:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP45:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP43:%.*]] = icmp ne <2 x i64> [[TMP44]], [[TMP45]]
+// CHECK:   [[SEXT44:%.*]] = sext <2 x i1> [[CMP43]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT44]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP46:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP47:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[CMP45:%.*]] = icmp ne <2 x i64> [[TMP46]], [[TMP47]]
+// CHECK:   [[SEXT46:%.*]] = sext <2 x i1> [[CMP45]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT46]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP48:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP49:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[CMP47:%.*]] = icmp ne <2 x i64> [[TMP48]], [[TMP49]]
+// CHECK:   [[SEXT48:%.*]] = sext <2 x i1> [[CMP47]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT48]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP50:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP51:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP49:%.*]] = icmp ne <2 x i64> [[TMP50]], [[TMP51]]
+// CHECK:   [[SEXT50:%.*]] = sext <2 x i1> [[CMP49]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT50]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP52:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP53:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[CMP51:%.*]] = icmp ne <2 x i64> [[TMP52]], [[TMP53]]
+// CHECK:   [[SEXT52:%.*]] = sext <2 x i1> [[CMP51]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT52]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP54:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP55:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP53:%.*]] = icmp ne <2 x i64> [[TMP54]], [[TMP55]]
+// CHECK:   [[SEXT54:%.*]] = sext <2 x i1> [[CMP53]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT54]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP56:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP57:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[CMP55:%.*]] = fcmp une <2 x double> [[TMP56]], [[TMP57]]
+// CHECK:   [[SEXT56:%.*]] = sext <2 x i1> [[CMP55]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT56]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_cmpne(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = sc != sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = sc != bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc != sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = uc != uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = uc != bc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc != uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc != bc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = ss != ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = ss != bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs != ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = us != us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = us != bs2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs != us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs != bs2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = si != si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = si != bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi != si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = ui != ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = ui != bi2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi != ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi != bi2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = sl != sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = sl != bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl != sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = ul != ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = ul != bl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl != ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp ne <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl != bl2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[CMP:%[^ ]+]] = fcmp une <2 x double> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = fd != fd2;
 }
 
-void test_cmpge (void)
-{
-// CHECK-LABEL: test_cmpge
+// CHECK-LABEL: define void @test_cmpge() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[CMP:%.*]] = icmp sge <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   [[SEXT:%.*]] = sext <16 x i1> [[CMP]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[CMP1:%.*]] = icmp uge <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   [[SEXT2:%.*]] = sext <16 x i1> [[CMP1]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT2]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP3:%.*]] = icmp uge <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   [[SEXT4:%.*]] = sext <16 x i1> [[CMP3]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT4]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[CMP5:%.*]] = icmp sge <8 x i16> [[TMP6]], [[TMP7]]
+// CHECK:   [[SEXT6:%.*]] = sext <8 x i1> [[CMP5]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT6]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[CMP7:%.*]] = icmp uge <8 x i16> [[TMP8]], [[TMP9]]
+// CHECK:   [[SEXT8:%.*]] = sext <8 x i1> [[CMP7]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT8]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP9:%.*]] = icmp uge <8 x i16> [[TMP10]], [[TMP11]]
+// CHECK:   [[SEXT10:%.*]] = sext <8 x i1> [[CMP9]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT10]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[CMP11:%.*]] = icmp sge <4 x i32> [[TMP12]], [[TMP13]]
+// CHECK:   [[SEXT12:%.*]] = sext <4 x i1> [[CMP11]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT12]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[CMP13:%.*]] = icmp uge <4 x i32> [[TMP14]], [[TMP15]]
+// CHECK:   [[SEXT14:%.*]] = sext <4 x i1> [[CMP13]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT14]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP15:%.*]] = icmp uge <4 x i32> [[TMP16]], [[TMP17]]
+// CHECK:   [[SEXT16:%.*]] = sext <4 x i1> [[CMP15]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT16]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[CMP17:%.*]] = icmp sge <2 x i64> [[TMP18]], [[TMP19]]
+// CHECK:   [[SEXT18:%.*]] = sext <2 x i1> [[CMP17]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT18]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[CMP19:%.*]] = icmp uge <2 x i64> [[TMP20]], [[TMP21]]
+// CHECK:   [[SEXT20:%.*]] = sext <2 x i1> [[CMP19]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT20]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP21:%.*]] = icmp uge <2 x i64> [[TMP22]], [[TMP23]]
+// CHECK:   [[SEXT22:%.*]] = sext <2 x i1> [[CMP21]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT22]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[CMP23:%.*]] = fcmp oge <2 x double> [[TMP24]], [[TMP25]]
+// CHECK:   [[SEXT24:%.*]] = sext <2 x i1> [[CMP23]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT24]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_cmpge(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[CMP:%[^ ]+]] = icmp sge <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = sc >= sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[CMP:%[^ ]+]] = icmp uge <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = uc >= uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp uge <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc >= bc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[CMP:%[^ ]+]] = icmp sge <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = ss >= ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[CMP:%[^ ]+]] = icmp uge <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = us >= us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp uge <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs >= bs2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[CMP:%[^ ]+]] = icmp sge <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = si >= si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[CMP:%[^ ]+]] = icmp uge <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = ui >= ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp uge <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi >= bi2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[CMP:%[^ ]+]] = icmp sge <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = sl >= sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[CMP:%[^ ]+]] = icmp uge <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = ul >= ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp uge <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl >= bl2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[CMP:%[^ ]+]] = fcmp oge <2 x double> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = fd >= fd2;
 }
 
-void test_cmpgt (void)
-{
-// CHECK-LABEL: test_cmpgt
+// CHECK-LABEL: define void @test_cmpgt() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[CMP:%.*]] = icmp sgt <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   [[SEXT:%.*]] = sext <16 x i1> [[CMP]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[CMP1:%.*]] = icmp ugt <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   [[SEXT2:%.*]] = sext <16 x i1> [[CMP1]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT2]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP3:%.*]] = icmp ugt <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   [[SEXT4:%.*]] = sext <16 x i1> [[CMP3]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT4]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[CMP5:%.*]] = icmp sgt <8 x i16> [[TMP6]], [[TMP7]]
+// CHECK:   [[SEXT6:%.*]] = sext <8 x i1> [[CMP5]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT6]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[CMP7:%.*]] = icmp ugt <8 x i16> [[TMP8]], [[TMP9]]
+// CHECK:   [[SEXT8:%.*]] = sext <8 x i1> [[CMP7]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT8]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP9:%.*]] = icmp ugt <8 x i16> [[TMP10]], [[TMP11]]
+// CHECK:   [[SEXT10:%.*]] = sext <8 x i1> [[CMP9]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT10]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[CMP11:%.*]] = icmp sgt <4 x i32> [[TMP12]], [[TMP13]]
+// CHECK:   [[SEXT12:%.*]] = sext <4 x i1> [[CMP11]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT12]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[CMP13:%.*]] = icmp ugt <4 x i32> [[TMP14]], [[TMP15]]
+// CHECK:   [[SEXT14:%.*]] = sext <4 x i1> [[CMP13]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT14]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP15:%.*]] = icmp ugt <4 x i32> [[TMP16]], [[TMP17]]
+// CHECK:   [[SEXT16:%.*]] = sext <4 x i1> [[CMP15]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT16]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[CMP17:%.*]] = icmp sgt <2 x i64> [[TMP18]], [[TMP19]]
+// CHECK:   [[SEXT18:%.*]] = sext <2 x i1> [[CMP17]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT18]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[CMP19:%.*]] = icmp ugt <2 x i64> [[TMP20]], [[TMP21]]
+// CHECK:   [[SEXT20:%.*]] = sext <2 x i1> [[CMP19]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT20]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP21:%.*]] = icmp ugt <2 x i64> [[TMP22]], [[TMP23]]
+// CHECK:   [[SEXT22:%.*]] = sext <2 x i1> [[CMP21]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT22]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[CMP23:%.*]] = fcmp ogt <2 x double> [[TMP24]], [[TMP25]]
+// CHECK:   [[SEXT24:%.*]] = sext <2 x i1> [[CMP23]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT24]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_cmpgt(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[CMP:%[^ ]+]] = icmp sgt <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = sc > sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ugt <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = uc > uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ugt <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc > bc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[CMP:%[^ ]+]] = icmp sgt <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = ss > ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[CMP:%[^ ]+]] = icmp ugt <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = us > us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp ugt <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs > bs2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[CMP:%[^ ]+]] = icmp sgt <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = si > si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[CMP:%[^ ]+]] = icmp ugt <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = ui > ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp ugt <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi > bi2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[CMP:%[^ ]+]] = icmp sgt <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = sl > sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[CMP:%[^ ]+]] = icmp ugt <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = ul > ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp ugt <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl > bl2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[CMP:%[^ ]+]] = fcmp ogt <2 x double> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = fd > fd2;
 }
 
-void test_cmple (void)
-{
-// CHECK-LABEL: test_cmple
+// CHECK-LABEL: define void @test_cmple() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[CMP:%.*]] = icmp sle <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   [[SEXT:%.*]] = sext <16 x i1> [[CMP]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[CMP1:%.*]] = icmp ule <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   [[SEXT2:%.*]] = sext <16 x i1> [[CMP1]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT2]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP3:%.*]] = icmp ule <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   [[SEXT4:%.*]] = sext <16 x i1> [[CMP3]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT4]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[CMP5:%.*]] = icmp sle <8 x i16> [[TMP6]], [[TMP7]]
+// CHECK:   [[SEXT6:%.*]] = sext <8 x i1> [[CMP5]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT6]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[CMP7:%.*]] = icmp ule <8 x i16> [[TMP8]], [[TMP9]]
+// CHECK:   [[SEXT8:%.*]] = sext <8 x i1> [[CMP7]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT8]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP9:%.*]] = icmp ule <8 x i16> [[TMP10]], [[TMP11]]
+// CHECK:   [[SEXT10:%.*]] = sext <8 x i1> [[CMP9]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT10]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[CMP11:%.*]] = icmp sle <4 x i32> [[TMP12]], [[TMP13]]
+// CHECK:   [[SEXT12:%.*]] = sext <4 x i1> [[CMP11]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT12]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[CMP13:%.*]] = icmp ule <4 x i32> [[TMP14]], [[TMP15]]
+// CHECK:   [[SEXT14:%.*]] = sext <4 x i1> [[CMP13]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT14]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP15:%.*]] = icmp ule <4 x i32> [[TMP16]], [[TMP17]]
+// CHECK:   [[SEXT16:%.*]] = sext <4 x i1> [[CMP15]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT16]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[CMP17:%.*]] = icmp sle <2 x i64> [[TMP18]], [[TMP19]]
+// CHECK:   [[SEXT18:%.*]] = sext <2 x i1> [[CMP17]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT18]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[CMP19:%.*]] = icmp ule <2 x i64> [[TMP20]], [[TMP21]]
+// CHECK:   [[SEXT20:%.*]] = sext <2 x i1> [[CMP19]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT20]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP21:%.*]] = icmp ule <2 x i64> [[TMP22]], [[TMP23]]
+// CHECK:   [[SEXT22:%.*]] = sext <2 x i1> [[CMP21]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT22]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[CMP23:%.*]] = fcmp ole <2 x double> [[TMP24]], [[TMP25]]
+// CHECK:   [[SEXT24:%.*]] = sext <2 x i1> [[CMP23]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT24]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_cmple(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[CMP:%[^ ]+]] = icmp sle <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = sc <= sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ule <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = uc <= uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ule <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc <= bc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[CMP:%[^ ]+]] = icmp sle <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = ss <= ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[CMP:%[^ ]+]] = icmp ule <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = us <= us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp ule <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs <= bs2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[CMP:%[^ ]+]] = icmp sle <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = si <= si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[CMP:%[^ ]+]] = icmp ule <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = ui <= ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp ule <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi <= bi2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[CMP:%[^ ]+]] = icmp sle <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = sl <= sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[CMP:%[^ ]+]] = icmp ule <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = ul <= ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp ule <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl <= bl2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[CMP:%[^ ]+]] = fcmp ole <2 x double> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = fd <= fd2;
 }
 
-void test_cmplt (void)
-{
-// CHECK-LABEL: test_cmplt
+// CHECK-LABEL: define void @test_cmplt() #0 {
+// CHECK:   [[TMP0:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc, align 8
+// CHECK:   [[TMP1:%.*]] = load volatile <16 x i8>, <16 x i8>* @sc2, align 8
+// CHECK:   [[CMP:%.*]] = icmp slt <16 x i8> [[TMP0]], [[TMP1]]
+// CHECK:   [[SEXT:%.*]] = sext <16 x i1> [[CMP]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP2:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc, align 8
+// CHECK:   [[TMP3:%.*]] = load volatile <16 x i8>, <16 x i8>* @uc2, align 8
+// CHECK:   [[CMP1:%.*]] = icmp ult <16 x i8> [[TMP2]], [[TMP3]]
+// CHECK:   [[SEXT2:%.*]] = sext <16 x i1> [[CMP1]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT2]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP4:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc, align 8
+// CHECK:   [[TMP5:%.*]] = load volatile <16 x i8>, <16 x i8>* @bc2, align 8
+// CHECK:   [[CMP3:%.*]] = icmp ult <16 x i8> [[TMP4]], [[TMP5]]
+// CHECK:   [[SEXT4:%.*]] = sext <16 x i1> [[CMP3]] to <16 x i8>
+// CHECK:   store volatile <16 x i8> [[SEXT4]], <16 x i8>* @bc, align 8
+// CHECK:   [[TMP6:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss, align 8
+// CHECK:   [[TMP7:%.*]] = load volatile <8 x i16>, <8 x i16>* @ss2, align 8
+// CHECK:   [[CMP5:%.*]] = icmp slt <8 x i16> [[TMP6]], [[TMP7]]
+// CHECK:   [[SEXT6:%.*]] = sext <8 x i1> [[CMP5]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT6]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP8:%.*]] = load volatile <8 x i16>, <8 x i16>* @us, align 8
+// CHECK:   [[TMP9:%.*]] = load volatile <8 x i16>, <8 x i16>* @us2, align 8
+// CHECK:   [[CMP7:%.*]] = icmp ult <8 x i16> [[TMP8]], [[TMP9]]
+// CHECK:   [[SEXT8:%.*]] = sext <8 x i1> [[CMP7]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT8]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP10:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs, align 8
+// CHECK:   [[TMP11:%.*]] = load volatile <8 x i16>, <8 x i16>* @bs2, align 8
+// CHECK:   [[CMP9:%.*]] = icmp ult <8 x i16> [[TMP10]], [[TMP11]]
+// CHECK:   [[SEXT10:%.*]] = sext <8 x i1> [[CMP9]] to <8 x i16>
+// CHECK:   store volatile <8 x i16> [[SEXT10]], <8 x i16>* @bs, align 8
+// CHECK:   [[TMP12:%.*]] = load volatile <4 x i32>, <4 x i32>* @si, align 8
+// CHECK:   [[TMP13:%.*]] = load volatile <4 x i32>, <4 x i32>* @si2, align 8
+// CHECK:   [[CMP11:%.*]] = icmp slt <4 x i32> [[TMP12]], [[TMP13]]
+// CHECK:   [[SEXT12:%.*]] = sext <4 x i1> [[CMP11]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT12]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP14:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui, align 8
+// CHECK:   [[TMP15:%.*]] = load volatile <4 x i32>, <4 x i32>* @ui2, align 8
+// CHECK:   [[CMP13:%.*]] = icmp ult <4 x i32> [[TMP14]], [[TMP15]]
+// CHECK:   [[SEXT14:%.*]] = sext <4 x i1> [[CMP13]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT14]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP16:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi, align 8
+// CHECK:   [[TMP17:%.*]] = load volatile <4 x i32>, <4 x i32>* @bi2, align 8
+// CHECK:   [[CMP15:%.*]] = icmp ult <4 x i32> [[TMP16]], [[TMP17]]
+// CHECK:   [[SEXT16:%.*]] = sext <4 x i1> [[CMP15]] to <4 x i32>
+// CHECK:   store volatile <4 x i32> [[SEXT16]], <4 x i32>* @bi, align 8
+// CHECK:   [[TMP18:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl, align 8
+// CHECK:   [[TMP19:%.*]] = load volatile <2 x i64>, <2 x i64>* @sl2, align 8
+// CHECK:   [[CMP17:%.*]] = icmp slt <2 x i64> [[TMP18]], [[TMP19]]
+// CHECK:   [[SEXT18:%.*]] = sext <2 x i1> [[CMP17]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT18]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP20:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul, align 8
+// CHECK:   [[TMP21:%.*]] = load volatile <2 x i64>, <2 x i64>* @ul2, align 8
+// CHECK:   [[CMP19:%.*]] = icmp ult <2 x i64> [[TMP20]], [[TMP21]]
+// CHECK:   [[SEXT20:%.*]] = sext <2 x i1> [[CMP19]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT20]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP22:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl, align 8
+// CHECK:   [[TMP23:%.*]] = load volatile <2 x i64>, <2 x i64>* @bl2, align 8
+// CHECK:   [[CMP21:%.*]] = icmp ult <2 x i64> [[TMP22]], [[TMP23]]
+// CHECK:   [[SEXT22:%.*]] = sext <2 x i1> [[CMP21]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT22]], <2 x i64>* @bl, align 8
+// CHECK:   [[TMP24:%.*]] = load volatile <2 x double>, <2 x double>* @fd, align 8
+// CHECK:   [[TMP25:%.*]] = load volatile <2 x double>, <2 x double>* @fd2, align 8
+// CHECK:   [[CMP23:%.*]] = fcmp olt <2 x double> [[TMP24]], [[TMP25]]
+// CHECK:   [[SEXT24:%.*]] = sext <2 x i1> [[CMP23]] to <2 x i64>
+// CHECK:   store volatile <2 x i64> [[SEXT24]], <2 x i64>* @bl, align 8
+// CHECK:   ret void
+void test_cmplt(void) {
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @sc2
-// CHECK: [[CMP:%[^ ]+]] = icmp slt <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = sc < sc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @uc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ult <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = uc < uc2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <16 x i8>, <16 x i8>* @bc2
-// CHECK: [[CMP:%[^ ]+]] = icmp ult <16 x i8> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <16 x i1> [[CMP]] to <16 x i8>
   bc = bc < bc2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @ss2
-// CHECK: [[CMP:%[^ ]+]] = icmp slt <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = ss < ss2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @us2
-// CHECK: [[CMP:%[^ ]+]] = icmp ult <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = us < us2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <8 x i16>, <8 x i16>* @bs2
-// CHECK: [[CMP:%[^ ]+]] = icmp ult <8 x i16> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <8 x i1> [[CMP]] to <8 x i16>
   bs = bs < bs2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @si2
-// CHECK: [[CMP:%[^ ]+]] = icmp slt <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = si < si2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @ui2
-// CHECK: [[CMP:%[^ ]+]] = icmp ult <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = ui < ui2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x i32>, <4 x i32>* @bi2
-// CHECK: [[CMP:%[^ ]+]] = icmp ult <4 x i32> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
   bi = bi < bi2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @sl2
-// CHECK: [[CMP:%[^ ]+]] = icmp slt <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = sl < sl2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @ul2
-// CHECK: [[CMP:%[^ ]+]] = icmp ult <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = ul < ul2;
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x i64>, <2 x i64>* @bl2
-// CHECK: [[CMP:%[^ ]+]] = icmp ult <2 x i64> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = bl < bl2;
 
-// CHECK: [[VAL1:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd
-// CHECK: [[VAL2:%[^ ]+]] = load volatile <2 x double>, <2 x double>* @fd2
-// CHECK: [[CMP:%[^ ]+]] = fcmp olt <2 x double> [[VAL1]], [[VAL2]]
-// CHECK: %{{.*}} = sext <2 x i1> [[CMP]] to <2 x i64>
   bl = fd < fd2;
 }
 
diff --git a/test/CodeGenCUDA/propagate-metadata.cu b/test/CodeGenCUDA/propagate-metadata.cu
new file mode 100644
index 0000000..f8db765
--- /dev/null
+++ b/test/CodeGenCUDA/propagate-metadata.cu
@@ -0,0 +1,62 @@
+// Check that when we link a bitcode module into a file using
+// -mlink-cuda-bitcode, we apply the same attributes to the functions in that
+// bitcode module as we apply to functions we generate.
+//
+// In particular, we check that ftz and unsafe-math are propagated into the
+// bitcode library as appropriate.
+//
+// In addition, we set -ftrapping-math on the bitcode library, but then set
+// -fno-trapping-math on the main compilations, and ensure that the latter flag
+// overrides the flag on the bitcode library.
+
+// Build the bitcode library.  This is not built in CUDA mode, otherwise it
+// might have incompatible attributes.  This mirrors how libdevice is built.
+// RUN: %clang_cc1 -x c++ -emit-llvm-bc -ftrapping-math -DLIB \
+// RUN:   %s -o %t.bc -triple nvptx-unknown-unknown
+
+// RUN: %clang_cc1 -x cuda %s -emit-llvm -mlink-cuda-bitcode %t.bc -o - \
+// RUN:   -fno-trapping-math -fcuda-is-device -triple nvptx-unknown-unknown \
+// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=NOFTZ --check-prefix=NOFAST
+
+// RUN: %clang_cc1 -x cuda %s -emit-llvm -mlink-cuda-bitcode %t.bc \
+// RUN:   -fno-trapping-math -fcuda-flush-denormals-to-zero -o - \
+// RUN:   -fcuda-is-device -triple nvptx-unknown-unknown \
+// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=FTZ \
+// RUN:   --check-prefix=NOFAST
+
+// RUN: %clang_cc1 -x cuda %s -emit-llvm -mlink-cuda-bitcode %t.bc \
+// RUN:   -fno-trapping-math -fcuda-flush-denormals-to-zero -o - \
+// RUN:   -fcuda-is-device -menable-unsafe-fp-math -triple nvptx-unknown-unknown \
+// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
+
+// Wrap everything in extern "C" so we don't ahve to worry about name mangling
+// in the IR.
+extern "C" {
+#ifdef LIB
+
+// This function is defined in the library and only declared in the main
+// compilation.
+void lib_fn() {}
+
+#else
+
+#include "Inputs/cuda.h"
+__device__ void lib_fn();
+__global__ void kernel() { lib_fn(); }
+
+#endif
+}
+
+// The kernel and lib function should have the same attributes.
+// CHECK: define void @kernel() [[attr:#[0-9]+]]
+// CHECK: define internal void @lib_fn() [[attr]]
+
+// Check the attribute list.
+// CHECK: attributes [[attr]] = {
+// CHECK: "no-trapping-math"="true"
+
+// FTZ-SAME: "nvptx-f32ftz"="true"
+// NOFTZ-NOT: "nvptx-f32ftz"="true"
+
+// FAST-SAME: "unsafe-fp-math"="true"
+// NOFAST-NOT: "unsafe-fp-math"="true"
diff --git a/test/CodeGenCXX/PR26569.cpp b/test/CodeGenCXX/PR26569.cpp
index f00b831..859b6e2 100644
--- a/test/CodeGenCXX/PR26569.cpp
+++ b/test/CodeGenCXX/PR26569.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-optzns %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-passes %s -o - | FileCheck %s
 
 class __declspec(dllimport) A {
   virtual void m_fn1();
@@ -9,12 +9,12 @@
 extern template class __declspec(dllimport) B<int>;
 class __declspec(dllexport) C : B<int> {};
 
-// CHECK-DAG: @[[VTABLE_C:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)]
-// CHECK-DAG: @[[VTABLE_B:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$B@H@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)], comdat($"\01??_S?$B@H@@6B@")
-// CHECK-DAG: @[[VTABLE_A:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4A@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)], comdat($"\01??_SA@@6B@")
+// CHECK-DAG: @[[VTABLE_C:.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)] }
+// CHECK-DAG: @[[VTABLE_B:.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$B@H@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)] }, comdat($"\01??_S?$B@H@@6B@")
+// CHECK-DAG: @[[VTABLE_A:.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4A@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)] }, comdat($"\01??_SA@@6B@")
 
-// CHECK-DAG: @"\01??_7C@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_C]], i32 0, i32 1)
-// CHECK-DAG: @"\01??_S?$B@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_B]], i32 0, i32 1)
-// CHECK-DAG: @"\01??_SA@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_A]], i32 0, i32 1)
+// CHECK-DAG: @"\01??_7C@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_C]], i32 0, i32 0, i32 1)
+// CHECK-DAG: @"\01??_S?$B@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_B]], i32 0, i32 0, i32 1)
+// CHECK-DAG: @"\01??_SA@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_A]], i32 0, i32 0, i32 1)
 
 // CHECK-DAG: @"\01??_8?$B@H@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
diff --git a/test/CodeGenCXX/alloc-size.cpp b/test/CodeGenCXX/alloc-size.cpp
new file mode 100644
index 0000000..e93e231
--- /dev/null
+++ b/test/CodeGenCXX/alloc-size.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s
+
+namespace templates {
+void *my_malloc(int N) __attribute__((alloc_size(1)));
+void *my_calloc(int N, int M) __attribute__((alloc_size(1, 2)));
+
+struct MyType {
+  int arr[4];
+};
+
+template <typename T> int callMalloc();
+
+template <typename T, int N> int callCalloc();
+
+// CHECK-LABEL: define i32 @_ZN9templates6testItEv()
+int testIt() {
+  // CHECK: call i32 @_ZN9templates10callMallocINS_6MyTypeEEEiv
+  // CHECK: call i32 @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv
+  return callMalloc<MyType>() + callCalloc<MyType, 4>();
+}
+
+// CHECK-LABEL: define linkonce_odr i32
+// @_ZN9templates10callMallocINS_6MyTypeEEEiv
+template <typename T> int callMalloc() {
+  static_assert(sizeof(T) == 16, "");
+  // CHECK: ret i32 16
+  return __builtin_object_size(my_malloc(sizeof(T)), 0);
+}
+
+// CHECK-LABEL: define linkonce_odr i32
+// @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv
+template <typename T, int N> int callCalloc() {
+  static_assert(sizeof(T) * N == 64, "");
+  // CHECK: ret i32 64
+  return __builtin_object_size(my_malloc(sizeof(T) * N), 0);
+}
+}
+
+namespace templated_alloc_size {
+using size_t = unsigned long;
+
+// We don't need bodies for any of these, because they're only used in
+// __builtin_object_size, and that shouldn't need anything but a function
+// decl with alloc_size on it.
+template <typename T>
+T *my_malloc(size_t N = sizeof(T)) __attribute__((alloc_size(1)));
+
+template <typename T>
+T *my_calloc(size_t M, size_t N = sizeof(T)) __attribute__((alloc_size(2, 1)));
+
+template <size_t N>
+void *dependent_malloc(size_t NT = N) __attribute__((alloc_size(1)));
+
+template <size_t N, size_t M>
+void *dependent_calloc(size_t NT = N, size_t MT = M)
+    __attribute__((alloc_size(1, 2)));
+
+template <typename T, size_t M>
+void *dependent_calloc2(size_t NT = sizeof(T), size_t MT = M)
+    __attribute__((alloc_size(1, 2)));
+
+// CHECK-LABEL: define i32 @_ZN20templated_alloc_size6testItEv
+int testIt() {
+  // 122 = 4 + 5*4 + 6 + 7*8 + 4*9
+  // CHECK: ret i32 122
+  return __builtin_object_size(my_malloc<int>(), 0) +
+         __builtin_object_size(my_calloc<int>(5), 0) +
+         __builtin_object_size(dependent_malloc<6>(), 0) +
+         __builtin_object_size(dependent_calloc<7, 8>(), 0) +
+         __builtin_object_size(dependent_calloc2<int, 9>(), 0);
+}
+}
diff --git a/test/CodeGenCXX/apple-kext-indirect-call-2.cpp b/test/CodeGenCXX/apple-kext-indirect-call-2.cpp
index d441b78..3b2cda8 100644
--- a/test/CodeGenCXX/apple-kext-indirect-call-2.cpp
+++ b/test/CodeGenCXX/apple-kext-indirect-call-2.cpp
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: @_ZTV1A = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null]
-// CHECK: @_ZTV4Base = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null]
-// CHECK: @_ZTV8Derived2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null]
-// CHECK: @_ZTV2D2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_ZNK2D23abcEv to i8*), i8* null]
+// CHECK: @_ZTV1A = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null] }
+// CHECK: @_ZTV4Base = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null] }
+// CHECK: @_ZTV8Derived2 = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null] }
+// CHECK: @_ZTV2D2 = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_ZNK2D23abcEv to i8*), i8* null] }
 
 struct A {
   virtual const char* abc(void) const;
@@ -18,7 +18,7 @@
 void B::VF() {}
 
 void FUNC(B* p) {
-// CHECK: [[T1:%.*]] = load i8* (%struct.A*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV1A to i8* (%struct.A*)**), i64 2)
+// CHECK: [[T1:%.*]] = load i8* (%struct.A*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, i8* (%struct.A*)** bitcast ({ [4 x i8*] }* @_ZTV1A to i8* (%struct.A*)**), i64 2)
 // CHECK-NEXT:  [[T2:%.*]] = call i8* [[T1]]
   const char* c = p->A::abc();
 }
@@ -33,7 +33,7 @@
 };
 
 void FUNC1(Derived* p) {
-// CHECK: [[U1:%.*]] = load i8* (%struct.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to i8* (%struct.Base*)**), i64 2)
+// CHECK: [[U1:%.*]] = load i8* (%struct.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ({ [4 x i8*] }* @_ZTV4Base to i8* (%struct.Base*)**), i64 2)
 // CHECK-NEXT:  [[U2:%.*]] = call i8* [[U1]]
   char* c = p->Base::abc();
 }
@@ -49,7 +49,7 @@
 char* Derived2::efg(void) const { return 0; }
 
 void FUNC2(Derived2* p) {
-// CHECK: [[V1:%.*]] = load i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ([5 x i8*]* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), i64 3)
+// CHECK: [[V1:%.*]] = load i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ({ [5 x i8*] }* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), i64 3)
 // CHECK-NEXT:  [[V2:%.*]] = call i8* [[V1]]
   char* c = p->Derived2::efg();
 }
@@ -70,7 +70,7 @@
 char* D2::abc(void) const { return 0; }
 
 void FUNC3(Sub* p) {
-// CHECK: [[W1:%.*]] = load i8* (%struct.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ([5 x i8*]* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3)
+// CHECK: [[W1:%.*]] = load i8* (%struct.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ({ [5 x i8*] }* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3)
 // CHECK-NEXT:  [[W2:%.*]] = call i8* [[W1]]
   char* c = p->D2::abc();
 }
diff --git a/test/CodeGenCXX/apple-kext-indirect-call.cpp b/test/CodeGenCXX/apple-kext-indirect-call.cpp
index e4c03b5..ac0e3f4 100644
--- a/test/CodeGenCXX/apple-kext-indirect-call.cpp
+++ b/test/CodeGenCXX/apple-kext-indirect-call.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null]
+// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
 
 struct Base { 
   virtual void abc(void) const; 
@@ -12,7 +12,7 @@
   p->Base::abc();
 }
 
-// CHECK: getelementptr inbounds (void (%struct.Base*)*, void (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to void (%struct.Base*)**), i64 2)
+// CHECK: getelementptr inbounds (void (%struct.Base*)*, void (%struct.Base*)** bitcast ({ [4 x i8*] }* @_ZTV4Base to void (%struct.Base*)**), i64 2)
 // CHECK-NOT: call void @_ZNK4Base3abcEv
 
 template<class T>
@@ -37,6 +37,6 @@
   t->Templ::f();
 }
 
-// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ([5 x i8*]* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
+// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [5 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
 // CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this)
 // CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this)
diff --git a/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
index 5f6bdb2..4cfa88d 100644
--- a/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
+++ b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null]
+// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [7 x i8*] } { [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
 
 struct B1 { 
   virtual ~B1(); 
@@ -12,10 +12,10 @@
   pb1->B1::~B1();
 }
 // CHECK-LABEL: define void @_ZN2B1D0Ev
-// CHECK: [[T1:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
+// CHECK: [[T1:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ({ [5 x i8*] }* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
 // CHECK-NEXT: call void [[T1]](%struct.B1* [[T2:%.*]])
 // CHECK-LABEL: define void @_Z6DELETEP2B1
-// CHECK: [[T3:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
+// CHECK: [[T3:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ({ [5 x i8*] }* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
 // CHECK-NEXT:  call void [[T3]](%struct.B1* [[T4:%.*]])
 
 template<class T>
@@ -42,7 +42,7 @@
   t->Templ::~Templ();
 }
 
-// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ([7 x i8*]* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
+// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [7 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
 // CHECK: declare void @_ZN5TemplIiED0Ev(%struct.Templ*)
 // CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this)
 // CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this)
diff --git a/test/CodeGenCXX/arm-swiftcall.cpp b/test/CodeGenCXX/arm-swiftcall.cpp
index 535350c..5c932c7 100644
--- a/test/CodeGenCXX/arm-swiftcall.cpp
+++ b/test/CodeGenCXX/arm-swiftcall.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s -Wno-return-type-c-linkage | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s -Wno-return-type-c-linkage -std=c++03 | FileCheck %s -check-prefixes=CHECK
 
 // This isn't really testing anything ARM-specific; it's just a convenient
 // 32-bit platform.
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp
index d0b896d..7eba017 100644
--- a/test/CodeGenCXX/arm.cpp
+++ b/test/CodeGenCXX/arm.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -o - -fexceptions | FileCheck %s
+// RUN: %clang_cc1 %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -std=gnu++98 -o - -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -std=gnu++11 -o - -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
 
 // CHECK: @_ZZN5test74testEvE1x = internal global i32 0, align 4
 // CHECK: @_ZGVZN5test74testEvE1x = internal global i32 0
@@ -156,7 +157,8 @@
     // CHECK: getelementptr {{.*}}, i32 4
     // CHECK: bitcast {{.*}} to i32*
     // CHECK: load
-    // CHECK: invoke {{.*}} @_ZN5test31AD1Ev
+    // CHECK98: invoke {{.*}} @_ZN5test31AD1Ev
+    // CHECK11: call {{.*}} @_ZN5test31AD1Ev
     // CHECK: call void @_ZdaPv
     delete [] x;
   }
@@ -168,7 +170,8 @@
     // CHECK: getelementptr {{.*}}, i32 4
     // CHECK: bitcast {{.*}} to i32*
     // CHECK: load
-    // CHECK: invoke {{.*}} @_ZN5test31AD1Ev
+    // CHECK98: invoke {{.*}} @_ZN5test31AD1Ev
+    // CHECK11: call {{.*}} @_ZN5test31AD1Ev
     // CHECK: call void @_ZdaPv
     delete [] x;
   }
diff --git a/test/CodeGenCXX/atomic-dllexport.cpp b/test/CodeGenCXX/atomic-dllexport.cpp
new file mode 100644
index 0000000..ae14222
--- /dev/null
+++ b/test/CodeGenCXX/atomic-dllexport.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++11 -fms-extensions -O0 -o - %s | FileCheck --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++11 -fms-extensions -O0 -o - %s | FileCheck --check-prefix=M64 %s
+
+struct __declspec(dllexport) SomeStruct {
+  // Copy assignment operator should be produced, and exported:
+  // M32: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.SomeStruct* @"\01??4SomeStruct@@QAEAAU0@ABU0@@Z"
+  // M64: define weak_odr dllexport                dereferenceable({{[0-9]+}}) %struct.SomeStruct* @"\01??4SomeStruct@@QEAAAEAU0@AEBU0@@Z"
+  _Atomic(int) mData;
+};
diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp
index 67993b4..7f5595f 100644
--- a/test/CodeGenCXX/attr.cpp
+++ b/test/CodeGenCXX/attr.cpp
@@ -31,4 +31,4 @@
 // CHECK at top of file
 extern "C" int test2() __attribute__((alias("_Z5test1v")));
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/block-in-ctor-dtor.cpp b/test/CodeGenCXX/block-in-ctor-dtor.cpp
index 0dc0ab0..0ec9db1 100644
--- a/test/CodeGenCXX/block-in-ctor-dtor.cpp
+++ b/test/CodeGenCXX/block-in-ctor-dtor.cpp
@@ -42,7 +42,5 @@
 // CHECK-LABEL: define internal void @___ZN4ZoneD2Ev_block_invoke_
 // CHECK-LABEL: define internal void @___ZN1XC2Ev_block_invoke
 // CHECK-LABEL: define internal void @___ZN1XC2Ev_block_invoke_
-// CHECK-LABEL: define internal void @___ZN1XC1Ev_block_invoke
-// CHECK-LABEL: define internal void @___ZN1XC1Ev_block_invoke_
 // CHECK-LABEL: define internal void @___ZN1XD2Ev_block_invoke
 // CHECK-LABEL: define internal void @___ZN1XD2Ev_block_invoke_
diff --git a/test/CodeGenCXX/builtins.cpp b/test/CodeGenCXX/builtins.cpp
index 98e2d1a..a49deea 100644
--- a/test/CodeGenCXX/builtins.cpp
+++ b/test/CodeGenCXX/builtins.cpp
@@ -26,3 +26,7 @@
 long y = __builtin_abs(-2l);
 // CHECK:  [[Y:%.+]] = call i64 @_Z13__builtin_absl(i64 -2)
 // CHECK:  store i64 [[Y]], i64* @y, align 8
+
+extern const char char_memchr_arg[32];
+char *memchr_result = __builtin_char_memchr(char_memchr_arg, 123, 32);
+// CHECK: call i8* @memchr(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @char_memchr_arg, i32 0, i32 0), i32 123, i64 32)
diff --git a/test/CodeGenCXX/cfi-cross-dso.cpp b/test/CodeGenCXX/cfi-cross-dso.cpp
index d67927d..bfa0705 100644
--- a/test/CodeGenCXX/cfi-cross-dso.cpp
+++ b/test/CodeGenCXX/cfi-cross-dso.cpp
@@ -26,7 +26,7 @@
   b.f();
 }
 
-// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant [2 x i8*] {{.*}}@"\01??_R4B@?A@@6B@"{{.*}}@"\01?f@B@?A@@UEAAXXZ"
+// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant { [2 x i8*] } {{.*}}@"\01??_R4B@?A@@6B@"{{.*}}@"\01?f@B@?A@@UEAAXXZ"
 
 // CHECK:   %[[VT:.*]] = load void (%struct.A*)**, void (%struct.A*)***
 // CHECK:   %[[VT2:.*]] = bitcast {{.*}}%[[VT]] to i8*, !nosanitize
diff --git a/test/CodeGenCXX/cfi-ms-rtti.cpp b/test/CodeGenCXX/cfi-ms-rtti.cpp
index fbebad4..328297d 100644
--- a/test/CodeGenCXX/cfi-ms-rtti.cpp
+++ b/test/CodeGenCXX/cfi-ms-rtti.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -flto -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall | FileCheck --check-prefix=RTTI %s
-// RUN: %clang_cc1 -flto -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall -fno-rtti-data | FileCheck --check-prefix=NO-RTTI %s
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall | FileCheck --check-prefix=RTTI %s
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall -fno-rtti-data | FileCheck --check-prefix=NO-RTTI %s
 
 struct A {
   A();
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index 0c2193f..c4962bc 100644
--- a/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/test/CodeGenCXX/const-init-cxx11.cpp
@@ -343,13 +343,13 @@
     constexpr E() : B(3), c{'b','y','e'} {}
     char c[3];
   };
-  // CHECK: @_ZN14VirtualMembers1eE = global { i8**, double, i32, i8**, double, [5 x i8], i16, i8**, double, [5 x i8], [3 x i8] } { i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i32 0, i32 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i32 0, i32 5), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i32 0, i32 9), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" }
+  // CHECK: @_ZN14VirtualMembers1eE = global { i8**, double, i32, i8**, double, [5 x i8], i16, i8**, double, [5 x i8], [3 x i8] } { i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 0, i32 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 1, i32 2), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 2, i32 2), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" }
   E e;
 
   struct nsMemoryImpl {
     virtual void f();
   };
-  // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers12nsMemoryImplE, i32 0, i32 2) }
+  // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN14VirtualMembers12nsMemoryImplE, i32 0, inrange i32 0, i32 2) }
   __attribute__((used))
   static nsMemoryImpl sGlobalMemory;
 
@@ -360,7 +360,7 @@
 
     T t;
   };
-  // CHECK: @_ZN14VirtualMembers1tE = global { i8**, i32 } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers13TemplateClassIiEE, i32 0, i32 2), i32 42 }
+  // CHECK: @_ZN14VirtualMembers1tE = global { i8**, i32 } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN14VirtualMembers13TemplateClassIiEE, i32 0, inrange i32 0, i32 2), i32 42 }
   TemplateClass<int> t;
 }
 
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
index c78534a..fe15ccf 100644
--- a/test/CodeGenCXX/constructor-init.cpp
+++ b/test/CodeGenCXX/constructor-init.cpp
@@ -95,14 +95,14 @@
 
   // CHECK-LABEL: define void @_ZN10InitVTable1BC2Ev(%"struct.InitVTable::B"* %this) unnamed_addr
   // CHECK:      [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i32 (...)***
-  // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN10InitVTable1BE, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+  // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
   // CHECK:      [[VTBL:%.*]] = load i32 ([[B]]*)**, i32 ([[B]]*)*** {{%.*}}
   // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)*, i32 ([[B]]*)** [[VTBL]], i64 0
   // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)*, i32 ([[B]]*)** [[FNP]]
   // CHECK-NEXT: [[ARG:%.*]] = call i32 [[FN]]([[B]]* [[THIS]])
   // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]])
   // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i32 (...)***
-  // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN10InitVTable1BE, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+  // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
   // CHECK-NEXT: ret void
   B::B() : A(foo()) {}
 
@@ -110,7 +110,7 @@
   // CHECK:      [[ARG:%.*]] = add nsw i32 {{%.*}}, 5
   // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]])
   // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i32 (...)***
-  // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN10InitVTable1BE, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+  // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
   // CHECK-NEXT: ret void
   B::B(int x) : A(x + 5) {}
 }
@@ -207,20 +207,17 @@
 
     // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_
     // CHECK-PR10720-NOT: ret
-    // CHECK-PR10720: load
-    // CHECK-PR10720: icmp ult
-    // CHECK-PR10720-NEXT: br i1
     // CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_
-    // CHECK-PR10720-NEXT: br label
+    // CHECK-PR10720: icmp eq
+    // CHECK-PR10720-NEXT: br i1
     // CHECK-PR10720: ret void
 
     // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_
     // CHECK-PR10720-NOT: ret
     // CHECK-PR10720: load
-    // CHECK-PR10720: icmp ult
-    // CHECK-PR10720-NEXT: br i1
     // CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_
-    // CHECK-PR10720-NEXT: br label
+    // CHECK-PR10720: icmp eq
+    // CHECK-PR10720-NEXT: br i1
     // CHECK-PR10720: ret void
     pair2(pair2&&) = default;
 
diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp
index ecbe5bb..a898140 100644
--- a/test/CodeGenCXX/constructors.cpp
+++ b/test/CodeGenCXX/constructors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output
 
 struct Member { int x; Member(); Member(int); Member(const Member &); };
 struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); };
@@ -109,3 +109,57 @@
   // CHECK:      [[THIS:%.*]] = load [[B:%.*]]*, [[B:%.*]]**
   // CHECK-NEXT: ret void
 }
+
+// Ensure that we
+// a) emit the ABI-required but useless complete object and deleting destructor
+//    symbols for an abstract class, and 
+// b) do *not* emit references to virtual base destructors for an abstract class
+//
+// Our approach to this is to give these functions a body that simply traps.
+//
+// FIXME: We should ideally not create these symbols at all, but Clang can
+// actually generate references to them in other TUs in some cases, so we can't
+// stop emitting them without breaking ABI. See:
+//
+//   https://github.com/itanium-cxx-abi/cxx-abi/issues/10
+namespace abstract {
+  // Note, the destructor of this class is not instantiated here.
+  template<typename T> struct should_not_appear_in_output {
+    ~should_not_appear_in_output() { int arr[-(int)sizeof(T)]; }
+  };
+
+  struct X { ~X(); };
+
+  struct A : virtual should_not_appear_in_output<int>, X {
+    virtual ~A() = 0;
+  };
+
+  // CHECK-LABEL: define void @_ZN8abstract1AD2Ev(
+  // CHECK: call {{.*}}@_ZN8abstract1XD2Ev(
+  // CHECK: ret
+
+  // CHECK-LABEL: define void @_ZN8abstract1AD1Ev(
+  // CHECK: call {{.*}}@llvm.trap(
+  // CHECK: unreachable
+
+  // CHECK-LABEL: define void @_ZN8abstract1AD0Ev(
+  // CHECK: call {{.*}}@llvm.trap(
+  // CHECK: unreachable
+  A::~A() {}
+
+  struct B : virtual should_not_appear_in_output<int>, X {
+    virtual void f() = 0;
+    ~B();
+  };
+
+  // CHECK-LABEL: define void @_ZN8abstract1BD2Ev(
+  // CHECK: call {{.*}}@_ZN8abstract1XD2Ev(
+  // CHECK: ret
+
+  // CHECK-LABEL: define void @_ZN8abstract1BD1Ev(
+  // CHECK: call {{.*}}@llvm.trap(
+  // CHECK: unreachable
+
+  // CHECK-NOT: @_ZN8abstract1BD0Ev(
+  B::~B() {}
+}
diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
index 9790ca8..9d7e18e 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
@@ -24,4 +24,4 @@
 A x(A& y) { return y; }
 
 // CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* {{.*}}%this, %struct.A* dereferenceable({{[0-9]+}})) unnamed_addr
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange i32 0, i32 2) to i32 (...)**)
diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp
index 4928c61..5a2cc14 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -166,7 +166,7 @@
 // CHECK-LABEL:    define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_(
 // CHECK:      [[THIS:%.*]] = load [[A]]*, [[A]]**
 // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i32 (...)***
-// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN12rdar138169401AE, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN12rdar138169401AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1
 // CHECK-NEXT: [[OTHER:%.*]] = load [[A]]*, [[A]]**
 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OTHER]], i32 0, i32 1
diff --git a/test/CodeGenCXX/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp
index 018e958..6826ee5 100644
--- a/test/CodeGenCXX/ctor-dtor-alias.cpp
+++ b/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
 
-// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns > %t
+// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes > %t
 // RUN: FileCheck --check-prefix=CHECK1 --input-file=%t %s
 // RUN: FileCheck --check-prefix=CHECK2 --input-file=%t %s
 // RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s
@@ -8,7 +8,7 @@
 // RUN: FileCheck --check-prefix=CHECK5 --input-file=%t %s
 // RUN: FileCheck --check-prefix=CHECK6 --input-file=%t %s
 
-// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck --check-prefix=COFF %s
+// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck --check-prefix=COFF %s
 
 namespace test1 {
 // Test that we produce the apropriate comdats when creating aliases to
@@ -172,7 +172,7 @@
 }
 }
 
-// CHECK5: @_ZTV1C = linkonce_odr unnamed_addr constant [4 x i8*] [{{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}]
+// CHECK5: @_ZTV1C = linkonce_odr unnamed_addr constant { [4 x i8*] } {{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}]
 // r194296 replaced C::~C with B::~B without emitting the later.
 
 class A {
diff --git a/test/CodeGenCXX/cxx11-exception-spec.cpp b/test/CodeGenCXX/cxx11-exception-spec.cpp
index 6a3a394..fbff078 100644
--- a/test/CodeGenCXX/cxx11-exception-spec.cpp
+++ b/test/CodeGenCXX/cxx11-exception-spec.cpp
@@ -121,7 +121,7 @@
 }
 
 // CHECK: attributes [[NONE]] = { {{.*}} }
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
 // CHECK: attributes [[NUW2]] = { nounwind{{.*}} }
 
 
diff --git a/test/CodeGenCXX/cxx11-initializer-aggregate.cpp b/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
index be4fd73..8bf3596 100644
--- a/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
+++ b/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
@@ -2,7 +2,16 @@
 
 struct A { int a, b; int f(); };
 
-// CHECK: define {{.*}}@_Z3fn1i(
+namespace NonAggregateCopyInAggregateInit { // PR32044
+  struct A { constexpr A(int n) : x(n), y() {} int x, y; } extern a;
+  // CHECK-DAG: @_ZN31NonAggregateCopyInAggregateInit1bE = global %{{.*}} { %[[A:.*]]* @_ZN31NonAggregateCopyInAggregateInit1aE }
+  struct B { A &p; } b{{a}};
+  // CHECK-DAG: @_ZGRN31NonAggregateCopyInAggregateInit1cE_ = internal global %[[A]] { i32 1, i32 0 }
+  // CHECK-DAG: @_ZN31NonAggregateCopyInAggregateInit1cE = global %{{.*}} { %{{.*}}* @_ZGRN31NonAggregateCopyInAggregateInit1cE_ }
+  struct C { A &&p; } c{{1}};
+}
+
+// CHECK-LABEL: define {{.*}}@_Z3fn1i(
 int fn1(int x) {
   // CHECK: %[[INITLIST:.*]] = alloca %struct.A
   // CHECK: %[[A:.*]] = getelementptr inbounds %struct.A, %struct.A* %[[INITLIST]], i32 0, i32 0
@@ -15,7 +24,7 @@
 
 struct B { int &r; int &f() { return r; } };
 
-// CHECK: define {{.*}}@_Z3fn2Ri(
+// CHECK-LABEL: define {{.*}}@_Z3fn2Ri(
 int &fn2(int &v) {
   // CHECK: %[[INITLIST2:.*]] = alloca %struct.B, align 8
   // CHECK: %[[R:.*]] = getelementptr inbounds %struct.B, %struct.B* %[[INITLIST2:.*]], i32 0, i32 0
@@ -24,7 +33,7 @@
   return B{v}.f();
 }
 
-// CHECK: define {{.*}}@__cxx_global_var_init(
+// CHECK-LABEL: define {{.*}}@__cxx_global_var_init(
 //
 // CHECK: call {{.*}}@_ZN14NonTrivialInit1AC1Ev(
 // CHECK: getelementptr inbounds {{.*}}, i64 1
diff --git a/test/CodeGenCXX/cxx11-noreturn.cpp b/test/CodeGenCXX/cxx11-noreturn.cpp
index b876bb9..58a5a37 100644
--- a/test/CodeGenCXX/cxx11-noreturn.cpp
+++ b/test/CodeGenCXX/cxx11-noreturn.cpp
@@ -7,4 +7,4 @@
   while (g()) {}
 }
 
-// CHECK: attributes [[NR]] = { noreturn nounwind{{.*}} }
+// CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} }
diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp
index f465cbd..3231a76 100644
--- a/test/CodeGenCXX/cxx11-thread-local.cpp
+++ b/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -6,18 +6,18 @@
 int f();
 int g();
 
-// LINUX: @a = thread_local global i32 0
-// DARWIN: @a = internal thread_local global i32 0
+// LINUX-DAG: @a = thread_local global i32 0
+// DARWIN-DAG: @a = internal thread_local global i32 0
 thread_local int a = f();
 extern thread_local int b;
-// CHECK: @c = global i32 0
+// CHECK-DAG: @c = global i32 0
 int c = b;
-// CHECK: @_ZL1d = internal thread_local global i32 0
+// CHECK-DAG: @_ZL1d = internal thread_local global i32 0
 static thread_local int d = g();
 
 struct U { static thread_local int m; };
-// LINUX: @_ZN1U1mE = thread_local global i32 0
-// DARWIN: @_ZN1U1mE = internal thread_local global i32 0
+// LINUX-DAG: @_ZN1U1mE = thread_local global i32 0
+// DARWIN-DAG: @_ZN1U1mE = internal thread_local global i32 0
 thread_local int U::m = f();
 
 namespace MismatchedInitType {
@@ -35,37 +35,64 @@
 template<typename T> struct V { static thread_local int m; };
 template<typename T> thread_local int V<T>::m = g();
 
-// CHECK: @e = global i32 0
-int e = V<int>::m;
+template<typename T> struct W { static thread_local int m; };
+template<typename T> thread_local int W<T>::m = 123;
 
-// CHECK: @_ZN1VIiE1mE = linkonce_odr thread_local global i32 0
+struct Dtor { ~Dtor(); };
+template<typename T> struct X { static thread_local Dtor m; };
+template<typename T> thread_local Dtor X<T>::m;
 
-// CHECK: @_ZZ1fvE1n = internal thread_local global i32 0
+// CHECK-DAG: @e = global
+void *e = V<int>::m + W<int>::m + &X<int>::m;
 
-// CHECK: @_ZGVZ1fvE1n = internal thread_local global i8 0
+template thread_local int V<float>::m;
+template thread_local int W<float>::m;
+template thread_local Dtor X<float>::m;
 
-// CHECK: @_ZZ8tls_dtorvE1s = internal thread_local global
-// CHECK: @_ZGVZ8tls_dtorvE1s = internal thread_local global i8 0
+extern template thread_local int V<char>::m;
+extern template thread_local int W<char>::m;
+extern template thread_local Dtor X<char>::m;
 
-// CHECK: @_ZZ8tls_dtorvE1t = internal thread_local global
-// CHECK: @_ZGVZ8tls_dtorvE1t = internal thread_local global i8 0
+void *e2 = V<char>::m + W<char>::m + &X<char>::m;
 
-// CHECK: @_ZZ8tls_dtorvE1u = internal thread_local global
-// CHECK: @_ZGVZ8tls_dtorvE1u = internal thread_local global i8 0
-// CHECK: @_ZGRZ8tls_dtorvE1u_ = internal thread_local global
+// CHECK-DAG: @_ZN1VIiE1mE = linkonce_odr thread_local global i32 0
+// CHECK-DAG: @_ZN1WIiE1mE = linkonce_odr thread_local global i32 123
+// CHECK-DAG: @_ZN1XIiE1mE = linkonce_odr thread_local global {{.*}}
+// CHECK-DAG: @_ZN1VIfE1mE = weak_odr thread_local global i32 0
+// CHECK-DAG: @_ZN1WIfE1mE = weak_odr thread_local global i32 123
+// CHECK-DAG: @_ZN1XIfE1mE = weak_odr thread_local global {{.*}}
 
-// CHECK: @_ZGVN1VIiE1mE = linkonce_odr thread_local global i64 0
+// CHECK-DAG: @_ZZ1fvE1n = internal thread_local global i32 0
 
-// CHECK: @__tls_guard = internal thread_local global i8 0
+// CHECK-DAG: @_ZGVZ1fvE1n = internal thread_local global i8 0
 
-// CHECK: @llvm.global_ctors = appending global {{.*}} @[[GLOBAL_INIT:[^ ]*]]
+// CHECK-DAG: @_ZZ8tls_dtorvE1s = internal thread_local global
+// CHECK-DAG: @_ZGVZ8tls_dtorvE1s = internal thread_local global i8 0
 
-// LINUX: @_ZTH1a = alias void (), void ()* @__tls_init
-// DARWIN: @_ZTH1a = internal alias void (), void ()* @__tls_init
-// CHECK: @_ZTHL1d = internal alias void (), void ()* @__tls_init
-// LINUX: @_ZTHN1U1mE = alias void (), void ()* @__tls_init
-// DARWIN: @_ZTHN1U1mE = internal alias void (), void ()* @__tls_init
-// CHECK: @_ZTHN1VIiE1mE = linkonce_odr alias void (), void ()* @__tls_init
+// CHECK-DAG: @_ZZ8tls_dtorvE1t = internal thread_local global
+// CHECK-DAG: @_ZGVZ8tls_dtorvE1t = internal thread_local global i8 0
+
+// CHECK-DAG: @_ZZ8tls_dtorvE1u = internal thread_local global
+// CHECK-DAG: @_ZGVZ8tls_dtorvE1u = internal thread_local global i8 0
+// CHECK-DAG: @_ZGRZ8tls_dtorvE1u_ = internal thread_local global
+
+// CHECK-DAG: @_ZGVN1VIiE1mE = linkonce_odr thread_local global i64 0
+
+// CHECK-DAG: @__tls_guard = internal thread_local global i8 0
+
+// CHECK-DAG: @llvm.global_ctors = appending global {{.*}} @[[GLOBAL_INIT:[^ ]*]]
+
+// LINUX-DAG: @_ZTH1a = alias void (), void ()* @__tls_init
+// DARWIN-DAG: @_ZTH1a = internal alias void (), void ()* @__tls_init
+// CHECK-DAG: @_ZTHL1d = internal alias void (), void ()* @__tls_init
+// LINUX-DAG: @_ZTHN1U1mE = alias void (), void ()* @__tls_init
+// DARWIN-DAG: @_ZTHN1U1mE = internal alias void (), void ()* @__tls_init
+// CHECK-DAG: @_ZTHN1VIiE1mE = linkonce_odr alias void (), void ()* @[[V_M_INIT:[^, ]*]]
+// CHECK-NOT: @_ZTHN1WIiE1mE =
+// CHECK-DAG: @_ZTHN1XIiE1mE = linkonce_odr alias void (), void ()* @[[X_M_INIT:[^, ]*]]
+// CHECK-DAG: @_ZTHN1VIfE1mE = weak_odr alias void (), void ()* @[[VF_M_INIT:[^, ]*]]
+// CHECK-NOT: @_ZTHN1WIfE1mE =
+// CHECK-DAG: @_ZTHN1XIfE1mE = weak_odr alias void (), void ()* @[[XF_M_INIT:[^, ]*]]
 
 
 // Individual variable initialization functions:
@@ -118,7 +145,9 @@
 // LINUX: call i32* @_ZTWN1VIiE1mE()
 // DARWIN: call cxx_fast_tlscc i32* @_ZTWN1VIiE1mE()
 // CHECK-NEXT: load i32, i32* %{{.*}}, align 4
-// CHECK-NEXT: store i32 %{{.*}}, i32* @e, align 4
+// LINUX: call {{.*}}* @_ZTWN1XIiE1mE()
+// DARWIN: call cxx_fast_tlscc {{.*}}* @_ZTWN1XIiE1mE()
+// CHECK: store {{.*}} @e
 
 // LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1VIiE1mE()
 // DARWIN-LABEL: define weak_odr hidden cxx_fast_tlscc i32* @_ZTWN1VIiE1mE()
@@ -126,6 +155,64 @@
 // DARWIN: call cxx_fast_tlscc void @_ZTHN1VIiE1mE()
 // CHECK: ret i32* @_ZN1VIiE1mE
 
+// LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1WIiE1mE()
+// DARWIN-LABEL: define weak_odr hidden cxx_fast_tlscc i32* @_ZTWN1WIiE1mE()
+// CHECK-NOT: call
+// CHECK: ret i32* @_ZN1WIiE1mE
+
+// LINUX-LABEL: define weak_odr hidden {{.*}}* @_ZTWN1XIiE1mE()
+// DARWIN-LABEL: define weak_odr hidden cxx_fast_tlscc {{.*}}* @_ZTWN1XIiE1mE()
+// LINUX: call void @_ZTHN1XIiE1mE()
+// DARWIN: call cxx_fast_tlscc void @_ZTHN1XIiE1mE()
+// CHECK: ret {{.*}}* @_ZN1XIiE1mE
+
+// CHECK: define internal {{.*}} @[[VF_M_INIT]]()
+// LINUX-SAME: comdat($_ZN1VIfE1mE)
+// DARWIN-NOT: comdat
+// CHECK: load i8, i8* bitcast (i64* @_ZGVN1VIfE1mE to i8*)
+// CHECK: %[[VF_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: br i1 %[[VF_M_INITIALIZED]],
+// need init:
+// CHECK: call i32 @_Z1gv()
+// CHECK: store i32 %{{.*}}, i32* @_ZN1VIfE1mE, align 4
+// CHECK: store i64 1, i64* @_ZGVN1VIfE1mE
+// CHECK: br label
+
+// CHECK: define internal {{.*}} @[[XF_M_INIT]]()
+// LINUX-SAME: comdat($_ZN1XIfE1mE)
+// DARWIN-NOT: comdat
+// CHECK: load i8, i8* bitcast (i64* @_ZGVN1XIfE1mE to i8*)
+// CHECK: %[[XF_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: br i1 %[[XF_M_INITIALIZED]],
+// need init:
+// LINUX: call {{.*}}__cxa_thread_atexit
+// DARWIN: call {{.*}}_tlv_atexit
+// CHECK: store i64 1, i64* @_ZGVN1XIfE1mE
+// CHECK: br label
+
+// LINUX: declare i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
+// DARWIN: declare i32 @_tlv_atexit(void (i8*)*, i8*, i8*)
+
+// DARWIN: declare cxx_fast_tlscc i32* @_ZTWN1VIcE1mE()
+// LINUX: define weak_odr hidden i32* @_ZTWN1VIcE1mE()
+// LINUX-NOT: comdat
+// LINUX: br i1 icmp ne (void ()* @_ZTHN1VIcE1mE,
+// LINUX: call void @_ZTHN1VIcE1mE()
+// LINUX: ret i32* @_ZN1VIcE1mE
+
+// DARWIN: declare cxx_fast_tlscc i32* @_ZTWN1WIcE1mE()
+// LINUX: define weak_odr hidden i32* @_ZTWN1WIcE1mE()
+// LINUX-NOT: comdat
+// LINUX: br i1 icmp ne (void ()* @_ZTHN1WIcE1mE,
+// LINUX: call void @_ZTHN1WIcE1mE()
+// LINUX: ret i32* @_ZN1WIcE1mE
+
+// DARWIN: declare cxx_fast_tlscc {{.*}}* @_ZTWN1XIcE1mE()
+// LINUX: define weak_odr hidden {{.*}}* @_ZTWN1XIcE1mE()
+// LINUX-NOT: comdat
+// LINUX: br i1 icmp ne (void ()* @_ZTHN1XIcE1mE,
+// LINUX: call void @_ZTHN1XIcE1mE()
+// LINUX: ret {{.*}}* @_ZN1XIcE1mE
 
 struct S { S(); ~S(); };
 struct T { ~T(); };
@@ -154,9 +241,6 @@
   static thread_local const S &u = S();
 }
 
-// LINUX: declare i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
-// DARWIN: declare i32 @_tlv_atexit(void (i8*)*, i8*, i8*)
-
 // CHECK: define {{.*}} @_Z7PR15991v(
 int PR15991() {
   thread_local int n;
@@ -184,7 +268,9 @@
 // LINUX-LABEL: define internal i32* @_ZTWN12_GLOBAL__N_16anon_iE()
 // DARWIN-LABEL: define internal cxx_fast_tlscc i32* @_ZTWN12_GLOBAL__N_16anon_iE()
 
-// CHECK: define {{.*}} @[[V_M_INIT:.*]]()
+// CHECK: define internal {{.*}} @[[V_M_INIT]]()
+// LINUX-SAME: comdat($_ZN1VIiE1mE)
+// DARWIN-NOT: comdat
 // CHECK: load i8, i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*)
 // CHECK: %[[V_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
 // CHECK: br i1 %[[V_M_INITIALIZED]],
@@ -194,6 +280,18 @@
 // CHECK: store i64 1, i64* @_ZGVN1VIiE1mE
 // CHECK: br label
 
+// CHECK: define internal {{.*}} @[[X_M_INIT]]()
+// LINUX-SAME: comdat($_ZN1XIiE1mE)
+// DARWIN-NOT: comdat
+// CHECK: load i8, i8* bitcast (i64* @_ZGVN1XIiE1mE to i8*)
+// CHECK: %[[X_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: br i1 %[[X_M_INITIALIZED]],
+// need init:
+// LINUX: call {{.*}}__cxa_thread_atexit
+// DARWIN: call {{.*}}_tlv_atexit
+// CHECK: store i64 1, i64* @_ZGVN1XIiE1mE
+// CHECK: br label
+
 // CHECK: define {{.*}}@[[GLOBAL_INIT:.*]]()
 // CHECK: call void @[[C_INIT]]()
 // CHECK: call void @[[E_INIT]]()
@@ -205,10 +303,13 @@
 // CHECK: br i1 %[[NEED_TLS_INIT]],
 // init:
 // CHECK: store i8 1, i8* @__tls_guard
+// CHECK-NOT: call void @[[V_M_INIT]]()
 // CHECK: call void @[[A_INIT]]()
+// CHECK-NOT: call void @[[V_M_INIT]]()
 // CHECK: call void @[[D_INIT]]()
+// CHECK-NOT: call void @[[V_M_INIT]]()
 // CHECK: call void @[[U_M_INIT]]()
-// CHECK: call void @[[V_M_INIT]]()
+// CHECK-NOT: call void @[[V_M_INIT]]()
 
 
 // LIUNX: define weak_odr hidden i32* @_ZTW1a() {
diff --git a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
index 8c0b8c2..bc77556 100644
--- a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
+++ b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-optzns %s -o - | FileCheck %s -check-prefix=CHECKA -check-prefix=CHECK
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -fcxx-exceptions %s -o - | FileCheck %s -check-prefix=CHECKB -check-prefix=CHECK
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-passes %s -o - | FileCheck %s -check-prefix=CHECKA -check-prefix=CHECK
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-passes -fcxx-exceptions %s -o - | FileCheck %s -check-prefix=CHECKB -check-prefix=CHECK
 // expected-no-diagnostics
 
 // The variable template specialization x<Foo> generated in each file
diff --git a/test/CodeGenCXX/debug-info-class-optzns.cpp b/test/CodeGenCXX/debug-info-class-optzns.cpp
new file mode 100644
index 0000000..d58510b
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-class-optzns.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited %s -O1 -o - | FileCheck %s
+
+// Ensure class definitions are not emitted to debug info just because the
+// vtable is emitted for optimization purposes (as available_externally). The
+// class definition debug info should only go where the vtable is actually
+// emitted into the object file.
+
+// CHECK: @_ZTV3foo = available_externally
+
+// Verify that this doesn't involve querying for the vtable of types that aren't
+// dynamic (that would cause an assertion in the case below)
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "bar<int>"
+template <typename> struct bar {};
+extern template struct bar<int>;
+bar<int> *p1;
+bar<int> a;
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
+// CHECK-SAME: DIFlagFwdDecl
+
+struct foo {
+  virtual void f();
+};
+
+foo f;
diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp
index d03c084..e06ef8d 100644
--- a/test/CodeGenCXX/debug-info-class.cpp
+++ b/test/CodeGenCXX/debug-info-class.cpp
@@ -83,12 +83,17 @@
   return 0;
 }
 
-// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions %s -o - | FileCheck %s
-// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions %s -o - | FileCheck %s
-// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
+// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
 
-// CHECK: invoke {{.+}} @_ZN1BD1Ev(%class.B* %b)
-// CHECK-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]]
+// CHECK98: invoke {{.+}} @_ZN1BD1Ev(%class.B* %b)
+// CHECK98-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]]
+// CHECK11: call {{.+}} @_ZN1BD1Ev(%class.B* %b){{.*}}, !dbg ![[EXCEPTLOC:.*]]
+
 // CHECK: store i32 0, i32* %{{.+}}, !dbg ![[RETLOC:.*]]
 
 // CHECK: [[F:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "F"
@@ -122,6 +127,7 @@
 // CHECK: [[C_DTOR]] = !DISubprogram(name: "~C"
 
 // CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D"
+// CHECK-NOT:              size:
 // CHECK-SAME:             DIFlagFwdDecl
 // CHECK-SAME:             identifier: "_ZTS1D"
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "E"
diff --git a/test/CodeGenCXX/debug-info-global.cpp b/test/CodeGenCXX/debug-info-global.cpp
index 7956023..5abc050 100644
--- a/test/CodeGenCXX/debug-info-global.cpp
+++ b/test/CodeGenCXX/debug-info-global.cpp
@@ -15,7 +15,8 @@
 
 // CHECK: [[GLOBALS]] = !{[[CNST:![0-9]*]]}
 
-// CHECK: [[CNST]] = distinct !DIGlobalVariable(name: "cnst",
-// CHECK-SAME:                                  scope: [[NS:![0-9]*]]
+// CHECK: [[CNST]] = !DIGlobalVariableExpression(var: [[CNSTV:.*]], expr:
+// CHECK: [[CNSTV]] = distinct !DIGlobalVariable(name: "cnst",
+// CHECK-SAME:                                   scope: [[NS:![0-9]*]]
 // CHECK: [[NS]] = !DINamespace(name: "ns"
 
diff --git a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
new file mode 100644
index 0000000..e3708e2
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -debug-info-kind=standalone -std=c++11 -triple x86_64-darwin -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+  A(int, ...);
+};
+struct B : A {
+  using A::A;
+};
+
+A::A(int i, ...) {}
+// CHECK: define void @{{.*}}foo
+// CHECK-NOT ret void
+// CHECK: call void @llvm.dbg.declare
+// CHECK-NOT ret void
+// CHECK: call void @llvm.dbg.declare(metadata %{{.*}}** %{{[^,]+}},
+// CHECK-SAME: metadata ![[THIS:[0-9]+]], metadata !{{[0-9]+}}), !dbg ![[LOC:[0-9]+]]
+// CHECK: ret void, !dbg ![[NOINL:[0-9]+]]
+// CHECK: ![[FOO:.*]] = distinct !DISubprogram(name: "foo"
+// CHECK-DAG: ![[A:.*]] = distinct !DISubprogram(name: "A", linkageName: "_ZN1BCI11AEiz"
+void foo() {
+// CHECK-DAG: ![[LOC]] = !DILocation(line: 0, scope: ![[A]], inlinedAt: ![[INL:[0-9]+]])
+// CHECK-DAG: ![[INL]] = !DILocation(line: [[@LINE+1]], scope: ![[FOO]])
+  B b(0);
+// CHECK: ![[NOINL]] = !DILocation(line: [[@LINE+1]], scope: !{{[0-9]+}})
+}
diff --git a/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp b/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp
new file mode 100644
index 0000000..f876267
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple i686--windows -emit-llvm -debug-info-kind=line-tables-only -x c++ %s -fms-extensions -o - | FileCheck %s
+
+struct __declspec(dllexport) S { virtual ~S(); };
+struct __declspec(dllexport) T { virtual ~T(); };
+struct __declspec(dllexport) U : S, T { virtual ~U(); };
+
+// CHECK-LABEL: define {{.*}} @"\01??_GS@@UAEPAXI@Z"
+// CHECK: call x86_thiscallcc void @"\01??_DS@@QAEXXZ"(%struct.S* %this1){{.*}}!dbg !{{[0-9]+}}
+
+// CHECK-LABEL: define {{.*}} @"\01??_GT@@UAEPAXI@Z"
+// CHECK: call x86_thiscallcc void @"\01??_DT@@QAEXXZ"(%struct.T* %this1){{.*}}!dbg !{{[0-9]+}}
+
+// CHECK-LABEL: define {{.*}} @"\01??_GU@@UAEPAXI@Z"
+// CHECK: call x86_thiscallcc void @"\01??_DU@@QAEXXZ"(%struct.U* %this1){{.*}}!dbg !{{[0-9]+}}
diff --git a/test/CodeGenCXX/debug-info-static-member.cpp b/test/CodeGenCXX/debug-info-static-member.cpp
index d28c2ac..c777ccb 100644
--- a/test/CodeGenCXX/debug-info-static-member.cpp
+++ b/test/CodeGenCXX/debug-info-static-member.cpp
@@ -32,7 +32,9 @@
 // why the definition of "a" comes before the declarations while
 // "b" and "c" come after.
 
-// CHECK: [[A]] = distinct !DIGlobalVariable(name: "a", {{.*}} declaration: ![[DECL_A:[0-9]+]])
+// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]])
+// CHECK: [[AV]] = distinct !DIGlobalVariable(name: "a",
+// CHECK-SAME:                                declaration: ![[DECL_A:[0-9]+]])
 //
 // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}, identifier: "_ZTS1X")
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct"
@@ -43,7 +45,9 @@
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var"
 
 int C::a = 4;
-// CHECK: [[B]] = distinct !DIGlobalVariable(name: "b", {{.*}} declaration: ![[DECL_B:[0-9]+]])
+// CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]])
+// CHECK: [[BV]] = distinct !DIGlobalVariable(name: "b",
+// CHECK-SAME:                                declaration: ![[DECL_B:[0-9]+]])
 // CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
 // CHECK-NOT:                                 size:
 // CHECK-NOT:                                 align:
@@ -89,7 +93,8 @@
 // CHECK-SAME:           flags: DIFlagPublic | DIFlagStaticMember)
 
 int C::b = 2;
-// CHECK: [[C]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]])
+// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]])
+// CHECK: [[CV]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]])
 int C::c = 1;
 
 int main()
diff --git a/test/CodeGenCXX/debug-info-template-deduction-guide.cpp b/test/CodeGenCXX/debug-info-template-deduction-guide.cpp
new file mode 100644
index 0000000..26eb215
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-template-deduction-guide.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++1z | FileCheck %s
+
+// Verify that we don't crash when emitting debug information for objects
+// created from a deduced template specialization.
+
+template <class T>
+struct S {
+  S(T) {}
+};
+
+// CHECK: !DIGlobalVariable(name: "s1"
+// CHECK-SAME: type: [[TYPE_NUM:![0-9]+]]
+// CHECK: !DIGlobalVariable(name: "s2"
+// CHECK-SAME: type: [[TYPE_NUM]]
+// CHECK: [[TYPE_NUM]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S<int>",
+S s1(42);
+S<int> s2(42);
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index 749b92e..2b84074 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -19,8 +19,9 @@
 }
 
 // The compile unit pulls in the global variables first.
-// CHECK: [[X]] = distinct !DIGlobalVariable(name: "x",
-// CHECK-SAME:              type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]])
+// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x",
+// CHECK-SAME:                                type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
 
 // CHECK: ![[OUTER_FOO_INNER_ID:[0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier:
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp
index d4a7112..54fac0b 100644
--- a/test/CodeGenCXX/debug-info-template.cpp
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -25,8 +25,9 @@
 int glb;
 void func();
 
-// CHECK: [[TCI]] = distinct !DIGlobalVariable(name: "tci",
-// CHECK-SAME:              type: ![[TCNESTED:[0-9]+]]
+// CHECK: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]])
+// CHECK: [[TCIV]] = distinct !DIGlobalVariable(name: "tci",
+// CHECK-SAME:                                  type: ![[TCNESTED:[0-9]+]]
 // CHECK: ![[TCNESTED]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "nested",
 // CHECK-SAME:             scope: ![[TC:[0-9]+]],
 
@@ -83,8 +84,9 @@
 // CHECK: [[TCARG7_3]] = !DITemplateValueParameter(type: [[INT]], value: i32 3)
   3>::nested tci;
 
-// CHECK: [[TCN]] = distinct !DIGlobalVariable(name: "tcn"
-// CHECK-SAME:              type: ![[TCNT:[0-9]+]]
+// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]])
+// CHECK: [[TCNV]] = distinct !DIGlobalVariable(name: "tcn"
+// CHECK-SAME:                                  type: ![[TCNT:[0-9]+]]
 TC
 // CHECK: ![[TCNT]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "TC<int, -3, nullptr, nullptr, nullptr, nullptr>"
 // CHECK-SAME:             templateParams: [[TCNARGS:![0-9]*]]
@@ -123,8 +125,9 @@
 struct NN {
 };
 
-// CHECK: [[NN]] = distinct !DIGlobalVariable(name: "nn"
-// CHECK-SAME:              type: ![[NNT:[0-9]+]]
+// CHECK: [[NN]] = !DIGlobalVariableExpression(var: [[NNV:.*]])
+// CHECK: [[NNV]] = distinct !DIGlobalVariable(name: "nn"
+// CHECK-SAME:                                 type: ![[NNT:[0-9]+]]
 
 // FIXME: these parameters should probably be rendered as 'glb' rather than
 // '&glb', since they're references, not pointers.
diff --git a/test/CodeGenCXX/debug-info-use-after-free.cpp b/test/CodeGenCXX/debug-info-use-after-free.cpp
index f87763b..1001248 100644
--- a/test/CodeGenCXX/debug-info-use-after-free.cpp
+++ b/test/CodeGenCXX/debug-info-use-after-free.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple -emit-llvm-only %s
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple -emit-llvm-only -std=c++98 %s
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple -emit-llvm-only -std=c++11 %s
 // Check that we don't crash.
 // PR12305, PR12315
 
@@ -233,6 +235,7 @@
 namespace {
 class
     AAA {
+protected:
       virtual ~
           AAA () {
           }};
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 722b9c0..9575a51 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -8,8 +8,9 @@
 
 // !llvm.dbg.cu pulls in globals and their types first.
 // CHECK-NOT: !DIGlobalVariable(name: "c"
-// CHECK: [[X]] = distinct !DIGlobalVariable(name: "x", linkageName: "_ZN6pr96081xE"
-// CHECK-SAME:              type: [[INCARRAYPTR:![0-9]*]]
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:!.*]])
+// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x", linkageName: "_ZN6pr96081xE"
+// CHECK-SAME:                                type: [[INCARRAYPTR:![0-9]*]]
 // CHECK: [[INCARRAYPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[INCARRAY:![0-9]+]]
 // CHECK: [[INCARRAY]] = !DICompositeType(tag: DW_TAG_array_type
 // CHECK-NOT:                             line:
diff --git a/test/CodeGenCXX/derived-to-base.cpp b/test/CodeGenCXX/derived-to-base.cpp
index c69b456..3bd5e35 100644
--- a/test/CodeGenCXX/derived-to-base.cpp
+++ b/test/CodeGenCXX/derived-to-base.cpp
@@ -46,4 +46,4 @@
   }
 }
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index d6aabee..b082908 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -1,11 +1,16 @@
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions -O1 -disable-llvm-optzns > %t
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions -O1 -disable-llvm-passes -std=c++03 > %t
 // RUN: FileCheck --check-prefix=CHECK1 --input-file=%t %s
 // RUN: FileCheck --check-prefix=CHECK2 --input-file=%t %s
 // RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s
-// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t %s
-// RUN: FileCheck --check-prefix=CHECK5 --input-file=%t %s
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -O1 -disable-llvm-optzns -std=c++11 > %t2
-// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t2 %s
+// RUN: FileCheck --check-prefixes=CHECK4,CHECK4v03 --input-file=%t %s
+// RUN: FileCheck --check-prefixes=CHECK5,CHECK5v03 --input-file=%t %s
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions -O1 -disable-llvm-passes -std=c++11 > %t2
+// RUN: FileCheck --check-prefix=CHECK1    --input-file=%t2 %s
+// RUN: FileCheck --check-prefix=CHECK2v11 --input-file=%t2 %s
+// RUN: FileCheck --check-prefix=CHECK3    --input-file=%t2 %s
+// RUN: FileCheck --check-prefixes=CHECK4,CHECK4v11 --input-file=%t2 %s
+// RUN: FileCheck --check-prefixes=CHECK5,CHECK5v11 --input-file=%t2 %s
+// RUN: FileCheck --check-prefix=CHECK6    --input-file=%t2 %s
 // REQUIRES: asserts
 
 struct A {
@@ -98,6 +103,12 @@
 // CHECK2: invoke void @_ZN5test04BaseD2Ev
 // CHECK2:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
 
+// In C++11, the destructors are often known not to throw.
+// CHECK2v11-LABEL: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
+// CHECK2v11-LABEL: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr
+// CHECK2v11: call void @_ZN5test06MemberD1Ev
+// CHECK2v11: call void @_ZN5test04BaseD2Ev
+
   struct B : Base, virtual VBase {
     Member M;
     ~B();
@@ -111,6 +122,10 @@
 // CHECK2: invoke void @_ZN5test04BaseD2Ev
 // CHECK2:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
 
+// CHECK2v11-LABEL: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr
+// CHECK2v11: call void @_ZN5test06MemberD1Ev
+// CHECK2v11: call void @_ZN5test04BaseD2Ev
+
 // CHECK2-LABEL: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr
 // CHECK2: invoke void @_ZN5test06MemberD1Ev
 // CHECK2:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
@@ -118,6 +133,11 @@
 // CHECK2:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
 // CHECK2: invoke void @_ZN5test05VBaseD2Ev
 // CHECK2:   unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]]
+
+// CHECK2v11-LABEL: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr
+// CHECK2v11: call void @_ZN5test06MemberD1Ev
+// CHECK2v11: call void @_ZN5test04BaseD2Ev
+// CHECK2v11: call void @_ZN5test05VBaseD2Ev
 }
 
 // Test base-class aliasing.
@@ -189,19 +209,22 @@
   }
 
   // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
-  // CHECK4: invoke void @_ZN5test31BD2Ev(
+  // CHECK4v03: invoke void @_ZN5test31BD2Ev(
+  // CHECK4v11: call   void @_ZN5test31BD2Ev(
   // CHECK4: call void @_ZN5test31AD2Ev(
   // CHECK4: ret void
 
   // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::(anonymous namespace)::D"* %this) unnamed_addr
-  // CHECK4-SAME:  personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
-  // CHECK4: invoke void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+  // CHECK4v03-SAME:  personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+  // CHECK4v03: invoke void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+  // CHECK4v11: call   void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
   // CHECK4: call void @_ZdlPv({{.*}}) [[NUW:#[0-9]+]]
   // CHECK4: ret void
-  // CHECK4: landingpad { i8*, i32 }
-  // CHECK4-NEXT: cleanup
-  // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]]
-  // CHECK4: resume { i8*, i32 }
+  // CHECK4v03: landingpad { i8*, i32 }
+  // CHECK4v03-NEXT: cleanup
+  // CHECK4v03: call void @_ZdlPv({{.*}}) [[NUW]]
+  // CHECK4v03: resume { i8*, i32 }
+  // CHECK4v11-NOT: landingpad
 
   // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD1Ev(
   // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8
@@ -214,14 +237,15 @@
   // CHECK4: ret void
 
   // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
-  // CHECK4-SAME:  personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
-  // CHECK4: invoke void @_ZN5test312_GLOBAL__N_11CD2Ev(
+  // CHECK4v03-SAME:  personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+  // CHECK4v03: invoke void @_ZN5test312_GLOBAL__N_11CD2Ev(
+  // CHECK4v11: call   void @_ZN5test312_GLOBAL__N_11CD2Ev(
   // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]]
   // CHECK4: ret void
-  // CHECK4: landingpad { i8*, i32 }
-  // CHECK4-NEXT: cleanup
-  // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]]
-  // CHECK4: resume { i8*, i32 }
+  // CHECK4v03: landingpad { i8*, i32 }
+  // CHECK4v03-NEXT: cleanup
+  // CHECK4v03: call void @_ZdlPv({{.*}}) [[NUW]]
+  // CHECK4v03: resume { i8*, i32 }
 
   // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev(
   // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8
@@ -282,8 +306,8 @@
 
   // CHECK5-LABEL: define void @_ZN5test53fooEv()
   // CHECK5:      [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align
-  // CHECK5-NEXT: [[EXN:%.*]] = alloca i8*
-  // CHECK5-NEXT: [[SEL:%.*]] = alloca i32
+  // CHECK5v03-NEXT: [[EXN:%.*]] = alloca i8*
+  // CHECK5v03-NEXT: [[SEL:%.*]] = alloca i32
   // CHECK5-NEXT: [[PELEMS:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to i8*
   // CHECK5-NEXT: call void @llvm.lifetime.start(i64 5, i8* [[PELEMS]])
   // CHECK5-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]], [5 x [[A]]]* [[ELEMS]], i32 0, i32 0
@@ -291,19 +315,22 @@
   // CHECK5-NEXT: br label
   // CHECK5:      [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
   // CHECK5-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[POST]], i64 -1
-  // CHECK5-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]])
+  // CHECK5v03-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]])
+  // CHECK5v11-NEXT: call   void @_ZN5test51AD1Ev([[A]]* [[ELT]])
   // CHECK5:      [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]]
   // CHECK5-NEXT: br i1 [[T0]],
   // CHECK5:      call void @llvm.lifetime.end
   // CHECK5-NEXT: ret void
   // lpad
-  // CHECK5:      [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]]
-  // CHECK5-NEXT: br i1 [[EMPTY]]
-  // CHECK5:      [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
-  // CHECK5-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
-  // CHECK5-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]])
-  // CHECK5:      [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
-  // CHECK5-NEXT: br i1 [[DONE]],
+  // CHECK5v03:      [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]]
+  // CHECK5v03-NEXT: br i1 [[EMPTY]]
+  // CHECK5v03:      [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+  // CHECK5v03-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
+  // CHECK5v03-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]])
+  // CHECK5v03:      [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+  // CHECK5v03-NEXT: br i1 [[DONE]],
+  // CHECK5v11-NOT: landingpad
+  // CHECK5v11:   }
   void foo() {
     A elems[5];
   }
@@ -334,25 +361,34 @@
   C::~C() { opaque(); }
   // CHECK5-LABEL: define void @_ZN5test61CD2Ev(%"struct.test6::C"* %this, i8** %vtt) unnamed_addr
   // CHECK5:   invoke void @_ZN5test66opaqueEv
-  // CHECK5:   invoke void @_ZN5test61AD1Ev
-  // CHECK5:   invoke void @_ZN5test61AD1Ev
-  // CHECK5:   invoke void @_ZN5test61AD1Ev
-  // CHECK5:   invoke void @_ZN5test61BILj1EED2Ev
+  // CHECK5v03:   invoke void @_ZN5test61AD1Ev
+  // CHECK5v03:   invoke void @_ZN5test61AD1Ev
+  // CHECK5v03:   invoke void @_ZN5test61AD1Ev
+  // CHECK5v03:   invoke void @_ZN5test61BILj1EED2Ev
+  // CHECK5v11:   call   void @_ZN5test61AD1Ev
+  // CHECK5v11:   call   void @_ZN5test61AD1Ev
+  // CHECK5v11:   call   void @_ZN5test61AD1Ev
+  // CHECK5v11:   call   void @_ZN5test61BILj1EED2Ev
   // CHECK5:   call void @_ZN5test61BILj0EED2Ev
   // CHECK5:   ret void
-  // CHECK5:   invoke void @_ZN5test61AD1Ev
-  // CHECK5:   invoke void @_ZN5test61AD1Ev
-  // CHECK5:   invoke void @_ZN5test61AD1Ev
-  // CHECK5:   invoke void @_ZN5test61BILj1EED2Ev
-  // CHECK5:   invoke void @_ZN5test61BILj0EED2Ev
+  // CHECK5v03:   invoke void @_ZN5test61AD1Ev
+  // CHECK5v03:   invoke void @_ZN5test61AD1Ev
+  // CHECK5v03:   invoke void @_ZN5test61AD1Ev
+  // CHECK5v03:   invoke void @_ZN5test61BILj1EED2Ev
+  // CHECK5v03:   invoke void @_ZN5test61BILj0EED2Ev
 
   // CHECK5-LABEL: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr
-  // CHECK5:   invoke void @_ZN5test61CD2Ev
-  // CHECK5:   invoke void @_ZN5test61BILj3EED2Ev
-  // CHECK5:   call void @_ZN5test61BILj2EED2Ev
-  // CHECK5:   ret void
-  // CHECK5:   invoke void @_ZN5test61BILj3EED2Ev
-  // CHECK5:   invoke void @_ZN5test61BILj2EED2Ev
+  // CHECK5v03:   invoke void @_ZN5test61CD2Ev
+  // CHECK5v03:   invoke void @_ZN5test61BILj3EED2Ev
+  // CHECK5v03:   call void @_ZN5test61BILj2EED2Ev
+  // CHECK5v03:   ret void
+  // CHECK5v03:   invoke void @_ZN5test61BILj3EED2Ev
+  // CHECK5v03:   invoke void @_ZN5test61BILj2EED2Ev
+
+  // CHECK5v11:   call void @_ZN5test61CD2Ev
+  // CHECK5v11:   call void @_ZN5test61BILj3EED2Ev
+  // CHECK5v11:   call void @_ZN5test61BILj2EED2Ev
+  // CHECK5v11:   ret void
 }
 
 // PR 9197
@@ -369,7 +405,8 @@
 
   // Verify that this doesn't get emitted as an alias
   // CHECK5-LABEL: define void @_ZN5test71BD2Ev(
-  // CHECK5:   invoke void @_ZN5test71DD1Ev(
+  // CHECK5v03:   invoke void @_ZN5test71DD1Ev(
+  // CHECK5v11:   call   void @_ZN5test71DD1Ev(
   // CHECK5:   call void @_ZN5test71AD2Ev(
   B::~B() {}
 }
@@ -394,7 +431,8 @@
   // CHECK5:      call void @_ZN5test81AC1Ev([[A]]* [[X]])
   // CHECK5-NEXT: br label
   // CHECK5:      invoke void @_ZN5test81AC1Ev([[A]]* [[Y]])
-  // CHECK5:      invoke void @_ZN5test81AD1Ev([[A]]* [[Y]])
+  // CHECK5v03:   invoke void @_ZN5test81AD1Ev([[A]]* [[Y]])
+  // CHECK5v11:   call   void @_ZN5test81AD1Ev([[A]]* [[Y]])
   // CHECK5-NOT:  switch
   // CHECK5:      invoke void @_ZN5test83dieEv()
   // CHECK5:      unreachable
diff --git a/test/CodeGenCXX/dllexport-ctor-closure.cpp b/test/CodeGenCXX/dllexport-ctor-closure.cpp
new file mode 100644
index 0000000..4fae7e1
--- /dev/null
+++ b/test/CodeGenCXX/dllexport-ctor-closure.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++14 \
+// RUN:    -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases \
+// RUN:    -disable-llvm-passes -o - %s -w -fms-compatibility-version=19.00 | \
+// RUN:    FileCheck %s
+
+struct CtorWithClosure {
+  __declspec(dllexport) CtorWithClosure(...) {}
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK:   %[[this_addr:.*]] = alloca %struct.CtorWithClosure*, align 4
+// CHECK:   store %struct.CtorWithClosure* %this, %struct.CtorWithClosure** %[[this_addr]], align 4
+// CHECK:   %[[this:.*]] = load %struct.CtorWithClosure*, %struct.CtorWithClosure** %[[this_addr]]
+// CHECK:   call %struct.CtorWithClosure* (%struct.CtorWithClosure*, ...) @"\01??0CtorWithClosure@@QAA@ZZ"(%struct.CtorWithClosure* %[[this]])
+// CHECK:   ret void
+};
+
+struct CtorWithClosureOutOfLine {
+  __declspec(dllexport) CtorWithClosureOutOfLine(...);
+};
+CtorWithClosureOutOfLine::CtorWithClosureOutOfLine(...) {}
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosureOutOfLine@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+
+#define DELETE_IMPLICIT_MEMBERS(ClassName) \
+    ClassName(ClassName &&) = delete; \
+    ClassName(ClassName &) = delete; \
+    ~ClassName() = delete; \
+    ClassName &operator=(ClassName &) = delete
+
+struct __declspec(dllexport) ClassWithClosure {
+  DELETE_IMPLICIT_MEMBERS(ClassWithClosure);
+  ClassWithClosure(...) {}
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FClassWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK:   %[[this_addr:.*]] = alloca %struct.ClassWithClosure*, align 4
+// CHECK:   store %struct.ClassWithClosure* %this, %struct.ClassWithClosure** %[[this_addr]], align 4
+// CHECK:   %[[this:.*]] = load %struct.ClassWithClosure*, %struct.ClassWithClosure** %[[this_addr]]
+// CHECK:   call %struct.ClassWithClosure* (%struct.ClassWithClosure*, ...) @"\01??0ClassWithClosure@@QAA@ZZ"(%struct.ClassWithClosure* %[[this]])
+// CHECK:   ret void
+};
+
+template <typename T> struct TemplateWithClosure {
+  TemplateWithClosure(int x = sizeof(T)) {}
+};
+extern template struct TemplateWithClosure<char>;
+template struct __declspec(dllexport) TemplateWithClosure<char>;
+extern template struct TemplateWithClosure<int>;
+template struct __declspec(dllexport) TemplateWithClosure<int>;
+
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$TemplateWithClosure@D@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK:   call {{.*}} @"\01??0?$TemplateWithClosure@D@@QAE@H@Z"({{.*}}, i32 1)
+
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$TemplateWithClosure@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK:   call {{.*}} @"\01??0?$TemplateWithClosure@H@@QAE@H@Z"({{.*}}, i32 4)
+
+struct __declspec(dllexport) NestedOuter {
+  DELETE_IMPLICIT_MEMBERS(NestedOuter);
+  NestedOuter(void *p = 0) {}
+  struct __declspec(dllexport) NestedInner {
+    DELETE_IMPLICIT_MEMBERS(NestedInner);
+    NestedInner(void *p = 0) {}
+  };
+};
+
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+
+struct HasDtor {
+  ~HasDtor();
+  int o;
+};
+struct HasImplicitDtor1 { HasDtor o; };
+struct HasImplicitDtor2 { HasDtor o; };
+struct __declspec(dllexport) CtorClosureInline {
+  CtorClosureInline(const HasImplicitDtor1 &v = {}) {}
+};
+struct __declspec(dllexport) CtorClosureOutOfLine {
+  CtorClosureOutOfLine(const HasImplicitDtor2 &v = {});
+};
+CtorClosureOutOfLine::CtorClosureOutOfLine(const HasImplicitDtor2 &v) {}
+
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorClosureInline@@QAEXXZ"
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??1HasImplicitDtor1@@QAE@XZ"
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorClosureOutOfLine@@QAEXXZ"
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??1HasImplicitDtor2@@QAE@XZ"
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
index bf699eb..33e524c 100644
--- a/test/CodeGenCXX/dllexport.cpp
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w -fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2015 -check-prefix=M32MSVC2015 %s
-// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w -fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2013 -check-prefix=M32MSVC2013 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-passes -o - %s -w -fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2015 -check-prefix=M32MSVC2015 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-passes -o - %s -w -fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2013 -check-prefix=M32MSVC2013 %s
 
 // RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2015 -check-prefix=M64MSVC2015 %s
 // RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2013 -check-prefix=M64MSVC2013 %s
@@ -488,45 +488,6 @@
   };
 };
 
-struct CtorWithClosure {
-  __declspec(dllexport) CtorWithClosure(...) {}
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
-// M32-DAG:   %[[this_addr:.*]] = alloca %struct.CtorWithClosure*, align 4
-// M32-DAG:   store %struct.CtorWithClosure* %this, %struct.CtorWithClosure** %[[this_addr]], align 4
-// M32-DAG:   %[[this:.*]] = load %struct.CtorWithClosure*, %struct.CtorWithClosure** %[[this_addr]]
-// M32-DAG:   call %struct.CtorWithClosure* (%struct.CtorWithClosure*, ...) @"\01??0CtorWithClosure@@QAA@ZZ"(%struct.CtorWithClosure* %[[this]])
-// M32-DAG:   ret void
-};
-
-#define DELETE_IMPLICIT_MEMBERS(ClassName) \
-    ClassName(ClassName &&) = delete; \
-    ClassName(ClassName &) = delete; \
-    ~ClassName() = delete; \
-    ClassName &operator=(ClassName &) = delete
-
-struct __declspec(dllexport) ClassWithClosure {
-  DELETE_IMPLICIT_MEMBERS(ClassWithClosure);
-  ClassWithClosure(...) {}
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FClassWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
-// M32-DAG:   %[[this_addr:.*]] = alloca %struct.ClassWithClosure*, align 4
-// M32-DAG:   store %struct.ClassWithClosure* %this, %struct.ClassWithClosure** %[[this_addr]], align 4
-// M32-DAG:   %[[this:.*]] = load %struct.ClassWithClosure*, %struct.ClassWithClosure** %[[this_addr]]
-// M32-DAG:   call %struct.ClassWithClosure* (%struct.ClassWithClosure*, ...) @"\01??0ClassWithClosure@@QAA@ZZ"(%struct.ClassWithClosure* %[[this]])
-// M32-DAG:   ret void
-};
-
-struct __declspec(dllexport) NestedOuter {
-  DELETE_IMPLICIT_MEMBERS(NestedOuter);
-  NestedOuter(void *p = 0) {}
-  struct __declspec(dllexport) NestedInner {
-    DELETE_IMPLICIT_MEMBERS(NestedInner);
-    NestedInner(void *p = 0) {}
-  };
-};
-
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
-
 template <typename T>
 struct SomeTemplate {
   SomeTemplate(T o = T()) : o(o) {}
@@ -612,9 +573,9 @@
 // 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 i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[W_VTABLE]], i32 0, i32 1)
-// G32-DAG: @_ZTV1W = dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
+// M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant { [2 x i8*] } { [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 i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[W_VTABLE]], i32 0, i32 0, i32 1)
+// G32-DAG: @_ZTV1W = dllexport unnamed_addr constant { [3 x i8*] } { [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:
@@ -771,13 +732,27 @@
 // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAE@XZ"
 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclExportedDefTemplateIiE1fEv
 
-template <typename T> struct ImplicitInstantiationExplicitInstantiationDefExportedTemplate { void f() {} };
+template <typename T> struct ImplicitInstantiationExportedExplicitInstantiationDefTemplate { virtual void f() {} };
+ImplicitInstantiationExportedExplicitInstantiationDefTemplate<int> ImplicitInstantiationExportedExplicitInstantiationDefTemplateInstance;
+template struct __declspec(dllexport) ImplicitInstantiationExportedExplicitInstantiationDefTemplate<int>;
+USEMEMFUNC(ImplicitInstantiationExportedExplicitInstantiationDefTemplate<int>, f);
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExportedExplicitInstantiationDefTemplate@H@@UAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN61ImplicitInstantiationExportedExplicitInstantiationDefTemplateIiE1fEv
+
+template <typename T> struct __declspec(dllexport) ImplicitInstantiationExplicitInstantiationDefExportedTemplate { virtual void f() {} };
 ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int> ImplicitInstantiationExplicitInstantiationDefExportedTemplateInstance;
-template class __declspec(dllexport) ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>;
+template struct ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>;
 USEMEMFUNC(ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>, f);
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExplicitInstantiationDefExportedTemplate@H@@QAEXXZ"
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExplicitInstantiationDefExportedTemplate@H@@UAEXXZ"
 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN61ImplicitInstantiationExplicitInstantiationDefExportedTemplateIiE1fEv
 
+template <typename T> struct __declspec(dllexport) ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate { virtual void f() {} };
+ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate<int> ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplateInstance;
+template struct __declspec(dllexport) ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate<int>;
+USEMEMFUNC(ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate<int>, f);
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate@H@@UAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN69ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplateIiE1fEv
+
 namespace { struct InternalLinkageType {}; }
 struct __declspec(dllexport) PR23308 {
   void f(InternalLinkageType*);
diff --git a/test/CodeGenCXX/dllimport-rtti.cpp b/test/CodeGenCXX/dllimport-rtti.cpp
index 4baee50..91e747a 100644
--- a/test/CodeGenCXX/dllimport-rtti.cpp
+++ b/test/CodeGenCXX/dllimport-rtti.cpp
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=MSVC
-// RUN: %clang_cc1 -triple i686-windows-gnu  -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=GNU
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple i686-windows-gnu  -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=GNU
 
 struct __declspec(dllimport) S {
   virtual void f() {}
 } s;
-// MSVC: [[VF_S:.*]] = private unnamed_addr constant [2 x i8*]
-// MSVC-DAG: @"\01??_SS@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VF_S]], i32 0, i32 1)
+// MSVC: [[VF_S:.*]] = private unnamed_addr constant { [2 x i8*] }
+// MSVC-DAG: @"\01??_SS@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VF_S]], i32 0, i32 0, i32 1)
 // MSVC-DAG: @"\01??_R0?AUS@@@8" = linkonce_odr
 // MSVC-DAG: @"\01??_R1A@?0A@EA@S@@8" = linkonce_odr
 // MSVC-DAG: @"\01??_R2S@@8" = linkonce_odr
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp
index ec5c68a..372a96b 100644
--- a/test/CodeGenCXX/dllimport.cpp
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -2,8 +2,8 @@
 // RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s
 // RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s         -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s
 // RUN: %clang_cc1 -triple x86_64-windows-gnu  -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s         -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s
-// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s
-// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s
 // RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O1 -o - %s         -w | FileCheck --check-prefix=GO1 %s
 
 // CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
@@ -26,6 +26,7 @@
 #define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
 #define USEVAR(var) USEVARTYPE(int, var)
 #define USE(func) void UNIQ(use)() { func(); }
+#define USE1(func) void UNIQ(use)() { func(nullptr); }
 #define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
 #define USESTATICMEMFUNC(class, func) void (*UNIQ(use)())() { return &class::func; }
 #define USECLASS(class) void UNIQ(USE)() { class x; }
@@ -316,10 +317,13 @@
 USE(ns::externalFunc)
 
 // A dllimport function referencing non-imported vars or functions must not be available_externally.
+
 __declspec(dllimport) int ImportedVar;
 int NonImportedVar;
 __declspec(dllimport) int ImportedFunc();
 int NonImportedFunc();
+struct ClassWithNonImportedMethod { int f(); };
+
 __declspec(dllimport) inline int ReferencingImportedVar() { return ImportedVar; }
 // MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingImportedVar@@YAHXZ"
 __declspec(dllimport) inline int ReferencingNonImportedVar() { return NonImportedVar; }
@@ -328,10 +332,16 @@
 // MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingImportedFunc@@YAHXZ"
 __declspec(dllimport) inline int ReferencingNonImportedFunc() { return NonImportedFunc(); }
 // MO1-DAG: declare dllimport i32 @"\01?ReferencingNonImportedFunc@@YAHXZ"()
+__declspec(dllimport) inline int ReferencingNonImportedMethod(ClassWithNonImportedMethod *x) { return x->f(); }
+// MO1-DAG: declare dllimport i32 @"\01?ReferencingNonImportedMethod
+__declspec(dllimport) inline int ReferencingClassMemberPtr(int (ClassWithNonImportedMethod::*p)(), ClassWithNonImportedMethod *x) { return (x->*p)(); }
+// MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingClassMemberPtr@@YAHP8ClassWithNonImportedMethod@@AEHXZPAU1@@Z"
 USE(ReferencingImportedVar)
 USE(ReferencingNonImportedVar)
 USE(ReferencingImportedFunc)
 USE(ReferencingNonImportedFunc)
+USE1(ReferencingNonImportedMethod)
+void UNIQ(use)() { ReferencingClassMemberPtr(&ClassWithNonImportedMethod::f, nullptr); }
 // References to operator new and delete count too, despite not being DeclRefExprs.
 __declspec(dllimport) inline int *ReferencingNonImportedNew() { return new int[2]; }
 // MO1-DAG: declare dllimport i32* @"\01?ReferencingNonImportedNew@@YAPAHXZ"
@@ -348,7 +358,7 @@
 USE(ReferencingImportedNew)
 USE(ReferencingImportedDelete)
 struct ClassWithDtor { ~ClassWithDtor() {} };
-struct __declspec(dllimport) ClassWithNonDllImportField { ClassWithDtor t; };
+struct __declspec(dllimport) ClassWithNonDllImportField { using X = ClassWithDtor; X t[2]; };
 struct __declspec(dllimport) ClassWithNonDllImportBase : public ClassWithDtor { };
 USECLASS(ClassWithNonDllImportField);
 USECLASS(ClassWithNonDllImportBase);
@@ -358,6 +368,13 @@
 struct __declspec(dllimport) ClassWithNonDllImportFieldWithCtor { ClassWithCtor t; };
 USECLASS(ClassWithNonDllImportFieldWithCtor);
 // MO1-DAG: declare dllimport x86_thiscallcc %struct.ClassWithNonDllImportFieldWithCtor* @"\01??0ClassWithNonDllImportFieldWithCtor@@QAE@XZ"(%struct.ClassWithNonDllImportFieldWithCtor* returned)
+struct ClassWithImplicitDtor { __declspec(dllimport) ClassWithImplicitDtor(); ClassWithDtor member; };
+__declspec(dllimport) inline void ReferencingDtorThroughDefinition() { ClassWithImplicitDtor x; };
+USE(ReferencingDtorThroughDefinition)
+// MO1-DAG: declare dllimport void @"\01?ReferencingDtorThroughDefinition@@YAXXZ"()
+__declspec(dllimport) inline void ReferencingDtorThroughTemporary() { ClassWithImplicitDtor(); };
+USE(ReferencingDtorThroughTemporary)
+// MO1-DAG: declare dllimport void @"\01?ReferencingDtorThroughTemporary@@YAXXZ"()
 
 // A dllimport function with a TLS variable must not be available_externally.
 __declspec(dllimport) inline void FunctionWithTLSVar() { static __thread int x = 42; }
@@ -395,17 +412,17 @@
 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
 USE(inlineFuncTmpl2<ImplicitInst_Imported>)
 
-// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// MSC-DAG: define linkonce_odr void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
 // GNU-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
-// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// MO1-DAG: define linkonce_odr void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
 // GO1-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
 template<typename T>                              void inlineFuncTmplDecl() {}
 USE(inlineFuncTmplDecl<ImplicitInst_Imported>)
 
-// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
+// MSC-DAG: define linkonce_odr void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
 // GNU-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
-// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
+// MO1-DAG: define linkonce_odr void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
 // GO1-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
 template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
 template<typename T>                inline void inlineFuncTmplDef() {}
@@ -439,7 +456,7 @@
 // GNU-DAG: declare             void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv()
 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"()
 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv()
-// MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"()
+// MSC-DAG: define linkonce_odr void @"\01??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"()
 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()
 struct FuncTmplFriend {
   template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
@@ -631,15 +648,15 @@
 struct __declspec(dllimport) W { virtual void foo() {} };
 USECLASS(W)
 // vftable:
-// MO1-DAG: @"\01??_SW@@6B@" = linkonce_odr 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*)]
+// MO1-DAG: @"\01??_SW@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [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*] } { [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] }
 
 struct __declspec(dllimport) KeyFuncClass {
   constexpr KeyFuncClass() {}
   virtual void foo();
 };
 extern constexpr KeyFuncClass keyFuncClassVar = {};
-// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
+// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x i8*] }
 
 struct __declspec(dllimport) X : public virtual W {};
 USECLASS(X)
@@ -745,7 +762,7 @@
   // S::~S is a key function, so we would ordinarily emit a strong definition for
   // the vtable. However, S is imported, so the vtable should be too.
 
-  // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant [4 x i8*]
+  // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant { [4 x i8*] }
 }
 
 namespace PR21366 {
@@ -767,7 +784,7 @@
   };
   extern template struct __declspec(dllimport) A<int>;
   void f() { new A<int>(); }
-  // MO1-DAG: @"\01??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*]
+  // MO1-DAG: @"\01??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] }
 }
 
 // MS ignores DLL attributes on partial specializations.
diff --git a/test/CodeGenCXX/dynamic-cast-hint.cpp b/test/CodeGenCXX/dynamic-cast-hint.cpp
index 27b76e0..f88d39d 100644
--- a/test/CodeGenCXX/dynamic-cast-hint.cpp
+++ b/test/CodeGenCXX/dynamic-cast-hint.cpp
@@ -1,7 +1,9 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -std=c++98 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -std=c++11 -o - %s | FileCheck %s
 
-class A { virtual ~A() {} };
-class B { virtual ~B() {} };
+class A { protected: virtual ~A() {} };
+class B { protected: virtual ~B() {} };
 
 class C : A { char x; };
 class D : public A { short y; };
diff --git a/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp b/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp
index 29fb556..9f0f36c 100644
--- a/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp
+++ b/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp
@@ -1,7 +1,8 @@
 // Check that in case of copying an array of memcpy-able objects, their
 // destructors will be called if an exception is thrown.
 //
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -std=c++98 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -std=c++11 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
 
 struct ImplicitCopy {
   int x;
@@ -25,7 +26,8 @@
     // CHECK_LABEL: main
     // CHECK-NOT: call void @_ZN9ThrowCopyC1ERKS_
     // CHECK: invoke void @_ZN9ThrowCopyC1ERKS_
-    // CHECK: invoke void @_ZN12ImplicitCopyD1Ev
+    // CHECK98: invoke void @_ZN12ImplicitCopyD1Ev
+    // CHECK11: call void @_ZN12ImplicitCopyD1Ev
     Container c2(c1);
   }
   catch (...) {
diff --git a/test/CodeGenCXX/exceptions-cxx-new.cpp b/test/CodeGenCXX/exceptions-cxx-new.cpp
index 3329aea..9836da8 100644
--- a/test/CodeGenCXX/exceptions-cxx-new.cpp
+++ b/test/CodeGenCXX/exceptions-cxx-new.cpp
@@ -55,12 +55,12 @@
 // CHECK:           to label %[[LEAVE_FUNC:.*]] unwind label %[[CLEANUP:.*]]
 
 // CHECK: [[LEAVE_FUNC]]
-// CHECK:   call x86_thiscallcc void @"\01??_DCleanup@@QAE@XZ"(
+// CHECK:   call x86_thiscallcc void @"\01??_DCleanup@@QAEXXZ"(
 // CHECK:   ret void
 
 // CHECK: [[CLEANUP]]
 // CHECK:   %[[CLEANUPPAD:.*]] = cleanuppad within none []
-// CHECK:   call x86_thiscallcc void @"\01??_DCleanup@@QAE@XZ"(
+// CHECK:   call x86_thiscallcc void @"\01??_DCleanup@@QAEXXZ"(
 // CHECK:   cleanupret from %[[CLEANUPPAD]] unwind to caller
 
 
diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp
index 589bc22..4f7eacd 100644
--- a/test/CodeGenCXX/exceptions-seh.cpp
+++ b/test/CodeGenCXX/exceptions-seh.cpp
@@ -2,7 +2,7 @@
 // RUN:         -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \
 // RUN:         FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH
 // RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
-// RUN:         -o - -mconstructor-aliases -O1 -disable-llvm-optzns | \
+// RUN:         -o - -mconstructor-aliases -O1 -disable-llvm-passes | \
 // RUN:         FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX
 
 extern "C" unsigned long _exception_code();
@@ -118,7 +118,7 @@
   use_seh_in_inline_func();
 }
 
-// CHECK-LABEL: define linkonce_odr void @use_seh_in_inline_func() #{{[0-9]+}} comdat
+// CHECK-LABEL: define linkonce_odr void @use_seh_in_inline_func() #{{[0-9]+}}
 // CHECK-SAME:  personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
 // CHECK: invoke void @might_throw()
 //
@@ -134,12 +134,12 @@
 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
 // CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 1, i8* %[[fp]])
 
-// CHECK-LABEL: define internal i32 @"\01?filt$0@0@use_seh_in_inline_func@@"(i8* %exception_pointers, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func)
+// CHECK-LABEL: define internal i32 @"\01?filt$0@0@use_seh_in_inline_func@@"(i8* %exception_pointers, i8* %frame_pointer) #{{[0-9]+}}
 // CHECK: icmp eq i32 %{{.*}}, 424242
 // CHECK: zext i1 %{{.*}} to i32
 // CHECK: ret i32
 
-// CHECK-LABEL: define internal void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 %abnormal_termination, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func)
+// CHECK-LABEL: define internal void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 %abnormal_termination, i8* %frame_pointer) #{{[0-9]+}}
 // CHECK: store i32 1234, i32* @my_unique_global
 
 // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp
index 86616d1..e31d6fc 100644
--- a/test/CodeGenCXX/exceptions.cpp
+++ b/test/CodeGenCXX/exceptions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -std=c++98 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
 
 typedef __typeof(sizeof(0)) size_t;
 
@@ -64,7 +65,10 @@
     // CHECK-NEXT: [[T2:%.*]] = load i32, i32* [[T1]], align 4
     // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T2]])
     // CHECK:      store i1 false, i1* [[ACTIVE]]
-    // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
+    // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+    // CHECK11-NEXT: call void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
     // CHECK:      ret [[A]]* [[CAST]]
     // CHECK:      [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]]
     // CHECK-NEXT: br i1 [[ISACTIVE]]
@@ -74,10 +78,10 @@
 
   //   rdar://11904428
   //   Terminate landing pads should call __cxa_begin_catch first.
-  // CHECK:      define linkonce_odr hidden void @__clang_call_terminate(i8*) [[NI_NR_NUW:#[0-9]+]] comdat
-  // CHECK-NEXT:   [[T0:%.*]] = call i8* @__cxa_begin_catch(i8* %0) [[NUW:#[0-9]+]]
-  // CHECK-NEXT:   call void @_ZSt9terminatev() [[NR_NUW:#[0-9]+]]
-  // CHECK-NEXT:   unreachable
+  // CHECK98:      define linkonce_odr hidden void @__clang_call_terminate(i8*) [[NI_NR_NUW:#[0-9]+]] comdat
+  // CHECK98-NEXT:   [[T0:%.*]] = call i8* @__cxa_begin_catch(i8* %0) [[NUW:#[0-9]+]]
+  // CHECK98-NEXT:   call void @_ZSt9terminatev() [[NR_NUW:#[0-9]+]]
+  // CHECK98-NEXT:   unreachable
 
   A *d() {
     // CHECK:    define [[A:%.*]]* @_ZN5test11dEv()
@@ -89,7 +93,10 @@
     // CHECK:      [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
     // CHECK:      invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
     // CHECK:      store i1 false, i1* [[ACTIVE]]
-    // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
+    // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+    // CHECK11-NEXT: call void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
     // CHECK:      ret [[A]]* [[CAST]]
     // CHECK:      [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]]
     // CHECK-NEXT: br i1 [[ISACTIVE]]
@@ -109,8 +116,13 @@
     // CHECK:      [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T2]])
     // CHECK:      invoke void @_ZN5test11AC1Eii([[A]]* [[CAST]], i32 [[T1]], i32 [[T3]])
     // CHECK:      store i1 false, i1* [[ACTIVE]]
-    // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
-    // CHECK:      invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
+    // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
+    // CHECK11-NEXT: call void @_ZN5test11BD1Ev([[B]]* [[T2]])
+
+    // CHECK98:      invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+    // CHECK11:      call void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
     // CHECK:      ret [[A]]* [[CAST]]
     // CHECK:      [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]]
     // CHECK-NEXT: br i1 [[ISACTIVE]]
@@ -141,8 +153,13 @@
     // CHECK-NEXT: store [[A]]* [[CAST]], [[A]]** [[X]], align 8
     // CHECK:      invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T2:%.*]])
     // CHECK:      [[RET:%.*]] = load [[A]]*, [[A]]** [[X]], align 8
-    // CHECK:      invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
-    // CHECK:      invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
+    // CHECK98:      invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
+    // CHECK11:      call void @_ZN5test11BD1Ev([[B]]* [[T2]])
+
+    // CHECK98:      invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+    // CHECK11:      call void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
     // CHECK:      ret [[A]]* [[RET]]
     // CHECK:      [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]]
     // CHECK-NEXT: br i1 [[ISACTIVE]]
@@ -166,8 +183,11 @@
     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
     // CHECK-NEXT: invoke void @_ZN5test21AC1Ei([[A]]* [[CAST]], i32 5)
     // CHECK:      ret [[A]]* [[CAST]]
-    // CHECK:      invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
-    // CHECK:      call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
+
+    // CHECK98:      invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
+    // CHECK11:      call void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
+
+    // CHECK98:      call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
     return new A(5);
   }
 }
@@ -192,8 +212,11 @@
     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
     // CHECK-NEXT: invoke void @_ZN5test31AC1Ei([[A]]* [[CAST]], i32 5)
     // CHECK:      ret [[A]]* [[CAST]]
-    // CHECK:      invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
-    // CHECK:      call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
+
+    // CHECK98:      invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
+    // CHECK11:      call void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
+
+    // CHECK98:      call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
     return new(foo(),bar()) A(5);
   }
 
@@ -235,7 +258,9 @@
     // CHECK-NEXT: br i1 [[ISACTIVE]]
     // CHECK:      [[V0:%.*]] = load i8*, i8** [[SAVED0]]
     // CHECK-NEXT: [[V1:%.*]] = load i8*, i8** [[SAVED1]]
-    // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
+
+    // CHECK98-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
+    // CHECK11-NEXT: call void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
   }
 }
 
@@ -283,9 +308,13 @@
   // 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]]* dereferenceable({{[0-9]+}}) [[SRC]], [[T_T]]* dereferenceable({{[0-9]+}}) [[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]])
+
+  // CHECK98:      invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]])
+  // CHECK11:      call void @_ZN5test51TD1Ev([[T_T]]* [[T]])
+
+  // CHECK98:      call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]]
+  // CHECK98-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]])
+
   // CHECK:      call void @__cxa_end_catch()
   void test() {
     try {
@@ -380,12 +409,16 @@
     // Destroy the inner A object.
     // CHECK-NEXT: load i1, i1* [[INNER_A]]
     // CHECK-NEXT: br i1
-    // CHECK:      invoke void @_ZN5test71AD1Ev(
+
+    // CHECK98:    invoke void @_ZN5test71AD1Ev(
+    // CHECK11:    call void @_ZN5test71AD1Ev(
 
     // Destroy the outer A object.
     // CHECK:      load i1, i1* [[OUTER_A]]
     // CHECK-NEXT: br i1
-    // CHECK:      invoke void @_ZN5test71AD1Ev(
+
+    // CHECK98:    invoke void @_ZN5test71AD1Ev(
+    // CHECK11:    call void @_ZN5test71AD1Ev(
 
     return new B(A(), new B(A(), 0));
   }
@@ -456,8 +489,12 @@
   // CHECK-NEXT: load i8, i8* @_ZN6test108suppressE, align 1
   // CHECK-NEXT: trunc
   // CHECK-NEXT: br i1
-  // CHECK:      call void @__cxa_end_catch()
-  // CHECK-NEXT: br label
+
+  // CHECK98:      call void @__cxa_end_catch()
+  // CHECK98-NEXT: br label
+  // CHECK11:      invoke void @__cxa_end_catch()
+  // CHECK11-NEXT: to label
+
   // CHECK:      invoke void @__cxa_rethrow()
   // CHECK:      unreachable
 }
@@ -504,7 +541,10 @@
   // CHECK-NEXT: br i1 [[EMPTY]]
   // CHECK:      [[AFTER:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
   // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
-  // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+
+  // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+  // CHECK11-NEXT: call void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+
   // CHECK:      [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
   // CHECK-NEXT: br i1 [[DONE]],
   //     - Next, chain to cleanup for single.
@@ -517,13 +557,19 @@
   // CHECK-NEXT: br label
   // CHECK:      [[AFTER:%.*]] = phi [[A]]* [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
   // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
-  // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+
+  // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+  // CHECK11-NEXT: call void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+
   // CHECK:      [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
   // CHECK-NEXT: br i1 [[DONE]],
   //     - Next, chain to cleanup for single.
   // CHECK:      br label
   //   Finally, the cleanup for single.
-  // CHECK:      invoke void @_ZN6test111AD1Ev([[A]]* [[SINGLE]])
+
+  // CHECK98:      invoke void @_ZN6test111AD1Ev([[A]]* [[SINGLE]])
+  // CHECK11:      call void @_ZN6test111AD1Ev([[A]]* [[SINGLE]])
+
   // CHECK:      br label
   // CHECK:      resume
   //   (After this is a terminate landingpad.)
@@ -543,7 +589,9 @@
   // CHECK-NEXT:  [[CAST:%.*]] = bitcast i8* [[PTR]] to [[A:%.*]]*
   // CHECK-NEXT:  invoke void @_ZN6test121AC1Ev([[A]]* [[CAST]])
   // CHECK:       ret [[A]]* [[CAST]]
-  // CHECK:       invoke void @_ZN6test121AdlEPvS1_(i8* [[PTR]], i8* [[PTR]])
+
+  // CHECK98:       invoke void @_ZN6test121AdlEPvS1_(i8* [[PTR]], i8* [[PTR]])
+  // CHECK11:       call void @_ZN6test121AdlEPvS1_(i8* [[PTR]], i8* [[PTR]])
 }
 
-// CHECK: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind }
+// CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind }
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index 7e00d78..85857fb 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -1,10 +1,13 @@
 // RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO-OPT
-// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -O3 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-OPT
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -O3 -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-OPT
 // RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK-MS
 
 // This check logically is attached to 'template int S<int>::i;' below.
 // CHECK: @_ZN1SIiE1iE = weak_odr global i32
 
+// This check is logically attached to 'template int ExportedStaticLocal::f<int>()' below.
+// CHECK-OPT: @_ZZN19ExportedStaticLocal1fIiEEvvE1i = linkonce_odr global
+
 template<typename T, typename U, typename Result>
 struct plus {
   Result operator()(const T& t, const U& u) const;
@@ -153,3 +156,17 @@
 template <typename T> void S<T>::g() {}
 template <typename T> int S<T>::i;
 template <typename T> void S<T>::S2::h() {}
+
+namespace ExportedStaticLocal {
+void sink(int&);
+template <typename T>
+inline void f() {
+  static int i;
+  sink(i);
+}
+// See the check line at the top of the file.
+extern template void f<int>();
+void use() {
+  f<int>();
+}
+}
diff --git a/test/CodeGenCXX/float128-declarations.cpp b/test/CodeGenCXX/float128-declarations.cpp
index e1604a6..f1db8f4 100644
--- a/test/CodeGenCXX/float128-declarations.cpp
+++ b/test/CodeGenCXX/float128-declarations.cpp
@@ -8,6 +8,10 @@
 // RUN:   %s -o - | FileCheck %s -check-prefix=CHECK-X86
 // RUN: %clang_cc1 -emit-llvm -triple systemz-unknown-linux-gnu -std=c++11 \
 // RUN:   %s -o - | FileCheck %s -check-prefix=CHECK-SYSZ
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-openbsd -std=c++11 \
+// RUN:   %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple amd64-pc-openbsd -std=c++11 \
+// RUN:   %s -o - | FileCheck %s -check-prefix=CHECK-X86
 //
 /*  Various contexts where type __float128 can appear. The different check
     prefixes are due to different mangling on X86 and different calling
diff --git a/test/CodeGenCXX/funcsig.cpp b/test/CodeGenCXX/funcsig.cpp
index 2a6e641..16e5f7e 100644
--- a/test/CodeGenCXX/funcsig.cpp
+++ b/test/CodeGenCXX/funcsig.cpp
@@ -1,22 +1,43 @@
-// RUN: %clang_cc1 -std=c++11 -triple i686-pc-win32 %s -fms-extensions -fno-rtti -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple i686-pc-win32 %s -fms-extensions -fno-rtti -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX
+// RUN: %clang_cc1 -x c -triple i686-pc-win32 %s -fms-extensions -fno-rtti -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-C
 
 // Similar to predefined-expr.cpp, but not as exhaustive, since it's basically
 // equivalent to __PRETTY_FUNCTION__.
 
-extern "C" int printf(const char *, ...);
+#ifdef __cplusplus
+extern "C"
+#endif
+int printf(const char *, ...);
 
-void freeFunc(int *, char) {
+void funcNoProto() {
+  printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK-C:   @"\01??_C@_0BL@IHLLLCAO@void?5__cdecl?5funcNoProto?$CI?$CJ?$AA@" = linkonce_odr unnamed_addr constant [27 x i8] c"void __cdecl funcNoProto()\00"
+// CHECK-CXX: @"\01??_C@_0BP@PJOECCJN@void?5__cdecl?5funcNoProto?$CIvoid?$CJ?$AA@" = linkonce_odr unnamed_addr constant [31 x i8] c"void __cdecl funcNoProto(void)\00"
+
+void funcNoParams(void) {
+  printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK: @"\01??_C@_0CA@GBIDFNBN@void?5__cdecl?5funcNoParams?$CIvoid?$CJ?$AA@" = linkonce_odr unnamed_addr constant [32 x i8] c"void __cdecl funcNoParams(void)\00"
+
+void freeFunc(int *p, char c) {
   printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
 }
 // CHECK: @"\01??_C@_0CD@KLGMNNL@void?5__cdecl?5freeFunc?$CIint?5?$CK?0?5cha@" = linkonce_odr unnamed_addr constant [{{.*}} x i8] c"void __cdecl freeFunc(int *, char)\00"
 
+#ifdef __cplusplus
+void funcVarargs(...) {
+  printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK-CXX: @"\01??_C@_0BO@BOBPLEKP@void?5__cdecl?5funcVarargs?$CI?4?4?4?$CJ?$AA@" = linkonce_odr unnamed_addr constant [30 x i8] c"void __cdecl funcVarargs(...)\00"
+
 struct TopLevelClass {
   void topLevelMethod(int *, char);
 };
 void TopLevelClass::topLevelMethod(int *, char) {
   printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
 }
-// CHECK: @"\01??_C@_0DL@OBHNMDP@void?5__thiscall?5TopLevelClass?3?3t@" = linkonce_odr unnamed_addr constant [{{.*}} x i8] c"void __thiscall TopLevelClass::topLevelMethod(int *, char)\00"
+// CHECK-CXX: @"\01??_C@_0DL@OBHNMDP@void?5__thiscall?5TopLevelClass?3?3t@" = linkonce_odr unnamed_addr constant [{{.*}} x i8] c"void __thiscall TopLevelClass::topLevelMethod(int *, char)\00"
 
 namespace NS {
 struct NamespacedClass {
@@ -25,5 +46,6 @@
 void NamespacedClass::namespacedMethod(int *, char) {
   printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
 }
-// CHECK: @"\01??_C@_0ED@PFDKIEBA@void?5__thiscall?5NS?3?3NamespacedCl@" = linkonce_odr unnamed_addr constant [{{.*}} x i8] c"void __thiscall NS::NamespacedClass::namespacedMethod(int *, char)\00"
+// CHECK-CXX: @"\01??_C@_0ED@PFDKIEBA@void?5__thiscall?5NS?3?3NamespacedCl@" = linkonce_odr unnamed_addr constant [{{.*}} x i8] c"void __thiscall NS::NamespacedClass::namespacedMethod(int *, char)\00"
 }
+#endif
diff --git a/test/CodeGenCXX/global-array-destruction.cpp b/test/CodeGenCXX/global-array-destruction.cpp
index cb3524b..1ae7b72 100644
--- a/test/CodeGenCXX/global-array-destruction.cpp
+++ b/test/CodeGenCXX/global-array-destruction.cpp
@@ -39,7 +39,7 @@
 T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
 
 // CHECK: call {{.*}} @__cxa_atexit
-// CHECK: getelementptr inbounds ({{.*}} bitcast {{.*}}* @t to %struct.T*), i64 6
+// CHECK: getelementptr inbounds ({{.*}} getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @t, i32 0, i32 0, i32 0), i64 6)
 // CHECK: call void @_ZN1TD1Ev
 // CHECK: icmp eq {{.*}} @t
 // CHECK: br i1 {{.*}}
@@ -47,9 +47,9 @@
 static T t2[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
 
 // CHECK: call {{.*}} @__cxa_atexit
-// CHECK: getelementptr inbounds ({{.*}} bitcast {{.*}}* @_ZL2t2 to %struct.T*), i64 6
+// CHECK: getelementptr inbounds ({{.*}} getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZL2t2, i32 0, i32 0, i32 0), i64 6)
 // CHECK: call void @_ZN1TD1Ev
-// CHECK: icmp eq {{.*}} @_ZL2t
+// CHECK: icmp eq {{.*}} @_ZL2t2
 // CHECK: br i1 {{.*}}
 
 using U = T[2][3];
diff --git a/test/CodeGenCXX/global-dtor-no-atexit.cpp b/test/CodeGenCXX/global-dtor-no-atexit.cpp
index 9860412..8621941 100644
--- a/test/CodeGenCXX/global-dtor-no-atexit.cpp
+++ b/test/CodeGenCXX/global-dtor-no-atexit.cpp
@@ -43,4 +43,4 @@
   static A a1, a2;
 }
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index e806af9..f96e603 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -15,12 +15,9 @@
 
 struct D { ~D(); };
 
-// CHECK: @__dso_handle = external global i8
+// CHECK: @__dso_handle = external hidden global i8
 // CHECK: @c = global %struct.C zeroinitializer, align 8
 
-// It's okay if we ever implement the IR-generation optimization to remove this.
-// CHECK: @_ZN5test3L3varE = internal constant i8* getelementptr inbounds ([7 x i8], [7 x i8]* 
-
 // PR6205: The casts should not require global initializers
 // CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C"
 // CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* getelementptr inbounds (%"struct.PR5974::C", %"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0)
@@ -171,6 +168,8 @@
   const int b3 = B().n;
 
   // CHECK-NOT: @_ZN5test7L2c1E
+  // CHECK: call void @llvm.memset{{.*}} @_ZN5test7L2c1E
+  // CHECK-NOT: @_ZN5test7L2c1E
   // CHECK: @_ZN5test7L2c2E
   // CHECK-NOT: @_ZN5test7L2c3E
   // CHECK: @_ZN5test7L2c4E
@@ -205,8 +204,8 @@
 // rdar://problem/8090834: this should be nounwind
 // CHECK-NOEXC: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
 
-// CHECK-NOEXC: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK-NOEXC: attributes [[NUW]] = { noinline nounwind{{.*}} }
 
 // PR21811: attach the appropriate attribute to the global init function
 // CHECK-FP: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUX:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
-// CHECK-FP: attributes [[NUX]] = { nounwind {{.*}}"no-frame-pointer-elim-non-leaf"{{.*}} }
+// CHECK-FP: attributes [[NUX]] = { noinline nounwind {{.*}}"no-frame-pointer-elim-non-leaf"{{.*}} }
diff --git a/test/CodeGenCXX/goto.cpp b/test/CodeGenCXX/goto.cpp
index 27bd7af..2f5b719 100644
--- a/test/CodeGenCXX/goto.cpp
+++ b/test/CodeGenCXX/goto.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fcxx-exceptions -fexceptions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fcxx-exceptions -fexceptions -emit-llvm -std=c++98 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fcxx-exceptions -fexceptions -emit-llvm -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
 
 // Reduced from a crash on boost::interprocess's node_allocator_test.cpp.
 namespace test0 {
@@ -24,7 +25,9 @@
     // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[TMP]])
     // CHECK:      invoke void @_ZN5test01VC1ERKNS_1AE([[V]]* [[NEWCAST]], [[A]]* dereferenceable({{[0-9]+}}) [[TMP]])
     // CHECK:      store i1 false, i1* [[CLEANUPACTIVE]]
-    // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[TMP]])
+
+    // CHECK98-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[TMP]])
+    // CHECK11-NEXT: call void @_ZN5test01AD1Ev([[A]]* [[TMP]])
     A y;
     try {
       A z;
diff --git a/test/CodeGenCXX/homogeneous-aggregates.cpp b/test/CodeGenCXX/homogeneous-aggregates.cpp
index 67911c0..1338b25 100644
--- a/test/CodeGenCXX/homogeneous-aggregates.cpp
+++ b/test/CodeGenCXX/homogeneous-aggregates.cpp
@@ -47,7 +47,7 @@
 // PPC: define [3 x double] @_Z7func_D22D2([3 x double] %x.coerce)
 // ARM32: define arm_aapcs_vfpcc %struct.D2 @_Z7func_D22D2(%struct.D2 %x.coerce)
 // ARM64: define %struct.D2 @_Z7func_D22D2([3 x double] %x.coerce)
-// X64: define x86_vectorcallcc %struct.D2 @"\01_Z7func_D22D2@@24"(double %x.0, double %x.1, double %x.2)
+// X64: define x86_vectorcallcc %struct.D2 @"\01_Z7func_D22D2@@24"(%struct.D2 inreg %x.coerce)
 D2 CC func_D2(D2 x) { return x; }
 
 // PPC: define void @_Z7func_D32D3(%struct.D3* noalias sret %agg.result, [4 x i64] %x.coerce)
@@ -92,7 +92,7 @@
 void CC with_empty_base(HVAWithEmptyBase a) {}
 
 // FIXME: MSVC doesn't consider this an HVA because of the empty base.
-// X64: define x86_vectorcallcc void @"\01_Z15with_empty_base16HVAWithEmptyBase@@16"(float %a.0, float %a.1, float %a.2)
+// X64: define x86_vectorcallcc void @"\01_Z15with_empty_base16HVAWithEmptyBase@@16"(%struct.HVAWithEmptyBase inreg %a.coerce)
 
 struct HVAWithEmptyBitField : Float1, Float2 {
   int : 0; // Takes no space.
@@ -102,5 +102,5 @@
 // PPC: define void @_Z19with_empty_bitfield20HVAWithEmptyBitField([3 x float] %a.coerce)
 // ARM64: define void @_Z19with_empty_bitfield20HVAWithEmptyBitField([3 x float] %a.coerce)
 // ARM32: define arm_aapcs_vfpcc void @_Z19with_empty_bitfield20HVAWithEmptyBitField(%struct.HVAWithEmptyBitField %a.coerce)
-// X64: define x86_vectorcallcc void @"\01_Z19with_empty_bitfield20HVAWithEmptyBitField@@16"(float %a.0, float %a.1, float %a.2)
+// X64: define x86_vectorcallcc void @"\01_Z19with_empty_bitfield20HVAWithEmptyBitField@@16"(%struct.HVAWithEmptyBitField inreg %a.coerce)
 void CC with_empty_bitfield(HVAWithEmptyBitField a) {}
diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp
index d022413..3f8665a 100644
--- a/test/CodeGenCXX/implicit-copy-constructor.cpp
+++ b/test/CodeGenCXX/implicit-copy-constructor.cpp
@@ -48,12 +48,14 @@
 // CHECK: call void @_ZN1BC2ERS_
 // CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 28}}
 // CHECK: call void @_ZN1BC1ERS_
-// CHECK: br
-// CHECK: {{icmp ult.*, 2}}
-// CHECK: {{icmp ult.*, 3}}
+// CHECK: br label
 // CHECK: call void @_ZN1AC1Ev
 // CHECK: call void @_ZN1CC1ERS_1A
 // CHECK: call void @_ZN1AD1Ev
+// CHECK: {{icmp eq.*, 3}}
+// CHECK: br i1
+// CHECK: {{icmp eq.*, 2}}
+// CHECK: br i1
 // CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 300}}
 // CHECK: ret void
 
diff --git a/test/CodeGenCXX/implicit-exception-spec.cpp b/test/CodeGenCXX/implicit-exception-spec.cpp
new file mode 100644
index 0000000..cf363bd
--- /dev/null
+++ b/test/CodeGenCXX/implicit-exception-spec.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK %s
+
+struct A {
+  A();
+  A(const A&);
+  A(A&&);
+};
+struct B : virtual A {
+  virtual void f() = 0;
+};
+struct C : B {
+  void f();
+};
+
+// CHECK-DAG: define {{.*}} @_ZN1BC2Ev({{.*}} #[[NOUNWIND:[0-9]*]]
+C c1;
+// CHECK-DAG: define {{.*}} @_ZN1BC2ERKS_({{.*}} #[[NOUNWIND]]
+C c2(c1);
+// CHECK-DAG: define {{.*}} @_ZN1BC2EOS_({{.*}} #[[NOUNWIND]]
+C c3(static_cast<C&&>(c1));
+
+// CHECK-DAG: #[[NOUNWIND]] = {{{.*}} nounwind
diff --git a/test/CodeGenCXX/inheriting-constructor.cpp b/test/CodeGenCXX/inheriting-constructor.cpp
index a3adf70..1be59b9 100644
--- a/test/CodeGenCXX/inheriting-constructor.cpp
+++ b/test/CodeGenCXX/inheriting-constructor.cpp
@@ -137,7 +137,7 @@
   // WIN32: call {{.*}} @"\01??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
   // WIN32: call void @llvm.stackrestore(
   // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
-  // WIN32: call {{.*}} @"\01??_DQ@@QAE@XZ"(
+  // WIN32: call {{.*}} @"\01??_DQ@@QAEXXZ"(
 
   // On Win64, the Q arguments would be destroyed in the callee. We don't yet
   // support that in the non-inlined case, so we force inlining.
@@ -150,7 +150,7 @@
   // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
   // WIN64: call {{.*}} @"\01??0A@inalloca_nonvirt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
   // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
-  // WIN64: call void @"\01??_DQ@@QEAA@XZ"({{.*}}* %[[TMP]])
+  // WIN64: call void @"\01??_DQ@@QEAAXXZ"({{.*}}* %[[TMP]])
 
   struct C : B { using B::B; };
   C c(1, 2, 3, 4);
@@ -173,7 +173,7 @@
   // WIN32: call {{.*}} @"\01??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
   // WIN32: call void @llvm.stackrestore(
   // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
-  // WIN32: call {{.*}} @"\01??_DQ@@QAE@XZ"(
+  // WIN32: call {{.*}} @"\01??_DQ@@QAEXXZ"(
 
   // On Win64, the Q arguments would be destroyed in the callee. We don't yet
   // support that in the non-inlined case, so we force inlining.
@@ -186,7 +186,7 @@
   // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
   // WIN64: call {{.*}} @"\01??0A@inalloca_nonvirt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
   // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
-  // WIN64: call void @"\01??_DQ@@QEAA@XZ"({{.*}}* %[[TMP]])
+  // WIN64: call void @"\01??_DQ@@QEAAXXZ"({{.*}}* %[[TMP]])
 }
 
 namespace inalloca_virt {
@@ -224,7 +224,7 @@
   // destroy the parameters, but that's not actually possible.
   // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
   // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
-  // WIN32: call {{.*}} @"\01??_DQ@@QAE@XZ"(
+  // WIN32: call {{.*}} @"\01??_DQ@@QAEXXZ"(
 
   // On Win64, the Q arguments would be destroyed in the callee. We don't yet
   // support that in the non-inlined case, so we force inlining.
@@ -239,7 +239,7 @@
   // WIN64: br
   // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
   // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
-  // WIN64: call void @"\01??_DQ@@QEAA@XZ"({{.*}}* %[[TMP]])
+  // WIN64: call void @"\01??_DQ@@QEAAXXZ"({{.*}}* %[[TMP]])
 
   struct C : B { using B::B; };
   C c(1, 2, 3, 4);
@@ -281,7 +281,7 @@
   //
   // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
   // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
-  // WIN32: call {{.*}} @"\01??_DQ@@QAE@XZ"(
+  // WIN32: call {{.*}} @"\01??_DQ@@QAEXXZ"(
 
   // On Win64, the Q arguments would be destroyed in the callee. We don't yet
   // support that in the non-inlined case, so we force inlining.
@@ -301,7 +301,7 @@
   // WIN64: br
   // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
   // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
-  // WIN64: call void @"\01??_DQ@@QEAA@XZ"({{.*}}* %[[TMP]])
+  // WIN64: call void @"\01??_DQ@@QEAAXXZ"({{.*}}* %[[TMP]])
 }
 
 namespace inline_nonvirt {
diff --git a/test/CodeGenCXX/initializer-list-ctor-order.cpp b/test/CodeGenCXX/initializer-list-ctor-order.cpp
new file mode 100644
index 0000000..390fe4f
--- /dev/null
+++ b/test/CodeGenCXX/initializer-list-ctor-order.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple i686-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple i686-windows   | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MS
+
+extern "C" {
+int f();
+int g();
+}
+
+struct A {
+  A(int, int);
+};
+
+
+void foo() {
+  A a{f(), g()};
+}
+// CHECK-ITANIUM-LABEL: define void @_Z3foov
+// CHECK-MS-LABEL: define void @"\01?foo@@YAXXZ"
+// CHECK: call i32 @f()
+// CHECK: call i32 @g()
+
+struct B : A {
+  B();
+};
+B::B() : A{f(), g()} {}
+// CHECK-ITANIUM-LABEL: define void @_ZN1BC2Ev
+// CHECK-MS-LABEL: define x86_thiscallcc %struct.B* @"\01??0B@@QAE@XZ"
+// CHECK: call i32 @f()
+// CHECK: call i32 @g()
diff --git a/test/CodeGenCXX/inline-dllexport-member.cpp b/test/CodeGenCXX/inline-dllexport-member.cpp
index e1a19fb..66ef459 100644
--- a/test/CodeGenCXX/inline-dllexport-member.cpp
+++ b/test/CodeGenCXX/inline-dllexport-member.cpp
@@ -7,6 +7,7 @@
   static const unsigned int ui = 0;
 };
 
-// CHECK: [[UI]] = distinct !DIGlobalVariable(name: "ui", linkageName: "\01?ui@s@@2IB", scope: ![[SCOPE:[0-9]+]],
+// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]])
+// CHECK: [[UIV]] = distinct !DIGlobalVariable(name: "ui", linkageName: "\01?ui@s@@2IB", scope: ![[SCOPE:[0-9]+]],
 // CHECK: ![[SCOPE]] = distinct !DICompileUnit(
 
diff --git a/test/CodeGenCXX/inline-hint.cpp b/test/CodeGenCXX/inline-hint.cpp
index 9c14032..c4de751 100644
--- a/test/CodeGenCXX/inline-hint.cpp
+++ b/test/CodeGenCXX/inline-hint.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=SUITABLE
-// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-hint-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=HINTED
-// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -fno-inline -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NOINLINE
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-functions -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefix=CHECK --check-prefix=SUITABLE
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-hint-functions -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefix=CHECK --check-prefix=HINTED
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -fno-inline -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NOINLINE
 
 // Force non-trivial implicit constructors/destructors/operators for B by having explicit ones for A
 struct A {
diff --git a/test/CodeGenCXX/invariant.group-for-vptrs.cpp b/test/CodeGenCXX/invariant.group-for-vptrs.cpp
index ca737ee..5c76353 100644
--- a/test/CodeGenCXX/invariant.group-for-vptrs.cpp
+++ b/test/CodeGenCXX/invariant.group-for-vptrs.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -emit-llvm %s -fstrict-vtable-pointers -O1 -o - -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -emit-llvm %s -fstrict-vtable-pointers -O1 -o - -disable-llvm-passes | FileCheck %s
 
 struct A {
   virtual void foo();
@@ -23,7 +23,7 @@
   // CHECK: load {{.*}} !invariant.group ![[A_MD]]
   a2->foo();
 }
-// CHECK-LABEL: }
+// CHECK-LABEL: {{^}}}
 
 namespace {
 
@@ -52,7 +52,7 @@
 // Checking A::A()
 // CHECK-LABEL: define linkonce_odr void @_ZN1AC2Ev(
 // CHECK: store {{.*}}, !invariant.group ![[A_MD]]
-// CHECK-LABEL: }
+// CHECK-LABEL: {{^}}}
 
 // Checking D::D()
 // CHECK-LABEL: define linkonce_odr void @_ZN1DC2Ev(
diff --git a/test/CodeGenCXX/key-function-vtable.cpp b/test/CodeGenCXX/key-function-vtable.cpp
index f6aa16e..028017c 100644
--- a/test/CodeGenCXX/key-function-vtable.cpp
+++ b/test/CodeGenCXX/key-function-vtable.cpp
@@ -44,8 +44,8 @@
 void use_X1() { X1 x1; }
 
 // CHECK-DAG: @_ZTV2X1 = linkonce_odr unnamed_addr constant
-// CHECK-DAG: @_ZTV5testa = unnamed_addr constant [3 x i8*] [i8* null
-// CHECK-DAG: @_ZTV5testc = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
-// CHECK-DAG: @_ZTV5testb = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
-// CHECK-DAG: @_ZTV5teste = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
-// CHECK-DAG: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testa = unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testc = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testb = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5teste = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
diff --git a/test/CodeGenCXX/lambda-expressions.cpp b/test/CodeGenCXX/lambda-expressions.cpp
index 2006f0f..2c625da 100644
--- a/test/CodeGenCXX/lambda-expressions.cpp
+++ b/test/CodeGenCXX/lambda-expressions.cpp
@@ -54,12 +54,14 @@
 // CHECK: ret i32
 
 struct D { D(); D(const D&); int x; };
-int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
+int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
 
 // CHECK-LABEL: define i32 @_Z1di
 // CHECK: call void @_ZN1DC1Ev
-// CHECK: icmp ult i64 %{{.*}}, 10
+// CHECK: br label
 // CHECK: call void @_ZN1DC1ERKS_
+// CHECK: icmp eq i64 %{{.*}}, 10
+// CHECK: br i1
 // CHECK: call i32 @"_ZZ1diENK3$_4clEv"
 // CHECK-LABEL: define internal i32 @"_ZZ1diENK3$_4clEv"
 // CHECK: load i32, i32*
@@ -67,7 +69,7 @@
 // CHECK: ret i32
 
 struct E { E(); E(const E&); ~E(); int x; };
-int e(E a, E b, bool cond) { [a,b,cond](){ return (cond ? a : b).x; }(); }
+int e(E a, E b, bool cond) { return [a,b,cond](){ return (cond ? a : b).x; }(); }
 // CHECK-LABEL: define i32 @_Z1e1ES_b
 // CHECK: call void @_ZN1EC1ERKS_
 // CHECK: invoke void @_ZN1EC1ERKS_
@@ -127,42 +129,58 @@
     ~A();
   };
 
+  void after_init() noexcept;
+
   // CHECK-LABEL: define void @_ZN7pr285954testEv()
   void test() {
-    // CHECK: [[ARRAY:%.*]] = alloca [3 x [5 x [[A:%.*]]]], align 1
-    // CHECK: [[DESTIDX:%.*]] = alloca i64, align 8
-    // CHECK: [[I0:%.*]] = alloca i64, align 8
-    // CHECK: [[I1:%.*]] = alloca i64, align 8
+    // CHECK: %[[SRC:.*]] = alloca [3 x [5 x %[[A:.*]]]], align 1
     A array[3][5];
 
-    // CHECK: [[DESTBASE:%.*]] = bitcast [3 x [5 x [[A]]]]* {{.*}} to [[A]]*
-    // CHECK: store i64 0, i64* [[DESTIDX]], align 8
-    // CHECK: store i64 0, i64* [[I0]], align 8
+    // Skip over the initialization loop.
+    // CHECK: call {{.*}}after_init
+    after_init();
+
+    // CHECK: %[[DST_0:.*]] = getelementptr {{.*}} [3 x [5 x %[[A]]]]* %[[DST:.*]], i64 0, i64 0
     // CHECK: br label
-    // CHECK: icmp ult
-    // CHECK: store i64 0, i64* [[I1]], align 8
+    // CHECK: %[[I:.*]] = phi i64 [ 0, %{{.*}} ], [ %[[I_NEXT:.*]], {{.*}} ]
+    // CHECK: %[[DST_I:.*]] = getelementptr {{.*}} [5 x %[[A]]]* %[[DST_0]], i64 %[[I]]
+    // CHECK: %[[SRC_I:.*]] = getelementptr {{.*}} [3 x [5 x %[[A]]]]* %[[SRC]], i64 0, i64 %[[I]]
+    //
+    // CHECK: %[[DST_I_0:.*]] = getelementptr {{.*}} [5 x %[[A]]]* %[[DST_I]], i64 0, i64 0
     // CHECK: br label
-    // CHECK: icmp ult
-    // CHECK: [[T0:%.*]] = load i64, i64* [[DESTIDX]], align 8
-    // CHECK: [[DEST:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DESTBASE]], i64 [[T0]]
+    // CHECK: %[[J:.*]] = phi i64 [ 0, %{{.*}} ], [ %[[J_NEXT:.*]], {{.*}} ]
+    // CHECK: %[[DST_I_J:.*]] = getelementptr {{.*}} %[[A]]* %[[DST_I_0]], i64 %[[J]]
+    // CHECK: %[[DST_0_0:.*]] = bitcast [5 x %[[A]]]* %[[DST_0]] to %[[A]]*
+    // CHECK: %[[SRC_I_J:.*]] = getelementptr {{.*}} [5 x %[[A]]]* %[[SRC_I]], i64 0, i64 %[[J]]
+    //
     // CHECK: invoke void @_ZN7pr285954TempC1Ev
     // CHECK: invoke void @_ZN7pr285951AC1ERKS0_RKNS_4TempE
     // CHECK: invoke void @_ZN7pr285954TempD1Ev
+    //
+    // CHECK: add nuw i64 %[[J]], 1
+    // CHECK: icmp eq
+    // CHECK: br i1
+    //
+    // CHECK: add nuw i64 %[[I]], 1
+    // CHECK: icmp eq
+    // CHECK: br i1
+    //
+    // CHECK: ret void
+    //  
     // CHECK: landingpad
     // CHECK: landingpad
-    // CHECK: br label [[CLEANUP:%.*]]{{$}}
+    // CHECK: br label %[[CLEANUP:.*]]{{$}}
     // CHECK: landingpad
     // CHECK: invoke void @_ZN7pr285954TempD1Ev
-    // CHECK: br label [[CLEANUP]]
-    // CHECK: icmp eq [[A]]* [[DESTBASE]], [[DEST]]
-    // CHECK: [[T0:%.*]] = phi [[A]]*
-    // CHECK: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i64 -1
-    // CHECK: call void @_ZN7pr285951AD1Ev([[A]]* [[T1]])
-    // CHECK: icmp eq [[A]]* [[T1]], [[DESTBASE]]
+    // CHECK: br label %[[CLEANUP]]
+    //
+    // CHECK: [[CLEANUP]]:
+    // CHECK: icmp eq %[[A]]* %[[DST_0_0]], %[[DST_I_J]]
+    // CHECK: %[[T0:.*]] = phi %[[A]]*
+    // CHECK: %[[T1:.*]] = getelementptr inbounds %[[A]], %[[A]]* %[[T0]], i64 -1
+    // CHECK: call void @_ZN7pr285951AD1Ev(%[[A]]* %[[T1]])
+    // CHECK: icmp eq %[[A]]* %[[T1]], %[[DST_0_0]]
     (void) [array]{};
-
-    //   Skip over the initialization loop.
-    // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [5 x [[A]]]], [3 x [5 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
   }
 }
 
diff --git a/test/CodeGenCXX/linetable-cleanup.cpp b/test/CodeGenCXX/linetable-cleanup.cpp
index fbef05e..748f056 100644
--- a/test/CodeGenCXX/linetable-cleanup.cpp
+++ b/test/CodeGenCXX/linetable-cleanup.cpp
@@ -1,10 +1,12 @@
 // RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++98 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++11 %s -o - | FileCheck %s
 
 // Check the line numbers for cleanup code with EH in combination with
 // simple return expressions.
 
 // CHECK: define {{.*}}foo
-// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}), !dbg ![[RET:[0-9]+]]
+// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}){{( #[0-9])?}}, !dbg ![[RET:[0-9]+]]
 // CHECK: ret i32 0, !dbg ![[RET]]
 
 // CHECK: define {{.*}}bar
diff --git a/test/CodeGenCXX/linkage.cpp b/test/CodeGenCXX/linkage.cpp
index 60e53c6..69b4262 100644
--- a/test/CodeGenCXX/linkage.cpp
+++ b/test/CodeGenCXX/linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -O1 -disable-llvm-optzns %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -O1 -disable-llvm-passes %s -o - | FileCheck %s
 
 namespace test1 {
   // CHECK-DAG: define linkonce_odr void @_ZN5test11fIZNS_1gEvE1SEEvT_(
diff --git a/test/CodeGenCXX/lpad-linetable.cpp b/test/CodeGenCXX/lpad-linetable.cpp
index 6923669..9b429bc 100644
--- a/test/CodeGenCXX/lpad-linetable.cpp
+++ b/test/CodeGenCXX/lpad-linetable.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -fcxx-exceptions -fexceptions -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+// RUN: %clang_cc1  -fcxx-exceptions -fexceptions -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++98 %s -o - | FileCheck %s
 // The landing pad should have the line number of the closing brace of the function.
 // rdar://problem/13888152
 // CHECK: ret i32
diff --git a/test/CodeGenCXX/main-norecurse.cpp b/test/CodeGenCXX/main-norecurse.cpp
index 0f36402..a98677c 100644
--- a/test/CodeGenCXX/main-norecurse.cpp
+++ b/test/CodeGenCXX/main-norecurse.cpp
@@ -5,4 +5,4 @@
     return 1;
 }
 
-// CHECK: attributes #0 = { norecurse{{.*}} }
+// CHECK: attributes #0 = { noinline norecurse{{.*}} }
diff --git a/test/CodeGenCXX/mangle-ms-cxx11.cpp b/test/CodeGenCXX/mangle-ms-cxx11.cpp
index f21012b..819b0d9 100644
--- a/test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ b/test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -343,3 +343,7 @@
 
 int call_it = (A::default_args(), 1);
 }
+
+enum { enumerator };
+void f(decltype(enumerator)) {}
+// CHECK-DAG: define void @"\01?f@@YAXW4<unnamed-enum-enumerator>@@@Z"(
diff --git a/test/CodeGenCXX/mangle-unnamed.cpp b/test/CodeGenCXX/mangle-unnamed.cpp
index 43b7bd7..c90f47b 100644
--- a/test/CodeGenCXX/mangle-unnamed.cpp
+++ b/test/CodeGenCXX/mangle-unnamed.cpp
@@ -48,6 +48,7 @@
   return a;
 }
 
+#if __cplusplus <= 199711L
 int f6() {
   static union {
     union {
@@ -56,9 +57,10 @@
     int b;
   };
   
-  // CHECK: _ZZ2f6vE1b
+  // CXX98: _ZZ2f6vE1b
   return b;
 }
+#endif
 
 int f7() {
   static union {
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 3a94071..91fe6ae 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -1125,3 +1125,15 @@
   // CHECK-LABEL: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fIXLi0EEEET_E
   template void f<0>(int);
 }
+
+namespace test58 {
+  struct State {
+   bool m_fn1();
+  } a;
+  template <class T> struct identity { typedef T type; };
+  struct A {
+   template <typename T> A(T, bool (identity<T>::type::*)());
+  };
+  // CHECK-LABEL: @_ZN6test581AC1INS_5StateEEET_MNS_8identityIS3_E4typeEFbvE
+  void fn1() { A(a, &State::m_fn1); }
+}
diff --git a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
index 9ef1879..146a6c8 100644
--- a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
+++ b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
@@ -68,4 +68,4 @@
 void delete_s(S *s) { delete[] s; }
 }
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
index 319f39c..6972dac 100644
--- a/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
@@ -7,7 +7,7 @@
 };
 
 A a(42);
-// CHECK: @"\01?a@@3UA@@A" = global { [1 x i8*]*, i32 } { [1 x i8*]* @"\01??_7A@@6B@", i32 42 }, align 4
+// CHECK: @"\01?a@@3UA@@A" = global { { [1 x i8*] }*, i32 } { { [1 x i8*] }* @"\01??_7A@@6B@", i32 42 }, align 4
 
 struct B {
   constexpr B(int y) : y(y) {}
@@ -20,4 +20,4 @@
 };
 
 C c;
-// CHECK: @"\01?c@@3UC@@A" = global { [1 x i8*]*, i32, [1 x i8*]*, i32 } { [1 x i8*]* @"\01??_7C@@6BA@@@", i32 777, [1 x i8*]* @"\01??_7C@@6BB@@@", i32 13 }
+// CHECK: @"\01?c@@3UC@@A" = global { { [1 x i8*] }*, i32, { [1 x i8*] }*, i32 } { { [1 x i8*] }* @"\01??_7C@@6BA@@@", i32 777, { [1 x i8*] }* @"\01??_7C@@6BB@@@", i32 13 }
diff --git a/test/CodeGenCXX/microsoft-abi-default-cc.cpp b/test/CodeGenCXX/microsoft-abi-default-cc.cpp
index e3ca392..6259a53 100644
--- a/test/CodeGenCXX/microsoft-abi-default-cc.cpp
+++ b/test/CodeGenCXX/microsoft-abi-default-cc.cpp
@@ -45,3 +45,12 @@
 void static_qux() {}
 // GCABI-LABEL: define void @_Z10static_quxv
 // MSABI: define void @"\01?static_qux@@YAXXZ"
+
+namespace PR31656 {
+template <int I>
+void __cdecl callee(int args[I]);
+// GCABI-LABEL: declare void @_ZN7PR316566calleeILi1EEEvPi(
+// MSABI: declare void @"\01??$callee@$00@PR31656@@YAXQAH@Z"(
+
+void caller() { callee<1>(0); }
+}
diff --git a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
index f03cd6c..f3e4307 100644
--- a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
+++ b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -138,6 +138,6 @@
 // CHECK:    [[CALL:%.*]] = invoke i8* @__RTDynamicCast
 
 // CHECK:    [[BC:%.*]] = bitcast i8* [[CALL]] to %"struct.PR25606::S3"*
-// CHECK:    call x86_thiscallcc void @"\01??_DCleanup@PR25606@@QAE@XZ"(
+// CHECK:    call x86_thiscallcc void @"\01??_DCleanup@PR25606@@QAEXXZ"(
 // CHECK:    ret %"struct.PR25606::S3"* [[BC]]
 }
diff --git a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
index ac1321e..6e18b92 100644
--- a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
+++ b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc \
 // RUN:     -mconstructor-aliases -fexceptions -fcxx-exceptions \
-// RUN:     -O1 -disable-llvm-optzns \
+// RUN:     -O1 -disable-llvm-passes \
 // RUN:     | FileCheck -check-prefix WIN64 %s
 
 extern "C" void might_throw();
diff --git a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
index 61cb3f4..79ac1e1 100644
--- a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
+++ b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-O0 %s
-// RUN: %clang_cc1 -std=c++11 -emit-llvm -O3 -disable-llvm-optzns %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-O3 -check-prefix WIN32-LIFETIME %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -O3 -disable-llvm-passes %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-O3 -check-prefix WIN32-LIFETIME %s
 
 struct A {
   A();
diff --git a/test/CodeGenCXX/microsoft-abi-extern-template.cpp b/test/CodeGenCXX/microsoft-abi-extern-template.cpp
index de46d5b..c69b4f5 100644
--- a/test/CodeGenCXX/microsoft-abi-extern-template.cpp
+++ b/test/CodeGenCXX/microsoft-abi-extern-template.cpp
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -fno-rtti-data -O1 -disable-llvm-optzns %s -emit-llvm -o - -triple x86_64-windows-msvc | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti-data -O1 -disable-llvm-passes %s -emit-llvm -o - -triple x86_64-windows-msvc | FileCheck %s
 
 // Even though Foo<int> has an extern template declaration, we have to emit our
 // own copy the vftable when emitting the available externally constructor.
 
-// CHECK: @"\01??_7?$Foo@H@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [
+// CHECK: @"\01??_7?$Foo@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [
 // CHECK-SAME:   i8* bitcast (i8* (%struct.Foo*, i32)* @"\01??_G?$Foo@H@@UEAAPEAXI@Z" to i8*)
-// CHECK-SAME: ], comdat
+// CHECK-SAME: ] }, comdat
 
 // CHECK-LABEL: define %struct.Foo* @"\01?f@@YAPEAU?$Foo@H@@XZ"()
 // CHECK: call %struct.Foo* @"\01??0?$Foo@H@@QEAA@XZ"(%struct.Foo* %{{.*}})
diff --git a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
index 34cb85e..f9db268 100644
--- a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
@@ -150,35 +150,35 @@
   Left l;
   // CHECK: define {{.*}} @"\01??0Left@@QAE@XZ"
   // CHECK-NOT: getelementptr
-  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Left@@6B@" to i32 (...)**)
+  // CHECK:   store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Left@@6B@" to i32 (...)**)
   // CHECK: ret
 
   Right r;
   // CHECK: define {{.*}} @"\01??0Right@@QAE@XZ"
   // CHECK-NOT: getelementptr
-  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Right@@6B@" to i32 (...)**)
+  // CHECK:   store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Right@@6B@" to i32 (...)**)
   // CHECK: ret
 
   ChildOverride co;
   // CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"
   // CHECK:   %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride**
   // CHECK:   %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)***
-  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+  // CHECK:   store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
   // CHECK:   %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
   // CHECK:   %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
   // CHECK:   %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
-  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+  // CHECK:   store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
   // CHECK: ret
 
   GrandchildOverride gc;
   // CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"
   // CHECK:   %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride**
   // CHECK:   %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)***
-  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+  // CHECK:   store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
   // CHECK:   %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
   // CHECK:   %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
   // CHECK:   %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
-  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+  // CHECK:   store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
   // CHECK: ret
 }
 
diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index 7eea41c..eaae349 100644
--- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -64,6 +64,10 @@
   int a, b, c, d, e, f;
 };
 
+struct BaseNoByval : Small {
+  int bb;
+};
+
 // WIN32: declare void @"{{.*take_bools_and_chars.*}}"
 // WIN32:       (<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor,
 // WIN32:           i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca)
@@ -127,6 +131,12 @@
 // WIN64: define void @"\01?medium_arg@@YAXUMedium@@@Z"(i64 %s.coerce)
 // WOA: define arm_aapcs_vfpcc void @"\01?medium_arg@@YAXUMedium@@@Z"([2 x i32] %s.coerce)
 
+void base_no_byval_arg(BaseNoByval s) {}
+// LINUX-LABEL: define void @_Z17base_no_byval_arg11BaseNoByval(%struct.BaseNoByval* byval align 4 %s)
+// WIN32: define void @"\01?base_no_byval_arg@@YAXUBaseNoByval@@@Z"(i32 %s.0, i32 %s.1)
+// WIN64: define void @"\01?base_no_byval_arg@@YAXUBaseNoByval@@@Z"(i64 %s.coerce)
+// WOA: define arm_aapcs_vfpcc void @"\01?base_no_byval_arg@@YAXUBaseNoByval@@@Z"([2 x i32] %s.coerce)
+
 void small_arg_with_ctor(SmallWithCtor s) {}
 // LINUX-LABEL: define void @_Z19small_arg_with_ctor13SmallWithCtor(%struct.SmallWithCtor* byval align 4 %s)
 // WIN32: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.0)
diff --git a/test/CodeGenCXX/microsoft-abi-structors-alias.cpp b/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
index 08df374..4eb757a 100644
--- a/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fno-rtti -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fno-rtti -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck %s
 
 namespace test1 {
 template <typename T> class A {
diff --git a/test/CodeGenCXX/microsoft-abi-structors.cpp b/test/CodeGenCXX/microsoft-abi-structors.cpp
index cd453b6..4de6c33 100644
--- a/test/CodeGenCXX/microsoft-abi-structors.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -77,7 +77,7 @@
   C c;
 // The vftable pointer should point at the beginning of the vftable.
 // CHECK: [[THIS_PTR:%[0-9]+]] = bitcast %"struct.basic::C"* {{.*}} to i32 (...)***
-// CHECK: store i32 (...)** bitcast ([2 x i8*]* @"\01??_7C@basic@@6B@" to i32 (...)**), i32 (...)*** [[THIS_PTR]]
+// CHECK: store i32 (...)** bitcast ({ [2 x i8*] }* @"\01??_7C@basic@@6B@" to i32 (...)**), i32 (...)*** [[THIS_PTR]]
 }
 
 void call_complete_dtor(C *obj_ptr) {
@@ -207,7 +207,7 @@
 void foo() {
   F f;
 }
-// DTORS3-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DF@test2@@UAE@XZ"({{.*}} {{.*}} comdat
+// DTORS3-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DF@test2@@QAEXXZ"({{.*}} {{.*}} comdat
 //      Do an adjustment from C* to F*.
 // DTORS3:   getelementptr i8, i8* %{{.*}}, i32 20
 // DTORS3:   bitcast i8* %{{.*}} to %"struct.test2::F"*
@@ -361,12 +361,12 @@
 void call_vbase_complete(D *d) {
   d->~D();
 // CHECK: define void @"\01?call_vbase_complete@dtors@@YAXPAUD@1@@Z"
-// CHECK: call x86_thiscallcc void @"\01??_DD@dtors@@QAE@XZ"(%"struct.dtors::D"* %{{[^,]+}})
+// CHECK: call x86_thiscallcc void @"\01??_DD@dtors@@QAEXXZ"(%"struct.dtors::D"* %{{[^,]+}})
 // CHECK: ret
 }
 
 // The complete dtor should call the base dtors for D and the vbase A (once).
-// CHECK: define linkonce_odr x86_thiscallcc void @"\01??_DD@dtors@@QAE@XZ"({{.*}}) {{.*}} comdat
+// CHECK: define linkonce_odr x86_thiscallcc void @"\01??_DD@dtors@@QAEXXZ"({{.*}}) {{.*}} comdat
 // CHECK-NOT: call
 // CHECK: call x86_thiscallcc void @"\01??1D@dtors@@QAE@XZ"
 // CHECK-NOT: call
@@ -377,7 +377,7 @@
 void destroy_d_complete() {
   D d;
 // CHECK: define void @"\01?destroy_d_complete@dtors@@YAXXZ"
-// CHECK: call x86_thiscallcc void @"\01??_DD@dtors@@QAE@XZ"(%"struct.dtors::D"* %{{[^,]+}})
+// CHECK: call x86_thiscallcc void @"\01??_DD@dtors@@QAEXXZ"(%"struct.dtors::D"* %{{[^,]+}})
 // CHECK: ret
 }
 
@@ -387,7 +387,7 @@
 void call_nv_deleting_dtor(D *d) {
   delete d;
 // CHECK: define void @"\01?call_nv_deleting_dtor@dtors@@YAXPAUD@1@@Z"
-// CHECK: call x86_thiscallcc void @"\01??_DD@dtors@@QAE@XZ"(%"struct.dtors::D"* %{{[^,]+}})
+// CHECK: call x86_thiscallcc void @"\01??_DD@dtors@@QAEXXZ"(%"struct.dtors::D"* %{{[^,]+}})
 // CHECK: call void @"\01??3@YAXPAX@Z"
 // CHECK: ret
 }
diff --git a/test/CodeGenCXX/microsoft-abi-throw.cpp b/test/CodeGenCXX/microsoft-abi-throw.cpp
index 7c2e2a8..51076f8 100644
--- a/test/CodeGenCXX/microsoft-abi-throw.cpp
+++ b/test/CodeGenCXX/microsoft-abi-throw.cpp
@@ -12,7 +12,7 @@
 // CHECK-DAG: @"\01??_R0?AUV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUV@@\00" }, comdat
 // CHECK-DAG: @"_CT??_R0?AUV@@@81044" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUV@@@8" to i8*), i32 0, i32 4, i32 4, i32 1, i8* null }, section ".xdata", comdat
 // CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44", %eh.CatchableType* @"_CT??_R0?AUM@@@818", %eh.CatchableType* @"_CT??_R0?AUV@@@81044"] }, section ".xdata", comdat
-// CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAE@XZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAEXXZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CT??_R0?AUDefault@@@8??_ODefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor13* @"\01??_R0?AUDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Default*, %struct.Default*)* @"\01??_ODefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"\01??_R0?AUVariadic@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Variadic*, %struct.Variadic*)* @"\01??_OVariadic@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor25* @"\01??_R0?AUTemplateWithDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.TemplateWithDefault*, %struct.TemplateWithDefault*)* @"\01??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
diff --git a/test/CodeGenCXX/microsoft-abi-vftables.cpp b/test/CodeGenCXX/microsoft-abi-vftables.cpp
index 0c9b58b..968955f 100644
--- a/test/CodeGenCXX/microsoft-abi-vftables.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=NO-RTTI
-// RUN: %clang_cc1 %s -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=RTTI
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck %s -check-prefix=NO-RTTI
+// RUN: %clang_cc1 %s -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck %s -check-prefix=RTTI
 
 // RTTI-DAG: $"\01??_7S@@6B@" = comdat largest
 // RTTI-DAG: $"\01??_7V@@6B@" = comdat largest
@@ -8,38 +8,38 @@
   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 i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_S]], i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_S:@.*]] = private unnamed_addr constant { [2 x i8*] } { [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 i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_S]], i32 0, 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*)]
+// NO-RTTI-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)] }
 
 struct __declspec(dllimport) U {
   virtual ~U();
 } u;
 
-// RTTI-DAG: [[VTABLE_U:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4U@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
-// RTTI-DAG: @"\01??_SU@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_U]], i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_U:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4U@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)] }
+// RTTI-DAG: @"\01??_SU@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_U]], i32 0, i32 0, i32 1)
 
-// NO-RTTI-DAG: @"\01??_SU@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
+// NO-RTTI-DAG: @"\01??_SU@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [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 i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_V]], i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_V:@.*]] = private unnamed_addr constant { [2 x i8*] } { [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 i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_V]], i32 0, 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*)]
+// NO-RTTI-DAG: @"\01??_7V@@6B@" = weak_odr dllexport unnamed_addr constant { [1 x i8*] } { [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@" = internal unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_W]], i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant { [2 x i8*] } { [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@" = internal unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_W]], i32 0, 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*)]
+// NO-RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)] }
 
 struct X {};
 template <class> struct Y : virtual X {
@@ -49,7 +49,7 @@
 
 extern template class Y<int>;
 template Y<int>::Y();
-// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$Y@H@@6B@" to i8*), i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)], comdat($"\01??_7?$Y@H@@6B@")
-// RTTI-DAG: @"\01??_7?$Y@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_Y]], i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$Y@H@@6B@" to i8*), i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)] }, comdat($"\01??_7?$Y@H@@6B@")
+// RTTI-DAG: @"\01??_7?$Y@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_Y]], i32 0, i32 0, i32 1)
 
-// NO-RTTI-DAG: @"\01??_7?$Y@H@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)], comdat
+// NO-RTTI-DAG: @"\01??_7?$Y@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)] }, comdat
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
index eaf1e3d..20ecaf4 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -33,7 +33,7 @@
   // CHECK:   %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
   // CHECK:   %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
   // CHECK:   %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
-  // CHECK:   store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+  // CHECK:   store i32 (...)** bitcast ({ [3 x i8*] }* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
 
   // Initialize vtorDisp:
   // CHECK:   %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
@@ -66,7 +66,7 @@
   // CHECK:   %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
   // CHECK:   %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
   // CHECK:   %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
-  // CHECK:   store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+  // CHECK:   store i32 (...)** bitcast ({ [3 x i8*] }* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
 
   // Initialize vtorDisp:
   // CHECK:   %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
@@ -84,7 +84,7 @@
 
   // CHECK: ret
 
-  // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B*
+  // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B*
   // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** {{.*}}
   // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
   // CHECK2: %[[B_i8:.*]] = getelementptr i8, i8* %[[THIS_i8]], i32 8
@@ -102,7 +102,7 @@
   // CHECK2:   %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
   // CHECK2:   store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4
   // CHECK2:   %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
-  // CHECK2:   call x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* %[[THIS]])
+  // CHECK2:   call x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* %[[THIS]])
   // ...
   // CHECK2: ret
 }
@@ -208,7 +208,7 @@
   B b;
   // CHECK: call x86_thiscallcc %struct.B* @"\01??0B@@QAE@XZ"(%struct.B* %[[B:.*]], i32 1)
   // CHECK-NOT: getelementptr
-  // CHECK: call x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* %[[B]])
+  // CHECK: call x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* %[[B]])
   // CHECK: ret
 }
 
@@ -245,9 +245,9 @@
 D::D() {
   // CHECK-LABEL: define x86_thiscallcc %"struct.multiple_vbases::D"* @"\01??0D@multiple_vbases@@QAE@XZ"
   // Just make sure we emit 3 vtordisps after initializing vfptrs.
-  // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BA@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
-  // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BB@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
-  // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BC@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+  // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7D@multiple_vbases@@6BA@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+  // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7D@multiple_vbases@@6BB@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+  // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7D@multiple_vbases@@6BC@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
   // ...
   // CHECK: store i32 %{{.*}}, i32* %{{.*}}
   // CHECK: store i32 %{{.*}}, i32* %{{.*}}
@@ -397,7 +397,7 @@
   // CHECK-NOT: getelementptr
   // CHECK-NOT: bitcast
   // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to i32 (...)***
-  // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7C@test4@@6BB@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
+  // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7C@test4@@6BB@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
 
   foo(this);
   // CHECK: ret
@@ -432,7 +432,7 @@
   // CHECK-NOT: getelementptr
   // CHECK-NOT: bitcast
   // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to i32 (...)***
-  // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7E@test4@@6BD@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
+  // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7E@test4@@6BD@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
   foo(this);
 }
 
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
index d223448..2bf7da5 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
@@ -26,7 +26,7 @@
 // VFTABLES-NEXT:       [return adjustment (to type 'struct test1::C *'): 0 non-virtual]
 // VFTABLES-NEXT:   2 | test1::D *test1::J::foo()
 
-// GLOBALS-LABEL: @"\01??_7J@test1@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
+// GLOBALS-LABEL: @"\01??_7J@test1@@6B@" = linkonce_odr unnamed_addr constant { [3 x i8*] }
 // GLOBALS: @"\01?foo@J@test1@@QAEPAUB@2@XZ"
 // GLOBALS: @"\01?foo@J@test1@@QAEPAUC@2@XZ"
 // GLOBALS: @"\01?foo@J@test1@@UAEPAUD@2@XZ"
@@ -44,7 +44,7 @@
 
 // Only B to C requires adjustment, but we get 3 thunks in K's vftable, two of
 // which are trivial.
-// GLOBALS-LABEL: @"\01??_7K@test1@@6B@" = linkonce_odr unnamed_addr constant [4 x i8*]
+// GLOBALS-LABEL: @"\01??_7K@test1@@6B@" = linkonce_odr unnamed_addr constant { [4 x i8*] }
 // GLOBALS: @"\01?foo@K@test1@@QAEPAUB@2@XZ"
 // GLOBALS: @"\01?foo@K@test1@@QAEPAUC@2@XZ"
 // GLOBALS: @"\01?foo@K@test1@@QAEPAUD@2@XZ"
@@ -90,7 +90,7 @@
 // VFTABLES-NEXT:         [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
 // VFTABLES-NEXT:    1 | test2::D *test2::J::foo()
 
-// GLOBALS-LABEL: @"\01??_7J@test2@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// GLOBALS-LABEL: @"\01??_7J@test2@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
 
 K::K() {}
 
@@ -101,7 +101,7 @@
 // VFTABLES-NEXT:         [return adjustment (to type 'struct test2::D *'): 0 non-virtual]
 // VFTABLES-NEXT:    2 | test2::E *test2::K::foo()
 
-// GLOBALS-LABEL: @"\01??_7K@test2@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
+// GLOBALS-LABEL: @"\01??_7K@test2@@6B@" = linkonce_odr unnamed_addr constant { [3 x i8*] }
 
 }
 
@@ -124,7 +124,7 @@
 
 C::C() {}
 
-// GLOBALS-LABEL: @"\01??_7C@pr20479@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// GLOBALS-LABEL: @"\01??_7C@pr20479@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
 // GLOBALS: @"\01?f@B@pr20479@@QAEPAUA@2@XZ"
 // GLOBALS: @"\01?f@B@pr20479@@UAEPAU12@XZ"
 }
@@ -151,7 +151,7 @@
 
 C::C() {}
 
-// GLOBALS-LABEL: @"\01??_7C@pr21073@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// GLOBALS-LABEL: @"\01??_7C@pr21073@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
 // GLOBALS: @"\01?f@B@pr21073@@WPPPPPPPI@AEPAUA@2@XZ"
 // GLOBALS: @"\01?f@B@pr21073@@WPPPPPPPI@AEPAU12@XZ"
 }
@@ -168,7 +168,7 @@
 // VFTABLES-NEXT:       [return adjustment (to type 'struct pr21073_2::A *'): vbase #1, 0 non-virtual]
 // VFTABLES-NEXT:   1 | pr21073_2::C *pr21073_2::C::foo()
 
-// GLOBALS-LABEL: @"\01??_7D@pr21073_2@@6B@" = {{.*}} constant [2 x i8*]
+// GLOBALS-LABEL: @"\01??_7D@pr21073_2@@6B@" = {{.*}} constant { [2 x i8*] }
 // GLOBALS: @"\01?foo@C@pr21073_2@@QAEPAUA@2@XZ"
 // GLOBALS: @"\01?foo@C@pr21073_2@@UAEPAU12@XZ"
 }
@@ -196,7 +196,7 @@
 // VFTABLES-NEXT:       [return adjustment (to type 'struct test3::D *'): 0 non-virtual]
 // VFTABLES-NEXT:       [this adjustment: vtordisp at -4, 0 non-virtual]
 
-// GLOBALS-LABEL: @"\01??_7D@test3@@6B@" = {{.*}} constant [3 x i8*]
+// GLOBALS-LABEL: @"\01??_7D@test3@@6B@" = {{.*}} constant { [3 x i8*] }
 // GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAUA@2@XZ"
 // GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAUB@2@XZ"
 // GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAU12@XZ"
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
index aa39d6d..738c15d 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
@@ -19,7 +19,7 @@
   int ia;
 };
 A a;
-// EMITS-VFTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
+// EMITS-VFTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant { [3 x i8*] }
 void use(A *obj) { obj->f(); }
 
 struct B : A {
@@ -39,7 +39,7 @@
   virtual void j();
 };
 B b;
-// EMITS-VFTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+// EMITS-VFTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant { [5 x i8*] }
 void use(B *obj) { obj->f(); }
 
 struct C {
@@ -69,7 +69,7 @@
   virtual ~D();
 };
 D d;
-// EMITS-VFTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// EMITS-VFTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
 void use(D *obj) { obj->f(); }
 
 struct E : A {
@@ -107,7 +107,7 @@
   virtual ~F();
 };
 F f;
-// EMITS-VFTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+// EMITS-VFTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant { [5 x i8*] }
 void use(F *obj) { obj->i(); }
 
 struct G : E {
@@ -295,7 +295,7 @@
   // CHECK-NEXT:   0 | void S::f() [deleted]
   virtual void f() = delete;
   S();
-  // EMITS-VFTABLE-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)]
+  // EMITS-VFTABLE-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)] }
 };
 
 S::S() {}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
index 83f8114..342a584 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
@@ -771,7 +771,7 @@
 };
 struct __declspec(dllexport) B : virtual A {
   virtual void f() = 0;
-  // MANGLING-DAG: @"\01??_7B@Test13@@6B@" = weak_odr dllexport unnamed_addr constant [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)]
+  // MANGLING-DAG: @"\01??_7B@Test13@@6B@" = weak_odr dllexport unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)] }
 };
 }
 
@@ -788,8 +788,8 @@
 // CHECK-LABEL: VFTable for 'pr21031_1::B' in 'pr21031_1::C' (1 entry)
 // CHECK-NEXT:   0 | void pr21031_1::B::g()
 
-// MANGLING-DAG: @"\01??_7C@pr21031_1@@6BB@1@@" = {{.*}} constant [1 x i8*]
-// MANGLING-DAG: @"\01??_7C@pr21031_1@@6B@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7C@pr21031_1@@6BB@1@@" = {{.*}} constant { [1 x i8*] }
+// MANGLING-DAG: @"\01??_7C@pr21031_1@@6B@" = {{.*}} constant { [1 x i8*] }
 }
 
 namespace pr21031_2 {
@@ -804,8 +804,8 @@
 // CHECK-LABEL: VFTable for 'pr21031_2::A' in 'pr21031_2::B' in 'pr21031_2::C' (1 entry)
 // CHECK-NEXT:   0 | void pr21031_2::A::f()
 
-// MANGLING-DAG: @"\01??_7C@pr21031_2@@6BA@1@@" = {{.*}} constant [1 x i8*]
-// MANGLING-DAG: @"\01??_7C@pr21031_2@@6BB@1@@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7C@pr21031_2@@6BA@1@@" = {{.*}} constant { [1 x i8*] }
+// MANGLING-DAG: @"\01??_7C@pr21031_2@@6BB@1@@" = {{.*}} constant { [1 x i8*] }
 }
 
 namespace pr21062_1 {
@@ -818,7 +818,7 @@
 // CHECK-LABEL: VFTable for 'pr21062_1::A' in 'pr21062_1::D' (1 entry)
 // CHECK-NEXT:   0 | void pr21062_1::A::f()
 
-// MANGLING-DAG: @"\01??_7D@pr21062_1@@6B@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7D@pr21062_1@@6B@" = {{.*}} constant { [1 x i8*] }
 }
 
 namespace pr21062_2 {
@@ -831,7 +831,7 @@
 // CHECK-LABEL: VFTable for 'pr21062_2::A' in 'pr21062_2::D' (1 entry)
 // CHECK-NEXT:   0 | void pr21062_2::A::f()
 
-// MANGLING-DAG: @"\01??_7D@pr21062_2@@6B@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7D@pr21062_2@@6B@" = {{.*}} constant { [1 x i8*] }
 }
 
 namespace pr21064 {
@@ -843,5 +843,5 @@
 // CHECK-LABEL: VFTable for 'pr21064::B' in 'pr21064::C' in 'pr21064::D' (1 entry)
 // CHECK-NEXT:   0 | void pr21064::B::f()
 
-// MANGLING-DAG: @"\01??_7D@pr21064@@6B@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7D@pr21064@@6B@" = {{.*}} constant { [1 x i8*] }
 }
diff --git a/test/CodeGenCXX/microsoft-interface.cpp b/test/CodeGenCXX/microsoft-interface.cpp
index 8f4670a..5f3a94a 100644
--- a/test/CodeGenCXX/microsoft-interface.cpp
+++ b/test/CodeGenCXX/microsoft-interface.cpp
@@ -17,7 +17,7 @@
   return s.test();
 }
 
-// CHECK: @_ZTV1S = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1S to i8*), i8* bitcast (i32 (%struct.S*)* @_ZN1S4testEv to i8*)]
+// CHECK: @_ZTV1S = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1S to i8*), i8* bitcast (i32 (%struct.S*)* @_ZN1S4testEv to i8*)] }
 
 // CHECK-LABEL: define i32 @_Z2fnv()
 // CHECK:   call x86_thiscallcc void @_ZN1SC1Ev(%struct.S* %s)
@@ -31,10 +31,10 @@
 
 // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @_ZN1SC2Ev(%struct.S* %this)
 // CHECK:   call x86_thiscallcc void @_ZN1IC2Ev(%__interface.I* %{{[.0-9A-Z_a-z]+}})
-// CHECK:   store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1S, i32 0, i32 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}}
+// CHECK:   store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1S, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}}
 
 // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @_ZN1IC2Ev(%__interface.I* %this)
-// CHECK:   store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1I, i32 0, i32 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}}
+// CHECK:   store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1I, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}}
 
 // CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @_ZN1I4testEv(%__interface.I* %this)
 // CHECK:   ret i32 1
diff --git a/test/CodeGenCXX/microsoft-no-rtti-data.cpp b/test/CodeGenCXX/microsoft-no-rtti-data.cpp
index 68fdf05..0525590 100644
--- a/test/CodeGenCXX/microsoft-no-rtti-data.cpp
+++ b/test/CodeGenCXX/microsoft-no-rtti-data.cpp
@@ -2,7 +2,7 @@
 
 // vftable shouldn't have RTTI data in it.
 // CHECK-NOT: @"\01??_R4S@@6B@"
-// CHECK: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)], comdat
+// CHECK: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)] }, comdat
 
 struct type_info;
 namespace std { using ::type_info; }
diff --git a/test/CodeGenCXX/modules-ts.cppm b/test/CodeGenCXX/modules-ts.cppm
index da3bcb2..90f6b53 100644
--- a/test/CodeGenCXX/modules-ts.cppm
+++ b/test/CodeGenCXX/modules-ts.cppm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fmodules-ts -std=c++1z -triple=x86_64-linux-gnu -emit-module-interface %s -o %t.pcm
+// RUN: %clang_cc1 -fmodules-ts -std=c++1z -triple=x86_64-linux-gnu -fmodules-codegen -emit-module-interface %s -o %t.pcm
 // RUN: %clang_cc1 -fmodules-ts -std=c++1z -triple=x86_64-linux-gnu %t.pcm -emit-llvm -o - | FileCheck %s
 
 module FooBar;
@@ -8,6 +8,9 @@
   int f() { return 0; }
 }
 
+// CHECK-LABEL: define weak_odr void @_Z2f2v(
+inline void f2() { }
+
 // FIXME: Emit global variables and their initializers with this TU.
 // Emit an initialization function that other TUs can call, with guard variable.
 
diff --git a/test/CodeGenCXX/new-array-init.cpp b/test/CodeGenCXX/new-array-init.cpp
index 0429ae7..ccc218e 100644
--- a/test/CodeGenCXX/new-array-init.cpp
+++ b/test/CodeGenCXX/new-array-init.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -fsanitize=signed-integer-overflow -o - | FileCheck --check-prefix=SIO %s
 
 // CHECK: @[[ABC4:.*]] = {{.*}} constant [4 x i8] c"abc\00"
 // CHECK: @[[ABC15:.*]] = {{.*}} constant [15 x i8] c"abc\00\00\00\00
@@ -116,3 +117,9 @@
   struct Aggr { int a, b; };
   new Aggr[n] { 1, 2, 3 };
 }
+
+// SIO-LABEL: define void @_Z14constexpr_testv
+void constexpr_test() {
+  // SIO: call i8* @_Zna{{.}}(i32 4)
+  new int[0+1]{0};
+}
diff --git a/test/CodeGenCXX/no-exceptions.cpp b/test/CodeGenCXX/no-exceptions.cpp
index ceb3b8e..b970ef2 100644
--- a/test/CodeGenCXX/no-exceptions.cpp
+++ b/test/CodeGenCXX/no-exceptions.cpp
@@ -11,4 +11,4 @@
   // CHECK: ret void
 }
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/no-lto-unit.cpp b/test/CodeGenCXX/no-lto-unit.cpp
new file mode 100644
index 0000000..24b8fd0
--- /dev/null
+++ b/test/CodeGenCXX/no-lto-unit.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -flto=thin -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
+// RUN: llvm-dis -o - %t | FileCheck %s
+// RUN: %clang_cc1 -flto=thin -flto-unit -fno-lto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
+// RUN: llvm-dis -o - %t | FileCheck %s
+
+// CHECK-NOT: !type
+class A {
+  virtual void f() {}
+};
+
+A *f() {
+  return new A;
+}
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index d8e5b13..d02206a 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-03 %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-11 %s
 
 // Test code generation for the named return value optimization.
 class X {
@@ -91,16 +92,18 @@
   // -> %eh.cleanup
 
   // %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
-  // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
+  // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
   // -> %eh.cleanup, %terminate.lpad
+  // CHECK-EH-11: call   {{.*}} @_ZN1XD1Ev
 
   // %if.end: returning 'y'
   // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
   // -> %cleanup, %lpad1
 
   // %cleanup: normal cleanup for 'y'
-  // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
+  // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
   // -> %invoke.cont11, %lpad
+  // CHECK-EH-11: call   {{.*}} @_ZN1XD1Ev
 
   // %invoke.cont11: normal cleanup for 'x'
   // CHECK-EH:      call void @llvm.lifetime.end
@@ -109,19 +112,20 @@
   // CHECK-EH-NEXT: ret void
 
   // %eh.cleanup:  EH cleanup for 'x'
-  // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
+  // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
   // -> %invoke.cont17, %terminate.lpad
+  // CHECK-EH-11: call   {{.*}} @_ZN1XD1Ev
 
   // %invoke.cont17: rethrow block for %eh.cleanup.
   // This really should be elsewhere in the function.
   // CHECK-EH:      resume { i8*, i32 }
 
   // %terminate.lpad: terminate landing pad.
-  // CHECK-EH:      [[T0:%.*]] = landingpad { i8*, i32 }
-  // CHECK-EH-NEXT:   catch i8* null
-  // CHECK-EH-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
-  // CHECK-EH-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
-  // CHECK-EH-NEXT: unreachable
+  // CHECK-EH-03:      [[T0:%.*]] = landingpad { i8*, i32 }
+  // CHECK-EH-03-NEXT:   catch i8* null
+  // CHECK-EH-03-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
+  // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
+  // CHECK-EH-03-NEXT: unreachable
 
 }
 
@@ -217,4 +221,4 @@
 // CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv
 // CHECK: tail call {{.*}} @_ZN1YIiEC1Ev
 
-// CHECK-EH: attributes [[NR_NUW]] = { noreturn nounwind }
+// CHECK-EH-03: attributes [[NR_NUW]] = { noreturn nounwind }
diff --git a/test/CodeGenCXX/optnone-class-members.cpp b/test/CodeGenCXX/optnone-class-members.cpp
index 751f3dd..b1d2f7b 100644
--- a/test/CodeGenCXX/optnone-class-members.cpp
+++ b/test/CodeGenCXX/optnone-class-members.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 < %s -triple %itanium_abi_triple -fms-extensions -emit-llvm -x c++ | FileCheck %s
+// RUN: %clang_cc1 < %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-passes -emit-llvm -x c++ | FileCheck %s
 
 // Test attribute 'optnone' on methods:
 //  -- member functions;
diff --git a/test/CodeGenCXX/optnone-def-decl.cpp b/test/CodeGenCXX/optnone-def-decl.cpp
index 0240189..6e4e510 100644
--- a/test/CodeGenCXX/optnone-def-decl.cpp
+++ b/test/CodeGenCXX/optnone-def-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-passes -emit-llvm -o - | FileCheck %s
 
 // Test optnone on both function declarations and function definitions.
 // Verify also that we don't generate invalid IR functions with
diff --git a/test/CodeGenCXX/partial-destruction.cpp b/test/CodeGenCXX/partial-destruction.cpp
index 4097fbf..a5a2f40 100644
--- a/test/CodeGenCXX/partial-destruction.cpp
+++ b/test/CodeGenCXX/partial-destruction.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -std=c++03 | FileCheck %s -check-prefixes=CHECK,CHECKv03
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -std=c++11 | FileCheck %s -check-prefixes=CHECK,CHECKv11
 
 // Test IR generation for partial destruction of aggregates.
 
@@ -45,7 +46,8 @@
   // CHECK-NEXT: br label
   // CHECK:      [[ED_AFTER:%.*]] = phi [[A]]* [ [[ED_END]], {{%.*}} ], [ [[ED_CUR:%.*]], {{%.*}} ]
   // CHECK-NEXT: [[ED_CUR]] = getelementptr inbounds [[A]], [[A]]* [[ED_AFTER]], i64 -1
-  // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]])
+  // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]])
+  // CHECKv11-NEXT: call   void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]])
   // CHECK:      [[T0:%.*]] = icmp eq [[A]]* [[ED_CUR]], [[ED_BEGIN]]
   // CHECK-NEXT: br i1 [[T0]],
   // CHECK:      ret void
@@ -58,7 +60,8 @@
   // CHECK-NEXT: br i1 [[T0]],
   // CHECK:      [[E_AFTER:%.*]] = phi [[A]]* [ [[PARTIAL_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ]
   // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]], [[A]]* [[E_AFTER]], i64 -1
-  // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+  // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+  // CHECKv11-NEXT: call   void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
   // CHECK:      [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E_BEGIN]]
   // CHECK-NEXT: br i1 [[T0]],
 
@@ -73,20 +76,21 @@
   // FIXME: There's some really bad block ordering here which causes
   // the partial destroy for the primary normal destructor to fall
   // within the primary EH destructor.
-  // CHECK:      landingpad { i8*, i32 }
-  // CHECK-NEXT:   cleanup
-  // CHECK:      [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]]
-  // CHECK-NEXT: br i1 [[T0]]
-  // CHECK:      [[EDD_AFTER:%.*]] = phi [[A]]* [ [[ED_CUR]], {{%.*}} ], [ [[EDD_CUR:%.*]], {{%.*}} ]
-  // CHECK-NEXT: [[EDD_CUR]] = getelementptr inbounds [[A]], [[A]]* [[EDD_AFTER]], i64 -1
-  // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[EDD_CUR]])
-  // CHECK:      [[T0:%.*]] = icmp eq [[A]]* [[EDD_CUR]], [[ED_BEGIN]]
-  // CHECK-NEXT: br i1 [[T0]]
+  // CHECKv03:      landingpad { i8*, i32 }
+  // CHECKv03-NEXT:   cleanup
+  // CHECKv03:      [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]]
+  // CHECKv03-NEXT: br i1 [[T0]]
+  // CHECKv03:      [[EDD_AFTER:%.*]] = phi [[A]]* [ [[ED_CUR]], {{%.*}} ], [ [[EDD_CUR:%.*]], {{%.*}} ]
+  // CHECKv03-NEXT: [[EDD_CUR]] = getelementptr inbounds [[A]], [[A]]* [[EDD_AFTER]], i64 -1
+  // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[EDD_CUR]])
+  // CHECKv03:      [[T0:%.*]] = icmp eq [[A]]* [[EDD_CUR]], [[ED_BEGIN]]
+  // CHECKv03-NEXT: br i1 [[T0]]
 
   // Back to the primary EH destructor.
   // CHECK:      [[E_AFTER:%.*]] = phi [[A]]* [ [[E_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ]
   // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]], [[A]]* [[E_AFTER]], i64 -1
-  // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+  // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+  // CHECKv11-NEXT: call   void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
   // CHECK:      [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E0]]
   // CHECK-NEXT: br i1 [[T0]],
 
@@ -120,8 +124,10 @@
   // CHECK-NEXT:   cleanup
   // CHECK:      landingpad { i8*, i32 }
   // CHECK-NEXT:   cleanup
-  // CHECK:      invoke void @_ZN5test11AD1Ev([[A]]* [[Y]])
-  // CHECK:      invoke void @_ZN5test11AD1Ev([[A]]* [[X]])
+  // CHECKv03:      invoke void @_ZN5test11AD1Ev([[A]]* [[Y]])
+  // CHECKv03:      invoke void @_ZN5test11AD1Ev([[A]]* [[X]])
+  // CHECKv11:      call   void @_ZN5test11AD1Ev([[A]]* [[Y]])
+  // CHECKv11:      call   void @_ZN5test11AD1Ev([[A]]* [[X]])
 }
 
 namespace test2 {
@@ -153,7 +159,8 @@
     // CHECK-NEXT: br i1 [[EMPTY]],
     // CHECK:      [[PAST:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[DEL:%.*]], {{%.*}} ]
     // CHECK-NEXT: [[DEL]] = getelementptr inbounds [[A]], [[A]]* [[PAST]], i64 -1
-    // CHECK-NEXT: invoke void @_ZN5test21AD1Ev([[A]]* [[DEL]])
+    // CHECKv03-NEXT: invoke void @_ZN5test21AD1Ev([[A]]* [[DEL]])
+    // CHECKv11-NEXT: call   void @_ZN5test21AD1Ev([[A]]* [[DEL]])
     // CHECK:      [[T0:%.*]] = icmp eq [[A]]* [[DEL]], [[BEGIN]]
     // CHECK-NEXT: br i1 [[T0]],
   }
diff --git a/test/CodeGenCXX/pr24097.cpp b/test/CodeGenCXX/pr24097.cpp
index 122bf88..cdf78d2 100644
--- a/test/CodeGenCXX/pr24097.cpp
+++ b/test/CodeGenCXX/pr24097.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -fvisibility hidden -emit-llvm -O1 -disable-llvm-optzns -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -fvisibility hidden -emit-llvm -O1 -disable-llvm-passes -o - | FileCheck %s
 
 struct Filter {
   virtual void Foo();
diff --git a/test/CodeGenCXX/pr31054.cpp b/test/CodeGenCXX/pr31054.cpp
new file mode 100644
index 0000000..33b17b9
--- /dev/null
+++ b/test/CodeGenCXX/pr31054.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+struct A { ~A(); };
+void func() {
+  return;
+  static A k;
+}
+
+// Test that we did not crash, by checking whether function was created.
+// CHECK-LABEL: define void @_Z4funcv() #0 {
+// CHECK: ret void
+// CHECK: }
diff --git a/test/CodeGenCXX/reference-cast.cpp b/test/CodeGenCXX/reference-cast.cpp
index 02498a3..54faa64 100644
--- a/test/CodeGenCXX/reference-cast.cpp
+++ b/test/CodeGenCXX/reference-cast.cpp
@@ -193,4 +193,4 @@
   // CHECK: store i64
 }
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/reference-init.cpp b/test/CodeGenCXX/reference-init.cpp
index 3a3eaee..ba7b282 100644
--- a/test/CodeGenCXX/reference-init.cpp
+++ b/test/CodeGenCXX/reference-init.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - -std=c++98 | FileCheck %s --check-prefix=CHECK-CXX98
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - -std=c++11 | FileCheck %s --check-prefix=CHECK-CXX11
 // expected-no-diagnostics
 
 struct XPTParamDescriptor {};
@@ -23,3 +25,12 @@
 // Binding to a bit-field that requires a temporary. 
 struct { int bitfield : 3; } s = { 3 };
 const int &s2 = s.bitfield;
+
+// In C++98, this forms a reference to itself. In C++11 onwards, this performs
+// copy-construction.
+struct SelfReference { SelfReference &r; };
+extern SelfReference self_reference_1;
+SelfReference self_reference_2 = {self_reference_1};
+// CHECK-CXX98: @self_reference_2 = global %[[SELF_REF:.*]] { %[[SELF_REF]]* @self_reference_1 }
+// CHECK-CXX11: @self_reference_2 = global %[[SELF_REF:.*]] zeroinitializer
+// CHECK-CXX11: call {{.*}}memcpy{{.*}} @self_reference_2 {{.*}} @self_reference_1
diff --git a/test/CodeGenCXX/regcall.cpp b/test/CodeGenCXX/regcall.cpp
index 0cc6ad0..0ff6fdf 100644
--- a/test/CodeGenCXX/regcall.cpp
+++ b/test/CodeGenCXX/regcall.cpp
@@ -47,8 +47,8 @@
   // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD2Ev
   // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD1Ev
   // Windows ignores calling convention on constructor/destructors.
-  // CHECK-WIN64-DAG: define linkonce_odr void @"\01??_Dtest_class@@QEAA@XZ"
-  // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_Dtest_class@@QAE@XZ"
+  // CHECK-WIN64-DAG: define linkonce_odr void @"\01??_Dtest_class@@QEAAXXZ"
+  // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_Dtest_class@@QAEXXZ"
   
   test_class& __regcall operator+=(const test_class&){
     return *this;
diff --git a/test/CodeGenCXX/return.cpp b/test/CodeGenCXX/return.cpp
index 5c1cfda..584c292 100644
--- a/test/CodeGenCXX/return.cpp
+++ b/test/CodeGenCXX/return.cpp
@@ -1,12 +1,103 @@
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -O -o - %s | FileCheck %s --check-prefix=CHECK-OPT
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK,CHECK-COMMON %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -O -o - %s | FileCheck %s --check-prefixes=CHECK-OPT,CHECK-COMMON
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT,CHECK-COMMON
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -Wno-return-type -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT,CHECK-COMMON
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -O -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT-OPT,CHECK-COMMON
 
-// CHECK:     @_Z9no_return
-// CHECK-OPT: @_Z9no_return
+// CHECK-COMMON-LABEL: @_Z9no_return
 int no_return() {
   // CHECK:      call void @llvm.trap
   // CHECK-NEXT: unreachable
 
   // CHECK-OPT-NOT: call void @llvm.trap
   // CHECK-OPT:     unreachable
+
+  // -fno-strict-return should not emit trap + unreachable but it should return
+  // an undefined value instead.
+
+  // CHECK-NOSTRICT: alloca
+  // CHECK-NOSTRICT-NEXT: load
+  // CHECK-NOSTRICT-NEXT: ret i32
+  // CHECK-NOSTRICT-NEXT: }
+
+  // CHECK-NOSTRICT-OPT: ret i32 undef
+}
+
+enum Enum {
+  A, B
+};
+
+// CHECK-COMMON-LABEL: @_Z27returnNotViableDontOptimize4Enum
+int returnNotViableDontOptimize(Enum e) {
+  switch (e) {
+  case A: return 1;
+  case B: return 2;
+  }
+  // Undefined behaviour optimization shouldn't be used when -fno-strict-return
+  // is turned on, even if all the enum cases are covered in this function.
+
+  // CHECK-NOSTRICT-NOT: call void @llvm.trap
+  // CHECK-NOSTRICT-NOT: unreachable
+}
+
+struct Trivial {
+  int x;
+};
+
+// CHECK-NOSTRICT-LABEL: @_Z7trivialv
+Trivial trivial() {
+  // This function returns a trivial record so -fno-strict-return should avoid
+  // the undefined behaviour optimization.
+
+  // CHECK-NOSTRICT-NOT: call void @llvm.trap
+  // CHECK-NOSTRICT-NOT: unreachable
+}
+
+struct NonTrivialCopy {
+  NonTrivialCopy(const NonTrivialCopy &);
+};
+
+// CHECK-NOSTRICT-LABEL: @_Z14nonTrivialCopyv
+NonTrivialCopy nonTrivialCopy() {
+  // CHECK-NOSTRICT-NOT: call void @llvm.trap
+  // CHECK-NOSTRICT-NOT: unreachable
+}
+
+struct NonTrivialDefaultConstructor {
+  int x;
+
+  NonTrivialDefaultConstructor() { }
+};
+
+// CHECK-NOSTRICT-LABEL: @_Z28nonTrivialDefaultConstructorv
+NonTrivialDefaultConstructor nonTrivialDefaultConstructor() {
+  // CHECK-NOSTRICT-NOT: call void @llvm.trap
+  // CHECK-NOSTRICT-NOT: unreachable
+}
+
+// Functions that return records with non-trivial destructors should always use
+// the -fstrict-return optimization.
+
+struct NonTrivialDestructor {
+  ~NonTrivialDestructor();
+};
+
+// CHECK-NOSTRICT-LABEL: @_Z20nonTrivialDestructorv
+NonTrivialDestructor nonTrivialDestructor() {
+  // CHECK-NOSTRICT: call void @llvm.trap
+  // CHECK-NOSTRICT-NEXT: unreachable
+}
+
+// The behavior for lambdas should be identical to functions.
+// CHECK-COMMON-LABEL: @_Z10lambdaTestv
+void lambdaTest() {
+  auto lambda1 = []() -> int {
+  };
+  lambda1();
+
+  // CHECK: call void @llvm.trap
+  // CHECK-NEXT: unreachable
+
+  // CHECK-NOSTRICT-NOT: call void @llvm.trap
+  // CHECK-NOSTRICT-NOT: unreachable
 }
diff --git a/test/CodeGenCXX/runtime-dllstorage.cpp b/test/CodeGenCXX/runtime-dllstorage.cpp
new file mode 100644
index 0000000..76c002c
--- /dev/null
+++ b/test/CodeGenCXX/runtime-dllstorage.cpp
@@ -0,0 +1,158 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-MS -check-prefix CHECK-MS-DYNAMIC
+// RUN: %clang_cc1 -triple i686-windows-msvc -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-MS -check-prefix CHECK-MS-STATIC
+
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-NODECL-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-NODECL-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -DIMPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-IMPORT-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -DIMPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-IMPORT-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -DEXPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -DEXPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -DDECL -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-DECL-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -DDECL -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-DECL-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-IA-ATEXIT
+// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-IA-ATEXIT
+
+// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
+// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
+// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
+// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
+
+#if defined(IMPORT_DECLARATIONS)
+namespace __cxxabiv1 {
+extern "C" {
+__declspec(dllimport) void __cxa_guard_acquire(unsigned long long *);
+__declspec(dllimport) unsigned char *__cxa_allocate_exception(unsigned long);
+}
+extern "C" __declspec(dllimport) void __cxa_guard_release(unsigned long long *);
+}
+namespace std {
+__declspec(dllimport) __declspec(noreturn) void terminate();
+}
+#elif defined(EXPORT_DECLARATIONS)
+namespace __cxxabiv1 {
+extern "C" {
+__declspec(dllexport) void __cxa_guard_acquire(unsigned long long *);
+__declspec(dllexport) unsigned char *__cxa_allocate_exception(unsigned long);
+}
+extern "C" void __declspec(dllexport) __cxa_guard_release(unsigned long long *);
+}
+namespace std {
+__declspec(dllexport) __declspec(noreturn) void terminate();
+}
+#elif defined(DECL)
+namespace __cxxabiv1 {
+extern "C" unsigned char *__cxa_allocate_exception(unsigned long);
+}
+namespace std {
+__declspec(noreturn) void terminate();
+}
+#else
+namespace std {
+__declspec(noreturn) void terminate();
+}
+#endif
+
+struct s {
+  s() = default;
+  s(unsigned char) { throw 0; }
+  int m() const;
+};
+
+struct t {
+  ~t();
+  int m() const;
+};
+
+struct u {
+  ~u();
+};
+
+s o;
+thread_local t t;
+u v;
+__declspec(thread) s q;
+
+void __declspec(noinline) f() {
+  throw 0;
+}
+
+void g();
+void __declspec(noinline) h() {
+  try {
+    g();
+  } catch (const int &) {
+    return;
+  } catch (...) {
+    throw;
+  }
+}
+
+void i() {
+  s r(static_cast<unsigned char>('\t'));
+}
+
+int j() {
+  static thread_local struct t v;
+  static struct t *w = new struct t;
+  return w->m() ? v.m() : w->m();
+}
+
+void k() noexcept {
+  g();
+}
+
+void l() {
+  std::terminate();
+}
+
+// CHECK-MS-DAG: @_Init_thread_epoch = external thread_local global i32
+// CHECK-MS-DAG: declare i32 @__tlregdtor(void ()*)
+// CHECK-MS-DAG: declare i32 @atexit(void ()*)
+// CHECK-MS-DYNAMIC-DAG: declare dllimport {{.*}} void @_CxxThrowException
+// CHECK-MS-STATIC-DAG: declare {{.*}} void @_CxxThrowException
+// CHECK-MS-DAG: declare noalias i8* @"\01??2@YAPAXI@Z"
+// CHECK-MS-DAG: declare void @_Init_thread_header(i32*)
+// CHECK-MS-DAG: declare void @_Init_thread_footer(i32*)
+
+// CHECK-IA-DAG: declare i32 @__gxx_personality_v0(...)
+// CHECK-IA-DAG: define linkonce_odr hidden void @__clang_call_terminate(i8*)
+
+// CHECK-DYNAMIC-IA-DAG: declare dllimport i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
+// CHECK-DYNAMIC-IA-DAG: declare dllimport i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+// CHECK-DYNAMIC-IA-DECL-DAG: declare i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-NODECL-DAG: declare dllimport i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-IMPORT-DAG: declare dllimport i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-EXPORT-DAG: declare dllimport i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-DAG: declare dllimport void @__cxa_throw(i8*, i8*, i8*)
+// CHECK-DYNAMIC-DECL-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*)
+// CHECK-DYNAMIC-NODECL-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*)
+// CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*)
+// CHECK-DYNAMIC-EXPORT-IA-DAG: declare dllexport i32 @__cxa_guard_acquire(i64*)
+// CHECK-IA-DAG: declare noalias i8* @_Znwj(i32)
+// CHECK-DYNAMIC-DECL-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYNAMIC-NODECL-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYNAMIC-EXPORT-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYANMIC-IA-DAG: declare dllimport void @_ZSt9terminatev()
+// CHECK-DYNAMIC-NODECL-IA-DAG: declare void @_ZSt9terminatev()
+// CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport void @_ZSt9terminatev()
+// CHECK-DYNAMIC-EXPORT-IA-DAG: declare dllexport void @_ZSt9terminatev()
+
+// CHECK-STATIC-IA-DAG: declare i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
+// CHECK-STATIC-IA-DAG: declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+// CHECK-STATIC-IA-DAG: declare i8* @__cxa_allocate_exception(i32)
+// CHECK-STATIC-IA-DAG: declare void @__cxa_throw(i8*, i8*, i8*)
+// CHECK-STATIC-DECL-IA-DAG: declare i32 @__cxa_guard_acquire(i64*)
+// CHECK-STATIC-NODECL-IA-DAG: declare i32 @__cxa_guard_acquire(i64*)
+// CHECK-STATIC-IMPORT-IA-DAG: declare i32 @__cxa_guard_acquire(i64*)
+// CHECK-STATIC-EXPORT-IA-DAG: declare i32 @__cxa_guard_acquire(i64*)
+// CHECK-IA-DAG: declare noalias i8* @_Znwj(i32)
+// CHECK-STATIC-DECL-IA-DAG: declare void @__cxa_guard_release(i64*)
+// CHECK-STATIC-NODECL-IA-DAG: declare void @__cxa_guard_release(i64*)
+// CHECK-STATIC-IMPORT-IA-DAG: declare void @__cxa_guard_release(i64*)
+// CHECK-STATIC-EXPORT-IA-DAG: declare void @__cxa_guard_release(i64*)
+// CHECK-STATIC-IA-DAG: declare void @_ZSt9terminatev()
+// CHECK-STATIC-NODECL-IA-DAG: declare void @_ZSt9terminatev()
+// CHECK-STATIC-IMPORT-IA-DAG: declare void @_ZSt9terminatev()
+// CHECK-STATIC-EXPORT-IA-DAG: declare dllexport void @_ZSt9terminatev()
+
diff --git a/test/CodeGenCXX/sanitize-dtor-bit-field.cpp b/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
index d4497f6..19c46ba 100644
--- a/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
@@ -1,6 +1,6 @@
 // Test -fsanitize-memory-use-after-dtor
-// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
 // 24 bytes total
 struct Packed {
diff --git a/test/CodeGenCXX/sanitize-dtor-derived-class.cpp b/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
index f313471..618096a 100644
--- a/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
 // Base dtor poisons members
 // Complete dtor poisons vtable ptr after destroying members and
diff --git a/test/CodeGenCXX/sanitize-dtor-tail-call.cpp b/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
index de2fd8c..d6f5719 100644
--- a/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
@@ -1,6 +1,6 @@
 // Test -fsanitize-memory-use-after-dtor
-// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
 struct Simple {
   int x_;
diff --git a/test/CodeGenCXX/sanitize-dtor-trivial.cpp b/test/CodeGenCXX/sanitize-dtor-trivial.cpp
index 39f580a..9e328c0 100644
--- a/test/CodeGenCXX/sanitize-dtor-trivial.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-trivial.cpp
@@ -1,6 +1,6 @@
 // Test -fsanitize-memory-use-after-dtor
-// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
 // TODO Success pending on resolution of issue:
 //    https://github.com/google/sanitizers/issues/596
diff --git a/test/CodeGenCXX/sanitize-dtor-vtable.cpp b/test/CodeGenCXX/sanitize-dtor-vtable.cpp
index 78be794..2318ef0 100644
--- a/test/CodeGenCXX/sanitize-dtor-vtable.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
 class A {
  public:
diff --git a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
index 4734c02..83a2d61 100644
--- a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
+++ b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
@@ -11,7 +11,7 @@
 };
 
 // CHECK-LABEL: define void @_ZN5Test11AD2Ev
-// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
+// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
 A::~A() 
 {
 }
@@ -27,7 +27,7 @@
 };
 
 // CHECK-LABEL: define void @_ZN5Test21AD2Ev
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test21AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test21AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
 A::~A() {
   f();
 }
@@ -50,7 +50,7 @@
 };
 
 // CHECK-LABEL: define void @_ZN5Test31AD2Ev
-// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test31AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test31AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
 A::~A() {
   
 }
@@ -76,7 +76,7 @@
 };
 
 // CHECK-LABEL: define void @_ZN5Test41AD2Ev
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test41AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test41AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
 A::~A()
 {
 }
@@ -100,7 +100,7 @@
 };
 
 // CHECK-LABEL: define void @_ZN5Test51AD2Ev
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test51AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test51AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
 A::~A()
 {
 }
@@ -128,7 +128,7 @@
 };
 
 // CHECK-LABEL: define void @_ZN5Test61AD2Ev
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test61AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test61AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
 A::~A()
 {
 }
@@ -154,7 +154,7 @@
 };
 
 // CHECK-LABEL: define void @_ZN5Test71AD2Ev
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test71AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test71AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
 A::~A()
 {
 }
@@ -180,7 +180,7 @@
 };
 
 // CHECK-LABEL: define void @_ZN5Test81AD2Ev
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test81AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test81AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
 A::~A()
 {
 }
diff --git a/test/CodeGenCXX/stack-reuse-miscompile.cpp b/test/CodeGenCXX/stack-reuse-miscompile.cpp
index 63d15fd..3b860a5 100644
--- a/test/CodeGenCXX/stack-reuse-miscompile.cpp
+++ b/test/CodeGenCXX/stack-reuse-miscompile.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -S -target armv7l-unknown-linux-gnueabihf -emit-llvm -O1 -mllvm -disable-llvm-optzns -S %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -O1 -disable-llvm-passes -std=c++03 %s -o - | FileCheck %s
 
 // This test should not to generate llvm.lifetime.start/llvm.lifetime.end for
 // f function because all temporary objects in this function are used for the
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index bb97494..925ddec 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-pc-linuxs -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linuxs -emit-llvm -std=c++98 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linuxs -emit-llvm -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
 
 // CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
 // CHECK: @base_req = global [4 x i8] c"foo\00", align 1
@@ -9,7 +10,8 @@
 // CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0, comdat, align 4
 // CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat, align 8{{$}}
 // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
-// CHECK: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global %"struct.test4::HasVTable" zeroinitializer, comdat, align 8
+// CHECK98: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global %"struct.test4::HasVTable" zeroinitializer, comdat, align 8
+// CHECK11: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global { i8** } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5test49HasVTableE, i32 0, inrange i32 0, i32 2) }, comdat, align 8
 
 struct A {
   A();
@@ -169,5 +171,5 @@
   useStaticLocal();
 }
 // CHECK: define linkonce_odr dereferenceable(8) %"struct.test4::HasVTable"* @_ZN5test414useStaticLocalEv()
-// CHECK: ret %"struct.test4::HasVTable"* @_ZZN5test414useStaticLocalEvE3obj
+// CHECK: ret %"struct.test4::HasVTable"*{{.*}} @_ZZN5test414useStaticLocalEvE3obj
 }
diff --git a/test/CodeGenCXX/stmtexpr.cpp b/test/CodeGenCXX/stmtexpr.cpp
index 7bf19bb..5885a16 100644
--- a/test/CodeGenCXX/stmtexpr.cpp
+++ b/test/CodeGenCXX/stmtexpr.cpp
@@ -80,3 +80,85 @@
   y = ({ A a(1); if (b) goto G; a.i; });
   G: return y;
 }
+
+// When we emit a full expression with cleanups that contains branches out of
+// the full expression, the result of the inner expression (the call to
+// call_with_cleanups in this case) may not dominate the fallthrough destination
+// of the shared cleanup block.
+//
+// In this case the CFG will be a sequence of two diamonds, but the only
+// dynamically possible execution paths are both left hand branches and both
+// right hand branches. The first diamond LHS will call bar, and the second
+// diamond LHS will assign the result to v, but the call to bar does not
+// dominate the assignment.
+int bar(A, int);
+extern "C" int cleanup_exit_scalar(bool b) {
+  int v = bar(A(1), ({ if (b) return 42; 13; }));
+  return v;
+}
+
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_scalar({{.*}})
+// CHECK: call {{.*}} @_ZN1AC1Ei
+//    Spill after bar.
+// CHECK: %[[v:[^ ]*]] = call{{.*}} i32 @_Z3bar1Ai({{.*}})
+// CHECK-NEXT: store i32 %[[v]], i32* %[[tmp:[^, ]*]]
+//    Do cleanup.
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: switch
+//    Reload before v assignment.
+// CHECK: %[[v:[^ ]*]] = load i32, i32* %[[tmp]]
+// CHECK-NEXT: store i32 %[[v]], i32* %v
+
+// No need to spill when the expression result is a constant, constants don't
+// have dominance problems.
+extern "C" int cleanup_exit_scalar_constant(bool b) {
+  int v = (A(1), (void)({ if (b) return 42; 0; }), 13);
+  return v;
+}
+
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_scalar_constant({{.*}})
+// CHECK: store i32 13, i32* %v
+
+// Check for the same bug for lvalue expression evaluation kind.
+// FIXME: What about non-reference lvalues, like bitfield lvalues and vector
+// lvalues?
+int &getref();
+extern "C" int cleanup_exit_lvalue(bool cond) {
+  int &r = (A(1), ({ if (cond) return 0; (void)0; }), getref());
+  return r;
+}
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_lvalue({{.*}})
+// CHECK: call {{.*}} @_ZN1AC1Ei
+//    Spill after bar.
+// CHECK: %[[v:[^ ]*]] = call dereferenceable(4) i32* @_Z6getrefv({{.*}})
+// CHECK-NEXT: store i32* %[[v]], i32** %[[tmp:[^, ]*]]
+//    Do cleanup.
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: switch
+//    Reload before v assignment.
+// CHECK: %[[v:[^ ]*]] = load i32*, i32** %[[tmp]]
+// CHECK-NEXT: store i32* %[[v]], i32** %r
+
+
+// We handle ExprWithCleanups for complex evaluation type separately, and it had
+// the same bug.
+_Complex float bar_complex(A, int);
+extern "C" int cleanup_exit_complex(bool b) {
+  _Complex float v = bar_complex(A(1), ({ if (b) return 42; 13; }));
+  return v;
+}
+
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_complex({{.*}})
+// CHECK: call {{.*}} @_ZN1AC1Ei
+//    Spill after bar.
+// CHECK: call {{.*}} @_Z11bar_complex1Ai({{.*}})
+// CHECK: store float %{{.*}}, float* %[[tmp1:[^, ]*]]
+// CHECK: store float %{{.*}}, float* %[[tmp2:[^, ]*]]
+//    Do cleanup.
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: switch
+//    Reload before v assignment.
+// CHECK: %[[v1:[^ ]*]] = load float, float* %[[tmp1]]
+// CHECK: %[[v2:[^ ]*]] = load float, float* %[[tmp2]]
+// CHECK: store float %[[v1]], float* %v.realp
+// CHECK: store float %[[v2]], float* %v.imagp
diff --git a/test/CodeGenCXX/strict-vtable-pointers.cpp b/test/CodeGenCXX/strict-vtable-pointers.cpp
index 33f6399..21f85b1 100644
--- a/test/CodeGenCXX/strict-vtable-pointers.cpp
+++ b/test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fstrict-vtable-pointers -disable-llvm-optzns -O2 -emit-llvm -o %t.ll
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fstrict-vtable-pointers -disable-llvm-passes -O2 -emit-llvm -o %t.ll
 // RUN: FileCheck --check-prefix=CHECK-CTORS %s < %t.ll
 // RUN: FileCheck --check-prefix=CHECK-NEW %s < %t.ll
 // RUN: FileCheck --check-prefix=CHECK-DTORS %s < %t.ll
@@ -54,7 +54,7 @@
 
 // CHECK-NEW-LABEL: define void @_Z12LocalObjectsv()
 // CHECK-NEW-NOT: @llvm.invariant.group.barrier(
-// CHECK-NEW-LABEL: }
+// CHECK-NEW-LABEL: {{^}}}
 void LocalObjects() {
   DynamicBase1 DB;
   DB.foo();
@@ -82,12 +82,12 @@
 struct DynamicFromVirtualStatic1;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic1C1Ev
 // CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
 
 struct DynamicFrom2Virtuals;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN20DynamicFrom2VirtualsC1Ev
 // CHECK-CTORS: call i8* @llvm.invariant.group.barrier(
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
 
 
 // CHECK-NEW-LABEL: define void @_Z9Pointers1v()
@@ -97,7 +97,7 @@
 // CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS2:.*]])
 // CHECK-NEW: %[[THIS4:.*]] = bitcast i8* %[[THIS3]] to %[[DynamicDerived:.*]]*
 // CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(%[[DynamicDerived:.*]]* %[[THIS4]])
-// CHECK-NEW-LABEL: }
+// CHECK-NEW-LABEL: {{^}}}
 void Pointers1() {
   DynamicBase1 *DB = new DynamicBase1;
   DB->foo();
@@ -113,7 +113,7 @@
 // CHECK-NEW:  call void @_ZN14DynamicDerivedC1Ev(
 // CHECK-NEW:  call i8* @llvm.invariant.group.barrier(
 // CHECK-NEW: call void @_ZN12DynamicBase1C1Ev(
-// CHECK-NEW-LABEL: }
+// CHECK-NEW-LABEL: {{^}}}
 void HackingObjects() {
   DynamicBase1 DB;
   DB.foo();
@@ -132,7 +132,7 @@
 struct DynamicBase1;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1C2Ev(
 // CHECK-CTORS-NOT: call i8* @llvm.invariant.group.barrier(
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
 
 
 struct DynamicDerived;
@@ -147,7 +147,7 @@
 
 // CHECK-CTORS: %[[THIS5:.*]] = bitcast %struct.DynamicDerived* %[[THIS0]] to i32 (...)***
 // CHECK-CTORS: store {{.*}} %[[THIS5]]
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
 
 struct DynamicDerivedMultiple;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleC2Ev(
@@ -166,49 +166,49 @@
 
 
 // CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
-// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, i32 2) {{.*}} %[[THIS10]]
+// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 0, i32 2) {{.*}} %[[THIS10]]
 // CHECK-CTORS: %[[THIS11:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i8*
 // CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, i8* %[[THIS11]], i64 16
 // CHECK-CTORS: %[[THIS12:.*]]  = bitcast i8* %[[THIS_ADD]] to i32 (...)***
 
 
-// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, i32 6) {{.*}} %[[THIS12]]
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 1, i32 2) {{.*}} %[[THIS12]]
+// CHECK-CTORS-LABEL: {{^}}}
 
 struct DynamicFromStatic;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticC2Ev(
 // CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
 
 
 /** DTORS **/
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev(
 // CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
 
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic2D2Ev(
 // CHECK-DTORS-NOT: invariant.barrier
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticD2Ev
 // CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
 
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleD2Ev(
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase2D2Ev(
 // CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1D2Ev
 // CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedD2Ev
 // CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
 
 
 // CHECK-LINK-REQ: !llvm.module.flags = !{![[FIRST:.*]], ![[SEC:.*]]{{.*}}}
diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp
index 90b8099..098f18d 100644
--- a/test/CodeGenCXX/template-instantiation.cpp
+++ b/test/CodeGenCXX/template-instantiation.cpp
@@ -1,21 +1,22 @@
-// RUN: %clang_cc1 %s -O1 -disable-llvm-optzns -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -O1 -disable-llvm-passes -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -O1 -disable-llvm-passes -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK2
 
-// CHECK: @_ZN7PR100011xE = global
-// CHECK-NOT: @_ZN7PR100014kBarE = external global i32
-//
-// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
-// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
-// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE
-// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE
-// CHECK:     @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant
+// Instantiation order varies on different C++ dialects (IE, between C++98 and C++11).
+// CHECK-DAG: @_ZN7PR100011xE = global
+// CHECK-DAG: @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant
+// CHECK-DAG: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32]
+// CHECK-DAG: @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant
 
-// CHECK: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32]
-// CHECK-NOT: @_ZN7PR100011SIiE3arr2E = linkonce_odr global [3 x i32]A
+// Negative checks go under prefix "CHECK2" to avoid interference with CHECK and CHECK-DAG.
+// CHECK2-NOT: @_ZN7PR100014kBarE = external global i32
+// CHECK2-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
+// CHECK2-NOT: _ZTVN5test315basic_fstreamXXIcEE
+// CHECK2-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE
+// CHECK2-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE
+// CHECK2-NOT: @_ZN7PR100011SIiE3arr2E = linkonce_odr global [3 x i32]A
 
-// CHECK:     @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant
-
-// CHECK-NOT: _ZTVN5test31SIiEE
-// CHECK-NOT: _ZTSN5test31SIiEE
+// CHECK2-NOT: _ZTVN5test31SIiEE
+// CHECK2-NOT: _ZTSN5test31SIiEE
 
 // CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiEC1Ev(%"class.test2::C"* %this) unnamed_addr
 // CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_(
@@ -152,7 +153,7 @@
   void f () {}
 };
 // Should not instantiate class B since it is introduced in namespace scope.
-// CHECK-NOT: _ZN6PR85051AILi0EE1B1fEv
+// CHECK2-NOT: _ZN6PR85051AILi0EE1B1fEv
 template class A<0>;
 }
 
diff --git a/test/CodeGenCXX/threadsafe-statics.cpp b/test/CodeGenCXX/threadsafe-statics.cpp
index 9aecc2d..7cb7003 100644
--- a/test/CodeGenCXX/threadsafe-statics.cpp
+++ b/test/CodeGenCXX/threadsafe-statics.cpp
@@ -22,6 +22,6 @@
 // NO-TSS-NOT: call void @__cxa_guard_release
 // NO-TSS: ret void
 
-// WITH-TSS: attributes [[NUW]] = { nounwind{{.*}} }
+// WITH-TSS: attributes [[NUW]] = { noinline nounwind{{.*}} }
 
-// NO-TSS: attributes [[NUW]] = { nounwind{{.*}} }
+// NO-TSS: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
index 3a598b9..26e166c 100644
--- a/test/CodeGenCXX/thunks.cpp
+++ b/test/CodeGenCXX/thunks.cpp
@@ -1,9 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o %t
-// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o %t.opt -O1 -disable-llvm-optzns
-// RUN: FileCheck %s < %t
-// RUN: FileCheck %s < %t.opt
-// RUN: FileCheck --check-prefix=CHECK-NONOPT %s < %t
-// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-NONOPT %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck --check-prefix=CHECK --check-prefix=CHECK-OPT %s
 
 namespace Test1 {
 
@@ -405,4 +401,5 @@
 // CHECK-OPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
 // CHECK-OPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
 
-// CHECK: attributes [[NUW]] = { nounwind uwtable{{.*}} }
+// CHECK-NONOPT: attributes [[NUW]] = { noinline nounwind uwtable{{.*}} }
+// CHECK-OPT: attributes [[NUW]] = { nounwind uwtable{{.*}} }
diff --git a/test/CodeGenCXX/type-metadata-thinlto.cpp b/test/CodeGenCXX/type-metadata-thinlto.cpp
new file mode 100644
index 0000000..2a586fc
--- /dev/null
+++ b/test/CodeGenCXX/type-metadata-thinlto.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -flto=thin -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
+// RUN: llvm-modextract -o - -n 1 %t | llvm-dis | FileCheck %s
+
+// CHECK: @_ZTV1A = linkonce_odr
+class A {
+  virtual void f() {}
+};
+
+A *f() {
+  return new A;
+}
diff --git a/test/CodeGenCXX/type-metadata.cpp b/test/CodeGenCXX/type-metadata.cpp
index 076b1fd..6821e36 100644
--- a/test/CodeGenCXX/type-metadata.cpp
+++ b/test/CodeGenCXX/type-metadata.cpp
@@ -1,16 +1,16 @@
 // Tests for the cfi-vcall feature:
-// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=NDIAG %s
-// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-ABORT %s
-// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s
-// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=MS --check-prefix=TT-MS --check-prefix=NDIAG %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=NDIAG %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-ABORT %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=MS --check-prefix=TT-MS --check-prefix=NDIAG %s
 
 // Tests for the whole-program-vtables feature:
-// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM %s
-// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=MS --check-prefix=TT-MS %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-pc-windows-msvc -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=MS --check-prefix=TT-MS %s
 
 // Tests for cfi + whole-program-vtables:
-// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-VT --check-prefix=ITANIUM --check-prefix=TC-ITANIUM %s
-// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-VT --check-prefix=MS --check-prefix=TC-MS %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-VT --check-prefix=ITANIUM --check-prefix=TC-ITANIUM %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-VT --check-prefix=MS --check-prefix=TC-MS %s
 
 // ITANIUM: @_ZTV1A = {{[^!]*}}, !type [[A16:![0-9]+]]
 // ITANIUM-DIAG-SAME: !type [[ALL16:![0-9]+]]
diff --git a/test/CodeGenCXX/ubsan-bitfields.cpp b/test/CodeGenCXX/ubsan-bitfields.cpp
new file mode 100644
index 0000000..5595db0
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-bitfields.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=bool,enum | FileCheck %s
+
+enum E {
+  a = 1,
+  b = 2,
+  c = 3
+};
+
+struct S {
+  E e1 : 10;
+};
+
+// CHECK-LABEL: define i32 @_Z4loadP1S
+E load(S *s) {
+  // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}}
+  // CHECK: [[CLEAR:%.*]] = and i16 [[LOAD]], 1023
+  // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32
+  // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize
+  // CHECK: call void @__ubsan_handle_load_invalid_value
+  return s->e1;
+}
+
+struct Bool {
+  bool b1 : 1;
+  bool b2 : 7;
+  bool b3 : 16;
+};
+
+// CHECK-LABEL: define zeroext i1 @_Z13load_cpp_boolP4Bool
+bool load_cpp_bool(Bool *b) {
+  // CHECK-NOT: call void @__ubsan_handle_load_invalid_value
+  // CHECK-NOT: !nosanitize
+  return b->b1 || b->b2 || b->b3;
+}
diff --git a/test/CodeGenCXX/ubsan-suppress-null-checks.cpp b/test/CodeGenCXX/ubsan-suppress-null-checks.cpp
new file mode 100644
index 0000000..967c081
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-suppress-null-checks.cpp
@@ -0,0 +1,188 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null -DCHECK_LAMBDA | FileCheck %s --check-prefix=LAMBDA
+
+struct A {
+  int foo;
+
+  // CHECK-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv
+  void do_nothing() {
+    // CHECK: icmp ne %struct.A* %[[THIS1:[a-z0-9]+]], null, !nosanitize
+    // CHECK: ptrtoint %struct.A* %[[THIS1]] to i64, !nosanitize
+    // CHECK-NEXT: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    // CHECK: ret void
+  }
+
+#ifdef CHECK_LAMBDA
+  // LAMBDA-LABEL: define linkonce_odr void @_ZN1A22do_nothing_with_lambdaEv
+  void do_nothing_with_lambda() {
+    // LAMBDA: icmp ne %struct.A* %[[THIS2:[a-z0-9]+]], null, !nosanitize
+    // LAMBDA: ptrtoint %struct.A* %[[THIS2]] to i64, !nosanitize
+    // LAMBDA-NEXT: call void @__ubsan_handle_type_mismatch
+
+    auto f = [&] {
+      foo = 0;
+    };
+    f();
+
+    // LAMBDA: ret void
+  }
+
+// Check the IR for the lambda:
+//
+// LAMBDA-LABEL: define linkonce_odr void @_ZZN1A22do_nothing_with_lambdaEvENKUlvE_clEv
+// LAMBDA: call void @__ubsan_handle_type_mismatch
+// LAMBDA-NOT: call void @__ubsan_handle_type_mismatch
+// LAMBDA: ret void
+#endif
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1A11load_memberEv
+  int load_member() {
+    // CHECK: icmp ne %struct.A* %[[THIS3:[a-z0-9]+]], null, !nosanitize
+    // CHECK: ptrtoint %struct.A* %[[THIS3]] to i64, !nosanitize
+    // CHECK-NEXT: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return foo;
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1A11call_methodEv
+  int call_method() {
+    // CHECK: icmp ne %struct.A* %[[THIS4:[a-z0-9]+]], null, !nosanitize
+    // CHECK: ptrtoint %struct.A* %[[THIS4]] to i64, !nosanitize
+    // CHECK-NEXT: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return load_member();
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_1Ev
+  void assign_member_1() {
+    // CHECK: icmp ne %struct.A* %[[THIS5:[a-z0-9]+]], null, !nosanitize
+    // CHECK: ptrtoint %struct.A* %[[THIS5]] to i64, !nosanitize
+    // CHECK-NEXT: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    foo = 0;
+    // CHECK: ret void
+  }
+
+  // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_2Ev
+  void assign_member_2() {
+    // CHECK: icmp ne %struct.A* %[[THIS6:[a-z0-9]+]], null, !nosanitize
+    // CHECK: ptrtoint %struct.A* %[[THIS6]] to i64, !nosanitize
+    // CHECK-NEXT: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    (__extension__ (this))->foo = 0;
+    // CHECK: ret void
+  }
+
+  // CHECK-LABEL: define linkonce_odr void @_ZNK1A15assign_member_3Ev
+  void assign_member_3() const {
+    // CHECK: icmp ne %struct.A* %[[THIS7:[a-z0-9]+]], null, !nosanitize
+    // CHECK: ptrtoint %struct.A* %[[THIS7]] to i64, !nosanitize
+    // CHECK-NEXT: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    const_cast<A *>(this)->foo = 0;
+    // CHECK: ret void
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1A22call_through_referenceERS_
+  static int call_through_reference(A &a) {
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return a.load_member();
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1A20call_through_pointerEPS_
+  static int call_through_pointer(A *a) {
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    return a->load_member();
+    // CHECK: ret i32
+  }
+};
+
+struct B {
+  operator A*() const { return nullptr; }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEv
+  static int load_member() {
+    // Null-check &b before converting it to an A*.
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    //
+    // Null-check the result of the conversion before using it.
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    //
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    B b;
+    return static_cast<A *>(b)->load_member();
+    // CHECK: ret i32
+  }
+};
+
+struct Base {
+  int foo;
+
+  virtual int load_member_1() = 0;
+};
+
+struct Derived : public Base {
+  int bar;
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_2Ev
+  int load_member_2() {
+    // CHECK: icmp ne %struct.Derived* %[[THIS8:[a-z0-9]+]], null, !nosanitize
+    // CHECK: ptrtoint %struct.Derived* %[[THIS8]] to i64, !nosanitize
+    // CHECK-NEXT: call void @__ubsan_handle_type_mismatch
+    //
+    // Null-check the result of the cast before using it.
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    //
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return dynamic_cast<Base *>(this)->load_member_1();
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_3Ev
+  int load_member_3() {
+    // CHECK: icmp ne %struct.Derived* %[[THIS9:[a-z0-9]+]], null, !nosanitize
+    // CHECK: ptrtoint %struct.Derived* %[[THIS9]] to i64, !nosanitize
+    // CHECK-NEXT: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return reinterpret_cast<Derived *>(static_cast<Base *>(this))->foo;
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_1Ev
+  int load_member_1() override {
+    // CHECK: icmp ne %struct.Derived* %[[THIS10:[a-z0-9]+]], null, !nosanitize
+    // CHECK: ptrtoint %struct.Derived* %[[THIS10]] to i64, !nosanitize
+    // CHECK-NEXT: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return foo + bar;
+    // CHECK: ret i32
+  }
+};
+
+void force_irgen() {
+  A *a;
+  a->do_nothing();
+#ifdef CHECK_LAMBDA
+  a->do_nothing_with_lambda();
+#endif
+  a->load_member();
+  a->call_method();
+  a->assign_member_1();
+  a->assign_member_2();
+  a->assign_member_3();
+  A::call_through_reference(*a);
+  A::call_through_pointer(a);
+
+  B::load_member();
+
+  Base *b = new Derived;
+  b->load_member_1();
+
+  Derived *d;
+  d->load_member_2();
+  d->load_member_3();
+}
diff --git a/test/CodeGenCXX/ubsan-type-checks.cpp b/test/CodeGenCXX/ubsan-type-checks.cpp
new file mode 100644
index 0000000..b2cd475
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-type-checks.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s -check-prefixes=ALIGN,COMMON
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s -check-prefixes=NULL,COMMON
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=object-size | FileCheck %s -check-prefixes=OBJSIZE,COMMON
+
+struct A {
+  // COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv
+  void do_nothing() {
+    // ALIGN-NOT: ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+    // ALIGN-NOT: and i64 %{{.*}}, 7, !nosanitize
+ 
+    // NULL: icmp ne %struct.A* %{{.*}}, null, !nosanitize
+ 
+    // OBJSIZE-NOT: call i64 @llvm.objectsize
+  }
+};
+
+void force_irgen() {
+  A a;
+  a.do_nothing();
+}
diff --git a/test/CodeGenCXX/ubsan-vtable-checks.cpp b/test/CodeGenCXX/ubsan-vtable-checks.cpp
index 80af77d..e684ae9 100644
--- a/test/CodeGenCXX/ubsan-vtable-checks.cpp
+++ b/test/CodeGenCXX/ubsan-vtable-checks.cpp
@@ -21,7 +21,7 @@
   // CHECK-NULL-NOT: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
   // CHECK-NULL: [[UBSAN_CMP_RES:%[0-9]+]] = icmp ne %struct.T* %{{[_a-z0-9]+}}, null
   // CHECK-NULL-NEXT: br i1 [[UBSAN_CMP_RES]], label %{{.*}}, label %{{.*}}
-  // CHECK-NULL: call void @__ubsan_handle_type_mismatch_abort
+  // CHECK-NULL: call void @__ubsan_handle_type_mismatch_v1_abort
   // Second, we check that vtable is actually loaded once the type check is done.
   // CHECK-NULL: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
   return t->v();
diff --git a/test/CodeGenCXX/unaligned.cpp b/test/CodeGenCXX/unaligned.cpp
new file mode 100644
index 0000000..95549d3
--- /dev/null
+++ b/test/CodeGenCXX/unaligned.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s
+
+int foo() {
+  // CHECK: ret i32 1
+  return alignof(__unaligned int);
+}
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
index 735dc61..fc4e0d3 100644
--- a/test/CodeGenCXX/value-init.cpp
+++ b/test/CodeGenCXX/value-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
 
 struct A {
   virtual ~A();
@@ -315,6 +315,14 @@
   // CHECK: }
 }
 
+// CHECK-LABEL: define {{.*}}@_Z20explicitly_defaultedv
+int explicitly_defaulted() {
+  struct A { A() = default; int n; };
+  // CHECK: call void @llvm.memset
+  A a = A();
+  return a.n;
+} // CHECK-LABEL: }
+
 // CHECK-LABEL: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
 // CHECK: call void @llvm.memset.p0i8.i64
 // CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
diff --git a/test/CodeGenCXX/virtual-base-cast.cpp b/test/CodeGenCXX/virtual-base-cast.cpp
index 554e80d..b2f2b4f 100644
--- a/test/CodeGenCXX/virtual-base-cast.cpp
+++ b/test/CodeGenCXX/virtual-base-cast.cpp
@@ -82,4 +82,4 @@
 // MSVC:   add nsw i32 4, %[[offset]]
 // MSVC: }
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp
index e13adfc..2e63daa 100644
--- a/test/CodeGenCXX/virtual-destructor-calls.cpp
+++ b/test/CodeGenCXX/virtual-destructor-calls.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck %s
 
 struct Member {
   ~Member();
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index 7c0757b..6ea2348 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s
 
 // The trickery with optimization in the run line is to get IR
 // generation to emit available_externally function bodies, but not
diff --git a/test/CodeGenCXX/volatile-1.cpp b/test/CodeGenCXX/volatile-1.cpp
index f32e428..75fb0d2 100644
--- a/test/CodeGenCXX/volatile-1.cpp
+++ b/test/CodeGenCXX/volatile-1.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -std=c++98 -o - | FileCheck %s
+// RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
 
 // CHECK: @i = global [[INT:i[0-9]+]] 0
 volatile int i, j, k;
@@ -22,18 +23,22 @@
 
   asm("nop"); // CHECK: call void asm
 
-  // should not load
+  // should not load in C++98
   i;
+  // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @i
 
   (float)(ci);
   // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
   // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
   // CHECK-NEXT: sitofp [[INT]]
 
-  // These are not uses in C++:
+  // These are not uses in C++98:
   //   [expr.static.cast]p6:
   //     The lvalue-to-rvalue . . . conversions are not applied to the expression.
   (void)ci;
+  // CHECK11-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+  // CHECK11-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+
   (void)a;
 
   (void)(ci=ci);
@@ -126,7 +131,8 @@
   // CHECK-NEXT: load volatile
   // CHECK-NEXT: sitofp
 
-  (void)i;
+  (void)i; // This is now a load in C++11
+  // CHECK11-NEXT: load volatile
 
   i=i;
   // CHECK-NEXT: load volatile
@@ -155,13 +161,15 @@
   // CHECK-NEXT: br label
   // CHECK:      phi
 
-  (void)(i,(i=i));
+  (void)(i,(i=i)); // first i is also a load in C++11
+  // CHECK11-NEXT: load volatile
   // CHECK-NEXT: load volatile
   // CHECK-NEXT: store volatile
 
-  i=i,k;
+  i=i,k; // k is also a load in C++11
   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @i
   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
+  // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @k
 
   (i=j,k=j);
   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
@@ -169,11 +177,14 @@
   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @k
 
-  (i=j,k);
+  (i=j,k); // k is also a load in C++11
   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
+  // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @k
 
-  (i,j);
+  (i,j); // i and j both are loads in C++11
+  // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @i
+  // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @j
 
   // Extra load in C++.
   i=c=k;
@@ -190,7 +201,9 @@
   // CHECK-NEXT: add nsw [[INT]]
   // CHECK-NEXT: store volatile
 
-  ci;
+  ci; // ci is a load in C++11
+  // CHECK11-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
+  // CHECK11-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
 
   asm("nop"); // CHECK-NEXT: call void asm
 
@@ -338,8 +351,9 @@
   // CHECK-NEXT: load volatile
   // CHECK-NEXT: add
 
-  (i,j)=k;
+  (i,j)=k; // i is also a load in C++11
   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @k
+  // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @i
   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j
 
   (j=k,i)=i;
diff --git a/test/CodeGenCXX/volatile.cpp b/test/CodeGenCXX/volatile.cpp
index ea7429f..9c0271b 100644
--- a/test/CodeGenCXX/volatile.cpp
+++ b/test/CodeGenCXX/volatile.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++98 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
 
 // Check that IR gen doesn't try to do an lvalue-to-rvalue conversion
 // on a volatile reference result.  rdar://problem/8338198
@@ -27,6 +28,7 @@
   // CHECK-LABEL: define void @_ZN5test14testEv()
   void test() {
     // CHECK:      [[TMP:%.*]] = load i32*, i32** @_ZN5test11xE, align 8
+    // CHECK11-NEXT: {{%.*}} = load volatile i32, i32* [[TMP]], align 4
     // CHECK-NEXT: ret void
     *x;
   }
diff --git a/test/CodeGenCXX/vtable-align.cpp b/test/CodeGenCXX/vtable-align.cpp
index f1f10c0..1b82cbc 100644
--- a/test/CodeGenCXX/vtable-align.cpp
+++ b/test/CodeGenCXX/vtable-align.cpp
@@ -9,6 +9,6 @@
 
 void A::f() {}
 
-// CHECK-32: @_ZTV1A = unnamed_addr constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)], align 4
+// CHECK-32: @_ZTV1A = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)] }, align 4
 
-// CHECK-64: @_ZTV1A = unnamed_addr constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)], align 8
+// CHECK-64: @_ZTV1A = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)] }, align 8
diff --git a/test/CodeGenCXX/vtable-assume-load.cpp b/test/CodeGenCXX/vtable-assume-load.cpp
index 819b09d..b0857c2 100644
--- a/test/CodeGenCXX/vtable-assume-load.cpp
+++ b/test/CodeGenCXX/vtable-assume-load.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions -fstrict-vtable-pointers
-// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions -fstrict-vtable-pointers
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
 // FIXME: Assume load should not require -fstrict-vtable-pointers
 
 // RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
@@ -27,9 +27,9 @@
 // CHECK1-LABEL: define void @_ZN5test14fooAEv()
 // CHECK1: call void @_ZN5test11AC1Ev(%"struct.test1::A"*
 // CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
-// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i32 0, i32 2)
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5test11AE, i32 0, inrange i32 0, i32 2)
 // CHECK1: call void @llvm.assume(i1 %[[CMP]])
-// CHECK1-LABEL: }
+// CHECK1-LABEL: {{^}}}
 
 void fooA() {
   A a;
@@ -39,9 +39,9 @@
 // CHECK1-LABEL: define void @_ZN5test14fooBEv()
 // CHECK1: call void @_ZN5test11BC1Ev(%"struct.test1::B"* %{{.*}})
 // CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
-// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i32 0, i32 2)
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5test11BE, i32 0, inrange i32 0, i32 2)
 // CHECK1: call void @llvm.assume(i1 %[[CMP]])
-// CHECK1-LABEL: }
+// CHECK1-LABEL: {{^}}}
 
 void fooB() {
   B b;
@@ -50,7 +50,7 @@
 // there should not be any assumes in the ctor that calls base ctor
 // CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%"struct.test1::B"*
 // CHECK1-NOT: @llvm.assume(
-// CHECK1-LABEL: }
+// CHECK1-LABEL: {{^}}}
 }
 namespace test2 {
 struct A {
@@ -73,18 +73,18 @@
 // CHECK2-LABEL: define void @_ZN5test24testEv()
 // CHECK2: call void @_ZN5test21CC1Ev(%"struct.test2::C"*
 // CHECK2: %[[VTABLE:.*]] = load i8**, i8*** {{.*}}
-// CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i32 0, i32 2)
+// CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [3 x i8*], [3 x i8*] }, { [3 x i8*], [3 x i8*] }* @_ZTVN5test21CE, i32 0, inrange i32 0, i32 2)
 // CHECK2: call void @llvm.assume(i1 %[[CMP]])
 
 // CHECK2: %[[V2:.*]] = bitcast %"struct.test2::C"* %{{.*}} to i8*
 // CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 8
 // CHECK2: %[[V3:.*]] = bitcast i8* %[[ADD_PTR]] to i8***
 // CHECK2: %[[VTABLE2:.*]] = load i8**, i8*** %[[V3]]
-// CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i32 0, i32 5)
+// CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ({ [3 x i8*], [3 x i8*] }, { [3 x i8*], [3 x i8*] }* @_ZTVN5test21CE, i32 0, inrange i32 1, i32 2)
 // CHECK2: call void @llvm.assume(i1 %[[CMP2]])
 
 // CHECK2: call void @_ZN5test21gEPNS_1AE(
-// CHECK2-LABEL: }
+// CHECK2-LABEL: {{^}}}
 
 void test() {
   C c;
@@ -111,7 +111,7 @@
 
 // CHECK3-LABEL: define void @_ZN5test34testEv()
 // CHECK3: call void @_ZN5test31CC1Ev(%"struct.test3::C"*
-// CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN5test31CE, i32 0, i32 3)
+// CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN5test31CE, i32 0, inrange i32 0, i32 3)
 // CHECK3: call void @llvm.assume(i1 %[[CMP]])
 // CHECK3-LABLEL: }
 void test() {
@@ -140,13 +140,13 @@
 // CHECK4-LABEL: define void @_ZN5test44testEv()
 // CHECK4: call void @_ZN5test41CC1Ev(%"struct.test4::C"*
 // CHECK4: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
-// CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i32 0, i32 4)
+// CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5test41CE, i32 0, inrange i32 0, i32 4)
 // CHECK4: call void @llvm.assume(i1 %[[CMP]]
 
 // CHECK4: %[[VTABLE2:.*]] = load i8**, i8*** %{{.*}}
-// CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i32 0, i32 4)
+// CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5test41CE, i32 0, inrange i32 0, i32 4)
 // CHECK4: call void @llvm.assume(i1 %[[CMP2]])
-// CHECK4-LABEL: }
+// CHECK4-LABEL: {{^}}}
 
 void test() {
   C c;
@@ -166,7 +166,7 @@
 // CHECK-MS-LABEL: define void @"\01?test@testMS@@YAXXZ"()
 // CHECK-MS: call x86_thiscallcc %"struct.testMS::S"* @"\01??0S@testMS@@QAE@XZ"(
 // CHECK-MS-NOT: @llvm.assume
-// CHECK-MS-LABEL: }
+// CHECK-MS-LABEL: {{^}}}
 
 void test() {
   S s;
@@ -196,7 +196,7 @@
 
 // CHECK6-LABEL:   call void @_ZN5test61BC1Ev(
 // CHECK6-NOT: call void @llvm.assume(
-// CHECK6-LABEL: }
+// CHECK6-LABEL: {{^}}}
 void g() {
   A *a = new A;
   B *b = new B;
@@ -216,7 +216,7 @@
 // CHECK7-LABEL: define void @_ZN5test71gEv()
 // CHECK7: call void @_ZN5test71AC1Ev(
 // CHECK7: call void @llvm.assume(
-// CHECK7-LABEL: }
+// CHECK7-LABEL: {{^}}}
 void g() {
   A *a = new A();
   a->bar();
@@ -259,7 +259,7 @@
 
 // CHECK8-LABEL: define void @_ZN5test81bEv()
 // CHECK8: call void @llvm.assume(
-// CHECK8-LABEL: }
+// CHECK8-LABEL: {{^}}}
 void b() {
   B b;
   b.bar();
@@ -270,7 +270,7 @@
 // defined here) it would be correct to refer to it.
 // CHECK8-LABEL: define void @_ZN5test81cEv()
 // CHECK8-NOT: call void @llvm.assume(
-// CHECK8-LABEL: }
+// CHECK8-LABEL: {{^}}}
 void c() {
   C c;
   c.bar();
@@ -279,7 +279,7 @@
 // FIXME: We could generate assumption loads here.
 // CHECK8-LABEL: define void @_ZN5test81dEv()
 // CHECK8-NOT: call void @llvm.assume(
-// CHECK8-LABEL: }
+// CHECK8-LABEL: {{^}}}
 void d() {
   D d;
   d.bar();
@@ -287,7 +287,7 @@
 
 // CHECK8-LABEL: define void @_ZN5test81eEv()
 // CHECK8: call void @llvm.assume(
-// CHECK8-LABEL: }
+// CHECK8-LABEL: {{^}}}
 void e() {
   E e;
   e.bar();
diff --git a/test/CodeGenCXX/vtable-available-externally.cpp b/test/CodeGenCXX/vtable-available-externally.cpp
index f38d177..ae81959 100644
--- a/test/CodeGenCXX/vtable-available-externally.cpp
+++ b/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o %t
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -O2 -disable-llvm-optzns -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
index ca5384d..4a47e3c 100644
--- a/test/CodeGenCXX/vtable-layout.cpp
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -1919,6 +1919,8 @@
     virtual int i(int);
     virtual int i();
   };
+  // Force C's vtable to be generated.
+  int C::f() { return 1; }
 
   class D : C {};
 
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index 0b556d1..c4ebf75 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -1,6 +1,10 @@
 // RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o %t
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-optzns -O3 -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -std=c++03 -o %t.03
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -std=c++11 -o %t.11
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-passes -O3 -emit-llvm -o %t.opt
 // RUN: FileCheck %s < %t
+// RUN: FileCheck %s < %t.03
+// RUN: FileCheck %s < %t.11
 // RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
 
 namespace {
@@ -33,6 +37,11 @@
 
 static struct : D { } e;
 
+// Force 'e' to be constructed and therefore have a vtable defined.
+void use_e() {
+  e.f();
+}
+
 // The destructor is the key function.
 template<typename T>
 struct E {
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
index 130a55c..49c8de4 100644
--- a/test/CodeGenCXX/vtable-pointer-initialization.cpp
+++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp
@@ -21,13 +21,13 @@
 
 // CHECK-LABEL: define void @_ZN1AC2Ev(%struct.A* %this) unnamed_addr
 // CHECK: call void @_ZN4BaseC2Ev(
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange i32 0, i32 2) to i32 (...)**)
 // CHECK: call void @_ZN5FieldC1Ev(
 // CHECK: ret void
 A::A() { }
 
 // CHECK-LABEL: define void @_ZN1AD2Ev(%struct.A* %this) unnamed_addr
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange i32 0, i32 2) to i32 (...)**)
 // CHECK: call void @_ZN5FieldD1Ev(
 // CHECK: call void @_ZN4BaseD2Ev(
 // CHECK: ret void
@@ -49,12 +49,12 @@
 
 // CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ev(%struct.B* %this) unnamed_addr
 // CHECK: call void @_ZN4BaseC2Ev(
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1B, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1B, i32 0, inrange i32 0, i32 2) to i32 (...)**)
 // CHECK: call void @_ZN5FieldC1Ev
 // CHECK: ret void
 
 // CHECK-LABEL: define linkonce_odr void @_ZN1BD2Ev(%struct.B* %this) unnamed_addr
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1B, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1B, i32 0, inrange i32 0, i32 2) to i32 (...)**)
 // CHECK: call void @_ZN5FieldD1Ev(
 // CHECK: call void @_ZN4BaseD2Ev(
 // CHECK: ret void
diff --git a/test/CodeGenCXX/vtt-layout.cpp b/test/CodeGenCXX/vtt-layout.cpp
index 7ff93dd..a5f7802 100644
--- a/test/CodeGenCXX/vtt-layout.cpp
+++ b/test/CodeGenCXX/vtt-layout.cpp
@@ -78,11 +78,12 @@
   }
 }
 
-// CHECK: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN5Test11BE, i32 0, i32 3) to i8*)]
-// CHECK: @_ZTVN5Test51AE = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test51AE to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%"struct.Test5::A"*)* @_ZN5Test51A6anchorEv to i8*)]
-// CHECK: @_ZTVN5Test61AE = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test61AE to i8*), i8* bitcast (void ()* @__cxa_deleted_virtual to i8*), i8* bitcast (void (%"struct.Test6::A"*)* @_ZN5Test61A6anchorEv to i8*)]
-// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5Test21CE, i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5Test21CE, i32 0, i32 4) to i8*)] 
-// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i32 0, i32 5) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i32 0, i32 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i32 0, i32 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i32 0, i32 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i64 1, i32 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 6) to i8*)] 
-// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 18) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i32 0, i32 17) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i32 0, i32 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i32 0, i32 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i32 0, i32 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i64 1, i32 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 10) to i8*)] 
+// CHECK: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN5Test11BE, i32 0, inrange i32 0, i32 3) to i8*)]
+// CHECK: @_ZTVN5Test51AE = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test51AE to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%"struct.Test5::A"*)* @_ZN5Test51A6anchorEv to i8*)] }
+// CHECK: @_ZTVN5Test61AE = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test61AE to i8*), i8* bitcast (void ()* @__cxa_deleted_virtual to i8*), i8* bitcast (void (%"struct.Test6::A"*)* @_ZN5Test61A6anchorEv to i8*)] }
+// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4) to i8*)]
+// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 0, i32 5) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*)]
+// CHECK: @_ZTVN5Test41DE = linkonce_odr unnamed_addr constant { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] } { [6 x i8*] [i8* inttoptr (i64 72 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 56 to i8*), i8* inttoptr (i64 40 to i8*), i8* null, i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [8 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 56 to i8*), i8* null, i8* null, i8* inttoptr (i64 -16 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::V3"*)* @_ZN5Test42V31gEv to i8*)], [3 x i8*] [i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -40 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [4 x i8*] [i8* null, i8* inttoptr (i64 -56 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::A2"*)* @_ZN5Test42A21fEv to i8*)], [4 x i8*] [i8* inttoptr (i64 -16 to i8*), i8* inttoptr (i64 -32 to i8*), i8* inttoptr (i64 -72 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)] }
+// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 1, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 4, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 2, i32 3) to i8*)]
 // CHECK: declare void @__cxa_pure_virtual() unnamed_addr
 // CHECK: declare void @__cxa_deleted_virtual() unnamed_addr
diff --git a/test/CodeGenCoroutines/coro-alloc.cpp b/test/CodeGenCoroutines/coro-alloc.cpp
index 7dbbdd3..c795e27 100644
--- a/test/CodeGenCoroutines/coro-alloc.cpp
+++ b/test/CodeGenCoroutines/coro-alloc.cpp
@@ -4,12 +4,27 @@
 namespace experimental {
 template <typename... T>
 struct coroutine_traits; // expected-note {{declared here}}
+
+template <class Promise = void>
+struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) { return {}; }
+};
+
+template <>
+struct coroutine_handle<void> {
+  static coroutine_handle from_address(void *) { return {}; }
+  coroutine_handle() = default;
+  template <class PromiseType>
+  coroutine_handle(coroutine_handle<PromiseType>) {}
+};
+
 }
 }
 
 struct suspend_always {
   bool await_ready() { return false; }
-  void await_suspend() {}
+  void await_suspend(std::experimental::coroutine_handle<>) {}
   void await_resume() {}
 };
 
@@ -34,7 +49,7 @@
   // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
   // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
   // CHECK: call void @_ZdlPv(i8* %[[MEM]])
-  co_await suspend_always{};
+  co_return;
 }
 
 struct promise_new_tag {};
@@ -59,7 +74,7 @@
   // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
   // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
   // CHECK: call void @_ZdlPv(i8* %[[MEM]])
-  co_await suspend_always{};
+  co_return;
 }
 
 struct promise_delete_tag {};
@@ -84,7 +99,7 @@
   // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
   // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
   // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJv18promise_delete_tagEE12promise_typedlEPv(i8* %[[MEM]])
-  co_await suspend_always{};
+  co_return;
 }
 
 struct promise_sized_delete_tag {};
@@ -100,7 +115,7 @@
   };
 };
 
-// CHECK-LABEL: f3( 
+// CHECK-LABEL: f3(
 extern "C" void f3(promise_sized_delete_tag) {
   // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
   // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
@@ -110,5 +125,5 @@
   // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
   // CHECK: %[[SIZE2:.+]] = call i64 @llvm.coro.size.i64()
   // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJv24promise_sized_delete_tagEE12promise_typedlEPvm(i8* %[[MEM]], i64 %[[SIZE2]])
-  co_await suspend_always{};
+  co_return;
 }
diff --git a/test/CodeGenCoroutines/coro-builtins.c b/test/CodeGenCoroutines/coro-builtins.c
index 5c3e6c3..d18d5e7 100644
--- a/test/CodeGenCoroutines/coro-builtins.c
+++ b/test/CodeGenCoroutines/coro-builtins.c
@@ -43,7 +43,7 @@
   __builtin_coro_free(__builtin_coro_frame());
 
   // CHECK-NEXT: %[[FRAME6:.+]] = call i8* @llvm.coro.frame() 
-  // CHECK-NEXT: call void @llvm.coro.end(i8* %[[FRAME6]], i1 false)
+  // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME6]], i1 false)
   __builtin_coro_end(__builtin_coro_frame(), 0);
 
   // CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true)
diff --git a/test/CodeGenCoroutines/coro-return.cpp b/test/CodeGenCoroutines/coro-return.cpp
new file mode 100644
index 0000000..26aaa90
--- /dev/null
+++ b/test/CodeGenCoroutines/coro-return.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s
+
+namespace std {
+namespace experimental {
+template <typename... T>
+struct coroutine_traits;
+
+template <class Promise = void>
+struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) { return {}; }
+};
+
+template <>
+struct coroutine_handle<void> {
+  static coroutine_handle from_address(void *) { return {}; }
+  coroutine_handle() = default;
+  template <class PromiseType>
+  coroutine_handle(coroutine_handle<PromiseType>) {}
+};
+
+}
+}
+
+struct suspend_always {
+  bool await_ready();
+  void await_suspend(std::experimental::coroutine_handle<>);
+  void await_resume();
+};
+
+template<>
+struct std::experimental::coroutine_traits<void> {
+  struct promise_type {
+    void get_return_object();
+    suspend_always initial_suspend();
+    suspend_always final_suspend();
+    void return_void();
+  };
+};
+
+// CHECK-LABEL: f0(
+extern "C" void f0() {
+  // CHECK: %__promise = alloca %"struct.std::experimental::coroutine_traits<void>::promise_type"
+  // CHECK: %call = call i8* @_Znwm(
+  // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_type11return_voidEv(%"struct.std::experimental::coroutine_traits<void>::promise_type"* %__promise)
+  // CHECK: call void @_ZdlPv
+  co_return;
+}
+
+template<>
+struct std::experimental::coroutine_traits<int> {
+  struct promise_type {
+    int get_return_object();
+    suspend_always initial_suspend();
+    suspend_always final_suspend();
+    void return_value(int);
+  };
+};
+
+// CHECK-LABEL: f1(
+extern "C" int f1() {
+  // CHECK: %__promise = alloca %"struct.std::experimental::coroutine_traits<int>::promise_type"
+  // CHECK: %call = call i8* @_Znwm(
+  // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_type12return_valueEi(%"struct.std::experimental::coroutine_traits<int>::promise_type"* %__promise, i32 42)
+  // CHECK: call void @_ZdlPv
+  co_return 42;
+}
diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m
index 30f9271..06eb46b 100644
--- a/test/CodeGenObjC/arc-blocks.m
+++ b/test/CodeGenObjC/arc-blocks.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck %s
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-UNOPT %s
 
 // This shouldn't crash.
@@ -667,6 +667,41 @@
 // CHECK-UNOPT-NEXT: ret void
 }
 
+// Ensure that we don't emit helper code in copy/dispose routines for variables
+// that are const-captured.
+void testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers(id x, id y) {
+  id __unsafe_unretained unsafeObject = x;
+  (^ { testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers(x, unsafeObject); })();
+}
+
+// CHECK-LABEL: testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers_block_invoke
+// CHECK-UNOPT-LABEL: testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers_block_invoke
+
+// CHECK-UNOPT: @__copy_helper_block
+// CHECK-UNOPT: alloca
+// CHECK-UNOPT-NEXT: alloca
+// CHECK-UNOPT-NEXT: store
+// CHECK-UNOPT-NEXT: store
+// CHECK-UNOPT-NEXT: load
+// CHECK-UNOPT-NEXT: bitcast
+// CHECK-UNOPT-NEXT: load
+// CHECK-UNOPT-NEXT: bitcast
+// CHECK-UNOPT-NEXT: getelementptr
+// CHECK-UNOPT-NEXT: getelementptr
+// CHECK-UNOPT-NEXT: load
+// CHECK-UNOPT-NEXT: store
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong
+// CHECK-UNOPT-NEXT: ret
+
+// CHECK-UNOPT: @__destroy_helper_block
+// CHECK-UNOPT: alloca
+// CHECK-UNOPT-NEXT: store
+// CHECK-UNOPT-NEXT: load
+// CHECK-UNOPT-NEXT: bitcast
+// CHECK-UNOPT-NEXT: getelementptr
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong
+// CHECK-UNOPT-NEXT: ret
+
 // rdar://13588325
 void test19_sink(void (^)(int));
 void test19(void (^b)(void)) {
diff --git a/test/CodeGenObjC/arc-bridged-cast.m b/test/CodeGenObjC/arc-bridged-cast.m
index f489853..97a45c5 100644
--- a/test/CodeGenObjC/arc-bridged-cast.m
+++ b/test/CodeGenObjC/arc-bridged-cast.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 typedef const void *CFTypeRef;
 typedef const struct __CFString *CFStringRef;
diff --git a/test/CodeGenObjC/arc-linetable-autorelease.m b/test/CodeGenObjC/arc-linetable-autorelease.m
index 26a779b..6812e8a 100644
--- a/test/CodeGenObjC/arc-linetable-autorelease.m
+++ b/test/CodeGenObjC/arc-linetable-autorelease.m
@@ -30,11 +30,10 @@
   // CHECK: define {{.*}}_createBezierPathWithWidth
   // CHECK: load {{.*}} %path, align {{.*}}, !dbg ![[RET:[0-9]+]]
   // CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC:[0-9]+]]
-  // CHECK: call {{.*}} @objc_autoreleaseReturnValue{{.*}} !dbg ![[ARC1:[0-9]+]]
+  // CHECK: call {{.*}} @objc_autoreleaseReturnValue{{.*}} !dbg ![[ARC]]
   // CHECK: ret {{.*}} !dbg ![[ARC]]
   // CHECK: ![[RET]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
   return path;
-  // CHECK: ![[ARC]] = !DILocation(line: [[@LINE+2]], scope: !{{.*}})
-  // CHECK: ![[ARC1]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
+  // CHECK: ![[ARC]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
 }
 @end
diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m
index ab6c82b..74e231c 100644
--- a/test/CodeGenObjC/arc-literals.m
+++ b/test/CodeGenObjC/arc-literals.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 #include "literal-support.h"
 
diff --git a/test/CodeGenObjC/arc-no-arc-exceptions.m b/test/CodeGenObjC/arc-no-arc-exceptions.m
index f147b64..3338ad8 100644
--- a/test/CodeGenObjC/arc-no-arc-exceptions.m
+++ b/test/CodeGenObjC/arc-no-arc-exceptions.m
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -O2 -disable-llvm-optzns -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -disable-llvm-optzns -o - %s | FileCheck -check-prefix=NO-METADATA %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -O2 -disable-llvm-optzns -o - %s -fobjc-arc-exceptions | FileCheck -check-prefix=NO-METADATA %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -O2 -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -disable-llvm-passes -o - %s | FileCheck -check-prefix=NO-METADATA %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -O2 -disable-llvm-passes -o - %s -fobjc-arc-exceptions | FileCheck -check-prefix=NO-METADATA %s
 
 // The front-end should emit clang.arc.no_objc_arc_exceptions in -fobjc-arc-exceptions
 // mode when optimization is enabled, and not otherwise.
diff --git a/test/CodeGenObjC/arc-precise-lifetime.m b/test/CodeGenObjC/arc-precise-lifetime.m
index 42a0483..eb3111c 100644
--- a/test/CodeGenObjC/arc-precise-lifetime.m
+++ b/test/CodeGenObjC/arc-precise-lifetime.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 #define PRECISE_LIFETIME __attribute__((objc_precise_lifetime))
 
diff --git a/test/CodeGenObjC/arc-ternary-op.m b/test/CodeGenObjC/arc-ternary-op.m
index c6bbab2..883fcd3 100644
--- a/test/CodeGenObjC/arc-ternary-op.m
+++ b/test/CodeGenObjC/arc-ternary-op.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 void test0(_Bool cond) {
   id test0_helper(void) __attribute__((ns_returns_retained));
diff --git a/test/CodeGenObjC/arc-unsafeclaim.m b/test/CodeGenObjC/arc-unsafeclaim.m
index cda00b0..01329df 100644
--- a/test/CodeGenObjC/arc-unsafeclaim.m
+++ b/test/CodeGenObjC/arc-unsafeclaim.m
@@ -1,13 +1,16 @@
 //   Make sure it works on x86-64.
 // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED
 
+//   Make sure it works on x86-32.
+// RUN: %clang_cc1 -triple i386-apple-darwin11 -fobjc-runtime=macosx-fragile-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED
+
 //   Make sure it works on ARM.
 // RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED
-// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED
 
 //   Make sure it works on ARM64.
 // RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED
-// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED
+// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED
 
 //   Make sure that it's implicitly disabled if the runtime version isn't high enough.
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.10 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index f756df1..fc135af 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -1,36 +1,36 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-GLOBALS %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-GLOBALS %s
 
 // rdar://13129783. Check both native/non-native arc platforms. Here we check
 // that they treat nonlazybind differently.
-// RUN: %clang_cc1 -fobjc-runtime=macosx-10.6.0 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-ALIEN %s
-// RUN: %clang_cc1 -fobjc-runtime=macosx-10.7.0 -triple x86_64-apple-darwin11 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-NATIVE %s
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.6.0 -triple x86_64-apple-darwin10 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-ALIEN %s
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.7.0 -triple x86_64-apple-darwin11 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-NATIVE %s
 
 // ARC-ALIEN: declare extern_weak void @objc_storeStrong(i8**, i8*)
-// ARC-ALIEN: declare extern_weak i8* @objc_retain(i8*)
-// ARC-ALIEN: declare extern_weak i8* @objc_autoreleaseReturnValue(i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_retain(i8* returned)
+// ARC-ALIEN: declare extern_weak i8* @objc_autoreleaseReturnValue(i8* returned)
 // ARC-ALIEN: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB:#[0-9]+]]
 // ARC-ALIEN: declare extern_weak void @objc_release(i8*)
-// ARC-ALIEN: declare extern_weak i8* @objc_retainAutoreleasedReturnValue(i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_retainAutoreleasedReturnValue(i8* returned)
 // ARC-ALIEN: declare extern_weak i8* @objc_initWeak(i8**, i8*)
 // ARC-ALIEN: declare extern_weak i8* @objc_storeWeak(i8**, i8*)
 // ARC-ALIEN: declare extern_weak i8* @objc_loadWeakRetained(i8**)
 // ARC-ALIEN: declare extern_weak void @objc_destroyWeak(i8**)
-// ARC-ALIEN: declare extern_weak i8* @objc_autorelease(i8*)
-// ARC-ALIEN: declare extern_weak i8* @objc_retainAutorelease(i8*)
+// declare extern_weak i8* @objc_autorelease(i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_retainAutorelease(i8* returned)
 
 // ARC-NATIVE: declare void @objc_storeStrong(i8**, i8*)
-// ARC-NATIVE: declare i8* @objc_retain(i8*) [[NLB:#[0-9]+]]
-// ARC-NATIVE: declare i8* @objc_autoreleaseReturnValue(i8*)
+// ARC-NATIVE: declare i8* @objc_retain(i8* returned) [[NLB:#[0-9]+]]
+// ARC-NATIVE: declare i8* @objc_autoreleaseReturnValue(i8* returned)
 // ARC-NATIVE: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB]]
 // ARC-NATIVE: declare void @objc_release(i8*) [[NLB]]
-// ARC-NATIVE: declare i8* @objc_retainAutoreleasedReturnValue(i8*)
+// ARC-NATIVE: declare i8* @objc_retainAutoreleasedReturnValue(i8* returned)
 // ARC-NATIVE: declare i8* @objc_initWeak(i8**, i8*)
 // ARC-NATIVE: declare i8* @objc_storeWeak(i8**, i8*)
 // ARC-NATIVE: declare i8* @objc_loadWeakRetained(i8**)
 // ARC-NATIVE: declare void @objc_destroyWeak(i8**)
-// ARC-NATIVE: declare i8* @objc_autorelease(i8*)
-// ARC-NATIVE: declare i8* @objc_retainAutorelease(i8*)
+// declare i8* @objc_autorelease(i8*)
+// ARC-NATIVE: declare i8* @objc_retainAutorelease(i8* returned)
 
 // CHECK-LABEL: define void @test0
 void test0(id x) {
@@ -1504,7 +1504,9 @@
 // CHECK:      [[SELF:%.*]] = alloca [[TEST69:%.*]]*, align 8
 // CHECK:      [[T0:%.*]] = load [[TEST69]]*, [[TEST69]]** [[SELF]], align 8
 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST69]]* [[T0]] to i8*
-// CHECK-NEXT: ret i8* [[T1]]
+// CHECK-NEXT: [[RETAIN:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[AUTORELEASE:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[RETAIN]])
+// CHECK-NEXT: ret i8* [[AUTORELEASE]]
 
 // rdar://problem/10907547
 void test70(id i) {
diff --git a/test/CodeGenObjC/availability-check.m b/test/CodeGenObjC/availability-check.m
new file mode 100644
index 0000000..71c5ff7
--- /dev/null
+++ b/test/CodeGenObjC/availability-check.m
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11 -emit-llvm -o - %s | FileCheck %s
+
+void use_at_available() {
+  // CHECK: call i32 @__isOSVersionAtLeast(i32 10, i32 12, i32 0)
+  // CHECK-NEXT: icmp ne
+  if (__builtin_available(macos 10.12, *))
+    ;
+
+  // CHECK: call i32 @__isOSVersionAtLeast(i32 10, i32 12, i32 0)
+  // CHECK-NEXT: icmp ne
+  if (@available(macos 10.12, *))
+    ;
+
+  // CHECK: call i32 @__isOSVersionAtLeast(i32 10, i32 12, i32 42)
+  // CHECK-NEXT: icmp ne
+  if (__builtin_available(ios 10, macos 10.12.42, *))
+    ;
+
+  // CHECK-NOT: call i32 @__isOSVersionAtLeast
+  // CHECK: br i1 true
+  if (__builtin_available(ios 10, *))
+    ;
+
+  // This check should be folded: our deployment target is 10.11.
+  // CHECK-NOT: call i32 @__isOSVersionAtLeast
+  // CHECK: br i1 true
+  if (__builtin_available(macos 10.11, *))
+    ;
+}
+
+// CHECK: declare i32 @__isOSVersionAtLeast(i32, i32, i32)
diff --git a/test/CodeGenObjC/block-ptr-type-crash.m b/test/CodeGenObjC/block-ptr-type-crash.m
new file mode 100644
index 0000000..385d645
--- /dev/null
+++ b/test/CodeGenObjC/block-ptr-type-crash.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -Wno-objc-root-class -fblocks -o /dev/null -triple x86_64-- -emit-llvm %s
+// REQUIRES: asserts
+// Verify there is no assertion.
+
+// rdar://30111891
+
+typedef unsigned long long uint64_t;
+typedef enum AnEnum : uint64_t AnEnum;
+enum AnEnum: uint64_t {
+    AnEnumA
+};
+
+typedef void (^BlockType)();
+@interface MyClass
+@end
+@implementation MyClass
+- (void)_doStuff {
+  struct {
+    int identifier;
+    AnEnum type;
+    BlockType handler;
+  } var = {
+    "hello",
+    AnEnumA,
+    ((void *)0)
+  };
+}
+@end
diff --git a/test/CodeGenObjC/encode-test.m b/test/CodeGenObjC/encode-test.m
index 7f0e76f..a1f88e0 100644
--- a/test/CodeGenObjC/encode-test.m
+++ b/test/CodeGenObjC/encode-test.m
@@ -180,3 +180,14 @@
 
 // CHECK: @g15 = constant [2 x i8] c":\00"
 const char g15[] = @encode(SEL);
+
+typedef typeof(sizeof(int)) size_t;
+size_t strlen(const char *s);
+
+// CHECK-LABEL: @test_strlen(
+// CHECK: %[[i:.*]] = alloca i32
+// CHECK: store i32 1, i32* %[[i]]
+void test_strlen() {
+  const char array[] = @encode(int);
+  int i = strlen(array);
+}
diff --git a/test/CodeGenObjC/gnu-exceptions.m b/test/CodeGenObjC/gnu-exceptions.m
index 76e9e1d..2407f8f 100644
--- a/test/CodeGenObjC/gnu-exceptions.m
+++ b/test/CodeGenObjC/gnu-exceptions.m
@@ -32,4 +32,4 @@
   log(1);
 }
 
-// CHECK: attributes [[TF]] = { "{{.*}} }
+// CHECK: attributes [[TF]] = { noinline "{{.*}} }
diff --git a/test/CodeGenObjC/ivar-type-encoding.m b/test/CodeGenObjC/ivar-type-encoding.m
new file mode 100644
index 0000000..ffa5e0d
--- /dev/null
+++ b/test/CodeGenObjC/ivar-type-encoding.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -S -emit-llvm -fobjc-runtime=gcc -o - %s | FileCheck %s
+
+@protocol NSCopying
+@end
+
+@interface NSObject {
+  struct objc_object *isa;
+}
++ (id) new;
+- (id) init;
+@end
+
+@interface NSString : NSObject <NSCopying>
++ (NSString *)foo;
+@end
+
+@interface TestClass : NSObject {
+@public
+  NSString    *_stringIvar;
+  int         _intIvar;
+}
+@end
+@implementation TestClass
+
+@end
+
+int main() {
+  TestClass *c = [TestClass new];
+  return 0;
+}
+
+// CHECK: @0 = private unnamed_addr constant [12 x i8] c"_stringIvar\00"
+// CHECK: @1 = private unnamed_addr constant [12 x i8] c"@\22NSString\22\00"
+// CHECK: @2 = private unnamed_addr constant [9 x i8] c"_intIvar\00"
+// CHECK: @3 = private unnamed_addr constant [2 x i8] c"i\00"
diff --git a/test/CodeGenObjC/nsvalue-objc-boxable-ios-arc.m b/test/CodeGenObjC/nsvalue-objc-boxable-ios-arc.m
index 51e7bd6..bab6e27 100644
--- a/test/CodeGenObjC/nsvalue-objc-boxable-ios-arc.m
+++ b/test/CodeGenObjC/nsvalue-objc-boxable-ios-arc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -I %S/Inputs -triple armv7-apple-ios8.0.0 -emit-llvm -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs -triple armv7-apple-ios8.0.0 -emit-llvm -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 #import "nsvalue-boxed-expressions-support.h"
 
diff --git a/test/CodeGenObjC/nsvalue-objc-boxable-ios.m b/test/CodeGenObjC/nsvalue-objc-boxable-ios.m
index 583f409..dbbe0f4 100644
--- a/test/CodeGenObjC/nsvalue-objc-boxable-ios.m
+++ b/test/CodeGenObjC/nsvalue-objc-boxable-ios.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -I %S/Inputs -triple armv7-apple-ios8.0.0 -emit-llvm -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs -triple armv7-apple-ios8.0.0 -emit-llvm -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 #import "nsvalue-boxed-expressions-support.h"
 
diff --git a/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m b/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m
index 7a37535..a2b4dfd 100644
--- a/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m
+++ b/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx -emit-llvm -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx -emit-llvm -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 #import "nsvalue-boxed-expressions-support.h"
 
diff --git a/test/CodeGenObjC/nsvalue-objc-boxable-mac.m b/test/CodeGenObjC/nsvalue-objc-boxable-mac.m
index 749dc0e..6305b6b 100644
--- a/test/CodeGenObjC/nsvalue-objc-boxable-mac.m
+++ b/test/CodeGenObjC/nsvalue-objc-boxable-mac.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx -emit-llvm -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx -emit-llvm -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 #import "nsvalue-boxed-expressions-support.h"
 
diff --git a/test/CodeGenObjC/nullptr-assert.m b/test/CodeGenObjC/nullptr-assert.m
new file mode 100644
index 0000000..06e50db
--- /dev/null
+++ b/test/CodeGenObjC/nullptr-assert.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -Wno-objc-root-class -o /dev/null -triple x86_64-- -emit-llvm %s
+// REQUIRES: asserts
+// Verify there is no assertion.
+
+@interface A
+@end
+
+extern A *a;
+
+@interface X
+@end
+
+@implementation X
+
+-(void)test {
+  struct S {
+    A *a;
+    int b;
+  };
+  struct S s[] = {{a, 0}, {(void *)0, 0}};
+}
+@end
diff --git a/test/CodeGenObjC/objc-literal-tests.m b/test/CodeGenObjC/objc-literal-tests.m
index 03286e2..aa576d4 100644
--- a/test/CodeGenObjC/objc-literal-tests.m
+++ b/test/CodeGenObjC/objc-literal-tests.m
@@ -94,4 +94,4 @@
   bar(^(void) { return YES; });
 }
 
-// CHECK: attributes [[NUW]] = { {{(norecurse )?}}nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline {{(norecurse )?}}nounwind{{.*}} }
diff --git a/test/CodeGenObjC/ubsan-bool.m b/test/CodeGenObjC/ubsan-bool.m
new file mode 100644
index 0000000..b30562c
--- /dev/null
+++ b/test/CodeGenObjC/ubsan-bool.m
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC
+// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC
+// RUN: %clang_cc1 -x c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,C
+
+typedef signed char BOOL;
+
+// SHARED-LABEL: f1
+BOOL f1() {
+  // OBJC: call void @__ubsan_handle_load_invalid_value
+  // C-NOT: call void @__ubsan_handle_load_invalid_value
+  BOOL a = 2;
+  return a + 1;
+  // SHARED: ret i8
+}
+
+struct S1 {
+  BOOL b1 : 1;
+};
+
+// SHARED-LABEL: f2
+BOOL f2(struct S1 *s) {
+  // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}}
+  // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7
+  // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7
+  // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize
+  // OBJC: call void @__ubsan_handle_load_invalid_value
+
+  // C-NOT: call void @__ubsan_handle_load_invalid_value
+  return s->b1;
+  // SHARED: ret i8
+}
+
+#ifdef __OBJC__
+@interface I1 {
+@public
+  BOOL b1 : 1;
+}
+@property (nonatomic) BOOL b1;
+@end
+@implementation I1
+@synthesize b1;
+@end
+
+// Check the synthesized getter.
+// OBJC-LABEL: define internal signext i8 @"\01-[I1 b1]"
+// OBJC: [[IVAR:%.*]] = load i64, i64* @"OBJC_IVAR_$_I1.b1"
+// OBJC: [[ADDR:%.*]] = getelementptr inbounds i8, i8* {{.*}}, i64 [[IVAR]]
+// OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}}
+// OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7
+// OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7
+// OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize
+// OBJC: call void @__ubsan_handle_load_invalid_value
+
+// Also check direct accesses to the ivar.
+// OBJC-LABEL: f3
+BOOL f3(I1 *i) {
+  // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}}
+  // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7
+  // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7
+  // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize
+  // OBJC: call void @__ubsan_handle_load_invalid_value
+
+  return i->b1;
+  // OBJC: ret i8
+}
+#endif /* __OBJC__ */
diff --git a/test/CodeGenObjC/ubsan-nonnull-and-nullability.m b/test/CodeGenObjC/ubsan-nonnull-and-nullability.m
new file mode 100644
index 0000000..b927f55
--- /dev/null
+++ b/test/CodeGenObjC/ubsan-nonnull-and-nullability.m
@@ -0,0 +1,31 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-return,returns-nonnull-attribute,nullability-arg,nonnull-attribute %s -o - -w | FileCheck %s
+
+// If both the annotation and the attribute are present, prefer the attribute,
+// since it actually affects IRGen.
+
+// CHECK-LABEL: define nonnull i32* @f1
+__attribute__((returns_nonnull)) int *_Nonnull f1(int *_Nonnull p) {
+  // CHECK: entry:
+  // CHECK-NEXT: [[ADDR:%.*]] = alloca i32*
+  // CHECK-NEXT: store i32* [[P:%.*]], i32** [[ADDR]]
+  // CHECK-NEXT: [[ARG:%.*]] = load i32*, i32** [[ADDR]]
+  // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* [[ARG]], null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], label %[[CONT:.+]], label %[[HANDLE:[^,]+]]
+  // CHECK: [[HANDLE]]:
+  // CHECK-NEXT:   call void @__ubsan_handle_nonnull_return_abort
+  // CHECK-NEXT:   unreachable, !nosanitize
+  // CHECK: [[CONT]]:
+  // CHECK-NEXT:   ret i32*
+  return p;
+}
+
+// CHECK-LABEL: define void @f2
+void f2(int *_Nonnull __attribute__((nonnull)) p) {}
+
+// CHECK-LABEL: define void @call_f2
+void call_f2() {
+  // CHECK: call void @__ubsan_handle_nonnull_arg_abort
+  // CHECK-NOT: call void @__ubsan_handle_nonnull_arg_abort
+  f2((void *)0);
+}
diff --git a/test/CodeGenObjC/ubsan-nonnull.m b/test/CodeGenObjC/ubsan-nonnull.m
new file mode 100644
index 0000000..cc0850c
--- /dev/null
+++ b/test/CodeGenObjC/ubsan-nonnull.m
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nonnull-attribute %s -o - -w | FileCheck %s
+
+@interface A
+
+-(void) one_arg: (__attribute__((nonnull)) int *) arg1;
+
+-(void) varargs: (__attribute__((nonnull)) int *) arg1, ...;
+
++(void) clsmethod: (__attribute__((nonnull)) int *) arg1;
+
+@end
+
+@implementation A
+
+// CHECK-LABEL: define internal void @"\01-[A one_arg:]"
+// CHECK-SAME: i32* nonnull
+-(void) one_arg: (__attribute__((nonnull)) int *) arg1 {}
+
+// CHECK-LABEL: define internal void @"\01-[A varargs:]"
+// CHECK-SAME: i32* nonnull
+-(void) varargs: (__attribute__((nonnull)) int *) arg1, ... {}
+
+// CHECK-LABEL: define internal void @"\01+[A clsmethod:]"
+// CHECK-SAME: i32* nonnull
++(void) clsmethod: (__attribute__((nonnull)) int *) arg1 {}
+
+@end
+
+// CHECK-LABEL: define void @call_A
+void call_A(A *a, int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
+  // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
+  // CHECK: call void {{.*}} @objc_msgSend {{.*}} ({{.*}}, i32* [[P1]])
+  [a one_arg: p];
+
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], null, !nosanitize
+  // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
+  // CHECK: call void {{.*}} @objc_msgSend {{.*}} ({{.*}}, i32* [[P2]], {{.*}})
+  [a varargs: p, p];
+
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P3:%.*]], null, !nosanitize
+  // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
+  // CHECK: call void {{.*}} @objc_msgSend {{.*}} ({{.*}}, i32* [[P3]])
+  [A clsmethod: p];
+}
diff --git a/test/CodeGenObjC/ubsan-nullability.m b/test/CodeGenObjC/ubsan-nullability.m
new file mode 100644
index 0000000..d72b774
--- /dev/null
+++ b/test/CodeGenObjC/ubsan-nullability.m
@@ -0,0 +1,182 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
+
+// CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 109, i32 1 {{.*}} i32 100, i32 6
+// CHECK: [[NONNULL_ARG_LOC:@.*]] = private unnamed_addr global {{.*}} i32 204, i32 15 {{.*}} i32 190, i32 23
+// CHECK: [[NONNULL_ASSIGN1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 305, i32 9
+// CHECK: [[NONNULL_ASSIGN2_LOC:@.*]] = private unnamed_addr global {{.*}} i32 405, i32 10
+// CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 505, i32 10
+// CHECK: [[NONNULL_INIT1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 604, i32 25
+// CHECK: [[NONNULL_INIT2_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 26
+// CHECK: [[NONNULL_INIT2_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 29
+// CHECK: [[NONNULL_RV_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 817, i32 1 {{.*}} i32 800, i32 6
+
+#define NULL ((void *)0)
+
+// CHECK-LABEL: define i32* @nonnull_retval1
+#line 100
+int *_Nonnull nonnull_retval1(int *p) {
+  // CHECK: br i1 true, label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
+  // CHECK: [[NULL]]:
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_return{{.*}}[[NONNULL_RV_LOC1]]
+  return p;
+  // CHECK: [[NONULL]]:
+  // CHECK-NEXT: ret i32*
+}
+
+#line 190
+void nonnull_arg(int *_Nonnull p) {}
+
+// CHECK-LABEL: define void @call_func_with_nonnull_arg
+#line 200
+void call_func_with_nonnull_arg(int *_Nonnull p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}}[[NONNULL_ARG_LOC]]
+  nonnull_arg(p);
+}
+
+// CHECK-LABEL: define void @nonnull_assign1
+#line 300
+void nonnull_assign1(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]]
+  int *_Nonnull local;
+  local = p;
+}
+
+// CHECK-LABEL: define void @nonnull_assign2
+#line 400
+void nonnull_assign2(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]]
+  int *_Nonnull arr[1];
+  arr[0] = p;
+}
+
+struct S1 {
+  int *_Nonnull mptr;
+};
+
+// CHECK-LABEL: define void @nonnull_assign3
+#line 500
+void nonnull_assign3(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]]
+  struct S1 s;
+  s.mptr = p;
+}
+
+// CHECK-LABEL: define void @nonnull_init1
+#line 600
+void nonnull_init1(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]]
+  int *_Nonnull local = p;
+}
+
+// CHECK-LABEL: define void @nonnull_init2
+#line 700
+void nonnull_init2(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC1]]
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]]
+  int *_Nonnull arr[] = {p, p};
+}
+
+// CHECK-LABEL: define i32* @nonnull_retval2
+#line 800
+int *_Nonnull nonnull_retval2(int *_Nonnull arg1,  //< Test this.
+                              int *_Nonnull arg2,  //< Test this.
+                              int *_Nullable arg3, //< Don't test the rest.
+                              int *arg4,
+                              int arg5, ...) {
+  // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
+  // CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize
+  // CHECK: [[ARG2CMP:%.*]] = icmp ne i32* %arg2, null, !nosanitize
+  // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[DO_RV_CHECK_1]], [[ARG2CMP]]
+  // CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
+  // CHECK: [[NULL]]:
+  // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_return{{.*}}[[NONNULL_RV_LOC2]]
+  return arg1;
+  // CHECK: [[NONULL]]:
+  // CHECK-NEXT: ret i32*
+}
+
+@interface A
++(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1;
+-(int *_Nonnull) objc_method: (int *_Nonnull) arg1;
+@end
+
+@implementation A
+
+// CHECK-LABEL: define internal i32* @"\01+[A objc_clsmethod:]"
++(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1 {
+  // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
+  // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
+  // CHECK: br i1 [[DO_RV_CHECK]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
+  // CHECK: [[NULL]]:
+  // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_return{{.*}}
+  return arg1;
+  // CHECK: [[NONULL]]:
+  // CHECK-NEXT: ret i32*
+}
+
+// CHECK-LABEL: define internal i32* @"\01-[A objc_method:]"
+-(int *_Nonnull) objc_method: (int *_Nonnull) arg1 {
+  // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
+  // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
+  // CHECK: br i1 [[DO_RV_CHECK]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
+  // CHECK: [[NULL]]:
+  // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_return{{.*}}
+  return arg1;
+  // CHECK: [[NONULL]]:
+  // CHECK-NEXT: ret i32*
+}
+@end
+
+// CHECK-LABEL: define void @call_A
+void call_A(A *a, int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
+  // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P1]])
+  [a objc_method: p];
+
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
+  // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P2]])
+  [A objc_clsmethod: p];
+}
+
+void dont_crash(int *_Nonnull p, ...) {}
+
+int main() {
+  nonnull_retval1(NULL);
+  nonnull_retval2(NULL, NULL, NULL, NULL, 0, 0, 0, 0);
+  call_func_with_nonnull_arg(NULL);
+  nonnull_assign1(NULL);
+  nonnull_assign2(NULL);
+  nonnull_assign3(NULL);
+  nonnull_init1(NULL);
+  nonnull_init2(NULL);
+  call_A(NULL, NULL);
+  dont_crash(NULL, NULL);
+  return 0;
+}
diff --git a/test/CodeGenObjCXX/arc-attrs-abi.mm b/test/CodeGenObjCXX/arc-attrs-abi.mm
new file mode 100644
index 0000000..14bdf8b
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-attrs-abi.mm
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-apple -emit-llvm -fobjc-arc -o - %s -std=c++11 | FileCheck %s --check-prefix=ITANIUM
+// RUN: %clang_cc1 -triple x86_64-windows -emit-llvm -fobjc-arc -o - %s -std=c++11
+//
+// Test cases where we weren't properly adding extended parameter info, which
+// caused assertions to fire. Hence, minimal CHECKs.
+
+struct VirtualBase {
+  VirtualBase(__attribute__((ns_consumed)) id x,
+              void * __attribute__((pass_object_size(0))));
+};
+struct WithVirtualBase : virtual VirtualBase {
+  WithVirtualBase(__attribute__((ns_consumed)) id x);
+};
+
+WithVirtualBase::WithVirtualBase(__attribute__((ns_consumed)) id x)
+    : VirtualBase(x, (void *)0) {}
+
+
+struct VirtualBase2 {
+  VirtualBase2(__attribute__((ns_consumed)) id x, void *y);
+};
+
+// In this case, we don't actually end up passing the `id` param from
+// WithVirtualBaseLast's ctor to WithVirtualBaseMid's. So, we shouldn't emit
+// ext param info for `id` to `Mid`. Itanium-only check since MSABI seems to
+// emit the construction code inline.
+struct WithVirtualBaseMid : virtual VirtualBase2 {
+  // Ensure we only pass in `this` and a vtable. Otherwise this test is useless.
+  // ITANIUM: define {{.*}} void @_ZN18WithVirtualBaseMidCI212VirtualBase2EP11objc_objectPv({{[^,]*}}, {{[^,]*}})
+  using VirtualBase2::VirtualBase2;
+};
+struct WithVirtualBaseLast : WithVirtualBaseMid {
+  using WithVirtualBaseMid::WithVirtualBaseMid;
+};
+
+void callLast(__attribute__((ns_consumed)) id x) {
+  WithVirtualBaseLast{x, (void*)0};
+}
diff --git a/test/CodeGenObjCXX/arc-blocks.mm b/test/CodeGenObjCXX/arc-blocks.mm
index 2bae18a..1e43957 100644
--- a/test/CodeGenObjCXX/arc-blocks.mm
+++ b/test/CodeGenObjCXX/arc-blocks.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=gnu++98 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -o - %s | FileCheck %s
 
 // CHECK: [[A:.*]] = type { i64, [10 x i8*] }
 
diff --git a/test/CodeGenObjCXX/arc-globals.mm b/test/CodeGenObjCXX/arc-globals.mm
index c8be8c0..a03ac99 100644
--- a/test/CodeGenObjCXX/arc-globals.mm
+++ b/test/CodeGenObjCXX/arc-globals.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 // Test that we're properly retaining lifetime-qualified pointers
 // initialized statically and wrapping up those initialization in an
diff --git a/test/CodeGenObjCXX/arc-move.mm b/test/CodeGenObjCXX/arc-move.mm
index d1710e2..7437d6b 100644
--- a/test/CodeGenObjCXX/arc-move.mm
+++ b/test/CodeGenObjCXX/arc-move.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -std=c++11 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -std=c++11 -disable-llvm-passes -o - %s | FileCheck %s
 
 // define void @_Z11simple_moveRU8__strongP11objc_objectS2_
 void simple_move(__strong id &x, __strong id &y) {
diff --git a/test/CodeGenObjCXX/arc-new-delete.mm b/test/CodeGenObjCXX/arc-new-delete.mm
index 141f401..9fb5781 100644
--- a/test/CodeGenObjCXX/arc-new-delete.mm
+++ b/test/CodeGenObjCXX/arc-new-delete.mm
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=UNOPT
-// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -O -disable-llvm-optzns | FileCheck %s -check-prefix=CHECK -check-prefix=OPT
+// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -O -disable-llvm-passes | FileCheck %s -check-prefix=CHECK -check-prefix=OPT
 
 typedef __strong id strong_id;
 typedef __weak id weak_id;
diff --git a/test/CodeGenObjCXX/arc-references.mm b/test/CodeGenObjCXX/arc-references.mm
index 8397abe..c62df4e 100644
--- a/test/CodeGenObjCXX/arc-references.mm
+++ b/test/CodeGenObjCXX/arc-references.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 @interface A
 @end
diff --git a/test/CodeGenObjCXX/arc-special-member-functions.mm b/test/CodeGenObjCXX/arc-special-member-functions.mm
index df3c229..af161dd 100644
--- a/test/CodeGenObjCXX/arc-special-member-functions.mm
+++ b/test/CodeGenObjCXX/arc-special-member-functions.mm
@@ -141,10 +141,9 @@
 
 // Implicitly-generated copy constructor for ObjCArrayMember
 // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberC2ERKS_
-// CHECK: br i1
 // CHECK: call i8* @objc_retain
 // CHECK-NEXT: store i8*
-// CHECK-NEXT: br label
+// CHECK: br i1
 // CHECK: ret
 
 // Implicitly-generated default constructor for ObjCBlockMember
diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm
index e3a6349..b9d2c4d 100644
--- a/test/CodeGenObjCXX/arc.mm
+++ b/test/CodeGenObjCXX/arc.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 struct NSFastEnumerationState;
 @interface NSArray
diff --git a/test/CodeGenObjCXX/destroy.mm b/test/CodeGenObjCXX/destroy.mm
index 5d797d3..371f729 100644
--- a/test/CodeGenObjCXX/destroy.mm
+++ b/test/CodeGenObjCXX/destroy.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -disable-llvm-passes -o - %s | FileCheck %s
 // rdar://18249673
 
 @class MyObject;
diff --git a/test/CodeGenObjCXX/encode.mm b/test/CodeGenObjCXX/encode.mm
index 5bb4a1e..e4c7618 100644
--- a/test/CodeGenObjCXX/encode.mm
+++ b/test/CodeGenObjCXX/encode.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=gnu++98 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
 
 // CHECK: v17@0:8{vector<float, float, float>=}16
 // CHECK: {vector<float, float, float>=}
diff --git a/test/CodeGenObjCXX/implicit-copy-constructor.mm b/test/CodeGenObjCXX/implicit-copy-constructor.mm
index 6c56616..e1c7b8d 100644
--- a/test/CodeGenObjCXX/implicit-copy-constructor.mm
+++ b/test/CodeGenObjCXX/implicit-copy-constructor.mm
@@ -49,12 +49,14 @@
 // CHECK: call void @_ZN1BC2ERS_
 // CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 24}}
 // CHECK: call void @_ZN1BC1ERS_
-// CHECK: br
-// CHECK: {{icmp ult.*, 2}}
-// CHECK: {{icmp ult.*, 3}}
+// CHECK: br label
 // CHECK: call void @_ZN1AC1Ev
 // CHECK: call void @_ZN1CC1ERS_1A
 // CHECK: call void @_ZN1AD1Ev
+// CHECK: {{icmp eq.*, 3}}
+// CHECK: br i1
+// CHECK: {{icmp eq.*, 2}}
+// CHECK: br i1
 // CHECK: {{call.*@objc_memmove_collectable}}
 // CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}}
 // CHECK: ret void
diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm
index 35c747c..c8247e2 100644
--- a/test/CodeGenObjCXX/lambda-expressions.mm
+++ b/test/CodeGenObjCXX/lambda-expressions.mm
@@ -71,6 +71,10 @@
 // ARC:   %[[CAPTURE1:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %[[BLOCK]], i32 0, i32 5
 // ARC:   store i32 %{{.*}}, i32* %[[CAPTURE1]]
 
+// ARC-LABEL: define internal void @"_ZZ10-[Foo foo]ENK3$_4clEv"(
+// ARC-NOT: @objc_storeStrong(
+// ARC: ret void
+
 // ARC: define internal void @"___ZZN13LambdaCapture4foo1ERiENK3$_3clEv_block_invoke"
 // ARC:   %[[CAPTURE2:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %{{.*}}, i32 0, i32 5
 // ARC:   store i32 %{{.*}}, i32* %[[CAPTURE2]]
@@ -124,6 +128,15 @@
   };
 }
 
+@interface NSObject @end
+@interface Foo : NSObject @end
+@implementation Foo
+- (void)foo {
+  [&] {
+    ^{ (void)self; }();
+  }();
+}
+@end
 
-// ARC: attributes [[NUW]] = { nounwind{{.*}} }
-// MRC: attributes [[NUW]] = { nounwind{{.*}} }
+// ARC: attributes [[NUW]] = { noinline nounwind{{.*}} }
+// MRC: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenObjCXX/literals.mm b/test/CodeGenObjCXX/literals.mm
index 4d1b501..128601e 100644
--- a/test/CodeGenObjCXX/literals.mm
+++ b/test/CodeGenObjCXX/literals.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-arc-exceptions -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=gnu++98 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-arc-exceptions -O2 -disable-llvm-passes -o - %s | FileCheck %s
 
 #include "literal-support.h"
 
diff --git a/test/CodeGenObjCXX/return.mm b/test/CodeGenObjCXX/return.mm
new file mode 100644
index 0000000..53343e1
--- /dev/null
+++ b/test/CodeGenObjCXX/return.mm
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm -fblocks -triple x86_64-apple-darwin -fstrict-return -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fblocks -triple x86_64-apple-darwin -fstrict-return -O -o - %s | FileCheck %s
+
+@interface I
+@end
+
+@implementation I
+
+- (int)method {
+}
+
+@end
+
+enum Enum {
+  a
+};
+
+int (^block)(Enum) = ^int(Enum e) {
+  switch (e) {
+  case a:
+    return 1;
+  }
+};
+
+// Ensure that both methods and blocks don't use the -fstrict-return undefined
+// behaviour optimization.
+
+// CHECK-NOT: call void @llvm.trap
+// CHECK-NOT: unreachable
diff --git a/test/CodeGenOpenCL/address-space-constant-initializers.cl b/test/CodeGenOpenCL/address-space-constant-initializers.cl
index 44c4ddf..45c64c2 100644
--- a/test/CodeGenOpenCL/address-space-constant-initializers.cl
+++ b/test/CodeGenOpenCL/address-space-constant-initializers.cl
@@ -11,8 +11,8 @@
     __constant float* constant_float_ptr;
 } ConstantArrayPointerStruct;
 
-// CHECK: %struct.ConstantArrayPointerStruct = type { float addrspace(3)* }
-// CHECK: addrspace(3) constant %struct.ConstantArrayPointerStruct { float addrspace(3)* bitcast (i8 addrspace(3)* getelementptr (i8, i8 addrspace(3)* bitcast (%struct.ArrayStruct addrspace(3)* @constant_array_struct to i8 addrspace(3)*), i64 4) to float addrspace(3)*) }
+// CHECK: %struct.ConstantArrayPointerStruct = type { float addrspace(2)* }
+// CHECK: addrspace(2) constant %struct.ConstantArrayPointerStruct { float addrspace(2)* bitcast (i8 addrspace(2)* getelementptr (i8, i8 addrspace(2)* bitcast (%struct.ArrayStruct addrspace(2)* @constant_array_struct to i8 addrspace(2)*), i64 4) to float addrspace(2)*) }
 // Bug  18567
 __constant ConstantArrayPointerStruct constant_array_pointer_struct = {
     &constant_array_struct.f
diff --git a/test/CodeGenOpenCL/address-spaces-mangling.cl b/test/CodeGenOpenCL/address-spaces-mangling.cl
index 57fd132..3c74c71 100644
--- a/test/CodeGenOpenCL/address-spaces-mangling.cl
+++ b/test/CodeGenOpenCL/address-spaces-mangling.cl
@@ -31,14 +31,14 @@
 
 __attribute__((overloadable))
 void f(local int *arg) { }
-// ASMANG: @_Z1fPU3AS2i
+// ASMANG: @_Z1fPU3AS3i
 // NOASMANG: @_Z1fPU7CLlocali
-// OCL-20-DAG: @_Z1fPU3AS2i
-// OCL-12-DAG: @_Z1fPU3AS2i
+// OCL-20-DAG: @_Z1fPU3AS3i
+// OCL-12-DAG: @_Z1fPU3AS3i
 
 __attribute__((overloadable))
 void f(constant int *arg) { }
-// ASMANG: @_Z1fPU3AS3i
+// ASMANG: @_Z1fPU3AS2i
 // NOASMANG: @_Z1fPU10CLconstanti
-// OCL-20-DAG: @_Z1fPU3AS3i
-// OCL-12-DAG: @_Z1fPU3AS3i
+// OCL-20-DAG: @_Z1fPU3AS2i
+// OCL-12-DAG: @_Z1fPU3AS2i
diff --git a/test/CodeGenOpenCL/address-spaces.cl b/test/CodeGenOpenCL/address-spaces.cl
index 68fa02d..3b34986 100644
--- a/test/CodeGenOpenCL/address-spaces.cl
+++ b/test/CodeGenOpenCL/address-spaces.cl
@@ -7,10 +7,10 @@
 // CHECK: i32 addrspace(1)* %arg
 void f__g(__global int *arg) {}
 
-// CHECK: i32 addrspace(2)* %arg
+// CHECK: i32 addrspace(3)* %arg
 void f__l(__local int *arg) {}
 
-// CHECK: i32 addrspace(3)* %arg
+// CHECK: i32 addrspace(2)* %arg
 void f__c(__constant int *arg) {}
 
 // CHECK: i32* %arg
@@ -19,10 +19,10 @@
 // CHECK: i32 addrspace(1)* %arg
 void fg(global int *arg) {}
 
-// CHECK: i32 addrspace(2)* %arg
+// CHECK: i32 addrspace(3)* %arg
 void fl(local int *arg) {}
 
-// CHECK: i32 addrspace(3)* %arg
+// CHECK: i32 addrspace(2)* %arg
 void fc(constant int *arg) {}
 
 #ifdef CL20
diff --git a/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl b/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl
index f37fe66..3c69d11 100644
--- a/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl
+++ b/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl
@@ -1,5 +1,6 @@
 // REQUIRES: amdgpu-registered-target
 // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple r600-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
 
 // CHECK-NOT: %struct.single_element_struct_arg = type { i32 }
 typedef struct single_element_struct_arg
diff --git a/test/CodeGenOpenCL/amdgpu-alignment.cl b/test/CodeGenOpenCL/amdgpu-alignment.cl
new file mode 100644
index 0000000..35a8342
--- /dev/null
+++ b/test/CodeGenOpenCL/amdgpu-alignment.cl
@@ -0,0 +1,522 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+typedef char __attribute__((ext_vector_type(2))) char2;
+typedef char __attribute__((ext_vector_type(3))) char3;
+typedef char __attribute__((ext_vector_type(4))) char4;
+typedef char __attribute__((ext_vector_type(8))) char8;
+typedef char __attribute__((ext_vector_type(16))) char16;
+
+typedef short __attribute__((ext_vector_type(2))) short2;
+typedef short __attribute__((ext_vector_type(3))) short3;
+typedef short __attribute__((ext_vector_type(4))) short4;
+typedef short __attribute__((ext_vector_type(8))) short8;
+typedef short __attribute__((ext_vector_type(16))) short16;
+
+typedef int __attribute__((ext_vector_type(2))) int2;
+typedef int __attribute__((ext_vector_type(3))) int3;
+typedef int __attribute__((ext_vector_type(4))) int4;
+typedef int __attribute__((ext_vector_type(8))) int8;
+typedef int __attribute__((ext_vector_type(16))) int16;
+
+typedef long __attribute__((ext_vector_type(2))) long2;
+typedef long __attribute__((ext_vector_type(3))) long3;
+typedef long __attribute__((ext_vector_type(4))) long4;
+typedef long __attribute__((ext_vector_type(8))) long8;
+typedef long __attribute__((ext_vector_type(16))) long16;
+
+typedef half __attribute__((ext_vector_type(2))) half2;
+typedef half __attribute__((ext_vector_type(3))) half3;
+typedef half __attribute__((ext_vector_type(4))) half4;
+typedef half __attribute__((ext_vector_type(8))) half8;
+typedef half __attribute__((ext_vector_type(16))) half16;
+
+typedef float __attribute__((ext_vector_type(2))) float2;
+typedef float __attribute__((ext_vector_type(3))) float3;
+typedef float __attribute__((ext_vector_type(4))) float4;
+typedef float __attribute__((ext_vector_type(8))) float8;
+typedef float __attribute__((ext_vector_type(16))) float16;
+
+typedef double __attribute__((ext_vector_type(2))) double2;
+typedef double __attribute__((ext_vector_type(3))) double3;
+typedef double __attribute__((ext_vector_type(4))) double4;
+typedef double __attribute__((ext_vector_type(8))) double8;
+typedef double __attribute__((ext_vector_type(16))) double16;
+
+// CHECK: @local_memory_alignment_global.lds_i8 = internal addrspace(3) global [4 x i8] undef, align 1
+// CHECK: @local_memory_alignment_global.lds_v2i8 = internal addrspace(3) global [4 x <2 x i8>] undef, align 2
+// CHECK: @local_memory_alignment_global.lds_v3i8 = internal addrspace(3) global [4 x <3 x i8>] undef, align 4
+// CHECK: @local_memory_alignment_global.lds_v4i8 = internal addrspace(3) global [4 x <4 x i8>] undef, align 4
+// CHECK: @local_memory_alignment_global.lds_v8i8 = internal addrspace(3) global [4 x <8 x i8>] undef, align 8
+// CHECK: @local_memory_alignment_global.lds_v16i8 = internal addrspace(3) global [4 x <16 x i8>] undef, align 16
+// CHECK: @local_memory_alignment_global.lds_i16 = internal addrspace(3) global [4 x i16] undef, align 2
+// CHECK: @local_memory_alignment_global.lds_v2i16 = internal addrspace(3) global [4 x <2 x i16>] undef, align 4
+// CHECK: @local_memory_alignment_global.lds_v3i16 = internal addrspace(3) global [4 x <3 x i16>] undef, align 8
+// CHECK: @local_memory_alignment_global.lds_v4i16 = internal addrspace(3) global [4 x <4 x i16>] undef, align 8
+// CHECK: @local_memory_alignment_global.lds_v8i16 = internal addrspace(3) global [4 x <8 x i16>] undef, align 16
+// CHECK: @local_memory_alignment_global.lds_v16i16 = internal addrspace(3) global [4 x <16 x i16>] undef, align 32
+// CHECK: @local_memory_alignment_global.lds_i32 = internal addrspace(3) global [4 x i32] undef, align 4
+// CHECK: @local_memory_alignment_global.lds_v2i32 = internal addrspace(3) global [4 x <2 x i32>] undef, align 8
+// CHECK: @local_memory_alignment_global.lds_v3i32 = internal addrspace(3) global [4 x <3 x i32>] undef, align 16
+// CHECK: @local_memory_alignment_global.lds_v4i32 = internal addrspace(3) global [4 x <4 x i32>] undef, align 16
+// CHECK: @local_memory_alignment_global.lds_v8i32 = internal addrspace(3) global [4 x <8 x i32>] undef, align 32
+// CHECK: @local_memory_alignment_global.lds_v16i32 = internal addrspace(3) global [4 x <16 x i32>] undef, align 64
+// CHECK: @local_memory_alignment_global.lds_i64 = internal addrspace(3) global [4 x i64] undef, align 8
+// CHECK: @local_memory_alignment_global.lds_v2i64 = internal addrspace(3) global [4 x <2 x i64>] undef, align 16
+// CHECK: @local_memory_alignment_global.lds_v3i64 = internal addrspace(3) global [4 x <3 x i64>] undef, align 32
+// CHECK: @local_memory_alignment_global.lds_v4i64 = internal addrspace(3) global [4 x <4 x i64>] undef, align 32
+// CHECK: @local_memory_alignment_global.lds_v8i64 = internal addrspace(3) global [4 x <8 x i64>] undef, align 64
+// CHECK: @local_memory_alignment_global.lds_v16i64 = internal addrspace(3) global [4 x <16 x i64>] undef, align 128
+// CHECK: @local_memory_alignment_global.lds_f16 = internal addrspace(3) global [4 x half] undef, align 2
+// CHECK: @local_memory_alignment_global.lds_v2f16 = internal addrspace(3) global [4 x <2 x half>] undef, align 4
+// CHECK: @local_memory_alignment_global.lds_v3f16 = internal addrspace(3) global [4 x <3 x half>] undef, align 8
+// CHECK: @local_memory_alignment_global.lds_v4f16 = internal addrspace(3) global [4 x <4 x half>] undef, align 8
+// CHECK: @local_memory_alignment_global.lds_v8f16 = internal addrspace(3) global [4 x <8 x half>] undef, align 16
+// CHECK: @local_memory_alignment_global.lds_v16f16 = internal addrspace(3) global [4 x <16 x half>] undef, align 32
+// CHECK: @local_memory_alignment_global.lds_f32 = internal addrspace(3) global [4 x float] undef, align 4
+// CHECK: @local_memory_alignment_global.lds_v2f32 = internal addrspace(3) global [4 x <2 x float>] undef, align 8
+// CHECK: @local_memory_alignment_global.lds_v3f32 = internal addrspace(3) global [4 x <3 x float>] undef, align 16
+// CHECK: @local_memory_alignment_global.lds_v4f32 = internal addrspace(3) global [4 x <4 x float>] undef, align 16
+// CHECK: @local_memory_alignment_global.lds_v8f32 = internal addrspace(3) global [4 x <8 x float>] undef, align 32
+// CHECK: @local_memory_alignment_global.lds_v16f32 = internal addrspace(3) global [4 x <16 x float>] undef, align 64
+// CHECK: @local_memory_alignment_global.lds_f64 = internal addrspace(3) global [4 x double] undef, align 8
+// CHECK: @local_memory_alignment_global.lds_v2f64 = internal addrspace(3) global [4 x <2 x double>] undef, align 16
+// CHECK: @local_memory_alignment_global.lds_v3f64 = internal addrspace(3) global [4 x <3 x double>] undef, align 32
+// CHECK: @local_memory_alignment_global.lds_v4f64 = internal addrspace(3) global [4 x <4 x double>] undef, align 32
+// CHECK: @local_memory_alignment_global.lds_v8f64 = internal addrspace(3) global [4 x <8 x double>] undef, align 64
+// CHECK: @local_memory_alignment_global.lds_v16f64 = internal addrspace(3) global [4 x <16 x double>] undef, align 128
+
+
+// CHECK-LABEL: @local_memory_alignment_global(
+// CHECK: store volatile i8 0, i8 addrspace(3)* getelementptr inbounds ([4 x i8], [4 x i8] addrspace(3)* @local_memory_alignment_global.lds_i8, i32 0, i32 0), align 1
+// CHECK: store volatile <2 x i8> zeroinitializer, <2 x i8> addrspace(3)* getelementptr inbounds ([4 x <2 x i8>], [4 x <2 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v2i8, i32 0, i32 0), align 2
+// CHECK: store volatile <4 x i8> <i8 0, i8 0, i8 0, i8 undef>, <4 x i8> addrspace(3)* bitcast ([4 x <3 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v3i8 to <4 x i8> addrspace(3)*), align 4
+// CHECK: store volatile <4 x i8> zeroinitializer, <4 x i8> addrspace(3)* getelementptr inbounds ([4 x <4 x i8>], [4 x <4 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v4i8, i32 0, i32 0), align 4
+// CHECK: store volatile <8 x i8> zeroinitializer, <8 x i8> addrspace(3)* getelementptr inbounds ([4 x <8 x i8>], [4 x <8 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v8i8, i32 0, i32 0), align 8
+// CHECK: store volatile <16 x i8> zeroinitializer, <16 x i8> addrspace(3)* getelementptr inbounds ([4 x <16 x i8>], [4 x <16 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v16i8, i32 0, i32 0), align 16
+// CHECK: store volatile i16 0, i16 addrspace(3)* getelementptr inbounds ([4 x i16], [4 x i16] addrspace(3)* @local_memory_alignment_global.lds_i16, i32 0, i32 0), align 2
+// CHECK: store volatile <2 x i16> zeroinitializer, <2 x i16> addrspace(3)* getelementptr inbounds ([4 x <2 x i16>], [4 x <2 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v2i16, i32 0, i32 0), align 4
+// CHECK: store volatile <4 x i16> <i16 0, i16 0, i16 0, i16 undef>, <4 x i16> addrspace(3)* bitcast ([4 x <3 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v3i16 to <4 x i16> addrspace(3)*), align 8
+// CHECK: store volatile <4 x i16> zeroinitializer, <4 x i16> addrspace(3)* getelementptr inbounds ([4 x <4 x i16>], [4 x <4 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v4i16, i32 0, i32 0), align 8
+// CHECK: store volatile <8 x i16> zeroinitializer, <8 x i16> addrspace(3)* getelementptr inbounds ([4 x <8 x i16>], [4 x <8 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v8i16, i32 0, i32 0), align 16
+// CHECK: store volatile <16 x i16> zeroinitializer, <16 x i16> addrspace(3)* getelementptr inbounds ([4 x <16 x i16>], [4 x <16 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v16i16, i32 0, i32 0), align 32
+// CHECK: store volatile i32 0, i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* @local_memory_alignment_global.lds_i32, i32 0, i32 0), align 4
+// CHECK: store volatile <2 x i32> zeroinitializer, <2 x i32> addrspace(3)* getelementptr inbounds ([4 x <2 x i32>], [4 x <2 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v2i32, i32 0, i32 0), align 8
+// CHECK: store volatile <4 x i32> <i32 0, i32 0, i32 0, i32 undef>, <4 x i32> addrspace(3)* bitcast ([4 x <3 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v3i32 to <4 x i32> addrspace(3)*), align 16
+// CHECK: store volatile <4 x i32> zeroinitializer, <4 x i32> addrspace(3)* getelementptr inbounds ([4 x <4 x i32>], [4 x <4 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v4i32, i32 0, i32 0), align 16
+// CHECK: store volatile <8 x i32> zeroinitializer, <8 x i32> addrspace(3)* getelementptr inbounds ([4 x <8 x i32>], [4 x <8 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v8i32, i32 0, i32 0), align 32
+// CHECK: store volatile <16 x i32> zeroinitializer, <16 x i32> addrspace(3)* getelementptr inbounds ([4 x <16 x i32>], [4 x <16 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v16i32, i32 0, i32 0), align 64
+// CHECK: store volatile i64 0, i64 addrspace(3)* getelementptr inbounds ([4 x i64], [4 x i64] addrspace(3)* @local_memory_alignment_global.lds_i64, i32 0, i32 0), align 8
+// CHECK: store volatile <2 x i64> zeroinitializer, <2 x i64> addrspace(3)* getelementptr inbounds ([4 x <2 x i64>], [4 x <2 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v2i64, i32 0, i32 0), align 16
+// CHECK: store volatile <4 x i64> <i64 0, i64 0, i64 0, i64 undef>, <4 x i64> addrspace(3)* bitcast ([4 x <3 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v3i64 to <4 x i64> addrspace(3)*), align 32
+// CHECK: store volatile <4 x i64> zeroinitializer, <4 x i64> addrspace(3)* getelementptr inbounds ([4 x <4 x i64>], [4 x <4 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v4i64, i32 0, i32 0), align 32
+// CHECK: store volatile <8 x i64> zeroinitializer, <8 x i64> addrspace(3)* getelementptr inbounds ([4 x <8 x i64>], [4 x <8 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v8i64, i32 0, i32 0), align 64
+// CHECK: store volatile <16 x i64> zeroinitializer, <16 x i64> addrspace(3)* getelementptr inbounds ([4 x <16 x i64>], [4 x <16 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v16i64, i32 0, i32 0), align 128
+// CHECK: store volatile half 0xH0000, half addrspace(3)* getelementptr inbounds ([4 x half], [4 x half] addrspace(3)* @local_memory_alignment_global.lds_f16, i32 0, i32 0), align 2
+// CHECK: store volatile <2 x half> zeroinitializer, <2 x half> addrspace(3)* getelementptr inbounds ([4 x <2 x half>], [4 x <2 x half>] addrspace(3)* @local_memory_alignment_global.lds_v2f16, i32 0, i32 0), align 4
+// CHECK: store volatile <4 x half> <half 0xH0000, half 0xH0000, half 0xH0000, half undef>, <4 x half> addrspace(3)* bitcast ([4 x <3 x half>] addrspace(3)* @local_memory_alignment_global.lds_v3f16 to <4 x half> addrspace(3)*), align 8
+// CHECK: store volatile <4 x half> zeroinitializer, <4 x half> addrspace(3)* getelementptr inbounds ([4 x <4 x half>], [4 x <4 x half>] addrspace(3)* @local_memory_alignment_global.lds_v4f16, i32 0, i32 0), align 8
+// CHECK: store volatile <8 x half> zeroinitializer, <8 x half> addrspace(3)* getelementptr inbounds ([4 x <8 x half>], [4 x <8 x half>] addrspace(3)* @local_memory_alignment_global.lds_v8f16, i32 0, i32 0), align 16
+// CHECK: store volatile <16 x half> zeroinitializer, <16 x half> addrspace(3)* getelementptr inbounds ([4 x <16 x half>], [4 x <16 x half>] addrspace(3)* @local_memory_alignment_global.lds_v16f16, i32 0, i32 0), align 32
+// CHECK: store volatile float 0.000000e+00, float addrspace(3)* getelementptr inbounds ([4 x float], [4 x float] addrspace(3)* @local_memory_alignment_global.lds_f32, i32 0, i32 0), align 4
+// CHECK: store volatile <2 x float> zeroinitializer, <2 x float> addrspace(3)* getelementptr inbounds ([4 x <2 x float>], [4 x <2 x float>] addrspace(3)* @local_memory_alignment_global.lds_v2f32, i32 0, i32 0), align 8
+// CHECK: store volatile <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float undef>, <4 x float> addrspace(3)* bitcast ([4 x <3 x float>] addrspace(3)* @local_memory_alignment_global.lds_v3f32 to <4 x float> addrspace(3)*), align 16
+// CHECK: store volatile <4 x float> zeroinitializer, <4 x float> addrspace(3)* getelementptr inbounds ([4 x <4 x float>], [4 x <4 x float>] addrspace(3)* @local_memory_alignment_global.lds_v4f32, i32 0, i32 0), align 16
+// CHECK: store volatile <8 x float> zeroinitializer, <8 x float> addrspace(3)* getelementptr inbounds ([4 x <8 x float>], [4 x <8 x float>] addrspace(3)* @local_memory_alignment_global.lds_v8f32, i32 0, i32 0), align 32
+// CHECK: store volatile <16 x float> zeroinitializer, <16 x float> addrspace(3)* getelementptr inbounds ([4 x <16 x float>], [4 x <16 x float>] addrspace(3)* @local_memory_alignment_global.lds_v16f32, i32 0, i32 0), align 64
+// CHECK: store volatile double 0.000000e+00, double addrspace(3)* getelementptr inbounds ([4 x double], [4 x double] addrspace(3)* @local_memory_alignment_global.lds_f64, i32 0, i32 0), align 8
+// CHECK: store volatile <2 x double> zeroinitializer, <2 x double> addrspace(3)* getelementptr inbounds ([4 x <2 x double>], [4 x <2 x double>] addrspace(3)* @local_memory_alignment_global.lds_v2f64, i32 0, i32 0), align 16
+// CHECK: store volatile <4 x double> <double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, double undef>, <4 x double> addrspace(3)* bitcast ([4 x <3 x double>] addrspace(3)* @local_memory_alignment_global.lds_v3f64 to <4 x double> addrspace(3)*), align 32
+// CHECK: store volatile <4 x double> zeroinitializer, <4 x double> addrspace(3)* getelementptr inbounds ([4 x <4 x double>], [4 x <4 x double>] addrspace(3)* @local_memory_alignment_global.lds_v4f64, i32 0, i32 0), align 32
+// CHECK: store volatile <8 x double> zeroinitializer, <8 x double> addrspace(3)* getelementptr inbounds ([4 x <8 x double>], [4 x <8 x double>] addrspace(3)* @local_memory_alignment_global.lds_v8f64, i32 0, i32 0), align 64
+// CHECK: store volatile <16 x double> zeroinitializer, <16 x double> addrspace(3)* getelementptr inbounds ([4 x <16 x double>], [4 x <16 x double>] addrspace(3)* @local_memory_alignment_global.lds_v16f64, i32 0, i32 0), align 128
+kernel void local_memory_alignment_global()
+{
+  volatile local char lds_i8[4];
+  volatile local char2 lds_v2i8[4];
+  volatile local char3 lds_v3i8[4];
+  volatile local char4 lds_v4i8[4];
+  volatile local char8 lds_v8i8[4];
+  volatile local char16 lds_v16i8[4];
+
+  volatile local short lds_i16[4];
+  volatile local short2 lds_v2i16[4];
+  volatile local short3 lds_v3i16[4];
+  volatile local short4 lds_v4i16[4];
+  volatile local short8 lds_v8i16[4];
+  volatile local short16 lds_v16i16[4];
+
+  volatile local int lds_i32[4];
+  volatile local int2 lds_v2i32[4];
+  volatile local int3 lds_v3i32[4];
+  volatile local int4 lds_v4i32[4];
+  volatile local int8 lds_v8i32[4];
+  volatile local int16 lds_v16i32[4];
+
+  volatile local long lds_i64[4];
+  volatile local long2 lds_v2i64[4];
+  volatile local long3 lds_v3i64[4];
+  volatile local long4 lds_v4i64[4];
+  volatile local long8 lds_v8i64[4];
+  volatile local long16 lds_v16i64[4];
+
+  volatile local half lds_f16[4];
+  volatile local half2 lds_v2f16[4];
+  volatile local half3 lds_v3f16[4];
+  volatile local half4 lds_v4f16[4];
+  volatile local half8 lds_v8f16[4];
+  volatile local half16 lds_v16f16[4];
+
+  volatile local float lds_f32[4];
+  volatile local float2 lds_v2f32[4];
+  volatile local float3 lds_v3f32[4];
+  volatile local float4 lds_v4f32[4];
+  volatile local float8 lds_v8f32[4];
+  volatile local float16 lds_v16f32[4];
+
+  volatile local double lds_f64[4];
+  volatile local double2 lds_v2f64[4];
+  volatile local double3 lds_v3f64[4];
+  volatile local double4 lds_v4f64[4];
+  volatile local double8 lds_v8f64[4];
+  volatile local double16 lds_v16f64[4];
+
+  *lds_i8 = 0;
+  *lds_v2i8 = 0;
+  *lds_v3i8 = 0;
+  *lds_v4i8 = 0;
+  *lds_v8i8 = 0;
+  *lds_v16i8 = 0;
+
+  *lds_i16 = 0;
+  *lds_v2i16 = 0;
+  *lds_v3i16 = 0;
+  *lds_v4i16 = 0;
+  *lds_v8i16 = 0;
+  *lds_v16i16 = 0;
+
+  *lds_i32 = 0;
+  *lds_v2i32 = 0;
+  *lds_v3i32 = 0;
+  *lds_v4i32 = 0;
+  *lds_v8i32 = 0;
+  *lds_v16i32 = 0;
+
+  *lds_i64 = 0;
+  *lds_v2i64 = 0;
+  *lds_v3i64 = 0;
+  *lds_v4i64 = 0;
+  *lds_v8i64 = 0;
+  *lds_v16i64 = 0;
+
+  *lds_f16 = 0;
+  *lds_v2f16 = 0;
+  *lds_v3f16 = 0;
+  *lds_v4f16 = 0;
+  *lds_v8f16 = 0;
+  *lds_v16f16 = 0;
+
+  *lds_f32 = 0;
+  *lds_v2f32 = 0;
+  *lds_v3f32 = 0;
+  *lds_v4f32 = 0;
+  *lds_v8f32 = 0;
+  *lds_v16f32 = 0;
+
+  *lds_f64 = 0;
+  *lds_v2f64 = 0;
+  *lds_v3f64 = 0;
+  *lds_v4f64 = 0;
+  *lds_v8f64 = 0;
+  *lds_v16f64 = 0;
+}
+
+kernel void local_memory_alignment_arg(
+  volatile local char* lds_i8,
+  volatile local char2* lds_v2i8,
+  volatile local char3* lds_v3i8,
+  volatile local char4* lds_v4i8,
+  volatile local char8* lds_v8i8,
+  volatile local char16* lds_v16i8,
+
+  volatile local short* lds_i16,
+  volatile local short2* lds_v2i16,
+  volatile local short3* lds_v3i16,
+  volatile local short4* lds_v4i16,
+  volatile local short8* lds_v8i16,
+  volatile local short16* lds_v16i16,
+
+  volatile local int* lds_i32,
+  volatile local int2* lds_v2i32,
+  volatile local int3* lds_v3i32,
+  volatile local int4* lds_v4i32,
+  volatile local int8* lds_v8i32,
+  volatile local int16* lds_v16i32,
+
+  volatile local long* lds_i64,
+  volatile local long2* lds_v2i64,
+  volatile local long3* lds_v3i64,
+  volatile local long4* lds_v4i64,
+  volatile local long8* lds_v8i64,
+  volatile local long16* lds_v16i64,
+
+  volatile local half* lds_f16,
+  volatile local half2* lds_v2f16,
+  volatile local half3* lds_v3f16,
+  volatile local half4* lds_v4f16,
+  volatile local half8* lds_v8f16,
+  volatile local half16* lds_v16f16,
+
+  volatile local float* lds_f32,
+  volatile local float2* lds_v2f32,
+  volatile local float3* lds_v3f32,
+  volatile local float4* lds_v4f32,
+  volatile local float8* lds_v8f32,
+  volatile local float16* lds_v16f32,
+
+  volatile local double* lds_f64,
+  volatile local double2* lds_v2f64,
+  volatile local double3* lds_v3f64,
+  volatile local double4* lds_v4f64,
+  volatile local double8* lds_v8f64,
+  volatile local double16* lds_v16f64)
+{
+  *lds_i8 = 0;
+  *lds_v2i8 = 0;
+  *lds_v3i8 = 0;
+  *lds_v4i8 = 0;
+  *lds_v8i8 = 0;
+  *lds_v16i8 = 0;
+
+  *lds_i16 = 0;
+  *lds_v2i16 = 0;
+  *lds_v3i16 = 0;
+  *lds_v4i16 = 0;
+  *lds_v8i16 = 0;
+  *lds_v16i16 = 0;
+
+  *lds_i32 = 0;
+  *lds_v2i32 = 0;
+  *lds_v3i32 = 0;
+  *lds_v4i32 = 0;
+  *lds_v8i32 = 0;
+  *lds_v16i32 = 0;
+
+  *lds_i64 = 0;
+  *lds_v2i64 = 0;
+  *lds_v3i64 = 0;
+  *lds_v4i64 = 0;
+  *lds_v8i64 = 0;
+  *lds_v16i64 = 0;
+
+  *lds_f16 = 0;
+  *lds_v2f16 = 0;
+  *lds_v3f16 = 0;
+  *lds_v4f16 = 0;
+  *lds_v8f16 = 0;
+  *lds_v16f16 = 0;
+
+  *lds_f32 = 0;
+  *lds_v2f32 = 0;
+  *lds_v3f32 = 0;
+  *lds_v4f32 = 0;
+  *lds_v8f32 = 0;
+  *lds_v16f32 = 0;
+
+  *lds_f64 = 0;
+  *lds_v2f64 = 0;
+  *lds_v3f64 = 0;
+  *lds_v4f64 = 0;
+  *lds_v8f64 = 0;
+  *lds_v16f64 = 0;
+}
+
+// CHECK-LABEL: @private_memory_alignment_alloca(
+// CHECK: %private_i8 = alloca [4 x i8], align 1
+// CHECK: %private_v2i8 = alloca [4 x <2 x i8>], align 2
+// CHECK: %private_v3i8 = alloca [4 x <3 x i8>], align 4
+// CHECK: %private_v4i8 = alloca [4 x <4 x i8>], align 4
+// CHECK: %private_v8i8 = alloca [4 x <8 x i8>], align 8
+// CHECK: %private_v16i8 = alloca [4 x <16 x i8>], align 16
+// CHECK: %private_i16 = alloca [4 x i16], align 2
+// CHECK: %private_v2i16 = alloca [4 x <2 x i16>], align 4
+// CHECK: %private_v3i16 = alloca [4 x <3 x i16>], align 8
+// CHECK: %private_v4i16 = alloca [4 x <4 x i16>], align 8
+// CHECK: %private_v8i16 = alloca [4 x <8 x i16>], align 16
+// CHECK: %private_v16i16 = alloca [4 x <16 x i16>], align 32
+// CHECK: %private_i32 = alloca [4 x i32], align 4
+// CHECK: %private_v2i32 = alloca [4 x <2 x i32>], align 8
+// CHECK: %private_v3i32 = alloca [4 x <3 x i32>], align 16
+// CHECK: %private_v4i32 = alloca [4 x <4 x i32>], align 16
+// CHECK: %private_v8i32 = alloca [4 x <8 x i32>], align 32
+// CHECK: %private_v16i32 = alloca [4 x <16 x i32>], align 64
+// CHECK: %private_i64 = alloca [4 x i64], align 8
+// CHECK: %private_v2i64 = alloca [4 x <2 x i64>], align 16
+// CHECK: %private_v3i64 = alloca [4 x <3 x i64>], align 32
+// CHECK: %private_v4i64 = alloca [4 x <4 x i64>], align 32
+// CHECK: %private_v8i64 = alloca [4 x <8 x i64>], align 64
+// CHECK: %private_v16i64 = alloca [4 x <16 x i64>], align 128
+// CHECK: %private_f16 = alloca [4 x half], align 2
+// CHECK: %private_v2f16 = alloca [4 x <2 x half>], align 4
+// CHECK: %private_v3f16 = alloca [4 x <3 x half>], align 8
+// CHECK: %private_v4f16 = alloca [4 x <4 x half>], align 8
+// CHECK: %private_v8f16 = alloca [4 x <8 x half>], align 16
+// CHECK: %private_v16f16 = alloca [4 x <16 x half>], align 32
+// CHECK: %private_f32 = alloca [4 x float], align 4
+// CHECK: %private_v2f32 = alloca [4 x <2 x float>], align 8
+// CHECK: %private_v3f32 = alloca [4 x <3 x float>], align 16
+// CHECK: %private_v4f32 = alloca [4 x <4 x float>], align 16
+// CHECK: %private_v8f32 = alloca [4 x <8 x float>], align 32
+// CHECK: %private_v16f32 = alloca [4 x <16 x float>], align 64
+// CHECK: %private_f64 = alloca [4 x double], align 8
+// CHECK: %private_v2f64 = alloca [4 x <2 x double>], align 16
+// CHECK: %private_v3f64 = alloca [4 x <3 x double>], align 32
+// CHECK: %private_v4f64 = alloca [4 x <4 x double>], align 32
+// CHECK: %private_v8f64 = alloca [4 x <8 x double>], align 64
+// CHECK: %private_v16f64 = alloca [4 x <16 x double>], align 128
+
+// CHECK: store volatile i8 0, i8* %arraydecay, align 1
+// CHECK: store volatile <2 x i8> zeroinitializer, <2 x i8>* %arraydecay{{[0-9]+}}, align 2
+// CHECK: store volatile <4 x i8> <i8 0, i8 0, i8 0, i8 undef>, <4 x i8>* %storetmp, align 4
+// CHECK: store volatile <4 x i8> zeroinitializer, <4 x i8>* %arraydecay{{[0-9]+}}, align 4
+// CHECK: store volatile <8 x i8> zeroinitializer, <8 x i8>* %arraydecay{{[0-9]+}}, align 8
+// CHECK: store volatile <16 x i8> zeroinitializer, <16 x i8>* %arraydecay{{[0-9]+}}, align 16
+// CHECK: store volatile i16 0, i16* %arraydecay{{[0-9]+}}, align 2
+// CHECK: store volatile <2 x i16> zeroinitializer, <2 x i16>* %arraydecay{{[0-9]+}}, align 4
+// CHECK: store volatile <4 x i16> <i16 0, i16 0, i16 0, i16 undef>, <4 x i16>* %storetmp{{[0-9]+}}, align 8
+// CHECK: store volatile <4 x i16> zeroinitializer, <4 x i16>* %arraydecay{{[0-9]+}}, align 8
+// CHECK: store volatile <8 x i16> zeroinitializer, <8 x i16>* %arraydecay{{[0-9]+}}, align 16
+// CHECK: store volatile <16 x i16> zeroinitializer, <16 x i16>* %arraydecay{{[0-9]+}}, align 32
+// CHECK: store volatile i32 0, i32* %arraydecay{{[0-9]+}}, align 4
+// CHECK: store volatile <2 x i32> zeroinitializer, <2 x i32>* %arraydecay{{[0-9]+}}, align 8
+// CHECK: store volatile <4 x i32> <i32 0, i32 0, i32 0, i32 undef>, <4 x i32>* %storetmp16, align 16
+// CHECK: store volatile <4 x i32> zeroinitializer, <4 x i32>* %arraydecay{{[0-9]+}}, align 16
+// CHECK: store volatile <8 x i32> zeroinitializer, <8 x i32>* %arraydecay{{[0-9]+}}, align 32
+// CHECK: store volatile <16 x i32> zeroinitializer, <16 x i32>* %arraydecay{{[0-9]+}}, align 64
+// CHECK: store volatile i64 0, i64* %arraydecay{{[0-9]+}}, align 8
+// CHECK: store volatile <2 x i64> zeroinitializer, <2 x i64>* %arraydecay{{[0-9]+}}, align 16
+// CHECK: store volatile <4 x i64> <i64 0, i64 0, i64 0, i64 undef>, <4 x i64>* %storetmp23, align 32
+// CHECK: store volatile <4 x i64> zeroinitializer, <4 x i64>* %arraydecay{{[0-9]+}}, align 32
+// CHECK: store volatile <8 x i64> zeroinitializer, <8 x i64>* %arraydecay{{[0-9]+}}, align 64
+// CHECK: store volatile <16 x i64> zeroinitializer, <16 x i64>* %arraydecay{{[0-9]+}}, align 128
+// CHECK: store volatile half 0xH0000, half* %arraydecay{{[0-9]+}}, align 2
+// CHECK: store volatile <2 x half> zeroinitializer, <2 x half>* %arraydecay{{[0-9]+}}, align 4
+// CHECK: store volatile <4 x half> <half 0xH0000, half 0xH0000, half 0xH0000, half undef>, <4 x half>* %storetmp{{[0-9]+}}, align 8
+// CHECK: store volatile <4 x half> zeroinitializer, <4 x half>* %arraydecay{{[0-9]+}}, align 8
+// CHECK: store volatile <8 x half> zeroinitializer, <8 x half>* %arraydecay{{[0-9]+}}, align 16
+// CHECK: store volatile <16 x half> zeroinitializer, <16 x half>* %arraydecay{{[0-9]+}}, align 32
+// CHECK: store volatile float 0.000000e+00, float* %arraydecay34, align 4
+// CHECK: store volatile <2 x float> zeroinitializer, <2 x float>* %arraydecay{{[0-9]+}}, align 8
+// CHECK: store volatile <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float undef>, <4 x float>* %storetmp{{[0-9]+}}, align 16
+// CHECK: store volatile <4 x float> zeroinitializer, <4 x float>* %arraydecay{{[0-9]+}}, align 16
+// CHECK: store volatile <8 x float> zeroinitializer, <8 x float>* %arraydecay{{[0-9]+}}, align 32
+// CHECK: store volatile <16 x float> zeroinitializer, <16 x float>* %arraydecay{{[0-9]+}}, align 64
+// CHECK: store volatile double 0.000000e+00, double* %arraydecay{{[0-9]+}}, align 8
+// CHECK: store volatile <2 x double> zeroinitializer, <2 x double>* %arraydecay{{[0-9]+}}, align 16
+// CHECK: store volatile <4 x double> <double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, double undef>, <4 x double>* %storetmp{{[0-9]+}}, align 32
+// CHECK: store volatile <4 x double> zeroinitializer, <4 x double>* %arraydecay{{[0-9]+}}, align 32
+// CHECK: store volatile <8 x double> zeroinitializer, <8 x double>* %arraydecay{{[0-9]+}}, align 64
+// CHECK: store volatile <16 x double> zeroinitializer, <16 x double>* %arraydecay{{[0-9]+}}, align 128
+kernel void private_memory_alignment_alloca()
+{
+  volatile private char private_i8[4];
+  volatile private char2 private_v2i8[4];
+  volatile private char3 private_v3i8[4];
+  volatile private char4 private_v4i8[4];
+  volatile private char8 private_v8i8[4];
+  volatile private char16 private_v16i8[4];
+
+  volatile private short private_i16[4];
+  volatile private short2 private_v2i16[4];
+  volatile private short3 private_v3i16[4];
+  volatile private short4 private_v4i16[4];
+  volatile private short8 private_v8i16[4];
+  volatile private short16 private_v16i16[4];
+
+  volatile private int private_i32[4];
+  volatile private int2 private_v2i32[4];
+  volatile private int3 private_v3i32[4];
+  volatile private int4 private_v4i32[4];
+  volatile private int8 private_v8i32[4];
+  volatile private int16 private_v16i32[4];
+
+  volatile private long private_i64[4];
+  volatile private long2 private_v2i64[4];
+  volatile private long3 private_v3i64[4];
+  volatile private long4 private_v4i64[4];
+  volatile private long8 private_v8i64[4];
+  volatile private long16 private_v16i64[4];
+
+  volatile private half private_f16[4];
+  volatile private half2 private_v2f16[4];
+  volatile private half3 private_v3f16[4];
+  volatile private half4 private_v4f16[4];
+  volatile private half8 private_v8f16[4];
+  volatile private half16 private_v16f16[4];
+
+  volatile private float private_f32[4];
+  volatile private float2 private_v2f32[4];
+  volatile private float3 private_v3f32[4];
+  volatile private float4 private_v4f32[4];
+  volatile private float8 private_v8f32[4];
+  volatile private float16 private_v16f32[4];
+
+  volatile private double private_f64[4];
+  volatile private double2 private_v2f64[4];
+  volatile private double3 private_v3f64[4];
+  volatile private double4 private_v4f64[4];
+  volatile private double8 private_v8f64[4];
+  volatile private double16 private_v16f64[4];
+
+  *private_i8 = 0;
+  *private_v2i8 = 0;
+  *private_v3i8 = 0;
+  *private_v4i8 = 0;
+  *private_v8i8 = 0;
+  *private_v16i8 = 0;
+
+  *private_i16 = 0;
+  *private_v2i16 = 0;
+  *private_v3i16 = 0;
+  *private_v4i16 = 0;
+  *private_v8i16 = 0;
+  *private_v16i16 = 0;
+
+  *private_i32 = 0;
+  *private_v2i32 = 0;
+  *private_v3i32 = 0;
+  *private_v4i32 = 0;
+  *private_v8i32 = 0;
+  *private_v16i32 = 0;
+
+  *private_i64 = 0;
+  *private_v2i64 = 0;
+  *private_v3i64 = 0;
+  *private_v4i64 = 0;
+  *private_v8i64 = 0;
+  *private_v16i64 = 0;
+
+  *private_f16 = 0;
+  *private_v2f16 = 0;
+  *private_v3f16 = 0;
+  *private_v4f16 = 0;
+  *private_v8f16 = 0;
+  *private_v16f16 = 0;
+
+  *private_f32 = 0;
+  *private_v2f32 = 0;
+  *private_v3f32 = 0;
+  *private_v4f32 = 0;
+  *private_v8f32 = 0;
+  *private_v16f32 = 0;
+
+  *private_f64 = 0;
+  *private_v2f64 = 0;
+  *private_v3f64 = 0;
+  *private_v4f64 = 0;
+  *private_v8f64 = 0;
+  *private_v16f64 = 0;
+}
diff --git a/test/CodeGenOpenCL/amdgpu-attrs.cl b/test/CodeGenOpenCL/amdgpu-attrs.cl
index e5ef58a..4ca85d3 100644
--- a/test/CodeGenOpenCL/amdgpu-attrs.cl
+++ b/test/CodeGenOpenCL/amdgpu-attrs.cl
@@ -141,26 +141,26 @@
 // CHECK-NOT: "amdgpu-num-sgpr"="0"
 // CHECK-NOT: "amdgpu-num-vgpr"="0"
 
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2]] = { nounwind "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_4]] = { nounwind "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[NUM_SGPR_32]] = { nounwind "amdgpu-num-sgpr"="32"
-// CHECK-DAG: attributes [[NUM_VGPR_64]] = { nounwind "amdgpu-num-vgpr"="64"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2]] = { noinline nounwind "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_4]] = { noinline nounwind "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[NUM_SGPR_32]] = { noinline nounwind "amdgpu-num-sgpr"="32"
+// CHECK-DAG: attributes [[NUM_VGPR_64]] = { noinline nounwind "amdgpu-num-vgpr"="64"
 
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_SGPR_32]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_SGPR_32]] = { nounwind "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_VGPR_64]] = { nounwind "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_SGPR_32]] = { nounwind "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_VGPR_64]] = { nounwind "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[NUM_SGPR_32_NUM_VGPR_64]] = { nounwind "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_SGPR_32]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_SGPR_32]] = { noinline nounwind "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_VGPR_64]] = { noinline nounwind "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_SGPR_32]] = { noinline nounwind "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_VGPR_64]] = { noinline nounwind "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[NUM_SGPR_32_NUM_VGPR_64]] = { noinline nounwind "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64"
 
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
 
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl b/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
new file mode 100644
index 0000000..c0b3009
--- /dev/null
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
@@ -0,0 +1,125 @@
+// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa -mcpu=fiji -o - %s | FileCheck %s
+
+// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_NONE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}})
+// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_LOCAL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 2)
+// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_PRIVATE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 1)
+
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+global int *FileVar0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+constant int *FileVar1;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: false, isDefinition: true)
+local int *FileVar2;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: false, isDefinition: true)
+private int *FileVar3;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+int *FileVar4;
+
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+global int *global FileVar5;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+constant int *global FileVar6;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: false, isDefinition: true)
+local int *global FileVar7;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: false, isDefinition: true)
+private int *global FileVar8;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+int *global FileVar9;
+
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+global int *constant FileVar10 = 0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+constant int *constant FileVar11 = 0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: false, isDefinition: true)
+local int *constant FileVar12 = 0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: false, isDefinition: true)
+private int *constant FileVar13 = 0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+int *constant FileVar14 = 0;
+
+kernel void kernel1(
+    // CHECK-DAG: !DILocalVariable(name: "KernelArg0", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+    global int *KernelArg0,
+    // CHECK-DAG: !DILocalVariable(name: "KernelArg1", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+    constant int *KernelArg1,
+    // CHECK-DAG: !DILocalVariable(name: "KernelArg2", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
+    local int *KernelArg2) {
+  private int *Tmp0;
+  int *Tmp1;
+
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  global int *FuncVar0 = KernelArg0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  constant int *FuncVar1 = KernelArg1;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
+  local int *FuncVar2 = KernelArg2;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]])
+  private int *FuncVar3 = Tmp0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  int *FuncVar4 = Tmp1;
+
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  global int *constant FuncVar5 = KernelArg0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  constant int *constant FuncVar6 = KernelArg1;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
+  local int *constant FuncVar7 = KernelArg2;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]])
+  private int *constant FuncVar8 = Tmp0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  int *constant FuncVar9 = Tmp1;
+
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+  global int *local FuncVar10; FuncVar10 = KernelArg0;
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+  constant int *local FuncVar11; FuncVar11 = KernelArg1;
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: true, isDefinition: true)
+  local int *local FuncVar12; FuncVar12 = KernelArg2;
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: true, isDefinition: true)
+  private int *local FuncVar13; FuncVar13 = Tmp0;
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+  int *local FuncVar14; FuncVar14 = Tmp1;
+
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar15", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  global int *private FuncVar15 = KernelArg0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar16", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  constant int *private FuncVar16 = KernelArg1;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar17", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
+  local int *private FuncVar17 = KernelArg2;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar18", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]])
+  private int *private FuncVar18 = Tmp0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar19", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  int *private FuncVar19 = Tmp1;
+}
+
+struct FileStruct0 {
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}})
+  global int *StructMem0;
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}, offset: {{[0-9]+}})
+  constant int *StructMem1;
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_LOCAL]], size: {{[0-9]+}}, offset: {{[0-9]+}})
+  local int *StructMem2;
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_PRIVATE]], size: {{[0-9]+}}, offset: {{[0-9]+}})
+  private int *StructMem3;
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}, offset: {{[0-9]+}})
+  int *StructMem4;
+};
+
+struct FileStruct1 {
+  union {
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}})
+    global int *UnionMem0;
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}})
+    constant int *UnionMem1;
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_LOCAL]], size: {{[0-9]+}})
+    local int *UnionMem2;
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_PRIVATE]], size: {{[0-9]+}})
+    private int *UnionMem3;
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}})
+    int *UnionMem4;
+  };
+  long StructMem0;
+};
+
+kernel void kernel2(global struct FileStruct0 *Kernel2Arg0,
+                    global struct FileStruct1 *Kernel2Arg1) {}
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
new file mode 100644
index 0000000..b02ad46
--- /dev/null
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
@@ -0,0 +1,131 @@
+// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa -mcpu=fiji -o - %s | FileCheck %s
+
+// CHECK-DAG: ![[NONE:[0-9]+]] = !DIExpression()
+// CHECK-DAG: ![[LOCAL:[0-9]+]] = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
+// CHECK-DAG: ![[PRIVATE:[0-9]+]] = !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)
+
+// CHECK-DAG: ![[FILEVAR0:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR0]])
+global int *FileVar0;
+// CHECK-DAG: ![[FILEVAR1:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR1]])
+constant int *FileVar1;
+// CHECK-DAG: ![[FILEVAR2:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR2]])
+local int *FileVar2;
+// CHECK-DAG: ![[FILEVAR3:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR3]])
+private int *FileVar3;
+// CHECK-DAG: ![[FILEVAR4:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR4]])
+int *FileVar4;
+
+// CHECK-DAG: ![[FILEVAR5:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR5]])
+global int *global FileVar5;
+// CHECK-DAG: ![[FILEVAR6:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR6]])
+constant int *global FileVar6;
+// CHECK-DAG: ![[FILEVAR7:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR7]])
+local int *global FileVar7;
+// CHECK-DAG: ![[FILEVAR8:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR8]])
+private int *global FileVar8;
+// CHECK-DAG: ![[FILEVAR9:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR9]])
+int *global FileVar9;
+
+// CHECK-DAG: ![[FILEVAR10:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR10]])
+global int *constant FileVar10 = 0;
+// CHECK-DAG: ![[FILEVAR11:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR11]])
+constant int *constant FileVar11 = 0;
+// CHECK-DAG: ![[FILEVAR12:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR12]])
+local int *constant FileVar12 = 0;
+// CHECK-DAG: ![[FILEVAR13:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR13]])
+private int *constant FileVar13 = 0;
+// CHECK-DAG: ![[FILEVAR14:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR14]])
+int *constant FileVar14 = 0;
+
+kernel void kernel1(
+    // CHECK-DAG: ![[KERNELARG0:[0-9]+]] = !DILocalVariable(name: "KernelArg0", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+    // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[KERNELARG0]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+    global int *KernelArg0,
+    // CHECK-DAG: ![[KERNELARG1:[0-9]+]] = !DILocalVariable(name: "KernelArg1", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+    // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[KERNELARG1]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+    constant int *KernelArg1,
+    // CHECK-DAG: ![[KERNELARG2:[0-9]+]] = !DILocalVariable(name: "KernelArg2", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+    // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[KERNELARG2]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+    local int *KernelArg2) {
+  private int *Tmp0;
+  int *Tmp1;
+
+  // CHECK-DAG: ![[FUNCVAR0:[0-9]+]] = !DILocalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR0]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  global int *FuncVar0 = KernelArg0;
+  // CHECK-DAG: ![[FUNCVAR1:[0-9]+]] = !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR1]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  constant int *FuncVar1 = KernelArg1;
+  // CHECK-DAG: ![[FUNCVAR2:[0-9]+]] = !DILocalVariable(name: "FuncVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR2]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  local int *FuncVar2 = KernelArg2;
+  // CHECK-DAG: ![[FUNCVAR3:[0-9]+]] = !DILocalVariable(name: "FuncVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR3]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  private int *FuncVar3 = Tmp0;
+  // CHECK-DAG: ![[FUNCVAR4:[0-9]+]] = !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR4]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  int *FuncVar4 = Tmp1;
+
+  // CHECK-DAG: ![[FUNCVAR5:[0-9]+]] = !DILocalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR5]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
+  global int *constant FuncVar5 = KernelArg0;
+  // CHECK-DAG: ![[FUNCVAR6:[0-9]+]] = !DILocalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR6]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
+  constant int *constant FuncVar6 = KernelArg1;
+  // CHECK-DAG: ![[FUNCVAR7:[0-9]+]] = !DILocalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR7]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
+  local int *constant FuncVar7 = KernelArg2;
+  // CHECK-DAG: ![[FUNCVAR8:[0-9]+]] = !DILocalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR8]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
+  private int *constant FuncVar8 = Tmp0;
+  // CHECK-DAG: ![[FUNCVAR9:[0-9]+]] = !DILocalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR9]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
+  int *constant FuncVar9 = Tmp1;
+
+  // CHECK-DAG: ![[FUNCVAR10:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: ![[LOCAL]])
+  global int *local FuncVar10; FuncVar10 = KernelArg0;
+  // CHECK-DAG: ![[FUNCVAR11:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR11]], expr: ![[LOCAL]])
+  constant int *local FuncVar11; FuncVar11 = KernelArg1;
+  // CHECK-DAG: ![[FUNCVAR12:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR12]], expr: ![[LOCAL]])
+  local int *local FuncVar12; FuncVar12 = KernelArg2;
+  // CHECK-DAG: ![[FUNCVAR13:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR13]], expr: ![[LOCAL]])
+  private int *local FuncVar13; FuncVar13 = Tmp0;
+  // CHECK-DAG: ![[FUNCVAR14:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR14]], expr: ![[LOCAL]])
+  int *local FuncVar14; FuncVar14 = Tmp1;
+
+  // CHECK-DAG: ![[FUNCVAR15:[0-9]+]] = !DILocalVariable(name: "FuncVar15", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR15]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  global int *private FuncVar15 = KernelArg0;
+  // CHECK-DAG: ![[FUNCVAR16:[0-9]+]] = !DILocalVariable(name: "FuncVar16", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR16]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  constant int *private FuncVar16 = KernelArg1;
+  // CHECK-DAG: ![[FUNCVAR17:[0-9]+]] = !DILocalVariable(name: "FuncVar17", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR17]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  local int *private FuncVar17 = KernelArg2;
+  // CHECK-DAG: ![[FUNCVAR18:[0-9]+]] = !DILocalVariable(name: "FuncVar18", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR18]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  private int *private FuncVar18 = Tmp0;
+  // CHECK-DAG: ![[FUNCVAR19:[0-9]+]] = !DILocalVariable(name: "FuncVar19", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR19]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  int *private FuncVar19 = Tmp1;
+}
diff --git a/test/CodeGenOpenCL/amdgpu-nullptr.cl b/test/CodeGenOpenCL/amdgpu-nullptr.cl
new file mode 100644
index 0000000..37c7469
--- /dev/null
+++ b/test/CodeGenOpenCL/amdgpu-nullptr.cl
@@ -0,0 +1,624 @@
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -O0 -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -emit-llvm -o - | FileCheck --check-prefix=NOOPT %s
+
+typedef struct {
+  private char *p1;
+  local char *p2;
+  constant char *p3;
+  global char *p4;
+  generic char *p5;
+} StructTy1;
+
+typedef struct {
+  constant char *p3;
+  global char *p4;
+  generic char *p5;
+} StructTy2;
+
+// LLVM requests global variable with common linkage to be initialized with zeroinitializer, therefore use -fno-common
+// to suppress common linkage for tentative definition.
+
+// Test 0 as initializer.
+
+// CHECK: @private_p = local_unnamed_addr addrspace(1) global i8* null, align 4
+private char *private_p = 0;
+
+// CHECK: @local_p = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
+local char *local_p = 0;
+
+// CHECK: @global_p = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 4
+global char *global_p = 0;
+
+// CHECK: @constant_p = local_unnamed_addr addrspace(1) global i8 addrspace(2)* null, align 4
+constant char *constant_p = 0;
+
+// CHECK: @generic_p = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 4
+generic char *generic_p = 0;
+
+// Test NULL as initializer.
+
+// CHECK: @private_p_NULL = local_unnamed_addr addrspace(1) global i8* null, align 4
+private char *private_p_NULL = NULL;
+
+// CHECK: @local_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
+local char *local_p_NULL = NULL;
+
+// CHECK: @global_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 4
+global char *global_p_NULL = NULL;
+
+// CHECK: @constant_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(2)* null, align 4
+constant char *constant_p_NULL = NULL;
+
+// CHECK: @generic_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 4
+generic char *generic_p_NULL = NULL;
+
+// Test constant folding of null pointer.
+// A null pointer should be folded to a null pointer in the target address space.
+
+// CHECK: @fold_generic = local_unnamed_addr addrspace(1) global i32 addrspace(4)* null, align 4
+generic int *fold_generic = (global int*)(generic float*)(private char*)0;
+
+// CHECK: @fold_priv = local_unnamed_addr addrspace(1) global i16* null, align 4
+private short *fold_priv = (private short*)(generic int*)(global void*)0;
+
+// CHECK: @fold_priv_arith = local_unnamed_addr addrspace(1) global i8* inttoptr (i32 10 to i8*), align 4
+private char *fold_priv_arith = (private char*)0 + 10;
+
+// CHECK: @fold_int = local_unnamed_addr addrspace(1) global i32 14, align 4
+int fold_int = (int)(private void*)(generic char*)(global int*)0 + 14;
+
+// CHECK: @fold_int2 = local_unnamed_addr addrspace(1) global i32 13, align 4
+int fold_int2 = (int) ((private void*)0 + 13);
+
+// CHECK: @fold_int3 = local_unnamed_addr addrspace(1) global i32 0, align 4
+int fold_int3 = (int) ((private int*)0);
+
+// CHECK: @fold_int4 = local_unnamed_addr addrspace(1) global i32 8, align 4
+int fold_int4 = (int) &((private int*)0)[2];
+
+// CHECK: @fold_int5 = local_unnamed_addr addrspace(1) global i32 4, align 4
+int fold_int5 = (int) &((private StructTy1*)0)->p2;
+
+
+// CHECK: @fold_int_local = local_unnamed_addr addrspace(1) global i32 13, align 4
+int fold_int_local = (int)(local void*)(generic char*)(global int*)0 + 14;
+
+// CHECK: @fold_int2_local = local_unnamed_addr addrspace(1) global i32 12, align 4
+int fold_int2_local = (int) ((local void*)0 + 13);
+
+// CHECK: @fold_int3_local = local_unnamed_addr addrspace(1) global i32 -1, align 4
+int fold_int3_local = (int) ((local int*)0);
+
+// CHECK: @fold_int4_local = local_unnamed_addr addrspace(1) global i32 7, align 4
+int fold_int4_local = (int) &((local int*)0)[2];
+
+// CHECK: @fold_int5_local = local_unnamed_addr addrspace(1) global i32 3, align 4
+int fold_int5_local = (int) &((local StructTy1*)0)->p2;
+
+
+// Test static variable initialization.
+
+// NOOPT: @test_static_var_private.sp1 = internal addrspace(1) global i8* null, align 4
+// NOOPT: @test_static_var_private.sp2 = internal addrspace(1) global i8* null, align 4
+// NOOPT: @test_static_var_private.sp3 = internal addrspace(1) global i8* null, align 4
+// NOOPT: @test_static_var_private.sp4 = internal addrspace(1) global i8* null, align 4
+// NOOPT: @test_static_var_private.sp5 = internal addrspace(1) global i8* null, align 4
+// NOOPT: @test_static_var_private.SS1 = internal addrspace(1) global %struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }, align 4
+// NOOPT: @test_static_var_private.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 4
+
+void test_static_var_private(void) {
+  static private char *sp1 = 0;
+  static private char *sp2 = NULL;
+  static private char *sp3;
+  static private char *sp4 = (private char*)((void)0, 0);
+  const int x = 0;
+  static private char *sp5 = (private char*)x;
+  static StructTy1 SS1;
+  static StructTy2 SS2;
+}
+
+// NOOPT: @test_static_var_local.sp1 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
+// NOOPT: @test_static_var_local.sp2 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
+// NOOPT: @test_static_var_local.sp3 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
+// NOOPT: @test_static_var_local.sp4 = internal addrspace(1) global i8 addrspace(3)* null, align 4
+// NOOPT: @test_static_var_local.sp5 = internal addrspace(1) global i8 addrspace(3)* null, align 4
+// NOOPT: @test_static_var_local.SS1 = internal addrspace(1) global %struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }, align 4
+// NOOPT: @test_static_var_local.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 4
+void test_static_var_local(void) {
+  static local char *sp1 = 0;
+  static local char *sp2 = NULL;
+  static local char *sp3;
+  static local char *sp4 = (local char*)((void)0, 0);
+  const int x = 0;
+  static local char *sp5 = (local char*)x;
+  static StructTy1 SS1;
+  static StructTy2 SS2;
+}
+
+// Test function-scope variable initialization.
+// NOOPT-LABEL: @test_func_scope_var_private(
+// NOOPT: store i8* null, i8** %sp1, align 4
+// NOOPT: store i8* null, i8** %sp2, align 4
+// NOOPT: store i8* null, i8** %sp3, align 4
+// NOOPT: store i8* null, i8** %sp4, align 4
+// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1* %SS1 to i8*
+// NOOPT: call void @llvm.memcpy.p0i8.p2i8.i64(i8* %[[SS1]], i8 addrspace(2)* bitcast (%struct.StructTy1 addrspace(2)* @test_func_scope_var_private.SS1 to i8 addrspace(2)*), i64 32, i32 4, i1 false)
+// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2* %SS2 to i8*
+// NOOPT: call void @llvm.memset.p0i8.i64(i8* %[[SS2]], i8 0, i64 24, i32 4, i1 false)
+void test_func_scope_var_private(void) {
+  private char *sp1 = 0;
+  private char *sp2 = NULL;
+  private char *sp3 = (private char*)((void)0, 0);
+  const int x = 0;
+  private char *sp4 = (private char*)x;
+  StructTy1 SS1 = {0, 0, 0, 0, 0};
+  StructTy2 SS2 = {0, 0, 0};
+}
+
+// Test function-scope variable initialization.
+// NOOPT-LABEL: @test_func_scope_var_local(
+// NOOPT: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)** %sp1, align 4
+// NOOPT: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)** %sp2, align 4
+// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)** %sp3, align 4
+// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)** %sp4, align 4
+// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1* %SS1 to i8*
+// NOOPT: call void @llvm.memcpy.p0i8.p2i8.i64(i8* %[[SS1]], i8 addrspace(2)* bitcast (%struct.StructTy1 addrspace(2)* @test_func_scope_var_local.SS1 to i8 addrspace(2)*), i64 32, i32 4, i1 false)
+// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2* %SS2 to i8*
+// NOOPT: call void @llvm.memset.p0i8.i64(i8* %[[SS2]], i8 0, i64 24, i32 4, i1 false)
+void test_func_scope_var_local(void) {
+  local char *sp1 = 0;
+  local char *sp2 = NULL;
+  local char *sp3 = (local char*)((void)0, 0);
+  const int x = 0;
+  local char *sp4 = (local char*)x;
+  StructTy1 SS1 = {0, 0, 0, 0, 0};
+  StructTy2 SS2 = {0, 0, 0};
+}
+
+
+// Test default initialization of pointers.
+
+// Tentative definition of global variables with non-zero initializer
+// cannot have common linkage since common linkage requires zero initialization
+// and does not have explicit section.
+
+// CHECK: @p1 = common local_unnamed_addr addrspace(1) global i8* null, align 4
+private char *p1;
+
+// CHECK: @p2 = weak local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
+local char *p2;
+
+// CHECK: @p3 = common local_unnamed_addr addrspace(1) global i8 addrspace(2)* null, align 4
+constant char *p3;
+
+// CHECK: @p4 = common local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 4
+global char *p4;
+
+// CHECK: @p5 = common local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 4
+generic char *p5;
+
+// Test default initialization of sturcture.
+
+// CHECK: @S1 = weak local_unnamed_addr addrspace(1) global %struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }, align 4
+StructTy1 S1;
+
+// CHECK: @S2 = common local_unnamed_addr addrspace(1) global %struct.StructTy2 zeroinitializer, align 4
+StructTy2 S2;
+
+// Test default initialization of array.
+// CHECK: @A1 = weak local_unnamed_addr addrspace(1) global [2 x %struct.StructTy1] [%struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }, %struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }], align 4
+StructTy1 A1[2];
+
+// CHECK: @A2 = common local_unnamed_addr addrspace(1) global [2 x %struct.StructTy2] zeroinitializer, align 4
+StructTy2 A2[2];
+
+// Test comparison with 0.
+
+// CHECK-LABEL: cmp_private
+// CHECK: icmp eq i8* %p, null
+void cmp_private(private char* p) {
+  if (p != 0)
+    *p = 0;
+}
+
+// CHECK-LABEL: cmp_local
+// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
+void cmp_local(local char* p) {
+  if (p != 0)
+    *p = 0;
+}
+
+// CHECK-LABEL: cmp_global
+// CHECK: icmp eq i8 addrspace(1)* %p, null
+void cmp_global(global char* p) {
+  if (p != 0)
+    *p = 0;
+}
+
+// CHECK-LABEL: cmp_constant
+// CHECK: icmp eq i8 addrspace(2)* %p, null
+char cmp_constant(constant char* p) {
+  if (p != 0)
+    return *p;
+  else
+    return 0;
+}
+
+// CHECK-LABEL: cmp_generic
+// CHECK: icmp eq i8 addrspace(4)* %p, null
+void cmp_generic(generic char* p) {
+  if (p != 0)
+    *p = 0;
+}
+
+// Test comparison with NULL.
+
+// CHECK-LABEL: cmp_NULL_private
+// CHECK: icmp eq i8* %p, null
+void cmp_NULL_private(private char* p) {
+  if (p != NULL)
+    *p = 0;
+}
+
+// CHECK-LABEL: cmp_NULL_local
+// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
+void cmp_NULL_local(local char* p) {
+  if (p != NULL)
+    *p = 0;
+}
+
+// CHECK-LABEL: cmp_NULL_global
+// CHECK: icmp eq i8 addrspace(1)* %p, null
+void cmp_NULL_global(global char* p) {
+  if (p != NULL)
+    *p = 0;
+}
+
+// CHECK-LABEL: cmp_NULL_constant
+// CHECK: icmp eq i8 addrspace(2)* %p, null
+char cmp_NULL_constant(constant char* p) {
+  if (p != NULL)
+    return *p;
+  else
+    return 0;
+}
+
+// CHECK-LABEL: cmp_NULL_generic
+// CHECK: icmp eq i8 addrspace(4)* %p, null
+void cmp_NULL_generic(generic char* p) {
+  if (p != NULL)
+    *p = 0;
+}
+
+// Test storage 0 as null pointer.
+// CHECK-LABEL: test_storage_null_pointer
+// CHECK: store i8* null, i8* addrspace(4)* %arg_private
+// CHECK: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(4)* %arg_local
+// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)* addrspace(4)* %arg_global
+// CHECK: store i8 addrspace(2)* null, i8 addrspace(2)* addrspace(4)* %arg_constant
+// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)* addrspace(4)* %arg_generic
+void test_storage_null_pointer(private char** arg_private,
+                               local char** arg_local,
+                               global char** arg_global,
+                               constant char** arg_constant,
+                               generic char** arg_generic) {
+   *arg_private = 0;
+   *arg_local = 0;
+   *arg_global = 0;
+   *arg_constant = 0;
+   *arg_generic = 0;
+}
+
+// Test storage NULL as null pointer.
+// CHECK-LABEL: test_storage_null_pointer_NULL
+// CHECK: store i8* null, i8* addrspace(4)* %arg_private
+// CHECK: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(4)* %arg_local
+// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)* addrspace(4)* %arg_global
+// CHECK: store i8 addrspace(2)* null, i8 addrspace(2)* addrspace(4)* %arg_constant
+// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)* addrspace(4)* %arg_generic
+void test_storage_null_pointer_NULL(private char** arg_private,
+                                    local char** arg_local,
+                                    global char** arg_global,
+                                    constant char** arg_constant,
+                                    generic char** arg_generic) {
+   *arg_private = NULL;
+   *arg_local = NULL;
+   *arg_global = NULL;
+   *arg_constant = NULL;
+   *arg_generic = NULL;
+}
+
+// Test pass null pointer to function as argument.
+void test_pass_null_pointer_arg_calee(private char* arg_private,
+                                      local char* arg_local,
+                                      global char* arg_global,
+                                      constant char* arg_constant,
+                                      generic char* arg_generic);
+
+// CHECK-LABEL: test_pass_null_pointer_arg
+// CHECK: call void @test_pass_null_pointer_arg_calee(i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(2)* null, i8 addrspace(4)* null)
+// CHECK: call void @test_pass_null_pointer_arg_calee(i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(2)* null, i8 addrspace(4)* null)
+void test_pass_null_pointer_arg(void) {
+  test_pass_null_pointer_arg_calee(0, 0, 0, 0, 0);
+  test_pass_null_pointer_arg_calee(NULL, NULL, NULL, NULL, NULL);
+}
+
+// Test cast null pointer to size_t.
+void test_cast_null_pointer_to_sizet_calee(size_t arg_private,
+                                           size_t arg_local,
+                                           size_t arg_global,
+                                           size_t arg_constant,
+                                           size_t arg_generic);
+
+// CHECK-LABEL: test_cast_null_pointer_to_sizet
+// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0)
+// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0)
+void test_cast_null_pointer_to_sizet(void) {
+  test_cast_null_pointer_to_sizet_calee((size_t)((private char*)0),
+                                        (size_t)((local char*)0),
+                                        (size_t)((global char*)0),
+                                        (size_t)((constant char*)0),
+                                        (size_t)((generic char*)0));
+  test_cast_null_pointer_to_sizet_calee((size_t)((private char*)NULL),
+                                        (size_t)((local char*)NULL),
+                                        (size_t)((global char*)NULL),
+                                        (size_t)((constant char*)0), // NULL cannot be casted to constant pointer since it is defined as a generic pointer
+                                        (size_t)((generic char*)NULL));
+}
+
+// Test comparision between null pointers.
+#define TEST_EQ00(addr1, addr2) int test_eq00_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)0; }
+#define TEST_EQ0N(addr1, addr2) int test_eq0N_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
+#define TEST_EQN0(addr1, addr2) int test_eqN0_##addr1##_##addr2(void) { return (addr1 char*)NULL == (addr2 char*)0; }
+#define TEST_EQNN(addr1, addr2) int test_eqNN_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
+#define TEST_NE00(addr1, addr2) int test_ne00_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)0; }
+#define TEST_NE0N(addr1, addr2) int test_ne0N_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
+#define TEST_NEN0(addr1, addr2) int test_neN0_##addr1##_##addr2(void) { return (addr1 char*)NULL != (addr2 char*)0; }
+#define TEST_NENN(addr1, addr2) int test_neNN_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
+#define TEST(addr1, addr2) \
+        TEST_EQ00(addr1, addr2) \
+        TEST_EQ0N(addr1, addr2) \
+        TEST_EQN0(addr1, addr2) \
+        TEST_EQNN(addr1, addr2) \
+        TEST_NE00(addr1, addr2) \
+        TEST_NE0N(addr1, addr2) \
+        TEST_NEN0(addr1, addr2) \
+        TEST_NENN(addr1, addr2)
+
+// CHECK-LABEL: test_eq00_generic_private
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eq0N_generic_private
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eqN0_generic_private
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eqNN_generic_private
+// CHECK: ret i32 1
+// CHECK-LABEL: test_ne00_generic_private
+// CHECK: ret i32 0
+// CHECK-LABEL: test_ne0N_generic_private
+// CHECK: ret i32 0
+// CHECK-LABEL: test_neN0_generic_private
+// CHECK: ret i32 0
+// CHECK-LABEL: test_neNN_generic_private
+// CHECK: ret i32 0
+TEST(generic, private)
+
+// CHECK-LABEL: test_eq00_generic_local
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eq0N_generic_local
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eqN0_generic_local
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eqNN_generic_local
+// CHECK: ret i32 1
+// CHECK-LABEL: test_ne00_generic_local
+// CHECK: ret i32 0
+// CHECK-LABEL: test_ne0N_generic_local
+// CHECK: ret i32 0
+// CHECK-LABEL: test_neN0_generic_local
+// CHECK: ret i32 0
+// CHECK-LABEL: test_neNN_generic_local
+// CHECK: ret i32 0
+TEST(generic, local)
+
+// CHECK-LABEL: test_eq00_generic_global
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eq0N_generic_global
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eqN0_generic_global
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eqNN_generic_global
+// CHECK: ret i32 1
+// CHECK-LABEL: test_ne00_generic_global
+// CHECK: ret i32 0
+// CHECK-LABEL: test_ne0N_generic_global
+// CHECK: ret i32 0
+// CHECK-LABEL: test_neN0_generic_global
+// CHECK: ret i32 0
+// CHECK-LABEL: test_neNN_generic_global
+// CHECK: ret i32 0
+TEST(generic, global)
+
+// CHECK-LABEL: test_eq00_generic_generic
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eq0N_generic_generic
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eqN0_generic_generic
+// CHECK: ret i32 1
+// CHECK-LABEL: test_eqNN_generic_generic
+// CHECK: ret i32 1
+// CHECK-LABEL: test_ne00_generic_generic
+// CHECK: ret i32 0
+// CHECK-LABEL: test_ne0N_generic_generic
+// CHECK: ret i32 0
+// CHECK-LABEL: test_neN0_generic_generic
+// CHECK: ret i32 0
+// CHECK-LABEL: test_neNN_generic_generic
+// CHECK: ret i32 0
+TEST(generic, generic)
+
+// CHECK-LABEL: test_eq00_constant_constant
+// CHECK: ret i32 1
+TEST_EQ00(constant, constant)
+
+// Test cast to bool.
+
+// CHECK-LABEL: cast_bool_private
+// CHECK: icmp eq i8* %p, null
+void cast_bool_private(private char* p) {
+  if (p)
+    *p = 0;
+}
+
+// CHECK-LABEL: cast_bool_local
+// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
+void cast_bool_local(local char* p) {
+  if (p)
+    *p = 0;
+}
+
+// CHECK-LABEL: cast_bool_global
+// CHECK: icmp eq i8 addrspace(1)* %p, null
+void cast_bool_global(global char* p) {
+  if (p)
+    *p = 0;
+}
+
+// CHECK-LABEL: cast_bool_constant
+// CHECK: icmp eq i8 addrspace(2)* %p, null
+char cast_bool_constant(constant char* p) {
+  if (p)
+    return *p;
+  else
+    return 0;
+}
+
+// CHECK-LABEL: cast_bool_generic
+// CHECK: icmp eq i8 addrspace(4)* %p, null
+void cast_bool_generic(generic char* p) {
+  if (p)
+    *p = 0;
+}
+
+// Test initialize a struct using memset.
+// For large structures which is mostly zero, clang generats llvm.memset for
+// the zero part and store for non-zero members.
+typedef struct {
+  long a, b, c, d;
+  private char *p;
+} StructTy3;
+
+// CHECK-LABEL: test_memset_private
+// CHECK: call void @llvm.memset.p0i8.i64(i8* nonnull {{.*}}, i8 0, i64 40, i32 8, i1 false)
+StructTy3 test_memset_private(void) {
+  StructTy3 S3 = {0, 0, 0, 0, 0};
+  return S3;
+}
+
+// Test casting literal 0 to pointer.
+// A 0 literal casted to pointer should become a null pointer.
+
+// CHECK-LABEL: test_cast_0_to_local_ptr
+// CHECK: ret i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*)
+local int* test_cast_0_to_local_ptr(void) {
+  return (local int*)0;
+}
+
+// CHECK-LABEL: test_cast_0_to_private_ptr
+// CHECK: ret i32* null
+private int* test_cast_0_to_private_ptr(void) {
+  return (private int*)0;
+}
+
+// Test casting non-literal integer with 0 value to pointer.
+// A non-literal integer expression with 0 value is casted to a pointer with
+// zero value.
+
+// CHECK-LABEL: test_cast_int_to_ptr1_private
+// CHECK: ret i32* null
+private int* test_cast_int_to_ptr1_private(void) {
+  return (private int*)((void)0, 0);
+}
+
+// CHECK-LABEL: test_cast_int_to_ptr1_local
+ // CHECK: ret i32 addrspace(3)* null
+local int* test_cast_int_to_ptr1_local(void) {
+  return (local int*)((void)0, 0);
+}
+
+// CHECK-LABEL: test_cast_int_to_ptr2
+// CHECK: ret i32* null
+private int* test_cast_int_to_ptr2(void) {
+  int x = 0;
+  return (private int*)x;
+}
+
+// Test logical operations.
+// CHECK-LABEL: test_not_nullptr
+// CHECK: ret i32 1
+int test_not_nullptr(void) {
+  return !(private char*)NULL;
+}
+
+// CHECK-LABEL: test_and_nullptr
+// CHECK: ret i32 0
+int test_and_nullptr(int a) {
+  return a && ((private char*)NULL);
+}
+
+// CHECK-LABEL: test_not_private_ptr
+// CHECK: %[[lnot:.*]] = icmp eq i8* %p, null
+// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
+// CHECK: ret i32 %[[lnot_ext]]
+int test_not_private_ptr(private char* p) {
+  return !p;
+}
+
+// CHECK-LABEL: test_not_local_ptr
+// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
+// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
+// CHECK: ret i32 %[[lnot_ext]]
+int test_not_local_ptr(local char* p) {
+  return !p;
+}
+
+
+// CHECK-LABEL: test_and_ptr
+// CHECK: %[[tobool:.*]] = icmp ne i8* %p1, null
+// CHECK: %[[tobool1:.*]] = icmp ne i8 addrspace(3)* %p2, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
+// CHECK: %[[res:.*]] = and i1 %[[tobool]], %[[tobool1]]
+// CHECK: %[[land_ext:.*]] = zext i1 %[[res]] to i32
+// CHECK: ret i32 %[[land_ext]]
+int test_and_ptr(private char* p1, local char* p2) {
+  return p1 && p2;
+}
+
+// Test folding of null pointer in function scope.
+// NOOPT-LABEL: test_fold_private
+// NOOPT: call void @test_fold_callee
+// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)** %glob, align 4
+// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
+// NOOPT: call void @test_fold_callee
+// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, 0
+// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
+void test_fold_callee(void);
+void test_fold_private(void) {
+  global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
+  long x = glob - (global int*)(generic char*)0;
+  x = x + (int)(test_fold_callee(), (private int*)(generic char*)(global short*)0);
+  x = x - (int)((private int*)0 == (private int*)(generic char*)0);
+}
+
+// NOOPT-LABEL: test_fold_local
+// NOOPT: call void @test_fold_callee
+// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)** %glob, align 4
+// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
+// NOOPT: call void @test_fold_callee
+// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, sext (i32 ptrtoint (i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*) to i32) to i64)
+// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
+void test_fold_local(void) {
+  global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
+  long x = glob - (global int*)(generic char*)0;
+  x = x + (int)(test_fold_callee(), (local int*)(generic char*)(global short*)0);
+  x = x - (int)((local int*)0 == (local int*)(generic char*)0);
+}
diff --git a/test/CodeGenOpenCL/blocks.cl b/test/CodeGenOpenCL/blocks.cl
new file mode 100644
index 0000000..5f0ccea
--- /dev/null
+++ b/test/CodeGenOpenCL/blocks.cl
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple spir-unknown-unknown | FileCheck -check-prefix=GENERIC -check-prefix=COMMON %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple amdgcn-amd-amdhsa-opencl | FileCheck -check-prefix=AMD -check-prefix=COMMON %s
+
+// Checking for null instead of @__NSConcreteGlobalBlock symbol
+// COMMON: @__block_literal_global = internal addrspace(1) constant { i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } { i8** null
+void (^block_A)(local void *) = ^(local void *a) {
+  return;
+};
+
+void foo(){
+  int i;
+// Checking for null instead of @_NSConcreteStackBlock symbol
+// COMMON: store i8* null, i8** %block.isa
+  int (^ block_B)(void) = ^{
+    return i;
+  };
+}
diff --git a/test/CodeGenOpenCL/builtins-amdgcn-gfx9.cl b/test/CodeGenOpenCL/builtins-amdgcn-gfx9.cl
new file mode 100644
index 0000000..333b610
--- /dev/null
+++ b/test/CodeGenOpenCL/builtins-amdgcn-gfx9.cl
@@ -0,0 +1,11 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx900 -S -emit-llvm -o - %s | FileCheck %s
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// CHECK-LABEL: @test_fmed3_f16
+// CHECK: call half @llvm.amdgcn.fmed3.f16(half %a, half %b, half %c)
+void test_fmed3_f16(global half* out, half a, half b, half c)
+{
+  *out = __builtin_amdgcn_fmed3h(a, b, c);
+}
diff --git a/test/CodeGenOpenCL/builtins-amdgcn-vi.cl b/test/CodeGenOpenCL/builtins-amdgcn-vi.cl
index 0c88fdf..1dad674 100644
--- a/test/CodeGenOpenCL/builtins-amdgcn-vi.cl
+++ b/test/CodeGenOpenCL/builtins-amdgcn-vi.cl
@@ -81,3 +81,11 @@
 {
   *out = __builtin_amdgcn_s_memrealtime();
 }
+
+// CHECK-LABEL: @test_mov_dpp
+// CHECK: call i32 @llvm.amdgcn.mov.dpp.i32(i32 %src, i32 0, i32 0, i32 0, i1 false)
+void test_mov_dpp(global int* out, int src)
+{
+  *out = __builtin_amdgcn_mov_dpp(src, 0, 0, 0, false);
+}
+
diff --git a/test/CodeGenOpenCL/builtins-amdgcn.cl b/test/CodeGenOpenCL/builtins-amdgcn.cl
index ce566b6..a19ce2f 100644
--- a/test/CodeGenOpenCL/builtins-amdgcn.cl
+++ b/test/CodeGenOpenCL/builtins-amdgcn.cl
@@ -235,6 +235,34 @@
   *out = __builtin_amdgcn_ds_swizzle(a, 32);
 }
 
+// CHECK-LABEL: @test_ds_permute
+// CHECK: call i32 @llvm.amdgcn.ds.permute(i32 %a, i32 %b)
+void test_ds_permute(global int* out, int a, int b)
+{
+  out[0] = __builtin_amdgcn_ds_permute(a, b);
+}
+
+// CHECK-LABEL: @test_ds_bpermute
+// CHECK: call i32 @llvm.amdgcn.ds.bpermute(i32 %a, i32 %b)
+void test_ds_bpermute(global int* out, int a, int b)
+{
+  *out = __builtin_amdgcn_ds_bpermute(a, b);
+}
+
+// CHECK-LABEL: @test_readfirstlane
+// CHECK: call i32 @llvm.amdgcn.readfirstlane(i32 %a)
+void test_readfirstlane(global int* out, int a)
+{
+  *out = __builtin_amdgcn_readfirstlane(a);
+}
+
+// CHECK-LABEL: @test_readlane
+// CHECK: call i32 @llvm.amdgcn.readlane(i32 %a, i32 %b)
+void test_readlane(global int* out, int a, int b)
+{
+  *out = __builtin_amdgcn_readlane(a, b);
+}
+
 // CHECK-LABEL: @test_fcmp_f32
 // CHECK: call i64 @llvm.amdgcn.fcmp.f32(float %a, float %b, i32 5)
 void test_fcmp_f32(global ulong* out, float a, float b)
@@ -263,6 +291,55 @@
   *out = __builtin_amdgcn_class(a, b);
 }
 
+// CHECK-LABEL: @test_buffer_wbinvl1
+// CHECK: call void @llvm.amdgcn.buffer.wbinvl1(
+void test_buffer_wbinvl1()
+{
+  __builtin_amdgcn_buffer_wbinvl1();
+}
+
+// CHECK-LABEL: @test_s_dcache_inv
+// CHECK: call void @llvm.amdgcn.s.dcache.inv(
+void test_s_dcache_inv()
+{
+  __builtin_amdgcn_s_dcache_inv();
+}
+
+// CHECK-LABEL: @test_s_waitcnt
+// CHECK: call void @llvm.amdgcn.s.waitcnt(
+void test_s_waitcnt()
+{
+  __builtin_amdgcn_s_waitcnt(0);
+}
+
+// CHECK-LABEL: @test_s_sendmsg
+// CHECK: call void @llvm.amdgcn.s.sendmsg(
+void test_s_sendmsg()
+{
+  __builtin_amdgcn_s_sendmsg(1, 0);
+}
+
+// CHECK-LABEL: @test_s_sendmsg_var
+// CHECK: call void @llvm.amdgcn.s.sendmsg(
+void test_s_sendmsg_var(int in)
+{
+  __builtin_amdgcn_s_sendmsg(1, in);
+}
+
+// CHECK-LABEL: @test_s_sendmsghalt
+// CHECK: call void @llvm.amdgcn.s.sendmsghalt(
+void test_s_sendmsghalt()
+{
+  __builtin_amdgcn_s_sendmsghalt(1, 0);
+}
+
+// CHECK-LABEL: @test_s_sendmsghalt
+// CHECK: call void @llvm.amdgcn.s.sendmsghalt(
+void test_s_sendmsghalt_var(int in)
+{
+  __builtin_amdgcn_s_sendmsghalt(1, in);
+}
+
 // CHECK-LABEL: @test_s_barrier
 // CHECK: call void @llvm.amdgcn.s.barrier(
 void test_s_barrier()
@@ -371,6 +448,17 @@
 	}
 }
 
+// CHECK-LABEL: @test_s_getreg(
+// CHECK: tail call i32 @llvm.amdgcn.s.getreg(i32 0)
+// CHECK: tail call i32 @llvm.amdgcn.s.getreg(i32 1)
+// CHECK: tail call i32 @llvm.amdgcn.s.getreg(i32 65535)
+void test_s_getreg(volatile global uint *out)
+{
+  *out = __builtin_amdgcn_s_getreg(0);
+  *out = __builtin_amdgcn_s_getreg(1);
+  *out = __builtin_amdgcn_s_getreg(65535);
+}
+
 // CHECK-LABEL: @test_get_local_id(
 // CHECK: tail call i32 @llvm.amdgcn.workitem.id.x(), !range [[WI_RANGE:![0-9]*]]
 // CHECK: tail call i32 @llvm.amdgcn.workitem.id.y(), !range [[WI_RANGE]]
@@ -385,6 +473,13 @@
 	}
 }
 
+// CHECK-LABEL: @test_fmed3_f32
+// CHECK: call float @llvm.amdgcn.fmed3.f32(
+void test_fmed3_f32(global float* out, float a, float b, float c)
+{
+  *out = __builtin_amdgcn_fmed3f(a, b, c);
+}
+
 // CHECK-DAG: [[WI_RANGE]] = !{i32 0, i32 1024}
 // CHECK-DAG: attributes #[[NOUNWIND_READONLY:[0-9]+]] = { nounwind readonly }
 // CHECK-DAG: attributes #[[READ_EXEC_ATTRS]] = { convergent }
diff --git a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
index 77ec747..def2906 100644
--- a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
+++ b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
@@ -2,7 +2,10 @@
 // RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -O0 -emit-llvm -o - -triple "spir64-unknown-unknown" | FileCheck %s --check-prefix=COMMON --check-prefix=B64
 
 typedef void (^bl_t)(local void *);
+typedef struct {int a;} ndrange_t;
 
+// N.B. The check here only exists to set BL_GLOBAL
+// COMMON: @block_G =  addrspace(1) constant void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_GLOBAL:@__block_literal_global(\.[0-9]+)?]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*)
 const bl_t block_G = (bl_t) ^ (local void *a) {};
 
 kernel void device_side_enqueue(global int *a, global int *b, int i) {
@@ -10,7 +13,7 @@
   queue_t default_queue;
   // COMMON: %flags = alloca i32
   unsigned flags = 0;
-  // COMMON: %ndrange = alloca %opencl.ndrange_t*
+  // COMMON: %ndrange = alloca %struct.ndrange_t
   ndrange_t ndrange;
   // COMMON: %clk_event = alloca %opencl.clk_event_t*
   clk_event_t clk_event;
@@ -19,12 +22,12 @@
   // COMMON: %event_wait_list2 = alloca [1 x %opencl.clk_event_t*]
   clk_event_t event_wait_list2[] = {clk_event};
 
+  // COMMON: [[NDR:%[a-z0-9]+]] = alloca %struct.ndrange_t, align 4
   // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
   // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
-  // COMMON: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange
-  // COMMON: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor addrspace(3)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block to void ()*
-  // COMMON: [[BL_I8:%[0-9]+]] = bitcast void ()* [[BL]] to i8*
-  // COMMON: call i32 @__enqueue_kernel_basic(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* [[BL_I8]])
+  // COMMON: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor addrspace(2)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block to void ()*
+  // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* [[BL]] to i8 addrspace(4)*
+  // COMMON: call i32 @__enqueue_kernel_basic(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* byval [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* [[BL_I8]])
   enqueue_kernel(default_queue, flags, ndrange,
                  ^(void) {
                    a[i] = b[i];
@@ -32,12 +35,11 @@
 
   // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
   // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
-  // COMMON: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange
   // COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %event_wait_list to %opencl.clk_event_t{{.*}}* addrspace(4)*
   // COMMON: [[EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
-  // COMMON: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor addrspace(3)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to void ()*
-  // COMMON: [[BL_I8:%[0-9]+]] = bitcast void ()* [[BL]] to i8*
-  // COMMON: call i32 @__enqueue_kernel_basic_events(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %opencl.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]], i8* [[BL_I8]])
+  // COMMON: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor addrspace(2)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to void ()*
+  // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* [[BL]] to i8 addrspace(4)*
+  // COMMON: call i32 @__enqueue_kernel_basic_events(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]], i8 addrspace(4)* [[BL_I8]])
   enqueue_kernel(default_queue, flags, ndrange, 2, &event_wait_list, &clk_event,
                  ^(void) {
                    a[i] = b[i];
@@ -45,9 +47,8 @@
 
   // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
   // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
-  // COMMON: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange
-  // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 256)
-  // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i64 256)
+  // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 256)
+  // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 256)
   enqueue_kernel(default_queue, flags, ndrange,
                  ^(local void *p) {
                    return;
@@ -56,11 +57,10 @@
   char c;
   // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
   // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
-  // COMMON: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange
   // B32: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i32
-  // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 [[SIZE]])
+  // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 [[SIZE]])
   // B64: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i64
-  // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i64 [[SIZE]])
+  // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 [[SIZE]])
   enqueue_kernel(default_queue, flags, ndrange,
                  ^(local void *p) {
                    return;
@@ -69,12 +69,11 @@
 
   // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
   // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
-  // COMMON: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange
   // COMMON: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i32 0, i32 0
   // COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** [[AD]] to %opencl.clk_event_t{{.*}}* addrspace(4)*
   // COMMON: [[EVNT:%[0-9]+]]  = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
-  // B32: call i32 (%opencl.queue_t{{.*}}*, i32,  %opencl.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %opencl.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}} [[WAIT_EVNT]], %opencl.clk_event_t{{.*}} [[EVNT]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 256)
-  // B64: call i32 (%opencl.queue_t{{.*}}*, i32,  %opencl.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %opencl.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}} [[WAIT_EVNT]], %opencl.clk_event_t{{.*}} [[EVNT]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i64 256)
+  // B32: call i32 (%opencl.queue_t{{.*}}*, i32,  %struct.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}} [[WAIT_EVNT]], %opencl.clk_event_t{{.*}} [[EVNT]], i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 256)
+  // B64: call i32 (%opencl.queue_t{{.*}}*, i32,  %struct.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}} [[WAIT_EVNT]], %opencl.clk_event_t{{.*}} [[EVNT]], i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 256)
   enqueue_kernel(default_queue, flags, ndrange, 2, event_wait_list2, &clk_event,
                  ^(local void *p) {
                    return;
@@ -83,14 +82,13 @@
 
   // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
   // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
-  // COMMON: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange
   // COMMON: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i32 0, i32 0
   // COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** [[AD]] to %opencl.clk_event_t{{.*}}* addrspace(4)*
   // COMMON: [[EVNT:%[0-9]+]]  = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
   // B32: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i32
-  // B32: call i32 (%opencl.queue_t{{.*}}*, i32,  %opencl.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %opencl.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 [[SIZE]])
+  // B32: call i32 (%opencl.queue_t{{.*}}*, i32,  %struct.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]], i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 [[SIZE]])
   // B64: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i64
-  // B64: call i32 (%opencl.queue_t{{.*}}*, i32,  %opencl.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %opencl.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i64 [[SIZE]])
+  // B64: call i32 (%opencl.queue_t{{.*}}*, i32,  %struct.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]],  %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]], i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 [[SIZE]])
   enqueue_kernel(default_queue, flags, ndrange, 2, event_wait_list2, &clk_event,
                  ^(local void *p) {
                    return;
@@ -100,11 +98,10 @@
   long l;
   // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
   // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
-  // COMMON: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange
   // B32: [[SIZE:%[0-9]+]] = trunc i64 {{%[0-9]+}} to i32
-  // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 [[SIZE]])
+  // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 [[SIZE]])
   // B64: [[SIZE:%[0-9]+]] = load i64, i64* %l
-  // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i64 [[SIZE]])
+  // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 [[SIZE]])
   enqueue_kernel(default_queue, flags, ndrange,
                  ^(local void *p) {
                    return;
@@ -113,37 +110,32 @@
 
   // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t*, %opencl.queue_t** %default_queue
   // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
-  // COMMON: [[NDR:%[0-9]+]] = load %opencl.ndrange_t*, %opencl.ndrange_t** %ndrange
-  // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i32 0)
-  // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %opencl.ndrange_t*, i8*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %opencl.ndrange_t* [[NDR]], i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(3)* }* @__block_literal_global{{(.[0-9]+)?}} to i8*), i32 1, i64 4294967296)
+  // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 0)
+  // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 4294967296)
   enqueue_kernel(default_queue, flags, ndrange,
                  ^(local void *p) {
                    return;
                  },
                  4294967296L);
 
-
+  // The full type of these expressions are long (and repeated elsewhere), so we
+  // capture it as part of the regex for convenience and clarity.
+  // COMMON: store void () addrspace(4)* addrspacecast (void () addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_A:@__block_literal_global(\.[0-9]+)?]] to void () addrspace(1)*) to void () addrspace(4)*), void () addrspace(4)** %block_A
   void (^const block_A)(void) = ^{
     return;
   };
+
+  // COMMON: store void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_B:@__block_literal_global(\.[0-9]+)?]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*), void (i8 addrspace(3)*) addrspace(4)** %block_B
   void (^const block_B)(local void *) = ^(local void *a) {
     return;
   };
 
-  // COMMON: [[BL:%[0-9]+]] = load void ()*, void ()** %block_A
-  // COMMON: [[BL_I8:%[0-9]+]] = bitcast void ()* [[BL]] to i8*
-  // COMMON: call i32 @__get_kernel_work_group_size_impl(i8* [[BL_I8]])
+  // COMMON: call i32 @__get_kernel_work_group_size_impl(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_A]] to i8 addrspace(1)*) to i8 addrspace(4)*))
   unsigned size = get_kernel_work_group_size(block_A);
-  // COMMON: [[BL:%[0-9]+]] = load void (i8 addrspace(2)*)*, void (i8 addrspace(2)*)** %block_B
-  // COMMON: [[BL_I8:%[0-9]+]] = bitcast void (i8 addrspace(2)*)* [[BL]] to i8*
-  // COMMON: call i32 @__get_kernel_work_group_size_impl(i8* [[BL_I8]])
+  // COMMON: call i32 @__get_kernel_work_group_size_impl(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_B]] to i8 addrspace(1)*) to i8 addrspace(4)*))
   size = get_kernel_work_group_size(block_B);
-  // COMMON: [[BL:%[0-9]+]] = load void ()*, void ()** %block_A
-  // COMMON: [[BL_I8:%[0-9]+]] = bitcast void ()* [[BL]] to i8*
-  // COMMON: call i32 @__get_kernel_preferred_work_group_multiple_impl(i8* [[BL_I8]])
+  // COMMON: call i32 @__get_kernel_preferred_work_group_multiple_impl(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_A]] to i8 addrspace(1)*) to i8 addrspace(4)*))
   size = get_kernel_preferred_work_group_size_multiple(block_A);
-  // COMMON: [[BL:%[0-9]+]] = load void (i8 addrspace(2)*)*, void (i8 addrspace(2)*)* addrspace(1)* @block_G
-  // COMMON: [[BL_I8:%[0-9]+]] = bitcast void (i8 addrspace(2)*)* [[BL]] to i8*
-  // COMMON: call i32 @__get_kernel_preferred_work_group_multiple_impl(i8* [[BL_I8]])
+  // COMMON: call i32 @__get_kernel_preferred_work_group_multiple_impl(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_GLOBAL]] to i8 addrspace(1)*) to i8 addrspace(4)*))
   size = get_kernel_preferred_work_group_size_multiple(block_G);
 }
diff --git a/test/CodeGenOpenCL/const-str-array-decay.cl b/test/CodeGenOpenCL/const-str-array-decay.cl
index af8c355..353aa3a 100644
--- a/test/CodeGenOpenCL/const-str-array-decay.cl
+++ b/test/CodeGenOpenCL/const-str-array-decay.cl
@@ -6,6 +6,6 @@
   test_func("Test string literal");
 }
 
-// CHECK: i8 addrspace(3)* getelementptr inbounds ([20 x i8], [20 x i8] addrspace(3)*
+// CHECK: i8 addrspace(2)* getelementptr inbounds ([20 x i8], [20 x i8] addrspace(2)*
 // CHECK-NOT: addrspacecast
 
diff --git a/test/CodeGenOpenCL/constant-addr-space-globals.cl b/test/CodeGenOpenCL/constant-addr-space-globals.cl
index 4b88913..4f0d1ea 100644
--- a/test/CodeGenOpenCL/constant-addr-space-globals.cl
+++ b/test/CodeGenOpenCL/constant-addr-space-globals.cl
@@ -12,9 +12,9 @@
 // in the constant address space).
 
 void foo(constant const int *p1, const int *p2, const int *p3);
-// CHECK: @k.arr1 = internal addrspace(3) constant [3 x i32] [i32 1, i32 2, i32 3]
-// CHECK: @k.arr2 = private unnamed_addr addrspace(3) constant [3 x i32] [i32 4, i32 5, i32 6]
-// CHECK: @k.arr3 = private unnamed_addr addrspace(3) constant [3 x i32] [i32 7, i32 8, i32 9]
+// CHECK: @k.arr1 = internal addrspace(2) constant [3 x i32] [i32 1, i32 2, i32 3]
+// CHECK: @k.arr2 = private unnamed_addr addrspace(2) constant [3 x i32] [i32 4, i32 5, i32 6]
+// CHECK: @k.arr3 = private unnamed_addr addrspace(2) constant [3 x i32] [i32 7, i32 8, i32 9]
 kernel void k(void) {
   // CHECK-NOT: %arr1 = alloca [3 x i32]
   constant const int arr1[] = {1, 2, 3};
diff --git a/test/CodeGenOpenCL/denorms-are-zero.cl b/test/CodeGenOpenCL/denorms-are-zero.cl
index f398218..ca7969a 100644
--- a/test/CodeGenOpenCL/denorms-are-zero.cl
+++ b/test/CodeGenOpenCL/denorms-are-zero.cl
@@ -1,19 +1,19 @@
 // RUN: %clang_cc1 -S -cl-denorms-are-zero -o - %s 2>&1
 // RUN: %clang_cc1 -emit-llvm -cl-denorms-are-zero -o - -triple amdgcn--amdhsa -target-cpu fiji %s | FileCheck %s
 // RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn--amdhsa -target-cpu fiji %s | FileCheck %s --check-prefix=CHECK-DENORM
-// RUN: %clang_cc1 -emit-llvm -target-feature +fp32-denormals -target-feature -fp64-denormals -cl-denorms-are-zero -o - -triple amdgcn--amdhsa -target-cpu fiji %s | FileCheck --check-prefix=CHECK-FEATURE %s
+// RUN: %clang_cc1 -emit-llvm -target-feature +fp32-denormals -target-feature -fp64-fp16-denormals -cl-denorms-are-zero -o - -triple amdgcn--amdhsa -target-cpu fiji %s | FileCheck --check-prefix=CHECK-FEATURE %s
 
 // For non-amdgcn targets, this test just checks that the -cl-denorms-are-zero argument is accepted
 // by clang.  This option is currently a no-op, which is allowed by the
 // OpenCL specification.
 
 // For amdgcn target cpu fiji, fp32 should be flushed since fiji does not support fp32 denormals, unless +fp32-denormals is
-// explicitly set. amdgcn target always do not flush fp64 denormals.
+// explicitly set. amdgcn target always do not flush fp64 denormals. The control for fp64 and fp16 denormals is the same.
 
 // CHECK-DENORM-LABEL: define void @f()
-// CHECK-DENORM: attributes #{{[0-9]*}} = {{{[^}]*}} "target-features"="{{[^"]*}}+fp64-denormals,{{[^"]*}}-fp32-denormals{{[^"]*}}"
+// CHECK-DENORM: attributes #{{[0-9]*}} = {{{[^}]*}} "target-features"="{{[^"]*}}+fp64-fp16-denormals,{{[^"]*}}-fp32-denormals{{[^"]*}}"
 // CHECK-LABEL: define void @f()
-// CHECK: attributes #{{[0-9]*}} = {{{[^}]*}} "target-features"="{{[^"]*}}+fp64-denormals,{{[^"]*}}-fp32-denormals{{[^"]*}}"
+// CHECK: attributes #{{[0-9]*}} = {{{[^}]*}} "target-features"="{{[^"]*}}+fp64-fp16-denormals,{{[^"]*}}-fp32-denormals{{[^"]*}}"
 // CHECK-FEATURE-LABEL: define void @f()
-// CHECK-FEATURE: attributes #{{[0-9]*}} = {{{[^}]*}} "target-features"="{{[^"]*}}+fp32-denormals,{{[^"]*}}-fp64-denormals{{[^"]*}}"
+// CHECK-FEATURE: attributes #{{[0-9]*}} = {{{[^}]*}} "target-features"="{{[^"]*}}+fp32-denormals,{{[^"]*}}-fp64-fp16-denormals{{[^"]*}}"
 void f() {}
diff --git a/test/CodeGenOpenCL/extension-begin.cl b/test/CodeGenOpenCL/extension-begin.cl
new file mode 100644
index 0000000..1d5f789
--- /dev/null
+++ b/test/CodeGenOpenCL/extension-begin.cl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -o - | FileCheck %s
+
+__attribute__((overloadable)) void f(int x);
+
+#pragma OPENCL EXTENSION my_ext : begin
+
+__attribute__((overloadable)) void f(long x);
+
+#pragma OPENCL EXTENSION my_ext : end
+
+#pragma OPENCL EXTENSION my_ext : enable
+
+//CHECK: define spir_func void @test_f1(i64 %x)
+//CHECK: call spir_func void @_Z1fl(i64 %{{.*}})
+void test_f1(long x) {
+  f(x);
+}
+
+#pragma OPENCL EXTENSION my_ext : disable
+
+//CHECK: define spir_func void @test_f2(i64 %x)
+//CHECK: call spir_func void @_Z1fi(i32 %{{.*}})
+void test_f2(long x) {
+  f(x);
+}
diff --git a/test/CodeGenOpenCL/fpmath.cl b/test/CodeGenOpenCL/fpmath.cl
index 780c95f..8908861 100644
--- a/test/CodeGenOpenCL/fpmath.cl
+++ b/test/CodeGenOpenCL/fpmath.cl
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - -triple spir-unknown-unknown | FileCheck --check-prefix=CHECK --check-prefix=NODIVOPT %s
 // RUN: %clang_cc1 %s -emit-llvm -o - -triple spir-unknown-unknown -cl-fp32-correctly-rounded-divide-sqrt | FileCheck --check-prefix=CHECK --check-prefix=DIVOPT %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -DNOFP64 -cl-std=CL1.2 -triple r600-unknown-unknown -target-cpu r600 -pedantic | FileCheck --check-prefix=CHECK-FLT %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -DFP64 -cl-std=CL1.2 -triple spir-unknown-unknown -pedantic | FileCheck --check-prefix=CHECK-DBL %s
 
 typedef __attribute__(( ext_vector_type(4) )) float float4;
 
@@ -21,14 +23,26 @@
   return a / b;
 }
 
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+#if __OPENCL_C_VERSION__ >=120
+void printf(constant char* fmt, ...);
 
+void testdbllit(long *val) {
+  // CHECK-FLT: float 2.000000e+01
+  // CHECK-DBL: double 2.000000e+01
+  printf("%f", 20.0);
+}
+
+#endif
+
+#ifndef NOFP64
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
 double dpscalardiv(double a, double b) {
   // CHECK: @dpscalardiv
   // CHECK: #[[ATTR]]
   // CHECK-NOT: !fpmath
   return a / b;
 }
+#endif
 
 // CHECK: attributes #[[ATTR]] = {
 // NODIVOPT: "correctly-rounded-divide-sqrt-fp-math"="false"
diff --git a/test/CodeGenOpenCL/local-initializer-undef.cl b/test/CodeGenOpenCL/local-initializer-undef.cl
index 5d34f56..f209b1f 100644
--- a/test/CodeGenOpenCL/local-initializer-undef.cl
+++ b/test/CodeGenOpenCL/local-initializer-undef.cl
@@ -6,10 +6,10 @@
     float z;
 } Foo;
 
-// CHECK-DAG: @test.lds_int = internal addrspace(2) global i32 undef
-// CHECK-DAG: @test.lds_int_arr = internal addrspace(2) global [128 x i32] undef
-// CHECK-DAG: @test.lds_struct = internal addrspace(2) global %struct.Foo undef
-// CHECK-DAG: @test.lds_struct_arr = internal addrspace(2) global [64 x %struct.Foo] undef
+// CHECK-DAG: @test.lds_int = internal addrspace(3) global i32 undef
+// CHECK-DAG: @test.lds_int_arr = internal addrspace(3) global [128 x i32] undef
+// CHECK-DAG: @test.lds_struct = internal addrspace(3) global %struct.Foo undef
+// CHECK-DAG: @test.lds_struct_arr = internal addrspace(3) global [64 x %struct.Foo] undef
 __kernel void test()
 {
     __local int lds_int;
diff --git a/test/CodeGenOpenCL/local.cl b/test/CodeGenOpenCL/local.cl
index da371f8..6f44b68 100644
--- a/test/CodeGenOpenCL/local.cl
+++ b/test/CodeGenOpenCL/local.cl
@@ -3,7 +3,7 @@
 void func(local int*);
 
 __kernel void foo(void) {
-  // CHECK: @foo.i = internal addrspace(2) global i32 undef
+  // CHECK: @foo.i = internal addrspace(3) global i32 undef
   __local int i;
   func(&i);
 }
diff --git a/test/CodeGenOpenCL/memcpy.cl b/test/CodeGenOpenCL/memcpy.cl
index cb27803..5911b5c 100644
--- a/test/CodeGenOpenCL/memcpy.cl
+++ b/test/CodeGenOpenCL/memcpy.cl
@@ -2,7 +2,7 @@
 
 // CHECK-LABEL: @test
 // CHECK-NOT: addrspacecast
-// CHECK: call void @llvm.memcpy.p1i8.p3i8
+// CHECK: call void @llvm.memcpy.p1i8.p2i8
 kernel void test(global float *g, constant float *c) {
   __builtin_memcpy(g, c, 32);
 }
diff --git a/test/CodeGenOpenCL/null_queue.cl b/test/CodeGenOpenCL/null_queue.cl
new file mode 100644
index 0000000..cdcd7ee
--- /dev/null
+++ b/test/CodeGenOpenCL/null_queue.cl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -O0 -cl-std=CL2.0  -emit-llvm %s -o - | FileCheck %s
+extern queue_t get_default_queue();
+
+bool compare() {
+  return 0 == get_default_queue() &&
+         get_default_queue() == 0;
+  // CHECK: icmp eq %opencl.queue_t* null, %{{.*}}
+  // CHECK: icmp eq %opencl.queue_t* %{{.*}}, null
+}
+
+void func(queue_t q);
+
+void init() {
+  queue_t q = 0;
+  func(0);
+  // CHECK: store %opencl.queue_t* null, %opencl.queue_t** %q
+  // CHECK: call void @func(%opencl.queue_t* null)
+}
diff --git a/test/CodeGenOpenCL/str_literals.cl b/test/CodeGenOpenCL/str_literals.cl
index 1c0acd1..8fe5cef 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: unnamed_addr addrspace(3) constant
-// CHECK-NOT: addrspace(3) unnamed_addr constant
-// CHECK: @x = addrspace(3) constant i8 addrspace(3)*
-// CHECK: @y = addrspace(3) constant i8 addrspace(3)*
+// CHECK: unnamed_addr addrspace(2) constant
+// CHECK-NOT: addrspace(2) unnamed_addr constant
+// CHECK: @x = addrspace(2) constant i8 addrspace(2)*
+// CHECK: @y = addrspace(2) constant i8 addrspace(2)*
diff --git a/test/CodeGenOpenCL/unroll-hint.cl b/test/CodeGenOpenCL/unroll-hint.cl
index a86762e..6a9ba87 100644
--- a/test/CodeGenOpenCL/unroll-hint.cl
+++ b/test/CodeGenOpenCL/unroll-hint.cl
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL1.2 -o - %s | FileCheck %s
 
 /*** for ***/
 void for_count()
diff --git a/test/Coverage/ast-printing.cpp b/test/Coverage/ast-printing.cpp
index 5cff09d..e03c517 100644
--- a/test/Coverage/ast-printing.cpp
+++ b/test/Coverage/ast-printing.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -fsyntax-only %s
-// RUN: %clang_cc1 -ast-print %s -o %t.1.cpp
-// RUN: %clang_cc1 -ast-print %t.1.cpp -o %t.2.cpp
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only %s
+// RUN: %clang_cc1 -std=c++14 -ast-print %s -o %t.1.cpp
+// RUN: %clang_cc1 -std=c++14 -ast-print %t.1.cpp -o %t.2.cpp
 // RUN: diff %t.1.cpp %t.2.cpp
-// RUN: %clang_cc1 -ast-dump %s
-// RUN: %clang_cc1 -print-decl-contexts %s
-// RUN: %clang_cc1 -fdump-record-layouts %s
+// RUN: %clang_cc1 -std=c++14 -ast-dump %s
+// RUN: %clang_cc1 -std=c++14 -print-decl-contexts %s
+// RUN: %clang_cc1 -std=c++14 -fdump-record-layouts %s
 
 #include "cxx-language-features.inc"
diff --git a/test/Coverage/cxx-language-features.inc b/test/Coverage/cxx-language-features.inc
index 31b50be..1e3b074 100644
--- a/test/Coverage/cxx-language-features.inc
+++ b/test/Coverage/cxx-language-features.inc
@@ -25,3 +25,43 @@
 template <E1 v> class C1 {};
 template <E1 v> C1<v> f1() { return C1<v>(); }
 void f2() { f1<EC1>(); }
+
+// Friend declarations
+struct FriendlyStruct {
+  friend bool operator==(FriendlyStruct, FriendlyStruct) { return true; }
+  friend struct FriendedStruct;
+};
+
+struct FriendedStruct { };
+
+// Using declaration
+namespace provider {
+  void foo();
+}
+namespace user {
+  using provider::foo;
+}
+
+// Empty declaration
+;
+
+// Template specialization declarations
+template<typename T> class ClassTemplateSpecialization;
+
+template<>
+class ClassTemplateSpecialization<bool> { };
+
+template<typename T, bool> struct ClassTemplatePartialSpecialization;
+
+template<typename T>
+struct ClassTemplatePartialSpecialization<T, true> { };
+
+// Access specifier
+struct AccessSpec {
+private:
+};
+
+// Variable template
+template <typename T> T varTemplate = 0;
+
+static_assert(true, "");
diff --git a/test/CoverageMapping/implicit-def-in-macro.m b/test/CoverageMapping/implicit-def-in-macro.m
index 902fc8b..71184fc 100644
--- a/test/CoverageMapping/implicit-def-in-macro.m
+++ b/test/CoverageMapping/implicit-def-in-macro.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -triple x86_64-apple-darwin -fobjc-runtime=macosx-10.10.0 -fblocks -fobjc-arc %s | FileCheck %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -triple x86_64-apple-darwin -fobjc-runtime=macosx-10.10.0 -fblocks -fobjc-arc -w %s | FileCheck %s
 
 @interface Foo
 @end
diff --git a/test/CoverageMapping/macro-expressions.cpp b/test/CoverageMapping/macro-expressions.cpp
index 3852fc6..3eba869 100644
--- a/test/CoverageMapping/macro-expressions.cpp
+++ b/test/CoverageMapping/macro-expressions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name macro-expressions.cpp %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name macro-expressions.cpp -w %s | FileCheck %s
 
 #define EXPR(x) (x)
 #define NEXPR(x) (!x)
diff --git a/test/CoverageMapping/objc.m b/test/CoverageMapping/objc.m
index 89da5da..55c7545 100644
--- a/test/CoverageMapping/objc.m
+++ b/test/CoverageMapping/objc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name objc.m -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name objc.m -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -w %s | FileCheck %s
 
 @interface A
 - (void)bork:(int)msg;
diff --git a/test/CoverageMapping/unused_names.c b/test/CoverageMapping/unused_names.c
index a03d18b..49fa119 100644
--- a/test/CoverageMapping/unused_names.c
+++ b/test/CoverageMapping/unused_names.c
@@ -2,14 +2,15 @@
 // RUN: FileCheck -input-file %t %s
 // RUN: FileCheck -check-prefix=SYSHEADER -input-file %t %s
 
-// Since foo is never emitted, there should not be a profile name for it.
-
-// CHECK-DAG: @__profn_bar = {{.*}} [3 x i8] c"bar"
-// CHECK-DAG: @__profn_baz = {{.*}} [3 x i8] c"baz"
-// CHECK-DAG: @__profn_unused_names.c_qux = {{.*}} [18 x i8] c"unused_names.c:qux"
+// CHECK-DAG: @__profc_bar
 // CHECK-DAG: @__llvm_prf_nm = private constant {{.*}}, section "{{.*}}__llvm_prf_names"
 
-// SYSHEADER-NOT: @__profn_foo =
+// These are never instantiated, so we shouldn't get counters for them.
+//
+// CHECK-NOT: @__profc_baz
+// CHECK-NOT: @__profc_unused_names.c_qux
+
+// SYSHEADER-NOT: @__profc_foo =
 
 
 #ifdef IS_SYSHEADER
diff --git a/test/Driver/B-opt.c b/test/Driver/B-opt.c
index 3180094..51273fd 100644
--- a/test/Driver/B-opt.c
+++ b/test/Driver/B-opt.c
@@ -1,22 +1,22 @@
 // Check -B driver option.
 //
 // RUN: %clang %s -### -o %t.o -target i386-unknown-linux \
-// RUN:     -B %S/Inputs/B_opt_tree/dir1 2>&1 \
+// RUN:     -B %S/Inputs/B_opt_tree/dir1 -fuse-ld=ld 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-B-OPT-TRIPLE %s
 // CHECK-B-OPT-TRIPLE: "{{.*}}/Inputs/B_opt_tree/dir1{{/|\\\\}}i386-unknown-linux-ld"
 //
 // RUN: %clang %s -### -o %t.o -target i386-unknown-linux \
-// RUN:     -B %S/Inputs/B_opt_tree/dir2 2>&1 \
+// RUN:     -B %S/Inputs/B_opt_tree/dir2 -fuse-ld=ld 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-B-OPT-DIR %s
 // CHECK-B-OPT-DIR: "{{.*}}/Inputs/B_opt_tree/dir2{{/|\\\\}}ld"
 //
 // RUN: %clang %s -### -o %t.o -target i386-unknown-linux \
-// RUN:     -B %S/Inputs/B_opt_tree/dir3/prefix- 2>&1 \
+// RUN:     -B %S/Inputs/B_opt_tree/dir3/prefix- -fuse-ld=ld 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-B-OPT-PREFIX %s
 // CHECK-B-OPT-PREFIX: "{{.*}}/Inputs/B_opt_tree/dir3{{/|\\\\}}prefix-ld"
 //
 // RUN: %clang %s -### -o %t.o -target i386-unknown-linux \
 // RUN:     -B %S/Inputs/B_opt_tree/dir3/prefix- \
-// RUN:     -B %S/Inputs/B_opt_tree/dir2 2>&1 \
+// RUN:     -B %S/Inputs/B_opt_tree/dir2 2>&1 -fuse-ld=ld \
 // RUN:   | FileCheck --check-prefix=CHECK-B-OPT-MULT %s
 // CHECK-B-OPT-MULT: "{{.*}}/Inputs/B_opt_tree/dir3{{/|\\\\}}prefix-ld"
diff --git a/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/bin/.keep b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/bin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/bin/.keep
diff --git a/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/include/.keep b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/include/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/include/.keep
diff --git a/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/.keep b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/.keep
diff --git a/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/nvvm/libdevice/libdevice.compute_30.10.bc b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/nvvm/libdevice/libdevice.compute_30.10.bc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/nvvm/libdevice/libdevice.compute_30.10.bc
diff --git a/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/nvvm/libdevice/libdevice.compute_35.10.bc b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/nvvm/libdevice/libdevice.compute_35.10.bc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/nvvm/libdevice/libdevice.compute_35.10.bc
diff --git a/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/32/crtbegin.o b/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/32/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/32/crtbegin.o
diff --git a/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/x32/crtbegin.o b/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/x32/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/x32/crtbegin.o
diff --git a/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/32/crtbegin.o b/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/32/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/32/crtbegin.o
diff --git a/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/x32/crtbegin.o b/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/x32/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/gentoo_linux_gcc_multi_version_tree/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/x32/crtbegin.o
diff --git a/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/crt1.o b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/crt1.o
diff --git a/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/crti.o b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/crti.o
diff --git a/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/crtn.o b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/crtn.o
diff --git a/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/crtbegin.o b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/crtbegin.o
diff --git a/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/crtend.o b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/opensuse_42.2_aarch64_tree/usr/lib64/gcc/aarch64-suse-linux/4.8/crtend.o
diff --git a/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/aarch64/.keep b/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/aarch64/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/aarch64/.keep
diff --git a/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/arm/.keep b/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/arm/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/arm/.keep
diff --git a/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/i386/.keep b/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/i386/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/i386/.keep
diff --git a/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/x86_64/.keep b/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/x86_64/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/x86_64/.keep
diff --git a/test/Driver/XRay/xray-instrument-cpu.c b/test/Driver/XRay/xray-instrument-cpu.c
index 6133420..ee0e098 100644
--- a/test/Driver/XRay/xray-instrument-cpu.c
+++ b/test/Driver/XRay/xray-instrument-cpu.c
@@ -1,4 +1,4 @@
 // RUN: not %clang -o /dev/null -v -fxray-instrument -c %s
-// XFAIL: amd64-, x86_64-, x86_64h-, arm, aarch64, arm64
+// XFAIL: amd64-, x86_64-, x86_64h-, arm, aarch64, arm64, powerpc64le-, mips, mipsel, mips64, mips64el
 // REQUIRES: linux
 typedef int a;
diff --git a/test/Driver/aarch64-cpus.c b/test/Driver/aarch64-cpus.c
index e0539af..554c59d 100644
--- a/test/Driver/aarch64-cpus.c
+++ b/test/Driver/aarch64-cpus.c
@@ -104,6 +104,14 @@
 // RUN: %clang -target aarch64_be -mlittle-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2 %s
 // M2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "exynos-m2"
 
+// RUN: %clang -target aarch64_be -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
+// RUN: %clang -target aarch64 -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
+// RUN: %clang -target aarch64_be -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
+// RUN: %clang -target aarch64_be -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
+// M3: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m3"
+
 // RUN: %clang -target arm64 -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s
 // RUN: %clang -target arm64 -mlittle-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s
 // RUN: %clang -target arm64 -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s
@@ -116,6 +124,12 @@
 // RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M2 %s
 // ARM64-M2: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "exynos-m2"
 
+// RUN: %clang -target arm64 -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3 %s
+// RUN: %clang -target arm64 -mlittle-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3 %s
+// RUN: %clang -target arm64 -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3 %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3 %s
+// ARM64-M3: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "exynos-m3"
+
 // RUN: %clang -target aarch64 -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s
 // RUN: %clang -target aarch64 -mlittle-endian -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s
 // RUN: %clang -target aarch64 -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s
@@ -140,19 +154,23 @@
 // RUN: %clang -target arm64 -mlittle-endian -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-KRYO %s
 // ARM64-KRYO: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "kryo"
 
-// RUN: %clang -target aarch64 -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN %s
-// RUN: %clang -target aarch64 -mlittle-endian -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN %s
-// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN %s
-// RUN: %clang -target aarch64 -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN %s
-// RUN: %clang -target aarch64 -mlittle-endian -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN %s
-// RUN: %clang -target aarch64_be -mlittle-endian -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN %s
-// VULCAN: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "vulcan"
+// RUN: %clang -target aarch64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99 %s
+// RUN: %clang -target aarch64 -mlittle-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99 %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99 %s
+// RUN: %clang -target aarch64 -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-TUNE %s
+// THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "thunderx2t99" "-target-feature" "+v8.1a"
+// THUNDERX2T99-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "thunderx2t99"
+// THUNDERX2T99-TUNE-NOT: +v8.1a
 
-// RUN: %clang -target arm64 -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-VULCAN %s
-// RUN: %clang -target arm64 -mlittle-endian -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-VULCAN %s
-// RUN: %clang -target arm64 -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-VULCAN %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-VULCAN %s
-// ARM64-VULCAN: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "vulcan"
+// RUN: %clang -target arm64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99 %s
+// RUN: %clang -target arm64 -mlittle-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99 %s
+// RUN: %clang -target arm64 -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99-TUNE %s
+// ARM64-THUNDERX2T99: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "thunderx2t99" "-target-feature" "+v8.1a"
+// ARM64-THUNDERX2T99-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "thunderx2t99"
+// ARM64-THUNDERX2T99-TUNE-NOT: +v8.1a
 
 // RUN: %clang -target aarch64_be -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC-BE %s
 // RUN: %clang -target aarch64 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC-BE %s
@@ -215,21 +233,29 @@
 // RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE %s
 // M2-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m2"
 
-// RUN: %clang -target aarch64_be -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-BE %s
-// RUN: %clang -target aarch64_be -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-BE %s
-// VULCAN-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "vulcan"
+// RUN: %clang -target aarch64_be -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
+// RUN: %clang -target aarch64_be -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
+// M3-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m3"
+
+// RUN: %clang -target aarch64_be -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
+// RUN: %clang -target aarch64_be -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
+// THUNDERX2T99-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "thunderx2t99"
 
 // RUN: %clang -target aarch64 -mcpu=cortex-a57 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
 // RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a57  -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
 // RUN: %clang -target aarch64 -mcpu=cortex-a72 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
 // RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a72  -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
 // RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a73     -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mcpu=vulcan -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=vulcan  -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
+// RUN: %clang -target aarch64 -mcpu=thunderx2t99 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
+// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=thunderx2t99  -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
 // MCPU-MTUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a53"
 
 // RUN: %clang -target aarch64 -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
diff --git a/test/Driver/analyzer-target-enabled-checkers.cpp b/test/Driver/analyzer-target-enabled-checkers.cpp
new file mode 100644
index 0000000..e1706f6
--- /dev/null
+++ b/test/Driver/analyzer-target-enabled-checkers.cpp
@@ -0,0 +1,60 @@
+// Tests for static analyzer checkers that the driver enables by default based
+// on the target triple.
+
+// RUN: %clang -### -target x86_64-apple-darwin10 --analyze %s 2>&1 | FileCheck --check-prefix=CHECK-DARWIN %s
+
+// CHECK-DARWIN: "-analyzer-checker=core"
+// CHECK-DARWIN-SAME: "-analyzer-checker=apiModeling"
+// CHECK-DARWIN-SAME: "-analyzer-checker=unix"
+// CHECK-DARWIN-SAME: "-analyzer-checker=osx"
+// CHECK-DARWIN-SAME: "-analyzer-checker=deadcode"
+// CHECK-DARWIN-SAME: "-analyzer-checker=cplusplus"
+// CHECK-DARWIN-SAME: "-analyzer-checker=security.insecureAPI.UncheckedReturn"
+// CHECK-DARWIN-SAME: "-analyzer-checker=security.insecureAPI.getpw"
+// CHECK-DARWIN-SAME: "-analyzer-checker=security.insecureAPI.gets"
+// CHECK-DARWIN-SAME: "-analyzer-checker=security.insecureAPI.mktemp"
+// CHECK-DARWIN-SAME: "-analyzer-checker=security.insecureAPI.mkstemp"
+// CHECK-DARWIN-SAME: "-analyzer-checker=security.insecureAPI.vfork"
+// CHECK-DARWIN-SAME: "-analyzer-checker=nullability.NullPassedToNonnull"
+// CHECK-DARWIN-SAME: "-analyzer-checker=nullability.NullReturnedFromNonnull"
+
+
+// RUN: %clang -### -target x86_64-unknown-linux --analyze %s 2>&1 | FileCheck --check-prefix=CHECK-LINUX %s
+
+// CHECK-LINUX: "-analyzer-checker=core"
+// CHECK-LINUX-SAME: "-analyzer-checker=apiModeling"
+// CHECK-LINUX-SAME: "-analyzer-checker=unix"
+// CHECK-LINUX-NOT:  "-analyzer-checker=osx"
+// CHECK-LINUX-SAME: "-analyzer-checker=deadcode"
+// CHECK-LINUX-SAME: "-analyzer-checker=cplusplus"
+// CHECK-LINUX-SAME: "-analyzer-checker=security.insecureAPI.UncheckedReturn"
+// CHECK-LINUX-SAME: "-analyzer-checker=security.insecureAPI.getpw"
+// CHECK-LINUX-SAME: "-analyzer-checker=security.insecureAPI.gets"
+// CHECK-LINUX-SAME: "-analyzer-checker=security.insecureAPI.mktemp"
+// CHECK-LINUX-SAME: "-analyzer-checker=security.insecureAPI.mkstemp"
+// CHECK-LINUX-SAME: "-analyzer-checker=security.insecureAPI.vfork"
+// CHECK-LINUX-SAME: "-analyzer-checker=nullability.NullPassedToNonnull"
+// CHECK-LINUX-SAME: "-analyzer-checker=nullability.NullReturnedFromNonnull"
+
+
+// RUN: %clang -### -target x86_64-windows --analyze %s 2>&1 | FileCheck --check-prefix=CHECK-WINDOWS %s
+
+// CHECK-WINDOWS: "-analyzer-checker=core"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=apiModeling"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=unix.API"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=unix.Malloc"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=unix.MallocSizeof"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=unix.MismatchedDeallocator"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=unix.cstring.BadSizeArg"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=unix.cstring.NullArg"
+// CHECK-WINDOWS-NOT:  "-analyzer-checker=osx"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=deadcode"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=cplusplus"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=security.insecureAPI.UncheckedReturn"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=security.insecureAPI.getpw"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=security.insecureAPI.gets"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=security.insecureAPI.mktemp"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=security.insecureAPI.mkstemp"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=security.insecureAPI.vfork"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=nullability.NullPassedToNonnull"
+// CHECK-WINDOWS-SAME: "-analyzer-checker=nullability.NullReturnedFromNonnull"
diff --git a/test/Driver/arch-specific-libdir-rpath.c b/test/Driver/arch-specific-libdir-rpath.c
new file mode 100644
index 0000000..e6a5da8
--- /dev/null
+++ b/test/Driver/arch-specific-libdir-rpath.c
@@ -0,0 +1,50 @@
+// Test that the driver adds an arch-specific subdirectory in
+// {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath' for native
+// compilations.
+//
+// -rpath only gets added during native compilation.  To keep the test simple,
+// just test for x86_64-linux native compilation.
+// REQUIRES: x86_64-linux
+//
+// Add LIBPATH but no RPATH for -fsanitizer=address w/o -shared-libasan
+// RUN: %clang %s -### 2>&1 -fsanitize=undefined \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,LIBPATH,NO-RPATH %s
+//
+// Add LIBPATH, RPATH for -fsanitize=address -shared-libasan
+// RUN: %clang %s -### 2>&1 -target x86_64-linux \
+// RUN:     -fsanitize=address -shared-libasan \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,LIBPATH,RPATH %s
+//
+// Add LIBPATH, RPATH with -fsanitize=address for Android
+// RUN: %clang %s -### 2>&1 -target x86_64-linux-android -fsanitize=address \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,LIBPATH,RPATH %s
+//
+// Add LIBPATH, RPATH for OpenMP
+// RUN: %clang %s -### 2>&1 -fopenmp \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,LIBPATH,RPATH %s
+//
+// Add LIBPATH but no RPATH for ubsan (or any other sanitizer)
+// RUN: %clang %s -### 2>&1 -fsanitize=undefined \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,LIBPATH,NO-RPATH %s
+//
+// Add LIBPATH but no RPATH if no sanitizer or runtime is specified
+// RUN: %clang %s -### 2>&1 \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,LIBPATH,NO-RPATH %s
+//
+// Do not add LIBPATH or RPATH if arch-specific subdir doesn't exist
+// RUN: %clang %s -### 2>&1 \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,NO-LIBPATH,NO-RPATH %s
+//
+//
+// FILEPATH: "-x" "c" "[[FILE_PATH:.*]]/{{.*}}.c"
+// LIBPATH: -L[[FILE_PATH]]/Inputs/resource_dir_with_arch_subdir/lib/linux/x86_64
+// RPATH: "-rpath" "[[FILE_PATH]]/Inputs/resource_dir_with_arch_subdir/lib/linux/x86_64"
+// NO-LIBPATH-NOT: -L{{.*}}Inputs/resource_dir
+// NO-RPATH-NOT: "-rpath" {{.*}}/Inputs/resource_dir
diff --git a/test/Driver/arch-specific-libdir.c b/test/Driver/arch-specific-libdir.c
new file mode 100644
index 0000000..3889b37
--- /dev/null
+++ b/test/Driver/arch-specific-libdir.c
@@ -0,0 +1,55 @@
+// Test that the driver adds an arch-specific subdirectory in
+// {RESOURCE_DIR}/lib/linux to the search path.
+//
+// REQUIRES: linux
+//
+// RUN: %clang %s -### 2>&1 -target i386-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,ARCHDIR-i386 %s
+//
+// RUN: %clang %s -### 2>&1 -target i386-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,NO-ARCHDIR %s
+//
+// RUN: %clang %s -### 2>&1 -target i686-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,ARCHDIR-i386 %s
+//
+// RUN: %clang %s -### 2>&1 -target i686-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,NO-ARCHDIR %s
+//
+// RUN: %clang %s -### 2>&1 -target x86_64-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,ARCHDIR-x86_64 %s
+//
+// RUN: %clang %s -### 2>&1 -target x86_64-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,NO-ARCHDIR %s
+//
+// RUN: %clang %s -### 2>&1 -target arm-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,ARCHDIR-arm %s
+//
+// RUN: %clang %s -### 2>&1 -target arm-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,NO-ARCHDIR %s
+//
+// RUN: %clang %s -### 2>&1 -target aarch64-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,ARCHDIR-aarch64 %s
+//
+// RUN: %clang %s -### 2>&1 -target aarch64-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:   | FileCheck --check-prefixes=FILEPATH,NO-ARCHDIR %s
+//
+//
+// FILEPATH: "-x" "c" "[[FILE_PATH:.*]]/{{.*}}.c"
+// ARCHDIR-i386:    -L[[FILE_PATH]]/Inputs/resource_dir_with_arch_subdir/lib/linux/i386
+// ARCHDIR-x86_64:  -L[[FILE_PATH]]/Inputs/resource_dir_with_arch_subdir/lib/linux/x86_64
+// ARCHDIR-arm:     -L[[FILE_PATH]]/Inputs/resource_dir_with_arch_subdir/lib/linux/arm
+// ARCHDIR-aarch64: -L[[FILE_PATH]]/Inputs/resource_dir_with_arch_subdir/lib/linux/aarch64
+//
+// Have a stricter check for no-archdir - that the driver doesn't add any
+// subdirectory from the provided resource directory.
+// NO-ARCHDIR-NOT: -L[[FILE_PATH]]/Inputs/resource_dir
diff --git a/test/Driver/arm-abi.c b/test/Driver/arm-abi.c
index 897c108..ba5c4ba 100644
--- a/test/Driver/arm-abi.c
+++ b/test/Driver/arm-abi.c
@@ -28,6 +28,10 @@
 // RUN: %clang -target arm--netbsd-eabihf %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-AAPCS %s
 
+// OpenBSD defaults to aapcs-linux
+// RUN: %clang -target arm--openbsd- %s -### -o %t.o 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-AAPCS-LINUX %s
+
 // Otherwise, ABI is selected based on environment
 // RUN: %clang -target arm---android %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-AAPCS-LINUX %s
diff --git a/test/Driver/arm-cortex-cpus.c b/test/Driver/arm-cortex-cpus.c
index e978c9f..c52e643 100644
--- a/test/Driver/arm-cortex-cpus.c
+++ b/test/Driver/arm-cortex-cpus.c
@@ -495,6 +495,7 @@
 // RUN: %clang -target arm -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // RUN: %clang -target arm -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // RUN: %clang -target arm -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
+// RUN: %clang -target arm -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // RUN: %clang -target arm -mcpu=cortex-a32 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // RUN: %clang -target arm -mcpu=cortex-a35 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // RUN: %clang -target arm -mcpu=cortex-a53 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
@@ -503,6 +504,7 @@
 // RUN: %clang -target arm -mcpu=cortex-a73 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // RUN: %clang -target arm -mcpu=exynos-m1 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // RUN: %clang -target arm -mcpu=exynos-m2 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
+// RUN: %clang -target arm -mcpu=exynos-m3 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // CHECK-CPUV8A: "-cc1"{{.*}} "-triple" "armv8-{{.*}}
 
 // RUN: %clang -target armeb -mcpu=cortex-a32 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
@@ -513,6 +515,7 @@
 // RUN: %clang -target armeb -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
 // RUN: %clang -target armeb -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
 // RUN: %clang -target armeb -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
+// RUN: %clang -target armeb -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
 // RUN: %clang -target arm -mcpu=cortex-a32 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
 // RUN: %clang -target arm -mcpu=cortex-a35 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
 // RUN: %clang -target arm -mcpu=cortex-a53 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
@@ -521,6 +524,7 @@
 // RUN: %clang -target arm -mcpu=cortex-a73 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
 // RUN: %clang -target arm -mcpu=exynos-m1 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
 // RUN: %clang -target arm -mcpu=exynos-m2 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
+// RUN: %clang -target arm -mcpu=exynos-m3 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
 // CHECK-BE-CPUV8A: "-cc1"{{.*}} "-triple" "armebv8-{{.*}}
 
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r52 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8R %s
@@ -534,6 +538,7 @@
 // RUN: %clang -target arm -mcpu=cortex-a73 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=exynos-m1 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=exynos-m2 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
+// RUN: %clang -target arm -mcpu=exynos-m3 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=cortex-a32 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=cortex-a35 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=cortex-a53 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
@@ -542,6 +547,7 @@
 // RUN: %clang -target arm -mcpu=cortex-a73 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=exynos-m1 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=exynos-m2 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
+// RUN: %clang -target arm -mcpu=exynos-m3 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
 // CHECK-CPUV8A-THUMB: "-cc1"{{.*}} "-triple" "thumbv8-{{.*}}
 
 // RUN: %clang -target armeb -mcpu=cortex-a32 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
@@ -552,6 +558,7 @@
 // RUN: %clang -target armeb -mcpu=cortex-a73 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
 // RUN: %clang -target armeb -mcpu=exynos-m1 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
 // RUN: %clang -target armeb -mcpu=exynos-m2 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
+// RUN: %clang -target armeb -mcpu=exynos-m3 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=cortex-a32 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=cortex-a35 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=cortex-a53 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
@@ -560,6 +567,7 @@
 // RUN: %clang -target arm -mcpu=cortex-a73 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=exynos-m1 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
 // RUN: %clang -target arm -mcpu=exynos-m2 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
+// RUN: %clang -target arm -mcpu=exynos-m3 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
 // CHECK-BE-CPUV8A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8-{{.*}}
 
 // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A73 %s
@@ -571,6 +579,12 @@
 // CHECK-CORTEX-A73-SOFT: "-target-feature" "+soft-float"
 // CHECK-CORTEX-A73-SOFT: "-target-feature" "+soft-float-abi"
 
+// RUN: %clang -target arm -mcpu=cortex-m23 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8MBASE %s
+// CHECK-CPUV8MBASE:  "-cc1"{{.*}} "-triple" "thumbv8m.base-
+
+// RUN: %clang -target arm -mcpu=cortex-m33 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8MMAIN %s
+// CHECK-CPUV8MMAIN:  "-cc1"{{.*}} "-triple" "thumbv8m.main-
+
 // ================== Check whether -mcpu accepts mixed-case values.
 // RUN: %clang -target arm-linux-gnueabi -mcpu=Cortex-a5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CASE-INSENSITIVE-CPUV7A %s
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-A7 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CASE-INSENSITIVE-CPUV7A %s
diff --git a/test/Driver/arm-execute-only.c b/test/Driver/arm-execute-only.c
new file mode 100644
index 0000000..a485448
--- /dev/null
+++ b/test/Driver/arm-execute-only.c
@@ -0,0 +1,103 @@
+// RUN: %clang -target armv6t2-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv6t2-eabi -### -mexecute-only %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY
+
+// RUN: %clang -target armv6t2-eabi -### -mexecute-only -mno-execute-only %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv7m-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv7m-eabi -### -mexecute-only %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY
+
+// RUN: %clang -target armv7m-eabi -### -mexecute-only -mno-execute-only %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.base-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.base-eabi -### -mexecute-only %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.base-eabi -### -mexecute-only -mno-execute-only %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.main-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.main-eabi -### -mexecute-only %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.main-eabi -### -mexecute-only -mno-execute-only %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: not %clang -c -target thumbv6m-eabi -mexecute-only %s 2>&1 | \
+// RUN:   FileCheck --check-prefix CHECK-EXECUTE-ONLY-NOT-SUPPORTED %s
+
+// RUN: not %clang -target armv8m.main-eabi -mexecute-only -mno-movt %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY-NO-MOVT
+
+// RUN: not %clang -target armv8m.main-eabi -mexecute-only -mlong-calls %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY-LONG-CALLS
+
+
+// -mpure-code flag for GCC compatibility
+// RUN: %clang -target armv6t2-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv6t2-eabi -### -mpure-code %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY
+
+// RUN: %clang -target armv6t2-eabi -### -mpure-code -mno-pure-code %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv7m-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv7m-eabi -### -mpure-code %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY
+
+// RUN: %clang -target armv7m-eabi -### -mpure-code -mno-pure-code %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.base-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.base-eabi -### -mpure-code %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.base-eabi -### -mpure-code -mno-pure-code %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.main-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.main-eabi -### -mpure-code %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY
+
+// RUN: %clang -target armv8m.main-eabi -### -mpure-code -mno-pure-code %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY
+
+// RUN: not %clang -c -target thumbv6m-eabi -mpure-code %s 2>&1 | \
+// RUN:   FileCheck --check-prefix CHECK-EXECUTE-ONLY-NOT-SUPPORTED %s
+
+// RUN: not %clang -target armv8m.main-eabi -mpure-code -mno-movt %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY-NO-MOVT
+
+// RUN: not %clang -target armv8m.main-eabi -mpure-code -mlong-calls %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY-LONG-CALLS
+
+// RUN: %clang -target armv7m-eabi -x assembler -mexecute-only %s -c -### 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY -check-prefix CHECK-NO-EXECUTE-ONLY-ASM
+
+//
+// CHECK-NO-EXECUTE-ONLY-NOT: "-backend-option" "-arm-execute-only"
+// CHECK-EXECUTE-ONLY: "-backend-option" "-arm-execute-only"
+
+// CHECK-EXECUTE-ONLY-NOT-SUPPORTED: error: execute only is not supported for the thumbv6m sub-architecture
+// CHECK-EXECUTE-ONLY-NO-MOVT: error: option '-mexecute-only' cannot be specified with '-mno-movt'
+// CHECK-EXECUTE-ONLY-LONG-CALLS: error: option '-mexecute-only' cannot be specified with '-mlong-calls'
+// CHECK-NO-EXECUTE-ONLY-ASM: warning: argument unused during compilation: '-mexecute-only'
diff --git a/test/Driver/avr-toolchain.c b/test/Driver/avr-toolchain.c
new file mode 100644
index 0000000..46a3c10
--- /dev/null
+++ b/test/Driver/avr-toolchain.c
@@ -0,0 +1,4 @@
+// A basic clang -cc1 command-line.
+
+// RUN: %clang %s -### -no-canonical-prefixes -target avr 2>&1 | FileCheck -check-prefix=CC1 %s
+// CC1: clang{{.*}} "-cc1" "-triple" "avr"
diff --git a/test/Driver/cc1-response-files.c b/test/Driver/cc1-response-files.c
index f47e644..fbeda06 100644
--- a/test/Driver/cc1-response-files.c
+++ b/test/Driver/cc1-response-files.c
@@ -1,2 +1,2 @@
-// RUN: %clang @%S/Inputs/cc1-response.txt -fsyntax-only -disable-llvm-optzns
+// RUN: %clang @%S/Inputs/cc1-response.txt -fsyntax-only -disable-llvm-passes
 int main() {}
diff --git a/test/Driver/cl-link.c b/test/Driver/cl-link.c
index b195676..4cc170c 100644
--- a/test/Driver/cl-link.c
+++ b/test/Driver/cl-link.c
@@ -13,8 +13,10 @@
 // ASAN: link.exe
 // ASAN: "-debug"
 // ASAN: "-incremental:no"
-// ASAN: "{{.*}}clang_rt.asan-i386.lib"
-// ASAN: "{{.*}}clang_rt.asan_cxx-i386.lib"
+// ASAN: "{{[^"]*}}clang_rt.asan-i386.lib"
+// ASAN: "-wholearchive:{{.*}}clang_rt.asan-i386.lib"
+// ASAN: "{{[^"]*}}clang_rt.asan_cxx-i386.lib"
+// ASAN: "-wholearchive:{{.*}}clang_rt.asan_cxx-i386.lib"
 // ASAN: "{{.*}}cl-link{{.*}}.obj"
 
 // RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /MD /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-MD %s
@@ -22,8 +24,9 @@
 // ASAN-MD: "-debug"
 // ASAN-MD: "-incremental:no"
 // ASAN-MD: "{{.*}}clang_rt.asan_dynamic-i386.lib"
-// ASAN-MD: "{{.*}}clang_rt.asan_dynamic_runtime_thunk-i386.lib"
+// ASAN-MD: "{{[^"]*}}clang_rt.asan_dynamic_runtime_thunk-i386.lib"
 // ASAN-MD: "-include:___asan_seh_interceptor"
+// ASAN-MD: "-wholearchive:{{.*}}clang_rt.asan_dynamic_runtime_thunk-i386.lib"
 // ASAN-MD: "{{.*}}cl-link{{.*}}.obj"
 
 // RUN: %clang_cl /LD -### /Tc%s 2>&1 | FileCheck --check-prefix=DLL %s
diff --git a/test/Driver/cl-options.c b/test/Driver/cl-options.c
index 5054d8a..c425e21 100644
--- a/test/Driver/cl-options.c
+++ b/test/Driver/cl-options.c
@@ -295,6 +295,14 @@
 // RUN: %clang_cl -c -fno-strict-aliasing -### -- %s 2>&1 | FileCheck -check-prefix=NOSTRICT %s
 // NOSTRICT: "-relaxed-aliasing"
 
+// We recognize -f[no-]delayed-template-parsing.
+// RUN: %clang_cl -c -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDDEFAULT %s
+// DELAYEDDEFAULT: "-fdelayed-template-parsing"
+// RUN: %clang_cl -c -fdelayed-template-parsing -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDON %s
+// DELAYEDON: "-fdelayed-template-parsing"
+// RUN: %clang_cl -c -fno-delayed-template-parsing -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDOFF %s
+// DELAYEDOFF-NOT: "-fdelayed-template-parsing"
+
 // For some warning ids, we can map from MSVC warning to Clang warning.
 // RUN: %clang_cl -wd4005 -wd4100 -wd4910 -wd4996 -### -- %s 2>&1 | FileCheck -check-prefix=Wno %s
 // Wno: "-cc1"
@@ -434,6 +442,12 @@
 // Xclang: "-cc1"
 // Xclang: "hellocc1"
 
+// Files under /Users are often confused with the /U flag. (This could happen
+// for other flags too, but this is the one people run into.)
+// RUN: %clang_cl /c /Users/me/myfile.c -### 2>&1 | FileCheck -check-prefix=SlashU %s
+// SlashU: warning: '/Users/me/myfile.c' treated as the '/U' option
+// SlashU: note: Use '--' to treat subsequent arguments as filenames
+
 // 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"
@@ -508,6 +522,15 @@
 
 // RUN: env CL="%s" _CL_="%s" not %clang --rsp-quoting=windows -c
 
+// RUN: %clang_cl -### /c -flto -- %s 2>&1 | FileCheck -check-prefix=LTO %s
+// LTO: -flto
+
+// RUN: %clang_cl -### /c -flto=thin -- %s 2>&1 | FileCheck -check-prefix=LTO-THIN %s
+// LTO-THIN: -flto=thin
+
+// RUN: %clang_cl -### -Fe%t.exe -entry:main -flto -- %s 2>&1 | FileCheck -check-prefix=LTO-WITHOUT-LLD %s
+// LTO-WITHOUT-LLD: LTO requires -fuse-ld=lld
+
 // Accept "core" clang options.
 // (/Zs is for syntax-only, -Werror makes it fail hard on unknown options)
 // RUN: %clang_cl \
@@ -527,7 +550,7 @@
 // RUN:     -fno-ms-compatibility \
 // RUN:     -fms-extensions \
 // RUN:     -fno-ms-extensions \
-// RUN:     -mllvm -disable-llvm-optzns \
+// RUN:     -Xclang -disable-llvm-passes \
 // RUN:     -resource-dir asdf \
 // RUN:     -resource-dir=asdf \
 // RUN:     -Wunused-variable \
diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c
index cc3cd1b..7c7b2f0 100644
--- a/test/Driver/clang-translation.c
+++ b/test/Driver/clang-translation.c
@@ -11,19 +11,36 @@
 // I386: "hidden"
 // I386: "-o"
 // I386: clang-translation
+
 // RUN: %clang -target i386-apple-darwin9 -### -S %s -o %t.s 2>&1 | \
 // RUN: FileCheck -check-prefix=YONAH %s
+// RUN: %clang -target i386-apple-macosx10.11 -### -S %s -o %t.s 2>&1 | \
+// RUN: FileCheck -check-prefix=YONAH %s
 // YONAH: "-target-cpu"
 // YONAH: "yonah"
+
 // RUN: %clang -target x86_64-apple-darwin9 -### -S %s -o %t.s 2>&1 | \
 // RUN: FileCheck -check-prefix=CORE2 %s
+// RUN: %clang -target x86_64-apple-macosx10.11 -### -S %s -o %t.s 2>&1 | \
+// RUN: FileCheck -check-prefix=CORE2 %s
 // CORE2: "-target-cpu"
 // CORE2: "core2"
+
 // RUN: %clang -target x86_64h-apple-darwin -### -S %s -o %t.s 2>&1 | \
 // RUN: FileCheck -check-prefix=AVX2 %s
+// RUN: %clang -target x86_64h-apple-macosx10.12 -### -S %s -o %t.s 2>&1 | \
+// RUN: FileCheck -check-prefix=AVX2 %s
 // AVX2: "-target-cpu"
 // AVX2: "core-avx2"
 
+// RUN: %clang -target i386-apple-macosx10.12 -### -S %s -o %t.s 2>&1 | \
+// RUN: FileCheck -check-prefix=PENRYN %s
+// RUN: %clang -target x86_64-apple-macosx10.12 -### -S %s -o %t.s 2>&1 | \
+// RUN: FileCheck -check-prefix=PENRYN %s
+// PENRYN: "-target-cpu"
+// PENRYN: "penryn"
+
+
 // RUN: %clang -target x86_64-apple-darwin10 -### -S %s -arch armv7 2>&1 | \
 // RUN: FileCheck -check-prefix=ARMV7_DEFAULT %s
 // ARMV7_DEFAULT: clang
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index 2952d0e..0261d93 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -469,3 +469,21 @@
 // CHECK-WCHAR2: -fshort-wchar
 // CHECK-WCHAR2-NOT: -fno-short-wchar
 // DELIMITERS: {{^ *"}}
+
+// RUN: %clang -### -fno-experimental-new-pass-manager -fexperimental-new-pass-manager %s 2>&1 | FileCheck --check-prefix=CHECK-PM --check-prefix=CHECK-NEW-PM %s
+// RUN: %clang -### -fexperimental-new-pass-manager -fno-experimental-new-pass-manager %s 2>&1 | FileCheck --check-prefix=CHECK-PM --check-prefix=CHECK-NO-NEW-PM %s
+// CHECK-PM-NOT: argument unused
+// CHECK-NEW-PM: -fexperimental-new-pass-manager
+// CHECK-NEW-PM-NOT: -fno-experimental-new-pass-manager
+// CHECK-NO-NEW-PM: -fno-experimental-new-pass-manager
+// CHECK-NO-NEW-PM-NOT: -fexperimental-new-pass-manager
+
+// RUN: %clang -### -S -fstrict-return %s 2>&1 | FileCheck -check-prefix=CHECK-STRICT-RETURN %s
+// RUN: %clang -### -S -fno-strict-return %s 2>&1 | FileCheck -check-prefix=CHECK-NO-STRICT-RETURN %s
+// CHECK-STRICT-RETURN-NOT: "-fno-strict-return"
+// CHECK-NO-STRICT-RETURN: "-fno-strict-return"
+
+// RUN: %clang -### -S -fno-debug-info-for-profiling -fdebug-info-for-profiling %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DEBUG %s
+// RUN: %clang -### -S -fdebug-info-for-profiling -fno-debug-info-for-profiling %s 2>&1 | FileCheck -check-prefix=CHECK-NO-PROFILE-DEBUG %s
+// CHECK-PROFILE-DEBUG: -fdebug-info-for-profiling
+// CHECK-NO-PROFILE-DEBUG-NOT: -fdebug-info-for-profiling
diff --git a/test/Driver/coverage-ld.c b/test/Driver/coverage-ld.c
index 1eda5f1..206d9ab 100644
--- a/test/Driver/coverage-ld.c
+++ b/test/Driver/coverage-ld.c
@@ -1,7 +1,7 @@
 // Test coverage ld flags.
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux --coverage \
+// RUN:     -target i386-unknown-linux --coverage -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LINUX-I386 %s
@@ -10,7 +10,7 @@
 // CHECK-LINUX-I386: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-i386.a" {{.*}} "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux --coverage \
+// RUN:     -target x86_64-unknown-linux --coverage -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LINUX-X86-64 %s
@@ -19,7 +19,7 @@
 // CHECK-LINUX-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-x86_64.a" {{.*}} "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-freebsd --coverage \
+// RUN:     -target x86_64-unknown-freebsd --coverage -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_freebsd64_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-FREEBSD-X86-64 %s
@@ -28,7 +28,7 @@
 // CHECK-FREEBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}freebsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target arm-linux-androideabi --coverage \
+// RUN:     -target arm-linux-androideabi --coverage -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-ARM %s
diff --git a/test/Driver/cross-linux.c b/test/Driver/cross-linux.c
index 3b13504..a5ea832 100644
--- a/test/Driver/cross-linux.c
+++ b/test/Driver/cross-linux.c
@@ -1,4 +1,4 @@
-// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \
 // RUN:   --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \
 // RUN:   --target=i386-unknown-linux-gnu \
 // RUN:   | FileCheck --check-prefix=CHECK-I386 %s
@@ -6,7 +6,7 @@
 // CHECK-I386: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/4.6.0/../../../../i386-unknown-linux-gnu/bin{{/|\\\\}}as" "--32"
 // CHECK-I386: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/4.6.0/../../../../i386-unknown-linux-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf_i386"
 //
-// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \
 // RUN:   --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \
 // RUN:   --target=x86_64-unknown-linux-gnu \
 // RUN:   | FileCheck --check-prefix=CHECK-X86-64 %s
@@ -14,7 +14,7 @@
 // CHECK-X86-64: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}as" "--64"
 // CHECK-X86-64: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf_x86_64"
 //
-// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \
 // RUN:   --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \
 // RUN:   --target=x86_64-unknown-linux-gnux32 \
 // RUN:   | FileCheck --check-prefix=CHECK-X32 %s
@@ -22,17 +22,17 @@
 // 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: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \
 // 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
 //
-// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \
 // RUN:   --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \
 // RUN:   --target=i386-unknown-linux-gnu -m64 \
 // RUN:   | FileCheck --check-prefix=CHECK-X86-64 %s
 //
-// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \
 // RUN:   --gcc-toolchain=%S/Inputs/multilib_32bit_linux_tree/usr \
 // RUN:   --target=i386-unknown-linux \
 // RUN:   --sysroot=%S/Inputs/basic_linux_tree \
@@ -49,7 +49,7 @@
 // CHECK-MULTI32-I386: "-L[[sysroot]]/lib"
 // CHECK-MULTI32-I386: "-L[[sysroot]]/usr/lib"
 //
-// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \
 // RUN:   --gcc-toolchain=%S/Inputs/multilib_32bit_linux_tree/usr \
 // RUN:   --target=x86_64-unknown-linux \
 // RUN:   --sysroot=%S/Inputs/basic_linux_tree \
@@ -67,7 +67,7 @@
 // CHECK-MULTI32-X86-64: "-L[[sysroot]]/lib"
 // CHECK-MULTI32-X86-64: "-L[[sysroot]]/usr/lib"
 //
-// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \
 // RUN:   --gcc-toolchain=%S/Inputs/multilib_64bit_linux_tree/usr \
 // RUN:   --target=i386-unknown-linux \
 // RUN:   --sysroot=%S/Inputs/basic_linux_tree \
@@ -85,7 +85,7 @@
 // CHECK-MULTI64-I386: "-L[[sysroot]]/lib"
 // CHECK-MULTI64-I386: "-L[[sysroot]]/usr/lib"
 //
-// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \
 // RUN:   --gcc-toolchain=%S/Inputs/multilib_64bit_linux_tree/usr \
 // RUN:   --target=x86_64-unknown-linux \
 // RUN:   --sysroot=%S/Inputs/basic_linux_tree \
diff --git a/test/Driver/cuda-no-stack-protector.cu b/test/Driver/cuda-no-stack-protector.cu
new file mode 100644
index 0000000..f94cc18
--- /dev/null
+++ b/test/Driver/cuda-no-stack-protector.cu
@@ -0,0 +1,23 @@
+// Check that -stack-protector doesn't get passed down to device-side
+// compilation.
+//
+// REQUIRES: clang-driver
+//
+// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 \
+// RUN:   -fstack-protector-all %s 2>&1 | \
+// RUN: FileCheck %s
+//
+// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 \
+// RUN:   -fstack-protector-strong %s 2>&1 | \
+// RUN: FileCheck %s
+//
+// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 \
+// RUN:   -fstack-protector %s 2>&1 | \
+// RUN: FileCheck %s
+//
+// CHECK-NOT: error: unsupported option '-fstack-protector
+// CHECK-DAG: "-fcuda-is-device"
+// CHECK-NOT: "-stack-protector"
+// CHECK-NOT: "-stack-protector-buffer-size"
+// CHECK-DAG: "-triple" "x86_64--linux-gnu"
+// CHECK: "-stack-protector"
diff --git a/test/Driver/cuda-options.cu b/test/Driver/cuda-options.cu
index 5d65076..c4bfda9 100644
--- a/test/Driver/cuda-options.cu
+++ b/test/Driver/cuda-options.cu
@@ -64,9 +64,9 @@
 
 // Verify that --cuda-gpu-arch option passes the correct GPU archtecture to
 // device compilation.
-// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_35 -c %s 2>&1 \
+// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_30 -c %s 2>&1 \
 // RUN: | FileCheck -check-prefix DEVICE -check-prefix DEVICE-NOSAVE \
-// RUN:    -check-prefix DEVICE-SM35 -check-prefix HOST \
+// RUN:    -check-prefix DEVICE-SM30 -check-prefix HOST \
 // RUN:    -check-prefix INCLUDES-DEVICE -check-prefix NOLINK %s
 
 // Verify that there is one device-side compilation per --cuda-gpu-arch args
@@ -74,8 +74,8 @@
 // RUN: %clang -### -target x86_64-linux-gnu \
 // RUN:   --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_30 -c %s 2>&1 \
 // RUN: | FileCheck -check-prefix DEVICE -check-prefix DEVICE-NOSAVE \
-// RUN:    -check-prefix DEVICE2 -check-prefix DEVICE-SM35 \
-// RUN:    -check-prefix DEVICE2-SM30 -check-prefix HOST \
+// RUN:    -check-prefix DEVICE2 -check-prefix DEVICE-SM30 \
+// RUN:    -check-prefix DEVICE2-SM35 -check-prefix HOST \
 // RUN:    -check-prefix HOST-NOSAVE -check-prefix INCLUDES-DEVICE \
 // RUN:    -check-prefix NOLINK %s
 
@@ -92,6 +92,65 @@
 // RUN:    -check-prefix HOST -check-prefix HOST-NOSAVE \
 // RUN:    -check-prefix HOST-AS -check-prefix NOLINK %s
 
+// Verify that --[no-]cuda-gpu-arch arguments are handled correctly.
+// a) --no-cuda-gpu-arch=X negates preceeding --cuda-gpu-arch=X
+// RUN: %clang -### -target x86_64-linux-gnu --cuda-device-only \
+// RUN:   --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_30 \
+// RUN:   --no-cuda-gpu-arch=sm_35 \
+// RUN:   -c %s 2>&1 \
+// RUN: | FileCheck -check-prefixes NOARCH-SM20,ARCH-SM30,NOARCH-SM35 %s
+
+// b) --no-cuda-gpu-arch=X negates more than one preceeding --cuda-gpu-arch=X
+// RUN: %clang -### -target x86_64-linux-gnu --cuda-device-only \
+// RUN:   --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_30 \
+// RUN:   --no-cuda-gpu-arch=sm_35 \
+// RUN:   -c %s 2>&1 \
+// RUN: | FileCheck -check-prefixes NOARCH-SM20,ARCH-SM30,NOARCH-SM35 %s
+
+// c) if --no-cuda-gpu-arch=X negates all preceeding --cuda-gpu-arch=X
+//    we default to sm_20 -- same as if no --cuda-gpu-arch were passed.
+// RUN: %clang -### -target x86_64-linux-gnu --cuda-device-only \
+// RUN:   --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_30 \
+// RUN:   --no-cuda-gpu-arch=sm_35 --no-cuda-gpu-arch=sm_30 \
+// RUN:   -c %s 2>&1 \
+// RUN: | FileCheck -check-prefixes ARCH-SM20,NOARCH-SM30,NOARCH-SM35 %s
+
+// d) --no-cuda-gpu-arch=X is a no-op if there's no preceding --cuda-gpu-arch=X
+// RUN: %clang -### -target x86_64-linux-gnu --cuda-device-only \
+// RUN:   --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_30\
+// RUN:   --no-cuda-gpu-arch=sm_50 \
+// RUN:   -c %s 2>&1 \
+// RUN: | FileCheck -check-prefixes NOARCH-SM20,ARCH-SM30,ARCH-SM35 %s
+
+// e) --no-cuda-gpu-arch=X does not affect following --cuda-gpu-arch=X
+// RUN: %clang -### -target x86_64-linux-gnu --cuda-device-only \
+// RUN:   --no-cuda-gpu-arch=sm_35 --no-cuda-gpu-arch=sm_30 \
+// RUN:   --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_30 \
+// RUN:   -c %s 2>&1 \
+// RUN: | FileCheck -check-prefixes NOARCH-SM20,ARCH-SM30,ARCH-SM35 %s
+
+// f) --no-cuda-gpu-arch=all negates all preceding --cuda-gpu-arch=X
+// RUN: %clang -### -target x86_64-linux-gnu --cuda-device-only \
+// RUN:   --cuda-gpu-arch=sm_20 --cuda-gpu-arch=sm_30 \
+// RUN:   --no-cuda-gpu-arch=all \
+// RUN:   --cuda-gpu-arch=sm_35 \
+// RUN:   -c %s 2>&1 \
+// RUN: | FileCheck -check-prefixes NOARCH-SM20,NOARCH-SM30,ARCH-SM35 %s
+
+// g) There's no --cuda-gpu-arch=all
+// RUN: %clang -### -target x86_64-linux-gnu --cuda-device-only \
+// RUN:   --cuda-gpu-arch=all \
+// RUN:   -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix ARCHALLERROR %s
+
+// ARCH-SM20: "-cc1"{{.*}}"-target-cpu" "sm_20"
+// NOARCH-SM20-NOT: "-cc1"{{.*}}"-target-cpu" "sm_20"
+// ARCH-SM30: "-cc1"{{.*}}"-target-cpu" "sm_30"
+// NOARCH-SM30-NOT: "-cc1"{{.*}}"-target-cpu" "sm_30"
+// ARCH-SM35: "-cc1"{{.*}}"-target-cpu" "sm_35"
+// NOARCH-SM35-NOT: "-cc1"{{.*}}"-target-cpu" "sm_35"
+// ARCHALLERROR: error: Unsupported CUDA gpu architecture: all
+
 // Match device-side preprocessor and compiler phases with -save-temps.
 // DEVICE-SAVE: "-cc1" "-triple" "nvptx64-nvidia-cuda"
 // DEVICE-SAVE-SAME: "-aux-triple" "x86_64--linux-gnu"
@@ -107,14 +166,14 @@
 // DEVICE: "-cc1" "-triple" "nvptx64-nvidia-cuda"
 // DEVICE-NOSAVE-SAME: "-aux-triple" "x86_64--linux-gnu"
 // DEVICE-SAME: "-fcuda-is-device"
-// DEVICE-SM35-SAME: "-target-cpu" "sm_35"
+// DEVICE-SM30-SAME: "-target-cpu" "sm_30"
 // DEVICE-SAME: "-o" "[[PTXFILE:[^"]*]]"
 // DEVICE-NOSAVE-SAME: "-x" "cuda"
 // DEVICE-SAVE-SAME: "-x" "ir"
 
 // Match the call to ptxas (which assembles PTX to SASS).
 // DEVICE:ptxas
-// DEVICE-SM35-DAG: "--gpu-name" "sm_35"
+// DEVICE-SM30-DAG: "--gpu-name" "sm_30"
 // DEVICE-DAG: "--output-file" "[[CUBINFILE:[^"]*]]"
 // DEVICE-DAG: "[[PTXFILE]]"
 
@@ -122,7 +181,7 @@
 // DEVICE2: "-cc1" "-triple" "nvptx64-nvidia-cuda"
 // DEVICE2-SAME: "-aux-triple" "x86_64--linux-gnu"
 // DEVICE2-SAME: "-fcuda-is-device"
-// DEVICE2-SM30-SAME: "-target-cpu" "sm_30"
+// DEVICE2-SM35-SAME: "-target-cpu" "sm_35"
 // DEVICE2-SAME: "-o" "[[GPUBINARY2:[^"]*]]"
 // DEVICE2-SAME: "-x" "cuda"
 
diff --git a/test/Driver/cuda-ptxas-path.cu b/test/Driver/cuda-ptxas-path.cu
new file mode 100644
index 0000000..3ac5932
--- /dev/null
+++ b/test/Driver/cuda-ptxas-path.cu
@@ -0,0 +1,12 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
+
+// RUN: %clang -### --target=i386-unknown-linux \
+// RUN:   --cuda-path=%S/Inputs/CUDA_80/usr/local/cuda \
+// RUN:   --ptxas-path=/some/path/to/ptxas %s 2>&1 \
+// RUN: | FileCheck %s
+
+// CHECK-NOT: "ptxas"
+// CHECK: "/some/path/to/ptxas"
+// CHECK-SAME: "--gpu-name" "sm_20"
diff --git a/test/Driver/cuda-version-check.cu b/test/Driver/cuda-version-check.cu
index cb2ac79..46ca72f 100644
--- a/test/Driver/cuda-version-check.cu
+++ b/test/Driver/cuda-version-check.cu
@@ -2,40 +2,40 @@
 // REQUIRES: x86-registered-target
 // REQUIRES: nvptx-registered-target
 
-// RUN: %clang -v -### --cuda-gpu-arch=sm_20 --sysroot=%S/Inputs/CUDA 2>&1 %s | \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_20 --sysroot=%S/Inputs/CUDA 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=OK
-// RUN: %clang -v -### --cuda-gpu-arch=sm_20 --sysroot=%S/Inputs/CUDA_80 2>&1 %s | \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_20 --sysroot=%S/Inputs/CUDA_80 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=OK
-// RUN: %clang -v -### --cuda-gpu-arch=sm_60 --sysroot=%S/Inputs/CUDA_80 2>&1 %s | \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --sysroot=%S/Inputs/CUDA_80 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=OK
 
 // The installation at Inputs/CUDA is CUDA 7.0, which doesn't support sm_60.
-// RUN: %clang -v -### --cuda-gpu-arch=sm_60 --sysroot=%S/Inputs/CUDA 2>&1 %s | \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --sysroot=%S/Inputs/CUDA 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=ERR_SM60
 
 // This should only complain about sm_60, not sm_35.
-// RUN: %clang -v -### --cuda-gpu-arch=sm_60 --cuda-gpu-arch=sm_35 \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-gpu-arch=sm_35 \
 // RUN:    --sysroot=%S/Inputs/CUDA 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=ERR_SM60 --check-prefix=OK_SM35
 
 // We should get two errors here, one for sm_60 and one for sm_61.
-// RUN: %clang -v -### --cuda-gpu-arch=sm_60 --cuda-gpu-arch=sm_61 \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-gpu-arch=sm_61 \
 // RUN:    --sysroot=%S/Inputs/CUDA 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=ERR_SM60 --check-prefix=ERR_SM61
 
 // We should still get an error if we pass -nocudainc, because this compilation
 // would invoke ptxas, and we do a version check on that, too.
-// RUN: %clang -v -### --cuda-gpu-arch=sm_60 -nocudainc --sysroot=%S/Inputs/CUDA 2>&1 %s | \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 -nocudainc --sysroot=%S/Inputs/CUDA 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=ERR_SM60
 
 // If with -nocudainc and -E, we don't touch the CUDA install, so we
 // shouldn't get an error.
-// RUN: %clang -v -### -E --cuda-device-only --cuda-gpu-arch=sm_60 -nocudainc \
+// RUN: %clang --target=x86_64-linux -v -### -E --cuda-device-only --cuda-gpu-arch=sm_60 -nocudainc \
 // RUN:    --sysroot=%S/Inputs/CUDA 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=OK
 
 // --no-cuda-version-check should suppress all of these errors.
-// RUN: %clang -v -### --cuda-gpu-arch=sm_60 --sysroot=%S/Inputs/CUDA 2>&1 \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --sysroot=%S/Inputs/CUDA 2>&1 \
 // RUN:    --no-cuda-version-check %s | \
 // RUN:    FileCheck %s --check-prefix=OK
 
@@ -43,9 +43,9 @@
 // therefore we should not get an error in host-only mode. We use the -S here
 // to avoid the error being produced in case by the assembler tool, which does
 // the same check.
-// RUN: %clang -v -### --cuda-gpu-arch=sm_60 --cuda-host-only --sysroot=%S/Inputs/CUDA -S 2>&1 %s | \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-host-only --sysroot=%S/Inputs/CUDA -S 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=OK
-// RUN: %clang -v -### --cuda-gpu-arch=sm_60 --cuda-device-only --sysroot=%S/Inputs/CUDA -S 2>&1 %s | \
+// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-device-only --sysroot=%S/Inputs/CUDA -S 2>&1 %s | \
 // RUN:    FileCheck %s --check-prefix=ERR_SM60
 
 // OK-NOT: error: GPU arch
diff --git a/test/Driver/cuda-windows.cu b/test/Driver/cuda-windows.cu
new file mode 100644
index 0000000..1d67710
--- /dev/null
+++ b/test/Driver/cuda-windows.cu
@@ -0,0 +1,14 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
+//
+// RUN: %clang -v --target=i386-pc-windows-msvc \
+// RUN:   --sysroot=%S/Inputs/CUDA-windows 2>&1 %s -### | FileCheck %s
+// RUN: %clang -v --target=i386-pc-windows-mingw32 \
+// RUN:   --sysroot=%S/Inputs/CUDA-windows 2>&1 %s -### | FileCheck %s
+
+// CHECK: Found CUDA installation: {{.*}}/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0
+// CHECK: "-cc1" "-triple" "nvptx-nvidia-cuda"
+// CHECK-SAME: "-fms-extensions"
+// CHECK-SAME: "-fms-compatibility"
+// CHECK-SAME: "-fms-compatibility-version=
diff --git a/test/Driver/darwin-iphone-defaults.m b/test/Driver/darwin-iphone-defaults.m
index 63bbbe0..d98416d 100644
--- a/test/Driver/darwin-iphone-defaults.m
+++ b/test/Driver/darwin-iphone-defaults.m
@@ -26,4 +26,4 @@
   [I1 alloc];
 }
 
-// CHECK: attributes [[F0]] = { ssp{{.*}} }
+// CHECK: attributes [[F0]] = { noinline ssp{{.*}} }
diff --git a/test/Driver/darwin-ld-pthread.c b/test/Driver/darwin-ld-pthread.c
new file mode 100644
index 0000000..b22b68a
--- /dev/null
+++ b/test/Driver/darwin-ld-pthread.c
@@ -0,0 +1,4 @@
+// RUN: %clang -Wunused-command-line-argument -pthread -target x86_64-apple-darwin -### /dev/null -o /dev/null 2>&1 | FileCheck %s
+
+// There is nothing to do at link time to get pthread support. But do not warn.
+// CHECK-NOT: argument unused during compilation: '-pthread'
diff --git a/test/Driver/debug-options.c b/test/Driver/debug-options.c
index 94c769f..be50ee8 100644
--- a/test/Driver/debug-options.c
+++ b/test/Driver/debug-options.c
@@ -214,3 +214,9 @@
 // BADSTRING1: error: invalid value 'watkind' in '-debug-info-kind=watkind'
 // RUN: not %clang -cc1 -debugger-tuning=gmodal 2>&1 | FileCheck -check-prefix=BADSTRING2 %s
 // BADSTRING2: error: invalid value 'gmodal' in '-debugger-tuning=gmodal'
+
+// RUN: %clang -### -fdebug-macro    %s 2>&1 | FileCheck -check-prefix=MACRO %s
+// RUN: %clang -### -fno-debug-macro %s 2>&1 | FileCheck -check-prefix=NOMACRO %s
+// RUN: %clang -###                  %s 2>&1 | FileCheck -check-prefix=NOMACRO %s
+// MACRO: "-debug-info-macro"
+// NOMACRO-NOT: "-debug-info-macro"
diff --git a/test/Driver/disable-llvm.c b/test/Driver/disable-llvm.c
new file mode 100644
index 0000000..3ac6b9e
--- /dev/null
+++ b/test/Driver/disable-llvm.c
@@ -0,0 +1,22 @@
+// We support a CC1 option for disabling LLVM's passes.
+// RUN: %clang -O2 -Xclang -disable-llvm-passes -### %s 2>&1 \
+// RUN:     | FileCheck --check-prefix=DISABLED %s
+// DISABLED: -cc1
+// DISABLED-NOT: "-mllvm" "-disable-llvm-passes"
+// DISABLED: "-disable-llvm-passes"
+//
+// We also support two alternative spellings for historical reasons.
+// RUN: %clang -O2 -Xclang -disable-llvm-optzns -### %s 2>&1 \
+// RUN:     | FileCheck --check-prefix=DISABLED-LEGACY %s
+// RUN: %clang -O2 -mllvm -disable-llvm-optzns -### %s 2>&1 \
+// RUN:     | FileCheck --check-prefix=DISABLED-LEGACY %s
+// DISABLED-LEGACY: -cc1
+// DISABLED-LEGACY-NOT: "-mllvm" "-disable-llvm-optzns"
+// DISABLED-LEGACY: "-disable-llvm-optzns"
+//
+// The main flag shouldn't be specially handled when used with '-mllvm'.
+// RUN: %clang -O2 -mllvm -disable-llvm-passes -### %s 2>&1 | FileCheck --check-prefix=MLLVM %s
+// MLLVM: -cc1
+// MLLVM-NOT: -disable-llvm-passes
+// MLLVM: "-mllvm" "-disable-llvm-passes"
+// MLLVM-NOT: -disable-llvm-passes
diff --git a/test/Driver/embed-bitcode.c b/test/Driver/embed-bitcode.c
index 36314e6..07e4378 100644
--- a/test/Driver/embed-bitcode.c
+++ b/test/Driver/embed-bitcode.c
@@ -34,6 +34,13 @@
 // CHECK-LTO-NOT: warning: argument unused during compilation: '-fembed-bitcode'
 // CHECK-LTO-NOT: -cc1
 // CHECK-LTO-NOT: -fembed-bitcode=all
+// RUN: touch %t.o
+// RUN: %clang  -target armv7-apple-darwin -miphoneos-version-min=6.0 %t.o -fembed-bitcode  -fembed-bitcode-marker -mlinker-version=277  2>&1 -### | FileCheck %s -check-prefix=CHECK-LTO-MARKER-277
+// RUN: %clang  -target armv7-apple-darwin -miphoneos-version-min=6.0 %t.o -fembed-bitcode  -fembed-bitcode-marker -mlinker-version=278  2>&1 -### | FileCheck %s -check-prefix=CHECK-LTO-MARKER-278
+// CHECK-LTO-MARKER-277-NOT: bitcode_process_mode
+// CHECK-LTO-MARKER-278: bitcode_process_mode
+
+
 
 // RUN: %clang -c %s -fembed-bitcode-marker -fintegrated-as 2>&1 -### | FileCheck %s -check-prefix=CHECK-MARKER
 // CHECK-MARKER: -cc1
@@ -51,5 +58,5 @@
 // CHECK-NO-LINKER-NOT: -bitcode_bundle
 
 // RUN: %clang -target armv7-apple-darwin -miphoneos-version-min=5.0 %s -fembed-bitcode -### 2>&1 | \
-// RUN:   FileCheck %s -check-prefix=CHECK-PLATFORM-UNSUPPORTED
-// CHECK-PLATFORM-UNSUPPORTED: -fembed-bitcode is not supported on versions of iOS prior to 6.0
+// RUN:   FileCheck %s -check-prefix=CHECK-PLATFORM-NOTSUPPORTED
+// CHECK-PLATFORM-NOTSUPPORTED: -fembed-bitcode is not supported on versions of iOS prior to 6.0
diff --git a/test/Driver/frame-pointer-elim.c b/test/Driver/frame-pointer-elim.c
index e1d816e..e39499a 100644
--- a/test/Driver/frame-pointer-elim.c
+++ b/test/Driver/frame-pointer-elim.c
@@ -49,9 +49,9 @@
 
 // RUN: %clang -### -target armv7s-apple-ios8.0 -momit-leaf-frame-pointer %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=WARN-OMIT-LEAF-7S %s
-// WARN-OMIT-LEAF-7S: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
+// WARN-OMIT-LEAF-7S-NOT: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
 // WARN-OMIT-LEAF-7S: "-mdisable-fp-elim"
-// WARN-OMIT-LEAF-7S-NOT: "-momit-leaf-frame-pointer"
+// WARN-OMIT-LEAF-7S: "-momit-leaf-frame-pointer"
 
 // On the PS4, we default to omitting the frame pointer on leaf functions
 // (OMIT_LEAF check line is above)
diff --git a/test/Driver/frame-pointer.c b/test/Driver/frame-pointer.c
index cec1686..ecb16af 100644
--- a/test/Driver/frame-pointer.c
+++ b/test/Driver/frame-pointer.c
@@ -17,6 +17,13 @@
 // RUN: %clang -target s390x-pc-linux -### -S -O0 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK0-64 %s
 // RUN: %clang -target s390x-pc-linux -### -S -O1 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK1-64 %s
 
+// RUN: %clang -target powerpc-unknown-linux-gnu -### -S -O0 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK0-64 %s
+// RUN: %clang -target powerpc-unknown-linux-gnu -### -S -O1 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK1-64 %s
+// RUN: %clang -target powerpc64-unknown-linux-gnu -### -S -O0 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK0-64 %s
+// RUN: %clang -target powerpc64-unknown-linux-gnu -### -S -O1 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK1-64 %s
+// RUN: %clang -target powerpc64le-unknown-linux-gnu -### -S -O0 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK0-64 %s
+// RUN: %clang -target powerpc64le-unknown-linux-gnu -### -S -O1 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK1-64 %s
+
 // RUN: %clang -target mips-linux-gnu -### -S -O0 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK0-32 %s
 // RUN: %clang -target mips-linux-gnu -### -S -O1 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK1-32 %s
 // RUN: %clang -target mipsel-linux-gnu -### -S -O0 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK0-32 %s
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index 25aea01..c5a8e11 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -231,6 +231,12 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address,leak -fno-sanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANA-SANL-NO-SANA
 // CHECK-SANA-SANL-NO-SANA: "-fsanitize=leak"
 
+// RUN: %clang -target i686-linux-gnu -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-X86
+// CHECK-SANL-X86: "-fsanitize=leak"
+
+// RUN: %clang -target i686-linux-gnu -fsanitize=address,leak -fno-sanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANA-SANL-NO-SANA-X86
+// CHECK-SANA-SANL-NO-SANA-X86: "-fsanitize=leak"
+
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN
 // CHECK-MSAN: "-fno-assume-sane-operator-new"
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN
diff --git a/test/Driver/fuchsia.c b/test/Driver/fuchsia.c
index 229b588..58c2bbe 100644
--- a/test/Driver/fuchsia.c
+++ b/test/Driver/fuchsia.c
@@ -1,5 +1,5 @@
 // RUN: %clang %s -### -no-canonical-prefixes --target=x86_64-unknown-fuchsia \
-// RUN:     --sysroot=%S/platform 2>&1 | FileCheck %s
+// RUN:     --sysroot=%S/platform -fuse-ld=ld 2>&1 | FileCheck %s
 // CHECK: {{.*}}clang{{.*}}" "-cc1"
 // CHECK: "-fuse-init-array"
 // CHECK: "-isysroot" "[[SYSROOT:[^"]+]]"
@@ -38,3 +38,8 @@
 // CHECK-RELOCATABLE-NOT: "-pie"
 // CHECK-RELOCATABLE-NOT: "--build-id"
 // CHECK-RELOCATABLE: "-r"
+
+// RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
+// RUN:     -fsanitize=safe-stack 2>&1 \
+// RUN:     | FileCheck %s -check-prefix=CHECK-SAFESTACK
+// CHECK-SAFESTACK: "-fsanitize=safe-stack"
diff --git a/test/Driver/fuchsia.cpp b/test/Driver/fuchsia.cpp
index 275891d..4490f94 100644
--- a/test/Driver/fuchsia.cpp
+++ b/test/Driver/fuchsia.cpp
@@ -1,5 +1,5 @@
 // RUN: %clangxx %s -### -no-canonical-prefixes --target=x86_64-unknown-fuchsia \
-// RUN:     --sysroot=%S/platform 2>&1 | FileCheck %s
+// RUN:     --sysroot=%S/platform 2>&1 -fuse-ld=ld | FileCheck %s
 // CHECK: {{.*}}clang{{.*}}" "-cc1"
 // CHECK: "-fuse-init-array"
 // CHECK: "-isysroot" "[[SYSROOT:[^"]+]]"
diff --git a/test/Driver/fuse-ld.c b/test/Driver/fuse-ld.c
index ca89eb9..bd8c9a5 100644
--- a/test/Driver/fuse-ld.c
+++ b/test/Driver/fuse-ld.c
@@ -32,7 +32,7 @@
 
 
 
-// RUN: %clang %s -### \
+// RUN: %clang %s -### -fuse-ld=ld \
 // RUN:     -target arm-linux-androideabi \
 // RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD
@@ -50,7 +50,7 @@
 // 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: %clang %s -### -fuse-ld=ld \
 // 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
diff --git a/test/Driver/gold-lto-samplepgo.c b/test/Driver/gold-lto-samplepgo.c
new file mode 100644
index 0000000..ee4b51c
--- /dev/null
+++ b/test/Driver/gold-lto-samplepgo.c
@@ -0,0 +1,7 @@
+// RUN: touch %t.o
+//
+// RUN: %clang -target x86_64-unknown-linux -### %t.o -flto 2>&1 \
+// RUN:     -Wl,-plugin-opt=foo -O3 \
+// RUN:     -fprofile-sample-use=%s \
+// RUN:     | FileCheck %s
+// CHECK: -plugin-opt=sample-profile=
diff --git a/test/Driver/instrprof-ld.c b/test/Driver/instrprof-ld.c
index 05f65d6..ea20105 100644
--- a/test/Driver/instrprof-ld.c
+++ b/test/Driver/instrprof-ld.c
@@ -1,7 +1,7 @@
 // Test instrumented profiling ld flags.
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux -fprofile-instr-generate \
+// RUN:     -target i386-unknown-linux -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LINUX-I386 %s
@@ -10,7 +10,7 @@
 // CHECK-LINUX-I386: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-i386.a" {{.*}} "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux -fprofile-instr-generate \
+// RUN:     -target x86_64-unknown-linux -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LINUX-X86-64 %s
@@ -19,7 +19,7 @@
 // CHECK-LINUX-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-x86_64.a" {{.*}} "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux -fprofile-instr-generate -nostdlib \
+// RUN:     -target x86_64-unknown-linux -fprofile-instr-generate -nostdlib -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LINUX-NOSTDLIB-X86-64 %s
@@ -28,7 +28,7 @@
 // CHECK-LINUX-NOSTDLIB-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-x86_64.a"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-freebsd -fprofile-instr-generate \
+// RUN:     -target x86_64-unknown-freebsd -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_freebsd64_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-FREEBSD-X86-64 %s
@@ -38,7 +38,7 @@
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -shared \
-// RUN:     -target i386-unknown-linux -fprofile-instr-generate \
+// RUN:     -target i386-unknown-linux -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LINUX-I386-SHARED %s
@@ -48,7 +48,7 @@
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -shared \
-// RUN:     -target x86_64-unknown-linux -fprofile-instr-generate \
+// RUN:     -target x86_64-unknown-linux -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LINUX-X86-64-SHARED %s
@@ -58,7 +58,7 @@
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -shared \
-// RUN:     -target x86_64-unknown-freebsd -fprofile-instr-generate \
+// RUN:     -target x86_64-unknown-freebsd -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_freebsd64_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-FREEBSD-X86-64-SHARED %s
@@ -67,7 +67,7 @@
 // CHECK-FREEBSD-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}freebsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-apple-darwin14 -fprofile-instr-generate \
+// RUN:     -target x86_64-apple-darwin14 -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:   | FileCheck --check-prefix=CHECK-DARWIN-X86-64 %s
 //
@@ -75,7 +75,7 @@
 // CHECK-DARWIN-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}darwin{{/|\\\\}}libclang_rt.profile_osx.a"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-apple-darwin14 -fprofile-instr-generate -nostdlib \
+// RUN:     -target x86_64-apple-darwin14 -fprofile-instr-generate -nostdlib -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:   | FileCheck --check-prefix=CHECK-DARWIN-NOSTDLIB-X86-64 %s
 //
@@ -83,7 +83,7 @@
 // CHECK-DARWIN-NOSTDLIB-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}darwin{{/|\\\\}}libclang_rt.profile_osx.a"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target arm64-apple-ios -fprofile-instr-generate \
+// RUN:     -target arm64-apple-ios -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:   | FileCheck --check-prefix=CHECK-DARWIN-ARM64 %s
 //
@@ -91,7 +91,7 @@
 // CHECK-DARWIN-ARM64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}darwin{{/|\\\\}}libclang_rt.profile_ios.a"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target armv7-apple-darwin -mtvos-version-min=8.3 -fprofile-instr-generate \
+// RUN:     -target armv7-apple-darwin -mtvos-version-min=8.3 -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:   | FileCheck --check-prefix=CHECK-TVOS-ARMV7 %s
 //
@@ -99,7 +99,7 @@
 // CHECK-TVOS-ARMV7: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}darwin{{/|\\\\}}libclang_rt.profile_tvos.a"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target armv7s-apple-darwin10 -mwatchos-version-min=2.0 -arch armv7k -fprofile-instr-generate \
+// RUN:     -target armv7s-apple-darwin10 -mwatchos-version-min=2.0 -arch armv7k -fprofile-instr-generate -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:   | FileCheck --check-prefix=CHECK-WATCHOS-ARMV7 %s
 //
diff --git a/test/Driver/integrated-as.s b/test/Driver/integrated-as.s
index 5316f52..1dcd4f6 100644
--- a/test/Driver/integrated-as.s
+++ b/test/Driver/integrated-as.s
@@ -1,52 +1,52 @@
-// RUN: %clang -### -c -integrated-as %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s 2>&1 | FileCheck %s
 // CHECK: cc1as
 // CHECK-NOT: -relax-all
 
-// RUN: %clang -### -c -integrated-as -Wa,-L %s 2>&1 | FileCheck --check-prefix=OPT_L %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as -Wa,-L %s 2>&1 | FileCheck --check-prefix=OPT_L %s
 // OPT_L: msave-temp-labels
 
 // Test that -I params in -Wa, and -Xassembler args are passed to integrated assembler
-// RUN: %clang -### -c -integrated-as %s -Wa,-I,foo_dir 2>&1 | FileCheck --check-prefix=WA_INCLUDE1 %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -Wa,-I,foo_dir 2>&1 | FileCheck --check-prefix=WA_INCLUDE1 %s
 // WA_INCLUDE1: cc1as
 // WA_INCLUDE1: "-I" "foo_dir"
 
-// RUN: %clang -### -c -integrated-as %s -Wa,-Ifoo_dir 2>&1 | FileCheck --check-prefix=WA_INCLUDE2 %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -Wa,-Ifoo_dir 2>&1 | FileCheck --check-prefix=WA_INCLUDE2 %s
 // WA_INCLUDE2: cc1as
 // WA_INCLUDE2: "-Ifoo_dir"
 
-// RUN: %clang -### -c -integrated-as %s -Wa,-I -Wa,foo_dir 2>&1 | FileCheck --check-prefix=WA_INCLUDE3 %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -Wa,-I -Wa,foo_dir 2>&1 | FileCheck --check-prefix=WA_INCLUDE3 %s
 // WA_INCLUDE3: cc1as
 // WA_INCLUDE3: "-I" "foo_dir"
 
-// RUN: %clang -### -c -integrated-as %s -Xassembler -I -Xassembler foo_dir 2>&1 | FileCheck --check-prefix=XA_INCLUDE1 %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -Xassembler -I -Xassembler foo_dir 2>&1 | FileCheck --check-prefix=XA_INCLUDE1 %s
 // XA_INCLUDE1: cc1as
 // XA_INCLUDE1: "-I" "foo_dir"
 
-// RUN: %clang -### -c -integrated-as %s -Xassembler -Ifoo_dir 2>&1 | FileCheck --check-prefix=XA_INCLUDE2 %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -Xassembler -Ifoo_dir 2>&1 | FileCheck --check-prefix=XA_INCLUDE2 %s
 // XA_INCLUDE2: cc1as
 // XA_INCLUDE2: "-Ifoo_dir"
 
-// RUN: %clang -### -c -integrated-as %s -gdwarf-4 -gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2 %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -gdwarf-4 -gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2 %s
 // DWARF2: "-debug-info-kind=limited" "-dwarf-version=2"
 
-// RUN: %clang -### -c -integrated-as %s -gdwarf-3 2>&1 | FileCheck --check-prefix=DWARF3 %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -gdwarf-3 2>&1 | FileCheck --check-prefix=DWARF3 %s
 // DWARF3: "-debug-info-kind=limited" "-dwarf-version=3"
 
-// RUN: %clang -### -c -integrated-as %s -gdwarf-4 2>&1 | FileCheck --check-prefix=DWARF4 %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -gdwarf-4 2>&1 | FileCheck --check-prefix=DWARF4 %s
 // DWARF4: "-debug-info-kind=limited" "-dwarf-version=4"
 
-// RUN: %clang -### -c -integrated-as %s -Xassembler -gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2XASSEMBLER %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -Xassembler -gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2XASSEMBLER %s
 // DWARF2XASSEMBLER: "-debug-info-kind=limited" "-dwarf-version=2"
 
-// RUN: %clang -### -c -integrated-as %s -Wa,-gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2WA %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -Wa,-gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2WA %s
 // DWARF2WA: "-debug-info-kind=limited" "-dwarf-version=2"
 
 // A dwarf version number that driver can't parse is just stuffed in.
-// RUN: %clang -### -c -integrated-as %s -Wa,-gdwarf-huh 2>&1 | FileCheck --check-prefix=BOGODWARF %s
+// RUN: %clang -### -target x86_64--- -c -integrated-as %s -Wa,-gdwarf-huh 2>&1 | FileCheck --check-prefix=BOGODWARF %s
 // BOGODWARF: "-gdwarf-huh"
 
-// RUN: %clang -### -x assembler -c -integrated-as %s -I myincludedir 2>&1 | FileCheck --check-prefix=INCLUDEPATH %s
+// RUN: %clang -### -target x86_64--- -x assembler -c -integrated-as %s -I myincludedir 2>&1 | FileCheck --check-prefix=INCLUDEPATH %s
 // INCLUDEPATH: "-I" "myincludedir"
 
-// RUN: %clang -### -x assembler -c -fPIC -integrated-as %s 2>&1 | FileCheck --check-prefix=PIC %s
+// RUN: %clang -### -target x86_64--- -x assembler -c -fPIC -integrated-as %s 2>&1 | FileCheck --check-prefix=PIC %s
 // PIC: "-mrelocation-model" "pic"
diff --git a/test/Driver/linux-header-search.cpp b/test/Driver/linux-header-search.cpp
index 491bb4d..274895f 100644
--- a/test/Driver/linux-header-search.cpp
+++ b/test/Driver/linux-header-search.cpp
@@ -310,6 +310,39 @@
 // RUN:     --gcc-toolchain="" \
 // RUN:   | FileCheck --check-prefix=CHECK-GENTOO-4-9-3 %s
 //
+// Test that gcc-config support does not break multilib.
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnux32 -stdlib=libstdc++ \
+// RUN:     --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=CHECK-GENTOO-4-9-3-X32 %s
+// CHECK-GENTOO-4-9-3-X32: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK-GENTOO-4-9-3-X32: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-GENTOO-4-9-3-X32: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3"
+// CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/x86_64-pc-linux-gnu/x32"
+// CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/backward"
+// CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-GENTOO-4-9-3-X32: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include"
+// CHECK-GENTOO-4-9-3-X32: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-GENTOO-4-9-3-X32: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target i386-unknown-linux-gnu -stdlib=libstdc++ \
+// RUN:     --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=CHECK-GENTOO-4-9-3-32 %s
+// CHECK-GENTOO-4-9-3-32: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK-GENTOO-4-9-3-32: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-GENTOO-4-9-3-32: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3"
+// CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/x86_64-pc-linux-gnu/32"
+// CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4.9.3/backward"
+// CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-GENTOO-4-9-3-32: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include"
+// CHECK-GENTOO-4-9-3-32: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-GENTOO-4-9-3-32: "-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 -stdlib=libstdc++ \
diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
index 60b30dd..e5aa870 100644
--- a/test/Driver/linux-ld.c
+++ b/test/Driver/linux-ld.c
@@ -618,6 +618,26 @@
 // CHECK-SUSE-10-3-PPC64: "-L[[SYSROOT]]/lib/../lib64"
 // CHECK-SUSE-10-3-PPC64: "-L[[SYSROOT]]/usr/lib/../lib64"
 //
+// Check openSuse Leap 42.2 on AArch64
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-unknown-linux-gnu \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/opensuse_42.2_aarch64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-OPENSUSE-42-2-AARCH64 %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-unknown-linux-gnu \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/opensuse_42.2_aarch64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-OPENSUSE-42-2-AARCH64 %s
+// CHECK-OPENSUSE-42-2-AARCH64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-OPENSUSE-42-2-AARCH64: "{{.*}}/usr/lib64/gcc/aarch64-suse-linux/4.8/../../../../lib64{{/|\\\\}}crt1.o"
+// CHECK-OPENSUSE-42-2-AARCH64: "{{.*}}/usr/lib64/gcc/aarch64-suse-linux/4.8/../../../../lib64{{/|\\\\}}crti.o"
+// CHECK-OPENSUSE-42-2-AARCH64: "{{.*}}/usr/lib64/gcc/aarch64-suse-linux/4.8{{/|\\\\}}crtbegin.o"
+// CHECK-OPENSUSE-42-2-AARCH64: "-L[[SYSROOT]]/usr/lib64/gcc/aarch64-suse-linux/4.8"
+// CHECK-OPENSUSE-42-2-AARCH64: "-L[[SYSROOT]]/usr/lib64/gcc/aarch64-suse-linux/4.8/../../../../lib64"
+// CHECK-OPENSUSE-42-2-AARCH64: "{{.*}}/usr/lib64/gcc/aarch64-suse-linux/4.8{{/|\\\\}}crtend.o"
+// CHECK-OPENSUSE-42-2-AARCH64: "{{.*}}/usr/lib64/gcc/aarch64-suse-linux/4.8/../../../../lib64{{/|\\\\}}crtn.o"
+//
 // Check dynamic-linker for different archs
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=arm-linux-gnueabi \
@@ -685,6 +705,14 @@
 // CHECK-PPC64LE-ELFv2: "-m" "elf64lppc"
 // CHECK-PPC64LE-ELFv2: "-dynamic-linker" "{{.*}}/lib{{(64)?}}/ld64.so.2"
 //
+// Check that we do not pass --hash-style=gnu or --hash-style=both to
+// hexagon linux linker
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN:     --target=hexagon-linux-gnu \
+// RUN:   | FileCheck --check-prefix=CHECK-HEXAGON %s
+// CHECK-HEXAGON: "{{.*}}hexagon-link{{(.exe)?}}"
+// CHECK-HEXAGON-NOT: "--hash-style={{gnu|both}}"
+//
 // 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.
@@ -1662,3 +1690,56 @@
 // CHECK-MUSL-ARMEBHF:    "-dynamic-linker" "/lib/ld-musl-armebhf.so.1"
 // CHECK-MUSL-AARCH64:    "-dynamic-linker" "/lib/ld-musl-aarch64.so.1"
 // CHECK-MUSL-AARCH64_BE: "-dynamic-linker" "/lib/ld-musl-aarch64_be.so.1"
+
+// Check whether multilib gcc install works fine on Gentoo with gcc-config
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux-gnu -rtlib=platform \
+// RUN:     --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-GENTOO %s
+// CHECK-LD-GENTOO-NOT: warning:
+// CHECK-LD-GENTOO: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-LD-GENTOO: "--eh-frame-hdr"
+// CHECK-LD-GENTOO: "-m" "elf_x86_64"
+// CHECK-LD-GENTOO: "-dynamic-linker"
+// CHECK-LD-GENTOO: "{{.*}}/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3{{/|\\\\}}crtbegin.o"
+// CHECK-LD-GENTOO: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3"
+// CHECK-LD-GENTOO: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../../../x86_64-pc-linux-gnu/lib"
+// CHECK-LD-GENTOO: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../.."
+// CHECK-LD-GENTOO: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// CHECK-LD-GENTOO: "-lc"
+// CHECK-LD-GENTOO: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-unknown-linux-gnu -rtlib=platform \
+// RUN:     --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-GENTOO-32 %s
+// CHECK-LD-GENTOO-32-NOT: warning:
+// CHECK-LD-GENTOO-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-LD-GENTOO-32: "--eh-frame-hdr"
+// CHECK-LD-GENTOO-32: "-m" "elf_i386"
+// CHECK-LD-GENTOO-32: "-dynamic-linker"
+// CHECK-LD-GENTOO-32: "{{.*}}/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/32{{/|\\\\}}crtbegin.o"
+// CHECK-LD-GENTOO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/32"
+// CHECK-LD-GENTOO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../../../x86_64-pc-linux-gnu/lib"
+// CHECK-LD-GENTOO-32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../.."
+// CHECK-LD-GENTOO-32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// CHECK-LD-GENTOO-32: "-lc"
+// CHECK-LD-GENTOO-32: "-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 -rtlib=platform \
+// RUN:     --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-GENTOO-X32 %s
+// CHECK-LD-GENTOO-X32-NOT: warning:
+// CHECK-LD-GENTOO-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-LD-GENTOO-X32: "--eh-frame-hdr"
+// CHECK-LD-GENTOO-X32: "-m" "elf32_x86_64"
+// CHECK-LD-GENTOO-X32: "-dynamic-linker"
+// CHECK-LD-GENTOO-X32: "{{.*}}/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/x32{{/|\\\\}}crtbegin.o"
+// CHECK-LD-GENTOO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/x32"
+// CHECK-LD-GENTOO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../../../x86_64-pc-linux-gnu/lib"
+// CHECK-LD-GENTOO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/../../.."
+// CHECK-LD-GENTOO-X32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// CHECK-LD-GENTOO-X32: "-lc"
+// CHECK-LD-GENTOO-X32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
diff --git a/test/Driver/lto-unit.c b/test/Driver/lto-unit.c
new file mode 100644
index 0000000..8a800fa
--- /dev/null
+++ b/test/Driver/lto-unit.c
@@ -0,0 +1,7 @@
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=full 2>&1 | FileCheck --check-prefix=UNIT %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin 2>&1 | FileCheck --check-prefix=UNIT %s
+// RUN: %clang -target x86_64-apple-darwin13.3.0 -### %s -flto=full 2>&1 | FileCheck --check-prefix=UNIT %s
+// RUN: %clang -target x86_64-apple-darwin13.3.0 -### %s -flto=thin 2>&1 | FileCheck --check-prefix=NOUNIT %s
+
+// UNIT: "-flto-unit"
+// NOUNIT-NOT: "-flto-unit"
diff --git a/test/Driver/mbig-obj.c b/test/Driver/mbig-obj.c
new file mode 100644
index 0000000..8e0106d
--- /dev/null
+++ b/test/Driver/mbig-obj.c
@@ -0,0 +1,6 @@
+// RUN: %clang --target=x86_64-windows -c -Wa,-mbig-obj %s -### 2>&1 | FileCheck %s --check-prefix=WINDOWS
+// RUN: %clang --target=x86_64-windows -c -Xassembler -mbig-obj %s -### 2>&1 | FileCheck %s --check-prefix=WINDOWS
+// RUN: %clang --target=x86_64-linux -c -Wa,-mbig-obj %s -### 2>&1 | FileCheck %s --check-prefix=LINUX
+// RUN: %clang --target=x86_64-linux -c -Xassembler -mbig-obj %s -### 2>&1 | FileCheck %s --check-prefix=LINUX
+// WINDOWS-NOT: argument unused during compilation
+// LINUX: unsupported argument '-mbig-obj' to option '{{(Wa,|Xassembler)}}'
diff --git a/test/Driver/mglobal-merge.c b/test/Driver/mglobal-merge.c
index ad76736..271011e 100644
--- a/test/Driver/mglobal-merge.c
+++ b/test/Driver/mglobal-merge.c
@@ -11,7 +11,7 @@
 // RUN: FileCheck --check-prefix=CHECK-NONE < %t %s
 
 // CHECK-NGM-ARM: "-backend-option" "-arm-global-merge=false"
-// CHECK-NGM-AARCH64: "-backend-option" "-aarch64-global-merge=false"
+// CHECK-NGM-AARCH64: "-backend-option" "-aarch64-enable-global-merge=false"
 
 // RUN: %clang -target armv7-unknown-unknown -### -fsyntax-only %s 2> %t \
 // RUN:   -mglobal-merge
@@ -26,7 +26,7 @@
 // RUN: FileCheck --check-prefix=CHECK-NONE < %t %s
 
 // CHECK-GM-ARM: "-backend-option" "-arm-global-merge=true"
-// CHECK-GM-AARCH64: "-backend-option" "-aarch64-global-merge=true"
+// CHECK-GM-AARCH64: "-backend-option" "-aarch64-enable-global-merge=true"
 
 // RUN: %clang -target armv7-unknown-unknown -### -fsyntax-only %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-NONE < %t %s
diff --git a/test/Driver/mingw.cpp b/test/Driver/mingw.cpp
index c939c7a..4e25c1d 100644
--- a/test/Driver/mingw.cpp
+++ b/test/Driver/mingw.cpp
@@ -7,8 +7,6 @@
 // CHECK_MINGW_ORG_TREE: "{{.*}}/Inputs/mingw_mingw_org_tree/mingw{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}mingw32{{/|\\\\}}4.8.1{{/|\\\\}}include{{/|\\\\}}c++"
 // CHECK_MINGW_ORG_TREE: "{{.*}}/Inputs/mingw_mingw_org_tree/mingw{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}mingw32{{/|\\\\}}4.8.1{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}mingw32"
 // CHECK_MINGW_ORG_TREE: "{{.*}}{{/|\\\\}}Inputs/mingw_mingw_org_tree/mingw{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}mingw32{{/|\\\\}}4.8.1{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}backward"
-// CHECK_MINGW_ORG_TREE: "{{.*}}/Inputs/mingw_mingw_org_tree/mingw{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}mingw32{{/|\\\\}}4.8.1{{/|\\\\}}include"
-// CHECK_MINGW_ORG_TREE: "{{.*}}/Inputs/mingw_mingw_org_tree/mingw{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}mingw32{{/|\\\\}}4.8.1{{/|\\\\}}include-fixed"
 // CHECK_MINGW_ORG_TREE: "{{.*}}/Inputs/mingw_mingw_org_tree/mingw{{/|\\\\}}mingw32{{/|\\\\}}include"
 // CHECK_MINGW_ORG_TREE: {{.*}}/Inputs/mingw_mingw_org_tree/mingw{{/|\\\\}}include
 
@@ -17,8 +15,6 @@
 // CHECK_MINGW_BUILDS_TREE: "{{.*}}/Inputs/mingw_mingw_builds_tree/mingw32{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include{{/|\\\\}}c++"
 // CHECK_MINGW_BUILDS_TREE: "{{.*}}/Inputs/mingw_mingw_builds_tree/mingw32{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}i686-w64-mingw32"
 // CHECK_MINGW_BUILDS_TREE: "{{.*}}/Inputs/mingw_mingw_builds_tree/mingw32{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}backward"
-// CHECK_MINGW_BUILDS_TREE: "{{.*}}/Inputs/mingw_mingw_builds_tree/mingw32{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}4.9.1{{/|\\\\}}include"
-// CHECK_MINGW_BUILDS_TREE: "{{.*}}/Inputs/mingw_mingw_builds_tree/mingw32{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}4.9.1{{/|\\\\}}include-fixed"
 // CHECK_MINGW_BUILDS_TREE: "{{.*}}/Inputs/mingw_mingw_builds_tree/mingw32{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include"
 
 
@@ -26,8 +22,6 @@
 // CHECK_MINGW_MSYS_TREE: "{{.*}}/Inputs/mingw_msys2_tree/msys64{{/|\\\\}}mingw32{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}4.9.2"
 // CHECK_MINGW_MSYS_TREE: "{{.*}}/Inputs/mingw_msys2_tree/msys64/mingw32{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}4.9.2{{/|\\\\}}i686-w64-mingw32"
 // CHECK_MINGW_MSYS_TREE: "{{.*}}/Inputs/mingw_msys2_tree/msys64/mingw32{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}4.9.2{{/|\\\\}}backward"
-// CHECK_MINGW_MSYS_TREE:  "{{.*}}/Inputs/mingw_msys2_tree/msys64/mingw32{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}4.9.2{{/|\\\\}}include"
-// CHECK_MINGW_MSYS_TREE:  "{{.*}}/Inputs/mingw_msys2_tree/msys64/mingw32{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}4.9.2{{/|\\\\}}include-fixed"
 // CHECK_MINGW_MSYS_TREE: "{{.*}}/Inputs/mingw_msys2_tree/msys64/mingw32{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include"
 // CHECK_MINGW_MSYS_TREE: "{{.*}}/Inputs/mingw_msys2_tree/msys64/mingw32{{/|\\\\}}include"
 
@@ -36,17 +30,13 @@
 // CHECK_MINGW_OPENSUSE_TREE: "{{.*}}/Inputs/mingw_opensuse_tree/usr{{/|\\\\}}lib64{{/|\\\\}}gcc{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}5.1.0{{/|\\\\}}include{{/|\\\\}}c++"
 // CHECK_MINGW_OPENSUSE_TREE: "{{.*}}/Inputs/mingw_opensuse_tree/usr{{/|\\\\}}lib64{{/|\\\\}}gcc{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}5.1.0{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}x86_64-w64-mingw32"
 // CHECK_MINGW_OPENSUSE_TREE: "{{.*}}/Inputs/mingw_opensuse_tree/usr{{/|\\\\}}lib64{{/|\\\\}}gcc{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}5.1.0{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}backward"
-// CHECK_MINGW_OPENSUSE_TREE: "{{.*}}/Inputs/mingw_opensuse_tree/usr{{/|\\\\}}lib64{{/|\\\\}}gcc{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}5.1.0{{/|\\\\}}include"
 // CHECK_MINGW_OPENSUSE_TREE: "{{.*}}/Inputs/mingw_opensuse_tree/usr{{/|\\\\}}x86_64-w64-mingw32/sys-root/mingw/include"
-// CHECK_MINGW_OPENSUSE_TREE: "{{.*}}/Inputs/mingw_opensuse_tree/usr{{/|\\\\}}lib64{{/|\\\\}}gcc{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}5.1.0{{/|\\\\}}include-fixed"
 
 
 // RUN: %clang -target i686-pc-windows-gnu -rtlib=platform -stdlib=libstdc++ -c -### --sysroot=%S/Inputs/mingw_arch_tree/usr %s 2>&1 | FileCheck -check-prefix=CHECK_MINGW_ARCH_TREE %s
 // CHECK_MINGW_ARCH_TREE: "{{.*}}/Inputs/mingw_arch_tree/usr{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}5.1.0"
 // CHECK_MINGW_ARCH_TREE: "{{.*}}/Inputs/mingw_arch_tree/usr{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}5.1.0{{/|\\\\}}i686-w64-mingw32"
 // CHECK_MINGW_ARCH_TREE: "{{.*}}/Inputs/mingw_arch_tree/usr{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}5.1.0{{/|\\\\}}backward"
-// CHECK_MINGW_ARCH_TREE: "{{.*}}/Inputs/mingw_arch_tree/usr{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}5.1.0{{/|\\\\}}include"
-// CHECK_MINGW_ARCH_TREE: "{{.*}}/Inputs/mingw_arch_tree/usr{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}5.1.0{{/|\\\\}}include-fixed"
 // CHECK_MINGW_ARCH_TREE: "{{.*}}/Inputs/mingw_arch_tree/usr{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include"
 
 
@@ -54,6 +44,4 @@
 // CHECK_MINGW_UBUNTU_TREE: "{{.*}}/Inputs/mingw_ubuntu_tree/usr{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}4.8"
 // CHECK_MINGW_UBUNTU_TREE: "{{.*}}/Inputs/mingw_ubuntu_tree/usr{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}4.8{{/|\\\\}}x86_64-w64-mingw32"
 // CHECK_MINGW_UBUNTU_TREE: "{{.*}}/Inputs/mingw_ubuntu_tree/usr{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}4.8{{/|\\\\}}backward"
-// CHECK_MINGW_UBUNTU_TREE: "{{.*}}/Inputs/mingw_ubuntu_tree/usr{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}4.8{{/|\\\\}}include"
-// CHECK_MINGW_UBUNTU_TREE: "{{.*}}/Inputs/mingw_ubuntu_tree/usr{{/|\\\\}}lib{{/|\\\\}}gcc{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}4.8{{/|\\\\}}include-fixed"
 // CHECK_MINGW_UBUNTU_TREE: "{{.*}}/Inputs/mingw_ubuntu_tree/usr{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}include"
diff --git a/test/Driver/mips-as.c b/test/Driver/mips-as.c
index 4d95620..560b595 100644
--- a/test/Driver/mips-as.c
+++ b/test/Driver/mips-as.c
@@ -21,17 +21,32 @@
 // MIPS32R2-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EL"
 //
 // RUN: %clang -target mips64-linux-gnu -### \
-// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   -no-integrated-as -fno-pic -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS64R2-EB-AS %s
-// MIPS64R2-EB-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-KPIC" "-EB"
+// MIPS64R2-EB-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-EB"
+//
+// RUN: %clang -target mips64-linux-gnu -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS64R2-EB-AS-PIC %s
+// MIPS64R2-EB-AS-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB" "-KPIC"
+//
+// RUN: %clang -target mips64el-linux-gnu -### \
+// RUN:   -no-integrated-as -c -fno-pic %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS64R2-DEF-EL-AS %s
+// MIPS64R2-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64"  "-mno-shared" "-EL"
 //
 // RUN: %clang -target mips64el-linux-gnu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS64R2-DEF-EL-AS %s
-// MIPS64R2-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64"  "-mno-shared" "-KPIC" "-EL"
+// RUN:   | FileCheck -check-prefix=MIPS64R2-DEF-EL-AS-PIC %s
+// MIPS64R2-DEF-EL-AS-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL" "-KPIC"
 //
 // RUN: %clang -target mips64-linux-gnu -mabi=n32 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-N32-PIC %s
+// MIPS-N32-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "n32" "-call_nonpic" "-EB" "-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -mabi=n32 -### \
+// RUN:   -no-integrated-as -c %s -fno-pic 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-N32 %s
 // MIPS-N32: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "n32" "-mno-shared" "-call_nonpic" "-EB"
 //
@@ -45,8 +60,13 @@
 //
 // RUN: %clang -target mips64el-linux-gnu -mabi=64 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS64R2-EL-AS-PIC %s
+// MIPS64R2-EL-AS-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL" "-KPIC"
+//
+// RUN: %clang -target mips64el-linux-gnu -mabi=64 -### \
+// RUN:   -no-integrated-as -c %s -fno-pic 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS64R2-EL-AS %s
-// MIPS64R2-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-KPIC" "-EL"
+// MIPS64R2-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-EL"
 //
 // RUN: %clang -target mips-linux-gnu -march=mips32r2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
@@ -60,8 +80,13 @@
 //
 // RUN: %clang -target mips64-linux-gnu -march=octeon -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-OCTEON-PIC %s
+// MIPS-OCTEON-PIC: as{{(.exe)?}}" "-march" "octeon" "-mabi" "64" "-EB" "-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -march=octeon -### \
+// RUN:   -no-integrated-as -c %s -fno-pic 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-OCTEON %s
-// MIPS-OCTEON: as{{(.exe)?}}" "-march" "octeon" "-mabi" "64" "-mno-shared" "-KPIC" "-EB"
+// MIPS-OCTEON: as{{(.exe)?}}" "-march" "octeon" "-mabi" "64" "-mno-shared" "-EB"
 //
 // RUN: %clang -target mips-linux-gnu -mips1 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
@@ -115,28 +140,48 @@
 //
 // RUN: %clang -target mips64-linux-gnu -mips64 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64-PIC %s
+// MIPS-ALIAS-64-PIC: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB" "-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -mips64 -### \
+// RUN:   -no-integrated-as -c -fno-pic %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64 %s
-// MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-mno-shared" "-KPIC" "-EB"
+// MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-mno-shared" "-EB"
 //
 // 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" "-mno-shared" "-KPIC" "-EB"
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R2-PIC %s
+// MIPS-ALIAS-64R2-PIC: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB" "-KPIC"
 //
 // RUN: %clang -target mips64-linux-gnu -mips64r3 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R3-PIC %s
+// MIPS-ALIAS-64R3-PIC: as{{(.exe)?}}" "-march" "mips64r3" "-mabi" "64" "-EB" "-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -mips64r3 -### \
+// RUN:   -no-integrated-as -c %s -fno-pic 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R3 %s
-// MIPS-ALIAS-64R3: as{{(.exe)?}}" "-march" "mips64r3" "-mabi" "64" "-mno-shared" "-KPIC" "-EB"
+// MIPS-ALIAS-64R3: as{{(.exe)?}}" "-march" "mips64r3" "-mabi" "64" "-mno-shared" "-EB"
 //
 // RUN: %clang -target mips64-linux-gnu -mips64r5 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R5-PIC %s
+// MIPS-ALIAS-64R5-PIC: as{{(.exe)?}}" "-march" "mips64r5" "-mabi" "64" "-EB" "-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -mips64r5 -### \
+// RUN:   -no-integrated-as -c %s -fno-pic 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R5 %s
-// MIPS-ALIAS-64R5: as{{(.exe)?}}" "-march" "mips64r5" "-mabi" "64" "-mno-shared" "-KPIC" "-EB"
+// MIPS-ALIAS-64R5: as{{(.exe)?}}" "-march" "mips64r5" "-mabi" "64" "-mno-shared" "-EB"
 //
 // RUN: %clang -target mips64-linux-gnu -mips64r6 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R6-PIC %s
+// MIPS-ALIAS-64R6-PIC: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-EB" "-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -mips64r6 -### \
+// RUN:   -no-integrated-as -c %s -fno-pic 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R6 %s
-// MIPS-ALIAS-64R6: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-mno-shared" "-KPIC" "-EB"
+// MIPS-ALIAS-64R6: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-mno-shared" "-EB"
 //
 // RUN: %clang -target mips-linux-gnu -mno-mips16 -mips16 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
@@ -234,15 +279,15 @@
 //
 // 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" "-mno-shared" "-KPIC" "-EB"
+// MIPS3-EB-AS: as{{(.exe)?}}" "-march" "mips3" "-mabi" "64" "-EB" "-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" "-mno-shared" "-KPIC" "-EB"
+// MIPS4-EB-AS: as{{(.exe)?}}" "-march" "mips4" "-mabi" "64" "-EB" "-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" "-mno-shared" "-KPIC" "-EB"
+// MIPS5-EB-AS: as{{(.exe)?}}" "-march" "mips5" "-mabi" "64" "-EB" "-KPIC"
 //
 // RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips32 \
 // RUN:   2>&1 | FileCheck -check-prefix=MIPS32-EB-AS %s
@@ -256,11 +301,11 @@
 //
 // 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" "-mno-shared" "-KPIC" "-EB"
+// MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB" "-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" "-mno-shared" "-KPIC" "-EB"
+// MIPS64R6-EB-AS: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-EB" "-KPIC"
 //
 // RUN: %clang -target mips-linux-gnu -### -no-integrated-as -msoft-float -mhard-float -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=HARDFLOAT --implicit-check-not=-msoft-float %s
diff --git a/test/Driver/mips-mti-linux.c b/test/Driver/mips-mti-linux.c
index 4835d79..91a63e2 100644
--- a/test/Driver/mips-mti-linux.c
+++ b/test/Driver/mips-mti-linux.c
@@ -8,7 +8,7 @@
 
 // = Big-endian, mips32r2, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips-mti-linux -mips32r2 -mhard-float -rtlib=platform \
+// RUN:     --target=mips-mti-linux -mips32r2 -mhard-float -rtlib=platform -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/mips_mti_linux/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-BE-HF-32R2 %s
 //
@@ -26,7 +26,7 @@
 
 // = Little-endian, mips32r2, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips-mti-linux -mips32r2 -EL -mhard-float -rtlib=platform \
+// RUN:     --target=mips-mti-linux -mips32r2 -EL -mhard-float -rtlib=platform -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/mips_mti_linux/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-LE-HF-32R2 %s
 //
diff --git a/test/Driver/msc-version.c b/test/Driver/msc-version.c
index 7e71b9c..ec87e4d 100644
--- a/test/Driver/msc-version.c
+++ b/test/Driver/msc-version.c
@@ -63,4 +63,4 @@
 
 // CHECK-MS-EXTENSIONS: _MSC_BUILD 1
 // CHECK-MS-EXTENSIONS: _MSC_FULL_VER {{.+}}
-// CHECK-MS-EXTENSIONS: _MSC_VER {{..}}00
+// CHECK-MS-EXTENSIONS: _MSC_VER {{....}}
diff --git a/test/Driver/netbsd.c b/test/Driver/netbsd.c
index 1a87d8e..06b5ead 100644
--- a/test/Driver/netbsd.c
+++ b/test/Driver/netbsd.c
@@ -23,6 +23,12 @@
 // RUN: %clang -no-canonical-prefixes -target aarch64--netbsd7.0.0 \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=AARCH64-7 %s
+// RUN: %clang -no-canonical-prefixes -target aarch64_be--netbsd \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=AARCH64_BE %s
+// RUN: %clang -no-canonical-prefixes -target aarch64_be--netbsd7.0.0 \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=AARCH64_BE-7 %s
 // RUN: %clang -no-canonical-prefixes -target arm--netbsd-eabi \
 // RUN: -no-integrated-as --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=ARM %s
@@ -84,6 +90,12 @@
 // RUN: %clang -no-canonical-prefixes -target aarch64--netbsd7.0.0 -static \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=S-AARCH64-7 %s
+// RUN: %clang -no-canonical-prefixes -target aarch64_be--netbsd -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-AARCH64_BE %s
+// RUN: %clang -no-canonical-prefixes -target aarch64_be--netbsd7.0.0 -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-AARCH64_BE-7 %s
 // RUN: %clang -no-canonical-prefixes -target arm--netbsd-eabi -static \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=S-ARM %s
@@ -114,6 +126,8 @@
 // RUN: %clang -no-canonical-prefixes -target powerpc64--netbsd -static \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=S-POWERPC64 %s
+// RUN: %clang -target x86_64--netbsd -pthread -dM -E %s \
+// RUN: | FileCheck -check-prefix=PTHREAD %s
 
 // STATIC: ld{{.*}}" "--eh-frame-hdr"
 // STATIC-NOT: "-pie"
@@ -171,6 +185,18 @@
 // AARCH64-7:  "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
 // AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
+// AARCH64_BE: clang{{.*}}" "-cc1" "-triple" "aarch64_be--netbsd"
+// AARCH64_BE: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// AARCH64_BE: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// AARCH64_BE: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// AARCH64_BE: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// AARCH64_BE-7: clang{{.*}}" "-cc1" "-triple" "aarch64_be--netbsd7.0.0"
+// AARCH64_BE-7: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// AARCH64_BE-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// AARCH64_BE-7:  "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// AARCH64_BE-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
 // ARM: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd-eabi"
 // ARM: as{{.*}}" "-mcpu=arm926ej-s" "-o"
 // ARM: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
@@ -311,6 +337,18 @@
 // S-AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
 // S-AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
+// S-AARCH64_BE: clang{{.*}}" "-cc1" "-triple" "aarch64_be--netbsd"
+// S-AARCH64_BE: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-AARCH64_BE: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-AARCH64_BE: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-AARCH64_BE: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-AARCH64_BE-7: clang{{.*}}" "-cc1" "-triple" "aarch64_be--netbsd7.0.0"
+// S-AARCH64_BE-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-AARCH64_BE-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-AARCH64_BE-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-AARCH64_BE-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
 // S-ARM: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd-eabi"
 // S-ARM: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
 // S-ARM: "-m" "armelf_nbsd_eabi"
@@ -391,3 +429,7 @@
 // S-POWERPC64: "{{.*}}/usr/lib{{/|\\\\}}crti.o"
 // S-POWERPC64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
 // S-POWERPC64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// PTHREAD-NOT: _POSIX_THREADS
+// PTHREAD:     _REENTRANT
+// PTHREAD-NOT: _POSIX_THREADS
diff --git a/test/Driver/netbsd.cpp b/test/Driver/netbsd.cpp
index 104d03e..e9b1759 100644
--- a/test/Driver/netbsd.cpp
+++ b/test/Driver/netbsd.cpp
@@ -19,6 +19,12 @@
 // RUN: %clangxx -no-canonical-prefixes -target aarch64--netbsd7.0.0 \
 // RUN: -stdlib=platform --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=AARCH64-7 %s
+// RUN: %clangxx -no-canonical-prefixes -target aarch64_be--netbsd \
+// RUN: -stdlib=platform --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=AARCH64_BE %s
+// RUN: %clangxx -no-canonical-prefixes -target aarch64_be--netbsd7.0.0 \
+// RUN: -stdlib=platform --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=AARCH64_BE-7 %s
 // RUN: %clangxx -no-canonical-prefixes -target sparc--netbsd \
 // RUN: -stdlib=platform --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=SPARC %s
@@ -65,6 +71,12 @@
 // RUN: %clangxx -no-canonical-prefixes -target aarch64--netbsd7.0.0 -static \
 // RUN: -stdlib=platform --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=S-AARCH64-7 %s
+// RUN: %clangxx -no-canonical-prefixes -target aarch64_be--netbsd -static \
+// RUN: -stdlib=platform --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-AARCH64_BE %s
+// RUN: %clangxx -no-canonical-prefixes -target aarch64_be--netbsd7.0.0 -static \
+// RUN: -stdlib=platform --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-AARCH64_BE-7 %s
 // RUN: %clangxx -no-canonical-prefixes -target sparc--netbsd -static \
 // RUN: -stdlib=platform --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=S-SPARC %s
@@ -136,6 +148,20 @@
 // AARCH64-7: "-lm" "-lc"
 // AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
+// AARCH64_BE: clang{{.*}}" "-cc1" "-triple" "aarch64_be--netbsd"
+// AARCH64_BE: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// AARCH64_BE: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// AARCH64_BE: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc++"
+// AARCH64_BE: "-lm" "-lc"
+// AARCH64_BE: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// AARCH64_BE-7: clang{{.*}}" "-cc1" "-triple" "aarch64_be--netbsd7.0.0"
+// AARCH64_BE-7: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// AARCH64_BE-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// AARCH64_BE-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc++"
+// AARCH64_BE-7: "-lm" "-lc"
+// AARCH64_BE-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
 // SPARC: clang{{.*}}" "-cc1" "-triple" "sparc--netbsd"
 // SPARC: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
 // SPARC: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
@@ -241,6 +267,20 @@
 // S-AARCH64-7: "-lm" "-lc"
 // S-AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
+// S-AARCH64_BE: clang{{.*}}" "-cc1" "-triple" "aarch64_be--netbsd"
+// S-AARCH64_BE: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-AARCH64_BE: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-AARCH64_BE: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc++"
+// S-AARCH64_BE: "-lm" "-lc"
+// S-AARCH64_BE: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-AARCH64_BE-7: clang{{.*}}" "-cc1" "-triple" "aarch64_be--netbsd7.0.0"
+// S-AARCH64_BE-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-AARCH64_BE-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-AARCH64_BE-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc++"
+// S-AARCH64_BE-7: "-lm" "-lc"
+// S-AARCH64_BE-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
 // S-SPARC: clang{{.*}}" "-cc1" "-triple" "sparc--netbsd"
 // S-SPARC: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
 // S-SPARC: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
diff --git a/test/Driver/no-arc-exception-silence.m b/test/Driver/no-arc-exception-silence.m
new file mode 100644
index 0000000..c16b220
--- /dev/null
+++ b/test/Driver/no-arc-exception-silence.m
@@ -0,0 +1,2 @@
+// RUN: %clang -Werror -fobjc-arc -fobjc-arc-exceptions -fno-objc-arc -Xclang -verify -c -o /dev/null %s
+// expected-no-diagnostics
diff --git a/test/Driver/nostdlib.c b/test/Driver/nostdlib.c
index 7269312..a9ef665 100644
--- a/test/Driver/nostdlib.c
+++ b/test/Driver/nostdlib.c
@@ -13,12 +13,12 @@
 // In the presence of -nostdlib, the standard libraries should not be
 // passed down to link line
 // RUN: %clang -no-canonical-prefixes %s -### -Wno-liblto -o %t.o 2>&1 \
-// RUN:     -target i686-pc-linux-gnu -nostdlib --rtlib=compiler-rt \
+// RUN:     -target i686-pc-linux-gnu -nostdlib --rtlib=compiler-rt -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir -lclang_rt.builtins-i686 \
 // RUN:   | FileCheck --check-prefix=CHECK-LINUX-NOSTDLIB %s
 //
 // RUN: %clang -no-canonical-prefixes %s -### -Wno-liblto -o %t.o 2>&1 \
-// RUN:     -target i686-pc-linux-gnu --rtlib=compiler-rt -nostdlib \
+// RUN:     -target i686-pc-linux-gnu --rtlib=compiler-rt -nostdlib -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir -lclang_rt.builtins-i686 \
 // RUN:   | FileCheck --check-prefix=CHECK-LINUX-NOSTDLIB %s
 //
diff --git a/test/Driver/openbsd.c b/test/Driver/openbsd.c
index 95b9e6a..b4e2796 100644
--- a/test/Driver/openbsd.c
+++ b/test/Driver/openbsd.c
@@ -3,6 +3,12 @@
 // CHECK-LD: clang{{.*}}" "-cc1" "-triple" "i686-pc-openbsd"
 // CHECK-LD: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}crt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lgcc" "-lc" "-lgcc" "{{.*}}crtend.o"
 
+// Check for --eh-frame-hdr being passed with static linking
+// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -static %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-STATIC-EH %s
+// CHECK-LD-STATIC-EH: clang{{.*}}" "-cc1" "-triple" "i686-pc-openbsd"
+// CHECK-LD-STATIC-EH: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bstatic" "-o" "a.out" "{{.*}}rcrt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lgcc" "-lc" "-lgcc" "{{.*}}crtend.o"
+
 // RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -pg -pthread %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-PG %s
 // CHECK-PG: clang{{.*}}" "-cc1" "-triple" "i686-pc-openbsd"
@@ -67,3 +73,31 @@
 // CHECK-MIPS64-PIC: as{{.*}}" "-mabi" "64" "-EB" "-KPIC"
 // CHECK-MIPS64EL: as{{.*}}" "-mabi" "64" "-EL"
 // CHECK-MIPS64EL-PIC: as{{.*}}" "-mabi" "64" "-EL" "-KPIC"
+
+// Check linking against correct startup code when (not) using PIE
+// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd %s -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-PIE %s
+// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd %s -fno-pie %s -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-PIE %s
+// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -static %s -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-STATIC-PIE %s
+// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -static -fno-pie %s -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-STATIC-PIE %s
+// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -nopie %s -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-NOPIE %s
+// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -fno-pie -nopie %s -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-NOPIE %s
+// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -static -nopie %s -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-NOPIE %s
+// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -fno-pie -static -nopie %s -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-NOPIE %s
+// CHECK-PIE: "{{.*}}crt0.o"
+// CHECK-PIE-NOT: "-nopie"
+// CHECK-STATIC-PIE: "{{.*}}rcrt0.o"
+// CHECK-STATIC-PIE-NOT: "-nopie"
+// CHECK-NOPIE: "-nopie" "{{.*}}crt0.o"
+
+// Check ARM float ABI
+// RUN: %clang -target arm-unknown-openbsd -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM-FLOAT-ABI %s
+// CHECK-ARM-FLOAT-ABI: "-mfloat-abi" "soft"
diff --git a/test/Driver/ppc-abi.c b/test/Driver/ppc-abi.c
index 958fd77..cebc90d 100644
--- a/test/Driver/ppc-abi.c
+++ b/test/Driver/ppc-abi.c
@@ -24,7 +24,10 @@
 // RUN: %clang -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \
 // RUN:   -mabi=altivec | FileCheck -check-prefix=CHECK-ELFv2 %s
 
+// CHECK-ELFv1: "-mrelocation-model" "pic" "-pic-level" "2"
 // CHECK-ELFv1: "-target-abi" "elfv1"
+// CHECK-ELFv1-QPX: "-mrelocation-model" "pic" "-pic-level" "2"
 // CHECK-ELFv1-QPX: "-target-abi" "elfv1-qpx"
+// CHECK-ELFv2: "-mrelocation-model" "pic" "-pic-level" "2"
 // CHECK-ELFv2: "-target-abi" "elfv2"
 
diff --git a/test/Driver/prefixed-tools.c b/test/Driver/prefixed-tools.c
index cdd59da..63f7f29 100644
--- a/test/Driver/prefixed-tools.c
+++ b/test/Driver/prefixed-tools.c
@@ -1,8 +1,8 @@
-// RUN: %clang -### -B%S/Inputs/prefixed_tools_tree -o %t.o -no-integrated-as \
+// RUN: %clang -### -B%S/Inputs/prefixed_tools_tree -o %t.o -no-integrated-as -fuse-ld=ld \
 // RUN:        -target x86_64--linux %s 2>&1 | \
 // RUN: FileCheck --check-prefix=CHECK-M64 %s
 
-// RUN: %clang -### -B%S/Inputs/prefixed_tools_tree -o %t.o -no-integrated-as \
+// RUN: %clang -### -B%S/Inputs/prefixed_tools_tree -o %t.o -no-integrated-as -fuse-ld=ld \
 // RUN:        -m32 -target x86_64--linux %s 2>&1 | \
 // RUN: FileCheck --check-prefix=CHECK-M32 %s
 
diff --git a/test/Driver/r600-mcpu.cl b/test/Driver/r600-mcpu.cl
index 325e571..b99cac3 100644
--- a/test/Driver/r600-mcpu.cl
+++ b/test/Driver/r600-mcpu.cl
@@ -40,6 +40,8 @@
 // RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=carrizo %s -o - 2>&1 | FileCheck --check-prefix=CARRIZO-CHECK %s
 // RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=fiji %s -o - 2>&1 | FileCheck --check-prefix=FIJI-CHECK %s
 // RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=stoney %s -o - 2>&1 | FileCheck --check-prefix=STONEY-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx900 %s -o - 2>&1 | FileCheck --check-prefix=GFX900-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx901 %s -o - 2>&1 | FileCheck --check-prefix=GFX901-CHECK %s
 
 // R600-CHECK:  "-target-cpu" "r600"
 // RS880-CHECK: "-target-cpu" "rs880"
@@ -70,3 +72,5 @@
 // CARRIZO-CHECK: "-target-cpu" "carrizo"
 // FIJI-CHECK: "-target-cpu" "fiji"
 // STONEY-CHECK: "-target-cpu" "stoney"
+// GFX900-CHECK: "-target-cpu" "gfx900"
+// GFX901-CHECK: "-target-cpu" "gfx901"
diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c
index 91798b9..c4a6f43 100644
--- a/test/Driver/sanitizer-ld.c
+++ b/test/Driver/sanitizer-ld.c
@@ -1,7 +1,7 @@
 // Test sanitizers ld flags.
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux -fsanitize=address \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=address \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-LINUX %s
@@ -17,7 +17,7 @@
 // CHECK-ASAN-LINUX: "-ldl"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux -fsanitize=address -shared-libasan \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libasan \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
@@ -34,7 +34,7 @@
 // CHECK-SHARED-ASAN-LINUX-NOT: "--dynamic-list"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \
-// RUN:     -target i386-unknown-linux -fsanitize=address -shared-libasan \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libasan \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-DSO-SHARED-ASAN-LINUX %s
@@ -51,7 +51,7 @@
 // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "--dynamic-list"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-freebsd -fsanitize=address \
+// RUN:     -target i386-unknown-freebsd -fuse-ld=ld -fsanitize=address \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-FREEBSD %s
@@ -67,7 +67,7 @@
 // CHECK-ASAN-FREEBSD: "-lrt"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-freebsd -fsanitize=address \
+// RUN:     -target i386-unknown-freebsd -fuse-ld=ld -fsanitize=address \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-FREEBSD-LDL %s
@@ -76,7 +76,7 @@
 // CHECK-ASAN-FREEBSD-LDL-NOT: "-ldl"
 
 // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux -stdlib=platform -fsanitize=address \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -stdlib=platform -fsanitize=address \
 // RUN:     -resource-dir=%S/Inputs/empty_resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-LINUX-CXX %s
@@ -93,7 +93,7 @@
 // CHECK-ASAN-LINUX-CXX: "-ldl"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o /dev/null -fsanitize=address \
-// RUN:     -target i386-unknown-linux -stdlib=platform \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -stdlib=platform \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree -lstdc++ -static 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-LINUX-CXX-STATIC %s
 //
@@ -103,7 +103,7 @@
 // CHECK-ASAN-LINUX-CXX-STATIC: stdc++
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target arm-linux-gnueabi -fsanitize=address \
+// RUN:     -target arm-linux-gnueabi -fuse-ld=ld -fsanitize=address \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-ARM %s
 //
@@ -112,7 +112,7 @@
 // CHECK-ASAN-ARM: libclang_rt.asan-arm.a"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target armv7l-linux-gnueabi -fsanitize=address \
+// RUN:     -target armv7l-linux-gnueabi -fuse-ld=ld -fsanitize=address \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-ARMv7 %s
 //
@@ -121,7 +121,7 @@
 // CHECK-ASAN-ARMv7: libclang_rt.asan-arm.a"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target arm-linux-androideabi -fsanitize=address \
+// RUN:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=address \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID %s
 //
@@ -141,7 +141,7 @@
 // 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:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=address \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID-SHARED %s
@@ -152,7 +152,7 @@
 // CHECK-ASAN-ANDROID-SHARED-NOT: "-lpthread"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target sparcel-myriad-rtems-elf -fsanitize=address \
+// RUN:     -target sparcel-myriad-rtems-elf -fuse-ld=ld -fsanitize=address \
 // RUN:     --sysroot=%S/Inputs/basic_myriad_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-MYRIAD %s
 //
@@ -161,7 +161,7 @@
 // CHECK-ASAN-MYRIAD: libclang_rt.asan-sparcel.a"
 
 // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux -stdlib=platform -lstdc++ \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld -stdlib=platform -lstdc++ \
 // RUN:     -fsanitize=thread \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
@@ -180,7 +180,7 @@
 // CHECK-TSAN-LINUX-CXX: "-ldl"
 
 // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux -stdlib=platform -lstdc++ \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld -stdlib=platform -lstdc++ \
 // RUN:     -fsanitize=memory \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
@@ -199,7 +199,7 @@
 // CHECK-MSAN-LINUX-CXX: "-ldl"
 
 // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s
 // CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -220,7 +220,7 @@
 // CHECK-UBSAN-LINUX-LINK-CXX-NOT: "-lstdc++"
 
 // RUN: %clangxx -fsanitize=undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux -stdlib=platform \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -stdlib=platform \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-CXX %s
@@ -235,7 +235,7 @@
 // CHECK-UBSAN-LINUX-CXX: "-lpthread"
 
 // RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX %s
 // CHECK-ASAN-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -245,7 +245,7 @@
 // CHECK-ASAN-UBSAN-LINUX: "-lpthread"
 
 // RUN: %clangxx -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux -stdlib=platform \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -stdlib=platform \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX-CXX %s
 // CHECK-ASAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
@@ -256,7 +256,7 @@
 // CHECK-ASAN-UBSAN-LINUX-CXX: "-lpthread"
 
 // RUN: %clangxx -fsanitize=memory,undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-MSAN-UBSAN-LINUX-CXX %s
 // CHECK-MSAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
@@ -264,7 +264,7 @@
 // CHECK-MSAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
 
 // RUN: %clangxx -fsanitize=thread,undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-TSAN-UBSAN-LINUX-CXX %s
 // CHECK-TSAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
@@ -272,7 +272,7 @@
 // CHECK-TSAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
 
 // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:     -shared \
@@ -283,7 +283,7 @@
 // CHECK-UBSAN-LINUX-SHARED-NOT: libclang_rt.ubsan
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux -fsanitize=leak \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld -fsanitize=leak \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LSAN-LINUX %s
 //
@@ -295,7 +295,7 @@
 // CHECK-LSAN-LINUX: "-ldl"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:  -target x86_64-unknown-linux -fsanitize=leak -fsanitize-coverage=func \
+// RUN:  -target x86_64-unknown-linux -fuse-ld=ld -fsanitize=leak -fsanitize-coverage=func \
 // RUN:  --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LSAN-COV-LINUX %s
 //
@@ -308,7 +308,7 @@
 // CHECK-LSAN-COV-LINUX: "-ldl"
 
 // RUN: %clang -fsanitize=leak,address %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LSAN-ASAN-LINUX %s
 // CHECK-LSAN-ASAN-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -317,7 +317,7 @@
 // CHECK-LSAN-ASAN-LINUX-NOT: libclang_rt.lsan
 
 // RUN: %clang -fsanitize=address -fsanitize-coverage=func %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-COV-LINUX %s
 // CHECK-ASAN-COV-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -327,7 +327,7 @@
 // CHECK-ASAN-COV-LINUX: "-lpthread"
 
 // RUN: %clang -fsanitize=memory -fsanitize-coverage=func %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-MSAN-COV-LINUX %s
 // CHECK-MSAN-COV-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -337,7 +337,7 @@
 // CHECK-MSAN-COV-LINUX: "-lpthread"
 
 // RUN: %clang -fsanitize=dataflow -fsanitize-coverage=func %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-DFSAN-COV-LINUX %s
 // CHECK-DFSAN-COV-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -347,7 +347,7 @@
 // CHECK-DFSAN-COV-LINUX: "-lpthread"
 
 // RUN: %clang -fsanitize=undefined -fsanitize-coverage=func %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-COV-LINUX %s
 // CHECK-UBSAN-COV-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -356,7 +356,7 @@
 // CHECK-UBSAN-COV-LINUX: "-lpthread"
 
 // RUN: %clang -fsanitize-coverage=func %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-COV-LINUX %s
 // CHECK-COV-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -366,7 +366,7 @@
 
 // CFI by itself does not link runtime libraries.
 // RUN: %clang -fsanitize=cfi %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux -rtlib=platform \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld -rtlib=platform \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CFI-LINUX %s
 // CHECK-CFI-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -375,7 +375,7 @@
 // CFI with diagnostics links the UBSan runtime.
 // RUN: %clang -fsanitize=cfi -fno-sanitize-trap=cfi -fsanitize-recover=cfi \
 // RUN:     %s -### -o %t.o 2>&1\
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CFI-DIAG-LINUX %s
 // CHECK-CFI-DIAG-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -383,7 +383,7 @@
 
 // Cross-DSO CFI links the CFI runtime.
 // RUN: %clang -fsanitize=cfi -fsanitize-cfi-cross-dso %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CFI-CROSS-DSO-LINUX %s
 // CHECK-CFI-CROSS-DSO-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -393,7 +393,7 @@
 // Cross-DSO CFI with diagnostics links just the CFI runtime.
 // RUN: %clang -fsanitize=cfi -fsanitize-cfi-cross-dso %s -### -o %t.o 2>&1 \
 // RUN:     -fno-sanitize-trap=cfi -fsanitize-recover=cfi \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CFI-CROSS-DSO-DIAG-LINUX %s
 // CHECK-CFI-CROSS-DSO-DIAG-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -402,7 +402,7 @@
 
 // RUN: %clangxx -fsanitize=address %s -### -o %t.o 2>&1 \
 // RUN:     -mmacosx-version-min=10.6 \
-// RUN:     -target x86_64-apple-darwin13.4.0 -stdlib=platform \
+// RUN:     -target x86_64-apple-darwin13.4.0 -fuse-ld=ld -stdlib=platform \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-DARWIN106-CXX %s
 // CHECK-ASAN-DARWIN106-CXX: "{{.*}}ld{{(.exe)?}}"
@@ -410,18 +410,20 @@
 // CHECK-ASAN-DARWIN106-CXX-NOT: -lc++abi
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux -fsanitize=safe-stack \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld -fsanitize=safe-stack \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-SAFESTACK-LINUX %s
 //
 // CHECK-SAFESTACK-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
 // CHECK-SAFESTACK-LINUX-NOT: "-lc"
+// CHECK-SAFESTACK-LINUX-NOT: whole-archive
 // CHECK-SAFESTACK-LINUX: libclang_rt.safestack-x86_64.a"
+// CHECK-SAFESTACK-LINUX: "-u" "__safestack_init"
 // CHECK-SAFESTACK-LINUX: "-lpthread"
 // CHECK-SAFESTACK-LINUX: "-ldl"
 
 // RUN: %clang -fsanitize=cfi -fsanitize-stats %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CFI-STATS-LINUX %s
 // CHECK-CFI-STATS-LINUX: "{{.*}}ld{{(.exe)?}}"
@@ -430,7 +432,7 @@
 // CHECK-CFI-STATS-LINUX: "{{[^"]*}}libclang_rt.stats-x86_64.a"
 
 // RUN: %clang -fsanitize=cfi -fsanitize-stats %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-apple-darwin \
+// RUN:     -target x86_64-apple-darwin -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CFI-STATS-DARWIN %s
 // CHECK-CFI-STATS-DARWIN: "{{.*}}ld{{(.exe)?}}"
@@ -454,7 +456,7 @@
 // CHECK-CFI-STATS-WIN32: "--linker-option=/include:___sanitizer_stats_register"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target arm-linux-androideabi -fsanitize=safe-stack \
+// RUN:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=safe-stack \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-SAFESTACK-ANDROID-ARM %s
 //
@@ -462,7 +464,7 @@
 // CHECK-SAFESTACK-ANDROID-ARM-NOT: libclang_rt.safestack
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o -shared 2>&1 \
-// RUN:     -target arm-linux-androideabi -fsanitize=safe-stack \
+// RUN:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=safe-stack \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-SAFESTACK-SHARED-ANDROID-ARM %s
 //
@@ -470,7 +472,7 @@
 // CHECK-SAFESTACK-SHARED-ANDROID-ARM-NOT: libclang_rt.safestack
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target aarch64-linux-android -fsanitize=safe-stack \
+// RUN:     -target aarch64-linux-android -fuse-ld=ld -fsanitize=safe-stack \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-SAFESTACK-ANDROID-AARCH64 %s
 //
@@ -478,7 +480,7 @@
 // CHECK-SAFESTACK-ANDROID-AARCH64-NOT: libclang_rt.safestack
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target arm-linux-androideabi -fsanitize=cfi \
+// RUN:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=cfi \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CFI-ANDROID %s
 //
@@ -487,7 +489,7 @@
 // CHECK-CFI-ANDROID-NOT: __cfi_check
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target arm-linux-androideabi -fsanitize=cfi \
+// RUN:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=cfi \
 // RUN:     -fsanitize-cfi-cross-dso \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-CROSSDSO-CFI-ANDROID %s
@@ -498,31 +500,31 @@
 // CHECK-CROSSDSO-CFI-ANDROID-NOT: libclang_rt.cfi
 
 // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-scei-ps4 \
+// RUN:     -target x86_64-scei-ps4 -fuse-ld=ld \
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-PS4 %s
 // CHECK-UBSAN-PS4: "{{.*}}ld{{(.gold)?(.exe)?}}"
 // CHECK-UBSAN-PS4: -lSceDbgUBSanitizer_stub_weak
 
 // RUN: %clang -fsanitize=address %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-scei-ps4 \
+// RUN:     -target x86_64-scei-ps4 -fuse-ld=ld \
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-PS4 %s
 // CHECK-ASAN-PS4: "{{.*}}ld{{(.gold)?(.exe)?}}"
 // CHECK-ASAN-PS4: -lSceDbgAddressSanitizer_stub_weak
 
 // RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-scei-ps4 \
+// RUN:     -target x86_64-scei-ps4 -fuse-ld=ld \
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-AUBSAN-PS4 %s
 // CHECK-AUBSAN-PS4: "{{.*}}ld{{(.gold)?(.exe)?}}"
 // CHECK-AUBSAN-PS4: -lSceDbgAddressSanitizer_stub_weak
 
 // RUN: %clang -fsanitize=efficiency-cache-frag %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:   | FileCheck --check-prefix=CHECK-ESAN-LINUX %s
 // RUN: %clang -fsanitize=efficiency-working-set %s -### -o %t.o 2>&1 \
-// RUN:     -target x86_64-unknown-linux \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
 // RUN:   | FileCheck --check-prefix=CHECK-ESAN-LINUX %s
 //
 // CHECK-ESAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
diff --git a/test/Driver/unknown-std.S b/test/Driver/unknown-std.S
new file mode 100644
index 0000000..ecb6a9e
--- /dev/null
+++ b/test/Driver/unknown-std.S
@@ -0,0 +1,2 @@
+// RUN: %clang -std=c++11 %s -E -o /dev/null 2>&1 | FileCheck %s --allow-empty
+// CHECK-NOT: error
diff --git a/test/Driver/unknown-std.c b/test/Driver/unknown-std.c
new file mode 100644
index 0000000..ba3035f
--- /dev/null
+++ b/test/Driver/unknown-std.c
@@ -0,0 +1,34 @@
+// This file checks output given when processing C/ObjC files.
+// When user selects invalid language standard
+// print out supported values with short description.
+
+// RUN: not %clang %s -std=foobar -c 2>&1 | \
+// RUN: FileCheck --match-full-lines %s
+
+// CHECK: error: invalid value 'foobar' in '-std=foobar'
+// CHECK-NEXT: note: use 'c89' for 'ISO C 1990' standard
+// CHECK-NEXT: note: use 'c90' for 'ISO C 1990' standard
+// CHECK-NEXT: note: use 'iso9899:1990' for 'ISO C 1990' standard
+// CHECK-NEXT: note: use 'iso9899:199409' for 'ISO C 1990 with amendment 1' standard
+// CHECK-NEXT: note: use 'gnu89' for 'ISO C 1990 with GNU extensions' standard
+// CHECK-NEXT: note: use 'gnu90' for 'ISO C 1990 with GNU extensions' standard
+// CHECK-NEXT: note: use 'c99' for 'ISO C 1999' standard
+// CHECK-NEXT: note: use 'c9x' for 'ISO C 1999' standard
+// CHECK-NEXT: note: use 'iso9899:1999' for 'ISO C 1999' standard
+// CHECK-NEXT: note: use 'iso9899:199x' for 'ISO C 1999' standard
+// CHECK-NEXT: note: use 'gnu99' for 'ISO C 1999 with GNU extensions' standard
+// CHECK-NEXT: note: use 'gnu9x' for 'ISO C 1999 with GNU extensions' standard
+// CHECK-NEXT: note: use 'c11' for 'ISO C 2011' standard
+// CHECK-NEXT: note: use 'c1x' for 'ISO C 2011' standard
+// CHECK-NEXT: note: use 'iso9899:2011' for 'ISO C 2011' standard
+// CHECK-NEXT: note: use 'iso9899:201x' for 'ISO C 2011' standard
+// CHECK-NEXT: note: use 'gnu11' for 'ISO C 2011 with GNU extensions' standard
+// CHECK-NEXT: note: use 'gnu1x' for 'ISO C 2011 with GNU extensions' standard
+// CHECK-NEXT: note: use 'cl' for 'OpenCL 1.0' standard
+// CHECK-NEXT: note: use 'cl1.1' for 'OpenCL 1.1' standard
+// CHECK-NEXT: note: use 'cl1.2' for 'OpenCL 1.2' standard
+// CHECK-NEXT: note: use 'cl2.0' for 'OpenCL 2.0' standard
+
+// Make sure that no other output is present.
+// CHECK-NOT: {{^.+$}}
+
diff --git a/test/Driver/unknown-std.cl b/test/Driver/unknown-std.cl
new file mode 100644
index 0000000..b87a8c8
--- /dev/null
+++ b/test/Driver/unknown-std.cl
@@ -0,0 +1,16 @@
+// This file checks output given when processing OpenCL files.
+// When user selects invalid language standard
+// print out supported values with short description.
+
+// RUN: not %clang %s -std=foobar -c 2>&1 | \
+// RUN: FileCheck --match-full-lines %s
+
+// CHECK: error: invalid value 'foobar' in '-std=foobar'
+// CHECK-NEXT: note: use 'cl' for 'OpenCL 1.0' standard
+// CHECK-NEXT: note: use 'cl1.1' for 'OpenCL 1.1' standard
+// CHECK-NEXT: note: use 'cl1.2' for 'OpenCL 1.2' standard
+// CHECK-NEXT: note: use 'cl2.0' for 'OpenCL 2.0' standard
+
+// Make sure that no other output is present.
+// CHECK-NOT: {{^.+$}}
+
diff --git a/test/Driver/unknown-std.cpp b/test/Driver/unknown-std.cpp
new file mode 100644
index 0000000..faeb2cb
--- /dev/null
+++ b/test/Driver/unknown-std.cpp
@@ -0,0 +1,26 @@
+// This file checks output given when processing C++/ObjC++ files.
+// When user selects invalid language standard
+// print out supported values with short description.
+
+// RUN: not %clang %s -std=foobar -c 2>&1 | \
+// RUN: FileCheck --match-full-lines %s
+
+// CHECK: error: invalid value 'foobar' in '-std=foobar'
+// CHECK-NEXT: note: use 'c++98' for 'ISO C++ 1998 with amendments' standard
+// CHECK-NEXT: note: use 'c++03' for 'ISO C++ 1998 with amendments' standard
+// CHECK-NEXT: note: use 'gnu++98' for 'ISO C++ 1998 with amendments and GNU extensions' standard
+// CHECK-NEXT: note: use 'c++0x' for 'ISO C++ 2011 with amendments' standard
+// CHECK-NEXT: note: use 'c++11' for 'ISO C++ 2011 with amendments' standard
+// CHECK-NEXT: note: use 'gnu++0x' for 'ISO C++ 2011 with amendments and GNU extensions' standard
+// CHECK-NEXT: note: use 'gnu++11' for 'ISO C++ 2011 with amendments and GNU extensions' standard
+// CHECK-NEXT: note: use 'c++1y' for 'ISO C++ 2014 with amendments' standard
+// CHECK-NEXT: note: use 'c++14' for 'ISO C++ 2014 with amendments' standard
+// CHECK-NEXT: note: use 'gnu++1y' for 'ISO C++ 2014 with amendments and GNU extensions' standard
+// CHECK-NEXT: note: use 'gnu++14' for 'ISO C++ 2014 with amendments and GNU extensions' standard
+// CHECK-NEXT: note: use 'c++1z' for 'Working draft for ISO C++ 2017' standard
+// CHECK-NEXT: note: use 'gnu++1z' for 'Working draft for ISO C++ 2017 with GNU extensions' standard
+// CHECK-NEXT: note: use 'cuda' for 'NVIDIA CUDA(tm)' standard
+
+// Make sure that no other output is present.
+// CHECK-NOT: {{^.+$}}
+
diff --git a/test/Driver/windows-cross.c b/test/Driver/windows-cross.c
index 84ef2df..5a2fe52 100644
--- a/test/Driver/windows-cross.c
+++ b/test/Driver/windows-cross.c
@@ -1,34 +1,34 @@
-// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -stdlib=libstdc++ -rtlib=platform -o /dev/null %s 2>&1 \
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -stdlib=libstdc++ -rtlib=platform -o /dev/null %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-BASIC
 
 // CHECK-BASIC: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/crtbegin.obj" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/gcc" "{{.*}}.o" "-lmsvcrt" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
 
-// RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -rtlib=compiler-rt -stdlib=libstdc++ -o /dev/null %s 2>&1 \
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libstdc++ -o /dev/null %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-RTLIB
 
 // CHECK-RTLIB: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/crtbegin.obj" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/gcc" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
 
-// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -rtlib=compiler-rt -stdlib=libc++ -o /dev/null %s 2>&1 \
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libc++ -o /dev/null %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-C-LIBCXX
 
 // CHECK-C-LIBCXX: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/crtbegin.obj" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
 
-// RUN: %clangxx -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -rtlib=compiler-rt -stdlib=libc++ -o /dev/null %s 2>&1 \
+// RUN: %clangxx -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libc++ -o /dev/null %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-LIBCXX
 
 // CHECK-LIBCXX: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/crtbegin.obj" "{{.*}}.o" "-lc++" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
 
-// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -shared -rtlib=compiler-rt -stdlib=libc++ -o shared.dll %s 2>&1 \
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -o shared.dll %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-SHARED
 
 // CHECK-SHARED: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/crtbeginS.obj" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
 
-// RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -shared -rtlib=compiler-rt -stdlib=libc++ -nostartfiles -o shared.dll %s 2>&1 \
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -nostartfiles -o shared.dll %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-NOSTARTFILES
 
 // CHECK-NOSTARTFILES: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
 
-// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -shared -rtlib=compiler-rt -stdlib=libc++ -nostartfiles -nodefaultlibs -o shared.dll %s 2>&1 \
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -nostartfiles -nodefaultlibs -o shared.dll %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-STANDALONE
 
 // CHECK-STANDALONE: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o"
diff --git a/test/Driver/windows-pic.cpp b/test/Driver/windows-pic.cpp
new file mode 100644
index 0000000..3b77a7c
--- /dev/null
+++ b/test/Driver/windows-pic.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang -### -target i686-windows -fPIC %s 2>&1 | FileCheck -check-prefix CHECK-PIC-ERROR %s
+// RUN: %clang -### -target i686-windows -fpic %s 2>&1 | FileCheck -check-prefix CHECK-pic-ERROR %s
+// RUN: %clang -### -target i686-windows -fPIE %s 2>&1 | FileCheck -check-prefix CHECK-PIE-ERROR %s
+// RUN: %clang -### -target i686-windows -fpie %s 2>&1 | FileCheck -check-prefix CHECK-pie-ERROR %s
+// RUN: %clang -### -target i686-windows -fPIC -fno-pic %s
+// RUN: %clang -### -target i686-windows -Fpic -fno-pic %s
+// RUN: %clang -### -target i686-windows -fPIE -fno-pie %s
+// RUN: %clang -### -target i686-windows -fpie -fno-pie %s
+
+// RUN: %clang -### -target i686-windows-itanium -fPIC %s 2>&1 | FileCheck -check-prefix CHECK-PIC-ERROR %s
+// RUN: %clang -### -target i686-windows-itanium -fpic %s 2>&1 | FileCheck -check-prefix CHECK-pic-ERROR %s
+// RUN: %clang -### -target i686-windows-itanium -fPIE %s 2>&1 | FileCheck -check-prefix CHECK-PIE-ERROR %s
+// RUN: %clang -### -target i686-windows-itanium -fpie %s 2>&1 | FileCheck -check-prefix CHECK-pie-ERROR %s
+// RUN: %clang -### -target i686-windows-itanium -fPIC -fno-pic %s
+// RUN: %clang -### -target i686-windows-itanium -Fpic -fno-pic %s
+// RUN: %clang -### -target i686-windows-itanium -fPIE -fno-pie %s
+// RUN: %clang -### -target i686-windows-itanium -fpie -fno-pie %s
+
+// RUN: %clang -### -target i686-windows-gnu -fPIC %s 2>&1 | FileCheck -check-prefix CHECK-PIC-ERROR %s
+// RUN: %clang -### -target i686-windows-gnu -fpic %s 2>&1 | FileCheck -check-prefix CHECK-pic-ERROR %s
+// RUN: %clang -### -target i686-windows-gnu -fPIE %s 2>&1 | FileCheck -check-prefix CHECK-PIE-ERROR %s
+// RUN: %clang -### -target i686-windows-gnu -fpie %s 2>&1 | FileCheck -check-prefix CHECK-pie-ERROR %s
+// RUN: %clang -### -target i686-windows-gnu -fPIC -fno-pic %s
+// RUN: %clang -### -target i686-windows-gnu -Fpic -fno-pic %s
+// RUN: %clang -### -target i686-windows-gnu -fPIE -fno-pie %s
+// RUN: %clang -### -target i686-windows-gnu -fpie -fno-pie %s
+
+// RUN: %clang -### -target x86_64-windows -fPIC %s 2>&1 | FileCheck -check-prefix CHECK-PIC-ERROR %s
+// RUN: %clang -### -target x86_64-windows -fpic %s 2>&1 | FileCheck -check-prefix CHECK-pic-ERROR %s
+// RUN: %clang -### -target x86_64-windows -fPIE %s 2>&1 | FileCheck -check-prefix CHECK-PIE-ERROR %s
+// RUN: %clang -### -target x86_64-windows -fpie %s 2>&1 | FileCheck -check-prefix CHECK-pie-ERROR %s
+// RUN: %clang -### -target x86_64-windows -fPIC -fno-pic %s
+// RUN: %clang -### -target x86_64-windows -Fpic -fno-pic %s
+// RUN: %clang -### -target x86_64-windows -fPIE -fno-pie %s
+// RUN: %clang -### -target x86_64-windows -fpie -fno-pie %s
+
+// RUN: %clang -### -target x86_64-windows-itanium -fPIC %s 2>&1 | FileCheck -check-prefix CHECK-PIC-ERROR %s
+// RUN: %clang -### -target x86_64-windows-itanium -fpic %s 2>&1 | FileCheck -check-prefix CHECK-pic-ERROR %s
+// RUN: %clang -### -target x86_64-windows-itanium -fPIE %s 2>&1 | FileCheck -check-prefix CHECK-PIE-ERROR %s
+// RUN: %clang -### -target x86_64-windows-itanium -fpie %s 2>&1 | FileCheck -check-prefix CHECK-pie-ERROR %s
+// RUN: %clang -### -target x86_64-windows-itanium -fPIC -fno-pic %s
+// RUN: %clang -### -target x86_64-windows-itanium -Fpic -fno-pic %s
+// RUN: %clang -### -target x86_64-windows-itanium -fPIE -fno-pie %s
+// RUN: %clang -### -target x86_64-windows-itanium -fpie -fno-pie %s
+
+// RUN: %clang -### -target x86_64-windows-gnu -fPIC %s 2>&1 | FileCheck -check-prefix CHECK-PIC-ERROR %s
+// RUN: %clang -### -target x86_64-windows-gnu -fpic %s 2>&1 | FileCheck -check-prefix CHECK-pic-ERROR %s
+// RUN: %clang -### -target x86_64-windows-gnu -fPIE %s 2>&1 | FileCheck -check-prefix CHECK-PIE-ERROR %s
+// RUN: %clang -### -target x86_64-windows-gnu -fpie %s 2>&1 | FileCheck -check-prefix CHECK-pie-ERROR %s
+// RUN: %clang -### -target x86_64-windows-gnu -fPIC -fno-pic %s
+// RUN: %clang -### -target x86_64-windows-gnu -Fpic -fno-pic %s
+// RUN: %clang -### -target x86_64-windows-gnu -fPIE -fno-pie %s
+// RUN: %clang -### -target x86_64-windows-gnu -fpie -fno-pie %s
+
+// CHECK-PIC-ERROR: unsupported option '-fPIC' for target '{{.*}}
+// CHECK-pic-ERROR: unsupported option '-fpic' for target '{{.*}}
+// CHECK-PIE-ERROR: unsupported option '-fPIE' for target '{{.*}}
+// CHECK-pie-ERROR: unsupported option '-fpie' for target '{{.*}}
+
diff --git a/test/Driver/x86-march.c b/test/Driver/x86-march.c
index fd6e30b..b12bf40 100644
--- a/test/Driver/x86-march.c
+++ b/test/Driver/x86-march.c
@@ -36,6 +36,30 @@
 // RUN:   | FileCheck %s -check-prefix=broadwell
 // broadwell: "-target-cpu" "broadwell"
 //
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=skylake 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=skylake
+// skylake: "-target-cpu" "skylake"
+//
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=skylake-avx512 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=skylake-avx512
+// skylake-avx512: "-target-cpu" "skylake-avx512"
+//
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=skx 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=skx
+// skx: "-target-cpu" "skx"
+//
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=knl 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=knl
+// knl: "-target-cpu" "knl"
+//
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=cannonlake 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=cannonlake
+// cannonlake: "-target-cpu" "cannonlake"
+//
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=lakemont 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=lakemont
+// lakemont: "-target-cpu" "lakemont"
+//
 // RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=bonnell 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=bonnell
 // bonnell: "-target-cpu" "bonnell"
@@ -103,3 +127,7 @@
 // RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=btver2 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=btver2
 // btver2: "-target-cpu" "btver2"
+//
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=znver1 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=znver1
+// znver1: "-target-cpu" "znver1"
diff --git a/test/Driver/x86-target-features.c b/test/Driver/x86-target-features.c
index ce35b2c..dc32f6c 100644
--- a/test/Driver/x86-target-features.c
+++ b/test/Driver/x86-target-features.c
@@ -49,3 +49,38 @@
 // RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-xsave -mno-xsaveopt -mno-xsavec -mno-xsaves %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-XSAVE %s
 // XSAVE: "-target-feature" "+xsave" "-target-feature" "+xsaveopt" "-target-feature" "+xsavec" "-target-feature" "+xsaves"
 // NO-XSAVE: "-target-feature" "-xsave" "-target-feature" "-xsaveopt" "-target-feature" "-xsavec" "-target-feature" "-xsaves"
+
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mclflushopt %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CLFLUSHOPT %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-clflushopt %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-CLFLUSHOPT %s
+// CLFLUSHOPT: "-target-feature" "+clflushopt"
+// NO-CLFLUSHOPT: "-target-feature" "-clflushopt"
+
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mclwb %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CLWB %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-clwb %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-CLWB %s
+// CLWB: "-target-feature" "+clwb"
+// NO-CLWB: "-target-feature" "-clwb"
+
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mmovbe %s -### -o %t.o 2>&1 | FileCheck -check-prefix=MOVBE %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-movbe %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-MOVBE %s
+// MOVBE: "-target-feature" "+movbe"
+// NO-MOVBE: "-target-feature" "-movbe"
+
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mmpx %s -### -o %t.o 2>&1 | FileCheck -check-prefix=MPX %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-mpx %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-MPX %s
+// MPX: "-target-feature" "+mpx"
+// NO-MPX: "-target-feature" "-mpx"
+
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -msgx %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SGX %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-sgx %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-SGX %s
+// SGX: "-target-feature" "+sgx"
+// NO-SGX: "-target-feature" "-sgx"
+
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mprefetchwt1 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=PREFETCHWT1 %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-prefetchwt1 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-PREFETCHWT1 %s
+// PREFETCHWT1: "-target-feature" "+prefetchwt1"
+// NO-PREFETCHWT1: "-target-feature" "-prefetchwt1"
+
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mclzero %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CLZERO %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-clzero %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-CLZERO %s
+// CLZERO: "-target-feature" "+clzero"
+// NO-CLZERO: "-target-feature" "-clzero"
diff --git a/test/FixIt/Inputs/nullability.h b/test/FixIt/Inputs/nullability.h
new file mode 100644
index 0000000..bdfa01e
--- /dev/null
+++ b/test/FixIt/Inputs/nullability.h
@@ -0,0 +1,27 @@
+int * _Nonnull forceNullabilityWarnings(void);
+
+void arrayParameter(int x[]); // expected-warning {{array parameter is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-3]]:27-[[@LINE-3]]:27}:"_Nullable"
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-4]]:27-[[@LINE-4]]:27}:"_Nonnull"
+
+void arrayParameterWithSize(int x[5]); // expected-warning {{array parameter is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-3]]:35-[[@LINE-3]]:35}:"_Nullable "
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-4]]:35-[[@LINE-4]]:35}:"_Nonnull "
+
+void arrayParameterWithStar(int x[*]); // expected-warning {{array parameter is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-3]]:35-[[@LINE-3]]:35}:"_Nullable "
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-4]]:35-[[@LINE-4]]:35}:"_Nonnull "
+
+
+// No fix-its on either the macro definition or instantiation.
+// CHECK-NOT: fix-it:"{{.*}}nullability.h":{[[@LINE+2]]
+// CHECK-NOT: fix-it:"{{.*}}nullability.h":{[[@LINE+2]]
+#define PTR(X) X *
+PTR(int) a; // expected-warning{{pointer is missing a nullability type specifier}}
+#undef PTR
diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp
index 686cc23..0b7fc62 100644
--- a/test/FixIt/fixit.cpp
+++ b/test/FixIt/fixit.cpp
@@ -1,8 +1,12 @@
-// RUN: %clang_cc1 -pedantic -Wall -Wno-comment -verify -fcxx-exceptions -x c++ %s
+// RUN: %clang_cc1 -pedantic -Wall -Wno-comment -verify -fcxx-exceptions -x c++ -std=c++98 %s
+// RUN: cp %s %t-98
+// RUN: not %clang_cc1 -pedantic -Wall -Wno-comment -fcxx-exceptions -fixit -x c++ -std=c++98 %t-98
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -Wno-comment -fcxx-exceptions -x c++ -std=c++98 %t-98
 // RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -x c++ -std=c++11 %s 2>&1 | FileCheck %s
-// RUN: cp %s %t
-// RUN: not %clang_cc1 -pedantic -Wall -Wno-comment -fcxx-exceptions -fixit -x c++ %t
-// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -Wno-comment -fcxx-exceptions -x c++ %t
+// RUN: %clang_cc1 -pedantic -Wall -Wno-comment -verify -fcxx-exceptions -x c++ -std=c++11 %s
+// RUN: cp %s %t-11
+// RUN: not %clang_cc1 -pedantic -Wall -Wno-comment -fcxx-exceptions -fixit -x c++ -std=c++11 %t-11
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -Wno-comment -fcxx-exceptions -x c++ -std=c++11 %t-11
 
 /* This is a test of the various code modification hints that are
    provided as part of warning or extension diagnostics. All of the
@@ -21,7 +25,11 @@
 
 template<int Value> struct CT { template<typename> struct Inner; }; // expected-note{{previous use is here}}
 
+// FIXME: In C++11 this gets 'expected unqualified-id' which fixit can't fix.
+// Probably parses as `CT<10> > 2 > ct;` rather than `CT<(10 >> 2)> ct;`.
+#if __cplusplus < 201103L
 CT<10 >> 2> ct; // expected-warning{{require parentheses}}
+#endif
 
 class C3 {
 public:
@@ -41,7 +49,11 @@
 };
 
 class B : public A {
+#if __cplusplus >= 201103L
+  A::foo; // expected-error{{ISO C++11 does not allow access declarations}}
+#else
   A::foo; // expected-warning{{access declarations are deprecated}}
+#endif
 };
 
 void f() throw(); // expected-note{{previous}}
@@ -285,8 +297,10 @@
     void (*p)() = &t<int>;
     (void)(&t<int>==p); // expected-error {{use '> ='}}
     (void)(&t<int>>=p); // expected-error {{use '> >'}}
+#if __cplusplus < 201103L
     (void)(&t<S<int>>>=p); // expected-error {{use '> >'}}
     (Shr)&t<S<int>>>>=p; // expected-error {{use '> >'}}
+#endif
 
     // FIXME: We correct this to '&t<int> > >= p;' not '&t<int> >>= p;'
     //(Shr)&t<int>>>=p;
@@ -395,3 +409,14 @@
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"{}"
 int use_czi = czi.a;
 
+namespace dotPointerDestructor {
+
+struct Bar {
+  ~Bar();
+};
+
+void bar(Bar *o) {
+  o.~Bar(); // expected-error {{member reference type 'dotPointerDestructor::Bar *' is a pointer; did you mean to use '->'}}
+}  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:5}:"->"
+
+}
diff --git a/test/FixIt/no-fixit.cpp b/test/FixIt/no-fixit.cpp
index 7e8e1fb..2dad28d 100644
--- a/test/FixIt/no-fixit.cpp
+++ b/test/FixIt/no-fixit.cpp
@@ -11,3 +11,15 @@
     (void)&i;
   }
 } x;
+
+namespace dotPointerDestructor {
+
+struct Bar {
+  ~Bar() = delete;
+};
+
+void bar(Bar *o) {
+  o.~Bar(); // no fixit
+}
+
+}
diff --git a/test/FixIt/nullability.mm b/test/FixIt/nullability.mm
index 2449066..815c844 100644
--- a/test/FixIt/nullability.mm
+++ b/test/FixIt/nullability.mm
@@ -1,59 +1,69 @@
-// RUN: %clang_cc1 -fsyntax-only -fblocks -std=gnu++11 -verify %s
-// RUN: not %clang_cc1 -fdiagnostics-parseable-fixits -fblocks -std=gnu++11 %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -fblocks -std=gnu++11 -I %S/Inputs -verify %s
+// RUN: not %clang_cc1 -fdiagnostics-parseable-fixits -fblocks -std=gnu++11 -I %S/Inputs %s >%t.txt 2>&1
+// RUN: FileCheck %s < %t.txt
+// RUN: FileCheck %S/Inputs/nullability.h < %t.txt
+
+#include "nullability.h"
 
 #pragma clang assume_nonnull begin
 
 extern void *array[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull "
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull "
 
 extern void* array2[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" _Nonnull"
 
 extern void *nestedArray[2][3]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull "
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull "
+
+// No fix-its on either the macro definition or instantiation.
+// CHECK-NOT: fix-it:"{{.*}}nullability.mm":{[[@LINE+2]]
+// CHECK-NOT: fix-it:"{{.*}}nullability.mm":{[[@LINE+2]]
+#define PTR(X) X *
+extern PTR(void) array[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
 
 
 typedef const void *CFTypeRef;
 
 extern CFTypeRef typedefArray[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull"
 
 
 extern void *&ref; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
 
 extern void * &ref2; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
 
 extern void *&&ref3; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
 
 extern void * &&ref4; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
 
 extern void *(&arrayRef)[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
 
 extern void * (&arrayRef2)[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
 
 extern CFTypeRef &typedefRef; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull"
 extern CFTypeRef& typedefRef2; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull "
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull "
 
 
 void arrayNameless(void *[]); // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"_Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"_Nonnull"
 
 void arrayNameless2(void * []); // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:27-[[@LINE-1]]:27}:" _Nonnull"
 
 void arrayNamelessTypedef(CFTypeRef[]); // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:36-[[@LINE-1]]:36}:" _Nonnull "
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:36-[[@LINE-1]]:36}:" _Nonnull "
 
 void arrayNamelessTypedef2(CFTypeRef []); // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:37-[[@LINE-1]]:37}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:37-[[@LINE-1]]:37}:" _Nonnull"
 
 
 extern int (*pointerToArray)[2]; // no-warning
diff --git a/test/Format/inplace.cpp b/test/Format/inplace.cpp
new file mode 100644
index 0000000..175a8b6
--- /dev/null
+++ b/test/Format/inplace.cpp
@@ -0,0 +1,264 @@
+// Regression test to check that clang-format does not leave behind temporary
+// files on Windows when doing in-place formatting.
+// RUN: rm -rf %t.dir
+// RUN: mkdir %t.dir
+// RUN: cp %s %t.dir/inplace.cpp
+// RUN: clang-format -style=LLVM -i %t.dir/inplace.cpp
+// RUN: ls %t.dir > %t.dir/files.txt
+// RUN: FileCheck -strict-whitespace -input-file=%t.dir/files.txt %s
+
+// CHECK-NOT: RF{{.*}}.TMP
+
+// The file needs to be larger than 16kiB so that Windows creates a real file
+// mapping object for it.
+ int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
+int this_is_my_int_there_are_many_like_it_but_this_one_is_mine;
diff --git a/test/Format/style-on-command-line.cpp b/test/Format/style-on-command-line.cpp
index 08da60a..b272435 100644
--- a/test/Format/style-on-command-line.cpp
+++ b/test/Format/style-on-command-line.cpp
@@ -1,30 +1,37 @@
 // RUN: clang-format -style="{BasedOnStyle: Google, IndentWidth: 8}" %s | FileCheck -strict-whitespace -check-prefix=CHECK1 %s
 // RUN: clang-format -style="{BasedOnStyle: LLVM, IndentWidth: 7}" %s | FileCheck -strict-whitespace -check-prefix=CHECK2 %s
-// RUN: clang-format -style="{BasedOnStyle: invalid, IndentWidth: 7}" -fallback-style=LLVM %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK3 %s
-// RUN: clang-format -style="{lsjd}" %s -fallback-style=LLVM 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK4 %s
+// RUN: not clang-format -style="{BasedOnStyle: invalid, IndentWidth: 7}" -fallback-style=LLVM %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK3 %s
+// RUN: not clang-format -style="{lsjd}" %s -fallback-style=LLVM 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK4 %s
 // RUN: printf "BasedOnStyle: google\nIndentWidth: 5\n" > %T/.clang-format
 // RUN: clang-format -style=file -assume-filename=%T/foo.cpp < %s | FileCheck -strict-whitespace -check-prefix=CHECK5 %s
 // RUN: printf "\n" > %T/.clang-format
-// RUN: clang-format -style=file -fallback-style=webkit -assume-filename=%T/foo.cpp < %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK6 %s
+// RUN: not clang-format -style=file -fallback-style=webkit -assume-filename=%T/foo.cpp < %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK6 %s
 // RUN: rm %T/.clang-format
 // RUN: printf "BasedOnStyle: google\nIndentWidth: 6\n" > %T/_clang-format
 // RUN: clang-format -style=file -assume-filename=%T/foo.cpp < %s | FileCheck -strict-whitespace -check-prefix=CHECK7 %s
 // RUN: clang-format -style="{BasedOnStyle: LLVM, PointerBindsToType: true}" %s | FileCheck -strict-whitespace -check-prefix=CHECK8 %s
 // RUN: clang-format -style="{BasedOnStyle: WebKit, PointerBindsToType: false}" %s | FileCheck -strict-whitespace -check-prefix=CHECK9 %s
+
+// Fallback style tests
+// Test config file with no based style, and fallback style "none", formatting is applied
+// RUN: printf "IndentWidth: 6\n" > %T/_clang-format
+// RUN: clang-format -style=file -fallback-style=none -assume-filename=%T/foo.cpp < %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK10 %s
+// Test yaml with no based style, and fallback style "none", LLVM formatting applied
+// RUN: clang-format -style="{IndentWidth: 7}" -fallback-style=none %s | FileCheck -strict-whitespace -check-prefix=CHECK11 %s
+
 void f() {
 // CHECK1: {{^        int\* i;$}}
 // CHECK2: {{^       int \*i;$}}
 // CHECK3: Unknown value for BasedOnStyle: invalid
-// CHECK3: Error parsing -style: {{I|i}}nvalid argument, using LLVM style
-// CHECK3: {{^  int \*i;$}}
-// CHECK4: Error parsing -style: {{I|i}}nvalid argument, using LLVM style
-// CHECK4: {{^  int \*i;$}}
+// CHECK3: Error parsing -style: {{I|i}}nvalid argument
+// CHECK4: Error parsing -style: {{I|i}}nvalid argument
 // CHECK5: {{^     int\* i;$}}
 // CHECK6: {{^Error reading .*\.clang-format: (I|i)nvalid argument}}
-// CHECK6: {{^    int\* i;$}}
 // CHECK7: {{^      int\* i;$}}
 // CHECK8: {{^  int\* i;$}}
 // CHECK9: {{^    int \*i;$}}
+// CHECK10: {{^      int \*i;$}}
+// CHECK11: {{^       int \*i;$}}
 int*i;
 int j;
 }
diff --git a/test/Frontend/aarch64-target-cpu.c b/test/Frontend/aarch64-target-cpu.c
index 9054647..c803694 100644
--- a/test/Frontend/aarch64-target-cpu.c
+++ b/test/Frontend/aarch64-target-cpu.c
@@ -9,6 +9,6 @@
 // RUN: %clang_cc1 -triple aarch64-unknown-unknown -target-cpu exynos-m1 -verify %s
 // RUN: %clang_cc1 -triple aarch64-unknown-unknown -target-cpu generic -verify %s
 // RUN: %clang_cc1 -triple aarch64-unknown-unknown -target-cpu kryo -verify %s
-// RUN: %clang_cc1 -triple aarch64-unknown-unknown -target-cpu vulcan -verify %s
+// RUN: %clang_cc1 -triple aarch64-unknown-unknown -target-cpu thunderx2t99 -verify %s
 //
 // expected-no-diagnostics
diff --git a/test/Frontend/gnu-mcount.c b/test/Frontend/gnu-mcount.c
index 690a103..508be14 100644
--- a/test/Frontend/gnu-mcount.c
+++ b/test/Frontend/gnu-mcount.c
@@ -6,11 +6,11 @@
 // RUN: %clang -target aarch64-unknown-none-eabi -pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-MEABI-GNU
 // RUN: %clang -target armv7-unknown-linux-gnueabi -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI
 // RUN: %clang -target armv7-unknown-linux-gnueabi -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU
-// RUN: %clang -target aarch64-unknown-linux-gnueabi -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI
+// RUN: %clang -target aarch64-unknown-linux-gnueabi -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-LINUX
 // RUN: %clang -target aarch64-unknown-linux-gnueabi -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-MEABI-GNU
 // RUN: %clang -target armv7-unknown-linux-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI
 // RUN: %clang -target armv7-unknown-linux-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU
-// RUN: %clang -target aarch64-unknown-linux-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI
+// RUN: %clang -target aarch64-unknown-linux-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-LINUX
 // RUN: %clang -target aarch64-unknown-linux-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-MEABI-GNU
 // RUN: %clang -target armv7-unknown-freebsd-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-FREEBSD
 // RUN: %clang -target armv7-unknown-freebsd-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-FREEBSD
@@ -53,6 +53,7 @@
 // CHECK-ARM64-EABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
 // CHECK-ARM64-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01_mcount"{{.*}} }
 // CHECK-ARM64-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM64-EABI-LINUX: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01_mcount"{{.*}} }
 // CHECK-ARM-EABI-FREEBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} }
 // CHECK-ARM-EABI-FREEBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
 // CHECK-ARM64-EABI-FREEBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"=".mcount"{{.*}} }
@@ -61,7 +62,7 @@
 // CHECK-ARM-EABI-NETBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
 // CHECK-ARM-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} }
 // CHECK-ARM-EABI-OPENBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM64-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
+// CHECK-ARM64-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} }
 // CHECK-ARM64-EABI-OPENBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
 // CHECK-ARM-EABI-MEABI-GNU-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
 // CHECK-ARM-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
diff --git a/test/Frontend/iframework.c b/test/Frontend/iframework.c
index 6f801f2..2354553 100644
--- a/test/Frontend/iframework.c
+++ b/test/Frontend/iframework.c
@@ -1,4 +1,5 @@
 // RUN: %clang -fsyntax-only -iframework %S/Inputs %s -Xclang -verify
+// RUN: %clang -fsyntax-only -isysroot %S -iframeworkwithsysroot /Inputs %s -Xclang -verify
 // expected-no-diagnostics
 
 #include <TestFramework/TestFramework.h>
diff --git a/test/Frontend/objc-bool-is-bool.m b/test/Frontend/objc-bool-is-bool.m
index 464fe2e..ee4fb58 100644
--- a/test/Frontend/objc-bool-is-bool.m
+++ b/test/Frontend/objc-bool-is-bool.m
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -E -dM -triple=armv7k-apple-watchos %s | FileCheck --check-prefix=BOOL %s
 // RUN: %clang_cc1 -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
-// RUN: %clang_cc1 -x c -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=NONE %s
+// RUN: %clang_cc1 -x c -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
 
 // rdar://21170440
 
@@ -9,5 +11,3 @@
 
 // CHAR: #define __OBJC_BOOL_IS_BOOL 0
 // CHAR-NOT: #define __OBJC_BOOL_IS_BOOL 1
-
-// NONE-NOT: __OBJC_BOOL_IS_BOOL
diff --git a/test/Frontend/optimization-remark-with-hotness.c b/test/Frontend/optimization-remark-with-hotness.c
index 4c27e86..708f5ec 100644
--- a/test/Frontend/optimization-remark-with-hotness.c
+++ b/test/Frontend/optimization-remark-with-hotness.c
@@ -4,11 +4,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
 // RUN:     optimization-remark-with-hotness.c %s -emit-llvm-only \
 // RUN:     -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
-// RUN:     -Rpass-analysis=inline -fdiagnostics-show-hotness -verify
+// RUN:     -Rpass-analysis=inline -Rpass-missed=inline \
+// RUN:     -fdiagnostics-show-hotness -verify
 // The clang version of the previous test.
 // RUN: %clang -target x86_64-apple-macosx10.9 %s -c -emit-llvm -o /dev/null \
 // RUN:     -fprofile-instr-use=%t.profdata -Rpass=inline \
-// RUN:     -Rpass-analysis=inline -fdiagnostics-show-hotness -Xclang -verify
+// RUN:     -Rpass-analysis=inline -Rpass-missed=inline \
+// RUN:     -fdiagnostics-show-hotness -Xclang -verify
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
 // RUN:     optimization-remark-with-hotness.c %s -emit-llvm-only \
 // RUN:     -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
@@ -39,7 +41,7 @@
 
 int main(int argc, const char *argv[]) {
   for (int i = 0; i < 30; i++)
-    // expected-remark@+1 {{bar should never be inlined}}
+    // expected-remark@+1 {{bar not inlined into main because it should never be inlined}}
     bar(argc);
   return sum;
 }
diff --git a/test/Frontend/optimization-remark.c b/test/Frontend/optimization-remark.c
index 72cad8f..7c02233 100644
--- a/test/Frontend/optimization-remark.c
+++ b/test/Frontend/optimization-remark.c
@@ -42,10 +42,8 @@
 // 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@+4 {{foz not inlined into bar because it should never be inlined (cost=never)}}
+// expected-remark@+3 {{foz not inlined into bar because it should never be inlined (cost=never)}}
 // 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/preprocessed-input.i b/test/Frontend/preprocessed-input.i
new file mode 100644
index 0000000..9d5867e
--- /dev/null
+++ b/test/Frontend/preprocessed-input.i
@@ -0,0 +1,10 @@
+# 1 "preprocessed-input.c"
+# 1 "<built-in>" 1
+# 1 "<built-in>" 3
+# 318 "<built-in>" 3
+# 1 "<command line>" 1
+# 1 "<built-in>" 2
+# 1 "preprocessed-input.c" 2
+
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
+// CHECK: source_filename = "preprocessed-input.c"{{$}}
diff --git a/test/Frontend/x86-target-cpu.c b/test/Frontend/x86-target-cpu.c
index 769c40a..4e0db55 100644
--- a/test/Frontend/x86-target-cpu.c
+++ b/test/Frontend/x86-target-cpu.c
@@ -9,6 +9,11 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu ivybridge -verify %s
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu haswell -verify %s
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu broadwell -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu skylake -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu skylake-avx512 -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu skx -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu cannonlake -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu knl -verify %s
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu bonnell -verify %s
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu silvermont -verify %s
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu k8 -verify %s
@@ -26,5 +31,6 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu bdver4 -verify %s
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu btver1 -verify %s
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu btver2 -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu znver1 -verify %s
 //
 // expected-no-diagnostics
diff --git a/test/Headers/Inputs/usr/include/tgmath.h b/test/Headers/Inputs/usr/include/tgmath.h
deleted file mode 100644
index 897962d..0000000
--- a/test/Headers/Inputs/usr/include/tgmath.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef SYS_TGMATH_H
-#define SYS_TGMATH_H
-
-#endif /* SYS_TGMATH_H */
diff --git a/test/Headers/opencl-c-header.cl b/test/Headers/opencl-c-header.cl
index 457a619..2c28be1 100644
--- a/test/Headers/opencl-c-header.cl
+++ b/test/Headers/opencl-c-header.cl
@@ -1,16 +1,11 @@
-// RUN: %clang_cc1 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s
-
-// CHECK: _Z16convert_char_rtec
-// CHECK-NOT: _Z3ctzc
-// CHECK20: _Z3ctzc
-// CHECK20-NOT: _Z16convert_char_rtec
-// CHECK-MOD: Reading modules
+// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s| FileCheck %s
+// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s
 
 // Test including the default header as a module.
 // The module should be compiled only once and loaded from cache afterwards.
 // Change the directory mode to read only to make sure no new modules are created.
 // Check time report to make sure module is used.
+// Check that some builtins occur in the generated IR when called.
 
 // ===
 // Clear current directory.
@@ -30,32 +25,50 @@
 
 // ===
 // Compile for OpenCL 2.0 for the first time. The module should change.
-// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s
+// RUN: %clang_cc1 -triple spir-unknown-unknown -O0 -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s
 // RUN: not diff %t/1_0.pcm %t/opencl_c.pcm
 // RUN: chmod u-w %t/opencl_c.pcm
 
 // ===
 // Compile for OpenCL 2.0 for the second time. The module should not change.
-// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s
+// RUN: %clang_cc1 -triple spir-unknown-unknown -O0 -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s
 
 // Check cached module works for different OpenCL versions.
 // RUN: rm -rf %t
 // RUN: mkdir -p %t
 // RUN: %clang_cc1 -triple spir64-unknown-unknown -emit-llvm -o - -cl-std=CL1.2 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-MOD %s
-// RUN: %clang_cc1 -triple amdgcn--amdhsa -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s
+// RUN: %clang_cc1 -triple amdgcn--amdhsa -O0 -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s
 // RUN: chmod u-w %t 
 // RUN: %clang_cc1 -triple spir64-unknown-unknown -emit-llvm -o - -cl-std=CL1.2 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-MOD %s
-// RUN: %clang_cc1 -triple amdgcn--amdhsa -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s
+// RUN: %clang_cc1 -triple amdgcn--amdhsa -O0 -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s
 // RUN: chmod u+w %t
 
+// Verify that called builtins occur in the generated IR.
+
+// CHECK-NOT: ndrange_t
+// CHECK20: ndrange_t
+// CHECK: _Z16convert_char_rtec
+// CHECK-NOT: _Z3ctzc
+// CHECK20: _Z3ctzc
+// CHECK20-NOT: _Z16convert_char_rtec
 char f(char x) {
 #if __OPENCL_C_VERSION__ != CL_VERSION_2_0
   return convert_char_rte(x);
-#ifdef NO_HEADER
-  //expected-warning@-2{{implicit declaration of function 'convert_char_rte' is invalid in C99}}
-#endif //NO_HEADER
 
 #else //__OPENCL_C_VERSION__
+  ndrange_t t;
   return ctz(x);
 #endif //__OPENCL_C_VERSION__
 }
+
+// Verify that a builtin using a write_only image3d_t type is available
+// from OpenCL 2.0 onwards.
+
+// CHECK20: _Z12write_imagef14ocl_image3d_wo
+#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
+void test_image3dwo(write_only image3d_t img) {
+  write_imagef(img, (0), (0.0f));
+}
+#endif //__OPENCL_C_VERSION__
+
+// CHECK-MOD: Reading modules
diff --git a/test/Headers/stdarg-gnuc_va_list.c b/test/Headers/stdarg-gnuc_va_list.c
new file mode 100644
index 0000000..da9db8d
--- /dev/null
+++ b/test/Headers/stdarg-gnuc_va_list.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wsystem-headers -std=c99 %s
+// expected-no-diagnostics
+
+// Check that no warnings are emitted from stdarg.h if __gnuc_va_list has
+// previously been defined in another header file.
+typedef __builtin_va_list __va_list;
+typedef __va_list __gnuc_va_list;
+#define __GNUC_VA_LIST
+
+#include <stdarg.h>
diff --git a/test/Headers/tgmath-darwin.c b/test/Headers/tgmath-darwin.c
deleted file mode 100644
index b24b6c0..0000000
--- a/test/Headers/tgmath-darwin.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// REQUIRES: system-darwin
-// RUN: %clang -target x86_64-apple-darwin10 -fsyntax-only -std=c11 -isysroot %S/Inputs %s
-#include <tgmath.h>
-
-// Test the #include_next on tgmath.h works on Darwin.
-#ifndef SYS_TGMATH_H
-  #error "SYS_TGMATH_H not defined"
-#endif
-
-#ifndef __TGMATH_H
-  #error "__TGMATH_H not defined"
-#endif
diff --git a/test/Import/clang-flags/Inputs/S.c b/test/Import/clang-flags/Inputs/S.c
new file mode 100644
index 0000000..742dac8
--- /dev/null
+++ b/test/Import/clang-flags/Inputs/S.c
@@ -0,0 +1,2 @@
+STRUCT S {
+};
diff --git a/test/Import/clang-flags/test.c b/test/Import/clang-flags/test.c
new file mode 100644
index 0000000..7a19ea7
--- /dev/null
+++ b/test/Import/clang-flags/test.c
@@ -0,0 +1,5 @@
+// RUN: clang-import-test -import %S/Inputs/S.c -expression %s -Xcc -DSTRUCT=struct
+void expr() {
+  STRUCT S MyS;
+  void *MyPtr = &MyS;
+}
diff --git a/test/Import/empty-struct/Inputs/S.c b/test/Import/empty-struct/Inputs/S.c
new file mode 100644
index 0000000..8c90352
--- /dev/null
+++ b/test/Import/empty-struct/Inputs/S.c
@@ -0,0 +1,2 @@
+struct S {
+};
diff --git a/test/Import/empty-struct/test.c b/test/Import/empty-struct/test.c
new file mode 100644
index 0000000..d51a697
--- /dev/null
+++ b/test/Import/empty-struct/test.c
@@ -0,0 +1,5 @@
+// RUN: clang-import-test -import %S/Inputs/S.c -expression %s
+void expr() {
+  struct S MyS;
+  void *MyPtr = &MyS;
+}
diff --git a/test/Import/error-in-expression/Inputs/S.c b/test/Import/error-in-expression/Inputs/S.c
new file mode 100644
index 0000000..8c90352
--- /dev/null
+++ b/test/Import/error-in-expression/Inputs/S.c
@@ -0,0 +1,2 @@
+struct S {
+};
diff --git a/test/Import/error-in-expression/test.c b/test/Import/error-in-expression/test.c
new file mode 100644
index 0000000..65d3b4a
--- /dev/null
+++ b/test/Import/error-in-expression/test.c
@@ -0,0 +1,6 @@
+// RUN: not clang-import-test -import %S/Inputs/S.c -expression %s 2>&1 | FileCheck %s
+// CHECK: {{.*}}no viable conversion{{.*}}
+void expr() {
+  struct S MyS;
+  void *MyPtr = MyS;
+}
diff --git a/test/Import/error-in-import/Inputs/S.c b/test/Import/error-in-import/Inputs/S.c
new file mode 100644
index 0000000..23ca763f
--- /dev/null
+++ b/test/Import/error-in-import/Inputs/S.c
@@ -0,0 +1,2 @@
+struct S [
+];
diff --git a/test/Import/error-in-import/test.c b/test/Import/error-in-import/test.c
new file mode 100644
index 0000000..197d4e3
--- /dev/null
+++ b/test/Import/error-in-import/test.c
@@ -0,0 +1,6 @@
+// RUN: not clang-import-test -import %S/Inputs/S.c -expression %s 2>&1 | FileCheck %s
+// CHECK: {{.*}}expected unqualified-id{{.*}}
+void expr() {
+  struct S MyS;
+  void *MyPtr = &MyS;
+}
diff --git a/test/Import/missing-import/test.c b/test/Import/missing-import/test.c
new file mode 100644
index 0000000..acf6389
--- /dev/null
+++ b/test/Import/missing-import/test.c
@@ -0,0 +1,6 @@
+// RUN: not clang-import-test -import %S/Inputs/S.c -expression %s 2>&1 | FileCheck %s
+// CHECK: {{.*}}Couldn't open{{.*}}Inputs/S.c{{.*}}
+void expr() {
+  struct S MyS;
+  void *MyPtr = &MyS;
+}
diff --git a/test/Index/Core/designated-inits.c b/test/Index/Core/designated-inits.c
index 24bb9a9..a31cb95 100644
--- a/test/Index/Core/designated-inits.c
+++ b/test/Index/Core/designated-inits.c
@@ -5,7 +5,7 @@
 };
 
 enum {
-  MyValToSet;
+  MyValToSet
 };
 
 // CHECK: [[@LINE+1]]:14 | struct/C | MyStruct |
@@ -20,7 +20,7 @@
       [0] = {
         [0][0] = {
           [0] = {
-            // CHECK: [[@LINE+2]]:14 | field/C | myfield | {{.*}} | Ref |
+            // CHECK: [[@LINE+2]]:14 | field/C | myfield | {{.*}} | Ref,RelCont |
             // CHECK: [[@LINE+1]]:24 | enumerator/C | MyValToSet |
             .myfield = MyValToSet,
             // CHECK-NOT: | field/C | myfield |
diff --git a/test/Index/Core/index-pch.c b/test/Index/Core/index-pch.c
new file mode 100644
index 0000000..773cfc5
--- /dev/null
+++ b/test/Index/Core/index-pch.c
@@ -0,0 +1,13 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+// RUN: %clang_cc1 -emit-pch %s -o %t.pch
+// RUN: c-index-test core -print-source-symbols -module-file %t.pch | FileCheck %s
+
+// CHECK: [[@LINE+1]]:6 | function/C | test1 | [[TEST1_USR:.*]] | [[TEST1_CG:.*]] | Decl | rel: 0
+void test1();
+
+// CHECK: [[@LINE+1]]:20 | function/C | test2 | [[TEST2_USR:.*]] | {{.*}} | Def | rel: 0
+static inline void test2() {
+  // CHECK: [[@LINE+2]]:3 | function/C | test1 | [[TEST1_USR]] | [[TEST1_CG]] | Ref,Call,RelCall,RelCont | rel: 1
+  // CHECK-NEXT: RelCall,RelCont | test2 | [[TEST2_USR]]
+  test1();
+}
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index 7db5d53..ab7c6f4 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -1,5 +1,29 @@
 // RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
 
+// CHECK: [[@LINE+1]]:7 | class/C++ | Cls | [[Cls_USR:.*]] | <no-cgname> | Def | rel: 0
+class Cls {
+  // CHECK: [[@LINE+2]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1
+  // CHECK-NEXT: RelChild | Cls | c:@S@Cls
+  Cls(int x);
+  // CHECK: [[@LINE+1]]:3 | constructor/cxx-copy-ctor/C++ | Cls | c:@S@Cls@F@Cls#&1$@S@Cls# | __ZN3ClsC1ERKS_ | Decl,RelChild | rel: 1
+  Cls(const Cls &);
+  // CHECK: [[@LINE+1]]:3 | constructor/cxx-move-ctor/C++ | Cls | c:@S@Cls@F@Cls#&&$@S@Cls# | __ZN3ClsC1EOS_ | Decl,RelChild | rel: 1
+  Cls(Cls &&);
+};
+
+// CHECK: [[@LINE+3]]:7 | class/C++ | SubCls1 | [[SubCls1_USR:.*]] | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+2]]:24 | class/C++ | Cls | [[Cls_USR]] | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | SubCls1 | [[SubCls1_USR]]
+class SubCls1 : public Cls {};
+// CHECK: [[@LINE+1]]:13 | type-alias/C | ClsAlias | [[ClsAlias_USR:.*]] | <no-cgname> | Def | rel: 0
+typedef Cls ClsAlias;
+// CHECK: [[@LINE+5]]:7 | class/C++ | SubCls2 | [[SubCls2_USR:.*]] | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+4]]:24 | type-alias/C | ClsAlias | [[ClsAlias_USR]] | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | SubCls2 | [[SubCls2_USR]]
+// CHECK: [[@LINE+2]]:24 | class/C++ | Cls | [[Cls_USR]] | <no-cgname> | Ref,Impl,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | SubCls2 | [[SubCls2_USR]]
+class SubCls2 : public ClsAlias {};
+
 template <typename TemplArg>
 class TemplCls {
 // CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Def | rel: 0
@@ -10,7 +34,17 @@
 };
 
 TemplCls<int> gtv(0);
-// CHECK: [[@LINE-1]]:1 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-1]]:1 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Ref,RelCont | rel: 1
+
+template<class T>
+class Wrapper {};
+template<class T, class P>
+class Wrapper<T(P)> {};
+
+// CHECK: [[@LINE+1]]:6 | function/C | test1 | [[TEST1_USR:.*]] | [[TEST1_CG:.*]] | Decl | rel: 0
+void test1(Wrapper<void(int)> f);
+// CHECK: [[@LINE+1]]:6 | function/C | test1 | [[TEST1_USR]] | [[TEST1_CG]] | Def | rel: 0
+void test1(Wrapper<void(int)> f) {}
 
 template <typename T>
 class BT {
@@ -27,7 +61,7 @@
 // CHECK: [[@LINE+1]]:23 | type-alias/C | size_t |
 typedef unsigned long size_t;
 // CHECK: [[@LINE+2]]:7 | function/C | operator new | c:@F@operator new#l# | __Znwm |
-// CHECK: [[@LINE+1]]:20 | type-alias/C | size_t | {{.*}} | Ref |
+// CHECK: [[@LINE+1]]:20 | type-alias/C | size_t | {{.*}} | Ref,RelCont |
 void* operator new(size_t sz);
 
 // CHECK: [[@LINE+1]]:37 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Def | rel: 0
@@ -35,8 +69,8 @@
 // CHECK: [[@LINE+1]]:29 | variable(Gen,TS)/C++ | tmplVar | c:index-source.cpp@tmplVar>#I | __ZL7tmplVarIiE | Def | rel: 0
 template<> static const int tmplVar<int> = 0;
 // CHECK: [[@LINE+2]]:5 | variable/C | gvi | c:@gvi | _gvi | Def | rel: 0
-// CHECK: [[@LINE+1]]:11 | variable(Gen,TS)/C++ | tmplVar | c:index-source.cpp@tmplVar>#I | __ZL7tmplVarIiE | Ref,Read | rel: 0
+// CHECK: [[@LINE+1]]:11 | variable(Gen,TS)/C++ | tmplVar | c:index-source.cpp@tmplVar>#I | __ZL7tmplVarIiE | Ref,Read,RelCont | rel: 1
 int gvi = tmplVar<int>;
 // CHECK: [[@LINE+2]]:5 | variable/C | gvf | c:@gvf | _gvf | Def | rel: 0
-// CHECK: [[@LINE+1]]:11 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Ref,Read | rel: 0
+// CHECK: [[@LINE+1]]:11 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Ref,Read,RelCont | rel: 1
 int gvf = tmplVar<float>;
diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m
index fc1b623..2675edd 100644
--- a/test/Index/Core/index-source.m
+++ b/test/Index/Core/index-source.m
@@ -1,22 +1,63 @@
 // RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s
+// RUN: c-index-test core -print-source-symbols -include-locals -- %s -target x86_64-apple-macosx10.7 | FileCheck -check-prefix=LOCAL %s
 
 @interface Base
 // CHECK: [[@LINE-1]]:12 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Decl | rel: 0
 -(void)meth;
-// CHECK: [[@LINE-1]]:1 | instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Decl,Dyn,RelChild | rel: 1
+// CHECK: [[@LINE-1]]:8 | instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Decl,Dyn,RelChild | rel: 1
 // CHECK-NEXT: RelChild | Base | c:objc(cs)Base
++(Base*)class_meth;
+// CHECK: [[@LINE-1]]:9 | class-method/ObjC | class_meth | c:objc(cs)Base(cm)class_meth | +[Base class_meth] | Decl,Dyn,RelChild | rel: 1
+// CHECK: [[@LINE-2]]:3 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | class_meth | c:objc(cs)Base(cm)class_meth
+
 @end
 
 void foo();
-// CHECK: [[@LINE+1]]:6 | function/C | goo | c:@F@goo | _goo | Def | rel: 0
+// CHECK: [[@LINE+6]]:6 | function/C | goo | c:@F@goo | _goo | Def | rel: 0
+// CHECK: [[@LINE+5]]:10 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | goo | c:@F@goo
+// CHECK-NOT: [[@LINE+3]]:16 | param
+// LOCAL: [[@LINE+2]]:16 | param(local)/C | b | [[b_USR:c:.*]] | _b | Def,RelChild | rel: 1
+// LOCAL-NEXT: RelChild | goo | c:@F@goo
 void goo(Base *b) {
-  // CHECK: [[@LINE+2]]:3 | function/C | foo | c:@F@foo | _foo | Ref,Call,RelCall | rel: 1
-  // CHECK-NEXT: RelCall | goo | c:@F@goo
+  // CHECK-NOT: [[@LINE+6]]:7 | variable
+  // LOCAL: [[@LINE+5]]:7 | variable(local)/C | x | [[x_USR:c:.*]] | _x | Def,RelCont | rel: 1
+  // LOCAL-NEXT: RelCont | goo | c:@F@goo
+  // CHECK-NOT: [[@LINE+3]]:11 | param
+  // LOCAL: [[@LINE+2]]:11 | param(local)/C | b | [[b_USR]] | _b | Ref,Read,RelCont | rel: 1
+  // LOCAL-NEXT: RelCont | x | [[x_USR]]
+  int x = b;
+  // CHECK-NOT: [[@LINE+5]]:7 | variable
+  // LOCAL: [[@LINE+4]]:7 | variable(local)/C | y | [[y_USR:c:.*]] | _y | Def,RelCont | rel: 1
+  // CHECK-NOT: [[@LINE+3]]:11 | variable
+  // LOCAL: [[@LINE+2]]:11 | variable(local)/C | x | [[x_USR]] | _x | Ref,Read,RelCont | rel: 1
+  // LOCAL-NEXT: RelCont | y | [[y_USR]]
+  int y = x;
+
+  // CHECK-NOT: [[@LINE+1]]:10 | struct
+  // LOCAL: [[@LINE+1]]:10 | struct(local)/C | Foo | c:{{.*}} | <no-cgname> | Def,RelCont | rel: 1
+  struct Foo {
+    int i;
+  };
+
+  // CHECK: [[@LINE+2]]:3 | function/C | foo | c:@F@foo | _foo | Ref,Call,RelCall,RelCont | rel: 1
+  // CHECK-NEXT: RelCall,RelCont | goo | c:@F@goo
   foo();
-  // CHECK: [[@LINE+3]]:6 | instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Ref,Call,Dyn,RelRec,RelCall | rel: 2
-  // CHECK-NEXT: RelCall | goo | c:@F@goo
+  // CHECK: [[@LINE+3]]:6 | instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Ref,Call,Dyn,RelRec,RelCall,RelCont | rel: 2
+  // CHECK-NEXT: RelCall,RelCont | goo | c:@F@goo
   // CHECK-NEXT: RelRec | Base | c:objc(cs)Base
   [b meth];
+
+  // CHECK: [[@LINE+2]]:4 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
+  // CHECK-NEXT: RelCont | goo | c:@F@goo
+  [Base class_meth];
+
+  // CHECK: [[@LINE+4]]:3 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
+  // CHECK-NEXT: RelCont | goo | c:@F@goo
+  // CHECK: [[@LINE+2]]:14 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
+  // CHECK-NEXT: RelCont | goo | c:@F@goo
+  Base *f = (Base *) 2;
 }
 
 // CHECK: [[@LINE+1]]:11 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Decl | rel: 0
@@ -24,18 +65,18 @@
 @end
 
 // CHECK: [[@LINE+3]]:11 | protocol/ObjC | Prot2 | c:objc(pl)Prot2 | <no-cgname> | Decl | rel: 0
-// CHECK: [[@LINE+2]]:17 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase | rel: 1
-// CHECK-NEXT: RelBase | Prot2 | c:objc(pl)Prot2
+// CHECK: [[@LINE+2]]:17 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | Prot2 | c:objc(pl)Prot2
 @protocol Prot2<Prot1>
 @end
 
 // CHECK: [[@LINE+7]]:12 | class/ObjC | Sub | c:objc(cs)Sub | _OBJC_CLASS_$_Sub | Decl | rel: 0
-// CHECK: [[@LINE+6]]:18 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelBase | rel: 1
-// CHECK-NEXT: RelBase | Sub | c:objc(cs)Sub
-// CHECK: [[@LINE+4]]:23 | protocol/ObjC | Prot2 | c:objc(pl)Prot2 | <no-cgname> | Ref,RelBase | rel: 1
-// CHECK-NEXT: RelBase | Sub | c:objc(cs)Sub
-// CHECK: [[@LINE+2]]:30 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase | rel: 1
-// CHECK-NEXT: RelBase | Sub | c:objc(cs)Sub
+// CHECK: [[@LINE+6]]:18 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | Sub | c:objc(cs)Sub
+// CHECK: [[@LINE+4]]:23 | protocol/ObjC | Prot2 | c:objc(pl)Prot2 | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | Sub | c:objc(cs)Sub
+// CHECK: [[@LINE+2]]:30 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | Sub | c:objc(cs)Sub
 @interface Sub : Base<Prot2, Prot1>
 @end
 
@@ -68,65 +109,90 @@
 
 // CHECK: [[@LINE+1]]:13 | type-alias/C | jmp_buf | c:index-source.m@T@jmp_buf | <no-cgname> | Def | rel: 0
 typedef int jmp_buf[(18)];
-// CHECK: [[@LINE+2]]:12 | function/C | setjmp | c:@F@setjmp | _setjmp | Decl | rel: 0
-// CHECK: [[@LINE+1]]:19 | type-alias/C | jmp_buf | c:index-source.m@T@jmp_buf | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE+3]]:12 | function/C | setjmp | c:@F@setjmp | _setjmp | Decl | rel: 0
+// CHECK: [[@LINE+2]]:19 | type-alias/C | jmp_buf | c:index-source.m@T@jmp_buf | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | setjmp | c:@F@setjmp
 extern int setjmp(jmp_buf);
 
 @class I1;
 @interface I1
-// CHECK: [[@LINE+1]]:1 | instance-method/ObjC | meth | c:objc(cs)I1(im)meth | -[I1 meth] | Decl,Dyn,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:8 | instance-method/ObjC | meth | c:objc(cs)I1(im)meth | -[I1 meth] | Decl,Dyn,RelChild | rel: 1
 -(void)meth;
 @end
 
 @interface I2
 @property (readwrite) id prop;
+
+// CHECK: [[@LINE+4]]:63 | instance-property(IB,IBColl)/ObjC | buttons | c:objc(cs)I2(py)buttons | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
+// CHECK: [[@LINE+2]]:50 | class/ObjC | I1 | c:objc(cs)I1 | _OBJC_CLASS_$_I1 | Ref,RelCont,RelIBType | rel: 1
+// CHECK-NEXT: RelCont,RelIBType | buttons | c:objc(cs)I2(py)buttons
+@property (nonatomic, strong) IBOutletCollection(I1) NSArray *buttons;
 @end
 
-// CHECK: [[@LINE+2]]:17 | field/ObjC | _prop | c:objc(cs)I2@_prop | <no-cgname> | Def,Impl,RelChild | rel: 1
-// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
 @implementation I2
-// CHECK: [[@LINE+5]]:13 | instance-property/ObjC | prop | c:objc(cs)I2(py)prop | <no-cgname> | Ref | rel: 0
-// CHECK: [[@LINE+4]]:13 | instance-method/ObjC | prop | c:objc(cs)I2(im)prop | -[I2 prop] | Def,RelChild | rel: 1
+// CHECK: [[@LINE+9]]:13 | instance-property/ObjC | prop | c:objc(cs)I2(py)prop | <no-cgname> | Def,RelChild,RelAcc | rel: 2
 // CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
-// CHECK: [[@LINE+2]]:13 | instance-method/ObjC | setProp: | c:objc(cs)I2(im)setProp: | -[I2 setProp:] | Def,RelChild | rel: 1
+// CHECK-NEXT: RelAcc | _prop | c:objc(cs)I2@_prop
+// CHECK: [[@LINE+6]]:13 | instance-method/acc-get/ObjC | prop | c:objc(cs)I2(im)prop | -[I2 prop] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
+// CHECK: [[@LINE+4]]:13 | instance-method/acc-set/ObjC | setProp: | c:objc(cs)I2(im)setProp: | -[I2 setProp:] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
+// CHECK: [[@LINE+2]]:20 | field/ObjC | _prop | c:objc(cs)I2@_prop | <no-cgname> | Def,RelChild | rel: 1
 // CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
 @synthesize prop = _prop;
+
+// CHECK: [[@LINE+11]]:12 | instance-method(IB)/ObjC | doAction:foo: | c:objc(cs)I2(im)doAction:foo: | -[I2 doAction:foo:] | Def,Dyn,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
+// CHECK: [[@LINE+9]]:22 | class/ObjC | I1 | c:objc(cs)I1 | _OBJC_CLASS_$_I1 | Ref,RelCont,RelIBType | rel: 1
+// CHECK-NEXT: RelCont,RelIBType | doAction:foo: | c:objc(cs)I2(im)doAction:foo:
+// CHECK-NOT: [[@LINE+7]]:27 | param
+// LOCAL: [[@LINE+6]]:27 | param(local)/C | sender | c:{{.*}} | _sender | Def,RelChild | rel: 1
+// LOCAL-NEXT: RelChild | doAction:foo: | c:objc(cs)I2(im)doAction:foo:
+// CHECK: [[@LINE+4]]:39 | class/ObjC | I1 | c:objc(cs)I1 | _OBJC_CLASS_$_I1 | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE+3]]:44 | param
+// LOCAL: [[@LINE+2]]:44 | param(local)/C | bar | c:{{.*}} | _bar | Def,RelChild | rel: 1
+// LOCAL-NEXT: RelChild | doAction:foo: | c:objc(cs)I2(im)doAction:foo:
+-(IBAction)doAction:(I1 *)sender foo:(I1 *)bar {}
 @end
 
 @interface I3
 @property (readwrite) id prop;
-// CHECK: [[@LINE+3]]:1 | instance-method/ObjC | prop | c:objc(cs)I3(im)prop | -[I3 prop] | Decl,Dyn,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE+3]]:6 | instance-method/acc-get/ObjC | prop | c:objc(cs)I3(im)prop | -[I3 prop] | Decl,Dyn,RelChild,RelAcc | rel: 2
 // CHECK-NEXT: RelChild | I3 | c:objc(cs)I3
 // CHECK-NEXT: RelAcc | prop | c:objc(cs)I3(py)prop
 -(id)prop;
-// CHECK: [[@LINE+3]]:1 | instance-method/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Decl,Dyn,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE+4]]:8 | instance-method/acc-set/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Decl,Dyn,RelChild,RelAcc | rel: 2
 // CHECK-NEXT: RelChild | I3 | c:objc(cs)I3
 // CHECK-NEXT: RelAcc | prop | c:objc(cs)I3(py)prop
+// LOCAL-NOT: [[@LINE+1]]:20 | param
 -(void)setProp:(id)p;
 @end
 
 // CHECK: [[@LINE+1]]:17 | class/ObjC | I3 | c:objc(cs)I3 | <no-cgname> | Def | rel: 0
 @implementation I3
-// CHECK: [[@LINE+3]]:13 | instance-property/ObjC | prop | c:objc(cs)I3(py)prop | <no-cgname> | Ref | rel: 0
-// CHECK: [[@LINE+2]]:13 | instance-method/ObjC | prop | c:objc(cs)I3(im)prop | -[I3 prop] | Def,RelChild | rel: 1
-// CHECK: [[@LINE+1]]:13 | instance-method/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Def,RelChild | rel: 1
+// CHECK: [[@LINE+5]]:13 | instance-property/ObjC | prop | c:objc(cs)I3(py)prop | <no-cgname> | Def,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I3 | c:objc(cs)I3
+// CHECK-NEXT: RelAcc | _prop | c:objc(cs)I3@_prop
+// CHECK: [[@LINE+2]]:13 | instance-method/acc-get/ObjC | prop | c:objc(cs)I3(im)prop | -[I3 prop] | Def,Impl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:13 | instance-method/acc-set/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Def,Impl,RelChild | rel: 1
 @synthesize prop = _prop;
 @end
 
-// CHECK: [[@LINE+5]]:12 | class/ObjC | I3 | c:objc(cs)I3 | _OBJC_CLASS_$_I3 | Ref,RelExt | rel: 1
-// CHECK-NEXT: RelExt | bar | c:objc(cy)I3@bar
+// CHECK: [[@LINE+5]]:12 | class/ObjC | I3 | c:objc(cs)I3 | _OBJC_CLASS_$_I3 | Ref,RelExt,RelCont | rel: 1
+// CHECK-NEXT: RelExt,RelCont | bar | c:objc(cy)I3@bar
 // CHECK: [[@LINE+3]]:15 | extension/ObjC | bar | c:objc(cy)I3@bar | <no-cgname> | Decl | rel: 0
-// CHECK: [[@LINE+2]]:21 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase | rel: 1
-// CHECK-NEXT: RelBase | bar | c:objc(cy)I3@bar
+// CHECK: [[@LINE+2]]:21 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | bar | c:objc(cy)I3@bar
 @interface I3(bar) <Prot1>
 @end
 
-// CHECK: [[@LINE+2]]:17 | class/ObjC | I3 | c:objc(cs)I3 | _OBJC_CLASS_$_I3 | Ref | rel: 0
-// CHECK: [[@LINE+1]]:20 | extension/ObjC | I3 | c:objc(cy)I3@bar | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+2]]:17 | class/ObjC | I3 | c:objc(cs)I3 | _OBJC_CLASS_$_I3 | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:20 | extension/ObjC | bar | c:objc(cy)I3@bar | <no-cgname> | Def | rel: 0
 @implementation I3(bar)
 @end
 
-// CHECK: [[@LINE+1]]:12 | extension/ObjC | <no-name> | <no-usr> | <no-cgname> | Decl | rel: 0
+// CHECK-NOT: [[@LINE+1]]:12 | extension/ObjC |
 @interface NonExistent()
 @end
 
@@ -136,16 +202,109 @@
 @protocol MyEnumerating
 @end
 
-// CHECK: [[@LINE+4]]:41 | type-alias/C | MyEnumerator | c:index-source.m@T@MyEnumerator | <no-cgname> | Def | rel: 0
-// CHECK: [[@LINE+3]]:26 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref | rel: 0
-// CHECK: [[@LINE+2]]:9 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref | rel: 0
-// CHECK: [[@LINE+1]]:18 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref | rel: 0
+// CHECK: [[@LINE+4]]:41 | type-alias/C | MyEnumerator | [[MyEnumerator_USR:.*]] | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+3]]:26 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+2]]:9 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:18 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
 typedef MyGenCls<Base *><MyEnumerating> MyEnumerator;
 
-// CHECK: [[@LINE+5]]:12 | class/ObjC | PermanentEnumerator | c:objc(cs)PermanentEnumerator | _OBJC_CLASS_$_PermanentEnumerator | Decl | rel: 0
-// CHECK: [[@LINE+4]]:34 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,RelBase | rel: 1
-// CHECK-NEXT: RelBase | PermanentEnumerator | c:objc(cs)PermanentEnumerator
-// CHECK: [[@LINE+2]]:34 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,RelBase | rel: 1
-// CHECK-NEXT: RelBase | PermanentEnumerator | c:objc(cs)PermanentEnumerator
+// CHECK: [[@LINE+7]]:12 | class/ObjC | PermanentEnumerator | [[PermanentEnumerator_USR:.*]] | _OBJC_CLASS_$_PermanentEnumerator | Decl | rel: 0
+// CHECK: [[@LINE+6]]:34 | type-alias/C | MyEnumerator | [[MyEnumerator_USR]] | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | PermanentEnumerator | [[PermanentEnumerator_USR]]
+// CHECK: [[@LINE+4]]:34 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,Impl,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | [[PermanentEnumerator_USR]]
+// CHECK: [[@LINE+2]]:34 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,Impl,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | [[PermanentEnumerator_USR]]
 @interface PermanentEnumerator : MyEnumerator
 @end
+
+// CHECK: [[@LINE+2]]:48 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:35 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,Impl,RelBase,RelCont | rel: 1
+@interface PermanentEnumerator2 : MyEnumerator<Prot1>
+@end
+
+@interface I4
+@property id foo;
+@end
+
+@implementation I4 {
+  id _blahfoo; // explicit def
+  // CHECK: [[@LINE-1]]:6 | field/ObjC | _blahfoo | c:objc(cs)I4@_blahfoo | <no-cgname> | Def,RelChild | rel: 1
+}
+@synthesize foo = _blahfoo; // ref of field _blahfoo
+// CHECK: [[@LINE-1]]:13 | instance-property/ObjC | foo | c:objc(cs)I4(py)foo | <no-cgname> | Def,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I4 | c:objc(cs)I4
+// CHECK-NEXT: RelAcc | _blahfoo | c:objc(cs)I4@_blahfoo
+// CHECK: [[@LINE-4]]:13 | instance-method/acc-get/ObjC | foo | c:objc(cs)I4(im)foo | -[I4 foo] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I4 | c:objc(cs)I4
+// CHECK: [[@LINE-6]]:13 | instance-method/acc-set/ObjC | setFoo: | c:objc(cs)I4(im)setFoo: | -[I4 setFoo:] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I4 | c:objc(cs)I4
+// CHECK: [[@LINE-8]]:19 | field/ObjC | _blahfoo | c:objc(cs)I4@_blahfoo | <no-cgname> | Ref | rel: 0
+
+-(void)method {
+  _blahfoo = 0;
+  // CHECK: [[@LINE-1]]:3 | field/ObjC | _blahfoo | c:objc(cs)I4@_blahfoo | <no-cgname> | Ref,Writ,RelCont | rel: 1
+}
+@end
+
+@interface I5
+@property id foo;
+@end
+
+@implementation I5
+@synthesize foo = _blahfoo; // explicit def of field _blahfoo
+// CHECK: [[@LINE-1]]:13 | instance-property/ObjC | foo | c:objc(cs)I5(py)foo | <no-cgname> | Def,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I5 | c:objc(cs)I5
+// CHECK-NEXT: RelAcc | _blahfoo | c:objc(cs)I5@_blahfoo
+// CHECK: [[@LINE-4]]:13 | instance-method/acc-get/ObjC | foo | c:objc(cs)I5(im)foo | -[I5 foo] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I5 | c:objc(cs)I5
+// CHECK: [[@LINE-6]]:13 | instance-method/acc-set/ObjC | setFoo: | c:objc(cs)I5(im)setFoo: | -[I5 setFoo:] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I5 | c:objc(cs)I5
+// CHECK: [[@LINE-8]]:19 | field/ObjC | _blahfoo | c:objc(cs)I5@_blahfoo | <no-cgname> | Def,RelChild | rel: 1
+
+-(void)method {
+  _blahfoo = 0;
+  // CHECK: [[@LINE-1]]:3 | field/ObjC | _blahfoo | c:objc(cs)I5@_blahfoo | <no-cgname> | Ref,Writ,RelCont | rel: 1
+}
+@end
+
+@interface I6
+@property id foo;
+@end
+
+@implementation I6
+@synthesize foo; // implicit def of field foo
+// CHECK: [[@LINE-1]]:13 | instance-property/ObjC | foo | c:objc(cs)I6(py)foo | <no-cgname> | Def,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I6 | c:objc(cs)I6
+// CHECK-NEXT: RelAcc | foo | c:objc(cs)I6@foo
+// CHECK: [[@LINE-4]]:13 | instance-method/acc-get/ObjC | foo | c:objc(cs)I6(im)foo | -[I6 foo] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I6 | c:objc(cs)I6
+// CHECK: [[@LINE-6]]:13 | instance-method/acc-set/ObjC | setFoo: | c:objc(cs)I6(im)setFoo: | -[I6 setFoo:] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I6 | c:objc(cs)I6
+// CHECK: [[@LINE-8]]:13 | field/ObjC | foo | c:objc(cs)I6@foo | <no-cgname> | Def,Impl,RelChild | rel: 1
+
+-(void)method {
+  foo = 0;
+  // CHECK: [[@LINE-1]]:3 | field/ObjC | foo | c:objc(cs)I6@foo | <no-cgname> | Ref,Writ,RelCont | rel: 1
+}
+@end
+
+@interface I7
+@property id foo;
+@end
+
+@implementation I7 // implicit def of field _foo
+// CHECK: [[@LINE-1]]:17 | instance-property/ObjC | foo | c:objc(cs)I7(py)foo | <no-cgname> | Def,Impl,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I7 | c:objc(cs)I7
+// CHECK-NEXT: RelAcc | _foo | c:objc(cs)I7@_foo
+// CHECK: [[@LINE-4]]:17 | instance-method/acc-get/ObjC | foo | c:objc(cs)I7(im)foo | -[I7 foo] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I7 | c:objc(cs)I7
+// CHECK: [[@LINE-6]]:17 | instance-method/acc-set/ObjC | setFoo: | c:objc(cs)I7(im)setFoo: | -[I7 setFoo:] | Def,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I7 | c:objc(cs)I7
+// CHECK: [[@LINE-8]]:17 | field/ObjC | _foo | c:objc(cs)I7@_foo | <no-cgname> | Def,Impl,RelChild | rel: 1
+
+-(void)method {
+  _foo = 0;
+// CHECK: [[@LINE-1]]:3 | field/ObjC | _foo | c:objc(cs)I7@_foo | <no-cgname> | Ref,Writ,RelCont | rel: 1
+}
+@end
diff --git a/test/Index/Core/index-subkinds.m b/test/Index/Core/index-subkinds.m
index 38be73b..5eea046 100644
--- a/test/Index/Core/index-subkinds.m
+++ b/test/Index/Core/index-subkinds.m
@@ -9,11 +9,11 @@
 @end
 // CHECK: [[@LINE+1]]:17 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | <no-cgname> | Def | rel: 0
 @implementation MyTestCase
-// CHECK: [[@LINE+1]]:1 | instance-method(test)/ObjC | testMe | c:objc(cs)MyTestCase(im)testMe | -[MyTestCase testMe] | Def,Dyn,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:8 | instance-method(test)/ObjC | testMe | c:objc(cs)MyTestCase(im)testMe | -[MyTestCase testMe] | Def,Dyn,RelChild | rel: 1
 -(void)testMe {}
-// CHECK: [[@LINE+1]]:1 | instance-method/ObjC | testResult | c:objc(cs)MyTestCase(im)testResult | -[MyTestCase testResult] | Def,Dyn,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:6 | instance-method/ObjC | testResult | c:objc(cs)MyTestCase(im)testResult | -[MyTestCase testResult] | Def,Dyn,RelChild | rel: 1
 -(id)testResult { return 0; }
-// CHECK: [[@LINE+1]]:1 | instance-method/ObjC | testWithInt: | c:objc(cs)MyTestCase(im)testWithInt: | -[MyTestCase testWithInt:] | Def,Dyn,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:8 | instance-method/ObjC | testWithInt: | c:objc(cs)MyTestCase(im)testWithInt: | -[MyTestCase testWithInt:] | Def,Dyn,RelChild | rel: 1
 -(void)testWithInt:(int)i {}
 @end
 
@@ -22,19 +22,19 @@
 @end
 // CHECK: [[@LINE+1]]:17 | class(test)/ObjC | SubTestCase | c:objc(cs)SubTestCase | <no-cgname> | Def | rel: 0
 @implementation SubTestCase
-// CHECK: [[@LINE+1]]:1 | instance-method(test)/ObjC | testIt2 | c:objc(cs)SubTestCase(im)testIt2 | -[SubTestCase testIt2] | Def,Dyn,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:8 | instance-method(test)/ObjC | testIt2 | c:objc(cs)SubTestCase(im)testIt2 | -[SubTestCase testIt2] | Def,Dyn,RelChild | rel: 1
 -(void)testIt2 {}
 @end
 
-// CHECK: [[@LINE+3]]:12 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelExt | rel: 1
-// CHECK-NEXT: RelExt | cat | c:objc(cy)MyTestCase@cat
-// CHECK: [[@LINE+1]]:23 | extension/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Decl | rel: 0
+// CHECK: [[@LINE+3]]:12 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelExt,RelCont | rel: 1
+// CHECK-NEXT: RelExt,RelCont | cat | c:objc(cy)MyTestCase@cat
+// CHECK: [[@LINE+1]]:23 | extension(test)/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Decl | rel: 0
 @interface MyTestCase(cat)
 @end
-// CHECK: [[@LINE+2]]:17 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref | rel: 0
-// CHECK: [[@LINE+1]]:28 | extension/ObjC | MyTestCase | c:objc(cy)MyTestCase@cat | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+2]]:17 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:28 | extension(test)/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Def | rel: 0
 @implementation MyTestCase(cat)
-// CHECK: [[@LINE+1]]:1 | instance-method(test)/ObjC | testInCat | c:objc(cs)MyTestCase(im)testInCat | -[MyTestCase(cat) testInCat] | Def,Dyn,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | instance-method(test)/ObjC | testInCat | c:objc(cs)MyTestCase(im)testInCat | -[MyTestCase(cat) testInCat] | Def,Dyn,RelChild | rel: 1
 - (void)testInCat {}
 @end
 
@@ -42,12 +42,12 @@
 @class NSButton;
 @interface IBCls
 
-// CHECK: [[@LINE+2]]:34 | instance-method/ObjC | prop | c:objc(cs)IBCls(im)prop | -[IBCls prop] | Decl,Dyn,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE+2]]:34 | instance-method/acc-get/ObjC | prop | c:objc(cs)IBCls(im)prop | -[IBCls prop] | Decl,Dyn,Impl,RelChild,RelAcc | rel: 2
 // CHECK: [[@LINE+1]]:34 | instance-property(IB)/ObjC | prop | c:objc(cs)IBCls(py)prop | <no-cgname> | Decl,RelChild | rel: 1
 @property (readonly) IBOutlet id prop;
 // CHECK: [[@LINE+1]]:54 | instance-property(IB,IBColl)/ObjC | propColl | c:objc(cs)IBCls(py)propColl | <no-cgname> | Decl,RelChild | rel: 1
 @property (readonly) IBOutletCollection(NSButton) id propColl;
-// CHECK: [[@LINE+1]]:1 | instance-method(IB)/ObjC | doIt | c:objc(cs)IBCls(im)doIt | -[IBCls doIt] | Decl,Dyn,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:12 | instance-method(IB)/ObjC | doIt | c:objc(cs)IBCls(im)doIt | -[IBCls doIt] | Decl,Dyn,RelChild | rel: 1
 -(IBAction)doIt;
 @end
 
diff --git a/test/Index/Core/index-with-module.m b/test/Index/Core/index-with-module.m
index 03fd5cd..c83de63 100644
--- a/test/Index/Core/index-with-module.m
+++ b/test/Index/Core/index-with-module.m
@@ -1,5 +1,5 @@
 // RUN: rm -rf %t.mcp
-// RUN: c-index-test core -print-source-symbols -- %s -I %S/Inputs/module -fmodules -fmodules-cache-path=%t.mcp | FileCheck %s
+// RUN: c-index-test core -print-source-symbols -dump-imported-module-files -- %s -I %S/Inputs/module -fmodules -fmodules-cache-path=%t.mcp | FileCheck %s
 
 // CHECK: [[@LINE+1]]:9 | module/C | ModA | Decl |
 @import ModA;
@@ -7,6 +7,12 @@
 #include "ModA.h"
 
 void foo() {
-  // CHECK: [[@LINE+1]]:3 | function/C | ModA_func | c:@F@ModA_func | {{.*}} | Ref,Call,RelCall | rel: 1
+  // CHECK: [[@LINE+1]]:3 | function/C | ModA_func | c:@F@ModA_func | {{.*}} | Ref,Call,RelCall,RelCont | rel: 1
   ModA_func();
 }
+
+// CHECK: ==== Module ModA ====
+// CHECK: 2:6 | function/C | ModA_func | c:@F@ModA_func | {{.*}} | Decl | rel: 0
+// CHECK: ---- Module Inputs ----
+// CHECK: user | {{.*}}ModA.h
+// CHECK: user | {{.*}}module.modulemap
diff --git a/test/Index/annotate-nested-name-specifier.cpp b/test/Index/annotate-nested-name-specifier.cpp
index eddd215..a7338db 100644
--- a/test/Index/annotate-nested-name-specifier.cpp
+++ b/test/Index/annotate-nested-name-specifier.cpp
@@ -211,7 +211,7 @@
 // CHECK: Punctuation: "::" [40:30 - 40:32] UsingDeclaration=iterator:40:46
 // CHECK: Identifier: "vector" [40:32 - 40:38] TemplateRef=vector:4:12
 // CHECK: Punctuation: "<" [40:38 - 40:39] UsingDeclaration=iterator:40:46
-// CHECK: Identifier: "type" [40:39 - 40:43] TypeRef=type:39:13
+// CHECK: Identifier: "type" [40:39 - 40:43] TypeRef=X2::type:39:13
 // CHECK: Punctuation: ">" [40:43 - 40:44] UsingDeclaration=iterator:40:46
 // CHECK: Punctuation: "::" [40:44 - 40:46] UsingDeclaration=iterator:40:46
 // CHECK: Identifier: "iterator" [40:46 - 40:54] UsingDeclaration=iterator:40:46
@@ -223,7 +223,7 @@
 // CHECK: Punctuation: "::" [41:21 - 41:23] UsingDeclaration=push_back:41:37
 // CHECK: Identifier: "vector" [41:23 - 41:29] TemplateRef=vector:4:12
 // CHECK: Punctuation: "<" [41:29 - 41:30] UsingDeclaration=push_back:41:37
-// CHECK: Identifier: "type" [41:30 - 41:34] TypeRef=type:39:13
+// CHECK: Identifier: "type" [41:30 - 41:34] TypeRef=X2::type:39:13
 // CHECK: Punctuation: ">" [41:34 - 41:35] UsingDeclaration=push_back:41:37
 // CHECK: Punctuation: "::" [41:35 - 41:37] UsingDeclaration=push_back:41:37
 // CHECK: Identifier: "push_back" [41:37 - 41:46] UsingDeclaration=push_back:41:37
@@ -266,7 +266,7 @@
 // CHECK: Identifier: "vector" [57:51 - 57:57] TemplateRef=vector:4:12
 // CHECK: Punctuation: "<" [57:57 - 57:58] MemberRefExpr=
 // CHECK: Identifier: "T" [57:58 - 57:59] TypeRef=T:54:19
-// CHECK: Punctuation: ">" [57:59 - 57:60] CallExpr=
+// CHECK: Punctuation: ">" [57:59 - 57:60] MemberRefExpr=
 // CHECK: Punctuation: "(" [57:60 - 57:61] CallExpr=
 // CHECK: Punctuation: ")" [57:61 - 57:62] CallExpr=
 
@@ -283,7 +283,7 @@
 // CHECK: Punctuation: "::" [76:5 - 76:7] MemberRefExpr=[71:8, 72:8]
 // CHECK: Identifier: "X4" [76:7 - 76:9] TemplateRef=X4:69:8
 // CHECK: Punctuation: "<" [76:9 - 76:10] MemberRefExpr=[71:8, 72:8]
-// CHECK: Identifier: "type" [76:10 - 76:14] TypeRef=type:70:13
+// CHECK: Identifier: "type" [76:10 - 76:14] TypeRef=X4::type:70:13
 // CHECK: Punctuation: ">" [76:14 - 76:15] MemberRefExpr=[71:8, 72:8]
 // CHECK: Punctuation: "::" [76:15 - 76:17] MemberRefExpr=[71:8, 72:8]
 // CHECK: Identifier: "g" [76:17 - 76:18] OverloadedDeclRef=g[71:8, 72:8]
@@ -296,7 +296,7 @@
 // CHECK: Punctuation: "::" [77:11 - 77:13] MemberRefExpr=
 // CHECK: Identifier: "X4" [77:13 - 77:15] TemplateRef=X4:69:8
 // CHECK: Punctuation: "<" [77:15 - 77:16] MemberRefExpr=
-// CHECK: Identifier: "type" [77:16 - 77:20] TypeRef=type:70:13
+// CHECK: Identifier: "type" [77:16 - 77:20] TypeRef=X4::type:70:13
 // CHECK: Punctuation: ">" [77:20 - 77:21] MemberRefExpr=
 // CHECK: Punctuation: "::" [77:21 - 77:23] MemberRefExpr=
 // CHECK: Identifier: "g" [77:23 - 77:24] MemberRefExpr=
@@ -318,7 +318,7 @@
 // CHECK: Punctuation: "::" [91:5 - 91:7] MemberRefExpr=g:86:8
 // CHECK: Identifier: "X4" [91:7 - 91:9] TemplateRef=X4:69:8
 // CHECK: Punctuation: "<" [91:9 - 91:10] MemberRefExpr=g:86:8
-// CHECK: Identifier: "type" [91:10 - 91:14] TypeRef=type:84:19
+// CHECK: Identifier: "type" [91:10 - 91:14] TypeRef=X4<int>::type:84:19
 // CHECK: Punctuation: ">" [91:14 - 91:15] MemberRefExpr=g:86:8
 // CHECK: Punctuation: "::" [91:15 - 91:17] MemberRefExpr=g:86:8
 // CHECK: Identifier: "g" [91:17 - 91:18] MemberRefExpr=g:86:8
@@ -331,7 +331,7 @@
 // CHECK: Punctuation: "::" [92:11 - 92:13] MemberRefExpr=g:86:8
 // CHECK: Identifier: "X4" [92:13 - 92:15] TemplateRef=X4:69:8
 // CHECK: Punctuation: "<" [92:15 - 92:16] MemberRefExpr=g:86:8
-// CHECK: Identifier: "type" [92:16 - 92:20] TypeRef=type:84:19
+// CHECK: Identifier: "type" [92:16 - 92:20] TypeRef=X4<int>::type:84:19
 // CHECK: Punctuation: ">" [92:20 - 92:21] MemberRefExpr=g:86:8
 // CHECK: Punctuation: "::" [92:21 - 92:23] MemberRefExpr=g:86:8
 // CHECK: Identifier: "g" [92:23 - 92:24] MemberRefExpr=g:86:8
@@ -348,7 +348,7 @@
 // CHECK: Punctuation: "::" [100:38 - 100:40] TypedefDecl=iter_type:100:63 (Definition)
 // CHECK: Identifier: "vector" [100:40 - 100:46] TemplateRef=vector:4:12
 // CHECK: Punctuation: "<" [100:46 - 100:47] TypedefDecl=iter_type:100:63 (Definition)
-// CHECK: Identifier: "type" [100:47 - 100:51] TypeRef=type:99:13
+// CHECK: Identifier: "type" [100:47 - 100:51] TypeRef=X5::type:99:13
 // CHECK: Punctuation: ">" [100:51 - 100:52] TypedefDecl=iter_type:100:63 (Definition)
 // CHECK: Punctuation: "::" [100:52 - 100:54] TypedefDecl=iter_type:100:63 (Definition)
 // CHECK: Identifier: "iterator" [100:54 - 100:62] TypedefDecl=iter_type:100:63 (Definition)
@@ -365,7 +365,7 @@
 // CHECK: Keyword: "int" [101:47 - 101:50] TypedefDecl=int_ptr_type:101:62 (Definition)
 // CHECK: Punctuation: ">" [101:50 - 101:51] TypedefDecl=int_ptr_type:101:62 (Definition)
 // CHECK: Punctuation: "::" [101:51 - 101:53] TypedefDecl=int_ptr_type:101:62 (Definition)
-// CHECK: Identifier: "iterator" [101:53 - 101:61] TypeRef=iterator:5:18
+// CHECK: Identifier: "iterator" [101:53 - 101:61] TypeRef=outer::inner::vector<int>::iterator:5:18
 // CHECK: Identifier: "int_ptr_type" [101:62 - 101:74] TypedefDecl=int_ptr_type:101:62 (Definition)
 
 // Dependent template specialization types
@@ -376,13 +376,13 @@
 // CHECK: Punctuation: "::" [107:38 - 107:40] TypedefDecl=type1:107:76 (Definition)
 // CHECK: Identifier: "vector" [107:40 - 107:46] TemplateRef=vector:4:12
 // CHECK: Punctuation: "<" [107:46 - 107:47] TypedefDecl=type1:107:76 (Definition)
-// CHECK: Identifier: "type" [107:47 - 107:51] TypeRef=type:106:14
+// CHECK: Identifier: "type" [107:47 - 107:51] TypeRef=X6::type:106:14
 // CHECK: Punctuation: ">" [107:51 - 107:52] TypedefDecl=type1:107:76 (Definition)
 // CHECK: Punctuation: "::" [107:52 - 107:54] TypedefDecl=type1:107:76 (Definition)
 // CHECK: Keyword: "template" [107:54 - 107:62] TypedefDecl=type1:107:76 (Definition)
 // CHECK: Identifier: "rebind" [107:63 - 107:69] TypedefDecl=type1:107:76 (Definition)
 // CHECK: Punctuation: "<" [107:69 - 107:70] TypedefDecl=type1:107:76 (Definition)
-// CHECK: Identifier: "type" [107:70 - 107:74] TypeRef=type:106:14
+// CHECK: Identifier: "type" [107:70 - 107:74] TypeRef=X6::type:106:14
 // CHECK: Punctuation: ">" [107:74 - 107:75] TypedefDecl=type1:107:76 (Definition)
 // CHECK: Identifier: "type1" [107:76 - 107:81] TypedefDecl=type1:107:76 (Definition)
 
@@ -394,13 +394,13 @@
 // CHECK: Punctuation: "::" [108:38 - 108:40] TypedefDecl=type2:108:83 (Definition)
 // CHECK: Identifier: "vector" [108:40 - 108:46] TemplateRef=vector:4:12
 // CHECK: Punctuation: "<" [108:46 - 108:47] TypedefDecl=type2:108:83 (Definition)
-// CHECK: Identifier: "type" [108:47 - 108:51] TypeRef=type:106:14
+// CHECK: Identifier: "type" [108:47 - 108:51] TypeRef=X6::type:106:14
 // CHECK: Punctuation: ">" [108:51 - 108:52] TypedefDecl=type2:108:83 (Definition)
 // CHECK: Punctuation: "::" [108:52 - 108:54] TypedefDecl=type2:108:83 (Definition)
 // CHECK: Keyword: "template" [108:54 - 108:62] TypedefDecl=type2:108:83 (Definition)
 // CHECK: Identifier: "rebind" [108:63 - 108:69] TypedefDecl=type2:108:83 (Definition)
 // CHECK: Punctuation: "<" [108:69 - 108:70] TypedefDecl=type2:108:83 (Definition)
-// CHECK: Identifier: "type" [108:70 - 108:74] TypeRef=type:106:14
+// CHECK: Identifier: "type" [108:70 - 108:74] TypeRef=X6::type:106:14
 // CHECK: Punctuation: ">" [108:74 - 108:75] TypedefDecl=type2:108:83 (Definition)
 // CHECK: Punctuation: "::" [108:75 - 108:77] TypedefDecl=type2:108:83 (Definition)
 // CHECK: Identifier: "other" [108:77 - 108:82] TypedefDecl=type2:108:83 (Definition)
@@ -414,13 +414,13 @@
 // CHECK: Punctuation: "::" [109:35 - 109:37] TypedefDecl=type3:109:73 (Definition)
 // CHECK: Identifier: "vector" [109:37 - 109:43] TemplateRef=vector:4:12
 // CHECK: Punctuation: "<" [109:43 - 109:44] TypedefDecl=type3:109:73 (Definition)
-// CHECK: Identifier: "type" [109:44 - 109:48] TypeRef=type:106:14
+// CHECK: Identifier: "type" [109:44 - 109:48] TypeRef=X6::type:106:14
 // CHECK: Punctuation: ">" [109:48 - 109:49] TypedefDecl=type3:109:73 (Definition)
 // CHECK: Punctuation: "::" [109:49 - 109:51] TypedefDecl=type3:109:73 (Definition)
 // CHECK: Keyword: "template" [109:51 - 109:59] TypedefDecl=type3:109:73 (Definition)
 // CHECK: Identifier: "rebind" [109:60 - 109:66] TypedefDecl=type3:109:73 (Definition)
 // CHECK: Punctuation: "<" [109:66 - 109:67] TypedefDecl=type3:109:73 (Definition)
-// CHECK: Identifier: "type" [109:67 - 109:71] TypeRef=type:106:14
+// CHECK: Identifier: "type" [109:67 - 109:71] TypeRef=X6::type:106:14
 // CHECK: Punctuation: ">" [109:71 - 109:72] TypedefDecl=type3:109:73 (Definition)
 // CHECK: Identifier: "type3" [109:73 - 109:78] TypedefDecl=type3:109:73 (Definition)
 
@@ -431,13 +431,13 @@
 // CHECK: Punctuation: "::" [110:35 - 110:37] TypedefDecl=type4:110:80 (Definition)
 // CHECK: Identifier: "vector" [110:37 - 110:43] TemplateRef=vector:4:12
 // CHECK: Punctuation: "<" [110:43 - 110:44] TypedefDecl=type4:110:80 (Definition)
-// CHECK: Identifier: "type" [110:44 - 110:48] TypeRef=type:106:14
+// CHECK: Identifier: "type" [110:44 - 110:48] TypeRef=X6::type:106:14
 // CHECK: Punctuation: ">" [110:48 - 110:49] TypedefDecl=type4:110:80 (Definition)
 // CHECK: Punctuation: "::" [110:49 - 110:51] TypedefDecl=type4:110:80 (Definition)
 // CHECK: Keyword: "template" [110:51 - 110:59] TypedefDecl=type4:110:80 (Definition)
 // CHECK: Identifier: "rebind" [110:60 - 110:66] TypedefDecl=type4:110:80 (Definition)
 // CHECK: Punctuation: "<" [110:66 - 110:67] TypedefDecl=type4:110:80 (Definition)
-// CHECK: Identifier: "type" [110:67 - 110:71] TypeRef=type:106:14
+// CHECK: Identifier: "type" [110:67 - 110:71] TypeRef=X6::type:106:14
 // CHECK: Punctuation: ">" [110:71 - 110:72] TypedefDecl=type4:110:80 (Definition)
 // CHECK: Punctuation: "::" [110:72 - 110:74] TypedefDecl=type4:110:80 (Definition)
 // CHECK: Identifier: "other" [110:74 - 110:79] TypedefDecl=type4:110:80 (Definition)
@@ -451,9 +451,9 @@
 // CHECK: Punctuation: "::" [126:29 - 126:31] TypedefDecl=type:126:74 (Definition)
 // CHECK: Identifier: "apply_meta" [126:31 - 126:41] TemplateRef=apply_meta:116:12
 // CHECK: Punctuation: "<" [126:41 - 126:42] TypedefDecl=type:126:74 (Definition)
-// CHECK: Identifier: "T_type" [126:42 - 126:48] TypeRef=T_type:124:13
+// CHECK: Identifier: "T_type" [126:42 - 126:48] TypeRef=X7::T_type:124:13
 // CHECK: Punctuation: "," [126:48 - 126:49] TypedefDecl=type:126:74 (Definition)
-// CHECK: Identifier: "U_type" [126:50 - 126:56] TypeRef=U_type:125:13
+// CHECK: Identifier: "U_type" [126:50 - 126:56] TypeRef=X7::U_type:125:13
 // CHECK: Punctuation: "::" [126:56 - 126:58] TypedefDecl=type:126:74 (Definition)
 // CHECK: Keyword: "template" [126:58 - 126:66] TypedefDecl=type:126:74 (Definition)
 // CHECK: Identifier: "apply" [126:67 - 126:72] TypedefDecl=type:126:74 (Definition)
@@ -461,6 +461,6 @@
 // CHECK: Identifier: "type" [126:74 - 126:78] TypedefDecl=type:126:74 (Definition)
 
 // Member access expressions
-// CHECK: Identifier: "inherited" [136:5 - 136:14] TypeRef=inherited:134:14
+// CHECK: Identifier: "inherited" [136:5 - 136:14] TypeRef=X9::inherited:134:14
 // CHECK: Punctuation: "::" [136:14 - 136:16] MemberRefExpr=f:130:8
 // CHECK: Identifier: "f" [136:16 - 136:17] MemberRefExpr=f:130:8
diff --git a/test/Index/comment-cplus-decls.cpp b/test/Index/comment-cplus-decls.cpp
index d4f968f..463aa9e 100644
--- a/test/Index/comment-cplus-decls.cpp
+++ b/test/Index/comment-cplus-decls.cpp
@@ -2,9 +2,15 @@
 // RUN: mkdir %t
 // RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng -target x86_64-apple-darwin10 %s > %t/out
 // RUN: FileCheck %s < %t/out
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng -target x86_64-apple-darwin10 -std=c++98 %s > %t/98
+// RUN: FileCheck %s < %t/98
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng -target x86_64-apple-darwin10 -std=c++11 %s > %t/11
+// RUN: FileCheck %s < %t/11
 
 // Ensure that XML we generate is not invalid.
 // RUN: FileCheck %s -check-prefix=WRONG < %t/out
+// RUN: FileCheck %s -check-prefix=WRONG < %t/98
+// RUN: FileCheck %s -check-prefix=WRONG < %t/11
 // WRONG-NOT: CommentXMLInvalid
 // rdar://12378714
 
@@ -42,7 +48,7 @@
 // CHECK: <Declaration>class Test {}</Declaration>
 // CHECK: <Declaration>Test() : reserved(new Test::data()) {}</Declaration>
 // CHECK: <Declaration>unsigned int getID() const</Declaration>
-// CHECK: <Declaration>~Test()</Declaration>
+// CHECK: <Declaration>~Test(){{( noexcept)?}}</Declaration>
 // CHECK: <Declaration>Test::data *reserved</Declaration>
 
 
diff --git a/test/Index/complete-block-properties.m b/test/Index/complete-block-properties.m
index d166147..a754712 100644
--- a/test/Index/complete-block-properties.m
+++ b/test/Index/complete-block-properties.m
@@ -43,7 +43,7 @@
 //CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText block}{LeftParen (}{RightParen )} (35)
 //CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void (^)()}{TypedText block}{Equal  = }{Placeholder ^(void)} (38)
 //CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Foo}{TypedText blocker}{LeftParen (}{Placeholder int x}{Comma , }{Placeholder Foo y}{Comma , }{Placeholder ^(Foo *someParameter)foo}{RightParen )} (35)
-//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Foo (^)(int, Foo, FooBlock)}{TypedText blocker}{Equal  = }{Placeholder ^Foo(int x, Foo y, FooBlock foo)} (38)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Foo (^)(int, Foo, FooBlock)}{TypedText blocker}{Equal  = }{Placeholder ^Foo(int x, Foo y, FooBlock foo)} (32)
 //CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35)
 //CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText fooBlock}{LeftParen (}{Placeholder Foo *someParameter}{RightParen )} (35)
 //CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Test *}{TypedText getObject}{LeftParen (}{Placeholder int index}{RightParen )} (35)
@@ -68,8 +68,8 @@
 // RUN: c-index-test -code-completion-at=%s:65:6 %s | FileCheck -check-prefix=CHECK-CC2 %s
 //CHECK-CC2: ObjCInstanceMethodDecl:{ResultType void (^)(void)}{TypedText blockProperty} (35)
 //CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType BarBlock}{TypedText blockProperty2} (35)
-//CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlockProperty2:}{Placeholder BarBlock blockProperty2} (35)
-//CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlockProperty:}{Placeholder void (^)(void)blockProperty} (35)
+//CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlockProperty2:}{Placeholder ^int(int *)blockProperty2} (35)
+//CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlockProperty:}{Placeholder ^(void)blockProperty} (35)
 
 @interface ClassProperties
 
@@ -86,3 +86,9 @@
 //CHECK-CC3: ObjCPropertyDecl:{ResultType void}{TypedText explicit}{LeftParen (}{RightParen )} (35)
 //CHECK-CC3-NEXT: ObjCPropertyDecl:{ResultType void (^)()}{TypedText explicit}{Equal  = }{Placeholder ^(void)} (38)
 //CHECK-CC3-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText explicitReadonly}{LeftParen (}{RightParen )} (35)
+
+void implicitSetterBlockPlaceholder(Test* test) {
+  [test setBlock: ^{}];
+}
+// RUN: c-index-test -code-completion-at=%s:91:9 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlocker:}{Placeholder ^Foo(int x, Foo y, FooBlock foo)blocker} (37)
diff --git a/test/Index/complete-block-property-assignment.m b/test/Index/complete-block-property-assignment.m
index ced3b7f..908e186 100644
--- a/test/Index/complete-block-property-assignment.m
+++ b/test/Index/complete-block-property-assignment.m
@@ -15,6 +15,7 @@
 @interface Test : Obj
 @property (readwrite, nonatomic, copy) FooBlock onEventHandler;
 @property (readonly, nonatomic, copy) void (^onReadonly)(int *someParameter);
+@property (readwrite, nonatomic, copy) int (^processEvent)(int eventCode);
 @property (readonly, nonatomic, strong) Obj *obj;
 @end
 
@@ -29,10 +30,10 @@
   SELFY.foo = 2
 }
 
-// RUN: c-index-test -code-completion-at=%s:26:8 %s | FileCheck -check-prefix=CHECK-CC1 %s
-// RUN: c-index-test -code-completion-at=%s:27:27 %s | FileCheck -check-prefix=CHECK-CC1 %s
-// RUN: c-index-test -code-completion-at=%s:28:22 %s | FileCheck -check-prefix=CHECK-CC1 %s
-// RUN: c-index-test -code-completion-at=%s:29:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:27:8 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:28:27 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:29:22 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:30:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35)
 // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35)
 // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onAction}{LeftParen (}{Placeholder Obj *object}{RightParen )} (35)
@@ -40,6 +41,8 @@
 // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onEventHandler}{LeftParen (}{Placeholder Foo *someParameter}{RightParen )} (35)
 // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler}{Equal  = }{Placeholder ^(Foo *someParameter)} (38)
 // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onReadonly}{LeftParen (}{Placeholder int *someParameter}{RightParen )} (35)
+// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText processEvent}{LeftParen (}{Placeholder int eventCode}{RightParen )} (35)
+// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent}{Equal  = }{Placeholder ^int(int eventCode)} (32)
 
 - (void) takeInt:(int)x { }
 
@@ -53,16 +56,17 @@
   return self.foo;
 }
 
-// RUN: c-index-test -code-completion-at=%s:47:9 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:48:16 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:49:23 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:50:12 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:51:15 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:53:15 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:50:9 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:51:16 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:52:23 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:53:12 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:54:15 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:56:15 %s | FileCheck -check-prefix=CHECK-NO %s
 // CHECK-NO: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText onReadonly} (35)
+// CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent} (35)
 
 @end
diff --git a/test/Index/complete-cached-globals.cpp b/test/Index/complete-cached-globals.cpp
new file mode 100644
index 0000000..791faf2
--- /dev/null
+++ b/test/Index/complete-cached-globals.cpp
@@ -0,0 +1,25 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+namespace SomeNamespace {
+    class SomeClass {
+    };
+    void SomeFunction();
+}
+
+using SomeNamespace::SomeClass;
+using SomeNamespace::SomeFunction;
+
+static void foo() {
+  return;
+}
+
+// rdar://23454249
+
+// RUN: c-index-test -code-completion-at=%s:14:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+
+// CHECK-CC1: ClassDecl:{TypedText SomeClass} (50)
+// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText SomeFunction}{LeftParen (}{RightParen )} (50)
+// CHECK-CC1-NOT: {Text SomeNamespace::}{TypedText SomeClass}
+// CHECK-CC1-NOT: {Text SomeNamespace::}{TypedText SomeFunction}
diff --git a/test/Index/complete-designated-initializer.m b/test/Index/complete-designated-initializer.m
new file mode 100644
index 0000000..4ccafc2
--- /dev/null
+++ b/test/Index/complete-designated-initializer.m
@@ -0,0 +1,43 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+// rdar://21014571
+
+#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
+
+@interface DesignatedInitializerCompletion
+
+- (instancetype)init ;
+- (instancetype)initWithFoo:(int)foo ;
+- (instancetype)initWithX:(int)x andY:(int)y ;
+
+@end
+
+@implementation DesignatedInitializerCompletion
+
+- (instancetype)init {
+}
+
+- (instancetype)initWithFoo:(int)foo {
+}
+
+- (instancetype)initWithX:(int)x andY:(int)y {
+}
+
+@end
+
+// RUN: c-index-test -code-completion-at=%s:10:22 %s | FileCheck %s
+// RUN: c-index-test -code-completion-at=%s:11:38 %s | FileCheck %s
+// RUN: c-index-test -code-completion-at=%s:11:29 %s | FileCheck -check-prefix=CHECK-NONE %s
+// RUN: c-index-test -code-completion-at=%s:11:34 %s | FileCheck -check-prefix=CHECK-NONE %s
+// RUN: c-index-test -code-completion-at=%s:12:34 %s | FileCheck %s
+// RUN: c-index-test -code-completion-at=%s:12:46 %s | FileCheck %s
+
+// RUN: c-index-test -code-completion-at=%s:18:22 %s | FileCheck %s
+// RUN: c-index-test -code-completion-at=%s:21:38 %s | FileCheck %s
+// RUN: c-index-test -code-completion-at=%s:24:34 %s | FileCheck %s
+// RUN: c-index-test -code-completion-at=%s:24:46 %s | FileCheck %s
+
+// CHECK: macro definition:{TypedText NS_DESIGNATED_INITIALIZER} (70)
+
+// CHECK-NONE-NOT: NS_DESIGNATED_INITIALIZER
diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m
index e3fce6b..c2b0670 100644
--- a/test/Index/complete-objc-message.m
+++ b/test/Index/complete-objc-message.m
@@ -346,3 +346,54 @@
 
 // RUN: c-index-test -code-completion-at=%s:197:6 %s | FileCheck -check-prefix=CHECK-NULLABLE %s
 // CHECK-NULLABLE: ObjCInstanceMethodDecl:{ResultType A * _Nonnull}{TypedText method:}{Placeholder (nullable A *)}
+
+// rdar://28012953
+// Code completion results should include instance methods from RootProtocol and
+// RootClass when completing a method invocation for a RootClass object because
+// RootClasses metaclass subclasses from RootClass (i.e. RootClass is actually
+// an instance of RootClass).
+
+@protocol SubRootProtocol
+
+- (void)subProtocolInstanceMethod;
+
+@end
+
+@protocol RootProtocol <SubRootProtocol>
+
+- (void)protocolInstanceMethod;
++ (void)protocolClassMethod;
+
+@end
+
+@interface RootClass <RootProtocol>
+
+- (void)instanceMethod;
++ (void)classMethod;
+
+@end
+
+@protocol RootCategoryProtocol
+
+- (void)categoryProtocolInstanceMethod;
+
+@end
+
+@interface RootClass (Cat) <RootCategoryProtocol>
+
+- (void)categoryInstanceMethod;
+
+@end
+
+void completeAllTheRootThings() {
+  [RootClass classMethod];
+}
+
+// RUN: c-index-test -code-completion-at=%s:389:14 %s | FileCheck -check-prefix=CHECK-ROOT %s
+// CHECK-ROOT: ObjCInstanceMethodDecl:{ResultType void}{TypedText categoryInstanceMethod} (35)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText categoryProtocolInstanceMethod} (37)
+// CHECK-ROOT-NEXT: ObjCClassMethodDecl:{ResultType void}{TypedText classMethod} (35)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText instanceMethod} (35)
+// CHECK-ROOT-NEXT: ObjCClassMethodDecl:{ResultType void}{TypedText protocolClassMethod} (37)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText protocolInstanceMethod} (37)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText subProtocolInstanceMethod} (37)
diff --git a/test/Index/complete-preamble.h b/test/Index/complete-preamble.h
index e696284..1972c2a 100644
--- a/test/Index/complete-preamble.h
+++ b/test/Index/complete-preamble.h
@@ -1,6 +1,11 @@
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+
 namespace std {
   void wibble();
 }
 
+#pragma clang diagnostic pop
+
 namespace std {
 }
diff --git a/test/Index/file-refs.cpp b/test/Index/file-refs.cpp
index c5a728b..a645527 100644
--- a/test/Index/file-refs.cpp
+++ b/test/Index/file-refs.cpp
@@ -98,7 +98,7 @@
 // RUN:  -file-refs-at=%s:44:16 \
 // CHECK-NEXT: CallExpr=S:35:3
 // CHECK-NEXT: TypedefDecl=Cake:39:11 (Definition) =[39:11 - 39:15]
-// CHECK-NEXT: TypeRef=Cake:39:11 =[42:3 - 42:7]
-// CHECK-NEXT: TypeRef=Cake:39:11 =[44:14 - 44:18]
+// CHECK-NEXT: TypeRef=Test2::Cake:39:11 =[42:3 - 42:7]
+// CHECK-NEXT: TypeRef=Test2::Cake:39:11 =[44:14 - 44:18]
 
 // RUN:   %s | FileCheck %s
diff --git a/test/Index/get-cursor.cpp b/test/Index/get-cursor.cpp
index a2c4693..27f7593 100644
--- a/test/Index/get-cursor.cpp
+++ b/test/Index/get-cursor.cpp
@@ -143,6 +143,8 @@
   }
 }
 
+const int operator""_toint(unsigned long long val) { return int(val); }
+
 // RUN: c-index-test -cursor-at=%s:6:4 %s | FileCheck -check-prefix=CHECK-COMPLETION-1 %s
 // CHECK-COMPLETION-1: CXXConstructor=X:6:3
 // CHECK-COMPLETION-1-NEXT: Completion string: {TypedText X}{LeftParen (}{Placeholder int}{Comma , }{Placeholder int}{RightParen )}
@@ -207,7 +209,7 @@
 // RUN: c-index-test -cursor-at=%s:66:23 %s | FileCheck -check-prefix=CHECK-TEMPLSPEC %s
 // CHECK-TEMPLSPEC: 66:23 ClassDecl=TC:66:23 (Definition) [Specialization of TC:59:7] Extent=[66:1 - 66:31] Spelling=TC ([66:23 - 66:25])
 
-// RUN: c-index-test -cursor-at=%s:69:3 -cursor-at=%s:70:11 -cursor-at=%s:73:6 -cursor-at=%s:74:6 -cursor-at=%s:77:8 -cursor-at=%s:78:8 -cursor-at=%s:79:8 -cursor-at=%s:80:8 -cursor-at=%s:81:8 -cursor-at=%s:82:8 -cursor-at=%s:85:6 -cursor-at=%s:86:6 -cursor-at=%s:87:6 -cursor-at=%s:88:6 -cursor-at=%s:91:5 -cursor-at=%s:92:5 -cursor-at=%s:93:5 -cursor-at=%s:94:5 -cursor-at=%s:95:5 -cursor-at=%s:96:5 -cursor-at=%s:97:5 -cursor-at=%s:98:5 -cursor-at=%s:100:5 -cursor-at=%s:101:5 -cursor-at=%s:104:6 -cursor-at=%s:105:6 -cursor-at=%s:106:6 -cursor-at=%s:107:6 -cursor-at=%s:108:6 -cursor-at=%s:109:6 -cursor-at=%s:110:6 -cursor-at=%s:111:6 -cursor-at=%s:113:6 -cursor-at=%s:114:6 -cursor-at=%s:117:8 -cursor-at=%s:118:8 -cursor-at=%s:120:8 -cursor-at=%s:121:8 -cursor-at=%s:122:8 -cursor-at=%s:123:8 -cursor-at=%s:124:8 -cursor-at=%s:125:8 -cursor-at=%s:128:6 -cursor-at=%s:129:6 -cursor-at=%s:130:6 -cursor-at=%s:132:3 -std=c++11 %s | FileCheck -check-prefix=CHECK-SPELLING %s
+// RUN: c-index-test -cursor-at=%s:69:3 -cursor-at=%s:70:11 -cursor-at=%s:73:6 -cursor-at=%s:74:6 -cursor-at=%s:77:8 -cursor-at=%s:78:8 -cursor-at=%s:79:8 -cursor-at=%s:80:8 -cursor-at=%s:81:8 -cursor-at=%s:82:8 -cursor-at=%s:85:6 -cursor-at=%s:86:6 -cursor-at=%s:87:6 -cursor-at=%s:88:6 -cursor-at=%s:91:5 -cursor-at=%s:92:5 -cursor-at=%s:93:5 -cursor-at=%s:94:5 -cursor-at=%s:95:5 -cursor-at=%s:96:5 -cursor-at=%s:97:5 -cursor-at=%s:98:5 -cursor-at=%s:100:5 -cursor-at=%s:101:5 -cursor-at=%s:104:6 -cursor-at=%s:105:6 -cursor-at=%s:106:6 -cursor-at=%s:107:6 -cursor-at=%s:108:6 -cursor-at=%s:109:6 -cursor-at=%s:110:6 -cursor-at=%s:111:6 -cursor-at=%s:113:6 -cursor-at=%s:114:6 -cursor-at=%s:117:8 -cursor-at=%s:118:8 -cursor-at=%s:120:8 -cursor-at=%s:121:8 -cursor-at=%s:122:8 -cursor-at=%s:123:8 -cursor-at=%s:124:8 -cursor-at=%s:125:8 -cursor-at=%s:128:6 -cursor-at=%s:129:6 -cursor-at=%s:130:6 -cursor-at=%s:132:3 -cursor-at=%s:146:15 -std=c++11 %s | FileCheck -check-prefix=CHECK-SPELLING %s
 // CHECK-SPELLING: 69:3 CXXConstructor=A:69:3 (default constructor) Extent=[69:3 - 69:6] Spelling=A ([69:3 - 69:4])
 // CHECK-SPELLING: 70:11 CXXDestructor=~A:70:11 (virtual) Extent=[70:3 - 70:15] Spelling=~A ([70:11 - 70:13])
 // CHECK-SPELLING: 73:6 CXXMethod=operator=:73:6 Extent=[73:3 - 73:25] Spelling=operator= ([73:6 - 73:15])
@@ -254,6 +256,7 @@
 // CHECK-SPELLING: 129:6 CXXMethod=operator->:129:6 Extent=[129:3 - 129:18] Spelling=operator-> ([129:6 - 129:16])
 // CHECK-SPELLING: 130:6 CXXMethod=operator():130:6 (const) Extent=[130:3 - 130:37] Spelling=operator() ([130:6 - 130:16])
 // CHECK-SPELLING: 132:12 CXXConversion=operator bool:132:12 (const) Extent=[132:3 - 132:33] Spelling=operator bool ([132:12 - 132:25])
+// CHECK-SPELLING: 146:11 FunctionDecl=operator""_toint:146:11 (Definition) Extent=[146:1 - 146:72] Spelling=operator""_toint ([146:11 - 146:27])
 
 // RUN: c-index-test -cursor-at=%s:141:13 -cursor-at=%s:141:18 -cursor-at=%s:142:11 -std=c++11 %s | FileCheck -check-prefix=CHECK-FORRANGE %s
 // CHECK-FORRANGE: 141:13 VarDecl=lv:141:13 (Definition) Extent=[141:8 - 141:17] Spelling=lv ([141:13 - 141:15])
diff --git a/test/Index/index-decls.m b/test/Index/index-decls.m
index a39d9e3..a5368ec 100644
--- a/test/Index/index-decls.m
+++ b/test/Index/index-decls.m
@@ -58,15 +58,15 @@
 // RUN: c-index-test -index-file %s -target x86_64-apple-macosx10.7 > %t
 // RUN: FileCheck %s -input-file=%t
 // CHECK: [indexDeclaration]: kind: objc-class | name: I | {{.*}} | loc: 1:12
-// CHECK: [indexDeclaration]: kind: objc-instance-method | name: prop | {{.*}} | loc: 3:2
+// CHECK: [indexDeclaration]: kind: objc-instance-method | name: prop | {{.*}} | loc: 3:7
 // CHECK: [indexDeclaration]: kind: objc-property | name: prop | {{.*}} | loc: 2:25
 // CHECK: [indexDeclaration]: kind: objc-category | name:  | {{.*}} | loc: 6:12
 // CHECK: [indexDeclaration]: kind: objc-instance-method | name: setProp: | {{.*}} | loc: 7:33
 // CHECK: [indexDeclaration]: kind: objc-property | name: prop | {{.*}} | loc: 7:33
 
-// CHECK: [indexDeclaration]: kind: objc-ivar | name: _prop | {{.*}} | loc: 11:20
 // CHECK: [indexDeclaration]: kind: objc-instance-method | name: prop | {{.*}} | loc: 11:13 | {{.*}} | lexical-container: [I:10:17]
 // CHECK: [indexDeclaration]: kind: objc-instance-method | name: setProp: | {{.*}} | loc: 11:13 | {{.*}} | lexical-container: [I:10:17]
+// CHECK: [indexDeclaration]: kind: objc-ivar | name: _prop | {{.*}} | loc: 11:20
 
 // CHECK: [indexDeclaration]: kind: objc-ivar | name: _auto_prop | {{.*}} | loc: 20:33
 // CHECK: [indexEntityReference]: kind: objc-ivar | name: _auto_prop | {{.*}} | loc: 25:3
@@ -82,5 +82,5 @@
 // CHECK-NOT: [indexDeclaration]: kind: objc-instance-method {{.*}} loc: 37:
 // CHECK-NOT: [indexDeclaration]: kind: objc-instance-method {{.*}} loc: 43:
 
-// CHECK: [indexDeclaration]: kind: objc-instance-method | name: meth | {{.*}} loc: 54:1 | {{.*}} | isRedecl: 0 | isDef: 0 |
+// CHECK: [indexDeclaration]: kind: objc-instance-method | name: meth | {{.*}} loc: 54:8 | {{.*}} | isRedecl: 0 | isDef: 0 |
 // CHECK: [indexDeclaration]: kind: objc-property | name: c | USR: c:objc(cs)I5(cpy)c | lang: ObjC | cursor: ObjCPropertyDecl=c:55:23 [class,] | loc: 55:23
diff --git a/test/Index/index-module.m b/test/Index/index-module.m
index d1c0b36..51faea2 100644
--- a/test/Index/index-module.m
+++ b/test/Index/index-module.m
@@ -52,7 +52,7 @@
 // CHECK-TMOD-NEXT: [indexDeclaration]: kind: objc-class | name: Module | {{.*}} | loc: [[TMOD_MODULE_H]]:15:12
 // CHECK-TMOD-NEXT:      <ObjCContainerInfo>: kind: interface
 // CHECK-TMOD-NEXT: [indexDeclaration]: kind: objc-class-method | name: version | {{.*}} | loc: [[TMOD_MODULE_H]]:16:1
-// CHECK-TMOD-NEXT: [indexDeclaration]: kind: objc-class-method | name: alloc | {{.*}} | loc: [[TMOD_MODULE_H]]:17:1
+// CHECK-TMOD-NEXT: [indexDeclaration]: kind: objc-class-method | name: alloc | {{.*}} | loc: [[TMOD_MODULE_H]]:17:2
 // CHECK-TMOD-NEXT: [indexDeclaration]: kind: typedef | name: FILE | {{.*}} | loc: [[TMOD_MODULE_H]]:30:3
 // CHECK-TMOD-NEXT: [indexDeclaration]: kind: struct | name: __sFILE | {{.*}} | loc: [[TMOD_MODULE_H]]:28:16
 // CHECK-TMOD-NEXT: [indexDeclaration]: kind: field | name: _offset | {{.*}} | loc: [[TMOD_MODULE_H]]:29:7
diff --git a/test/Index/index-templates.cpp b/test/Index/index-templates.cpp
index 79b9c18..966cc4f 100644
--- a/test/Index/index-templates.cpp
+++ b/test/Index/index-templates.cpp
@@ -49,9 +49,9 @@
 struct Z4 {
   template<typename T> T getAs();
 };
-
+template<typename T, T> struct value { };
 void template_exprs() {
-  f<Unsigned, OneDimension, array>(array<Unsigned, OneDimension>());
+  f<Unsigned, OneDimension, value>(value<Unsigned, OneDimension>());
   Z4().getAs<Unsigned>();
 }
 
@@ -173,7 +173,7 @@
 // CHECK-LOAD: index-templates.cpp:54:3: DeclRefExpr=f:4:6 RefName=[54:3 - 54:4] RefName=[54:4 - 54:35] Extent=[54:3 - 54:35]
 // CHECK-LOAD: index-templates.cpp:54:5: TypeRef=Unsigned:42:18 Extent=[54:5 - 54:13]
 // CHECK-LOAD: index-templates.cpp:54:15: DeclRefExpr=OneDimension:35:16 Extent=[54:15 - 54:27]
-// CHECK-LOAD: index-templates.cpp:54:29: TemplateRef=array:37:8 Extent=[54:29 - 54:34]
+// CHECK-LOAD: index-templates.cpp:54:29: TemplateRef=value:52:32 Extent=[54:29 - 54:34]
 // CHECK-LOAD: index-templates.cpp:55:8: MemberRefExpr=getAs:50:26 SingleRefName=[55:8 - 55:13] RefName=[55:8 - 55:13] Extent=[55:3 - 55:23]
 // CHECK-LOAD: index-templates.cpp:55:3: CallExpr=Z4:49:8 Extent=[55:3 - 55:7]
 // CHECK-LOAD: index-templates.cpp:55:14: TypeRef=Unsigned:42:18 Extent=[55:14 - 55:22]
diff --git a/test/Index/keep-going.cpp b/test/Index/keep-going.cpp
index a25d1c4..82987c6 100644
--- a/test/Index/keep-going.cpp
+++ b/test/Index/keep-going.cpp
@@ -19,10 +19,10 @@
 // CHECK: FieldDecl=a:4:13 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
 // CHECK: TypeRef=T:3:16 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
 // CHECK: ClassDecl=B:6:7 (Definition) [type=B] [typekind=Record] [isPOD=0]
-// CHECK: C++ base class specifier=A<int>:4:7 [access=public isVirtual=false] [type=A<int>] [typekind=Unexposed] [canonicaltype=A<int>] [canonicaltypekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0] [nbFields=1]
+// CHECK: C++ base class specifier=A<int>:4:7 [access=public isVirtual=false] [type=A<int>] [typekind=Unexposed] [templateargs/1= [type=int] [typekind=Int]] [canonicaltype=A<int>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=int] [typekind=Int]] [isPOD=0] [nbFields=1]
 // CHECK: TemplateRef=A:4:7 [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: ClassDecl=C:10:7 (Definition) [type=C] [typekind=Record] [isPOD=0]
-// CHECK: C++ base class specifier=A<float>:4:7 [access=public isVirtual=false] [type=A<float>] [typekind=Unexposed] [canonicaltype=A<float>] [canonicaltypekind=Record] [templateargs/1= [type=float] [typekind=Float]] [isPOD=0] [nbFields=1]
+// CHECK: C++ base class specifier=A<float>:4:7 [access=public isVirtual=false] [type=A<float>] [typekind=Unexposed] [templateargs/1= [type=float] [typekind=Float]] [canonicaltype=A<float>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=float] [typekind=Float]] [isPOD=0] [nbFields=1]
 // CHECK: TemplateRef=A:4:7 [type=] [typekind=Invalid] [isPOD=0]
 
 // CHECK-DIAG: keep-going.cpp:1:10: error: 'missing1.h' file not found
diff --git a/test/Index/opencl-types.cl b/test/Index/opencl-types.cl
new file mode 100644
index 0000000..f15bc74
--- /dev/null
+++ b/test/Index/opencl-types.cl
@@ -0,0 +1,24 @@
+// RUN: c-index-test -test-print-type %s | FileCheck %s
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+typedef half half4 __attribute__((ext_vector_type(4)));
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef double double4 __attribute__((ext_vector_type(4)));
+
+void kernel testFloatTypes() {
+  half scalarHalf;
+  half4 vectorHalf;
+  float scalarFloat;
+  float4 vectorFloat;
+  double scalarDouble;
+  double4 vectorDouble;
+}
+
+// CHECK: VarDecl=scalarHalf:11:8 (Definition) [type=half] [typekind=Half] [isPOD=1]
+// CHECK: VarDecl=vectorHalf:12:9 (Definition) [type=half4] [typekind=Typedef] [canonicaltype=half __attribute__((ext_vector_type(4)))] [canonicaltypekind=Unexposed] [isPOD=1]
+// CHECK: VarDecl=scalarFloat:13:9 (Definition) [type=float] [typekind=Float] [isPOD=1]
+// CHECK: VarDecl=vectorFloat:14:10 (Definition) [type=float4] [typekind=Typedef] [canonicaltype=float __attribute__((ext_vector_type(4)))] [canonicaltypekind=Unexposed] [isPOD=1]
+// CHECK: VarDecl=scalarDouble:15:10 (Definition) [type=double] [typekind=Double] [isPOD=1]
+// CHECK: VarDecl=vectorDouble:16:11 (Definition) [type=double4] [typekind=Typedef] [canonicaltype=double __attribute__((ext_vector_type(4)))] [canonicaltypekind=Unexposed] [isPOD=1]
diff --git a/test/Index/overriding-ftemplate-comments.cpp b/test/Index/overriding-ftemplate-comments.cpp
index 7fc15f0..855d269 100644
--- a/test/Index/overriding-ftemplate-comments.cpp
+++ b/test/Index/overriding-ftemplate-comments.cpp
@@ -82,5 +82,5 @@
 template<class CCC1, template<class CCC2, template<class CCC3, class CCC4> class QQQ> class PPP>
 void comment_to_html_conversion_22();
 
-// CHECK: FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}overriding-ftemplate-comments.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_22</Name><USR>c:@FT@&gt;2#T#t&gt;2#T#t&gt;2#T#Tcomment_to_html_conversion_22#v#</USR><Declaration>template &lt;class CCC1, template &lt;class CCC2, template &lt;class CCC3, class CCC4&gt;\n                            class QQQ&gt; class PPP&gt;\nvoid comment_to_html_conversion_22()</Declaration><TemplateParameters><Parameter><Name>CCC1</Name><Index>0</Index><Discussion><Para> Ccc 1 </Para></Discussion></Parameter><Parameter><Name>PPP</Name><Index>1</Index><Discussion><Para> Zzz </Para></Discussion></Parameter><Parameter><Name>CCC2</Name><Discussion><Para> Ccc 2 </Para></Discussion></Parameter><Parameter><Name>CCC3</Name><Discussion><Para> Ccc 3 </Para></Discussion></Parameter><Parameter><Name>CCC4</Name><Discussion><Para> Ccc 4 </Para></Discussion></Parameter><Parameter><Name>QQQ</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>]
+// CHECK: FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}overriding-ftemplate-comments.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_22</Name><USR>c:@FT@&gt;2#T#t&gt;2#T#t&gt;2#T#Tcomment_to_html_conversion_22#v#</USR><Declaration>template &lt;class CCC1, template &lt;class CCC2, template &lt;class CCC3, class CCC4&gt;\n class QQQ&gt; class PPP&gt;\nvoid comment_to_html_conversion_22()</Declaration><TemplateParameters><Parameter><Name>CCC1</Name><Index>0</Index><Discussion><Para> Ccc 1 </Para></Discussion></Parameter><Parameter><Name>PPP</Name><Index>1</Index><Discussion><Para> Zzz </Para></Discussion></Parameter><Parameter><Name>CCC2</Name><Discussion><Para> Ccc 2 </Para></Discussion></Parameter><Parameter><Name>CCC3</Name><Discussion><Para> Ccc 3 </Para></Discussion></Parameter><Parameter><Name>CCC4</Name><Discussion><Para> Ccc 4 </Para></Discussion></Parameter><Parameter><Name>QQQ</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>]
 
diff --git a/test/Index/pch-from-libclang.c b/test/Index/pch-from-libclang.c
new file mode 100644
index 0000000..349fcac
--- /dev/null
+++ b/test/Index/pch-from-libclang.c
@@ -0,0 +1,27 @@
+// Check that clang can use a PCH created from libclang.
+
+// FIXME: Non-darwin bots fail. Would need investigation using -module-file-info to see what is the difference in modules generated from libclang vs the compiler invocation, in those systems.
+// REQUIRES: system-darwin
+
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+// RUN: c-index-test -write-pch %t.h.pch %s -fmodules -fmodules-cache-path=%t.mcp -Xclang -triple -Xclang x86_64-apple-darwin
+// RUN: %clang -fsyntax-only -include %t.h %s -Xclang -verify -fmodules -fmodules-cache-path=%t.mcp -Xclang -detailed-preprocessing-record -Xclang -triple -Xclang x86_64-apple-darwin -Xclang -fallow-pch-with-compiler-errors
+// RUN: %clang -x c-header %s -o %t.clang.h.pch -fmodules -fmodules-cache-path=%t.mcp -Xclang -detailed-preprocessing-record -Xclang -triple -Xclang x86_64-apple-darwin -Xclang -fallow-pch-with-compiler-errors -Xclang -verify
+// RUN: c-index-test -test-load-source local %s -include %t.clang.h -fmodules -fmodules-cache-path=%t.mcp -Xclang -triple -Xclang x86_64-apple-darwin | FileCheck %s
+
+#ifndef HEADER
+#define HEADER
+
+void some_function(undeclared_type p); // expected-error{{unknown type name}}
+
+struct S { int x; };
+
+#else
+// expected-no-diagnostics
+
+void test(struct S *s) {
+  // CHECK: [[@LINE+1]]:6: MemberRefExpr=x:[[@LINE-6]]:16
+  s->x = 0;
+}
+
+#endif
diff --git a/test/Index/print-type.cpp b/test/Index/print-type.cpp
index b17d518..108ba53 100644
--- a/test/Index/print-type.cpp
+++ b/test/Index/print-type.cpp
@@ -17,6 +17,7 @@
   Bar(outer::Foo<bool>* foo) { }
 
   typedef int FooType;
+  using AliasType = double;
   int *p;
   int *f(int *p, char *x, FooType z) {
     const FooType w = z;
@@ -25,7 +26,7 @@
   typedef double OtherType;
   typedef int ArrayType[5];
   Baz<int, 1, Foo> baz;
-  Qux<int, char*, Foo<int>> qux;
+  Qux<int, char*, Foo<int>, FooType> qux;
 };
 
 }
@@ -61,6 +62,15 @@
 
 struct TypeAliasUser { TypeAlias<int> foo; };
 
+template<typename T>
+struct Specialization {};
+
+template<>
+struct Specialization<int>;
+
+Specialization<Specialization<bool>& > templRefParam;
+auto autoTemplRefParam = templRefParam;
+
 // RUN: c-index-test -test-print-type %s -std=c++14 | FileCheck %s
 // CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
@@ -78,82 +88,92 @@
 // CHECK: NamespaceRef=outer:1:11 [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: TypedefDecl=FooType:19:15 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: FieldDecl=p:20:8 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
-// CHECK: CXXMethod=f:21:8 (Definition) [type=int *(int *, char *, FooType){{.*}}] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int){{.*}}] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef]] [isPOD=0]
-// CHECK: ParmDecl=p:21:15 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
-// CHECK: ParmDecl=x:21:24 (Definition) [type=char *] [typekind=Pointer] [isPOD=1] [pointeetype=char] [pointeekind=Char_{{[US]}}]
-// CHECK: ParmDecl=z:21:35 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypeRef=FooType:19:15 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: TypedefDecl=FooType:19:15 (Definition) [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: TypeAliasDecl=AliasType:20:9 (Definition) [type=outer::inner::Bar::AliasType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
+// CHECK: FieldDecl=p:21:8 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
+// CHECK: CXXMethod=f:22:8 (Definition) [type=int *(int *, char *, outer::inner::Bar::FooType){{.*}}] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int){{.*}}] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [outer::inner::Bar::FooType] [Typedef]] [isPOD=0]
+// CHECK: ParmDecl=p:22:15 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
+// CHECK: ParmDecl=x:22:24 (Definition) [type=char *] [typekind=Pointer] [isPOD=1] [pointeetype=char] [pointeekind=Char_{{[US]}}]
+// CHECK: ParmDecl=z:22:35 (Definition) [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: TypeRef=outer::inner::Bar::FooType:19:15 [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: VarDecl=w:22:19 (Definition) [type=const FooType] [typekind=Typedef] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypeRef=FooType:19:15 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: UnexposedExpr=z:21:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: DeclRefExpr=z:21:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: VarDecl=w:23:19 (Definition) [type=const outer::inner::Bar::FooType] [typekind=Typedef] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: TypeRef=outer::inner::Bar::FooType:19:15 [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: UnexposedExpr=z:22:35 [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: DeclRefExpr=z:22:35 [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: ReturnStmt= [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: BinaryOperator= [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
-// CHECK: UnexposedExpr=p:21:15 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
-// CHECK: DeclRefExpr=p:21:15 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
-// CHECK: UnexposedExpr=z:21:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: DeclRefExpr=z:21:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypedefDecl=OtherType:25:18 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
-// CHECK: TypedefDecl=ArrayType:26:15 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]
+// CHECK: UnexposedExpr=p:22:15 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
+// CHECK: DeclRefExpr=p:22:15 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
+// CHECK: UnexposedExpr=z:22:35 [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: DeclRefExpr=z:22:35 [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: TypedefDecl=OtherType:26:18 (Definition) [type=outer::inner::Bar::OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
+// CHECK: TypedefDecl=ArrayType:27:15 (Definition) [type=outer::inner::Bar::ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: FieldDecl=baz:27:20 (Definition) [type=Baz<int, 1, Foo>] [typekind=Unexposed] [canonicaltype=outer::Baz<int, 1, Foo>] [canonicaltypekind=Record] [templateargs/3= [type=int] [typekind=Int]] [isPOD=1]
+// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz<int, 1, Foo>] [typekind=Unexposed] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz<int, 1, Foo>] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1]
 // CHECK: TemplateRef=Baz:9:8 [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
 // CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: FieldDecl=qux:28:29 (Definition) [type=Qux<int, char *, Foo<int> >] [typekind=Unexposed] [canonicaltype=outer::Qux<int, char *, outer::Foo<int> >] [canonicaltypekind=Record] [templateargs/3= [type=int] [typekind=Int] [type=char *] [typekind=Pointer] [type=Foo<int>] [typekind=Unexposed]] [isPOD=1]
+// CHECK: FieldDecl=qux:29:38 (Definition) [type=Qux<int, char *, Foo<int>, outer::inner::Bar::FooType>] [typekind=Unexposed] [templateargs/4= [type=int] [typekind=Int] [type=char *] [typekind=Pointer] [type=Foo<int>] [typekind=Unexposed] [type=outer::inner::Bar::FooType] [typekind=Typedef]] [canonicaltype=outer::Qux<int, char *, outer::Foo<int>, int>] [canonicaltypekind=Record] [canonicaltemplateargs/4= [type=int] [typekind=Int] [type=char *] [typekind=Pointer] [type=outer::Foo<int>] [typekind=Record] [type=int] [typekind=Int]] [isPOD=1]
 // CHECK: TemplateRef=Qux:12:8 [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: FunctionTemplate=tbar:35:3 [type=T (int)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
-// CHECK: TemplateTypeParameter=T:34:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: TypeRef=T:34:20 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: ParmDecl=:35:11 (Definition) [type=int] [typekind=Int] [isPOD=1]
-// CHECK: FunctionTemplate=tbar:38:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
-// CHECK: TemplateTypeParameter=T:37:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: TypeRef=T:37:20 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: ParmDecl=:38:11 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
+// CHECK: FunctionTemplate=tbar:36:3 [type=T (int)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
+// CHECK: TemplateTypeParameter=T:35:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: TypeRef=T:35:20 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: ParmDecl=:36:11 (Definition) [type=int] [typekind=Int] [isPOD=1]
+// CHECK: FunctionTemplate=tbar:39:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
+// CHECK: TemplateTypeParameter=T:38:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: TypeRef=T:38:20 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: ParmDecl=:39:11 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: FunctionTemplate=tbar:41:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
-// CHECK: TemplateTypeParameter=T:40:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: NonTypeTemplateParameter=size:40:27 (Definition) [type=int] [typekind=Int] [isPOD=1]
-// CHECK: TypeRef=T:40:20 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: ParmDecl=:41:11 (Definition) [type=int [size]] [typekind=DependentSizedArray] [isPOD=0]
-// CHECK: DeclRefExpr=size:40:27 [type=int] [typekind=Int] [isPOD=1]
-// CHECK: FunctionDecl=foo:43:6 (Definition) [type=void (int, int *)] [typekind=FunctionProto] [canonicaltype=void (int, int *)] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int] [int []] [IncompleteArray]] [isPOD=0]
-// CHECK: ParmDecl=i:43:14 (Definition) [type=int] [typekind=Int] [isPOD=1]
-// CHECK: ParmDecl=incomplete_array:43:21 (Definition) [type=int []] [typekind=IncompleteArray] [isPOD=1]
+// CHECK: FunctionTemplate=tbar:42:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
+// CHECK: TemplateTypeParameter=T:41:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: NonTypeTemplateParameter=size:41:27 (Definition) [type=int] [typekind=Int] [isPOD=1]
+// CHECK: TypeRef=T:41:20 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: ParmDecl=:42:11 (Definition) [type=int [size]] [typekind=DependentSizedArray] [isPOD=0]
+// CHECK: DeclRefExpr=size:41:27 [type=int] [typekind=Int] [isPOD=1]
+// CHECK: FunctionDecl=foo:44:6 (Definition) [type=void (int, int *)] [typekind=FunctionProto] [canonicaltype=void (int, int *)] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int] [int []] [IncompleteArray]] [isPOD=0]
+// CHECK: ParmDecl=i:44:14 (Definition) [type=int] [typekind=Int] [isPOD=1]
+// CHECK: ParmDecl=incomplete_array:44:21 (Definition) [type=int []] [typekind=IncompleteArray] [isPOD=1]
 // CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: VarDecl=variable_array:43:47 (Definition) [type=int [i]] [typekind=VariableArray] [isPOD=1]
-// CHECK: DeclRefExpr=i:43:14 [type=int] [typekind=Int] [isPOD=1]
-// CHECK: StructDecl=Blob:45:8 (Definition) [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2]
-// CHECK: FieldDecl=i:46:7 (Definition) [type=int] [typekind=Int] [isPOD=1]
-// CHECK: VarDecl=member_pointer:49:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1]
-// CHECK: FunctionDecl=elaboratedNamespaceType:51:42 [type=NS::Type (const NS::Type)] [typekind=FunctionProto] [canonicaltype=NS::Type (NS::Type)] [canonicaltypekind=FunctionProto] [resulttype=NS::Type] [resulttypekind=Elaborated] [args= [const NS::Type] [Elaborated]] [isPOD=0]
-// CHECK: NamespaceRef=NS:51:11 [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: TypeRef=struct NS::Type:51:23 [type=NS::Type] [typekind=Record] [isPOD=1]
-// CHECK: ParmDecl=t:51:81 (Definition) [type=const NS::Type] [typekind=Elaborated] const [canonicaltype=const NS::Type] [canonicaltypekind=Record] [isPOD=1]
-// CHECK: VarDecl=autoI:53:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: VarDecl=variable_array:44:47 (Definition) [type=int [i]] [typekind=VariableArray] [isPOD=1]
+// CHECK: DeclRefExpr=i:44:14 [type=int] [typekind=Int] [isPOD=1]
+// CHECK: StructDecl=Blob:46:8 (Definition) [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2]
+// CHECK: FieldDecl=i:47:7 (Definition) [type=int] [typekind=Int] [isPOD=1]
+// CHECK: VarDecl=member_pointer:50:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1]
+// CHECK: FunctionDecl=elaboratedNamespaceType:52:42 [type=NS::Type (const NS::Type)] [typekind=FunctionProto] [canonicaltype=NS::Type (NS::Type)] [canonicaltypekind=FunctionProto] [resulttype=NS::Type] [resulttypekind=Elaborated] [args= [const NS::Type] [Elaborated]] [isPOD=0]
+// CHECK: NamespaceRef=NS:52:11 [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: TypeRef=struct NS::Type:52:23 [type=NS::Type] [typekind=Record] [isPOD=1]
+// CHECK: ParmDecl=t:52:81 (Definition) [type=const NS::Type] [typekind=Elaborated] const [canonicaltype=const NS::Type] [canonicaltypekind=Record] [isPOD=1]
+// CHECK: VarDecl=autoI:54:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: VarDecl=autoTbar:54:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: CallExpr=tbar:35:3 [type=int] [typekind=Unexposed] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1]
-// CHECK: UnexposedExpr=tbar:35:3 [type=int (*)(int)] [typekind=Pointer] [canonicaltype=int (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=int (int)] [pointeekind=FunctionProto]
-// CHECK: DeclRefExpr=tbar:35:3 RefName=[54:17 - 54:21] RefName=[54:21 - 54:26] [type=int (int)] [typekind=FunctionProto] [canonicaltype=int (int)] [canonicaltypekind=FunctionProto] [isPOD=0]
+// CHECK: VarDecl=autoTbar:55:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: CallExpr=tbar:36:3 [type=int] [typekind=Unexposed] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1]
+// CHECK: UnexposedExpr=tbar:36:3 [type=int (*)(int)] [typekind=Pointer] [canonicaltype=int (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=int (int)] [pointeekind=FunctionProto]
+// CHECK: DeclRefExpr=tbar:36:3 RefName=[55:17 - 55:21] RefName=[55:21 - 55:26] [type=int (int)] [typekind=FunctionProto] [canonicaltype=int (int)] [canonicaltypekind=FunctionProto] [isPOD=0]
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: VarDecl=autoBlob:55:6 (Definition) [type=Blob *] [typekind=Auto] [canonicaltype=Blob *] [canonicaltypekind=Pointer] [isPOD=1]
+// CHECK: VarDecl=autoBlob:56:6 (Definition) [type=Blob *] [typekind=Auto] [canonicaltype=Blob *] [canonicaltypekind=Pointer] [isPOD=1]
 // CHECK: CXXNewExpr= [type=Blob *] [typekind=Pointer] [isPOD=1] [pointeetype=Blob] [pointeekind=Record]
-// CHECK: TypeRef=struct Blob:45:8 [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2]
-// CHECK: CallExpr=Blob:45:8 [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2]
-// CHECK: FunctionDecl=autoFunction:56:6 (Definition) [type=int ()] [typekind=FunctionProto] [canonicaltype=int ()] [canonicaltypekind=FunctionProto] [resulttype=int] [resulttypekind=Auto] [isPOD=0]
+// CHECK: TypeRef=struct Blob:46:8 [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2]
+// CHECK: CallExpr=Blob:46:8 [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2]
+// CHECK: FunctionDecl=autoFunction:57:6 (Definition) [type=int ()] [typekind=FunctionProto] [canonicaltype=int ()] [canonicaltypekind=FunctionProto] [resulttype=int] [resulttypekind=Auto] [isPOD=0]
 // CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: ReturnStmt= [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: UnexposedExpr= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: VarDecl=autoInt:57:16 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: VarDecl=autoInt:58:16 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: TypeAliasTemplateDecl=TypeAlias:60:1 (Definition) [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: TemplateTypeParameter=T:59:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: FieldDecl=foo:62:39 (Definition) [type=TypeAlias<int>] [typekind=Unexposed] [canonicaltype=outer::Qux<int>] [canonicaltypekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=1]
-// CHECK: TemplateRef=TypeAlias:60:1 [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: TypeAliasTemplateDecl=TypeAlias:61:1 (Definition) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: TemplateTypeParameter=T:60:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: FieldDecl=foo:63:39 (Definition) [type=TypeAlias<int>] [typekind=Unexposed] [templateargs/1= [type=int] [typekind=Int]] [canonicaltype=outer::Qux<int>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=int] [typekind=Int]] [isPOD=1]
+// CHECK: TemplateRef=TypeAlias:61:1 [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: ClassTemplate=Specialization:66:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: TemplateTypeParameter=T:65:19 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: StructDecl=Specialization:69:8 [Specialization of Specialization:66:8] [type=Specialization<int>] [typekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0]
+// CHECK: VarDecl=templRefParam:71:40 (Definition) [type=Specialization<Specialization<bool> &>] [typekind=Unexposed] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: TemplateRef=Specialization:66:8 [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: CallExpr=Specialization:66:8 [type=Specialization<Specialization<bool> &>] [typekind=Unexposed] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: VarDecl=autoTemplRefParam:72:6 (Definition) [type=Specialization<Specialization<bool> &>] [typekind=Auto] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: UnexposedExpr=templRefParam:71:40 [type=const Specialization<Specialization<bool> &>] [typekind=Unexposed] const [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=const Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: DeclRefExpr=templRefParam:71:40 [type=Specialization<Specialization<bool> &>] [typekind=Unexposed] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
diff --git a/test/Index/recursive-cxx-member-calls.cpp b/test/Index/recursive-cxx-member-calls.cpp
index 36d617f..9dd2d67 100644
--- a/test/Index/recursive-cxx-member-calls.cpp
+++ b/test/Index/recursive-cxx-member-calls.cpp
@@ -536,7 +536,7 @@
 // CHECK-tokens: Punctuation: ")" [49:73 - 49:74] CXXConstructor=StringRef:49:3 (Definition)
 // CHECK-tokens: Punctuation: "{" [49:75 - 49:76] CompoundStmt=
 // CHECK-tokens: Punctuation: "}" [49:76 - 49:77] CompoundStmt=
-// CHECK-tokens: Identifier: "iterator" [50:3 - 50:11] TypeRef=iterator:40:23
+// CHECK-tokens: Identifier: "iterator" [50:3 - 50:11] TypeRef=llvm::StringRef::iterator:40:23
 // CHECK-tokens: Identifier: "end" [50:12 - 50:15] CXXMethod=end:50:12 (Definition)
 // CHECK-tokens: Punctuation: "(" [50:15 - 50:16] CXXMethod=end:50:12 (Definition)
 // CHECK-tokens: Punctuation: ")" [50:16 - 50:17] CXXMethod=end:50:12 (Definition)
@@ -1681,7 +1681,7 @@
 // CHECK: 49:67: DeclRefExpr=length:49:38 Extent=[49:67 - 49:73]
 // CHECK: 49:75: CompoundStmt= Extent=[49:75 - 49:77]
 // CHECK: 50:12: CXXMethod=end:50:12 (Definition) (const) Extent=[50:3 - 50:40] [access=public]
-// CHECK: 50:3: TypeRef=iterator:40:23 Extent=[50:3 - 50:11]
+// CHECK: 50:3: TypeRef=llvm::StringRef::iterator:40:23 Extent=[50:3 - 50:11]
 // CHECK: 50:24: CompoundStmt= Extent=[50:24 - 50:40]
 // CHECK: 50:26: ReturnStmt= Extent=[50:26 - 50:37]
 // CHECK: 50:33: MemberRefExpr=Data:43:15 Extent=[50:33 - 50:37]
diff --git a/test/Layout/ms-x86-basic-layout.cpp b/test/Layout/ms-x86-basic-layout.cpp
index c39e6ce..46752a7 100644
--- a/test/Layout/ms-x86-basic-layout.cpp
+++ b/test/Layout/ms-x86-basic-layout.cpp
@@ -807,12 +807,12 @@
 
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct RecordArrayTypedef
-// CHECK-NEXT:    0 |   ArrayTy [2] InlineElts
+// CHECK-NEXT:    0 |   RecordArrayTypedef::ArrayTy [2] InlineElts
 // CHECK-NEXT:      | [sizeof=16, align=4
 // CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct RecordArrayTypedef
-// CHECK-X64-NEXT:    0 |   ArrayTy [2] InlineElts
+// CHECK-X64-NEXT:    0 |   RecordArrayTypedef::ArrayTy [2] InlineElts
 // CHECK-X64-NEXT:      | [sizeof=16, align=4
 // CHECK-X64-NEXT:      |  nvsize=16, nvalign=4]
 
diff --git a/test/Lexer/case-insensitive-include-pr31836.sh b/test/Lexer/case-insensitive-include-pr31836.sh
new file mode 100644
index 0000000..a419f26
--- /dev/null
+++ b/test/Lexer/case-insensitive-include-pr31836.sh
@@ -0,0 +1,9 @@
+// REQUIRES: case-insensitive-filesystem
+// UNSUPPORTED: system-windows
+
+// RUN: mkdir -p %T
+// RUN: touch %T/case-insensitive-include-pr31836.h
+// RUN: echo "#include \"%T/Case-Insensitive-Include-Pr31836.h\"" | %clang_cc1 -E - 2>&1 | FileCheck %s
+
+// CHECK: warning: non-portable path to file
+// CHECK-SAME: /case-insensitive-include-pr31836.h
diff --git a/test/Lexer/cxx-features.cpp b/test/Lexer/cxx-features.cpp
index d38541f..d69ef08 100644
--- a/test/Lexer/cxx-features.cpp
+++ b/test/Lexer/cxx-features.cpp
@@ -22,6 +22,10 @@
 
 // --- C++17 features ---
 
+#if check(variadic_using, 0, 0, 0, 201611) // FIXME: provisional name
+#error "wrong value for __cpp_variadic_using"
+#endif
+
 #if check(hex_float, 0, 0, 0, 201603)
 #error "wrong value for __cpp_hex_float"
 #endif
@@ -46,7 +50,7 @@
 #error "wrong value for __cpp_capture_star_this"
 #endif
 
-// FIXME: bump __cpp_constexpr to 201603 for constexpr lambda support
+// constexpr checked below
 
 #if check(if_constexpr, 0, 0, 0, 201606) // FIXME: provisional name
 #error "wrong value for __cpp_if_constexpr"
@@ -74,17 +78,28 @@
 #error "wrong value for __cpp_nested_namespace_definitions"
 #endif
 
+// inheriting_constructors checked below
+
 #if check(aggregate_bases, 0, 0, 0, 201603)
 #error "wrong value for __cpp_aggregate_bases"
 #endif
 
-// FIXME: structured_bindings / decomposition_decl name not yet settled, and
-// Clang implementation is incomplete.
+#if check(structured_bindings, 0, 0, 0, 201606)
+#error "wrong value for __cpp_structured_bindings"
+#endif
 
 #if check(nontype_template_args, 0, 0, 0, 201411)
 #error "wrong value for __cpp_nontype_template_args"
 #endif
 
+#if check(template_template_args, 0, 0, 0, 0) // FIXME: should be 201611 when feature is enabled
+#error "wrong value for __cpp_template_template_args"
+#endif
+
+#if check(deduction_guides, 0, 0, 0, 201611) // FIXME: provisional name
+#error "wrong value for __cpp_deduction_guides"
+#endif
+
 // --- C++14 features ---
 
 #if check(binary_literals, 0, 0, 201304, 201304)
@@ -152,7 +167,7 @@
 #error "wrong value for __cpp_lambdas"
 #endif
 
-#if check(constexpr, 0, 200704, 201304, 201304)
+#if check(constexpr, 0, 200704, 201304, 201603)
 #error "wrong value for __cpp_constexpr"
 #endif
 
diff --git a/test/Lexer/has_feature_cxx0x.cpp b/test/Lexer/has_feature_cxx0x.cpp
index 8c7ff18..9082ca8 100644
--- a/test/Lexer/has_feature_cxx0x.cpp
+++ b/test/Lexer/has_feature_cxx0x.cpp
@@ -301,6 +301,17 @@
 // CHECK-11: has_constexpr
 // CHECK-NO-11: no_constexpr
 
+#if __has_feature(cxx_constexpr_string_builtins)
+int has_constexpr_string_builtins();
+#else
+int no_constexpr_string_builtins();
+#endif
+
+// CHECK-1Z: has_constexpr_string_builtins
+// CHECK-14: has_constexpr_string_builtins
+// CHECK-11: has_constexpr_string_builtins
+// CHECK-NO-11: no_constexpr_string_builtins
+
 #if __has_feature(cxx_generalized_initializers)
 int has_generalized_initializers();
 #else
diff --git a/test/Misc/ast-dump-attr.cpp b/test/Misc/ast-dump-attr.cpp
index e0575cb..f18fbac 100644
--- a/test/Misc/ast-dump-attr.cpp
+++ b/test/Misc/ast-dump-attr.cpp
@@ -154,3 +154,28 @@
 struct __attribute__((objc_bridge_related(NSParagraphStyle,,))) TestBridgedRef;
 // CHECK: CXXRecordDecl{{.*}} struct TestBridgedRef
 // CHECK-NEXT: ObjCBridgeRelatedAttr{{.*}} NSParagraphStyle
+
+void TestExternalSourceSymbolAttr1()
+__attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration)));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr1
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration
+
+void TestExternalSourceSymbolAttr2()
+__attribute__((external_source_symbol(defined_in="module", language="Swift")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr2
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module"{{$}}
+
+void TestExternalSourceSymbolAttr3()
+__attribute__((external_source_symbol(generated_declaration, language="Objective-C++", defined_in="module")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr3
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Objective-C++" "module" GeneratedDeclaration
+
+void TestExternalSourceSymbolAttr4()
+__attribute__((external_source_symbol(defined_in="Some external file.cs", generated_declaration, language="C Sharp")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr4
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "C Sharp" "Some external file.cs" GeneratedDeclaration
+
+void TestExternalSourceSymbolAttr5()
+__attribute__((external_source_symbol(generated_declaration, defined_in="module", language="Swift")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr5
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration
diff --git a/test/Misc/ast-dump-decl.c b/test/Misc/ast-dump-decl.c
index 7d39e6b..45edea2 100644
--- a/test/Misc/ast-dump-decl.c
+++ b/test/Misc/ast-dump-decl.c
@@ -102,16 +102,22 @@
 // CHECK-NEXT:   Field{{.*}} ''
 // CHECK-NEXT:   Field{{.*}} 'TestIndirectFieldDecl'
 
+// FIXME: It would be nice to dump the enum and its enumerators.
 int TestFunctionDecl(int x, enum { e } y) {
   return x;
 }
 // CHECK:      FunctionDecl{{.*}} TestFunctionDecl 'int (int, enum {{.*}})'
-// CHECK-NEXT:   EnumDecl
-// CHECK-NEXT:     EnumConstantDecl{{.*}} e
 // CHECK-NEXT:   ParmVarDecl{{.*}} x
 // CHECK-NEXT:   ParmVarDecl{{.*}} y
 // CHECK-NEXT:   CompoundStmt
 
+// FIXME: It would be nice to 'Enum' and 'e'.
+int TestFunctionDecl2(enum Enum { e } x) { return x; }
+// CHECK:      FunctionDecl{{.*}} TestFunctionDecl2 'int (enum {{.*}})'
+// CHECK-NEXT:   ParmVarDecl{{.*}} x
+// CHECK-NEXT:   CompoundStmt
+
+
 int TestFunctionDeclProto(int x);
 // CHECK:      FunctionDecl{{.*}} TestFunctionDeclProto 'int (int)'
 // CHECK-NEXT:   ParmVarDecl{{.*}} x
diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp
index 1cfcd50..e1cdeb0 100644
--- a/test/Misc/ast-dump-decl.cpp
+++ b/test/Misc/ast-dump-decl.cpp
@@ -336,7 +336,6 @@
   // CHECK-NEXT:       ClassTemplateDecl{{.*}} TestClassTemplate
   // CHECK-NEXT:         TemplateTypeParmDecl
   // CHECK-NEXT:         CXXRecordDecl{{.*}} class TestClassTemplate
-  // CHECK-NEXT:         ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
   // CHECK-NEXT:   ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
   // CHECK-NEXT:     TemplateArgument{{.*}}A
   // CHECK-NEXT:     CXXRecordDecl{{.*}} class TestClassTemplate
@@ -356,8 +355,8 @@
 }
 // CHECK:      NamespaceDecl{{.*}} TestTemplateTypeParmDecl
 // CHECK-NEXT:   FunctionTemplateDecl
-// CHECK-NEXT:     TemplateTypeParmDecl{{.*}} typename ... T
-// CHECK-NEXT:     TemplateTypeParmDecl{{.*}} class U
+// CHECK-NEXT:     TemplateTypeParmDecl{{.*}} typename depth 0 index 0 ... T
+// CHECK-NEXT:     TemplateTypeParmDecl{{.*}} class depth 0 index 1 U
 // CHECK-NEXT:       TemplateArgument type 'int'
 
 namespace TestNonTypeTemplateParmDecl {
@@ -365,10 +364,10 @@
 }
 // CHECK:      NamespaceDecl{{.*}} TestNonTypeTemplateParmDecl
 // CHECK-NEXT:   FunctionTemplateDecl
-// CHECK-NEXT:     NonTypeTemplateParmDecl{{.*}} 'int' I
+// CHECK-NEXT:     NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I
 // CHECK-NEXT:       TemplateArgument expr
 // CHECK-NEXT:         IntegerLiteral{{.*}} 'int' 1
-// CHECK-NEXT:     NonTypeTemplateParmDecl{{.*}} 'int' ... J
+// CHECK-NEXT:     NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J
 
 namespace TestTemplateTemplateParmDecl {
   template<typename T> class A;
diff --git a/test/Misc/ast-dump-decl.m b/test/Misc/ast-dump-decl.m
index 539923b..4cfb8aa 100644
--- a/test/Misc/ast-dump-decl.m
+++ b/test/Misc/ast-dump-decl.m
@@ -77,7 +77,7 @@
 @end
 // CHECK:      ObjCCategoryDecl{{.*}} TestObjCCategoryDecl
 // CHECK-NEXT:   ObjCInterface{{.*}} 'TestObjCClass'
-// CHECK-NEXT:   ObjCCategoryImpl{{.*}} 'TestObjCClass'
+// CHECK-NEXT:   ObjCCategoryImpl{{.*}} 'TestObjCCategoryDecl'
 // CHECK-NEXT:   ObjCProtocol{{.*}} 'P'
 // CHECK-NEXT:   ObjCMethodDecl{{.*}} bar
 
@@ -85,7 +85,7 @@
 - (void) bar {
 }
 @end
-// CHECK:      ObjCCategoryImplDecl{{.*}} TestObjCClass
+// CHECK:      ObjCCategoryImplDecl{{.*}} TestObjCCategoryDecl
 // CHECK-NEXT:   ObjCInterface{{.*}} 'TestObjCClass'
 // CHECK-NEXT:   ObjCCategory{{.*}} 'TestObjCCategoryDecl'
 // CHECK-NEXT:   ObjCMethodDecl{{.*}} bar
diff --git a/test/Misc/ast-dump-templates.cpp b/test/Misc/ast-dump-templates.cpp
index eb493b4..89feee7 100644
--- a/test/Misc/ast-dump-templates.cpp
+++ b/test/Misc/ast-dump-templates.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -ast-print %s > %t
+// RUN: %clang_cc1 -std=c++1z -ast-print %s > %t
 // RUN: FileCheck < %t %s -check-prefix=CHECK1
 // RUN: FileCheck < %t %s -check-prefix=CHECK2
-// RUN: %clang_cc1 -ast-dump %s | FileCheck --check-prefix=DUMP %s
+// RUN: %clang_cc1 -std=c++1z -ast-dump %s | FileCheck --check-prefix=DUMP %s
 
 template <int X, typename Y, int Z = 5>
 struct foo {
@@ -61,3 +61,9 @@
 
 // DUMP: UnresolvedLookupExpr {{.*}} <col:3> '<overloaded function type>' lvalue (ADL) = 'func'
 }
+
+namespace test3 {
+  template<typename T> struct A {};
+  template<typename T> A(T) -> A<int>;
+  // CHECK1: template <typename T> A(T) -> A<int>;
+}
diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp
index 7808398..174a969 100644
--- a/test/Misc/diag-template-diffing.cpp
+++ b/test/Misc/diag-template-diffing.cpp
@@ -24,17 +24,17 @@
   }
 } // end namespace std
 // CHECK-ELIDE-NOTREE: no matching function for call to 'f'
-// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::basic_string>' to 'vector<versa_string>' for 1st argument
+// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::string>' to 'vector<string>' for 1st argument
 // CHECK-NOELIDE-NOTREE: no matching function for call to 'f'
-// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::basic_string>' to 'vector<versa_string>' for 1st argument
+// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::string>' to 'vector<string>' for 1st argument
 // CHECK-ELIDE-TREE: no matching function for call to 'f'
 // CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument
 // CHECK-ELIDE-TREE:   vector<
-// CHECK-ELIDE-TREE:     [std::basic_string != versa_string]>
+// CHECK-ELIDE-TREE:     [std::string != string]>
 // CHECK-NOELIDE-TREE: no matching function for call to 'f'
 // CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument
 // CHECK-NOELIDE-TREE:   vector<
-// CHECK-NOELIDE-TREE:     [std::basic_string != versa_string]>
+// CHECK-NOELIDE-TREE:     [std::string != string]>
 
 template <int... A>
 class I1{};
@@ -1265,7 +1265,7 @@
   foo<BoolT<true>>(X);
 }
 // CHECK-ELIDE-NOTREE: no matching function for call to 'foo'
-// CHECK-ELIDE-NOTREE: candidate function [with T = BoolArgumentBitExtended::BoolT<true>] not viable: no known conversion from 'BoolT<false>' to 'BoolT<true>' for 1st argument
+// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'BoolT<false>' to 'BoolT<true>' for 1st argument
 }
 
 namespace DifferentIntegralTypes {
@@ -1401,7 +1401,7 @@
   f(1, integral_constant<bool, true>{});
 }
 // CHECK-ELIDE-NOTREE: error: no matching function for call to 'f'
-// CHECK-ELIDE-NOTREE: note: candidate function [with T = int] not viable: no known conversion from 'integral_constant<[...], true>' to 'integral_constant<[...], false>' for 2nd argument
+// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'integral_constant<[...], true>' to 'integral_constant<[...], false>' for 2nd argument
 }
 
 namespace ZeroArgs {
@@ -1454,7 +1454,7 @@
   D<X::X1>(VectorType<X::X2>());
 }
 // CHECK-ELIDE-NOTREE: error: no matching function for call to 'D'
-// CHECK-ELIDE-NOTREE: note: candidate function [with x = TypeAlias::X::X1] not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(TypeAlias::X)0>' for 1st argument
+// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(TypeAlias::X)0>' for 1st argument
 }
 
 namespace TypeAlias2 {
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index 1a33265..be02e12 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 (79):
+CHECK: Warnings without flags (78):
 CHECK-NEXT:   ext_excess_initializers
 CHECK-NEXT:   ext_excess_initializers_in_char_array_initializer
 CHECK-NEXT:   ext_expected_semi_decl_list
@@ -78,7 +78,6 @@
 CHECK-NEXT:   warn_objc_property_copy_missing_on_block
 CHECK-NEXT:   warn_objc_protocol_qualifier_missing_id
 CHECK-NEXT:   warn_on_superclass_use
-CHECK-NEXT:   warn_partial_specs_not_deducible
 CHECK-NEXT:   warn_pp_convert_to_positive
 CHECK-NEXT:   warn_pp_expr_overflow
 CHECK-NEXT:   warn_pp_line_decimal
diff --git a/test/Modules/Inputs/FooFramework.framework/Modules/module.modulemap b/test/Modules/Inputs/FooFramework.framework/Modules/module.modulemap
new file mode 100644
index 0000000..62e5636
--- /dev/null
+++ b/test/Modules/Inputs/FooFramework.framework/Modules/module.modulemap
@@ -0,0 +1,12 @@
+framework module FooFramework {
+    umbrella header "FooUmbrella.h"
+
+    export *
+    module * {
+        export *
+    }
+
+    explicit module Private {
+        textual header "Baz_Private.h"
+    }
+}
diff --git a/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/Bar.h b/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/Bar.h
new file mode 100644
index 0000000..d16b395
--- /dev/null
+++ b/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/Bar.h
@@ -0,0 +1,2 @@
+@interface Bar
+@end
diff --git a/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/Baz_Private.h b/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/Baz_Private.h
new file mode 100644
index 0000000..3ea082b
--- /dev/null
+++ b/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/Baz_Private.h
@@ -0,0 +1,3 @@
+#ifndef Baz_h
+#define Baz_h
+#endif /* Baz_h */
diff --git a/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/Foo.h b/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/Foo.h
new file mode 100644
index 0000000..26b9698
--- /dev/null
+++ b/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/Foo.h
@@ -0,0 +1,10 @@
+__attribute__((objc_root_class))
+@interface NSObject
++ (instancetype) alloc;
+- (instancetype) init;
+- (instancetype)retain;
+- (void)release;
+@end
+
+@interface Foo : NSObject
+@end
diff --git a/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/FooUmbrella.h b/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/FooUmbrella.h
new file mode 100644
index 0000000..c752fb2
--- /dev/null
+++ b/test/Modules/Inputs/FooFramework.framework/PrivateHeaders/FooUmbrella.h
@@ -0,0 +1,3 @@
+#import <FooFramework/Foo.h>
+#import <FooFramework/Bar.h>
+
diff --git a/test/Modules/Inputs/PR31469/empty.h b/test/Modules/Inputs/PR31469/empty.h
new file mode 100644
index 0000000..51e115f
--- /dev/null
+++ b/test/Modules/Inputs/PR31469/empty.h
@@ -0,0 +1 @@
+// This file is triggers loading of module M.
diff --git a/test/Modules/Inputs/PR31469/module.modulemap b/test/Modules/Inputs/PR31469/module.modulemap
new file mode 100644
index 0000000..bada81d
--- /dev/null
+++ b/test/Modules/Inputs/PR31469/module.modulemap
@@ -0,0 +1,5 @@
+module M {
+  module "textual_shadow" { header "textual_file_shadow.h" export *}
+  module "trigger" { header "empty.h" export * }
+  export *
+}
diff --git a/test/Modules/Inputs/PR31469/textual.h b/test/Modules/Inputs/PR31469/textual.h
new file mode 100644
index 0000000..abdc662
--- /dev/null
+++ b/test/Modules/Inputs/PR31469/textual.h
@@ -0,0 +1,17 @@
+namespace A {
+inline
+namespace __1 {
+  template <class _Tp> class allocator;
+  template <class _Tp, class _Alloc = allocator<_Tp>> class list;
+  template <class _VoidPtr> class __list_iterator {
+    //template <class> friend class list; // causes another crash in ASTDeclReader::attachPreviousDecl
+    template <class, class> friend class list;
+  };
+  template <class _Tp, class _Alloc> class __list_imp {};
+  template <class _Tp, class _Alloc> class list : __list_imp<_Tp, _Alloc> {
+  public:
+    list() {}
+  };
+  template <class _Tp> void f(list<_Tp>);
+}
+}
diff --git a/test/Modules/Inputs/PR31469/textual_file_shadow.h b/test/Modules/Inputs/PR31469/textual_file_shadow.h
new file mode 100644
index 0000000..48a53dd
--- /dev/null
+++ b/test/Modules/Inputs/PR31469/textual_file_shadow.h
@@ -0,0 +1,2 @@
+#include "textual.h"
+
diff --git a/test/Modules/Inputs/anon-redecl/a.h b/test/Modules/Inputs/anon-redecl/a.h
new file mode 100644
index 0000000..1b23e72
--- /dev/null
+++ b/test/Modules/Inputs/anon-redecl/a.h
@@ -0,0 +1,2 @@
+struct X { union { int n; }; };
+inline int a(X x) { return x.n; }
diff --git a/test/Modules/Inputs/anon-redecl/b.h b/test/Modules/Inputs/anon-redecl/b.h
new file mode 100644
index 0000000..23ea804
--- /dev/null
+++ b/test/Modules/Inputs/anon-redecl/b.h
@@ -0,0 +1,2 @@
+struct X { union { int n; }; };
+inline int b(X x) { return x.n; }
diff --git a/test/Modules/Inputs/anon-redecl/c1.h b/test/Modules/Inputs/anon-redecl/c1.h
new file mode 100644
index 0000000..600af31
--- /dev/null
+++ b/test/Modules/Inputs/anon-redecl/c1.h
@@ -0,0 +1,2 @@
+#include "a.h"
+#include "b.h"
diff --git a/test/Modules/Inputs/anon-redecl/c2.h b/test/Modules/Inputs/anon-redecl/c2.h
new file mode 100644
index 0000000..2e99b27
--- /dev/null
+++ b/test/Modules/Inputs/anon-redecl/c2.h
@@ -0,0 +1,2 @@
+struct X { union { int n; }; };
+inline int c(X x) { return x.n; }
diff --git a/test/Modules/Inputs/anon-redecl/module.modulemap b/test/Modules/Inputs/anon-redecl/module.modulemap
new file mode 100644
index 0000000..4967845
--- /dev/null
+++ b/test/Modules/Inputs/anon-redecl/module.modulemap
@@ -0,0 +1,6 @@
+module a { header "a.h" }
+module b { header "b.h" }
+module c {
+  module c1 { header "c1.h" }
+  module c2 { header "c2.h" }
+}
diff --git a/test/Modules/Inputs/category_right_sub.h b/test/Modules/Inputs/category_right_sub.h
index 231f65f..c8ba793 100644
--- a/test/Modules/Inputs/category_right_sub.h
+++ b/test/Modules/Inputs/category_right_sub.h
@@ -15,3 +15,8 @@
 
 @interface Foo(LeftP4) <P4>
 @end
+
+// A hidden extension
+@interface Foo ()
+@property (assign) int hiddenPropertyFromExtension;
+@end
diff --git a/test/Modules/Inputs/codegen-opt/bar.h b/test/Modules/Inputs/codegen-opt/bar.h
new file mode 100644
index 0000000..a00e8f7
--- /dev/null
+++ b/test/Modules/Inputs/codegen-opt/bar.h
@@ -0,0 +1,2 @@
+#include "foo.h"
+inline void bar() { foo(); }
diff --git a/test/Modules/Inputs/codegen-opt/bar.modulemap b/test/Modules/Inputs/codegen-opt/bar.modulemap
new file mode 100644
index 0000000..f1dc625
--- /dev/null
+++ b/test/Modules/Inputs/codegen-opt/bar.modulemap
@@ -0,0 +1 @@
+module bar { header "bar.h" }
diff --git a/test/Modules/Inputs/codegen-opt/foo.h b/test/Modules/Inputs/codegen-opt/foo.h
new file mode 100644
index 0000000..b3a7af7
--- /dev/null
+++ b/test/Modules/Inputs/codegen-opt/foo.h
@@ -0,0 +1,10 @@
+void f1(int &);
+static void f2() {}
+inline void foo() {
+  static int i;
+  f1(i);
+  f2();
+}
+inline void foo2() {
+}
+void foo_ext() {}
diff --git a/test/Modules/Inputs/codegen-opt/foo.modulemap b/test/Modules/Inputs/codegen-opt/foo.modulemap
new file mode 100644
index 0000000..2e095d2
--- /dev/null
+++ b/test/Modules/Inputs/codegen-opt/foo.modulemap
@@ -0,0 +1 @@
+module foo { header "foo.h" }
diff --git a/test/Modules/Inputs/codegen-opt/use.cpp b/test/Modules/Inputs/codegen-opt/use.cpp
new file mode 100644
index 0000000..b55a31f
--- /dev/null
+++ b/test/Modules/Inputs/codegen-opt/use.cpp
@@ -0,0 +1,2 @@
+#include "bar.h"
+int main() { bar(); }
diff --git a/test/Modules/Inputs/codegen/foo.h b/test/Modules/Inputs/codegen/foo.h
new file mode 100644
index 0000000..3fcab71
--- /dev/null
+++ b/test/Modules/Inputs/codegen/foo.h
@@ -0,0 +1,4 @@
+inline void f1(const char* fmt, ...) {
+  __builtin_va_list args;
+  __builtin_va_start(args, fmt);
+}
diff --git a/test/Modules/Inputs/codegen/foo.modulemap b/test/Modules/Inputs/codegen/foo.modulemap
new file mode 100644
index 0000000..2e095d2
--- /dev/null
+++ b/test/Modules/Inputs/codegen/foo.modulemap
@@ -0,0 +1 @@
+module foo { header "foo.h" }
diff --git a/test/Modules/Inputs/cxx17/decls.h b/test/Modules/Inputs/cxx17/decls.h
new file mode 100644
index 0000000..473b6d1
--- /dev/null
+++ b/test/Modules/Inputs/cxx17/decls.h
@@ -0,0 +1,3 @@
+struct MergeExceptionSpec {
+  ~MergeExceptionSpec(); // unevaluated exception spec
+};
diff --git a/test/Modules/Inputs/cxx17/module.modulemap b/test/Modules/Inputs/cxx17/module.modulemap
new file mode 100644
index 0000000..2339e49
--- /dev/null
+++ b/test/Modules/Inputs/cxx17/module.modulemap
@@ -0,0 +1 @@
+module Decls { header "decls.h" }
diff --git a/test/Modules/Inputs/diag_pragma.h b/test/Modules/Inputs/diag_pragma.h
index a8f9589..59c73ea 100644
--- a/test/Modules/Inputs/diag_pragma.h
+++ b/test/Modules/Inputs/diag_pragma.h
@@ -1,3 +1,13 @@
 #define DIAG_PRAGMA_MACRO 1
 
 #pragma clang diagnostic ignored "-Wparentheses"
+
+#ifdef __cplusplus
+template<typename T> const char *f(T t) {
+  return "foo" + t;
+}
+#pragma clang diagnostic ignored "-Wstring-plus-int"
+template<typename T> const char *g(T t) {
+  return "foo" + t;
+}
+#endif
diff --git a/test/Modules/Inputs/gnumode-non-benign/module.h b/test/Modules/Inputs/gnumode-non-benign/module.h
new file mode 100644
index 0000000..efde0ad
--- /dev/null
+++ b/test/Modules/Inputs/gnumode-non-benign/module.h
@@ -0,0 +1,5 @@
+// Check for GNUMode = 1 by looking for the "linux" define which only exists
+// for GNUMode = 1.
+#ifdef linux
+ #error "Submodule has GNUMode=1"
+#endif
diff --git a/test/Modules/Inputs/gnumode-non-benign/module.modulemap b/test/Modules/Inputs/gnumode-non-benign/module.modulemap
new file mode 100644
index 0000000..702ef59
--- /dev/null
+++ b/test/Modules/Inputs/gnumode-non-benign/module.modulemap
@@ -0,0 +1 @@
+module "module.h" { header "module.h"}
diff --git a/test/Modules/Inputs/hidden-names/hidden.h b/test/Modules/Inputs/hidden-names/hidden.h
new file mode 100644
index 0000000..e5c2f55
--- /dev/null
+++ b/test/Modules/Inputs/hidden-names/hidden.h
@@ -0,0 +1,3 @@
+namespace NS {
+  struct X {};
+}
diff --git a/test/Modules/Inputs/hidden-names/module.modulemap b/test/Modules/Inputs/hidden-names/module.modulemap
new file mode 100644
index 0000000..1471f58
--- /dev/null
+++ b/test/Modules/Inputs/hidden-names/module.modulemap
@@ -0,0 +1,4 @@
+module hidden {
+  header "visible.h"
+  explicit module sub { header "hidden.h" }
+}
diff --git a/test/Modules/Inputs/hidden-names/visible.h b/test/Modules/Inputs/hidden-names/visible.h
new file mode 100644
index 0000000..3dfc9c7
--- /dev/null
+++ b/test/Modules/Inputs/hidden-names/visible.h
@@ -0,0 +1,2 @@
+// hidden-names/visible.h
+namespace NS {}
diff --git a/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Headers/a.h b/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Headers/a.h
new file mode 100644
index 0000000..8b4b198
--- /dev/null
+++ b/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Headers/a.h
@@ -0,0 +1 @@
+extern int APUBLIC;
diff --git a/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Headers/aprivate.h b/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Headers/aprivate.h
new file mode 100644
index 0000000..760d901
--- /dev/null
+++ b/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Headers/aprivate.h
@@ -0,0 +1 @@
+extern int APRIVATE;
diff --git a/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Modules/module.modulemap b/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Modules/module.modulemap
new file mode 100644
index 0000000..95eabf9
--- /dev/null
+++ b/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Modules/module.modulemap
@@ -0,0 +1,4 @@
+framework module A {
+  header "a.h"
+  export *
+}
diff --git a/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Modules/module.private.modulemap b/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..020d5d3
--- /dev/null
+++ b/test/Modules/Inputs/implicit-private-with-different-name/A.framework/Modules/module.private.modulemap
@@ -0,0 +1,4 @@
+framework module APrivate {
+  header "aprivate.h"
+  export *
+}
diff --git a/test/Modules/Inputs/import-textual/M/A/A.h b/test/Modules/Inputs/import-textual/M/A/A.h
new file mode 100644
index 0000000..ebe4979
--- /dev/null
+++ b/test/Modules/Inputs/import-textual/M/A/A.h
@@ -0,0 +1,4 @@
+
+#import "someheader.h"
+
+typedef myint aint;
diff --git a/test/Modules/Inputs/import-textual/M/B/B.h b/test/Modules/Inputs/import-textual/M/B/B.h
new file mode 100644
index 0000000..ba85071
--- /dev/null
+++ b/test/Modules/Inputs/import-textual/M/B/B.h
@@ -0,0 +1,4 @@
+
+#import "someheader.h"
+
+typedef myint bint;
diff --git a/test/Modules/Inputs/import-textual/M/module.modulemap b/test/Modules/Inputs/import-textual/M/module.modulemap
new file mode 100644
index 0000000..f801948
--- /dev/null
+++ b/test/Modules/Inputs/import-textual/M/module.modulemap
@@ -0,0 +1,17 @@
+
+module M {
+
+  module A {
+    header "A/A.h"
+    textual header "someheader.h"
+    export *
+  }
+
+  module B {
+    header "B/B.h"
+    textual header "someheader.h"
+    export *
+  }
+
+  export *
+}
diff --git a/test/Modules/Inputs/import-textual/M/someheader.h b/test/Modules/Inputs/import-textual/M/someheader.h
new file mode 100644
index 0000000..16fae40
--- /dev/null
+++ b/test/Modules/Inputs/import-textual/M/someheader.h
@@ -0,0 +1,6 @@
+#ifndef C_GUARD
+#define C_GUARD
+
+typedef int myint;
+
+#endif
diff --git a/test/Modules/Inputs/import-textual/M2/A/A.h b/test/Modules/Inputs/import-textual/M2/A/A.h
new file mode 100644
index 0000000..ebe4979
--- /dev/null
+++ b/test/Modules/Inputs/import-textual/M2/A/A.h
@@ -0,0 +1,4 @@
+
+#import "someheader.h"
+
+typedef myint aint;
diff --git a/test/Modules/Inputs/import-textual/M2/B/B.h b/test/Modules/Inputs/import-textual/M2/B/B.h
new file mode 100644
index 0000000..ba85071
--- /dev/null
+++ b/test/Modules/Inputs/import-textual/M2/B/B.h
@@ -0,0 +1,4 @@
+
+#import "someheader.h"
+
+typedef myint bint;
diff --git a/test/Modules/Inputs/import-textual/M2/module.modulemap b/test/Modules/Inputs/import-textual/M2/module.modulemap
new file mode 100644
index 0000000..f801948
--- /dev/null
+++ b/test/Modules/Inputs/import-textual/M2/module.modulemap
@@ -0,0 +1,17 @@
+
+module M {
+
+  module A {
+    header "A/A.h"
+    textual header "someheader.h"
+    export *
+  }
+
+  module B {
+    header "B/B.h"
+    textual header "someheader.h"
+    export *
+  }
+
+  export *
+}
diff --git a/test/Modules/Inputs/import-textual/M2/someheader.h b/test/Modules/Inputs/import-textual/M2/someheader.h
new file mode 100644
index 0000000..df2009a
--- /dev/null
+++ b/test/Modules/Inputs/import-textual/M2/someheader.h
@@ -0,0 +1 @@
+typedef int myint;
diff --git a/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch b/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch
new file mode 100644
index 0000000..73a9816
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch
@@ -0,0 +1,3 @@
+#ifdef __OBJC__
+  #import <NC/NULog.h>
+#endif
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h
new file mode 100644
index 0000000..3866c88
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h
@@ -0,0 +1 @@
+#import <NC/NUGeometry.h>
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h
new file mode 100644
index 0000000..1e7614c
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h
@@ -0,0 +1 @@
+// NU-Visibility.h
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h
new file mode 100644
index 0000000..8923e04
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h
@@ -0,0 +1 @@
+#import <NC/NU-Visibility.h>
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap
new file mode 100644
index 0000000..475b414
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module NC {
+  umbrella header "NC.h"
+
+  export *
+  module * { export * }
+}
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..80488bd
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap
@@ -0,0 +1,5 @@
+explicit module NC.Private
+{
+	header "NULog.h"
+	header "NUAssert.h"
+}
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h
new file mode 100644
index 0000000..7bf8def
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h
@@ -0,0 +1 @@
+#import <NC/NULog.h>
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h
new file mode 100644
index 0000000..8923e04
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h
@@ -0,0 +1 @@
+#import <NC/NU-Visibility.h>
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/cstddef b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/cstddef
new file mode 100644
index 0000000..4898c05
--- /dev/null
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/cstddef
@@ -0,0 +1,9 @@
+#ifndef _LIBCPP_CSTDDEF
+#define _LIBCPP_CSTDDEF
+
+#include <stddef.h>
+#include <type_traits>
+
+typedef ptrdiff_t my_ptrdiff_t;
+
+#endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
index f761b91..9e2b693 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
@@ -4,4 +4,6 @@
 #include_next <math.h>
 template<typename T> T abs(T t) { return (t < 0) ? -t : t; }
 
+#include <type_traits>
+
 #endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
index b06142a..f57c11c 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
@@ -6,5 +6,7 @@
   // FIXME: remove "textual" from stdint module below once the issue
   // between umbrella headers and builtins is resolved.
   module stdint { textual header "stdint.h" export * }
+  module type_traits { header "type_traits" export * }
+  module cstddef { header "cstddef" export * }
   module __config { header "__config" export * }
 }
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
index bd42008..14167cf 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
@@ -2,5 +2,6 @@
 #define LIBCXX_STDDEF_H
 
 #include <__config>
+#include_next <stddef.h>
 
 #endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/type_traits b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/type_traits
new file mode 100644
index 0000000..a91056e
--- /dev/null
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/type_traits
@@ -0,0 +1,6 @@
+#ifndef _LIBCPP_TYPE_TRAITS
+#define _LIBCPP_TYPE_TRAITS
+
+#include <cstddef>
+
+#endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
index 7244cb0..25b9468 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
@@ -5,4 +5,12 @@
   module stdint { header "stdint.h" export * }
   module stdio { header "stdio.h" export * }
   module util { header "util.h" export * }
+  module POSIX {
+    module sys {
+      module types {
+        umbrella header "sys/_types/_types.h"
+        export *
+      }
+    }
+  }
 }
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
index eca7241..b98249f 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
@@ -1 +1,6 @@
-// stddef.h
+#ifndef __STDDEF_H__
+#define __STDDEF_H__
+
+#include "sys/_types/_ptrdiff_t.h"
+
+#endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_ptrdiff_t.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_ptrdiff_t.h
new file mode 100644
index 0000000..d14110e
--- /dev/null
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_ptrdiff_t.h
@@ -0,0 +1,4 @@
+#ifndef _PTRDIFF_T
+#define _PTRDIFF_T
+typedef int * ptrdiff_t;
+#endif /* _PTRDIFF_T */
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_types.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_types.h
new file mode 100644
index 0000000..33d5e51
--- /dev/null
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_types.h
@@ -0,0 +1,6 @@
+#ifndef _SYS_TYPES_UMBRELLA
+#define _SYS_TYPES_UMBRELLA
+
+#include "_ptrdiff_t.h"
+
+#endif
diff --git a/test/Modules/Inputs/merge-function-defs/a.h b/test/Modules/Inputs/merge-function-defs/a.h
new file mode 100644
index 0000000..7fc0e52
--- /dev/null
+++ b/test/Modules/Inputs/merge-function-defs/a.h
@@ -0,0 +1,4 @@
+struct X {
+  virtual void f();
+};
+inline void X::f() {}
diff --git a/test/Modules/Inputs/merge-function-defs/b.h b/test/Modules/Inputs/merge-function-defs/b.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Modules/Inputs/merge-function-defs/b.h
diff --git a/test/Modules/Inputs/merge-function-defs/map b/test/Modules/Inputs/merge-function-defs/map
new file mode 100644
index 0000000..f84c7dd
--- /dev/null
+++ b/test/Modules/Inputs/merge-function-defs/map
@@ -0,0 +1,4 @@
+module m {
+  module a { header "a.h" }
+  module b { header "b.h" }
+}
diff --git a/test/Modules/Inputs/merge-name-for-linkage/b.h b/test/Modules/Inputs/merge-name-for-linkage/b.h
index 82f2fdd..5593e41 100644
--- a/test/Modules/Inputs/merge-name-for-linkage/b.h
+++ b/test/Modules/Inputs/merge-name-for-linkage/b.h
@@ -1 +1,5 @@
 typedef union {} pthread_mutex_t;
+
+// Define then merge with another definition.
+typedef struct {} merged_after_definition;
+#include "c1.h"
diff --git a/test/Modules/Inputs/merge-name-for-linkage/c1.h b/test/Modules/Inputs/merge-name-for-linkage/c1.h
new file mode 100644
index 0000000..b3fd8ac
--- /dev/null
+++ b/test/Modules/Inputs/merge-name-for-linkage/c1.h
@@ -0,0 +1 @@
+// c1
diff --git a/test/Modules/Inputs/merge-name-for-linkage/c2.h b/test/Modules/Inputs/merge-name-for-linkage/c2.h
new file mode 100644
index 0000000..3ac8356
--- /dev/null
+++ b/test/Modules/Inputs/merge-name-for-linkage/c2.h
@@ -0,0 +1,2 @@
+// c2.h
+typedef struct {} merged_after_definition;
diff --git a/test/Modules/Inputs/merge-name-for-linkage/module.modulemap b/test/Modules/Inputs/merge-name-for-linkage/module.modulemap
index 61578a1..216add7 100644
--- a/test/Modules/Inputs/merge-name-for-linkage/module.modulemap
+++ b/test/Modules/Inputs/merge-name-for-linkage/module.modulemap
@@ -1,2 +1,3 @@
 module a { header "a.h" export * }
 module b { header "b.h" export * }
+module c { module c1 { header "c1.h" export * } module c2 { header "c2.h" export * } }
diff --git a/test/Modules/Inputs/merge-using-decls/b.h b/test/Modules/Inputs/merge-using-decls/b.h
index 3595555..5d112ff 100644
--- a/test/Modules/Inputs/merge-using-decls/b.h
+++ b/test/Modules/Inputs/merge-using-decls/b.h
@@ -29,11 +29,13 @@
   using typename X::t;
 };
 
+#if __cplusplus <= 199711L // C++11 does not allow access declarations
 template<typename T> struct E : X, T {
   // Mismatch in using/access-declaration-ness.
   T::value;
   X::v;
 };
+#endif
 
 template<typename T> struct F : X, T {
   // Mismatch in nested-name-specifier.
@@ -46,5 +48,9 @@
 // Force instantiation.
 typedef C<YB>::type I;
 typedef D<YBRev>::t I;
+
+#if __cplusplus <= 199711L // C++11 does not allow access declarations
 typedef E<YB>::type I;
+#endif
+
 typedef F<YB>::type I;
diff --git a/test/Modules/Inputs/module-impl-with-link/foo.h b/test/Modules/Inputs/module-impl-with-link/foo.h
new file mode 100644
index 0000000..90fe1bc
--- /dev/null
+++ b/test/Modules/Inputs/module-impl-with-link/foo.h
@@ -0,0 +1 @@
+//empty
diff --git a/test/Modules/Inputs/module-impl-with-link/module.modulemap b/test/Modules/Inputs/module-impl-with-link/module.modulemap
new file mode 100644
index 0000000..b85f8b6
--- /dev/null
+++ b/test/Modules/Inputs/module-impl-with-link/module.modulemap
@@ -0,0 +1,4 @@
+module Clib {
+  header "foo.h"
+  link "Clib"
+}
diff --git a/test/Modules/Inputs/overloadable-attrs/a.h b/test/Modules/Inputs/overloadable-attrs/a.h
new file mode 100644
index 0000000..1af769d
--- /dev/null
+++ b/test/Modules/Inputs/overloadable-attrs/a.h
@@ -0,0 +1,28 @@
+namespace enable_if_attrs {
+constexpr int fn1() __attribute__((enable_if(0, ""))) { return 0; }
+constexpr int fn1() { return 1; }
+
+constexpr int fn2() { return 1; }
+constexpr int fn2() __attribute__((enable_if(0, ""))) { return 0; }
+
+constexpr int fn3(int i) __attribute__((enable_if(!i, ""))) { return 0; }
+constexpr int fn3(int i) __attribute__((enable_if(i, ""))) { return 1; }
+
+constexpr int fn4(int i) { return 0; }
+constexpr int fn4(int i) __attribute__((enable_if(i, ""))) { return 1; }
+
+constexpr int fn5(int i) __attribute__((enable_if(i, ""))) { return 1; }
+constexpr int fn5(int i) { return 0; }
+}
+
+namespace pass_object_size_attrs {
+constexpr int fn1(void *const a __attribute__((pass_object_size(0)))) {
+  return 1;
+}
+constexpr int fn1(void *const a) { return 0; }
+
+constexpr int fn2(void *const a) { return 0; }
+constexpr int fn2(void *const a __attribute__((pass_object_size(0)))) {
+  return 1;
+}
+}
diff --git a/test/Modules/Inputs/overloadable-attrs/module.modulemap b/test/Modules/Inputs/overloadable-attrs/module.modulemap
new file mode 100644
index 0000000..514d745
--- /dev/null
+++ b/test/Modules/Inputs/overloadable-attrs/module.modulemap
@@ -0,0 +1,3 @@
+module a {
+  header "a.h"
+}
diff --git a/test/Modules/Inputs/pch-with-module-name/A.h b/test/Modules/Inputs/pch-with-module-name/A.h
new file mode 100644
index 0000000..a73b375
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/A.h
@@ -0,0 +1 @@
+// in pch
diff --git a/test/Modules/Inputs/pch-with-module-name/C.h b/test/Modules/Inputs/pch-with-module-name/C.h
new file mode 100644
index 0000000..f681dd8
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/C.h
@@ -0,0 +1 @@
+#include "D.h"
diff --git a/test/Modules/Inputs/pch-with-module-name/C.m b/test/Modules/Inputs/pch-with-module-name/C.m
new file mode 100644
index 0000000..90fe1bc
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/C.m
@@ -0,0 +1 @@
+//empty
diff --git a/test/Modules/Inputs/pch-with-module-name/D.h b/test/Modules/Inputs/pch-with-module-name/D.h
new file mode 100644
index 0000000..90fe1bc
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/D.h
@@ -0,0 +1 @@
+//empty
diff --git a/test/Modules/Inputs/pch-with-module-name/module.modulemap b/test/Modules/Inputs/pch-with-module-name/module.modulemap
new file mode 100644
index 0000000..379b0d4
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/module.modulemap
@@ -0,0 +1,9 @@
+module CloudKit {
+  header "C.h"
+  export *
+}
+
+module Contacts {
+  header "D.h"
+  export *
+}
diff --git a/test/Modules/Inputs/pch-with-module-name/test.h b/test/Modules/Inputs/pch-with-module-name/test.h
new file mode 100644
index 0000000..7a13ba4
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/test.h
@@ -0,0 +1 @@
+#include "A.h"
diff --git a/test/Modules/anon-redecl.cpp b/test/Modules/anon-redecl.cpp
new file mode 100644
index 0000000..c3c5c9e
--- /dev/null
+++ b/test/Modules/anon-redecl.cpp
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-local-submodule-visibility \
+// RUN:            -fmodule-map-file=%S/Inputs/anon-redecl/module.modulemap \
+// RUN:            -I%S/Inputs/anon-redecl \
+// RUN:            -verify -std=c++11 %s
+
+#include "a.h"
+#include "b.h"
+#include "c1.h"
+#include "c2.h"
+
+// expected-no-diagnostics
+int x = a({});
+int y = b({});
+int z = c({});
diff --git a/test/Modules/builtin-import.mm b/test/Modules/builtin-import.mm
new file mode 100644
index 0000000..2536ac5
--- /dev/null
+++ b/test/Modules/builtin-import.mm
@@ -0,0 +1,12 @@
+// REQUIRES: system-darwin
+
+// RUN: rm -rf %t
+// RUN: %clang -cc1 -fsyntax-only -nostdinc++ -isysroot %S/Inputs/libc-libcxx/sysroot -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s
+
+#include <stdio.h>
+#include <stddef.h>
+#include <cstddef>
+
+typedef ptrdiff_t try1_ptrdiff_t;
+typedef my_ptrdiff_t try2_ptrdiff_t;
+
diff --git a/test/Modules/codegen-opt.test b/test/Modules/codegen-opt.test
new file mode 100644
index 0000000..2f4997a
--- /dev/null
+++ b/test/Modules/codegen-opt.test
@@ -0,0 +1,65 @@
+RUN: rm -rf %t
+REQUIRES: x86-registered-target
+
+RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen-opt/foo.modulemap -o %t/foo.pcm
+RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++ -fmodules -emit-module -fmodule-name=bar %S/Inputs/codegen-opt/bar.modulemap -o %t/bar.pcm -fmodule-file=%t/foo.pcm
+
+RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %t/foo.pcm | FileCheck --check-prefix=FOO %s
+RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %t/bar.pcm -fmodule-file=%t/foo.pcm | FileCheck --check-prefix=BAR-CMN --check-prefix=BAR %s
+RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -fmodules -fmodule-file=%t/foo.pcm -fmodule-file=%t/bar.pcm %S/Inputs/codegen-opt/use.cpp | FileCheck --check-prefix=USE-CMN --check-prefix=USE %s
+
+RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -O2 -disable-llvm-passes %t/foo.pcm | FileCheck --check-prefix=FOO %s
+RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -O2 -disable-llvm-passes %t/bar.pcm -fmodule-file=%t/foo.pcm | FileCheck --check-prefix=BAR-CMN --check-prefix=BAR-OPT %s
+RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -O2 -disable-llvm-passes -fmodules -fmodule-file=%t/foo.pcm -fmodule-file=%t/bar.pcm %S/Inputs/codegen-opt/use.cpp | FileCheck --check-prefix=USE-CMN --check-prefix=USE-OPT %s
+
+FOO-NOT: comdat
+FOO: $_Z3foov = comdat any
+FOO: $_Z4foo2v = comdat any
+FOO: $_ZZ3foovE1i = comdat any
+FOO: @_ZZ3foovE1i = linkonce_odr global i32 0, comdat
+FOO-NOT: {{comdat|define|declare}}
+FOO: define void @_Z7foo_extv()
+FOO-NOT: {{define|declare}}
+FOO: define weak_odr void @_Z3foov() #{{[0-9]+}} comdat
+FOO-NOT: {{define|declare}}
+FOO: declare void @_Z2f1Ri(i32*
+FOO-NOT: {{define|declare}}
+
+FIXME: this internal function should be weak_odr, comdat, and with a new mangling
+FOO: define internal void @_ZL2f2v() #{{[0-9]+}}
+FOO-NOT: {{define|declare}}
+
+FOO: define weak_odr void @_Z4foo2v() #{{[0-9]+}} comdat
+FOO-NOT: {{define|declare}}
+
+
+BAR-CMN-NOT: comdat
+BAR-CMN: $_Z3barv = comdat any
+BAR-OPT: @_ZZ3foovE1i = linkonce_odr global i32 0, comdat
+BAR-CMN-NOT: {{comdat|define|declare}}
+BAR-CMN: define weak_odr void @_Z3barv() #{{[0-9]+}} comdat
+BAR-CMN-NOT: {{define|declare}}
+BAR: declare void @_Z3foov()
+Include all the available_externally definitions required for bar (foo -> f2)
+BAR-OPT: define available_externally void @_Z3foov()
+BAR-CMN-NOT: {{define|declare}}
+BAR-OPT: declare void @_Z2f1Ri(i32*
+BAR-OPT-NOT: {{define|declare}}
+BAR-OPT: define available_externally void @_ZL2f2v()
+BAR-OPT-NOT: {{define|declare}}
+
+
+USE-OPT: @_ZZ3foovE1i = linkonce_odr global i32 0, comdat
+USE-CMN-NOT: {{comdat|define|declare}}
+USE-CMN: define i32 @main()
+USE-CMN-NOT: {{define|declare}}
+USE: declare void @_Z3barv()
+Include all the available_externally definitions required for main (bar -> foo -> f2)
+USE-OPT: define available_externally void @_Z3barv()
+USE-CMN-NOT: {{define|declare}}
+USE-OPT: define available_externally void @_Z3foov()
+USE-OPT-NOT: {{define|declare}}
+USE-OPT: declare void @_Z2f1Ri(i32*
+USE-OPT-NOT: {{define|declare}}
+USE-OPT: define available_externally void @_ZL2f2v()
+USE-OPT-NOT: {{define|declare}}
diff --git a/test/Modules/codegen.test b/test/Modules/codegen.test
new file mode 100644
index 0000000..f1823d5
--- /dev/null
+++ b/test/Modules/codegen.test
@@ -0,0 +1,10 @@
+RUN: rm -rf %t
+REQUIRES: x86-registered-target
+
+RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen/foo.modulemap -o %t/foo.pcm
+
+RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %t/foo.pcm | FileCheck %s
+
+CHECK: $_Z2f1PKcz = comdat any
+CHECK: define weak_odr void @_Z2f1PKcz(i8* %fmt, ...) #{{[0-9]+}} comdat
+CHECK:   call void @llvm.va_start(i8* %{{[a-zA-Z0-9]*}})
diff --git a/test/Modules/crash-vfs-headermaps.m b/test/Modules/crash-vfs-headermaps.m
new file mode 100644
index 0000000..4f88f3b
--- /dev/null
+++ b/test/Modules/crash-vfs-headermaps.m
@@ -0,0 +1,55 @@
+// REQUIRES: crash-recovery, shell, system-darwin
+
+// This uses a headermap with this entry:
+//   Foo.h -> Foo/Foo.h
+
+// Copy out the headermap from test/Preprocessor/Inputs/headermap-rel and avoid
+// adding another binary format to the repository.
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/m
+// RUN: cp -a %S/../Preprocessor/Inputs/headermap-rel %t/i
+// RUN: echo '// Foo.h' > %t/i/Foo.framework/Headers/Foo.h
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only -fmodules -fmodules-cache-path=%t/m %s \
+// RUN:     -I %t/i/foo.hmap -F %t/i 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN:   %t/crash-vfs-*.cache/vfs/vfs.yaml
+
+#include "Foo.h"
+#include "Foo.h"
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "-I" "/[[INCPATH:.*]]/foo.hmap"
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/repro-modules"
+
+// CHECKYAML: 'case-sensitive':
+// CHECKYAML-NEXT: 'use-external-names': 'false',
+// CHECKYAML-NEXT: 'overlay-relative': 'true',
+// CHECKYAML-NEXT: 'ignore-non-existent-contents': 'false'
+// CHECKYAML: 'type': 'directory'
+// CHECKYAML: 'name': "/[[PATH:.*]]/Foo.framework/Headers",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT:   {
+// CHECKYAML-NEXT:     'type': 'file',
+// CHECKYAML-NEXT:     'name': "Foo.h",
+// CHECKYAML-NEXT:     'external-contents': "/[[PATH]]/Foo.framework/Headers/Foo.h"
+// CHECKYAML: 'type': 'directory'
+// CHECKYAML: 'name': "/[[PATH:.*]]/i",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT:   {
+// CHECKYAML-NEXT:     'type': 'file',
+// CHECKYAML-NEXT:     'name': "foo.hmap",
+// CHECKYAML-NEXT:     'external-contents': "/[[PATH]]/i/foo.hmap"
diff --git a/test/Modules/crash-vfs-include-pch.m b/test/Modules/crash-vfs-include-pch.m
new file mode 100644
index 0000000..78a8e14
--- /dev/null
+++ b/test/Modules/crash-vfs-include-pch.m
@@ -0,0 +1,43 @@
+// REQUIRES: crash-recovery, shell, system-darwin
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/m %t/out
+
+// RUN: %clang_cc1 -x objective-c-header -emit-pch %S/Inputs/pch-used.h \
+// RUN:     -o %t/out/pch-used.h.pch -fmodules -fimplicit-module-maps \
+// RUN:     -fmodules-cache-path=%t/cache -O0 \
+// RUN:     -isystem %S/Inputs/System/usr/include
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang %s -E -include-pch %t/out/pch-used.h.pch -fmodules -nostdlibinc \
+// RUN:     -fimplicit-module-maps -fmodules-cache-path=%t/cache -O0 \
+// RUN:     -Xclang -fno-validate-pch -isystem %S/Inputs/System/usr/include \
+// RUN:     -o %t/output.E 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN:   %t/crash-vfs-*.cache/vfs/vfs.yaml
+
+void f() { SPXTrace(); }
+void g() { double x = DBL_MAX; }
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSH: "-include-pch" "/[[INCPATH:.*]]/out/pch-used.h.pch"
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/repro-modules"
+
+// CHECKYAML: 'case-sensitive':
+// CHECKYAML-NEXT: 'use-external-names': 'false',
+// CHECKYAML-NEXT: 'overlay-relative': 'true',
+// CHECKYAML-NEXT: 'ignore-non-existent-contents': 'false'
+// CHECKYAML: 'type': 'directory'
+// CHECKYAML: 'name': "/[[PATH:.*]]/out",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT:   {
+// CHECKYAML-NEXT:     'type': 'file',
+// CHECKYAML-NEXT:     'name': "pch-used.h.pch",
+// CHECKYAML-NEXT:     'external-contents': "/[[PATH]]/out/pch-used.h.pch"
diff --git a/test/Modules/crash-vfs-ivfsoverlay.m b/test/Modules/crash-vfs-ivfsoverlay.m
new file mode 100644
index 0000000..abbc015
--- /dev/null
+++ b/test/Modules/crash-vfs-ivfsoverlay.m
@@ -0,0 +1,45 @@
+// REQUIRES: crash-recovery, shell, system-darwin
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/m
+// RUN: cp %S/../VFS/Inputs/actual_module2.map %t/actual_module2.map
+// RUN: sed -e "s:INPUT_DIR:%t:g" -e "s:OUT_DIR:%t/example:g" \
+// RUN:   %S/../VFS/Inputs/vfsoverlay2.yaml > %t/srcvfs.yaml
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only -nostdinc %s \
+// RUN:     -I %S/Inputs/crash-recovery/usr/include \
+// RUN:     -ivfsoverlay %t/srcvfs.yaml \
+// RUN:     -fmodules -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN:   %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN:   grep "%t/actual_module2.map" | count 1
+
+#include <stdio.h>
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/repro-modules"
+
+// CHECKYAML: 'case-sensitive':
+// CHECKYAML-NEXT: 'use-external-names': 'false',
+// CHECKYAML-NEXT: 'overlay-relative': 'true',
+// CHECKYAML-NEXT: 'ignore-non-existent-contents': 'false'
+// CHECKYAML: 'type': 'directory'
+// CHECKYAML: 'name': "/[[PATH:.*]]/example"
+// CHECKYAML: 'contents': [
+// CHECKYAML-NEXT:   {
+// CHECKYAML-NEXT:     'type': 'file',
+// CHECKYAML-NEXT:     'name': "module.map",
+// CHECKYAML-NEXT:     'external-contents': "/[[OTHERPATH:.*]]/actual_module2.map"
diff --git a/test/Modules/cxx-irgen.cpp b/test/Modules/cxx-irgen.cpp
index 75fb2c1..6cc32ad 100644
--- a/test/Modules/cxx-irgen.cpp
+++ b/test/Modules/cxx-irgen.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -debug-info-kind=limited -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-passes -emit-llvm -debug-info-kind=limited -o - %s | FileCheck %s
 // FIXME: When we have a syntax for modules in C++, use that.
 
 @import cxx_irgen_top;
diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp
index c2d3849..59e9136 100644
--- a/test/Modules/cxx-templates.cpp
+++ b/test/Modules/cxx-templates.cpp
@@ -49,14 +49,8 @@
   // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}}
   // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}}
 
-  // FIXME: This should be valid, but we incorrectly match the template template
-  // argument against both template template parameters.
-  template_param_kinds_3<Tmpl_T_T_A>(); // expected-error {{ambiguous}}
-  // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}}
-  // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}}
-  template_param_kinds_3<Tmpl_T_T_B>(); // expected-error {{ambiguous}}
-  // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}}
-  // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}}
+  template_param_kinds_3<Tmpl_T_T_A>();
+  template_param_kinds_3<Tmpl_T_T_B>();
 
   // Trigger the instantiation of a template in 'a' that uses a type defined in
   // 'common'. That type is not visible here.
@@ -195,8 +189,8 @@
     cls<void>::nested_cls_t<int> *nk2; // ok
     cls<void>::nested_cls_t<char> *nk3; // ok
     cls<int> uk1; // expected-error 1+{{explicit specialization of 'cls<int>' must be imported}} expected-error 1+{{definition of}}
-    cls<int*> uk3; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}} expected-error 1+{{definition of}}
-    cls<char*> uk4; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}} expected-error 1+{{definition of}}
+    cls<int*> uk3; // expected-error 1+{{partial specialization of 'cls<T *>' must be imported}} expected-error 1+{{definition of}}
+    cls<char*> uk4; // expected-error 1+{{partial specialization of 'cls<T *>' must be imported}} expected-error 1+{{definition of}}
     cls<void>::nested_cls unk1; // expected-error 1+{{explicit specialization of 'nested_cls' must be imported}} expected-error 1+{{definition of}}
     cls<void>::nested_cls_t<int> unk2; // expected-error 1+{{explicit specialization of 'nested_cls_t' must be imported}} expected-error 1+{{definition of}}
     cls<void>::nested_cls_t<char> unk3; // expected-error 1+{{explicit specialization of 'nested_cls_t' must be imported}}
@@ -211,8 +205,8 @@
     (void)sizeof(var<void>); // ok
     (void)sizeof(var<char>); // ok
     (void)sizeof(var<int>); // expected-error 1+{{explicit specialization of 'var<int>' must be imported}}
-    (void)sizeof(var<int*>); // expected-error 1+{{partial specialization of 'var<type-parameter-0-0 *>' must be imported}}
-    (void)sizeof(var<char*>); // expected-error 1+{{partial specialization of 'var<type-parameter-0-0 *>' must be imported}}
+    (void)sizeof(var<int*>); // expected-error 1+{{partial specialization of 'var<T *>' must be imported}}
+    (void)sizeof(var<char*>); // expected-error 1+{{partial specialization of 'var<T *>' must be imported}}
     (void)sizeof(cls<void>::nested_var); // ok
     (void)cls<void>::nested_var; // expected-error 1+{{explicit specialization of 'nested_var' must be imported}}
     (void)sizeof(cls<void>::nested_var_t<int>); // expected-error 1+{{explicit specialization of 'nested_var_t' must be imported}}
@@ -224,10 +218,10 @@
   int cls<int>::nested_var; // expected-error 1+{{explicit specialization of 'cls<int>' must be imported}} expected-error 1+{{definition of}}
   enum cls<int>::nested_enum : int {}; // expected-error 1+{{explicit specialization of 'cls<int>' must be imported}} expected-error 1+{{definition of}}
 
-  template<typename T> void cls<T*>::nested_fn() {} // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}}
-  template<typename T> struct cls<T*>::nested_cls {}; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}}
-  template<typename T> int cls<T*>::nested_var; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}}
-  template<typename T> enum cls<T*>::nested_enum : int {}; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' must be imported}}
+  template<typename T> void cls<T*>::nested_fn() {} // expected-error 1+{{partial specialization of 'cls<T *>' must be imported}}
+  template<typename T> struct cls<T*>::nested_cls {}; // expected-error 1+{{partial specialization of 'cls<T *>' must be imported}}
+  template<typename T> int cls<T*>::nested_var; // expected-error 1+{{partial specialization of 'cls<T *>' must be imported}}
+  template<typename T> enum cls<T*>::nested_enum : int {}; // expected-error 1+{{partial specialization of 'cls<T *>' must be imported}}
 }
 
 namespace Std {
diff --git a/test/Modules/cxx17.cpp b/test/Modules/cxx17.cpp
new file mode 100644
index 0000000..1efb490
--- /dev/null
+++ b/test/Modules/cxx17.cpp
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x c++ -std=c++1z -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/cxx17 %s -verify -fno-modules-error-recovery
+
+// expected-no-diagnostics
+struct MergeExceptionSpec {
+  ~MergeExceptionSpec();
+} mergeExceptionSpec; // trigger evaluation of exception spec
+
+#include "decls.h"
+
+MergeExceptionSpec mergeExceptionSpec2;
diff --git a/test/Modules/dependency-dump-dependent-module.m b/test/Modules/dependency-dump-dependent-module.m
index 2430726..4906986 100644
--- a/test/Modules/dependency-dump-dependent-module.m
+++ b/test/Modules/dependency-dump-dependent-module.m
@@ -1,6 +1,8 @@
 // When a module depends on another, check that we dump the dependency header
 // files for both.
 
+// REQUIRES: shell
+
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -module-dependency-dir %t/vfs -F %S/Inputs -I %S/Inputs -verify %s
 // expected-no-diagnostics
diff --git a/test/Modules/dependency-dump.m b/test/Modules/dependency-dump.m
index f3a4875..deb6618 100644
--- a/test/Modules/dependency-dump.m
+++ b/test/Modules/dependency-dump.m
@@ -1,6 +1,8 @@
 // Check that we can dump all of the headers a module depends on, and a VFS map
 // for the same.
 
+// REQUIRES: shell
+
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -module-dependency-dir %t/vfs -F %S/Inputs -I %S/Inputs -verify %s
 // expected-no-diagnostics
diff --git a/test/Modules/diag-pragma.cpp b/test/Modules/diag-pragma.cpp
new file mode 100644
index 0000000..347401f
--- /dev/null
+++ b/test/Modules/diag-pragma.cpp
@@ -0,0 +1,47 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -fmodules-ts
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -fmodules-ts -o %t/explicit.pcm -Werror=string-plus-int
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DEXPLICIT_FLAG -fmodule-file=%t/explicit.pcm
+
+import diag_pragma;
+
+int foo(int x) {
+  // Diagnostics from templates in the module follow the diagnostic state from
+  // when the module was built.
+#ifdef EXPLICIT_FLAG
+  // expected-error@diag_pragma.h:7 {{adding 'int' to a string}}
+#else
+  // expected-warning@diag_pragma.h:7 {{adding 'int' to a string}}
+#endif
+  // expected-note@diag_pragma.h:7 {{use array indexing}}
+  f(0); // expected-note {{instantiation of}}
+
+  g(0); // ok, warning was ignored when building module
+
+  // Diagnostics from this source file ignore the diagnostic state from the
+  // module.
+  void("foo" + x); // expected-warning {{adding 'int' to a string}}
+  // expected-note@-1 {{use array indexing}}
+
+#pragma clang diagnostic ignored "-Wstring-plus-int"
+
+  // Diagnostics from the module ignore diagnostic state changes from this
+  // source file.
+#ifdef EXPLICIT_FLAG
+  // expected-error@diag_pragma.h:7 {{adding 'long' to a string}}
+#else
+  // expected-warning@diag_pragma.h:7 {{adding 'long' to a string}}
+#endif
+  // expected-note@diag_pragma.h:7 {{use array indexing}}
+  f(0L); // expected-note {{instantiation of}}
+
+  g(0L);
+
+  void("bar" + x);
+
+  if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                             // expected-note {{place parentheses}} expected-note {{use '=='}}
+    return 0;
+  return 1;
+}
diff --git a/test/Modules/diagnostic-options-out-of-date.m b/test/Modules/diagnostic-options-out-of-date.m
index ed9e8e1..fd98a8f 100644
--- a/test/Modules/diagnostic-options-out-of-date.m
+++ b/test/Modules/diagnostic-options-out-of-date.m
@@ -7,6 +7,16 @@
 // RUN: %clang_cc1 -Werror -Wconversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s -fmodules-disable-diagnostic-validation
 // Make sure we don't error out when using the pch
 // RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify -fmodules-disable-diagnostic-validation
+
+// Build A.pcm
+// RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s
+// Build pch that imports A.pcm
+// RUN: %clang_cc1 -Werror -Wno-conversion -emit-pch -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -o %t.pch -I %S/Inputs -x objective-c-header %S/Inputs/pch-import-module-out-of-date.pch
+// We will rebuild A.pcm and overwrite the original A.pcm that the pch imports, but the two versions have the same hash.
+// RUN: %clang_cc1 -Werror -Wconversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s
+// Make sure we don't error out when using the pch
+// RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify
+
 // expected-no-diagnostics
 
 @import DiagOutOfDate;
diff --git a/test/Modules/gnumode-non-benign.cpp b/test/Modules/gnumode-non-benign.cpp
new file mode 100644
index 0000000..9255dfe
--- /dev/null
+++ b/test/Modules/gnumode-non-benign.cpp
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/gnumode-non-benign -verify %s
+
+// expected-no-diagnostics
+
+// This test ensures that submodules have the same GNUMode language option
+// setting as the main clang invocation.
+// Note that we set GNUMode = 0 with -std=c++11 for this file.
+
+// This module fails to compile with GNUMode = 1.
+#include "module.h"
diff --git a/test/Modules/hidden-names.cpp b/test/Modules/hidden-names.cpp
new file mode 100644
index 0000000..ba945a1
--- /dev/null
+++ b/test/Modules/hidden-names.cpp
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/hidden-names %s -verify
+// expected-no-diagnostics
+
+#include "visible.h"
+
+using namespace NS;
+
+namespace {
+  struct X { void f(); };
+}
+
+void X::f() {}
diff --git a/test/Modules/implicit-private-with-different-name.m b/test/Modules/implicit-private-with-different-name.m
new file mode 100644
index 0000000..c09d397
--- /dev/null
+++ b/test/Modules/implicit-private-with-different-name.m
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+
+// Build PCH using A, with adjacent private module APrivate, which winds up being implicitly referenced
+// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -emit-pch -o %t-A.pch %s
+
+// Use the PCH with no explicit way to resolve APrivate, still pick it up by automatic second-chance search for "A" with "Private" appended
+// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -include-pch %t-A.pch %s -fsyntax-only
+
+// Check the fixit
+// RUN: %clang_cc1  -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -include-pch %t-A.pch %s -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+// expected-warning@Inputs/implicit-private-with-different-name/A.framework/Modules/module.private.modulemap:1{{top-level module 'APrivate' in private module map, expected a submodule of 'A'}}
+// expected-note@Inputs/implicit-private-with-different-name/A.framework/Modules/module.private.modulemap:1{{make 'APrivate' a submodule of 'A' to ensure it can be found by name}}
+// CHECK: fix-it:"{{.*}}module.private.modulemap":{1:18-1:26}:"A.Private"
+
+#ifndef HEADER
+#define HEADER
+#import "A/aprivate.h"
+const int *y = &APRIVATE;
+#endif
diff --git a/test/Modules/import-textual-noguard.mm b/test/Modules/import-textual-noguard.mm
new file mode 100644
index 0000000..dd124b6
--- /dev/null
+++ b/test/Modules/import-textual-noguard.mm
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fmodules -fimplicit-module-maps -I%S/Inputs/import-textual/M2 -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s -verify
+
+#include "A/A.h" // expected-error {{could not build module 'M'}}
+#include "B/B.h"
+
+typedef aint xxx;
+typedef bint yyy;
diff --git a/test/Modules/import-textual.mm b/test/Modules/import-textual.mm
new file mode 100644
index 0000000..6593239
--- /dev/null
+++ b/test/Modules/import-textual.mm
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fmodules -fimplicit-module-maps -I%S/Inputs/import-textual/M -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s -verify
+
+// expected-no-diagnostics
+
+#include "A/A.h"
+#include "B/B.h"
+
+typedef aint xxx;
+typedef bint yyy;
diff --git a/test/Modules/invalid-pch-module-id.m b/test/Modules/invalid-pch-module-id.m
new file mode 100644
index 0000000..34d9995
--- /dev/null
+++ b/test/Modules/invalid-pch-module-id.m
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t.cache
+//
+// RUN: %clang_cc1 -x objective-c-header -fmodules -F%S/Inputs/invalid-module-id \
+// RUN:  -fmodule-implementation-of NC -fmodules-cache-path=%t.cache \
+// RUN:  -fimplicit-module-maps \
+// RUN:  -emit-pch %S/Inputs/invalid-module-id/NC-Prefix.pch -o %t.pch
+//
+// RUN: %clang_cc1 -x objective-c -fmodules -F%S/Inputs/invalid-module-id \
+// RUN:  -fmodule-implementation-of NC -fmodules-cache-path=%t.cache \
+// RUN:  -fimplicit-module-maps -include-pch %t.pch %s -fsyntax-only
+
+#import <NC/NULog.h>
+#import <NC/NUGeometry.h>
diff --git a/test/Modules/merge-function-defs.cpp b/test/Modules/merge-function-defs.cpp
new file mode 100644
index 0000000..2f08f52
--- /dev/null
+++ b/test/Modules/merge-function-defs.cpp
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/merge-function-defs -fmodules -fmodule-map-file=%S/Inputs/merge-function-defs/map -fmodules-cache-path=%t %s -emit-llvm-only
+
+#include "b.h"
+
+struct X {
+  virtual void f();
+};
+inline void X::f() {}
+
+X x;
diff --git a/test/Modules/merge-name-for-linkage.cpp b/test/Modules/merge-name-for-linkage.cpp
index 75534bd..1fd1686 100644
--- a/test/Modules/merge-name-for-linkage.cpp
+++ b/test/Modules/merge-name-for-linkage.cpp
@@ -7,3 +7,4 @@
 pthread_mutex_t x;
 #include "b.h"
 pthread_mutex_t y;
+merged_after_definition z;
diff --git a/test/Modules/merge-using-decls.cpp b/test/Modules/merge-using-decls.cpp
index 98989d1..1ec9a9a 100644
--- a/test/Modules/merge-using-decls.cpp
+++ b/test/Modules/merge-using-decls.cpp
@@ -1,6 +1,10 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=1
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++98 %s -DORDER=1
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++11 %s -DORDER=1
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=2
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++98 %s -DORDER=2
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++11 %s -DORDER=2
 
 #if ORDER == 1
 #include "a.h"
@@ -24,7 +28,11 @@
 }
 
 template<typename T> int UseAll() {
+#if __cplusplus <= 199711L // C++11 does not allow access declarations
   return Use<C<T> >() + Use<D<T> >() + Use<E<T> >() + Use<F<T> >(); // expected-note 0-2{{instantiation of}}
+#else
+  return Use<C<T> >() + Use<D<T> >() + Use<F<T> >(); // expected-note 0-2{{instantiation of}}
+#endif
 }
 
 template int UseAll<YA>();
@@ -37,8 +45,10 @@
 // Here, we're instantiating the definition from 'A' and merging the definition
 // from 'B' into it.
 
+#if __cplusplus <= 199711L // C++11 does not allow access declarations
 // expected-error@b.h:* {{'E::value' from module 'B' is not present in definition of 'E<T>' in module 'A'}}
 // expected-error@b.h:* {{'E::v' from module 'B' is not present in definition of 'E<T>' in module 'A'}}
+#endif
 
 // expected-error@b.h:* {{'F::type' from module 'B' is not present in definition of 'F<T>' in module 'A'}}
 // expected-error@b.h:* {{'F::t' from module 'B' is not present in definition of 'F<T>' in module 'A'}}
@@ -55,11 +65,14 @@
 // expected-error@b.h:* 2{{'typename' keyword used on a non-type}}
 // expected-error@b.h:* 2{{dependent using declaration resolved to type without 'typename'}}
 
+#if __cplusplus <= 199711L // C++11 does not allow access declarations
 // expected-error@a.h:* {{'E::type' from module 'A' is not present in definition of 'E<T>' in module 'B'}}
 // expected-error@a.h:* {{'E::t' from module 'A' is not present in definition of 'E<T>' in module 'B'}}
 // expected-error@a.h:* {{'E::value' from module 'A' is not present in definition of 'E<T>' in module 'B'}}
 // expected-error@a.h:* {{'E::v' from module 'A' is not present in definition of 'E<T>' in module 'B'}}
 // expected-note@b.h:* 2{{definition has no member}}
+#endif
+
 
 // expected-error@a.h:* {{'F::type' from module 'A' is not present in definition of 'F<T>' in module 'B'}}
 // expected-error@a.h:* {{'F::t' from module 'A' is not present in definition of 'F<T>' in module 'B'}}
diff --git a/test/Modules/module-impl-with-link.c b/test/Modules/module-impl-with-link.c
new file mode 100644
index 0000000..5e5ca83
--- /dev/null
+++ b/test/Modules/module-impl-with-link.c
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fmodule-name=Clib %s -I %S/Inputs/module-impl-with-link -emit-llvm -o -
+#include "foo.h"
+// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[LINK_OPTIONS:[0-9]+]]}
+// Make sure we don't generate linker option for module Clib since this TU is
+// an implementation of Clib.
+// CHECK: ![[LINK_OPTIONS]] = !{}
diff --git a/test/Modules/module_file_info.m b/test/Modules/module_file_info.m
index fa841b7..f2967be 100644
--- a/test/Modules/module_file_info.m
+++ b/test/Modules/module_file_info.m
@@ -29,13 +29,9 @@
 // CHECK:     CPU:
 // CHECK:     ABI:
 
-// CHECK: Diagnostic options:
-// CHECK:   IgnoreWarnings: Yes
-// CHECK:   Diagnostic flags:
-// CHECK:     -Wunused
-
 // CHECK: Header search options:
 // CHECK:   System root [-isysroot=]: '/'
+// CHECK:   Resource dir [ -resource-dir=]: '{{.*}}clang{{.*}}'
 // CHECK:   Use builtin include directories [-nobuiltininc]: Yes
 // CHECK:   Use standard system include directories [-nostdinc]: No
 // CHECK:   Use standard C++ include directories [-nostdinc++]: Yes
@@ -47,3 +43,8 @@
 // CHECK:   Predefined macros:
 // CHECK:     -DBLARG
 // CHECK:     -DWIBBLE=WOBBLE
+
+// CHECK: Diagnostic options:
+// CHECK:   IgnoreWarnings: Yes
+// CHECK:   Diagnostic flags:
+// CHECK:     -Wunused
diff --git a/test/Modules/module_map_cwd.c b/test/Modules/module_map_cwd.c
new file mode 100644
index 0000000..d76734a
--- /dev/null
+++ b/test/Modules/module_map_cwd.c
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo 'module X { header "x.h" }' > %t/map
+// RUN: echo 'extern int n;' > %t/x.h
+// RUN: cd %t
+// RUN: %clang_cc1 %s -fmodules -fmodule-map-file=map -fmodules-cache-path=. -verify -I.
+// expected-no-diagnostics
+#include "x.h"
+int *m = &n;
diff --git a/test/Modules/objc-categories.m b/test/Modules/objc-categories.m
index 42baf35..fcffe3c 100644
--- a/test/Modules/objc-categories.m
+++ b/test/Modules/objc-categories.m
@@ -53,6 +53,9 @@
   p3p = foo.p3_prop; // expected-error{{property 'p3_prop' not found on object of type 'Foo *'}}
   id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}}
   p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'}}
+
+  if (foo.hiddenPropertyFromExtension) { // expected-error {{property 'hiddenPropertyFromExtension' not found on object of type 'Foo *'}}
+  }
 }
 
 @import category_left.sub;
@@ -74,6 +77,7 @@
   id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}}
   p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'; did you mean 'p3_prop'?}}
   // expected-note@Inputs/category_left_sub.h:7{{'p3_prop' declared here}}
+  int hiddenFromExtension = foo.hiddenPropertyFromExtension; // expected-error {{property 'hiddenPropertyFromExtension' not found on object of type 'Foo *'}}
 }
 
 @import category_right.sub;
@@ -92,4 +96,6 @@
   p3p = foo.p3_prop;
   id p4p = p4.p4_prop;
   p4p = foo.p4_prop;
+  if (foo.hiddenPropertyFromExtension) {
+  }
 }
diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp
new file mode 100644
index 0000000..7543670
--- /dev/null
+++ b/test/Modules/odr_hash.cpp
@@ -0,0 +1,953 @@
+// Clear and create directories
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: mkdir %t/cache
+// RUN: mkdir %t/Inputs
+
+// Build first header file
+// RUN: echo "#define FIRST" >> %t/Inputs/first.h
+// RUN: cat %s               >> %t/Inputs/first.h
+
+// Build second header file
+// RUN: echo "#define SECOND" >> %t/Inputs/second.h
+// RUN: cat %s                >> %t/Inputs/second.h
+
+// Build module map file
+// RUN: echo "module FirstModule {"     >> %t/Inputs/module.map
+// RUN: echo "    header \"first.h\""   >> %t/Inputs/module.map
+// RUN: echo "}"                        >> %t/Inputs/module.map
+// RUN: echo "module SecondModule {"    >> %t/Inputs/module.map
+// RUN: echo "    header \"second.h\""  >> %t/Inputs/module.map
+// RUN: echo "}"                        >> %t/Inputs/module.map
+
+// Run test
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=c++1z
+
+#if !defined(FIRST) && !defined(SECOND)
+#include "first.h"
+#include "second.h"
+#endif
+
+namespace AccessSpecifiers {
+#if defined(FIRST)
+struct S1 {
+};
+#elif defined(SECOND)
+struct S1 {
+  private:
+};
+#else
+S1 s1;
+// expected-error@second.h:* {{'AccessSpecifiers::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found end of class}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+  public:
+};
+#elif defined(SECOND)
+struct S2 {
+  protected:
+};
+#else
+S2 s2;
+// expected-error@second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+} // namespace AccessSpecifiers
+
+namespace StaticAssert {
+#if defined(FIRST)
+struct S1 {
+  static_assert(1 == 1, "First");
+};
+#elif defined(SECOND)
+struct S1 {
+  static_assert(1 == 1, "Second");
+};
+#else
+S1 s1;
+// expected-error@second.h:* {{'StaticAssert::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with message}}
+// expected-note@first.h:* {{but in 'FirstModule' found static assert with different message}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+  static_assert(2 == 2, "Message");
+};
+#elif defined(SECOND)
+struct S2 {
+  static_assert(2 == 2);
+};
+#else
+S2 s2;
+// expected-error@second.h:* {{'StaticAssert::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with no message}}
+// expected-note@first.h:* {{but in 'FirstModule' found static assert with message}}
+#endif
+
+#if defined(FIRST)
+struct S3 {
+  static_assert(3 == 3, "Message");
+};
+#elif defined(SECOND)
+struct S3 {
+  static_assert(3 != 4, "Message");
+};
+#else
+S3 s3;
+// expected-error@second.h:* {{'StaticAssert::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with condition}}
+// expected-note@first.h:* {{but in 'FirstModule' found static assert with different condition}}
+#endif
+
+#if defined(FIRST)
+struct S4 {
+  static_assert(4 == 4, "Message");
+};
+#elif defined(SECOND)
+struct S4 {
+  public:
+};
+#else
+S4 s4;
+// expected-error@second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found static assert}}
+#endif
+}
+
+namespace Field {
+#if defined(FIRST)
+struct S1 {
+  int x;
+  private:
+  int y;
+};
+#elif defined(SECOND)
+struct S1 {
+  int x;
+  int y;
+};
+#else
+S1 s1;
+// expected-error@second.h:* {{'Field::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
+// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+  int x;
+  int y;
+};
+#elif defined(SECOND)
+struct S2 {
+  int y;
+  int x;
+};
+#else
+S2 s2;
+// expected-error@second.h:* {{'Field::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
+// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}}
+#endif
+
+#if defined(FIRST)
+struct S3 {
+  double x;
+};
+#elif defined(SECOND)
+struct S3 {
+  int x;
+};
+#else
+S3 s3;
+// expected-error@first.h:* {{'Field::S3::x' from module 'FirstModule' is not present in definition of 'Field::S3' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'x' does not match}}
+#endif
+
+#if defined(FIRST)
+typedef int A;
+struct S4 {
+  A x;
+};
+
+struct S5 {
+  A x;
+};
+#elif defined(SECOND)
+typedef int B;
+struct S4 {
+  B x;
+};
+
+struct S5 {
+  int x;
+};
+#else
+S4 s4;
+// expected-error@second.h:* {{'Field::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'Field::B' (aka 'int')}}
+// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}}
+
+S5 s5;
+// expected-error@second.h:* {{'Field::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'int'}}
+// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}}
+#endif
+
+#if defined(FIRST)
+struct S6 {
+  unsigned x;
+};
+#elif defined(SECOND)
+struct S6 {
+  unsigned x : 1;
+};
+#else
+S6 s6;
+// expected-error@second.h:* {{'Field::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x'}}
+// expected-note@first.h:* {{but in 'FirstModule' found non-bitfield 'x'}}
+#endif
+
+#if defined(FIRST)
+struct S7 {
+  unsigned x : 2;
+};
+#elif defined(SECOND)
+struct S7 {
+  unsigned x : 1;
+};
+#else
+S7 s7;
+// expected-error@second.h:* {{'Field::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}}
+// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}}
+#endif
+
+#if defined(FIRST)
+struct S8 {
+  unsigned x : 2;
+};
+#elif defined(SECOND)
+struct S8 {
+  unsigned x : 1 + 1;
+};
+#else
+S8 s8;
+// expected-error@second.h:* {{'Field::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}}
+// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}}
+#endif
+
+#if defined(FIRST)
+struct S9 {
+  mutable int x;
+};
+#elif defined(SECOND)
+struct S9 {
+  int x;
+};
+#else
+S9 s9;
+// expected-error@second.h:* {{'Field::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found non-mutable field 'x'}}
+// expected-note@first.h:* {{but in 'FirstModule' found mutable field 'x'}}
+#endif
+
+#if defined(FIRST)
+struct S10 {
+  unsigned x = 5;
+};
+#elif defined(SECOND)
+struct S10 {
+  unsigned x;
+};
+#else
+S10 s10;
+// expected-error@second.h:* {{'Field::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with no initalizer}}
+// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with an initializer}}
+#endif
+
+#if defined(FIRST)
+struct S11 {
+  unsigned x = 5;
+};
+#elif defined(SECOND)
+struct S11 {
+  unsigned x = 7;
+};
+#else
+S11 s11;
+// expected-error@second.h:* {{'Field::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}}
+// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}
+#endif
+
+}  // namespace Field
+
+namespace Method {
+#if defined(FIRST)
+struct S1 {
+  void A() {}
+};
+#elif defined(SECOND)
+struct S1 {
+  private:
+  void A() {}
+};
+#else
+S1 s1;
+// expected-error@second.h:* {{'Method::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found method}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+  void A() {}
+  void B() {}
+};
+#elif defined(SECOND)
+struct S2 {
+  void B() {}
+  void A() {}
+};
+#else
+S2 s2;
+// expected-error@second.h:* {{'Method::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'B'}}
+// expected-note@first.h:* {{but in 'FirstModule' found method 'A'}}
+#endif
+
+#if defined(FIRST)
+struct S3 {
+  static void A() {}
+  void A(int) {}
+};
+#elif defined(SECOND)
+struct S3 {
+  void A(int) {}
+  static void A() {}
+};
+#else
+S3 s3;
+// expected-error@second.h:* {{'Method::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not static}}
+// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is static}}
+#endif
+
+#if defined(FIRST)
+struct S4 {
+  virtual void A() {}
+  void B() {}
+};
+#elif defined(SECOND)
+struct S4 {
+  void A() {}
+  virtual void B() {}
+};
+#else
+S4 s4;
+// expected-error@second.h:* {{'Method::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not virtual}}
+// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is virtual}}
+#endif
+
+#if defined(FIRST)
+struct S5 {
+  virtual void A() = 0;
+  virtual void B() {};
+};
+#elif defined(SECOND)
+struct S5 {
+  virtual void A() {}
+  virtual void B() = 0;
+};
+#else
+S5 *s5;
+// expected-error@second.h:* {{'Method::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is virtual}}
+// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is pure virtual}}
+#endif
+
+#if defined(FIRST)
+struct S6 {
+  inline void A() {}
+};
+#elif defined(SECOND)
+struct S6 {
+  void A() {}
+};
+#else
+S6 s6;
+// expected-error@second.h:* {{'Method::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not inline}}
+// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is inline}}
+#endif
+
+#if defined(FIRST)
+struct S7 {
+  void A() volatile {}
+  void A() {}
+};
+#elif defined(SECOND)
+struct S7 {
+  void A() {}
+  void A() volatile {}
+};
+#else
+S7 s7;
+// expected-error@second.h:* {{'Method::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not volatile}}
+// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is volatile}}
+#endif
+
+#if defined(FIRST)
+struct S8 {
+  void A() const {}
+  void A() {}
+};
+#elif defined(SECOND)
+struct S8 {
+  void A() {}
+  void A() const {}
+};
+#else
+S8 s8;
+// expected-error@second.h:* {{'Method::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not const}}
+// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is const}}
+#endif
+
+}  // namespace Method
+
+// Naive parsing of AST can lead to cycles in processing.  Ensure
+// self-references don't trigger an endless cycles of AST node processing.
+namespace SelfReference {
+#if defined(FIRST)
+template <template <int> class T> class Wrapper {};
+
+template <int N> class S {
+  S(Wrapper<::SelfReference::S> &Ref) {}
+};
+
+struct Xx {
+  struct Yy {
+  };
+};
+
+Xx::Xx::Xx::Yy yy;
+
+namespace NNS {
+template <typename> struct Foo;
+template <template <class> class T = NNS::Foo>
+struct NestedNamespaceSpecifier {};
+}
+#endif
+}  // namespace SelfReference
+
+namespace TypeDef {
+#if defined(FIRST)
+struct S1 {
+  typedef int a;
+};
+#elif defined(SECOND)
+struct S1 {
+  typedef double a;
+};
+#else
+S1 s1;
+// expected-error@first.h:* {{'TypeDef::S1::a' from module 'FirstModule' is not present in definition of 'TypeDef::S1' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'a' does not match}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+  typedef int a;
+};
+#elif defined(SECOND)
+struct S2 {
+  typedef int b;
+};
+#else
+S2 s2;
+// expected-error@first.h:* {{'TypeDef::S2::a' from module 'FirstModule' is not present in definition of 'TypeDef::S2' in module 'SecondModule'}}
+// expected-note@second.h:* {{definition has no member 'a'}}
+#endif
+
+#if defined(FIRST)
+typedef int T;
+struct S3 {
+  typedef T a;
+};
+#elif defined(SECOND)
+typedef double T;
+struct S3 {
+  typedef T a;
+};
+#else
+S3 s3;
+// expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'a' does not match}}
+#endif
+}  // namespace TypeDef
+
+namespace Using {
+#if defined(FIRST)
+struct S1 {
+  using a = int;
+};
+#elif defined(SECOND)
+struct S1 {
+  using a = double;
+};
+#else
+S1 s1;
+// expected-error@first.h:* {{'Using::S1::a' from module 'FirstModule' is not present in definition of 'Using::S1' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'a' does not match}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+  using a = int;
+};
+#elif defined(SECOND)
+struct S2 {
+  using b = int;
+};
+#else
+S2 s2;
+// expected-error@first.h:* {{'Using::S2::a' from module 'FirstModule' is not present in definition of 'Using::S2' in module 'SecondModule'}}
+// expected-note@second.h:* {{definition has no member 'a'}}
+#endif
+
+#if defined(FIRST)
+typedef int T;
+struct S3 {
+  using a = T;
+};
+#elif defined(SECOND)
+typedef double T;
+struct S3 {
+  using a = T;
+};
+#else
+S3 s3;
+// expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'a' does not match}}
+#endif
+}  // namespace Using
+
+
+// Interesting cases that should not cause errors.  struct S should not error
+// while struct T should error at the access specifier mismatch at the end.
+namespace AllDecls {
+#if defined(FIRST)
+typedef int INT;
+struct S {
+  public:
+  private:
+  protected:
+
+  static_assert(1 == 1, "Message");
+  static_assert(2 == 2);
+
+  int x;
+  double y;
+
+  INT z;
+
+  unsigned a : 1;
+  unsigned b : 2*2 + 5/2;
+
+  mutable int c = sizeof(x + y);
+
+  void method() {}
+  static void static_method() {}
+  virtual void virtual_method() {}
+  virtual void pure_virtual_method() = 0;
+  inline void inline_method() {}
+  void volatile_method() volatile {}
+  void const_method() const {}
+
+  typedef int typedef_int;
+  using using_int = int;
+};
+#elif defined(SECOND)
+typedef int INT;
+struct S {
+  public:
+  private:
+  protected:
+
+  static_assert(1 == 1, "Message");
+  static_assert(2 == 2);
+
+  int x;
+  double y;
+
+  INT z;
+
+  unsigned a : 1;
+  unsigned b : 2 * 2 + 5 / 2;
+
+  mutable int c = sizeof(x + y);
+
+  void method() {}
+  static void static_method() {}
+  virtual void virtual_method() {}
+  virtual void pure_virtual_method() = 0;
+  inline void inline_method() {}
+  void volatile_method() volatile {}
+  void const_method() const {}
+
+  typedef int typedef_int;
+  using using_int = int;
+};
+#else
+S *s;
+#endif
+
+#if defined(FIRST)
+typedef int INT;
+struct T {
+  public:
+  private:
+  protected:
+
+  static_assert(1 == 1, "Message");
+  static_assert(2 == 2);
+
+  int x;
+  double y;
+
+  INT z;
+
+  unsigned a : 1;
+  unsigned b : 2 * 2 + 5 / 2;
+
+  mutable int c = sizeof(x + y);
+
+  void method() {}
+  static void static_method() {}
+  virtual void virtual_method() {}
+  virtual void pure_virtual_method() = 0;
+  inline void inline_method() {}
+  void volatile_method() volatile {}
+  void const_method() const {}
+
+  typedef int typedef_int;
+  using using_int = int;
+
+  private:
+};
+#elif defined(SECOND)
+typedef int INT;
+struct T {
+  public:
+  private:
+  protected:
+
+  static_assert(1 == 1, "Message");
+  static_assert(2 == 2);
+
+  int x;
+  double y;
+
+  INT z;
+
+  unsigned a : 1;
+  unsigned b : 2 * 2 + 5 / 2;
+
+  mutable int c = sizeof(x + y);
+
+  void method() {}
+  static void static_method() {}
+  virtual void virtual_method() {}
+  virtual void pure_virtual_method() = 0;
+  inline void inline_method() {}
+  void volatile_method() volatile {}
+  void const_method() const {}
+
+  typedef int typedef_int;
+  using using_int = int;
+
+  public:
+};
+#else
+T *t;
+// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
+#endif
+}
+
+namespace FriendFunction {
+#if defined(FIRST)
+void F(int = 0);
+struct S { friend void F(int); };
+#elif defined(SECOND)
+void F(int);
+struct S { friend void F(int); };
+#else
+S s;
+#endif
+
+#if defined(FIRST)
+void G(int = 0);
+struct T {
+  friend void G(int);
+
+  private:
+};
+#elif defined(SECOND)
+void G(int);
+struct T {
+  friend void G(int);
+
+  public:
+};
+#else
+T t;
+// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
+#endif
+}  // namespace FriendFunction
+
+namespace ImplicitDecl {
+#if defined(FIRST)
+struct S { };
+void S_Constructors() {
+  // Trigger creation of implicit contructors
+  S foo;
+  S bar = foo;
+  S baz(bar);
+}
+#elif defined(SECOND)
+struct S { };
+#else
+S s;
+#endif
+
+#if defined(FIRST)
+struct T {
+  private:
+};
+void T_Constructors() {
+  // Trigger creation of implicit contructors
+  T foo;
+  T bar = foo;
+  T baz(bar);
+}
+#elif defined(SECOND)
+struct T {
+  public:
+};
+#else
+T t;
+// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
+// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
+#endif
+
+}  // namespace ImplicitDelc
+
+namespace TemplatedClass {
+#if defined(FIRST)
+template <class>
+struct S {};
+#elif defined(SECOND)
+template <class>
+struct S {};
+#else
+S<int> s;
+#endif
+
+#if defined(FIRST)
+template <class>
+struct T {
+  private:
+};
+#elif defined(SECOND)
+template <class>
+struct T {
+  public:
+};
+#else
+T<int> t;
+// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
+#endif
+}  // namespace TemplatedClass
+
+namespace TemplateClassWithField {
+#if defined(FIRST)
+template <class A>
+struct S {
+  A a;
+};
+#elif defined(SECOND)
+template <class A>
+struct S {
+  A a;
+};
+#else
+S<int> s;
+#endif
+
+#if defined(FIRST)
+template <class A>
+struct T {
+  A a;
+
+  private:
+};
+#elif defined(SECOND)
+template <class A>
+struct T {
+  A a;
+
+  public:
+};
+#else
+T<int> t;
+// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
+#endif
+}  // namespace TemplateClassWithField
+
+namespace TemplateClassWithTemplateField {
+#if defined(FIRST)
+template <class A>
+class WrapperS;
+template <class A>
+struct S {
+  WrapperS<A> a;
+};
+#elif defined(SECOND)
+template <class A>
+class WrapperS;
+template <class A>
+struct S {
+  WrapperS<A> a;
+};
+#else
+template <class A>
+class WrapperS{};
+S<int> s;
+#endif
+
+#if defined(FIRST)
+template <class A>
+class WrapperT;
+template <class A>
+struct T {
+  WrapperT<A> a;
+
+  public:
+};
+#elif defined(SECOND)
+template <class A>
+class WrapperT;
+template <class A>
+struct T {
+  WrapperT<A> a;
+
+  private:
+};
+#else
+template <class A>
+class WrapperT{};
+T<int> t;
+// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+}  // namespace TemplateClassWithTemplateField
+
+namespace EnumWithForwardDeclaration {
+#if defined(FIRST)
+enum E : int;
+struct S {
+  void get(E) {}
+};
+#elif defined(SECOND)
+enum E : int { A, B };
+struct S {
+  void get(E) {}
+};
+#else
+S s;
+#endif
+
+#if defined(FIRST)
+struct T {
+  void get(E) {}
+  public:
+};
+#elif defined(SECOND)
+struct T {
+  void get(E) {}
+  private:
+};
+#else
+T t;
+// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+}  // namespace EnumWithForwardDeclaration
+
+namespace StructWithForwardDeclaration {
+#if defined(FIRST)
+struct P {};
+struct S {
+  struct P *ptr;
+};
+#elif defined(SECOND)
+struct S {
+  struct P *ptr;
+};
+#else
+S s;
+#endif
+
+#if defined(FIRST)
+struct Q {};
+struct T {
+  struct Q *ptr;
+  public:
+};
+#elif defined(SECOND)
+struct T {
+  struct Q *ptr;
+  private:
+};
+#else
+T t;
+// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+}  // namespace StructWithForwardDeclaration
+
+namespace StructWithForwardDeclarationNoDefinition {
+#if defined(FIRST)
+struct P;
+struct S {
+  struct P *ptr;
+};
+#elif defined(SECOND)
+struct S {
+  struct P *ptr;
+};
+#else
+S s;
+#endif
+
+#if defined(FIRST)
+struct Q;
+struct T {
+  struct Q *ptr;
+
+  public:
+};
+#elif defined(SECOND)
+struct T {
+  struct Q *ptr;
+
+  private:
+};
+#else
+T t;
+// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+}  // namespace StructWithForwardDeclarationNoDefinition
+
+// Keep macros contained to one file.
+#ifdef FIRST
+#undef FIRST
+#endif
+#ifdef SECOND
+#undef SECOND
+#endif
diff --git a/test/Modules/overloadable-attrs.cpp b/test/Modules/overloadable-attrs.cpp
new file mode 100644
index 0000000..38c9558
--- /dev/null
+++ b/test/Modules/overloadable-attrs.cpp
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/overloadable-attrs -fmodules \
+// RUN:            -fmodule-map-file=%S/Inputs/overloadable-attrs/module.modulemap \
+// RUN:            -fmodules-cache-path=%t -verify %s -std=c++11
+//
+// Ensures that we don't merge decls with attrs that we allow overloading on.
+//
+// expected-no-diagnostics
+
+#include "a.h"
+
+static_assert(enable_if_attrs::fn1() == 1, "");
+static_assert(enable_if_attrs::fn2() == 1, "");
+static_assert(enable_if_attrs::fn3(0) == 0, "");
+static_assert(enable_if_attrs::fn3(1) == 1, "");
+static_assert(enable_if_attrs::fn4(0) == 0, "");
+static_assert(enable_if_attrs::fn4(1) == 1, "");
+static_assert(enable_if_attrs::fn5(0) == 0, "");
+static_assert(enable_if_attrs::fn5(1) == 1, "");
+
+static_assert(pass_object_size_attrs::fn1(nullptr) == 1, "");
+static_assert(pass_object_size_attrs::fn2(nullptr) == 1, "");
diff --git a/test/Modules/pch-with-module-name.m b/test/Modules/pch-with-module-name.m
new file mode 100644
index 0000000..c409630
--- /dev/null
+++ b/test/Modules/pch-with-module-name.m
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/pch-with-module-name -emit-pch -o %t-A.pch %S/Inputs/pch-with-module-name/test.h -fmodule-name=Contacts -x objective-c-header
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/pch-with-module-name -include-pch %t-A.pch %s -fsyntax-only -fmodule-name=Contacts -verify
+// expected-no-diagnostics 
+#include "C.h"
diff --git a/test/Modules/pr31469.cpp b/test/Modules/pr31469.cpp
new file mode 100644
index 0000000..8f7d522
--- /dev/null
+++ b/test/Modules/pr31469.cpp
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR31469 -verify %s
+// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR31469 -fmodules -fmodules-local-submodule-visibility \
+// RUN:    -fimplicit-module-maps -fmodules-cache-path=%t  -verify %s
+
+#include "textual.h"
+#include "empty.h"
+
+namespace A {
+  template <class _Tp> void f();
+}
+
+A::list<int> use;
+
+// expected-no-diagnostics
diff --git a/test/Modules/rebuild.m b/test/Modules/rebuild.m
index 40f2d47..150c2ce 100644
--- a/test/Modules/rebuild.m
+++ b/test/Modules/rebuild.m
@@ -19,11 +19,10 @@
 // RUN: diff %t/Module.size %t/Module.size.saved
 // RUN: cp %t/Module.pcm %t/Module.pcm.saved.2
 
-// But the signature at least is expected to change, so we rebuild DependsOnModule.
-// NOTE: if we change how the signature is created, this test may need updating.
+// The signature is the hash of the PCM content, we will not rebuild rebuild DependsOnModule.
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -fsyntax-only -F %S/Inputs %s
 // RUN: diff %t/Module.pcm %t/Module.pcm.saved.2
-// RUN: not diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
+// RUN: diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
 
 // Rebuild Module, reset its timestamp, and verify its size hasn't changed
 // RUN: rm %t/Module.pcm
@@ -34,10 +33,9 @@
 // RUN: cp %t/Module.pcm %t/Module.pcm.saved.2
 
 // Verify again with Module pre-imported.
-// NOTE: if we change how the signature is created, this test may need updating.
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -fsyntax-only -F %S/Inputs %s
 // RUN: diff %t/Module.pcm %t/Module.pcm.saved.2
-// RUN: not diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
+// RUN: diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
 
 #ifdef PREIMPORT
 @import Module;
diff --git a/test/Modules/textual-hdr-in-umbrella-hdr.m b/test/Modules/textual-hdr-in-umbrella-hdr.m
new file mode 100644
index 0000000..f92cdb9
--- /dev/null
+++ b/test/Modules/textual-hdr-in-umbrella-hdr.m
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t.cache
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t.cache \
+// RUN:   %s -fsyntax-only -F %S/Inputs -Wincomplete-umbrella -verify
+
+// expected-no-diagnostics
+
+#import <FooFramework/Foo.h>
+
+@implementation Foo
+@end
diff --git a/test/OpenMP/atomic_codegen.cpp b/test/OpenMP/atomic_codegen.cpp
index 536f2cd..7f62a9b 100644
--- a/test/OpenMP/atomic_codegen.cpp
+++ b/test/OpenMP/atomic_codegen.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -x c++ -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -x c++ -emit-llvm -std=c++98 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -x c++ -emit-llvm -std=c++11 %s -o - | FileCheck %s
 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
 // expected-no-diagnostics
 
@@ -21,14 +23,15 @@
       // CHECK: [[SCALAR_ADDR:%.+]] = invoke dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* [[TEMP_ST_ADDR]])
       // CHECK: [[SCALAR_VAL:%.+]] = load atomic i32, i32* [[SCALAR_ADDR]] monotonic
       // CHECK: store i32 [[SCALAR_VAL]], i32* @b
-      // CHECK: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]])
+      // CHECK98: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]])
+      // CHECK11: call void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]])
 #pragma omp atomic read
       b = St().get();
       // CHECK-DAG: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]])
       // CHECK-DAG: [[SCALAR_ADDR:%.+]] = invoke dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* [[TEMP_ST_ADDR]])
       // CHECK-DAG: [[B_VAL:%.+]] = load i32, i32* @b
       // CHECK: store atomic i32 [[B_VAL]], i32* [[SCALAR_ADDR]] monotonic
-      // CHECK: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]])
+      // CHECK: {{invoke|call}} void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]])
 #pragma omp atomic write
       St().get() = b;
       // CHECK: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]])
@@ -46,7 +49,7 @@
       // CHECK: [[COND:%.+]] = extractvalue { i32, i1 } [[RES]], 1
       // CHECK: br i1 [[COND]], label %[[OMP_DONE:.+]], label %[[OMP_UPDATE]]
       // CHECK: [[OMP_DONE]]
-      // CHECK: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]])
+      // CHECK: {{invoke|call}} void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]])
 #pragma omp atomic
       St().get() %= b;
 #pragma omp atomic
@@ -67,7 +70,7 @@
       // CHECK: br i1 [[COND]], label %[[OMP_DONE:.+]], label %[[OMP_UPDATE]]
       // CHECK: [[OMP_DONE]]
       // CHECK: store i32 [[NEW_CALC_VAL]], i32* @a,
-      // CHECK: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]])
+      // CHECK: {{invoke|call}} void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]])
 #pragma omp atomic capture
       a = St().get() %= b;
     }
diff --git a/test/OpenMP/cancel_ast_print.cpp b/test/OpenMP/cancel_ast_print.cpp
index 007237a..be55084 100644
--- a/test/OpenMP/cancel_ast_print.cpp
+++ b/test/OpenMP/cancel_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/cancel_codegen.cpp b/test/OpenMP/cancel_codegen.cpp
index 5a3b96b..2ff9dcc 100644
--- a/test/OpenMP/cancel_codegen.cpp
+++ b/test/OpenMP/cancel_codegen.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin13.4.0 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-apple-darwin13.4.0 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - | FileCheck %s
 // expected-no-diagnostics
 #ifndef HEADER
 #define HEADER
@@ -12,6 +12,8 @@
 {
 #pragma omp cancel parallel if(flag)
   argv[0][0] = argc;
+#pragma omp barrier
+  argv[0][0] += argc;
 }
 // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
 #pragma omp sections
@@ -20,7 +22,6 @@
 }
 // CHECK: call void @__kmpc_for_static_init_4(
 // CHECK: call i32 @__kmpc_cancel(
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: call void @__kmpc_for_static_fini(
 // CHECK: call void @__kmpc_barrier(%ident_t*
 #pragma omp sections
@@ -36,7 +37,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -44,7 +44,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -62,7 +61,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -109,9 +107,10 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]],
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label %[[RETURN:.+]]
 // CHECK: [[ELSE]]
+// The barrier directive should now call __kmpc_cancel_barrier
+// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[RETURN]]
 // CHECK: ret void
@@ -121,7 +120,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]],
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label %[[RETURN:.+]]
 // CHECK: [[RETURN]]
 // CHECK: ret i32 0
@@ -129,7 +127,6 @@
 // CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}})
 // CHECK: call void @__kmpc_for_static_init_4(
 // CHECK: call i32 @__kmpc_cancel(
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: call void @__kmpc_for_static_fini(
 // CHECK: ret void
 
@@ -139,7 +136,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -147,7 +143,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -160,7 +155,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
diff --git a/test/OpenMP/cancel_if_messages.cpp b/test/OpenMP/cancel_if_messages.cpp
index 8d1afc9..426ac49 100644
--- a/test/OpenMP/cancel_if_messages.cpp
+++ b/test/OpenMP/cancel_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
@@ -24,7 +24,7 @@
     #pragma omp cancel parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if(argc)
-    #pragma omp cancel parallel if(cancel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+    #pragma omp cancel parallel if(cancel // expected-error {{use of undeclared identifier 'cancel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if(cancel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if(cancel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if(cancel : argc)
@@ -52,7 +52,7 @@
     #pragma omp cancel parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
-    #pragma omp cancel parallel if(cancel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+    #pragma omp cancel parallel if(cancel // expected-error {{use of undeclared identifier 'cancel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if(cancel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if(cancel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
     #pragma omp cancel parallel if(cancel : argc)
diff --git a/test/OpenMP/cancel_messages.cpp b/test/OpenMP/cancel_messages.cpp
index e23b5c3..f8bbe2c 100644
--- a/test/OpenMP/cancel_messages.cpp
+++ b/test/OpenMP/cancel_messages.cpp
@@ -4,8 +4,16 @@
 #pragma omp cancellation       // expected-error {{expected an OpenMP directive}}
 #pragma omp cancel // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
   ;
+#pragma omp parallel
+  {
+#pragma omp cancel // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+  }
 #pragma omp cancel parallel untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancel'}}
 #pragma omp cancel unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+#pragma omp parallel
+  {
+#pragma omp cancel unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+  }
 #pragma omp cancel sections(       // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
 #pragma omp cancel for, )          // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
 #pragma omp cancel taskgroup()     // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
diff --git a/test/OpenMP/cancellation_point_codegen.cpp b/test/OpenMP/cancellation_point_codegen.cpp
index c87d401..de65c11 100644
--- a/test/OpenMP/cancellation_point_codegen.cpp
+++ b/test/OpenMP/cancellation_point_codegen.cpp
@@ -26,7 +26,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -46,7 +45,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -54,7 +52,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -69,7 +66,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -82,6 +78,12 @@
 }
 // CHECK: call i8* @__kmpc_omp_task_alloc(
 // CHECK: call i32 @__kmpc_omp_task(
+#pragma omp task
+{
+#pragma omp cancellation point taskgroup
+}
+// CHECK: call i8* @__kmpc_omp_task_alloc(
+// CHECK: call i32 @__kmpc_omp_task(
 #pragma omp parallel sections
 {
   {
@@ -116,7 +118,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]],
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label %[[RETURN:.+]]
 // CHECK: [[RETURN]]
 // CHECK: ret void
@@ -126,7 +127,15 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]],
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
+// CHECK: br label %[[RETURN:.+]]
+// CHECK: [[RETURN]]
+// CHECK: ret i32 0
+
+// CHECK: define internal i32 @{{[^(]+}}(i32
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 4)
+// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
+// CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]],
+// CHECK: [[EXIT]]
 // CHECK: br label %[[RETURN:.+]]
 // CHECK: [[RETURN]]
 // CHECK: ret i32 0
@@ -137,7 +146,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -150,7 +158,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -158,7 +165,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
@@ -171,7 +177,6 @@
 // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
 // CHECK: [[EXIT]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
 // CHECK: br label
 // CHECK: [[CONTINUE]]
 // CHECK: br label
diff --git a/test/OpenMP/cancellation_point_messages.cpp b/test/OpenMP/cancellation_point_messages.cpp
index 2324915..21b0e9c 100644
--- a/test/OpenMP/cancellation_point_messages.cpp
+++ b/test/OpenMP/cancellation_point_messages.cpp
@@ -4,8 +4,16 @@
 #pragma omp cancellation       // expected-error {{expected an OpenMP directive}}
 #pragma omp cancellation point // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
   ;
+#pragma omp parallel
+  {
+#pragma omp cancellation point // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+  }
 #pragma omp cancellation point parallel untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancellation point'}}
 #pragma omp cancellation point unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+#pragma omp parallel
+  {
+#pragma omp cancellation point unknown         // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
+  }
 #pragma omp cancellation point sections(       // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}
 #pragma omp cancellation point for, )          // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}
 #pragma omp cancellation point taskgroup()     // expected-warning {{extra tokens at the end of '#pragma omp cancellation point' are ignored}}
diff --git a/test/OpenMP/declare_reduction_codegen.c b/test/OpenMP/declare_reduction_codegen.c
index ecb9726..579b664 100644
--- a/test/OpenMP/declare_reduction_codegen.c
+++ b/test/OpenMP/declare_reduction_codegen.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -x c -emit-llvm %s -triple %itanium_abi_triple -o - -femit-all-decls -disable-llvm-optzns | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-optzns
-// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-optzns | FileCheck --check-prefix=CHECK-LOAD %s
+// RUN: %clang_cc1 -verify -fopenmp -x c -emit-llvm %s -triple %itanium_abi_triple -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
+// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix=CHECK-LOAD %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/declare_reduction_codegen.cpp b/test/OpenMP/declare_reduction_codegen.cpp
index a18e73f..11ce430 100644
--- a/test/OpenMP/declare_reduction_codegen.cpp
+++ b/test/OpenMP/declare_reduction_codegen.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-optzns | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-optzns
-// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-optzns | FileCheck --check-prefix=CHECK-LOAD %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
+// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix=CHECK-LOAD %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/declare_reduction_messages.cpp b/test/OpenMP/declare_reduction_messages.cpp
index a1373b1..198d775 100644
--- a/test/OpenMP/declare_reduction_messages.cpp
+++ b/test/OpenMP/declare_reduction_messages.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 %s
 
 int temp; // expected-note 7 {{'temp' declared here}}
 
@@ -51,7 +53,17 @@
 #pragma omp declare reduction(fun222 : long : omp_out += omp_in)                                        // expected-error {{redefinition of user-defined reduction for type 'long'}}
 #pragma omp declare reduction(fun1 : long : omp_out += omp_in) initializer                              // expected-error {{expected '(' after 'initializer'}}
 #pragma omp declare reduction(fun2 : long : omp_out += omp_in) initializer {                            // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
-#pragma omp declare reduction(fun3 : long : omp_out += omp_in) initializer[                             // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
+#pragma omp declare reduction(fun3 : long : omp_out += omp_in) initializer[
+#if __cplusplus <= 199711L
+// expected-error@-2 {{expected '(' after 'initializer'}}
+// expected-error@-3 {{expected expression}}
+// expected-warning@-4 {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
+#else
+// expected-error@-6 {{expected '(' after 'initializer'}}
+// expected-error@-7 {{expected variable name or 'this' in lambda capture list}}
+// expected-error@-8 {{expected ')'}}
+// expected-note@-9 {{to match this '('}}
+#endif
 #pragma omp declare reduction(fun4 : long : omp_out += omp_in) initializer()                            // expected-error {{expected expression}}
 #pragma omp declare reduction(fun5 : long : omp_out += omp_in) initializer(temp)                        // expected-error {{only 'omp_priv' or 'omp_orig' variables are allowed in initializer expression}}
 #pragma omp declare reduction(fun6 : long : omp_out += omp_in) initializer(omp_orig                     // expected-error {{expected ')'}} expected-note {{to match this '('}}
diff --git a/test/OpenMP/distribute_collapse_messages.cpp b/test/OpenMP/distribute_collapse_messages.cpp
index 8818d65..4897e69 100644
--- a/test/OpenMP/distribute_collapse_messages.cpp
+++ b/test/OpenMP/distribute_collapse_messages.cpp
@@ -1,8 +1,13 @@
 // RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
 
 void foo() {
 }
 
+#if __cplusplus >= 201103L
+  // expected-note@+2 4 {{declared here}}
+#endif
 bool foobool(int argc) {
   return argc;
 }
@@ -29,6 +34,9 @@
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   #pragma omp distribute 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 distribute', but found only 1}}
+#if __cplusplus >= 201103L
+  // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
   // expected-error@+3 2 {{directive '#pragma omp distribute' cannot contain more than one 'collapse' clause}}
   // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
   // expected-error@+1 2 {{expression is not an integral constant expression}}
@@ -36,7 +44,11 @@
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   #pragma omp distribute 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}}
+#if __cplusplus <= 199711L
+  // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
   #pragma omp distribute 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 distribute collapse (1)
@@ -59,8 +71,14 @@
   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 distribute', but found only 1}}
   #pragma omp distribute collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute' 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 distribute', but found only 1}}
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
   #pragma omp distribute 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];
+#if __cplusplus >= 201103L
+  // expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
   // expected-error@+3 {{expression is not an integral constant expression}}
   // expected-error@+2 2 {{directive '#pragma omp distribute' cannot contain more than one 'collapse' clause}}
   // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
@@ -68,7 +86,11 @@
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   #pragma omp distribute 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}}
+#if __cplusplus <= 199711L
+  // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
   #pragma omp distribute 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 distribute' must be a for loop}}
diff --git a/test/OpenMP/distribute_firstprivate_codegen.cpp b/test/OpenMP/distribute_firstprivate_codegen.cpp
new file mode 100644
index 0000000..718fc87
--- /dev/null
+++ b/test/OpenMP/distribute_firstprivate_codegen.cpp
@@ -0,0 +1,382 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1  -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1  -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1  -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1  -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1  -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1  -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+  T f;
+  S(T a) : f(a) {}
+  S() : f() {}
+  operator T() { return T(); }
+  ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+  S<T> test;
+  T t_var = T();
+  T vec[] = {1, 2};
+  S<T> s_arr[] = {1, 2};
+  S<T> &var = test;
+  #pragma omp target
+  #pragma omp teams
+#pragma omp distribute firstprivate(t_var, vec, s_arr, s_arr, var, var)
+  for (int i = 0; i < 2; ++i) {
+    vec[i] = t_var;
+    s_arr[i] = var;
+  }
+  return T();
+}
+
+int main() {
+  static int svar;
+  volatile double g;
+  volatile double &g1 = g;
+
+  #ifdef LAMBDA
+  // LAMBDA-LABEL: @main
+  // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+  [&]() {
+    static float sfvar;
+    // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+    // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+    // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+    // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+    // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+    #pragma omp target
+    #pragma omp teams
+#pragma omp distribute firstprivate(g, g1, svar, sfvar)
+    for (int i = 0; i < 2; ++i) {
+      // LAMBDA-64: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i{{[0-9]+}} [[G_IN:%.+]], i{{[0-9]+}} [[G1_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]], i{{[0-9]+}} [[SFVAR_IN:%.+]])
+      // LAMBDA-32: define internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.*}} [[G_IN:%.+]], i{{[0-9]+}} [[G1_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]], i{{[0-9]+}} [[SFVAR_IN:%.+]])
+      // Private alloca's for conversion
+      // LAMBDA-64: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+      // LAMBDA-32: [[G_ADDR:%.+]] = alloca double*,
+      // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+      // LAMBDA: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+      // LAMBDA: [[SFVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+      // LAMBDA: [[G1_REF:%.+]] = alloca double*,
+      // LAMBDA: [[TMP:%.+]] = alloca double*,
+
+      // Actual private variables to be used in the body (tmp is used for the reference type)
+      // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+      // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+      // LAMBDA: [[TMP_PRIVATE:%.+]] = alloca double*,
+      // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+      // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+
+      // Store input parameter addresses into private alloca's for conversion
+      // LAMBDA-64: store i{{[0-9]+}} [[G_IN]], i{{[0-9]+}}* [[G_ADDR]],
+      // LAMBDA-32: store double* [[G_IN]], double** [[G_ADDR]],
+      // LAMBDA: store i{{[0-9]+}} [[G1_IN]], i{{[0-9]+}}* [[G1_ADDR]],
+      // LAMBDA: store i{{[0-9]+}} [[SVAR_IN]], i{{[0-9]+}}* [[SVAR_ADDR]],
+      // LAMBDA: store i{{[0-9]+}} [[SFVAR_IN]], i{{[0-9]+}}* [[SFVAR_ADDR]],
+
+      // LAMBDA-64-DAG: [[G_CONV:%.+]] = bitcast i{{[0-9]+}}* [[G_ADDR]] to double*
+      // LAMBDA-32-DAG: [[G_ADDR_VAL:%.+]] = load double*, double** [[G_ADDR]],
+      // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast i{{[0-9]+}}* [[G1_ADDR]] to double*
+      // LAMBDA-DAG: store double* [[G1_CONV]], double** [[G1_REF]],
+      // LAMBDA-64-DAG: [[SVAR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[SVAR_ADDR]] to i{{[0-9]+}}*
+      // LAMBDA-DAG: [[SFVAR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[SFVAR_ADDR]] to float*
+      // LAMBDA-DAG: [[G1_REF_VAL:%.+]] = load double*, double** [[G1_REF]],
+      // LAMBDA-DAG: store double* [[G1_REF_VAL]], double** [[TMP]],
+      // LAMBDA-64-DAG: [[G_CONV_VAL:%.+]] = load{{.*}} double, double* [[G_CONV]],
+      // LAMBDA-32-DAG: [[G_CONV_VAL:%.+]] = load{{.*}} double, double* [[G_ADDR_VAL]],
+      // LAMBDA-DAG: store double [[G_CONV_VAL]], double* [[G_PRIVATE]],
+      // LAMBDA-DAG: [[TMP_VAL:%.+]] = load double*, double** [[TMP]],
+      // LAMBDA-DAG: [[TMP_VAL_VAL:%.+]] = load{{.*}} double, double* [[TMP_VAL]],
+      // LAMBDA-DAG: store double [[TMP_VAL_VAL]], double* [[G1_PRIVATE]],
+      // LAMBDA-DAG: store double* [[G1_PRIVATE]], double** [[TMP_PRIVATE]],
+      // LAMBDA-64-DAG: [[SVAR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_CONV]],
+      // LAMBDA-32-DAG: [[SVAR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_ADDR]],
+      // LAMBDA-DAG: store i{{[0-9]+}} [[SVAR_CONV_VAL]], i{{[0-9]+}}* [[SVAR_PRIVATE]],
+      // LAMBDA-DAG: [[SFVAR_CONV_VAL:%.+]] = load float, float* [[SFVAR_CONV]],
+      // LAMBDA-DAG: store float [[SFVAR_CONV_VAL]], float* [[SFVAR_PRIVATE]],
+      // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+      g += 1;
+      g1 += 1;
+      svar += 3;
+      sfvar += 4.0;
+      // LAMBDA-DAG: [[G_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+      // LAMBDA-DAG: [[G_NEXT:%.+]] = fadd double [[G_VAL]], 1.{{.+}}
+      // LAMBDA-DAG: store double [[G_NEXT]], double* [[G_PRIVATE]],
+      // LAMBDA-DAG: [[TMP_VAL1:%.+]] = load double*, double** [[TMP_PRIVATE]],
+      // LAMBDA-DAG: [[TMP_VAL_VAL1:%.+]] = load{{.*}} double, double* [[TMP_VAL1]],
+      // LAMBDA-DAG: [[TMP_ADD:%.+]] = fadd double [[TMP_VAL_VAL1]], 1.{{.+}}
+      // LAMBDA-DAG: store{{.*}} double [[TMP_ADD]], double* [[TMP_VAL1]],
+      // LAMBDA-DAG: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+      // LAMBDA-DAG: [[SVAR_ADD:%.+]] = add{{.*}} i{{[0-9]+}} [[SVAR_VAL]], 3
+      // LAMBDA-DAG: store i{{[0-9]+}} [[SVAR_ADD]], i{{[0-9]+}}* [[SVAR_PRIVATE]],
+      // LAMBDA-DAG: [[SFVAR_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+      // LAMBDA-DAG: [[SFVAR_CONV_VAL1:%.+]] = fpext float [[SFVAR_VAL]] to double
+      // LAMBDA-DAG: [[SFVAR_ADD:%.+]] = fadd double [[SFVAR_CONV_VAL1]], 4.{{.+}}
+      // LAMBDA-DAG: [[SFVAR_CONV_VAL2:%.+]] = fptrunc double [[SFVAR_ADD]] to float
+      // LAMBDA-DAG: store float [[SFVAR_CONV_VAL2:%.+]], float* [[SFVAR_PRIVATE]],
+
+      // call inner lambda (use refs to private alloca's)
+      // LAMBDA: [[GEP_0:%.+]] = getelementptr{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+      // LAMBDA: store double* [[G_PRIVATE]], double** [[GEP_0]],
+      // LAMBDA: [[GEP_1:%.+]] = getelementptr{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+      // LAMBDA: [[TMP_PAR:%.+]] = load double*, double** [[TMP_PRIVATE]],
+      // LAMBDA: store double* [[TMP_PAR]], double** [[GEP_1]],
+      // LAMBDA: [[GEP_2:%.+]] = getelementptr{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+      // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[GEP_2]],
+      // LAMBDA: [[GEP_3:%.+]] = getelementptr{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+      // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[GEP_3]],
+      // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* {{.+}})
+      // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+      [&]() {
+	// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+	// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+	g += 2;
+	g1 += 2;
+	svar += 4;
+	sfvar += 8.0;
+	// LAMBDA-DAG: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+	// LAMBDA-DAG: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+	// LAMBDA-DAG: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]],
+	// LAMBDA-DAG: [[G_REF_VAL:%.+]] = load double, double* [[G_REF]],
+	// LAMBDA-DAG: [[G_REF_ADD:%.+]] = fadd double [[G_REF_VAL]], 2.{{.+}}
+	// LAMBDA-DAG: store double [[G_REF_ADD]], double* [[G_REF]]
+
+	// LAMBDA-DAG: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+	// LAMBDA-DAG: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+	// LAMBDA-DAG: [[G1_REF_VAL:%.+]] = load double, double* [[G1_REF]],
+	// LAMBDA-DAG: [[G1_ADD:%.+]] = fadd double [[G1_REF_VAL]], 2.{{.+}}
+	// LAMBDA-DAG: store double [[G1_ADD]], double* [[G1_REF]],
+
+	// LAMBDA-DAG: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+	// LAMBDA-DAG: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+	// LAMBDA-DAG: [[SVAR_REF_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_REF]]
+	// LAMBDA-DAG: [[SVAR_ADD:%.+]] = add{{.*}} i{{[0-9]+}} [[SVAR_REF_VAL]], 4
+	// LAMBDA-DAG: store i{{[0-9]+}} [[SVAR_ADD]], i{{[0-9]+}}* [[SVAR_REF]]
+
+	// LAMBDA-DAG: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+	// LAMBDA-DAG: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+	// LAMBDA-DAG: [[SFVAR_REF_VAL:%.+]] = load float, float* [[SFVAR_REF]]
+	// LAMBDA-DAG: [[SFVAR_REF_CONV:%.+]] = fpext float [[SFVAR_REF_VAL]] to double
+	// LAMBDA-DAG: [[SFVAR_ADD:%.+]] = fadd double [[SFVAR_REF_CONV]], 8.{{.+}}
+	// LAMBDA-DAG: [[SFVAR_ADD_CONV:%.+]] = fptrunc double [[SFVAR_ADD]] to float
+	// LAMBDA-DAG: store float [[SFVAR_ADD_CONV]], float* [[SFVAR_REF]],
+      }();
+    }
+  }();
+  return 0;
+  #else
+  S<float> test;
+  int t_var = 0;
+  int vec[] = {1, 2};
+  S<float> s_arr[] = {1, 2};
+  S<float> &var = test;
+
+  #pragma omp target
+  #pragma omp teams
+  #pragma omp distribute firstprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+  for (int i = 0; i < 2; ++i) {
+    vec[i] = t_var;
+    s_arr[i] = var;
+  }
+  return tmain<int>();
+  #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[OMP_OUTLINED:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED]](i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}}, i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.*}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.*}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.*}} [[VAR_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]])
+
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[TMP:%.+]] = alloca [[S_FLOAT_TY]]*,
+
+// discard omp loop variables
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK: store i{{[0-9]+}} [[T_VAR_IN]], i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} [[SVAR_IN]], i{{[0-9]+}}* [[SVAR_ADDR]],
+
+// init t_var
+// CHECK-64-DAG: [[T_VAR_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_ADDR]] to i{{[0-9]+}}*
+// CHECK-64-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR_CONV]],
+// CHECK-32-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK-DAG: store i{{[0-9]+}} [[T_VAR_ADDR_CONV_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
+
+// init vec
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[VEC_ADDR_VAL_BCAST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i{{[0-9]+}}*
+// CHECK-DAG: [[VEC_PRIV_BCAST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i{{[0-9]+}}*
+// CHECK-DAG: call void @llvm.memcpy.{{.*}}(i{{[0-9]+}}* [[VEC_PRIV_BCAST]], i{{[0-9]+}}* [[VEC_ADDR_VAL_BCAST]],{{.+}})
+
+// init s_arr
+// CHECK-DAG: [[S_ARR_ADDR_VAL:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_VAL]] to [[S_FLOAT_TY]]*
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.+}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]]{{.+}}
+// CHECK-DAG: [[S_ARR_PRIV_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BGN]]{{.+}}
+// CHECK-DAG: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BGN]], [[S_ARR_PRIV_NEXT]]
+// CHECK-DAG: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_CPY_DONE:.+]], label %[[S_ARR_CPY_BODY:.+]]
+
+// CHECK-DAG: [[S_ARR_CPY_BODY]]:
+// CHECK-DAG: [[S_ARR_SRC_PAST:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BCAST]],{{.+}} ], [ [[S_ARR_SRC:%.+]],{{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_PAST:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]],{{.+}} ], [ [[S_ARR_DST:%.+]],{{.+}} ]
+// CHECK-DAG: [[S_ARR_SRC_BCAST:%.+]] = bitcast{{.+}} [[S_ARR_SRC_PAST]] to{{.+}}
+// CHECK-DAG: [[S_ARR_DST_BCAST:%.+]] = bitcast{{.+}} [[S_ARR_DST_PAST]] to{{.+}}
+// CHECK-DAG: call{{.+}} @llvm.memcpy.{{.+}}({{.+}}* [[S_ARR_DST_BCAST]], {{.+}}* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr{{.+}}
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr{{.+}}
+// CHECK-DAG: [[S_ARR_CPY_FIN:%.+]] = icmp{{.+}} [[S_ARR_DST]], [[S_ARR_PRIV_NEXT]]
+// CHECK-DAG: br i1 [[S_ARR_CPY_FIN]], label %[[S_ARR_CPY_DONE]], label %[[S_ARR_CPY_BODY]]
+// CHECK-DAG: [[S_ARR_CPY_DONE]]:
+
+// init var
+// CHECK-DAG: [[VAR_ADDR_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK-DAG: store{{.+}} [[VAR_ADDR_VAL]],{{.+}} [[TMP]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP]],
+// CHECK-DAG: [[VAR_PRIV_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_PRIV]] to{{.+}}
+// CHECK-DAG: [[TMP_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to{{.+}}
+// CHECK-DAG: call{{.+}} @llvm.memcpy.{{.+}}({{.+}}* [[VAR_PRIV_BCAST]], {{.+}}* [[TMP_BCAST]],{{.+}})
+// CHECK-DAG: store [[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]** [[TMP_PRIV]],
+
+// init svar
+// CHECK-64-DAG: [[SVAR_ADDR_CONV:%.+]] = bitcast{{.+}} [[SVAR_ADDR]] to{{.+}}
+// CHECK-64-DAG: [[SVAR_CONV_VAL:%.+]] = load{{.+}},{{.+}} [[SVAR_ADDR_CONV]],
+// CHECK-32-DAG: [[SVAR_CONV_VAL:%.+]] = load{{.+}},{{.+}} [[SVAR_ADDR]],
+// CHECK-DAG: store{{.+}} [[SVAR_CONV_VAL]],{{.+}} [[SVAR_PRIV]],
+
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 1, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 1, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* %.omp{{.+}},
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// Template
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[OMP_OUTLINED_1:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED_1]](i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}}, i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.*}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]*{{.*}} [[S_ARR_IN:%.+]], [[S_INT_TY]]*{{.*}} [[VAR_IN:%.+]])
+
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// discard omp loop variables
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK-DAG: [[TMP_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+
+// CHECK: store i{{[0-9]+}} [[T_VAR_IN]], i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN]], [[S_INT_TY]]** [[VAR_ADDR]],
+
+// init t_var
+// CHECK-64-DAG: [[T_VAR_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_ADDR]] to i{{[0-9]+}}*
+// CHECK-64-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR_CONV]],
+// CHECK-32-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK-DAG: store i{{[0-9]+}} [[T_VAR_ADDR_CONV_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
+
+// init vec
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[VEC_ADDR_VAL_BCAST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i{{[0-9]+}}*
+// CHECK-DAG: [[VEC_PRIV_BCAST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i{{[0-9]+}}*
+// CHECK-DAG: call void @llvm.memcpy.{{.*}}(i{{[0-9]+}}* [[VEC_PRIV_BCAST]], i{{[0-9]+}}* [[VEC_ADDR_VAL_BCAST]],{{.+}})
+
+// init s_arr
+// CHECK-DAG: [[S_ARR_ADDR_VAL:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_VAL]] to [[S_INT_TY]]*
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.+}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]]{{.+}}
+// CHECK-DAG: [[S_ARR_PRIV_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BGN]]{{.+}}
+// CHECK-DAG: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BGN]], [[S_ARR_PRIV_NEXT]]
+// CHECK-DAG: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_CPY_DONE:.+]], label %[[S_ARR_CPY_BODY:.+]]
+
+// CHECK-DAG: [[S_ARR_CPY_BODY]]:
+// CHECK-DAG: [[S_ARR_SRC_PAST:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BCAST]],{{.+}} ], [ [[S_ARR_SRC:%.+]],{{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_PAST:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]],{{.+}} ], [ [[S_ARR_DST:%.+]],{{.+}} ]
+// CHECK-DAG: [[S_ARR_SRC_BCAST:%.+]] = bitcast{{.+}} [[S_ARR_SRC_PAST]] to{{.+}}
+// CHECK-DAG: [[S_ARR_DST_BCAST:%.+]] = bitcast{{.+}} [[S_ARR_DST_PAST]] to{{.+}}
+// CHECK-DAG: call{{.+}} @llvm.memcpy.{{.+}}({{.+}}* [[S_ARR_DST_BCAST]], {{.+}}* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr{{.+}}
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr{{.+}}
+// CHECK-DAG: [[S_ARR_CPY_FIN:%.+]] = icmp{{.+}} [[S_ARR_DST]], [[S_ARR_PRIV_NEXT]]
+// CHECK-DAG: br i1 [[S_ARR_CPY_FIN]], label %[[S_ARR_CPY_DONE]], label %[[S_ARR_CPY_BODY]]
+// CHECK-DAG: [[S_ARR_CPY_DONE]]:
+
+// init var
+// CHECK-DAG: [[VAR_ADDR_VAL:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR]],
+// CHECK-DAG: store{{.+}} [[VAR_ADDR_VAL]],{{.+}} [[TMP]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP]],
+// CHECK-DAG: [[VAR_PRIV_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_PRIV]] to{{.+}}
+// CHECK-DAG: [[TMP_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL]] to{{.+}}
+// CHECK-DAG: call{{.+}} @llvm.memcpy.{{.+}}({{.+}}* [[VAR_PRIV_BCAST]], {{.+}}* [[TMP_BCAST]],{{.+}})
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP_PRIV]],
+
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 1, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 1, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* %.omp{{.+}},
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/distribute_lastprivate_codegen.cpp b/test/OpenMP/distribute_lastprivate_codegen.cpp
new file mode 100644
index 0000000..abcbfd8
--- /dev/null
+++ b/test/OpenMP/distribute_lastprivate_codegen.cpp
@@ -0,0 +1,377 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1  -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1  -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1  -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1  -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1  -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1  -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+  T f;
+  S(T a) : f(a) {}
+  S() : f() {}
+  operator T() { return T(); }
+  ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+  S<T> test;
+  T t_var = T();
+  T vec[] = {1, 2};
+  S<T> s_arr[] = {1, 2};
+  S<T> &var = test;
+  #pragma omp target
+  #pragma omp teams
+#pragma omp distribute lastprivate(t_var, vec, s_arr, s_arr, var, var)
+  for (int i = 0; i < 2; ++i) {
+    vec[i] = t_var;
+    s_arr[i] = var;
+  }
+  return T();
+}
+
+int main() {
+  static int svar;
+  volatile double g;
+  volatile double &g1 = g;
+
+  #ifdef LAMBDA
+  // LAMBDA-LABEL: @main
+  // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+  [&]() {
+    static float sfvar;
+    // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+    // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+    // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+    // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+    // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+    #pragma omp target
+    #pragma omp teams
+#pragma omp distribute lastprivate(g, g1, svar, sfvar)
+    for (int i = 0; i < 2; ++i) {
+      // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+      // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+      // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+      // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+      // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+      // LAMBDA: [[TMP_G1:%.+]] = alloca double*,
+      // loop variables
+      // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+      // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+      // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+      // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+      // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+      // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+      // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+      // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+      // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+      // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+      // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+      // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+      // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+      // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+      // init private variables
+      // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+      // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+      // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+      // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+      // LAMBDA: store double* [[G1_IN_REF]], double** [[TMP_G1]],
+      // LAMBDA: [[TMP_G1_VAL:%.+]] = load double*, double** [[TMP_G1]],
+      // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+      g = 1;
+      g1 = 1;
+      svar = 3;
+      sfvar = 4.0;
+      // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+      // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE]],
+      // LAMBDA: [[TMP_G1_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+      // LAMBDA: store{{.+}} double 1.0{{.+}}, double* [[TMP_G1_REF]],
+      // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+      // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE]],
+      // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+      // LAMBDA: store double* [[G_PRIVATE]], double** [[G_PRIVATE_ADDR_REF]],
+      // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+      // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+      // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+      // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+      // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+      // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+      // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+      // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+      // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+      // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+      // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+      // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+      // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+      // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+      // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+      // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+      // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+      // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[TMP_G1_VAL]],
+
+      // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+      // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+      // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+      // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+      // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+      // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+      // LAMBDA: ret
+      [&]() {
+	// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+	// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+	g = 2;
+	g1 = 2;
+	svar = 4;
+	sfvar = 8.0;
+	// LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+	// LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+	// LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+	// LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+	// LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+	// LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+	// LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+	// LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+	// LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+	// LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+	// LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+	// LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+	// LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+      }();
+    }
+  }();
+  return 0;
+  #else
+  S<float> test;
+  int t_var = 0;
+  int vec[] = {1, 2};
+  S<float> s_arr[] = {1, 2};
+  S<float> &var = test;
+
+  #pragma omp target
+  #pragma omp teams
+#pragma omp distribute lastprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+  for (int i = 0; i < 2; ++i) {
+    vec[i] = t_var;
+    s_arr[i] = var;
+  }
+  int i;
+
+  return tmain<int>();
+  #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_FLOAT_TY]]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} {{.+}}, [2 x [[S_FLOAT_TY]]]*{{.+}} {{.+}}, [[S_FLOAT_TY]]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.*}} [[S_VAR_IN:%.+]])
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[TMP:%.*]] = alloca [[S_FLOAT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_ADDR_REF]], [[S_FLOAT_TY]]** [[TMP]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[TMP_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK:  store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_INT_TY]]]* {{.+}}, [[S_INT_TY]]* {{.+}})
+// CHECK: ret
+
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_1:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN1:%.+]], [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]],  [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN1]], i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[T_VAR_ADDR_REF1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_ADDR1_REF]], [[S_INT_TY]]** [[TMP]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK-DAG: [[TMP_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[IV_VAL1:%.+]] =
+// CHECK: [[T_VAR_PRIV_VAL1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: [[VEC_PTR1:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV1]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK:  store i{{[0-9]+}} [[T_VAR_PRIV_VAL1]], i{{[0-9]+}}* [[VEC_PTR1]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR1:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]],
+// CHECK-DAG: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_PTR1]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST1]], i8* [[TMP_VAL_BCAST1]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/distribute_parallel_for_ast_print.cpp b/test/OpenMP/distribute_parallel_for_ast_print.cpp
index 012f278..874345b 100644
--- a/test/OpenMP/distribute_parallel_for_ast_print.cpp
+++ b/test/OpenMP/distribute_parallel_for_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/distribute_parallel_for_if_messages.cpp b/test/OpenMP/distribute_parallel_for_if_messages.cpp
index c864340..5e9d9ad 100644
--- a/test/OpenMP/distribute_parallel_for_if_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
@@ -58,7 +58,7 @@
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp distribute parallel for if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams
@@ -144,7 +144,7 @@
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp distribute parallel for if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams
diff --git a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
index 021b8f8..6ed3f21 100644
--- a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp
index 01236b5..c6957b9 100644
--- a/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
@@ -58,7 +58,7 @@
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp distribute parallel for simd if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams
@@ -144,7 +144,7 @@
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp distribute parallel for simd if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams
diff --git a/test/OpenMP/distribute_private_codegen.cpp b/test/OpenMP/distribute_private_codegen.cpp
new file mode 100644
index 0000000..c637fb4
--- /dev/null
+++ b/test/OpenMP/distribute_private_codegen.cpp
@@ -0,0 +1,206 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1  -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1  -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1  -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1  -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1  -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1  -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+  T f;
+  S(T a) : f(a) {}
+  S() : f() {}
+  operator T() { return T(); }
+  ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+  S<T> test;
+  T t_var = T();
+  T vec[] = {1, 2};
+  S<T> s_arr[] = {1, 2};
+  S<T> &var = test;
+  #pragma omp target
+  #pragma omp teams
+#pragma omp distribute private(t_var, vec, s_arr, s_arr, var, var)
+  for (int i = 0; i < 2; ++i) {
+    vec[i] = t_var;
+    s_arr[i] = var;
+  }
+  return T();
+}
+
+int main() {
+  static int svar;
+  volatile double g;
+  volatile double &g1 = g;
+
+  #ifdef LAMBDA
+  // LAMBDA-LABEL: @main
+  // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+  [&]() {
+    static float sfvar;
+    // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+    // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+    // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+    // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]]()
+    // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+    #pragma omp target
+    #pragma omp teams
+#pragma omp distribute private(g, g1, svar, sfvar)
+    for (int i = 0; i < 2; ++i) {
+      // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
+      // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double,
+      // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double,
+      // LAMBDA: [[TMP_PRIVATE_ADDR:%.+]] = alloca double*,
+      // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+      // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float,
+      // LAMBDA: store double* [[G1_PRIVATE_ADDR]], double** [[TMP_PRIVATE_ADDR]],
+      g = 1;
+      g1 = 1;
+      svar = 3;
+      sfvar = 4.0;
+      // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+      // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
+      // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]],
+      // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE_ADDR]],
+      // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+      // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]],
+      // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+      // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_PRIVATE_ADDR]],
+      // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+      // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+      // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+      // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+      // LAMBDA: store float* [[SFVAR_PRIVATE_ADDR]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+      // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+      // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+      [&]() {
+	// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+	// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+	g = 2;
+	g1 = 2;
+	svar = 4;
+	sfvar = 8.0;
+	// LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+	// LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+	// LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+	// LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+	// LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+	// LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+	// LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+	// LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+	// LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+	// LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+	// LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+	// LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+	// LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+      }();
+    }
+  }();
+  return 0;
+  #else
+  S<float> test;
+  int t_var = 0;
+  int vec[] = {1, 2};
+  S<float> s_arr[] = {1, 2};
+  S<float> &var = test;
+
+  #pragma omp target
+  #pragma omp teams
+#pragma omp distribute private(t_var, vec, s_arr, s_arr, var, var, svar)
+  for (int i = 0; i < 2; ++i) {
+    vec[i] = t_var;
+    s_arr[i] = var;
+  }
+  int i;
+
+  #pragma omp target
+  #pragma omp teams
+#pragma omp distribute private(i)
+  for (i = 0; i < 2; ++i) {
+    ;
+  }
+  return tmain<int>();
+  #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]]()
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-NOT: alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-NOT: alloca [[S_FLOAT_TY]],
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]*
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](
+// CHECK: ret
+
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]]()
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_1:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED_1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK-NOT: alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK-NOT: alloca [[S_INT_TY]],
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp
index 4706255..b27bd7b 100644
--- a/test/OpenMP/for_codegen.cpp
+++ b/test/OpenMP/for_codegen.cpp
@@ -2,10 +2,13 @@
 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
+// RUN: %clang_cc1 -main-file-name for_codegen.cpp %s -o - -emit-llvm -fprofile-instrument=clang -fprofile-instrument-path=for_codegen-test.profraw | FileCheck %s --check-prefix=PROF-INSTR-PATH
 //
 // expected-no-diagnostics
 #ifndef HEADER
 #define HEADER
+// PROF-INSTR-PATH: constant [25 x i8] c"for_codegen-test.profraw\00"
+
 // CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
 // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
 // CHECK-DAG: [[I:@.+]] = global i8 1,
diff --git a/test/OpenMP/linking.c b/test/OpenMP/linking.c
index 7b30592..71e978f 100644
--- a/test/OpenMP/linking.c
+++ b/test/OpenMP/linking.c
@@ -7,42 +7,42 @@
 // RUN:     -fopenmp -target i386-unknown-linux -rtlib=platform \
 // RUN:   | FileCheck --check-prefix=CHECK-LD-32 %s
 // CHECK-LD-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-LD-32: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" "-lgcc"
+// CHECK-LD-32: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]"
 // CHECK-LD-32: "-lpthread" "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -fopenmp -target x86_64-unknown-linux -rtlib=platform \
 // RUN:   | FileCheck --check-prefix=CHECK-LD-64 %s
 // CHECK-LD-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-LD-64: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" "-lgcc"
+// CHECK-LD-64: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]"
 // CHECK-LD-64: "-lpthread" "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -fopenmp=libgomp -target i386-unknown-linux -rtlib=platform \
 // RUN:   | FileCheck --check-prefix=CHECK-GOMP-LD-32 %s
 // CHECK-GOMP-LD-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-GOMP-LD-32: "-lgomp" "-lrt" "-lgcc"
+// CHECK-GOMP-LD-32: "-lgomp" "-lrt"
 // CHECK-GOMP-LD-32: "-lpthread" "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -fopenmp=libgomp -target x86_64-unknown-linux -rtlib=platform \
 // RUN:   | FileCheck --check-prefix=CHECK-GOMP-LD-64 %s
 // CHECK-GOMP-LD-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-GOMP-LD-64: "-lgomp" "-lrt" "-lgcc"
+// CHECK-GOMP-LD-64: "-lgomp" "-lrt"
 // CHECK-GOMP-LD-64: "-lpthread" "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -fopenmp -target i386-unknown-linux -rtlib=platform \
 // RUN:   | FileCheck --check-prefix=CHECK-IOMP5-LD-32 %s
 // CHECK-IOMP5-LD-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-IOMP5-LD-32: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" "-lgcc"
+// CHECK-IOMP5-LD-32: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]"
 // CHECK-IOMP5-LD-32: "-lpthread" "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -fopenmp -target x86_64-unknown-linux -rtlib=platform \
 // RUN:   | FileCheck --check-prefix=CHECK-IOMP5-LD-64 %s
 // CHECK-IOMP5-LD-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-IOMP5-LD-64: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" "-lgcc"
+// CHECK-IOMP5-LD-64: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]"
 // CHECK-IOMP5-LD-64: "-lpthread" "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
@@ -60,7 +60,7 @@
 // RUN:     -rtlib=platform \
 // RUN:   | FileCheck --check-prefix=CHECK-LD-OVERRIDE-32 %s
 // CHECK-LD-OVERRIDE-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-LD-OVERRIDE-32: "-lgomp" "-lrt" "-lgcc"
+// CHECK-LD-OVERRIDE-32: "-lgomp" "-lrt"
 // CHECK-LD-OVERRIDE-32: "-lpthread" "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
@@ -68,7 +68,7 @@
 // RUN:     -rtlib=platform \
 // RUN:   | FileCheck --check-prefix=CHECK-LD-OVERRIDE-64 %s
 // CHECK-LD-OVERRIDE-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-LD-OVERRIDE-64: "-lgomp" "-lrt" "-lgcc"
+// CHECK-LD-OVERRIDE-64: "-lgomp" "-lrt"
 // CHECK-LD-OVERRIDE-64: "-lpthread" "-lc"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
diff --git a/test/OpenMP/nesting_of_regions.cpp b/test/OpenMP/nesting_of_regions.cpp
index 1b96bd2..6282de4 100644
--- a/test/OpenMP/nesting_of_regions.cpp
+++ b/test/OpenMP/nesting_of_regions.cpp
@@ -185,6 +185,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp parallel
+  {
+#pragma omp target teams // OK
+    ++a;
+  }
+#pragma omp parallel
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // SIMD DIRECTIVE
 #pragma omp simd
@@ -407,7 +436,36 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
-
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+  
 // FOR DIRECTIVE
 #pragma omp for
   for (int i = 0; i < 10; ++i) {
@@ -642,6 +700,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // OK
+    ++a;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // FOR SIMD DIRECTIVE
 #pragma omp for simd
@@ -865,6 +952,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // SECTIONS DIRECTIVE
 #pragma omp sections
@@ -1105,6 +1221,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp sections
+  {
+#pragma omp target teams // OK
+    ++a;
+  }
+#pragma omp sections
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // SECTION DIRECTIVE
 #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
@@ -1407,6 +1552,40 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams // OK
+    ++a;
+  }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // SINGLE DIRECTIVE
 #pragma omp single
@@ -1633,6 +1812,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp single
+  {
+#pragma omp target teams // OK
+    ++a;
+  }
+#pragma omp single
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // MASTER DIRECTIVE
 #pragma omp master
@@ -1859,6 +2067,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp master
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp master
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // CRITICAL DIRECTIVE
 #pragma omp critical
@@ -2099,6 +2336,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp critical
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp critical
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // PARALLEL FOR DIRECTIVE
 #pragma omp parallel for
@@ -2339,6 +2605,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // PARALLEL FOR SIMD DIRECTIVE
 #pragma omp parallel for simd
@@ -2580,6 +2875,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // PARALLEL SECTIONS DIRECTIVE
 #pragma omp parallel sections
@@ -2809,6 +3133,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp parallel sections
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TASK DIRECTIVE
 #pragma omp task
@@ -2985,6 +3338,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp task
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp task
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp task
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp task
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp task
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // ORDERED DIRECTIVE
 #pragma omp ordered
@@ -3232,6 +3614,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp ordered
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp ordered
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp ordered
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp ordered
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp ordered
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // ATOMIC DIRECTIVE
 #pragma omp atomic
@@ -3517,6 +3928,45 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    a++;
+  }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TARGET DIRECTIVE
 #pragma omp target
@@ -3709,6 +4159,36 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp target
+  { 
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+  { 
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+  { 
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+  { 
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+  { 
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TARGET PARALLEL DIRECTIVE
 #pragma omp target parallel
@@ -3895,6 +4375,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp target parallel
+  { 
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target parallel' region}}
+    a++;
+  }
+#pragma omp target parallel
+  { 
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target parallel' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target parallel
+  { 
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target parallel' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target parallel
+  { 
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target parallel' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target parallel
+  { 
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target parallel' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TARGET PARALLEL FOR DIRECTIVE
 #pragma omp target parallel for
@@ -4135,6 +4644,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }    
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    a++;
+  }    
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }    
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // TEAMS DIRECTIVE
 #pragma omp teams // expected-error {{orphaned 'omp teams' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
@@ -4248,7 +4786,7 @@
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target' directive into a parallel region?}}
+#pragma omp target // expected-error {{region cannot be nested inside 'target' region}}
     ++a;
   }
 #pragma omp target
@@ -4265,13 +4803,13 @@
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target enter data map(to: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target enter data' directive into a parallel region?}}
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}}
     ++a;
   }
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target exit data map(from: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target exit data' directive into a parallel region?}}
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
     ++a;
   }
 #pragma omp target
@@ -4303,7 +4841,7 @@
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target update to(a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
   }
 #pragma omp target
 #pragma omp teams
@@ -4338,7 +4876,7 @@
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target simd // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target simd' directive into a parallel region?}}
+#pragma omp target simd // expected-error {{region cannot be nested inside 'target' region}}
   for (int i = 0; i < 10; ++i)
     ;
   }
@@ -4370,6 +4908,40 @@
   for (int i = 0; i < 10; ++i)
     ;
   }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    a++;
+  }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
 
 // TASKLOOP DIRECTIVE
 #pragma omp taskloop
@@ -4601,6 +5173,35 @@
   for (int j = 0; j < 10; ++j)
     ++a;
   }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // OK
+    ++a;
+  }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // OK
+  for (int j = 0; j < 10; ++j)
+    ++a;
+  }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // OK
+  for (int j = 0; j < 10; ++j)
+    ++a;
+  }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // OK
+  for (int j = 0; j < 10; ++j)
+    ++a;
+  }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // OK
+  for (int j = 0; j < 10; ++j)
+    ++a;
+  }
 
 // DISTRIBUTE DIRECTIVE
 #pragma omp target
@@ -4866,6 +5467,45 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    a++;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // DISTRIBUTE PARALLEL FOR DIRECTIVE
 #pragma omp target
@@ -5139,6 +5779,45 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    a++;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE
 #pragma omp target
@@ -5420,6 +6099,45 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
 
 // TARGET SIMD DIRECTIVE
 #pragma omp target simd
@@ -5625,8 +6343,26 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
 
- // TEAMS DISTRIBUTE DIRECTIVE
+// TEAMS DISTRIBUTE DIRECTIVE
 #pragma omp teams distribute // expected-error {{orphaned 'omp teams distribute' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
   for (int i = 0; i < 10; ++i)
     ;
@@ -5867,8 +6603,29 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
 
- // TEAMS DISTRIBUTE DIRECTIVE
+// TEAMS DISTRIBUTE DIRECTIVE
 #pragma omp teams distribute // expected-error {{orphaned 'omp teams distribute' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
   for (int i = 0; i < 10; ++i)
     ;
@@ -6116,6 +6873,40 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
 
 // TEAMS DISTRIBUTE SIMD DIRECTIVE
 #pragma omp teams distribute simd // expected-error {{orphaned 'omp teams distribute simd' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
@@ -6365,6 +7156,40 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
 
 // TEAMS DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE
 #pragma omp teams distribute parallel for simd // expected-error {{orphaned 'omp teams distribute parallel for simd' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
@@ -6614,6 +7439,40 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
 
 // TEAMS DISTRIBUTE PARALLEL FOR DIRECTIVE
 #pragma omp teams distribute parallel for // expected-error {{orphaned 'omp teams distribute parallel for' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
@@ -6863,6 +7722,1234 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+
+// TARGET TEAMS DIRECTIVE
+#pragma omp target teams
+#pragma omp parallel
+  bar();
+#pragma omp target teams
+#pragma omp for // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp simd // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp simd' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp for simd // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target teams region}}
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp single // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+  bar();
+
+#pragma omp target teams
+#pragma omp master // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp master' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp critical // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp critical' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp parallel sections
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp task // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp task' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp taskyield // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp taskyield' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp barrier' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp taskwait // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp flush // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp flush' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp atomic // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp atomic' directive into a parallel region?}}
+    ++a;
+  }
+#pragma omp target teams
+  {
+#pragma omp target // expected-error {{region cannot be nested inside 'target teams' region}}
+    ++a;
+  }
+#pragma omp target teams
+  {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target teams' region}}
+    ++a;
+  }
+#pragma omp target teams
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+  {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target teams' region}}
+  }
+#pragma omp target teams
+  {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target teams' region}}
+  }
+#pragma omp target teams
+  {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+    ++a;
+  }
+#pragma omp target teams
+  {
+#pragma omp taskloop // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp taskloop' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
+#pragma omp target teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+  {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target teams' region}}
+    ++a;
+  }
+#pragma omp target teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+  {
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp distribute parallel for
+  for (int j = 0; j < 10; ++j)
+    ;  
+  }
+#pragma omp target teams
+  {
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp distribute parallel for simd
+  for (int j = 0; j < 10; ++j)
+    ;  
+  }
+#pragma omp target teams
+  {
+#pragma omp distribute simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp distribute simd
+  for (int j = 0; j < 10; ++j)
+    ;  
+  }
+#pragma omp target teams
+  {
+#pragma omp target simd // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp teams distribute // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams distribute' directive into a target region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp teams distribute simd // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams distribute simd' directive into a target region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp teams distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams distribute parallel for simd' directive into a target region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp teams distribute parallel for // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams distribute parallel for' directive into a target region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target teams' region}}
+    a++;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+
+// TARGET TEAMS DISTRIBUTE DIRECTIVE
+#pragma omp target teams distribute // OK
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  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 target teams distribute region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // OK
+    {
+#pragma omp single
+      {
+	bar();
+      }
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // OK
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // OK
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // OK
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // OK
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // OK
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel  // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target simd // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams distribute' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute simd // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams distribute simd' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams distribute parallel for simd' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams distribute parallel for' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    a++;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+
+// TARGET TEAMS DISTRIBUTE PARALLEL FOR DIRECTIVE
+#pragma omp target teams distribute parallel for // OK
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute 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 target teams distribute parallel for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // OK
+    {
+#pragma omp single
+      {
+	bar();
+      }
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // OK
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // OK
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // OK
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // OK
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel  // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target simd // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams distribute' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams distribute simd' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams distribute parallel for simd' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams distribute parallel for' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    a++;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+
+// TARGET TEAMS DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE
+#pragma omp target teams distribute parallel for simd // OK
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+#pragma omp single
+      {
+	bar();
+      }
+    }
+  }
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for 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();
+    }
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}OK
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel  // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+
+// TARGET TEAMS DISTRIBUTE SIMD DIRECTIVE
+#pragma omp target teams distribute simd // OK
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute 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 target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+#pragma omp single
+      {
+	bar();
+      }
+    }
+  }
+#pragma omp target teams distribute 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 target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute 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();
+    }
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}OK
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel  // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+
 }
 
 void foo() {
@@ -7046,6 +9133,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp parallel
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp parallel
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // SIMD DIRECTIVE
 #pragma omp simd
@@ -7252,6 +9368,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // FOR DIRECTIVE
 #pragma omp for
@@ -7478,6 +9623,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // FOR SIMD DIRECTIVE
 #pragma omp for simd
@@ -7684,6 +9858,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // SECTIONS DIRECTIVE
 #pragma omp sections
@@ -7899,6 +10102,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp sections
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp sections
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // SECTION DIRECTIVE
 #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
@@ -8211,6 +10443,40 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp section
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // SINGLE DIRECTIVE
 #pragma omp single
@@ -8427,6 +10693,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp single
+  {
+#pragma omp target teams // oK
+    a++;
+  }
+#pragma omp single
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // MASTER DIRECTIVE
 #pragma omp master
@@ -8653,6 +10948,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp master
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp master
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // CRITICAL DIRECTIVE
 #pragma omp critical
@@ -8898,6 +11222,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp critical
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp critical
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // PARALLEL FOR DIRECTIVE
 #pragma omp parallel for
@@ -9139,6 +11492,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // OK
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // PARALLEL FOR SIMD DIRECTIVE
 #pragma omp parallel for simd
@@ -9380,6 +11762,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // PARALLEL SECTIONS DIRECTIVE
 #pragma omp parallel sections
@@ -9605,6 +12016,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp parallel sections
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TASK DIRECTIVE
 #pragma omp task
@@ -9780,6 +12220,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp task
+  {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp task
+  {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp task
+  {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp task
+  {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp task
+  {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // ATOMIC DIRECTIVE
 #pragma omp atomic
@@ -10064,6 +12533,45 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    a++;
+  }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp atomic
+  // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+  // expected-note@+1 {{expected an expression statement}}
+  {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TARGET DIRECTIVE
 #pragma omp target
@@ -10253,6 +12761,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp target
+  { 
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    a++;
+  }
+#pragma omp target
+  { 
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+  { 
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+  { 
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+  { 
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TARGET PARALLEL DIRECTIVE
 #pragma omp target parallel
@@ -10439,6 +12976,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp target parallel
+  { 
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target parallel' region}}
+    a++;
+  }
+#pragma omp target parallel
+  { 
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target parallel' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target parallel
+  { 
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target parallel' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target parallel
+  { 
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target parallel' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target parallel
+  { 
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target parallel' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TARGET PARALLEL FOR DIRECTIVE
 #pragma omp target parallel for
@@ -10680,6 +13246,35 @@
     for (int j = 0; j < 10; ++j)
       ;
   }
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    a++;
+  }
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target parallel for' region}}
+    for (int j = 0; j < 10; ++j)
+      ;
+  }
 
 // TEAMS DIRECTIVE
 #pragma omp target
@@ -10791,7 +13386,7 @@
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target' directive into a parallel region?}}
+#pragma omp target // expected-error {{region cannot be nested inside 'target' region}}
     ++a;
   }
 #pragma omp target
@@ -10808,12 +13403,12 @@
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target enter data map(to: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target enter data' directive into a parallel region?}}
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}}
   }
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target exit data map(from: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target exit data' directive into a parallel region?}}
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
   }
 #pragma omp target
 #pragma omp teams
@@ -10844,7 +13439,7 @@
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target update to(a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
     ++a;
   }
 #pragma omp target
@@ -10885,7 +13480,7 @@
 #pragma omp target
 #pragma omp teams
   {
-#pragma omp target simd // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target simd' directive into a parallel region?}}
+#pragma omp target simd // expected-error {{region cannot be nested inside 'target' region}}
   for (int i = 0; i < 10; ++i)
     ;
   }
@@ -10917,6 +13512,40 @@
   for (int i = 0; i < 10; ++i)
     ;
   }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    a++;
+  }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target
+#pragma omp teams
+  {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
 
 // TASKLOOP DIRECTIVE
 #pragma omp taskloop
@@ -11148,6 +13777,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // OK
+    a++;
+  }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // DISTRIBUTE DIRECTIVE
 #pragma omp target
@@ -11421,6 +14079,46 @@
   for (int i = 0; i < 10; ++i)
     ++a;
   }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
 
 // DISTRIBUTE PARALLEL FOR DIRECTIVE
 #pragma omp target
@@ -11703,6 +14401,45 @@
   for (int i = 0; i < 10; ++i)
     ++a;
   }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
 
 // DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE
 #pragma omp target
@@ -11976,6 +14713,45 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // DISTRIBUTE SIMD DIRECTIVE
 #pragma omp target
@@ -12249,6 +15025,45 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TARGET SIMD DIRECTIVE
 #pragma omp target simd
@@ -12454,6 +15269,35 @@
     for (int i = 0; i < 10; ++i)
       ;
   }
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
 // TEAMS DISTRIBUTE DIRECTIVE
 #pragma omp teams distribute // expected-error {{orphaned 'omp teams distribute' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
@@ -12703,6 +15547,40 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
 
 // TEAMS DISTRIBUTE SIMD DIRECTIVE
 #pragma omp teams distribute simd // expected-error {{orphaned 'omp teams distribute simd' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
@@ -12952,6 +15830,40 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
 
 // TEAMS DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE
 #pragma omp teams distribute parallel for simd // expected-error {{orphaned 'omp teams distribute parallel for simd' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
@@ -13201,8 +16113,40 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
-
-//--------------------
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
 
 // TEAMS DISTRIBUTE PARALLEL FOR DIRECTIVE
 #pragma omp teams distribute parallel for // expected-error {{orphaned 'omp teams distribute parallel for' directives are prohibited; perhaps you forget to enclose the directive into a target region?}}
@@ -13452,6 +16396,1233 @@
     for (int i = 0; i < 10; ++i)
       ++a;
   }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target' region}}
+    ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+
+// TARGET TEAMS DIRECTIVE
+#pragma omp target teams
+#pragma omp parallel
+  bar();
+#pragma omp target teams
+#pragma omp for // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp simd // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp simd' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp for simd // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target teams region}}
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp single // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+  bar();
+
+#pragma omp target teams
+#pragma omp master // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp master' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp critical // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp critical' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+#pragma omp parallel sections
+  {
+    bar();
+  }
+#pragma omp target teams
+#pragma omp task // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp task' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp taskyield // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp taskyield' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp barrier' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp taskwait // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp flush // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp flush' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp target teams
+  {
+#pragma omp atomic // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp atomic' directive into a parallel region?}}
+    ++a;
+  }
+#pragma omp target teams
+  {
+#pragma omp target // expected-error {{region cannot be nested inside 'target teams' region}}
+    ++a;
+  }
+#pragma omp target teams
+  {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target teams' region}}
+    ++a;
+  }
+#pragma omp target teams
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+  {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target teams' region}}
+  }
+#pragma omp target teams
+  {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target teams' region}}
+  }
+#pragma omp target teams
+  {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+    ++a;
+  }
+#pragma omp target teams
+  {
+#pragma omp taskloop // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp taskloop' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ++a;
+  }
+#pragma omp target teams
+#pragma omp distribute
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+  {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target teams' region}}
+    ++a;
+  }
+#pragma omp target teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams
+  {
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp distribute parallel for
+  for (int j = 0; j < 10; ++j)
+    ;  
+  }
+#pragma omp target teams
+  {
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp distribute parallel for simd
+  for (int j = 0; j < 10; ++j)
+    ;  
+  }
+#pragma omp target teams
+  {
+#pragma omp distribute simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp distribute simd
+  for (int j = 0; j < 10; ++j)
+    ;  
+  }
+#pragma omp target teams
+  {
+#pragma omp target simd // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp teams distribute // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams distribute' directive into a target region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp teams distribute simd // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams distribute simd' directive into a target region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp teams distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams distribute parallel for simd' directive into a target region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp teams distribute parallel for // expected-error {{region cannot be closely nested inside 'target teams' region; perhaps you forget to enclose 'omp teams distribute parallel for' directive into a target region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target teams' region}}
+    a++;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+#pragma omp target teams
+  {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target teams' region}}
+  for (int i = 0; i < 10; ++i)
+    ;
+  }
+
+// TARGET TEAMS DISTRIBUTE DIRECTIVE
+#pragma omp target teams distribute // OK
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  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 target teams distribute region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // OK
+    {
+#pragma omp single
+      {
+	bar();
+      }
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // OK
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // OK
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // OK
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // OK
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // OK
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel  // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target simd // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams distribute' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute simd // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams distribute simd' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams distribute parallel for simd' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for // expected-error {{region cannot be closely nested inside 'target teams distribute' region; perhaps you forget to enclose 'omp teams distribute parallel for' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target teams distribute' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+
+// TARGET TEAMS DISTRIBUTE PARALLEL FOR DIRECTIVE
+#pragma omp target teams distribute parallel for // OK
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute 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 target teams distribute parallel for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // OK
+    {
+#pragma omp single
+      {
+	bar();
+      }
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // OK
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task // OK
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // OK
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // OK
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // OK
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // OK
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel  // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target simd // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams distribute' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams distribute simd' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams distribute parallel for simd' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for // expected-error {{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp teams distribute parallel for' directive into a target region?}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{region cannot be nested inside 'target teams distribute parallel for' region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+
+// TARGET TEAMS DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE
+#pragma omp target teams distribute parallel for simd // OK
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+#pragma omp single
+      {
+	bar();
+      }
+    }
+  }
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for 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();
+    }
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}OK
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel  // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+
+// TARGET TEAMS DISTRIBUTE SIMD DIRECTIVE
+#pragma omp target teams distribute simd // OK
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute 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 target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+#pragma omp single
+      {
+	bar();
+      }
+    }
+  }
+#pragma omp target teams distribute 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 target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute 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();
+    }
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}OK
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel  // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ++a;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    a++;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp target teams distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
 
   return foo<int>();
 }
diff --git a/test/OpenMP/nvptx_parallel_codegen.cpp b/test/OpenMP/nvptx_parallel_codegen.cpp
new file mode 100644
index 0000000..224f245
--- /dev/null
+++ b/test/OpenMP/nvptx_parallel_codegen.cpp
@@ -0,0 +1,317 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+  short aa = 0;
+  tx b[10];
+
+  #pragma omp target if(0)
+  {
+    #pragma omp parallel
+    {
+      int a = 41;
+    }
+    a += 1;
+  }
+
+  #pragma omp target
+  {
+    #pragma omp parallel
+    {
+      int a = 42;
+    }
+    #pragma omp parallel if(0)
+    {
+      int a = 43;
+    }
+    #pragma omp parallel if(1)
+    {
+      int a = 44;
+    }
+    a += 1;
+  }
+
+  #pragma omp target if(n>40)
+  {
+    #pragma omp parallel if(n>1000)
+    {
+      int a = 45;
+    }
+    a += 1;
+    aa += 1;
+    b[2] += 1;
+  }
+
+  return a;
+}
+
+int bar(int n){
+  int a = 0;
+
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+  // CHECK-NOT: define {{.*}}void {{@__omp_offloading_.+template.+l17}}_worker()
+
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l26}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+  //
+  // CHECK: [[AWAIT_WORK]]
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]])
+  // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
+  // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
+  // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+  //
+  // CHECK: [[SEL_WORKERS]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]]
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
+  // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+  //
+  // CHECK: [[EXEC_PARALLEL]]
+  // CHECK: [[WF1:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[WM1:%.+]] = icmp eq i8* [[WF1]], bitcast (void (i32*, i32*)* [[PARALLEL_FN1:@.+]] to i8*)
+  // CHECK: br i1 [[WM1]], label {{%?}}[[EXEC_PFN1:.+]], label {{%?}}[[CHECK_NEXT1:.+]]
+  //
+  // CHECK: [[EXEC_PFN1]]
+  // CHECK: call void [[PARALLEL_FN1]](
+  // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+  //
+  // CHECK: [[CHECK_NEXT1]]
+  // CHECK: [[WF2:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[WM2:%.+]] = icmp eq i8* [[WF2]], bitcast (void (i32*, i32*)* [[PARALLEL_FN2:@.+]] to i8*)
+  // CHECK: br i1 [[WM2]], label {{%?}}[[EXEC_PFN2:.+]], label {{%?}}[[CHECK_NEXT2:.+]]
+  //
+  // CHECK: [[EXEC_PFN2]]
+  // CHECK: call void [[PARALLEL_FN2]](
+  // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+  //
+  // CHECK: [[CHECK_NEXT2]]
+  // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+  //
+  // CHECK: [[TERM_PARALLEL]]
+  // CHECK: call void @__kmpc_kernel_end_parallel()
+  // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+  //
+  // CHECK: [[BAR_PARALLEL]]
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: br label {{%?}}[[AWAIT_WORK]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+
+  // CHECK: define {{.*}}void [[T6:@__omp_offloading_.+template.+l26]](i[[SZ:32|64]]
+  // Create local storage for each capture.
+  // CHECK:  [[LOCAL_A:%.+]] = alloca i[[SZ]],
+  // CHECK-DAG:  store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+  // Store captures in the context.
+  // CHECK-64-DAG:[[REF_A:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+  //
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
+  //
+  // CHECK: [[WORKER]]
+  // CHECK: {{call|invoke}} void [[T6]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
+  //
+  // CHECK: [[MASTER]]
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
+  // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i32*, i32*)* [[PARALLEL_FN1]] to i8*))
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @__kmpc_serialized_parallel(
+  // CHECK: {{call|invoke}} void [[PARALLEL_FN3:@.+]](
+  // CHECK: call void @__kmpc_end_serialized_parallel(
+  // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i32*, i32*)* [[PARALLEL_FN2]] to i8*))
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK-64-DAG: load i32, i32* [[REF_A]]
+  // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
+  //
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: br label {{%?}}[[EXIT]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+
+  // CHECK-DAG: define internal void [[PARALLEL_FN1]](
+  // CHECK: [[A:%.+]] = alloca i[[SZ:32|64]],
+  // CHECK: store i[[SZ]] 42, i[[SZ]]* %a,
+  // CHECK: ret void
+
+  // CHECK-DAG: define internal void [[PARALLEL_FN3]](
+  // CHECK: [[A:%.+]] = alloca i[[SZ:32|64]],
+  // CHECK: store i[[SZ]] 43, i[[SZ]]* %a,
+  // CHECK: ret void
+
+  // CHECK-DAG: define internal void [[PARALLEL_FN2]](
+  // CHECK: [[A:%.+]] = alloca i[[SZ:32|64]],
+  // CHECK: store i[[SZ]] 44, i[[SZ]]* %a,
+  // CHECK: ret void
+
+
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l43}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+  //
+  // CHECK: [[AWAIT_WORK]]
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]])
+  // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
+  // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
+  // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+  //
+  // CHECK: [[SEL_WORKERS]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]]
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
+  // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+  //
+  // CHECK: [[EXEC_PARALLEL]]
+  // CHECK: [[WF:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[WM:%.+]] = icmp eq i8* [[WF]], bitcast (void (i32*, i32*)* [[PARALLEL_FN4:@.+]] to i8*)
+  // CHECK: br i1 [[WM]], label {{%?}}[[EXEC_PFN:.+]], label {{%?}}[[CHECK_NEXT:.+]]
+  //
+  // CHECK: [[EXEC_PFN]]
+  // CHECK: call void [[PARALLEL_FN4]](
+  // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+  //
+  // CHECK: [[CHECK_NEXT]]
+  // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+  //
+  // CHECK: [[TERM_PARALLEL]]
+  // CHECK: call void @__kmpc_kernel_end_parallel()
+  // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+  //
+  // CHECK: [[BAR_PARALLEL]]
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: br label {{%?}}[[AWAIT_WORK]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+
+  // CHECK: define {{.*}}void [[T6:@__omp_offloading_.+template.+l43]](i[[SZ:32|64]]
+  // Create local storage for each capture.
+  // CHECK:  [[LOCAL_N:%.+]] = alloca i[[SZ]],
+  // CHECK:  [[LOCAL_A:%.+]] = alloca i[[SZ]],
+  // CHECK:  [[LOCAL_AA:%.+]] = alloca i[[SZ]],
+  // CHECK:  [[LOCAL_B:%.+]] = alloca [10 x i32]*
+  // CHECK-DAG:  store i[[SZ]] [[ARG_N:%.+]], i[[SZ]]* [[LOCAL_N]]
+  // CHECK-DAG:  store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+  // CHECK-DAG:  store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+  // CHECK-DAG:   store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+  // Store captures in the context.
+  // CHECK-64-DAG:[[REF_N:%.+]] = bitcast i[[SZ]]* [[LOCAL_N]] to i32*
+  // CHECK-64-DAG:[[REF_A:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+  // CHECK-DAG:   [[REF_AA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+  // CHECK-DAG:   [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+  //
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
+  //
+  // CHECK: [[WORKER]]
+  // CHECK: {{call|invoke}} void [[T6]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
+  //
+  // CHECK: [[MASTER]]
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
+  // CHECK-64: [[N:%.+]] = load i32, i32* [[REF_N]],
+  // CHECK-32: [[N:%.+]] = load i32, i32* [[LOCAL_N]],
+  // CHECK: [[CMP:%.+]] = icmp sgt i32 [[N]], 1000
+  // CHECK: br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
+  //
+  // CHECK: [[IF_THEN]]
+  // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i32*, i32*)* [[PARALLEL_FN4]] to i8*))
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: br label {{%?}}[[IF_END:.+]]
+  //
+  // CHECK: [[IF_ELSE]]
+  // CHECK: call void @__kmpc_serialized_parallel(
+  // CHECK: {{call|invoke}} void [[PARALLEL_FN4]](
+  // CHECK: call void @__kmpc_end_serialized_parallel(
+  // br label [[IF_END]]
+  //
+  // CHECK: [[IF_END]]
+  // CHECK-64-DAG: load i32, i32* [[REF_A]]
+  // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
+  // CHECK-DAG:    load i16, i16* [[REF_AA]]
+  // CHECK-DAG:    getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2
+  //
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
+  //
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: br label {{%?}}[[EXIT]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+
+  // CHECK: define internal void [[PARALLEL_FN4]](
+  // CHECK: [[A:%.+]] = alloca i[[SZ:32|64]],
+  // CHECK: store i[[SZ]] 45, i[[SZ]]* %a,
+  // CHECK: ret void
+#endif
diff --git a/test/OpenMP/nvptx_target_codegen.cpp b/test/OpenMP/nvptx_target_codegen.cpp
index c4df636..dab0c5a 100644
--- a/test/OpenMP/nvptx_target_codegen.cpp
+++ b/test/OpenMP/nvptx_target_codegen.cpp
@@ -3,12 +3,18 @@
 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
 // expected-no-diagnostics
 #ifndef HEADER
 #define HEADER
 
-// CHECK-DAG: [[OMP_NT:@.+]] = common addrspace(3) global i32 0
-// CHECK-DAG: [[OMP_WID:@.+]] = common addrspace(3) global i64 0
+// Check that the execution mode of all 6 target regions is set to Generic Mode.
+// CHECK-DAG: {{@__omp_offloading_.+l98}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l175}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l284}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l321}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l339}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l304}}_exec_mode = weak constant i8 1
 
 template<typename tx, typename ty>
 struct TT{
@@ -25,19 +31,22 @@
   double cn[5][n];
   TT<long long, char> d;
 
-  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l86}}_worker()
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l98}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
   // CHECK: call void @llvm.nvvm.barrier0()
-  // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
-  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
   //
   // CHECK: [[SEL_WORKERS]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
-  // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
   // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
   //
   // CHECK: [[EXEC_PARALLEL]]
@@ -53,31 +62,34 @@
   // CHECK: [[EXIT]]
   // CHECK: ret void
 
-  // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+foo.+l86]]()
-  // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
-  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
-  // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
-  // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
-  // CHECK: [[MID:%.+]] = and i32 [[B]],
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
-  //
-  // CHECK: [[CHECK_WORKER]]
-  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+  // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+foo.+l98]]()
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
   //
   // CHECK: [[WORKER]]
-  // CHECK: call void [[T1]]_worker()
-  // CHECK: br label {{%?}}[[EXIT]]
+  // CHECK: {{call|invoke}} void [[T1]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
   //
   // CHECK: [[MASTER]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
-  // CHECK: br label {{%?}}[[TERM:.+]]
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
   //
-  // CHECK: [[TERM]]
-  // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
   // CHECK: call void @llvm.nvvm.barrier0()
   // CHECK: br label {{%?}}[[EXIT]]
   //
@@ -92,19 +104,22 @@
   {
   }
 
-  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l157}}_worker()
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l175}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
   // CHECK: call void @llvm.nvvm.barrier0()
-  // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
-  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
   //
   // CHECK: [[SEL_WORKERS]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
-  // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
   // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
   //
   // CHECK: [[EXEC_PARALLEL]]
@@ -120,35 +135,38 @@
   // CHECK: [[EXIT]]
   // CHECK: ret void
 
-  // CHECK: define {{.*}}void [[T3:@__omp_offloading_.+foo.+l157]](i[[SZ:32|64]] [[ARG1:%.+]])
+  // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+foo.+l175]](i[[SZ:32|64]] [[ARG1:%[a-zA-Z_]+]])
   // CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]],
   // CHECK: store i[[SZ]] [[ARG1]], i[[SZ]]* [[AA_ADDR]],
   // CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
-  // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
-  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
-  // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
-  // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
-  // CHECK: [[MID:%.+]] = and i32 [[B]],
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
-  //
-  // CHECK: [[CHECK_WORKER]]
-  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
   //
   // CHECK: [[WORKER]]
-  // CHECK: call void [[T3]]_worker()
-  // CHECK: br label {{%?}}[[EXIT]]
+  // CHECK: {{call|invoke}} void [[T2]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
   //
   // CHECK: [[MASTER]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
   // CHECK: load i16, i16* [[AA_CADDR]],
-  // CHECK: br label {{%?}}[[TERM:.+]]
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
   //
-  // CHECK: [[TERM]]
-  // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
   // CHECK: call void @llvm.nvvm.barrier0()
   // CHECK: br label {{%?}}[[EXIT]]
   //
@@ -159,19 +177,22 @@
     aa += 1;
   }
 
-  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l260}}_worker()
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l284}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
   // CHECK: call void @llvm.nvvm.barrier0()
-  // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
-  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
   //
   // CHECK: [[SEL_WORKERS]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
-  // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
   // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
   //
   // CHECK: [[EXEC_PARALLEL]]
@@ -187,7 +208,7 @@
   // CHECK: [[EXIT]]
   // CHECK: ret void
 
-  // CHECK: define {{.*}}void [[T4:@__omp_offloading_.+foo.+l260]](i[[SZ]]
+  // CHECK: define {{.*}}void [[T3:@__omp_offloading_.+foo.+l284]](i[[SZ]]
   // Create local storage for each capture.
   // CHECK:    [[LOCAL_A:%.+]] = alloca i[[SZ]]
   // CHECK:    [[LOCAL_B:%.+]] = alloca [10 x float]*
@@ -218,26 +239,29 @@
   // CHECK-DAG:    [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
   // CHECK-DAG:    [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
   //
-  // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
-  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
-  // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
-  // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
-  // CHECK: [[MID:%.+]] = and i32 [[B]],
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
-  //
-  // CHECK: [[CHECK_WORKER]]
-  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
   //
   // CHECK: [[WORKER]]
-  // CHECK: call void [[T4]]_worker()
-  // CHECK: br label {{%?}}[[EXIT]]
+  // CHECK: {{call|invoke}} void [[T3]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
   //
   // CHECK: [[MASTER]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
   //
   // Use captures.
   // CHECK-64-DAG:  load i32, i32* [[REF_A]]
@@ -248,10 +272,10 @@
   // CHECK-DAG:  getelementptr inbounds double, double* [[REF_CN]], i[[SZ]] %{{.+}}
   // CHECK-DAG:     getelementptr inbounds [[TT]], [[TT]]* [[REF_D]], i32 0, i32 0
   //
-  // CHECK: br label {{%?}}[[TERM:.+]]
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
   //
-  // CHECK: [[TERM]]
-  // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
   // CHECK: call void @llvm.nvvm.barrier0()
   // CHECK: br label {{%?}}[[EXIT]]
   //
@@ -337,19 +361,22 @@
   return a;
 }
 
-  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+static.+l297}}_worker()
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+static.+321}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
   // CHECK: call void @llvm.nvvm.barrier0()
-  // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
-  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
   //
   // CHECK: [[SEL_WORKERS]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
-  // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
   // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
   //
   // CHECK: [[EXEC_PARALLEL]]
@@ -365,7 +392,7 @@
   // CHECK: [[EXIT]]
   // CHECK: ret void
 
-  // CHECK: define {{.*}}void [[T5:@__omp_offloading_.+static.+l297]](i[[SZ]]
+  // CHECK: define {{.*}}void [[T4:@__omp_offloading_.+static.+l321]](i[[SZ]]
   // Create local storage for each capture.
   // CHECK:  [[LOCAL_A:%.+]] = alloca i[[SZ]]
   // CHECK:  [[LOCAL_AA:%.+]] = alloca i[[SZ]]
@@ -381,36 +408,37 @@
   // CHECK-DAG:      [[REF_AAA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
   // CHECK-DAG:      [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
   //
-  // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
-  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
-  // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
-  // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
-  // CHECK: [[MID:%.+]] = and i32 [[B]],
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
-  //
-  // CHECK: [[CHECK_WORKER]]
-  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
   //
   // CHECK: [[WORKER]]
-  // CHECK: call void [[T5]]_worker()
-  // CHECK: br label {{%?}}[[EXIT]]
+  // CHECK: {{call|invoke}} void [[T4]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
   //
   // CHECK: [[MASTER]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
-  //
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
   // CHECK-64-DAG: load i32, i32* [[REF_A]]
   // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
   // CHECK-DAG:    load i16, i16* [[REF_AA]]
   // CHECK-DAG:    getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
   //
-  // CHECK: br label {{%?}}[[TERM:.+]]
-  //
-  // CHECK: [[TERM]]
-  // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
   // CHECK: call void @llvm.nvvm.barrier0()
   // CHECK: br label {{%?}}[[EXIT]]
   //
@@ -419,19 +447,22 @@
 
 
 
-  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+S1.+l315}}_worker()
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+S1.+l339}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
   // CHECK: call void @llvm.nvvm.barrier0()
-  // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
-  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
   //
   // CHECK: [[SEL_WORKERS]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
-  // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
   // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
   //
   // CHECK: [[EXEC_PARALLEL]]
@@ -447,7 +478,7 @@
   // CHECK: [[EXIT]]
   // CHECK: ret void
 
-  // CHECK: define {{.*}}void [[T6:@__omp_offloading_.+S1.+l315]](
+  // CHECK: define {{.*}}void [[T5:@__omp_offloading_.+S1.+l339]](
   // Create local storage for each capture.
   // CHECK:       [[LOCAL_THIS:%.+]] = alloca [[S1:%struct.*]]*
   // CHECK:       [[LOCAL_B:%.+]] = alloca i[[SZ]]
@@ -465,35 +496,39 @@
   // CHECK-DAG:   [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
   // CHECK-DAG:   [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
   // CHECK-DAG:   [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
-  // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
-  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
-  // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
-  // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
-  // CHECK: [[MID:%.+]] = and i32 [[B]],
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
   //
-  // CHECK: [[CHECK_WORKER]]
-  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
   //
   // CHECK: [[WORKER]]
-  // CHECK: call void [[T6]]_worker()
-  // CHECK: br label {{%?}}[[EXIT]]
+  // CHECK: {{call|invoke}} void [[T5]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
   //
   // CHECK: [[MASTER]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
   // Use captures.
   // CHECK-DAG:   getelementptr inbounds [[S1]], [[S1]]* [[REF_THIS]], i32 0, i32 0
   // CHECK-64-DAG:load i32, i32* [[REF_B]]
   // CHECK-32-DAG:load i32, i32* [[LOCAL_B]]
   // CHECK-DAG:   getelementptr inbounds i16, i16* [[REF_C]], i[[SZ]] %{{.+}}
-  // CHECK: br label {{%?}}[[TERM:.+]]
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
   //
-  // CHECK: [[TERM]]
-  // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
   // CHECK: call void @llvm.nvvm.barrier0()
   // CHECK: br label {{%?}}[[EXIT]]
   //
@@ -502,19 +537,22 @@
 
 
 
-  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l280}}_worker()
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l304}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
   // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
   //
   // CHECK: [[AWAIT_WORK]]
   // CHECK: call void @llvm.nvvm.barrier0()
-  // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
-  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
   // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
   //
   // CHECK: [[SEL_WORKERS]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
-  // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
   // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
   //
   // CHECK: [[EXEC_PARALLEL]]
@@ -530,7 +568,7 @@
   // CHECK: [[EXIT]]
   // CHECK: ret void
 
-  // CHECK: define {{.*}}void [[T7:@__omp_offloading_.+template.+l280]](i[[SZ]]
+  // CHECK: define {{.*}}void [[T6:@__omp_offloading_.+template.+l304]](i[[SZ]]
   // Create local storage for each capture.
   // CHECK:  [[LOCAL_A:%.+]] = alloca i[[SZ]]
   // CHECK:  [[LOCAL_AA:%.+]] = alloca i[[SZ]]
@@ -543,36 +581,39 @@
   // CHECK-DAG:   [[REF_AA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
   // CHECK-DAG:   [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
   //
-  // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
-  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
-  // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
-  // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
-  // CHECK: [[MID:%.+]] = and i32 [[B]],
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
-  //
-  // CHECK: [[CHECK_WORKER]]
-  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
-  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
   //
   // CHECK: [[WORKER]]
-  // CHECK: call void [[T7]]_worker()
-  // CHECK: br label {{%?}}[[EXIT]]
+  // CHECK: {{call|invoke}} void [[T6]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
   //
   // CHECK: [[MASTER]]
-  // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
-  // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
   //
   // CHECK-64-DAG: load i32, i32* [[REF_A]]
   // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
   // CHECK-DAG:    load i16, i16* [[REF_AA]]
   // CHECK-DAG:    getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2
   //
-  // CHECK: br label {{%?}}[[TERM:.+]]
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
   //
-  // CHECK: [[TERM]]
-  // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
   // CHECK: call void @llvm.nvvm.barrier0()
   // CHECK: br label {{%?}}[[EXIT]]
   //
diff --git a/test/OpenMP/nvptx_target_parallel_codegen.cpp b/test/OpenMP/nvptx_target_parallel_codegen.cpp
new file mode 100644
index 0000000..7d16624
--- /dev/null
+++ b/test/OpenMP/nvptx_target_parallel_codegen.cpp
@@ -0,0 +1,136 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Check that the execution mode of all 2 target regions on the gpu is set to SPMD Mode.
+// CHECK-DAG: {{@__omp_offloading_.+l26}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l31}}_exec_mode = weak constant i8 0
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+  short aa = 0;
+  tx b[10];
+
+  #pragma omp target parallel if(target: 0)
+  {
+    a += 1;
+  }
+
+  #pragma omp target parallel map(tofrom: aa)
+  {
+    aa += 1;
+  }
+
+  #pragma omp target parallel map(tofrom:a, aa, b) if(target: n>40)
+  {
+    a += 1;
+    aa += 1;
+    b[2] += 1;
+  }
+
+  return a;
+}
+
+int bar(int n){
+  int a = 0;
+
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+  // CHECK-NOT: define {{.*}}void {{@__omp_offloading_.+template.+l17}}
+
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l26}}(
+  // CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
+  // CHECK: store i16* {{%.+}}, i16** [[AA_ADDR]], align
+  // CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
+  // CHECK: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]],
+  // CHECK: br label {{%?}}[[EXEC:.+]]
+  //
+  // CHECK: [[EXEC]]
+  // CHECK: {{call|invoke}} void [[OP1:@.+]](i32* null, i32* null, i16* [[AA]])
+  // CHECK: br label {{%?}}[[DONE:.+]]
+  //
+  // CHECK: [[DONE]]
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+  // CHECK: }
+
+  // CHECK: define internal void [[OP1]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i16* {{[^%]*}}[[ARG:%.+]])
+  // CHECK: = alloca i32*, align
+  // CHECK: = alloca i32*, align
+  // CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
+  // CHECK: store i16* [[ARG]], i16** [[AA_ADDR]], align
+  // CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
+  // CHECK: [[VAL:%.+]] = load i16, i16* [[AA]], align
+  // CHECK: store i16 {{%.+}}, i16* [[AA]], align
+  // CHECK: ret void
+  // CHECK: }
+
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l31}}(
+  // CHECK: [[A_ADDR:%.+]] = alloca i32*, align
+  // CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
+  // CHECK: [[B_ADDR:%.+]] = alloca [10 x i32]*, align
+  // CHECK: store i32* {{%.+}}, i32** [[A_ADDR]], align
+  // CHECK: store i16* {{%.+}}, i16** [[AA_ADDR]], align
+  // CHECK: store [10 x i32]* {{%.+}}, [10 x i32]** [[B_ADDR]], align
+  // CHECK: [[A:%.+]] = load i32*, i32** [[A_ADDR]], align
+  // CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
+  // CHECK: [[B:%.+]] = load [10 x i32]*, [10 x i32]** [[B_ADDR]], align
+  // CHECK: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]],
+  // CHECK: br label {{%?}}[[EXEC:.+]]
+  //
+  // CHECK: [[EXEC]]
+  // CHECK: {{call|invoke}} void [[OP2:@.+]](i32* null, i32* null, i32* [[A]], i16* [[AA]], [10 x i32]* [[B]])
+  // CHECK: br label {{%?}}[[DONE:.+]]
+  //
+  // CHECK: [[DONE]]
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+  // CHECK: }
+
+  // CHECK: define internal void [[OP2]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* {{[^%]*}}[[ARG1:%.+]], i16* {{[^%]*}}[[ARG2:%.+]], [10 x i32]* {{[^%]*}}[[ARG3:%.+]])
+  // CHECK: = alloca i32*, align
+  // CHECK: = alloca i32*, align
+  // CHECK: [[A_ADDR:%.+]] = alloca i32*, align
+  // CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
+  // CHECK: [[B_ADDR:%.+]] = alloca [10 x i32]*, align
+  // CHECK: store i32* [[ARG1]], i32** [[A_ADDR]], align
+  // CHECK: store i16* [[ARG2]], i16** [[AA_ADDR]], align
+  // CHECK: store [10 x i32]* [[ARG3]], [10 x i32]** [[B_ADDR]], align
+  // CHECK: [[A:%.+]] = load i32*, i32** [[A_ADDR]], align
+  // CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
+  // CHECK: [[B:%.+]] = load [10 x i32]*, [10 x i32]** [[B_ADDR]], align
+  // CHECK: store i32 {{%.+}}, i32* [[A]], align
+  // CHECK: store i16 {{%.+}}, i16* [[AA]], align
+  // CHECK: [[ELT:%.+]] = getelementptr inbounds [10 x i32], [10 x i32]* [[B]],
+  // CHECK: store i32 {{%.+}}, i32* [[ELT]], align
+  // CHECK: ret void
+  // CHECK: }
+#endif
diff --git a/test/OpenMP/nvptx_target_parallel_num_threads_codegen.cpp b/test/OpenMP/nvptx_target_parallel_num_threads_codegen.cpp
new file mode 100644
index 0000000..bc423c1
--- /dev/null
+++ b/test/OpenMP/nvptx_target_parallel_num_threads_codegen.cpp
@@ -0,0 +1,126 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Check that the execution mode of all 2 target regions on the gpu is set to SPMD Mode.
+// CHECK-DAG: {{@__omp_offloading_.+l21}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l26}}_exec_mode = weak constant i8 0
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+  short aa = 0;
+  tx b[10];
+
+  #pragma omp target parallel map(tofrom: aa) num_threads(1024)
+  {
+    aa += 1;
+  }
+
+  #pragma omp target parallel map(tofrom:a, aa, b) if(target: n>40) num_threads(n)
+  {
+    a += 1;
+    aa += 1;
+    b[2] += 1;
+  }
+
+  return a;
+}
+
+int bar(int n){
+  int a = 0;
+
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l21}}(
+  // CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
+  // CHECK: store i16* {{%.+}}, i16** [[AA_ADDR]], align
+  // CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
+  // CHECK: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]],
+  // CHECK: br label {{%?}}[[EXEC:.+]]
+  //
+  // CHECK: [[EXEC]]
+  // CHECK-NOT: call void @__kmpc_push_num_threads
+  // CHECK: {{call|invoke}} void [[OP1:@.+]](i32* null, i32* null, i16* [[AA]])
+  // CHECK: br label {{%?}}[[DONE:.+]]
+  //
+  // CHECK: [[DONE]]
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+  // CHECK: }
+
+  // CHECK: define internal void [[OP1]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i16* {{[^%]*}}[[ARG:%.+]])
+  // CHECK: = alloca i32*, align
+  // CHECK: = alloca i32*, align
+  // CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
+  // CHECK: store i16* [[ARG]], i16** [[AA_ADDR]], align
+  // CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
+  // CHECK: [[VAL:%.+]] = load i16, i16* [[AA]], align
+  // CHECK: store i16 {{%.+}}, i16* [[AA]], align
+  // CHECK: ret void
+  // CHECK: }
+
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l26}}(
+  // CHECK: [[A_ADDR:%.+]] = alloca i32*, align
+  // CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
+  // CHECK: [[B_ADDR:%.+]] = alloca [10 x i32]*, align
+  // CHECK: store i32* {{%.+}}, i32** [[A_ADDR]], align
+  // CHECK: store i16* {{%.+}}, i16** [[AA_ADDR]], align
+  // CHECK: store [10 x i32]* {{%.+}}, [10 x i32]** [[B_ADDR]], align
+  // CHECK: [[A:%.+]] = load i32*, i32** [[A_ADDR]], align
+  // CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
+  // CHECK: [[B:%.+]] = load [10 x i32]*, [10 x i32]** [[B_ADDR]], align
+  // CHECK: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]],
+  // CHECK: br label {{%?}}[[EXEC:.+]]
+  //
+  // CHECK: [[EXEC]]
+  // CHECK-NOT: call void @__kmpc_push_num_threads
+  // CHECK: {{call|invoke}} void [[OP2:@.+]](i32* null, i32* null, i32* [[A]], i16* [[AA]], [10 x i32]* [[B]])
+  // CHECK: br label {{%?}}[[DONE:.+]]
+  //
+  // CHECK: [[DONE]]
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+  // CHECK: }
+
+  // CHECK: define internal void [[OP2]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* {{[^%]*}}[[ARG1:%.+]], i16* {{[^%]*}}[[ARG2:%.+]], [10 x i32]* {{[^%]*}}[[ARG3:%.+]])
+  // CHECK: = alloca i32*, align
+  // CHECK: = alloca i32*, align
+  // CHECK: [[A_ADDR:%.+]] = alloca i32*, align
+  // CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
+  // CHECK: [[B_ADDR:%.+]] = alloca [10 x i32]*, align
+  // CHECK: store i32* [[ARG1]], i32** [[A_ADDR]], align
+  // CHECK: store i16* [[ARG2]], i16** [[AA_ADDR]], align
+  // CHECK: store [10 x i32]* [[ARG3]], [10 x i32]** [[B_ADDR]], align
+  // CHECK: [[A:%.+]] = load i32*, i32** [[A_ADDR]], align
+  // CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
+  // CHECK: [[B:%.+]] = load [10 x i32]*, [10 x i32]** [[B_ADDR]], align
+  // CHECK: store i32 {{%.+}}, i32* [[A]], align
+  // CHECK: store i16 {{%.+}}, i16* [[AA]], align
+  // CHECK: [[ELT:%.+]] = getelementptr inbounds [10 x i32], [10 x i32]* [[B]],
+  // CHECK: store i32 {{%.+}}, i32* [[ELT]], align
+  // CHECK: ret void
+  // CHECK: }
+#endif
diff --git a/test/OpenMP/nvptx_target_parallel_proc_bind_codegen.cpp b/test/OpenMP/nvptx_target_parallel_proc_bind_codegen.cpp
new file mode 100644
index 0000000..91c6de1
--- /dev/null
+++ b/test/OpenMP/nvptx_target_parallel_proc_bind_codegen.cpp
@@ -0,0 +1,106 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Check that the execution mode of all 3 target regions on the gpu is set to SPMD Mode.
+// CHECK-DAG: {{@__omp_offloading_.+l22}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l26}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l31}}_exec_mode = weak constant i8 0
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+  short aa = 0;
+  tx b[10];
+
+  #pragma omp target parallel proc_bind(master)
+  {
+  }
+
+  #pragma omp target parallel proc_bind(spread)
+  {
+    aa += 1;
+  }
+
+  #pragma omp target parallel proc_bind(close)
+  {
+    a += 1;
+    aa += 1;
+    b[2] += 1;
+  }
+
+  return a;
+}
+
+int bar(int n){
+  int a = 0;
+
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l22}}(
+  // CHECK: call void @__kmpc_spmd_kernel_init(
+  // CHECK: br label {{%?}}[[EXEC:.+]]
+  //
+  // CHECK: [[EXEC]]
+  // CHECK-NOT: call void @__kmpc_push_proc_bind
+  // CHECK: {{call|invoke}} void [[OP1:@.+]](i32* null, i32* null
+  // CHECK: br label {{%?}}[[DONE:.+]]
+  //
+  // CHECK: [[DONE]]
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+  // CHECK: }
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l26}}(
+  // CHECK: call void @__kmpc_spmd_kernel_init(
+  // CHECK: br label {{%?}}[[EXEC:.+]]
+  //
+  // CHECK: [[EXEC]]
+  // CHECK-NOT: call void @__kmpc_push_proc_bind
+  // CHECK: {{call|invoke}} void [[OP1:@.+]](i32* null, i32* null
+  // CHECK: br label {{%?}}[[DONE:.+]]
+  //
+  // CHECK: [[DONE]]
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+  // CHECK: }
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l31}}(
+  // CHECK: call void @__kmpc_spmd_kernel_init(
+  // CHECK: br label {{%?}}[[EXEC:.+]]
+  //
+  // CHECK: [[EXEC]]
+  // CHECK-NOT: call void @__kmpc_push_proc_bind
+  // CHECK: {{call|invoke}} void [[OP1:@.+]](i32* null, i32* null
+  // CHECK: br label {{%?}}[[DONE:.+]]
+  //
+  // CHECK: [[DONE]]
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+  // CHECK: }
+#endif
diff --git a/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp b/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
new file mode 100644
index 0000000..c4c3e97
--- /dev/null
+++ b/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
@@ -0,0 +1,830 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Check for the data transfer medium in shared memory to transfer the reduction list to the first warp.
+// CHECK-DAG: [[TRANSFER_STORAGE:@.+]] = common addrspace([[SHARED_ADDRSPACE:[0-9]+]]) global [32 x i64]
+
+// Check that the execution mode of all 3 target regions is set to Spmd Mode.
+// CHECK-DAG: {{@__omp_offloading_.+l27}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l32}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l38}}_exec_mode = weak constant i8 0
+
+template<typename tx>
+tx ftemplate(int n) {
+  int a;
+  short b;
+  tx c;
+  float d;
+  double e;
+
+  #pragma omp target parallel reduction(+: e) map(tofrom: e)
+  {
+    e += 5;
+  }
+
+  #pragma omp target parallel reduction(^: c) reduction(*: d) map(tofrom: c,d)
+  {
+    c ^= 2;
+    d *= 33;
+  }
+
+  #pragma omp target parallel reduction(|: a) reduction(max: b) map(tofrom: a,b)
+  {
+    a |= 1;
+    b = 99 > b ? 99 : b;
+  }
+
+  return a+b+c+d+e;
+}
+
+int bar(int n){
+  int a = 0;
+
+  a += ftemplate<char>(n);
+
+  return a;
+}
+
+  // CHECK: define {{.*}}void {{@__omp_offloading_.+template.+l27}}(
+  //
+  // CHECK: call void @__kmpc_spmd_kernel_init(
+  // CHECK: br label {{%?}}[[EXECUTE:.+]]
+  //
+  // CHECK: [[EXECUTE]]
+  // CHECK: {{call|invoke}} void [[PFN:@.+]](i32*
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  //
+  //
+  // define internal void [[PFN]](
+  // CHECK: store double {{[0\.e\+]+}}, double* [[E:%.+]], align
+  // CHECK: [[EV:%.+]] = load double, double* [[E]], align
+  // CHECK: [[ADD:%.+]] = fadd double [[EV]], 5
+  // CHECK: store double [[ADD]], double* [[E]], align
+  // CHECK: [[PTR1:%.+]] = getelementptr inbounds [[RLT:.+]], [1 x i8*]* [[RL:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[E_CAST:%.+]] = bitcast double* [[E]] to i8*
+  // CHECK: store i8* [[E_CAST]], i8** [[PTR1]], align
+  // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait(i32 {{.+}}, i32 1, i{{32|64}} {{4|8}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]])
+  // CHECK: switch i32 [[RET]], label {{%?}}[[DEFAULTLABEL:.+]] [
+  // CHECK: i32 1, label {{%?}}[[REDLABEL:.+]]
+
+  // CHECK: [[REDLABEL]]
+  // CHECK: [[E_INV:%.+]] = load double, double* [[E_IN:%.+]], align
+  // CHECK: [[EV:%.+]] = load double, double* [[E]], align
+  // CHECK: [[ADD:%.+]] = fadd double [[E_INV]], [[EV]]
+  // CHECK: store double [[ADD]], double* [[E_IN]], align
+  // CHECK: call void @__kmpc_nvptx_end_reduce_nowait(
+  // CHECK: br label %[[DEFAULTLABEL]]
+  //
+  // CHECK: [[DEFAULTLABEL]]
+  // CHECK: ret
+
+  //
+  // Reduction function
+  // CHECK: define internal void [[REDUCTION_FUNC:@.+]](i8*, i8*)
+  // CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
+  // CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to double*
+  //
+  // CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
+  // CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to double*
+  //
+  // CHECK: [[VAR_LHS_VAL:%.+]] = load double, double* [[VAR_LHS]],
+  // CHECK: [[VAR_RHS_VAL:%.+]] = load double, double* [[VAR_RHS]],
+  // CHECK: [[RES:%.+]] = fadd double [[VAR_LHS_VAL]], [[VAR_RHS_VAL]]
+  // CHECK: store double [[RES]], double* [[VAR_LHS]],
+  // CHECK: ret void
+
+  //
+  // Shuffle and reduce function
+  // CHECK: define internal void [[SHUFFLE_REDUCE_FN]](i8*, i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+  // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [[RLT]], align
+  // CHECK: [[REMOTE_ELT:%.+]] = alloca double
+  //
+  // CHECK: [[LANEID:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[LANEOFFSET:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[ALGVER:%.+]] = load i16, i16* {{.+}}, align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: [[ELT_VAL:%.+]] = load double, double* [[ELT]], align
+  //
+  // CHECK: [[ELT_CAST:%.+]] = bitcast double [[ELT_VAL]] to i64
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT_VAL64:%.+]] = call i64 @__kmpc_shuffle_int64(i64 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = bitcast i64 [[REMOTE_ELT_VAL64]] to double
+  //
+  // CHECK: store double [[REMOTE_ELT_VAL]], double* [[REMOTE_ELT]], align
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = bitcast double* [[REMOTE_ELT]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT_VOID]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // Condition to reduce
+  // CHECK: [[CONDALG0:%.+]] = icmp eq i16 [[ALGVER]], 0
+  //
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp ult i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[CONDALG1:%.+]] = and i1 [[COND1]], [[COND2]]
+  //
+  // CHECK: [[COND3:%.+]] = icmp eq i16 [[ALGVER]], 2
+  // CHECK: [[COND4:%.+]] = and i16 [[LANEID]], 1
+  // CHECK: [[COND5:%.+]] = icmp eq i16 [[COND4]], 0
+  // CHECK: [[COND6:%.+]] = and i1 [[COND3]], [[COND5]]
+  // CHECK: [[COND7:%.+]] = icmp sgt i16 [[LANEOFFSET]], 0
+  // CHECK: [[CONDALG2:%.+]] = and i1 [[COND6]], [[COND7]]
+  //
+  // CHECK: [[COND8:%.+]] = or i1 [[CONDALG0]], [[CONDALG1]]
+  // CHECK: [[SHOULD_REDUCE:%.+]] = or i1 [[COND8]], [[CONDALG2]]
+  // CHECK: br i1 [[SHOULD_REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+  //
+  // CHECK: [[DO_REDUCE]]
+  // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [[RLT]]* [[RED_LIST]] to i8*
+  // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [[RLT]]* [[REMOTE_RED_LIST]] to i8*
+  // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+  // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+  //
+  // CHECK: [[REDUCE_ELSE]]
+  // CHECK: br label {{%?}}[[REDUCE_CONT]]
+  //
+  // CHECK: [[REDUCE_CONT]]
+  // Now check if we should just copy over the remote reduction list
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp uge i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[SHOULD_COPY:%.+]] = and i1 [[COND1]], [[COND2]]
+  // CHECK: br i1 [[SHOULD_COPY]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // CHECK: [[DO_COPY]]
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to double*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load double, double* [[REMOTE_ELT]], align
+  // CHECK: store double [[REMOTE_ELT_VAL]], double* [[ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // CHECK: [[COPY_CONT]]
+  // CHECK: void
+
+  //
+  // Inter warp copy function
+  // CHECK: define internal void [[WARP_COPY_FN]](i8*, i32)
+  // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31
+  // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5
+  // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: [[ELT_VAL:%.+]] = load double, double* [[ELT]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to double addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store double [[ELT_VAL]], double addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to double addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load double, double addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: store double [[MEDIUM_ELT_VAL]], double* [[ELT]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: ret
+
+
+
+
+
+
+
+
+
+
+  // CHECK: define {{.*}}void {{@__omp_offloading_.+template.+l32}}(
+  //
+  // CHECK: call void @__kmpc_spmd_kernel_init(
+  // CHECK: br label {{%?}}[[EXECUTE:.+]]
+  //
+  // CHECK: [[EXECUTE]]
+  // CHECK: {{call|invoke}} void [[PFN1:@.+]](i32*
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  //
+  //
+  // define internal void [[PFN1]](
+  // CHECK: store float {{1\.[0e\+]+}}, float* [[D:%.+]], align
+  // CHECK: [[C_VAL:%.+]] = load i8, i8* [[C:%.+]], align
+  // CHECK: [[CONV:%.+]] = sext i8 [[C_VAL]] to i32
+  // CHECK: [[XOR:%.+]] = xor i32 [[CONV]], 2
+  // CHECK: [[TRUNC:%.+]] = trunc i32 [[XOR]] to i8
+  // CHECK: store i8 [[TRUNC]], i8* [[C]], align
+  // CHECK: [[DV:%.+]] = load float, float* [[D]], align
+  // CHECK: [[MUL:%.+]] = fmul float [[DV]], {{[0-9e\.\+]+}}
+  // CHECK: store float [[MUL]], float* [[D]], align
+  // CHECK: [[PTR1:%.+]] = getelementptr inbounds [[RLT:.+]], [2 x i8*]* [[RL:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: store i8* [[C]], i8** [[PTR1]], align
+  // CHECK: [[PTR2:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RL]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[D_CAST:%.+]] = bitcast float* [[D]] to i8*
+  // CHECK: store i8* [[D_CAST]], i8** [[PTR2]], align
+  // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait(i32 {{.+}}, i32 2, i{{32|64}} {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]])
+  // CHECK: switch i32 [[RET]], label {{%?}}[[DEFAULTLABEL:.+]] [
+  // CHECK: i32 1, label {{%?}}[[REDLABEL:.+]]
+
+  // CHECK: [[REDLABEL]]
+  // CHECK: [[C_INV8:%.+]] = load i8, i8* [[C_IN:%.+]], align
+  // CHECK: [[C_INV:%.+]] = sext i8 [[C_INV8]] to i32
+  // CHECK: [[CV8:%.+]] = load i8, i8* [[C]], align
+  // CHECK: [[CV:%.+]] = sext i8 [[CV8]] to i32
+  // CHECK: [[XOR:%.+]] = xor i32 [[C_INV]], [[CV]]
+  // CHECK: [[TRUNC:%.+]] = trunc i32 [[XOR]] to i8
+  // CHECK: store i8 [[TRUNC]], i8* [[C_IN]], align
+  // CHECK: [[D_INV:%.+]] = load float, float* [[D_IN:%.+]], align
+  // CHECK: [[DV:%.+]] = load float, float* [[D]], align
+  // CHECK: [[MUL:%.+]] = fmul float [[D_INV]], [[DV]]
+  // CHECK: store float [[MUL]], float* [[D_IN]], align
+  // CHECK: call void @__kmpc_nvptx_end_reduce_nowait(
+  // CHECK: br label %[[DEFAULTLABEL]]
+  //
+  // CHECK: [[DEFAULTLABEL]]
+  // CHECK: ret
+
+  //
+  // Reduction function
+  // CHECK: define internal void [[REDUCTION_FUNC:@.+]](i8*, i8*)
+  // CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[VAR1_RHS:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
+  //
+  // CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[VAR1_LHS:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
+  //
+  // CHECK: [[VAR2_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[VAR2_RHS_VOID:%.+]] = load i8*, i8** [[VAR2_RHS_REF]],
+  // CHECK: [[VAR2_RHS:%.+]] = bitcast i8* [[VAR2_RHS_VOID]] to float*
+  //
+  // CHECK: [[VAR2_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[VAR2_LHS_VOID:%.+]] = load i8*, i8** [[VAR2_LHS_REF]],
+  // CHECK: [[VAR2_LHS:%.+]] = bitcast i8* [[VAR2_LHS_VOID]] to float*
+  //
+  // CHECK: [[VAR1_LHS_VAL8:%.+]] = load i8, i8* [[VAR1_LHS]],
+  // CHECK: [[VAR1_LHS_VAL:%.+]] = sext i8 [[VAR1_LHS_VAL8]] to i32
+  // CHECK: [[VAR1_RHS_VAL8:%.+]] = load i8, i8* [[VAR1_RHS]],
+  // CHECK: [[VAR1_RHS_VAL:%.+]] = sext i8 [[VAR1_RHS_VAL8]] to i32
+  // CHECK: [[XOR:%.+]] = xor i32 [[VAR1_LHS_VAL]], [[VAR1_RHS_VAL]]
+  // CHECK: [[RES:%.+]] = trunc i32 [[XOR]] to i8
+  // CHECK: store i8 [[RES]], i8* [[VAR1_LHS]],
+  //
+  // CHECK: [[VAR2_LHS_VAL:%.+]] = load float, float* [[VAR2_LHS]],
+  // CHECK: [[VAR2_RHS_VAL:%.+]] = load float, float* [[VAR2_RHS]],
+  // CHECK: [[RES:%.+]] = fmul float [[VAR2_LHS_VAL]], [[VAR2_RHS_VAL]]
+  // CHECK: store float [[RES]], float* [[VAR2_LHS]],
+  // CHECK: ret void
+
+  //
+  // Shuffle and reduce function
+  // CHECK: define internal void [[SHUFFLE_REDUCE_FN]](i8*, i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+  // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [[RLT]], align
+  // CHECK: [[REMOTE_ELT1:%.+]] = alloca i8
+  // CHECK: [[REMOTE_ELT2:%.+]] = alloca float
+  //
+  // CHECK: [[LANEID:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[LANEOFFSET:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[ALGVER:%.+]] = load i16, i16* {{.+}}, align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VAL:%.+]] = load i8, i8* [[ELT_VOID]], align
+  //
+  // CHECK: [[ELT_CAST:%.+]] = sext i8 [[ELT_VAL]] to i32
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT1_VAL32:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+  // CHECK: [[REMOTE_ELT1_VAL:%.+]] = trunc i32 [[REMOTE_ELT1_VAL32]] to i8
+  //
+  // CHECK: store i8 [[REMOTE_ELT1_VAL]], i8* [[REMOTE_ELT1]], align
+  // CHECK: store i8* [[REMOTE_ELT1]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: [[ELT_VAL:%.+]] = load float, float* [[ELT]], align
+  //
+  // CHECK: [[ELT_CAST:%.+]] = bitcast float [[ELT_VAL]] to i32
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT2_VAL32:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+  // CHECK: [[REMOTE_ELT2_VAL:%.+]] = bitcast i32 [[REMOTE_ELT2_VAL32]] to float
+  //
+  // CHECK: store float [[REMOTE_ELT2_VAL]], float* [[REMOTE_ELT2]], align
+  // CHECK: [[REMOTE_ELT2C:%.+]] = bitcast float* [[REMOTE_ELT2]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT2C]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // Condition to reduce
+  // CHECK: [[CONDALG0:%.+]] = icmp eq i16 [[ALGVER]], 0
+  //
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp ult i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[CONDALG1:%.+]] = and i1 [[COND1]], [[COND2]]
+  //
+  // CHECK: [[COND3:%.+]] = icmp eq i16 [[ALGVER]], 2
+  // CHECK: [[COND4:%.+]] = and i16 [[LANEID]], 1
+  // CHECK: [[COND5:%.+]] = icmp eq i16 [[COND4]], 0
+  // CHECK: [[COND6:%.+]] = and i1 [[COND3]], [[COND5]]
+  // CHECK: [[COND7:%.+]] = icmp sgt i16 [[LANEOFFSET]], 0
+  // CHECK: [[CONDALG2:%.+]] = and i1 [[COND6]], [[COND7]]
+  //
+  // CHECK: [[COND8:%.+]] = or i1 [[CONDALG0]], [[CONDALG1]]
+  // CHECK: [[SHOULD_REDUCE:%.+]] = or i1 [[COND8]], [[CONDALG2]]
+  // CHECK: br i1 [[SHOULD_REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+  //
+  // CHECK: [[DO_REDUCE]]
+  // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [[RLT]]* [[RED_LIST]] to i8*
+  // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [[RLT]]* [[REMOTE_RED_LIST]] to i8*
+  // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+  // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+  //
+  // CHECK: [[REDUCE_ELSE]]
+  // CHECK: br label {{%?}}[[REDUCE_CONT]]
+  //
+  // CHECK: [[REDUCE_CONT]]
+  // Now check if we should just copy over the remote reduction list
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp uge i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[SHOULD_COPY:%.+]] = and i1 [[COND1]], [[COND2]]
+  // CHECK: br i1 [[SHOULD_COPY]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // CHECK: [[DO_COPY]]
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i8, i8* [[REMOTE_ELT_VOID]], align
+  // CHECK: store i8 [[REMOTE_ELT_VAL]], i8* [[ELT_VOID]], align
+  //
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to float*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load float, float* [[REMOTE_ELT]], align
+  // CHECK: store float [[REMOTE_ELT_VAL]], float* [[ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // CHECK: [[COPY_CONT]]
+  // CHECK: void
+
+  //
+  // Inter warp copy function
+  // CHECK: define internal void [[WARP_COPY_FN]](i8*, i32)
+  // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31
+  // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5
+  // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT_VAL:%.+]] = load i8, i8* [[ELT_VOID]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i8 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store i8 [[ELT_VAL]], i8 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i8 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load i8, i8 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: store i8 [[MEDIUM_ELT_VAL]], i8* [[ELT_VOID]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: [[ELT_VAL:%.+]] = load float, float* [[ELT]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to float addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store float [[ELT_VAL]], float addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to float addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load float, float addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: store float [[MEDIUM_ELT_VAL]], float* [[ELT]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: ret
+
+
+
+
+
+
+
+
+
+
+  // CHECK: define {{.*}}void {{@__omp_offloading_.+template.+l38}}(
+  //
+  // CHECK: call void @__kmpc_spmd_kernel_init(
+  // CHECK: br label {{%?}}[[EXECUTE:.+]]
+  //
+  // CHECK: [[EXECUTE]]
+  // CHECK: {{call|invoke}} void [[PFN2:@.+]](i32*
+  // CHECK: call void @__kmpc_spmd_kernel_deinit()
+  //
+  //
+  // define internal void [[PFN2]](
+  // CHECK: store i32 0, i32* [[A:%.+]], align
+  // CHECK: store i16 -32768, i16* [[B:%.+]], align
+  // CHECK: [[A_VAL:%.+]] = load i32, i32* [[A:%.+]], align
+  // CHECK: [[OR:%.+]] = or i32 [[A_VAL]], 1
+  // CHECK: store i32 [[OR]], i32* [[A]], align
+  // CHECK: [[BV16:%.+]] = load i16, i16* [[B]], align
+  // CHECK: [[BV:%.+]] = sext i16 [[BV16]] to i32
+  // CHECK: [[CMP:%.+]] = icmp sgt i32 99, [[BV]]
+  // CHECK: br i1 [[CMP]], label {{%?}}[[DO_MAX:.+]], label {{%?}}[[MAX_ELSE:.+]]
+  //
+  // CHECK: [[DO_MAX]]
+  // CHECK: br label {{%?}}[[MAX_CONT:.+]]
+  //
+  // CHECK: [[MAX_ELSE]]
+  // CHECK: [[BV:%.+]] = load i16, i16* [[B]], align
+  // CHECK: [[MAX:%.+]] = sext i16 [[BV]] to i32
+  // CHECK: br label {{%?}}[[MAX_CONT]]
+  //
+  // CHECK: [[MAX_CONT]]
+  // CHECK: [[B_LVALUE:%.+]] = phi i32 [ 99, %[[DO_MAX]] ], [ [[MAX]], %[[MAX_ELSE]] ]
+  // CHECK: [[TRUNC:%.+]] = trunc i32 [[B_LVALUE]] to i16
+  // CHECK: store i16 [[TRUNC]], i16* [[B]], align
+  // CHECK: [[PTR1:%.+]] = getelementptr inbounds [[RLT:.+]], [2 x i8*]* [[RL:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[A_CAST:%.+]] = bitcast i32* [[A]] to i8*
+  // CHECK: store i8* [[A_CAST]], i8** [[PTR1]], align
+  // CHECK: [[PTR2:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RL]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[B_CAST:%.+]] = bitcast i16* [[B]] to i8*
+  // CHECK: store i8* [[B_CAST]], i8** [[PTR2]], align
+  // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait(i32 {{.+}}, i32 2, i{{32|64}} {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]])
+  // CHECK: switch i32 [[RET]], label {{%?}}[[DEFAULTLABEL:.+]] [
+  // CHECK: i32 1, label {{%?}}[[REDLABEL:.+]]
+
+  // CHECK: [[REDLABEL]]
+  // CHECK: [[A_INV:%.+]] = load i32, i32* [[A_IN:%.+]], align
+  // CHECK: [[AV:%.+]] = load i32, i32* [[A]], align
+  // CHECK: [[OR:%.+]] = or i32 [[A_INV]], [[AV]]
+  // CHECK: store i32 [[OR]], i32* [[A_IN]], align
+  // CHECK: [[B_INV16:%.+]] = load i16, i16* [[B_IN:%.+]], align
+  // CHECK: [[B_INV:%.+]] = sext i16 [[B_INV16]] to i32
+  // CHECK: [[BV16:%.+]] = load i16, i16* [[B]], align
+  // CHECK: [[BV:%.+]] = sext i16 [[BV16]] to i32
+  // CHECK: [[CMP:%.+]] = icmp sgt i32 [[B_INV]], [[BV]]
+  // CHECK: br i1 [[CMP]], label {{%?}}[[DO_MAX:.+]], label {{%?}}[[MAX_ELSE:.+]]
+  //
+  // CHECK: [[DO_MAX]]
+  // CHECK: [[MAX1:%.+]] = load i16, i16* [[B_IN]], align
+  // CHECK: br label {{%?}}[[MAX_CONT:.+]]
+  //
+  // CHECK: [[MAX_ELSE]]
+  // CHECK: [[MAX2:%.+]] = load i16, i16* [[B]], align
+  // CHECK: br label {{%?}}[[MAX_CONT]]
+  //
+  // CHECK: [[MAX_CONT]]
+  // CHECK: [[B_MAX:%.+]] = phi i16 [ [[MAX1]], %[[DO_MAX]] ], [ [[MAX2]], %[[MAX_ELSE]] ]
+  // CHECK: store i16 [[B_MAX]], i16* [[B_IN]], align
+  // CHECK: call void @__kmpc_nvptx_end_reduce_nowait(
+  // CHECK: br label %[[DEFAULTLABEL]]
+  //
+  // CHECK: [[DEFAULTLABEL]]
+  // CHECK: ret
+
+  //
+  // Reduction function
+  // CHECK: define internal void [[REDUCTION_FUNC:@.+]](i8*, i8*)
+  // CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
+  // CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to i32*
+  //
+  // CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
+  // CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to i32*
+  //
+  // CHECK: [[VAR2_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[VAR2_RHS_VOID:%.+]] = load i8*, i8** [[VAR2_RHS_REF]],
+  // CHECK: [[VAR2_RHS:%.+]] = bitcast i8* [[VAR2_RHS_VOID]] to i16*
+  //
+  // CHECK: [[VAR2_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[VAR2_LHS_VOID:%.+]] = load i8*, i8** [[VAR2_LHS_REF]],
+  // CHECK: [[VAR2_LHS:%.+]] = bitcast i8* [[VAR2_LHS_VOID]] to i16*
+  //
+  // CHECK: [[VAR1_LHS_VAL:%.+]] = load i32, i32* [[VAR1_LHS]],
+  // CHECK: [[VAR1_RHS_VAL:%.+]] = load i32, i32* [[VAR1_RHS]],
+  // CHECK: [[OR:%.+]] = or i32 [[VAR1_LHS_VAL]], [[VAR1_RHS_VAL]]
+  // CHECK: store i32 [[OR]], i32* [[VAR1_LHS]],
+  //
+  // CHECK: [[VAR2_LHS_VAL16:%.+]] = load i16, i16* [[VAR2_LHS]],
+  // CHECK: [[VAR2_LHS_VAL:%.+]] = sext i16 [[VAR2_LHS_VAL16]] to i32
+  // CHECK: [[VAR2_RHS_VAL16:%.+]] = load i16, i16* [[VAR2_RHS]],
+  // CHECK: [[VAR2_RHS_VAL:%.+]] = sext i16 [[VAR2_RHS_VAL16]] to i32
+  //
+  // CHECK: [[CMP:%.+]] = icmp sgt i32 [[VAR2_LHS_VAL]], [[VAR2_RHS_VAL]]
+  // CHECK: br i1 [[CMP]], label {{%?}}[[DO_MAX:.+]], label {{%?}}[[MAX_ELSE:.+]]
+  //
+  // CHECK: [[DO_MAX]]
+  // CHECK: [[MAX1:%.+]] = load i16, i16* [[VAR2_LHS]], align
+  // CHECK: br label {{%?}}[[MAX_CONT:.+]]
+  //
+  // CHECK: [[MAX_ELSE]]
+  // CHECK: [[MAX2:%.+]] = load i16, i16* [[VAR2_RHS]], align
+  // CHECK: br label {{%?}}[[MAX_CONT]]
+  //
+  // CHECK: [[MAX_CONT]]
+  // CHECK: [[MAXV:%.+]] = phi i16 [ [[MAX1]], %[[DO_MAX]] ], [ [[MAX2]], %[[MAX_ELSE]] ]
+  // CHECK: store i16 [[MAXV]], i16* [[VAR2_LHS]],
+  // CHECK: ret void
+
+  //
+  // Shuffle and reduce function
+  // CHECK: define internal void [[SHUFFLE_REDUCE_FN]](i8*, i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+  // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [[RLT]], align
+  // CHECK: [[REMOTE_ELT1:%.+]] = alloca i32
+  // CHECK: [[REMOTE_ELT2:%.+]] = alloca i16
+  //
+  // CHECK: [[LANEID:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[LANEOFFSET:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[ALGVER:%.+]] = load i16, i16* {{.+}}, align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT]], align
+  //
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT1_VAL:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_VAL]], i16 [[LANEOFFSET]], i16 [[WS]])
+  //
+  // CHECK: store i32 [[REMOTE_ELT1_VAL]], i32* [[REMOTE_ELT1]], align
+  // CHECK: [[REMOTE_ELT1C:%.+]] = bitcast i32* [[REMOTE_ELT1]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT1C]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: [[ELT_VAL:%.+]] = load i16, i16* [[ELT]], align
+  //
+  // CHECK: [[ELT_CAST:%.+]] = sext i16 [[ELT_VAL]] to i32
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT2_VAL32:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+  // CHECK: [[REMOTE_ELT2_VAL:%.+]] = trunc i32 [[REMOTE_ELT2_VAL32]] to i16
+  //
+  // CHECK: store i16 [[REMOTE_ELT2_VAL]], i16* [[REMOTE_ELT2]], align
+  // CHECK: [[REMOTE_ELT2C:%.+]] = bitcast i16* [[REMOTE_ELT2]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT2C]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // Condition to reduce
+  // CHECK: [[CONDALG0:%.+]] = icmp eq i16 [[ALGVER]], 0
+  //
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp ult i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[CONDALG1:%.+]] = and i1 [[COND1]], [[COND2]]
+  //
+  // CHECK: [[COND3:%.+]] = icmp eq i16 [[ALGVER]], 2
+  // CHECK: [[COND4:%.+]] = and i16 [[LANEID]], 1
+  // CHECK: [[COND5:%.+]] = icmp eq i16 [[COND4]], 0
+  // CHECK: [[COND6:%.+]] = and i1 [[COND3]], [[COND5]]
+  // CHECK: [[COND7:%.+]] = icmp sgt i16 [[LANEOFFSET]], 0
+  // CHECK: [[CONDALG2:%.+]] = and i1 [[COND6]], [[COND7]]
+  //
+  // CHECK: [[COND8:%.+]] = or i1 [[CONDALG0]], [[CONDALG1]]
+  // CHECK: [[SHOULD_REDUCE:%.+]] = or i1 [[COND8]], [[CONDALG2]]
+  // CHECK: br i1 [[SHOULD_REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+  //
+  // CHECK: [[DO_REDUCE]]
+  // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [[RLT]]* [[RED_LIST]] to i8*
+  // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [[RLT]]* [[REMOTE_RED_LIST]] to i8*
+  // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+  // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+  //
+  // CHECK: [[REDUCE_ELSE]]
+  // CHECK: br label {{%?}}[[REDUCE_CONT]]
+  //
+  // CHECK: [[REDUCE_CONT]]
+  // Now check if we should just copy over the remote reduction list
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp uge i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[SHOULD_COPY:%.+]] = and i1 [[COND1]], [[COND2]]
+  // CHECK: br i1 [[SHOULD_COPY]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // CHECK: [[DO_COPY]]
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to i32*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i32, i32* [[REMOTE_ELT]], align
+  // CHECK: store i32 [[REMOTE_ELT_VAL]], i32* [[ELT]], align
+  //
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to i16*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i16, i16* [[REMOTE_ELT]], align
+  // CHECK: store i16 [[REMOTE_ELT_VAL]], i16* [[ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // CHECK: [[COPY_CONT]]
+  // CHECK: void
+
+  //
+  // Inter warp copy function
+  // CHECK: define internal void [[WARP_COPY_FN]](i8*, i32)
+  // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31
+  // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5
+  // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i32 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store i32 [[ELT_VAL]], i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i32 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load i32, i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: store i32 [[MEDIUM_ELT_VAL]], i32* [[ELT]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: [[ELT_VAL:%.+]] = load i16, i16* [[ELT]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i16 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store i16 [[ELT_VAL]], i16 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i16 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load i16, i16 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: store i16 [[MEDIUM_ELT_VAL]], i16* [[ELT]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: ret
+
+#endif
diff --git a/test/OpenMP/nvptx_target_printf_codegen.c b/test/OpenMP/nvptx_target_printf_codegen.c
new file mode 100644
index 0000000..0de6885
--- /dev/null
+++ b/test/OpenMP/nvptx_target_printf_codegen.c
@@ -0,0 +1,116 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+#include <stdarg.h>
+
+// expected-no-diagnostics
+extern int printf(const char *, ...);
+extern int vprintf(const char *, va_list);
+
+// Check a simple call to printf end-to-end.
+// CHECK: [[SIMPLE_PRINTF_TY:%[a-zA-Z0-9_]+]] = type { i32, i64, double }
+int CheckSimple() {
+    // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+CheckSimple.+]]_worker()
+#pragma omp target
+  {
+    // Entry point.
+    // CHECK: define {{.*}}void [[T1]]()
+    // Alloca in entry block.
+    // CHECK: [[BUF:%[a-zA-Z0-9_]+]] = alloca [[SIMPLE_PRINTF_TY]]
+
+    // CHECK: {{call|invoke}} void [[T1]]_worker()
+    // CHECK: br label {{%?}}[[EXIT:.+]]
+    //
+    // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+    // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+    // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+    // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+    // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
+    //
+    // CHECK: [[MASTER]]
+    // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+    // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+    // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+    // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
+
+    // printf in master-only basic block.
+    // CHECK: [[FMT:%[0-9]+]] = load{{.*}}%fmt
+    const char* fmt = "%d %lld %f";
+    // CHECK: [[PTR0:%[0-9]+]] = getelementptr inbounds [[SIMPLE_PRINTF_TY]], [[SIMPLE_PRINTF_TY]]* [[BUF]], i32 0, i32 0
+    // CHECK: store i32 1, i32* [[PTR0]], align 4
+    // CHECK: [[PTR1:%[0-9]+]] = getelementptr inbounds [[SIMPLE_PRINTF_TY]], [[SIMPLE_PRINTF_TY]]* [[BUF]], i32 0, i32 1
+    // CHECK: store i64 2, i64* [[PTR1]], align 8
+    // CHECK: [[PTR2:%[0-9]+]] = getelementptr inbounds [[SIMPLE_PRINTF_TY]], [[SIMPLE_PRINTF_TY]]* [[BUF]], i32 0, i32 2
+
+    // CHECK: store double 3.0{{[^,]*}}, double* [[PTR2]], align 8
+    // CHECK: [[BUF_CAST:%[0-9]+]] = bitcast [[SIMPLE_PRINTF_TY]]* [[BUF]] to i8*
+    // CHECK: [[RET:%[0-9]+]] = call i32 @vprintf(i8* [[FMT]], i8* [[BUF_CAST]])
+    printf(fmt, 1, 2ll, 3.0);
+  }
+
+  return 0;
+}
+
+void CheckNoArgs() {
+    // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+CheckNoArgs.+]]_worker()
+#pragma omp target
+  {
+    // Entry point.
+    // CHECK: define {{.*}}void [[T2]]()
+
+    // CHECK: {{call|invoke}} void [[T2]]_worker()
+    // CHECK: br label {{%?}}[[EXIT:.+]]
+    //
+    // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+    // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+    // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+    // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+    // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
+    //
+    // CHECK: [[MASTER]]
+    // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+    // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+    // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+    // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
+
+    // printf in master-only basic block.
+    // CHECK: call i32 @vprintf({{.*}}, i8* null){{$}}
+    printf("hello, world!");
+  }
+}
+
+// Check that printf's alloca happens in the entry block, not inside the if
+// statement.
+int foo;
+void CheckAllocaIsInEntryBlock() {
+    // CHECK: define {{.*}}void [[T3:@__omp_offloading_.+CheckAllocaIsInEntryBlock.+]]_worker()
+#pragma omp target
+  {
+    // Entry point.
+    // CHECK: define {{.*}}void [[T3]](
+    // Alloca in entry block.
+    // CHECK: alloca %printf_args
+
+    // CHECK: {{call|invoke}} void [[T3]]_worker()
+    // CHECK: br label {{%?}}[[EXIT:.+]]
+    //
+    // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+    // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+    // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+    // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+    // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
+    //
+    // CHECK: [[MASTER]]
+    // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+    // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+    // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+    // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
+
+    if (foo) {
+      printf("%d", 42);
+    }
+  }
+}
diff --git a/test/OpenMP/nvptx_target_teams_codegen.cpp b/test/OpenMP/nvptx_target_teams_codegen.cpp
new file mode 100644
index 0000000..e823eab
--- /dev/null
+++ b/test/OpenMP/nvptx_target_teams_codegen.cpp
@@ -0,0 +1,222 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Check that the execution mode of all 2 target regions is set to Generic Mode.
+// CHECK-DAG: {{@__omp_offloading_.+l26}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l31}}_exec_mode = weak constant i8 1
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+  short aa = 0;
+  tx b[10];
+
+  #pragma omp target teams if(0)
+  {
+    b[2] += 1;
+  }
+
+  #pragma omp target teams if(1)
+  {
+    a = '1';
+  }
+
+  #pragma omp target teams if(n>40)
+  {
+    aa = 1;
+  }
+
+  return a;
+}
+
+int bar(int n){
+  int a = 0;
+
+  a += ftemplate<char>(n);
+
+  return a;
+}
+
+  // CHECK-NOT: define {{.*}}void {{@__omp_offloading_.+template.+l21}}_worker()
+
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l26}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+  //
+  // CHECK: [[AWAIT_WORK]]
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]])
+  // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
+  // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
+  // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+  //
+  // CHECK: [[SEL_WORKERS]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]]
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
+  // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+  //
+  // CHECK: [[EXEC_PARALLEL]]
+  // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+  //
+  // CHECK: [[TERM_PARALLEL]]
+  // CHECK: call void @__kmpc_kernel_end_parallel()
+  // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+  //
+  // CHECK: [[BAR_PARALLEL]]
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: br label {{%?}}[[AWAIT_WORK]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+
+  // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+template.+l26]](i[[SZ:32|64]] [[A:%[^)]+]])
+  // CHECK: store i[[SZ]] [[A]], i[[SZ]]* [[A_ADDR:%.+]], align
+  // CHECK: [[CONV:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i8*
+
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
+  //
+  // CHECK: [[WORKER]]
+  // CHECK: {{call|invoke}} void [[T1]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
+  //
+  // CHECK: [[MASTER]]
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
+  //
+  // CHECK-NOT: kmpc_fork_teams
+  // CHECK: [[A_VAL:%.+]] = load i8, i8* [[CONV]], align
+  // CHECK: [[ACP:%.+]] = bitcast i[[SZ]]* [[AC:%.+]] to i8*
+  // CHECK: store i8 [[A_VAL]], i8* [[ACP]], align
+  // CHECK: [[ACV:%.+]] = load i[[SZ]], i[[SZ]]* [[AC]], align
+  // CHECK: store i[[SZ]] [[ACV]], i[[SZ]]* [[A_ADDR_T:%.+]], align
+  // CHECK: [[CONV2:%.+]] = bitcast i[[SZ]]* [[A_ADDR_T]] to i8*
+  // CHECK: store i8 49, i8* [[CONV2]], align
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
+  //
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: br label {{%?}}[[EXIT]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l31}}_worker()
+  // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
+  // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
+  // CHECK: store i8* null, i8** [[OMP_WORK_FN]],
+  // CHECK: store i8 0, i8* [[OMP_EXEC_STATUS]],
+  // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+  //
+  // CHECK: [[AWAIT_WORK]]
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]])
+  // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
+  // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
+  // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
+  // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i8* [[WORK]], null
+  // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+  //
+  // CHECK: [[SEL_WORKERS]]
+  // CHECK: [[ST:%.+]] = load i8, i8* [[OMP_EXEC_STATUS]]
+  // CHECK: [[IS_ACTIVE:%.+]] = icmp ne i8 [[ST]], 0
+  // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+  //
+  // CHECK: [[EXEC_PARALLEL]]
+  // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+  //
+  // CHECK: [[TERM_PARALLEL]]
+  // CHECK: call void @__kmpc_kernel_end_parallel()
+  // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+  //
+  // CHECK: [[BAR_PARALLEL]]
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: br label {{%?}}[[AWAIT_WORK]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+
+  // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+template.+l31]](i[[SZ:32|64]] [[AA:%[^)]+]])
+  // CHECK: store i[[SZ]] [[AA]], i[[SZ]]* [[AA_ADDR:%.+]], align
+  // CHECK: [[CONV:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+
+  // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK-DAG: [[TH_LIMIT:%.+]] = sub i32 [[NTH]], [[WS]]
+  // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[TH_LIMIT]]
+  // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]]
+  //
+  // CHECK: [[WORKER]]
+  // CHECK: {{call|invoke}} void [[T2]]_worker()
+  // CHECK: br label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[CHECK_MASTER]]
+  // CHECK-DAG: [[CMTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+  // CHECK-DAG: [[CMNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[CMWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[IS_MASTER:%.+]] = icmp eq i32 [[CMTID]],
+  // CHECK: br i1 [[IS_MASTER]], label {{%?}}[[MASTER:.+]], label {{%?}}[[EXIT]]
+  //
+  // CHECK: [[MASTER]]
+  // CHECK-DAG: [[MNTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+  // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
+  // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
+  //
+  // CHECK-NOT: kmpc_fork_teams
+  // CHECK: [[AA_VAL:%.+]] = load i16, i16* [[CONV]], align
+  // CHECK: [[ACP:%.+]] = bitcast i[[SZ]]* [[AC:%.+]] to i16*
+  // CHECK: store i16 [[AA_VAL]], i16* [[ACP]], align
+  // CHECK: [[ACV:%.+]] = load i[[SZ]], i[[SZ]]* [[AC]], align
+  // CHECK: store i[[SZ]] [[ACV]], i[[SZ]]* [[AA_ADDR_T:%.+]], align
+  // CHECK: [[CONV2:%.+]] = bitcast i[[SZ]]* [[AA_ADDR_T]] to i16*
+  // CHECK: store i16 1, i16* [[CONV2]], align
+  // CHECK: br label {{%?}}[[TERMINATE:.+]]
+  //
+  // CHECK: [[TERMINATE]]
+  // CHECK: call void @__kmpc_kernel_deinit()
+  // CHECK: call void @llvm.nvvm.barrier0()
+  // CHECK: br label {{%?}}[[EXIT]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: ret void
+
+
+#endif
diff --git a/test/OpenMP/nvptx_teams_reduction_codegen.cpp b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
new file mode 100644
index 0000000..ae129eb
--- /dev/null
+++ b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
@@ -0,0 +1,1143 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Check for the data transfer medium in shared memory to transfer the reduction list to the first warp.
+// CHECK-DAG: [[TRANSFER_STORAGE:@.+]] = common addrspace([[SHARED_ADDRSPACE:[0-9]+]]) global [32 x i64]
+
+// Check that the execution mode of all 3 target regions is set to Generic Mode.
+// CHECK-DAG: {{@__omp_offloading_.+l27}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l33}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l40}}_exec_mode = weak constant i8 1
+
+template<typename tx>
+tx ftemplate(int n) {
+  int a;
+  short b;
+  tx c;
+  float d;
+  double e;
+
+  #pragma omp target
+  #pragma omp teams reduction(+: e)
+  {
+    e += 5;
+  }
+
+  #pragma omp target
+  #pragma omp teams reduction(^: c) reduction(*: d)
+  {
+    c ^= 2;
+    d *= 33;
+  }
+
+  #pragma omp target
+  #pragma omp teams reduction(|: a) reduction(max: b)
+  {
+    a |= 1;
+    b = 99 > b ? 99 : b;
+  }
+
+  return a+b+c+d+e;
+}
+
+int bar(int n){
+  int a = 0;
+
+  a += ftemplate<char>(n);
+
+  return a;
+}
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l27}}_worker()
+
+  // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+template.+l27]](
+  //
+  // CHECK: {{call|invoke}} void [[T1]]_worker()
+  //
+  // CHECK: call void @__kmpc_kernel_init(
+  //
+  // CHECK: store double {{[0\.e\+]+}}, double* [[E:%.+]], align
+  // CHECK: [[EV:%.+]] = load double, double* [[E]], align
+  // CHECK: [[ADD:%.+]] = fadd double [[EV]], 5
+  // CHECK: store double [[ADD]], double* [[E]], align
+  // CHECK: [[PTR1:%.+]] = getelementptr inbounds [[RLT:.+]], [1 x i8*]* [[RL:%.+]], i[[SZ:32|64]] 0, i{{32|64}} 0
+  // CHECK: [[E_CAST:%.+]] = bitcast double* [[E]] to i8*
+  // CHECK: store i8* [[E_CAST]], i8** [[PTR1]], align
+  // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_teams_reduce_nowait(i32 {{.+}}, i32 1, i[[SZ]] {{4|8}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]], void (i8*, i8*, i32, i32)* [[SCRATCH_COPY_FN:@.+]], void (i8*, i8*, i32, i32, i32)* [[LOAD_REDUCE_FN:@.+]])
+  // CHECK: [[COND:%.+]] = icmp eq i32 [[RET]], 1
+  // CHECK: br i1 [[COND]], label {{%?}}[[IFLABEL:.+]], label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[IFLABEL]]
+  // CHECK: [[E_INV:%.+]] = load double, double* [[E_IN:%.+]], align
+  // CHECK: [[EV:%.+]] = load double, double* [[E]], align
+  // CHECK: [[ADD:%.+]] = fadd double [[E_INV]], [[EV]]
+  // CHECK: store double [[ADD]], double* [[E_IN]], align
+  // CHECK: call void @__kmpc_nvptx_end_reduce_nowait(
+  // CHECK: br label %[[EXIT]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: call void @__kmpc_kernel_deinit()
+
+  //
+  // Reduction function
+  // CHECK: define internal void [[REDUCTION_FUNC:@.+]](i8*, i8*)
+  // CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
+  // CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to double*
+  //
+  // CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
+  // CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to double*
+  //
+  // CHECK: [[VAR_LHS_VAL:%.+]] = load double, double* [[VAR_LHS]],
+  // CHECK: [[VAR_RHS_VAL:%.+]] = load double, double* [[VAR_RHS]],
+  // CHECK: [[RES:%.+]] = fadd double [[VAR_LHS_VAL]], [[VAR_RHS_VAL]]
+  // CHECK: store double [[RES]], double* [[VAR_LHS]],
+  // CHECK: ret void
+
+  //
+  // Shuffle and reduce function
+  // CHECK: define internal void [[SHUFFLE_REDUCE_FN]](i8*, i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+  // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [[RLT]], align
+  // CHECK: [[REMOTE_ELT:%.+]] = alloca double
+  //
+  // CHECK: [[LANEID:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[LANEOFFSET:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[ALGVER:%.+]] = load i16, i16* {{.+}}, align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: [[ELT_VAL:%.+]] = load double, double* [[ELT]], align
+  //
+  // CHECK: [[ELT_CAST:%.+]] = bitcast double [[ELT_VAL]] to i64
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT_VAL64:%.+]] = call i64 @__kmpc_shuffle_int64(i64 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = bitcast i64 [[REMOTE_ELT_VAL64]] to double
+  //
+  // CHECK: store double [[REMOTE_ELT_VAL]], double* [[REMOTE_ELT]], align
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = bitcast double* [[REMOTE_ELT]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT_VOID]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // Condition to reduce
+  // CHECK: [[CONDALG0:%.+]] = icmp eq i16 [[ALGVER]], 0
+  //
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp ult i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[CONDALG1:%.+]] = and i1 [[COND1]], [[COND2]]
+  //
+  // CHECK: [[COND3:%.+]] = icmp eq i16 [[ALGVER]], 2
+  // CHECK: [[COND4:%.+]] = and i16 [[LANEID]], 1
+  // CHECK: [[COND5:%.+]] = icmp eq i16 [[COND4]], 0
+  // CHECK: [[COND6:%.+]] = and i1 [[COND3]], [[COND5]]
+  // CHECK: [[COND7:%.+]] = icmp sgt i16 [[LANEOFFSET]], 0
+  // CHECK: [[CONDALG2:%.+]] = and i1 [[COND6]], [[COND7]]
+  //
+  // CHECK: [[COND8:%.+]] = or i1 [[CONDALG0]], [[CONDALG1]]
+  // CHECK: [[SHOULD_REDUCE:%.+]] = or i1 [[COND8]], [[CONDALG2]]
+  // CHECK: br i1 [[SHOULD_REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+  //
+  // CHECK: [[DO_REDUCE]]
+  // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [[RLT]]* [[RED_LIST]] to i8*
+  // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [[RLT]]* [[REMOTE_RED_LIST]] to i8*
+  // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+  // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+  //
+  // CHECK: [[REDUCE_ELSE]]
+  // CHECK: br label {{%?}}[[REDUCE_CONT]]
+  //
+  // CHECK: [[REDUCE_CONT]]
+  // Now check if we should just copy over the remote reduction list
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp uge i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[SHOULD_COPY:%.+]] = and i1 [[COND1]], [[COND2]]
+  // CHECK: br i1 [[SHOULD_COPY]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // CHECK: [[DO_COPY]]
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to double*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load double, double* [[REMOTE_ELT]], align
+  // CHECK: store double [[REMOTE_ELT_VAL]], double* [[ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // CHECK: [[COPY_CONT]]
+  // CHECK: void
+
+  //
+  // Inter warp copy function
+  // CHECK: define internal void [[WARP_COPY_FN]](i8*, i32)
+  // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31
+  // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5
+  // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: [[ELT_VAL:%.+]] = load double, double* [[ELT]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to double addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store double [[ELT_VAL]], double addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to double addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load double, double addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: store double [[MEDIUM_ELT_VAL]], double* [[ELT]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: ret
+
+  //
+  // Copy to scratchpad function
+  // CHECK: define internal void [[SCRATCH_COPY_FN]](i8*, i8*, i32, i32)
+  // CHECK: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[SCRATCHPAD_PTR:%.+]] = load i8*, i8** {{.+}}, align
+  // CHECK-64: [[TEAM32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[TEAM:%.+]] = sext i32 [[TEAM32]] to i64
+  // CHECK-32: [[TEAM:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS:%.+]] = sext i32 [[NUM_TEAMS32]] to i64
+  // CHECK-32: [[NUM_TEAMS:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK: [[SCRATCHPAD:%.+]] = ptrtoint i8* [[SCRATCHPAD_PTR]] to i[[SZ]]
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 8, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR_VOID:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+  // CHECK: [[SCRATCHPAD_ELT_PTR:%.+]] = bitcast i8* [[SCRATCHPAD_ELT_PTR_VOID]] to double*
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: [[ELT_VAL:%.+]] = load double, double* [[ELT]], align
+  // CHECK: store double [[ELT_VAL]], double* [[SCRATCHPAD_ELT_PTR]], align
+  //
+  // CHECK: ret
+
+  //
+  // Load and reduce function
+  // CHECK: define internal void [[LOAD_REDUCE_FN]](i8*, i8*, i32, i32, i32)
+  // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [[RLT]], align
+  // CHECK: [[REMOTE_ELT:%.+]] = alloca double
+  // CHECK: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[SCRATCHPAD_PTR:%.+]] = load i8*, i8** {{.+}}, align
+  // CHECK-64: [[TEAM32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[TEAM:%.+]] = sext i32 [[TEAM32]] to i64
+  // CHECK-32: [[TEAM:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS:%.+]] = sext i32 [[NUM_TEAMS32]] to i64
+  // CHECK-32: [[NUM_TEAMS:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK: [[SHOULD_REDUCE:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK: [[SCRATCHPAD:%.+]] = ptrtoint i8* [[SCRATCHPAD_PTR]] to i[[SZ]]
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 8, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR_VOID:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[SCRATCHPAD_ELT_PTR:%.+]] = bitcast i8* [[SCRATCHPAD_ELT_PTR_VOID]] to double*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load double, double* [[SCRATCHPAD_ELT_PTR]], align
+  // CHECK: store double [[REMOTE_ELT_VAL]], double* [[REMOTE_ELT]], align
+  // CHECK: [[REMOTE_ELT_PTR:%.+]] = bitcast double* [[REMOTE_ELT]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT_PTR]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // CHECK: [[REDUCE:%.+]] = icmp eq i32 [[SHOULD_REDUCE]], 1
+  // CHECK: br i1 [[REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+  //
+  // CHECK: [[DO_REDUCE]]
+  // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [[RLT]]* [[RED_LIST]] to i8*
+  // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [[RLT]]* [[REMOTE_RED_LIST]] to i8*
+  // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+  // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+  //
+  // Copy element from remote reduce list
+  // CHECK: [[REDUCE_ELSE]]
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to double*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load double, double* [[REMOTE_ELT]], align
+  // CHECK: store double [[REMOTE_ELT_VAL]], double* [[ELT]], align
+  // CHECK: br label {{%?}}[[REDUCE_CONT]]
+  //
+  // CHECK: [[REDUCE_CONT]]
+  // CHECK: ret
+
+
+
+
+
+
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l33}}_worker()
+
+  // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+template.+l33]](
+  //
+  // CHECK: {{call|invoke}} void [[T2]]_worker()
+  //
+  // CHECK: call void @__kmpc_kernel_init(
+  //
+  // CHECK: store float {{1\.[0e\+]+}}, float* [[D:%.+]], align
+  // CHECK: [[C_VAL:%.+]] = load i8, i8* [[C:%.+]], align
+  // CHECK: [[CONV:%.+]] = sext i8 [[C_VAL]] to i32
+  // CHECK: [[XOR:%.+]] = xor i32 [[CONV]], 2
+  // CHECK: [[TRUNC:%.+]] = trunc i32 [[XOR]] to i8
+  // CHECK: store i8 [[TRUNC]], i8* [[C]], align
+  // CHECK: [[DV:%.+]] = load float, float* [[D]], align
+  // CHECK: [[MUL:%.+]] = fmul float [[DV]], {{[0-9e\.\+]+}}
+  // CHECK: store float [[MUL]], float* [[D]], align
+  // CHECK: [[PTR1:%.+]] = getelementptr inbounds [[RLT:.+]], [2 x i8*]* [[RL:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: store i8* [[C]], i8** [[PTR1]], align
+  // CHECK: [[PTR2:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RL]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[D_CAST:%.+]] = bitcast float* [[D]] to i8*
+  // CHECK: store i8* [[D_CAST]], i8** [[PTR2]], align
+  // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_teams_reduce_nowait(i32 {{.+}}, i32 2, i[[SZ]] {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]], void (i8*, i8*, i32, i32)* [[SCRATCH_COPY_FN:@.+]], void (i8*, i8*, i32, i32, i32)* [[LOAD_REDUCE_FN:@.+]])
+  // CHECK: [[COND:%.+]] = icmp eq i32 [[RET]], 1
+  // CHECK: br i1 [[COND]], label {{%?}}[[IFLABEL:.+]], label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[IFLABEL]]
+  // CHECK: [[C_INV8:%.+]] = load i8, i8* [[C_IN:%.+]], align
+  // CHECK: [[C_INV:%.+]] = sext i8 [[C_INV8]] to i32
+  // CHECK: [[CV8:%.+]] = load i8, i8* [[C]], align
+  // CHECK: [[CV:%.+]] = sext i8 [[CV8]] to i32
+  // CHECK: [[XOR:%.+]] = xor i32 [[C_INV]], [[CV]]
+  // CHECK: [[TRUNC:%.+]] = trunc i32 [[XOR]] to i8
+  // CHECK: store i8 [[TRUNC]], i8* [[C_IN]], align
+  // CHECK: [[D_INV:%.+]] = load float, float* [[D_IN:%.+]], align
+  // CHECK: [[DV:%.+]] = load float, float* [[D]], align
+  // CHECK: [[MUL:%.+]] = fmul float [[D_INV]], [[DV]]
+  // CHECK: store float [[MUL]], float* [[D_IN]], align
+  // CHECK: call void @__kmpc_nvptx_end_reduce_nowait(
+  // CHECK: br label %[[EXIT]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: call void @__kmpc_kernel_deinit()
+
+  //
+  // Reduction function
+  // CHECK: define internal void [[REDUCTION_FUNC:@.+]](i8*, i8*)
+  // CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[VAR1_RHS:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
+  //
+  // CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[VAR1_LHS:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
+  //
+  // CHECK: [[VAR2_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[VAR2_RHS_VOID:%.+]] = load i8*, i8** [[VAR2_RHS_REF]],
+  // CHECK: [[VAR2_RHS:%.+]] = bitcast i8* [[VAR2_RHS_VOID]] to float*
+  //
+  // CHECK: [[VAR2_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[VAR2_LHS_VOID:%.+]] = load i8*, i8** [[VAR2_LHS_REF]],
+  // CHECK: [[VAR2_LHS:%.+]] = bitcast i8* [[VAR2_LHS_VOID]] to float*
+  //
+  // CHECK: [[VAR1_LHS_VAL8:%.+]] = load i8, i8* [[VAR1_LHS]],
+  // CHECK: [[VAR1_LHS_VAL:%.+]] = sext i8 [[VAR1_LHS_VAL8]] to i32
+  // CHECK: [[VAR1_RHS_VAL8:%.+]] = load i8, i8* [[VAR1_RHS]],
+  // CHECK: [[VAR1_RHS_VAL:%.+]] = sext i8 [[VAR1_RHS_VAL8]] to i32
+  // CHECK: [[XOR:%.+]] = xor i32 [[VAR1_LHS_VAL]], [[VAR1_RHS_VAL]]
+  // CHECK: [[RES:%.+]] = trunc i32 [[XOR]] to i8
+  // CHECK: store i8 [[RES]], i8* [[VAR1_LHS]],
+  //
+  // CHECK: [[VAR2_LHS_VAL:%.+]] = load float, float* [[VAR2_LHS]],
+  // CHECK: [[VAR2_RHS_VAL:%.+]] = load float, float* [[VAR2_RHS]],
+  // CHECK: [[RES:%.+]] = fmul float [[VAR2_LHS_VAL]], [[VAR2_RHS_VAL]]
+  // CHECK: store float [[RES]], float* [[VAR2_LHS]],
+  // CHECK: ret void
+
+  //
+  // Shuffle and reduce function
+  // CHECK: define internal void [[SHUFFLE_REDUCE_FN]](i8*, i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+  // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [[RLT]], align
+  // CHECK: [[REMOTE_ELT1:%.+]] = alloca i8
+  // CHECK: [[REMOTE_ELT2:%.+]] = alloca float
+  //
+  // CHECK: [[LANEID:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[LANEOFFSET:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[ALGVER:%.+]] = load i16, i16* {{.+}}, align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VAL:%.+]] = load i8, i8* [[ELT_VOID]], align
+  //
+  // CHECK: [[ELT_CAST:%.+]] = sext i8 [[ELT_VAL]] to i32
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT1_VAL32:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+  // CHECK: [[REMOTE_ELT1_VAL:%.+]] = trunc i32 [[REMOTE_ELT1_VAL32]] to i8
+  //
+  // CHECK: store i8 [[REMOTE_ELT1_VAL]], i8* [[REMOTE_ELT1]], align
+  // CHECK: store i8* [[REMOTE_ELT1]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: [[ELT_VAL:%.+]] = load float, float* [[ELT]], align
+  //
+  // CHECK: [[ELT_CAST:%.+]] = bitcast float [[ELT_VAL]] to i32
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT2_VAL32:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+  // CHECK: [[REMOTE_ELT2_VAL:%.+]] = bitcast i32 [[REMOTE_ELT2_VAL32]] to float
+  //
+  // CHECK: store float [[REMOTE_ELT2_VAL]], float* [[REMOTE_ELT2]], align
+  // CHECK: [[REMOTE_ELT2C:%.+]] = bitcast float* [[REMOTE_ELT2]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT2C]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // Condition to reduce
+  // CHECK: [[CONDALG0:%.+]] = icmp eq i16 [[ALGVER]], 0
+  //
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp ult i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[CONDALG1:%.+]] = and i1 [[COND1]], [[COND2]]
+  //
+  // CHECK: [[COND3:%.+]] = icmp eq i16 [[ALGVER]], 2
+  // CHECK: [[COND4:%.+]] = and i16 [[LANEID]], 1
+  // CHECK: [[COND5:%.+]] = icmp eq i16 [[COND4]], 0
+  // CHECK: [[COND6:%.+]] = and i1 [[COND3]], [[COND5]]
+  // CHECK: [[COND7:%.+]] = icmp sgt i16 [[LANEOFFSET]], 0
+  // CHECK: [[CONDALG2:%.+]] = and i1 [[COND6]], [[COND7]]
+  //
+  // CHECK: [[COND8:%.+]] = or i1 [[CONDALG0]], [[CONDALG1]]
+  // CHECK: [[SHOULD_REDUCE:%.+]] = or i1 [[COND8]], [[CONDALG2]]
+  // CHECK: br i1 [[SHOULD_REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+  //
+  // CHECK: [[DO_REDUCE]]
+  // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [[RLT]]* [[RED_LIST]] to i8*
+  // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [[RLT]]* [[REMOTE_RED_LIST]] to i8*
+  // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+  // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+  //
+  // CHECK: [[REDUCE_ELSE]]
+  // CHECK: br label {{%?}}[[REDUCE_CONT]]
+  //
+  // CHECK: [[REDUCE_CONT]]
+  // Now check if we should just copy over the remote reduction list
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp uge i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[SHOULD_COPY:%.+]] = and i1 [[COND1]], [[COND2]]
+  // CHECK: br i1 [[SHOULD_COPY]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // CHECK: [[DO_COPY]]
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i8, i8* [[REMOTE_ELT_VOID]], align
+  // CHECK: store i8 [[REMOTE_ELT_VAL]], i8* [[ELT_VOID]], align
+  //
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to float*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load float, float* [[REMOTE_ELT]], align
+  // CHECK: store float [[REMOTE_ELT_VAL]], float* [[ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // CHECK: [[COPY_CONT]]
+  // CHECK: void
+
+  //
+  // Inter warp copy function
+  // CHECK: define internal void [[WARP_COPY_FN]](i8*, i32)
+  // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31
+  // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5
+  // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT_VAL:%.+]] = load i8, i8* [[ELT_VOID]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i8 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store i8 [[ELT_VAL]], i8 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i8 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load i8, i8 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: store i8 [[MEDIUM_ELT_VAL]], i8* [[ELT_VOID]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: [[ELT_VAL:%.+]] = load float, float* [[ELT]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to float addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store float [[ELT_VAL]], float addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to float addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load float, float addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: store float [[MEDIUM_ELT_VAL]], float* [[ELT]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: ret
+
+  //
+  // Copy to scratchpad function
+  // CHECK: define internal void [[SCRATCH_COPY_FN]](i8*, i8*, i32, i32)
+  // CHECK: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[SCRATCHPAD_PTR:%.+]] = load i8*, i8** {{.+}}, align
+  // CHECK-64: [[TEAM32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[TEAM:%.+]] = sext i32 [[TEAM32]] to i64
+  // CHECK-32: [[TEAM:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS:%.+]] = sext i32 [[NUM_TEAMS32]] to i64
+  // CHECK-32: [[NUM_TEAMS:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK: [[SCRATCHPAD:%.+]] = ptrtoint i8* [[SCRATCHPAD_PTR]] to i[[SZ]]
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 1, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+  // CHECK: [[ELT_VAL:%.+]] = load i8, i8* [[ELT_VOID]], align
+  // CHECK: store i8 [[ELT_VAL]], i8* [[SCRATCHPAD_ELT_PTR]], align
+  //
+  // CHECK: [[OF:%.+]] = mul i[[SZ]] [[NUM_TEAMS]], 1
+  // CHECK: [[POS1:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[OF]]
+  // CHECK: [[POS2:%.+]] = sub i[[SZ]] [[POS1]], 1
+  // CHECK: [[POS3:%.+]] = sdiv i[[SZ]] [[POS2]], 256
+  // CHECK: [[POS4:%.+]] = add i[[SZ]] [[POS3]], 1
+  // CHECK: [[SCRATCHPAD_NEXT:%.+]] = mul i[[SZ]] [[POS4]], 256
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 4, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD_NEXT]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR_VOID:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+  // CHECK: [[SCRATCHPAD_ELT_PTR:%.+]] = bitcast i8* [[SCRATCHPAD_ELT_PTR_VOID]] to float*
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: [[ELT_VAL:%.+]] = load float, float* [[ELT]], align
+  // CHECK: store float [[ELT_VAL]], float* [[SCRATCHPAD_ELT_PTR]], align
+  //
+  // CHECK: ret
+
+  //
+  // Load and reduce function
+  // CHECK: define internal void [[LOAD_REDUCE_FN]](i8*, i8*, i32, i32, i32)
+  // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [[RLT]], align
+  // CHECK: [[REMOTE_ELT1:%.+]] = alloca i8
+  // CHECK: [[REMOTE_ELT2:%.+]] = alloca float
+  // CHECK: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[SCRATCHPAD_PTR:%.+]] = load i8*, i8** {{.+}}, align
+  // CHECK-64: [[TEAM32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[TEAM:%.+]] = sext i32 [[TEAM32]] to i64
+  // CHECK-32: [[TEAM:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS:%.+]] = sext i32 [[NUM_TEAMS32]] to i64
+  // CHECK-32: [[NUM_TEAMS:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK: [[SHOULD_REDUCE:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK: [[SCRATCHPAD:%.+]] = ptrtoint i8* [[SCRATCHPAD_PTR]] to i[[SZ]]
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 1, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR_VOID:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i8, i8* [[SCRATCHPAD_ELT_PTR_VOID]], align
+  // CHECK: store i8 [[REMOTE_ELT_VAL]], i8* [[REMOTE_ELT1]], align
+  // CHECK: store i8* [[REMOTE_ELT1]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // CHECK: [[OF:%.+]] = mul i[[SZ]] [[NUM_TEAMS]], 1
+  // CHECK: [[POS1:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[OF]]
+  // CHECK: [[POS2:%.+]] = sub i[[SZ]] [[POS1]], 1
+  // CHECK: [[POS3:%.+]] = sdiv i[[SZ]] [[POS2]], 256
+  // CHECK: [[POS4:%.+]] = add i[[SZ]] [[POS3]], 1
+  // CHECK: [[SCRATCHPAD_NEXT:%.+]] = mul i[[SZ]] [[POS4]], 256
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 4, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD_NEXT]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR_VOID:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[SCRATCHPAD_ELT_PTR:%.+]] = bitcast i8* [[SCRATCHPAD_ELT_PTR_VOID]] to float*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load float, float* [[SCRATCHPAD_ELT_PTR]], align
+  // CHECK: store float [[REMOTE_ELT_VAL]], float* [[REMOTE_ELT2]], align
+  // CHECK: [[REMOTE_ELT_PTR:%.+]] = bitcast float* [[REMOTE_ELT2]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT_PTR]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // CHECK: [[REDUCE:%.+]] = icmp eq i32 [[SHOULD_REDUCE]], 1
+  // CHECK: br i1 [[REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+  //
+  // CHECK: [[DO_REDUCE]]
+  // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [[RLT]]* [[RED_LIST]] to i8*
+  // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [[RLT]]* [[REMOTE_RED_LIST]] to i8*
+  // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+  // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+  //
+  // Copy element from remote reduce list
+  // CHECK: [[REDUCE_ELSE]]
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i8, i8* [[REMOTE_ELT_VOID]], align
+  // CHECK: store i8 [[REMOTE_ELT_VAL]], i8* [[ELT_VOID]], align
+  //
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to float*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load float, float* [[REMOTE_ELT]], align
+  // CHECK: store float [[REMOTE_ELT_VAL]], float* [[ELT]], align
+  // CHECK: br label {{%?}}[[REDUCE_CONT]]
+  //
+  // CHECK: [[REDUCE_CONT]]
+  // CHECK: ret
+
+
+
+
+
+
+
+
+
+
+  // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l40}}_worker()
+
+  // CHECK: define {{.*}}void [[T3:@__omp_offloading_.+template.+l40]](
+  //
+  // CHECK: {{call|invoke}} void [[T3]]_worker()
+  //
+  // CHECK: call void @__kmpc_kernel_init(
+  //
+  // CHECK: store i32 0, i32* [[A:%.+]], align
+  // CHECK: store i16 -32768, i16* [[B:%.+]], align
+  // CHECK: [[A_VAL:%.+]] = load i32, i32* [[A:%.+]], align
+  // CHECK: [[OR:%.+]] = or i32 [[A_VAL]], 1
+  // CHECK: store i32 [[OR]], i32* [[A]], align
+  // CHECK: [[BV16:%.+]] = load i16, i16* [[B]], align
+  // CHECK: [[BV:%.+]] = sext i16 [[BV16]] to i32
+  // CHECK: [[CMP:%.+]] = icmp sgt i32 99, [[BV]]
+  // CHECK: br i1 [[CMP]], label {{%?}}[[DO_MAX:.+]], label {{%?}}[[MAX_ELSE:.+]]
+  //
+  // CHECK: [[DO_MAX]]
+  // CHECK: br label {{%?}}[[MAX_CONT:.+]]
+  //
+  // CHECK: [[MAX_ELSE]]
+  // CHECK: [[BV:%.+]] = load i16, i16* [[B]], align
+  // CHECK: [[MAX:%.+]] = sext i16 [[BV]] to i32
+  // CHECK: br label {{%?}}[[MAX_CONT]]
+  //
+  // CHECK: [[MAX_CONT]]
+  // CHECK: [[B_LVALUE:%.+]] = phi i32 [ 99, %[[DO_MAX]] ], [ [[MAX]], %[[MAX_ELSE]] ]
+  // CHECK: [[TRUNC:%.+]] = trunc i32 [[B_LVALUE]] to i16
+  // CHECK: store i16 [[TRUNC]], i16* [[B]], align
+  // CHECK: [[PTR1:%.+]] = getelementptr inbounds [[RLT:.+]], [2 x i8*]* [[RL:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[A_CAST:%.+]] = bitcast i32* [[A]] to i8*
+  // CHECK: store i8* [[A_CAST]], i8** [[PTR1]], align
+  // CHECK: [[PTR2:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RL]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[B_CAST:%.+]] = bitcast i16* [[B]] to i8*
+  // CHECK: store i8* [[B_CAST]], i8** [[PTR2]], align
+  // CHECK: [[ARG_RL:%.+]] = bitcast [[RLT]]* [[RL]] to i8*
+  // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_teams_reduce_nowait(i32 {{.+}}, i32 2, i[[SZ]] {{8|16}}, i8* [[ARG_RL]], void (i8*, i16, i16, i16)* [[SHUFFLE_REDUCE_FN:@.+]], void (i8*, i32)* [[WARP_COPY_FN:@.+]], void (i8*, i8*, i32, i32)* [[SCRATCH_COPY_FN:@.+]], void (i8*, i8*, i32, i32, i32)* [[LOAD_REDUCE_FN:@.+]])
+  // CHECK: [[COND:%.+]] = icmp eq i32 [[RET]], 1
+  // CHECK: br i1 [[COND]], label {{%?}}[[IFLABEL:.+]], label {{%?}}[[EXIT:.+]]
+  //
+  // CHECK: [[IFLABEL]]
+  // CHECK: [[A_INV:%.+]] = load i32, i32* [[A_IN:%.+]], align
+  // CHECK: [[AV:%.+]] = load i32, i32* [[A]], align
+  // CHECK: [[OR:%.+]] = or i32 [[A_INV]], [[AV]]
+  // CHECK: store i32 [[OR]], i32* [[A_IN]], align
+  // CHECK: [[B_INV16:%.+]] = load i16, i16* [[B_IN:%.+]], align
+  // CHECK: [[B_INV:%.+]] = sext i16 [[B_INV16]] to i32
+  // CHECK: [[BV16:%.+]] = load i16, i16* [[B]], align
+  // CHECK: [[BV:%.+]] = sext i16 [[BV16]] to i32
+  // CHECK: [[CMP:%.+]] = icmp sgt i32 [[B_INV]], [[BV]]
+  // CHECK: br i1 [[CMP]], label {{%?}}[[DO_MAX:.+]], label {{%?}}[[MAX_ELSE:.+]]
+  //
+  // CHECK: [[DO_MAX]]
+  // CHECK: [[MAX1:%.+]] = load i16, i16* [[B_IN]], align
+  // CHECK: br label {{%?}}[[MAX_CONT:.+]]
+  //
+  // CHECK: [[MAX_ELSE]]
+  // CHECK: [[MAX2:%.+]] = load i16, i16* [[B]], align
+  // CHECK: br label {{%?}}[[MAX_CONT]]
+  //
+  // CHECK: [[MAX_CONT]]
+  // CHECK: [[B_MAX:%.+]] = phi i16 [ [[MAX1]], %[[DO_MAX]] ], [ [[MAX2]], %[[MAX_ELSE]] ]
+  // CHECK: store i16 [[B_MAX]], i16* [[B_IN]], align
+  // CHECK: call void @__kmpc_nvptx_end_reduce_nowait(
+  // CHECK: br label %[[EXIT]]
+  //
+  // CHECK: [[EXIT]]
+  // CHECK: call void @__kmpc_kernel_deinit()
+
+  //
+  // Reduction function
+  // CHECK: define internal void [[REDUCTION_FUNC:@.+]](i8*, i8*)
+  // CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
+  // CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to i32*
+  //
+  // CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
+  // CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to i32*
+  //
+  // CHECK: [[VAR2_RHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_RHS]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[VAR2_RHS_VOID:%.+]] = load i8*, i8** [[VAR2_RHS_REF]],
+  // CHECK: [[VAR2_RHS:%.+]] = bitcast i8* [[VAR2_RHS_VOID]] to i16*
+  //
+  // CHECK: [[VAR2_LHS_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST_LHS]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[VAR2_LHS_VOID:%.+]] = load i8*, i8** [[VAR2_LHS_REF]],
+  // CHECK: [[VAR2_LHS:%.+]] = bitcast i8* [[VAR2_LHS_VOID]] to i16*
+  //
+  // CHECK: [[VAR1_LHS_VAL:%.+]] = load i32, i32* [[VAR1_LHS]],
+  // CHECK: [[VAR1_RHS_VAL:%.+]] = load i32, i32* [[VAR1_RHS]],
+  // CHECK: [[OR:%.+]] = or i32 [[VAR1_LHS_VAL]], [[VAR1_RHS_VAL]]
+  // CHECK: store i32 [[OR]], i32* [[VAR1_LHS]],
+  //
+  // CHECK: [[VAR2_LHS_VAL16:%.+]] = load i16, i16* [[VAR2_LHS]],
+  // CHECK: [[VAR2_LHS_VAL:%.+]] = sext i16 [[VAR2_LHS_VAL16]] to i32
+  // CHECK: [[VAR2_RHS_VAL16:%.+]] = load i16, i16* [[VAR2_RHS]],
+  // CHECK: [[VAR2_RHS_VAL:%.+]] = sext i16 [[VAR2_RHS_VAL16]] to i32
+  //
+  // CHECK: [[CMP:%.+]] = icmp sgt i32 [[VAR2_LHS_VAL]], [[VAR2_RHS_VAL]]
+  // CHECK: br i1 [[CMP]], label {{%?}}[[DO_MAX:.+]], label {{%?}}[[MAX_ELSE:.+]]
+  //
+  // CHECK: [[DO_MAX]]
+  // CHECK: [[MAX1:%.+]] = load i16, i16* [[VAR2_LHS]], align
+  // CHECK: br label {{%?}}[[MAX_CONT:.+]]
+  //
+  // CHECK: [[MAX_ELSE]]
+  // CHECK: [[MAX2:%.+]] = load i16, i16* [[VAR2_RHS]], align
+  // CHECK: br label {{%?}}[[MAX_CONT]]
+  //
+  // CHECK: [[MAX_CONT]]
+  // CHECK: [[MAXV:%.+]] = phi i16 [ [[MAX1]], %[[DO_MAX]] ], [ [[MAX2]], %[[MAX_ELSE]] ]
+  // CHECK: store i16 [[MAXV]], i16* [[VAR2_LHS]],
+  // CHECK: ret void
+
+  //
+  // Shuffle and reduce function
+  // CHECK: define internal void [[SHUFFLE_REDUCE_FN]](i8*, i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+  // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [[RLT]], align
+  // CHECK: [[REMOTE_ELT1:%.+]] = alloca i32
+  // CHECK: [[REMOTE_ELT2:%.+]] = alloca i16
+  //
+  // CHECK: [[LANEID:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[LANEOFFSET:%.+]] = load i16, i16* {{.+}}, align
+  // CHECK: [[ALGVER:%.+]] = load i16, i16* {{.+}}, align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT]], align
+  //
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT1_VAL:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_VAL]], i16 [[LANEOFFSET]], i16 [[WS]])
+  //
+  // CHECK: store i32 [[REMOTE_ELT1_VAL]], i32* [[REMOTE_ELT1]], align
+  // CHECK: [[REMOTE_ELT1C:%.+]] = bitcast i32* [[REMOTE_ELT1]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT1C]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: [[ELT_VAL:%.+]] = load i16, i16* [[ELT]], align
+  //
+  // CHECK: [[ELT_CAST:%.+]] = sext i16 [[ELT_VAL]] to i32
+  // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+  // CHECK: [[REMOTE_ELT2_VAL32:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+  // CHECK: [[REMOTE_ELT2_VAL:%.+]] = trunc i32 [[REMOTE_ELT2_VAL32]] to i16
+  //
+  // CHECK: store i16 [[REMOTE_ELT2_VAL]], i16* [[REMOTE_ELT2]], align
+  // CHECK: [[REMOTE_ELT2C:%.+]] = bitcast i16* [[REMOTE_ELT2]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT2C]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // Condition to reduce
+  // CHECK: [[CONDALG0:%.+]] = icmp eq i16 [[ALGVER]], 0
+  //
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp ult i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[CONDALG1:%.+]] = and i1 [[COND1]], [[COND2]]
+  //
+  // CHECK: [[COND3:%.+]] = icmp eq i16 [[ALGVER]], 2
+  // CHECK: [[COND4:%.+]] = and i16 [[LANEID]], 1
+  // CHECK: [[COND5:%.+]] = icmp eq i16 [[COND4]], 0
+  // CHECK: [[COND6:%.+]] = and i1 [[COND3]], [[COND5]]
+  // CHECK: [[COND7:%.+]] = icmp sgt i16 [[LANEOFFSET]], 0
+  // CHECK: [[CONDALG2:%.+]] = and i1 [[COND6]], [[COND7]]
+  //
+  // CHECK: [[COND8:%.+]] = or i1 [[CONDALG0]], [[CONDALG1]]
+  // CHECK: [[SHOULD_REDUCE:%.+]] = or i1 [[COND8]], [[CONDALG2]]
+  // CHECK: br i1 [[SHOULD_REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+  //
+  // CHECK: [[DO_REDUCE]]
+  // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [[RLT]]* [[RED_LIST]] to i8*
+  // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [[RLT]]* [[REMOTE_RED_LIST]] to i8*
+  // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+  // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+  //
+  // CHECK: [[REDUCE_ELSE]]
+  // CHECK: br label {{%?}}[[REDUCE_CONT]]
+  //
+  // CHECK: [[REDUCE_CONT]]
+  // Now check if we should just copy over the remote reduction list
+  // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+  // CHECK: [[COND2:%.+]] = icmp uge i16 [[LANEID]], [[LANEOFFSET]]
+  // CHECK: [[SHOULD_COPY:%.+]] = and i1 [[COND1]], [[COND2]]
+  // CHECK: br i1 [[SHOULD_COPY]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // CHECK: [[DO_COPY]]
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to i32*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i32, i32* [[REMOTE_ELT]], align
+  // CHECK: store i32 [[REMOTE_ELT_VAL]], i32* [[ELT]], align
+  //
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to i16*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i16, i16* [[REMOTE_ELT]], align
+  // CHECK: store i16 [[REMOTE_ELT_VAL]], i16* [[ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // CHECK: [[COPY_CONT]]
+  // CHECK: void
+
+  //
+  // Inter warp copy function
+  // CHECK: define internal void [[WARP_COPY_FN]](i8*, i32)
+  // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31
+  // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5
+  // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i32 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store i32 [[ELT_VAL]], i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i32 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load i32, i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: store i32 [[MEDIUM_ELT_VAL]], i32* [[ELT]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+  // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+  //
+  // [[DO_COPY]]
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: [[ELT_VAL:%.+]] = load i16, i16* [[ELT]], align
+  //
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i16 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: store i16 [[ELT_VAL]], i16 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+  //
+  // CHECK: [[COPY_ELSE]]
+  // CHECK: br label {{%?}}[[COPY_CONT]]
+  //
+  // Barrier after copy to shared memory storage medium.
+  // CHECK: [[COPY_CONT]]
+  // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+  // CHECK: [[ACTIVE_THREADS:%.+]] = mul nsw i32 [[ACTIVE_WARPS:%.+]], [[WS]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  //
+  // Read into warp 0.
+  // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+  // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+  //
+  // CHECK: [[DO_READ]]
+  // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i64], [32 x i64] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+  // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i64 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i16 addrspace([[SHARED_ADDRSPACE]])*
+  // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load i16, i16 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: store i16 [[MEDIUM_ELT_VAL]], i16* [[ELT]], align
+  // CHECK: br label {{%?}}[[READ_CONT:.+]]
+  //
+  // CHECK: [[READ_ELSE]]
+  // CHECK: br label {{%?}}[[READ_CONT]]
+  //
+  // CHECK: [[READ_CONT]]
+  // CHECK: call void @llvm.nvvm.barrier(i32 1, i32 [[ACTIVE_THREADS]])
+  // CHECK: ret
+
+  //
+  // Copy to scratchpad function
+  // CHECK: define internal void [[SCRATCH_COPY_FN]](i8*, i8*, i32, i32)
+  // CHECK: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[SCRATCHPAD_PTR:%.+]] = load i8*, i8** {{.+}}, align
+  // CHECK-64: [[TEAM32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[TEAM:%.+]] = sext i32 [[TEAM32]] to i64
+  // CHECK-32: [[TEAM:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS:%.+]] = sext i32 [[NUM_TEAMS32]] to i64
+  // CHECK-32: [[NUM_TEAMS:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK: [[SCRATCHPAD:%.+]] = ptrtoint i8* [[SCRATCHPAD_PTR]] to i[[SZ]]
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 4, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR_VOID:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+  // CHECK: [[SCRATCHPAD_ELT_PTR:%.+]] = bitcast i8* [[SCRATCHPAD_ELT_PTR_VOID]] to i32*
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT]], align
+  // CHECK: store i32 [[ELT_VAL]], i32* [[SCRATCHPAD_ELT_PTR]], align
+  //
+  // CHECK: [[OF:%.+]] = mul i[[SZ]] [[NUM_TEAMS]], 4
+  // CHECK: [[POS1:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[OF]]
+  // CHECK: [[POS2:%.+]] = sub i[[SZ]] [[POS1]], 1
+  // CHECK: [[POS3:%.+]] = sdiv i[[SZ]] [[POS2]], 256
+  // CHECK: [[POS4:%.+]] = add i[[SZ]] [[POS3]], 1
+  // CHECK: [[SCRATCHPAD_NEXT:%.+]] = mul i[[SZ]] [[POS4]], 256
+  //
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 2, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD_NEXT]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR_VOID:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+  // CHECK: [[SCRATCHPAD_ELT_PTR:%.+]] = bitcast i8* [[SCRATCHPAD_ELT_PTR_VOID]] to i16*
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: [[ELT_VAL:%.+]] = load i16, i16* [[ELT]], align
+  // CHECK: store i16 [[ELT_VAL]], i16* [[SCRATCHPAD_ELT_PTR]], align
+  //
+  // CHECK: ret
+
+  //
+  // Load and reduce function
+  // CHECK: define internal void [[LOAD_REDUCE_FN]](i8*, i8*, i32, i32, i32)
+  // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [[RLT]], align
+  // CHECK: [[REMOTE_ELT1:%.+]] = alloca i32
+  // CHECK: [[REMOTE_ELT2:%.+]] = alloca i16
+  // CHECK: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+  // CHECK: [[SCRATCHPAD_PTR:%.+]] = load i8*, i8** {{.+}}, align
+  // CHECK-64: [[TEAM32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[TEAM:%.+]] = sext i32 [[TEAM32]] to i64
+  // CHECK-32: [[TEAM:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS32:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK-64: [[NUM_TEAMS:%.+]] = sext i32 [[NUM_TEAMS32]] to i64
+  // CHECK-32: [[NUM_TEAMS:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK: [[SHOULD_REDUCE:%.+]] = load i32, i32* {{.+}}, align
+  // CHECK: [[SCRATCHPAD:%.+]] = ptrtoint i8* [[SCRATCHPAD_PTR]] to i[[SZ]]
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 4, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR_VOID:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[SCRATCHPAD_ELT_PTR:%.+]] = bitcast i8* [[SCRATCHPAD_ELT_PTR_VOID]] to i32*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i32, i32* [[SCRATCHPAD_ELT_PTR]], align
+  // CHECK: store i32 [[REMOTE_ELT_VAL]], i32* [[REMOTE_ELT1]], align
+  // CHECK: [[REMOTE_ELT1_PTR:%.+]] = bitcast i32* [[REMOTE_ELT1]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT1_PTR]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // CHECK: [[OF:%.+]] = mul i[[SZ]] [[NUM_TEAMS]], 4
+  // CHECK: [[POS1:%.+]] = add i[[SZ]] [[SCRATCHPAD]], [[OF]]
+  // CHECK: [[POS2:%.+]] = sub i[[SZ]] [[POS1]], 1
+  // CHECK: [[POS3:%.+]] = sdiv i[[SZ]] [[POS2]], 256
+  // CHECK: [[POS4:%.+]] = add i[[SZ]] [[POS3]], 1
+  // CHECK: [[SCRATCHPAD_NEXT:%.+]] = mul i[[SZ]] [[POS4]], 256
+  //
+  // CHECK: [[P:%.+]] = mul i[[SZ]] 2, [[TEAM]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR64:%.+]] = add i[[SZ]] [[SCRATCHPAD_NEXT]], [[P]]
+  // CHECK: [[SCRATCHPAD_ELT_PTR_VOID:%.+]] = inttoptr i[[SZ]] [[SCRATCHPAD_ELT_PTR64]] to i8*
+
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[SCRATCHPAD_ELT_PTR:%.+]] = bitcast i8* [[SCRATCHPAD_ELT_PTR_VOID]] to i16*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i16, i16* [[SCRATCHPAD_ELT_PTR]], align
+  // CHECK: store i16 [[REMOTE_ELT_VAL]], i16* [[REMOTE_ELT2]], align
+  // CHECK: [[REMOTE_ELT_PTR:%.+]] = bitcast i16* [[REMOTE_ELT2]] to i8*
+  // CHECK: store i8* [[REMOTE_ELT_PTR]], i8** [[REMOTE_ELT_REF]], align
+  //
+  // CHECK: [[REDUCE:%.+]] = icmp eq i32 [[SHOULD_REDUCE]], 1
+  // CHECK: br i1 [[REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+  //
+  // CHECK: [[DO_REDUCE]]
+  // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [[RLT]]* [[RED_LIST]] to i8*
+  // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [[RLT]]* [[REMOTE_RED_LIST]] to i8*
+  // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+  // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+  //
+  // Copy element from remote reduce list
+  // CHECK: [[REDUCE_ELSE]]
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to i32*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i32, i32* [[REMOTE_ELT]], align
+  // CHECK: store i32 [[REMOTE_ELT_VAL]], i32* [[ELT]], align
+  //
+  // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[REMOTE_RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+  // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 1
+  // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+  // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+  // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to i16*
+  // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i16, i16* [[REMOTE_ELT]], align
+  // CHECK: store i16 [[REMOTE_ELT_VAL]], i16* [[ELT]], align
+  // CHECK: br label {{%?}}[[REDUCE_CONT]]
+  //
+  // CHECK: [[REDUCE_CONT]]
+  // CHECK: ret
+
+
+#endif
diff --git a/test/OpenMP/openmp_check.cpp b/test/OpenMP/openmp_check.cpp
index c9b5eb0..d46213a 100644
--- a/test/OpenMP/openmp_check.cpp
+++ b/test/OpenMP/openmp_check.cpp
@@ -1,15 +1,35 @@
 // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 %s
+
 int nested(int a) {
 #pragma omp parallel
   ++a;
 
-  auto F = [&]() { // expected-error {{expected expression}} expected-error {{expected ';' at end of declaration}} expected-warning {{'auto' type specifier is a C++11 extension}}
+  auto F = [&]() {
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{'auto' type specifier is a C++11 extension}}
+  // expected-error@-3 {{expected expression}}
+  // expected-error@-4 {{expected ';' at end of declaration}}
+#else
+  // expected-no-diagnostics
+#endif
+
 #pragma omp parallel
     {
 #pragma omp target
       ++a;
     }
   };
-  F(); // expected-error {{C++ requires a type specifier for all declarations}}
-  return a; // expected-error {{expected unqualified-id}}
-}// expected-error {{extraneous closing brace ('}')}}
+  F();
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{C++ requires a type specifier for all declarations}}
+#endif
+  return a;
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{expected unqualified-id}}
+#endif
+}
+#if __cplusplus <= 199711L
+// expected-error@-2 {{extraneous closing brace ('}')}}
+#endif
diff --git a/test/OpenMP/openmp_seh.c b/test/OpenMP/openmp_seh.c
new file mode 100644
index 0000000..74dccec
--- /dev/null
+++ b/test/OpenMP/openmp_seh.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -verify -triple x86_64-pc-windows-msvc19.0.0 -fopenmp -fms-compatibility -x c++ -emit-llvm %s -o - | FileCheck %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+extern "C" {
+void __cpuid(int[4], int);
+}
+
+// CHECK-LABEL: @main
+int main(void) {
+  __try {
+    int info[4];
+    __cpuid(info, 1);
+  } __except (1) {
+  }
+
+  return 0;
+}
+
diff --git a/test/OpenMP/ordered_messages.cpp b/test/OpenMP/ordered_messages.cpp
index 36f9bb2..eb2c18e 100644
--- a/test/OpenMP/ordered_messages.cpp
+++ b/test/OpenMP/ordered_messages.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++98 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 -o - %s
 
 int foo();
 
@@ -123,6 +125,9 @@
 #pragma omp ordered depend(sink : j, i) // expected-error {{expected 'i' loop iteration variable}} expected-error {{expected 'j' loop iteration variable}}
 #pragma omp ordered depend(sink : i, j, k) // expected-error {{unexpected expression: number of expressions is larger than the number of associated loops}}
 #pragma omp ordered depend(sink : i+foo(), j/4) // expected-error {{expression is not an integral constant expression}} expected-error {{expected '+' or '-' operation}}
+#if __cplusplus >= 201103L
+// expected-note@-2 {{non-constexpr function 'foo' cannot be used in a constant expression}}
+#endif
 #pragma omp ordered depend(sink : i*0, j-4)// expected-error {{expected '+' or '-' operation}}
 #pragma omp ordered depend(sink : i-0, j+sizeof(T)) depend(sink : i-0, j+sizeof(T))
 #pragma omp ordered depend(sink : i-0, j+sizeof(T)) depend(source) // expected-error {{'depend(source)' clause cannot be mixed with 'depend(sink:vec)' clauses}}
@@ -133,6 +138,9 @@
 }
 
 int foo() {
+#if __cplusplus >= 201103L
+// expected-note@-2 2 {{declared here}}
+#endif
 int k;
   #pragma omp for ordered
   for (int i = 0; i < 10; ++i) {
@@ -252,6 +260,9 @@
 #pragma omp ordered depend(sink : j, i) // expected-error {{expected 'i' loop iteration variable}} expected-error {{expected 'j' loop iteration variable}}
 #pragma omp ordered depend(sink : i, j, k) // expected-error {{unexpected expression: number of expressions is larger than the number of associated loops}}
 #pragma omp ordered depend(sink : i+foo(), j/4) // expected-error {{expression is not an integral constant expression}} expected-error {{expected '+' or '-' operation}}
+#if __cplusplus >= 201103L
+// expected-note@-2 {{non-constexpr function 'foo' cannot be used in a constant expression}}
+#endif
 #pragma omp ordered depend(sink : i*0, j-4)// expected-error {{expected '+' or '-' operation}}
 #pragma omp ordered depend(sink : i-0, j+sizeof(int)) depend(sink : i-0, j+sizeof(int))
 #pragma omp ordered depend(sink : i-0, j+sizeof(int)) depend(source) // expected-error {{'depend(source)' clause cannot be mixed with 'depend(sink:vec)' clauses}}
diff --git a/test/OpenMP/parallel_ast_print.cpp b/test/OpenMP/parallel_ast_print.cpp
index 135c085..1e24c6e 100644
--- a/test/OpenMP/parallel_ast_print.cpp
+++ b/test/OpenMP/parallel_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/parallel_for_ast_print.cpp b/test/OpenMP/parallel_for_ast_print.cpp
index c400e9b..3c36bd8 100644
--- a/test/OpenMP/parallel_for_ast_print.cpp
+++ b/test/OpenMP/parallel_for_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/parallel_for_if_messages.cpp b/test/OpenMP/parallel_for_if_messages.cpp
index 2b7a5f7..b5a7fdc 100644
--- a/test/OpenMP/parallel_for_if_messages.cpp
+++ b/test/OpenMP/parallel_for_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
@@ -34,7 +34,7 @@
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for if(argc)
   for (i = 0; i < argc; ++i) foo();
-  #pragma omp parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel for if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
@@ -78,7 +78,7 @@
   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();
-  #pragma omp parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel for if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/parallel_for_simd_ast_print.cpp b/test/OpenMP/parallel_for_simd_ast_print.cpp
index 137d8dfa..2668961 100644
--- a/test/OpenMP/parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/parallel_for_simd_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/parallel_for_simd_if_messages.cpp b/test/OpenMP/parallel_for_simd_if_messages.cpp
index 829b825..7842524 100644
--- a/test/OpenMP/parallel_for_simd_if_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 %s
 
 void foo() {
 }
@@ -34,7 +34,7 @@
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for simd if(argc)
   for (i = 0; i < argc; ++i) foo();
-  #pragma omp parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel for simd if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
@@ -78,7 +78,7 @@
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
-  #pragma omp parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel for simd if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
   #pragma omp parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/parallel_if_codegen.cpp b/test/OpenMP/parallel_if_codegen.cpp
index 9ecf572..af154c0 100644
--- a/test/OpenMP/parallel_if_codegen.cpp
+++ b/test/OpenMP/parallel_if_codegen.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK %s
 // expected-no-diagnostics
 #ifndef HEADER
 #define HEADER
diff --git a/test/OpenMP/parallel_if_messages.cpp b/test/OpenMP/parallel_if_messages.cpp
index 1ffc567..094e83b 100644
--- a/test/OpenMP/parallel_if_messages.cpp
+++ b/test/OpenMP/parallel_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
@@ -22,7 +22,7 @@
   #pragma omp parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(argc)
-  #pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(parallel : argc)
@@ -47,7 +47,7 @@
   #pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
-  #pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
   #pragma omp parallel if(parallel : argc)
diff --git a/test/OpenMP/parallel_sections_ast_print.cpp b/test/OpenMP/parallel_sections_ast_print.cpp
index 4c298df..da3bd48 100644
--- a/test/OpenMP/parallel_sections_ast_print.cpp
+++ b/test/OpenMP/parallel_sections_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/parallel_sections_if_messages.cpp b/test/OpenMP/parallel_sections_if_messages.cpp
index c2e3f5e..ce067a2 100644
--- a/test/OpenMP/parallel_sections_if_messages.cpp
+++ b/test/OpenMP/parallel_sections_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
diff --git a/test/OpenMP/target_ast_print.cpp b/test/OpenMP/target_ast_print.cpp
index 24f6d5a..032a39f 100644
--- a/test/OpenMP/target_ast_print.cpp
+++ b/test/OpenMP/target_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/target_codegen.cpp b/test/OpenMP/target_codegen.cpp
index f263ebd..b5e4b07 100644
--- a/test/OpenMP/target_codegen.cpp
+++ b/test/OpenMP/target_codegen.cpp
@@ -22,11 +22,11 @@
 
 // CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
 // CHECK-DAG: [[S1:%.+]] = type { double }
-// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]] }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
 // CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
 // CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
 
-// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}} }
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
 
 // We have 8 target regions, but only 7 that actually will generate offloading
 // code, only 6 will have mapped arguments, and only 4 have all-constant map
diff --git a/test/OpenMP/target_codegen_registration.cpp b/test/OpenMP/target_codegen_registration.cpp
index a440faf..f2721b77f 100644
--- a/test/OpenMP/target_codegen_registration.cpp
+++ b/test/OpenMP/target_codegen_registration.cpp
@@ -30,11 +30,11 @@
 // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] }
 // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] }
 // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] }
-// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]] }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
 // CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
 // CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
 
-// TCHECK:    [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]] }
+// TCHECK:    [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
 
 // CHECK-DAG: [[A1:@.+]] = internal global [[SA]]
 // CHECK-DAG: [[A2:@.+]] = global [[SA]]
@@ -100,54 +100,54 @@
 // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
 
 // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
-// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
-// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
-// CHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
-// CHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
-// CHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
-// CHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
-// CHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
-// CHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
-// CHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
-// CHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
-// CHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
-// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 
 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
-// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
-// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
-// TCHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
-// TCHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
-// TCHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
-// TCHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
-// TCHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
-// TCHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
-// TCHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
-// TCHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
-// TCHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
-// TCHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
 
 // CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
 // CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
diff --git a/test/OpenMP/target_data_ast_print.cpp b/test/OpenMP/target_data_ast_print.cpp
index 88c8df8..bb55ea3 100644
--- a/test/OpenMP/target_data_ast_print.cpp
+++ b/test/OpenMP/target_data_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/target_data_if_messages.cpp b/test/OpenMP/target_data_if_messages.cpp
index ec6fe26..229d7f5 100644
--- a/test/OpenMP/target_data_if_messages.cpp
+++ b/test/OpenMP/target_data_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - %s
 
 void foo() {
 }
diff --git a/test/OpenMP/target_enter_data_ast_print.cpp b/test/OpenMP/target_enter_data_ast_print.cpp
index 9c4c62f..865cc7f 100644
--- a/test/OpenMP/target_enter_data_ast_print.cpp
+++ b/test/OpenMP/target_enter_data_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/target_enter_data_if_messages.cpp b/test/OpenMP/target_enter_data_if_messages.cpp
index 0d18af1..137ff97 100644
--- a/test/OpenMP/target_enter_data_if_messages.cpp
+++ b/test/OpenMP/target_enter_data_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - %s
 
 void foo() {
 }
diff --git a/test/OpenMP/target_exit_data_ast_print.cpp b/test/OpenMP/target_exit_data_ast_print.cpp
index bebb2da..a2f5d64 100644
--- a/test/OpenMP/target_exit_data_ast_print.cpp
+++ b/test/OpenMP/target_exit_data_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/target_exit_data_if_messages.cpp b/test/OpenMP/target_exit_data_if_messages.cpp
index cc674e6..6d5ada1 100644
--- a/test/OpenMP/target_exit_data_if_messages.cpp
+++ b/test/OpenMP/target_exit_data_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - %s
 
 void foo() {
 }
diff --git a/test/OpenMP/target_if_messages.cpp b/test/OpenMP/target_if_messages.cpp
index 189256e..14b6a5f 100644
--- a/test/OpenMP/target_if_messages.cpp
+++ b/test/OpenMP/target_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 %s
 
 void foo() {
 }
diff --git a/test/OpenMP/target_parallel_ast_print.cpp b/test/OpenMP/target_parallel_ast_print.cpp
index 7e31f50..82c9203 100644
--- a/test/OpenMP/target_parallel_ast_print.cpp
+++ b/test/OpenMP/target_parallel_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/target_parallel_codegen.cpp b/test/OpenMP/target_parallel_codegen.cpp
new file mode 100644
index 0000000..c7acb27
--- /dev/null
+++ b/test/OpenMP/target_parallel_codegen.cpp
@@ -0,0 +1,802 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// We have 8 target regions, but only 7 that actually will generate offloading
+// code, only 6 will have mapped arguments, and only 4 have all-constant map
+// sizes.
+
+// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 2]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 35, i32 288, i32 35, i32 35, i32 288, i32 288, i32 35, i32 35]
+// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 35]
+// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 35]
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }]
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* [[REGFN:@.+]] to void ()*), i8* null }]
+
+
+template<typename tx, typename ty>
+struct TT{
+  tx X;
+  ty Y;
+};
+
+// CHECK: define {{.*}}[[FOO:@.+]](
+int foo(int n) {
+  int a = 0;
+  short aa = 0;
+  float b[10];
+  float bn[n];
+  double c[5][10];
+  double cn[5][n];
+  TT<long long, char> d;
+
+  // CHECK:       [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i32* null, i32 1, i32 0)
+  // CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+  // CHECK:       [[FAIL]]
+  // CHECK:       call void [[HVT0:@.+]]()
+  // CHECK-NEXT:  br label %[[END]]
+  // CHECK:       [[END]]
+  #pragma omp target parallel
+  {
+  }
+
+  // CHECK:       store i32 0, i32* [[RHV:%.+]], align 4
+  // CHECK:       store i32 -1, i32* [[RHV]], align 4
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK:       call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}})
+  #pragma omp target parallel if(target: 0)
+  {
+    a += 1;
+  }
+
+  // CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT2]], i32 0, i32 0), i32 1, i32 0)
+  // CHECK-DAG:   [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
+  // CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR]], i32 0, i32 [[IDX0]]
+  // CHECK-DAG:   store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
+  // CHECK-DAG:   store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
+  // CHECK-DAG:   [[BP0]] = inttoptr i[[SZ]] %{{.+}} to i8*
+  // CHECK-DAG:   [[P0]] = inttoptr i[[SZ]] %{{.+}} to i8*
+
+  // CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+  // CHECK:       [[FAIL]]
+  // CHECK:       call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}})
+  // CHECK-NEXT:  br label %[[END]]
+  // CHECK:       [[END]]
+  #pragma omp target parallel if(target: 1)
+  {
+    aa += 1;
+  }
+
+  // CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
+  // CHECK:       br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+  // CHECK:       [[IFTHEN]]
+  // CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT3]], i32 0, i32 0), i32 1, i32 0)
+  // CHECK-DAG:   [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+
+  // CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
+  // CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
+  // CHECK-DAG:   store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
+  // CHECK-DAG:   store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
+  // CHECK-DAG:   [[BP0]] = inttoptr i[[SZ]] %{{.+}} to i8*
+  // CHECK-DAG:   [[P0]] = inttoptr i[[SZ]] %{{.+}} to i8*
+
+  // CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
+  // CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
+  // CHECK-DAG:   store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]]
+  // CHECK-DAG:   store i8* [[P1:%[^,]+]], i8** [[PADDR1]]
+  // CHECK-DAG:   [[BP1]] = inttoptr i[[SZ]] %{{.+}} to i8*
+  // CHECK-DAG:   [[P1]] = inttoptr i[[SZ]] %{{.+}} to i8*
+  // CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+  // CHECK-NEXT:  br label %[[IFEND:.+]]
+
+  // CHECK:       [[IFELSE]]
+  // CHECK:       store i32 -1, i32* [[RHV]], align 4
+  // CHECK-NEXT:  br label %[[IFEND:.+]]
+
+  // CHECK:       [[IFEND]]
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+  // CHECK:       [[FAIL]]
+  // CHECK:       call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
+  // CHECK-NEXT:  br label %[[END]]
+  // CHECK:       [[END]]
+  #pragma omp target parallel if(target: n>10)
+  {
+    a += 1;
+    aa += 1;
+  }
+
+  // We capture 3 VLA sizes in this target region
+  // CHECK-64:       [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+  // CHECK-64:       [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32*
+  // CHECK-64:       store i32 [[A_VAL]], i32* [[A_ADDR]],
+  // CHECK-64:       [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+  // CHECK-32:       [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+  // CHECK-32:       store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
+  // CHECK-32:       [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+  // CHECK:       [[BNSIZE:%.+]] = mul nuw i[[SZ]] [[VLA0:%.+]], 4
+  // CHECK:       [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
+  // CHECK:       [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
+
+  // CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
+  // CHECK:       br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+  // CHECK:       [[TRY]]
+  // CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT4]], i32 0, i32 0), i32 1, i32 0)
+  // CHECK-DAG:   [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
+
+  // CHECK-DAG:   [[SADDR0:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX0:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX0]]
+  // CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX0]]
+  // CHECK-DAG:   [[SADDR1:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX1:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX1]]
+  // CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX1]]
+  // CHECK-DAG:   [[SADDR2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX2:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX2]]
+  // CHECK-DAG:   [[PADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX2]]
+  // CHECK-DAG:   [[SADDR3:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX3:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX3]]
+  // CHECK-DAG:   [[PADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX3]]
+  // CHECK-DAG:   [[SADDR4:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX4:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX4]]
+  // CHECK-DAG:   [[PADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX4]]
+  // CHECK-DAG:   [[SADDR5:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX5:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX5]]
+  // CHECK-DAG:   [[PADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX5]]
+  // CHECK-DAG:   [[SADDR6:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX6:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX6]]
+  // CHECK-DAG:   [[PADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX6]]
+  // CHECK-DAG:   [[SADDR7:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX7:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX7]]
+  // CHECK-DAG:   [[PADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX7]]
+  // CHECK-DAG:   [[SADDR8:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX8:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX8]]
+  // CHECK-DAG:   [[PADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX8]]
+
+  // The names below are not necessarily consistent with the names used for the
+  // addresses above as some are repeated.
+  // CHECK-DAG:   [[BP0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
+  // CHECK-DAG:   [[P0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
+  // CHECK-DAG:   store i8* [[BP0]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P0]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP1:%[^,]+]] = inttoptr i[[SZ]] [[VLA1]] to i8*
+  // CHECK-DAG:   [[P1:%[^,]+]] = inttoptr i[[SZ]] [[VLA1]] to i8*
+  // CHECK-DAG:   store i8* [[BP1]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P1]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   store i8* inttoptr (i[[SZ]] 5 to i8*), i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* inttoptr (i[[SZ]] 5 to i8*), i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP3:%[^,]+]] = inttoptr i[[SZ]] [[A_CVAL]] to i8*
+  // CHECK-DAG:   [[P3:%[^,]+]] = inttoptr i[[SZ]] [[A_CVAL]] to i8*
+  // CHECK-DAG:   store i8* [[BP3]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P3]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP4:%[^,]+]] = bitcast [10 x float]* %{{.+}} to i8*
+  // CHECK-DAG:   [[P4:%[^,]+]] = bitcast [10 x float]* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP4]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P4]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] 40, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP5:%[^,]+]] = bitcast float* %{{.+}} to i8*
+  // CHECK-DAG:   [[P5:%[^,]+]] = bitcast float* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP5]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P5]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] [[BNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP6:%[^,]+]] = bitcast [5 x [10 x double]]* %{{.+}} to i8*
+  // CHECK-DAG:   [[P6:%[^,]+]] = bitcast [5 x [10 x double]]* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP6]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P6]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] 400, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP7:%[^,]+]] = bitcast double* %{{.+}} to i8*
+  // CHECK-DAG:   [[P7:%[^,]+]] = bitcast double* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP7]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P7]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] [[CNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP8:%[^,]+]] = bitcast [[TT]]* %{{.+}} to i8*
+  // CHECK-DAG:   [[P8:%[^,]+]] = bitcast [[TT]]* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP8]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P8]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+  // CHECK:       [[FAIL]]
+  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+  // CHECK-NEXT:  br label %[[END]]
+  // CHECK:       [[END]]
+  #pragma omp target parallel if(target: n>20)
+  {
+    a += 1;
+    b[2] += 1.0;
+    bn[3] += 1.0;
+    c[1][2] += 1.0;
+    cn[1][3] += 1.0;
+    d.X += 1;
+    d.Y += 1;
+  }
+
+  return a;
+}
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions in foo().
+
+// CHECK:       define internal void [[HVT0]]()
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*))
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid.)
+// CHECK:       ret void
+// CHECK-NEXT:  }
+
+
+// CHECK:       define internal void [[HVT1]](i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK:       store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64:    [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64:    [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32:    [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK-64:    [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i32*
+// CHECK-64:    store i32 [[AA]], i32* [[AA_C]], align
+// CHECK-32:    store i32 [[AA]], i32* [[AA_CASTED]], align
+// CHECK:       [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED1]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64:    [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64:    [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32:    [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK:       ret void
+// CHECK-NEXT:  }
+
+// CHECK:       define internal void [[HVT2]](i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK:       store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK:       [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK:       [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK:       [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK:       store i16 [[AA]], i16* [[AA_C]], align
+// CHECK:       [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED2]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK:       [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK:       [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK:       ret void
+// CHECK-NEXT:  }
+
+// CHECK:       define internal void [[HVT3]]
+// Create stack storage and store argument in there.
+// CHECK:       [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[A_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG:   store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG:   store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG:   [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK-64-DAG:[[A:%.+]] = load i32, i32* [[A_CADDR]], align
+// CHECK-32-DAG:[[A:%.+]] = load i32, i32* [[A_ADDR]], align
+// CHECK-64-DAG:[[A_C:%.+]] = bitcast i[[SZ]]* [[A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[A]], i32* [[A_C]], align
+// CHECK-32-DAG:store i32 [[A]], i32* [[A_CASTED]], align
+// CHECK-DAG:   [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK-DAG:   [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK-DAG:   store i16 [[AA]], i16* [[AA_C]], align
+// CHECK-DAG:   [[PARAM1:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CASTED]], align
+// CHECK-DAG:   [[PARAM2:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK-DAG:   call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]])* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM1]], i[[SZ]] [[PARAM2]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED3]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// CHECK:       [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG:   store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG:   store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG:   [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK:       ret void
+// CHECK-NEXT:  }
+
+// CHECK:       define internal void [[HVT4]]
+// Create local storage for each capture.
+// CHECK:       [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_B:%.+]] = alloca [10 x float]*
+// CHECK:       [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_BN:%.+]] = alloca float*
+// CHECK:       [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
+// CHECK:       [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_CN:%.+]] = alloca double*
+// CHECK:       [[LOCAL_D:%.+]] = alloca [[TT]]*
+// CHECK:       [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG:   store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG:   store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
+// CHECK-DAG:   store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
+// CHECK-DAG:   store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
+// CHECK-DAG:   store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
+
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG:   [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
+// CHECK-DAG:   [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG:   [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
+// CHECK-DAG:   [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
+// CHECK-DAG:   [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG:   [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
+// CHECK-DAG:   [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
+// CHECK-DAG:   [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG:   [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 9, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], [10 x float]*, i[[SZ]], float*, [5 x [10 x double]]*, i[[SZ]], i[[SZ]], double*, [[TT]]*)* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], [10 x float]* [[REF_B]], i[[SZ]] [[VAL_VLA1]], float* [[REF_BN]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] [[VAL_VLA2]], i[[SZ]] [[VAL_VLA3]], double* [[REF_CN]], [[TT]]* [[REF_D]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* %{{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* %{{.+}}, [[TT]]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+  short aa = 0;
+  tx b[10];
+
+  #pragma omp target parallel if(target: n>40)
+  {
+    a += 1;
+    aa += 1;
+    b[2] += 1;
+  }
+
+  return a;
+}
+
+static
+int fstatic(int n) {
+  int a = 0;
+  short aa = 0;
+  char aaa = 0;
+  int b[10];
+
+  #pragma omp target parallel if(target: n>50)
+  {
+    a += 1;
+    aa += 1;
+    aaa += 1;
+    b[2] += 1;
+  }
+
+  return a;
+}
+
+struct S1 {
+  double a;
+
+  int r1(int n){
+    int b = n+1;
+    short int c[2][n];
+
+    #pragma omp target parallel if(target: n>60)
+    {
+      this->a = (double)b + 1.5;
+      c[1][1] = ++a;
+    }
+
+    return c[1][1] + (int)b;
+  }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+  int a = 0;
+
+  // CHECK: call {{.*}}i32 [[FOO]](i32 {{.*}})
+  a += foo(n);
+
+  S1 S;
+  // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+  a += S.r1(n);
+
+  // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+  a += fstatic(n);
+
+  // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+//
+// CHECK: define {{.*}}[[FS1]]
+//
+// CHECK:          i8* @llvm.stacksave()
+// CHECK-64:       [[B_ADDR:%.+]] = bitcast i[[SZ]]* [[B_CADDR:%.+]] to i32*
+// CHECK-64:       store i32 %{{.+}}, i32* [[B_ADDR]],
+// CHECK-64:       [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_CADDR]],
+
+// CHECK-32:       store i32 %{{.+}}, i32* [[B_ADDR:%.+]],
+// CHECK-32:       [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_ADDR]],
+
+// We capture 2 VLA sizes in this target region
+// CHECK:       [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
+// CHECK:       [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
+
+// CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
+// CHECK:       br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+// CHECK:       [[TRY]]
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT7]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG:   [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[SADDR0:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX0:[0-9]+]]
+// CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX0]]
+// CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX0]]
+// CHECK-DAG:   [[SADDR1:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX1:[0-9]+]]
+// CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX1]]
+// CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX1]]
+// CHECK-DAG:   [[SADDR2:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX2:[0-9]+]]
+// CHECK-DAG:   [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX2]]
+// CHECK-DAG:   [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX2]]
+// CHECK-DAG:   [[SADDR3:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX3:[0-9]+]]
+// CHECK-DAG:   [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX3]]
+// CHECK-DAG:   [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX3]]
+
+// The names below are not necessarily consistent with the names used for the
+// addresses above as some are repeated.
+// CHECK-DAG:   [[BP0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
+// CHECK-DAG:   [[P0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
+// CHECK-DAG:   store i8* [[BP0]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* [[P0]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG:   store i8* inttoptr (i[[SZ]] 2 to i8*), i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* inttoptr (i[[SZ]] 2 to i8*), i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG:   [[BP2:%[^,]+]] = inttoptr i[[SZ]] [[B_CVAL]] to i8*
+// CHECK-DAG:   [[P2:%[^,]+]] = inttoptr i[[SZ]] [[B_CVAL]] to i8*
+// CHECK-DAG:   store i8* [[BP2]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* [[P2]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG:   [[BP3:%[^,]+]] = bitcast [[S1]]* %{{.+}} to i8*
+// CHECK-DAG:   [[P3:%[^,]+]] = bitcast [[S1]]* %{{.+}} to i8*
+// CHECK-DAG:   store i8* [[BP3]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* [[P3]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] 8, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG:   [[BP4:%[^,]+]] = bitcast i16* %{{.+}} to i8*
+// CHECK-DAG:   [[P4:%[^,]+]] = bitcast i16* %{{.+}} to i8*
+// CHECK-DAG:   store i8* [[BP4]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* [[P4]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
+
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+// CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT:  br label %[[END]]
+// CHECK:       [[END]]
+
+//
+// CHECK: define {{.*}}[[FSTATIC]]
+//
+// CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
+// CHECK:       br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK:       [[IFTHEN]]
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([4 x i32], [4 x i32]* [[MAPT6]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG:   [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG:   store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
+// CHECK-DAG:   store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
+// CHECK-DAG:   [[BP0]] = inttoptr i[[SZ]] [[VAL0:%.+]] to i8*
+// CHECK-DAG:   [[P0]] = inttoptr i[[SZ]] [[VAL0]] to i8*
+
+// CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG:   store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]]
+// CHECK-DAG:   store i8* [[P1:%[^,]+]], i8** [[PADDR1]]
+// CHECK-DAG:   [[BP1]] = inttoptr i[[SZ]] [[VAL1:%.+]] to i8*
+// CHECK-DAG:   [[P1]] = inttoptr i[[SZ]] [[VAL1]] to i8*
+
+// CHECK-DAG:   [[BPADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG:   [[PADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG:   store i8* [[BP2:%[^,]+]], i8** [[BPADDR2]]
+// CHECK-DAG:   store i8* [[P2:%[^,]+]], i8** [[PADDR2]]
+
+// CHECK-DAG:   [[BPADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 3
+// CHECK-DAG:   [[PADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 3
+// CHECK-DAG:   store i8* [[BP3:%[^,]+]], i8** [[BPADDR3]]
+// CHECK-DAG:   store i8* [[P3:%[^,]+]], i8** [[PADDR3]]
+// CHECK-DAG:   [[BP3]] = bitcast [10 x i32]* %{{.+}} to i8*
+// CHECK-DAG:   [[P3]] = bitcast [10 x i32]* %{{.+}} to i8*
+
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+// CHECK-NEXT:  br label %[[IFEND:.+]]
+
+// CHECK:       [[IFELSE]]
+// CHECK:       store i32 -1, i32* [[RHV]], align 4
+// CHECK-NEXT:  br label %[[IFEND:.+]]
+
+// CHECK:       [[IFEND]]
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT:  br label %[[END]]
+// CHECK:       [[END]]
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
+// CHECK:       br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK:       [[IFTHEN]]
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* [[MAPT5]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG:   [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG:   store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
+// CHECK-DAG:   store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
+// CHECK-DAG:   [[BP0]] = inttoptr i[[SZ]] [[VAL0:%.+]] to i8*
+// CHECK-DAG:   [[P0]] = inttoptr i[[SZ]] [[VAL0]] to i8*
+
+// CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG:   store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]]
+// CHECK-DAG:   store i8* [[P1:%[^,]+]], i8** [[PADDR1]]
+// CHECK-DAG:   [[BP1]] = inttoptr i[[SZ]] [[VAL1:%.+]] to i8*
+// CHECK-DAG:   [[P1]] = inttoptr i[[SZ]] [[VAL1]] to i8*
+
+// CHECK-DAG:   [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG:   [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG:   store i8* [[BP2:%[^,]+]], i8** [[BPADDR2]]
+// CHECK-DAG:   store i8* [[P2:%[^,]+]], i8** [[PADDR2]]
+// CHECK-DAG:   [[BP2]] = bitcast [10 x i32]* %{{.+}} to i8*
+// CHECK-DAG:   [[P2]] = bitcast [10 x i32]* %{{.+}} to i8*
+
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+// CHECK-NEXT:  br label %[[IFEND:.+]]
+
+// CHECK:       [[IFELSE]]
+// CHECK:       store i32 -1, i32* [[RHV]], align 4
+// CHECK-NEXT:  br label %[[IFEND:.+]]
+
+// CHECK:       [[IFEND]]
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT:  br label %[[END]]
+// CHECK:       [[END]]
+
+
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions of the callees of bar().
+
+// CHECK:       define internal void [[HVT7]]
+// Create local storage for each capture.
+// CHECK:       [[LOCAL_THIS:%.+]] = alloca [[S1]]*
+// CHECK:       [[LOCAL_B:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_C:%.+]] = alloca i16*
+// CHECK:       [[LOCAL_B_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG:   store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG:   store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
+// Store captures in the context.
+// CHECK-DAG:   [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
+// CHECK-64-DAG:[[CONV_BP:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
+// CHECK-DAG:   [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG:   [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG:   [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
+
+// CHECK-64-DAG:[[CONV_B:%.+]] = load i32, i32* [[CONV_BP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_B_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_B]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_BV:%.+]] = load i32, i32* [[LOCAL_B]]
+// CHECK-32-DAG:store i32 [[LOCAL_BV]], i32* [[LOCAL_B_CASTED]], align
+// CHECK-DAG:   [[REF_B:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_B_CASTED]],
+
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]], i[[SZ]], i[[SZ]], i16*)* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), [[S1]]* [[REF_THIS]], i[[SZ]] [[REF_B]], i[[SZ]] [[VAL_VLA1]], i[[SZ]] [[VAL_VLA2]], i16* [[REF_C]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* %{{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+
+// CHECK:       define internal void [[HVT6]]
+// Create local storage for each capture.
+// CHECK:       [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK:       [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AAA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
+// CHECK-DAG:   store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG:   [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG:   [[CONV_AAAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
+// CHECK-DAG:   [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG:   [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG:   [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG:   [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG:   store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG:   [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK-DAG:   [[CONV_AAA:%.+]] = load i8, i8* [[CONV_AAAP]]
+// CHECK-DAG:   [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA_CASTED]] to i8*
+// CHECK-DAG:   store i8 [[CONV_AAA]], i8* [[CONV]], align
+// CHECK-DAG:   [[REF_AAA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AAA_CASTED]],
+
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED6:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], i[[SZ]] [[REF_AAA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED6]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+// CHECK:       define internal void [[HVT5]]
+// Create local storage for each capture.
+// CHECK:       [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK:       [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG:   store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG:   [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG:   [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG:   [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG:   [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG:   [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG:   store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG:   [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED7:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED7]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+#endif
diff --git a/test/OpenMP/target_parallel_codegen_registration.cpp b/test/OpenMP/target_parallel_codegen_registration.cpp
new file mode 100644
index 0000000..6ba137f
--- /dev/null
+++ b/test/OpenMP/target_parallel_codegen_registration.cpp
@@ -0,0 +1,437 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target parallel codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// Check that no target code is emmitted if no omptests flag was provided.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NTARGET
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK:    [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+
+// CHECK-DAG: [[A1:@.+]] = internal global [[SA]]
+// CHECK-DAG: [[A2:@.+]] = global [[SA]]
+// CHECK-DAG: [[B1:@.+]] = global [[SB]]
+// CHECK-DAG: [[B2:@.+]] = global [[SB]]
+// CHECK-DAG: [[C1:@.+]] = internal global [[SC]]
+// CHECK-DAG: [[D1:@.+]] = global [[SD]]
+// CHECK-DAG: [[E1:@.+]] = global [[SE]]
+// CHECK-DAG: [[T1:@.+]] = global [[ST1]]
+// CHECK-DAG: [[T2:@.+]] = global [[ST2]]
+
+// CHECK-NTARGET-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-NTARGET-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-NTARGET-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-NTARGET-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-NTARGET-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-NTARGET-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-NTARGET-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-NTARGET-NOT: type { i8*, i8*, %
+// CHECK-NTARGET-NOT: type { i32, %
+
+// We have 7 target regions
+
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// TCHECK-NOT: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+
+// CHECK-NTARGET-NOT: private constant i8 0
+// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
+
+// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// CHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// CHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// CHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// CHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// CHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// CHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// CHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// CHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// CHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// TCHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// TCHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// TCHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// TCHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// TCHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// TCHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// TCHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// TCHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// TCHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// TCHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }]
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }
+
+// We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function.
+// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [
+// CHECK-SAME: { i32, void ()*, i8* } { i32 500, void ()* [[P500:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 501, void ()* [[P501:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 65535, void ()* [[PMAX:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* [[REGFN:@.+]] to void ()*), i8* null }]
+
+// CHECK-NTARGET: @llvm.global_ctors = appending global [3   x { i32, void ()*, i8* }] [
+
+extern int *R;
+
+struct SA {
+  int arr[4];
+  void foo() {
+    int a = *R;
+    a += 1;
+    *R = a;
+  }
+  SA() {
+    int a = *R;
+    a += 2;
+    *R = a;
+  }
+  ~SA() {
+    int a = *R;
+    a += 3;
+    *R = a;
+  }
+};
+
+struct SB {
+  int arr[8];
+  void foo() {
+    int a = *R;
+    #pragma omp target parallel
+    a += 4;
+    *R = a;
+  }
+  SB() {
+    int a = *R;
+    a += 5;
+    *R = a;
+  }
+  ~SB() {
+    int a = *R;
+    a += 6;
+    *R = a;
+  }
+};
+
+struct SC {
+  int arr[16];
+  void foo() {
+    int a = *R;
+    a += 7;
+    *R = a;
+  }
+  SC() {
+    int a = *R;
+    #pragma omp target parallel
+    a += 8;
+    *R = a;
+  }
+  ~SC() {
+    int a = *R;
+    a += 9;
+    *R = a;
+  }
+};
+
+struct SD {
+  int arr[32];
+  void foo() {
+    int a = *R;
+    a += 10;
+    *R = a;
+  }
+  SD() {
+    int a = *R;
+    a += 11;
+    *R = a;
+  }
+  ~SD() {
+    int a = *R;
+    #pragma omp target parallel
+    a += 12;
+    *R = a;
+  }
+};
+
+struct SE {
+  int arr[64];
+  void foo() {
+    int a = *R;
+    #pragma omp target parallel if(target: 0)
+    a += 13;
+    *R = a;
+  }
+  SE() {
+    int a = *R;
+    #pragma omp target parallel
+    a += 14;
+    *R = a;
+  }
+  ~SE() {
+    int a = *R;
+    #pragma omp target parallel
+    a += 15;
+    *R = a;
+  }
+};
+
+template <int x>
+struct ST {
+  int arr[128 + x];
+  void foo() {
+    int a = *R;
+    #pragma omp target parallel
+    a += 16 + x;
+    *R = a;
+  }
+  ST() {
+    int a = *R;
+    #pragma omp target parallel
+    a += 17 + x;
+    *R = a;
+  }
+  ~ST() {
+    int a = *R;
+    #pragma omp target parallel
+    a += 18 + x;
+    *R = a;
+  }
+};
+
+// We have to make sure we us all the target regions:
+//CHECK-DAG: define internal void @[[NAME1]](
+//CHECK-DAG: call void @[[NAME1]](
+//CHECK-DAG: define internal void @[[NAME2]](
+//CHECK-DAG: call void @[[NAME2]](
+//CHECK-DAG: define internal void @[[NAME3]](
+//CHECK-DAG: call void @[[NAME3]](
+//CHECK-DAG: define internal void @[[NAME4]](
+//CHECK-DAG: call void @[[NAME4]](
+//CHECK-DAG: define internal void @[[NAME5]](
+//CHECK-DAG: call void @[[NAME5]](
+//CHECK-DAG: define internal void @[[NAME6]](
+//CHECK-DAG: call void @[[NAME6]](
+//CHECK-DAG: define internal void @[[NAME7]](
+//CHECK-DAG: call void @[[NAME7]](
+//CHECK-DAG: define internal void @[[NAME8]](
+//CHECK-DAG: call void @[[NAME8]](
+//CHECK-DAG: define internal void @[[NAME9]](
+//CHECK-DAG: call void @[[NAME9]](
+//CHECK-DAG: define internal void @[[NAME10]](
+//CHECK-DAG: call void @[[NAME10]](
+//CHECK-DAG: define internal void @[[NAME11]](
+//CHECK-DAG: call void @[[NAME11]](
+//CHECK-DAG: define internal void @[[NAME12]](
+//CHECK-DAG: call void @[[NAME12]](
+
+//TCHECK-DAG: define void @[[NAME1]](
+//TCHECK-DAG: define void @[[NAME2]](
+//TCHECK-DAG: define void @[[NAME3]](
+//TCHECK-DAG: define void @[[NAME4]](
+//TCHECK-DAG: define void @[[NAME5]](
+//TCHECK-DAG: define void @[[NAME6]](
+//TCHECK-DAG: define void @[[NAME7]](
+//TCHECK-DAG: define void @[[NAME8]](
+//TCHECK-DAG: define void @[[NAME9]](
+//TCHECK-DAG: define void @[[NAME10]](
+//TCHECK-DAG: define void @[[NAME11]](
+//TCHECK-DAG: define void @[[NAME12]](
+
+// CHECK-NTARGET-NOT: __tgt_target
+// CHECK-NTARGET-NOT: __tgt_register_lib
+// CHECK-NTARGET-NOT: __tgt_unregister_lib
+
+// TCHECK-NOT: __tgt_target
+// TCHECK-NOT: __tgt_register_lib
+// TCHECK-NOT: __tgt_unregister_lib
+
+// We have 2 initializers with priority 500
+//CHECK: define internal void [[P500]](
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK:     ret void
+
+// We have 1 initializers with priority 501
+//CHECK: define internal void [[P501]](
+//CHECK:     call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK:     ret void
+
+// We have 6 initializers with default priority
+//CHECK: define internal void [[PMAX]](
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK:     ret void
+
+// Check registration and unregistration
+
+//CHECK:     define internal void [[UNREGFN:@.+]](i8*)
+//CHECK:     call i32 @__tgt_unregister_lib([[DSCTY]]* [[DESC]])
+//CHECK:     ret void
+//CHECK:     declare i32 @__tgt_unregister_lib([[DSCTY]]*)
+
+//CHECK:     define internal void [[REGFN]](i8*)
+//CHECK:     call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]])
+//CHECK:     call i32 @__cxa_atexit(void (i8*)* [[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*),
+//CHECK:     ret void
+//CHECK:     declare i32 @__tgt_register_lib([[DSCTY]]*)
+
+static __attribute__((init_priority(500))) SA a1;
+SA a2;
+SB __attribute__((init_priority(500))) b1;
+SB __attribute__((init_priority(501))) b2;
+static SC c1;
+SD d1;
+SE e1;
+ST<100> t1;
+ST<1000> t2;
+
+
+int bar(int a){
+  int r = a;
+
+  a1.foo();
+  a2.foo();
+  b1.foo();
+  b2.foo();
+  c1.foo();
+  d1.foo();
+  e1.foo();
+  t1.foo();
+  t2.foo();
+
+  #pragma omp target parallel
+  ++r;
+
+  return r + *R;
+}
+
+// Check metadata is properly generated:
+// CHECK:     !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 {{[0-9]+}}}
+
+// TCHECK:     !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 {{[0-9]+}}}
+
+#endif
diff --git a/test/OpenMP/target_parallel_codegen_registration_naming.cpp b/test/OpenMP/target_parallel_codegen_registration_naming.cpp
new file mode 100644
index 0000000..4b79402
--- /dev/null
+++ b/test/OpenMP/target_parallel_codegen_registration_naming.cpp
@@ -0,0 +1,66 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target parallel codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[CA:%.+]] = type { i32* }
+
+// CHECK: define {{.*}}i32 @[[NNAME:.+]](i32 {{.*}}%{{.+}})
+int nested(int a){
+  // CHECK: call void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME]]_l[[T1L:[0-9]+]](
+  #pragma omp target parallel
+    ++a;
+
+  // CHECK: call void @"[[LNAME:.+]]"([[CA]]*
+  auto F = [&](){
+    #pragma omp parallel
+    {
+      #pragma omp target parallel
+      ++a;
+    }
+  };
+
+  F();
+
+  return a;
+}
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T1L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME:.+]]_l[[T1L:[0-9]+]](
+
+// CHECK: define {{.*}}void @"[[LNAME]]"(
+// CHECK: call void {{.*}}@__kmpc_fork_call{{.+}}[[PNAME:@.+]] to
+
+// CHECK: define {{.*}}void [[PNAME]](
+// CHECK: call void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L:[0-9]+]](
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME:.+]]_l[[T2L:[0-9]+]](
+
+
+// Check metadata is properly generated:
+// CHECK:     !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+
+// TCHECK:     !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+#endif
diff --git a/test/OpenMP/target_parallel_default_messages.cpp b/test/OpenMP/target_parallel_default_messages.cpp
index 40f31b8..cf49793 100644
--- a/test/OpenMP/target_parallel_default_messages.cpp
+++ b/test/OpenMP/target_parallel_default_messages.cpp
@@ -23,5 +23,8 @@
   foo();
   #pragma omp target parallel default(shared)
   ++argc;
+  #pragma omp target parallel default(none)
+  #pragma omp parallel default(shared)
+  ++argc;
   return 0;
 }
diff --git a/test/OpenMP/target_parallel_for_ast_print.cpp b/test/OpenMP/target_parallel_for_ast_print.cpp
index b63f3bf..d5aa055 100644
--- a/test/OpenMP/target_parallel_for_ast_print.cpp
+++ b/test/OpenMP/target_parallel_for_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/target_parallel_for_collapse_messages.cpp b/test/OpenMP/target_parallel_for_collapse_messages.cpp
index 8cf502b..6163b52 100644
--- a/test/OpenMP/target_parallel_for_collapse_messages.cpp
+++ b/test/OpenMP/target_parallel_for_collapse_messages.cpp
@@ -1,9 +1,14 @@
 // RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
 
 void foo() {
 }
 
 bool foobool(int argc) {
+#if __cplusplus >= 201103L
+// expected-note@-2 4 {{declared here}}
+#endif
   return argc;
 }
 
@@ -33,10 +38,17 @@
   // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
   // expected-error@+1 2 {{expression is not an integral constant expression}}
   #pragma omp target parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
+#if __cplusplus >= 201103L
+// expected-note@-2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   #pragma omp target 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}}
+#if __cplusplus >= 201103L
+  // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#else
+  // expected-error@+2 2 {{expression is not an integral constant expression}}
+#endif
   #pragma omp target 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 target parallel for collapse (1)
@@ -60,15 +72,25 @@
   #pragma omp target parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target 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 target parallel for', but found only 1}}
   #pragma omp target parallel for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@-2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
   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 target parallel for' cannot contain more than one 'collapse' clause}}
   // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
   #pragma omp target parallel for collapse (foobool(argc)), collapse (true), collapse (-5) 
+#if __cplusplus >= 201103L
+// expected-note@-2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   #pragma omp target 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}}
+#if __cplusplus >= 201103L
+  // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#else
+  // expected-error@+2 {{expression is not an integral constant expression}}
+#endif
   #pragma omp target 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 target parallel for' must be a for loop}}
diff --git a/test/OpenMP/target_parallel_for_if_messages.cpp b/test/OpenMP/target_parallel_for_if_messages.cpp
index 01173c1..4acf4b8 100644
--- a/test/OpenMP/target_parallel_for_if_messages.cpp
+++ b/test/OpenMP/target_parallel_for_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 %s
 
 void foo() {
 }
diff --git a/test/OpenMP/target_parallel_for_is_device_ptr_ast_print.cpp b/test/OpenMP/target_parallel_for_is_device_ptr_ast_print.cpp
new file mode 100644
index 0000000..eaa0941
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_is_device_ptr_ast_print.cpp
@@ -0,0 +1,315 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int da[5] = { 0 };
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target parallel for is_device_ptr(k)
+    for (int i=0; i<100; i++) foo();
+
+#pragma omp target parallel for is_device_ptr(z)
+    for (int i=0; i<100; i++) foo();
+
+#pragma omp target parallel for is_device_ptr(aa) // OK
+    for (int i=0; i<100; i++) foo();
+
+#pragma omp target parallel for is_device_ptr(raa) // OK
+    for (int i=0; i<100; i++) foo();
+
+#pragma omp target parallel for is_device_ptr(g) // OK
+    for (int i=0; i<100; i++) foo();
+
+#pragma omp target parallel for is_device_ptr(rg) // OK
+    for (int i=0; i<100; i++) foo();
+
+#pragma omp target parallel for is_device_ptr(da) // OK
+    for (int i=0; i<100; i++) foo();
+
+    return;
+  }
+};
+// CHECK: struct SA
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: ST g[10];
+// CHECK-NEXT: STarr &rg = this->g;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = this->i;
+// CHECK-NEXT: int *k = &this->j;
+// CHECK-NEXT: int *&z = this->k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: arr &raa = this->aa;
+// CHECK-NEXT: func(
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(this->k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(this->z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(this->aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(this->raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(this->g)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(this->rg)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(this->da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T>
+T tmain(T argc) {
+  const T da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+#pragma omp target parallel for is_device_ptr(k)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target parallel for is_device_ptr(z)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target parallel for is_device_ptr(aa)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target parallel for is_device_ptr(raa)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target parallel for is_device_ptr(h)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target parallel for is_device_ptr(rh)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target parallel for is_device_ptr(da)
+  for (int i=0; i<100; i++) foo();
+  return 0;
+}
+
+// CHECK: template<> int tmain<int>(int argc) {
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+
+// CHECK: template<> int *tmain<int *>(int *argc) {
+// CHECK-NEXT: int *const da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int *i;
+// CHECK-NEXT: int *&j = i;
+// CHECK-NEXT: int **k = &j;
+// CHECK-NEXT: int **&z = k;
+// CHECK-NEXT: int *aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main(int argc, char **argv) {
+  const int da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+#pragma omp target parallel for is_device_ptr(k)
+  for (int i=0; i<100; i++) foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel for is_device_ptr(z)
+  for (int i=0; i<100; i++) foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel for is_device_ptr(aa)
+  for (int i=0; i<100; i++) foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel for is_device_ptr(raa)
+  for (int i=0; i<100; i++) foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel for is_device_ptr(h)
+  for (int i=0; i<100; i++) foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel for is_device_ptr(rh)
+  for (int i=0; i<100; i++) foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel for is_device_ptr(da)
+  for (int i=0; i<100; i++) foo();
+// CHECK-NEXT: #pragma omp target parallel for is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: foo();
+  return tmain<int>(argc) + *tmain<int *>(&argc);
+}
+
+
+#endif
diff --git a/test/OpenMP/target_parallel_for_is_device_ptr_messages.cpp b/test/OpenMP/target_parallel_for_is_device_ptr_messages.cpp
new file mode 100644
index 0000000..b3b33bf
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_is_device_ptr_messages.cpp
@@ -0,0 +1,311 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fopenmp %s
+
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+typedef struct {
+  int a;
+} S;
+struct SA {
+  const int d = 5;
+  const int da[5] = { 0 };
+  ST e;
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  S *ps;
+  void func(int arg) {
+#pragma omp target parallel for is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr() // expected-error {{expected expression}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(k) // OK
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(z) // OK
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(aa) // OK
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(raa) // OK
+    for (int ii=0; ii<10; ii++)
+      ;   
+#pragma omp target parallel for is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(g) // OK
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(rg) // OK
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(da) // OK
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for' directive}} expected-note{{defined as firstprivate}}
+    for (int ii=0; ii<10; ii++)
+      ;
+#pragma omp target parallel for private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for' directive}} expected-note{{defined as private}}
+    for (int ii=0; ii<10; ii++)
+      ;
+
+  return;
+ }
+};
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T, int I>
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+#pragma omp target parallel for is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr() // expected-error {{expected expression}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(k) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(z) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(aa) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(raa) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(h) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(rh) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(da) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+#pragma omp target parallel for is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr() // expected-error {{expected expression}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(k) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(z) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(aa) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(raa) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(h) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(rh) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int kk=0; kk<20; kk++)
+    ;
+#pragma omp target parallel for is_device_ptr(da) // OK
+  for (int kk=0; kk<20; kk++)
+    ;
+  return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_for_ordered_messages.cpp b/test/OpenMP/target_parallel_for_ordered_messages.cpp
index 36eb837..72bb6e3 100644
--- a/test/OpenMP/target_parallel_for_ordered_messages.cpp
+++ b/test/OpenMP/target_parallel_for_ordered_messages.cpp
@@ -1,9 +1,14 @@
 // RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
 
 void foo() {
 }
 
 bool foobool(int argc) {
+#if __cplusplus >= 201103L
+// expected-note@-2 4 {{declared here}}
+#endif
   return argc;
 }
 
@@ -36,6 +41,9 @@
 #pragma omp target parallel for ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' 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 target parallel for', but found only 1}}
+#if __cplusplus >= 201103L
+// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
 // expected-error@+3 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}}
 // expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
 // expected-error@+1 2 {{expression is not an integral constant expression}}
@@ -45,7 +53,11 @@
 #pragma omp target parallel for ordered(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}}
+#if __cplusplus >= 201103L
+  // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#else
+  // expected-error@+2 2 {{expression is not an integral constant expression}}
+#endif
 #pragma omp target parallel for ordered(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];
@@ -76,9 +88,15 @@
 #pragma omp target parallel for ordered(2 + 2))      // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}  expected-note {{as specified in 'ordered' 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 target parallel for', but found only 1}}
+#if __cplusplus >= 201103L
+// expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
 #pragma omp target parallel for ordered(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];
+#if __cplusplus >= 201103L
+// expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
 // expected-error@+3 {{expression is not an integral constant expression}}
 // expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}}
 // expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
@@ -88,7 +106,11 @@
 #pragma omp target parallel for ordered(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}}
+#if __cplusplus >= 201103L
+  // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#else
+  // expected-error@+2 {{expression is not an integral constant expression}}
+#endif
 #pragma omp target parallel for ordered(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];
diff --git a/test/OpenMP/target_parallel_for_simd_ast_print.cpp b/test/OpenMP/target_parallel_for_simd_ast_print.cpp
index 1765152..82d72c3 100644
--- a/test/OpenMP/target_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/target_parallel_for_simd_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/target_parallel_for_simd_if_messages.cpp b/test/OpenMP/target_parallel_for_simd_if_messages.cpp
index b9e2891..640e24c 100644
--- a/test/OpenMP/target_parallel_for_simd_if_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 %s
 
 void foo() {
 }
diff --git a/test/OpenMP/target_parallel_for_simd_is_device_ptr_ast_print.cpp b/test/OpenMP/target_parallel_for_simd_is_device_ptr_ast_print.cpp
new file mode 100644
index 0000000..af98f99
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_is_device_ptr_ast_print.cpp
@@ -0,0 +1,318 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int da[5] = { 0 };
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target parallel for simd is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(g) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(rg) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+  return;
+ }
+};
+// CHECK: struct SA
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: ST g[10];
+// CHECK-NEXT: STarr &rg = this->g;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = this->i;
+// CHECK-NEXT: int *k = &this->j;
+// CHECK-NEXT: int *&z = this->k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: arr &raa = this->aa;
+// CHECK-NEXT: func(
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(this->k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(this->z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(this->aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(this->raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(this->g)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(this->rg)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(this->da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T>
+T tmain(T argc) {
+  const T da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+#pragma omp target parallel for simd is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(aa)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(raa)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(h)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(rh)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(da)
+  for (int i=0; i<100; i++)
+    ;
+  return 0;
+}
+
+// CHECK: template<> int tmain<int>(int argc) {
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+// CHECK: template<> int *tmain<int *>(int *argc) {
+// CHECK-NEXT: int *const da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int *i;
+// CHECK-NEXT: int *&j = i;
+// CHECK-NEXT: int **k = &j;
+// CHECK-NEXT: int **&z = k;
+// CHECK-NEXT: int *aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main(int argc, char **argv) {
+  const int da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+#pragma omp target parallel for simd is_device_ptr(k)
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target parallel for simd is_device_ptr(z)
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target parallel for simd is_device_ptr(aa)
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(aa)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target parallel for simd is_device_ptr(raa)
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(raa)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target parallel for simd is_device_ptr(h)
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(h)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target parallel for simd is_device_ptr(rh)
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(rh)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target parallel for simd is_device_ptr(da)
+// CHECK-NEXT: #pragma omp target parallel for simd is_device_ptr(da)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+  return tmain<int>(argc) + *tmain<int *>(&argc);
+}
+#endif
diff --git a/test/OpenMP/target_parallel_for_simd_is_device_ptr_messages.cpp b/test/OpenMP/target_parallel_for_simd_is_device_ptr_messages.cpp
new file mode 100644
index 0000000..435b9a9
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_is_device_ptr_messages.cpp
@@ -0,0 +1,337 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fopenmp %s
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int d = 5;
+  const int da[5] = { 0 };
+  ST e;
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target parallel for simd is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(g) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(rg) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+  return;
+ }
+};
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T, int I>
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target parallel for simd is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(h) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(rh) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} expected-note{{defined as firstprivate}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} expected-note{{defined as private}}
+  for (int i=0; i<100; i++)
+    ;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target parallel for simd is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(h) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(rh) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} expected-note{{defined as firstprivate}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target parallel for simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} expected-note{{defined as private}}
+  for (int i=0; i<100; i++)
+    ;
+  return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_if_codegen.cpp b/test/OpenMP/target_parallel_if_codegen.cpp
new file mode 100644
index 0000000..02c69b9
--- /dev/null
+++ b/test/OpenMP/target_parallel_if_codegen.cpp
@@ -0,0 +1,413 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// We have 6 target regions
+
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }]
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* [[REGFN:@.+]] to void ()*), i8* null }]
+
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+
+  #pragma omp target parallel if(parallel: 0)
+  {
+    a += 1;
+  }
+
+  short b = 1;
+  #pragma omp target parallel if(parallel: 1)
+  {
+    a += b;
+  }
+
+  return a;
+}
+
+static
+int fstatic(int n) {
+
+  #pragma omp target parallel if(n>1)
+  {
+  }
+
+  #pragma omp target parallel if(target: n-2>2)
+  {
+  }
+
+  return n+1;
+}
+
+struct S1 {
+  double a;
+
+  int r1(int n){
+    int b = 1;
+
+    #pragma omp target parallel if(parallel: n>3)
+    {
+      this->a = (double)b + 1.5;
+    }
+
+    #pragma omp target parallel if(target: n>4) if(parallel: n>5)
+    {
+      this->a = 2.5;
+    }
+
+    return (int)a;
+  }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+  int a = 0;
+
+  S1 S;
+  // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+  a += S.r1(n);
+
+  // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+  a += fstatic(n);
+
+  // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+
+
+//
+// CHECK: define {{.*}}[[FS1]]([[S1]]* {{%.+}}, i32 {{[^%]*}}[[PARM:%.+]])
+//
+// CHECK-DAG:   store i32 [[PARM]], i32* [[N_ADDR:%.+]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[CMP:%.+]] = icmp sgt i32 [[NV]], 3
+// CHECK:       [[FB:%.+]] = zext i1 [[CMP]] to i8
+// CHECK:       store i8 [[FB]], i8* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CAPE:%.+]] = load i8, i8* [[CAPE_ADDR]], align
+// CHECK:       [[TB:%.+]] = trunc i8 [[CAPE]] to i1
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i8*
+// CHECK:       [[FB:%.+]] = zext i1 [[TB]] to i8
+// CHECK:       store i8 [[FB]], i8* [[CONV]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 0)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT1:@.+]]([[S1]]* {{%.+}}, i[[SZ]] {{%.+}}, i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[CMP:%.+]] = icmp sgt i32 [[NV]], 5
+// CHECK:       [[FB:%.+]] = zext i1 [[CMP]] to i8
+// CHECK:       store i8 [[FB]], i8* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CAPE:%.+]] = load i8, i8* [[CAPE_ADDR]], align
+// CHECK:       [[TB:%.+]] = trunc i8 [[CAPE]] to i1
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i8*
+// CHECK:       [[FB:%.+]] = zext i1 [[TB]] to i8
+// CHECK:       store i8 [[FB]], i8* [[CONV]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[CMP:%.+]] = icmp sgt i32 [[NV]], 4
+// CHECK:       br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
+//
+// CHECK:       [[IF_THEN]]
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 1, i32 0)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       br label {{%?}}[[END:.+]]
+//
+// CHECK:       [[IF_ELSE]]
+// CHECK:       store i32 -1, i32* [[RHV]], align
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT2:@.+]]([[S1]]* {{%.+}}, i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+
+
+
+
+
+
+//
+// CHECK: define {{.*}}[[FSTATIC]](i32 {{[^%]*}}[[PARM:%.+]])
+//
+// CHECK-DAG:   store i32 [[PARM]], i32* [[N_ADDR:%.+]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[CMP:%.+]] = icmp sgt i32 [[NV]], 1
+// CHECK:       [[FB:%.+]] = zext i1 [[CMP]] to i8
+// CHECK:       store i8 [[FB]], i8* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CAPE:%.+]] = load i8, i8* [[CAPE_ADDR]], align
+// CHECK:       [[TB:%.+]] = trunc i8 [[CAPE]] to i1
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i8*
+// CHECK:       [[FB:%.+]] = zext i1 [[TB]] to i8
+// CHECK:       store i8 [[FB]], i8* [[CONV]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[CAPE2:%.+]] = load i8, i8* [[CAPE_ADDR]], align
+// CHECK:       [[TB:%.+]] = trunc i8 [[CAPE2]] to i1
+// CHECK:       br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
+//
+// CHECK:       [[IF_THEN]]
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       br label {{%?}}[[END:.+]]
+//
+// CHECK:       [[IF_ELSE]]
+// CHECK:       store i32 -1, i32* [[RHV]], align
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT3:@.+]](i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK-DAG:   [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[SUB:%.+]] = sub nsw i32 [[NV]], 2
+// CHECK:       [[CMP:%.+]] = icmp sgt i32 [[SUB]], 2
+// CHECK:       br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
+//
+// CHECK:       [[IF_THEN]]
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 1, i32 0)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       br label {{%?}}[[END:.+]]
+//
+// CHECK:       [[IF_ELSE]]
+// CHECK:       store i32 -1, i32* [[RHV]], align
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT4:@.+]]()
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+
+
+
+
+
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0)
+// CHECK-NEXT:  store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK-NEXT:  [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT5:@.+]]({{[^,]+}})
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 1, i32 0)
+// CHECK-NEXT:  store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK-NEXT:  [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}})
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+
+
+
+
+
+
+// Check that the offloading functions are emitted and that the parallel function
+// is appropriately guarded.
+
+// CHECK:       define internal void [[HVT1]]([[S1]]* {{%.+}}, i[[SZ]] [[PARM1:%.+]], i[[SZ]] [[PARM2:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM1]], i[[SZ]]* [[B_ADDR:%.+]], align
+// CHECK-DAG:   store i[[SZ]] [[PARM2]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK-64:    [[CONVB:%.+]] = bitcast i[[SZ]]* [[B_ADDR]] to i32*
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i8*
+// CHECK-64:    [[BV:%.+]] = load i32, i32* [[CONVB]], align
+// CHECK-32:    [[BV:%.+]] = load i32, i32* [[B_ADDR]], align
+// CHECK-64:    [[BC:%.+]] = bitcast i64* [[ARGA:%.+]] to i32*
+// CHECK-64:    store i32 [[BV]], i32* [[BC]], align
+// CHECK-64:    [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[ARGA]], align
+// CHECK-32:    store i32 [[BV]], i32* [[ARGA:%.+]], align
+// CHECK-32:    [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[ARGA]], align
+// CHECK:       [[IFC:%.+]] = load i8, i8* [[CONV]], align
+// CHECK:       [[TB:%.+]] = trunc i8 [[IFC]] to i1
+// CHECK:       br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
+//
+// CHECK:       [[IF_THEN]]
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]])* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), [[S1]]* {{.+}}, i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END:.+]]
+//
+// CHECK:       [[IF_ELSE]]
+// CHECK:       call void @__kmpc_serialized_parallel(
+// CHECK:       call void [[OMP_OUTLINED3]](i32* {{%.+}}, i32* {{%.+}}, [[S1]]* {{.+}}, i[[SZ]] [[ARG]])
+// CHECK:       call void @__kmpc_end_serialized_parallel(
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+//
+//
+
+
+// CHECK:       define internal void [[HVT2]]([[S1]]* {{%.+}}, i[[SZ]] [[PARM:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i8*
+// CHECK:       [[IFC:%.+]] = load i8, i8* [[CONV]], align
+// CHECK:       [[TB:%.+]] = trunc i8 [[IFC]] to i1
+// CHECK:       br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
+//
+// CHECK:       [[IF_THEN]]
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*)* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), [[S1]]* {{.+}})
+// CHECK:       br label {{%?}}[[END:.+]]
+//
+// CHECK:       [[IF_ELSE]]
+// CHECK:       call void @__kmpc_serialized_parallel(
+// CHECK:       call void [[OMP_OUTLINED4]](i32* {{%.+}}, i32* {{%.+}}, [[S1]]* {{.+}})
+// CHECK:       call void @__kmpc_end_serialized_parallel(
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+//
+//
+
+
+
+
+
+
+
+
+// CHECK:       define internal void [[HVT3]](i[[SZ]] [[PARM:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i8*
+// CHECK:       [[IFC:%.+]] = load i8, i8* [[CONV]], align
+// CHECK:       [[TB:%.+]] = trunc i8 [[IFC]] to i1
+// CHECK:       br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
+//
+// CHECK:       [[IF_THEN]]
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*))
+// CHECK:       br label {{%?}}[[END:.+]]
+//
+// CHECK:       [[IF_ELSE]]
+// CHECK:       call void @__kmpc_serialized_parallel(
+// CHECK:       call void [[OMP_OUTLINED1]](i32* {{%.+}}, i32* {{%.+}})
+// CHECK:       call void @__kmpc_end_serialized_parallel(
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+//
+//
+// CHECK:       define internal void [[HVT4]]()
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*))
+// CHECK-NEXT:  ret
+//
+//
+
+
+
+
+
+// CHECK:       define internal void [[HVT5]](
+// CHECK-NOT:   @__kmpc_fork_call
+// CHECK:       call void @__kmpc_serialized_parallel(
+// CHECK:       call void [[OMP_OUTLINED5:@.+]](i32* {{%.+}}, i32* {{%.+}}, i[[SZ]] {{.+}})
+// CHECK:       call void @__kmpc_end_serialized_parallel(
+// CHECK:       ret
+//
+//
+
+
+// CHECK:       define internal void [[HVT6]](
+// CHECK-NOT:   call void @__kmpc_serialized_parallel(
+// CHECK-NOT:   call void [[OMP_OUTLINED5:@.+]](i32* {{%.+}}, i32* {{%.+}}, i[[SZ]] {{.+}})
+// CHECK-NOT:   call void @__kmpc_end_serialized_parallel(
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]])* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*),
+// CHECK:       ret
+//
+//
+
+
+
+#endif
diff --git a/test/OpenMP/target_parallel_if_messages.cpp b/test/OpenMP/target_parallel_if_messages.cpp
index e22eb81..06b7a59 100644
--- a/test/OpenMP/target_parallel_if_messages.cpp
+++ b/test/OpenMP/target_parallel_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 %s
 
 void foo() {
 }
diff --git a/test/OpenMP/target_parallel_is_device_ptr_ast_print.cpp b/test/OpenMP/target_parallel_is_device_ptr_ast_print.cpp
new file mode 100644
index 0000000..7fbddd8
--- /dev/null
+++ b/test/OpenMP/target_parallel_is_device_ptr_ast_print.cpp
@@ -0,0 +1,294 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int da[5] = { 0 };
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target parallel is_device_ptr(k)
+    {}
+#pragma omp target parallel is_device_ptr(z)
+    {}
+#pragma omp target parallel is_device_ptr(aa) // OK
+    {}
+#pragma omp target parallel is_device_ptr(raa) // OK
+    {}
+#pragma omp target parallel is_device_ptr(g) // OK
+    {}
+#pragma omp target parallel is_device_ptr(rg) // OK
+    {}
+#pragma omp target parallel is_device_ptr(da) // OK
+    {}
+  return;
+ }
+};
+// CHECK: struct SA
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: ST g[10];
+// CHECK-NEXT: STarr &rg = this->g;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = this->i;
+// CHECK-NEXT: int *k = &this->j;
+// CHECK-NEXT: int *&z = this->k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: arr &raa = this->aa;
+// CHECK-NEXT: func(
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(this->k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(this->z)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(this->aa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(this->raa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(this->g)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(this->rg)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(this->da)
+
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T>
+T tmain(T argc) {
+  const T da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+#pragma omp target parallel is_device_ptr(k)
+  {}
+#pragma omp target parallel is_device_ptr(z)
+  {}
+#pragma omp target parallel is_device_ptr(aa)
+  {}
+#pragma omp target parallel is_device_ptr(raa)
+  {}
+#pragma omp target parallel is_device_ptr(h)
+  {}
+#pragma omp target parallel is_device_ptr(rh)
+  {}
+#pragma omp target parallel is_device_ptr(da)
+  {}
+  return 0;
+}
+
+// CHECK: template<> int tmain<int>(int argc) {
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(z)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(aa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(raa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(h)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(rh)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(da)
+
+// CHECK: template<> int *tmain<int *>(int *argc) {
+// CHECK-NEXT: int *const da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int *i;
+// CHECK-NEXT: int *&j = i;
+// CHECK-NEXT: int **k = &j;
+// CHECK-NEXT: int **&z = k;
+// CHECK-NEXT: int *aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(z)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(aa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(raa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(h)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(rh)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(da)
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main(int argc, char **argv) {
+  const int da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+#pragma omp target parallel is_device_ptr(k)
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(k)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target parallel is_device_ptr(z)
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(z)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target parallel is_device_ptr(aa)
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(aa)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target parallel is_device_ptr(raa)
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(raa)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target parallel is_device_ptr(h)
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(h)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target parallel is_device_ptr(rh)
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(rh)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target parallel is_device_ptr(da)
+// CHECK-NEXT: #pragma omp target parallel is_device_ptr(da)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+  return tmain<int>(argc) + *tmain<int *>(&argc);
+}
+
+
+#endif
diff --git a/test/OpenMP/target_parallel_is_device_ptr_messages.cpp b/test/OpenMP/target_parallel_is_device_ptr_messages.cpp
new file mode 100644
index 0000000..d9c3ee9
--- /dev/null
+++ b/test/OpenMP/target_parallel_is_device_ptr_messages.cpp
@@ -0,0 +1,268 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -ferror-limit 200 %s
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int d = 5;
+  const int da[5] = { 0 };
+  ST e;
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target parallel is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+    {}
+#pragma omp target parallel is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+    {}
+#pragma omp target parallel is_device_ptr() // expected-error {{expected expression}}
+    {}
+#pragma omp target parallel is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+    {}
+#pragma omp target parallel is_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target parallel is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target parallel is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target parallel is_device_ptr(k) // OK
+    {}
+#pragma omp target parallel is_device_ptr(z) // OK
+    {}
+#pragma omp target parallel is_device_ptr(aa) // OK
+    {}
+#pragma omp target parallel is_device_ptr(raa) // OK
+    {}    
+#pragma omp target parallel is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target parallel is_device_ptr(g) // OK
+    {}
+#pragma omp target parallel is_device_ptr(rg) // OK
+    {}
+#pragma omp target parallel is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target parallel is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target parallel is_device_ptr(da) // OK
+    {}
+  return;
+ }
+};
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T, int I>
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target parallel is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  {}
+#pragma omp target parallel is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  {}
+#pragma omp target parallel is_device_ptr() // expected-error {{expected expression}}
+  {}
+#pragma omp target parallel is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  {}
+#pragma omp target parallel is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(k) // OK
+  {}
+#pragma omp target parallel is_device_ptr(z) // OK
+  {}
+#pragma omp target parallel is_device_ptr(aa) // OK
+  {}
+#pragma omp target parallel is_device_ptr(raa) // OK
+  {}
+#pragma omp target parallel is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(h) // OK
+  {}
+#pragma omp target parallel is_device_ptr(rh) // OK
+  {}
+#pragma omp target parallel is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(da) // OK
+  {}
+#pragma omp target parallel map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target parallel is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target parallel map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target parallel is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  {}
+#pragma omp target parallel is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}}
+  {}
+#pragma omp target parallel firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} expected-note{{defined as firstprivate}}
+  {}
+#pragma omp target parallel is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}}
+  {}
+#pragma omp target parallel private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} expected-note{{defined as private}}
+  {}
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target parallel is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  {}
+#pragma omp target parallel is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  {}
+#pragma omp target parallel is_device_ptr() // expected-error {{expected expression}}
+  {}
+#pragma omp target parallel is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  {}
+#pragma omp target parallel is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(k) // OK
+  {}
+#pragma omp target parallel is_device_ptr(z) // OK
+  {}
+#pragma omp target parallel is_device_ptr(aa) // OK
+  {}
+#pragma omp target parallel is_device_ptr(raa) // OK
+  {}
+#pragma omp target parallel is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(h) // OK
+  {}
+#pragma omp target parallel is_device_ptr(rh) // OK
+  {}
+#pragma omp target parallel is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target parallel is_device_ptr(da) // OK
+  {}
+#pragma omp target parallel map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target parallel is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target parallel map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target parallel is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  {}
+#pragma omp target parallel is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}}
+  {}
+#pragma omp target parallel firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} expected-note{{defined as firstprivate}}
+  {}
+#pragma omp target parallel is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}}
+  {}
+#pragma omp target parallel private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} expected-note{{defined as private}}
+  {}
+  return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_num_threads_codegen.cpp b/test/OpenMP/target_parallel_num_threads_codegen.cpp
new file mode 100644
index 0000000..de6a13d
--- /dev/null
+++ b/test/OpenMP/target_parallel_num_threads_codegen.cpp
@@ -0,0 +1,344 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// We have 6 target regions
+
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }]
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* [[REGFN:@.+]] to void ()*), i8* null }]
+
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+
+  #pragma omp target parallel num_threads(tx(20))
+  {
+  }
+
+  short b = 1;
+  #pragma omp target parallel num_threads(b)
+  {
+    a += b;
+  }
+
+  return a;
+}
+
+static
+int fstatic(int n) {
+
+  #pragma omp target parallel num_threads(n)
+  {
+  }
+
+  #pragma omp target parallel num_threads(32+n)
+  {
+  }
+
+  return n+1;
+}
+
+struct S1 {
+  double a;
+
+  int r1(int n){
+    int b = 1;
+
+    #pragma omp target parallel num_threads(n-b)
+    {
+      this->a = (double)b + 1.5;
+    }
+
+    #pragma omp target parallel num_threads(1024)
+    {
+      this->a = 2.5;
+    }
+
+    return (int)a;
+  }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+  int a = 0;
+
+  S1 S;
+  // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+  a += S.r1(n);
+
+  // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+  a += fstatic(n);
+
+  // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+
+
+//
+// CHECK: define {{.*}}[[FS1]]([[S1]]* {{%.+}}, i32 {{[^%]*}}[[PARM:%.+]])
+//
+// CHECK-DAG:   store i32 [[PARM]], i32* [[N_ADDR:%.+]], align
+// CHECK:       store i32 1, i32* [[B:%.+]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[BV:%.+]] = load i32, i32* [[B]], align
+// CHECK:       [[SUB:%.+]] = sub nsw i32 [[NV]], [[BV]]
+// CHECK:       store i32 [[SUB]], i32* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR:%.+]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[THREADS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 [[THREADS]])
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT1:@.+]]([[S1]]* {{%.+}}, i[[SZ]] {{%.+}}, i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.+}}, i32 1, i32 1024)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT2:@.+]]([[S1]]* {{[^,]+}})
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+
+
+
+
+
+
+//
+// CHECK: define {{.*}}[[FSTATIC]](i32 {{[^%]*}}[[PARM:%.+]])
+//
+// CHECK-DAG:   store i32 [[PARM]], i32* [[N_ADDR:%.+]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       store i32 [[NV]], i32* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR:%.+]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[THREADS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 [[THREADS]])
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT3:@.+]](i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[ADD:%.+]] = add nsw i32 32, [[NV]]
+// CHECK:       store i32 [[ADD]], i32* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR:%.+]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[THREADS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 [[THREADS]])
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT4:@.+]](i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+
+
+
+
+
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 1, i32 20)
+// CHECK-NEXT:  store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK-NEXT:  [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT5:@.+]]()
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK:       store i16 1, i16* [[B:%.+]], align
+// CHECK:       [[BV:%.+]] = load i16, i16* [[B]], align
+// CHECK:       store i16 [[BV]], i16* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i16, i16* [[CAPE_ADDR]], align
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i16*
+// CHECK:       store i16 [[CEV]], i16* [[CONV]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[T:%.+]] = load i16, i16* [[CAPE_ADDR]], align
+// CHECK:       [[THREADS:%.+]] = sext i16 [[T]] to i32
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 [[THREADS]])
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT6:@.+]](i[[SZ]] {{%.+}}, i[[SZ]] {{%.+}}, i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+
+
+
+
+
+
+// Check that the offloading functions are emitted and that the parallel function
+// is appropriately guarded.
+
+// CHECK:       define internal void [[HVT1]]([[S1]]* {{%.+}}, i[[SZ]] [[PARM1:%.+]], i[[SZ]] [[PARM2:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM2]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i32*
+// CHECK-64:    [[NT:%.+]] = load i32, i32* [[CONV]], align
+// CHECK-32:    [[NT:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK:       call void @__kmpc_push_num_threads(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]])
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2,
+//
+//
+
+
+// CHECK:       define internal void [[HVT2]]([[S1]]* {{%.+}})
+// CHECK:       call void @__kmpc_push_num_threads(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 1024)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 1,
+//
+//
+
+
+
+
+
+
+
+
+// CHECK:       define internal void [[HVT3]](i[[SZ]] [[PARM:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i32*
+// CHECK-64:    [[NT:%.+]] = load i32, i32* [[CONV]], align
+// CHECK-32:    [[NT:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK:       call void @__kmpc_push_num_threads(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]])
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0,
+//
+//
+// CHECK:       define internal void [[HVT4]](i[[SZ]] [[PARM:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i32*
+// CHECK-64:    [[NT:%.+]] = load i32, i32* [[CONV]], align
+// CHECK-32:    [[NT:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK:       call void @__kmpc_push_num_threads(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]])
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0,
+//
+//
+
+
+
+
+
+// CHECK:       define internal void [[HVT5]](
+// CHECK:       call void @__kmpc_push_num_threads(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 20)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0,
+//
+//
+
+
+// CHECK:       define internal void [[HVT6]](i[[SZ]] [[PARM1:%.+]], i[[SZ]] [[PARM2:%.+]], i[[SZ]] [[PARM3:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM3]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i16*
+// CHECK:       [[T:%.+]] = load i16, i16* [[CONV]], align
+// CHECK:       [[NT:%.+]] = sext i16 [[T]] to i32
+// CHECK:       call void @__kmpc_push_num_threads(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]])
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2,
+//
+//
+
+
+
+#endif
diff --git a/test/OpenMP/target_simd_ast_print.cpp b/test/OpenMP/target_simd_ast_print.cpp
index 0a936a0..01ce1d2 100644
--- a/test/OpenMP/target_simd_ast_print.cpp
+++ b/test/OpenMP/target_simd_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/target_simd_if_messages.cpp b/test/OpenMP/target_simd_if_messages.cpp
index e0834e7..ff68f6f 100644
--- a/test/OpenMP/target_simd_if_messages.cpp
+++ b/test/OpenMP/target_simd_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 %s
 
 void foo() {
 }
diff --git a/test/OpenMP/target_teams_ast_print.cpp b/test/OpenMP/target_teams_ast_print.cpp
new file mode 100644
index 0000000..a80b8d7
--- /dev/null
+++ b/test/OpenMP/target_teams_ast_print.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -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> struct S {
+// CHECK:        static T TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S::TS)
+// CHECK:      };
+// CHECK:      template<> struct S<int> {
+// CHECK:        static int TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<int>::TS)
+// CHECK-NEXT: }
+// CHECK:      template<> struct S<long> {
+// CHECK:        static long TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<long>::TS)
+// CHECK-NEXT: }
+
+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 target teams
+  a=2;
+#pragma omp target teams default(none), private(argc,b) firstprivate(argv) shared (d) reduction(+:c) reduction(max:e) num_teams(C) thread_limit(d*C)
+  foo();
+#pragma omp target teams reduction(^:e, f) reduction(&& : g)
+  foo();
+  return 0;
+}
+
+// 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 target teams
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(C) thread_limit(d * C)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target teams reduction(^: e,f) reduction(&&: g)
+// CHECK-NEXT: foo()
+// CHECK: template<> int tmain<int, 5>(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 target teams
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(5) thread_limit(d * 5)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target teams reduction(^: e,f) reduction(&&: g)
+// CHECK-NEXT: foo()
+// CHECK: template<> long tmain<long, 1>(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 target teams
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(1) thread_limit(d * 1)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target teams reduction(^: e,f) reduction(&&: g)
+// CHECK-NEXT: foo()
+
+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 target teams
+// CHECK-NEXT: #pragma omp target teams
+  a=2;
+// CHECK-NEXT: a = 2;
+#pragma omp target teams default(none), private(argc,b) num_teams(f) firstprivate(argv) reduction(| : c, d) reduction(* : e) thread_limit(f+g)
+// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) num_teams(f) firstprivate(argv) reduction(|: c,d) reduction(*: e) thread_limit(f + g)
+  foo();
+// CHECK-NEXT: foo();
+  return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
+}
+
+extern template int S<int>::TS;
+extern template long S<long>::TS;
+#endif
diff --git a/test/OpenMP/target_teams_codegen.cpp b/test/OpenMP/target_teams_codegen.cpp
new file mode 100644
index 0000000..6bac4e6
--- /dev/null
+++ b/test/OpenMP/target_teams_codegen.cpp
@@ -0,0 +1,802 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// We have 8 target regions, but only 7 that actually will generate offloading
+// code, only 6 will have mapped arguments, and only 4 have all-constant map
+// sizes.
+
+// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 2]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 35, i32 288, i32 35, i32 35, i32 288, i32 288, i32 35, i32 35]
+// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 35]
+// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 35]
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }]
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* [[REGFN:@.+]] to void ()*), i8* null }]
+
+
+template<typename tx, typename ty>
+struct TT{
+  tx X;
+  ty Y;
+};
+
+// CHECK: define {{.*}}[[FOO:@.+]](
+int foo(int n) {
+  int a = 0;
+  short aa = 0;
+  float b[10];
+  float bn[n];
+  double c[5][10];
+  double cn[5][n];
+  TT<long long, char> d;
+
+  // CHECK:       [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i32* null, i32 0, i32 0)
+  // CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+  // CHECK:       [[FAIL]]
+  // CHECK:       call void [[HVT0:@.+]]()
+  // CHECK-NEXT:  br label %[[END]]
+  // CHECK:       [[END]]
+  #pragma omp target teams
+  {
+  }
+
+  // CHECK:       store i32 0, i32* [[RHV:%.+]], align 4
+  // CHECK:       store i32 -1, i32* [[RHV]], align 4
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK:       call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}})
+  #pragma omp target teams if(target: 0)
+  {
+    a += 1;
+  }
+
+  // CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT2]], i32 0, i32 0), i32 0, i32 0)
+  // CHECK-DAG:   [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
+  // CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR]], i32 0, i32 [[IDX0]]
+  // CHECK-DAG:   store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
+  // CHECK-DAG:   store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
+  // CHECK-DAG:   [[BP0]] = inttoptr i[[SZ]] %{{.+}} to i8*
+  // CHECK-DAG:   [[P0]] = inttoptr i[[SZ]] %{{.+}} to i8*
+
+  // CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+  // CHECK:       [[FAIL]]
+  // CHECK:       call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}})
+  // CHECK-NEXT:  br label %[[END]]
+  // CHECK:       [[END]]
+  #pragma omp target teams if(target: 1)
+  {
+    aa += 1;
+  }
+
+  // CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
+  // CHECK:       br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+  // CHECK:       [[IFTHEN]]
+  // CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT3]], i32 0, i32 0), i32 0, i32 0)
+  // CHECK-DAG:   [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+
+  // CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
+  // CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
+  // CHECK-DAG:   store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
+  // CHECK-DAG:   store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
+  // CHECK-DAG:   [[BP0]] = inttoptr i[[SZ]] %{{.+}} to i8*
+  // CHECK-DAG:   [[P0]] = inttoptr i[[SZ]] %{{.+}} to i8*
+
+  // CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
+  // CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
+  // CHECK-DAG:   store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]]
+  // CHECK-DAG:   store i8* [[P1:%[^,]+]], i8** [[PADDR1]]
+  // CHECK-DAG:   [[BP1]] = inttoptr i[[SZ]] %{{.+}} to i8*
+  // CHECK-DAG:   [[P1]] = inttoptr i[[SZ]] %{{.+}} to i8*
+  // CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+  // CHECK-NEXT:  br label %[[IFEND:.+]]
+
+  // CHECK:       [[IFELSE]]
+  // CHECK:       store i32 -1, i32* [[RHV]], align 4
+  // CHECK-NEXT:  br label %[[IFEND:.+]]
+
+  // CHECK:       [[IFEND]]
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+  // CHECK:       [[FAIL]]
+  // CHECK:       call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
+  // CHECK-NEXT:  br label %[[END]]
+  // CHECK:       [[END]]
+  #pragma omp target teams if(target: n>10)
+  {
+    a += 1;
+    aa += 1;
+  }
+
+  // We capture 3 VLA sizes in this target region
+  // CHECK-64:       [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+  // CHECK-64:       [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32*
+  // CHECK-64:       store i32 [[A_VAL]], i32* [[A_ADDR]],
+  // CHECK-64:       [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+  // CHECK-32:       [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+  // CHECK-32:       store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
+  // CHECK-32:       [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+  // CHECK:       [[BNSIZE:%.+]] = mul nuw i[[SZ]] [[VLA0:%.+]], 4
+  // CHECK:       [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
+  // CHECK:       [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
+
+  // CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
+  // CHECK:       br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+  // CHECK:       [[TRY]]
+  // CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT4]], i32 0, i32 0), i32 0, i32 0)
+  // CHECK-DAG:   [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+  // CHECK-DAG:   [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
+
+  // CHECK-DAG:   [[SADDR0:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX0:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX0]]
+  // CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX0]]
+  // CHECK-DAG:   [[SADDR1:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX1:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX1]]
+  // CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX1]]
+  // CHECK-DAG:   [[SADDR2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX2:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX2]]
+  // CHECK-DAG:   [[PADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX2]]
+  // CHECK-DAG:   [[SADDR3:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX3:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX3]]
+  // CHECK-DAG:   [[PADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX3]]
+  // CHECK-DAG:   [[SADDR4:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX4:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX4]]
+  // CHECK-DAG:   [[PADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX4]]
+  // CHECK-DAG:   [[SADDR5:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX5:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX5]]
+  // CHECK-DAG:   [[PADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX5]]
+  // CHECK-DAG:   [[SADDR6:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX6:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX6]]
+  // CHECK-DAG:   [[PADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX6]]
+  // CHECK-DAG:   [[SADDR7:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX7:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX7]]
+  // CHECK-DAG:   [[PADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX7]]
+  // CHECK-DAG:   [[SADDR8:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX8:[0-9]+]]
+  // CHECK-DAG:   [[BPADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX8]]
+  // CHECK-DAG:   [[PADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX8]]
+
+  // The names below are not necessarily consistent with the names used for the
+  // addresses above as some are repeated.
+  // CHECK-DAG:   [[BP0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
+  // CHECK-DAG:   [[P0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
+  // CHECK-DAG:   store i8* [[BP0]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P0]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP1:%[^,]+]] = inttoptr i[[SZ]] [[VLA1]] to i8*
+  // CHECK-DAG:   [[P1:%[^,]+]] = inttoptr i[[SZ]] [[VLA1]] to i8*
+  // CHECK-DAG:   store i8* [[BP1]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P1]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   store i8* inttoptr (i[[SZ]] 5 to i8*), i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* inttoptr (i[[SZ]] 5 to i8*), i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP3:%[^,]+]] = inttoptr i[[SZ]] [[A_CVAL]] to i8*
+  // CHECK-DAG:   [[P3:%[^,]+]] = inttoptr i[[SZ]] [[A_CVAL]] to i8*
+  // CHECK-DAG:   store i8* [[BP3]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P3]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP4:%[^,]+]] = bitcast [10 x float]* %{{.+}} to i8*
+  // CHECK-DAG:   [[P4:%[^,]+]] = bitcast [10 x float]* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP4]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P4]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] 40, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP5:%[^,]+]] = bitcast float* %{{.+}} to i8*
+  // CHECK-DAG:   [[P5:%[^,]+]] = bitcast float* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP5]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P5]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] [[BNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP6:%[^,]+]] = bitcast [5 x [10 x double]]* %{{.+}} to i8*
+  // CHECK-DAG:   [[P6:%[^,]+]] = bitcast [5 x [10 x double]]* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP6]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P6]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] 400, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP7:%[^,]+]] = bitcast double* %{{.+}} to i8*
+  // CHECK-DAG:   [[P7:%[^,]+]] = bitcast double* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP7]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P7]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] [[CNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+  // CHECK-DAG:   [[BP8:%[^,]+]] = bitcast [[TT]]* %{{.+}} to i8*
+  // CHECK-DAG:   [[P8:%[^,]+]] = bitcast [[TT]]* %{{.+}} to i8*
+  // CHECK-DAG:   store i8* [[BP8]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i8* [[P8]], i8** {{%[^,]+}}
+  // CHECK-DAG:   store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
+
+  // CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+  // CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+  // CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+  // CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+  // CHECK:       [[FAIL]]
+  // CHECK:       call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+  // CHECK-NEXT:  br label %[[END]]
+  // CHECK:       [[END]]
+  #pragma omp target teams if(target: n>20)
+  {
+    a += 1;
+    b[2] += 1.0;
+    bn[3] += 1.0;
+    c[1][2] += 1.0;
+    cn[1][3] += 1.0;
+    d.X += 1;
+    d.Y += 1;
+  }
+
+  return a;
+}
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions in foo().
+
+// CHECK:       define internal void [[HVT0]]()
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*))
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid.)
+// CHECK:       ret void
+// CHECK-NEXT:  }
+
+
+// CHECK:       define internal void [[HVT1]](i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK:       store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64:    [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64:    [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32:    [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK-64:    [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i32*
+// CHECK-64:    store i32 [[AA]], i32* [[AA_C]], align
+// CHECK-32:    store i32 [[AA]], i32* [[AA_CASTED]], align
+// CHECK:       [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED1]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64:    [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64:    [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32:    [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK:       ret void
+// CHECK-NEXT:  }
+
+// CHECK:       define internal void [[HVT2]](i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK:       store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK:       [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK:       [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK:       [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK:       store i16 [[AA]], i16* [[AA_C]], align
+// CHECK:       [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED2]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK:       [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK:       [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK:       ret void
+// CHECK-NEXT:  }
+
+// CHECK:       define internal void [[HVT3]]
+// Create stack storage and store argument in there.
+// CHECK:       [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[A_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG:   store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG:   store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG:   [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK-64-DAG:[[A:%.+]] = load i32, i32* [[A_CADDR]], align
+// CHECK-32-DAG:[[A:%.+]] = load i32, i32* [[A_ADDR]], align
+// CHECK-64-DAG:[[A_C:%.+]] = bitcast i[[SZ]]* [[A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[A]], i32* [[A_C]], align
+// CHECK-32-DAG:store i32 [[A]], i32* [[A_CASTED]], align
+// CHECK-DAG:   [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK-DAG:   [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK-DAG:   store i16 [[AA]], i16* [[AA_C]], align
+// CHECK-DAG:   [[PARAM1:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CASTED]], align
+// CHECK-DAG:   [[PARAM2:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK-DAG:   call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]])* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM1]], i[[SZ]] [[PARAM2]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED3]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// CHECK:       [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK:       [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG:   store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG:   store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG:   [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK:       ret void
+// CHECK-NEXT:  }
+
+// CHECK:       define internal void [[HVT4]]
+// Create local storage for each capture.
+// CHECK:       [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_B:%.+]] = alloca [10 x float]*
+// CHECK:       [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_BN:%.+]] = alloca float*
+// CHECK:       [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
+// CHECK:       [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_CN:%.+]] = alloca double*
+// CHECK:       [[LOCAL_D:%.+]] = alloca [[TT]]*
+// CHECK:       [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG:   store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG:   store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
+// CHECK-DAG:   store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
+// CHECK-DAG:   store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
+// CHECK-DAG:   store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
+
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG:   [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
+// CHECK-DAG:   [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG:   [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
+// CHECK-DAG:   [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
+// CHECK-DAG:   [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG:   [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
+// CHECK-DAG:   [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
+// CHECK-DAG:   [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG:   [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 9, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], [10 x float]*, i[[SZ]], float*, [5 x [10 x double]]*, i[[SZ]], i[[SZ]], double*, [[TT]]*)* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], [10 x float]* [[REF_B]], i[[SZ]] [[VAL_VLA1]], float* [[REF_BN]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] [[VAL_VLA2]], i[[SZ]] [[VAL_VLA3]], double* [[REF_CN]], [[TT]]* [[REF_D]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* %{{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* %{{.+}}, [[TT]]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+  short aa = 0;
+  tx b[10];
+
+  #pragma omp target teams if(target: n>40)
+  {
+    a += 1;
+    aa += 1;
+    b[2] += 1;
+  }
+
+  return a;
+}
+
+static
+int fstatic(int n) {
+  int a = 0;
+  short aa = 0;
+  char aaa = 0;
+  int b[10];
+
+  #pragma omp target teams if(target: n>50)
+  {
+    a += 1;
+    aa += 1;
+    aaa += 1;
+    b[2] += 1;
+  }
+
+  return a;
+}
+
+struct S1 {
+  double a;
+
+  int r1(int n){
+    int b = n+1;
+    short int c[2][n];
+
+    #pragma omp target teams if(target: n>60)
+    {
+      this->a = (double)b + 1.5;
+      c[1][1] = ++a;
+    }
+
+    return c[1][1] + (int)b;
+  }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+  int a = 0;
+
+  // CHECK: call {{.*}}i32 [[FOO]](i32 {{.*}})
+  a += foo(n);
+
+  S1 S;
+  // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+  a += S.r1(n);
+
+  // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+  a += fstatic(n);
+
+  // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+//
+// CHECK: define {{.*}}[[FS1]]
+//
+// CHECK:          i8* @llvm.stacksave()
+// CHECK-64:       [[B_ADDR:%.+]] = bitcast i[[SZ]]* [[B_CADDR:%.+]] to i32*
+// CHECK-64:       store i32 %{{.+}}, i32* [[B_ADDR]],
+// CHECK-64:       [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_CADDR]],
+
+// CHECK-32:       store i32 %{{.+}}, i32* [[B_ADDR:%.+]],
+// CHECK-32:       [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_ADDR]],
+
+// We capture 2 VLA sizes in this target region
+// CHECK:       [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
+// CHECK:       [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
+
+// CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
+// CHECK:       br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+// CHECK:       [[TRY]]
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT7]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG:   [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[SADDR0:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX0:[0-9]+]]
+// CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX0]]
+// CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX0]]
+// CHECK-DAG:   [[SADDR1:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX1:[0-9]+]]
+// CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX1]]
+// CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX1]]
+// CHECK-DAG:   [[SADDR2:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX2:[0-9]+]]
+// CHECK-DAG:   [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX2]]
+// CHECK-DAG:   [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX2]]
+// CHECK-DAG:   [[SADDR3:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX3:[0-9]+]]
+// CHECK-DAG:   [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX3]]
+// CHECK-DAG:   [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX3]]
+
+// The names below are not necessarily consistent with the names used for the
+// addresses above as some are repeated.
+// CHECK-DAG:   [[BP0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
+// CHECK-DAG:   [[P0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
+// CHECK-DAG:   store i8* [[BP0]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* [[P0]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG:   store i8* inttoptr (i[[SZ]] 2 to i8*), i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* inttoptr (i[[SZ]] 2 to i8*), i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG:   [[BP2:%[^,]+]] = inttoptr i[[SZ]] [[B_CVAL]] to i8*
+// CHECK-DAG:   [[P2:%[^,]+]] = inttoptr i[[SZ]] [[B_CVAL]] to i8*
+// CHECK-DAG:   store i8* [[BP2]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* [[P2]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG:   [[BP3:%[^,]+]] = bitcast [[S1]]* %{{.+}} to i8*
+// CHECK-DAG:   [[P3:%[^,]+]] = bitcast [[S1]]* %{{.+}} to i8*
+// CHECK-DAG:   store i8* [[BP3]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* [[P3]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] 8, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG:   [[BP4:%[^,]+]] = bitcast i16* %{{.+}} to i8*
+// CHECK-DAG:   [[P4:%[^,]+]] = bitcast i16* %{{.+}} to i8*
+// CHECK-DAG:   store i8* [[BP4]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i8* [[P4]], i8** {{%[^,]+}}
+// CHECK-DAG:   store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
+
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+// CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT:  br label %[[END]]
+// CHECK:       [[END]]
+
+//
+// CHECK: define {{.*}}[[FSTATIC]]
+//
+// CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
+// CHECK:       br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK:       [[IFTHEN]]
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([4 x i32], [4 x i32]* [[MAPT6]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG:   [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG:   store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
+// CHECK-DAG:   store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
+// CHECK-DAG:   [[BP0]] = inttoptr i[[SZ]] [[VAL0:%.+]] to i8*
+// CHECK-DAG:   [[P0]] = inttoptr i[[SZ]] [[VAL0]] to i8*
+
+// CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG:   store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]]
+// CHECK-DAG:   store i8* [[P1:%[^,]+]], i8** [[PADDR1]]
+// CHECK-DAG:   [[BP1]] = inttoptr i[[SZ]] [[VAL1:%.+]] to i8*
+// CHECK-DAG:   [[P1]] = inttoptr i[[SZ]] [[VAL1]] to i8*
+
+// CHECK-DAG:   [[BPADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG:   [[PADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG:   store i8* [[BP2:%[^,]+]], i8** [[BPADDR2]]
+// CHECK-DAG:   store i8* [[P2:%[^,]+]], i8** [[PADDR2]]
+
+// CHECK-DAG:   [[BPADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 3
+// CHECK-DAG:   [[PADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 3
+// CHECK-DAG:   store i8* [[BP3:%[^,]+]], i8** [[BPADDR3]]
+// CHECK-DAG:   store i8* [[P3:%[^,]+]], i8** [[PADDR3]]
+// CHECK-DAG:   [[BP3]] = bitcast [10 x i32]* %{{.+}} to i8*
+// CHECK-DAG:   [[P3]] = bitcast [10 x i32]* %{{.+}} to i8*
+
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+// CHECK-NEXT:  br label %[[IFEND:.+]]
+
+// CHECK:       [[IFELSE]]
+// CHECK:       store i32 -1, i32* [[RHV]], align 4
+// CHECK-NEXT:  br label %[[IFEND:.+]]
+
+// CHECK:       [[IFEND]]
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT:  br label %[[END]]
+// CHECK:       [[END]]
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK:       [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
+// CHECK:       br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK:       [[IFTHEN]]
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* [[MAPT5]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG:   [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG:   [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG:   [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG:   [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG:   store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
+// CHECK-DAG:   store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
+// CHECK-DAG:   [[BP0]] = inttoptr i[[SZ]] [[VAL0:%.+]] to i8*
+// CHECK-DAG:   [[P0]] = inttoptr i[[SZ]] [[VAL0]] to i8*
+
+// CHECK-DAG:   [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG:   [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG:   store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]]
+// CHECK-DAG:   store i8* [[P1:%[^,]+]], i8** [[PADDR1]]
+// CHECK-DAG:   [[BP1]] = inttoptr i[[SZ]] [[VAL1:%.+]] to i8*
+// CHECK-DAG:   [[P1]] = inttoptr i[[SZ]] [[VAL1]] to i8*
+
+// CHECK-DAG:   [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG:   [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG:   store i8* [[BP2:%[^,]+]], i8** [[BPADDR2]]
+// CHECK-DAG:   store i8* [[P2:%[^,]+]], i8** [[PADDR2]]
+// CHECK-DAG:   [[BP2]] = bitcast [10 x i32]* %{{.+}} to i8*
+// CHECK-DAG:   [[P2]] = bitcast [10 x i32]* %{{.+}} to i8*
+
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align 4
+// CHECK-NEXT:  br label %[[IFEND:.+]]
+
+// CHECK:       [[IFELSE]]
+// CHECK:       store i32 -1, i32* [[RHV]], align 4
+// CHECK-NEXT:  br label %[[IFEND:.+]]
+
+// CHECK:       [[IFEND]]
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT:  br label %[[END]]
+// CHECK:       [[END]]
+
+
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions of the callees of bar().
+
+// CHECK:       define internal void [[HVT7]]
+// Create local storage for each capture.
+// CHECK:       [[LOCAL_THIS:%.+]] = alloca [[S1]]*
+// CHECK:       [[LOCAL_B:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_C:%.+]] = alloca i16*
+// CHECK:       [[LOCAL_B_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG:   store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG:   store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
+// Store captures in the context.
+// CHECK-DAG:   [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
+// CHECK-64-DAG:[[CONV_BP:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
+// CHECK-DAG:   [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG:   [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG:   [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
+
+// CHECK-64-DAG:[[CONV_B:%.+]] = load i32, i32* [[CONV_BP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_B_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_B]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_BV:%.+]] = load i32, i32* [[LOCAL_B]]
+// CHECK-32-DAG:store i32 [[LOCAL_BV]], i32* [[LOCAL_B_CASTED]], align
+// CHECK-DAG:   [[REF_B:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_B_CASTED]],
+
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]], i[[SZ]], i[[SZ]], i16*)* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), [[S1]]* [[REF_THIS]], i[[SZ]] [[REF_B]], i[[SZ]] [[VAL_VLA1]], i[[SZ]] [[VAL_VLA2]], i16* [[REF_C]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* %{{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+
+// CHECK:       define internal void [[HVT6]]
+// Create local storage for each capture.
+// CHECK:       [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK:       [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AAA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
+// CHECK-DAG:   store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG:   [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG:   [[CONV_AAAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
+// CHECK-DAG:   [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG:   [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG:   [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG:   [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG:   store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG:   [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK-DAG:   [[CONV_AAA:%.+]] = load i8, i8* [[CONV_AAAP]]
+// CHECK-DAG:   [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA_CASTED]] to i8*
+// CHECK-DAG:   store i8 [[CONV_AAA]], i8* [[CONV]], align
+// CHECK-DAG:   [[REF_AAA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AAA_CASTED]],
+
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED6:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], i[[SZ]] [[REF_AAA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED6]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+// CHECK:       define internal void [[HVT5]]
+// Create local storage for each capture.
+// CHECK:       [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK:       [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK:       [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG:   store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG:   store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG:   [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG:   [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG:   [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG:   [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG:   [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG:   store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG:   [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED7:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK:       define internal {{.*}}void [[OMP_OUTLINED7]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+#endif
diff --git a/test/OpenMP/target_teams_codegen_registration.cpp b/test/OpenMP/target_teams_codegen_registration.cpp
new file mode 100644
index 0000000..f65c701
--- /dev/null
+++ b/test/OpenMP/target_teams_codegen_registration.cpp
@@ -0,0 +1,437 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target teams codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// Check that no target code is emmitted if no omptests flag was provided.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NTARGET
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK:    [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+
+// CHECK-DAG: [[A1:@.+]] = internal global [[SA]]
+// CHECK-DAG: [[A2:@.+]] = global [[SA]]
+// CHECK-DAG: [[B1:@.+]] = global [[SB]]
+// CHECK-DAG: [[B2:@.+]] = global [[SB]]
+// CHECK-DAG: [[C1:@.+]] = internal global [[SC]]
+// CHECK-DAG: [[D1:@.+]] = global [[SD]]
+// CHECK-DAG: [[E1:@.+]] = global [[SE]]
+// CHECK-DAG: [[T1:@.+]] = global [[ST1]]
+// CHECK-DAG: [[T2:@.+]] = global [[ST2]]
+
+// CHECK-NTARGET-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-NTARGET-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-NTARGET-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-NTARGET-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-NTARGET-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-NTARGET-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-NTARGET-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-NTARGET-NOT: type { i8*, i8*, %
+// CHECK-NTARGET-NOT: type { i32, %
+
+// We have 7 target regions
+
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// TCHECK-NOT: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+
+// CHECK-NTARGET-NOT: private constant i8 0
+// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
+
+// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// CHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// CHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// CHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// CHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// CHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// CHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// CHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// CHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// CHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// TCHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// TCHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// TCHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// TCHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// TCHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// TCHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// TCHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// TCHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// TCHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// TCHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }]
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }
+
+// We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function.
+// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [
+// CHECK-SAME: { i32, void ()*, i8* } { i32 500, void ()* [[P500:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 501, void ()* [[P501:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 65535, void ()* [[PMAX:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* [[REGFN:@.+]] to void ()*), i8* null }]
+
+// CHECK-NTARGET: @llvm.global_ctors = appending global [3   x { i32, void ()*, i8* }] [
+
+extern int *R;
+
+struct SA {
+  int arr[4];
+  void foo() {
+    int a = *R;
+    a += 1;
+    *R = a;
+  }
+  SA() {
+    int a = *R;
+    a += 2;
+    *R = a;
+  }
+  ~SA() {
+    int a = *R;
+    a += 3;
+    *R = a;
+  }
+};
+
+struct SB {
+  int arr[8];
+  void foo() {
+    int a = *R;
+    #pragma omp target teams
+    a += 4;
+    *R = a;
+  }
+  SB() {
+    int a = *R;
+    a += 5;
+    *R = a;
+  }
+  ~SB() {
+    int a = *R;
+    a += 6;
+    *R = a;
+  }
+};
+
+struct SC {
+  int arr[16];
+  void foo() {
+    int a = *R;
+    a += 7;
+    *R = a;
+  }
+  SC() {
+    int a = *R;
+    #pragma omp target teams
+    a += 8;
+    *R = a;
+  }
+  ~SC() {
+    int a = *R;
+    a += 9;
+    *R = a;
+  }
+};
+
+struct SD {
+  int arr[32];
+  void foo() {
+    int a = *R;
+    a += 10;
+    *R = a;
+  }
+  SD() {
+    int a = *R;
+    a += 11;
+    *R = a;
+  }
+  ~SD() {
+    int a = *R;
+    #pragma omp target teams
+    a += 12;
+    *R = a;
+  }
+};
+
+struct SE {
+  int arr[64];
+  void foo() {
+    int a = *R;
+    #pragma omp target teams if(target: 0)
+    a += 13;
+    *R = a;
+  }
+  SE() {
+    int a = *R;
+    #pragma omp target teams
+    a += 14;
+    *R = a;
+  }
+  ~SE() {
+    int a = *R;
+    #pragma omp target teams
+    a += 15;
+    *R = a;
+  }
+};
+
+template <int x>
+struct ST {
+  int arr[128 + x];
+  void foo() {
+    int a = *R;
+    #pragma omp target teams
+    a += 16 + x;
+    *R = a;
+  }
+  ST() {
+    int a = *R;
+    #pragma omp target teams
+    a += 17 + x;
+    *R = a;
+  }
+  ~ST() {
+    int a = *R;
+    #pragma omp target teams
+    a += 18 + x;
+    *R = a;
+  }
+};
+
+// We have to make sure we us all the target regions:
+//CHECK-DAG: define internal void @[[NAME1]](
+//CHECK-DAG: call void @[[NAME1]](
+//CHECK-DAG: define internal void @[[NAME2]](
+//CHECK-DAG: call void @[[NAME2]](
+//CHECK-DAG: define internal void @[[NAME3]](
+//CHECK-DAG: call void @[[NAME3]](
+//CHECK-DAG: define internal void @[[NAME4]](
+//CHECK-DAG: call void @[[NAME4]](
+//CHECK-DAG: define internal void @[[NAME5]](
+//CHECK-DAG: call void @[[NAME5]](
+//CHECK-DAG: define internal void @[[NAME6]](
+//CHECK-DAG: call void @[[NAME6]](
+//CHECK-DAG: define internal void @[[NAME7]](
+//CHECK-DAG: call void @[[NAME7]](
+//CHECK-DAG: define internal void @[[NAME8]](
+//CHECK-DAG: call void @[[NAME8]](
+//CHECK-DAG: define internal void @[[NAME9]](
+//CHECK-DAG: call void @[[NAME9]](
+//CHECK-DAG: define internal void @[[NAME10]](
+//CHECK-DAG: call void @[[NAME10]](
+//CHECK-DAG: define internal void @[[NAME11]](
+//CHECK-DAG: call void @[[NAME11]](
+//CHECK-DAG: define internal void @[[NAME12]](
+//CHECK-DAG: call void @[[NAME12]](
+
+//TCHECK-DAG: define void @[[NAME1]](
+//TCHECK-DAG: define void @[[NAME2]](
+//TCHECK-DAG: define void @[[NAME3]](
+//TCHECK-DAG: define void @[[NAME4]](
+//TCHECK-DAG: define void @[[NAME5]](
+//TCHECK-DAG: define void @[[NAME6]](
+//TCHECK-DAG: define void @[[NAME7]](
+//TCHECK-DAG: define void @[[NAME8]](
+//TCHECK-DAG: define void @[[NAME9]](
+//TCHECK-DAG: define void @[[NAME10]](
+//TCHECK-DAG: define void @[[NAME11]](
+//TCHECK-DAG: define void @[[NAME12]](
+
+// CHECK-NTARGET-NOT: __tgt_target
+// CHECK-NTARGET-NOT: __tgt_register_lib
+// CHECK-NTARGET-NOT: __tgt_unregister_lib
+
+// TCHECK-NOT: __tgt_target
+// TCHECK-NOT: __tgt_register_lib
+// TCHECK-NOT: __tgt_unregister_lib
+
+// We have 2 initializers with priority 500
+//CHECK: define internal void [[P500]](
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK:     ret void
+
+// We have 1 initializers with priority 501
+//CHECK: define internal void [[P501]](
+//CHECK:     call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK:     ret void
+
+// We have 6 initializers with default priority
+//CHECK: define internal void [[PMAX]](
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK:     call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK:     ret void
+
+// Check registration and unregistration
+
+//CHECK:     define internal void [[UNREGFN:@.+]](i8*)
+//CHECK:     call i32 @__tgt_unregister_lib([[DSCTY]]* [[DESC]])
+//CHECK:     ret void
+//CHECK:     declare i32 @__tgt_unregister_lib([[DSCTY]]*)
+
+//CHECK:     define internal void [[REGFN]](i8*)
+//CHECK:     call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]])
+//CHECK:     call i32 @__cxa_atexit(void (i8*)* [[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*),
+//CHECK:     ret void
+//CHECK:     declare i32 @__tgt_register_lib([[DSCTY]]*)
+
+static __attribute__((init_priority(500))) SA a1;
+SA a2;
+SB __attribute__((init_priority(500))) b1;
+SB __attribute__((init_priority(501))) b2;
+static SC c1;
+SD d1;
+SE e1;
+ST<100> t1;
+ST<1000> t2;
+
+
+int bar(int a){
+  int r = a;
+
+  a1.foo();
+  a2.foo();
+  b1.foo();
+  b2.foo();
+  c1.foo();
+  d1.foo();
+  e1.foo();
+  t1.foo();
+  t2.foo();
+
+  #pragma omp target teams
+  ++r;
+
+  return r + *R;
+}
+
+// Check metadata is properly generated:
+// CHECK:     !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 {{[0-9]+}}}
+
+// TCHECK:     !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 {{[0-9]+}}}
+
+#endif
diff --git a/test/OpenMP/target_teams_codegen_registration_naming.cpp b/test/OpenMP/target_teams_codegen_registration_naming.cpp
new file mode 100644
index 0000000..fb42328
--- /dev/null
+++ b/test/OpenMP/target_teams_codegen_registration_naming.cpp
@@ -0,0 +1,66 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target teams codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[CA:%.+]] = type { i32* }
+
+// CHECK: define {{.*}}i32 @[[NNAME:.+]](i32 {{.*}}%{{.+}})
+int nested(int a){
+  // CHECK: call void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME]]_l[[T1L:[0-9]+]](
+  #pragma omp target teams
+    ++a;
+
+  // CHECK: call void @"[[LNAME:.+]]"([[CA]]*
+  auto F = [&](){
+    #pragma omp parallel
+    {
+      #pragma omp target teams
+      ++a;
+    }
+  };
+
+  F();
+
+  return a;
+}
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T1L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME:.+]]_l[[T1L:[0-9]+]](
+
+// CHECK: define {{.*}}void @"[[LNAME]]"(
+// CHECK: call void {{.*}}@__kmpc_fork_call{{.+}}[[PNAME:@.+]] to
+
+// CHECK: define {{.*}}void [[PNAME]](
+// CHECK: call void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L:[0-9]+]](
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME:.+]]_l[[T2L:[0-9]+]](
+
+
+// Check metadata is properly generated:
+// CHECK:     !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+
+// TCHECK:     !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+#endif
diff --git a/test/OpenMP/target_teams_default_messages.cpp b/test/OpenMP/target_teams_default_messages.cpp
new file mode 100644
index 0000000..0534637
--- /dev/null
+++ b/test/OpenMP/target_teams_default_messages.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -verify -fopenmp -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+#pragma omp target teams default // expected-error {{expected '(' after 'default'}}
+  foo();
+#pragma omp target teams default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  foo();
+#pragma omp target teams default (none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams default (shared), default(shared) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'default' clause}}
+  foo();
+#pragma omp target teams default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  foo();
+
+#pragma omp target teams default(none)
+  ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+#pragma omp target teams default(none)
+#pragma omp parallel default(shared)
+  ++argc;
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_defaultmap_messages.cpp b/test/OpenMP/target_teams_defaultmap_messages.cpp
new file mode 100644
index 0000000..f2d30fd
--- /dev/null
+++ b/test/OpenMP/target_teams_defaultmap_messages.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+template <class T, typename S, int N, int ST>
+T tmain(T argc, S **argv) {
+  #pragma omp target teams defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+  #pragma omp target teams defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  foo();
+  #pragma omp target teams defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp target teams defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+  #pragma omp target teams defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  foo();
+  #pragma omp target teams defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  foo();
+  #pragma omp target teams defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  foo();
+
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_teams_depend_messages.cpp b/test/OpenMP/target_teams_depend_messages.cpp
new file mode 100644
index 0000000..9308e89
--- /dev/null
+++ b/test/OpenMP/target_teams_depend_messages.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+class vector {
+  public:
+    int operator[](int index) { return 0; }
+};
+
+int main(int argc, char **argv, char *env[]) {
+  vector vec;
+  typedef float V __attribute__((vector_size(16)));
+  V a;
+  auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+
+#pragma omp target teams depend // expected-error {{expected '(' after 'depend'}}
+  foo();
+#pragma omp target teams depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+  foo();
+#pragma omp target teams depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+  foo();
+#pragma omp target teams depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+  foo();
+#pragma omp target teams depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+  foo();
+#pragma omp target teams depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams depend (out: ) // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+  foo();
+#pragma omp target teams depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp target teams depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+  foo();
+#pragma omp target teams depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+  foo();
+#pragma omp target teams depend (in : argv[0])
+  foo();
+#pragma omp target teams depend (in : ) // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams depend (in : main) // expected-error {{expected variable name, array element or array section}}
+  foo();
+#pragma omp target teams depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+  foo();
+#pragma omp target teams depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+  foo();
+#pragma omp target teams depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+  foo();
+#pragma omp target teams depend (in : argv[-1:0])
+  foo();
+#pragma omp target teams depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  foo();
+#pragma omp target teams depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+  foo();
+#pragma omp target teams depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+  foo();
+#pragma omp target teams depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+  foo();
+#pragma omp target teams depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  foo();
+#pragma omp target teams depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+  foo();
+#pragma omp target teams depend(in : argv[ : argc][1 : argc - 1])
+  foo();
+#pragma omp target teams depend(in : arr[0])
+  foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_device_messages.cpp b/test/OpenMP/target_teams_device_messages.cpp
new file mode 100644
index 0000000..bd75da8
--- /dev/null
+++ b/test/OpenMP/target_teams_device_messages.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+#pragma omp target teams device // expected-error {{expected '(' after 'device'}}
+  foo();
+#pragma omp target teams device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams device () // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  foo();
+#pragma omp target teams device (argc + argc)
+  foo();
+#pragma omp target teams device (argc), device (argc+1) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'device' clause}}
+  foo();
+#pragma omp target teams device (S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp target teams device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+  foo();
+#pragma omp target teams device (-10u)
+  foo();
+#pragma omp target teams device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_ast_print.cpp b/test/OpenMP/target_teams_distribute_ast_print.cpp
new file mode 100644
index 0000000..ae50366
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_ast_print.cpp
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+struct S {
+  S(): a(0) {}
+  S(int v) : a(v) {}
+  int a;
+  typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+  T a;
+  S7() : a(0) {}
+
+public:
+  S7(typename T::type v) : a(v) {
+#pragma omp target teams distribute private(a) private(this->a) private(T::a)
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
+  }
+  S7 &operator=(S7 &s) {
+#pragma omp target teams distribute private(a) private(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
+    return *this;
+  }
+
+  void foo() {
+    int b, argv, d, c, e, f;
+#pragma omp target teams distribute default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+};
+// CHECK: #pragma omp target teams distribute private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp target teams distribute private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK: #pragma omp target teams distribute private(this->a) private(this->a) private(this->S::a)
+
+class S8 : public S7<S> {
+  S8() {}
+
+public:
+  S8(int v) : S7<S>(v){
+#pragma omp target teams distribute private(a) private(this->a) private(S7<S>::a) 
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
+  }
+  S8 &operator=(S8 &s) {
+#pragma omp target teams distribute private(a) private(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
+    return *this;
+  }
+
+  void bar() {
+    int b, argv, d, c, e, f;
+#pragma omp target teams distribute default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+};
+// CHECK: #pragma omp target teams distribute private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp target teams distribute private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+
+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 target teams distribute
+  for (int i=0; i < 2; ++i)
+    a = 2;
+// CHECK: #pragma omp target teams distribute
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target teams distribute private(argc, b), firstprivate(c, d), collapse(2)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+// CHECK: #pragma omp target teams distribute private(argc,b) firstprivate(c,d) collapse(2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: #pragma omp target teams distribute
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();  
+#pragma omp target teams distribute default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < 10; ++k)
+      e += d + argc;
+// CHECK: #pragma omp target teams distribute default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+  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 target teams distribute
+  for (int i=0; i < 2; ++i)
+    a = 2;
+// CHECK: #pragma omp target teams distribute
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target teams distribute private(argc,b),firstprivate(argv, c), collapse(2)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+// CHECK: #pragma omp target teams distribute private(argc,b) firstprivate(argv,c) collapse(2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i)foo();
+// CHECK: #pragma omp target teams distribute
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+  return (0);
+}
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_collapse_messages.cpp b/test/OpenMP/target_teams_distribute_collapse_messages.cpp
new file mode 100644
index 0000000..4bc4a7b
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_collapse_messages.cpp
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+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 target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute 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 strictly positive integer value}}
+#pragma omp target teams distribute 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 target teams distribute collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute 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 target teams distribute', but found only 1}}
+
+#if __cplusplus >= 201103L
+// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+// expected-error@+3 2 {{directive '#pragma omp target teams distribute' cannot contain more than one 'collapse' clause}}
+// expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute 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 target teams distribute 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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute 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 target teams distribute collapse (1)
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}}
+  for (T i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp target teams distribute'}}
+  return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute collapse () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute 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 target teams distribute', but found only 1}}
+
+#pragma omp target teams distribute collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' 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 target teams distribute', but found only 1}}
+
+// expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute collapse (foobool(1) > 0 ? 1 : 2)
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus >= 201103L
+  // expected-note@+5{{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+// expected-error@+3 {{expression is not an integral constant expression}}
+// expected-error@+2 2 {{directive '#pragma omp target teams distribute' cannot contain more than one 'collapse' clause}}
+// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute 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 target teams distribute 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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute 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 target teams distribute' must be a for loop}}
+// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target teams distribute collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo();
+
+#pragma omp target teams distribute collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp target teams distribute'}}
+
+// 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/target_teams_distribute_default_messages.cpp b/test/OpenMP/target_teams_distribute_default_messages.cpp
new file mode 100644
index 0000000..1bd1067
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_default_messages.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo();
+
+int main(int argc, char **argv) {
+  #pragma omp target teams distribute default // expected-error {{expected '(' after 'default'}}
+  for (int i=0; i<200; i++) foo();
+  #pragma omp target teams distribute default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<200; i++) foo();
+  #pragma omp target teams distribute default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (int i=0; i<200; i++) foo();
+  #pragma omp target teams distribute default (none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<200; i++) foo();
+  #pragma omp target teams distribute default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'default' clause}}
+  for (int i=0; i<200; i++) foo();
+  #pragma omp target teams distribute default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (int i=0; i<200; i++) foo();
+
+  #pragma omp target teams distribute default(none)
+  for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_defaultmap_messages.cpp b/test/OpenMP/target_teams_distribute_defaultmap_messages.cpp
new file mode 100644
index 0000000..6608cee
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_defaultmap_messages.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+template <class T, typename S, int N, int ST>
+T tmain(T argc, S **argv) {
+  int i;
+#pragma omp target teams distribute defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_teams_distribute_depend_messages.cpp b/test/OpenMP/target_teams_distribute_depend_messages.cpp
new file mode 100644
index 0000000..b3e7331
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_depend_messages.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+class vector {
+  public:
+    int operator[](int index) { return 0; }
+};
+
+int main(int argc, char **argv, char *env[]) {
+  vector vec;
+  typedef float V __attribute__((vector_size(16)));
+  V a;
+  auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+  int i;
+
+#pragma omp target teams distribute depend // expected-error {{expected '(' after 'depend'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (out: ) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[0])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : ) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : main) // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[-1:0])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend(in : argv[ : argc][1 : argc - 1])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute depend(in : arr[0])
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_device_messages.cpp b/test/OpenMP/target_teams_distribute_device_messages.cpp
new file mode 100644
index 0000000..b35d0be
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_device_messages.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute device // expected-error {{expected '(' after 'device'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device (argc + argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device (argc), device (argc+1) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'device' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device (-10u)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp b/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
new file mode 100644
index 0000000..8770870
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  char ** argv;
+  static T a;
+// CHECK: static T a;
+
+#pragma omp target teams distribute dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'dist_schedule' clause}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'dist_schedule' clause}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp
new file mode 100644
index 0000000..602e039
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  
+public:
+  S2() : a(0) {}
+  S2(const 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) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+  S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
+};
+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) { }
+};
+class S6 {
+  int a;
+public:
+  S6() : a(0) { }
+};
+
+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);
+  S6 p;
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate (argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate (argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate(ba)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target
+#pragma omp teams distribute firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate(da)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate(i)
+  for (j = 0; j < argc; ++j) foo();
+
+#pragma omp target teams distribute firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp target teams distribute' directive may not be firstprivate, predetermined as private}}
+
+#pragma omp target teams distribute firstprivate(j)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(argc), firstprivate(argc) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_if_messages.cpp b/test/OpenMP/target_teams_distribute_if_messages.cpp
new file mode 100644
index 0000000..c9ef03a
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_if_messages.cpp
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 %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) {
+  int i;
+#pragma omp target teams distribute if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(teams: argc) // expected-error {{directive name modifier 'teams' is not allowed for '#pragma omp target teams distribute'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(distribute: argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(argc) if(teams: argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{directive name modifier 'teams' is not allowed for '#pragma omp target teams distribute'}} expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(argc) if(distribute: argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute'}} expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(distribute: argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target teams distribute'}} expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'if' clause with 'target' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : argc) if(distribute: argc) if (argc) // expected-note 2 {{previous clause with directive name modifier specified here}} expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute'}} expected-error {{expected one of  directive name modifiers}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(teams : argc) // expected-error {{directive name modifier 'teams' is not allowed for '#pragma omp target teams distribute'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : argc) if (distribute :argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'if' clause with 'target' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(argc) if(teams: argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{directive name modifier 'teams' is not allowed for '#pragma omp target teams distribute'}} expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute if(argc) if(distribute: argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute'}} expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
new file mode 100644
index 0000000..8d594e9
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
@@ -0,0 +1,229 @@
+// RUN: %clang_cc1 -verify -fopenmp %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) {}
+  const S2 &operator =(const S2&) const;
+  S2 &operator =(const S2&);
+  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 {
+  int a;
+  S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+
+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 {
+  int a;
+  S4();             // expected-note 3 {{implicitly declared private here}}
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 {
+  int a;
+  S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+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);
+  I g(5);
+  int i;
+  int &j = i;
+#pragma omp target teams distribute lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  int v = 0;
+#pragma omp target teams distribute lastprivate(i)
+  for (int k = 0; k < argc; ++k) {
+    i = k;
+    v += i;
+  }
+
+#pragma omp target teams distribute lastprivate(j) private(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute lastprivate(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp target teams distribute lastprivate(a)
+  for (int i = 0; i < 2; ++i) foo();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i;
+#pragma omp target teams distribute lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute 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 target teams distribute lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(ba)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+  int xa;
+#pragma omp target teams distribute lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute 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 target teams distribute lastprivate(xa)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(j)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+  static int si;
+#pragma omp target teams distribute  lastprivate(si) // OK
+  for (i = 0; i < argc; ++i) si = i + 1;
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_loop_messages.cpp b/test/OpenMP/target_teams_distribute_loop_messages.cpp
new file mode 100644
index 0000000..cb243a6
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_loop_messages.cpp
@@ -0,0 +1,620 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -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;
+// expected-note@+1 {{defined as threadprivate or thread local}}
+#pragma omp threadprivate(sii)
+static int globalii;
+
+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 target teams distribute
+  for (int i = 0; i < 10; i += 1) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute
+  for (char i = 0; i < 10; i += '\1') {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute
+// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (long long i = 0; i < 10; i += 1.5) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute
+  for (long long i = 0; i < 'z'; i += 1u) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute
+// expected-error@+1 {{variable must be of integer or random access iterator type}}
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp target teams distribute
+// expected-error@+1 {{variable must be of integer or random access iterator type}}
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp target teams distribute
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+#pragma omp target teams distribute
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-warning@+2 {{expression result unused}}
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (ii + 1; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (c[ii] = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// Ok to skip parenthesises.
+  for (((ii)) = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0;; i++)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute
+  for (ii = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; ++jj)
+    c[ii] = a[jj];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  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 target teams distribute
+  for (ii = 0; ii < 10; ii = ii + ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'float'}}
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+// Ok - step was converted to integer type.
+#pragma omp target teams distribute
+  for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; jj = ii + 2)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-warning@+2 {{relational comparison result unused}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii<10; jj> kk + 2)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10;)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-warning@+2 {{expression result unused}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; !ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; ii = ii < 10)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; ii < 10; ii = ii + 0)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; (ii) < 10; ii -= 25)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; (ii < 10); ii -= 0)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  for (ii = 0; ii > 10; (ii += 0))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  for ((ii = 0); ii > 10; (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; (ii < 10); (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute firstprivate(ii) // expected-note  {{defined as firstprivate}}
+// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute' directive may not be firstprivate, predetermined as private}}
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute private(ii)
+// OK
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute lastprivate(ii)
+// OK
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute
+// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute' directive may not be threadprivate or thread local, predetermined as private}}
+  for (sii = 0; sii < 10; sii++)
+    c[sii] = a[sii];
+
+  {
+#pragma omp target teams distribute collapse(2)
+  for (ii = 0; ii < 10; ii += 1)
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] += a[globalii] + ii;
+  }
+
+#pragma omp target teams distribute
+// expected-error@+1 {{statement after '#pragma omp target teams distribute' must be a for loop}}
+  for (auto &item : a) {
+    item = item + 1;
+  }
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int(*lb)[4] = nullptr;
+#pragma omp target teams distribute
+  for (int(*p)[4] = lb; p < lb + 8; ++p) {
+  }
+
+#pragma omp target teams distribute
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  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; }
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
+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;
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+int operator-(GoodIter a, GoodIter b) { return 0; }
+// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
+GoodIter operator-(GoodIter a) { return a; }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}}
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+#pragma omp target teams distribute
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+#pragma omp target teams distribute
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+#pragma omp target teams distribute
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+#pragma omp target teams distribute
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(1, 2); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute
+// expected-error@+2 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
+// expected-error@+1 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (++begin; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+#pragma omp target teams distribute
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+#pragma omp target teams distribute
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+#pragma omp target teams distribute
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+#pragma omp target teams distribute
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+#pragma omp target teams distribute
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+#pragma omp target teams distribute
+// expected-error@+1 {{invalid operands to binary expression ('Iter0' and 'int')}}
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+#pragma omp target teams distribute
+// Initializer is constructor without params.
+// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}}
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+#pragma omp target teams distribute
+// expected-error@+2 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
+// expected-error@+1 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+#pragma omp target teams distribute
+// expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'float')}}
+// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+// Initializer is constructor with all default params.
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  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 target teams distribute
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+    for (IT I = begin; I < end; I = I + ST) {
+      ++I;
+    }
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+    for (IT I = begin; I <= end; I += ST) {
+      ++I;
+    }
+#pragma omp target teams distribute
+    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 target teams distribute
+// expected-note@+2 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+#pragma omp target teams distribute
+// expected-note@+2 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+#pragma omp target teams distribute
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+#pragma omp target teams distribute
+  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 target teams distribute
+  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 target teams distribute
+  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 target teams distribute
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    try { // OK
+      for (int j = 0; j < 10; ++j) {
+        if (a[i] > b[j])
+          throw a[i]; // OK
+      }
+      throw a[i]; // OK
+    } catch (float f) {
+      if (f > 0.1)
+        throw a[i]; // OK
+      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]; // OK
+    }
+  }
+  if (c[9] > 10)
+    throw c[9]; // OK
+
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i) {
+    struct S {
+      void g() { throw 0; }
+    };
+  }
+}
+
+void test_loop_firstprivate_lastprivate() {
+  S s(4);
+#pragma omp target teams distribute lastprivate(s) firstprivate(s)
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
+void test_ordered() {
+#pragma omp target teams distribute ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp target teams distribute'}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_map_messages.cpp b/test/OpenMP/target_teams_distribute_map_messages.cpp
new file mode 100644
index 0000000..5d815de
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_map_messages.cpp
@@ -0,0 +1,281 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  S2(S2 &s2):a(s2.a) { }
+  static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+  static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+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 2 {{defined as threadprivate or thread local}}
+
+typedef int from;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  T i, t[20];
+  T &j = i;
+  T *k = &j;
+  T x;
+  T y;
+  T to, tofrom, always;
+  const T (&l)[5] = da;
+
+
+#pragma omp target teams distribute map // expected-error {{expected '(' after 'map'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to:) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l[-1:]) // expected-error 2 {{array section must be a subset of the original array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(tofrom: t[:I])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(T) // expected-error {{'T' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to: to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} 
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(ca)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(e, g)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(da[:4])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note 2 {{used here}}
+#pragma omp target teams distribute map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
+{
+#pragma omp target teams distribute map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l)
+  for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target teams distribute map(always, tofrom: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(always: x) // expected-error {{missing map type}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(always, tofrom: always, tofrom, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  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);
+  S5 g(5);
+  int i;
+  int &j = i;
+  int *k = &j;
+  int x;
+  int y;
+  int to, tofrom, always;
+  const int (&l)[5] = da;
+
+#pragma omp target teams distribute map // expected-error {{expected '(' after 'map'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to:) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l[-1:]) // expected-error {{array section must be a subset of the original array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to: to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(argv[1])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(ca)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(e, g)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(da[:4])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note {{used here}}
+#pragma omp target teams distribute map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}}
+{
+#pragma omp target teams distribute map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l)
+  for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target teams distribute map(always, tofrom: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(always: x) // expected-error {{missing map type}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(always, tofrom: always, tofrom, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
diff --git a/test/OpenMP/target_teams_distribute_messages.cpp b/test/OpenMP/target_teams_distribute_messages.cpp
new file mode 100644
index 0000000..91f3c76
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_messages.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 -o - %s
+
+void foo() {
+}
+
+static int pvt;
+#pragma omp threadprivate(pvt)
+
+#pragma omp target teams distribute // expected-error {{unexpected OpenMP directive '#pragma omp target teams distribute'}}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute { // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute ( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute[ // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute] // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute } // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute
+  for (int i = 0; i < argc; ++i)
+    foo();
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+#pragma omp target teams distribute unknown()
+  for (int i = 0; i < argc; ++i)
+    foo();
+L1:
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute
+  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 target teams distribute
+      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 target teams distribute 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 target teams distribute
+  for (int i = 0; i < argc; ++i)
+  L2:
+  foo();
+#pragma omp target teams distribute
+  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 target teams distribute
+      for (int n = 0; n < 100; ++n) {
+  }
+
+#pragma omp target teams distribute copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target teams distribute'}}
+  for (int n = 0; n < 100; ++n) {}
+
+  return 0;
+}
+
+void test_ordered() {
+#pragma omp target teams distribute ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp target teams distribute'}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_misc_messages.c b/test/OpenMP/target_teams_distribute_misc_messages.c
new file mode 100644
index 0000000..bf4df08
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_misc_messages.c
@@ -0,0 +1,312 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target teams distribute'}}
+#pragma omp target teams distribute
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target teams distribute'}}
+#pragma omp target teams distribute foo
+
+void test_no_clause() {
+  int i;
+#pragma omp target teams distribute
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{statement after '#pragma omp target teams distribute' must be a for loop}}
+#pragma omp target teams distribute
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp target teams distribute
+  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 target teams distribute' are ignored}}
+#pragma omp target teams distribute 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 target teams distribute' are ignored}}
+#pragma omp target teams distribute;
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+#pragma omp target teams distribute private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+#pragma omp target teams distribute, private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+extern int foo();
+
+void test_collapse() {
+  int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp target teams distribute collapse
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute collapse(
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute collapse()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute collapse(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}  expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute collapse(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp target teams distribute 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 target teams distribute collapse(4
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute collapse(4,
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute collapse(4, )
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute', but found only 1}}
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute collapse(4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute collapse(4 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute collapse(4, , 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute', but found only 1}}
+#pragma omp target teams distribute 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 target teams distribute collapse(4, 8)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute', but found only 1}}
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target teams distribute collapse(2.5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target teams distribute collapse(foo())
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute collapse(-5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute collapse(0)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute collapse(5 - 5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+3 {{loop iteration variable in the associated loop of 'omp target teams distribute' directive may not be firstprivate, predetermined as private}}
+// expected-note@+1 {{defined as firstprivate}}
+#pragma omp target teams distribute collapse(2) firstprivate(i)
+  for (i = 0; i < 16; ++i)
+    for (int j = 0; j < 16; ++j)
+#pragma omp parallel for reduction(+ : i, j)
+      for (int k = 0; k < 16; ++k)
+        i += j;
+}
+
+void test_private() {
+  int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute 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 target teams distribute private(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute private(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute private()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute private(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute private(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute private(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute private(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute lastprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute lastprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute lastprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute lastprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute lastprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute lastprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute lastprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute firstprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute firstprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute firstprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute firstprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute firstprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute lastprivate(x) firstprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute lastprivate(x, y) firstprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute 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 target teams distribute
+  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 target teams distribute
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/target_teams_distribute_nowait_messages.cpp b/test/OpenMP/target_teams_distribute_nowait_messages.cpp
new file mode 100644
index 0000000..17aa1dc
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_nowait_messages.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -verify -fopenmp -o - %s
+
+void foo() {
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute nowait device (-10u)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_num_teams_messages.cpp b/test/OpenMP/target_teams_distribute_num_teams_messages.cpp
new file mode 100644
index 0000000..9b36e9c
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_num_teams_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <typename T, int C> // expected-note {{declared here}}
+T tmain(T argc) {
+  char **a;
+#pragma omp target teams distribute num_teams(C)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(T) // expected-error {{'T' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams // expected-error {{expected '(' after 'num_teams'}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(argc + argc)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'num_teams' clause}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(-10u)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute num_teams(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int i=0; i<100; i++) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute num_teams // expected-error {{expected '(' after 'num_teams'}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams () // expected-error {{expected expression}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams (argc + argc)
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams (argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'num_teams' clause}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams (-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams (-10u)
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute num_teams (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int i=0; i<100; i++) foo();
+
+  return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp b/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp
new file mode 100644
index 0000000..8df3c97
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+struct S {
+  S(): a(0) {}
+  S(int v) : a(v) {}
+  int a;
+  typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+  T a;
+  S7() : a(0) {}
+
+public:
+  S7(typename T::type v) : a(v) {
+#pragma omp target teams distribute parallel for private(a) private(this->a) private(T::a)
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
+  }
+  S7 &operator=(S7 &s) {
+#pragma omp target teams distribute parallel for private(a) private(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
+
+    foo();
+    return *this;
+  }
+  void foo() {
+    int b, argv, d, c, e, f;
+#pragma omp target teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+};
+// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+
+class S8 : public S7<S> {
+  S8() {}
+
+public:
+  S8(int v) : S7<S>(v){
+#pragma omp target teams distribute parallel for private(a) private(this->a) private(S7<S>::a) 
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
+  }
+  S8 &operator=(S8 &s) {
+#pragma omp target teams distribute parallel for private(a) private(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
+
+    bar();
+    return *this;
+  }
+  void bar() {
+    int b, argv, d, c, e, f8;
+#pragma omp target teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+};
+// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d)
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+// CHECK: static T a;
+  const T clen = 5;
+  const T alen = 16;
+  int arr[10];
+#pragma omp target teams distribute parallel for
+  for (int i=0; i < 2; ++i)
+    a = 2;
+// CHECK: #pragma omp target teams distribute parallel for
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target teams distribute parallel for private(argc, b), firstprivate(c, d), collapse(2)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+// CHECK: #pragma omp target teams distribute parallel for private(argc,b) firstprivate(c,d) collapse(2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: #pragma omp target teams distribute parallel for
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();  
+#pragma omp target teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < 10; ++k)
+      e += d + argc;
+// CHECK: #pragma omp target teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute parallel for linear(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute parallel for linear(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+  return T();
+}
+
+int main (int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+  const int clen = 5;
+  const int N = 10;
+  int arr[10];
+#pragma omp target teams distribute parallel for
+  for (int i=0; i < 2; ++i)
+    a = 2;
+// CHECK: #pragma omp target teams distribute parallel for
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target teams distribute parallel for private(argc,b),firstprivate(argv, c), collapse(2)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+// CHECK: #pragma omp target teams distribute parallel for private(argc,b) firstprivate(argv,c) collapse(2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i)foo();
+// CHECK: #pragma omp target teams distribute parallel for
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute parallel for linear(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute parallel for linear(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+  return (0);
+}
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_collapse_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_collapse_messages.cpp
new file mode 100644
index 0000000..bd94ba5
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_collapse_messages.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++98
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++11
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+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 target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute 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 strictly positive integer value}}
+#pragma omp target teams distribute 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 target teams distribute parallel for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute 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 target teams distribute parallel for', but found only 1}}
+
+#if __cplusplus >= 201103L
+// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used}}
+#endif
+// expected-error@+3 2 {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'collapse' clause}}
+// expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute 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 distribute 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];
+
+#if __cplusplus >= 201103L
+// expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+2 2 {{expression is not an integral constant expression}}
+#endif
+#pragma omp target teams distribute 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 target teams distribute parallel for collapse (1)
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}}
+  for (T i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp target teams distribute parallel for'}}
+  return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute parallel for', but found only 1}}
+
+#pragma omp target teams distribute parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute 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 target teams distribute parallel for', but found only 1}}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 {{non-constexpr function 'foobool' cannot be used}}
+#endif
+#pragma omp target teams distribute 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];
+
+#if __cplusplus >= 201103L
+// expected-note@+5 {{non-constexpr function 'foobool' cannot be used}}
+#endif
+// expected-error@+3 {{expression is not an integral constant expression}}
+// expected-error@+2 2 {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'collapse' clause}}
+// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute 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 target teams distribute 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];
+
+#if __cplusplus >= 201103L
+// expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+2 {{expression is not an integral constant expression}}
+#endif
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute parallel for collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo();
+
+#pragma omp target teams distribute parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp target teams distribute 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/target_teams_distribute_parallel_for_default_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp
new file mode 100644
index 0000000..db47e68
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo();
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for default // expected-error {{expected '(' after 'default'}}
+  for (int i=0; i<200; i++) foo();
+ #pragma omp target teams distribute parallel for default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<200; i++) foo();
+#pragma omp target teams distribute parallel for default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (int i=0; i<200; i++) foo();
+#pragma omp target teams distribute parallel for default (none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<200; i++) foo();
+#pragma omp target teams distribute parallel for default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'default' clause}}
+  for (int i=0; i<200; i++) foo();
+#pragma omp target teams distribute parallel for default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (int i=0; i<200; i++) foo();
+
+#pragma omp target teams distribute parallel for default(none)
+  for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_defaultmap_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_defaultmap_messages.cpp
new file mode 100644
index 0000000..ad0295d
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_defaultmap_messages.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+template <class T, typename S, int N, int ST>
+T tmain(T argc, S **argv) {
+  int i;
+#pragma omp target teams distribute parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp
new file mode 100644
index 0000000..ca7241a
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+class vector {
+  public:
+    int operator[](int index) { return 0; }
+};
+
+int main(int argc, char **argv, char *env[]) {
+  vector vec;
+  typedef float V __attribute__((vector_size(16)));
+  V a;
+  auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+  int i;
+
+#pragma omp target teams distribute parallel for depend // expected-error {{expected '(' after 'depend'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (out: ) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[0])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : ) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : main) // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[-1:0])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend(in : argv[ : argc][1 : argc - 1])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for depend(in : arr[0])
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_device_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_device_messages.cpp
new file mode 100644
index 0000000..b1b86cd
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_device_messages.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for device // expected-error {{expected '(' after 'device'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device (argc + argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device (argc), device (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'device' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device (-10u)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
new file mode 100644
index 0000000..d9913bc
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  char ** argv;
+  static T a;
+// CHECK: static T a;
+
+#pragma omp target teams distribute parallel for dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'dist_schedule' clause}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'dist_schedule' clause}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp
new file mode 100644
index 0000000..d4e7083
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp
@@ -0,0 +1,131 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  
+public:
+  S2() : a(0) {}
+  S2(const 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) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+  S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
+};
+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) { }
+};
+class S6 {
+  int a;
+public:
+  S6() : a(0) { }
+};
+
+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);
+  S6 p;
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute 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 target teams distribute parallel for firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate (argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate (argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate(ba)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate(da)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate(i)
+  for (j = 0; j < argc; ++j) foo();
+
+#pragma omp target teams distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for' directive may not be firstprivate, predetermined as private}}
+
+#pragma omp target teams distribute parallel for firstprivate(j)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(argc), firstprivate(argc) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp
new file mode 100644
index 0000000..82d39ac
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -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 target teams distribute parallel for if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target teams distribute parallel for'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'if' clause with 'target' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc) if (argc) // expected-error {{expected  'target' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(target: argc) if (argc) // expected-error {{expected  'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute parallel for'}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute 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();
+#pragma omp target teams distribute parallel for if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target teams distribute parallel for'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(target: argc) if (target:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'if' clause with 'target' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(parallel : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected  'target' directive name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(target: argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected  'parallel' directive name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute parallel for'}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_ast_print.cpp b/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_ast_print.cpp
new file mode 100644
index 0000000..c566319
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_ast_print.cpp
@@ -0,0 +1,318 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int da[5] = { 0 };
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target teams distribute parallel for is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(g) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(rg) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+  return;
+ }
+};
+// CHECK: struct SA
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: ST g[10];
+// CHECK-NEXT: STarr &rg = this->g;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = this->i;
+// CHECK-NEXT: int *k = &this->j;
+// CHECK-NEXT: int *&z = this->k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: arr &raa = this->aa;
+// CHECK-NEXT: func(
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(this->k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(this->z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(this->aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(this->raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(this->g)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(this->rg)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(this->da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T>
+T tmain(T argc) {
+  const T da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+#pragma omp target teams distribute parallel for is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(aa)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(raa)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(h)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(rh)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(da)
+  for (int i=0; i<100; i++)
+    ;
+  return 0;
+}
+
+// CHECK: template<> int tmain<int>(int argc) {
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+// CHECK: template<> int *tmain<int *>(int *argc) {
+// CHECK-NEXT: int *const da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int *i;
+// CHECK-NEXT: int *&j = i;
+// CHECK-NEXT: int **k = &j;
+// CHECK-NEXT: int **&z = k;
+// CHECK-NEXT: int *aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main(int argc, char **argv) {
+  const int da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+#pragma omp target teams distribute parallel for is_device_ptr(k)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for is_device_ptr(z)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for is_device_ptr(aa)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(aa)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for is_device_ptr(raa)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(raa)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for is_device_ptr(h)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(h)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for is_device_ptr(rh)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(rh)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for is_device_ptr(da)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for is_device_ptr(da)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+  return tmain<int>(argc) + *tmain<int *>(&argc);
+}
+#endif
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_messages.cpp
new file mode 100644
index 0000000..eaa3190
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_messages.cpp
@@ -0,0 +1,337 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fopenmp %s
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int d = 5;
+  const int da[5] = { 0 };
+  ST e;
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target teams distribute parallel for is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(g) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(rg) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+  return;
+ }
+};
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T, int I>
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target teams distribute parallel for is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(h) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(rh) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} expected-note{{defined as firstprivate}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} expected-note{{defined as private}}
+  for (int i=0; i<100; i++)
+    ;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target teams distribute parallel for is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(h) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(rh) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} expected-note{{defined as firstprivate}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} expected-note{{defined as private}}
+  for (int i=0; i<100; i++)
+    ;
+  return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
new file mode 100644
index 0000000..d31acef
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
@@ -0,0 +1,233 @@
+// RUN: %clang_cc1 -verify -fopenmp %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) {}
+  const S2 &operator =(const S2&) const;
+  S2 &operator =(const S2&);
+  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 {
+  int a;
+  S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+
+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 {
+  int a;
+  S4();             // expected-note 3 {{implicitly declared private here}}
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 {
+  int a;
+  S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+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);
+  I g(5);
+  int i;
+  int &j = i;
+#pragma omp target teams distribute parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute 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 target teams distribute parallel for lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute 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 target teams distribute parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for lastprivate(argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  int v = 0;
+#pragma omp target teams distribute parallel for lastprivate(i)
+  for (int k = 0; k < argc; ++k) {
+    i = k;
+    v += i;
+  }
+
+#pragma omp target teams distribute parallel for lastprivate(j) private(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for lastprivate(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp target teams distribute parallel for lastprivate(a)
+  for (int i = 0; i < 2; ++i) foo();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i;
+  float k;
+#pragma omp target teams distribute parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute 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 target teams distribute parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute 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 target teams distribute parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(ba)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+  int xa;
+#pragma omp target teams distribute parallel for lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute 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 target teams distribute parallel for lastprivate(xa)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(j)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+  static int si;
+#pragma omp target teams distribute parallel for lastprivate(si) // OK
+  for (i = 0; i < argc; ++i) si = i + 1;
+
+#pragma omp target teams distribute parallel for lastprivate(k) map(k) // expected-error {{lastprivate variable cannot be in a map clause in '#pragma omp target teams distribute parallel for' directive}} expected-note {{defined as lastprivate}}
+  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/target_teams_distribute_parallel_for_linear_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_linear_messages.cpp
new file mode 100644
index 0000000..82220dc
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_linear_messages.cpp
@@ -0,0 +1,248 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+namespace X {
+  int x;
+};
+
+struct B {
+  static int ib; // expected-note {{'B::ib' declared here}}
+  static int bfoo() { return 8; }
+};
+
+int bfoo() { return 4; }
+
+int z;
+const int C1 = 1;
+const int C2 = 2;
+void test_linear_colons()
+{
+  int B = 0;
+
+#pragma omp target teams distribute parallel for linear(B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for linear(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for linear(X::x : ::z)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for linear(B,::z, X::x)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for linear(::z)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for linear(B::bfoo()) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for linear(B::ib,B:C1+C2)
+  for (int i = 0; i < 10; ++i) ;
+}
+
+template<int L, class T, class N> T test_template(T* arr, N num) {
+  N i;
+  T sum = (T)0;
+  T ind2 = - num * L; // expected-note {{'ind2' defined here}}
+
+#pragma omp target teams distribute parallel for linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}}
+  for (i = 0; i < num; ++i) {
+    T cur = arr[(int)ind2];
+    ind2 += L;
+    sum += cur;
+  }
+  return T();
+}
+
+template<int LEN> int test_warn() {
+  int ind2 = 0;
+#pragma omp target teams distribute parallel for linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
+  for (int i = 0; i < 100; i++) {
+    ind2 += LEN;
+  }
+  return ind2;
+}
+
+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; // expected-note 2 {{'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;
+#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;
+
+#pragma omp target teams distribute parallel for linear // expected-error {{expected '(' after 'linear'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argc : 5)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear(e, g)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp parallel
+  {
+    int v = 0;
+    int i;
+    #pragma omp target teams distribute parallel for linear(v:i)
+    for (int k = 0; k < argc; ++k) { i = k; v += i; }
+  }
+
+#pragma omp target teams distribute parallel for linear(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  int v = 0;
+
+#pragma omp target teams distribute parallel for linear(v:j)
+  for (int k = 0; k < argc; ++k) { ++k; v += j; }
+
+#pragma omp target teams distribute parallel for linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+  return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace C {
+using A::x;
+}
+
+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);
+  // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+  test_warn<0>();
+
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute parallel for linear // expected-error {{expected '(' after 'linear'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+
+#pragma omp target teams distribute parallel for linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp parallel
+{
+  int i;
+#pragma omp target teams distribute parallel for linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear(i : 4)
+  for (int k = 0; k < argc; ++k) { ++k; i += 4; }
+}
+
+#pragma omp target teams distribute parallel for linear(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+  return 0;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp
new file mode 100644
index 0000000..83c78f2
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp
@@ -0,0 +1,624 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -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;
+// expected-note@+1 {{defined as threadprivate or thread local}}
+#pragma omp threadprivate(sii)
+static int globalii;
+
+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 target teams distribute parallel for
+  for (int i = 0; i < 10; i += 1) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for
+  for (char i = 0; i < 10; i += '\1') {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (long long i = 0; i < 10; i += 1.5) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for
+  for (long long i = 0; i < 'z'; i += 1u) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{variable must be of integer or random access iterator type}}
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{variable must be of integer or random access iterator type}}
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-warning@+2 {{expression result unused}}
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (ii + 1; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (c[ii] = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// Ok to skip parenthesises.
+  for (((ii)) = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0;; i++)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute parallel for
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute parallel for
+  for (ii = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; ++jj)
+    c[ii] = a[jj];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  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 target teams distribute parallel for
+  for (ii = 0; ii < 10; ii = ii + ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'float'}}
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+// Ok - step was converted to integer type.
+#pragma omp target teams distribute parallel for
+  for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; jj = ii + 2)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-warning@+2 {{relational comparison result unused}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii<10; jj> kk + 2)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10;)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-warning@+2 {{expression result unused}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; !ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; ii = ii < 10)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; ii < 10; ii = ii + 0)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; (ii) < 10; ii -= 25)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; (ii < 10); ii -= 0)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  for (ii = 0; ii > 10; (ii += 0))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  for ((ii = 0); ii > 10; (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; (ii < 10); (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for firstprivate(ii) // expected-note {{defined as firstprivate}}
+// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for' directive may not be firstprivate, predetermined as private}}
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for private(ii) // OK
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for lastprivate(ii) // OK
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for' directive may not be threadprivate or thread local, predetermined as private}}
+  for (sii = 0; sii < 10; sii++)
+    c[sii] = a[sii];
+
+  {
+#pragma omp target teams distribute parallel for collapse(2)
+  for (ii = 0; ii < 10; ii += 1)
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] += a[globalii] + ii;
+  }
+
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{statement after '#pragma omp target teams distribute parallel for' must be a for loop}}
+  for (auto &item : a) {
+    item = item + 1;
+  }
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int(*lb)[4] = nullptr;
+#pragma omp target teams distribute parallel for
+  for (int(*p)[4] = lb; p < lb + 8; ++p) {
+  }
+
+#pragma omp target teams distribute parallel for
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  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; }
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
+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;
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+int operator-(GoodIter a, GoodIter b) { return 0; }
+// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
+GoodIter operator-(GoodIter a) { return a; }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}}
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+#pragma omp target teams distribute parallel for
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(1, 2); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute parallel for
+// expected-error@+2 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
+// expected-error@+1 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (++begin; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute parallel for
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+#pragma omp target teams distribute parallel for
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-error@+1 {{invalid operands to binary expression ('Iter0' and 'int')}}
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// Initializer is constructor without params.
+// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}}
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+#pragma omp target teams distribute parallel for
+// expected-error@+2 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
+// expected-error@+1 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for
+// expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'float')}}
+// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+// Initializer is constructor with all default params.
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  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 target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+    for (IT I = begin; I < end; I = I + ST) {
+      ++I;
+    }
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+    for (IT I = begin; I <= end; I += ST) {
+      ++I;
+    }
+#pragma omp target teams distribute 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) {
+#pragma omp target teams distribute parallel for
+// expected-note@+2 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+#pragma omp target teams distribute parallel for
+// expected-note@+2 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+#pragma omp target teams distribute parallel for
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute parallel for
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    try { // OK
+      for (int j = 0; j < 10; ++j) {
+        if (a[i] > b[j])
+          throw a[i]; // OK
+      }
+      throw a[i]; // OK
+    } catch (float f) {
+      if (f > 0.1)
+        throw a[i]; // OK
+      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]; // OK
+    }
+  }
+  if (c[9] > 10)
+    throw c[9]; // OK
+
+#pragma omp target teams distribute 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 target teams distribute parallel for lastprivate(s) firstprivate(s)
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
+void test_ordered() {
+#pragma omp target teams distribute parallel for ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp target teams distribute parallel for'}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
+void test_nowait() {
+#pragma omp target teams distribute parallel for nowait nowait // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'nowait' clause}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp
new file mode 100644
index 0000000..326db95
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp
@@ -0,0 +1,281 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  S2(S2 &s2):a(s2.a) { }
+  static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+  static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+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 2 {{defined as threadprivate or thread local}}
+
+typedef int from;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  T i, t[20];
+  T &j = i;
+  T *k = &j;
+  T x;
+  T y;
+  T to, tofrom, always;
+  const T (&l)[5] = da;
+
+
+#pragma omp target teams distribute parallel for map // expected-error {{expected '(' after 'map'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to:) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l[-1:]) // expected-error 2 {{array section must be a subset of the original array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(tofrom: t[:I])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(T) // expected-error {{'T' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to: to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} 
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(ca)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(e, g)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(da[:4])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note 2 {{used here}}
+#pragma omp target teams distribute parallel for map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
+{
+#pragma omp target teams distribute parallel for map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l)
+  for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target teams distribute parallel for map(always, tofrom: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(always: x) // expected-error {{missing map type}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(always, tofrom: always, tofrom, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  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);
+  S5 g(5);
+  int i;
+  int &j = i;
+  int *k = &j;
+  int x;
+  int y;
+  int to, tofrom, always;
+  const int (&l)[5] = da;
+
+#pragma omp target teams distribute parallel for map // expected-error {{expected '(' after 'map'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to:) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l[-1:]) // expected-error {{array section must be a subset of the original array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to: to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(argv[1])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(ca)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(e, g)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(da[:4])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note {{used here}}
+#pragma omp target teams distribute parallel for map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}}
+{
+#pragma omp target teams distribute parallel for map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l)
+  for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target teams distribute parallel for map(always, tofrom: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(always: x) // expected-error {{missing map type}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(always, tofrom: always, tofrom, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
new file mode 100644
index 0000000..cb76ef2
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+static int pvt;
+#pragma omp threadprivate(pvt)
+
+#pragma omp target teams distribute parallel for // expected-error {{unexpected OpenMP directive '#pragma omp target teams distribute parallel for'}}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for { // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for ( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for[ // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for] // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for } // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < argc; ++i)
+    foo();
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+#pragma omp target teams distribute parallel for unknown()
+  for (int i = 0; i < argc; ++i)
+    foo();
+L1:
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute parallel for default(none)
+  for (int i = 0; i < 10; ++i)
+    ++argc; // expected-error {{ariable 'argc' must have explicitly specified data sharing attributes}}
+
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < argc; ++i)
+  L2: foo();
+  
+#pragma omp target teams distribute 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 target teams distribute parallel for
+      for (int n = 0; n < 100; ++n) {
+  }
+
+#pragma omp target teams distribute parallel for copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target teams distribute parallel for'}}
+  for (int n = 0; n < 100; ++n) {}
+
+  return 0;
+}
+
+void test_ordered() {
+#pragma omp target teams distribute parallel for ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp target teams distribute parallel for'}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_misc_messages.c b/test/OpenMP/target_teams_distribute_parallel_for_misc_messages.c
new file mode 100644
index 0000000..769be6c
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_misc_messages.c
@@ -0,0 +1,312 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target teams distribute parallel for'}}
+#pragma omp target teams distribute parallel for
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target teams distribute parallel for'}}
+#pragma omp target teams distribute parallel for foo
+
+void test_no_clause() {
+  int i;
+#pragma omp target teams distribute parallel for
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{statement after '#pragma omp target teams distribute parallel for' must be a for loop}}
+#pragma omp target teams distribute parallel for
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp target teams distribute 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 target teams distribute parallel for' are ignored}}
+#pragma omp target teams distribute 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 target teams distribute parallel for' are ignored}}
+#pragma omp target teams distribute parallel for;
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+#pragma omp target teams distribute parallel for private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+#pragma omp target teams distribute parallel for, private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+extern int foo();
+
+void test_collapse() {
+  int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp target teams distribute 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 target teams distribute parallel for collapse(
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute parallel for collapse(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp target teams distribute 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 target teams distribute parallel for collapse(4
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute 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 target teams distribute parallel for collapse(4,
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute 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 target teams distribute parallel for collapse(4, )
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for', but found only 1}}
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute parallel for collapse(4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute 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 target teams distribute parallel for collapse(4 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute 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 target teams distribute parallel for collapse(4, , 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for', but found only 1}}
+#pragma omp target teams distribute 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 target teams distribute parallel for collapse(4, 8)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for', but found only 1}}
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target teams distribute parallel for collapse(2.5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target teams distribute parallel for collapse(foo())
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for collapse(-5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for collapse(0)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for collapse(5 - 5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+3 {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for' directive may not be firstprivate, predetermined as private}}
+// expected-note@+1 {{defined as firstprivate}}
+#pragma omp target teams distribute parallel for collapse(2) firstprivate(i)
+  for (i = 0; i < 16; ++i)
+    for (int j = 0; j < 16; ++j)
+#pragma omp parallel for reduction(+ : i, j)
+      for (int k = 0; k < 16; ++k)
+        i += j;
+}
+
+void test_private() {
+  int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute 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 target teams distribute parallel for private(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute parallel for private(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for private()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for private(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute parallel for private(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute parallel for private(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute parallel for private(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute parallel for lastprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute parallel for lastprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for lastprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for lastprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute parallel for lastprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute parallel for lastprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute parallel for lastprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute parallel for firstprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute parallel for firstprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for firstprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for firstprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute parallel for firstprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute parallel for lastprivate(x) firstprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute parallel for lastprivate(x, y) firstprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute parallel for
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_nowait_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_nowait_messages.cpp
new file mode 100644
index 0000000..30a6224
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_nowait_messages.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fopenmp %s
+
+void foo() {
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for nowait device (-10u)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_num_teams_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_num_teams_messages.cpp
new file mode 100644
index 0000000..fdc2d9c
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_num_teams_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <typename T, int C> // expected-note {{declared here}}
+T tmain(T argc) {
+  char **a;
+#pragma omp target teams distribute parallel for num_teams(C)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(T) // expected-error {{'T' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams // expected-error {{expected '(' after 'num_teams'}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(argc + argc)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'num_teams' clause}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(-10u)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for num_teams(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int i=0; i<100; i++) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for num_teams // expected-error {{expected '(' after 'num_teams'}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams () // expected-error {{expected expression}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams (argc + argc)
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams (argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'num_teams' clause}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams (-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams (-10u)
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for num_teams (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int i=0; i<100; i++) foo();
+
+  return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_num_threads_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_num_threads_messages.cpp
new file mode 100644
index 0000000..afd8c36
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_num_threads_messages.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -verify -fopenmp -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 target teams distribute parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute 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 target teams distribute parallel for num_threads () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute 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 target teams distribute parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for num_threads (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute 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 target teams distribute parallel for num_threads (argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute 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 target teams distribute parallel for num_threads () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute 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 target teams distribute 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/target_teams_distribute_parallel_for_private_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp
new file mode 100644
index 0000000..d89cb1a
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp
@@ -0,0 +1,124 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  static float S2s; // expected-note {{predetermined as shared}}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+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}}
+class S4 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+public:
+  S4(int v):a(v) { }
+};
+class S5 { 
+  int a;
+  S5():a(0) {} // expected-note {{implicitly declared private here}}
+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;  // expected-note {{predetermined as shared}}
+  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  S4 e(4);
+  S5 g(5);
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute parallel for private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute 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 target teams distribute parallel for private () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute 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 target teams distribute parallel for private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private(ba)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private(ca) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private(da) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private(S2::S2s) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for shared(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for firstprivate(i), private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for private(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for reduction(+:i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp distribute private(i)
+  for (int k = 0; k < 10; ++k) {
+#pragma omp target teams distribute parallel for private(i)
+    for (int x = 0; x < 10; ++x) foo();
+  }
+
+#pragma omp target teams distribute parallel for firstprivate(i)
+  for (int k = 0; k < 10; ++k) {
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_messages.cpp
new file mode 100644
index 0000000..b2bbfa8
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_messages.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+template <class T, typename S, int N>
+T tmain(T argc, S **argv) {
+  T i;
+#pragma omp target teams distribute parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'proc_bind' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute 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 target teams distribute parallel for proc_bind(master)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target teams distribute parallel for proc_bind(spread)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'proc_bind' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute 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 target teams distribute parallel for proc_bind(master)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target teams distribute parallel for proc_bind(spread)
+  for (i = 0; i < argc; ++i)
+    foo();
+  return tmain<int, char, 3>(argc, argv);
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
new file mode 100644
index 0000000..ba9586a
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
@@ -0,0 +1,241 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %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); } // expected-note 3 {{implicitly declared private here}}
+
+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 3 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  int b;
+  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 3 {{'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 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+  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) {} // expected-note {{implicitly declared private here}}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o;
+
+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) {
+  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;
+#pragma omp target teams distribute parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute 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 j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(&& : argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute 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 j=0; j<100; j++) foo();
+#pragma omp parallel private(k)
+#pragma omp target teams distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams distribute parallel for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : fl)
+    for (int j=0; j<100; j++) foo();
+
+  return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  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;
+#pragma omp target teams distribute parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute 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 j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute 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 j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(&& : argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item 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 list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : o) // expected-error {{no viable overloaded '='}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute 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 j=0; j<100; j++) foo();
+#pragma omp parallel private(k)
+#pragma omp target teams distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams distribute parallel for reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for reduction(+ : fl)
+    for (int j=0; j<100; j++) foo();
+  static int m;
+#pragma omp target teams distribute parallel for reduction(+ : m) // OK
+  for (int j=0; j<100; j++) 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/target_teams_distribute_parallel_for_schedule_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_schedule_messages.cpp
new file mode 100644
index 0000000..54e3020
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_schedule_messages.cpp
@@ -0,0 +1,143 @@
+// RUN: %clang_cc1 -verify -fopenmp %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-error@+1 {{expected '(' after 'schedule'}}
+#pragma omp target teams distribute parallel for schedule
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for schedule (
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+#pragma omp target teams distribute parallel for schedule ()
+  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 target teams distribute parallel for schedule (auto
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for schedule (auto_dynamic
+  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 target teams distribute parallel for schedule (auto,
+  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 target teams distribute parallel for schedule (runtime, 3)
+  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 target teams distribute 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 strictly positive integer value}}
+#pragma omp target teams distribute 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];
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+#pragma omp target teams distribute parallel for schedule (dynamic, 1))
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute 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 target teams distribute parallel for' cannot contain more than one 'schedule' clause}}
+// expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute 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];
+
+// expected-error@+1 {{'S' does not refer to a value}}
+#pragma omp target teams distribute parallel for schedule (static, S)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for schedule (guided, argv[1]=2)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for schedule (dynamic, 1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for schedule (static, N)
+  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) {
+// expected-error@+1 {{expected '(' after 'schedule'}}
+#pragma omp target teams distribute parallel for schedule
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for schedule (
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+#pragma omp target teams distribute parallel for schedule ()
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for schedule (auto
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for schedule (auto_dynamic
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for schedule (auto,
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for schedule (runtime, 3)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for schedule (guided, 4
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+#pragma omp target teams distribute parallel for schedule (static, 2+2))
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute 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 target teams distribute parallel for' cannot contain more than one 'schedule' clause}}
+// expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute 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];
+
+// expected-error@+1 {{'S1' does not refer to a value}}
+#pragma omp target teams distribute parallel for schedule (guided, S1)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute parallel for schedule (static, argv[1]=2)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+3 {{statement after '#pragma omp target teams distribute 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 target teams distribute parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{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/target_teams_distribute_parallel_for_shared_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_shared_messages.cpp
new file mode 100644
index 0000000..4f90000
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_shared_messages.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -verify -fopenmp %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}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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 target teams distribute parallel for shared // expected-error {{expected '(' after 'shared'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared () // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared (argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared (a, b, c, d, f)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared (argv[1]) // expected-error {{expected variable name}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared(ba)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared(ca)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared(da)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared(e, g)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for private(i)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared(i)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for shared(j)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for firstprivate(i)
+  for (int j=0; j<100; j++) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_aligned_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_aligned_messages.cpp
new file mode 100644
index 0000000..df5468c
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_aligned_messages.cpp
@@ -0,0 +1,231 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp %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 target teams distribute parallel for simd aligned(B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd aligned(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd aligned(z:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd aligned(X::x : ::z) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd aligned(B,rp,::z: X::x) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd aligned(::z)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd aligned(B::bfoo()) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd aligned(B::ib,B:C1+C2) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+  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.
+
+#pragma omp target teams distribute parallel for simd aligned(arr:L) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}}
+  for (i = 0; i < num; ++i) {
+    T cur = arr[(int)ind2];
+    ind2 += L;
+    sum += cur;
+  }
+
+#pragma omp target teams distribute parallel for simd aligned(num:4) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  for (i = 0; i < num; ++i);
+
+  return T();
+}
+
+template<int LEN> int test_warn() {
+  int *ind2 = 0;
+#pragma omp target teams distribute parallel for simd aligned(ind2:LEN) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}}
+  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 target teams distribute parallel for simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned () // expected-error {{expected expression}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+// FIXME: Should argc really be a pointer?
+#pragma omp target teams distribute parallel for simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned(e, g)
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned(i) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+  #pragma omp parallel
+  {
+    int *v = 0;
+    I i;
+    #pragma omp target teams distribute parallel for simd aligned(v:16)
+      for (I k = 0; k < argc; ++k) { i = k; v += 2; }
+  }
+  float *f;
+
+#pragma omp target teams distribute parallel for simd aligned(f)
+  for (I k = 0; k < argc; ++k) ++k;
+
+  int v = 0;
+
+#pragma omp target teams distribute parallel for simd aligned(f:j) // expected-note {{initializer of 'j' is not a constant expression}} expected-error {{expression is not an integral constant expression}}
+
+  for (I k = 0; k < argc; ++k) { ++k; v += j; }
+
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams
+#pragma omp distribute simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams
+#pragma omp distribute simd aligned (argc) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (a, b) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  int *pargc = &argc;
+  // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
+  foomain<int*,char>(pargc,argv);
+  return 0;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp
new file mode 100644
index 0000000..29a0c6d
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp
@@ -0,0 +1,204 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+struct S {
+  S(): a(0) {}
+  S(int v) : a(v) {}
+  int a;
+  typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+  T a;
+  S7() : a(0) {}
+
+public:
+  S7(typename T::type v) : a(v) {
+#pragma omp target teams distribute parallel for simd private(a) private(this->a) private(T::a)
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
+  }
+  S7 &operator=(S7 &s) {
+#pragma omp target teams distribute parallel for simd private(a) private(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
+
+    foo();
+    bar();
+    return *this;
+  }
+  void foo() {
+    int b, argv, d, c, e, f;
+#pragma omp target teams distribute parallel for simd default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+  void bar() {
+    int arr[10];
+    const int alen = 16;
+    const int slen1 = 8;
+    const int slen2 = 8;
+#pragma omp target teams distribute parallel for simd simdlen(slen1) safelen(slen2) aligned(arr:alen)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+};
+// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute parallel for simd default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK: #pragma omp target teams distribute parallel for simd simdlen(slen1) safelen(slen2) aligned(arr: alen)
+
+class S8 : public S7<S> {
+  S8() {}
+
+public:
+  S8(int v) : S7<S>(v){
+#pragma omp target teams distribute parallel for simd private(a) private(this->a) private(S7<S>::a)
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
+  }
+  S8 &operator=(S8 &s) {
+#pragma omp target teams distribute parallel for simd private(a) private(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
+
+    foo();
+    bar();
+    return *this;
+  }
+  void bar() {
+    int b, argv, d, c, e, f8;
+#pragma omp target teams distribute parallel for simd default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+  void foo() {
+    const int alen = 16;
+    const int slen1 = 8;
+    const int slen2 = 8;
+    int arr[10];
+#pragma omp target teams distribute parallel for simd simdlen(slen1) safelen(slen2) aligned(arr:alen)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+};
+// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute parallel for simd default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d)
+// CHECK: #pragma omp target teams distribute parallel for simd simdlen(slen1) safelen(slen2) aligned(arr: alen)
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+// CHECK: static T a;
+  const T clen = 5;
+  const T alen = 16;
+  int arr[10];
+#pragma omp target teams distribute parallel for simd
+  for (int i=0; i < 2; ++i)
+    a = 2;
+// CHECK: #pragma omp target teams distribute parallel for simd
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target teams distribute parallel for simd private(argc, b), firstprivate(c, d), collapse(2)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+// CHECK: #pragma omp target teams distribute parallel for simd private(argc,b) firstprivate(c,d) collapse(2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: #pragma omp target teams distribute parallel for simd
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();  
+#pragma omp target teams distribute parallel for simd default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < 10; ++k)
+      e += d + argc;
+// CHECK: #pragma omp target teams distribute parallel for simd default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute parallel for simd simdlen(clen-1) linear(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute parallel for simd simdlen(clen - 1) linear(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute parallel for simd safelen(clen-1) aligned(arr:alen)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc + arr[k];
+// CHECK: #pragma omp target teams distribute parallel for simd safelen(clen - 1) aligned(arr: alen)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc + arr[k];
+  return T();
+}
+
+int main (int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+  const int clen = 5;
+  const int N = 10;
+  int arr[10];
+#pragma omp target teams distribute parallel for simd
+  for (int i=0; i < 2; ++i)
+    a = 2;
+// CHECK: #pragma omp target teams distribute parallel for simd
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target teams distribute parallel for simd private(argc,b),firstprivate(argv, c), collapse(2)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+// CHECK: #pragma omp target teams distribute parallel for simd private(argc,b) firstprivate(argv,c) collapse(2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i)foo();
+// CHECK: #pragma omp target teams distribute parallel for simd
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute parallel for simd default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute parallel for simd default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute parallel for simd simdlen(clen-1) linear(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute parallel for simd simdlen(clen - 1) linear(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute parallel for simd safelen(clen-1) aligned(arr:N+6)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc + arr[k];
+// CHECK: #pragma omp target teams distribute parallel for simd safelen(clen - 1) aligned(arr: N + 6)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc + arr[k];
+  return (0);
+}
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_messages.cpp
new file mode 100644
index 0000000..d0c8a58
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_messages.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++98
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++11
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+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 target teams distribute parallel for simd 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 target teams distribute parallel for simd 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 target teams distribute parallel for simd 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 target teams distribute parallel for simd 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 strictly positive integer value}}
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd', but found only 1}}
+
+#if __cplusplus >= 201103L
+// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used}}
+#endif
+// expected-error@+3 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'collapse' clause}}
+// expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd 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];
+
+#if __cplusplus >= 201103L
+// expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+2 2 {{expression is not an integral constant expression}}
+#endif
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd collapse (1)
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}}
+  for (T i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp target teams distribute parallel for simd'}}
+  return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for simd', but found only 1}}
+
+#pragma omp target teams distribute parallel for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd', but found only 1}}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 {{non-constexpr function 'foobool' cannot be used}}
+#endif
+#pragma omp target teams distribute parallel for 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];
+
+#if __cplusplus >= 201103L
+// expected-note@+5 {{non-constexpr function 'foobool' cannot be used}}
+#endif
+// expected-error@+3 {{expression is not an integral constant expression}}
+// expected-error@+2 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'collapse' clause}}
+// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd 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];
+
+#if __cplusplus >= 201103L
+// expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+2 {{expression is not an integral constant expression}}
+#endif
+#pragma omp target teams distribute parallel for 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];
+
+// expected-error@+3 {{statement after '#pragma omp target teams distribute parallel for simd' must be a for loop}}
+// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target teams distribute parallel for simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo();
+
+#pragma omp target teams distribute parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp target teams distribute parallel for simd'}}
+
+// 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/target_teams_distribute_parallel_for_simd_default_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp
new file mode 100644
index 0000000..7d07280
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo();
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for simd default // expected-error {{expected '(' after 'default'}}
+  for (int i=0; i<200; i++) foo();
+
+#pragma omp target teams distribute parallel for simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<200; i++) foo();
+
+#pragma omp target teams distribute parallel for simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (int i=0; i<200; i++) foo();
+
+#pragma omp target teams distribute parallel for simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<200; i++) foo();
+
+#pragma omp target teams distribute parallel for simd default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'default' clause}}
+  for (int i=0; i<200; i++) foo();
+
+#pragma omp target teams distribute parallel for simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (int i=0; i<200; i++) foo();
+
+#pragma omp target teams distribute parallel for simd default(none)
+  for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_defaultmap_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_defaultmap_messages.cpp
new file mode 100644
index 0000000..6f0ea7e
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_defaultmap_messages.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+template <class T, typename S, int N, int ST>
+T tmain(T argc, S **argv) {
+  int i;
+#pragma omp target teams distribute parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp
new file mode 100644
index 0000000..2dc9979
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+class vector {
+  public:
+    int operator[](int index) { return 0; }
+};
+
+int main(int argc, char **argv, char *env[]) {
+  vector vec;
+  typedef float V __attribute__((vector_size(16)));
+  V a;
+  auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+  int i;
+
+#pragma omp target teams distribute parallel for simd depend // expected-error {{expected '(' after 'depend'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (out: ) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[0])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : ) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : main) // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[-1:0])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend(in : argv[ : argc][1 : argc - 1])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd depend(in : arr[0])
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_device_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_device_messages.cpp
new file mode 100644
index 0000000..6a72579
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_device_messages.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for simd device // expected-error {{expected '(' after 'device'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device (argc + argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device (argc), device (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'device' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device (-10u)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
new file mode 100644
index 0000000..4fb3753
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  char ** argv;
+  static T a;
+// CHECK: static T a;
+
+#pragma omp target teams distribute parallel for simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'dist_schedule' clause}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'dist_schedule' clause}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp
new file mode 100644
index 0000000..d26044a
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp
@@ -0,0 +1,131 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  
+public:
+  S2() : a(0) {}
+  S2(const 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) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+  S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
+};
+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) { }
+};
+class S6 {
+  int a;
+public:
+  S6() : a(0) { }
+};
+
+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);
+  S6 p;
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate (argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate (argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate(ba)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate(da)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note 2 {{defined as private}}
+  for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for simd' directive may not be private, predetermined as linear}}
+
+#pragma omp target teams distribute parallel for simd firstprivate(i)
+  for (j = 0; j < argc; ++j) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for simd' directive may not be firstprivate, predetermined as linear}}
+
+#pragma omp target teams distribute parallel for simd firstprivate(j)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(argc), firstprivate(argc) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_if_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_if_messages.cpp
new file mode 100644
index 0000000..96db02e
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_if_messages.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -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 target teams distribute parallel for simd if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target // expected-error {{use of undeclared identifier 'target'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target: argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target: argc) if (target:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause with 'target' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected  'target' directive name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target: argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected  'parallel' directive name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target: argc) if(parallel:argc) // OK
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel: argc) if(target:argc) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for simd if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target // expected-error {{use of undeclared identifier 'target'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target: argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target: argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target: argc) if (target:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause with 'target' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected  'target' directive name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target: argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected  'parallel' directive name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(target: argc) if(parallel:argc) // OK
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd if(parallel: argc) if(target:argc) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_ast_print.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_ast_print.cpp
new file mode 100644
index 0000000..e73f40e
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_ast_print.cpp
@@ -0,0 +1,318 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int da[5] = { 0 };
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target teams distribute parallel for simd is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(g) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(rg) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+  return;
+ }
+};
+// CHECK: struct SA
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: ST g[10];
+// CHECK-NEXT: STarr &rg = this->g;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = this->i;
+// CHECK-NEXT: int *k = &this->j;
+// CHECK-NEXT: int *&z = this->k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: arr &raa = this->aa;
+// CHECK-NEXT: func(
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(this->k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(this->z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(this->aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(this->raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(this->g)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(this->rg)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(this->da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T>
+T tmain(T argc) {
+  const T da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+#pragma omp target teams distribute parallel for simd is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(aa)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(raa)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(h)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(rh)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(da)
+  for (int i=0; i<100; i++)
+    ;
+  return 0;
+}
+
+// CHECK: template<> int tmain<int>(int argc) {
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+// CHECK: template<> int *tmain<int *>(int *argc) {
+// CHECK-NEXT: int *const da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int *i;
+// CHECK-NEXT: int *&j = i;
+// CHECK-NEXT: int **k = &j;
+// CHECK-NEXT: int **&z = k;
+// CHECK-NEXT: int *aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main(int argc, char **argv) {
+  const int da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+#pragma omp target teams distribute parallel for simd is_device_ptr(k)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(z)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(aa)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(aa)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(raa)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(raa)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(h)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(h)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(rh)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(rh)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(da)
+// CHECK-NEXT: #pragma omp target teams distribute parallel for simd is_device_ptr(da)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+  return tmain<int>(argc) + *tmain<int *>(&argc);
+}
+#endif
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_messages.cpp
new file mode 100644
index 0000000..520f746
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_messages.cpp
@@ -0,0 +1,337 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fopenmp %s
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int d = 5;
+  const int da[5] = { 0 };
+  ST e;
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target teams distribute parallel for simd is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(g) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(rg) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+  return;
+ }
+};
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T, int I>
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target teams distribute parallel for simd is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(h) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(rh) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} expected-note{{defined as firstprivate}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} expected-note{{defined as private}}
+  for (int i=0; i<100; i++)
+    ;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target teams distribute parallel for simd is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(h) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(rh) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} expected-note{{defined as firstprivate}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute parallel for simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} expected-note{{defined as private}}
+  for (int i=0; i<100; i++)
+    ;
+  return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
new file mode 100644
index 0000000..954830e
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -0,0 +1,232 @@
+// RUN: %clang_cc1 -verify -fopenmp %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) {}
+  const S2 &operator =(const S2&) const;
+  S2 &operator =(const S2&);
+  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 {
+  int a;
+  S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+
+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 {
+  int a;
+  S4();             // expected-note 3 {{implicitly declared private here}}
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 {
+  int a;
+  S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+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);
+  I g(5);
+  int i;
+  int &j = i;
+#pragma omp target teams distribute parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate(argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  int v = 0;
+#pragma omp target teams distribute parallel for simd lastprivate(i)
+  for (int k = 0; k < argc; ++k) {
+    i = k;
+    v += i;
+  }
+
+#pragma omp target teams distribute parallel for simd lastprivate(j) private(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd lastprivate(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp target teams distribute parallel for simd lastprivate(a)
+  for (int i = 0; i < 2; ++i) foo();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i;
+  float k;
+#pragma omp target teams distribute parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(ba)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+  int xa;
+#pragma omp target teams distribute parallel for simd lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd lastprivate(xa)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(j)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute parallel for simd lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+  static int si;
+#pragma omp target teams distribute parallel for simd lastprivate(si) // OK
+  for (i = 0; i < argc; ++i) si = i + 1;
+
+#pragma omp target teams distribute parallel for simd lastprivate(k) map(k) // expected-error {{lastprivate variable cannot be in a map clause in '#pragma omp target teams distribute parallel for simd' directive}} expected-note {{defined as lastprivate}}
+  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/target_teams_distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
new file mode 100644
index 0000000..24c432a
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -0,0 +1,248 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+namespace X {
+  int x;
+};
+
+struct B {
+  static int ib; // expected-note {{'B::ib' declared here}}
+  static int bfoo() { return 8; }
+};
+
+int bfoo() { return 4; }
+
+int z;
+const int C1 = 1;
+const int C2 = 2;
+void test_linear_colons()
+{
+  int B = 0;
+
+#pragma omp target teams distribute parallel for simd linear(B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd linear(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd linear(X::x : ::z)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd linear(B,::z, X::x)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd linear(::z)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd linear(B::bfoo()) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute parallel for simd linear(B::ib,B:C1+C2)
+  for (int i = 0; i < 10; ++i) ;
+}
+
+template<int L, class T, class N> T test_template(T* arr, N num) {
+  N i;
+  T sum = (T)0;
+  T ind2 = - num * L; // expected-note {{'ind2' defined here}}
+
+#pragma omp target teams distribute parallel for simd linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}}
+  for (i = 0; i < num; ++i) {
+    T cur = arr[(int)ind2];
+    ind2 += L;
+    sum += cur;
+  }
+  return T();
+}
+
+template<int LEN> int test_warn() {
+  int ind2 = 0;
+  #pragma omp target teams distribute parallel for simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
+  for (int i = 0; i < 100; i++) {
+    ind2 += LEN;
+  }
+  return ind2;
+}
+
+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; // expected-note 2 {{'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;
+#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;
+
+#pragma omp target teams distribute parallel for simd linear // expected-error {{expected '(' after 'linear'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argc : 5)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear(e, g)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp parallel
+  {
+    int v = 0;
+    int i;
+    #pragma omp target teams distribute parallel for simd linear(v:i)
+    for (int k = 0; k < argc; ++k) { i = k; v += i; }
+  }
+
+#pragma omp target teams distribute parallel for simd linear(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  int v = 0;
+
+#pragma omp target teams distribute parallel for simd linear(v:j)
+  for (int k = 0; k < argc; ++k) { ++k; v += j; }
+
+#pragma omp target teams distribute parallel for simd linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+  return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace C {
+using A::x;
+}
+
+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);
+  // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+  test_warn<0>();
+
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute parallel for simd linear // expected-error {{expected '(' after 'linear'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+
+#pragma omp target teams distribute parallel for simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp parallel
+  {
+    int i;
+    #pragma omp target teams distribute parallel for simd linear(i)
+      for (int k = 0; k < argc; ++k) ++k;
+
+    #pragma omp target teams distribute parallel for simd linear(i : 4)
+      for (int k = 0; k < argc; ++k) { ++k; i += 4; }
+  }
+
+#pragma omp target teams distribute parallel for simd linear(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute parallel for simd linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+  return 0;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp
new file mode 100644
index 0000000..a6b6dd8
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp
@@ -0,0 +1,627 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -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;
+// expected-note@+1 {{defined as threadprivate or thread local}}
+#pragma omp threadprivate(sii)
+static int globalii;
+
+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 target teams distribute parallel for simd
+  for (int i = 0; i < 10; i += 1) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for simd
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for simd
+  for (char i = 0; i < 10; i += '\1') {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for simd
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (long long i = 0; i < 10; i += 1.5) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for simd
+  for (long long i = 0; i < 'z'; i += 1u) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{variable must be of integer or random access iterator type}}
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{variable must be of integer or random access iterator type}}
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for simd
+// expected-warning@+2 {{expression result unused}}
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (ii + 1; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (c[ii] = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for simd
+// Ok to skip parenthesises.
+  for (((ii)) = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for simd
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0;; i++)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute parallel for simd
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+// Ok - step was converted to integer type.
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (ii = 0; (ii < 10); (ii -= 0))
+    c[ii] = a[ii];
+
+// expected-error@+3 {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for simd' directive may not be firstprivate, predetermined as linear}}
+// expected-note@+1 {{defined as firstprivate}}
+#pragma omp target teams distribute parallel for simd firstprivate(ii) 
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for simd' directive may not be private, predetermined as linear}}
+#pragma omp target teams distribute parallel for simd private(ii) // expected-note {{defined as private}}
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for simd' directive may not be lastprivate, predetermined as linear}}
+#pragma omp target teams distribute parallel for simd lastprivate(ii) // expected-note {{defined as lastprivate}}
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for simd' directive may not be threadprivate or thread local, predetermined as linear}}
+#pragma omp target teams distribute parallel for simd
+  for (sii = 0; sii < 10; sii++)
+    c[sii] = a[sii];
+
+  {
+#pragma omp target teams distribute parallel for simd collapse(2)
+  for (ii = 0; ii < 10; ii += 1)
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] += a[globalii] + ii;
+  }
+
+// expected-error@+2 {{statement after '#pragma omp target teams distribute parallel for simd' must be a for loop}}
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int(*lb)[4] = nullptr;
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for 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; }
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
+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;
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+int operator-(GoodIter a, GoodIter b) { return 0; }
+// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
+GoodIter operator-(GoodIter a) { return a; }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}}
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+#pragma omp target teams distribute parallel for simd
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(1, 2); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+2 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
+// expected-error@+1 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (++begin; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute parallel for simd
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+1 {{invalid operands to binary expression ('Iter0' and 'int')}}
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// Initializer is constructor without params.
+// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}}
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+2 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
+// expected-error@+1 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+#pragma omp target teams distribute parallel for simd
+// expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'float')}}
+// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+// Initializer is constructor with all default params.
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  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 target teams distribute parallel for simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+    for (IT I = begin; I < end; I = I + ST) {
+      ++I;
+    }
+#pragma omp target teams distribute parallel for simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+    for (IT I = begin; I <= end; I += ST) {
+      ++I;
+    }
+#pragma omp target teams distribute parallel for 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) {
+#pragma omp target teams distribute parallel for simd
+// expected-note@+2 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+#pragma omp target teams distribute parallel for simd
+// expected-note@+2 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+#pragma omp target teams distribute parallel for simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+#pragma omp target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i) {
+    struct S {
+      void g() { throw 0; }
+    };
+  }
+}
+
+void test_loop_firstprivate_lastprivate() {
+  S s(4);
+#pragma omp target teams distribute parallel for simd lastprivate(s) firstprivate(s)
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
+void test_ordered() {
+#pragma omp target teams distribute parallel for simd ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp target teams distribute parallel for simd'}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
+void test_nowait() {
+#pragma omp target teams distribute parallel for simd nowait nowait // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'nowait' clause}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp
new file mode 100644
index 0000000..8f9c3e7
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp
@@ -0,0 +1,281 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  S2(S2 &s2):a(s2.a) { }
+  static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+  static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+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 2 {{defined as threadprivate or thread local}}
+
+typedef int from;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  T i, t[20];
+  T &j = i;
+  T *k = &j;
+  T x;
+  T y;
+  T to, tofrom, always;
+  const T (&l)[5] = da;
+
+
+#pragma omp target teams distribute parallel for simd map // expected-error {{expected '(' after 'map'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to:) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l[-1:]) // expected-error 2 {{array section must be a subset of the original array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(tofrom: t[:I])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(T) // expected-error {{'T' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to: to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} 
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(ca)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(e, g)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(da[:4])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note 2 {{used here}}
+#pragma omp target teams distribute parallel for simd map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
+{
+#pragma omp target teams distribute parallel for simd map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l)
+  for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target teams distribute parallel for simd map(always, tofrom: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(always: x) // expected-error {{missing map type}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(always, tofrom: always, tofrom, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  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);
+  S5 g(5);
+  int i;
+  int &j = i;
+  int *k = &j;
+  int x;
+  int y;
+  int to, tofrom, always;
+  const int (&l)[5] = da;
+
+#pragma omp target teams distribute parallel for simd map // expected-error {{expected '(' after 'map'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to:) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l[-1:]) // expected-error {{array section must be a subset of the original array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to: to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(argv[1])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(ca)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(e, g)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(da[:4])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note {{used here}}
+#pragma omp target teams distribute parallel for simd map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}}
+{
+#pragma omp target teams distribute parallel for simd map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l)
+  for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target teams distribute parallel for simd map(always, tofrom: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(always: x) // expected-error {{missing map type}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(always, tofrom: always, tofrom, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
new file mode 100644
index 0000000..7e16c79
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+static int pvt;
+#pragma omp threadprivate(pvt)
+
+#pragma omp target teams distribute parallel for simd // expected-error {{unexpected OpenMP directive '#pragma omp target teams distribute parallel for simd'}}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for simd { // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd ( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd[ // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd] // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd } // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < argc; ++i)
+    foo();
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+#pragma omp target teams distribute parallel for simd unknown()
+  for (int i = 0; i < argc; ++i)
+    foo();
+L1:
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd
+  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 target teams distribute parallel for simd
+      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 target teams distribute parallel for simd default(none)
+  for (int i = 0; i < 10; ++i)
+    ++argc; // expected-error {{ariable 'argc' must have explicitly specified data sharing attributes}}
+
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < argc; ++i)
+  L2:
+  foo();
+#pragma omp target teams distribute parallel for simd
+  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 target teams distribute parallel for simd
+      for (int n = 0; n < 100; ++n) {
+  }
+
+#pragma omp target teams distribute parallel for simd copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target teams distribute parallel for simd'}}
+  for (int n = 0; n < 100; ++n) {}
+
+  return 0;
+}
+
+void test_ordered() {
+#pragma omp target teams distribute parallel for simd ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp target teams distribute parallel for simd'}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_misc_messages.c b/test/OpenMP/target_teams_distribute_parallel_for_simd_misc_messages.c
new file mode 100644
index 0000000..d444844
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_misc_messages.c
@@ -0,0 +1,312 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target teams distribute parallel for simd'}}
+#pragma omp target teams distribute parallel for simd
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target teams distribute parallel for simd'}}
+#pragma omp target teams distribute parallel for simd foo
+
+void test_no_clause() {
+  int i;
+#pragma omp target teams distribute parallel for simd
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{statement after '#pragma omp target teams distribute parallel for simd' must be a for loop}}
+#pragma omp target teams distribute parallel for simd
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp target teams distribute parallel for simd
+  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 target teams distribute parallel for simd' are ignored}}
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd' are ignored}}
+#pragma omp target teams distribute parallel for simd;
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+#pragma omp target teams distribute parallel for simd private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+#pragma omp target teams distribute parallel for simd, private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+extern int foo();
+
+void test_collapse() {
+  int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp target teams distribute parallel for simd collapse
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd collapse(
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for simd collapse()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd collapse(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}  expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd collapse(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd collapse(4
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute parallel for simd collapse(4,
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute parallel for simd collapse(4, )
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for simd', but found only 1}}
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute parallel for simd collapse(4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute parallel for simd collapse(4 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute parallel for simd collapse(4, , 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for simd', but found only 1}}
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd collapse(4, 8)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute parallel for simd', but found only 1}}
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target teams distribute parallel for simd collapse(2.5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target teams distribute parallel for simd collapse(foo())
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for simd collapse(-5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for simd collapse(0)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for simd collapse(5 - 5)
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+4 {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp target teams distribute parallel for simd collapse(2) firstprivate(i)
+  for (i = 0; i < 16; ++i)
+    for (int j = 0; j < 16; ++j)
+#pragma omp parallel for reduction(+ : i, j)
+      for (int k = 0; k < 16; ++k)
+        i += j;
+}
+
+void test_private() {
+  int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd private(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute parallel for simd private(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for simd private()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for simd private(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute parallel for simd private(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute parallel for simd private(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute parallel for simd private(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for 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 target teams distribute parallel for simd lastprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute parallel for simd lastprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for simd lastprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for simd lastprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute parallel for simd lastprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute parallel for simd lastprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute parallel for simd lastprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd 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 target teams distribute parallel for simd firstprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute parallel for simd firstprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for simd firstprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute parallel for simd firstprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute parallel for simd firstprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute parallel for simd lastprivate(x) firstprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute parallel for simd lastprivate(x, y) firstprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for 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 target teams distribute parallel for simd
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_nowait_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_nowait_messages.cpp
new file mode 100644
index 0000000..4c65130
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_nowait_messages.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fopenmp %s
+
+void foo() {
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for simd nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd nowait device (-10u)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_num_teams_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_num_teams_messages.cpp
new file mode 100644
index 0000000..240d7d7
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_num_teams_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <typename T, int C> // expected-note {{declared here}}
+T tmain(T argc) {
+  char **a;
+#pragma omp target teams distribute parallel for simd num_teams(C)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(T) // expected-error {{'T' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams // expected-error {{expected '(' after 'num_teams'}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(argc + argc)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'num_teams' clause}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(-10u)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute parallel for simd num_teams(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int i=0; i<100; i++) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for simd num_teams // expected-error {{expected '(' after 'num_teams'}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams () // expected-error {{expected expression}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams (argc + argc)
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams (argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'num_teams' clause}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams (-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams (-10u)
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute parallel for simd num_teams (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int i=0; i<100; i++) foo();
+
+  return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_num_threads_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_num_threads_messages.cpp
new file mode 100644
index 0000000..9032996
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_num_threads_messages.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -verify -fopenmp %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 target teams distribute parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd num_threads (argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd 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/target_teams_distribute_parallel_for_simd_private_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp
new file mode 100644
index 0000000..20e1850
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp
@@ -0,0 +1,124 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  static float S2s; // expected-note {{predetermined as shared}}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+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}}
+class S4 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+public:
+  S4(int v):a(v) { }
+};
+class S5 { 
+  int a;
+  S5():a(0) {} // expected-note {{implicitly declared private here}}
+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;  // expected-note {{predetermined as shared}}
+  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  S4 e(4);
+  S5 g(5);
+  int i;
+  int &j = i;
+
+  #pragma omp target teams distribute parallel for simd private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private(ba)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private(ca) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private(da) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private(S2::S2s) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd shared(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd firstprivate(i), private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd private(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp target teams distribute parallel for simd reduction(+:i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp distribute private(i)
+  for (int k = 0; k < 10; ++k) {
+    #pragma omp target teams distribute parallel for simd private(i)
+    for (int x = 0; x < 10; ++x) foo();
+  }
+
+  #pragma omp target teams distribute parallel for simd firstprivate(i)
+  for (int k = 0; k < 10; ++k) {
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_messages.cpp
new file mode 100644
index 0000000..1471412
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_messages.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -verify -fopenmp -o - %s
+
+void foo();
+
+template <class T, typename S, int N>
+T tmain(T argc, S **argv) {
+  T i;
+#pragma omp target teams distribute parallel for simd proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'proc_bind' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp target teams distribute parallel for simd proc_bind(master)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target teams distribute parallel for simd proc_bind(spread)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute parallel for simd proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'proc_bind' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute parallel for simd proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp target teams distribute parallel for simd proc_bind(master)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target teams distribute parallel for simd proc_bind(spread)
+  for (i = 0; i < argc; ++i)
+    foo();
+  return tmain<int, char, 3>(argc, argv);
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
new file mode 100644
index 0000000..cadccbf
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
@@ -0,0 +1,241 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %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); } // expected-note 3 {{implicitly declared private here}}
+
+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 3 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  int b;
+  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 3 {{'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 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+  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) {} // expected-note {{implicitly declared private here}}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o;
+
+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) {
+  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;
+#pragma omp target teams distribute parallel for simd reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(&& : argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for 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 j=0; j<100; j++) foo();
+#pragma omp parallel private(k)
+#pragma omp target teams distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams distribute parallel for simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : fl)
+    for (int j=0; j<100; j++) foo();
+
+  return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  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;
+#pragma omp target teams distribute parallel for simd reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for 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 j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(&& : argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item 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 list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : o) // expected-error {{no viable overloaded '='}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for 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 j=0; j<100; j++) foo();
+#pragma omp parallel private(k)
+#pragma omp target teams distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams distribute parallel for simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd reduction(+ : fl)
+    for (int j=0; j<100; j++) foo();
+  static int m;
+#pragma omp target teams distribute parallel for simd reduction(+ : m) // OK
+  for (int j=0; j<100; j++) 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/target_teams_distribute_parallel_for_simd_safelen_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_safelen_messages.cpp
new file mode 100644
index 0000000..beb3c1e
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_safelen_messages.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+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 target teams distribute parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen ( // 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 target teams distribute parallel for simd safelen () // expected-error {{expected expression}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}}
+  for (int i = ST; i < N; i++) 
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+  
+#pragma omp target teams distribute parallel for simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} 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 target teams distribute parallel for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = ST; i < N; i++)
+     argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen ((ST > 0) ? 1 + ST : 2)
+  for (int i = ST; i < N; i++) 
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus >= 201103L
+  // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen (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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (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 target teams distribute parallel for simd safelen (4)
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly 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 target teams distribute parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute parallel for simd safelen ( // 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 target teams distribute parallel for simd safelen () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute parallel for simd safelen (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 target teams distribute parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+  
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (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];
+
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} 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];
+
+#pragma omp target teams distribute parallel for simd safelen (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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (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-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target teams distribute parallel for simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo(); // expected-error {{statement after '#pragma omp target teams distribute parallel for simd' must be a for loop}}
+
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+  return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_messages.cpp
new file mode 100644
index 0000000..773a148
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_messages.cpp
@@ -0,0 +1,143 @@
+// RUN: %clang_cc1 -verify -fopenmp %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-error@+1 {{expected '(' after 'schedule'}}
+#pragma omp target teams distribute parallel for simd schedule
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd schedule (
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+#pragma omp target teams distribute parallel for simd schedule ()
+  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 target teams distribute parallel for simd schedule (auto
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd schedule (auto_dynamic
+  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 target teams distribute parallel for simd schedule (auto,
+  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 target teams distribute parallel for simd schedule (runtime, 3)
+  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 target teams distribute parallel for simd 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 strictly positive integer value}}
+#pragma omp target teams distribute parallel for simd 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];
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+#pragma omp target teams distribute parallel for simd schedule (dynamic, 1))
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd' cannot contain more than one 'schedule' clause}}
+// expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for simd 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];
+
+// expected-error@+1 {{'S' does not refer to a value}}
+#pragma omp target teams distribute parallel for simd schedule (static, S)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd schedule (guided, argv[1]=2)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd schedule (dynamic, 1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for simd schedule (static, N)
+  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) {
+// expected-error@+1 {{expected '(' after 'schedule'}}
+#pragma omp target teams distribute parallel for simd schedule
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd schedule (
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+#pragma omp target teams distribute parallel for simd schedule ()
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd schedule (auto
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd schedule (auto_dynamic
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd schedule (auto,
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd schedule (runtime, 3)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute parallel for simd schedule (guided, 4
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+#pragma omp target teams distribute parallel for simd schedule (static, 2+2))
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute parallel for simd 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 target teams distribute parallel for simd' cannot contain more than one 'schedule' clause}}
+// expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute parallel for simd 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];
+
+// expected-error@+1 {{'S1' does not refer to a value}}
+#pragma omp target teams distribute parallel for simd schedule (guided, S1)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute parallel for simd schedule (static, argv[1]=2)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+3 {{statement after '#pragma omp target teams distribute parallel for simd' must be a for loop}}
+// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target teams distribute parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{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/target_teams_distribute_parallel_for_simd_shared_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_shared_messages.cpp
new file mode 100644
index 0000000..cbef07a
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_shared_messages.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -verify -fopenmp %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}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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 target teams distribute parallel for simd shared // expected-error {{expected '(' after 'shared'}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared () // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared (argc)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared (a, b, c, d, f)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared (argv[1]) // expected-error {{expected variable name}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared(ba)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared(ca)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared(da)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared(e, g)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd private(i)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared(i)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd shared(j)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute parallel for simd firstprivate(i)
+  for (int j=0; j<100; j++) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_simdlen_messages.cpp
new file mode 100644
index 0000000..c2a82d5
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_simdlen_messages.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+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 target teams distribute parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen ( // 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 target teams distribute parallel for simd safelen () // expected-error {{expected expression}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}}
+  for (int i = ST; i < N; i++) 
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+  
+#pragma omp target teams distribute parallel for simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} 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 target teams distribute parallel for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = ST; i < N; i++)
+     argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen ((ST > 0) ? 1 + ST : 2)
+  for (int i = ST; i < N; i++) 
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus >= 201103L
+  // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen (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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (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 target teams distribute parallel for simd safelen (4)
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute parallel for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly 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 target teams distribute parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute parallel for simd safelen ( // 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 target teams distribute parallel for simd safelen () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute parallel for simd safelen (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 target teams distribute parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+  
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (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];
+
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} 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];
+
+#pragma omp target teams distribute parallel for simd safelen (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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute parallel for simd safelen (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-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target teams distribute parallel for simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo(); // expected-error {{statement after '#pragma omp target teams distribute parallel for simd' must be a for loop}}
+
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+  return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_thread_limit_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_thread_limit_messages.cpp
new file mode 100644
index 0000000..159d1b0
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_thread_limit_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <typename T, int C> // expected-note {{declared here}}
+T tmain(T argc) {
+  char **a;
+#pragma omp target teams distribute parallel for simd thread_limit(C)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(T) // expected-error {{'T' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit // expected-error {{expected '(' after 'thread_limit'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit() // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(argc + argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'thread_limit' clause}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(-10u)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute parallel for simd thread_limit(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int j=0; j<100; j++) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for simd thread_limit // expected-error {{expected '(' after 'thread_limit'}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit () // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit (argc + argc)
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit (argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'thread_limit' clause}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit (-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit (-10u)
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for simd thread_limit (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int j=0; j<100; j++) foo();
+
+  return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_thread_limit_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_thread_limit_messages.cpp
new file mode 100644
index 0000000..1db0726
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_parallel_for_thread_limit_messages.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <typename T, int C> // expected-note {{declared here}}
+T tmain(T argc) {
+  char **a;
+#pragma omp target teams distribute parallel for thread_limit(C)
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(T) // expected-error {{'T' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit // expected-error {{expected '(' after 'thread_limit'}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit() // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(argc + argc)
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'thread_limit' clause}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(-10u)
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int j=0; j<100; j++) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute parallel for thread_limit // expected-error {{expected '(' after 'thread_limit'}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit () // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit (argc + argc)
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit (argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'thread_limit' clause}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit (-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit (-10u)
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute parallel for thread_limit (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int j=0; j<100; j++) foo();
+
+  return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_private_messages.cpp b/test/OpenMP/target_teams_distribute_private_messages.cpp
new file mode 100644
index 0000000..fcbd4f8
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_private_messages.cpp
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  static float S2s; // expected-note {{predetermined as shared}}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+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}}
+class S4 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+public:
+  S4(int v):a(v) { }
+};
+class S5 { 
+  int a;
+  S5():a(0) {} // expected-note {{implicitly declared private here}}
+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;  // expected-note {{predetermined as shared}}
+  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  S4 e(4);
+  S5 g(5);
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private(ba)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private(ca) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private(da) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private(S2::S2s) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute shared(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute firstprivate(i), private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute private(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_reduction_messages.cpp
new file mode 100644
index 0000000..d52ee07
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_reduction_messages.cpp
@@ -0,0 +1,246 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+void foobar(int &ref) {
+#pragma omp target teams distribute reduction(+:ref)
+  for (int j=0; j<100; j++) foo();
+}
+
+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); } // expected-note 3 {{implicitly declared private here}}
+
+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 3 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  int b;
+  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 3 {{'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 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+  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) {} // expected-note {{implicitly declared private here}}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o;
+
+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) {
+  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;
+#pragma omp target teams distribute reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(&& : argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel private(k)
+#pragma omp target teams distribute reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams distribute reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : fl)
+    for (int j=0; j<100; j++) foo();
+
+  return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  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;
+#pragma omp target teams distribute reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(&& : argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(min : a, b, c, d, f) // expected-error {{a reduction list item 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 list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : o) // expected-error {{no viable overloaded '='}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel private(k)
+#pragma omp target teams distribute reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams distribute reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute reduction(+ : fl)
+    for (int j=0; j<100; j++) foo();
+  static int m;
+#pragma omp target teams distribute reduction(+ : m) // OK
+  for (int j=0; j<100; j++) 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/target_teams_distribute_shared_messages.cpp b/test/OpenMP/target_teams_distribute_shared_messages.cpp
new file mode 100644
index 0000000..13f4d47
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_shared_messages.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -verify -fopenmp %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}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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 target teams distribute shared // expected-error {{expected '(' after 'shared'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared () // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared (argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared (a, b, c, d, f)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared (argv[1]) // expected-error {{expected variable name}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared(ba)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared(ca)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared(da)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared(e, g)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute private(i)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared(i)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared(j)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute firstprivate(i)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared(i)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute shared(j)
+  for (int j=0; j<100; j++) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_aligned_messages.cpp b/test/OpenMP/target_teams_distribute_simd_aligned_messages.cpp
new file mode 100644
index 0000000..e9df563
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_aligned_messages.cpp
@@ -0,0 +1,231 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp %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 target teams distribute simd aligned(B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd aligned(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd aligned(z:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd aligned(X::x : ::z) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd aligned(B,rp,::z: X::x) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd aligned(::z)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd aligned(B::bfoo()) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd aligned(B::ib,B:C1+C2) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+  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.
+
+#pragma omp target teams distribute simd aligned(arr:L) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}}
+  for (i = 0; i < num; ++i) {
+    T cur = arr[(int)ind2];
+    ind2 += L;
+    sum += cur;
+  }
+
+#pragma omp target teams distribute simd aligned(num:4) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  for (i = 0; i < num; ++i);
+
+  return T();
+}
+
+template<int LEN> int test_warn() {
+  int *ind2 = 0;
+#pragma omp target teams distribute simd aligned(ind2:LEN) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}}
+  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 target teams distribute simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned () // expected-error {{expected expression}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+// FIXME: Should argc really be a pointer?
+#pragma omp target teams distribute simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned(e, g)
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned(i) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  for (I k = 0; k < argc; ++k) ++k;
+
+  #pragma omp parallel
+  {
+    int *v = 0;
+    I i;
+    #pragma omp target teams distribute simd aligned(v:16)
+      for (I k = 0; k < argc; ++k) { i = k; v += 2; }
+  }
+  float *f;
+
+#pragma omp target teams distribute simd aligned(f)
+  for (I k = 0; k < argc; ++k) ++k;
+
+  int v = 0;
+
+#pragma omp target teams distribute simd aligned(f:j) // expected-note {{initializer of 'j' is not a constant expression}} expected-error {{expression is not an integral constant expression}}
+
+  for (I k = 0; k < argc; ++k) { ++k; v += j; }
+
+#pragma omp target teams distribute 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 target teams distribute simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams
+#pragma omp distribute simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams
+#pragma omp distribute simd aligned (argc) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (a, b) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  int *pargc = &argc;
+  // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
+  foomain<int*,char>(pargc,argv);
+  return 0;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_simd_ast_print.cpp b/test/OpenMP/target_teams_distribute_simd_ast_print.cpp
new file mode 100644
index 0000000..77732ef
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_ast_print.cpp
@@ -0,0 +1,198 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+struct S {
+  S(): a(0) {}
+  S(int v) : a(v) {}
+  int a;
+  typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+  T a;
+  S7() : a(0) {}
+
+public:
+  S7(typename T::type v) : a(v) {
+#pragma omp target teams distribute simd private(a) private(this->a) private(T::a)
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
+  }
+  S7 &operator=(S7 &s) {
+#pragma omp target teams distribute simd private(a) private(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
+    return *this;
+  }
+  void foo() {
+    int b, argv, d, c, e, f;
+#pragma omp target teams distribute simd private(b), firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+  void bar() {
+    int arr[10];
+    const int alen = 16;
+    const int slen1 = 8;
+    const int slen2 = 8;
+#pragma omp target teams distribute simd simdlen(slen1) safelen(slen2) aligned(arr:alen)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+};
+// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute simd private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK: #pragma omp target teams distribute simd simdlen(slen1) safelen(slen2) aligned(arr: alen)
+// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a) private(this->S::a)
+
+class S8 : public S7<S> {
+  S8() {}
+
+public:
+  S8(int v) : S7<S>(v){
+#pragma omp target teams distribute simd private(a) private(this->a) private(S7<S>::a)
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
+  }
+  S8 &operator=(S8 &s) {
+#pragma omp target teams distribute simd private(a) private(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
+    return *this;
+  }
+  void bar() {
+    int b, argv, d, c, e, f;
+#pragma omp target teams distribute simd private(b), firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+  void foo() {
+    const int alen = 16;
+    const int slen1 = 8;
+    const int slen2 = 8;
+    int arr[10];
+#pragma omp target teams distribute simd simdlen(slen1) safelen(slen2) aligned(arr:alen)
+    for (int k = 0; k < a.a; ++k)
+      ++a.a;
+  }
+};
+// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute simd private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK: #pragma omp target teams distribute simd simdlen(slen1) safelen(slen2) aligned(arr: alen)
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+// CHECK: static T a;
+  const T clen = 5;
+  const T alen = 16;
+  int arr[10];
+#pragma omp target teams distribute simd
+  for (int i=0; i < 2; ++i)
+    a = 2;
+// CHECK: #pragma omp target teams distribute simd
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target teams distribute simd private(argc, b), firstprivate(c, d), collapse(2)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+// CHECK: #pragma omp target teams distribute simd private(argc,b) firstprivate(c,d) collapse(2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: #pragma omp target teams distribute simd
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();  
+#pragma omp target teams distribute simd private(b), firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+    for (int k = 0; k < 10; ++k)
+      e += d + argc;
+// CHECK: #pragma omp target teams distribute simd private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute simd simdlen(clen-1) linear(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute simd simdlen(clen - 1) linear(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute simd safelen(clen-1) aligned(arr:alen)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc + arr[k];
+// CHECK: #pragma omp target teams distribute simd safelen(clen - 1) aligned(arr: alen)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc + arr[k];
+  return T();
+}
+
+int main (int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+  const int clen = 5;
+  const int N = 10;
+  int arr[10];
+#pragma omp target teams distribute simd
+  for (int i=0; i < 2; ++i)
+    a = 2;
+// CHECK: #pragma omp target teams distribute simd
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target teams distribute simd private(argc,b),firstprivate(argv, c), collapse(2)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+// CHECK: #pragma omp target teams distribute simd private(argc,b) firstprivate(argv,c) collapse(2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+  for (int i = 0; i < 10; ++i)
+    foo();
+// CHECK: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i)foo();
+// CHECK: #pragma omp target teams distribute simd
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp target teams distribute simd private(b), firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute simd private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute simd simdlen(clen-1) linear(d)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc;
+// CHECK: #pragma omp target teams distribute simd simdlen(clen - 1) linear(d)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc;
+#pragma omp target teams distribute simd safelen(clen-1) aligned(arr:N+6)
+  for (int k = 0; k < 10; ++k)
+    e += d + argc + arr[k];
+// CHECK: #pragma omp target teams distribute simd safelen(clen - 1) aligned(arr: N + 6)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: e += d + argc + arr[k];
+  return (0);
+}
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_collapse_messages.cpp b/test/OpenMP/target_teams_distribute_simd_collapse_messages.cpp
new file mode 100644
index 0000000..39937f9
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_collapse_messages.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+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 target teams distribute simd 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 target teams distribute simd 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 target teams distribute simd 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 target teams distribute simd 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 strictly positive integer value}}
+#pragma omp target teams distribute simd 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 target teams distribute simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute 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 target teams distribute simd', but found only 1}}
+
+// expected-error@+6 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'collapse' clause}}
+// expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute simd 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 distribute 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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute simd 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 target teams distribute simd collapse (1)
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}}
+  for (T i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp target teams distribute simd'}}
+  return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute simd 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 target teams distribute simd 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 target teams distribute 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 target teams distribute 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 target teams distribute simd', but found only 1}}
+
+#pragma omp target teams distribute simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute 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 target teams distribute simd', but found only 1}}
+
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute 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@+6 {{expression is not an integral constant expression}}
+// expected-error@+5 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'collapse' clause}}
+// expected-error@+4 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#if __cplusplus >= 201103L
+// expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute simd 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 target teams distribute simd 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];
+
+#if __cplusplus >= 201103L
+  // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#else
+  // expected-error@+2 {{expression is not an integral constant expression}}
+#endif
+#pragma omp target teams distribute 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];
+
+// expected-error@+3 {{statement after '#pragma omp target teams distribute simd' must be a for loop}}
+// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target teams distribute simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo();
+
+#pragma omp target teams distribute simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp target teams distribute simd'}}
+
+// 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/target_teams_distribute_simd_defaultmap_messages.cpp b/test/OpenMP/target_teams_distribute_simd_defaultmap_messages.cpp
new file mode 100644
index 0000000..3bea411
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_defaultmap_messages.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+template <class T, typename S, int N, int ST>
+T tmain(T argc, S **argv) {
+  int i;
+#pragma omp target teams distribute simd defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute simd defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp b/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp
new file mode 100644
index 0000000..39d12d8
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+class vector {
+  public:
+    int operator[](int index) { return 0; }
+};
+
+int main(int argc, char **argv, char *env[]) {
+  vector vec;
+  typedef float V __attribute__((vector_size(16)));
+  V a;
+  auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+  int i;
+
+#pragma omp target teams distribute simd depend // expected-error {{expected '(' after 'depend'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (out: ) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[0])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : ) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : main) // expected-error {{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[-1:0])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend(in : argv[ : argc][1 : argc - 1])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd depend(in : arr[0])
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_device_messages.cpp b/test/OpenMP/target_teams_distribute_simd_device_messages.cpp
new file mode 100644
index 0000000..e9246cb
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_device_messages.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute simd device // expected-error {{expected '(' after 'device'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device (argc + argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device (argc), device (argc+1) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'device' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device (-10u)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp b/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
new file mode 100644
index 0000000..9b9239d
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  char ** argv;
+  static T a;
+// CHECK: static T a;
+
+#pragma omp target teams distribute simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'dist_schedule' clause}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'dist_schedule' clause}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i) foo();
+
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp
new file mode 100644
index 0000000..b9b039e
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp
@@ -0,0 +1,134 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  
+public:
+  S2() : a(0) {}
+  S2(const 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) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}} expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+  S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}} expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
+};
+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) { }
+};
+class S6 {
+  int a;
+public:
+  S6() : a(0) { }
+};
+
+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);
+  S6 p;
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute simd firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate (argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate (argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate(ba)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate(da)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note 2 {{defined as private}}
+  for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be private, predetermined as linear}}
+
+#pragma omp target teams distribute simd firstprivate(i)
+  for (j = 0; j < argc; ++j) foo();
+
+#pragma omp target teams distribute simd firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be firstprivate, predetermined as linear}}
+
+#pragma omp target teams distribute simd firstprivate(j)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(argc), firstprivate(argc) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate(argc) map(argc) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target teams distribute simd' directive}} expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_if_messages.cpp b/test/OpenMP/target_teams_distribute_simd_if_messages.cpp
new file mode 100644
index 0000000..6cb2ad4
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_if_messages.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -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 target teams distribute simd if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target // expected-error {{use of undeclared identifier 'target'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target: argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target : argc) if (distribute:argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute simd'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target: argc) if (target:argc) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'if' clause with 'target' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target: argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute simd'}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute simd if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target // expected-error {{use of undeclared identifier 'target'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target: argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target: argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target : argc) if (distribute:argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute simd'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target: argc) if (target:argc) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'if' clause with 'target' name modifier}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(target: argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{no more 'if' clause is allowed}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute simd'}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_is_device_ptr_ast_print.cpp b/test/OpenMP/target_teams_distribute_simd_is_device_ptr_ast_print.cpp
new file mode 100644
index 0000000..61aede4
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_is_device_ptr_ast_print.cpp
@@ -0,0 +1,318 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int da[5] = { 0 };
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target teams distribute simd is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(g) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(rg) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+  return;
+ }
+};
+// CHECK: struct SA
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: ST g[10];
+// CHECK-NEXT: STarr &rg = this->g;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = this->i;
+// CHECK-NEXT: int *k = &this->j;
+// CHECK-NEXT: int *&z = this->k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: arr &raa = this->aa;
+// CHECK-NEXT: func(
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(this->k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(this->z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(this->aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(this->raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(this->g)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(this->rg)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(this->da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T>
+T tmain(T argc) {
+  const T da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+#pragma omp target teams distribute simd is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(aa)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(raa)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(h)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(rh)
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(da)
+  for (int i=0; i<100; i++)
+    ;
+  return 0;
+}
+
+// CHECK: template<> int tmain<int>(int argc) {
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+// CHECK: template<> int *tmain<int *>(int *argc) {
+// CHECK-NEXT: int *const da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int *i;
+// CHECK-NEXT: int *&j = i;
+// CHECK-NEXT: int **k = &j;
+// CHECK-NEXT: int **&z = k;
+// CHECK-NEXT: int *aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(k)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(z)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(aa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(raa)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(h)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(rh)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(da)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main(int argc, char **argv) {
+  const int da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+#pragma omp target teams distribute simd is_device_ptr(k)
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(k)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute simd is_device_ptr(z)
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(z)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute simd is_device_ptr(aa)
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(aa)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute simd is_device_ptr(raa)
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(raa)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute simd is_device_ptr(h)
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(h)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute simd is_device_ptr(rh)
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(rh)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+#pragma omp target teams distribute simd is_device_ptr(da)
+// CHECK-NEXT: #pragma omp target teams distribute simd is_device_ptr(da)
+  for (int i=0; i<100; i++)
+    ;
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: ;
+  return tmain<int>(argc) + *tmain<int *>(&argc);
+}
+#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_is_device_ptr_messages.cpp b/test/OpenMP/target_teams_distribute_simd_is_device_ptr_messages.cpp
new file mode 100644
index 0000000..013b703
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_is_device_ptr_messages.cpp
@@ -0,0 +1,337 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fopenmp %s
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int d = 5;
+  const int da[5] = { 0 };
+  ST e;
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target teams distribute simd is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(g) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(rg) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+  return;
+ }
+};
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T, int I>
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target teams distribute simd is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(h) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(rh) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} expected-note{{defined as firstprivate}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} expected-note{{defined as private}}
+  for (int i=0; i<100; i++)
+    ;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target teams distribute simd is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(k) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(z) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(aa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(raa) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(h) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(rh) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(da) // OK
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} expected-note{{defined as firstprivate}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}}
+  for (int i=0; i<100; i++)
+    ;
+#pragma omp target teams distribute simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} expected-note{{defined as private}}
+  for (int i=0; i<100; i++)
+    ;
+  return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
new file mode 100644
index 0000000..3b533e2
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
@@ -0,0 +1,233 @@
+// RUN: %clang_cc1 -verify -fopenmp %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) {}
+  const S2 &operator =(const S2&) const;
+  S2 &operator =(const S2&);
+  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 {
+  int a;
+  S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+
+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 {
+  int a;
+  S4();             // expected-note 3 {{implicitly declared private here}}
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 {
+  int a;
+  S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+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);
+  I g(5);
+  int i;
+  int &j = i;
+#pragma omp target teams distribute simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute 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 target teams distribute simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate(argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  int v = 0;
+#pragma omp target teams distribute simd lastprivate(i)
+  for (int k = 0; k < argc; ++k) {
+    i = k;
+    v += i;
+  }
+
+#pragma omp target teams distribute simd lastprivate(j) private(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd lastprivate(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp target teams distribute simd lastprivate(a)
+  for (int i = 0; i < 2; ++i) foo();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i;
+  float k;
+#pragma omp target teams distribute simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(argc)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute 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 target teams distribute simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(ba)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+  int xa;
+#pragma omp target teams distribute simd lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute 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 target teams distribute simd lastprivate(xa)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(j)
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+  for (i = 0; i < argc; ++i) foo();
+
+#pragma omp target teams distribute simd lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i) foo();
+
+  static int si;
+#pragma omp target teams distribute simd lastprivate(si) // OK
+  for (i = 0; i < argc; ++i) si = i + 1;
+
+#pragma omp target teams distribute simd lastprivate(k) map(k) // expected-error {{lastprivate variable cannot be in a map clause in '#pragma omp target teams distribute simd' directive}} expected-note {{defined as lastprivate}}
+  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/target_teams_distribute_simd_linear_messages.cpp b/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
new file mode 100644
index 0000000..8db57a0
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
@@ -0,0 +1,248 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+namespace X {
+  int x;
+};
+
+struct B {
+  static int ib; // expected-note {{'B::ib' declared here}}
+  static int bfoo() { return 8; }
+};
+
+int bfoo() { return 4; }
+
+int z;
+const int C1 = 1;
+const int C2 = 2;
+void test_linear_colons()
+{
+  int B = 0;
+
+#pragma omp target teams distribute simd linear(B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd linear(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd linear(X::x : ::z)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd linear(B,::z, X::x)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd linear(::z)
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd linear(B::bfoo()) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target teams distribute simd linear(B::ib,B:C1+C2)
+  for (int i = 0; i < 10; ++i) ;
+}
+
+template<int L, class T, class N> T test_template(T* arr, N num) {
+  N i;
+  T sum = (T)0;
+  T ind2 = - num * L; // expected-note {{'ind2' defined here}}
+
+#pragma omp target teams distribute simd linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}}
+  for (i = 0; i < num; ++i) {
+    T cur = arr[(int)ind2];
+    ind2 += L;
+    sum += cur;
+  }
+  return T();
+}
+
+template<int LEN> int test_warn() {
+  int ind2 = 0;
+  #pragma omp target teams distribute simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
+  for (int i = 0; i < 100; i++) {
+    ind2 += LEN;
+  }
+  return ind2;
+}
+
+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; // expected-note 2 {{'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;
+#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;
+
+#pragma omp target teams distribute simd linear // expected-error {{expected '(' after 'linear'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argc : 5)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear(e, g)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp parallel
+  {
+    int v = 0;
+    int i;
+    #pragma omp target teams distribute simd linear(v:i)
+    for (int k = 0; k < argc; ++k) { i = k; v += i; }
+  }
+
+#pragma omp target teams distribute simd linear(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  int v = 0;
+
+#pragma omp target teams distribute simd linear(v:j)
+  for (int k = 0; k < argc; ++k) { ++k; v += j; }
+
+#pragma omp target teams distribute simd linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+  return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace C {
+using A::x;
+}
+
+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);
+  // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+  test_warn<0>();
+
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute simd linear // expected-error {{expected '(' after 'linear'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+
+#pragma omp target teams distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  #pragma omp parallel
+  {
+    int i;
+    #pragma omp target teams distribute simd linear(i)
+      for (int k = 0; k < argc; ++k) ++k;
+
+    #pragma omp target teams distribute simd linear(i : 4)
+      for (int k = 0; k < argc; ++k) { ++k; i += 4; }
+  }
+
+#pragma omp target teams distribute simd linear(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+  return 0;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp b/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp
new file mode 100644
index 0000000..3ddabce
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp
@@ -0,0 +1,627 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -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;
+// expected-note@+1 {{defined as threadprivate or thread local}}
+#pragma omp threadprivate(sii)
+static int globalii;
+
+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 target teams distribute simd
+  for (int i = 0; i < 10; i += 1) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute simd
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute simd
+  for (char i = 0; i < 10; i += '\1') {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute simd
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute simd
+// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (long long i = 0; i < 10; i += 1.5) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute simd
+  for (long long i = 0; i < 'z'; i += 1u) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp target teams distribute simd
+// expected-error@+1 {{variable must be of integer or random access iterator type}}
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp target teams distribute simd
+// expected-error@+1 {{variable must be of integer or random access iterator type}}
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp target teams distribute simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+#pragma omp target teams distribute simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-warning@+2 {{expression result unused}}
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (ii + 1; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (c[ii] = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// Ok to skip parenthesises.
+  for (((ii)) = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute simd
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  for (int i = 0;; i++)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute simd
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp target teams distribute simd
+  for (ii = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; ++jj)
+    c[ii] = a[jj];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  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 target teams distribute simd
+  for (ii = 0; ii < 10; ii = ii + ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'float'}}
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+// Ok - step was converted to integer type.
+#pragma omp target teams distribute simd
+  for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; jj = ii + 2)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-warning@+2 {{relational comparison result unused}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii<10; jj> kk + 2)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10;)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-warning@+2 {{expression result unused}}
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; !ii)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  for (ii = 0; ii < 10; ii = ii < 10)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; ii < 10; ii = ii + 0)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; (ii) < 10; ii -= 25)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; (ii < 10); ii -= 0)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  for (ii = 0; ii > 10; (ii += 0))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  for ((ii = 0); ii > 10; (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  for (ii = 0; (ii < 10); (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd firstprivate(ii) // expected-note {{defined as firstprivate}}
+// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be firstprivate, predetermined as linear}}
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd private(ii) // expected-note {{defined as private}}
+// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be private, predetermined as linear}}
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd lastprivate(ii) // expected-note {{defined as lastprivate}}
+// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be lastprivate, predetermined as linear}}
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be threadprivate or thread local, predetermined as linear}}
+  for (sii = 0; sii < 10; sii++)
+    c[sii] = a[sii];
+
+  {
+#pragma omp target teams distribute simd collapse(2)
+  for (ii = 0; ii < 10; ii += 1)
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] += a[globalii] + ii;
+  }
+
+#pragma omp target teams distribute simd
+// expected-error@+1 {{statement after '#pragma omp target teams distribute simd' must be a for loop}}
+  for (auto &item : a) {
+    item = item + 1;
+  }
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int(*lb)[4] = nullptr;
+#pragma omp target teams distribute simd
+  for (int(*p)[4] = lb; p < lb + 8; ++p) {
+  }
+
+#pragma omp target teams distribute simd
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  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; }
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
+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;
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+int operator-(GoodIter a, GoodIter b) { return 0; }
+// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
+GoodIter operator-(GoodIter a) { return a; }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}}
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+#pragma omp target teams distribute simd
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (GoodIter I(1, 2); I < end; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute simd
+// expected-error@+2 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
+// expected-error@+1 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute simd
+// expected-error@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (++begin; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute simd
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+#pragma omp target teams distribute simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+#pragma omp target teams distribute simd
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-error@+1 {{invalid operands to binary expression ('Iter0' and 'int')}}
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// Initializer is constructor without params.
+// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}}
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+#pragma omp target teams distribute simd
+// expected-error@+2 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
+// expected-error@+1 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+#pragma omp target teams distribute simd
+// expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'float')}}
+// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+// Initializer is constructor with all default params.
+// expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  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 target teams distribute simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+    for (IT I = begin; I < end; I = I + ST) {
+      ++I;
+    }
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be positive due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+    for (IT I = begin; I <= end; I += ST) {
+      ++I;
+    }
+#pragma omp target teams distribute 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) {
+#pragma omp target teams distribute simd
+// expected-note@+2 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+#pragma omp target teams distribute simd
+// expected-note@+2 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+#pragma omp target teams distribute simd
+// expected-note@+2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+1 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+#pragma omp target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute 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 target teams distribute simd
+  for (int i = 0; i < 10; ++i) {
+    struct S {
+      void g() { throw 0; }
+    };
+  }
+}
+
+void test_loop_firstprivate_lastprivate() {
+  S s(4);
+#pragma omp target teams distribute simd lastprivate(s) firstprivate(s)
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
+void test_ordered() {
+#pragma omp target teams distribute simd ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp target teams distribute simd'}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
+void test_nowait() {
+// expected-error@+1 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'nowait' clause}}
+#pragma omp target teams distribute simd nowait nowait
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_simd_map_messages.cpp b/test/OpenMP/target_teams_distribute_simd_map_messages.cpp
new file mode 100644
index 0000000..414f6f8
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_map_messages.cpp
@@ -0,0 +1,281 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  S2(S2 &s2):a(s2.a) { }
+  static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+  static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+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 2 {{defined as threadprivate or thread local}}
+
+typedef int from;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  T i, t[20];
+  T &j = i;
+  T *k = &j;
+  T x;
+  T y;
+  T to, tofrom, always;
+  const T (&l)[5] = da;
+
+
+#pragma omp target teams distribute simd map // expected-error {{expected '(' after 'map'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to:) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l[-1:]) // expected-error 2 {{array section must be a subset of the original array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(tofrom: t[:I])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(T) // expected-error {{'T' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to: to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} 
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(ca)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(e, g)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(da[:4])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note 2 {{used here}}
+#pragma omp target teams distribute simd map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
+{
+#pragma omp target teams distribute simd map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l)
+  for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target teams distribute simd map(always, tofrom: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(always: x) // expected-error {{missing map type}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(always, tofrom: always, tofrom, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  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);
+  S5 g(5);
+  int i;
+  int &j = i;
+  int *k = &j;
+  int x;
+  int y;
+  int to, tofrom, always;
+  const int (&l)[5] = da;
+
+#pragma omp target teams distribute simd map // expected-error {{expected '(' after 'map'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to:) // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l[-1:]) // expected-error {{array section must be a subset of the original array}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to: to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(argc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(argv[1])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(ca)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(S2::S2s)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(S2::S2sc)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(e, g)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(da)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(da[:4])
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note {{used here}}
+#pragma omp target teams distribute simd map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}}
+{
+#pragma omp target teams distribute simd map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(j)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l)
+  for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target teams distribute simd map(always, tofrom: x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(always: x) // expected-error {{missing map type}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(always, tofrom: always, tofrom, x)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
diff --git a/test/OpenMP/target_teams_distribute_simd_messages.cpp b/test/OpenMP/target_teams_distribute_simd_messages.cpp
new file mode 100644
index 0000000..aa82c94
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_messages.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+static int pvt;
+#pragma omp threadprivate(pvt)
+
+#pragma omp target teams distribute simd // expected-error {{unexpected OpenMP directive '#pragma omp target teams distribute simd'}}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute simd { // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute simd ( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute simd[ // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute simd] // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute simd) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute simd } // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute simd
+  for (int i = 0; i < argc; ++i)
+    foo();
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+#pragma omp target teams distribute simd unknown()
+  for (int i = 0; i < argc; ++i)
+    foo();
+L1:
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute simd
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target teams distribute simd
+  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 target teams distribute simd
+      for (int i = 0; i < argc; ++i) {
+        foo();
+        break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+        continue;
+      }
+    default:
+      break;
+    }
+  }
+// expected-error@+1 {{unexpected OpenMP clause 'default' in directive '#pragma omp target teams distribute simd'}}
+#pragma omp target teams distribute simd default(none)
+  for (int i = 0; i < 10; ++i)
+    ++argc; // expected-error {{ariable 'argc' must have explicitly specified data sharing attributes}}
+
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+#pragma omp target teams distribute simd
+  for (int i = 0; i < argc; ++i)
+  L2:
+  foo();
+#pragma omp target teams distribute simd
+  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 target teams distribute simd
+      for (int n = 0; n < 100; ++n) {
+  }
+
+#pragma omp target teams distribute simd copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target teams distribute simd'}}
+  for (int n = 0; n < 100; ++n) {}
+
+  return 0;
+}
+
+void test_ordered() {
+#pragma omp target teams distribute simd ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp target teams distribute simd'}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
diff --git a/test/OpenMP/target_teams_distribute_simd_misc_messages.c b/test/OpenMP/target_teams_distribute_simd_misc_messages.c
new file mode 100644
index 0000000..c76fdea
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_misc_messages.c
@@ -0,0 +1,312 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target teams distribute simd'}}
+#pragma omp target teams distribute simd
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target teams distribute simd'}}
+#pragma omp target teams distribute simd foo
+
+void test_no_clause() {
+  int i;
+#pragma omp target teams distribute simd
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{statement after '#pragma omp target teams distribute simd' must be a for loop}}
+#pragma omp target teams distribute simd
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp target teams distribute simd
+  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 target teams distribute simd' are ignored}}
+#pragma omp target teams distribute simd 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 target teams distribute simd' are ignored}}
+#pragma omp target teams distribute simd;
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+#pragma omp target teams distribute simd private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+#pragma omp target teams distribute simd, private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+extern int foo();
+
+void test_collapse() {
+  int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp target teams distribute simd collapse
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute simd collapse(
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute simd collapse()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute simd collapse(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}  expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute simd collapse(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp target teams distribute simd 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 target teams distribute simd collapse(4
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute simd collapse(4,
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute simd collapse(4, )
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute simd', but found only 1}}
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute simd collapse(4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute simd collapse(4 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target teams distribute simd collapse(4, , 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute simd', but found only 1}}
+#pragma omp target teams distribute simd 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 target teams distribute simd collapse(4, 8)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp target teams distribute simd', but found only 1}}
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target teams distribute simd collapse(2.5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target teams distribute simd collapse(foo())
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute simd collapse(-5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute simd collapse(0)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target teams distribute simd collapse(5 - 5)
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+4 {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp target teams distribute simd collapse(2) firstprivate(i)
+  for (i = 0; i < 16; ++i)
+    for (int j = 0; j < 16; ++j)
+#pragma omp parallel for reduction(+ : i, j)
+      for (int k = 0; k < 16; ++k)
+        i += j;
+}
+
+void test_private() {
+  int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target teams distribute simd 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 target teams distribute simd private(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute simd private(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute simd private()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute simd private(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute simd private(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute simd private(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute simd private(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute simd 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 target teams distribute 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 target teams distribute simd lastprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute simd lastprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute simd lastprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute simd lastprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute simd lastprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute simd lastprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute simd lastprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute simd 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 target teams distribute simd 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 target teams distribute simd firstprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target teams distribute simd firstprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute simd firstprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target teams distribute simd firstprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target teams distribute simd firstprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp target teams distribute simd lastprivate(x) firstprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute simd lastprivate(x, y) firstprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp target teams distribute simd 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 target teams distribute 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 target teams distribute simd
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/target_teams_distribute_simd_nowait_messages.cpp b/test/OpenMP/target_teams_distribute_simd_nowait_messages.cpp
new file mode 100644
index 0000000..6c2c2a5
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_nowait_messages.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fopenmp %s
+
+void foo() {
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target teams distribute simd nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd nowait device (-10u)
+  for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_num_teams_messages.cpp b/test/OpenMP/target_teams_distribute_simd_num_teams_messages.cpp
new file mode 100644
index 0000000..63926bc
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_num_teams_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <typename T, int C> // expected-note {{declared here}}
+T tmain(T argc) {
+  char **a;
+#pragma omp target teams distribute simd num_teams(C)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(T) // expected-error {{'T' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams // expected-error {{expected '(' after 'num_teams'}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams() // expected-error {{expected expression}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(argc + argc)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'num_teams' clause}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(-10u)
+  for (int i=0; i<100; i++) foo();
+#pragma omp target teams distribute simd num_teams(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int i=0; i<100; i++) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute simd num_teams // expected-error {{expected '(' after 'num_teams'}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams () // expected-error {{expected expression}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams (argc + argc)
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams (argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'num_teams' clause}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams (-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams (-10u)
+  for (int i=0; i<100; i++) foo();
+
+#pragma omp target teams distribute simd num_teams (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int i=0; i<100; i++) foo();
+
+  return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_private_messages.cpp b/test/OpenMP/target_teams_distribute_simd_private_messages.cpp
new file mode 100644
index 0000000..3d351bd
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_private_messages.cpp
@@ -0,0 +1,127 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  static float S2s; // expected-note {{predetermined as shared}}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+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}}
+class S4 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+public:
+  S4(int v):a(v) { }
+};
+class S5 { 
+  int a;
+  S5():a(0) {} // expected-note {{implicitly declared private here}}
+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;  // expected-note {{predetermined as shared}}
+  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  S4 e(4);
+  S5 g(5);
+  int i;
+  int &j = i;
+
+#pragma omp target teams distribute simd private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private(ba)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private(ca) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private(da) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private(S2::S2s) // expected-error {{shared variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd shared(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd firstprivate(i), private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd private(j)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target teams distribute simd reduction(+:i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp distribute private(i)
+  for (int k = 0; k < 10; ++k) {
+    #pragma omp target teams distribute simd private(i)
+    for (int x = 0; x < 10; ++x) foo();
+  }
+
+#pragma omp target teams distribute simd firstprivate(i)
+  for (int k = 0; k < 10; ++k) {
+  }
+
+#pragma omp target teams distribute simd private(j) map(j) // expected-error {{private variable cannot be in a map clause in '#pragma omp target teams distribute simd' directive}} expected-note {{defined as private}}
+  for (int k = 0; k < argc; ++k) ++k;
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
new file mode 100644
index 0000000..1c02832
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
@@ -0,0 +1,241 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %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); } // expected-note 3 {{implicitly declared private here}}
+
+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 3 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  int b;
+  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 3 {{'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 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+  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) {} // expected-note {{implicitly declared private here}}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o;
+
+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) {
+  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;
+#pragma omp target teams distribute simd reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(&& : argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute 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 j=0; j<100; j++) foo();
+#pragma omp parallel private(k)
+#pragma omp target teams distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams distribute simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : fl)
+    for (int j=0; j<100; j++) foo();
+
+  return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  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;
+#pragma omp target teams distribute simd reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute 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 j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(&& : argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item 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 list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : o) // expected-error {{no viable overloaded '='}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute 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 j=0; j<100; j++) foo();
+#pragma omp parallel private(k)
+#pragma omp target teams distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams distribute simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd reduction(+ : fl)
+    for (int j=0; j<100; j++) foo();
+  static int m;
+#pragma omp target teams distribute simd reduction(+ : m) // OK
+  for (int j=0; j<100; j++) 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/target_teams_distribute_simd_safelen_messages.cpp b/test/OpenMP/target_teams_distribute_simd_safelen_messages.cpp
new file mode 100644
index 0000000..1f41c53
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_safelen_messages.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+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 target teams distribute simd safelen // expected-error {{expected '(' after 'safelen'}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen ( // 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 target teams distribute simd safelen () // expected-error {{expected expression}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}}
+  for (int i = ST; i < N; i++) 
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+  
+#pragma omp target teams distribute simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} 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 target teams distribute simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = ST; i < N; i++)
+     argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen ((ST > 0) ? 1 + ST : 2)
+  for (int i = ST; i < N; i++) 
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus >= 201103L
+  // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen (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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute simd safelen (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 target teams distribute simd safelen (4)
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly 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 target teams distribute simd safelen // expected-error {{expected '(' after 'safelen'}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute simd safelen ( // 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 target teams distribute simd safelen () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute simd safelen (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 target teams distribute simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+  
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute simd safelen (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];
+
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}} 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];
+
+#pragma omp target teams distribute simd safelen (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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute simd safelen (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-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target teams distribute simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+   foo(); // expected-error {{statement after '#pragma omp target teams distribute simd' must be a for loop}}
+
+// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+  return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_teams_distribute_simd_shared_messages.cpp b/test/OpenMP/target_teams_distribute_simd_shared_messages.cpp
new file mode 100644
index 0000000..9f98ab9
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_shared_messages.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -verify -fopenmp %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}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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 target teams distribute simd shared // expected-error {{expected '(' after 'shared'}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared () // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared (argc)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared (a, b, c, d, f)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared (argv[1]) // expected-error {{expected variable name}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared(ba)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared(ca)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared(da)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared(e, g)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd private(i)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared(i)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd shared(j)
+  for (int j=0; j<100; j++) foo();
+  #pragma omp target teams distribute simd firstprivate(i)
+  for (int j=0; j<100; j++) foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_distribute_simd_simdlen_messages.cpp b/test/OpenMP/target_teams_distribute_simd_simdlen_messages.cpp
new file mode 100644
index 0000000..1b7ad66
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_simdlen_messages.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+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 target teams distribute simd safelen // expected-error {{expected '(' after 'safelen'}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen ( // 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 target teams distribute simd safelen () // expected-error {{expected expression}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}}
+  for (int i = ST; i < N; i++) 
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+  
+#pragma omp target teams distribute simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} 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 target teams distribute simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = ST; i < N; i++)
+     argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen ((ST > 0) ? 1 + ST : 2)
+  for (int i = ST; i < N; i++) 
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus >= 201103L
+  // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen (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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute simd safelen (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 target teams distribute simd safelen (4)
+  for (int i = ST; i < N; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target teams distribute simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly 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 target teams distribute simd safelen // expected-error {{expected '(' after 'safelen'}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute simd safelen ( // 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 target teams distribute simd safelen () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target teams distribute simd safelen (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 target teams distribute simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int i = 4; i < 12; i++)
+    argv[0][i] = argv[0][i] - argv[0][i-4];
+  
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute simd safelen (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];
+
+#if __cplusplus >= 201103L
+  // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}} 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];
+
+#pragma omp target teams distribute simd safelen (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];
+
+#if __cplusplus <= 199711L
+  // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+  // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target teams distribute simd safelen (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-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target teams distribute simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo(); // expected-error {{statement after '#pragma omp target teams distribute simd' must be a for loop}}
+
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+  return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_teams_distribute_simd_thread_limit_messages.cpp b/test/OpenMP/target_teams_distribute_simd_thread_limit_messages.cpp
new file mode 100644
index 0000000..357f5dd
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_thread_limit_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <typename T, int C> // expected-note {{declared here}}
+T tmain(T argc) {
+  char **a;
+#pragma omp target teams distribute simd thread_limit(C)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(T) // expected-error {{'T' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit // expected-error {{expected '(' after 'thread_limit'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit() // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(argc + argc)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'thread_limit' clause}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}}
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(-10u)
+  for (int j=0; j<100; j++) foo();
+#pragma omp target teams distribute simd thread_limit(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int j=0; j<100; j++) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams distribute simd thread_limit // expected-error {{expected '(' after 'thread_limit'}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit () // expected-error {{expected expression}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit (argc + argc)
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit (argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'thread_limit' clause}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit (-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}}
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit (-10u)
+  for (int j=0; j<100; j++) foo();
+
+#pragma omp target teams distribute simd thread_limit (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  for (int j=0; j<100; j++) foo();
+
+  return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_firstprivate_messages.cpp b/test/OpenMP/target_teams_firstprivate_messages.cpp
new file mode 100644
index 0000000..84fc4ab
--- /dev/null
+++ b/test/OpenMP/target_teams_firstprivate_messages.cpp
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(const 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;
+
+public:
+  S3() : a(0) {}
+  S3(const 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); // expected-note {{implicitly declared private here}}
+public:
+  S4(int v) : a(v) {}
+};
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {} // expected-note {{implicitly declared private here}}
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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 target teams firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  foo();
+#pragma omp target teams firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams firstprivate() // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp target teams firstprivate(argc)
+  foo();
+#pragma omp target teams firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp target teams firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  foo();
+#pragma omp target teams firstprivate(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp target teams firstprivate(ba)
+  foo();
+#pragma omp target teams firstprivate(ca)
+  foo();
+#pragma omp target teams firstprivate(da)
+  foo();
+#pragma omp target teams firstprivate(S2::S2s)
+  foo();
+#pragma omp target teams firstprivate(S2::S2sc)
+  foo();
+#pragma omp target teams firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  foo();
+#pragma omp target teams firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}}
+  foo();
+#pragma omp target teams private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}}
+  foo();
+#pragma omp target teams shared(i)
+  foo();
+#pragma omp target teams firstprivate(i)
+  foo();
+#pragma omp target teams firstprivate(j)
+  foo();
+  static int m;
+#pragma omp target teams firstprivate(m) // OK
+  foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_if_messages.cpp b/test/OpenMP/target_teams_if_messages.cpp
new file mode 100644
index 0000000..0ab8fc3
--- /dev/null
+++ b/test/OpenMP/target_teams_if_messages.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 %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 target teams if // expected-error {{expected '(' after 'if'}}
+  foo();
+#pragma omp target teams if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if () // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams if (argc > 0 ? argv[1] : argv[2])
+  foo();
+#pragma omp target teams if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'if' clause}}
+  foo();
+#pragma omp target teams if (S) // expected-error {{'S' does not refer to a value}}
+  foo();
+#pragma omp target teams if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if(argc)
+  foo();
+#pragma omp target teams if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if(target : argc)
+  foo();
+#pragma omp target teams if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target teams'}}
+  foo();
+#pragma omp target teams if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'if' clause with 'target' name modifier}}
+  foo();
+#pragma omp target teams if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+  foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams if // expected-error {{expected '(' after 'if'}}
+  foo();
+#pragma omp target teams if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if () // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams if (argc > 0 ? argv[1] : argv[2])
+  foo();
+#pragma omp target teams if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'if' clause}}
+  foo();
+#pragma omp target teams if (S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp target teams if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams if(target : argc)
+  foo();
+#pragma omp target teams if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target teams'}}
+  foo();
+#pragma omp target teams if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'if' clause with 'target' name modifier}}
+  foo();
+#pragma omp target teams if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+  foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_teams_is_device_ptr_ast_print.cpp b/test/OpenMP/target_teams_is_device_ptr_ast_print.cpp
new file mode 100644
index 0000000..3a9cee5
--- /dev/null
+++ b/test/OpenMP/target_teams_is_device_ptr_ast_print.cpp
@@ -0,0 +1,291 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int da[5] = { 0 };
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target teams is_device_ptr(k)
+    {}
+#pragma omp target teams is_device_ptr(z)
+    {}
+#pragma omp target teams is_device_ptr(aa) // OK
+    {}
+#pragma omp target teams is_device_ptr(raa) // OK
+    {}
+#pragma omp target teams is_device_ptr(g) // OK
+    {}
+#pragma omp target teams is_device_ptr(rg) // OK
+    {}
+#pragma omp target teams is_device_ptr(da) // OK
+    {}
+  return;
+ }
+};
+// CHECK: struct SA
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: ST g[10];
+// CHECK-NEXT: STarr &rg = this->g;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = this->i;
+// CHECK-NEXT: int *k = &this->j;
+// CHECK-NEXT: int *&z = this->k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: arr &raa = this->aa;
+// CHECK-NEXT: func(
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(this->k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(this->z)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(this->aa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(this->raa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(this->g)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(this->rg)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(this->da)
+
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T>
+T tmain(T argc) {
+  const T da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+#pragma omp target teams is_device_ptr(k)
+  {}
+#pragma omp target teams is_device_ptr(z)
+  {}
+#pragma omp target teams is_device_ptr(aa)
+  {}
+#pragma omp target teams is_device_ptr(raa)
+  {}
+#pragma omp target teams is_device_ptr(h)
+  {}
+#pragma omp target teams is_device_ptr(rh)
+  {}
+#pragma omp target teams is_device_ptr(da)
+  {}
+  return 0;
+}
+
+// CHECK: template<> int tmain<int>(int argc) {
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(z)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(aa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(raa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(h)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(rh)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(da)
+
+// CHECK: template<> int *tmain<int *>(int *argc) {
+// CHECK-NEXT: int *const da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int *i;
+// CHECK-NEXT: int *&j = i;
+// CHECK-NEXT: int **k = &j;
+// CHECK-NEXT: int **&z = k;
+// CHECK-NEXT: int *aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(z)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(aa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(raa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(h)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(rh)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(da)
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main(int argc, char **argv) {
+  const int da[5] = { 0 };
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+#pragma omp target teams is_device_ptr(k)
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(k)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target teams is_device_ptr(z)
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(z)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target teams is_device_ptr(aa)
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(aa)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target teams is_device_ptr(raa)
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(raa)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target teams is_device_ptr(h)
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(h)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target teams is_device_ptr(rh)
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(rh)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target teams is_device_ptr(da)
+// CHECK-NEXT: #pragma omp target teams is_device_ptr(da)
+  {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+  return tmain<int>(argc) + *tmain<int *>(&argc);
+}
+#endif
diff --git a/test/OpenMP/target_teams_is_device_ptr_messages.cpp b/test/OpenMP/target_teams_is_device_ptr_messages.cpp
new file mode 100644
index 0000000..0f5be43
--- /dev/null
+++ b/test/OpenMP/target_teams_is_device_ptr_messages.cpp
@@ -0,0 +1,268 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -ferror-limit 200 %s
+struct ST {
+  int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+  const int d = 5;
+  const int da[5] = { 0 };
+  ST e;
+  ST g[10];
+  STarr &rg = g;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  arr &raa = aa;
+  void func(int arg) {
+#pragma omp target teams is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+    {}
+#pragma omp target teams is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+    {}
+#pragma omp target teams is_device_ptr() // expected-error {{expected expression}}
+    {}
+#pragma omp target teams is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+    {}
+#pragma omp target teams is_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target teams is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target teams is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target teams is_device_ptr(k) // OK
+    {}
+#pragma omp target teams is_device_ptr(z) // OK
+    {}
+#pragma omp target teams is_device_ptr(aa) // OK
+    {}
+#pragma omp target teams is_device_ptr(raa) // OK
+    {}    
+#pragma omp target teams is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target teams is_device_ptr(g) // OK
+    {}
+#pragma omp target teams is_device_ptr(rg) // OK
+    {}
+#pragma omp target teams is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target teams is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+    {}
+#pragma omp target teams is_device_ptr(da) // OK
+    {}
+  return;
+ }
+};
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+struct 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;
+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)
+
+typedef struct {
+  int a;
+} S6;
+
+template <typename T, int I>
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  T i;
+  T &j = i;
+  T *k = &j;
+  T *&z = k;
+  T aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target teams is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  {}
+#pragma omp target teams is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  {}
+#pragma omp target teams is_device_ptr() // expected-error {{expected expression}}
+  {}
+#pragma omp target teams is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  {}
+#pragma omp target teams is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(k) // OK
+  {}
+#pragma omp target teams is_device_ptr(z) // OK
+  {}
+#pragma omp target teams is_device_ptr(aa) // OK
+  {}
+#pragma omp target teams is_device_ptr(raa) // OK
+  {}
+#pragma omp target teams is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(h) // OK
+  {}
+#pragma omp target teams is_device_ptr(rh) // OK
+  {}
+#pragma omp target teams is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(da) // OK
+  {}
+#pragma omp target teams map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target teams is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target teams map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target teams is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  {}
+#pragma omp target teams is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}}
+  {}
+#pragma omp target teams firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} expected-note{{defined as firstprivate}}
+  {}
+#pragma omp target teams is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}}
+  {}
+#pragma omp target teams private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} expected-note{{defined as private}}
+  {}
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  S6 h[10];
+  auto &rh = h;
+  int i;
+  int &j = i;
+  int *k = &j;
+  int *&z = k;
+  int aa[10];
+  auto &raa = aa;
+  S6 *ps;
+#pragma omp target teams is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+  {}
+#pragma omp target teams is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  {}
+#pragma omp target teams is_device_ptr() // expected-error {{expected expression}}
+  {}
+#pragma omp target teams is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  {}
+#pragma omp target teams is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(k) // OK
+  {}
+#pragma omp target teams is_device_ptr(z) // OK
+  {}
+#pragma omp target teams is_device_ptr(aa) // OK
+  {}
+#pragma omp target teams is_device_ptr(raa) // OK
+  {}
+#pragma omp target teams is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(h) // OK
+  {}
+#pragma omp target teams is_device_ptr(rh) // OK
+  {}
+#pragma omp target teams is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+  {}
+#pragma omp target teams is_device_ptr(da) // OK
+  {}
+#pragma omp target teams map(ps) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target teams is_device_ptr(ps) map(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target teams map(ps->a) is_device_ptr(ps) // expected-error{{variable already marked as mapped in current construct}} expected-note{{used here}}
+  {}
+#pragma omp target teams is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}}
+  {}
+#pragma omp target teams is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}}
+  {}
+#pragma omp target teams firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} expected-note{{defined as firstprivate}}
+  {}
+#pragma omp target teams is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}}
+  {}
+#pragma omp target teams private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} expected-note{{defined as private}}
+  {}
+  return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_map_messages.cpp b/test/OpenMP/target_teams_map_messages.cpp
new file mode 100644
index 0000000..15839b8
--- /dev/null
+++ b/test/OpenMP/target_teams_map_messages.cpp
@@ -0,0 +1,538 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 200 %s
+// rUN: %clang_cc1 -DCCODE -verify -fopenmp -ferror-limit 200 -x c %s
+#ifdef CCODE
+void foo(int arg) {
+  const int n = 0;
+
+  double marr[10][10][10];
+
+  #pragma omp target teams map(marr[2][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[:][0:][:])
+  {}
+  #pragma omp target teams map(marr[:][1:][:]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[:][n:][:])
+  {}
+}
+#else
+template <typename T, int I>
+struct SA {
+  static int ss;
+  #pragma omp threadprivate(ss) // expected-note {{defined as threadprivate or thread local}}
+  float a;
+  int b[12];
+  float *c;
+  T d;
+  float e[I];
+  T *f;
+  void func(int arg) {
+    #pragma omp target teams map(arg,a,d)
+    {}
+    #pragma omp target teams map(arg[2:2],a,d) // expected-error {{subscripted value is not an array or pointer}}
+    {}
+    #pragma omp target teams map(arg,a*2) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+    {}
+    #pragma omp target teams map(arg,(c+1)[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+    {}
+    #pragma omp target teams map(arg,a[:2],d) // expected-error {{subscripted value is not an array or pointer}}
+    {}
+    #pragma omp target teams map(arg,a,d[:2]) // expected-error {{subscripted value is not an array or pointer}}
+    {}
+
+    #pragma omp target teams map(to:ss) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+    {}
+
+    #pragma omp target teams map(to:b,e)
+    {}
+    #pragma omp target teams map(to:b,e) map(to:b) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+    {}
+    #pragma omp target teams map(to:b[:2],e)
+    {}
+    #pragma omp target teams map(to:b,e[:])
+    {}
+    #pragma omp target teams map(b[-1:]) // expected-error {{array section must be a subset of the original array}}
+    {}
+    #pragma omp target teams map(b[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+    {}
+
+    #pragma omp target teams map(always, tofrom: c,f)
+    {}
+    #pragma omp target teams map(always, tofrom: c[1:2],f)
+    {}
+    #pragma omp target teams map(always, tofrom: c,f[1:2])
+    {}
+    #pragma omp target teams map(always, tofrom: c[:],f)   // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+    {}
+    #pragma omp target teams map(always, tofrom: c,f[:])   // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+    {}
+    return;
+  }
+};
+
+struct SB {
+  unsigned A;
+  unsigned B;
+  float Arr[100];
+  float *Ptr;
+  float *foo() {
+    return &Arr[0];
+  }
+};
+
+struct SC {
+  unsigned A : 2;
+  unsigned B : 3;
+  unsigned C;
+  unsigned D;
+  float Arr[100];
+  SB S;
+  SB ArrS[100];
+  SB *PtrS;
+  SB *&RPtrS;
+  float *Ptr;
+
+  SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+  unsigned A;
+  float B;
+};
+
+void SAclient(int arg) {
+  SA<int,123> s;
+  s.func(arg); // expected-note {{in instantiation of member function}}
+  double marr[10][10][10];
+  double marr2[5][10][1];
+  double mvla[5][arg][10];
+  double ***mptr;
+  const int n = 0;
+  const int m = 1;
+  double mvla2[5][arg][m+n+10];
+
+  SB *p;
+
+  SD u;
+  SC r(p),t(p);
+  #pragma omp target teams map(r)
+  {}
+  #pragma omp target teams map(marr[2][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[:][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[2][3][0:2])
+  {}
+  #pragma omp target teams map(marr[:][:][:])
+  {}
+  #pragma omp target teams map(marr[:2][:][:])
+  {}
+  #pragma omp target teams map(marr[arg:][:][:])
+  {}
+  #pragma omp target teams map(marr[arg:])
+  {}
+  #pragma omp target teams map(marr[arg:][:arg][:]) // correct if arg is the size of dimension 2
+  {}
+  #pragma omp target teams map(marr[:arg][:])
+  {}
+  #pragma omp target teams map(marr[:arg][n:])
+  {}
+  #pragma omp target teams map(marr[:][:arg][n:]) // correct if arg is the size of  dimension 2
+  {}
+  #pragma omp target teams map(marr[:][:m][n:]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[n:m][:arg][n:])
+  {}
+  #pragma omp target teams map(marr[:2][:1][:]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[:2][1:][:]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[:2][:][:1]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[:2][:][1:]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[:1][:2][:])
+  {}
+  #pragma omp target teams map(marr[:1][0][:])
+  {}
+  #pragma omp target teams map(marr[:arg][:2][:]) // correct if arg is 1
+  {}
+  #pragma omp target teams map(marr[:1][3:1][:2])
+  {}
+  #pragma omp target teams map(marr[:1][3:arg][:2]) // correct if arg is 1
+  {}
+  #pragma omp target teams map(marr[:1][3:2][:2]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr[:2][:10][:])
+  {}
+  #pragma omp target teams map(marr[:2][:][:5+5])
+  {}
+  #pragma omp target teams map(marr[:2][2+2-4:][0:5+5])
+  {}
+
+  #pragma omp target teams map(marr[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(marr2[:1][:2][0])
+  {}
+
+  #pragma omp target teams map(mvla[:1][:][0]) // correct if the size of dimension 2 is 1.
+  {}
+  #pragma omp target teams map(mvla[:2][:arg][:]) // correct if arg is the size of dimension 2.
+  {}
+  #pragma omp target teams map(mvla[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}}
+   {}
+  #pragma omp target teams map(mvla[1][2:arg][:])
+  {}
+  #pragma omp target teams map(mvla[:1][:][:])
+  {}
+  #pragma omp target teams map(mvla2[:1][:2][:11])
+  {}
+  #pragma omp target teams map(mvla2[:1][:2][:10]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+
+  #pragma omp target teams map(mptr[:2][2+2-4:1][0:5+5]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(mptr[:1][:2-1][2:4-3])
+  {}
+  #pragma omp target teams map(mptr[:1][:arg][2:4-3]) // correct if arg is 1.
+  {}
+  #pragma omp target teams map(mptr[:1][:2-1][0:2])
+  {}
+  #pragma omp target teams map(mptr[:1][:2][0:2]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+  #pragma omp target teams map(mptr[:1][:][0:2]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  {}
+  #pragma omp target teams map(mptr[:2][:1][0:2]) // expected-error {{array section does not specify contiguous storage}}
+  {}
+
+  #pragma omp target teams map(r.ArrS[0].B)
+  {}
+  #pragma omp target teams map(r.ArrS[:1].B) // expected-error {{OpenMP array section is not allowed here}}
+  {}
+  #pragma omp target teams map(r.ArrS[:arg].B) // expected-error {{OpenMP array section is not allowed here}}
+  {}
+  #pragma omp target teams map(r.ArrS[0].Arr[1:23])
+  {}
+  #pragma omp target teams map(r.ArrS[0].Arr[1:arg])
+  {}
+  #pragma omp target teams map(r.ArrS[0].Arr[arg:23])
+  {}
+  #pragma omp target teams map(r.ArrS[0].Error) // expected-error {{no member named 'Error' in 'SB'}}
+  {}
+  #pragma omp target teams map(r.ArrS[0].A, r.ArrS[1].A) // expected-error {{multiple array elements associated with the same variable are not allowed in map clauses of the same construct}} expected-note {{used here}}
+  {}
+  #pragma omp target teams map(r.ArrS[0].A, t.ArrS[1].A)
+  {}
+  #pragma omp target teams map(r.PtrS[0], r.PtrS->B) // expected-error {{same pointer derreferenced in multiple different ways in map clause expressions}} expected-note {{used here}}
+  {}
+  #pragma omp target teams map(r.RPtrS[0], r.RPtrS->B) // expected-error {{same pointer derreferenced in multiple different ways in map clause expressions}} expected-note {{used here}}
+  {}
+  #pragma omp target teams map(r.S.Arr[:12])
+  {}
+  #pragma omp target teams map(r.S.foo()[:12]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+  {}
+  #pragma omp target teams map(r.C, r.D)
+  {}
+  #pragma omp target teams map(r.C, r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+  {}
+  #pragma omp target teams map(r.C) map(r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+  {}
+  #pragma omp target teams map(r.C, r.S)  // this would be an error only caught at runtime - Sema would have to make sure there is not way for the missing data between fields to be mapped somewhere else.
+  {}
+  #pragma omp target teams map(r, r.S)  // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+  {}
+  #pragma omp target teams map(r.C, t.C)
+  {}
+  #pragma omp target teams map(r.A)   // expected-error {{bit fields cannot be used to specify storage in a 'map' clause}}
+  {}
+  #pragma omp target teams map(r.Arr)
+  {}
+  #pragma omp target teams map(r.Arr[3:5])
+  {}
+  #pragma omp target teams map(r.Ptr[3:5])
+  {}
+  #pragma omp target teams map(r.ArrS[3:5].A)   // expected-error {{OpenMP array section is not allowed here}}
+  {}
+  #pragma omp target teams map(r.ArrS[3:5].Arr[6:7])   // expected-error {{OpenMP array section is not allowed here}}
+  {}
+  #pragma omp target teams map(r.ArrS[3].Arr[6:7])
+  {}
+  #pragma omp target teams map(r.S.Arr[4:5])
+  {}
+  #pragma omp target teams map(r.S.Ptr[4:5])
+  {}
+  #pragma omp target teams map(r.S.Ptr[:])  // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+  {}
+  #pragma omp target teams map((p+1)->A)  // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+  {}
+  #pragma omp target teams map(u.B)  // expected-error {{mapped storage cannot be derived from a union}}
+  {}
+
+  #pragma omp target data map(to: r.C) //expected-note {{used here}}
+  {
+    #pragma omp target teams map(r.D)  // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
+    {}
+  }
+
+  #pragma omp target data map(to: t.Ptr) //expected-note {{used here}}
+  {
+    #pragma omp target teams map(t.Ptr[:23])  // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+    {}
+  }
+
+  #pragma omp target data map(to: t.C, t.D)
+  {
+  #pragma omp target data map(to: t.C)
+  {
+    #pragma omp target teams map(t.D)
+    {}
+  }
+  }
+
+  #pragma omp target data map(to: t)
+  {
+  #pragma omp target data map(to: t.C)
+  {
+    #pragma omp target teams map(t.D)
+    {}
+  }
+  }
+}
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  S2(S2 &s2):a(s2.a) { }
+  static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+  static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+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) { }
+};
+
+template <class T>
+struct S6;
+
+template<>
+struct S6<int>  // expected-note {{mappable type cannot be polymorphic}}
+{
+   virtual void foo();
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+typedef int from;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+  const T d = 5;
+  const T da[5] = { 0 };
+  S4 e(4);
+  S5 g(5);
+  T i, t[20];
+  T &j = i;
+  T *k = &j;
+  T x;
+  T y;
+  T to, tofrom, always;
+  const T (&l)[5] = da;
+#pragma omp target teams map // expected-error {{expected '(' after 'map'}}
+  {}
+#pragma omp target teams map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+  {}
+#pragma omp target teams map() // expected-error {{expected expression}}
+  {}
+#pragma omp target teams map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+  {}
+#pragma omp target teams map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+  {}
+#pragma omp target teams map(to:) // expected-error {{expected expression}}
+  {}
+#pragma omp target teams map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {}
+#pragma omp target teams map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+  {}
+#pragma omp target teams map(x)
+  foo();
+#pragma omp target teams map(tofrom: t[:I])
+  foo();
+#pragma omp target teams map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}}
+  foo();
+#pragma omp target teams map(T) // expected-error {{'T' does not refer to a value}}
+  foo();
+#pragma omp target teams map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+  foo();
+#pragma omp target teams map(S2::S2s)
+  foo();
+#pragma omp target teams map(S2::S2sc)
+  foo();
+#pragma omp target teams map(x)
+  foo();
+#pragma omp target teams map(to: x)
+  foo();
+#pragma omp target teams map(to: to)
+  foo();
+#pragma omp target teams map(to)
+  foo();
+#pragma omp target teams map(to, x)
+  foo();
+
+#pragma omp target data map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+#pragma omp target data map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target data map(argc)
+#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(ca)
+#pragma omp target data map(da)
+#pragma omp target data map(S2::S2s)
+#pragma omp target data map(S2::S2sc)
+#pragma omp target data map(e, g)
+#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+#pragma omp target data map(k) map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+#pragma omp target teams map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
+  foo();
+
+#pragma omp target data map(da)
+#pragma omp target teams map(da[:4])
+  foo();
+
+#pragma omp target data map(k, j, l) // expected-note 2 {{used here}}
+#pragma omp target data map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+#pragma omp target data map(j)
+#pragma omp target teams map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+  foo();
+
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
+#pragma omp target data map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+#pragma omp target data map(j)
+#pragma omp target teams map(l)
+  foo();
+
+#pragma omp target data map(always, tofrom: x)
+#pragma omp target data map(always: x) // expected-error {{missing map type}}
+#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+#pragma omp target data map(always, tofrom: always, tofrom, x)
+#pragma omp target teams map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  foo();
+  return 0;
+}
+
+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;
+  int *k = &j;
+  S6<int> m;
+  int x;
+  int y;
+  int to, tofrom, always;
+  const int (&l)[5] = da;
+#pragma omp target data map // expected-error {{expected '(' after 'map'}} expected-error {{expected at least one map clause for '#pragma omp target data'}}
+#pragma omp target data map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+#pragma omp target data map() // expected-error {{expected expression}}
+#pragma omp target data map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+#pragma omp target data map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+#pragma omp target data map(to:) // expected-error {{expected expression}}
+#pragma omp target data map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target data map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+#pragma omp target teams map(x)
+  foo();
+
+#pragma omp target teams map(to: x)
+  foo();
+#pragma omp target teams map(to: to)
+  foo();
+#pragma omp target teams map(to)
+  foo();
+#pragma omp target teams map(to, x)
+  foo();
+
+#pragma omp target data map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+#pragma omp target data map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{xpected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target data map(argc)
+#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(argv[1])
+#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(ca)
+#pragma omp target data map(da)
+#pragma omp target data map(S2::S2s)
+#pragma omp target data map(S2::S2sc)
+#pragma omp target data map(e, g)
+#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+#pragma omp target data map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+#pragma omp target teams map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
+  foo();
+
+#pragma omp target data map(da)
+#pragma omp target teams map(da[:4])
+  foo();
+
+#pragma omp target data map(k, j, l) // expected-note {{used here}}
+#pragma omp target data map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+#pragma omp target data map(j)
+#pragma omp target teams map(l) map(l[:5]) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+  foo();
+
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}}
+#pragma omp target data map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+#pragma omp target data map(j)
+#pragma omp target teams map(l)
+  foo();
+
+#pragma omp target data map(always, tofrom: x)
+#pragma omp target data map(always: x) // expected-error {{missing map type}}
+#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+#pragma omp target data map(always, tofrom: always, tofrom, x)
+#pragma omp target teams map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+  foo();
+
+#pragma omp target teams private(j) map(j) // expected-error {{private variable cannot be in a map clause in '#pragma omp target teams' directive}}  expected-note {{defined as private}}
+  {}
+
+#pragma omp target teams firstprivate(j) map(j)  // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target teams' directive}} expected-note {{defined as firstprivate}}
+  {}
+
+#pragma omp target teams map(m) // expected-error {{type 'S6<int>' is not mappable to target}}
+  {}
+
+  return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+#endif
diff --git a/test/OpenMP/target_teams_messages.cpp b/test/OpenMP/target_teams_messages.cpp
new file mode 100644
index 0000000..7fc7d1f
--- /dev/null
+++ b/test/OpenMP/target_teams_messages.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s
+
+void foo() {
+}
+
+#pragma omp target teams // expected-error {{unexpected OpenMP directive '#pragma omp target teams'}}
+
+int main(int argc, char **argv) {
+#pragma omp target teams { // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams ( // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams [ // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams ] // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams ) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams } // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams
+  foo();
+#pragma omp target teams unknown() // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+  L1:
+    foo();
+#pragma omp target teams
+  ;
+#pragma omp target teams
+  {
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+    argc++;
+  }
+
+  for (int i = 0; i < 10; ++i) {
+    switch(argc) {
+     case (0):
+      #pragma omp target teams
+      {
+        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 target teams 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 target teams
+  L2:
+  foo();
+#pragma omp target teams
+  {
+    return 1; // expected-error {{cannot return from OpenMP region}}
+  }
+
+  [[]] // expected-error {{an attribute list cannot appear here}}
+#pragma omp target teams
+  for (int n = 0; n < 100; ++n) {}
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_nowait_messages.cpp b/test/OpenMP/target_teams_nowait_messages.cpp
new file mode 100644
index 0000000..9cf8cc3
--- /dev/null
+++ b/test/OpenMP/target_teams_nowait_messages.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fopenmp -o - %s
+
+void foo() {
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams nowait device (-10u)
+  foo();
+#pragma omp target teams nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_num_teams_codegen.cpp b/test/OpenMP/target_teams_num_teams_codegen.cpp
new file mode 100644
index 0000000..6fcfa38
--- /dev/null
+++ b/test/OpenMP/target_teams_num_teams_codegen.cpp
@@ -0,0 +1,344 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// We have 6 target regions
+
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }]
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* [[REGFN:@.+]] to void ()*), i8* null }]
+
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+
+  #pragma omp target teams num_teams(tx(20))
+  {
+  }
+
+  short b = 1;
+  #pragma omp target teams num_teams(b)
+  {
+    a += b;
+  }
+
+  return a;
+}
+
+static
+int fstatic(int n) {
+
+  #pragma omp target teams num_teams(n)
+  {
+  }
+
+  #pragma omp target teams num_teams(32+n)
+  {
+  }
+
+  return n+1;
+}
+
+struct S1 {
+  double a;
+
+  int r1(int n){
+    int b = 1;
+
+    #pragma omp target teams num_teams(n-b)
+    {
+      this->a = (double)b + 1.5;
+    }
+
+    #pragma omp target teams num_teams(1024)
+    {
+      this->a = 2.5;
+    }
+
+    return (int)a;
+  }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+  int a = 0;
+
+  S1 S;
+  // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+  a += S.r1(n);
+
+  // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+  a += fstatic(n);
+
+  // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+
+
+//
+// CHECK: define {{.*}}[[FS1]]([[S1]]* {{%.+}}, i32 {{[^%]*}}[[PARM:%.+]])
+//
+// CHECK-DAG:   store i32 [[PARM]], i32* [[N_ADDR:%.+]], align
+// CHECK:       store i32 1, i32* [[B:%.+]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[BV:%.+]] = load i32, i32* [[B]], align
+// CHECK:       [[SUB:%.+]] = sub nsw i32 [[NV]], [[BV]]
+// CHECK:       store i32 [[SUB]], i32* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR:%.+]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[TEAMS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 [[TEAMS]], i32 0)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT1:@.+]]([[S1]]* {{%.+}}, i[[SZ]] {{%.+}}, i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.+}}, i32 1024, i32 0)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT2:@.+]]([[S1]]* {{[^,]+}})
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+
+
+
+
+
+
+//
+// CHECK: define {{.*}}[[FSTATIC]](i32 {{[^%]*}}[[PARM:%.+]])
+//
+// CHECK-DAG:   store i32 [[PARM]], i32* [[N_ADDR:%.+]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       store i32 [[NV]], i32* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR:%.+]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[TEAMS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 [[TEAMS]], i32 0)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT3:@.+]](i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[ADD:%.+]] = add nsw i32 32, [[NV]]
+// CHECK:       store i32 [[ADD]], i32* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR:%.+]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[TEAMS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 [[TEAMS]], i32 0)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT4:@.+]](i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+
+
+
+
+
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 20, i32 0)
+// CHECK-NEXT:  store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK-NEXT:  [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT5:@.+]]()
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK:       store i16 1, i16* [[B:%.+]], align
+// CHECK:       [[BV:%.+]] = load i16, i16* [[B]], align
+// CHECK:       store i16 [[BV]], i16* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i16, i16* [[CAPE_ADDR]], align
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i16*
+// CHECK:       store i16 [[CEV]], i16* [[CONV]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[T:%.+]] = load i16, i16* [[CAPE_ADDR]], align
+// CHECK:       [[TEAMS:%.+]] = sext i16 [[T]] to i32
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 [[TEAMS]], i32 0)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT6:@.+]](i[[SZ]] {{%.+}}, i[[SZ]] {{%.+}}, i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+
+
+
+
+
+
+// Check that the offloading functions are emitted and that the parallel function
+// is appropriately guarded.
+
+// CHECK:       define internal void [[HVT1]]([[S1]]* {{%.+}}, i[[SZ]] [[PARM1:%.+]], i[[SZ]] [[PARM2:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM2]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i32*
+// CHECK-64:    [[NT:%.+]] = load i32, i32* [[CONV]], align
+// CHECK-32:    [[NT:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]], i32 0)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 2,
+//
+//
+
+
+// CHECK:       define internal void [[HVT2]]([[S1]]* {{%.+}})
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 1024, i32 0)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1,
+//
+//
+
+
+
+
+
+
+
+
+// CHECK:       define internal void [[HVT3]](i[[SZ]] [[PARM:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i32*
+// CHECK-64:    [[NT:%.+]] = load i32, i32* [[CONV]], align
+// CHECK-32:    [[NT:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]], i32 0)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 0,
+//
+//
+// CHECK:       define internal void [[HVT4]](i[[SZ]] [[PARM:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i32*
+// CHECK-64:    [[NT:%.+]] = load i32, i32* [[CONV]], align
+// CHECK-32:    [[NT:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]], i32 0)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 0,
+//
+//
+
+
+
+
+
+// CHECK:       define internal void [[HVT5]](
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 20, i32 0)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 0,
+//
+//
+
+
+// CHECK:       define internal void [[HVT6]](i[[SZ]] [[PARM1:%.+]], i[[SZ]] [[PARM2:%.+]], i[[SZ]] [[PARM3:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM3]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i16*
+// CHECK:       [[T:%.+]] = load i16, i16* [[CONV]], align
+// CHECK:       [[NT:%.+]] = sext i16 [[T]] to i32
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]], i32 0)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 2,
+//
+//
+
+
+
+#endif
diff --git a/test/OpenMP/target_teams_num_teams_messages.cpp b/test/OpenMP/target_teams_num_teams_messages.cpp
new file mode 100644
index 0000000..e220fb6
--- /dev/null
+++ b/test/OpenMP/target_teams_num_teams_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <typename T, int C> // expected-note {{declared here}}
+T tmain(T argc) {
+  char **a;
+#pragma omp target teams num_teams(C)
+  foo();
+#pragma omp target teams num_teams(T) // expected-error {{'T' does not refer to a value}}
+  foo();
+#pragma omp target teams num_teams // expected-error {{expected '(' after 'num_teams'}}
+  foo();
+#pragma omp target teams num_teams( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams num_teams() // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams num_teams(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams num_teams(argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams num_teams(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  foo();
+#pragma omp target teams num_teams(argc + argc)
+  foo();
+#pragma omp target teams num_teams(argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'num_teams' clause}}
+  foo();
+#pragma omp target teams num_teams(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp target teams num_teams(-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  foo();
+#pragma omp target teams num_teams(-10u)
+  foo();
+#pragma omp target teams num_teams(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams num_teams // expected-error {{expected '(' after 'num_teams'}}
+  foo();
+
+#pragma omp target teams num_teams ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+
+#pragma omp target teams num_teams () // expected-error {{expected expression}}
+  foo();
+
+#pragma omp target teams num_teams (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+
+#pragma omp target teams num_teams (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+
+#pragma omp target teams num_teams (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  foo();
+
+#pragma omp target teams num_teams (argc + argc)
+  foo();
+
+#pragma omp target teams num_teams (argc), num_teams (argc+1) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'num_teams' clause}}
+  foo();
+
+#pragma omp target teams num_teams (S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+
+#pragma omp target teams num_teams (-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}}
+  foo();
+
+#pragma omp target teams num_teams (-10u)
+  foo();
+
+#pragma omp target teams num_teams (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  foo();
+
+  return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
+}
diff --git a/test/OpenMP/target_teams_private_messages.cpp b/test/OpenMP/target_teams_private_messages.cpp
new file mode 100644
index 0000000..69551ff
--- /dev/null
+++ b/test/OpenMP/target_teams_private_messages.cpp
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+public:
+  S3():a(0) { }
+};
+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 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+public:
+  S4(int v):a(v) { }
+};
+class S5 {
+  int a;
+  S5():a(0) {} // expected-note {{implicitly declared private here}}
+public:
+  S5(int v):a(v) { }
+};
+
+int threadvar;
+#pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  int i;
+  int &j = i;
+#pragma omp target teams private // expected-error {{expected '(' after 'private'}}
+  foo();
+#pragma omp target teams private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams private () // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams private (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams private (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp target teams private (argc argv) // expected-error {{expected ',' or ')' in 'private' clause}}
+  foo();
+#pragma omp target teams private (S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp target teams private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+  foo();
+#pragma omp target teams private (argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp target teams private(ba)
+  foo();
+#pragma omp target teams private(ca) // expected-error {{shared variable cannot be private}}
+  foo();
+#pragma omp target teams private(da) // expected-error {{shared variable cannot be private}}
+  foo();
+#pragma omp target teams private(S2::S2s) // expected-error {{shared variable cannot be private}}
+  foo();
+#pragma omp target teams private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+  foo();
+#pragma omp target teams private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
+  foo();
+#pragma omp target teams shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}}
+  foo();
+#pragma omp target teams firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}}
+  foo();
+#pragma omp target teams private(i)
+  foo();
+#pragma omp target teams private(j)
+  foo();
+#pragma omp target teams firstprivate(i)
+  for (int k = 0; k < 10; ++k) {
+#pragma omp parallel private(i)
+    foo();
+  }
+  static int m;
+#pragma omp target teams private(m) // OK
+  foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_reduction_messages.cpp b/test/OpenMP/target_teams_reduction_messages.cpp
new file mode 100644
index 0000000..48fa310
--- /dev/null
+++ b/test/OpenMP/target_teams_reduction_messages.cpp
@@ -0,0 +1,266 @@
+// RUN: %clang_cc1 -verify -fopenmp -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+void foobar(int &ref) {
+#pragma omp target teams reduction(+:ref)
+  foo();
+}
+
+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); } // expected-note 3 {{implicitly declared private here}}
+
+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 3 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  int b;
+  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 3 {{'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 {
+  int a;
+  S4(); // expected-note {{implicitly declared private here}}
+  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) {} // expected-note {{implicitly declared private here}}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o;
+
+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) {
+  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;
+#pragma omp target teams reduction // expected-error {{expected '(' after 'reduction'}}
+  foo();
+#pragma omp target teams reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp target teams reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  foo();
+#pragma omp target teams reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp target teams reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  foo();
+#pragma omp target teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  foo();
+#pragma omp target teams reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+  foo();
+#pragma omp target teams reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+  foo();
+#pragma omp target teams reduction(&& : argc)
+  foo();
+#pragma omp target teams reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  foo();
+#pragma omp target teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+  foo();
+#pragma omp target teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  foo();
+#pragma omp target teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  foo();
+#pragma omp target teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+  foo();
+#pragma omp target teams 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 target teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp target teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+  foo();
+#pragma omp target teams reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp target teams
+#pragma omp parallel for private(fl)
+  for (int i = 0; i < 10; ++i)
+  {}
+#pragma omp target teams reduction(+ : fl)
+    foo();
+#pragma omp target teams
+#pragma omp parallel for reduction(- : fl)
+  for (int i = 0; i < 10; ++i)
+  {}
+#pragma omp target teams reduction(+ : fl)
+    foo();
+
+  return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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);
+  S5 g(5);
+  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;
+#pragma omp target teams reduction // expected-error {{expected '(' after 'reduction'}}
+  foo();
+#pragma omp target teams reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp target teams reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  foo();
+#pragma omp target teams reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp target teams 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 target teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+  foo();
+#pragma omp target teams reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  foo();
+#pragma omp target teams reduction(&& : argc)
+  foo();
+#pragma omp target teams reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp target teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+  foo();
+#pragma omp target teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item 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 list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+  foo();
+#pragma omp target teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+  foo();
+#pragma omp target teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+  foo();
+#pragma omp target teams reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+  foo();
+#pragma omp target teams reduction(+ : o) // expected-error {{no viable overloaded '='}}
+  foo();
+#pragma omp target teams 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 target teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp target teams reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  foo();
+#pragma omp target teams reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+  foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target teams reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp target teams
+#pragma omp parallel for private(fl)
+  for (int i = 0; i < 10; ++i)
+  {}
+#pragma omp target teams reduction(+ : fl)
+    foo();
+#pragma omp target teams
+#pragma omp parallel for reduction(- : fl)
+  for (int i = 0; i < 10; ++i)
+  {}
+#pragma omp target teams reduction(+ : fl)
+    foo();
+  static int m;
+#pragma omp target teams reduction(+ : m) // OK
+  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/target_teams_shared_messages.cpp b/test/OpenMP/target_teams_shared_messages.cpp
new file mode 100644
index 0000000..84e412e
--- /dev/null
+++ b/test/OpenMP/target_teams_shared_messages.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -verify -fopenmp %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}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+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 target teams shared // expected-error {{expected '(' after 'shared'}}
+  foo();
+#pragma omp target teams shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams shared () // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp target teams shared (argc)
+ foo();
+#pragma omp target teams shared (S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp target teams shared (a, b, c, d, f)
+  foo();
+#pragma omp target teams shared (argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp target teams shared(ba)
+  foo();
+#pragma omp target teams shared(ca)
+  foo();
+#pragma omp target teams shared(da)
+  foo();
+#pragma omp target teams shared(e, g)
+  foo();
+#pragma omp target teams shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+  foo();
+#pragma omp target teams private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+  foo();
+#pragma omp target teams firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+  foo();
+#pragma omp target teams private(i)
+  foo();
+#pragma omp target teams shared(i)
+  foo();
+#pragma omp target teams shared(j)
+  foo();
+#pragma omp target teams firstprivate(i)
+  foo();
+#pragma omp target teams shared(i)
+  foo();
+#pragma omp target teams shared(j)
+  foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/target_teams_thread_limit_codegen.cpp b/test/OpenMP/target_teams_thread_limit_codegen.cpp
new file mode 100644
index 0000000..b2fe1bf
--- /dev/null
+++ b/test/OpenMP/target_teams_thread_limit_codegen.cpp
@@ -0,0 +1,357 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// We have 6 target regions
+
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }]
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* [[REGFN:@.+]] to void ()*), i8* null }]
+
+
+template<typename tx>
+tx ftemplate(int n) {
+  tx a = 0;
+
+  #pragma omp target teams thread_limit(tx(20))
+  {
+  }
+
+  short b = 1;
+  #pragma omp target teams num_teams(b) thread_limit(1024)
+  {
+    a += b;
+  }
+
+  return a;
+}
+
+static
+int fstatic(int n) {
+
+  #pragma omp target teams num_teams(n) thread_limit(n*32)
+  {
+  }
+
+  #pragma omp target teams thread_limit(32+n)
+  {
+  }
+
+  return n+1;
+}
+
+struct S1 {
+  double a;
+
+  int r1(int n){
+    int b = 1;
+
+    #pragma omp target teams thread_limit(n-b)
+    {
+      this->a = (double)b + 1.5;
+    }
+
+    #pragma omp target teams thread_limit(1024)
+    {
+      this->a = 2.5;
+    }
+
+    return (int)a;
+  }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+  int a = 0;
+
+  S1 S;
+  // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+  a += S.r1(n);
+
+  // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+  a += fstatic(n);
+
+  // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+  a += ftemplate<int>(n);
+
+  return a;
+}
+
+
+
+//
+// CHECK: define {{.*}}[[FS1]]([[S1]]* {{%.+}}, i32 {{[^%]*}}[[PARM:%.+]])
+//
+// CHECK-DAG:   store i32 [[PARM]], i32* [[N_ADDR:%.+]], align
+// CHECK:       store i32 1, i32* [[B:%.+]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[BV:%.+]] = load i32, i32* [[B]], align
+// CHECK:       [[SUB:%.+]] = sub nsw i32 [[NV]], [[BV]]
+// CHECK:       store i32 [[SUB]], i32* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR:%.+]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[TL:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 0, i32 [[TL]])
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT1:@.+]]([[S1]]* {{%.+}}, i[[SZ]] {{%.+}}, i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.+}}, i32 0, i32 1024)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT2:@.+]]([[S1]]* {{[^,]+}})
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+
+
+
+
+
+
+//
+// CHECK: define {{.*}}[[FSTATIC]](i32 {{[^%]*}}[[PARM:%.+]])
+//
+// CHECK-DAG:   store i32 [[PARM]], i32* [[N_ADDR:%.+]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       store i32 [[NV]], i32* [[CAPE_ADDR1:%.+]], align
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[MUL:%.+]] = mul nsw i32 [[NV]], 32
+// CHECK:       store i32 [[MUL]], i32* [[CAPE_ADDR2:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR1]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR1:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR1:%.+]], align
+// CHECK:       [[ARG1:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR1]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR2]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR2:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR2:%.+]], align
+// CHECK:       [[ARG2:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR2]], align
+// CHECK:       [[TEAMS:%.+]] = load i32, i32* [[CAPE_ADDR1]], align
+// CHECK:       [[TL:%.+]] = load i32, i32* [[CAPE_ADDR2]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 [[TEAMS]], i32 [[TL]])
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT3:@.+]](i[[SZ]] [[ARG1]], i[[SZ]] [[ARG2]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK:       [[NV:%.+]] = load i32, i32* [[N_ADDR]], align
+// CHECK:       [[ADD:%.+]] = add nsw i32 32, [[NV]]
+// CHECK:       store i32 [[ADD]], i32* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i32*
+// CHECK-64:    store i32 [[CEV]], i32* [[CONV]], align
+// CHECK-32:    store i32 [[CEV]], i32* [[CAPEC_ADDR:%.+]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[TL:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 0, i32 [[TL]])
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT4:@.+]](i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+
+
+
+
+
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 0, i32 20)
+// CHECK-NEXT:  store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK-NEXT:  [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK-NEXT:  [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT:  br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT5:@.+]]()
+// CHECK:       br label {{%?}}[[END]]
+//
+// CHECK:       [[END]]
+//
+//
+//
+// CHECK:       store i16 1, i16* [[B:%.+]], align
+// CHECK:       [[BV:%.+]] = load i16, i16* [[B]], align
+// CHECK:       store i16 [[BV]], i16* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CEV:%.+]] = load i16, i16* [[CAPE_ADDR]], align
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i16*
+// CHECK:       store i16 [[CEV]], i16* [[CONV]], align
+// CHECK:       [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
+// CHECK:       [[T:%.+]] = load i16, i16* [[CAPE_ADDR]], align
+// CHECK:       [[TEAMS:%.+]] = sext i16 [[T]] to i32
+//
+// CHECK-DAG:   [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 [[TEAMS]], i32 1024)
+// CHECK:       store i32 [[RET]], i32* [[RHV:%.+]], align
+// CHECK:       [[RET2:%.+]] = load i32, i32* [[RHV]], align
+// CHECK:       [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK:       br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+//
+// CHECK:       [[FAIL]]
+// CHECK:       call void [[HVT6:@.+]](i[[SZ]] {{%.+}}, i[[SZ]] {{%.+}}, i[[SZ]] [[ARG]])
+// CHECK:       br label {{%?}}[[END]]
+// CHECK:       [[END]]
+//
+
+
+
+
+
+
+// Check that the offloading functions are emitted and that the parallel function
+// is appropriately guarded.
+
+// CHECK:       define internal void [[HVT1]]([[S1]]* {{%.+}}, i[[SZ]] [[PARM1:%.+]], i[[SZ]] [[PARM2:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM2]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i32*
+// CHECK-64:    [[TL:%.+]] = load i32, i32* [[CONV]], align
+// CHECK-32:    [[TL:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 0, i32 [[TL]])
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 2,
+//
+//
+
+
+// CHECK:       define internal void [[HVT2]]([[S1]]* {{%.+}})
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 0, i32 1024)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1,
+//
+//
+
+
+
+
+
+
+
+
+// CHECK:       define internal void [[HVT3]](i[[SZ]] [[PARM1:%.+]], i[[SZ]] [[PARM2:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM1]], i[[SZ]]* [[CAPE_ADDR1:%.+]], align
+// CHECK-DAG:   store i[[SZ]] [[PARM2]], i[[SZ]]* [[CAPE_ADDR2:%.+]], align
+// CHECK-64:    [[CONV1:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR1]] to i32*
+// CHECK-64:    [[CONV2:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR2]] to i32*
+// CHECK-64:    [[NT:%.+]] = load i32, i32* [[CONV1]], align
+// CHECK-64:    [[TL:%.+]] = load i32, i32* [[CONV2]], align
+// CHECK-32:    [[NT:%.+]] = load i32, i32* [[CAPE_ADDR1]], align
+// CHECK-32:    [[TL:%.+]] = load i32, i32* [[CAPE_ADDR2]], align
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]], i32 [[TL]])
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 0,
+//
+//
+// CHECK:       define internal void [[HVT4]](i[[SZ]] [[PARM:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK-64:    [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i32*
+// CHECK-64:    [[TL:%.+]] = load i32, i32* [[CONV]], align
+// CHECK-32:    [[TL:%.+]] = load i32, i32* [[CAPE_ADDR]], align
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 0, i32 [[TL]])
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 0,
+//
+//
+
+
+
+
+
+// CHECK:       define internal void [[HVT5]](
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 0, i32 20)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 0,
+//
+//
+
+
+// CHECK:       define internal void [[HVT6]](i[[SZ]] [[PARM1:%.+]], i[[SZ]] [[PARM2:%.+]], i[[SZ]] [[PARM3:%.+]])
+// CHECK-DAG:   store i[[SZ]] [[PARM3]], i[[SZ]]* [[CAPE_ADDR:%.+]], align
+// CHECK:       [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i16*
+// CHECK:       [[T:%.+]] = load i16, i16* [[CONV]], align
+// CHECK:       [[NT:%.+]] = sext i16 [[T]] to i32
+// CHECK:       call i32 @__kmpc_push_num_teams(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 [[NT]], i32 1024)
+// CHECK:       call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 2,
+//
+//
+
+
+
+#endif
diff --git a/test/OpenMP/target_teams_thread_limit_messages.cpp b/test/OpenMP/target_teams_thread_limit_messages.cpp
new file mode 100644
index 0000000..2685f24
--- /dev/null
+++ b/test/OpenMP/target_teams_thread_limit_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <typename T, int C> // expected-note {{declared here}}
+T tmain(T argc) {
+  char **a;
+#pragma omp target teams thread_limit(C)
+  foo();
+#pragma omp target teams thread_limit(T) // expected-error {{'T' does not refer to a value}}
+  foo();
+#pragma omp target teams thread_limit // expected-error {{expected '(' after 'thread_limit'}}
+  foo();
+#pragma omp target teams thread_limit( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams thread_limit() // expected-error {{expected expression}}
+  foo();
+#pragma omp target teams thread_limit(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp target teams thread_limit(argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+#pragma omp target teams thread_limit(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  foo();
+#pragma omp target teams thread_limit(argc + argc)
+  foo();
+#pragma omp target teams thread_limit(argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'thread_limit' clause}}
+  foo();
+#pragma omp target teams thread_limit(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp target teams thread_limit(-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}}
+  foo();
+#pragma omp target teams thread_limit(-10u)
+  foo();
+#pragma omp target teams thread_limit(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target teams thread_limit // expected-error {{expected '(' after 'thread_limit'}}
+  foo();
+
+#pragma omp target teams thread_limit ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+
+#pragma omp target teams thread_limit () // expected-error {{expected expression}}
+  foo();
+
+#pragma omp target teams thread_limit (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+
+#pragma omp target teams thread_limit (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}}
+  foo();
+
+#pragma omp target teams thread_limit (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  foo();
+
+#pragma omp target teams thread_limit (argc + argc)
+  foo();
+
+#pragma omp target teams thread_limit (argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'thread_limit' clause}}
+  foo();
+
+#pragma omp target teams thread_limit (S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+
+#pragma omp target teams thread_limit (-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}}
+  foo();
+
+#pragma omp target teams thread_limit (-10u)
+  foo();
+
+#pragma omp target teams thread_limit (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+  foo();
+
+  return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
+}
diff --git a/test/OpenMP/target_update_if_messages.cpp b/test/OpenMP/target_update_if_messages.cpp
index 97715e0..3d076a6 100644
--- a/test/OpenMP/target_update_if_messages.cpp
+++ b/test/OpenMP/target_update_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
@@ -23,7 +23,7 @@
 #pragma omp target update to(n) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update from(n) if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update to(n) if(argc)
-#pragma omp target update from(n) if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update from(n) if(target update // expected-error {{use of undeclared identifier 'target'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update to(n) if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update from(n) if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update to(n) if(target update : argc)
@@ -47,7 +47,7 @@
 #pragma omp target update from(m) if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update to(m) if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update from(m) if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
-#pragma omp target update to(m) if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(m) if(target update // expected-error {{use of undeclared identifier 'target'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update from(m) if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update to(m) if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp target update from(m) if(target update : argc)
diff --git a/test/OpenMP/task_ast_print.cpp b/test/OpenMP/task_ast_print.cpp
index 3481d5d..9a7d64e 100644
--- a/test/OpenMP/task_ast_print.cpp
+++ b/test/OpenMP/task_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/task_if_codegen.cpp b/test/OpenMP/task_if_codegen.cpp
index f176897..5952085 100644
--- a/test/OpenMP/task_if_codegen.cpp
+++ b/test/OpenMP/task_if_codegen.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
 // expected-no-diagnostics
 #ifndef HEADER
 #define HEADER
diff --git a/test/OpenMP/task_if_messages.cpp b/test/OpenMP/task_if_messages.cpp
index f3f56d5..89b10f7 100644
--- a/test/OpenMP/task_if_messages.cpp
+++ b/test/OpenMP/task_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
diff --git a/test/OpenMP/taskloop_ast_print.cpp b/test/OpenMP/taskloop_ast_print.cpp
index b70fd8e..d2fae3f 100644
--- a/test/OpenMP/taskloop_ast_print.cpp
+++ b/test/OpenMP/taskloop_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/taskloop_simd_ast_print.cpp b/test/OpenMP/taskloop_simd_ast_print.cpp
index a7ec43e..f16b470 100644
--- a/test/OpenMP/taskloop_simd_ast_print.cpp
+++ b/test/OpenMP/taskloop_simd_ast_print.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_collapse_messages.cpp b/test/OpenMP/teams_distribute_collapse_messages.cpp
index e21eab2..37c10e5 100644
--- a/test/OpenMP/teams_distribute_collapse_messages.cpp
+++ b/test/OpenMP/teams_distribute_collapse_messages.cpp
@@ -1,8 +1,13 @@
 // RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++98
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++11
 
 void foo() {
 }
 
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
 bool foobool(int argc) {
   return argc;
 }
@@ -50,6 +55,9 @@
   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 teams distribute', but found only 1}}
 
+#if __cplusplus >= 201103L
+// expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used}}
+#endif
 // expected-error@+4 2 {{directive '#pragma omp teams distribute' cannot contain more than one 'collapse' clause}}
 // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
 // expected-error@+2 2 {{expression is not an integral constant expression}}
@@ -58,11 +66,16 @@
   for (int i = ST; i < N; i++)
     argv[0][i] = argv[0][i] - argv[0][i-ST];
 
-#pragma omp distribute collapse (S) // expected-error {{'S' does not refer to a value}}
+#pragma omp target
+#pragma omp teams distribute 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@+2 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-error@+5 2 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+3 2 {{expression is not an integral constant expression}}
+#endif
 #pragma omp target
 #pragma omp teams distribute collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = ST; i < N; i++)
@@ -110,11 +123,17 @@
   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 teams distribute', but found only 1}}
 
+#if __cplusplus >= 201103L
+// expected-note@+3 {{non-constexpr function 'foobool' cannot be used}}
+#endif
 #pragma omp target
 #pragma omp teams distribute 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];
 
+#if __cplusplus >= 201103L
+// expected-note@+6 {{non-constexpr function 'foobool' cannot be used}}
+#endif
 // expected-error@+4 {{expression is not an integral constant expression}}
 // expected-error@+3 2 {{directive '#pragma omp teams distribute' cannot contain more than one 'collapse' clause}}
 // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
@@ -128,7 +147,11 @@
   for (int i = 4; i < 12; i++)
     argv[0][i] = argv[0][i] - argv[0][i-4];
 
-// expected-error@+2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-error@+5 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+3 {{expression is not an integral constant expression}}
+#endif
 #pragma omp target
 #pragma omp teams distribute collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = 4; i < 12; i++)
diff --git a/test/OpenMP/teams_distribute_parallel_for_collapse_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_collapse_messages.cpp
index d48de04..ea4455d 100644
--- a/test/OpenMP/teams_distribute_parallel_for_collapse_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_collapse_messages.cpp
@@ -1,8 +1,13 @@
 // RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++98
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++11
 
 void foo() {
 }
 
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
 bool foobool(int argc) {
   return argc;
 }
@@ -50,6 +55,9 @@
   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 teams distribute parallel for', but found only 1}}
 
+#if __cplusplus >= 201103L
+// expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used}}
+#endif
 // expected-error@+4 2 {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'collapse' clause}}
 // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
 // expected-error@+2 2 {{expression is not an integral constant expression}}
@@ -62,7 +70,11 @@
   for (int i = ST; i < N; i++)
     argv[0][i] = argv[0][i] - argv[0][i-ST];
 
-// expected-error@+2 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-error@+5 2 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+3 2 {{expression is not an integral constant expression}}
+#endif
 #pragma omp target
 #pragma omp teams distribute parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = ST; i < N; i++)
@@ -110,11 +122,17 @@
   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 teams distribute parallel for', but found only 1}}
 
+#if __cplusplus >= 201103L
+// expected-note@+3 {{non-constexpr function 'foobool' cannot be used}}
+#endif
 #pragma omp target
 #pragma omp teams distribute 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];
 
+#if __cplusplus >= 201103L
+// expected-note@+6 {{non-constexpr function 'foobool' cannot be used}}
+#endif
 // expected-error@+4 {{expression is not an integral constant expression}}
 // expected-error@+3 2 {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'collapse' clause}}
 // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
@@ -128,7 +146,11 @@
   for (int i = 4; i < 12; i++)
     argv[0][i] = argv[0][i] - argv[0][i-4];
 
-// expected-error@+2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-error@+5 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+3 {{expression is not an integral constant expression}}
+#endif
 #pragma omp target
 #pragma omp teams distribute parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = 4; i < 12; i++)
diff --git a/test/OpenMP/teams_distribute_parallel_for_if_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_if_messages.cpp
index 67a89d1..14253b8 100644
--- a/test/OpenMP/teams_distribute_parallel_for_if_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
@@ -46,7 +46,7 @@
 #pragma omp teams distribute parallel for if(argc)
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp teams distribute parallel for if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -112,7 +112,7 @@
 #pragma omp teams distribute 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();
 #pragma omp target
-#pragma omp teams distribute parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp teams distribute parallel for if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
diff --git a/test/OpenMP/teams_distribute_parallel_for_proc_bind_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_proc_bind_messages.cpp
new file mode 100644
index 0000000..2a7074a
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_proc_bind_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo();
+
+template <class T, typename S, int N>
+T tmain(T argc, S **argv) {
+  T i;
+#pragma omp target
+#pragma omp teams distribute parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams distribute 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 target
+#pragma omp teams distribute 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 target
+#pragma omp teams distribute parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams distribute parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'proc_bind' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams distribute 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 target
+#pragma omp teams distribute parallel for proc_bind(master)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target
+#pragma omp teams distribute parallel for proc_bind(spread)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp target
+#pragma omp teams distribute parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams distribute 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 target
+#pragma omp teams distribute 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 target
+#pragma omp teams distribute parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams distribute parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'proc_bind' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams distribute 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 target
+#pragma omp teams distribute parallel for proc_bind(master)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target
+#pragma omp teams distribute parallel for proc_bind(spread)
+  for (i = 0; i < argc; ++i)
+    foo();
+  return tmain<int, char, 3>(argc, argv);
+}
diff --git a/test/OpenMP/teams_distribute_parallel_for_schedule_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_schedule_messages.cpp
new file mode 100644
index 0000000..477d1a0
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_schedule_messages.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 -verify -fopenmp %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-error@+2 {{expected '(' after 'schedule'}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule ()
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (auto
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (auto_dynamic
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (auto,
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (runtime, 3)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (guided argc
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 2 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams distribute 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];
+
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp teams distribute parallel for' are ignored}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (dynamic, 1))
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams distribute 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@+3 2 {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'schedule' clause}}
+// expected-error@+2 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams distribute 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];
+
+// expected-error@+2 {{'S' does not refer to a value}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (static, S)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+3 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (guided, argv[1]=2)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (dynamic, 1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+2 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (static, N)
+  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) {
+// expected-error@+2 {{expected '(' after 'schedule'}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+2 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+2 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule ()
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (auto
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+2 {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (auto_dynamic
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (auto,
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (runtime, 3)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (guided, 4
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp teams distribute parallel for' are ignored}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (static, 2+2))
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams distribute 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@+3 2 {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'schedule' clause}}
+// expected-error@+2 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams distribute 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];
+
+// expected-error@+2 {{'S1' does not refer to a value}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (guided, S1)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule (static, argv[1]=2)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+4 {{statement after '#pragma omp teams distribute parallel for' must be a for loop}}
+// expected-note@+2 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target
+#pragma omp teams distribute parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{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/teams_distribute_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_collapse_messages.cpp
index 33eb9ee..197c5f1 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_collapse_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_collapse_messages.cpp
@@ -1,8 +1,13 @@
 // RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++98
+// RUN: %clang_cc1 -verify -fopenmp %s -std=c++11
 
 void foo() {
 }
 
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
 bool foobool(int argc) {
   return argc;
 }
@@ -19,8 +24,8 @@
 #pragma omp target
 #pragma omp teams distribute parallel for simd 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 target
 #pragma omp teams distribute parallel for simd collapse () // expected-error {{expected expression}}
   for (int i = ST; i < N; i++)
@@ -50,6 +55,9 @@
   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 teams distribute parallel for simd', but found only 1}}
 
+#if __cplusplus >= 201103L
+// expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used}}
+#endif
 // expected-error@+4 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'collapse' clause}}
 // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
 // expected-error@+2 2 {{expression is not an integral constant expression}}
@@ -62,7 +70,11 @@
   for (int i = ST; i < N; i++)
     argv[0][i] = argv[0][i] - argv[0][i-ST];
 
-// expected-error@+2 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-error@+5 2 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+3 2 {{expression is not an integral constant expression}}
+#endif
 #pragma omp target
 #pragma omp teams distribute parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = ST; i < N; i++)
@@ -110,11 +122,17 @@
   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 teams distribute parallel for simd', but found only 1}}
 
+#if __cplusplus >= 201103L
+// expected-note@+3 {{non-constexpr function 'foobool' cannot be used}}
+#endif
 #pragma omp target
 #pragma omp teams distribute parallel for 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];
 
+#if __cplusplus >= 201103L
+// expected-note@+6 {{non-constexpr function 'foobool' cannot be used}}
+#endif
 // expected-error@+4 {{expression is not an integral constant expression}}
 // expected-error@+3 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'collapse' clause}}
 // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
@@ -128,7 +146,11 @@
   for (int i = 4; i < 12; i++)
     argv[0][i] = argv[0][i] - argv[0][i-4];
 
-// expected-error@+2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-error@+5 {{integral constant expression must have integral or unscoped enumeration type}}
+#else
+// expected-error@+3 {{expression is not an integral constant expression}}
+#endif
 #pragma omp target
 #pragma omp teams distribute parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = 4; i < 12; i++)
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_if_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_if_messages.cpp
index 81bc383..01978d7 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_if_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_if_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s
 
 void foo() {
 }
@@ -46,7 +46,7 @@
 #pragma omp teams distribute parallel for simd if(argc)
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp teams distribute parallel for simd if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -112,7 +112,7 @@
 #pragma omp teams distribute parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
-#pragma omp teams distribute parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp teams distribute parallel for simd if(parallel // expected-error {{use of undeclared identifier 'parallel'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target
 #pragma omp teams distribute parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp
index 5f0d4a3..675ecb4 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp
@@ -659,12 +659,12 @@
     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}}
       }
-      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}}
+        throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
       return; // expected-error {{cannot return from OpenMP region}}
     }
     switch (i) {
@@ -676,7 +676,7 @@
     }
     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}}
+        throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
     }
   }
   if (c[9] > 10)
diff --git a/test/OpenMP/threadprivate_codegen.cpp b/test/OpenMP/threadprivate_codegen.cpp
index d2cbc15..3785b70 100644
--- a/test/OpenMP/threadprivate_codegen.cpp
+++ b/test/OpenMP/threadprivate_codegen.cpp
@@ -176,12 +176,12 @@
 // CHECK-TLS-DAG:  [[ST_S4_ST:@.+]] = linkonce_odr thread_local global %struct.S4 zeroinitializer
 // CHECK-TLS-DAG:  [[ST_S4_ST_GUARD:@_ZGVN2STI2S4E2stE]] = linkonce_odr thread_local global i64 0
 // CHECK-TLS-DAG:  @__tls_guard = internal thread_local global i8 0
-// CHECK-TLS-DAG:  @__dso_handle = external global i8
+// CHECK-TLS-DAG:  @__dso_handle = external hidden global i8
 // CHECK-TLS-DAG:  [[GS1_TLS_INIT:@_ZTHL3gs1]] = internal alias void (), void ()* @__tls_init
 // CHECK-TLS-DAG:  [[ARR_X_TLS_INIT:@_ZTH5arr_x]] = alias void (), void ()* @__tls_init
-// CHECK-TLS-DAG:  [[ST_INT_ST_TLS_INIT:@_ZTHN2STIiE2stE]] = linkonce_odr alias void (), void ()* @__tls_init
-// CHECK-TLS-DAG:  [[ST_FLOAT_ST_TLS_INIT:@_ZTHN2STIfE2stE]] = linkonce_odr alias void (), void ()* @__tls_init
-// CHECK-TLS-DAG:  [[ST_S4_ST_TLS_INIT:@_ZTHN2STI2S4E2stE]] = linkonce_odr alias void (), void ()* @__tls_init
+
+
+// CHECK-TLS-DAG:  [[ST_S4_ST_TLS_INIT:@_ZTHN2STI2S4E2stE]] = linkonce_odr alias void (), void ()* [[ST_S4_ST_CXX_INIT:@[^, ]*]]
 
 struct Static {
   static S3 s;
@@ -275,7 +275,7 @@
 // CHECK:      {{.*}}[[ARR_LOOP]]{{.*}}
 // CHECK-NEXT: [[ARR_ELEMENTPAST:%.*]] = phi [[S1]]* [ [[ARR_CUR]], {{.*}} ], [ [[ARR_ELEMENT:%.*]], {{.*}} ]
 // CHECK-NEXT: [[ARR_ELEMENT:%.*]] = getelementptr inbounds [[S1]], [[S1]]* [[ARR_ELEMENTPAST]], i{{.*}} -1
-// CHECK-NEXT: invoke {{.*}} [[S1_DTOR]]([[S1]]* [[ARR_ELEMENT]])
+// CHECK-NEXT: {{call|invoke}} {{.*}} [[S1_DTOR]]([[S1]]* [[ARR_ELEMENT]])
 // CHECK:      [[ARR_DONE:%.*]] = icmp eq [[S1]]* [[ARR_ELEMENT]], [[ARR_BEGIN]]
 // CHECK-NEXT: br i1 [[ARR_DONE]], label %[[ARR_EXIT:.*]], label %[[ARR_LOOP]]
 // CHECK:      {{.*}}[[ARR_EXIT]]{{.*}}
@@ -640,11 +640,11 @@
 // CHECK-TLS:   ret [2 x [3 x [[S1]]]]* [[ARR_X]]
 // CHECK-TLS: }
 // CHECK-TLS: define {{.*}} i32* [[ST_INT_ST_TLS_INITD]] {{#[0-9]+}} {
-// CHECK-TLS:   call void [[ST_INT_ST_TLS_INIT]]
+// CHECK-TLS-NOT:   call
 // CHECK-TLS:   ret i32* [[ST_INT_ST]]
 // CHECK-TLS: }
 // CHECK-TLS: define {{.*}} float* [[ST_FLOAT_ST_TLS_INITD]] {{#[0-9]+}} {
-// CHECK-TLS:   call void [[ST_FLOAT_ST_TLS_INIT]]
+// CHECK-TLS-NOT:   call
 // CHECK-TLS:   ret float* [[ST_FLOAT_ST]]
 // CHECK-TLS: }
 // CHECK-TLS: define {{.*}} [[S4]]* [[ST_S4_ST_TLS_INITD]] {{#[0-9]+}} {
@@ -923,7 +923,7 @@
 // CHECK-TLS: define {{.*}}void [[SM_CTOR2]]([[SMAIN]]* {{.*}}, i32 {{.*}})
 // CHECK-TLS: define {{.*}}void [[SM_DTOR2]]([[SMAIN]]* {{.*}})
 
-// CHECK-TLS: define internal void [[ST_S4_ST_CXX_INIT:@.*]]()
+// CHECK-TLS: define internal void [[ST_S4_ST_CXX_INIT]]()
 // CHECK-TLS: call void [[ST_S4_ST_CTOR1:@.*]]([[S4]]* [[ST_S4_ST]], i32 23)
 // CHECK-TLS: call i32 @__cxa_thread_atexit(void (i8*)* bitcast (void ([[S4]]*)* [[ST_S4_ST_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*)
 // CHECK-TLS: }
@@ -945,7 +945,7 @@
 // CHECK-TLS:      call void [[GS1_CXX_INIT]]
 // CHECK-TLS-NOT:  call void [[GS2_CXX_INIT]]
 // CHECK-TLS:      call void [[ARR_X_CXX_INIT]]
-// CHECK-TLS:      call void [[ST_S4_ST_CXX_INIT]]
+// CHECK-TLS-NOT:  call void [[ST_S4_ST_CXX_INIT]]
 // CHECK-TLS:      [[DONE_LABEL]]
 
 // CHECK-TLS-DAG:      declare {{.*}} void [[GS3_TLS_INIT]]
diff --git a/test/PCH/builtin-macro.c b/test/PCH/builtin-macro.c
new file mode 100644
index 0000000..4d01540
--- /dev/null
+++ b/test/PCH/builtin-macro.c
@@ -0,0 +1,35 @@
+// Test this without pch.
+// RUN: %clang_cc1 -D__DATE__= -D__TIMESTAMP__= -include %s -Wno-builtin-macro-redefined -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -D__DATE__= -D__TIMESTAMP__= -Wno-builtin-macro-redefined -emit-pch -o %t %s
+// RUN: %clang_cc1 -D__DATE__= -D__TIMESTAMP__= -Wno-builtin-macro-redefined -include-pch %t -fsyntax-only -verify %s 
+
+#if !defined(HEADER)
+#define HEADER
+
+#define __TIME__
+
+#undef __TIMESTAMP__
+#define __TIMESTAMP__
+
+// FIXME: undefs don't work well with pchs yet, see PR31311
+// Once that's fixed, add -U__COUNTER__ to all command lines and check that
+// an attempt to use __COUNTER__ at the bottom produces an error in both non-pch
+// and pch case (works fine in the former case already).
+// Same for #undef __FILE__ right here and a use of that at the bottom.
+//#undef __FILE__
+
+// Also spot-check a predefine
+#undef __STDC_HOSTED__
+
+#else
+
+const char s[] = __DATE__ " " __TIME__ " " __TIMESTAMP__;
+
+// Check that we pick up __DATE__ from the -D flag:
+int i = __DATE__ 4;
+
+const int d = __STDC_HOSTED__; // expected-error{{use of undeclared identifier '__STDC_HOSTED__'}}
+
+#endif
diff --git a/test/PCH/cxx1z-using-declaration.cpp b/test/PCH/cxx1z-using-declaration.cpp
new file mode 100644
index 0000000..a185ff1
--- /dev/null
+++ b/test/PCH/cxx1z-using-declaration.cpp
@@ -0,0 +1,35 @@
+// No PCH:
+// RUN: %clang_cc1 -pedantic -std=c++1z -include %s -verify %s
+//
+// With PCH:
+// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch %s -o %t
+// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s
+
+#ifndef HEADER
+#define HEADER
+
+template<typename ...T> struct A : T... {
+  using T::f ...;
+  template<typename ...U> void g(U ...u) { f(u...); }
+};
+
+struct X { void f(); };
+struct Y { void f(int); };
+struct Z { void f(int, int); };
+
+inline A<X, Y, Z> a;
+
+#else
+
+void test() {
+  a.g();
+  a.g(0);
+  a.g(0, 0);
+  // expected-error@13 {{no match}}
+  // expected-note@16 {{candidate}}
+  // expected-note@17 {{candidate}}
+  // expected-note@18 {{candidate}}
+  a.g(0, 0, 0); // expected-note {{instantiation of}}
+}
+
+#endif
diff --git a/test/PCH/decl-in-prototype.c b/test/PCH/decl-in-prototype.c
new file mode 100644
index 0000000..a291bf2
--- /dev/null
+++ b/test/PCH/decl-in-prototype.c
@@ -0,0 +1,27 @@
+// Test that we serialize the enum decl in the function prototype somehow.
+// These decls aren't serialized quite the same way as parameters.
+
+// Test this without pch.
+// RUN: %clang_cc1 -include %s -emit-llvm -o - %s | FileCheck %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %s
+// RUN: %clang_cc1 -include-pch %t -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define {{.*}}i32 @main()
+// CHECK:   ret i32 1
+
+#ifndef HEADER
+#define HEADER
+
+static inline __attribute__((always_inline)) f(enum { x, y } p) {
+  return y;
+}
+
+#else
+
+int main() {
+  return f(0);
+}
+
+#endif
diff --git a/test/PCH/empty-def-fwd-struct.h b/test/PCH/empty-def-fwd-struct.h
new file mode 100644
index 0000000..dda9827
--- /dev/null
+++ b/test/PCH/empty-def-fwd-struct.h
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-pch -x c++-header %s -std=c++14 -o %t.pch
+// RUN: %clang_cc1 -emit-llvm-only -x c++ /dev/null -std=c++14 -include-pch %t.pch -o %t.o
+struct FVector;
+struct FVector {};
+struct FBox {
+  FVector Min;
+  FBox(int);
+};
+namespace {
+FBox InvalidBoundingBox(0);
+}
+
diff --git a/test/PCH/macro-undef.cpp b/test/PCH/macro-undef.cpp
index c0ce2de..bfe87d1 100644
--- a/test/PCH/macro-undef.cpp
+++ b/test/PCH/macro-undef.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fsyntax-only -include-pch %t %s -Wuninitialized -verify
-// RUN: %clang_cc1 -fsyntax-only -include-pch %t %s -Wuninitialized -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++98 -emit-pch -o %t %s
+// RUN: %clang_cc1 -std=c++98 -fsyntax-only -include-pch %t %s -Wuninitialized -verify
+// RUN: %clang_cc1 -std=c++98 -fsyntax-only -include-pch %t %s -Wuninitialized -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
 
 #ifndef HEADER
 #define HEADER
diff --git a/test/PCH/objc_container.m b/test/PCH/objc_container.m
index 2af51cb..1852d5e 100644
--- a/test/PCH/objc_container.m
+++ b/test/PCH/objc_container.m
@@ -21,5 +21,5 @@
 // CHECK-IR: {{call.*objc_msgSend}}
 // CHECK-IR: ret void
 
-// CHECK-IR: attributes #0 = { nounwind {{.*}} }
+// CHECK-IR: attributes #0 = { noinline nounwind {{.*}} }
 // CHECK-IR: attributes #1 = { nonlazybind }
diff --git a/test/PCH/ocl_types.cl b/test/PCH/ocl_types.cl
index 21097c4..60323e1 100644
--- a/test/PCH/ocl_types.cl
+++ b/test/PCH/ocl_types.cl
@@ -1,9 +1,9 @@
 // Test this without pch.
-// RUN: %clang_cc1 -include %S/ocl_types.h -fsyntax-only %s -cl-std=CL2.0 -D__OPENCL_VERSION__=200
+// RUN: %clang_cc1 -triple spir-unknown-unknown -include %S/ocl_types.h -fsyntax-only %s -cl-std=CL2.0 -D__OPENCL_VERSION__=200
 
 // Test with pch.
-// RUN: %clang_cc1 -x cl -emit-pch -o %t %S/ocl_types.h -cl-std=CL2.0 -D__OPENCL_VERSION__=200
-// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s -ast-print -cl-std=CL2.0 -D__OPENCL_VERSION__=200
+// RUN: %clang_cc1 -triple spir-unknown-unknown -x cl -emit-pch -o %t %S/ocl_types.h -cl-std=CL2.0 -D__OPENCL_VERSION__=200
+// RUN: %clang_cc1 -triple spir-unknown-unknown -include-pch %t -fsyntax-only %s -ast-print -cl-std=CL2.0 -D__OPENCL_VERSION__=200
 
 void foo1(img1d_t img);
 
diff --git a/test/PCH/ocl_types.h b/test/PCH/ocl_types.h
index bdc4bb1..9639128 100644
--- a/test/PCH/ocl_types.h
+++ b/test/PCH/ocl_types.h
@@ -32,9 +32,6 @@
 // queue_t
 typedef queue_t q_t;
 
-// ndrange_t
-typedef ndrange_t range_t;
-
 // reserve_id_t
 typedef reserve_id_t reserveid_t;
 
diff --git a/test/PCH/uses-seh.cpp b/test/PCH/uses-seh.cpp
new file mode 100644
index 0000000..6fbfc97
--- /dev/null
+++ b/test/PCH/uses-seh.cpp
@@ -0,0 +1,29 @@
+// Make SEH works in PCH
+//
+// Test this without pch.
+// RUN: %clang_cc1 -fms-extensions -triple x86_64-windows-msvc -std=c++11 -include %s -emit-llvm -o - %s | FileCheck %s
+
+// Test with pch.
+// RUN: %clang_cc1 -fms-extensions -triple x86_64-windows-msvc -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fms-extensions -triple x86_64-windows-msvc -std=c++11 -include-pch %t -emit-llvm -o - %s | FileCheck %s
+
+#ifndef HEADER
+#define HEADER
+
+int shouldCatch();
+inline int f() {
+  __try {
+  } __except (shouldCatch()) {
+  }
+  return 0;
+}
+int x = f();
+
+// CHECK: define linkonce_odr i32 @"\01?f@@YAHXZ"()
+// CHECK: define internal i32 @"\01?filt$0@0@f@@"({{.*}})
+
+#else
+
+// empty
+
+#endif
diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp
index 4aba8f0..830412e 100644
--- a/test/Parser/MicrosoftExtensions.cpp
+++ b/test/Parser/MicrosoftExtensions.cpp
@@ -65,6 +65,12 @@
 struct
 struct_with_uuid2 {} ;
 
+enum __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
+enum_with_uuid { };
+enum enum_without_uuid { };
+
+int __declspec(uuid("000000A0-0000-0000-C000-000000000046")) inappropriate_uuid; // expected-warning {{'uuid' attribute only applies to classes and enumerations}}
+
 int uuid_sema_test()
 {
    struct_with_uuid var_with_uuid[1];
@@ -81,6 +87,15 @@
    __uuidof(const struct_with_uuid[1][1]);
    __uuidof(const struct_with_uuid*[1][1]); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
 
+   __uuidof(enum_with_uuid);
+   __uuidof(enum_without_uuid); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
+   __uuidof(enum_with_uuid*);
+   __uuidof(enum_without_uuid*); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
+   __uuidof(enum_with_uuid[1]);
+   __uuidof(enum_with_uuid*[1]); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
+   __uuidof(const enum_with_uuid[1][1]);
+   __uuidof(const enum_with_uuid*[1][1]); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
+
    __uuidof(var_with_uuid);
    __uuidof(var_without_uuid);// expected-error {{cannot call operator __uuidof on a type with no GUID}}
    __uuidof(var_with_uuid[1]);
diff --git a/test/Parser/attr-external-source-symbol-cxx11.cpp b/test/Parser/attr-external-source-symbol-cxx11.cpp
new file mode 100644
index 0000000..3457c6a
--- /dev/null
+++ b/test/Parser/attr-external-source-symbol-cxx11.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+[[clang::external_source_symbol(language="Swift", defined_in="module")]]
+void function() { }
diff --git a/test/Parser/attr-external-source-symbol.m b/test/Parser/attr-external-source-symbol.m
new file mode 100644
index 0000000..772fde0
--- /dev/null
+++ b/test/Parser/attr-external-source-symbol.m
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void function() __attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration)));
+
+__attribute__((external_source_symbol(language="Swift", defined_in="module")))
+@interface I
+
+- (void)method __attribute__((external_source_symbol(defined_in= "module")));
+
+@end
+
+enum E {
+  CaseA __attribute__((external_source_symbol(generated_declaration))),
+  CaseB __attribute__((external_source_symbol(generated_declaration, language="Swift")))
+} __attribute__((external_source_symbol(language = "Swift")));
+
+void f2()
+__attribute__((external_source_symbol())); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+void f3()
+__attribute__((external_source_symbol(invalid))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+void f4()
+__attribute__((external_source_symbol(language))); // expected-error {{expected '=' after language}}
+void f5()
+__attribute__((external_source_symbol(language=))); // expected-error {{expected string literal for language name in 'external_source_symbol' attribute}}
+void f6()
+__attribute__((external_source_symbol(defined_in=20))); // expected-error {{expected string literal for source container name in 'external_source_symbol' attribute}}
+
+void f7()
+__attribute__((external_source_symbol(generated_declaration, generated_declaration))); // expected-error {{duplicate 'generated_declaration' clause in an 'external_source_symbol' attribute}}
+void f8()
+__attribute__((external_source_symbol(language="Swift", language="Swift"))); // expected-error {{duplicate 'language' clause in an 'external_source_symbol' attribute}}
+void f9()
+__attribute__((external_source_symbol(defined_in="module", language="Swift", defined_in="foo"))); // expected-error {{duplicate 'defined_in' clause in an 'external_source_symbol' attribute}}
+
+void f10()
+__attribute__((external_source_symbol(generated_declaration, language="Swift", defined_in="foo", generated_declaration, generated_declaration, language="Swift"))); // expected-error {{duplicate 'generated_declaration' clause in an 'external_source_symbol' attribute}}
+
+void f11()
+__attribute__((external_source_symbol(language="Objective-C++", defined_in="Some file with spaces")));
+
+void f12()
+__attribute__((external_source_symbol(language="C Sharp", defined_in="file:////Hello world with spaces. cs")));
+
+void f13()
+__attribute__((external_source_symbol(language=Swift))); // expected-error {{expected string literal for language name in 'external_source_symbol' attribute}}
+
+void f14()
+__attribute__((external_source_symbol(=))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+
+void f15()
+__attribute__((external_source_symbol(="Swift"))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+
+void f16()
+__attribute__((external_source_symbol("Swift", "module", generated_declaration))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+
+void f17()
+__attribute__((external_source_symbol(language="Swift", "generated_declaration"))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+
+void f18()
+__attribute__((external_source_symbol(language= =))); // expected-error {{expected string literal for language name in 'external_source_symbol' attribute}}
+
+void f19()
+__attribute__((external_source_symbol(defined_in="module" language="swift"))); // expected-error {{expected ')'}} expected-note {{to match this '('}}
+
+void f20()
+__attribute__((external_source_symbol(defined_in="module" language="swift" generated_declaration))); // expected-error {{expected ')'}} expected-note {{to match this '('}}
+
+void f21()
+__attribute__((external_source_symbol(defined_in= language="swift"))); // expected-error {{expected string literal for source container name in 'external_source_symbol' attribute}}
+
+void f22()
+__attribute__((external_source_symbol)); // expected-error {{'external_source_symbol' attribute takes at least 1 argument}}
+
+void f23()
+__attribute__((external_source_symbol(defined_in=, language="swift" generated_declaration))); // expected-error {{expected string literal for source container name in 'external_source_symbol' attribute}} expected-error{{expected ')'}} expected-note{{to match this '('}}
+
+void f24()
+__attribute__((external_source_symbol(language = generated_declaration))); // expected-error {{expected string literal for language name in 'external_source_symbol' attribute}}
+
+void f25()
+__attribute__((external_source_symbol(defined_in=123, defined_in="module"))); // expected-error {{expected string literal for source container name in 'external_source_symbol'}} expected-error {{duplicate 'defined_in' clause in an 'external_source_symbol' attribute}}
+
+void f26()
+__attribute__((external_source_symbol(language=Swift, language="Swift", error))); // expected-error {{expected string literal for language name in 'external_source_symbol'}} expected-error {{duplicate 'language' clause in an 'external_source_symbol' attribute}} expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
diff --git a/test/Parser/backtrack-off-by-one.cpp b/test/Parser/backtrack-off-by-one.cpp
index 74b51cb..52e1c41 100644
--- a/test/Parser/backtrack-off-by-one.cpp
+++ b/test/Parser/backtrack-off-by-one.cpp
@@ -1,4 +1,7 @@
 // RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify %s -std=c++98
+// RUN: %clang_cc1 -verify %s -std=c++11
+// RUN: %clang_cc1 -verify %s -std=c++1z
 
 // PR25946
 // We had an off-by-one error in an assertion when annotating A<int> below.  Our
@@ -10,8 +13,14 @@
 
 // expected-error@+1 {{expected '{' after base class list}}
 template <typename T> class B : T // not ',' or '{'
-// expected-error@+3 {{C++ requires a type specifier for all declarations}}
-// expected-error@+2 {{expected ';' after top level declarator}}
+#if __cplusplus < 201103L
+// expected-error@+8 {{expected ';' after top level declarator}}
+#endif
+#if __cplusplus <= 201402L
+// expected-error@+5 {{C++ requires a type specifier for all declarations}}
+#else
+// expected-error@+3 {{expected unqualified-id}}
+#endif
 // expected-error@+1 {{expected ';' after class}}
 A<int> {
 };
diff --git a/test/Parser/colon-colon-parentheses.cpp b/test/Parser/colon-colon-parentheses.cpp
index b3db4fb..804e4f7 100644
--- a/test/Parser/colon-colon-parentheses.cpp
+++ b/test/Parser/colon-colon-parentheses.cpp
@@ -1,30 +1,36 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -DPR21815
-// RUN: cp %s %t
-// RUN: not %clang_cc1 -x c++ -fixit %t
-// RUN: %clang_cc1 -x c++ %t
+// RUN: %clang_cc1 %s -verify -fno-spell-checking
 
 struct S { static int a,b,c;};
-int S::(a);  // expected-error{{unexpected parenthesis after '::'}}
-int S::(b;  // expected-error{{unexpected parenthesis after '::'}}
+int S::(a);  // expected-error{{expected unqualified-id}}
+int S::(b;  // expected-error{{expected unqualified-id}}
+        );
 int S::c;
-int S::(*d);  // expected-error{{unexpected parenthesis after '::'}}
-int S::(*e;  // expected-error{{unexpected parenthesis after '::'}}
+int S::(*d);  // expected-error{{expected unqualified-id}}
+int S::(*e;  // expected-error{{expected unqualified-id}}
+        );
 int S::*f;
-int g = S::(a);  // expected-error{{unexpected parenthesis after '::'}}
-int h = S::(b;  // expected-error{{unexpected parenthesis after '::'}}
+int g = S::(a);  // expected-error {{expected unqualified-id}} expected-error {{use of undeclared identifier 'a'}}
+int h = S::(b;  // expected-error {{expected unqualified-id}} expected-error {{use of undeclared identifier 'b'}}
+            );
 int i = S::c;
 
 void foo() {
   int a;
-  a = ::(g);  // expected-error{{unexpected parenthesis after '::'}}
-  a = ::(h;  // expected-error{{unexpected parenthesis after '::'}}
+  a = ::(g);  // expected-error{{expected unqualified-id}}
+  a = ::(h;  // expected-error{{expected unqualified-id}}
   a = ::i;
 }
 
-#ifdef PR21815
+// The following tests used to be crash bugs.
+
+// PR21815
 // expected-error@+2{{C++ requires a type specifier for all declarations}}
 // expected-error@+1{{expected unqualified-id}}
 a (::( ));
 
 ::((c )); // expected-error{{expected unqualified-id}}
-#endif
+
+// PR26623
+int f1(::(B) p); // expected-error {{expected unqualified-id}} expected-error {{use of undeclared identifier 'B'}}
+
+int f2(::S::(C) p); // expected-error {{expected unqualified-id}} expected-error {{use of undeclared identifier 'C'}}
diff --git a/test/Parser/cxx-template-decl.cpp b/test/Parser/cxx-template-decl.cpp
index efa42ad..9ad422e 100644
--- a/test/Parser/cxx-template-decl.cpp
+++ b/test/Parser/cxx-template-decl.cpp
@@ -238,3 +238,13 @@
 // expected-error@-1 {{expected '{' after base class list}}
 
 }
+
+namespace class_scope_instantiation {
+  struct A {
+    template<typename T> void f(T);
+    template void f<int>(int); // expected-error {{expected '<' after 'template'}}
+    template void f(float); // expected-error {{expected '<' after 'template'}}
+    extern template // expected-error {{expected member name or ';'}}
+      void f(double);
+  };
+}
diff --git a/test/Parser/cxx0x-ambig.cpp b/test/Parser/cxx0x-ambig.cpp
index a47585f..4a1b4ad 100644
--- a/test/Parser/cxx0x-ambig.cpp
+++ b/test/Parser/cxx0x-ambig.cpp
@@ -109,7 +109,7 @@
 namespace ellipsis {
   template<typename...T>
   struct S {
-    void e(S::S());
+    void e(S::S()); // expected-error {{is a constructor name}}
     void f(S(...args[sizeof(T)])); // expected-note {{here}} expected-note {{here}}
     void f(S(...args)[sizeof(T)]); // expected-error {{redeclared}}
     void f(S ...args[sizeof(T)]); // expected-error {{redeclared}}
diff --git a/test/Parser/cxx0x-attributes.cpp b/test/Parser/cxx0x-attributes.cpp
index 906d72b..647762f 100644
--- a/test/Parser/cxx0x-attributes.cpp
+++ b/test/Parser/cxx0x-attributes.cpp
@@ -99,11 +99,13 @@
 }
 [[]];
 struct ctordtor {
-  [[]] ctordtor();
-  [[]] ~ctordtor();
+  [[]] ctordtor [[]] () [[]];
+  ctordtor (C) [[]];
+  [[]] ~ctordtor [[]] () [[]];
 };
-[[]] ctordtor::ctordtor() {}
-[[]] ctordtor::~ctordtor() {}
+[[]] ctordtor::ctordtor [[]] () [[]] {}
+[[]] ctordtor::ctordtor (C) [[]] try {} catch (...) {}
+[[]] ctordtor::~ctordtor [[]] () [[]] {}
 extern "C++" [[]] int extern_attr;
 template <typename T> [[]] void template_attr ();
 [[]] [[]] int [[]] [[]] multi_attr [[]] [[]];
diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp
index c4f0356..d912e19 100644
--- a/test/Parser/cxx0x-decl.cpp
+++ b/test/Parser/cxx0x-decl.cpp
@@ -136,5 +136,5 @@
                                                      ... [N]);
 
 // This must be at the end of the file; we used to look ahead past the EOF token here.
-// expected-error@+1 {{expected unqualified-id}}
+// expected-error@+1 {{expected unqualified-id}} expected-error@+1{{expected ';'}}
 using
diff --git a/test/Parser/cxx1z-class-template-argument-deduction.cpp b/test/Parser/cxx1z-class-template-argument-deduction.cpp
new file mode 100644
index 0000000..dac17df
--- /dev/null
+++ b/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -0,0 +1,194 @@
+// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
+
+template <typename T> struct A { // expected-note 35{{declared here}}
+  constexpr A() {}
+  constexpr A(int) {}
+  constexpr operator int() { return 0; }
+};
+A() -> A<int>;
+A(int) -> A<int>;
+
+// Make sure we still correctly parse cases where a template can appear without arguments.
+namespace template_template_arg {
+  template<template<typename> typename> struct X {};
+  template<typename> struct Y {};
+
+  X<A> xa;
+  Y<A> ya; // expected-error {{requires template arguments}}
+  X<::A> xcca;
+  Y<::A> ycca; // expected-error {{requires template arguments}}
+
+  template<template<typename> typename = A> struct XD {};
+  template<typename = A> struct YD {}; // expected-error {{requires template arguments}}
+  template<template<typename> typename = ::A> struct XCCD {};
+  template<typename = ::A> struct YCCD {}; // expected-error {{requires template arguments}}
+
+  // FIXME: replacing the invalid type with 'int' here is horrible
+  template <A a = A<int>()> class C { }; // expected-error {{requires template arguments}}
+  template<typename T = A> struct G { }; // expected-error {{requires template arguments}}
+}
+
+namespace injected_class_name {
+  template<typename T> struct A {
+    A(T);
+    void f(int) { // expected-note {{previous}}
+      A a = 1;
+      injected_class_name::A b = 1; // expected-note {{in instantiation of template class 'injected_class_name::A<int>'}}
+    }
+    void f(T); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (int)}}
+  };
+  A<short> ai = 1;
+  A<double>::A b(1); // expected-error {{constructor name}}
+}
+
+struct member {
+  A a; // expected-error {{requires template arguments}}
+  A *b; // expected-error {{requires template arguments}}
+  const A c; // expected-error {{requires template arguments}}
+
+  void f() throw (A); // expected-error {{requires template arguments}}
+
+  friend A; // expected-error {{requires template arguments; argument deduction not allowed in friend declaration}}
+
+  operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
+
+  static A x; // expected-error {{declaration of variable 'x' with deduced type 'A' requires an initializer}}
+  static constexpr A y = 0;
+};
+
+namespace in_typedef {
+  typedef A *AutoPtr; // expected-error {{requires template arguments; argument deduction not allowed in typedef}}
+  typedef A (*PFun)(int a); // expected-error{{requires template arguments; argument deduction not allowed in typedef}}
+  typedef A Fun(int a) -> decltype(a + a); // expected-error{{requires template arguments; argument deduction not allowed in function return type}}
+}
+
+namespace stmt {
+  void g(A a) { // expected-error{{requires template arguments; argument deduction not allowed in function prototype}}
+    try { }
+    catch (A &a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
+    catch (const A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
+    try { } catch (A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
+
+    // FIXME: The standard only permits class template argument deduction in a
+    // simple-declaration or cast. We also permit it in conditions,
+    // for-range-declarations, member-declarations for static data members, and
+    // new-expressions, because not doing so would be bizarre.
+    A local = 0;
+    static A local_static = 0;
+    static thread_local A thread_local_static = 0;
+    if (A a = 0) {}
+    if (A a = 0; a) {}
+    switch (A a = 0) {} // expected-warning {{no case matching constant switch condition '0'}}
+    switch (A a = 0; a) {} // expected-warning {{no case matching constant switch condition '0'}}
+    for (A a = 0; a; /**/) {}
+    for (/**/; A a = 0; /**/) {}
+    while (A a = 0) {}
+    int arr[3];
+    for (A a : arr) {}
+  }
+
+  namespace std {
+    class type_info;
+  }
+}
+
+namespace expr {
+  template<typename T> struct U {};
+  void j() {
+    (void)typeid(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
+    (void)sizeof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
+    (void)__alignof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
+
+    U<A> v; // expected-error {{requires template arguments}}
+
+    int n;
+    (void)dynamic_cast<A&>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
+    (void)static_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
+    (void)reinterpret_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
+    (void)const_cast<A>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
+    (void)*(A*)(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
+    (void)(A)(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
+    (void)(A){n}; // expected-error{{requires template arguments; argument deduction not allowed here}}
+
+    (void)A(n);
+    (void)A{n};
+    (void)new A(n);
+    (void)new A{n};
+    // FIXME: We should diagnose the lack of an initializer here.
+    (void)new A;
+  }
+}
+
+namespace decl {
+  enum E : A {}; // expected-error{{requires template arguments; argument deduction not allowed here}}
+  struct F : A {}; // expected-error{{expected class name}}
+
+  using B = A; // expected-error{{requires template arguments}}
+
+  auto k() -> A; // expected-error{{requires template arguments}}
+
+  A a; // expected-error {{declaration of variable 'a' with deduced type 'A' requires an initializer}}
+  A b = 0;
+  const A c = 0;
+  A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
+  A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
+  A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
+  A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
+  A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
+  A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
+  A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{type 'A<int>' decomposes into 0 elements, but 2 names were provided}}
+}
+
+namespace typename_specifier {
+  struct F {};
+
+  void e() {
+    (void) typename ::A(0);
+    (void) typename ::A{0};
+    new typename ::A(0);
+    new typename ::A{0};
+    typename ::A a = 0;
+    const typename ::A b = 0;
+    if (typename ::A a = 0) {}
+    for (typename ::A a = 0; typename ::A b = 0; /**/) {}
+
+    (void)(typename ::A)(0); // expected-error{{requires template arguments; argument deduction not allowed here}}
+    (void)(typename ::A){0}; // expected-error{{requires template arguments; argument deduction not allowed here}}
+  }
+  typename ::A a = 0;
+  const typename ::A b = 0;
+  typename ::A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
+  typename ::A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
+  typename ::A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
+  typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
+  typename ::A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
+  typename ::A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
+  typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{type 'typename ::A<int>' (aka 'A<int>') decomposes into 0}}
+
+  struct X { template<typename T> struct A { A(T); }; }; // expected-note 8{{declared here}}
+
+  template<typename T> void f() {
+    (void) typename T::A(0);
+    (void) typename T::A{0};
+    new typename T::A(0);
+    new typename T::A{0};
+    typename T::A a = 0;
+    const typename T::A b = 0;
+    if (typename T::A a = 0) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
+    for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
+
+    {(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
+    {(void)(typename T::A){0};} // expected-error{{refers to class template member}}
+    {typename T::A (parens) = 0;} // expected-error {{refers to class template member in 'typename_specifier::X'; argument deduction not allowed here}}
+    {typename T::A *p = 0;} // expected-error {{refers to class template member}}
+    {typename T::A &r = *p;} // expected-error {{refers to class template member}}
+    {typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
+    {typename T::A F::*pm = 0;} // expected-error {{refers to class template member}}
+    {typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}}
+    {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') decomposes into 0}}
+  }
+  template void f<X>(); // expected-note {{instantiation of}}
+
+  template<typename T> void g(typename T::A = 0); // expected-note {{refers to class template member}}
+  void h() { g<X>(); } // expected-error {{no matching function}}
+}
diff --git a/test/Parser/cxx1z-decomposition.cpp b/test/Parser/cxx1z-decomposition.cpp
index c5651c5..9cbe70e 100644
--- a/test/Parser/cxx1z-decomposition.cpp
+++ b/test/Parser/cxx1z-decomposition.cpp
@@ -139,9 +139,11 @@
     int arr[1];
     struct S { int n; };
     auto &[bad1]; // expected-error {{decomposition declaration '[bad1]' requires an initializer}}
-    const auto &[bad2](S{}); // expected-error {{decomposition declaration '[bad2]' cannot have a parenthesized initializer}}
+    const auto &[bad2](S{}, S{}); // expected-error {{initializer for variable '[bad2]' with type 'const auto &' contains multiple expressions}}
+    const auto &[bad3](); // expected-error {{expected expression}}
     auto &[good1] = arr;
     auto &&[good2] = S{};
+    const auto &[good3](S{});
     S [goodish3] = { 4 }; // expected-error {{cannot be declared with type 'S'}}
     S [goodish4] { 4 }; // expected-error {{cannot be declared with type 'S'}}
   }
diff --git a/test/Parser/cxx1z-fold-expressions.cpp b/test/Parser/cxx1z-fold-expressions.cpp
index 0306385..b1f7318 100644
--- a/test/Parser/cxx1z-fold-expressions.cpp
+++ b/test/Parser/cxx1z-fold-expressions.cpp
@@ -34,3 +34,12 @@
 template<int ...N> int bad10() { return (3 ? ... : N); } // expected-error +{{}} expected-note {{to match}}
 template<int ...N> int bad11() { return (N + ... 0); } // expected-error {{expected a foldable binary operator}} expected-error {{expected expression}}
 template<int ...N> int bad12() { return (... N); } // expected-error {{expected expression}}
+
+template<typename ...T> void as_operand_of_cast(int a, T ...t) {
+  return
+    (int)(a + ... + undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}}
+    (int)(t + ... + undeclared_junk) + // expected-error {{undeclared}}
+    (int)(... + undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}}
+    (int)(undeclared_junk + ...) + // expected-error {{undeclared}}
+    (int)(a + ...); // expected-error {{does not contain any unexpanded}}
+}
diff --git a/test/Parser/cxx1z-using-declaration.cpp b/test/Parser/cxx1z-using-declaration.cpp
new file mode 100644
index 0000000..0be8167
--- /dev/null
+++ b/test/Parser/cxx1z-using-declaration.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+namespace A {
+  int m, n;
+};
+
+namespace B {
+  using A::m, A::n, A::n;
+  int q = m + n;
+}
+
+struct X {
+  int x1, x2, y, z; // expected-note 2{{conflicting}}
+};
+struct Y {
+  int x1, x2, y, z; // expected-note 2{{target}}
+};
+struct Z : X, Y {
+  using X::x1,
+        blah::blah, // expected-error {{undeclared}}
+        X::x2, // expected-note {{previous}}
+        Y::y,
+        X::x2, // expected-error {{redeclaration}}
+        X::z,
+        Y::z; // expected-error {{conflicts with}}
+};
+int X::*px1 = &Z::x1;
+int X::*px2 = &Z::x2;
+int Y::*py = &Z::y;
+int X::*pz = &Z::z;
+
+template<typename ...T> struct Q : T... {
+  using T::z...; // expected-error {{conflicts}}
+};
+Q<X,Y> q; // expected-note {{instantiation of}}
diff --git a/test/Parser/declspec-recovery.c b/test/Parser/declspec-recovery.c
new file mode 100644
index 0000000..b256861
--- /dev/null
+++ b/test/Parser/declspec-recovery.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -verify %s
+
+__declspec(naked) void f(void) {} // expected-error{{'__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes}}
+
+struct S {
+  __declspec(property(get=Getter, put=Setter)) int X; // expected-error{{'__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes}}
+  int Y;
+};
diff --git a/test/Parser/declspec-supported.c b/test/Parser/declspec-supported.c
new file mode 100644
index 0000000..f900489
--- /dev/null
+++ b/test/Parser/declspec-supported.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -fms-extensions -verify %s
+// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -fdeclspec -verify %s
+// expected-no-diagnostics
+
+__declspec(naked) void f(void) {}
+
+struct S {
+  __declspec(property(get=Getter, put=Setter)) int X;
+  int Y;
+};
diff --git a/test/Parser/eof.cpp b/test/Parser/eof.cpp
index 3c966c5..4a06587 100644
--- a/test/Parser/eof.cpp
+++ b/test/Parser/eof.cpp
@@ -1,6 +1,6 @@
 // RUN: not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s
 
-// CHECK: error: expected member name or ';' after declaration specifiers
+// CHECK: error: expected '<' after 'template'
 // CHECK: error: expected '}'
 // CHECK: note: to match this '{'
 // CHECK: error: expected ';' after class
diff --git a/test/Parser/objc-property-syntax.m b/test/Parser/objc-property-syntax.m
index 38d12d5..8e56a09 100644
--- a/test/Parser/objc-property-syntax.m
+++ b/test/Parser/objc-property-syntax.m
@@ -4,7 +4,7 @@
   int prop;
 };
 @property unsigned char bufferedUTF8Bytes[4];  // expected-error {{property cannot have array or function type}}
-@property unsigned char bufferedUTFBytes:1;    // expected-error {{property name cannot be a bitfield}}
+@property unsigned char bufferedUTFBytes:1;    // expected-error {{property name cannot be a bit-field}}
 @property(nonatomic, retain, setter=ab_setDefaultToolbarItems) MyClass *ab_defaultToolbarItems; // expected-error {{method name referenced in property setter attribute must end with ':'}}
 
 @property int prop;
diff --git a/test/Parser/opencl-atomics-cl20.cl b/test/Parser/opencl-atomics-cl20.cl
index cd37757..65fb9d9 100644
--- a/test/Parser/opencl-atomics-cl20.cl
+++ b/test/Parser/opencl-atomics-cl20.cl
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20
+// RUN: %clang_cc1 %s -triple spir64-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20 -DEXT -Wpedantic-core-features
 
 #ifdef EXT
@@ -47,14 +48,16 @@
 // expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics extension to be enabled}}
 // expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics extension to be enabled}}
 // expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics extension to be enabled}}
-// expected-error-re@-27 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
-// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
-// expected-error-re@-28 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
-// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
-// expected-error-re@-29 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
-// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
-// expected-error-re@-30 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
-// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+#if __LP64__
+// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+#endif
 #endif
 
 #ifdef CL20
diff --git a/test/Parser/opencl-pragma.cl b/test/Parser/opencl-pragma.cl
index b002b08..02f053f 100644
--- a/test/Parser/opencl-pragma.cl
+++ b/test/Parser/opencl-pragma.cl
@@ -5,9 +5,9 @@
 #pragma OPENCL EXTENSION cl_no_such_extension : disable /* expected-warning {{unknown OpenCL extension 'cl_no_such_extension' - ignoring}} */
 
 #pragma OPENCL EXTENSION all : disable
-#pragma OPENCL EXTENSION all : enable /* expected-warning {{unknown OpenCL extension 'all' - ignoring}} */
+#pragma OPENCL EXTENSION all : enable /* expected-warning {{expected 'disable' - ignoring}} */
 
-#pragma OPENCL EXTENSION cl_khr_fp64 : on /* expected-warning {{expected 'enable' or 'disable' - ignoring}} */
+#pragma OPENCL EXTENSION cl_khr_fp64 : on /* expected-warning {{expected 'enable', 'disable', 'begin' or 'end' - ignoring}} */
 
 #pragma OPENCL FP_CONTRACT ON
 #pragma OPENCL FP_CONTRACT OFF
diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c
index 9a968e0..c9c7f2d 100644
--- a/test/Preprocessor/aarch64-target-features.c
+++ b/test/Preprocessor/aarch64-target-features.c
@@ -95,8 +95,9 @@
 // RUN: %clang -target aarch64 -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-CORTEX-A73 %s
 // RUN: %clang -target aarch64 -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M1 %s
 // RUN: %clang -target aarch64 -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M1 %s
+// RUN: %clang -target aarch64 -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M1 %s
 // RUN: %clang -target aarch64 -mcpu=kryo -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-KRYO %s
-// RUN: %clang -target aarch64 -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-VULCAN %s
+// RUN: %clang -target aarch64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-THUNDERX2T99 %s
 // CHECK-MCPU-CYCLONE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crypto" "-target-feature" "+zcm" "-target-feature" "+zcz"
 // CHECK-MCPU-A35: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
 // CHECK-MCPU-A53: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
@@ -105,7 +106,7 @@
 // CHECK-MCPU-CORTEX-A73: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
 // CHECK-MCPU-M1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
 // CHECK-MCPU-KRYO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
-// CHECK-MCPU-VULCAN: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
+// CHECK-MCPU-THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
 
 // RUN: %clang -target x86_64-apple-macosx -arch arm64 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH-ARM64 %s
 // CHECK-ARCH-ARM64: "-target-cpu" "cyclone" "-target-feature" "+neon" "-target-feature" "+crypto" "-target-feature" "+zcm" "-target-feature" "+zcz"
diff --git a/test/Preprocessor/arm-acle-6.4.c b/test/Preprocessor/arm-acle-6.4.c
index 11be2c1..3102bd4 100644
--- a/test/Preprocessor/arm-acle-6.4.c
+++ b/test/Preprocessor/arm-acle-6.4.c
@@ -120,6 +120,21 @@
 
 // CHECK-V7A-NO-IDIV-NOT: __ARM_FEATURE_IDIV
 
+// RUN: %clang -target arm-none-linux-eabi -march=armv7ve -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-V7VE
+
+// CHECK-V7VE: __ARM_ARCH 7
+// CHECK-V7VE: __ARM_ARCH_ISA_ARM 1
+// CHECK-V7VE: __ARM_ARCH_ISA_THUMB 2
+// CHECK-V7VE: __ARM_ARCH_PROFILE 'A'
+// CHECK-V7VE: __ARM_FEATURE_CLZ 1
+// CHECK-V7VE: __ARM_FEATURE_DSP 1
+// CHECK-V7VE: __ARM_FEATURE_IDIV 1
+// CHECK-V7VE: __ARM_FEATURE_LDREX 0xF
+// CHECK-V7VE: __ARM_FEATURE_QBIT 1
+// CHECK-V7VE: __ARM_FEATURE_SAT 1
+// CHECK-V7VE: __ARM_FEATURE_SIMD32 1
+// CHECK-V7VE: __ARM_FEATURE_UNALIGNED 1
+
 // RUN: %clang -target arm-none-linux-eabi -march=armv7-r -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-V7R
 
 // CHECK-V7R: __ARM_ARCH 7
diff --git a/test/Preprocessor/arm-acle-6.5.c b/test/Preprocessor/arm-acle-6.5.c
index cc158c8..7ad91bd 100644
--- a/test/Preprocessor/arm-acle-6.5.c
+++ b/test/Preprocessor/arm-acle-6.5.c
@@ -24,6 +24,7 @@
 // RUN: %clang -target arm-eabi -mfpu=neon -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-SP-DP
 // RUN: %clang -target armv6-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-SP-DP
 // RUN: %clang -target armv7a-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-SP-DP
+// RUN: %clang -target armv7ve-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-SP-DP
 
 // CHECK-SP-DP: __ARM_FP 0xC
 
@@ -51,6 +52,8 @@
 
 // RUN: %clang -target armv7a-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-NO-FMA
 // RUN: %clang -target armv7a-eabi -mfpu=vfpv4 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-FMA
+// RUN: %clang -target armv7ve-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-NO-FMA
+// RUN: %clang -target armv7ve-eabi -mfpu=vfpv4 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-FMA
 // RUN: %clang -target armv7r-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-NO-FMA
 // RUN: %clang -target armv7r-eabi -mfpu=vfpv4 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-FMA
 // RUN: %clang -target armv7em-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-FMA
diff --git a/test/Preprocessor/arm-target-features.c b/test/Preprocessor/arm-target-features.c
index 1a27d5b..81dab47 100644
--- a/test/Preprocessor/arm-target-features.c
+++ b/test/Preprocessor/arm-target-features.c
@@ -27,6 +27,13 @@
 // CHECK-V7-NOT: __ARM_FEATURE_DIRECTED_ROUNDING
 // CHECK-V7: #define __ARM_FP 0xC
 
+// RUN: %clang -target armv7ve-none-linux-gnu -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V7VE %s
+// CHECK-V7VE: #define __ARMEL__ 1
+// CHECK-V7VE: #define __ARM_ARCH 7
+// CHECK-V7VE: #define __ARM_ARCH_7VE__ 1
+// CHECK-V7VE: #define __ARM_ARCH_EXT_IDIV__ 1
+// CHECK-V7VE: #define __ARM_FP 0xC
+
 // RUN: %clang -target x86_64-apple-macosx10.10 -arch armv7s -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V7S %s
 // CHECK-V7S: #define __ARMEL__ 1
 // CHECK-V7S: #define __ARM_ARCH 7
@@ -389,6 +396,32 @@
 // M7-THUMB:#define __ARM_ARCH_EXT_IDIV__ 1
 // M7-THUMB:#define __ARM_FEATURE_DSP 1
 // M7-THUMB:#define __ARM_FP 0xE
+// M7-THUMB:#define __ARM_FPV5__ 1
+
+// Test whether predefines are as expected when targeting v8m cores
+// RUN: %clang -target arm -mcpu=cortex-m23 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=M23 %s
+// M23: #define __ARM_ARCH 8
+// M23: #define __ARM_ARCH_8M_BASE__ 1
+// M23: #define __ARM_ARCH_EXT_IDIV__ 1
+// M23-NOT: __ARM_ARCH_ISA_ARM
+// M23: #define __ARM_ARCH_ISA_THUMB 1
+// M23: #define __ARM_ARCH_PROFILE 'M'
+// M23-NOT: __ARM_FEATURE_CRC32
+// M23-NOT: __ARM_FEATURE_DSP
+// M23-NOT: __ARM_FP 0x{{.*}}
+// M23-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+
+// RUN: %clang -target arm -mcpu=cortex-m33 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=M33 %s
+// M33: #define __ARM_ARCH 8
+// M33: #define __ARM_ARCH_8M_MAIN__ 1
+// M33: #define __ARM_ARCH_EXT_IDIV__ 1
+// M33-NOT: __ARM_ARCH_ISA_ARM
+// M33: #define __ARM_ARCH_ISA_THUMB 2
+// M33: #define __ARM_ARCH_PROFILE 'M'
+// M33-NOT: __ARM_FEATURE_CRC32
+// M33: #define __ARM_FEATURE_DSP 1
+// M33: #define __ARM_FP 0x6
+// M33: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
 
 // Test whether predefines are as expected when targeting krait.
 // RUN: %clang -target armv7 -mcpu=krait -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=KRAIT %s
diff --git a/test/Preprocessor/cuda-types.cu b/test/Preprocessor/cuda-types.cu
index 2b6160b..5f7b916 100644
--- a/test/Preprocessor/cuda-types.cu
+++ b/test/Preprocessor/cuda-types.cu
@@ -28,3 +28,19 @@
 // RUN:   | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
 // RUN:   | grep -v '__LDBL\|_LONG_DOUBLE' > %T/powerpc64-device-defines-filtered
 // RUN: diff %T/powerpc64-host-defines-filtered %T/powerpc64-device-defines-filtered
+
+// RUN: %clang --cuda-host-only -nocudainc -target i386-windows-msvc -x cuda -E -dM -o - /dev/null \
+// RUN:   | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+// RUN:   | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-msvc-host-defines-filtered
+// RUN: %clang --cuda-device-only -nocudainc -nocudalib -target i386-windows-msvc -x cuda -E -dM -o - /dev/null \
+// RUN:   | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+// RUN:   | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-msvc-device-defines-filtered
+// RUN: diff %T/i386-msvc-host-defines-filtered %T/i386-msvc-device-defines-filtered
+
+// RUN: %clang --cuda-host-only -nocudainc -target x86_64-windows-msvc -x cuda -E -dM -o - /dev/null \
+// RUN:   | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+// RUN:   | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-msvc-host-defines-filtered
+// RUN: %clang --cuda-device-only -nocudainc -nocudalib -target x86_64-windows-msvc -x cuda -E -dM -o - /dev/null \
+// RUN:   | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+// RUN:   | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-msvc-device-defines-filtered
+// RUN: diff %T/x86_64-msvc-host-defines-filtered %T/x86_64-msvc-device-defines-filtered
diff --git a/test/Preprocessor/dependencies-and-pp.c b/test/Preprocessor/dependencies-and-pp.c
index fb49638..8bf32dc 100644
--- a/test/Preprocessor/dependencies-and-pp.c
+++ b/test/Preprocessor/dependencies-and-pp.c
@@ -32,5 +32,12 @@
 // RUN: FileCheck -check-prefix=TEST5 %s < %t.d
 // TEST5: foo $$(bar) b az qu\ ux \ space:
 
+// Test self dependency, PR31644
+
+// RUN: %clang -E -MD -MP -MF %t.d %s
+// RUN: FileCheck -check-prefix=TEST6 %s < %t.d
+// TEST6: dependencies-and-pp.c
+// TEST6-NOT: dependencies-and-pp.c:
+
 // TODO: Test default target without quoting
 // TODO: Test default target with quoting
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index b003404..cae6aa0 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -831,6 +831,198 @@
 // AARCH64-NETBSD:#define __WINT_WIDTH__ 32
 // AARCH64-NETBSD:#define __aarch64__ 1
 //
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=aarch64-openbsd < /dev/null | FileCheck -match-full-lines -check-prefix AARCH64-OPENBSD %s
+//
+// AARCH64-OPENBSD:#define _LP64 1
+// AARCH64-OPENBSD-NOT:#define __AARCH64EB__ 1
+// AARCH64-OPENBSD:#define __AARCH64EL__ 1
+// AARCH64-OPENBSD-NOT:#define __AARCH_BIG_ENDIAN 1
+// AARCH64-OPENBSD:#define __ARM_64BIT_STATE 1
+// AARCH64-OPENBSD:#define __ARM_ARCH 8
+// AARCH64-OPENBSD:#define __ARM_ARCH_ISA_A64 1
+// AARCH64-OPENBSD-NOT:#define __ARM_BIG_ENDIAN 1
+// AARCH64-OPENBSD:#define __BIGGEST_ALIGNMENT__ 16
+// AARCH64-OPENBSD:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// AARCH64-OPENBSD:#define __CHAR16_TYPE__ unsigned short
+// AARCH64-OPENBSD:#define __CHAR32_TYPE__ unsigned int
+// AARCH64-OPENBSD:#define __CHAR_BIT__ 8
+// AARCH64-OPENBSD:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// AARCH64-OPENBSD:#define __DBL_DIG__ 15
+// AARCH64-OPENBSD:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// AARCH64-OPENBSD:#define __DBL_HAS_DENORM__ 1
+// AARCH64-OPENBSD:#define __DBL_HAS_INFINITY__ 1
+// AARCH64-OPENBSD:#define __DBL_HAS_QUIET_NAN__ 1
+// AARCH64-OPENBSD:#define __DBL_MANT_DIG__ 53
+// AARCH64-OPENBSD:#define __DBL_MAX_10_EXP__ 308
+// AARCH64-OPENBSD:#define __DBL_MAX_EXP__ 1024
+// AARCH64-OPENBSD:#define __DBL_MAX__ 1.7976931348623157e+308
+// AARCH64-OPENBSD:#define __DBL_MIN_10_EXP__ (-307)
+// AARCH64-OPENBSD:#define __DBL_MIN_EXP__ (-1021)
+// AARCH64-OPENBSD:#define __DBL_MIN__ 2.2250738585072014e-308
+// AARCH64-OPENBSD:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+// AARCH64-OPENBSD:#define __ELF__ 1
+// AARCH64-OPENBSD:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// AARCH64-OPENBSD:#define __FLT_DIG__ 6
+// AARCH64-OPENBSD:#define __FLT_EPSILON__ 1.19209290e-7F
+// AARCH64-OPENBSD:#define __FLT_EVAL_METHOD__ 0
+// AARCH64-OPENBSD:#define __FLT_HAS_DENORM__ 1
+// AARCH64-OPENBSD:#define __FLT_HAS_INFINITY__ 1
+// AARCH64-OPENBSD:#define __FLT_HAS_QUIET_NAN__ 1
+// AARCH64-OPENBSD:#define __FLT_MANT_DIG__ 24
+// AARCH64-OPENBSD:#define __FLT_MAX_10_EXP__ 38
+// AARCH64-OPENBSD:#define __FLT_MAX_EXP__ 128
+// AARCH64-OPENBSD:#define __FLT_MAX__ 3.40282347e+38F
+// AARCH64-OPENBSD:#define __FLT_MIN_10_EXP__ (-37)
+// AARCH64-OPENBSD:#define __FLT_MIN_EXP__ (-125)
+// AARCH64-OPENBSD:#define __FLT_MIN__ 1.17549435e-38F
+// AARCH64-OPENBSD:#define __FLT_RADIX__ 2
+// AARCH64-OPENBSD:#define __INT16_C_SUFFIX__
+// AARCH64-OPENBSD:#define __INT16_FMTd__ "hd"
+// AARCH64-OPENBSD:#define __INT16_FMTi__ "hi"
+// AARCH64-OPENBSD:#define __INT16_MAX__ 32767
+// AARCH64-OPENBSD:#define __INT16_TYPE__ short
+// AARCH64-OPENBSD:#define __INT32_C_SUFFIX__
+// AARCH64-OPENBSD:#define __INT32_FMTd__ "d"
+// AARCH64-OPENBSD:#define __INT32_FMTi__ "i"
+// AARCH64-OPENBSD:#define __INT32_MAX__ 2147483647
+// AARCH64-OPENBSD:#define __INT32_TYPE__ int
+// AARCH64-OPENBSD:#define __INT64_C_SUFFIX__ LL
+// AARCH64-OPENBSD:#define __INT64_FMTd__ "lld"
+// AARCH64-OPENBSD:#define __INT64_FMTi__ "lli"
+// AARCH64-OPENBSD:#define __INT64_MAX__ 9223372036854775807LL
+// AARCH64-OPENBSD:#define __INT64_TYPE__ long long int
+// AARCH64-OPENBSD:#define __INT8_C_SUFFIX__
+// AARCH64-OPENBSD:#define __INT8_FMTd__ "hhd"
+// AARCH64-OPENBSD:#define __INT8_FMTi__ "hhi"
+// AARCH64-OPENBSD:#define __INT8_MAX__ 127
+// AARCH64-OPENBSD:#define __INT8_TYPE__ signed char
+// AARCH64-OPENBSD:#define __INTMAX_C_SUFFIX__ LL
+// AARCH64-OPENBSD:#define __INTMAX_FMTd__ "lld"
+// AARCH64-OPENBSD:#define __INTMAX_FMTi__ "lli"
+// AARCH64-OPENBSD:#define __INTMAX_MAX__ 9223372036854775807LL
+// AARCH64-OPENBSD:#define __INTMAX_TYPE__ long long int
+// AARCH64-OPENBSD:#define __INTMAX_WIDTH__ 64
+// AARCH64-OPENBSD:#define __INTPTR_FMTd__ "ld"
+// AARCH64-OPENBSD:#define __INTPTR_FMTi__ "li"
+// AARCH64-OPENBSD:#define __INTPTR_MAX__ 9223372036854775807L
+// AARCH64-OPENBSD:#define __INTPTR_TYPE__ long int
+// AARCH64-OPENBSD:#define __INTPTR_WIDTH__ 64
+// AARCH64-OPENBSD:#define __INT_FAST16_FMTd__ "hd"
+// AARCH64-OPENBSD:#define __INT_FAST16_FMTi__ "hi"
+// AARCH64-OPENBSD:#define __INT_FAST16_MAX__ 32767
+// AARCH64-OPENBSD:#define __INT_FAST16_TYPE__ short
+// AARCH64-OPENBSD:#define __INT_FAST32_FMTd__ "d"
+// AARCH64-OPENBSD:#define __INT_FAST32_FMTi__ "i"
+// AARCH64-OPENBSD:#define __INT_FAST32_MAX__ 2147483647
+// AARCH64-OPENBSD:#define __INT_FAST32_TYPE__ int
+// AARCH64-OPENBSD:#define __INT_FAST64_FMTd__ "ld"
+// AARCH64-OPENBSD:#define __INT_FAST64_FMTi__ "li"
+// AARCH64-OPENBSD:#define __INT_FAST64_MAX__ 9223372036854775807L
+// AARCH64-OPENBSD:#define __INT_FAST64_TYPE__ long int
+// AARCH64-OPENBSD:#define __INT_FAST8_FMTd__ "hhd"
+// AARCH64-OPENBSD:#define __INT_FAST8_FMTi__ "hhi"
+// AARCH64-OPENBSD:#define __INT_FAST8_MAX__ 127
+// AARCH64-OPENBSD:#define __INT_FAST8_TYPE__ signed char
+// AARCH64-OPENBSD:#define __INT_LEAST16_FMTd__ "hd"
+// AARCH64-OPENBSD:#define __INT_LEAST16_FMTi__ "hi"
+// AARCH64-OPENBSD:#define __INT_LEAST16_MAX__ 32767
+// AARCH64-OPENBSD:#define __INT_LEAST16_TYPE__ short
+// AARCH64-OPENBSD:#define __INT_LEAST32_FMTd__ "d"
+// AARCH64-OPENBSD:#define __INT_LEAST32_FMTi__ "i"
+// AARCH64-OPENBSD:#define __INT_LEAST32_MAX__ 2147483647
+// AARCH64-OPENSD:#define __INT_LEAST32_TYPE__ int
+// AARCH64-OPENBSD:#define __INT_LEAST64_FMTd__ "ld"
+// AARCH64-OPENBSD:#define __INT_LEAST64_FMTi__ "li"
+// AARCH64-OPENBSD:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// AARCH64-OPENBSD:#define __INT_LEAST64_TYPE__ long int
+// AARCH64-OPENBSD:#define __INT_LEAST8_FMTd__ "hhd"
+// AARCH64-OPENBSD:#define __INT_LEAST8_FMTi__ "hhi"
+// AARCH64-OPENBSD:#define __INT_LEAST8_MAX__ 127
+// AARCH64-OPENBSD:#define __INT_LEAST8_TYPE__ signed char
+// AARCH64-OPENBSD:#define __INT_MAX__ 2147483647
+// AARCH64-OPENBSD:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
+// AARCH64-OPENBSD:#define __LDBL_DIG__ 33
+// AARCH64-OPENBSD:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
+// AARCH64-OPENBSD:#define __LDBL_HAS_DENORM__ 1
+// AARCH64-OPENBSD:#define __LDBL_HAS_INFINITY__ 1
+// AARCH64-OPENBSD:#define __LDBL_HAS_QUIET_NAN__ 1
+// AARCH64-OPENBSD:#define __LDBL_MANT_DIG__ 113
+// AARCH64-OPENBSD:#define __LDBL_MAX_10_EXP__ 4932
+// AARCH64-OPENBSD:#define __LDBL_MAX_EXP__ 16384
+// AARCH64-OPENBSD:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
+// AARCH64-OPENBSD:#define __LDBL_MIN_10_EXP__ (-4931)
+// AARCH64-OPENBSD:#define __LDBL_MIN_EXP__ (-16381)
+// AARCH64-OPENBSD:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// AARCH64-OPENBSD:#define __LITTLE_ENDIAN__ 1
+// AARCH64-OPENBSD:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// AARCH64-OPENBSD:#define __LONG_MAX__ 9223372036854775807L
+// AARCH64-OPENBSD:#define __LP64__ 1
+// AARCH64-OPENBSD:#define __OpenBSD__ 1
+// AARCH64-OPENBSD:#define __POINTER_WIDTH__ 64
+// AARCH64-OPENBSD:#define __PTRDIFF_TYPE__ long int
+// AARCH64-OPENBSD:#define __PTRDIFF_WIDTH__ 64
+// AARCH64-OPENBSD:#define __SCHAR_MAX__ 127
+// AARCH64-OPENBSD:#define __SHRT_MAX__ 32767
+// AARCH64-OPENBSD:#define __SIG_ATOMIC_MAX__ 2147483647
+// AARCH64-OPENBSD:#define __SIG_ATOMIC_WIDTH__ 32
+// AARCH64-OPENBSD:#define __SIZEOF_DOUBLE__ 8
+// AARCH64-OPENBSD:#define __SIZEOF_FLOAT__ 4
+// AARCH64-OPENBSD:#define __SIZEOF_INT__ 4
+// AARCH64-OPENBSD:#define __SIZEOF_LONG_DOUBLE__ 16
+// AARCH64-OPENBSD:#define __SIZEOF_LONG_LONG__ 8
+// AARCH64-OPENBSD:#define __SIZEOF_LONG__ 8
+// AARCH64-OPENBSD:#define __SIZEOF_POINTER__ 8
+// AARCH64-OPENBSD:#define __SIZEOF_PTRDIFF_T__ 8
+// AARCH64-OPENBSD:#define __SIZEOF_SHORT__ 2
+// AARCH64-OPENBSD:#define __SIZEOF_SIZE_T__ 8
+// AARCH64-OPENBSD:#define __SIZEOF_WCHAR_T__ 4
+// AARCH64-OPENBSD:#define __SIZEOF_WINT_T__ 4
+// AARCH64-OPENBSD:#define __SIZE_MAX__ 18446744073709551615UL
+// AARCH64-OPENBSD:#define __SIZE_TYPE__ long unsigned int
+// AARCH64-OPENBSD:#define __SIZE_WIDTH__ 64
+// AARCH64-OPENBSD:#define __UINT16_C_SUFFIX__
+// AARCH64-OPENBSD:#define __UINT16_MAX__ 65535
+// AARCH64-OPENBSD:#define __UINT16_TYPE__ unsigned short
+// AARCH64-OPENBSD:#define __UINT32_C_SUFFIX__ U
+// AARCH64-OPENBSD:#define __UINT32_MAX__ 4294967295U
+// AARCH64-OPENBSD:#define __UINT32_TYPE__ unsigned int
+// AARCH64-OPENBSD:#define __UINT64_C_SUFFIX__ ULL
+// AARCH64-OPENBSD:#define __UINT64_MAX__ 18446744073709551615ULL
+// AARCH64-OPENBSD:#define __UINT64_TYPE__ long long unsigned int
+// AARCH64-OPENBSD:#define __UINT8_C_SUFFIX__
+// AARCH64-OPENBSD:#define __UINT8_MAX__ 255
+// AARCH64-OPENBSD:#define __UINT8_TYPE__ unsigned char
+// AARCH64-OPENBSD:#define __UINTMAX_C_SUFFIX__ ULL
+// AARCH64-OPENBSD:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// AARCH64-OPENBSD:#define __UINTMAX_TYPE__ long long unsigned int
+// AARCH64-OPENBSD:#define __UINTMAX_WIDTH__ 64
+// AARCH64-OPENBSD:#define __UINTPTR_MAX__ 18446744073709551615UL
+// AARCH64-OPENBSD:#define __UINTPTR_TYPE__ long unsigned int
+// AARCH64-OPENBSD:#define __UINTPTR_WIDTH__ 64
+// AARCH64-OPENBSD:#define __UINT_FAST16_MAX__ 65535
+// AARCH64-OPENBSD:#define __UINT_FAST16_TYPE__ unsigned short
+// AARCH64-OPENBSD:#define __UINT_FAST32_MAX__ 4294967295U
+// AARCH64-OPENBSD:#define __UINT_FAST32_TYPE__ unsigned int
+// AARCH64-OPENBSD:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// AARCH64-OPENBSD:#define __UINT_FAST64_TYPE__ long unsigned int
+// AARCH64-OPENBSD:#define __UINT_FAST8_MAX__ 255
+// AARCH64-OPENBSD:#define __UINT_FAST8_TYPE__ unsigned char
+// AARCH64-OPENBSD:#define __UINT_LEAST16_MAX__ 65535
+// AARCH64-OPENBSD:#define __UINT_LEAST16_TYPE__ unsigned short
+// AARCH64-OPENBSD:#define __UINT_LEAST32_MAX__ 4294967295U
+// AARCH64-OPENBSD:#define __UINT_LEAST32_TYPE__ unsigned int
+// AARCH64-OPENBSD:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// AARCH64-OPENBSD:#define __UINT_LEAST64_TYPE__ long unsigned int
+// AARCH64-OPENBSD:#define __UINT_LEAST8_MAX__ 255
+// AARCH64-OPENBSD:#define __UINT_LEAST8_TYPE__ unsigned char
+// AARCH64-OPENBSD:#define __USER_LABEL_PREFIX__
+// AARCH64-OPENBSD:#define __WCHAR_MAX__ 2147483647
+// AARCH64-OPENBSD:#define __WCHAR_TYPE__ int
+// AARCH64-OPENBSD:#define __WCHAR_WIDTH__ 32
+// AARCH64-OPENBSD:#define __WINT_TYPE__ int
+// AARCH64-OPENBSD:#define __WINT_WIDTH__ 32
+// AARCH64-OPENBSD:#define __aarch64__ 1
+//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=aarch64-freebsd11 < /dev/null | FileCheck -match-full-lines -check-prefix AARCH64-FREEBSD %s
 //
 // AARCH64-FREEBSD:#define _LP64 1
@@ -3040,6 +3232,7 @@
 // MIPS32BE:#define __llvm__ 1
 // MIPS32BE:#define __mips 32
 // MIPS32BE:#define __mips__ 1
+// MIPS32BE:#define __mips_abicalls 1
 // MIPS32BE:#define __mips_fpr 32
 // MIPS32BE:#define __mips_hard_float 1
 // MIPS32BE:#define __mips_o32 1
@@ -3246,6 +3439,7 @@
 // MIPS32EL:#define __llvm__ 1
 // MIPS32EL:#define __mips 32
 // MIPS32EL:#define __mips__ 1
+// MIPS32EL:#define __mips_abicalls 1
 // MIPS32EL:#define __mips_fpr 32
 // MIPS32EL:#define __mips_hard_float 1
 // MIPS32EL:#define __mips_o32 1
@@ -3555,6 +3749,7 @@
 // MIPSN32BE: #define __mips64 1
 // MIPSN32BE: #define __mips64__ 1
 // MIPSN32BE: #define __mips__ 1
+// MIPSN32BE: #define __mips_abicalls 1
 // MIPSN32BE: #define __mips_fpr 64
 // MIPSN32BE: #define __mips_hard_float 1
 // MIPSN32BE: #define __mips_isa_rev 2
@@ -3861,6 +4056,7 @@
 // MIPSN32EL: #define __mips64 1
 // MIPSN32EL: #define __mips64__ 1
 // MIPSN32EL: #define __mips__ 1
+// MIPSN32EL: #define __mips_abicalls 1
 // MIPSN32EL: #define __mips_fpr 64
 // MIPSN32EL: #define __mips_hard_float 1
 // MIPSN32EL: #define __mips_isa_rev 2
@@ -4073,6 +4269,7 @@
 // MIPS64BE:#define __mips64 1
 // MIPS64BE:#define __mips64__ 1
 // MIPS64BE:#define __mips__ 1
+// MIPS64BE:#define __mips_abicalls 1
 // MIPS64BE:#define __mips_fpr 64
 // MIPS64BE:#define __mips_hard_float 1
 // MIPS64BE:#define __mips_n64 1
@@ -4282,6 +4479,7 @@
 // MIPS64EL:#define __mips64 1
 // MIPS64EL:#define __mips64__ 1
 // MIPS64EL:#define __mips__ 1
+// MIPS64EL:#define __mips_abicalls 1
 // MIPS64EL:#define __mips_fpr 64
 // MIPS64EL:#define __mips_hard_float 1
 // MIPS64EL:#define __mips_n64 1
@@ -4513,6 +4711,45 @@
 // MIPS-XXR6:#define __mips_fpr 64
 // MIPS-XXR6:#define __mips_nan2008 1
 //
+// RUN: %clang_cc1 -target-cpu mips32 \
+// RUN:   -E -dM -triple=mips-unknown-netbsd -mrelocation-model pic < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefix MIPS-ABICALLS-NETBSD %s
+// MIPS-ABICALLS-NETBSD-NOT: #define __ABICALLS__ 1
+// MIPS-ABICALLS-NETBSD: #define __mips_abicalls 1
+//
+// RUN: %clang_cc1 -target-cpu mips64 \
+// RUN:   -E -dM -triple=mips64-unknown-netbsd -mrelocation-model pic < \
+// RUN:   /dev/null | FileCheck -match-full-lines \
+// RUN:   -check-prefix MIPS-ABICALLS-NETBSD64 %s
+// MIPS-ABICALLS-NETBSD64-NOT: #define __ABICALLS__ 1
+// MIPS-ABICALLS-NETBSD64: #define __mips_abicalls 1
+//
+// RUN: %clang_cc1 -target-cpu mips32 \
+// RUN:   -E -dM -triple=mips-unknown-freebsd -mrelocation-model pic < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefix MIPS-ABICALLS-FREEBSD %s
+// MIPS-ABICALLS-FREEBSD: #define __ABICALLS__ 1
+// MIPS-ABICALLS-FREEBSD: #define __mips_abicalls 1
+//
+// RUN: %clang_cc1 -target-cpu mips64 \
+// RUN:   -E -dM -triple=mips64-unknown-freebsd -mrelocation-model pic < \
+// RUN:   /dev/null | FileCheck -match-full-lines \
+// RUN:   -check-prefix MIPS-ABICALLS-FREEBSD64 %s
+// MIPS-ABICALLS-FREEBSD64: #define __ABICALLS__ 1
+// MIPS-ABICALLS-FREEBSD64: #define __mips_abicalls 1
+//
+// RUN: %clang_cc1 -target-cpu mips32 \
+// RUN:   -E -dM -triple=mips-unknown-openbsd -mrelocation-model pic < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefix MIPS-ABICALLS-OPENBSD %s
+// MIPS-ABICALLS-OPENBSD: #define __ABICALLS__ 1
+// MIPS-ABICALLS-OPENBSD: #define __mips_abicalls 1
+//
+// RUN: %clang_cc1 -target-cpu mips64 \
+// RUN:   -E -dM -triple=mips64-unknown-openbsd -mrelocation-model pic < \
+// RUN:   /dev/null | FileCheck -match-full-lines \
+// RUN:   -check-prefix MIPS-ABICALLS-OPENBSD64 %s
+// MIPS-ABICALLS-OPENBSD64: #define __ABICALLS__ 1
+// MIPS-ABICALLS-OPENBSD64: #define __mips_abicalls 1
+//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=msp430-none-none < /dev/null | FileCheck -match-full-lines -check-prefix MSP430 %s
 // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=msp430-none-none < /dev/null | FileCheck -match-full-lines -check-prefix MSP430 -check-prefix MSP430-CXX %s
 //
@@ -5635,6 +5872,7 @@
 // PPC64LE:#define __SIZE_MAX__ 18446744073709551615UL
 // PPC64LE:#define __SIZE_TYPE__ long unsigned int
 // PPC64LE:#define __SIZE_WIDTH__ 64
+// PPC64LE:#define __STRUCT_PARM_ALIGN__ 16
 // PPC64LE:#define __UINT16_C_SUFFIX__
 // PPC64LE:#define __UINT16_MAX__ 65535
 // PPC64LE:#define __UINT16_TYPE__ unsigned short
@@ -8466,6 +8704,7 @@
 // PS4:#define __unix__ 1
 // PS4:#define __x86_64 1
 // PS4:#define __x86_64__ 1
+// PS4:#define unix 1
 //
 // RUN: %clang_cc1 -E -dM -triple=x86_64-pc-mingw32 < /dev/null | FileCheck -match-full-lines -check-prefix X86-64-DECLSPEC %s
 // RUN: %clang_cc1 -E -dM -fms-extensions -triple=x86_64-unknown-mingw32 < /dev/null | FileCheck -match-full-lines -check-prefix X86-64-DECLSPEC %s
@@ -8523,8 +8762,12 @@
 // LANAI: #define __lanai__ 1
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=amd64-unknown-openbsd6.1 < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=aarch64-unknown-openbsd6.1 < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD %s
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-unknown-openbsd6.1-gnueabi < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD %s
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-unknown-openbsd6.1 < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-unknown-openbsd6.1 < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips64-unknown-openbsd6.1 < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips64el-unknown-openbsd6.1 < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD %s
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc64-unknown-openbsd6.1 < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD %s
 // OPENBSD:#define __ELF__ 1
 // OPENBSD:#define __INT16_TYPE__ short
@@ -8705,6 +8948,7 @@
 // WEBASSEMBLY32-NEXT:#define __LONG_MAX__ 2147483647L
 // WEBASSEMBLY32-NOT:#define __LP64__
 // WEBASSEMBLY32-NEXT:#define __NO_INLINE__ 1
+// WEBASSEMBLY32-NEXT:#define __OBJC_BOOL_IS_BOOL 0
 // WEBASSEMBLY32-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
 // WEBASSEMBLY32-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
 // WEBASSEMBLY32-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
@@ -9020,6 +9264,7 @@
 // WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L
 // WEBASSEMBLY64-NEXT:#define __LP64__ 1
 // WEBASSEMBLY64-NEXT:#define __NO_INLINE__ 1
+// WEBASSEMBLY64-NEXT:#define __OBJC_BOOL_IS_BOOL 0
 // WEBASSEMBLY64-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
 // WEBASSEMBLY64-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
 // WEBASSEMBLY64-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
@@ -9189,3 +9434,174 @@
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple x86_64-windows-cygnus < /dev/null | FileCheck -match-full-lines -check-prefix CYGWIN-X64 %s
 // CYGWIN-X64: #define __USER_LABEL_PREFIX__
 
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=avr \
+// RUN:   < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefix=AVR %s
+//
+// AVR:#define __ATOMIC_ACQUIRE 2
+// AVR:#define __ATOMIC_ACQ_REL 4
+// AVR:#define __ATOMIC_CONSUME 1
+// AVR:#define __ATOMIC_RELAXED 0
+// AVR:#define __ATOMIC_RELEASE 3
+// AVR:#define __ATOMIC_SEQ_CST 5
+// AVR:#define __AVR__ 1
+// AVR:#define __BIGGEST_ALIGNMENT__ 1
+// AVR:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// AVR:#define __CHAR16_TYPE__ unsigned int
+// AVR:#define __CHAR32_TYPE__ long unsigned int
+// AVR:#define __CHAR_BIT__ 8
+// AVR:#define __DBL_DECIMAL_DIG__ 9
+// AVR:#define __DBL_DENORM_MIN__ 1.40129846e-45
+// AVR:#define __DBL_DIG__ 6
+// AVR:#define __DBL_EPSILON__ 1.19209290e-7
+// AVR:#define __DBL_HAS_DENORM__ 1
+// AVR:#define __DBL_HAS_INFINITY__ 1
+// AVR:#define __DBL_HAS_QUIET_NAN__ 1
+// AVR:#define __DBL_MANT_DIG__ 24
+// AVR:#define __DBL_MAX_10_EXP__ 38
+// AVR:#define __DBL_MAX_EXP__ 128
+// AVR:#define __DBL_MAX__ 3.40282347e+38
+// AVR:#define __DBL_MIN_10_EXP__ (-37)
+// AVR:#define __DBL_MIN_EXP__ (-125)
+// AVR:#define __DBL_MIN__ 1.17549435e-38
+// AVR:#define __FINITE_MATH_ONLY__ 0
+// AVR:#define __FLT_DECIMAL_DIG__ 9
+// AVR:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// AVR:#define __FLT_DIG__ 6
+// AVR:#define __FLT_EPSILON__ 1.19209290e-7F
+// AVR:#define __FLT_EVAL_METHOD__ 0
+// AVR:#define __FLT_HAS_DENORM__ 1
+// AVR:#define __FLT_HAS_INFINITY__ 1
+// AVR:#define __FLT_HAS_QUIET_NAN__ 1
+// AVR:#define __FLT_MANT_DIG__ 24
+// AVR:#define __FLT_MAX_10_EXP__ 38
+// AVR:#define __FLT_MAX_EXP__ 128
+// AVR:#define __FLT_MAX__ 3.40282347e+38F
+// AVR:#define __FLT_MIN_10_EXP__ (-37)
+// AVR:#define __FLT_MIN_EXP__ (-125)
+// AVR:#define __FLT_MIN__ 1.17549435e-38F
+// AVR:#define __FLT_RADIX__ 2
+// AVR:#define __GCC_ATOMIC_BOOL_LOCK_FREE 1
+// AVR:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 1
+// AVR:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 1
+// AVR:#define __GCC_ATOMIC_CHAR_LOCK_FREE 1
+// AVR:#define __GCC_ATOMIC_INT_LOCK_FREE 1
+// AVR:#define __GCC_ATOMIC_LLONG_LOCK_FREE 1
+// AVR:#define __GCC_ATOMIC_LONG_LOCK_FREE 1
+// AVR:#define __GCC_ATOMIC_POINTER_LOCK_FREE 1
+// AVR:#define __GCC_ATOMIC_SHORT_LOCK_FREE 1
+// AVR:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// AVR:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 1
+// AVR:#define __GXX_ABI_VERSION 1002
+// AVR:#define __INT16_C_SUFFIX__ 
+// AVR:#define __INT16_MAX__ 32767
+// AVR:#define __INT16_TYPE__ short
+// AVR:#define __INT32_C_SUFFIX__ L
+// AVR:#define __INT32_MAX__ 2147483647L
+// AVR:#define __INT32_TYPE__ long int
+// AVR:#define __INT64_C_SUFFIX__ LL
+// AVR:#define __INT64_MAX__ 9223372036854775807LL
+// AVR:#define __INT64_TYPE__ long long int
+// AVR:#define __INT8_C_SUFFIX__ 
+// AVR:#define __INT8_MAX__ 127
+// AVR:#define __INT8_TYPE__ signed char
+// AVR:#define __INTMAX_C_SUFFIX__ LL
+// AVR:#define __INTMAX_MAX__ 9223372036854775807LL
+// AVR:#define __INTMAX_TYPE__ long long int
+// AVR:#define __INTPTR_MAX__ 32767
+// AVR:#define __INTPTR_TYPE__ int
+// AVR:#define __INT_FAST16_MAX__ 32767
+// AVR:#define __INT_FAST16_TYPE__ int
+// AVR:#define __INT_FAST32_MAX__ 2147483647L
+// AVR:#define __INT_FAST32_TYPE__ long int
+// AVR:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// AVR:#define __INT_FAST64_TYPE__ long long int
+// AVR:#define __INT_FAST8_MAX__ 127
+// AVR:#define __INT_FAST8_TYPE__ signed char
+// AVR:#define __INT_LEAST16_MAX__ 32767
+// AVR:#define __INT_LEAST16_TYPE__ int
+// AVR:#define __INT_LEAST32_MAX__ 2147483647L
+// AVR:#define __INT_LEAST32_TYPE__ long int
+// AVR:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// AVR:#define __INT_LEAST64_TYPE__ long long int
+// AVR:#define __INT_LEAST8_MAX__ 127
+// AVR:#define __INT_LEAST8_TYPE__ signed char
+// AVR:#define __INT_MAX__ 32767
+// AVR:#define __LDBL_DECIMAL_DIG__ 9
+// AVR:#define __LDBL_DENORM_MIN__ 1.40129846e-45L
+// AVR:#define __LDBL_DIG__ 6
+// AVR:#define __LDBL_EPSILON__ 1.19209290e-7L
+// AVR:#define __LDBL_HAS_DENORM__ 1
+// AVR:#define __LDBL_HAS_INFINITY__ 1
+// AVR:#define __LDBL_HAS_QUIET_NAN__ 1
+// AVR:#define __LDBL_MANT_DIG__ 24
+// AVR:#define __LDBL_MAX_10_EXP__ 38
+// AVR:#define __LDBL_MAX_EXP__ 128
+// AVR:#define __LDBL_MAX__ 3.40282347e+38L
+// AVR:#define __LDBL_MIN_10_EXP__ (-37)
+// AVR:#define __LDBL_MIN_EXP__ (-125)
+// AVR:#define __LDBL_MIN__ 1.17549435e-38L
+// AVR:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// AVR:#define __LONG_MAX__ 2147483647L
+// AVR:#define __NO_INLINE__ 1
+// AVR:#define __ORDER_BIG_ENDIAN__ 4321
+// AVR:#define __ORDER_LITTLE_ENDIAN__ 1234
+// AVR:#define __ORDER_PDP_ENDIAN__ 3412
+// AVR:#define __PRAGMA_REDEFINE_EXTNAME 1
+// AVR:#define __PTRDIFF_MAX__ 32767
+// AVR:#define __PTRDIFF_TYPE__ int
+// AVR:#define __SCHAR_MAX__ 127
+// AVR:#define __SHRT_MAX__ 32767
+// AVR:#define __SIG_ATOMIC_MAX__ 127
+// AVR:#define __SIG_ATOMIC_WIDTH__ 8
+// AVR:#define __SIZEOF_DOUBLE__ 4
+// AVR:#define __SIZEOF_FLOAT__ 4
+// AVR:#define __SIZEOF_INT__ 2
+// AVR:#define __SIZEOF_LONG_DOUBLE__ 4
+// AVR:#define __SIZEOF_LONG_LONG__ 8
+// AVR:#define __SIZEOF_LONG__ 4
+// AVR:#define __SIZEOF_POINTER__ 2
+// AVR:#define __SIZEOF_PTRDIFF_T__ 2
+// AVR:#define __SIZEOF_SHORT__ 2
+// AVR:#define __SIZEOF_SIZE_T__ 2
+// AVR:#define __SIZEOF_WCHAR_T__ 2
+// AVR:#define __SIZEOF_WINT_T__ 2
+// AVR:#define __SIZE_MAX__ 65535U
+// AVR:#define __SIZE_TYPE__ unsigned int
+// AVR:#define __STDC__ 1
+// AVR:#define __UINT16_MAX__ 65535U
+// AVR:#define __UINT16_TYPE__ unsigned short
+// AVR:#define __UINT32_C_SUFFIX__ UL
+// AVR:#define __UINT32_MAX__ 4294967295UL
+// AVR:#define __UINT32_TYPE__ long unsigned int
+// AVR:#define __UINT64_C_SUFFIX__ ULL
+// AVR:#define __UINT64_MAX__ 18446744073709551615ULL
+// AVR:#define __UINT64_TYPE__ long long unsigned int
+// AVR:#define __UINT8_C_SUFFIX__ 
+// AVR:#define __UINT8_MAX__ 255
+// AVR:#define __UINT8_TYPE__ unsigned char
+// AVR:#define __UINTMAX_C_SUFFIX__ ULL
+// AVR:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// AVR:#define __UINTMAX_TYPE__ long long unsigned int
+// AVR:#define __UINTPTR_MAX__ 65535U
+// AVR:#define __UINTPTR_TYPE__ unsigned int
+// AVR:#define __UINT_FAST16_MAX__ 65535U
+// AVR:#define __UINT_FAST16_TYPE__ unsigned int
+// AVR:#define __UINT_FAST32_MAX__ 4294967295UL
+// AVR:#define __UINT_FAST32_TYPE__ long unsigned int
+// AVR:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// AVR:#define __UINT_FAST64_TYPE__ long long unsigned int
+// AVR:#define __UINT_FAST8_MAX__ 255
+// AVR:#define __UINT_FAST8_TYPE__ unsigned char
+// AVR:#define __UINT_LEAST16_MAX__ 65535U
+// AVR:#define __UINT_LEAST16_TYPE__ unsigned int
+// AVR:#define __UINT_LEAST32_MAX__ 4294967295UL
+// AVR:#define __UINT_LEAST32_TYPE__ long unsigned int
+// AVR:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// AVR:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// AVR:#define __UINT_LEAST8_MAX__ 255
+// AVR:#define __UINT_LEAST8_TYPE__ unsigned char
+// AVR:#define __USER_LABEL_PREFIX__ 
+// AVR:#define __WCHAR_MAX__ 32767
+// AVR:#define __WCHAR_TYPE__ int
+// AVR:#define __WINT_TYPE__ int
diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c
index 51b587e..73d0be6 100644
--- a/test/Preprocessor/predefined-arch-macros.c
+++ b/test/Preprocessor/predefined-arch-macros.c
@@ -651,15 +651,18 @@
 // CHECK_SKL_M32: #define __AVX__ 1
 // CHECK_SKL_M32: #define __BMI2__ 1
 // CHECK_SKL_M32: #define __BMI__ 1
+// CHECK_SKL_M32: #define __CLFLUSHOPT__ 1
 // CHECK_SKL_M32: #define __F16C__ 1
 // CHECK_SKL_M32: #define __FMA__ 1
 // CHECK_SKL_M32: #define __LZCNT__ 1
 // CHECK_SKL_M32: #define __MMX__ 1
+// CHECK_SKL_M32: #define __MPX__ 1
 // CHECK_SKL_M32: #define __PCLMUL__ 1
 // CHECK_SKL_M32: #define __POPCNT__ 1
 // CHECK_SKL_M32: #define __RDRND__ 1
 // CHECK_SKL_M32: #define __RDSEED__ 1
 // CHECK_SKL_M32: #define __RTM__ 1
+// CHECK_SKL_M32: #define __SGX__ 1
 // CHECK_SKL_M32: #define __SSE2__ 1
 // CHECK_SKL_M32: #define __SSE3__ 1
 // CHECK_SKL_M32: #define __SSE4_1__ 1
@@ -681,15 +684,18 @@
 // CHECK_SKL_M64: #define __AVX__ 1
 // CHECK_SKL_M64: #define __BMI2__ 1
 // CHECK_SKL_M64: #define __BMI__ 1
+// CHECK_SKL_M64: #define __CLFLUSHOPT__ 1
 // CHECK_SKL_M64: #define __F16C__ 1
 // CHECK_SKL_M64: #define __FMA__ 1
 // CHECK_SKL_M64: #define __LZCNT__ 1
 // CHECK_SKL_M64: #define __MMX__ 1
+// CHECK_SKL_M64: #define __MPX__ 1
 // CHECK_SKL_M64: #define __PCLMUL__ 1
 // CHECK_SKL_M64: #define __POPCNT__ 1
 // CHECK_SKL_M64: #define __RDRND__ 1
 // CHECK_SKL_M64: #define __RDSEED__ 1
 // CHECK_SKL_M64: #define __RTM__ 1
+// CHECK_SKL_M64: #define __SGX__ 1
 // CHECK_SKL_M64: #define __SSE2_MATH__ 1
 // CHECK_SKL_M64: #define __SSE2__ 1
 // CHECK_SKL_M64: #define __SSE3__ 1
@@ -725,6 +731,7 @@
 // CHECK_KNL_M32: #define __MMX__ 1
 // CHECK_KNL_M32: #define __PCLMUL__ 1
 // CHECK_KNL_M32: #define __POPCNT__ 1
+// CHECK_KNL_M32: #define __PREFETCHWT1__ 1
 // CHECK_KNL_M32: #define __RDRND__ 1
 // CHECK_KNL_M32: #define __RTM__ 1
 // CHECK_KNL_M32: #define __SSE2__ 1
@@ -760,6 +767,7 @@
 // CHECK_KNL_M64: #define __MMX__ 1
 // CHECK_KNL_M64: #define __PCLMUL__ 1
 // CHECK_KNL_M64: #define __POPCNT__ 1
+// CHECK_KNL_M64: #define __PREFETCHWT1__ 1
 // CHECK_KNL_M64: #define __RDRND__ 1
 // CHECK_KNL_M64: #define __RTM__ 1
 // CHECK_KNL_M64: #define __SSE2_MATH__ 1
@@ -793,14 +801,18 @@
 // CHECK_SKX_M32: #define __AVX__ 1
 // CHECK_SKX_M32: #define __BMI2__ 1
 // CHECK_SKX_M32: #define __BMI__ 1
+// CHECK_SKX_M32: #define __CLFLUSHOPT__ 1
+// CHECK_SKX_M32: #define __CLWB__ 1
 // CHECK_SKX_M32: #define __F16C__ 1
 // CHECK_SKX_M32: #define __FMA__ 1
 // CHECK_SKX_M32: #define __LZCNT__ 1
 // CHECK_SKX_M32: #define __MMX__ 1
+// CHECK_SKX_M32: #define __MPX__ 1
 // CHECK_SKX_M32: #define __PCLMUL__ 1
 // CHECK_SKX_M32: #define __POPCNT__ 1
 // CHECK_SKX_M32: #define __RDRND__ 1
 // CHECK_SKX_M32: #define __RTM__ 1
+// CHECK_SKX_M32: #define __SGX__ 1
 // CHECK_SKX_M32: #define __SSE2__ 1
 // CHECK_SKX_M32: #define __SSE3__ 1
 // CHECK_SKX_M32: #define __SSE4_1__ 1
@@ -831,14 +843,18 @@
 // CHECK_SKX_M64: #define __AVX__ 1
 // CHECK_SKX_M64: #define __BMI2__ 1
 // CHECK_SKX_M64: #define __BMI__ 1
+// CHECK_SKX_M64: #define __CLFLUSHOPT__ 1
+// CHECK_SKX_M64: #define __CLWB__ 1
 // CHECK_SKX_M64: #define __F16C__ 1
 // CHECK_SKX_M64: #define __FMA__ 1
 // CHECK_SKX_M64: #define __LZCNT__ 1
 // CHECK_SKX_M64: #define __MMX__ 1
+// CHECK_SKX_M64: #define __MPX__ 1
 // CHECK_SKX_M64: #define __PCLMUL__ 1
 // CHECK_SKX_M64: #define __POPCNT__ 1
 // CHECK_SKX_M64: #define __RDRND__ 1
 // CHECK_SKX_M64: #define __RTM__ 1
+// CHECK_SKX_M64: #define __SGX__ 1
 // CHECK_SKX_M64: #define __SSE2_MATH__ 1
 // CHECK_SKX_M64: #define __SSE2__ 1
 // CHECK_SKX_M64: #define __SSE3__ 1
@@ -874,14 +890,17 @@
 // CHECK_CNL_M32: #define __AVX__ 1
 // CHECK_CNL_M32: #define __BMI2__ 1
 // CHECK_CNL_M32: #define __BMI__ 1
+// CHECK_CNL_M32: #define __CLFLUSHOPT__ 1
 // CHECK_CNL_M32: #define __F16C__ 1
 // CHECK_CNL_M32: #define __FMA__ 1
 // CHECK_CNL_M32: #define __LZCNT__ 1
 // CHECK_CNL_M32: #define __MMX__ 1
+// CHECK_CNL_M32: #define __MPX__ 1
 // CHECK_CNL_M32: #define __PCLMUL__ 1
 // CHECK_CNL_M32: #define __POPCNT__ 1
 // CHECK_CNL_M32: #define __RDRND__ 1
 // CHECK_CNL_M32: #define __RTM__ 1
+// CHECK_CNL_M32: #define __SGX__ 1
 // CHECK_CNL_M32: #define __SHA__ 1
 // CHECK_CNL_M32: #define __SSE2__ 1
 // CHECK_CNL_M32: #define __SSE3__ 1
@@ -912,14 +931,17 @@
 // CHECK_CNL_M64: #define __AVX__ 1
 // CHECK_CNL_M64: #define __BMI2__ 1
 // CHECK_CNL_M64: #define __BMI__ 1
+// CHECK_CNL_M64: #define __CLFLUSHOPT__ 1
 // CHECK_CNL_M64: #define __F16C__ 1
 // CHECK_CNL_M64: #define __FMA__ 1
 // CHECK_CNL_M64: #define __LZCNT__ 1
 // CHECK_CNL_M64: #define __MMX__ 1
+// CHECK_CNL_M64: #define __MPX__ 1
 // CHECK_CNL_M64: #define __PCLMUL__ 1
 // CHECK_CNL_M64: #define __POPCNT__ 1
 // CHECK_CNL_M64: #define __RDRND__ 1
 // CHECK_CNL_M64: #define __RTM__ 1
+// CHECK_CNL_M64: #define __SGX__ 1
 // CHECK_CNL_M64: #define __SHA__ 1
 // CHECK_CNL_M64: #define __SSE2__ 1
 // CHECK_CNL_M64: #define __SSE3__ 1
@@ -1849,6 +1871,92 @@
 // CHECK_BDVER4_M64: #define __tune_bdver4__ 1
 // CHECK_BDVER4_M64: #define __x86_64 1
 // CHECK_BDVER4_M64: #define __x86_64__ 1
+// RUN: %clang -march=znver1 -m32 -E -dM %s -o - 2>&1 \
+// RUN:     -target i386-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_ZNVER1_M32
+// CHECK_ZNVER1_M32-NOT: #define __3dNOW_A__ 1
+// CHECK_ZNVER1_M32-NOT: #define __3dNOW__ 1
+// CHECK_ZNVER1_M32: #define __ADX__ 1
+// CHECK_ZNVER1_M32: #define __AES__ 1
+// CHECK_ZNVER1_M32: #define __AVX2__ 1
+// CHECK_ZNVER1_M32: #define __AVX__ 1
+// CHECK_ZNVER1_M32: #define __BMI2__ 1
+// CHECK_ZNVER1_M32: #define __BMI__ 1
+// CHECK_ZNVER1_M32: #define __CLFLUSHOPT__ 1
+// CHECK_ZNVER1_M32: #define __CLZERO__ 1
+// CHECK_ZNVER1_M32: #define __F16C__ 1
+// CHECK_ZNVER1_M32: #define __FMA__ 1
+// CHECK_ZNVER1_M32: #define __FSGSBASE__ 1
+// CHECK_ZNVER1_M32: #define __LZCNT__ 1
+// CHECK_ZNVER1_M32: #define __MMX__ 1
+// CHECK_ZNVER1_M32: #define __PCLMUL__ 1
+// CHECK_ZNVER1_M32: #define __POPCNT__ 1
+// CHECK_ZNVER1_M32: #define __PRFCHW__ 1
+// CHECK_ZNVER1_M32: #define __RDRND__ 1
+// CHECK_ZNVER1_M32: #define __RDSEED__ 1
+// CHECK_ZNVER1_M32: #define __SHA__ 1
+// CHECK_ZNVER1_M32: #define __SSE2_MATH__ 1
+// CHECK_ZNVER1_M32: #define __SSE2__ 1
+// CHECK_ZNVER1_M32: #define __SSE3__ 1
+// CHECK_ZNVER1_M32: #define __SSE4A__ 1
+// CHECK_ZNVER1_M32: #define __SSE4_1__ 1
+// CHECK_ZNVER1_M32: #define __SSE4_2__ 1
+// CHECK_ZNVER1_M32: #define __SSE_MATH__ 1
+// CHECK_ZNVER1_M32: #define __SSE__ 1
+// CHECK_ZNVER1_M32: #define __SSSE3__ 1
+// CHECK_ZNVER1_M32: #define __XSAVEC__ 1
+// CHECK_ZNVER1_M32: #define __XSAVEOPT__ 1
+// CHECK_ZNVER1_M32: #define __XSAVES__ 1
+// CHECK_ZNVER1_M32: #define __XSAVE__ 1
+// CHECK_ZNVER1_M32: #define __i386 1
+// CHECK_ZNVER1_M32: #define __i386__ 1
+// CHECK_ZNVER1_M32: #define __tune_znver1__ 1
+// CHECK_ZNVER1_M32: #define __znver1 1
+// CHECK_ZNVER1_M32: #define __znver1__ 1
+// RUN: %clang -march=znver1 -m64 -E -dM %s -o - 2>&1 \
+// RUN:     -target i386-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_ZNVER1_M64
+// CHECK_ZNVER1_M64-NOT: #define __3dNOW_A__ 1
+// CHECK_ZNVER1_M64-NOT: #define __3dNOW__ 1
+// CHECK_ZNVER1_M64: #define __ADX__ 1
+// CHECK_ZNVER1_M64: #define __AES__ 1
+// CHECK_ZNVER1_M64: #define __AVX2__ 1
+// CHECK_ZNVER1_M64: #define __AVX__ 1
+// CHECK_ZNVER1_M64: #define __BMI2__ 1
+// CHECK_ZNVER1_M64: #define __BMI__ 1
+// CHECK_ZNVER1_M64: #define __CLFLUSHOPT__ 1
+// CHECK_ZNVER1_M64: #define __CLZERO__ 1
+// CHECK_ZNVER1_M64: #define __F16C__ 1
+// CHECK_ZNVER1_M64: #define __FMA__ 1
+// CHECK_ZNVER1_M64: #define __FSGSBASE__ 1
+// CHECK_ZNVER1_M64: #define __LZCNT__ 1
+// CHECK_ZNVER1_M64: #define __MMX__ 1
+// CHECK_ZNVER1_M64: #define __PCLMUL__ 1
+// CHECK_ZNVER1_M64: #define __POPCNT__ 1
+// CHECK_ZNVER1_M64: #define __PRFCHW__ 1
+// CHECK_ZNVER1_M64: #define __RDRND__ 1
+// CHECK_ZNVER1_M64: #define __RDSEED__ 1
+// CHECK_ZNVER1_M64: #define __SHA__ 1
+// CHECK_ZNVER1_M64: #define __SSE2_MATH__ 1
+// CHECK_ZNVER1_M64: #define __SSE2__ 1
+// CHECK_ZNVER1_M64: #define __SSE3__ 1
+// CHECK_ZNVER1_M64: #define __SSE4A__ 1
+// CHECK_ZNVER1_M64: #define __SSE4_1__ 1
+// CHECK_ZNVER1_M64: #define __SSE4_2__ 1
+// CHECK_ZNVER1_M64: #define __SSE_MATH__ 1
+// CHECK_ZNVER1_M64: #define __SSE__ 1
+// CHECK_ZNVER1_M64: #define __SSSE3__ 1
+// CHECK_ZNVER1_M64: #define __XSAVEC__ 1
+// CHECK_ZNVER1_M64: #define __XSAVEOPT__ 1
+// CHECK_ZNVER1_M64: #define __XSAVES__ 1
+// CHECK_ZNVER1_M64: #define __XSAVE__ 1
+// CHECK_ZNVER1_M64: #define __amd64 1
+// CHECK_ZNVER1_M64: #define __amd64__ 1
+// CHECK_ZNVER1_M64: #define __tune_znver1__ 1
+// CHECK_ZNVER1_M64: #define __x86_64 1
+// CHECK_ZNVER1_M64: #define __x86_64__ 1
+// CHECK_ZNVER1_M64: #define __znver1 1
+// CHECK_ZNVER1_M64: #define __znver1__ 1
 //
 // End X86/GCC/Linux tests ------------------
 
@@ -1953,35 +2061,76 @@
 
 // Begin SystemZ/GCC/Linux tests ----------------
 //
+// RUN: %clang -march=arch8 -E -dM %s -o - 2>&1 \
+// RUN:     -target s390x-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH8
 // RUN: %clang -march=z10 -E -dM %s -o - 2>&1 \
 // RUN:     -target s390x-unknown-linux \
-// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_Z10
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH8
 //
-// CHECK_SYSTEMZ_Z10: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
-// CHECK_SYSTEMZ_Z10: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
-// CHECK_SYSTEMZ_Z10: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
-// CHECK_SYSTEMZ_Z10: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
-// CHECK_SYSTEMZ_Z10: #define __LONG_DOUBLE_128__ 1
-// CHECK_SYSTEMZ_Z10: #define __s390__ 1
-// CHECK_SYSTEMZ_Z10: #define __s390x__ 1
-// CHECK_SYSTEMZ_Z10: #define __zarch__ 1
+// CHECK_SYSTEMZ_ARCH8: #define __ARCH__ 8
+// CHECK_SYSTEMZ_ARCH8: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK_SYSTEMZ_ARCH8: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK_SYSTEMZ_ARCH8: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK_SYSTEMZ_ARCH8: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+// CHECK_SYSTEMZ_ARCH8: #define __LONG_DOUBLE_128__ 1
+// CHECK_SYSTEMZ_ARCH8: #define __s390__ 1
+// CHECK_SYSTEMZ_ARCH8: #define __s390x__ 1
+// CHECK_SYSTEMZ_ARCH8: #define __zarch__ 1
 //
-// RUN: %clang -march=zEC12 -E -dM %s -o - 2>&1 \
+// RUN: %clang -march=arch9 -E -dM %s -o - 2>&1 \
 // RUN:     -target s390x-unknown-linux \
-// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ZEC12
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH9
+// RUN: %clang -march=z196 -E -dM %s -o - 2>&1 \
+// RUN:     -target s390x-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH9
+//
+// CHECK_SYSTEMZ_ARCH9: #define __ARCH__ 9
+// CHECK_SYSTEMZ_ARCH9: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK_SYSTEMZ_ARCH9: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK_SYSTEMZ_ARCH9: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK_SYSTEMZ_ARCH9: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+// CHECK_SYSTEMZ_ARCH9: #define __LONG_DOUBLE_128__ 1
+// CHECK_SYSTEMZ_ARCH9: #define __s390__ 1
+// CHECK_SYSTEMZ_ARCH9: #define __s390x__ 1
+// CHECK_SYSTEMZ_ARCH9: #define __zarch__ 1
+//
 // RUN: %clang -march=arch10 -E -dM %s -o - 2>&1 \
 // RUN:     -target s390x-unknown-linux \
-// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ZEC12
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH10
+// RUN: %clang -march=zEC12 -E -dM %s -o - 2>&1 \
+// RUN:     -target s390x-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH10
 //
-// CHECK_SYSTEMZ_ZEC12: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
-// CHECK_SYSTEMZ_ZEC12: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
-// CHECK_SYSTEMZ_ZEC12: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
-// CHECK_SYSTEMZ_ZEC12: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
-// CHECK_SYSTEMZ_ZEC12: #define __HTM__ 1
-// CHECK_SYSTEMZ_ZEC12: #define __LONG_DOUBLE_128__ 1
-// CHECK_SYSTEMZ_ZEC12: #define __s390__ 1
-// CHECK_SYSTEMZ_ZEC12: #define __s390x__ 1
-// CHECK_SYSTEMZ_ZEC12: #define __zarch__ 1
+// CHECK_SYSTEMZ_ARCH10: #define __ARCH__ 10
+// CHECK_SYSTEMZ_ARCH10: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK_SYSTEMZ_ARCH10: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK_SYSTEMZ_ARCH10: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK_SYSTEMZ_ARCH10: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+// CHECK_SYSTEMZ_ARCH10: #define __HTM__ 1
+// CHECK_SYSTEMZ_ARCH10: #define __LONG_DOUBLE_128__ 1
+// CHECK_SYSTEMZ_ARCH10: #define __s390__ 1
+// CHECK_SYSTEMZ_ARCH10: #define __s390x__ 1
+// CHECK_SYSTEMZ_ARCH10: #define __zarch__ 1
+//
+// RUN: %clang -march=arch11 -E -dM %s -o - 2>&1 \
+// RUN:     -target s390x-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH11
+// RUN: %clang -march=z13 -E -dM %s -o - 2>&1 \
+// RUN:     -target s390x-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH11
+//
+// CHECK_SYSTEMZ_ARCH11: #define __ARCH__ 11
+// CHECK_SYSTEMZ_ARCH11: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK_SYSTEMZ_ARCH11: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK_SYSTEMZ_ARCH11: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK_SYSTEMZ_ARCH11: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+// CHECK_SYSTEMZ_ARCH11: #define __HTM__ 1
+// CHECK_SYSTEMZ_ARCH11: #define __LONG_DOUBLE_128__ 1
+// CHECK_SYSTEMZ_ARCH11: #define __VX__ 1
+// CHECK_SYSTEMZ_ARCH11: #define __s390__ 1
+// CHECK_SYSTEMZ_ARCH11: #define __s390x__ 1
+// CHECK_SYSTEMZ_ARCH11: #define __zarch__ 1
 //
 // RUN: %clang -mhtm -E -dM %s -o - 2>&1 \
 // RUN:     -target s390x-unknown-linux \
@@ -1989,6 +2138,12 @@
 //
 // CHECK_SYSTEMZ_HTM: #define __HTM__ 1
 //
+// RUN: %clang -mvx -E -dM %s -o - 2>&1 \
+// RUN:     -target s390x-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_VX
+//
+// CHECK_SYSTEMZ_VX: #define __VX__ 1
+//
 // RUN: %clang -fzvector -E -dM %s -o - 2>&1 \
 // RUN:     -target s390x-unknown-linux \
 // RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ZVECTOR
diff --git a/test/Preprocessor/x86_target_features.c b/test/Preprocessor/x86_target_features.c
index 43cf615..a201900 100644
--- a/test/Preprocessor/x86_target_features.c
+++ b/test/Preprocessor/x86_target_features.c
@@ -352,3 +352,7 @@
 
 // NOXSAVE-NOT: #define __XSAVEOPT__ 1
 // NOXSAVE-NOT: #define __XSAVE__ 1
+
+// RUN: %clang -target i386-unknown-unknown -march=atom -mclflushopt -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=CLFLUSHOPT %s
+
+// CLFLUSHOPT: #define __CLFLUSHOPT__ 1
diff --git a/test/Profile/Inputs/cxx-class.proftext b/test/Profile/Inputs/cxx-class.proftext
index b4645ed..77645fb 100644
--- a/test/Profile/Inputs/cxx-class.proftext
+++ b/test/Profile/Inputs/cxx-class.proftext
@@ -39,3 +39,14 @@
 100
 99
 
+_ZN7DerivedC1Ev
+10
+2
+100
+99
+
+_ZN7DerivedD2Ev
+10
+2
+100
+99
diff --git a/test/Profile/c-generate.c b/test/Profile/c-generate.c
index 5e5b22e..1e7a739 100644
--- a/test/Profile/c-generate.c
+++ b/test/Profile/c-generate.c
@@ -5,7 +5,8 @@
 //
 // PROF-INSTR-PATH: constant [24 x i8] c"c-generate-test.profraw\00"
 //
-// PROF-INSTR-NONE-NOT: @__profn_main
+// PROF-INSTR-NONE-NOT: __llvm_prf
+//
 // PROF-INSTR-GARBAGE: invalid PGO instrumentor in argument '-fprofile-instrument=garbage'
 
 int main(void) {
diff --git a/test/Profile/c-ternary.c b/test/Profile/c-ternary.c
new file mode 100644
index 0000000..af7922f
--- /dev/null
+++ b/test/Profile/c-ternary.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11.0 -x c %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck %s
+
+// PR32019: Clang can lower some ternary operator expressions to select
+// instructions. Make sure we only increment the profile counter for the
+// condition when the condition evaluates to true.
+// CHECK-LABEL: define i32 @f1
+int f1(int x) {
+// CHECK: [[TOBOOL:%.*]] = icmp ne i32 %{{.*}}, 0
+// CHECK-NEXT: [[STEP:%.*]] = zext i1 [[TOBOOL]] to i64
+// CHECK-NEXT: [[COUNTER:%.*]] = load i64, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @__profc_f1, i64 0, i64 1)
+// CHECK-NEXT: add i64 [[COUNTER]], [[STEP]]
+// CHECK: [[COND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 1
+  return x ? 0 : 1;
+// CHECK: ret i32 [[COND]]
+}
diff --git a/test/Profile/cxx-class.cpp b/test/Profile/cxx-class.cpp
index dbc93377..ab90d19 100644
--- a/test/Profile/cxx-class.cpp
+++ b/test/Profile/cxx-class.cpp
@@ -5,6 +5,8 @@
 // RUN: FileCheck --input-file=%tgen -check-prefix=DTRGEN %s
 // RUN: FileCheck --input-file=%tgen -check-prefix=MTHGEN %s
 // RUN: FileCheck --input-file=%tgen -check-prefix=WRPGEN %s
+// RUN: FileCheck --input-file=%tgen -check-prefix=VCTRGEN %s
+// RUN: FileCheck --input-file=%tgen -check-prefix=VDTRGEN %s
 
 // RUN: llvm-profdata merge %S/Inputs/cxx-class.proftext -o %t.profdata
 // RUN: %clang_cc1 %s -o - -emit-llvm -fprofile-instrument-use-path=%t.profdata -triple %itanium_abi_triple > %tuse
@@ -12,10 +14,12 @@
 // RUN: FileCheck --input-file=%tuse -check-prefix=DTRUSE %s
 // RUN: FileCheck --input-file=%tuse -check-prefix=MTHUSE %s
 // RUN: FileCheck --input-file=%tuse -check-prefix=WRPUSE %s
+// RUN: FileCheck --input-file=%tuse -check-prefix=VCTRUSE %s
+// RUN: FileCheck --input-file=%tuse -check-prefix=VDTRUSE %s
 
 class Simple {
-  int Member;
 public:
+  int Member;
   // CTRGEN-LABEL: define {{.*}} @_ZN6SimpleC2Ei(
   // CTRUSE-LABEL: define {{.*}} @_ZN6SimpleC2Ei(
   // CTRGEN: store {{.*}} @[[SCC:__profc__ZN6SimpleC2Ei]], i64 0, i64 0
@@ -56,6 +60,35 @@
   // MTHUSE: ![[SM1]] = !{!"branch_weights", i32 100, i32 2}
 };
 
+class Derived : virtual public Simple {
+public:
+  // VCTRGEN-LABEL: define {{.*}} @_ZN7DerivedC1Ev(
+  // VCTRUSE-LABEL: define {{.*}} @_ZN7DerivedC1Ev(
+  // VCTRGEN: store {{.*}} @[[SCC:__profc__ZN7DerivedC1Ev]], i64 0, i64 0
+  Derived() : Simple(0) {
+    // VCTRGEN: store {{.*}} @[[SCC]], i64 0, i64 1
+    // VCTRUSE: br {{.*}} !prof ![[SC1:[0-9]+]]
+    if (Member) {}
+    // VCTRGEN-NOT: store {{.*}} @[[SCC]],
+    // VCTRUSE-NOT: br {{.*}} !prof ![0-9]+
+    // VCTRUSE: ret
+  }
+  // VCTRUSE: ![[SC1]] = !{!"branch_weights", i32 100, i32 2}
+
+  // VDTRGEN-LABEL: define {{.*}} @_ZN7DerivedD2Ev(
+  // VDTRUSE-LABEL: define {{.*}} @_ZN7DerivedD2Ev(
+  // VDTRGEN: store {{.*}} @[[SDC:__profc__ZN7DerivedD2Ev]], i64 0, i64 0
+  ~Derived() {
+    // VDTRGEN: store {{.*}} @[[SDC]], i64 0, i64 1
+    // VDTRUSE: br {{.*}} !prof ![[SD1:[0-9]+]]
+    if (Member) {}
+    // VDTRGEN-NOT: store {{.*}} @[[SDC]],
+    // VDTRUSE-NOT: br {{.*}} !prof ![0-9]+
+    // VDTRUSE: ret
+  }
+  // VDTRUSE: ![[SD1]] = !{!"branch_weights", i32 100, i32 2}
+};
+
 // WRPGEN-LABEL: define {{.*}} @_Z14simple_wrapperv(
 // WRPUSE-LABEL: define {{.*}} @_Z14simple_wrapperv(
 // WRPGEN: store {{.*}} @[[SWC:__profc__Z14simple_wrapperv]], i64 0, i64 0
@@ -63,6 +96,7 @@
   // WRPGEN: store {{.*}} @[[SWC]], i64 0, i64 1
   // WRPUSE: br {{.*}} !prof ![[SW1:[0-9]+]]
   for (int I = 0; I < 100; ++I) {
+    Derived d;
     Simple S(I);
     S.method();
   }
diff --git a/test/Profile/cxx-structors.cpp b/test/Profile/cxx-structors.cpp
index 73562d3..8e0fac1 100644
--- a/test/Profile/cxx-structors.cpp
+++ b/test/Profile/cxx-structors.cpp
@@ -1,6 +1,8 @@
 // Tests for instrumentation of C++ constructors and destructors.
 //
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11.0 -x c++ %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11.0 -x c++ %s -o %t -emit-llvm -fprofile-instrument=clang
+// RUN: FileCheck %s -input-file=%t -check-prefix=INSTR
+// RUN: FileCheck %s -input-file=%t -check-prefix=NOINSTR
 
 struct Foo {
   Foo() {}
@@ -14,19 +16,40 @@
   ~Bar();
 };
 
+struct Baz : virtual public Foo {
+  Baz() {}
+  Baz(int x) : Foo(x) {}
+  ~Baz();
+};
+
+struct Quux : public Foo {
+  Quux(const char *y, ...) : Foo(0) {}
+};
+
 Foo foo;
 Foo foo2(1);
 Bar bar;
+Baz baz;
+Baz baz2(1);
+Quux qux("fi", "fo", "fum");
 
 // Profile data for complete constructors and destructors must absent.
 
-// CHECK-NOT: @__profn__ZN3FooC1Ev
-// CHECK-NOT: @__profn__ZN3FooC1Ei
-// CHECK-NOT: @__profn__ZN3FooD1Ev
-// CHECK-NOT: @__profn__ZN3BarC1Ev
-// CHECK-NOT: @__profn__ZN3BarD1Ev
-// CHECK-NOT: @__profc__ZN3FooD1Ev
-// CHECK-NOT: @__profd__ZN3FooD1Ev
+// INSTR: @__profc__ZN3BazC1Ev =
+// INSTR: @__profc__ZN3BazC1Ei =
+// INSTR: @__profc__ZN4QuuxC1EPKcz =
+// INSTR: @__profc_main =
+// INSTR: @__profc__ZN3FooC2Ev =
+// INSTR: @__profc__ZN3FooD2Ev =
+// INSTR: @__profc__ZN3FooC2Ei =
+// INSTR: @__profc__ZN3BarC2Ev =
+
+// NOINSTR-NOT: @__profc__ZN3FooC1Ev
+// NOINSTR-NOT: @__profc__ZN3FooC1Ei
+// NOINSTR-NOT: @__profc__ZN3FooD1Ev
+// NOINSTR-NOT: @__profc__ZN3BarC1Ev
+// NOINSTR-NOT: @__profc__ZN3BarD1Ev
+// NOINSTR-NOT: @__profc__ZN3FooD1Ev
 
 int main() {
 }
diff --git a/test/Profile/cxx-virtual-destructor-calls.cpp b/test/Profile/cxx-virtual-destructor-calls.cpp
index cc3df68..c60fc92 100644
--- a/test/Profile/cxx-virtual-destructor-calls.cpp
+++ b/test/Profile/cxx-virtual-destructor-calls.cpp
@@ -13,15 +13,6 @@
   virtual ~B();
 };
 
-// Base dtor
-// CHECK: @__profn__ZN1BD2Ev = private constant [9 x i8] c"_ZN1BD2Ev"
-
-// Complete dtor must not be instrumented
-// CHECK-NOT: @__profn__ZN1BD1Ev = private constant [9 x i8] c"_ZN1BD1Ev"
-
-// Deleting dtor must not be instrumented
-// CHECK-NOT: @__profn__ZN1BD0Ev = private constant [9 x i8] c"_ZN1BD0Ev"
-
 // Base dtor counters and profile data
 // CHECK: @__profc__ZN1BD2Ev = private global [1 x i64] zeroinitializer
 // CHECK: @__profd__ZN1BD2Ev =
diff --git a/test/Profile/func-entry.c b/test/Profile/func-entry.c
index 430ccb3..4a4ca22 100644
--- a/test/Profile/func-entry.c
+++ b/test/Profile/func-entry.c
@@ -1,7 +1,7 @@
 // Test that function entry counts are set correctly.
 
 // RUN: llvm-profdata merge %S/Inputs/func-entry.proftext -o %t.profdata
-// RUN: %clang_cc1 %s -o - -disable-llvm-optzns -emit-llvm -fprofile-instrument-use-path=%t.profdata | FileCheck %s
+// RUN: %clang_cc1 %s -o - -disable-llvm-passes -emit-llvm -fprofile-instrument-use-path=%t.profdata | FileCheck %s
 
 void foo(void);
 
diff --git a/test/Profile/gcc-flag-compatibility.c b/test/Profile/gcc-flag-compatibility.c
index 0376b0b..cfc1a35 100644
--- a/test/Profile/gcc-flag-compatibility.c
+++ b/test/Profile/gcc-flag-compatibility.c
@@ -18,14 +18,14 @@
 // RUN: rm -rf %t.dir
 // RUN: mkdir -p %t.dir/some/path
 // RUN: llvm-profdata merge %S/Inputs/gcc-flag-compatibility.proftext -o %t.dir/some/path/default.profdata
-// RUN: %clang %s -o - -mllvm -disable-llvm-optzns -emit-llvm -S -fprofile-use=%t.dir/some/path | FileCheck -check-prefix=PROFILE-USE-2 %s
+// RUN: %clang %s -o - -Xclang -disable-llvm-passes -emit-llvm -S -fprofile-use=%t.dir/some/path | FileCheck -check-prefix=PROFILE-USE-2 %s
 // PROFILE-USE-2: = !{!"branch_weights", i32 101, i32 2}
 
 // Check that -fprofile-use=some/path/file.prof reads some/path/file.prof
 // RUN: rm -rf %t.dir
 // RUN: mkdir -p %t.dir/some/path
 // RUN: llvm-profdata merge %S/Inputs/gcc-flag-compatibility.proftext -o %t.dir/some/path/file.prof
-// RUN: %clang %s -o - -mllvm -disable-llvm-optzns -emit-llvm -S -fprofile-use=%t.dir/some/path/file.prof | FileCheck -check-prefix=PROFILE-USE-3 %s
+// RUN: %clang %s -o - -Xclang -disable-llvm-passes -emit-llvm -S -fprofile-use=%t.dir/some/path/file.prof | FileCheck -check-prefix=PROFILE-USE-3 %s
 // PROFILE-USE-3: = !{!"branch_weights", i32 101, i32 2}
 
 int X = 0;
diff --git a/test/Profile/profile-summary.c b/test/Profile/profile-summary.c
index dc3112c..47fd9e8 100644
--- a/test/Profile/profile-summary.c
+++ b/test/Profile/profile-summary.c
@@ -1,7 +1,7 @@
 // Test that profile summary is set correctly.
 
 // RUN: llvm-profdata merge %S/Inputs/max-function-count.proftext -o %t.profdata
-// RUN: %clang_cc1 %s -o - -disable-llvm-optzns -emit-llvm -fprofile-instrument-use-path=%t.profdata | FileCheck %s
+// RUN: %clang_cc1 %s -o - -disable-llvm-passes -emit-llvm -fprofile-instrument-use-path=%t.profdata | FileCheck %s
 //
 int begin(int i) {
   if (i)
diff --git a/test/Rewriter/lit.local.cfg b/test/Rewriter/lit.local.cfg
index 69b733b..f5e1d03 100644
--- a/test/Rewriter/lit.local.cfg
+++ b/test/Rewriter/lit.local.cfg
@@ -1,3 +1,3 @@
 # The Objective-C rewriters are currently grouped with ARCMT.
-if config.root.clang_arcmt == 0:
+if not config.root.clang_arcmt:
     config.unsupported = True
diff --git a/test/Sema/Inputs/diagnose-if-warn-system-header.h b/test/Sema/Inputs/diagnose-if-warn-system-header.h
new file mode 100644
index 0000000..753c69d
--- /dev/null
+++ b/test/Sema/Inputs/diagnose-if-warn-system-header.h
@@ -0,0 +1,11 @@
+#pragma GCC system_header
+
+inline int system_header_func(int x)
+  __attribute__((diagnose_if(x == x, "system header warning", "warning"))) // expected-note {{from 'diagnose_if' attribute}}
+{
+  return 0;
+}
+
+void test_system_header() {
+  system_header_func(0); // expected-warning {{system header warning}}
+}
diff --git a/test/Sema/PR28181.c b/test/Sema/PR28181.c
new file mode 100644
index 0000000..3410f46
--- /dev/null
+++ b/test/Sema/PR28181.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct spinlock_t {
+  int lock;
+} audit_skb_queue;
+
+void fn1() {
+  audit_skb_queue = (lock); // expected-error {{use of undeclared identifier 'lock'; did you mean 'long'?}}
+}                           // expected-error@-1 {{assigning to 'struct spinlock_t' from incompatible type '<overloaded function type>'}}
+
+void fn2() {
+  audit_skb_queue + (lock); // expected-error {{use of undeclared identifier 'lock'; did you mean 'long'?}}
+}                           // expected-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}}
diff --git a/test/Sema/address-unaligned.c b/test/Sema/address-unaligned.c
new file mode 100644
index 0000000..6719509
--- /dev/null
+++ b/test/Sema/address-unaligned.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -fms-extensions -verify %s
+// expected-no-diagnostics
+
+typedef
+struct __attribute__((packed)) S1 {
+  char c0;
+  int x;
+  char c1;
+} S1;
+
+void bar(__unaligned int *);
+
+void foo(__unaligned S1* s1)
+{
+    bar(&s1->x);
+}
diff --git a/test/Sema/alias-redefinition.c b/test/Sema/alias-redefinition.c
index 91f4b27..a4c06ee 100644
--- a/test/Sema/alias-redefinition.c
+++ b/test/Sema/alias-redefinition.c
@@ -19,9 +19,8 @@
 void fun4(void) __attribute((alias("f4")));
 void fun4(void);
 
-// FIXME: We should produce a special case error for this.
 void f5() {}
-void __attribute((alias("f5"))) fun5(void) {} // expected-error {{redefinition of 'fun5'}} // expected-note {{previous definition}}
+void __attribute((alias("f5"))) fun5(void) {} // expected-error {{definition 'fun5' cannot also be an alias}}
 
 int var1 __attribute((alias("v1"))); // expected-error {{definition 'var1' cannot also be an alias}}
 static int var2 __attribute((alias("v2"))) = 2; // expected-error {{definition 'var2' cannot also be an alias}}
diff --git a/test/Sema/alloc-size.c b/test/Sema/alloc-size.c
new file mode 100644
index 0000000..7004a5a
--- /dev/null
+++ b/test/Sema/alloc-size.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -verify
+
+void *fail1(int a) __attribute__((alloc_size)); //expected-error{{'alloc_size' attribute takes at least 1 argument}}
+void *fail2(int a) __attribute__((alloc_size())); //expected-error{{'alloc_size' attribute takes at least 1 argument}}
+
+void *fail3(int a) __attribute__((alloc_size(0))); //expected-error{{'alloc_size' attribute parameter 0 is out of bounds}}
+void *fail4(int a) __attribute__((alloc_size(2))); //expected-error{{'alloc_size' attribute parameter 2 is out of bounds}}
+
+void *fail5(int a, int b) __attribute__((alloc_size(0, 1))); //expected-error{{'alloc_size' attribute parameter 0 is out of bounds}}
+void *fail6(int a, int b) __attribute__((alloc_size(3, 1))); //expected-error{{'alloc_size' attribute parameter 3 is out of bounds}}
+
+void *fail7(int a, int b) __attribute__((alloc_size(1, 0))); //expected-error{{'alloc_size' attribute parameter 0 is out of bounds}}
+void *fail8(int a, int b) __attribute__((alloc_size(1, 3))); //expected-error{{'alloc_size' attribute parameter 3 is out of bounds}}
+
+int fail9(int a) __attribute__((alloc_size(1))); //expected-warning{{'alloc_size' attribute only applies to return values that are pointers}}
+
+int fail10 __attribute__((alloc_size(1))); //expected-warning{{'alloc_size' attribute only applies to functions}}
+
+void *fail11(void *a) __attribute__((alloc_size(1))); //expected-error{{'alloc_size' attribute argument may only refer to a function parameter of integer type}}
+
+void *fail12(int a) __attribute__((alloc_size("abc"))); //expected-error{{'alloc_size' attribute requires parameter 1 to be an integer constant}}
+void *fail12(int a) __attribute__((alloc_size(1, "abc"))); //expected-error{{'alloc_size' attribute requires parameter 2 to be an integer constant}}
+void *fail13(int a) __attribute__((alloc_size(1U<<31))); //expected-error{{integer constant expression evaluates to value 2147483648 that cannot be represented in a 32-bit signed integer type}}
+
+int (*PR31453)(int) __attribute__((alloc_size(1))); //expected-warning{{'alloc_size' attribute only applies to functions}}
diff --git a/test/Sema/arm-interrupt-attr.c b/test/Sema/arm-interrupt-attr.c
index b9684f0..3a6cdbe 100644
--- a/test/Sema/arm-interrupt-attr.c
+++ b/test/Sema/arm-interrupt-attr.c
@@ -17,3 +17,19 @@
 __attribute__((interrupt)) void foo8() {}
 __attribute__((interrupt())) void foo9() {}
 __attribute__((interrupt(""))) void foo10() {}
+
+void callee1();
+__attribute__((interrupt("IRQ"))) void callee2();
+void caller1() {
+  callee1();
+  callee2();
+}
+__attribute__((interrupt("IRQ"))) void caller2() {
+  callee1(); // expected-warning {{call to function without interrupt attribute could clobber interruptee's VFP registers}}
+  callee2();
+}
+
+void (*callee3)();
+__attribute__((interrupt("IRQ"))) void caller3() {
+  callee3(); // expected-warning {{call to function without interrupt attribute could clobber interruptee's VFP registers}}
+}
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
index 69c33f7..e49a166 100644
--- a/test/Sema/asm.c
+++ b/test/Sema/asm.c
@@ -28,6 +28,16 @@
   asm ("nop" : : : "204"); // expected-error {{unknown register name '204' in asm}}
   asm ("nop" : : : "-1"); // expected-error {{unknown register name '-1' in asm}}
   asm ("nop" : : : "+1"); // expected-error {{unknown register name '+1' in asm}}
+  register void *clobber_conflict asm ("%rcx");
+  register void *no_clobber_conflict asm ("%rax");
+  int a,b,c;
+  asm ("nop" : "=r" (no_clobber_conflict) : "r" (clobber_conflict) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}}
+  asm ("nop" : "=r" (clobber_conflict) : "r" (no_clobber_conflict) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}}
+  asm ("nop" : "=r" (clobber_conflict) : "r" (clobber_conflict) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}}
+  asm ("nop" : "=c" (a) : "r" (no_clobber_conflict) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}}
+  asm ("nop" : "=r" (no_clobber_conflict) : "c" (c) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}}
+  asm ("nop" : "=r" (clobber_conflict) : "c" (c) : "%rcx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}}
+  asm ("nop" : "=a" (a) : "b" (b) : "%rcx", "%rbx"); // expected-error {{asm-specifier for input or output variable conflicts with asm clobber list}} 
 }
 
 // rdar://6094010
diff --git a/test/Sema/ast-print.c b/test/Sema/ast-print.c
index 4c0aef5..f701b12 100644
--- a/test/Sema/ast-print.c
+++ b/test/Sema/ast-print.c
@@ -65,3 +65,12 @@
   // CHECK: } z = {(struct Z){}};
   } z = {(struct Z){}};
 }
+
+// CHECK-LABEL: enum EnumWithAttributes {
+enum EnumWithAttributes {
+  // CHECK-NEXT: EnumWithAttributesFoo __attribute__((deprecated(""))),
+  EnumWithAttributesFoo __attribute__((deprecated)),
+  // CHECK-NEXT: EnumWithAttributesBar __attribute__((unavailable(""))) = 50
+  EnumWithAttributesBar __attribute__((unavailable)) = 50
+  // CHECK-NEXT: } __attribute__((deprecated("")))
+} __attribute__((deprecated));
diff --git a/test/Sema/attr-external-source-symbol.c b/test/Sema/attr-external-source-symbol.c
new file mode 100644
index 0000000..af6e6bc
--- /dev/null
+++ b/test/Sema/attr-external-source-symbol.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
+
+void threeClauses() __attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration)));
+
+void twoClauses() __attribute__((external_source_symbol(language="Swift", defined_in="module")));
+
+void fourClauses() __attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration, generated_declaration))); // expected-error {{duplicate 'generated_declaration' clause in an 'external_source_symbol' attribute}}
+
+void oneClause() __attribute__((external_source_symbol(generated_declaration)));
+
+void noArguments()
+__attribute__((external_source_symbol)); // expected-error {{'external_source_symbol' attribute takes at least 1 argument}}
+
+void namedDeclsOnly() {
+  int (^block)(void) = ^ (void)
+    __attribute__((external_source_symbol(language="Swift"))) { // expected-warning {{'external_source_symbol' attribute only applies to named declarations}}
+      return 1;
+  };
+}
diff --git a/test/Sema/attr-ifunc.c b/test/Sema/attr-ifunc.c
index d177b71..8f9c22f 100644
--- a/test/Sema/attr-ifunc.c
+++ b/test/Sema/attr-ifunc.c
@@ -39,5 +39,9 @@
 //expected-error@-1 {{definition with same mangled name as another definition}}
 void* f1_ifunc() { return 0; }
 
+void* f6_ifunc(int i);
+void __attribute__((ifunc("f6_ifunc"))) f6() {}
+//expected-error@-1 {{definition 'f6' cannot also be an ifunc}}
+
 #endif
 #endif
diff --git a/test/Sema/auto-type.c b/test/Sema/auto-type.c
index 9fadb90..ff72287 100644
--- a/test/Sema/auto-type.c
+++ b/test/Sema/auto-type.c
@@ -7,7 +7,7 @@
 __auto_type c = &b;
 __auto_type d = (struct {int a;}) {5};
 _Static_assert(__builtin_types_compatible_p(__typeof(a), int), "");
-__auto_type e = e; // expected-error {{variable 'e' declared with '__auto_type' type cannot appear in its own initializer}}
+__auto_type e = e; // expected-error {{variable 'e' declared with deduced type '__auto_type' cannot appear in its own initializer}}
 
 struct s { __auto_type a; }; // expected-error {{'__auto_type' not allowed in struct member}}
 
diff --git a/test/Sema/avr-interrupt-attr.c b/test/Sema/avr-interrupt-attr.c
new file mode 100644
index 0000000..2dfc72a
--- /dev/null
+++ b/test/Sema/avr-interrupt-attr.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only
+struct a { int b; };
+
+struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}}
+
+__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}}
+
+__attribute__((interrupt)) void food() {}
diff --git a/test/Sema/avr-signal-attr.c b/test/Sema/avr-signal-attr.c
new file mode 100644
index 0000000..a5920bf
--- /dev/null
+++ b/test/Sema/avr-signal-attr.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only
+struct a { int b; };
+
+struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions}}
+
+__attribute__((signal(12))) void foo(void) { } // expected-error {{'signal' attribute takes no arguments}}
+
+__attribute__((signal)) void food() {}
diff --git a/test/Sema/builtin-object-size.c b/test/Sema/builtin-object-size.c
index 14674c6..300c739 100644
--- a/test/Sema/builtin-object-size.c
+++ b/test/Sema/builtin-object-size.c
@@ -76,3 +76,18 @@
   a += __builtin_object_size(p3->b, 0);
   return a;
 }
+
+int pr31843() {
+  int n = 0;
+
+  struct { int f; } a;
+  int b;
+  n += __builtin_object_size(({&(b ? &a : &a)->f; pr31843;}), 0); // expected-warning{{expression result unused}}
+
+  struct statfs { char f_mntonname[1024];};
+  struct statfs *outStatFSBuf;
+  n += __builtin_object_size(outStatFSBuf->f_mntonname ? "" : "", 1); // expected-warning{{address of array}}
+  n += __builtin_object_size(outStatFSBuf->f_mntonname ?: "", 1);
+
+  return n;
+}
diff --git a/test/Sema/builtins-x86.c b/test/Sema/builtins-x86.c
index 6929dcc..f785438 100644
--- a/test/Sema/builtins-x86.c
+++ b/test/Sema/builtins-x86.c
@@ -4,6 +4,7 @@
 typedef float __m128 __attribute__((__vector_size__(16)));
 typedef double __m128d __attribute__((__vector_size__(16)));
 
+typedef long long __m512i __attribute__((__vector_size__(64)));
 typedef float __m512 __attribute__((__vector_size__(64)));
 typedef double __m512d __attribute__((__vector_size__(64)));
 
@@ -69,3 +70,16 @@
 __mmask16 test__builtin_ia32_cmpps512_mask_rounding(__m512 __a, __m512 __b, __mmask16 __u) {
   __builtin_ia32_cmpps512_mask(__a, __b, 0, __u, 0); // expected-error {{invalid rounding argument}}
 }
+
+__m128i test_mm_mask_i32gather_epi32(__m128i a, int const *b, __m128i c, __m128i mask) {
+  return __builtin_ia32_gatherd_d(a, b, c, mask, 5); // expected-error {{scale argument must be 1, 2, 4, or 8}}
+}
+
+__m512i _mm512_mask_prefetch_i32gather_ps(__m512i index, __mmask16 mask, int const *addr) {
+  return __builtin_ia32_gatherpfdps(mask, index, addr, 5, 1); // expected-error {{scale argument must be 1, 2, 4, or 8}}
+}
+
+__m512 _mm512_mask_prefetch_i32gather_ps_2(__m512i index, __mmask16 mask, int const *addr) {
+  return __builtin_ia32_gatherpfdps(mask, index, addr, 1, 3); // expected-error {{argument should be a value from 1 to 2}}
+}
+
diff --git a/test/Sema/callingconv-cast.c b/test/Sema/callingconv-cast.c
index 12c0dcb..599a7d1 100644
--- a/test/Sema/callingconv-cast.c
+++ b/test/Sema/callingconv-cast.c
@@ -15,6 +15,13 @@
 // expected-note@+1 3 {{consider defining 'mismatched' with the 'stdcall' calling convention}}
 void mismatched(int x) {}
 
+// expected-note@+1 {{consider defining 'mismatched_declaration' with the 'stdcall' calling convention}}
+void mismatched_declaration(int x);
+
+// expected-note@+1 {{consider defining 'suggest_fix_first_redecl' with the 'stdcall' calling convention}}
+void suggest_fix_first_redecl(int x);
+void suggest_fix_first_redecl(int x);
+
 typedef void (WINAPI *callback_t)(int);
 void take_callback(callback_t callback);
 
@@ -46,6 +53,12 @@
   // Another way to suppress the warning.
   take_callback((callback_t)(void*)mismatched);
 
+  // Warn on declarations as well as definitions.
+  // expected-warning@+1 {{cast between incompatible calling conventions 'cdecl' and 'stdcall'}}
+  take_callback((callback_t)mismatched_declaration);
+  // expected-warning@+1 {{cast between incompatible calling conventions 'cdecl' and 'stdcall'}}
+  take_callback((callback_t)suggest_fix_first_redecl);
+
   // Don't warn, because we're casting from stdcall to cdecl. Usually that means
   // the programmer is rinsing the function pointer through some kind of opaque
   // API.
diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c
index bfb58bc..1b0a325 100644
--- a/test/Sema/const-eval.c
+++ b/test/Sema/const-eval.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux %s -Wno-tautological-pointer-compare
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux %s -Wno-tautological-pointer-compare
 
 #define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];});
 int x;
@@ -126,7 +126,7 @@
 EVAL_EXPR(49, &x < &x - 100 ? 1 : -1) // expected-error {{must have a constant size}}
 
 extern struct Test50S Test50;
-EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned)&Test50 + 10)) // expected-error {{must have a constant size}}
+EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned long)&Test50 + 10)) // expected-error {{must have a constant size}}
 
 // <rdar://problem/11874571>
 EVAL_EXPR(51, 0 != (float)1e99)
@@ -137,3 +137,10 @@
 void PR24622();
 struct PR24622 {} pr24622;
 EVAL_EXPR(52, &pr24622 == (void *)&PR24622); // expected-error {{must have a constant size}}
+
+// We evaluate these by providing 2s' complement semantics in constant
+// expressions, like we do for integers.
+void *PR28739a = (__int128)(unsigned long)-1 + &PR28739a;
+void *PR28739b = &PR28739b + (__int128)(unsigned long)-1;
+__int128 PR28739c = (&PR28739c + (__int128)(unsigned long)-1) - &PR28739c;
+void *PR28739d = &(&PR28739d)[(__int128)(unsigned long)-1];
diff --git a/test/Sema/constant-conversion.c b/test/Sema/constant-conversion.c
index 224f2ee..bf82210 100644
--- a/test/Sema/constant-conversion.c
+++ b/test/Sema/constant-conversion.c
@@ -11,7 +11,7 @@
 void test_7809123(void) {
   struct { int i5 : 5; } a;
 
-  a.i5 = 36; // expected-warning {{implicit truncation from 'int' to bitfield changes value from 36 to 4}}
+  a.i5 = 36; // expected-warning {{implicit truncation from 'int' to bit-field changes value from 36 to 4}}
 }
 
 void test() {
@@ -31,11 +31,11 @@
     int bar : 2;
   };
 
-  struct A a = { 0, 10 };            // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to -2}}
-  struct A b[] = { 0, 10, 0, 0 };    // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to -2}}
-  struct A c[] = {{10, 0}};          // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to 2}}
-  struct A d = (struct A) { 10, 0 }; // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to 2}}
-  struct A e = { .foo = 10 };        // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to 2}}
+  struct A a = { 0, 10 };            // expected-warning {{implicit truncation from 'int' to bit-field changes value from 10 to -2}}
+  struct A b[] = { 0, 10, 0, 0 };    // expected-warning {{implicit truncation from 'int' to bit-field changes value from 10 to -2}}
+  struct A c[] = {{10, 0}};          // expected-warning {{implicit truncation from 'int' to bit-field changes value from 10 to 2}}
+  struct A d = (struct A) { 10, 0 }; // expected-warning {{implicit truncation from 'int' to bit-field changes value from 10 to 2}}
+  struct A e = { .foo = 10 };        // expected-warning {{implicit truncation from 'int' to bit-field changes value from 10 to 2}}
 }
 
 void test4() {
@@ -43,7 +43,7 @@
     char c : 2;
   } a;
 
-  a.c = 0x101; // expected-warning {{implicit truncation from 'int' to bitfield changes value from 257 to 1}}
+  a.c = 0x101; // expected-warning {{implicit truncation from 'int' to bit-field changes value from 257 to 1}}
 }
 
 void test5() {
@@ -52,7 +52,7 @@
   } a;
 
   // Don't warn about this implicit conversion to bool, or at least
-  // don't warn about it just because it's a bitfield.
+  // don't warn about it just because it's a bit-field.
   a.b = 100;
 }
 
@@ -71,7 +71,7 @@
 
 	f.twoBits1 = ~0; // no-warning
 	f.twoBits1 = ~1; // no-warning
-	f.twoBits2 = ~2; // expected-warning {{implicit truncation from 'int' to bitfield changes value from -3 to 1}}
+	f.twoBits2 = ~2; // expected-warning {{implicit truncation from 'int' to bit-field changes value from -3 to 1}}
 	f.twoBits1 &= ~1; // no-warning
 	f.twoBits2 &= ~2; // no-warning
 }
@@ -79,7 +79,7 @@
 void test8() {
   enum E { A, B, C };
   struct { enum E x : 1; } f;
-  f.x = C; // expected-warning {{implicit truncation from 'int' to bitfield changes value from 2 to 0}}
+  f.x = C; // expected-warning {{implicit truncation from 'int' to bit-field changes value from 2 to 0}}
 }
 
 void test9() {
@@ -128,6 +128,6 @@
   s.a = ~0U;
   s.a = ~(1<<A);
 
-  s.a = -9;  // expected-warning{{implicit truncation from 'int' to bitfield changes value from -9 to 7}}
-  s.a = 16;  // expected-warning{{implicit truncation from 'int' to bitfield changes value from 16 to 0}}
+  s.a = -9;  // expected-warning{{implicit truncation from 'int' to bit-field changes value from -9 to 7}}
+  s.a = 16;  // expected-warning{{implicit truncation from 'int' to bit-field changes value from 16 to 0}}
 }
diff --git a/test/Sema/decl-in-prototype.c b/test/Sema/decl-in-prototype.c
index 3b8a3b8..64caea6 100644
--- a/test/Sema/decl-in-prototype.c
+++ b/test/Sema/decl-in-prototype.c
@@ -1,13 +1,19 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
+#define SA(n, c) int arr##n[(c) ? 1 : -1] = {}
+
 const int AA = 5;
 
 int f1(enum {AA,BB} E) { // expected-warning {{will not be visible outside of this function}}
-    return BB;
+  SA(1, AA == 0);
+  SA(2, BB == 1);
+  return BB;
 }
 
 int f2(enum {AA=7,BB} E) { // expected-warning {{will not be visible outside of this function}}
-    return AA;
+  SA(1, AA == 7);
+  SA(2, BB == 8);
+  return AA;
 }
 
 struct a {
@@ -38,3 +44,52 @@
 
 // Only warn once, even if we create two declarations.
 void f(struct q *, struct __attribute__((aligned(4))) q *); // expected-warning {{will not be visible outside}}
+
+// This enum inside the function pointer parameter shouldn't leak into the
+// function.
+enum { BB = 0 };
+void enum_in_fun_in_fun(void (*fp)(enum { AA, BB } e)) { // expected-warning {{will not be visible}}
+  SA(1, AA == 5);
+  SA(2, BB == 0);
+}
+
+void f7() {
+  extern void ext(struct S { enum E7 { a, b } o; } p); // expected-warning 2 {{will not be visible}}
+  ext(a); // expected-error {{use of undeclared identifier}}
+}
+
+int f8(struct S { enum E8 { a, b } o; } p) { // expected-warning 2 {{will not be visible}}
+  struct S o;
+  enum E8 x;
+  return a + b;
+}
+// expected-note@+1 {{forward declaration}}
+struct S o; // expected-error {{'struct S' that is never completed}}
+// expected-note@+1 {{forward declaration}}
+enum E8 x = a + b; // expected-error 2 {{undeclared identifier}} expected-error {{incomplete type 'enum E8'}}
+
+int f9(struct { enum e { a = 1 } b; } c) { // expected-warning {{will not be visible}}
+  return a;
+}
+
+int f10(
+  struct S { // expected-warning {{will not be visible}}
+    enum E10 { a, b, c } f; // expected-warning {{will not be visible}}
+  } e) {
+  return a == b;
+}
+
+int f11(
+  struct S { // expected-warning {{will not be visible}}
+    enum E11 { // expected-warning {{will not be visible}}
+      a, b, c
+    } // expected-warning {{expected ';' at end of declaration list}}
+  } // expected-error {{expected member name or ';'}}
+  e);
+
+void f12() {
+  extern int ext12(
+      struct S12 { } e // expected-warning {{will not be visible}}
+      );
+  struct S12 o; // expected-error {{incomplete type}} expected-note {{forward declaration}}
+}
diff --git a/test/Sema/diagnose_if.c b/test/Sema/diagnose_if.c
new file mode 100644
index 0000000..27689f4
--- /dev/null
+++ b/test/Sema/diagnose_if.c
@@ -0,0 +1,155 @@
+// RUN: %clang_cc1 %s -verify -fno-builtin
+
+#define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))
+
+void failure() _diagnose_if(); // expected-error{{exactly 3 arguments}}
+void failure() _diagnose_if(0); // expected-error{{exactly 3 arguments}}
+void failure() _diagnose_if(0, ""); // expected-error{{exactly 3 arguments}}
+void failure() _diagnose_if(0, "", "error", 1); // expected-error{{exactly 3 arguments}}
+void failure() _diagnose_if(0, 0, "error"); // expected-error{{requires a string}}
+void failure() _diagnose_if(0, "", "invalid"); // expected-error{{invalid diagnostic type for 'diagnose_if'; use "error" or "warning" instead}}
+void failure() _diagnose_if(0, "", "ERROR"); // expected-error{{invalid diagnostic type}}
+void failure(int a) _diagnose_if(a, "", ""); // expected-error{{invalid diagnostic type}}
+void failure() _diagnose_if(a, "", ""); // expected-error{{undeclared identifier 'a'}}
+
+int globalVar;
+void never_constant() _diagnose_if(globalVar, "", "error"); // expected-error{{'diagnose_if' attribute expression never produces a constant expression}} expected-note{{subexpression not valid}}
+void never_constant() _diagnose_if(globalVar, "", "warning"); // expected-error{{'diagnose_if' attribute expression never produces a constant expression}} expected-note{{subexpression not valid}}
+
+int alwaysok(int q) _diagnose_if(0, "", "error");
+int neverok(int q) _diagnose_if(1, "oh no", "error"); // expected-note 5{{from 'diagnose_if' attribute on 'neverok'}}
+int alwayswarn(int q) _diagnose_if(1, "oh no", "warning"); // expected-note 5{{from 'diagnose_if' attribute}}
+int neverwarn(int q) _diagnose_if(0, "", "warning");
+
+void runConstant() {
+  int m;
+  alwaysok(0);
+  alwaysok(1);
+  alwaysok(m);
+
+  {
+    int (*pok)(int) = alwaysok;
+    pok = &alwaysok;
+  }
+
+  neverok(0); // expected-error{{oh no}}
+  neverok(1); // expected-error{{oh no}}
+  neverok(m); // expected-error{{oh no}}
+  {
+    int (*pok)(int) = neverok; // expected-error{{oh no}}
+    pok = &neverok; // expected-error{{oh no}}
+  }
+
+  alwayswarn(0); // expected-warning{{oh no}}
+  alwayswarn(1); // expected-warning{{oh no}}
+  alwayswarn(m); // expected-warning{{oh no}}
+  {
+    int (*pok)(int) = alwayswarn; // expected-warning{{oh no}}
+    pok = &alwayswarn; // expected-warning{{oh no}}
+  }
+
+  neverwarn(0);
+  neverwarn(1);
+  neverwarn(m);
+  {
+    int (*pok)(int) = neverwarn;
+    pok = &neverwarn;
+  }
+}
+
+int abs(int q) _diagnose_if(q >= 0, "redundant abs call", "error"); //expected-note{{from 'diagnose_if'}}
+void runVariable() {
+  int m;
+  abs(-1);
+  abs(1); // expected-error{{redundant abs call}}
+  abs(m);
+
+  int (*pabs)(int) = abs;
+  pabs = &abs;
+}
+
+#define _overloadable __attribute__((overloadable))
+
+int ovl1(const char *n) _overloadable _diagnose_if(n, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+int ovl1(void *m) _overloadable;
+
+int ovl2(const char *n) _overloadable _diagnose_if(n, "oh no", "error"); // expected-note{{candidate function}}
+int ovl2(char *m) _overloadable; // expected-note{{candidate function}}
+void overloadsYay() {
+  ovl1((void *)0);
+  ovl1(""); // expected-error{{oh no}}
+
+  ovl2((void *)0); // expected-error{{ambiguous}}
+}
+
+void errorWarnDiagnose1() _diagnose_if(1, "oh no", "error") // expected-note{{from 'diagnose_if'}}
+  _diagnose_if(1, "nop", "warning");
+void errorWarnDiagnose2() _diagnose_if(1, "oh no", "error") // expected-note{{from 'diagnose_if'}}
+  _diagnose_if(1, "nop", "error");
+void errorWarnDiagnose3() _diagnose_if(1, "nop", "warning")
+  _diagnose_if(1, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+
+void errorWarnDiagnoseArg1(int a) _diagnose_if(a == 1, "oh no", "error") // expected-note{{from 'diagnose_if'}}
+  _diagnose_if(a == 1, "nop", "warning");
+void errorWarnDiagnoseArg2(int a) _diagnose_if(a == 1, "oh no", "error") // expected-note{{from 'diagnose_if'}}
+  _diagnose_if(a == 1, "nop", "error");
+void errorWarnDiagnoseArg3(int a) _diagnose_if(a == 1, "nop", "warning")
+  _diagnose_if(a == 1, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+
+void runErrorWarnDiagnose() {
+  errorWarnDiagnose1(); // expected-error{{oh no}}
+  errorWarnDiagnose2(); // expected-error{{oh no}}
+  errorWarnDiagnose3(); // expected-error{{oh no}}
+
+  errorWarnDiagnoseArg1(1); // expected-error{{oh no}}
+  errorWarnDiagnoseArg2(1); // expected-error{{oh no}}
+  errorWarnDiagnoseArg3(1); // expected-error{{oh no}}
+}
+
+void warnWarnDiagnose() _diagnose_if(1, "oh no!", "warning") _diagnose_if(1, "foo", "warning"); // expected-note 2{{from 'diagnose_if'}}
+void runWarnWarnDiagnose() {
+  warnWarnDiagnose(); // expected-warning{{oh no!}} expected-warning{{foo}}
+}
+
+void declsStackErr1(int a) _diagnose_if(a & 1, "decl1", "error"); // expected-note 2{{from 'diagnose_if'}}
+void declsStackErr1(int a) _diagnose_if(a & 2, "decl2", "error"); // expected-note{{from 'diagnose_if'}}
+void declsStackErr2();
+void declsStackErr2() _diagnose_if(1, "complaint", "error"); // expected-note{{from 'diagnose_if'}}
+void declsStackErr3() _diagnose_if(1, "complaint", "error"); // expected-note{{from 'diagnose_if'}}
+void declsStackErr3();
+void runDeclsStackErr() {
+  declsStackErr1(0);
+  declsStackErr1(1); // expected-error{{decl1}}
+  declsStackErr1(2); // expected-error{{decl2}}
+  declsStackErr1(3); // expected-error{{decl1}}
+  declsStackErr2(); // expected-error{{complaint}}
+  declsStackErr3(); // expected-error{{complaint}}
+}
+
+void declsStackWarn1(int a) _diagnose_if(a & 1, "decl1", "warning"); // expected-note 2{{from 'diagnose_if'}}
+void declsStackWarn1(int a) _diagnose_if(a & 2, "decl2", "warning"); // expected-note 2{{from 'diagnose_if'}}
+void declsStackWarn2();
+void declsStackWarn2() _diagnose_if(1, "complaint", "warning"); // expected-note{{from 'diagnose_if'}}
+void declsStackWarn3() _diagnose_if(1, "complaint", "warning"); // expected-note{{from 'diagnose_if'}}
+void declsStackWarn3();
+void runDeclsStackWarn() {
+  declsStackWarn1(0);
+  declsStackWarn1(1); // expected-warning{{decl1}}
+  declsStackWarn1(2); // expected-warning{{decl2}}
+  declsStackWarn1(3); // expected-warning{{decl1}} expected-warning{{decl2}}
+  declsStackWarn2(); // expected-warning{{complaint}}
+  declsStackWarn3(); // expected-warning{{complaint}}
+}
+
+void noMsg(int n) _diagnose_if(n, "", "warning"); // expected-note{{from 'diagnose_if'}}
+void runNoMsg() {
+  noMsg(1); // expected-warning{{<no message provided>}}
+}
+
+void alwaysWarnWithArg(int a) _diagnose_if(1 || a, "alwaysWarn", "warning"); // expected-note{{from 'diagnose_if'}}
+void runAlwaysWarnWithArg(int a) {
+  alwaysWarnWithArg(a); // expected-warning{{alwaysWarn}}
+}
+
+// Test that diagnose_if warnings generated in system headers are not ignored.
+#include "Inputs/diagnose-if-warn-system-header.h"
diff --git a/test/Sema/enable_if.c b/test/Sema/enable_if.c
index a11f53e..9125bfa 100644
--- a/test/Sema/enable_if.c
+++ b/test/Sema/enable_if.c
@@ -139,8 +139,8 @@
 
 void f4(int m) __attribute__((enable_if(0, "")));
 void test8() {
-  void (*p1)(int) = &f4; // expected-error{{cannot take address of function 'f4' becuase it has one or more non-tautological enable_if conditions}}
-  void (*p2)(int) = f4; // expected-error{{cannot take address of function 'f4' becuase it has one or more non-tautological enable_if conditions}}
+  void (*p1)(int) = &f4; // expected-error{{cannot take address of function 'f4' because it has one or more non-tautological enable_if conditions}}
+  void (*p2)(int) = f4; // expected-error{{cannot take address of function 'f4' because it has one or more non-tautological enable_if conditions}}
 }
 
 void regular_enable_if(int a) __attribute__((enable_if(a, ""))); // expected-note 3{{declared here}}
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index 5c332bd..5465122 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -156,10 +156,10 @@
 
 void check_invalid_specifier(FILE* fp, char *buf)
 {
-  printf("%s%lb%d","unix",10,20); // expected-warning {{invalid conversion specifier 'b'}}
+  printf("%s%lb%d","unix",10,20); // expected-warning {{invalid conversion specifier 'b'}} expected-warning {{data argument not used by format string}}
   fprintf(fp,"%%%l"); // expected-warning {{incomplete format specifier}}
   sprintf(buf,"%%%%%ld%d%d", 1, 2, 3); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
-  snprintf(buf, 2, "%%%%%ld%;%d", 1, 2, 3); // expected-warning{{format specifies type 'long' but the argument has type 'int'}} expected-warning {{invalid conversion specifier ';'}}
+  snprintf(buf, 2, "%%%%%ld%;%d", 1, 2, 3); // expected-warning{{format specifies type 'long' but the argument has type 'int'}} expected-warning {{invalid conversion specifier ';'}} expected-warning {{data argument not used by format string}}
 }
 
 void check_null_char_string(char* b)
@@ -251,7 +251,7 @@
   printf("%**\n"); // expected-warning{{invalid conversion specifier '*'}}
   printf("%d%d\n", x); // expected-warning{{more '%' conversions than data arguments}}
   printf("%d\n", x, x); // expected-warning{{data argument not used by format string}}
-  printf("%W%d\n", x, x); // expected-warning{{invalid conversion specifier 'W'}}
+  printf("%W%d\n", x, x); // expected-warning{{invalid conversion specifier 'W'}}  expected-warning {{data argument not used by format string}}
   printf("%"); // expected-warning{{incomplete format specifier}}
   printf("%.d", x); // no-warning
   printf("%.", x);  // expected-warning{{incomplete format specifier}}
@@ -270,7 +270,7 @@
   printf("%.0Lf", (long double) 1.0); // no-warning
   printf("%c\n", "x"); // expected-warning{{format specifies type 'int' but the argument has type 'char *'}}
   printf("%c\n", 1.23); // expected-warning{{format specifies type 'int' but the argument has type 'double'}}
-  printf("Format %d, is %! %f", 1, 2, 4.4); // expected-warning{{invalid conversion specifier '!'}}
+  printf("Format %d, is %! %f", 1, 4.4); // expected-warning{{invalid conversion specifier '!'}}
 }
 
 typedef unsigned char uint8_t;
diff --git a/test/Sema/knr-def-call.c b/test/Sema/knr-def-call.c
index 80ad0d8..2bd4a79 100644
--- a/test/Sema/knr-def-call.c
+++ b/test/Sema/knr-def-call.c
@@ -1,13 +1,13 @@
-// RUN: %clang_cc1 -Wconversion -Wliteral-conversion -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-pc-unknown -Wconversion -Wliteral-conversion -fsyntax-only -verify %s
 
 // C DR #316, PR 3626.
 void f0(a, b, c, d) int a,b,c,d; {}
-void t0(void) { 
+void t0(void) {
   f0(1);  // expected-warning{{too few arguments}}
 }
 
 void f1(a, b) int a, b; {}
-void t1(void) { 
+void t1(void) {
   f1(1, 2, 3); // expected-warning{{too many arguments}}
 }
 
@@ -30,7 +30,7 @@
 
 // PR8314
 void proto(int);
-void proto(x) 
+void proto(x)
      int x;
 {
 }
@@ -39,3 +39,9 @@
   proto(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}}
   (&proto)(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}}
 }
+
+// PR31020
+void func(short d) __attribute__((cdecl)); // expected-note{{previous declaration is here}}
+void __attribute__((cdecl)) func(d)
+  short d; // expected-warning{{promoted type 'int' of K&R function parameter is not compatible with the parameter type 'short' declared in a previous prototype}}
+{}
diff --git a/test/Sema/nonnull.c b/test/Sema/nonnull.c
index e98a819..217bbb1 100644
--- a/test/Sema/nonnull.c
+++ b/test/Sema/nonnull.c
@@ -167,3 +167,10 @@
   int and_again = !returns_nonnull_whee(); // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
   and_again = !returns_nonnull_whee(); // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
 }
+
+void pr30828(char *p __attribute__((nonnull)));
+void pr30828(char *p) {}
+
+void call_pr30828() {
+  pr30828(0); // expected-warning {{null passed to a callee that requires a non-null argument}}
+}
diff --git a/test/Sema/pr30306.cpp b/test/Sema/pr30306.cpp
new file mode 100644
index 0000000..413e2f5
--- /dev/null
+++ b/test/Sema/pr30306.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c++ -triple x86_64-pc-linux-gnu -emit-llvm < %s | FileCheck %s
+
+struct A { A(int); ~A(); };
+int f(const A &);
+// CHECK: call void @_ZN1AC1Ei
+// CHECK-NEXT: call i32 @_Z1fRK1A
+// CHECK-NEXT: call void @_ZN1AD1Ev
+// CHECK: call void @_ZN1AC1Ei
+// CHECK-NEXT: call i32 @_Z1fRK1A
+// CHECK-NEXT: call void @_ZN1AD1Ev
+template<typename T> void g() {
+  int a[f(3)];
+  int b[f(3)];
+}
+int main() { g<int>(); }
diff --git a/test/Sema/transparent-union.c b/test/Sema/transparent-union.c
index a1a67df..dfbadcf 100644
--- a/test/Sema/transparent-union.c
+++ b/test/Sema/transparent-union.c
@@ -54,11 +54,21 @@
   aligned_struct8 s8; // expected-warning{{alignment of field}}
 } TU1 __attribute__((transparent_union));
 
+typedef union __attribute__((transparent_union)) {
+  aligned_struct4 s4; // expected-note{{alignment of first field}}
+  aligned_struct8 s8; // expected-warning{{alignment of field}}
+} TU1b ;
+
 typedef union {
   char c; // expected-note{{size of first field is 8 bits}}
   int i; // expected-warning{{size of field}}
 } TU2 __attribute__((transparent_union));
 
+typedef union __attribute__((transparent_union)){
+  char c; // expected-note{{size of first field is 8 bits}}
+  int i; // expected-warning{{size of field}}
+} TU2b;
+
 typedef union {
   float f; // expected-warning{{floating}}
 } TU3 __attribute__((transparent_union));
@@ -98,3 +108,17 @@
 union pr30520s { struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
 
 union pr30520s2 { int *v; struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
+
+typedef union __attribute__((__transparent_union__)) {
+  int *i;
+  struct st *s;
+} TU6;
+
+void bar(TU6);
+
+void foo11(int *i) {
+  bar(i);
+}
+void foo2(struct st *s) {
+  bar(s);
+}
diff --git a/test/Sema/unaligned-qualifier.c b/test/Sema/unaligned-qualifier.c
new file mode 100644
index 0000000..3a66c4f
--- /dev/null
+++ b/test/Sema/unaligned-qualifier.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -fms-extensions
+
+int __unaligned * p1; // expected-note {{previous definition is here}}
+int * p1; // expected-error {{redefinition of 'p1' with a different type: 'int *' vs '__unaligned int *'}}
diff --git a/test/Sema/vfprintf-invalid-redecl.c b/test/Sema/vfprintf-invalid-redecl.c
index cbf47a6..f06b1b6 100644
--- a/test/Sema/vfprintf-invalid-redecl.c
+++ b/test/Sema/vfprintf-invalid-redecl.c
@@ -3,4 +3,4 @@
 
 // The following declaration is not compatible with vfprintf(), but make
 // sure this isn't an error: autoconf expects this to build.
-char vfprintf(); // expected-warning {{incompatible redeclaration of library function 'vfprintf'}} expected-note {{'vfprintf' is a builtin}}
+char vfprintf(); // expected-warning {{declaration of built-in function 'vfprintf'}}
diff --git a/test/Sema/vfprintf-valid-redecl.c b/test/Sema/vfprintf-valid-redecl.c
index 8ed1878..eb5c4d3 100644
--- a/test/Sema/vfprintf-valid-redecl.c
+++ b/test/Sema/vfprintf-valid-redecl.c
@@ -1,16 +1,18 @@
 // RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify
 // RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify -DPREDECLARE
-// expected-no-diagnostics
 
 #ifdef PREDECLARE
 // PR16344
 // Clang has defined 'vfprint' in builtin list. If the following line occurs before any other
 // `vfprintf' in this file, and we getPreviousDecl()->getTypeSourceInfo() on it, then we will
 // get a null pointer since the one in builtin list doesn't has valid TypeSourceInfo.
-int vfprintf(void) { return 0; }
+int vfprintf(void) { return 0; } // expected-warning {{requires inclusion of the header <stdio.h>}}
 #endif
 
 // PR4290
 // The following declaration is compatible with vfprintf, so we shouldn't
-// warn.
+// reject.
 int vfprintf();
+#ifndef PREDECLARE
+// expected-warning@-2 {{requires inclusion of the header <stdio.h>}}
+#endif
diff --git a/test/Sema/warn-cast-align.c b/test/Sema/warn-cast-align.c
index e8f85bc..389c0c1 100644
--- a/test/Sema/warn-cast-align.c
+++ b/test/Sema/warn-cast-align.c
@@ -59,3 +59,11 @@
   i = (int *)&s.s0;
   i = (int *)a;
 }
+
+// No warnings.
+typedef int (*FnTy)(void);
+unsigned int func5(void);
+
+FnTy test5(void) {
+  return (FnTy)&func5;
+}
diff --git a/test/Sema/warn-overlap.c b/test/Sema/warn-overlap.c
index 1e8a614..6299c51 100644
--- a/test/Sema/warn-overlap.c
+++ b/test/Sema/warn-overlap.c
@@ -96,3 +96,48 @@
   int buffer[4];
   x = (-7 > 0) ? (buffer[-7]) : 0;
 }
+
+void bool_contexts(int x) {
+  if (x > 4 || x < 10) {}
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  for (;x > 4 || x < 10;) {}
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  while (x > 4 || x < 10) {}
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  do {} while (x > 4 || x < 10);
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  x = (x > 4 || x < 10) ? 1 : 2;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  if ((void)5, x > 4 || x < 10) {}
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+}
+
+void assignment(int x) {
+  int a = x > 4 || x < 10;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  int b = x < 2 && x > 5;
+  // expected-warning@-1{{overlapping comparisons always evaluate to false}}
+
+  int c = x != 1 || x != 3;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  int d = x == 1 && x == 2;
+  // expected-warning@-1{{overlapping comparisons always evaluate to false}}
+
+  int e = x < 1 || x != 0;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+}
+
+int returns(int x) {
+  return x > 4 || x < 10;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  return x < 2 && x > 5;
+  // expected-warning@-1{{overlapping comparisons always evaluate to false}}
+
+  return x != 1 || x != 3;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  return x == 1 && x == 2;
+  // expected-warning@-1{{overlapping comparisons always evaluate to false}}
+
+  return x < 1 || x != 0;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+}
diff --git a/test/Sema/warn-strict-prototypes.c b/test/Sema/warn-strict-prototypes.c
index 496579c..a28f57d 100644
--- a/test/Sema/warn-strict-prototypes.c
+++ b/test/Sema/warn-strict-prototypes.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -Wstrict-prototypes -verify %s
-// RUN: %clang_cc1 -fsyntax-only -Wstrict-prototypes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -Wstrict-prototypes -verify %s
+// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -Wstrict-prototypes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 // function declaration with unspecified params
 void foo1(); // expected-warning {{this function declaration is not a prototype}}
@@ -60,3 +60,8 @@
 // K&R function definition with previous prototype declared is not diagnosed.
 void foo11(int p, int p2);
 void foo11(p, p2) int p; int p2; {}
+
+// PR31020
+void __attribute__((cdecl)) foo12(d) // expected-warning {{this old-style function definition is not preceded by a prototype}}
+  short d;
+{}
diff --git a/test/Sema/warn-strict-prototypes.m b/test/Sema/warn-strict-prototypes.m
index cbb01a1..4567dab 100644
--- a/test/Sema/warn-strict-prototypes.m
+++ b/test/Sema/warn-strict-prototypes.m
@@ -14,7 +14,8 @@
   void (^block)() = // expected-warning {{this function declaration is not a prototype}}
                     ^void(int arg) { // no warning
   };
-  void (^block2)(void) = // no warning
-                         ^void() { // expected-warning {{this function declaration is not a prototype}}
+  void (^block2)(void) = ^void() { // no warning
+  };
+  void (^block3)(void) = ^ { // no warning
   };
 }
diff --git a/test/Sema/warn-thread-safety-analysis.c b/test/Sema/warn-thread-safety-analysis.c
index a0c4026..425ce4c 100644
--- a/test/Sema/warn-thread-safety-analysis.c
+++ b/test/Sema/warn-thread-safety-analysis.c
@@ -127,3 +127,7 @@
 
   return 0;
 }
+
+// We had a problem where we'd skip all attributes that follow a late-parsed
+// attribute in a single __attribute__.
+void run() __attribute__((guarded_by(mu1), guarded_by(mu1))); // expected-warning 2{{only applies to fields and global variables}}
diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c
index 31beff9..34e0296 100644
--- a/test/Sema/warn-unreachable.c
+++ b/test/Sema/warn-unreachable.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -I %S/Inputs
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -fdiagnostics-parseable-fixits -I %S/Inputs %s 2>&1 | FileCheck %s
 
 #include "warn-unreachable.h"
 
@@ -396,3 +397,57 @@
   else
     calledFun();
 }
+
+// rdar://24570531
+
+struct StructWithPointer {
+  void *p;
+};
+
+void emitJustOneWarningForOr(struct StructWithPointer *s) {
+  if (1 || !s->p) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("
+            // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:8-[[@LINE-2]]:8}:")"
+  emitJustOneWarningForOr(s); // expected-warning {{code will never be executed}}
+}
+
+void emitJustOneWarningForOrSilenced(struct StructWithPointer *s) {
+  if ((1) || !s->p)
+    return;
+
+  emitJustOneWarningForOrSilenced(s); // no warning
+}
+
+void emitJustOneWarningForOr2(struct StructWithPointer *s) {
+  if (1 || !s->p) // expected-warning {{code will never be executed}}
+    return; // expected-note@-1 {{silence by adding parentheses to mark code as explicitly dead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:7}:"/* DISABLES CODE */ ("
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:8-[[@LINE-3]]:8}:")"
+}
+
+void wrapOneInFixit(struct StructWithPointer *s) {
+  if (!s->p || 1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"/* DISABLES CODE */ ("
+            // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:")"
+  wrapOneInFixit(s); // expected-warning {{code will never be executed}}
+}
+
+void unaryOpNoFixit() {
+  if (- 1)
+    return; // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
+  unaryOpNoFixit(); // expected-warning {{code will never be executed}}
+}
+
+void unaryOpStrictFixit(struct StructWithPointer *s) {
+  if (!(s->p && 0)) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"/* DISABLES CODE */ ("
+            // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:18-[[@LINE-2]]:18}:")"
+  unaryOpStrictFixit(s); // expected-warning {{code will never be executed}}
+}
+
+void unaryOpFixitCastSubExpr(int x) {
+  if (! (int)0) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("
+            // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:")"
+  unaryOpFixitCastSubExpr(x); // expected-warning {{code will never be executed}}
+}
diff --git a/test/Sema/xray-log-args-oob.c b/test/Sema/xray-log-args-oob.c
new file mode 100644
index 0000000..a6be0f8
--- /dev/null
+++ b/test/Sema/xray-log-args-oob.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11
+void foo(int) __attribute__((xray_log_args(1)));
+struct __attribute__((xray_log_args(1))) a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}}
+
+void fop() __attribute__((xray_log_args(1))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
+
+void foq() __attribute__((xray_log_args(-1))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
+
+void fos() __attribute__((xray_log_args(0))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
diff --git a/test/Sema/xray-log-args-oob.cpp b/test/Sema/xray-log-args-oob.cpp
new file mode 100644
index 0000000..414bce0
--- /dev/null
+++ b/test/Sema/xray-log-args-oob.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++
+void foo [[clang::xray_log_args(1)]] (int);
+struct [[clang::xray_log_args(1)]] a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}}
+
+void fop [[clang::xray_log_args(1)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
+
+void foq [[clang::xray_log_args(-1)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
+
+void fos [[clang::xray_log_args(0)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
diff --git a/test/SemaCUDA/attr-declspec.cu b/test/SemaCUDA/attr-declspec.cu
new file mode 100644
index 0000000..dda12ce
--- /dev/null
+++ b/test/SemaCUDA/attr-declspec.cu
@@ -0,0 +1,34 @@
+// Test the __declspec spellings of CUDA attributes.
+//
+// RUN: %clang_cc1 -fsyntax-only -fms-extensions -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fms-extensions -fcuda-is-device -verify %s
+// Now pretend that we're compiling a C file. There should be warnings.
+// RUN: %clang_cc1 -DEXPECT_WARNINGS -fms-extensions -fsyntax-only -verify -x c %s
+
+#if defined(EXPECT_WARNINGS)
+// expected-warning@+12 {{'__device__' attribute ignored}}
+// expected-warning@+12 {{'__global__' attribute ignored}}
+// expected-warning@+12 {{'__constant__' attribute ignored}}
+// expected-warning@+12 {{'__shared__' attribute ignored}}
+// expected-warning@+12 {{'__host__' attribute ignored}}
+//
+// (Currently we don't for the other attributes. They are implemented with
+// IgnoredAttr, which is ignored irrespective of any LangOpts.)
+#else
+// expected-no-diagnostics
+#endif
+
+__declspec(__device__) void f_device();
+__declspec(__global__) void f_global();
+__declspec(__constant__) int* g_constant;
+__declspec(__shared__) float *g_shared;
+__declspec(__host__) void f_host();
+__declspec(__device_builtin__) void f_device_builtin();
+typedef __declspec(__device_builtin__) const void *t_device_builtin;
+enum __declspec(__device_builtin__) e_device_builtin {E};
+__declspec(__device_builtin__) int v_device_builtin;
+__declspec(__cudart_builtin__) void f_cudart_builtin();
+__declspec(__device_builtin_surface_type__) unsigned long long surface_var;
+__declspec(__device_builtin_texture_type__) unsigned long long texture_var;
+
+// Note that there's no __declspec spelling of nv_weak.
diff --git a/test/SemaCUDA/cuda-inherits-calling-conv.cu b/test/SemaCUDA/cuda-inherits-calling-conv.cu
new file mode 100644
index 0000000..67c438f
--- /dev/null
+++ b/test/SemaCUDA/cuda-inherits-calling-conv.cu
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++11 -triple i386-windows-msvc \
+// RUN:   -aux-triple nvptx-nvidia-cuda -fsyntax-only -verify %s
+
+// RUN: %clang_cc1 -std=c++11 -triple nvptx-nvidia-cuda \
+// RUN:   -aux-triple i386-windows-msvc -fsyntax-only \
+// RUN:   -fcuda-is-device -verify %s
+
+// RUN: %clang_cc1 -std=c++11 -triple nvptx-nvidia-cuda \
+// RUN:   -aux-triple x86_64-linux-gnu -fsyntax-only \
+// RUN:   -fcuda-is-device -verify -verify-ignore-unexpected=note \
+// RUN:   -DEXPECT_ERR %s
+
+// CUDA device code should inherit the host's calling conventions.
+
+template <class T>
+struct Foo;
+
+template <class T>
+struct Foo<T()> {};
+
+// On x86_64-linux-gnu, this is a redefinition of the template, because the
+// __fastcall calling convention doesn't exist (and is therefore ignored).
+#ifndef EXPECT_ERR
+// expected-no-diagnostics
+#else
+// expected-error@+4 {{redefinition of 'Foo}}
+// expected-warning@+3 {{calling convention '__fastcall' ignored}}
+#endif
+template <class T>
+struct Foo<T __fastcall()> {};
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index e12dea1..96088a0 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
+// RUN: %clang_cc1 -std=c++98 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
+// RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fexceptions -fcxx-exceptions -DTEST2
 
 #if TEST1
@@ -23,11 +25,17 @@
 };
 
 class A {
-  virtual ~A() throw();  // expected-note {{overridden virtual function is here}}
+  virtual ~A() throw();
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{overridden virtual function is here}}
+#endif
 };
 
 class B : public A {
-  virtual ~B();  // expected-warning {{exception specification of overriding function is more lax than base version}}
+  virtual ~B();
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{exception specification of overriding function is more lax than base version}}
+#endif
 };
 
 }
@@ -174,11 +182,18 @@
 typedef int Int;
 
 struct X0 {
-  enum E1 : Int { SomeOtherValue } field; // expected-warning{{enumeration types with a fixed underlying type are a C++11 extension}}
+  enum E1 : Int { SomeOtherValue } field;
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{enumeration types with a fixed underlying type are a C++11 extension}}
+#endif
+
   enum E1 : seventeen;
 };
 
-enum : long long {  // expected-warning{{enumeration types with a fixed underlying type are a C++11 extension}}
+#if __cplusplus <= 199711L
+// expected-warning@+2 {{enumeration types with a fixed underlying type are a C++11 extension}}
+#endif
+enum : long long {
   SomeValue = 0x100000000
 };
 
@@ -450,7 +465,9 @@
   // FIXME. warning can be suppressed if we're also issuing error for overriding a 'final' function.
   virtual void SealedFunction(); // expected-warning {{'SealedFunction' overrides a member function but is not marked 'override'}}
 
-  // expected-warning@+1 {{'override' keyword is a C++11 extension}}
+#if __cplusplus <= 199711L
+  // expected-warning@+2 {{'override' keyword is a C++11 extension}}
+#endif
   virtual void OverrideMe() override;
 };
 
diff --git a/test/SemaCXX/PR10177.cpp b/test/SemaCXX/PR10177.cpp
index 9286e29..59630be 100644
--- a/test/SemaCXX/PR10177.cpp
+++ b/test/SemaCXX/PR10177.cpp
@@ -24,6 +24,13 @@
   (void)class_ref<int, int&, U<2>::a>(); // expected-note {{here}}
 };
 
+template<typename T>
+void not_instantiated() {
+  // These cases (arguably) do not require instantiation of U<i>::a.
+  (void)alias_ref<int, int&, U<3>::a>();
+  (void)func_ref<int, int&, U<4>::a>();
+  (void)class_ref<int, int&, U<5>::a>();
+};
 
 template<int N>
 void fi() {
@@ -33,7 +40,7 @@
 };
 
 int main() {
-  f<int>();   // NOTE: Non-dependent name uses are type-checked at template definition time.
+  f<int>();   // expected-note 3{{here}}
   fi<10>();   // expected-note 3{{here}}
 }
 
diff --git a/test/SemaCXX/PR8755.cpp b/test/SemaCXX/PR8755.cpp
index 07778dd..6818f3f 100644
--- a/test/SemaCXX/PR8755.cpp
+++ b/test/SemaCXX/PR8755.cpp
@@ -7,7 +7,7 @@
 
 template <typename T>
 void f() {
-  class A <T> ::iterator foo;  // expected-error{{elaborated type refers to a typedef}}
+  class A <T> ::iterator foo;  // expected-error{{typedef 'iterator' cannot be referenced with a class specifier}}
 }
 
 void g() {
diff --git a/test/SemaCXX/PR9572.cpp b/test/SemaCXX/PR9572.cpp
index d6dc2e0..79d3327 100644
--- a/test/SemaCXX/PR9572.cpp
+++ b/test/SemaCXX/PR9572.cpp
@@ -1,15 +1,50 @@
 // 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
+
 class Base {
-  virtual ~Base(); // expected-note {{implicitly declared private here}}
+  virtual ~Base();
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{implicitly declared private here}}
+#else
+  // expected-note@-4 {{overridden virtual function is here}}
+#endif
 };
-struct Foo : public Base { // expected-error {{base class 'Base' has private destructor}}
-  const int kBlah = 3; // expected-warning {{is a C++11 extension}}
+
+struct Foo : public Base {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{base class 'Base' has private destructor}}
+#else
+// expected-error@-4 {{deleted function '~Foo' cannot override a non-deleted function}}
+// expected-note@-5 {{overridden virtual function is here}}
+// expected-note@-6 3 {{destructor of 'Foo' is implicitly deleted because base class 'Base' has an inaccessible destructor}}
+#endif
+
+  const int kBlah = 3;
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{in-class initialization of non-static data member is a C++11 extension}}
+#endif
+
   Foo();
 };
+
 struct Bar : public Foo {
-  Bar() { } // expected-note {{implicit destructor for 'Foo' first required here}}
+#if __cplusplus >= 201103L
+// expected-error@-2 {{non-deleted function '~Bar' cannot override a deleted function}}
+// expected-note@-3 {{while declaring the implicit destructor for 'Bar'}}
+#endif
+  Bar() { }
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{implicit destructor for 'Foo' first required here}}
+#else
+  // expected-error@-4 {{attempt to use a deleted function}}
+#endif
 };
+
 struct Baz {
   Foo f;
   Baz() { }
+#if __cplusplus >= 201103L
+  // expected-error@-2 {{attempt to use a deleted function}}
+#endif
 };
diff --git a/test/SemaCXX/aggregate-init-cxx98.cpp b/test/SemaCXX/aggregate-init-cxx98.cpp
new file mode 100644
index 0000000..332801f
--- /dev/null
+++ b/test/SemaCXX/aggregate-init-cxx98.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++98 -verify %s
+
+struct A {
+  A() = default; // expected-warning {{C++11}}
+  int n;
+};
+A a = {0};
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
index b416963..7b6abd2 100644
--- a/test/SemaCXX/aggregate-initialization.cpp
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -4,8 +4,6 @@
 
 // Verify that using an initializer list for a non-aggregate looks for
 // constructors..
-// Note that due to a (likely) standard bug, this is technically an aggregate,
-// but we do not treat it as one.
 struct NonAggr1 { // expected-note 2 {{candidate constructor}}
   NonAggr1(int, int) { } // expected-note {{candidate constructor}}
 
diff --git a/test/SemaCXX/array-bounds.cpp b/test/SemaCXX/array-bounds.cpp
index 80b3ee4..8ae92e7 100644
--- a/test/SemaCXX/array-bounds.cpp
+++ b/test/SemaCXX/array-bounds.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify -std=c++11 %s
 
 int foo() {
   int x[2]; // expected-note 4 {{array 'x' declared here}}
@@ -253,3 +253,19 @@
 	int a[128]; // expected-note {{array 'a' declared here}}
 	a[(unsigned char)'\xA1'] = 1; // expected-warning {{array index 161 is past the end of the array}}
 }
+
+struct P {
+  int a;
+  int b;
+};
+
+void test_struct_array_index() {
+  struct P p[10]; // expected-note {{array 'p' declared here}}
+  p[11] = {0, 1}; // expected-warning {{array index 11 is past the end of the array (which contains 10 elements)}}
+}
+
+int operator+(const struct P &s1, const struct P &s2);
+int test_operator_overload_struct_array_index() {
+  struct P x[10] = {0}; // expected-note {{array 'x' declared here}}
+  return x[1] + x[11]; // expected-warning {{array index 11 is past the end of the array (which contains 10 elements)}}
+}
diff --git a/test/SemaCXX/attr-mode-tmpl.cpp b/test/SemaCXX/attr-mode-tmpl.cpp
index 4e1489a..d83bb39 100644
--- a/test/SemaCXX/attr-mode-tmpl.cpp
+++ b/test/SemaCXX/attr-mode-tmpl.cpp
@@ -45,7 +45,7 @@
 
 // Check attributes on function parameters.
 template <class T1, class T2>
-void CheckParameters(T1 __attribute__((mode(SI)))   paramSI,     // expected-note2{{ignored: substitution failure}}
+void CheckParameters(T1 __attribute__((mode(SI)))   paramSI,     // expected-note{{ignored: substitution failure}} expected-note-re{{not viable: no known conversion from '{{.*}}' (vector of 4 '{{.*}}' values) to 'EnumType' for 2nd argument}}
                      T1 __attribute__((mode(V4DI))) paramV4DI,   // expected-warning{{deprecated}}
                      T2 __attribute__((mode(SF)))   paramSF,
                      T2 __attribute__((mode(V4DF))) paramV4DF) { // expected-warning{{deprecated}}
diff --git a/test/SemaCXX/attr-noreturn.cpp b/test/SemaCXX/attr-noreturn.cpp
index a8e71db..24598e1 100644
--- a/test/SemaCXX/attr-noreturn.cpp
+++ b/test/SemaCXX/attr-noreturn.cpp
@@ -244,11 +244,11 @@
   template <typename T>
   void qux(T) {}
 
-  // expected-note@+5 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
-  // expected-note@+4 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
-  // expected-note@+3 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
-  // expected-note@+2 {{candidate function [with T = void (*)(int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
-  // expected-note@+1 {{candidate function [with T = void (int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
+  // expected-note@+5 {{candidate function not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
+  // expected-note@+4 {{candidate function not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
+  // expected-note@+3 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
+  // expected-note@+2 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
+  // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
   template <typename T> void accept_T(T) {}
 
   // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
@@ -265,13 +265,13 @@
   typedef void (*fptr_t)(int);
   typedef void __attribute__((noreturn)) (*fptr_noreturn_t)(int);
 
-  // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'fptr_t' (aka 'void (*)(int)') for 1st argument}}
+  // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'PR15291::fptr_t' (aka 'void (*)(int)') for 1st argument}}
   void accept_fptr_t(fptr_t f) {
     f(42);
   }
 
-  // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
-  // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
+  // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'PR15291::fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
+  // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'PR15291::fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
   void accept_fptr_noreturn_t(fptr_noreturn_t f) {
     f(42);
   }
diff --git a/test/SemaCXX/attr-require-constant-initialization.cpp b/test/SemaCXX/attr-require-constant-initialization.cpp
index 73f81cb..3ed5107 100644
--- a/test/SemaCXX/attr-require-constant-initialization.cpp
+++ b/test/SemaCXX/attr-require-constant-initialization.cpp
@@ -81,16 +81,16 @@
 void test_basic_start_static_2_1() {
   const int non_global = 42;
   ATTR static const int &local_init = non_global; // expected-error {{variable does not have a constant initializer}}
-  // expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+  // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
   ATTR static const int &global_init = glvalue_int;
   ATTR static const int &temp_init = 42;
 }
 
 ATTR const int &temp_ref = 42;
 ATTR const int &temp_ref2 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 ATTR const NonLit &nl_temp_ref = 42; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 
 #if __cplusplus >= 201103L
 ATTR const LitType &lit_temp_ref = 42;
@@ -98,7 +98,7 @@
 #endif
 
 ATTR const int &nl_subobj_ref = NonLit().value; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 
 struct TT1 {
   ATTR static const int &no_init;
@@ -107,7 +107,7 @@
   ATTR static const int &subobj_init;
 #if __cplusplus >= 201103L
   ATTR static thread_local const int &tl_glvalue_init;
-  ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
+  ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initialization' attribute here}}
 #endif
 };
 const int &TT1::glvalue_init = glvalue_int;
@@ -128,18 +128,18 @@
   ATTR static PODType pod;
 #else
   ATTR static PODType pod; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 #endif
   ATTR static PODType pot2 = {ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
-                                            // expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+                                            // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 
 #if __cplusplus >= 201103L
   constexpr LitType l;
   ATTR static LitType static_lit = l;
   ATTR static LitType static_lit2 = (void *)0; // expected-error {{variable does not have a constant initializer}}
-  // expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+  // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
   ATTR static LitType static_lit3 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
-  // expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+  // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
   ATTR thread_local LitType tls = 42;
 #endif
 }
@@ -147,14 +147,14 @@
 struct TT2 {
   ATTR static PODType pod_noinit;
 #if __cplusplus >= 201103L
-// expected-note@-2 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-2 {{required by 'require_constant_initialization' attribute here}}
 #endif
-  ATTR static PODType pod_copy_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
+  ATTR static PODType pod_copy_init; // expected-note {{required by 'require_constant_initialization' attribute here}}
 #if __cplusplus >= 201402L
   ATTR static constexpr LitType lit = {};
   ATTR static const NonLit non_lit;
   ATTR static const NonLit non_lit_list_init;
-  ATTR static const NonLit non_lit_copy_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
+  ATTR static const NonLit non_lit_copy_init; // expected-note {{required by 'require_constant_initialization' attribute here}}
 #endif
 };
 PODType TT2::pod_noinit;
@@ -182,20 +182,20 @@
 ATTR StoresNonLit snl;
 #else
 ATTR NonLit nl_ctor; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 ATTR NonLit nl_ctor2{}; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 ATTR NonLit nl_ctor3 = {}; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 ATTR thread_local NonLit nl_ctor_tl = {}; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 ATTR StoresNonLit snl; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 #endif
 
 // Non-literal types cannot appear in the initializer of a non-literal type.
 ATTR int nl_in_init = NonLit{42}.value; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 ATTR int lit_in_init = LitType{42}.value;
 #endif
 
@@ -217,7 +217,7 @@
 ATTR PODType pod_missing_init = {42 /* should have second arg */};
 ATTR PODType pod_full_init = {1, 2};
 ATTR PODType pod_non_constexpr_init = {1, ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 
 #if __cplusplus >= 201103L
 ATTR int val_init{};
@@ -241,7 +241,7 @@
   T value;
 };
 ATTR TestCtor<NotC> t(42); // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 #endif
 
 // Test various array types
@@ -260,10 +260,10 @@
 };
 
 ATTR LitType non_const_lit(nullptr); // expected-error {{variable does not have a constant initializer}}
-// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
 ATTR NonLit non_const(nullptr); // expected-error {{variable does not have a constant initializer}}
 // expected-warning@-1 {{declaration requires a global destructor}}
-// expected-note@-2 {{required by 'require_constant_initializer' attribute here}}
+// expected-note@-2 {{required by 'require_constant_initialization' attribute here}}
 LitType const_init_lit(nullptr);              // expected-warning {{declaration requires a global constructor}}
 NonLit const_init{42};                        // expected-warning {{declaration requires a global destructor}}
 constexpr TestCtor<NotC> inval_constexpr(42); // expected-error {{must be initialized by a constant expression}}
diff --git a/test/SemaCXX/auto-cxx0x.cpp b/test/SemaCXX/auto-cxx0x.cpp
index f3daf1a..074a01b 100644
--- a/test/SemaCXX/auto-cxx0x.cpp
+++ b/test/SemaCXX/auto-cxx0x.cpp
@@ -6,3 +6,12 @@
 }
 
 typedef auto PR25449(); // expected-error {{'auto' not allowed in typedef}}
+
+thread_local auto x; // expected-error {{requires an initializer}}
+
+void g() {
+  [](auto){}(0);
+#if __cplusplus == 201103L
+  // expected-error@-2 {{'auto' not allowed in lambda parameter}}
+#endif
+}
diff --git a/test/SemaCXX/builtins.cpp b/test/SemaCXX/builtins.cpp
index 69bdfa6..f26931b 100644
--- a/test/SemaCXX/builtins.cpp
+++ b/test/SemaCXX/builtins.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11 -fcxx-exceptions
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++1z -fcxx-exceptions
 typedef const struct __CFString * CFStringRef;
 #define CFSTR __builtin___CFStringMakeConstantString
 
@@ -44,3 +45,11 @@
   __noop(1); // expected-error {{use of undeclared}}
   __debugbreak(); // expected-error {{use of undeclared}}
 }
+
+struct FILE;
+extern "C" int vfprintf(FILE *__restrict, const char *__restrict,
+                        __builtin_va_list va);
+
+void synchronize_args() {
+  __sync_synchronize(0); // expected-error {{too many arguments}}
+}
diff --git a/test/SemaCXX/calling-conv-compat.cpp b/test/SemaCXX/calling-conv-compat.cpp
index 20d93b4..4c4cc15 100644
--- a/test/SemaCXX/calling-conv-compat.cpp
+++ b/test/SemaCXX/calling-conv-compat.cpp
@@ -179,31 +179,31 @@
 typedef void (__cdecl    C::*memb_c_cdecl)();
 typedef void (__thiscall C::*memb_c_thiscall)();
 
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_default' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'NonVariadic::memb_a_default' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}}
 void cb_memb_a_default(memb_a_default ptr);
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}}
 void cb_memb_a_cdecl(memb_a_cdecl ptr);
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_thiscall' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'NonVariadic::memb_a_thiscall' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}}
 void cb_memb_a_thiscall(memb_a_thiscall ptr);
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_default' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'NonVariadic::memb_b_default' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}}
 void cb_memb_b_default(memb_b_default ptr);
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}}
 void cb_memb_b_cdecl(memb_b_cdecl ptr);
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_thiscall' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'NonVariadic::memb_b_thiscall' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}}
 void cb_memb_b_thiscall(memb_b_thiscall ptr);
-// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'NonVariadic::memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
 void cb_memb_c_default(memb_c_default ptr);
-// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}}
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'NonVariadic::memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}}
 void cb_memb_c_cdecl(memb_c_cdecl ptr);
-// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'NonVariadic::memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'NonVariadic::memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
 void cb_memb_c_thiscall(memb_c_thiscall ptr);
 
 void call_member() {
@@ -270,11 +270,11 @@
 void cb_memb_a_cdecl(memb_a_cdecl ptr);
 void cb_memb_b_default(memb_b_default ptr);
 void cb_memb_b_cdecl(memb_b_cdecl ptr);
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'Variadic::memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'Variadic::memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}}
 void cb_memb_c_default(memb_c_default ptr);
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'Variadic::memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'Variadic::memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
 void cb_memb_c_cdecl(memb_c_cdecl ptr);
 
 void call_member() {
@@ -319,7 +319,7 @@
 }
 
 void (A::*(*return_fptr_std_mptr(char))(short))(int) {
-  return return_mptr_std; // expected-error {{cannot initialize return object of type 'void (MultiChunkDecls::A::*(*)(short))(int) __attribute__((thiscall))' with an lvalue of type 'mptr_t (short) __attribute__((stdcall))'}}
+  return return_mptr_std; // expected-error {{cannot initialize return object of type 'void (MultiChunkDecls::A::*(*)(short))(int) __attribute__((thiscall))' with an lvalue of type 'MultiChunkDecls::mptr_t (short) __attribute__((stdcall))'}}
 }
 
 void call_return() {
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 8ecf4a4..4abbc8e 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
+// RUN: %clang_cc1 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
 
 namespace StaticAssertFoldTest {
 
@@ -386,6 +386,18 @@
   constexpr init_list_2_init_list_3_ints ils = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } };
 }
 
+namespace ConstAddedByReference {
+  const int &r = (0);
+  constexpr int n = r;
+
+  struct A { constexpr operator int() const { return 0; }};
+  struct B { constexpr operator const int() const { return 0; }};
+  const int &ra = A();
+  const int &rb = B();
+  constexpr int na = ra;
+  constexpr int nb = rb;
+}
+
 }
 
 constexpr int strcmp_ce(const char *p, const char *q) {
@@ -554,6 +566,21 @@
 };
 static_assert(ArrayRVal().elems[3].f() == 0, "");
 
+namespace CopyCtor {
+  struct A {
+    constexpr A() {}
+    constexpr A(const A &) {}
+  };
+  struct B {
+    A a;
+    int arr[10];
+  };
+  constexpr B b{{}, {1, 2, 3, 4, 5}};
+  constexpr B c = b;
+  static_assert(c.arr[2] == 3, "");
+  static_assert(c.arr[7] == 0, "");
+}
+
 constexpr int selfref[2][2][2] = {
   selfref[1][1][1] + 1, selfref[0][0][0] + 1,
   selfref[1][0][1] + 1, selfref[0][1][0] + 1,
@@ -1156,7 +1183,7 @@
 constexpr int m2b = const_cast<const int&>(n2); // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}}
 
 struct T { int n; };
-const T t = { 42 }; // expected-note {{declared here}}
+const T t = { 42 };
 
 constexpr int f(volatile int &&r) {
   return r; // expected-note {{read of volatile-qualified type 'volatile int'}}
@@ -1168,7 +1195,7 @@
   int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}}
   int k : g(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'g(0)'}}
   int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}}
-  int m : t.n; // expected-error {{constant expression}} expected-note {{read of non-constexpr variable}}
+  int m : t.n; // expected-warning{{width of bit-field 'm' (42 bits)}} expected-warning{{expression is not an integral constant expression}} expected-note{{read of non-constexpr variable 't' is not allowed}}
 };
 
 }
@@ -1253,6 +1280,15 @@
     constexpr TestVar testVar{-1};
     static_assert(testVar.value == -1, "");
   }
+
+  namespace PR32034 {
+    struct A {};
+    struct B { _Atomic(A) a; };
+    constexpr int n = (B(), B(), 0);
+
+    struct C { constexpr C() {} void *self = this; };
+    constexpr _Atomic(C) c = C();
+  }
 }
 
 namespace InstantiateCaseStmt {
@@ -1276,7 +1312,7 @@
     eo = (m +
           n // expected-error {{not a constant expression}}
           ),
-    eq = reinterpret_cast<int>((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}}
+    eq = reinterpret_cast<long>((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}}
   };
 }
 
@@ -1393,8 +1429,8 @@
   // otherwise a constant expression.
   #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
 
-  constexpr int n = (int)(char*)123; // expected-error {{constant expression}} expected-note {{reinterpret_cast}}
-  constexpr int m = fold((int)(char*)123); // ok
+  constexpr int n = (long)(char*)123; // expected-error {{constant expression}} expected-note {{reinterpret_cast}}
+  constexpr int m = fold((long)(char*)123); // ok
   static_assert(m == 123, "");
 
   #undef fold
@@ -1698,7 +1734,7 @@
   constexpr int error() { // expected-error {{no return statement}}
     return foobar; // expected-error {{undeclared identifier}}
   }
-  constexpr int k = error(); // expected-error {{must be initialized by a constant expression}}
+  constexpr int k = error();
 }
 
 namespace std {
@@ -1875,9 +1911,9 @@
 namespace BadDefaultInit {
   template<int N> struct X { static const int n = N; };
 
-  struct A { // expected-error {{default member initializer for 'k' needed within definition of enclosing class}}
+  struct A {
     int k = // expected-note {{default member initializer declared here}}
-        X<A().k>::n; // expected-error {{not a constant expression}} expected-note {{implicit default constructor for 'BadDefaultInit::A' first required here}}
+        X<A().k>::n; // expected-error {{default member initializer for 'k' needed within definition of enclosing class}}
   };
 
   // FIXME: The "constexpr constructor must initialize all members" diagnostic
@@ -2003,7 +2039,7 @@
 
 namespace PR21859 {
   constexpr int Fun() { return; } // expected-error {{non-void constexpr function 'Fun' should return a value}}
-  constexpr int Var = Fun(); // expected-error {{constexpr variable 'Var' must be initialized by a constant expression}}
+  constexpr int Var = Fun();
 }
 
 struct InvalidRedef {
@@ -2109,3 +2145,17 @@
 
 } //end ns PR28366
 
+namespace PointerArithmeticOverflow {
+  int n;
+  int a[1];
+  constexpr int *b = &n + 1 + (long)-1;
+  constexpr int *c = &n + 1 + (unsigned long)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element 1844}}
+  constexpr int *d = &n + 1 - (unsigned long)1;
+  constexpr int *e = a + 1 + (long)-1;
+  constexpr int *f = a + 1 + (unsigned long)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element 1844}}
+  constexpr int *g = a + 1 - (unsigned long)1;
+
+  constexpr int *p = (&n + 1) + (unsigned __int128)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element 3402}}
+  constexpr int *q = (&n + 1) - (unsigned __int128)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element -3402}}
+  constexpr int *r = &(&n + 1)[(unsigned __int128)-1]; // expected-error {{constant expression}} expected-note {{cannot refer to element 3402}}
+}
diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp
index f810322..ac4e0fd 100644
--- a/test/SemaCXX/constant-expression-cxx1y.cpp
+++ b/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -957,3 +957,28 @@
   }
   static_assert(f(0) == 1, "");
 }
+
+namespace const_char {
+template <int N>
+constexpr int sum(const char (&Arr)[N]) {
+  int S = 0;
+  for (unsigned I = 0; I != N; ++I)
+    S += Arr[I]; // expected-note 2{{read of non-constexpr variable 'Cs' is not allowed}}
+  return S;
+}
+
+// As an extension, we support evaluating some things that are `const` as though
+// they were `constexpr` when folding, but it should not be allowed in normal
+// constexpr evaluation.
+const char Cs[] = {'a', 'b'};
+void foo() __attribute__((enable_if(sum(Cs) == 'a' + 'b', "")));
+void run() { foo(); }
+
+static_assert(sum(Cs) == 'a' + 'b', ""); // expected-error{{not an integral constant expression}} expected-note{{in call to 'sum(Cs)'}}
+constexpr int S = sum(Cs); // expected-error{{must be initialized by a constant expression}} expected-note{{in call}}
+}
+
+constexpr void PR28739(int n) { // expected-error {{never produces a constant}}
+  int *p = &n;
+  p += (__int128)(unsigned long)-1; // expected-note {{cannot refer to element 18446744073709551615 of non-array object in a constant expression}}
+}
diff --git a/test/SemaCXX/constant-expression-cxx1z.cpp b/test/SemaCXX/constant-expression-cxx1z.cpp
index a045234..a48c9b1 100644
--- a/test/SemaCXX/constant-expression-cxx1z.cpp
+++ b/test/SemaCXX/constant-expression-cxx1z.cpp
@@ -28,7 +28,9 @@
 
 namespace NoexceptFunctionTypes {
   template<typename T> constexpr bool f() noexcept(true) { return true; }
+  constexpr bool (*fp)() = f<int>;
   static_assert(f<int>());
+  static_assert(fp());
 
   template<typename T> struct A {
     constexpr bool f() noexcept(true) { return true; }
@@ -39,3 +41,8 @@
   static_assert(A<int>().g());
   static_assert(A<int>()());
 }
+
+namespace Cxx17CD_NB_GB19 {
+  const int &r = 0;
+  constexpr int n = r;
+}
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
index f82a692..69e846b 100644
--- a/test/SemaCXX/constant-expression.cpp
+++ b/test/SemaCXX/constant-expression.cpp
@@ -143,3 +143,14 @@
 }
 
 char PR17381_ice = 1000000 * 1000000; // expected-warning {{overflow}} expected-warning {{changes value}}
+
+namespace PR31701 {
+  struct C {
+    template<int i> static int n; // expected-warning {{extension}}
+  };
+  template <int M> class D;
+  template <int M>
+  template<int i> void D<M>::set() { // expected-error {{from class 'D<M>' without definition}}
+    const C c = C::n<i>;
+  }
+}
diff --git a/test/SemaCXX/constexpr-string.cpp b/test/SemaCXX/constexpr-string.cpp
index 944038b..fba05e5 100644
--- a/test/SemaCXX/constexpr-string.cpp
+++ b/test/SemaCXX/constexpr-string.cpp
@@ -166,6 +166,27 @@
   static_assert(__builtin_memchr(nullptr, 'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
   static_assert(__builtin_memchr(nullptr, 'x', 0) == nullptr); // FIXME: Should we reject this?
 
+  static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr);
+  static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr);
+  static_assert(__builtin_char_memchr(kStr, '\0', 5) == nullptr);
+  static_assert(__builtin_char_memchr(kStr, '\0', 6) == kStr + 5);
+  static_assert(__builtin_char_memchr(kStr, '\xff', 8) == kStr + 4);
+  static_assert(__builtin_char_memchr(kStr, '\xff' + 256, 8) == kStr + 4);
+  static_assert(__builtin_char_memchr(kStr, '\xff' - 256, 8) == kStr + 4);
+  static_assert(__builtin_char_memchr(kFoo, 'x', 3) == nullptr);
+  static_assert(__builtin_char_memchr(kFoo, 'x', 4) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+  static_assert(__builtin_char_memchr(nullptr, 'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
+  static_assert(__builtin_char_memchr(nullptr, 'x', 0) == nullptr); // FIXME: Should we reject this?
+
+  static_assert(*__builtin_char_memchr(kStr, '\xff', 8) == '\xff');
+  constexpr bool char_memchr_mutable() {
+    char buffer[] = "mutable";
+    *__builtin_char_memchr(buffer, 't', 8) = 'r';
+    *__builtin_char_memchr(buffer, 'm', 8) = 'd';
+    return __builtin_strcmp(buffer, "durable") == 0;
+  }
+  static_assert(char_memchr_mutable());
+
   constexpr bool a = !strchr("hello", 'h'); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strchr' cannot be used in a constant expression}}
   constexpr bool b = !memchr("hello", 'h', 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'memchr' cannot be used in a constant expression}}
 }
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index c725a0d..531de81 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -440,7 +440,7 @@
 #endif
   } a;
   A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}}
-  A::E e = a; // expected-note {{here}}
+  A::E e = a;
   bool k1 = e == A::e; // expected-error {{no member named 'e'}}
   bool k2 = e.n == 0;
 }
diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp
index 7b86cec..dcd64fa 100644
--- a/test/SemaCXX/conversion.cpp
+++ b/test/SemaCXX/conversion.cpp
@@ -50,7 +50,7 @@
 namespace test2 {
   struct A {
     unsigned int x : 2;
-    A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to 2}}
+    A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bit-field changes value from 10 to 2}}
   };
 }
 
diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp
index 798582c..d6ad657 100644
--- a/test/SemaCXX/copy-assignment.cpp
+++ b/test/SemaCXX/copy-assignment.cpp
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s 
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+#if __cplusplus >= 201103L
+// expected-note@+3 2 {{candidate constructor}}
+// expected-note@+2 {{passing argument to parameter here}}
+#endif
 struct A {
 };
 
@@ -7,6 +14,9 @@
 };
 
 struct ConvertibleToConstA {
+#if __cplusplus >= 201103L
+// expected-note@+2 {{candidate function}}
+#endif
   operator const A();
 };
 
@@ -69,6 +79,9 @@
   na = a;
   na = constA;
   na = convertibleToA;
+#if __cplusplus >= 201103L
+// expected-error@+2 {{no viable conversion}}
+#endif
   na = convertibleToConstA;
   na += a; // expected-error{{no viable overloaded '+='}}
 
diff --git a/test/SemaCXX/coreturn.cpp b/test/SemaCXX/coreturn.cpp
index 4c41ae9..2ec7391 100644
--- a/test/SemaCXX/coreturn.cpp
+++ b/test/SemaCXX/coreturn.cpp
@@ -1,23 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wno-unreachable-code -Wno-unused-value
 
-struct awaitable {
-  bool await_ready();
-  void await_suspend(); // FIXME: coroutine_handle
-  void await_resume();
-} a;
-
-struct suspend_always {
-  bool await_ready() { return false; }
-  void await_suspend() {}
-  void await_resume() {}
-};
-
-struct suspend_never {
-  bool await_ready() { return true; }
-  void await_suspend() {}
-  void await_resume() {}
-};
-
 namespace std {
 namespace experimental {
 
@@ -25,10 +7,37 @@
 struct coroutine_traits { using promise_type = typename Ret::promise_type; };
 
 template <class Promise = void>
-struct coroutine_handle {};
+struct coroutine_handle {
+  static coroutine_handle from_address(void *);
+};
+template <>
+struct coroutine_handle<void> {
+  template <class PromiseType>
+  coroutine_handle(coroutine_handle<PromiseType>);
+  static coroutine_handle from_address(void *);
+};
+
 }
 }
 
+struct awaitable {
+  bool await_ready();
+  void await_suspend(std::experimental::coroutine_handle<>); // FIXME: coroutine_handle
+  void await_resume();
+} a;
+
+struct suspend_always {
+  bool await_ready() { return false; }
+  void await_suspend(std::experimental::coroutine_handle<>) {}
+  void await_resume() {}
+};
+
+struct suspend_never {
+  bool await_ready() { return true; }
+  void await_suspend(std::experimental::coroutine_handle<>) {}
+  void await_resume() {}
+};
+
 struct promise_void {
   void get_return_object();
   suspend_always initial_suspend();
diff --git a/test/SemaCXX/coroutines.cpp b/test/SemaCXX/coroutines.cpp
index a22383c..8876a14 100644
--- a/test/SemaCXX/coroutines.cpp
+++ b/test/SemaCXX/coroutines.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s
+// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions
 
 void no_coroutine_traits_bad_arg_await() {
   co_await a; // expected-error {{include <experimental/coroutine>}}
@@ -16,35 +16,15 @@
   // expected-error@-1 {{use of undeclared identifier 'a'}}
 }
 
-
-struct awaitable {
-  bool await_ready();
-  void await_suspend(); // FIXME: coroutine_handle
-  void await_resume();
-} a;
-
-struct suspend_always {
-  bool await_ready() { return false; }
-  void await_suspend() {}
-  void await_resume() {}
-};
-
-struct suspend_never {
-  bool await_ready() { return true; }
-  void await_suspend() {}
-  void await_resume() {}
-};
-
 void no_coroutine_traits() {
-  co_await a; // expected-error {{need to include <experimental/coroutine>}}
+  co_await 4; // expected-error {{std::experimental::coroutine_traits type was not found; include <experimental/coroutine>}}
 }
 
 namespace std {
 namespace experimental {
 template <typename... T>
 struct coroutine_traits; // expected-note {{declared here}}
-}
-}
+}}  // namespace std::experimental
 
 template<typename Promise> struct coro {};
 template <typename Promise, typename... Ps>
@@ -52,6 +32,24 @@
   using promise_type = Promise;
 };
 
+struct awaitable {
+  bool await_ready();
+  template <typename F> void await_suspend(F);
+  void await_resume();
+} a;
+
+struct suspend_always {
+  bool await_ready() { return false; }
+  template <typename F> void await_suspend(F);
+  void await_resume() {}
+};
+
+struct suspend_never {
+  bool await_ready() { return true; }
+  template <typename F> void await_suspend(F);
+  void await_resume() {}
+};
+
 void no_specialization() {
   co_await a; // expected-error {{implicit instantiation of undefined template 'std::experimental::coroutine_traits<void>'}}
 }
@@ -59,25 +57,25 @@
 template <typename... T>
 struct std::experimental::coroutine_traits<int, T...> {};
 
-int no_promise_type() {
-  co_await a; // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<int>' has no member named 'promise_type'}}
+int no_promise_type() { // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<int>' has no member named 'promise_type'}}
+  co_await a;
 }
 
 template <>
 struct std::experimental::coroutine_traits<double, double> { typedef int promise_type; };
-double bad_promise_type(double) {
-  co_await a; // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}}
+double bad_promise_type(double) { // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}}
+  co_await a;
 }
 
 template <>
 struct std::experimental::coroutine_traits<double, int> {
   struct promise_type {};
 };
-double bad_promise_type_2(int) {
+double bad_promise_type_2(int) { // expected-error {{no member named 'initial_suspend'}}
   co_yield 0; // expected-error {{no member named 'yield_value' in 'std::experimental::coroutine_traits<double, int>::promise_type'}}
 }
 
-struct promise; // expected-note 2{{forward declaration}}
+struct promise; // expected-note {{forward declaration}}
 struct promise_void;
 struct void_tag {};
 template <typename... T>
@@ -86,17 +84,8 @@
 struct std::experimental::coroutine_traits<void, void_tag, T...>
 { using promise_type = promise_void; };
 
-namespace std {
-namespace experimental {
-template <typename Promise = void>
-struct coroutine_handle;
-}
-}
-
 // FIXME: This diagnostic is terrible.
-void undefined_promise() { // expected-error {{variable has incomplete type 'promise_type'}}
-  // FIXME: This diagnostic doesn't make any sense.
-  // expected-error@-2 {{incomplete definition of type 'promise'}}
+void undefined_promise() { // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits<void>::promise_type' (aka 'promise') is an incomplete type}}
   co_await a;
 }
 
@@ -121,6 +110,25 @@
   void return_void();
 };
 
+void no_coroutine_handle() { // expected-error {{std::experimental::coroutine_handle type was not found; include <experimental/coroutine> before defining a coroutine}}
+  //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
+  co_return 5; //expected-note {{function is a coroutine due to use of 'co_return' here}}
+}
+
+namespace std {
+namespace experimental {
+template <class PromiseType = void>
+struct coroutine_handle {
+  static coroutine_handle from_address(void *);
+};
+template <>
+struct coroutine_handle<void> {
+  template <class PromiseType>
+  coroutine_handle(coroutine_handle<PromiseType>);
+  static coroutine_handle from_address(void *);
+};
+}} // namespace std::experimental
+
 void yield() {
   co_yield 0;
   co_yield {"foo", 1, 2};
@@ -143,28 +151,108 @@
   co_return 42;
 }
 
+template <class T>
+void co_await_non_dependent_arg(T) {
+  co_await a;
+}
+template void co_await_non_dependent_arg(int);
+
 void mixed_yield() {
   co_yield 0; // expected-note {{use of 'co_yield'}}
   return; // expected-error {{not allowed in coroutine}}
 }
 
+void mixed_yield_invalid() {
+  co_yield blah; // expected-error {{use of undeclared identifier}}
+  // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
+  return; // expected-error {{return statement not allowed in coroutine}}
+}
+
+template <class T>
+void mixed_yield_template(T) {
+  co_yield blah; // expected-error {{use of undeclared identifier}}
+  // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
+  return; // expected-error {{return statement not allowed in coroutine}}
+}
+
+template <class T>
+void mixed_yield_template2(T) {
+  co_yield 42;
+  // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
+  return; // expected-error {{return statement not allowed in coroutine}}
+}
+
+template <class T>
+void mixed_yield_template3(T v) {
+  co_yield blah(v);
+  // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
+  return; // expected-error {{return statement not allowed in coroutine}}
+}
+
 void mixed_await() {
   co_await a; // expected-note {{use of 'co_await'}}
   return; // expected-error {{not allowed in coroutine}}
 }
 
+void mixed_await_invalid() {
+  co_await 42; // expected-error {{'int' is not a structure or union}}
+  // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
+  return; // expected-error {{not allowed in coroutine}}
+}
+
+template <class T>
+void mixed_await_template(T) {
+  co_await 42;
+  // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
+  return; // expected-error {{not allowed in coroutine}}
+}
+
+template <class T>
+void mixed_await_template2(T v) {
+  co_await v; // expected-error {{'long' is not a structure or union}}
+  // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
+  return; // expected-error {{not allowed in coroutine}}
+}
+template void mixed_await_template2(long); // expected-note {{requested here}}
+
 void only_coreturn(void_tag) {
-  co_return; // expected-warning {{'co_return' used in a function that uses neither 'co_await' nor 'co_yield'}}
+  co_return; // OK
 }
 
 void mixed_coreturn(void_tag, bool b) {
   if (b)
-    // expected-warning@+1 {{'co_return' used in a function that uses neither}}
     co_return; // expected-note {{use of 'co_return'}}
   else
     return; // expected-error {{not allowed in coroutine}}
 }
 
+void mixed_coreturn_invalid(bool b) {
+  if (b)
+    co_return; // expected-note {{use of 'co_return'}}
+    // expected-error@-1 {{no member named 'return_void' in 'promise'}}
+  else
+    return; // expected-error {{not allowed in coroutine}}
+}
+
+template <class T>
+void mixed_coreturn_template(void_tag, bool b, T v) {
+  if (b)
+    co_return v; // expected-note {{use of 'co_return'}}
+    // expected-error@-1 {{no member named 'return_value' in 'promise_void'}}
+  else
+    return; // expected-error {{not allowed in coroutine}}
+}
+template void mixed_coreturn_template(void_tag, bool, int); // expected-note {{requested here}}
+
+template <class T>
+void mixed_coreturn_template2(bool b, T) {
+  if (b)
+    co_return v; // expected-note {{use of 'co_return'}}
+    // expected-error@-1 {{use of undeclared identifier 'v'}}
+  else
+    return; // expected-error {{not allowed in coroutine}}
+}
+
 struct CtorDtor {
   CtorDtor() {
     co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}}
@@ -217,6 +305,13 @@
 }
 
 struct outer {};
+struct await_arg_1 {};
+struct await_arg_2 {};
+
+namespace adl_ns {
+struct coawait_arg_type {};
+awaitable operator co_await(coawait_arg_type);
+}
 
 namespace dependent_operator_co_await_lookup {
   template<typename T> void await_template(T t) {
@@ -239,6 +334,94 @@
   };
   template void await_template(outer); // expected-note {{instantiation}}
   template void await_template_2(outer);
+
+  struct transform_awaitable {};
+  struct transformed {};
+
+  struct transform_promise {
+    typedef transform_awaitable await_arg;
+    coro<transform_promise> get_return_object();
+    transformed initial_suspend();
+    ::adl_ns::coawait_arg_type final_suspend();
+    transformed await_transform(transform_awaitable);
+  };
+  template <class AwaitArg>
+  struct basic_promise {
+    typedef AwaitArg await_arg;
+    coro<basic_promise> get_return_object();
+    awaitable initial_suspend();
+    awaitable final_suspend();
+  };
+
+  awaitable operator co_await(await_arg_1);
+
+  template <typename T, typename U>
+  coro<T> await_template_3(U t) {
+    co_await t;
+  }
+
+  template coro<basic_promise<await_arg_1>> await_template_3<basic_promise<await_arg_1>>(await_arg_1);
+
+  template <class T, int I = 0>
+  struct dependent_member {
+    coro<T> mem_fn() const {
+      co_await typename T::await_arg{}; // expected-error {{call to function 'operator co_await'}}}
+    }
+    template <class U>
+    coro<T> dep_mem_fn(U t) {
+      co_await t;
+    }
+  };
+
+  template <>
+  struct dependent_member<long> {
+    // FIXME this diagnostic is terrible
+    coro<transform_promise> mem_fn() const { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
+      // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
+      // expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
+      co_await transform_awaitable{};
+      // expected-error@-1 {{no member named 'await_ready'}}
+    }
+    template <class R, class U>
+    coro<R> dep_mem_fn(U u) { co_await u; }
+  };
+
+  awaitable operator co_await(await_arg_2); // expected-note {{'operator co_await' should be declared prior to the call site}}
+
+  template struct dependent_member<basic_promise<await_arg_1>, 0>;
+  template struct dependent_member<basic_promise<await_arg_2>, 0>; // expected-note {{in instantiation}}
+
+  template <>
+  coro<transform_promise>
+      // FIXME this diagnostic is terrible
+      dependent_member<long>::dep_mem_fn<transform_promise>(int) { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
+    //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
+    //expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
+    co_await transform_awaitable{};
+    // expected-error@-1 {{no member named 'await_ready'}}
+  }
+
+  void operator co_await(transform_awaitable) = delete;
+  awaitable operator co_await(transformed);
+
+  template coro<transform_promise>
+      dependent_member<long>::dep_mem_fn<transform_promise>(transform_awaitable);
+
+  template <>
+  coro<transform_promise> dependent_member<long>::dep_mem_fn<transform_promise>(long) {
+    co_await transform_awaitable{};
+  }
+
+  template <>
+  struct dependent_member<int> {
+    coro<transform_promise> mem_fn() const {
+      co_await transform_awaitable{};
+    }
+  };
+
+  template coro<transform_promise> await_template_3<transform_promise>(transform_awaitable);
+  template struct dependent_member<transform_promise>;
+  template coro<transform_promise> dependent_member<transform_promise>::dep_mem_fn(transform_awaitable);
 }
 
 struct yield_fn_tag {};
@@ -294,6 +477,7 @@
   // FIXME: We shouldn't offer a typo-correction here!
   suspend_always final_suspend(); // expected-note {{here}}
 };
+// FIXME: This shouldn't happen twice
 coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}}
   co_await a;
 }
@@ -314,7 +498,8 @@
 };
 // FIXME: This diagnostic is terrible.
 coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
-  co_await a;
+  // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
+  co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
 }
 
 struct bad_promise_5 {
@@ -324,7 +509,8 @@
 };
 // FIXME: This diagnostic is terrible.
 coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
-  co_await a;
+  // expected-note@-1 {{call to 'final_suspend' implicitly required by the final suspend point}}
+  co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
 }
 
 struct bad_promise_6 {
@@ -355,23 +541,89 @@
 int *current_exception();
 }
 
-struct bad_promise_8 {
+struct bad_promise_base {
+private:
+  void return_void();
+};
+struct bad_promise_8 : bad_promise_base {
   coro<bad_promise_8> get_return_object();
   suspend_always initial_suspend();
   suspend_always final_suspend();
-  void return_void();
   void set_exception();                                   // expected-note {{function not viable}}
   void set_exception(int *) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
   void set_exception(void *);                             // expected-note {{candidate function}}
 };
 coro<bad_promise_8> calls_set_exception() {
   // expected-error@-1 {{call to unavailable member function 'set_exception'}}
+  // FIXME: also warn about private 'return_void' here. Even though building
+  // the call to set_exception has already failed.
   co_await a;
 }
 
+struct bad_promise_9 {
+  coro<bad_promise_9> get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  void await_transform(void *);                                // expected-note {{candidate}}
+  awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
+  void return_void();
+};
+coro<bad_promise_9> calls_await_transform() {
+  co_await 42; // expected-error {{call to unavailable member function 'await_transform'}}
+  // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
+}
+
+struct bad_promise_10 {
+  coro<bad_promise_10> get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  int await_transform;
+  void return_void();
+};
+coro<bad_promise_10> bad_coawait() {
+  // FIXME this diagnostic is terrible
+  co_await 42; // expected-error {{called object type 'int' is not a function or function pointer}}
+  // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
+}
+
+struct call_operator {
+  template <class... Args>
+  awaitable operator()(Args...) const { return a; }
+};
+void ret_void();
+struct good_promise_1 {
+  coro<good_promise_1> get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  static const call_operator await_transform;
+  using Fn = void (*)();
+  Fn return_void = ret_void;
+};
+const call_operator good_promise_1::await_transform;
+coro<good_promise_1> ok_static_coawait() {
+  // FIXME this diagnostic is terrible
+  co_await 42;
+}
+
 template<> struct std::experimental::coroutine_traits<int, int, const char**>
 { using promise_type = promise; };
 
 int main(int, const char**) {
   co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}}
 }
+
+struct good_promise_2 {
+  float get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  void return_void();
+};
+template<> struct std::experimental::coroutine_handle<good_promise_2> {};
+
+template<> struct std::experimental::coroutine_traits<float>
+{ using promise_type = good_promise_2; };
+
+float badly_specialized_coro_handle() { // expected-error {{std::experimental::coroutine_handle missing a member named 'from_address'}}
+  //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
+  co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
+}
diff --git a/test/SemaCXX/cxx0x-class.cpp b/test/SemaCXX/cxx0x-class.cpp
index 2b1338f..c0e80da 100644
--- a/test/SemaCXX/cxx0x-class.cpp
+++ b/test/SemaCXX/cxx0x-class.cpp
@@ -37,3 +37,19 @@
     int y = x;
   };
 }
+
+// Instantiating another default member initializer while parsing one should
+// not cause us to mess up the 'this' override.
+template<typename> struct DefaultMemberTemplate { int n = 0; };
+class DefaultMemberInitSelf {
+  DefaultMemberTemplate<int> t = {};
+  int *p = &t.n;
+};
+
+namespace composed_templates {
+  // Regression test -- obtaining the type from composed templates should not
+  // require out-of-line definition.
+  template <typename T> struct Zero { static const typename T::type value = 0; };
+  struct Integer { using type = int; };
+  template struct Zero<Integer>;
+}
diff --git a/test/SemaCXX/cxx0x-initializer-aggregates.cpp b/test/SemaCXX/cxx0x-initializer-aggregates.cpp
index 1b01a35..7a7b92b 100644
--- a/test/SemaCXX/cxx0x-initializer-aggregates.cpp
+++ b/test/SemaCXX/cxx0x-initializer-aggregates.cpp
@@ -127,7 +127,7 @@
 
 namespace array_addressof {
   using T = int[5];
-  T *p = &T{1,2,3,4,5}; // expected-error {{taking the address of a temporary object of type 'T' (aka 'int [5]')}}
+  T *p = &T{1,2,3,4,5}; // expected-error {{taking the address of a temporary object of type 'array_addressof::T' (aka 'int [5]')}}
 }
 
 namespace PR24816 {
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 060a0f2..9b8fadd 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -103,6 +103,13 @@
 template <typename T>
 T deduce_ref(const std::initializer_list<T>&); // expected-note {{conflicting types for parameter 'T' ('int' vs. 'double')}}
 
+template<typename T, typename U> struct pair { pair(...); };
+template<typename T> void deduce_pairs(std::initializer_list<pair<T, typename T::type>>);
+// expected-note@-1 {{deduced type 'pair<[...], typename WithIntType::type>' of element of 1st parameter does not match adjusted type 'pair<[...], float>' of element of argument [with T = WithIntType]}}
+struct WithIntType { typedef int type; };
+
+template<typename ...T> void deduce_after_init_list_in_pack(void (*)(T...), T...); // expected-note {{<int, int> vs. <(no value), double>}}
+
 void argument_deduction() {
   static_assert(same_type<decltype(deduce({1, 2, 3})), int>::value, "bad deduction");
   static_assert(same_type<decltype(deduce({1.0, 2.0, 3.0})), double>::value, "bad deduction");
@@ -113,6 +120,14 @@
   static_assert(same_type<decltype(deduce_ref({1.0, 2.0, 3.0})), double>::value, "bad deduction");
 
   deduce_ref({1, 2.0}); // expected-error {{no matching function}}
+
+  pair<WithIntType, int> pi;
+  pair<WithIntType, float> pf;
+  deduce_pairs({pi, pi, pi}); // ok
+  deduce_pairs({pi, pf, pi}); // expected-error {{no matching function}}
+
+  deduce_after_init_list_in_pack((void(*)(int,int))0, {}, 0);
+  deduce_after_init_list_in_pack((void(*)(int,int))0, {}, 0.0); // expected-error {{no matching function}}
 }
 
 void auto_deduction() {
@@ -206,10 +221,14 @@
 namespace init_list_deduction_failure {
   void f();
   void f(int);
+  // FIXME: It'd be nice to track that 'T' became a non-deduced context due to
+  // overload resolution failure for 'f'.
   template<typename T> void g(std::initializer_list<T>);
-  // expected-note@-1 {{candidate template ignored: couldn't resolve reference to overloaded function 'f'}}
-  void h() { g({f}); }
-  // expected-error@-1 {{no matching function for call to 'g'}}
+  // expected-note@-1 {{candidate template ignored: couldn't infer template argument 'T'}}
+  void h() {
+    g({f}); // expected-error {{no matching function for call to 'g'}}
+    g({f, h}); // ok
+  }
 }
 
 namespace deleted_copy {
@@ -280,9 +299,18 @@
 
 namespace ParameterPackNestedInitializerLists_PR23904c3 {
   template <typename ...T>
-  void f(std::initializer_list<std::initializer_list<T>> ...tt);
+  void f(std::initializer_list<std::initializer_list<T>> ...tt); // expected-note 2{{conflicting}} expected-note {{incomplete pack}}
 
-  void foo() { f({{0}}, {{'\0'}}); }
+  void foo() {
+    f({{0}}, {{'\0'}}); // ok, T = <int, char>
+    f({{0}, {'\0'}}); // expected-error {{no match}}
+    f({{0, '\0'}}); // expected-error {{no match}}
+
+    f({{0}}, {{{}}}); // expected-error {{no match}}
+    f({{0}}, {{{}, '\0'}}); // ok, T = <int, char>
+    f({{0}, {{}}}); // ok, T = <int>
+    f({{0, {}}}); // ok, T = <int>
+  }
 }
 
 namespace update_rbrace_loc_crash {
@@ -309,3 +337,13 @@
     Explode<ContainsIncomplete, 4>([](int) {});
   }
 }
+
+namespace no_conversion_after_auto_list_deduction {
+  // We used to deduce 'auto' == 'std::initializer_list<X>' here, and then
+  // incorrectly accept the declaration of 'x'.
+  struct X { using T = std::initializer_list<X> X::*; operator T(); };
+  auto X::*x = { X() }; // expected-error {{from initializer list}}
+
+  struct Y { using T = std::initializer_list<Y>(*)(); operator T(); };
+  auto (*y)() = { Y() }; // expected-error {{from initializer list}}
+}
diff --git a/test/SemaCXX/cxx11-default-member-initializers.cpp b/test/SemaCXX/cxx11-default-member-initializers.cpp
new file mode 100644
index 0000000..9353e63
--- /dev/null
+++ b/test/SemaCXX/cxx11-default-member-initializers.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -pedantic
+
+namespace PR31692 {
+  struct A {
+    struct X { int n = 0; } x;
+    // Trigger construction of X() from a SFINAE context. This must not mark
+    // any part of X as invalid.
+    static_assert(!__is_constructible(X), "");
+    // Check that X::n is not marked invalid.
+    double &r = x.n; // expected-error {{non-const lvalue reference to type 'double' cannot bind to a value of unrelated type 'int'}}
+  };
+  // A::X can now be default-constructed.
+  static_assert(__is_constructible(A::X), "");
+}
diff --git a/test/SemaCXX/cxx11-inheriting-ctors.cpp b/test/SemaCXX/cxx11-inheriting-ctors.cpp
index 5ce8d1a..7d6f4f0 100644
--- a/test/SemaCXX/cxx11-inheriting-ctors.cpp
+++ b/test/SemaCXX/cxx11-inheriting-ctors.cpp
@@ -56,9 +56,9 @@
 }
 
 namespace ExplicitConv {
-  struct B {}; // expected-note 2{{candidate}}
+  struct B {};
   struct D : B { // expected-note 3{{candidate}}
-    using B::B; // expected-note 2{{inherited}}
+    using B::B;
   };
   struct X { explicit operator B(); } x;
   struct Y { explicit operator D(); } y;
@@ -68,19 +68,68 @@
 }
 
 namespace NestedListInit {
-  struct B { B(); } b; // expected-note 5{{candidate}}
-  struct D : B { // expected-note 3{{candidate}}
-    using B::B; // expected-note 2{{inherited}}
+  struct B { B(); } b; // expected-note 3{{candidate}}
+  struct D : B { // expected-note 14{{not viable}}
+    using B::B;
   };
   // This is a bit weird. We're allowed one pair of braces for overload
   // resolution, and one more pair of braces due to [over.ics.list]/2.
   B b1 = {b};
   B b2 = {{b}};
   B b3 = {{{b}}}; // expected-error {{no match}}
-  // This is the same, but we get one call to D's version of B::B(const B&)
-  // before the two permitted calls to D::D(D&&).
-  D d1 = {b};
-  D d2 = {{b}};
-  D d3 = {{{b}}};
+  // Per a proposed defect resolution, we don't get to call
+  // D's version of B::B(const B&) here.
+  D d0 = b; // expected-error {{no viable conversion}}
+  D d1 = {b}; // expected-error {{no match}}
+  D d2 = {{b}}; // expected-error {{no match}}
+  D d3 = {{{b}}}; // expected-error {{no match}}
   D d4 = {{{{b}}}}; // expected-error {{no match}}
 }
+
+namespace PR31606 {
+  // PR31606: as part of a proposed defect resolution, do not consider
+  // inherited constructors that would be copy constructors for any class
+  // between the declaring class and the constructed class (inclusive).
+  struct Base {};
+
+  struct A : Base {
+    using Base::Base;
+    bool operator==(A const &) const; // expected-note {{no known conversion from 'PR31606::B' to 'const PR31606::A' for 1st argument}}
+  };
+
+  struct B : Base {
+    using Base::Base;
+  };
+
+  bool a = A{} == A{};
+  // Note, we do *not* allow operator=='s argument to use the inherited A::A(Base&&) constructor to construct from B{}.
+  bool b = A{} == B{}; // expected-error {{invalid operands}}
+}
+
+namespace implicit_member_srcloc {
+  template<class T>
+  struct S3 {
+  };
+
+  template<class T>
+  struct S2 {
+    S2(S3<T> &&);
+  };
+
+  template<class T>
+  struct S1 : S2<T> {
+    using S2<T>::S2;
+    S1();
+  };
+
+  template<class T>
+  struct S0 {
+    S0();
+    S0(S0&&) = default;
+    S1<T> m1;
+  };
+
+  void foo1() {
+    S0<int> s0;
+  }
+}
diff --git a/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp b/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
index 58bbbb2..c7e6074 100644
--- a/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
+++ b/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
@@ -172,6 +172,6 @@
 #ifdef CXX1Y
 #else
 //expected-error@168 {{ambiguous conversion of array size expression of type 'extended_examples_array_bounds::Foo' to an integral or enumeration type}}
-//expected-note@162 {{conversion to integral type 'size_t'}}
+//expected-note@162 {{conversion to integral type 'extended_examples_array_bounds::size_t'}}
 //expected-note@163 {{conversion to integral type 'unsigned short' declared here}}
 #endif
diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp
index 593ec48..bfe0ab9 100644
--- a/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -314,7 +314,7 @@
 }
 
 namespace UseBeforeComplete {
-  auto n = n; // expected-error {{variable 'n' declared with 'auto' type cannot appear in its own initializer}}
+  auto n = n; // expected-error {{variable 'n' declared with deduced type 'auto' cannot appear in its own initializer}}
   auto f(); // expected-note {{declared here}}
   void g() { &f; } // expected-error {{function 'f' with deduced return type cannot be used before it is defined}}
   auto sum(int i) {
@@ -385,6 +385,33 @@
 }
 }
 
+// We resolve a wording bug here: 'decltype(auto)' should not be modeled as a
+// decltype-specifier, just as a simple-type-specifier. All the extra places
+// where a decltype-specifier can appear make no sense for 'decltype(auto)'.
+namespace DecltypeAutoShouldNotBeADecltypeSpecifier {
+  namespace NNS {
+    int n;
+    decltype(auto) i();
+    decltype(n) j();
+    struct X {
+      friend decltype(auto) ::DecltypeAutoShouldNotBeADecltypeSpecifier::NNS::i();
+      friend decltype(n) ::DecltypeAutoShouldNotBeADecltypeSpecifier::NNS::j(); // expected-error {{not a class}}
+    };
+  }
+
+  namespace Dtor {
+    struct A {};
+    void f(A a) { a.~decltype(auto)(); } // expected-error {{'decltype(auto)' not allowed here}}
+  }
+
+  namespace BaseClass {
+    struct A : decltype(auto) {}; // expected-error {{'decltype(auto)' not allowed here}}
+    struct B {
+      B() : decltype(auto)() {} // expected-error {{'decltype(auto)' not allowed here}}
+    };
+  }
+}
+
 namespace CurrentInstantiation {
   // PR16875
   template<typename T> struct S {
diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp
index 3774e8d..1993c6e 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -912,7 +912,7 @@
 template<class T> 
 template<class U>
 int X1::X2<T>::fooG3(T (*fp)(U)) { return 0; } 
-X1::X2<int> x2; //expected-note 3{{in instantiation of}}
+X1::X2<int> x2; //expected-note {{in instantiation of}}
 int run1 = x2.fooG2();
 int run2 = x2.fooG3();
 } // end ns
diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index 76f1bb9..66f0f10 100644
--- a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -17,8 +17,7 @@
   template<typename T> CONST float right<float,T> = 5;  // expected-error {{member 'right' declared as a template}}
   template<> static CONST int right<int,int> = 7;       // expected-error {{explicit specialization of 'right' in class scope}}
   template<> static CONST float right<float,int>;       // expected-error {{explicit specialization of 'right' in class scope}}
-  template static CONST int right<int,int>;     // expected-error {{template specialization requires 'template<>'}} \
-                                                // expected-error {{explicit specialization of 'right' in class scope}}
+  template static CONST int right<int,int>;     // expected-error {{expected '<' after 'template'}}
 };
 
 namespace out_of_line {
@@ -166,8 +165,7 @@
     template<typename T> constexpr float right<float,T> = 5;  // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}}
     template<> static constexpr int right<int,int> = 7;       // expected-error {{explicit specialization of 'right' in class scope}}
     template<> static constexpr float right<float,int>;       // expected-error {{explicit specialization of 'right' in class scope}}
-    template static constexpr int right<int,int>;     // expected-error {{template specialization requires 'template<>'}} \
-                                                  // expected-error {{explicit specialization of 'right' in class scope}}
+    template static constexpr int right<int,int>;     // expected-error {{expected '<' after 'template'}}
   };
 }
 #endif
diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index ec3e2b6..b496364 100644
--- a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -102,7 +102,7 @@
     template<typename T> extern int v;    // expected-error {{redeclaration of 'v' with a different type: 'int' vs 'T'}}
 
 #ifndef PRECXX11
-    template<typename T> extern auto v;   // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
+    template<typename T> extern auto v;   // expected-error {{declaration of variable 'v' with deduced type 'auto' requires an initializer}}
 #endif
 
     template<typename T> T var = T();     // expected-note {{previous definition is here}}
@@ -111,7 +111,7 @@
 
 #ifndef PRECXX11
   namespace pvt_auto {
-    template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}}
+    template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with deduced type 'auto' requires an initializer}}
     template<typename T> auto v1 = T();  // expected-note {{previous definition is here}}
     template<typename T> int v1;   // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
     template<typename T> auto v2 = T();  // expected-note {{previous definition is here}}
@@ -119,7 +119,7 @@
     template<typename T> auto v3 = T();   // expected-note {{previous definition is here}}
     template<typename T> extern T v3;     // expected-error {{redeclaration of 'v3' with a different type: 'T' vs 'auto'}}
     template<typename T> auto v4 = T();
-    template<typename T> extern auto v4;   // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}}
+    template<typename T> extern auto v4;   // expected-error {{declaration of variable 'v4' with deduced type 'auto' requires an initializer}}
   }
 #endif
   
@@ -464,3 +464,8 @@
 auto variadic1 = Variadic<>;
 auto variadic2 = Variadic<int, int>;
 #endif
+
+namespace VexingParse {
+  template <typename> int var; // expected-note {{declared here}}
+  int x(var); // expected-error {{cannot refer to variable template 'var' without a template argument list}}
+}
diff --git a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
new file mode 100644
index 0000000..5eee34e
--- /dev/null
+++ b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -0,0 +1,221 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+namespace std {
+  using size_t = decltype(sizeof(0));
+  template<typename T> struct initializer_list {
+    const T *p;
+    size_t n;
+    initializer_list();
+  };
+  // FIXME: This should probably not be necessary.
+  template<typename T> initializer_list(initializer_list<T>) -> initializer_list<T>;
+}
+
+template<typename T> constexpr bool has_type(...) { return false; }
+template<typename T> constexpr bool has_type(T) { return true; }
+
+std::initializer_list il = {1, 2, 3, 4, 5};
+
+template<typename T> struct vector {
+  template<typename Iter> vector(Iter, Iter);
+  vector(std::initializer_list<T>);
+};
+
+template<typename T> vector(std::initializer_list<T>) -> vector<T>;
+template<typename Iter> explicit vector(Iter, Iter) -> vector<typename Iter::value_type>;
+template<typename T> explicit vector(std::size_t, T) -> vector<T>;
+
+vector v1 = {1, 2, 3, 4};
+static_assert(has_type<vector<int>>(v1));
+
+struct iter { typedef char value_type; } it, end;
+vector v2(it, end);
+static_assert(has_type<vector<char>>(v2));
+
+vector v3(5, 5);
+static_assert(has_type<vector<int>>(v3));
+
+vector v4 = {it, end};
+static_assert(has_type<vector<iter>>(v4));
+
+vector v5{it, end};
+static_assert(has_type<vector<iter>>(v5));
+
+template<typename ...T> struct tuple { tuple(T...); };
+template<typename ...T> explicit tuple(T ...t) -> tuple<T...>; // expected-note {{declared}}
+// FIXME: Remove
+template<typename ...T> tuple(tuple<T...>) -> tuple<T...>;
+
+const int n = 4;
+tuple ta = tuple{1, 'a', "foo", n};
+static_assert(has_type<tuple<int, char, const char*, int>>(ta));
+
+tuple tb{ta};
+static_assert(has_type<tuple<int, char, const char*, int>>(tb));
+
+// FIXME: This should be tuple<tuple<...>>; when the above guide is removed.
+tuple tc = {ta};
+static_assert(has_type<tuple<int, char, const char*, int>>(tc));
+
+tuple td = {1, 2, 3}; // expected-error {{selected an explicit deduction guide}}
+static_assert(has_type<tuple<int, char, const char*, int>>(td));
+
+// FIXME: This is a GCC extension for now; if CWG don't allow this, at least
+// add a warning for it.
+namespace new_expr {
+  tuple<int> *p = new tuple{0};
+  tuple<float, float> *q = new tuple(1.0f, 2.0f);
+}
+
+namespace ambiguity {
+  template<typename T> struct A {};
+  A(unsigned short) -> A<int>; // expected-note {{candidate}}
+  A(short) -> A<int>; // expected-note {{candidate}}
+  A a = 0; // expected-error {{ambiguous deduction for template arguments of 'A'}}
+
+  template<typename T> struct B {};
+  template<typename T> B(T(&)(int)) -> B<int>; // expected-note {{candidate function [with T = int]}}
+  template<typename T> B(int(&)(T)) -> B<int>; // expected-note {{candidate function [with T = int]}}
+  int f(int);
+  B b = f; // expected-error {{ambiguous deduction for template arguments of 'B'}}
+}
+
+// FIXME: Revisit this once CWG decides if attributes, and [[deprecated]] in
+// particular, should be permitted here.
+namespace deprecated {
+  template<typename T> struct A { A(int); };
+  [[deprecated]] A(int) -> A<void>; // expected-note {{marked deprecated here}}
+  A a = 0; // expected-warning {{'<deduction guide for A>' is deprecated}}
+}
+
+namespace dependent {
+  template<template<typename...> typename A> decltype(auto) a = A{1, 2, 3};
+  static_assert(has_type<vector<int>>(a<vector>));
+  static_assert(has_type<tuple<int, int, int>>(a<tuple>));
+
+  struct B {
+    template<typename T> struct X { X(T); };
+    X(int) -> X<int>;
+    template<typename T> using Y = X<T>; // expected-note {{template}}
+  };
+  template<typename T> void f() {
+    typename T::X tx = 0;
+    typename T::Y ty = 0; // expected-error {{alias template 'Y' requires template arguments; argument deduction only allowed for class templates}}
+  }
+  template void f<B>(); // expected-note {{in instantiation of}}
+
+  template<typename T> struct C { C(T); };
+  template<typename T> C(T) -> C<T>;
+  template<typename T> void g(T a) {
+    C b = 0;
+    C c = a;
+    using U = decltype(b); // expected-note {{previous}}
+    using U = decltype(c); // expected-error {{different types ('C<const char *>' vs 'C<int>')}}
+  }
+  void h() {
+    g(0);
+    g("foo"); // expected-note {{instantiation of}}
+  }
+}
+
+namespace look_into_current_instantiation {
+  template<typename U> struct Q {};
+  template<typename T> struct A {
+    using U = T;
+    template<typename> using V = Q<A<T>::U>;
+    template<typename W = int> A(V<W>);
+  };
+  A a = Q<float>(); // ok, can look through class-scope typedefs and alias
+                    // templates, and members of the current instantiation
+  A<float> &r = a;
+
+  template<typename T> struct B { // expected-note {{could not match 'B<T>' against 'int'}}
+    struct X {
+      typedef T type;
+    };
+    B(typename X::type); // expected-note {{couldn't infer template argument 'T'}}
+  };
+  B b = 0; // expected-error {{no viable}}
+
+  // We should have a substitution failure in the immediate context of
+  // deduction when using the C(T, U) constructor (probably; core wording
+  // unclear).
+  template<typename T> struct C {
+    using U = typename T::type;
+    C(T, U);
+  };
+
+  struct R { R(int); typedef R type; };
+  C(...) -> C<R>;
+
+  C c = {1, 2};
+}
+
+namespace nondeducible {
+  template<typename A, typename B> struct X {};
+
+  template<typename A> // expected-note {{non-deducible template parameter 'A'}}
+  X() -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
+
+  template<typename A> // expected-note {{non-deducible template parameter 'A'}}
+  X(typename X<A, int>::type) -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
+
+  template<typename A = int,
+           typename B> // expected-note {{non-deducible template parameter 'B'}}
+  X(int) -> X<A, B>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
+
+  template<typename A = int,
+           typename ...B>
+  X(float) -> X<A, B...>; // ok
+}
+
+namespace default_args_from_ctor {
+  template <class A> struct S { S(A = 0) {} };
+  S s(0);
+
+  template <class A> struct T { template<typename B> T(A = 0, B = 0) {} };
+  T t(0, 0);
+}
+
+namespace transform_params {
+  template<typename T, T N, template<T (*v)[N]> typename U, T (*X)[N]>
+  struct A { // expected-note 2{{candidate}}
+    template<typename V, V M, V (*Y)[M], template<V (*v)[M]> typename W>
+    A(U<X>, W<Y>); // expected-note {{[with V = int, M = 12, Y = &transform_params::n]}}
+
+    static constexpr T v = N;
+  };
+
+  int n[12];
+  template<int (*)[12]> struct Q {};
+  Q<&n> qn;
+  // FIXME: The class template argument deduction result here is correct, but
+  // we incorrectly fail to deduce arguments for the constructor!
+  A a(qn, qn); // expected-error {{no matching constructor for initialization of 'transform_params::A<int, 12, Q, &transform_params::n>'}}
+  static_assert(a.v == 12);
+
+  template<typename ...T> struct B {
+    template<T ...V> B(const T (&...p)[V]) {
+      constexpr int Vs[] = {V...};
+      static_assert(Vs[0] == 3 && Vs[1] == 4 && Vs[2] == 4);
+    }
+    static constexpr int (*p)(T...) = (int(*)(int, char, char))nullptr;
+  };
+  B b({1, 2, 3}, "foo", {'x', 'y', 'z', 'w'}); // ok
+
+  // This should be accepted once -std=c++1z implies
+  // -frelaxed-template-template-args. Without that, a template template
+  // parameter 'template<int, int, int> typename' cannot bind to a template
+  // template argument 'template<int...> typename'.
+  template<typename ...T> struct C { // expected-note {{candidate}}
+    template<T ...V, template<T...> typename X>
+      C(X<V...>); // expected-note {{substitution failure [with T = <int, int, int>, V = <0, 1, 2>]}}
+  };
+  template<int...> struct Y {};
+  C c(Y<0, 1, 2>{}); // expected-error {{no viable constructor or deduction guide}}
+
+  template<typename ...T> struct D {
+    template<T ...V> D(Y<V...>);
+  };
+  D d(Y<0, 1, 2>{});
+}
diff --git a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp b/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
index 90a0766..4a98a1b 100644
--- a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ b/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s 
-// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -fcxx-exceptions
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions
+// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions
 
 
 namespace test_lambda_is_literal {
@@ -59,4 +59,215 @@
 }
 
 }
+
+namespace test_conversion_function_for_non_capturing_lambdas {
+
+namespace ns1 {
+auto L = [](int i) { return i; };
+constexpr int (*fpi)(int) = L;
+static_assert(fpi(3) == 3);
+auto GL = [](auto a) { return a; };
+
+constexpr char (*fp2)(char) = GL;
+constexpr double (*fp3)(double) = GL;
+constexpr const char* (*fp4)(const char*) = GL;
+static_assert(fp2('3') == '3');
+static_assert(fp3(3.14) == 3.14);
+constexpr const char *Str = "abc";
+static_assert(fp4(Str) == Str);
+
+auto NCL = [](int i) { static int j; return j; }; //expected-note{{declared here}}
+constexpr int (*fp5)(int) = NCL;
+constexpr int I =  //expected-error{{must be initialized by a constant expression}}
+                  fp5(5); //expected-note{{non-constexpr function}} 
+
+namespace test_dont_always_instantiate_constexpr_templates {
+
+auto explicit_return_type = [](auto x) -> int { return x.get(); };
+decltype(explicit_return_type(0)) c;  // OK
+
+auto deduced_return_type = [](auto x) { return x.get(); }; //expected-error{{not a structure or union}}
+decltype(deduced_return_type(0)) d;  //expected-note{{requested here}}
+
+
+  
+} // end ns test_dont_always_instantiate_constexpr_templates
+} // end ns1
+
+} // end ns test_conversion_function_for_non_capturing_lambdas
+
+namespace test_lambda_is_cce {
+namespace ns1_simple_lambda {
+
+namespace ns0 {
+constexpr int I = [](auto a) { return a; }(10);
+
+static_assert(I == 10); 
+static_assert(10 == [](auto a) { return a; }(10));
+static_assert(3.14 == [](auto a) { return a; }(3.14));
+
+} //end ns0
+
+namespace ns1 {
+constexpr auto f(int i) {
+  double d = 3.14;
+  auto L = [=](auto a) { 
+    int Isz = sizeof(i);
+    return sizeof(i) + sizeof(a) + sizeof(d); 
+  };
+  int I = L("abc") + L(nullptr);
+  return L;
+}
+constexpr auto L = f(3);
+constexpr auto M =  L("abc") + L(nullptr);
+
+static_assert(M == sizeof(int) * 2 + sizeof(double) * 2 + sizeof(nullptr) + sizeof(const char*));
+
+} // end ns1
+
+namespace ns2 {
+constexpr auto f(int i) {
+  auto L = [](auto a) { return a + a; };
+  return L;
+}
+constexpr auto L = f(3);
+constexpr int I = L(6);
+static_assert(I == 12);
+} // end ns2
+
+namespace contained_lambdas_call_operator_is_not_constexpr {
+constexpr auto f(int i) {
+  double d = 3.14;
+  auto L = [=](auto a) { //expected-note{{declared here}}
+    int Isz = sizeof(i);
+    asm("hello");
+    return sizeof(i) + sizeof(a) + sizeof(d); 
+  };
+  return L;
+}
+
+constexpr auto L = f(3);
+
+constexpr auto M =  // expected-error{{must be initialized by}} 
+    L("abc"); //expected-note{{non-constexpr function}}
+
+} // end ns contained_lambdas_call_operator_is_not_constexpr
+
+
+
+} // end ns1_simple_lambda
+
+namespace test_captures_1 {
+namespace ns1 {
+constexpr auto f(int i) {
+  struct S { int x; } s = { i * 2 };
+  auto L = [=](auto a) { 
+    return i + s.x + a;
+  };
+  return L;
+}
+constexpr auto M = f(3);  
+
+static_assert(M(10) == 19);
+
+} // end test_captures_1::ns1
+
+namespace ns2 {
+
+constexpr auto foo(int n) {
+  auto L = [i = n] (auto N) mutable {
+    if (!N(i)) throw "error";
+    return [&i] {
+      return ++i;
+    };
+  };
+  auto M = L([n](int p) { return p == n; });
+  M(); M();
+  L([n](int p) { return p == n + 2; });
+  
+  return L;
+}
+
+constexpr auto L = foo(3);
+
+} // end test_captures_1::ns2
+namespace ns3 {
+
+constexpr auto foo(int n) {
+  auto L = [i = n] (auto N) mutable {
+    if (!N(i)) throw "error";
+    return [&i] {
+      return [i]() mutable {
+        return ++i;
+      };
+    };
+  };
+  auto M = L([n](int p) { return p == n; });
+  M()(); M()();
+  L([n](int p) { return p == n; });
+  
+  return L;
+}
+
+constexpr auto L = foo(3);
+} // end test_captures_1::ns3
+
+namespace ns2_capture_this_byval {
+struct S {
+  int s;
+  constexpr S(int s) : s{s} { }
+  constexpr auto f(S o) {
+    return [*this,o] (auto a) { return s + o.s + a.s; };
+  }
+};
+
+constexpr auto L = S{5}.f(S{10});
+static_assert(L(S{100}) == 115);
+} // end test_captures_1::ns2_capture_this_byval
+
+namespace ns2_capture_this_byref {
+
+struct S {
+  int s;
+  constexpr S(int s) : s{s} { }
+  constexpr auto f() const {
+    return [this] { return s; };
+  }
+};
+
+constexpr S SObj{5};
+constexpr auto L = SObj.f();
+constexpr int I = L();
+static_assert(I == 5);
+
+} // end ns2_capture_this_byref
+
+} // end test_captures_1
+
+namespace test_capture_array {
+namespace ns1 {
+constexpr auto f(int I) {
+  int arr[] = { I, I *2, I * 3 };
+  auto L1 = [&] (auto a) { return arr[a]; };
+  int r = L1(2);
+  struct X { int x, y; };
+  return [=](auto a) { return X{arr[a],r}; };
+}
+constexpr auto L = f(3);
+static_assert(L(0).x == 3);
+static_assert(L(0).y == 9);
+static_assert(L(1).x == 6);
+static_assert(L(1).y == 9);
+} // end ns1
+
+} // end test_capture_array
+namespace ns1_test_lvalue_type {
+  void f() {
+    volatile int n;
+    constexpr bool B = [&]{ return &n; }() == &n; // should be accepted
+  }
+} // end ns1_unimplemented 
+
+} // end ns test_lambda_is_cce
+
 #endif // ndef CPP14_AND_EARLIER
diff --git a/test/SemaCXX/cxx1z-decomposition.cpp b/test/SemaCXX/cxx1z-decomposition.cpp
index 735a9e1..d457ace 100644
--- a/test/SemaCXX/cxx1z-decomposition.cpp
+++ b/test/SemaCXX/cxx1z-decomposition.cpp
@@ -65,4 +65,9 @@
   }
 }
 
+int error_recovery() {
+  auto [foobar]; // expected-error {{requires an initializer}}
+  return foobar_; // expected-error {{undeclared identifier 'foobar_'}}
+}
+
 // FIXME: by-value array copies
diff --git a/test/SemaCXX/cxx1z-user-defined-literals.cpp b/test/SemaCXX/cxx1z-user-defined-literals.cpp
new file mode 100644
index 0000000..978fd2f
--- /dev/null
+++ b/test/SemaCXX/cxx1z-user-defined-literals.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++1z %s -include %s -verify
+
+#ifndef INCLUDED
+#define INCLUDED
+
+#pragma clang system_header
+namespace std {
+  using size_t = decltype(sizeof(0));
+
+  struct string_view {};
+  string_view operator""sv(const char*, size_t);
+}
+
+#else
+
+using namespace std;
+string_view s = "foo"sv;
+const char* p = "bar"sv; // expected-error {{no viable conversion}}
+char error = 'x'sv; // expected-error {{invalid suffix}} expected-error {{expected ';'}}
+
+#endif
diff --git a/test/SemaCXX/default-arg-closures.cpp b/test/SemaCXX/default-arg-closures.cpp
index e076cc0..676bd48 100644
--- a/test/SemaCXX/default-arg-closures.cpp
+++ b/test/SemaCXX/default-arg-closures.cpp
@@ -4,16 +4,15 @@
 // instantiating and checking the semantics of default arguments. Make sure we
 // do that right.
 
-// FIXME: Don't diagnose this issue twice.
 template <typename T>
-struct DependentDefaultCtorArg { // expected-note {{in instantiation of default function argument}}
-  // expected-error@+1 2 {{type 'int' cannot be used prior to '::' because it has no members}}
+struct DependentDefaultCtorArg {
+  // expected-error@+1 {{type 'int' cannot be used prior to '::' because it has no members}}
   DependentDefaultCtorArg(int n = T::error);
 };
 struct
 __declspec(dllexport) // expected-note {{due to 'ExportDefaultCtorClosure' being dllexported}}
-ExportDefaultCtorClosure // expected-note {{implicit default constructor for 'ExportDefaultCtorClosure' first required here}}
-: DependentDefaultCtorArg<int> // expected-note {{in instantiation of template class}}
+ExportDefaultCtorClosure // expected-note {{in instantiation of default function argument expression for 'DependentDefaultCtorArg<int>' required here}} expected-note {{implicit default constructor for 'ExportDefaultCtorClosure' first required here}}
+: DependentDefaultCtorArg<int>
 {};
 
 template <typename T>
diff --git a/test/SemaCXX/default-assignment-operator.cpp b/test/SemaCXX/default-assignment-operator.cpp
index e57a898..80ceb37 100644
--- a/test/SemaCXX/default-assignment-operator.cpp
+++ b/test/SemaCXX/default-assignment-operator.cpp
@@ -1,16 +1,34 @@
 // 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
 
-class Base { // expected-error {{cannot define the implicit copy assignment operator for 'Base', because non-static reference member 'ref' cannot use copy assignment operator}} \
-  // expected-warning{{class 'Base' does not declare any constructor to initialize its non-modifiable members}}
-  int &ref;  // expected-note {{declared here}} \
-  // expected-note{{reference member 'ref' will never be initialized}}
+class Base { // expected-warning{{class 'Base' does not declare any constructor to initialize its non-modifiable members}}
+#if __cplusplus <= 199711L
+// expected-error@-2 {{cannot define the implicit copy assignment operator for 'Base', because non-static reference member 'ref' cannot use copy assignment operator}}
+#endif
+
+  int &ref; // expected-note{{reference member 'ref' will never be initialized}}
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{declared here}}
+#else
+  // expected-note@-4 2 {{copy assignment operator of 'Base' is implicitly deleted because field 'ref' is of reference type 'int &'}}
+#endif
 };
 
-class X  : Base {  // // expected-error {{cannot define the implicit copy assignment operator for 'X', because non-static const member 'cint' cannot use copy assignment operator}} \
-// expected-note{{assignment operator for 'Base' first required here}}
+class X  : Base {
+#if __cplusplus <= 199711L
+// expected-note@-2 {{assignment operator for 'Base' first required here}}
+// expected-error@-3 {{cannot define the implicit copy assignment operator for 'X', because non-static const member 'cint' cannot use copy assignment operator}}
+#else
+// expected-note@-5 2 {{copy assignment operator of 'X' is implicitly deleted because base class 'Base' has a deleted copy assignment operator}}
+#endif
+
 public: 
   X();
-  const int cint;  // expected-note {{declared here}}
+  const int cint;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{declared here}}
+#endif
 }; 
 
 struct Y  : X { 
@@ -28,8 +46,17 @@
 
 // Test1
 void f(X x, const X cx) {
-  x = cx; // expected-note{{assignment operator for 'X' first required here}}
   x = cx;
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{assignment operator for 'X' first required here}}
+#else
+  // expected-error@-4 {{object of type 'X' cannot be assigned because its copy assignment operator is implicitly deleted}}
+#endif
+
+  x = cx;
+#if __cplusplus >= 201103L
+  // expected-error@-2 {{object of type 'X' cannot be assigned because its copy assignment operator is implicitly deleted}}
+#endif
   z1 = z2;
 }
 
@@ -73,36 +100,62 @@
 
 // Test5
 
-class E1 { // expected-error{{cannot define the implicit copy assignment operator for 'E1', because non-static const member 'a' cannot use copy assignment operator}}
+class E1 {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{cannot define the implicit copy assignment operator for 'E1', because non-static const member 'a' cannot use copy assignment operator}}
+#endif
 
 public:
-  const int a; // expected-note{{declared here}}
-  E1() : a(0) {}  
+  const int a;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{declared here}}
+#else
+// expected-note@-4 {{copy assignment operator of 'E1' is implicitly deleted because field 'a' is of const-qualified type 'const int'}}
+#endif
+  E1() : a(0) {}
 
 };
 
 E1 e1, e2;
 
 void j() {
-  e1 = e2; // expected-note{{assignment operator for 'E1' first required here}}
+  e1 = e2;
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{assignment operator for 'E1' first required here}}
+#else
+  // expected-error@-4 {{object of type 'E1' cannot be assigned because its copy assignment operator is implicitly deleted}}
+#endif
 }
 
 namespace ProtectedCheck {
   struct X {
   protected:
-    X &operator=(const X&); // expected-note{{declared protected here}}
+    X &operator=(const X&);
+#if __cplusplus <= 199711L
+    // expected-note@-2 {{declared protected here}}
+#endif
   };
 
   struct Y : public X { };
 
   void f(Y y) { y = y; }
 
-  struct Z { // expected-error{{'operator=' is a protected member of 'ProtectedCheck::X'}}
+  struct Z {
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{'operator=' is a protected member of 'ProtectedCheck::X'}}
+#endif
     X x;
+#if __cplusplus >= 201103L
+    // expected-note@-2 {{copy assignment operator of 'Z' is implicitly deleted because field 'x' has an inaccessible copy assignment operator}}
+#endif
   };
 
-  void f(Z z) { z = z; }  // expected-note{{implicit copy assignment operator}}
-
+  void f(Z z) { z = z; }
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{implicit copy assignment operator}}
+#else
+  // expected-error@-4 {{object of type 'ProtectedCheck::Z' cannot be assigned because its copy assignment operator is implicitly deleted}}
+#endif
 }
 
 namespace MultiplePaths {
diff --git a/test/SemaCXX/default-constructor-initializers.cpp b/test/SemaCXX/default-constructor-initializers.cpp
index e783f49..25c7064 100644
--- a/test/SemaCXX/default-constructor-initializers.cpp
+++ b/test/SemaCXX/default-constructor-initializers.cpp
@@ -1,26 +1,59 @@
 // 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
 
 struct X1 { // has no implicit default constructor
    X1(int);
 };
 
-struct X2  : X1 {  // expected-note 2 {{'X2' declared here}}
+struct X2  : X1 {
+#if __cplusplus <= 199711L
+// expected-note@-2 2 {{'X2' declared here}}
+#endif
+
    X2(int);
 };
 
-struct X3 : public X2 { // expected-error {{implicit default constructor for 'X3' must explicitly initialize the base class 'X2' which does not have a default constructor}}
-};
-X3 x3; // expected-note {{first required here}}
-
-
-struct X4 { // expected-error {{must explicitly initialize the member 'x2'}} \
-            // expected-error {{must explicitly initialize the reference member 'rx2'}}
-  X2 x2; 	// expected-note {{member is declared here}}
-  X2 & rx2; // expected-note {{declared here}}
+struct X3 : public X2 {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{implicit default constructor for 'X3' must explicitly initialize the base class 'X2' which does not have a default constructor}}
+#else
+// expected-note@-4 {{default constructor of 'X3' is implicitly deleted because base class 'X2' has no default constructor}}
+#endif
 };
 
-X4 x4; // expected-note {{first required here}}
+X3 x3;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{first required here}}
+#else
+// expected-error@-4 {{call to implicitly-deleted default constructor of 'X3'}}
+#endif
 
+struct X4 {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{must explicitly initialize the member 'x2'}}
+// expected-error@-3 {{must explicitly initialize the reference member 'rx2'}}
+#endif
+
+  X2 x2;
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{member is declared here}}
+#else
+  // expected-note@-4 {{default constructor of 'X4' is implicitly deleted because field 'x2' has no default constructor}}
+#endif
+
+  X2 & rx2;
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{declared here}}
+#endif
+};
+
+X4 x4;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{first required here}}
+#else
+// expected-error@-4 {{call to implicitly-deleted default constructor of 'X4'}}
+#endif
 
 struct Y1 { // has no implicit default constructor
    Y1(int);
@@ -43,15 +76,33 @@
 
 // More tests
 
-struct Z1 { // expected-error {{must explicitly initialize the reference member 'z'}} \
-            // expected-error {{must explicitly initialize the const member 'c1'}}
-  int& z;       // expected-note {{declared here}}
-  const int c1; // expected-note {{declared here}}
+struct Z1 {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{must explicitly initialize the reference member 'z'}}
+// expected-error@-3 {{must explicitly initialize the const member 'c1'}}
+#endif
+
+  int& z;
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{declared here}}
+#else
+  // expected-note@-4 {{default constructor of 'Z1' is implicitly deleted because field 'z' of reference type 'int &' would not be initialized}}
+#endif
+
+  const int c1;
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{declared here}}
+#endif
   volatile int v1;
 };
 
 // Test default initialization which *requires* a constructor call for non-POD.
-Z1 z1; // expected-note {{first required here}}
+Z1 z1;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{first required here}}
+#else
+// expected-error@-4 {{call to implicitly-deleted default constructor of 'Z1'}}
+#endif
 
 // Ensure that value initialization doesn't use trivial implicit constructors.
 namespace PR7948 {
diff --git a/test/SemaCXX/designated-initializers-base-class.cpp b/test/SemaCXX/designated-initializers-base-class.cpp
new file mode 100644
index 0000000..9c2e61e
--- /dev/null
+++ b/test/SemaCXX/designated-initializers-base-class.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -Winitializer-overrides
+// expected-no-diagnostics
+
+struct B {
+  int x;
+};
+
+struct D : B {
+  int y;
+};
+
+void test() { D d = {1, .y = 2}; }
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index fe1dde5..49cdc50 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -431,3 +431,23 @@
 
 // The constructor definition should not have errors
 Invalid::~Invalid() {}
+
+namespace PR30361 {
+template <typename T>
+struct C1 {
+  ~C1() {}
+  operator C1<T>* () { return nullptr; }
+  void foo1();
+};
+
+template<typename T>
+void C1<T>::foo1() {
+  C1::operator C1<T>*();
+  C1::~C1();
+}
+
+void foo1() {
+  C1<int> x;
+  x.foo1();
+}
+}
diff --git a/test/SemaCXX/diagnose_if-ext.cpp b/test/SemaCXX/diagnose_if-ext.cpp
new file mode 100644
index 0000000..d5625b5
--- /dev/null
+++ b/test/SemaCXX/diagnose_if-ext.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -Wpedantic -fsyntax-only %s -verify
+
+void foo() __attribute__((diagnose_if(1, "", "error"))); // expected-warning{{'diagnose_if' is a clang extension}}
+void foo(int a) __attribute__((diagnose_if(a, "", "error"))); // expected-warning{{'diagnose_if' is a clang extension}}
+// FIXME: When diagnose_if gets a CXX11 spelling, this should be enabled.
+#if 0
+[[clang::diagnose_if(a, "", "error")]] void foo(double a);
+#endif
diff --git a/test/SemaCXX/diagnose_if.cpp b/test/SemaCXX/diagnose_if.cpp
new file mode 100644
index 0000000..02b3620
--- /dev/null
+++ b/test/SemaCXX/diagnose_if.cpp
@@ -0,0 +1,669 @@
+// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++14
+
+#define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))
+
+using size_t = decltype(sizeof(int));
+
+namespace type_dependent {
+template <typename T>
+void neverok() _diagnose_if(!T(), "oh no", "error") {} // expected-note 4{{from 'diagnose_if'}}
+
+template <typename T>
+void alwaysok() _diagnose_if(T(), "oh no", "error") {}
+
+template <typename T>
+void alwayswarn() _diagnose_if(!T(), "oh no", "warning") {} // expected-note 4{{from 'diagnose_if'}}
+
+template <typename T>
+void neverwarn() _diagnose_if(T(), "oh no", "warning") {}
+
+void runAll() {
+  alwaysok<int>();
+  alwaysok<int>();
+
+  {
+    void (*pok)() = alwaysok<int>;
+    pok = &alwaysok<int>;
+  }
+
+  neverok<int>(); // expected-error{{oh no}}
+  neverok<short>(); // expected-error{{oh no}}
+
+  {
+    void (*pok)() = neverok<int>; // expected-error{{oh no}}
+  }
+  {
+    void (*pok)();
+    pok = &neverok<int>; // expected-error{{oh no}}
+  }
+
+  alwayswarn<int>(); // expected-warning{{oh no}}
+  alwayswarn<short>(); // expected-warning{{oh no}}
+  {
+    void (*pok)() = alwayswarn<int>; // expected-warning{{oh no}}
+    pok = &alwayswarn<int>; // expected-warning{{oh no}}
+  }
+
+  neverwarn<int>();
+  neverwarn<short>();
+  {
+    void (*pok)() = neverwarn<int>;
+    pok = &neverwarn<int>;
+  }
+}
+
+template <typename T>
+void errorIf(T a) _diagnose_if(T() != a, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
+
+template <typename T>
+void warnIf(T a) _diagnose_if(T() != a, "oh no", "warning") {} // expected-note{{from 'diagnose_if'}}
+
+void runIf() {
+  errorIf(0);
+  errorIf(1); // expected-error{{oh no}}
+
+  warnIf(0);
+  warnIf(1); // expected-warning{{oh no}}
+}
+}
+
+namespace value_dependent {
+template <int N>
+void neverok() _diagnose_if(N == 0 || N != 0, "oh no", "error") {} // expected-note 4{{from 'diagnose_if'}}
+
+template <int N>
+void alwaysok() _diagnose_if(N == 0 && N != 0, "oh no", "error") {}
+
+template <int N>
+void alwayswarn() _diagnose_if(N == 0 || N != 0, "oh no", "warning") {} // expected-note 4{{from 'diagnose_if'}}
+
+template <int N>
+void neverwarn() _diagnose_if(N == 0 && N != 0, "oh no", "warning") {}
+
+void runAll() {
+  alwaysok<0>();
+  alwaysok<1>();
+
+  {
+    void (*pok)() = alwaysok<0>;
+    pok = &alwaysok<0>;
+  }
+
+  neverok<0>(); // expected-error{{oh no}}
+  neverok<1>(); // expected-error{{oh no}}
+
+  {
+    void (*pok)() = neverok<0>; // expected-error{{oh no}}
+  }
+  {
+    void (*pok)();
+    pok = &neverok<0>; // expected-error{{oh no}}
+  }
+
+  alwayswarn<0>(); // expected-warning{{oh no}}
+  alwayswarn<1>(); // expected-warning{{oh no}}
+  {
+    void (*pok)() = alwayswarn<0>; // expected-warning{{oh no}}
+    pok = &alwayswarn<0>; // expected-warning{{oh no}}
+  }
+
+  neverwarn<0>();
+  neverwarn<1>();
+  {
+    void (*pok)() = neverwarn<0>;
+    pok = &neverwarn<0>;
+  }
+}
+
+template <int N>
+void errorIf(int a) _diagnose_if(N != a, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
+
+template <int N>
+void warnIf(int a) _diagnose_if(N != a, "oh no", "warning") {} // expected-note{{from 'diagnose_if'}}
+
+void runIf() {
+  errorIf<0>(0);
+  errorIf<0>(1); // expected-error{{oh no}}
+
+  warnIf<0>(0);
+  warnIf<0>(1); // expected-warning{{oh no}}
+}
+}
+
+namespace no_overload_interaction {
+void foo(int) _diagnose_if(1, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+void foo(short);
+
+void bar(int);
+void bar(short) _diagnose_if(1, "oh no", "error");
+
+void fooArg(int a) _diagnose_if(a, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+void fooArg(short);
+
+void barArg(int);
+void barArg(short a) _diagnose_if(a, "oh no", "error");
+
+void runAll() {
+  foo(1); // expected-error{{oh no}}
+  bar(1);
+
+  fooArg(1); // expected-error{{oh no}}
+  barArg(1);
+
+  auto p = foo; // expected-error{{incompatible initializer of type '<overloaded function type>'}}
+}
+}
+
+namespace with_default_args {
+void foo(int a = 0) _diagnose_if(a, "oh no", "warning"); // expected-note 1{{from 'diagnose_if'}}
+void bar(int a = 1) _diagnose_if(a, "oh no", "warning"); // expected-note 2{{from 'diagnose_if'}}
+
+void runAll() {
+  foo();
+  foo(0);
+  foo(1); // expected-warning{{oh no}}
+
+  bar(); // expected-warning{{oh no}}
+  bar(0);
+  bar(1); // expected-warning{{oh no}}
+}
+}
+
+namespace naked_mem_expr {
+struct Foo {
+  void foo(int a) _diagnose_if(a, "should warn", "warning"); // expected-note{{from 'diagnose_if'}}
+  void bar(int a) _diagnose_if(a, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+};
+
+void runFoo() {
+  Foo().foo(0);
+  Foo().foo(1); // expected-warning{{should warn}}
+
+  Foo().bar(0);
+  Foo().bar(1); // expected-error{{oh no}}
+}
+}
+
+namespace class_template {
+template <typename T>
+struct Errors {
+  void foo(int i) _diagnose_if(i, "bad i", "error"); // expected-note{{from 'diagnose_if'}}
+  void bar(int i) _diagnose_if(i != T(), "bad i", "error"); // expected-note{{from 'diagnose_if'}}
+
+  void fooOvl(int i) _diagnose_if(i, "int bad i", "error"); // expected-note{{from 'diagnose_if'}}
+  void fooOvl(short i) _diagnose_if(i, "short bad i", "error"); // expected-note{{from 'diagnose_if'}}
+
+  void barOvl(int i) _diagnose_if(i != T(), "int bad i", "error"); // expected-note{{from 'diagnose_if'}}
+  void barOvl(short i) _diagnose_if(i != T(), "short bad i", "error"); // expected-note{{from 'diagnose_if'}}
+};
+
+void runErrors() {
+  Errors<int>().foo(0);
+  Errors<int>().foo(1); // expected-error{{bad i}}
+
+  Errors<int>().bar(0);
+  Errors<int>().bar(1); // expected-error{{bad i}}
+
+  Errors<int>().fooOvl(0);
+  Errors<int>().fooOvl(1); // expected-error{{int bad i}}
+  Errors<int>().fooOvl(short(0));
+  Errors<int>().fooOvl(short(1)); // expected-error{{short bad i}}
+
+  Errors<int>().barOvl(0);
+  Errors<int>().barOvl(1); // expected-error{{int bad i}}
+  Errors<int>().barOvl(short(0));
+  Errors<int>().barOvl(short(1)); // expected-error{{short bad i}}
+}
+
+template <typename T>
+struct Warnings {
+  void foo(int i) _diagnose_if(i, "bad i", "warning"); // expected-note{{from 'diagnose_if'}}
+  void bar(int i) _diagnose_if(i != T(), "bad i", "warning"); // expected-note{{from 'diagnose_if'}}
+
+  void fooOvl(int i) _diagnose_if(i, "int bad i", "warning"); // expected-note{{from 'diagnose_if'}}
+  void fooOvl(short i) _diagnose_if(i, "short bad i", "warning"); // expected-note{{from 'diagnose_if'}}
+
+  void barOvl(int i) _diagnose_if(i != T(), "int bad i", "warning"); // expected-note{{from 'diagnose_if'}}
+  void barOvl(short i) _diagnose_if(i != T(), "short bad i", "warning"); // expected-note{{from 'diagnose_if'}}
+};
+
+void runWarnings() {
+  Warnings<int>().foo(0);
+  Warnings<int>().foo(1); // expected-warning{{bad i}}
+
+  Warnings<int>().bar(0);
+  Warnings<int>().bar(1); // expected-warning{{bad i}}
+
+  Warnings<int>().fooOvl(0);
+  Warnings<int>().fooOvl(1); // expected-warning{{int bad i}}
+  Warnings<int>().fooOvl(short(0));
+  Warnings<int>().fooOvl(short(1)); // expected-warning{{short bad i}}
+
+  Warnings<int>().barOvl(0);
+  Warnings<int>().barOvl(1); // expected-warning{{int bad i}}
+  Warnings<int>().barOvl(short(0));
+  Warnings<int>().barOvl(short(1)); // expected-warning{{short bad i}}
+}
+}
+
+namespace template_specialization {
+template <typename T>
+struct Foo {
+  void foo() _diagnose_if(1, "override me", "error"); // expected-note{{from 'diagnose_if'}}
+  void bar(int i) _diagnose_if(i, "bad i", "error"); // expected-note{{from 'diagnose_if'}}
+  void baz(int i);
+};
+
+template <>
+struct Foo<int> {
+  void foo();
+  void bar(int i);
+  void baz(int i) _diagnose_if(i, "bad i", "error"); // expected-note{{from 'diagnose_if'}}
+};
+
+void runAll() {
+  Foo<double>().foo(); // expected-error{{override me}}
+  Foo<int>().foo();
+
+  Foo<double>().bar(1); // expected-error{{bad i}}
+  Foo<int>().bar(1);
+
+  Foo<double>().baz(1);
+  Foo<int>().baz(1); // expected-error{{bad i}}
+}
+}
+
+namespace late_constexpr {
+constexpr int foo();
+constexpr int foo(int a);
+
+void bar() _diagnose_if(foo(), "bad foo", "error"); // expected-note{{from 'diagnose_if'}}
+void bar(int a) _diagnose_if(foo(a), "bad foo", "error"); // expected-note{{from 'diagnose_if'}}
+
+void early() {
+  bar();
+  bar(0);
+  bar(1);
+}
+
+constexpr int foo() { return 1; }
+constexpr int foo(int a) { return a; }
+
+void late() {
+  bar(); // expected-error{{bad foo}}
+  bar(0);
+  bar(1); // expected-error{{bad foo}}
+}
+}
+
+namespace late_parsed {
+struct Foo {
+  int i;
+  constexpr Foo(int i): i(i) {}
+  constexpr bool isFooable() const { return i; }
+
+  void go() const _diagnose_if(isFooable(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
+  operator int() const _diagnose_if(isFooable(), "oh no", "error") { return 1; } // expected-note{{from 'diagnose_if'}}
+
+  void go2() const _diagnose_if(isFooable(), "oh no", "error") // expected-note{{from 'diagnose_if'}}
+      __attribute__((enable_if(true, ""))) {}
+  void go2() const _diagnose_if(isFooable(), "oh no", "error") {}
+
+  constexpr int go3() const _diagnose_if(isFooable(), "oh no", "error")
+      __attribute__((enable_if(true, ""))) {
+    return 1;
+  }
+
+  constexpr int go4() const _diagnose_if(isFooable(), "oh no", "error") {
+    return 1;
+  }
+  constexpr int go4() const _diagnose_if(isFooable(), "oh no", "error")
+      __attribute__((enable_if(true, ""))) {
+    return 1;
+  }
+
+  // We hope to support emitting these errors in the future. For now, though...
+  constexpr int runGo() const {
+    return go3() + go4();
+  }
+};
+
+void go(const Foo &f) _diagnose_if(f.isFooable(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
+
+void run() {
+  Foo(0).go();
+  Foo(1).go(); // expected-error{{oh no}}
+
+  (void)int(Foo(0));
+  (void)int(Foo(1)); // expected-error{{oh no}}
+
+  Foo(0).go2();
+  Foo(1).go2(); // expected-error{{oh no}}
+
+  go(Foo(0));
+  go(Foo(1)); // expected-error{{oh no}}
+}
+}
+
+namespace member_templates {
+struct Foo {
+  int i;
+  constexpr Foo(int i): i(i) {}
+  constexpr bool bad() const { return i; }
+
+  template <typename T> T getVal() _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
+    return T();
+  }
+
+  template <typename T>
+  constexpr T getVal2() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
+    return T();
+  }
+
+  template <typename T>
+  constexpr operator T() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
+    return T();
+  }
+
+  // We hope to support emitting these errors in the future.
+  int run() { return getVal<int>() + getVal2<int>() + int(*this); }
+};
+
+void run() {
+  Foo(0).getVal<int>();
+  Foo(1).getVal<int>(); // expected-error{{oh no}}
+
+  Foo(0).getVal2<int>();
+  Foo(1).getVal2<int>(); // expected-error{{oh no}}
+
+  (void)int(Foo(0));
+  (void)int(Foo(1)); // expected-error{{oh no}}
+}
+}
+
+namespace special_member_operators {
+struct Bar { int j; };
+struct Foo {
+  int i;
+  constexpr Foo(int i): i(i) {}
+  constexpr bool bad() const { return i; }
+  const Bar *operator->() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
+    return nullptr;
+  }
+  void operator()() const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
+};
+
+struct ParenOverload {
+  int i;
+  constexpr ParenOverload(int i): i(i) {}
+  constexpr bool bad() const { return i; }
+  void operator()(double) const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
+  void operator()(int) const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
+};
+
+struct ParenTemplate {
+  int i;
+  constexpr ParenTemplate(int i): i(i) {}
+  constexpr bool bad() const { return i; }
+  template <typename T>
+  void operator()(T) const _diagnose_if(bad(), "oh no", "error") {} // expected-note 2{{from 'diagnose_if'}}
+};
+
+void run() {
+  (void)Foo(0)->j;
+  (void)Foo(1)->j; // expected-error{{oh no}}
+
+  Foo(0)();
+  Foo(1)(); // expected-error{{oh no}}
+
+  ParenOverload(0)(1);
+  ParenOverload(0)(1.);
+
+  ParenOverload(1)(1); // expected-error{{oh no}}
+  ParenOverload(1)(1.); // expected-error{{oh no}}
+
+  ParenTemplate(0)(1);
+  ParenTemplate(0)(1.);
+
+  ParenTemplate(1)(1); // expected-error{{oh no}}
+  ParenTemplate(1)(1.); // expected-error{{oh no}}
+}
+
+void runLambda() {
+  auto L1 = [](int i) _diagnose_if(i, "oh no", "error") {}; // expected-note{{from 'diagnose_if'}}
+  L1(0);
+  L1(1); // expected-error{{oh no}}
+}
+
+struct Brackets {
+  int i;
+  constexpr Brackets(int i): i(i) {}
+  void operator[](int) _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
+    _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+};
+
+void runBrackets(int i) {
+  Brackets{0}[i];
+  Brackets{1}[i]; // expected-warning{{oh no}}
+  Brackets{2}[i]; // expected-error{{oh no}}
+}
+
+struct Unary {
+  int i;
+  constexpr Unary(int i): i(i) {}
+  void operator+() _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
+    _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+};
+
+void runUnary() {
+  +Unary{0};
+  +Unary{1}; // expected-warning{{oh no}}
+  +Unary{2}; // expected-error{{oh no}}
+}
+
+struct PostInc {
+  void operator++(int i) _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
+    _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+};
+
+void runPostInc() {
+  PostInc{}++;
+  PostInc{}.operator++(1); // expected-warning{{oh no}}
+  PostInc{}.operator++(2); // expected-error{{oh no}}
+}
+}
+
+namespace ctors {
+struct Foo {
+  int I;
+  constexpr Foo(int I): I(I) {}
+
+  constexpr const Foo &operator=(const Foo &) const
+      _diagnose_if(I, "oh no", "error") {  // expected-note{{from 'diagnose_if'}}
+    return *this;
+  }
+
+  constexpr const Foo &operator=(const Foo &&) const
+      _diagnose_if(I, "oh no", "error") { // expected-note{{from 'diagnose_if'}}
+    return *this;
+  }
+};
+
+struct Bar {
+  int I;
+  constexpr Bar(int I) _diagnose_if(I == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
+    _diagnose_if(I == 2, "oh no", "error"): I(I) {} // expected-note{{from 'diagnose_if'}}
+};
+
+void run() {
+  constexpr Foo F{0};
+  constexpr Foo F2{1};
+
+  F2 = F; // expected-error{{oh no}}
+  F2 = Foo{2}; // expected-error{{oh no}}
+
+  Bar{0};
+  Bar{1}; // expected-warning{{oh no}}
+  Bar{2}; // expected-error{{oh no}}
+}
+}
+
+namespace ref_init {
+struct Bar {};
+struct Baz {};
+struct Foo {
+  int i;
+  constexpr Foo(int i): i(i) {}
+  operator const Bar &() const _diagnose_if(i, "oh no", "warning"); // expected-note{{from 'diagnose_if'}}
+  operator const Baz &() const _diagnose_if(i, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+};
+void fooBar(const Bar &b);
+void fooBaz(const Baz &b);
+
+void run() {
+  fooBar(Foo{0});
+  fooBar(Foo{1}); // expected-warning{{oh no}}
+  fooBaz(Foo{0});
+  fooBaz(Foo{1}); // expected-error{{oh no}}
+}
+}
+
+namespace udl {
+void operator""_fn(char c)_diagnose_if(c == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
+    _diagnose_if(c == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+
+void run() {
+  '\0'_fn;
+  '\1'_fn; // expected-warning{{oh no}}
+  '\2'_fn; // expected-error{{oh no}}
+}
+}
+
+namespace PR31638 {
+struct String {
+  String(char const* __s) _diagnose_if(__s == nullptr, "oh no ptr", "warning"); // expected-note{{from 'diagnose_if'}}
+  String(int __s) _diagnose_if(__s != 0, "oh no int", "warning"); // expected-note{{from 'diagnose_if'}}
+};
+
+void run() {
+  String s(nullptr); // expected-warning{{oh no ptr}}
+  String ss(42); // expected-warning{{oh no int}}
+}
+}
+
+namespace PR31639 {
+struct Foo {
+  Foo(int I) __attribute__((diagnose_if(I, "oh no", "error"))); // expected-note{{from 'diagnose_if'}}
+};
+
+void bar() { Foo f(1); } // expected-error{{oh no}}
+}
+
+namespace user_defined_conversion {
+struct Foo {
+  int i;
+  constexpr Foo(int i): i(i) {}
+  operator size_t() const _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
+      _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
+};
+
+void run() {
+  // `new T[N]`, where N is implicitly convertible to size_t, calls
+  // PerformImplicitConversion directly. This lets us test the diagnostic logic
+  // in PerformImplicitConversion.
+  new int[Foo{0}];
+  new int[Foo{1}]; // expected-warning{{oh no}}
+  new int[Foo{2}]; // expected-error{{oh no}}
+}
+}
+
+namespace std {
+  template <typename T>
+  struct initializer_list {
+    const T *ptr;
+    size_t elems;
+
+    constexpr size_t size() const { return elems; }
+  };
+}
+
+namespace initializer_lists {
+struct Foo {
+  Foo(std::initializer_list<int> l)
+    _diagnose_if(l.size() == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
+    _diagnose_if(l.size() == 2, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
+};
+
+void run() {
+  Foo{std::initializer_list<int>{}};
+  Foo{std::initializer_list<int>{1}}; // expected-warning{{oh no}}
+  Foo{std::initializer_list<int>{1, 2}}; // expected-error{{oh no}}
+  Foo{std::initializer_list<int>{1, 2, 3}};
+}
+}
+
+namespace range_for_loop {
+  namespace adl {
+    struct Foo {
+      int i;
+      constexpr Foo(int i): i(i) {}
+    };
+    void **begin(const Foo &f) _diagnose_if(f.i, "oh no", "warning");
+    void **end(const Foo &f) _diagnose_if(f.i, "oh no", "warning");
+
+    struct Bar {
+      int i;
+      constexpr Bar(int i): i(i) {}
+    };
+    void **begin(const Bar &b) _diagnose_if(b.i, "oh no", "error");
+    void **end(const Bar &b) _diagnose_if(b.i, "oh no", "error");
+  }
+
+  void run() {
+    for (void *p : adl::Foo(0)) {}
+    // FIXME: This should emit diagnostics. It seems that our constexpr
+    // evaluator isn't able to evaluate `adl::Foo(1)` as a constant, though.
+    for (void *p : adl::Foo(1)) {}
+
+    for (void *p : adl::Bar(0)) {}
+    // FIXME: Same thing.
+    for (void *p : adl::Bar(1)) {}
+  }
+}
+
+namespace operator_new {
+struct Foo {
+  int j;
+  static void *operator new(size_t i) _diagnose_if(i, "oh no", "warning");
+};
+
+struct Bar {
+  int j;
+  static void *operator new(size_t i) _diagnose_if(!i, "oh no", "warning");
+};
+
+void run() {
+  // FIXME: This should emit a diagnostic.
+  new Foo();
+  // This is here because we sometimes pass a dummy argument `operator new`. We
+  // should ignore this, rather than complaining about it.
+  new Bar();
+}
+}
+
+namespace contextual_implicit_conv {
+struct Foo {
+  int i;
+  constexpr Foo(int i): i(i) {}
+  constexpr operator int() const _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
+      _diagnose_if(i == 2, "oh no", "error") { // expected-note{{from 'diagnose_if'}}
+    return i;
+  }
+};
+
+void run() {
+  switch (constexpr Foo i = 0) { default: break; }
+  switch (constexpr Foo i = 1) { default: break; } // expected-warning{{oh no}}
+  switch (constexpr Foo i = 2) { default: break; } // expected-error{{oh no}}
+}
+}
diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp
index b4850fc..a3fed70 100644
--- a/test/SemaCXX/dllexport.cpp
+++ b/test/SemaCXX/dllexport.cpp
@@ -741,6 +741,27 @@
   ClassWithMultipleDefaultCtors(int = 40) {} // expected-error{{'__declspec(dllexport)' cannot be applied to more than one default constructor}}
   ClassWithMultipleDefaultCtors(int = 30, ...) {} // expected-note{{declared here}}
 };
+template <typename T>
+struct ClassTemplateWithMultipleDefaultCtors {
+  __declspec(dllexport) ClassTemplateWithMultipleDefaultCtors(int = 40) {}      // expected-error{{'__declspec(dllexport)' cannot be applied to more than one default constructor}}
+  __declspec(dllexport) ClassTemplateWithMultipleDefaultCtors(int = 30, ...) {} // expected-note{{declared here}}
+};
+
+template <typename T> struct HasDefaults {
+  HasDefaults(int x = sizeof(T)) {} // expected-error {{invalid application of 'sizeof'}}
+};
+template struct __declspec(dllexport) HasDefaults<char>;
+
+template struct
+__declspec(dllexport) // expected-note {{in instantiation of default function argument expression for 'HasDefaults<void>' required here}}
+HasDefaults<void>; // expected-note {{in instantiation of member function 'HasDefaults<void>::HasDefaults' requested here}}
+
+template <typename T> struct HasDefaults2 {
+  __declspec(dllexport) // expected-note {{in instantiation of default function argument expression for 'HasDefaults2<void>' required here}}
+  HasDefaults2(int x = sizeof(T)) {} // expected-error {{invalid application of 'sizeof'}}
+};
+template struct HasDefaults2<void>; // expected-note {{in instantiation of member function 'HasDefaults2<void>::HasDefaults2' requested here}}
+
 #endif
 
 //===----------------------------------------------------------------------===//
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
index 36a8ac6..1c59cca 100644
--- a/test/SemaCXX/dllimport.cpp
+++ b/test/SemaCXX/dllimport.cpp
@@ -396,20 +396,28 @@
 template<typename T> __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
 
 // Import inline function template.
-#ifdef GNU
-// expected-warning@+5{{'dllimport' attribute ignored on inline function}}
-// expected-warning@+5{{'dllimport' attribute ignored on inline function}}
-// expected-warning@+6{{'dllimport' attribute ignored on inline function}}
-// expected-warning@+9{{'inlineFuncTmplDef' redeclared inline; 'dllimport' attribute ignored}}
-#endif
-template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
-template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
+#ifdef GNU // MinGW always ignores dllimport on inline functions.
 
-template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
+template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
+template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
+
+template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}}
 template<typename T>                              void inlineFuncTmplDecl() {}
 
 template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
-template<typename T>                inline void inlineFuncTmplDef() {}
+template<typename T>                inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared inline; 'dllimport' attribute ignored}}
+
+#else // MSVC drops dllimport when the function template is redeclared without it. (It doesn't warn, but we do.)
+
+template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
+template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
+
+template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                              void inlineFuncTmplDecl() {} // expected-warning{{'inlineFuncTmplDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+#endif
 
 // Redeclarations
 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
@@ -436,7 +444,9 @@
   template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
   template<typename T> friend                       void funcTmplFriend4(); // expected-note{{previous declaration is here}}
 #ifdef GNU
-// expected-warning@+2{{'dllimport' attribute ignored on inline function}}
+// expected-warning@+4{{'dllimport' attribute ignored on inline function}}
+#else
+// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}
 #endif
   template<typename T> friend __declspec(dllimport) inline void funcTmplFriend5();
 };
@@ -444,6 +454,9 @@
 template<typename T>                       void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
 template<typename T>                       void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
 template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}}
+#ifdef MS
+// expected-warning@+2{{'funcTmplFriend5' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+#endif
 template<typename T>                       inline void funcTmplFriend5() {}
 
 // External linkage is required.
@@ -827,21 +840,28 @@
 struct ImportMemberTmpl {
   template<typename T> __declspec(dllimport)               void normalDecl();
   template<typename T> __declspec(dllimport)               void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+#ifdef MS
+// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}
+#endif
   template<typename T> __declspec(dllimport)               void normalInlineDef();
   template<typename T> __declspec(dllimport) static        void staticDecl();
   template<typename T> __declspec(dllimport) static        void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+#ifdef MS
+// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}
+#endif
   template<typename T> __declspec(dllimport) static        void staticInlineDef();
 
 #ifdef GNU
-  // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
-  // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
-  // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
-  // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
-#endif
+  template<typename T> __declspec(dllimport)               void normalInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
+  template<typename T> __declspec(dllimport)        inline void normalInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}}
+  template<typename T> __declspec(dllimport) static        void staticInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
+  template<typename T> __declspec(dllimport) static inline void staticInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}}
+#else
   template<typename T> __declspec(dllimport)               void normalInclass() {}
-  template<typename T> __declspec(dllimport)        inline void normalInlineDecl();
+  template<typename T> __declspec(dllimport)        inline void normalInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
   template<typename T> __declspec(dllimport) static        void staticInclass() {}
-  template<typename T> __declspec(dllimport) static inline void staticInlineDecl();
+  template<typename T> __declspec(dllimport) static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+#endif
 
 #if __has_feature(cxx_variable_templates)
   template<typename T> __declspec(dllimport) static        int  StaticField;
@@ -856,16 +876,22 @@
 };
 
 template<typename T>        void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T>        void ImportMemberTmpl::normalInlineDecl() {}
 template<typename T>        void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+#ifdef GNU // dllimport was ignored above
+template<typename T>        void ImportMemberTmpl::normalInlineDecl() {}
 template<typename T>        void ImportMemberTmpl::staticInlineDecl() {}
+#else // dllimport dropped here
+template<typename T>        void ImportMemberTmpl::normalInlineDecl() {} // expected-warning{{'ImportMemberTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T>        void ImportMemberTmpl::staticInlineDecl() {} // expected-warning{{'ImportMemberTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+#endif
 
 #ifdef GNU
-// expected-warning@+3{{ImportMemberTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
-// expected-warning@+3{{ImportMemberTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
+template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
+template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
+#else
+template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
 #endif
-template<typename T> inline void ImportMemberTmpl::normalInlineDef() {}
-template<typename T> inline void ImportMemberTmpl::staticInlineDef() {}
 
 #if __has_feature(cxx_variable_templates)
 template<typename T>        int  ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
@@ -1240,20 +1266,32 @@
 struct ImportClsTmplMemTmpl {
   template<typename U> __declspec(dllimport)               void normalDecl();
   template<typename U> __declspec(dllimport)               void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+#ifdef MS
+// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}
+#endif
   template<typename U> __declspec(dllimport)               void normalInlineDef();
   template<typename U> __declspec(dllimport) static        void staticDecl();
   template<typename U> __declspec(dllimport) static        void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+#ifdef MS
+// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}
+#endif
   template<typename U> __declspec(dllimport) static        void staticInlineDef();
 
 #ifdef GNU
   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
-  // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
-  // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
-  // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
+  // expected-warning@+8{{'dllimport' attribute ignored on inline function}}
+  // expected-warning@+8{{'dllimport' attribute ignored on inline function}}
+  // expected-warning@+11{{'dllimport' attribute ignored on inline function}}
 #endif
   template<typename U> __declspec(dllimport)               void normalInclass() {}
+#ifdef MS
+// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}
+#endif
   template<typename U> __declspec(dllimport)        inline void normalInlineDecl();
   template<typename U> __declspec(dllimport) static        void staticInclass() {}
+#ifdef MS
+// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}
+#endif
   template<typename U> __declspec(dllimport) static inline void staticInlineDecl();
 
 #if __has_feature(cxx_variable_templates)
@@ -1269,16 +1307,22 @@
 };
 
 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalInlineDecl() {}
 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+#ifdef GNU
+template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalInlineDecl() {}
 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticInlineDecl() {}
+#else
+template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+#endif
 
 #ifdef GNU
-// expected-warning@+3{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
-// expected-warning@+3{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
+template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
+template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
+#else
+template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
 #endif
-template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {}
-template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {}
 
 #if __has_feature(cxx_variable_templates)
 template<typename T> template<typename U>        int  ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp
index 0f8fc9b..01b6f8f 100644
--- a/test/SemaCXX/enable_if.cpp
+++ b/test/SemaCXX/enable_if.cpp
@@ -246,11 +246,11 @@
 
   int noOvlNoCandidate(int m) __attribute__((enable_if(false, "")));
   void test8() {
-    int (*p)(int) = noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' becuase it has one or more non-tautological enable_if conditions}}
-    int (*p2)(int) = &noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' becuase it has one or more non-tautological enable_if conditions}}
+    int (*p)(int) = noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' because it has one or more non-tautological enable_if conditions}}
+    int (*p2)(int) = &noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' because it has one or more non-tautological enable_if conditions}}
     int (*a)(int);
-    a = noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' becuase it has one or more non-tautological enable_if conditions}}
-    a = &noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' becuase it has one or more non-tautological enable_if conditions}}
+    a = noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' because it has one or more non-tautological enable_if conditions}}
+    a = &noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' because it has one or more non-tautological enable_if conditions}}
   }
 }
 
@@ -464,3 +464,11 @@
   Foo<double>().bar(1);
 }
 }
+
+namespace instantiate_constexpr_in_enable_if {
+  template<typename T> struct X {
+    static constexpr bool ok() { return true; }
+    void f() __attribute__((enable_if(ok(), "")));
+  };
+  void g() { X<int>().f(); }
+}
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index 142edd3..3114bca 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -307,5 +307,5 @@
   typedef E E2;
   E2 f1() { return E::a; }
 
-  bool f() { return !f1(); } // expected-error {{invalid argument type 'E2' (aka 'test11::E') to unary expression}}
+  bool f() { return !f1(); } // expected-error {{invalid argument type 'test11::E2' (aka 'test11::E') to unary expression}}
 }
diff --git a/test/SemaCXX/format-strings.cpp b/test/SemaCXX/format-strings.cpp
index b7ef1d7..a0dcf01 100644
--- a/test/SemaCXX/format-strings.cpp
+++ b/test/SemaCXX/format-strings.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks -std=c++11 %s
 
 #include <stdarg.h>
 
@@ -9,9 +11,13 @@
 }
 
 void f(char **sp, float *fp) {
-  scanf("%as", sp); // expected-warning{{'a' length modifier is not supported by ISO C}}
+  scanf("%as", sp);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{'a' length modifier is not supported by ISO C}}
+#else
+  // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'char **'}}
+#endif
 
-  // TODO: Warn that the 'a' conversion specifier is a C++11 feature.
   printf("%a", 1.0);
   scanf("%afoobar", fp);
 }
@@ -46,11 +52,19 @@
 // Test handling __null for format string literal checking.
 extern "C" {
   int test_null_format(const char *format, ...) __attribute__((__format__ (__printf__, 1, 2)));
+#if __cplusplus >= 201103L
+  // expected-note@-2 {{candidate function not viable: no known conversion from 'bool' to 'const char *' for 1st argument}}
+#endif
 }
 
 void rdar8269537(const char *f)
 {
-  test_null_format(false); // expected-warning {{null from a constant boolean}}
+  test_null_format(false);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{null from a constant boolean}}
+#else
+  // expected-error@-4 {{no matching function for call to 'test_null_format'}}
+#endif
   test_null_format(0); // no-warning
   test_null_format(__null); // no-warning
   test_null_format(f); // expected-warning {{not a string literal}}
diff --git a/test/SemaCXX/friend3.cpp b/test/SemaCXX/friend3.cpp
new file mode 100644
index 0000000..8b83ca7
--- /dev/null
+++ b/test/SemaCXX/friend3.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -S -triple %itanium_abi_triple -std=c++11 -emit-llvm %s -o - | FileCheck %s
+
+namespace pr8852 {
+void foo();
+struct S {
+  friend void foo() {}
+};
+
+void main() {
+  foo();
+}
+// CHECK: define {{.*}} @_ZN6pr88523fooEv
+}
+
+namespace pr9518 {
+template<typename T>
+struct provide {
+  friend T f() { return T(); }
+};
+
+void g() {
+  void f();
+  provide<void> p;
+  f();
+}
+// CHECK: define {{.*}} @_ZN6pr95181fEv
+}
diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp
index 39c6b1f..9e01ccb 100644
--- a/test/SemaCXX/i-c-e-cxx.cpp
+++ b/test/SemaCXX/i-c-e-cxx.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -std=gnu++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -std=gnu++11 %s
 
 // C++-specific tests for integral constant expressions.
 
@@ -16,9 +18,21 @@
 }
 
 int a() {
-  const int t=t; // expected-note {{declared here}} expected-note {{read of object outside its lifetime}}
-  switch(1) { // expected-warning {{no case matching constant switch condition '1'}}
-    case t:; // expected-error {{not an integral constant expression}} expected-note {{initializer of 't' is not a constant expression}}
+  const int t=t; // expected-note {{declared here}}
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{read of object outside its lifetime}}
+#endif
+
+  switch(1) {
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{no case matching constant switch condition '1'}}
+#endif
+    case t:; // expected-note {{initializer of 't' is not a constant expression}}
+#if __cplusplus <= 199711L
+    // expected-error@-2 {{not an integral constant expression}}
+#else
+    // expected-error@-4 {{case value is not a constant expression}}
+#endif
   }
 }
 
@@ -48,7 +62,10 @@
 namespace rdar9204520 {
   
 struct A {
-  static const int B = int(0.75 * 1000 * 1000); // expected-warning {{not a constant expression; folding it to a constant is a GNU extension}}
+  static const int B = int(0.75 * 1000 * 1000);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{not a constant expression; folding it to a constant is a GNU extension}}
+#endif
 };
 
 int foo() { return A::B; }
@@ -59,10 +76,24 @@
 int* y = reinterpret_cast<const char&>(x); // expected-error {{cannot initialize}}
 
 // This isn't an integral constant expression, but make sure it folds anyway.
-struct PR8836 { char _; long long a; }; // expected-warning {{long long}}
-int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))]; // expected-warning {{folded to constant array as an extension}} expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+struct PR8836 { char _; long long a; };
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{'long long' is a C++11 extension}}
+#endif
 
-const int nonconst = 1.0; // expected-note {{declared here}}
-int arr[nonconst]; // expected-warning {{folded to constant array as an extension}} expected-note {{initializer of 'nonconst' is not a constant expression}}
+int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))];
+// expected-warning@-1 {{folded to constant array as an extension}}
+// expected-note@-2 {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+
+const int nonconst = 1.0;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{declared here}}
+#endif
+int arr[nonconst];
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{folded to constant array as an extension}}
+// expected-note@-3 {{initializer of 'nonconst' is not a constant expression}}
+#endif
+
 const int castfloat = static_cast<int>(1.0);
 int arr2[castfloat]; // ok
diff --git a/test/SemaCXX/implicit-exception-spec.cpp b/test/SemaCXX/implicit-exception-spec.cpp
index 12871b8..f400c22 100644
--- a/test/SemaCXX/implicit-exception-spec.cpp
+++ b/test/SemaCXX/implicit-exception-spec.cpp
@@ -16,34 +16,32 @@
   // Noexcept::Noexcept is not declared constexpr, therefore noexcept(Noexcept())
   // is false.
   bool ThrowSomething() noexcept(false);
-  struct ConstExpr { // expected-error {{default member initializer for 'b' needed}}
-    bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-note {{declared here}}
-  // expected-note@-1 {{implicit default constructor for 'InClassInitializers::ConstExpr' first required here}}
+  struct ConstExpr {
+    bool b = // expected-note {{declared here}}
+      noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{default member initializer for 'b' needed}}
   };
 
   // Much more obviously broken: we can't parse the initializer without already
   // knowing whether it produces a noexcept expression.
-  struct TemplateArg { // expected-error {{default member initializer for 'n' needed}}
-    int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-note {{declared here}}
-    // expected-note@-1 {{implicit default constructor for 'InClassInitializers::TemplateArg' first required here}}
+  struct TemplateArg {
+    int n = // expected-note {{declared here}}
+      ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{default member initializer for 'n' needed}}
   };
 
   // And within a nested class.
-  struct Nested { // expected-note {{implicit default constructor for 'InClassInitializers::Nested::Inner' first required here}}
-    struct Inner { // expected-error {{default member initializer for 'n' needed}}
+  struct Nested {
+    struct Inner {
       int n = // expected-note {{declared here}}
-        ExceptionIf<noexcept(Nested())>::f(); // expected-note {{implicit default constructor for 'InClassInitializers::Nested' first required here}}
-    } inner;
+        ExceptionIf<noexcept(Nested())>::f();
+    } inner; // expected-error {{default member initializer for 'n' needed}}
   };
 
-  struct Nested2 { // expected-error {{implicit default constructor for 'InClassInitializers::Nested2' must explicitly initialize the member 'inner' which does not have a default constructor}}
+  struct Nested2 {
     struct Inner;
-    int n = Inner().n; // expected-note {{implicit default constructor for 'InClassInitializers::Nested2::Inner' first required here}}
-    struct Inner { // expected-error {{initializer for 'n' needed}} expected-note {{declared here}}
-      // expected-note@+1 {{declared here}}
-      int n = ExceptionIf<noexcept(Nested2())>::f();
-      // expected-note@-1 {{implicit default constructor for 'InClassInitializers::Nested2' first required here}}
-    } inner; // expected-note {{member is declared here}}
+    int n = Inner().n; // expected-error {{initializer for 'n' needed}}
+    struct Inner {
+      int n = ExceptionIf<noexcept(Nested2())>::f(); // expected-note {{declared here}}
+    } inner;
   };
 }
 
@@ -94,3 +92,61 @@
     } e;
   };
 }
+
+struct nothrow_t {} nothrow;
+void *operator new(decltype(sizeof(0)), nothrow_t) noexcept;
+
+namespace PotentiallyConstructed {
+  template<bool NE> struct A {
+    A() noexcept(NE);
+    A(const A&) noexcept(NE);
+    A(A&&) noexcept(NE);
+    A &operator=(const A&) noexcept(NE);
+    A &operator=(A&&) noexcept(NE);
+    ~A() noexcept(NE);
+  };
+
+  template<bool NE> struct B : virtual A<NE> {};
+
+  template<bool NE> struct C : virtual A<NE> {
+    virtual void f() = 0; // expected-note 2{{unimplemented}}
+  };
+
+  template<bool NE> struct D final : C<NE> {
+    void f();
+  };
+
+  template<typename T, bool A, bool B, bool C, bool D, bool E, bool F> void check() {
+    T *p = nullptr;
+    T &a = *p;
+    static_assert(noexcept(a = a) == D, "");
+    static_assert(noexcept(a = static_cast<T&&>(a)) == E, "");
+    static_assert(noexcept(delete &a) == F, ""); // expected-warning 2{{abstract}}
+
+    // These are last because the first failure here causes instantiation to bail out.
+    static_assert(noexcept(new (nothrow) T()) == A, ""); // expected-error 2{{abstract}}
+    static_assert(noexcept(new (nothrow) T(a)) == B, "");
+    static_assert(noexcept(new (nothrow) T(static_cast<T&&>(a))) == C, "");
+  }
+
+  template void check<A<false>, 0, 0, 0, 0, 0, 0>();
+  template void check<A<true >, 1, 1, 1, 1, 1, 1>();
+  template void check<B<false>, 0, 0, 0, 0, 0, 0>();
+  template void check<B<true >, 1, 1, 1, 1, 1, 1>();
+  template void check<C<false>, 1, 1, 1, 0, 0, 0>(); // expected-note {{instantiation}}
+  template void check<C<true >, 1, 1, 1, 1, 1, 1>(); // expected-note {{instantiation}}
+  template void check<D<false>, 0, 0, 0, 0, 0, 0>();
+  template void check<D<true >, 1, 1, 1, 1, 1, 1>();
+
+  // ... the above trick doesn't work for this case...
+  struct Cfalse : virtual A<false> {
+    virtual void f() = 0;
+
+    Cfalse() noexcept;
+    Cfalse(const Cfalse&) noexcept;
+    Cfalse(Cfalse&&) noexcept;
+  };
+  Cfalse::Cfalse() noexcept = default;
+  Cfalse::Cfalse(const Cfalse&) noexcept = default;
+  Cfalse::Cfalse(Cfalse&&) noexcept = default;
+}
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
index de679fe..1554b1a 100644
--- a/test/SemaCXX/implicit-member-functions.cpp
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -66,7 +66,8 @@
     A(const T &);
     // expected-note@-1 {{in instantiation of default argument}}
   };
-  struct B { // expected-note {{candidate constructor (the implicit move }}
+  struct B { // expected-note {{while declaring the implicit copy constructor for 'B'}}
+    // expected-note@-1 {{candidate constructor (the implicit move }}
     B(); // expected-note {{candidate constructor not viable}}
     A a;
   };
diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp
index f88a55c..319cad7 100644
--- a/test/SemaCXX/implicit-virtual-member-functions.cpp
+++ b/test/SemaCXX/implicit-virtual-member-functions.cpp
@@ -1,33 +1,87 @@
 // RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++11 %s
 // RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++11 %s
+
 struct A {
   virtual ~A();
+#if __cplusplus >= 201103L
+// expected-note@-2 3 {{overridden virtual function is here}}
+#endif
 };
 
-struct B : A { // expected-error {{no suitable member 'operator delete' in 'B'}}
+struct B : A {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{no suitable member 'operator delete' in 'B'}}
+#else
+// expected-error@-4 {{deleted function '~B' cannot override a non-deleted function}}
+// expected-note@-5  {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+#ifdef MSABI
+// expected-note@-7 {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+#endif
+#endif
   virtual void f();
 
-  void operator delete (void *, int); // expected-note {{'operator delete' declared here}}
+  void operator delete (void *, int);
+#if __cplusplus <= 199711L
+// expected-note@-2 {{'operator delete' declared here}}
+#endif
 };
 
 #ifdef MSABI
-B b; // expected-note {{implicit destructor for 'B' first required here}}
+B b;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'B' first required here}}
 #else
-void B::f() { // expected-note {{implicit destructor for 'B' first required here}}
+// expected-error@-4 {{attempt to use a deleted function}}
+#endif
+
+#else
+void B::f() {
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'B' first required here}}
+#endif
 }
 #endif
 
-struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
+struct C : A {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{no suitable member 'operator delete' in 'C'}}
+#else
+// expected-error@-4 {{deleted function '~C' cannot override a non-deleted function}}
+// expected-note@-5  {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+#endif
+
   C();
-  void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
+  void operator delete(void *, int);
+#if __cplusplus <= 199711L
+// expected-note@-2 {{'operator delete' declared here}}
+#endif
 };
 
-C::C() { }  // expected-note {{implicit destructor for 'C' first required here}}
+C::C() { }
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'C' first required here}}
+#endif
 
-struct D : A { // expected-error {{no suitable member 'operator delete' in 'D'}}
-  void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
+struct D : A {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{no suitable member 'operator delete' in 'D'}}
+#else
+// expected-error@-4 {{deleted function '~D' cannot override a non-deleted function}}
+// expected-note@-5  {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+#endif
+  void operator delete(void *, int);
+#if __cplusplus <= 199711L
+// expected-note@-2 {{'operator delete' declared here}}
+#endif
 }; 
 
 void f() {
-  new D; // expected-note {{implicit destructor for 'D' first required here}}
+  new D;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'D' first required here}}
+#endif
 }
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index 4d06fdf..e0ab15d 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -558,3 +558,18 @@
   decltype(a)::D b;
 }
 }
+
+namespace PR30566 {
+int name1; // expected-note {{'name1' declared here}}
+
+struct S1 {
+  template<class T>
+  S1(T t) { s = sizeof(t); }
+  int s;
+};
+
+void foo1() {
+  auto s0 = S1{[name=]() {}}; // expected-error 2 {{expected expression}}
+  auto s1 = S1{[name=name]() {}}; // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
+}
+}
diff --git a/test/SemaCXX/libstdcxx_gets_hack.cpp b/test/SemaCXX/libstdcxx_gets_hack.cpp
new file mode 100644
index 0000000..0d915d0
--- /dev/null
+++ b/test/SemaCXX/libstdcxx_gets_hack.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++14 -verify
+
+// This is a test for an egregious hack in Clang that works around
+// an issue with libstdc++'s detection of whether glibc provides a
+// ::gets function. If there is no ::gets, ignore
+//   using ::gets;
+// in namespace std.
+//
+// See PR18402 and gcc.gnu.org/PR77795 for more details.
+
+#ifdef BE_THE_HEADER
+
+#pragma GCC system_header
+namespace std {
+  using ::gets;
+  using ::getx; // expected-error {{no member named 'getx'}}
+}
+
+#else
+
+#define BE_THE_HEADER
+#include "libstdcxx_pointer_return_false_hack.cpp"
+
+namespace foo {
+  using ::gets; // expected-error {{no member named 'gets'}}
+}
+
+#endif
diff --git a/test/SemaCXX/libstdcxx_pair_swap_hack.cpp b/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
index 9f9c71a..dff599b 100644
--- a/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
+++ b/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
@@ -88,7 +88,7 @@
 
   CLASS<int, int> pi;
 
-  static_assert(!noexcept(pi.swap(pi)), ""); // expected-note {{in instantiation of}}
+  static_assert(!noexcept(pi.swap(pi)), ""); // expected-note 2{{in instantiation of exception specification for 'swap'}}
 }
 
 #endif
diff --git a/test/SemaCXX/make_integer_seq.cpp b/test/SemaCXX/make_integer_seq.cpp
index a9b8d2b..8f72ce1 100644
--- a/test/SemaCXX/make_integer_seq.cpp
+++ b/test/SemaCXX/make_integer_seq.cpp
@@ -43,7 +43,7 @@
                    Blue };
 using illformed1 = ErrorSeq<Color, Blue>; // expected-note{{in instantiation}}
 
-using illformed2 = ErrorSeq<int, -5>;
+using illformed2 = ErrorSeq<int, -5>; // expected-note{{in instantiation}}
 
 template <typename T, T N> void f() {}
 __make_integer_seq<f, int, 0> x; // expected-error{{template template parameter must be a class template or type alias template}}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 836c1f7..c296baa 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall %s
 
 struct Bitfield {
-  int n : 3 = 7; // expected-error {{bitfield member cannot have an in-class initializer}}
+  int n : 3 = 7; // expected-error {{bit-field member cannot have an in-class initializer}}
 };
 
 int a;
@@ -13,10 +13,10 @@
 
 bool b();
 int k;
-struct Recurse { // expected-error {{initializer for 'n' needed}}
+struct Recurse {
   int &n = // expected-note {{declared here}}
       b() ?
-      Recurse().n : // expected-note {{implicit default constructor for 'Recurse' first required here}}
+      Recurse().n : // expected-error {{initializer for 'n' needed}}
       k;
 };
 
@@ -87,7 +87,7 @@
   struct thing {};
   struct another {
     another() : r(thing()) {}
-    // expected-error@-1 {{temporary of type 'const PR14838::function' has private destructor}}
+    // expected-error@-1 {{temporary of type 'PR14838::function' has private destructor}}
     // expected-warning@-2 {{binding reference member 'r' to a temporary value}}
     const function &r; // expected-note {{reference member declared here}}
   } af;
@@ -128,21 +128,19 @@
 namespace template_default_ctor {
 struct A {
   template <typename T>
-  struct B { // expected-error {{initializer for 'm1' needed}}
+  struct B {
     int m1 = 0; // expected-note {{declared here}}
   };
-  // expected-note@+1 {{implicit default constructor for 'template_default_ctor::A::B<int>' first required here}}
-  enum { NOE = noexcept(B<int>()) };
+  enum { NOE = noexcept(B<int>()) }; // expected-error {{initializer for 'm1' needed}}
 };
 }
 
 namespace default_ctor {
 struct A {
-  struct B { // expected-error {{initializer for 'm1' needed}}
+  struct B {
     int m1 = 0; // expected-note {{declared here}}
   };
-  // expected-note@+1 {{implicit default constructor for 'default_ctor::A::B' first required here}}
-  enum { NOE = noexcept(B()) };
+  enum { NOE = noexcept(B()) }; // expected-error {{initializer for 'm1' needed}}
 };
 }
 
@@ -150,19 +148,17 @@
 struct A {
   template <typename T>
   struct B {
-    struct C { // expected-error {{initializer for 'm1' needed}}
+    struct C {
       int m1 = 0; // expected-note {{declared here}}
     };
     template <typename U>
-    struct D { // expected-error {{initializer for 'm1' needed}}
+    struct D {
       int m1 = 0; // expected-note {{declared here}}
     };
   };
   enum {
-    // expected-note@+1 {{implicit default constructor for 'member_template::A::B<int>::C' first required here}}
-    NOE1 = noexcept(B<int>::C()),
-    // expected-note@+1 {{implicit default constructor for 'member_template::A::B<int>::D<int>' first required here}}
-    NOE2 = noexcept(B<int>::D<int>())
+    NOE1 = noexcept(B<int>::C()), // expected-error {{initializer for 'm1' needed}}
+    NOE2 = noexcept(B<int>::D<int>()) // expected-error {{initializer for 'm1' needed}}
   };
 };
 }
diff --git a/test/SemaCXX/microsoft-new-delete.cpp b/test/SemaCXX/microsoft-new-delete.cpp
index b929e61..beba4d9 100644
--- a/test/SemaCXX/microsoft-new-delete.cpp
+++ b/test/SemaCXX/microsoft-new-delete.cpp
@@ -16,7 +16,7 @@
 void *q = new (nc) int[4]; // expected-error {{calling a private constructor}}
 
 struct bitfield { int n : 3; } bf; // expected-note {{here}}
-void *operator new[](size_t, int &);
+void *operator new[](size_t, int &); // expected-note {{passing argument to parameter here}}
 void *operator new(size_t, const int &);
 void *r = new (bf.n) int[4]; // expected-error {{non-const reference cannot bind to bit-field}}
 
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index f445725..6ae45ff 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -310,7 +310,7 @@
 }
 
 namespace TypedefNamespace { typedef int F; };
-TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{'F' (aka 'int') is not a class, namespace, or enumeration}}
+TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{'TypedefNamespace::F' (aka 'int') is not a class, namespace, or enumeration}}
 
 namespace PR18587 {
 
@@ -449,7 +449,7 @@
 class B {
   typedef C D; // expected-error{{unknown type name 'C'}}
   A::D::F;
-  // expected-error@-1{{'D' (aka 'int') is not a class, namespace, or enumeration}}
+  // expected-error@-1{{'PR30619::A::B::D' (aka 'int') is not a class, namespace, or enumeration}}
 };
 }
 }
diff --git a/test/SemaCXX/new-delete-cxx0x.cpp b/test/SemaCXX/new-delete-cxx0x.cpp
index c551525..4ef586f 100644
--- a/test/SemaCXX/new-delete-cxx0x.cpp
+++ b/test/SemaCXX/new-delete-cxx0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -triple=i686-pc-linux-gnu
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -triple=i686-pc-linux-gnu -pedantic
 
 void ugly_news(int *ip) {
   (void)new int[-1]; // expected-error {{array size is negative}}
@@ -29,6 +29,7 @@
   (void) new int[2] {1, 2};
   (void) new S[2] {1, 2};
   (void) new S[3] {1, 2};
+  (void) new S[n] {};
   // 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,
@@ -44,6 +45,7 @@
   (void) new T[2] {1, 2}; // ok
   (void) new T[3] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of array element 2}}
   (void) new T[n] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of trailing array elements in runtime-sized array new}}
+  (void) new T[n] {}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of trailing array elements in runtime-sized array new}}
 }
 
 struct U {
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index e96603d..cb0d030 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -1,7 +1,12 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu -Wno-new-returns-null
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++98
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++11
 
 #include <stddef.h>
 
+#if __cplusplus >= 201103L
+// expected-note@+2 {{candidate constructor (the implicit move constructor) not viable}}
+#endif
 struct S // expected-note {{candidate}}
 {
   S(int, int, double); // expected-note {{candidate}}
@@ -72,7 +77,13 @@
   (void)new; // expected-error {{expected a type}}
   (void)new 4; // expected-error {{expected a type}}
   (void)new () int; // expected-error {{expected expression}}
-  (void)new int[1.1]; // expected-error {{array size expression must have integral or enumeration type, not 'double'}}
+  (void)new int[1.1];
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{array size expression must have integral or enumeration type, not 'double'}}
+#else
+  // expected-error@-4 {{array size expression must have integral or unscoped enumeration type, not 'double'}}
+#endif
+
   (void)new int[1][i]; // expected-error {{only the first dimension}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
   (void)new (int[1][i]); // expected-error {{only the first dimension}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
   (void)new (int[i]); // expected-warning {{when type is in parentheses}}
@@ -85,7 +96,13 @@
   // Undefined, but clang should reject it directly.
   (void)new int[-1]; // expected-error {{array size is negative}}
   (void)new int[2000000000]; // expected-error {{array is too large}}
-  (void)new int[*(S*)0]; // expected-error {{array size expression must have integral or enumeration type, not 'S'}}
+  (void)new int[*(S*)0];
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{array size expression must have integral or enumeration type, not 'S'}}
+#else
+  // expected-error@-4 {{array size expression must have integral or unscoped enumeration type, not 'S'}}
+#endif
+
   (void)::S::new int; // expected-error {{expected unqualified-id}}
   (void)new (0, 0) int; // expected-error {{no matching function for call to 'operator new'}}
   (void)new (0L) int; // expected-error {{call to 'operator new' is ambiguous}}
@@ -109,7 +126,12 @@
 void bad_deletes()
 {
   delete 0; // expected-error {{cannot delete expression of type 'int'}}
-  delete [0] (int*)0; // expected-error {{expected expression}}
+  delete [0] (int*)0;
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{expected expression}}
+#else
+  // expected-error@-4 {{expected variable name or 'this' in lambda capture list}}
+#endif
   delete (void*)0; // expected-warning {{cannot delete expression with pointer-to-'void' type 'void *'}}
   delete (T*)0; // expected-warning {{deleting pointer to incomplete type}}
   ::S::delete (int*)0; // expected-error {{expected unqualified-id}}
@@ -209,14 +231,31 @@
 
 struct X10 {
   virtual ~X10();
+#if __cplusplus >= 201103L
+  // expected-note@-2 {{overridden virtual function is here}}
+#endif
 };
 
-struct X11 : X10 { // expected-error {{no suitable member 'operator delete' in 'X11'}}
-  void operator delete(void*, int); // expected-note {{'operator delete' declared here}}
+struct X11 : X10 {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{no suitable member 'operator delete' in 'X11'}}
+#else
+// expected-error@-4 {{deleted function '~X11' cannot override a non-deleted function}}
+// expected-note@-5 2 {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+#endif
+  void operator delete(void*, int);
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{'operator delete' declared here}}
+#endif
 };
 
 void f() {
-  X11 x11; // expected-note {{implicit destructor for 'X11' first required here}}
+  X11 x11;
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{implicit destructor for 'X11' first required here}}
+#else
+  // expected-error@-4 {{attempt to use a deleted function}}
+#endif
 }
 
 struct X12 {
@@ -398,10 +437,24 @@
 }
 
 namespace ArrayNewNeedsDtor {
-  struct A { A(); private: ~A(); }; // expected-note {{declared private here}}
-  struct B { B(); A a; }; // expected-error {{field of type 'ArrayNewNeedsDtor::A' has private destructor}}
+  struct A { A(); private: ~A(); };
+#if __cplusplus <= 199711L
+  // expected-note@-2 {{declared private here}}
+#endif
+  struct B { B(); A a; };
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{field of type 'ArrayNewNeedsDtor::A' has private destructor}}
+#else
+  // expected-note@-4 {{destructor of 'B' is implicitly deleted because field 'a' has an inaccessible destructor}}
+#endif
+
   B *test9() {
-    return new B[5]; // expected-note {{implicit destructor for 'ArrayNewNeedsDtor::B' first required here}}
+    return new B[5];
+#if __cplusplus <= 199711L
+    // expected-note@-2 {{implicit destructor for 'ArrayNewNeedsDtor::B' first required here}}
+#else
+    // expected-error@-4 {{attempt to use a deleted function}}
+#endif
   }
 }
 
diff --git a/test/SemaCXX/no-wchar.cpp b/test/SemaCXX/no-wchar.cpp
index b6dcddf..040b46c 100644
--- a/test/SemaCXX/no-wchar.cpp
+++ b/test/SemaCXX/no-wchar.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only -fno-wchar -verify %s
+// RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only -fno-wchar -verify -std=c++98 %s
+// RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only -fno-wchar -verify -std=c++11 %s
 wchar_t x; // expected-error {{unknown type name 'wchar_t'}}
 
 typedef unsigned short wchar_t;
@@ -9,7 +11,11 @@
 }
 
 void foo1(wchar_t * t = L"");
-// expected-warning@-1 {{conversion from string literal to 'wchar_t *' (aka 'unsigned short *') is deprecated}}
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{conversion from string literal to 'wchar_t *' (aka 'unsigned short *') is deprecated}}
+#else
+// expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'wchar_t *' (aka 'unsigned short *')}}
+#endif
 
 short *a = L"";
 // expected-error@-1 {{cannot initialize a variable of type 'short *' with an lvalue of type 'const unsigned short [1]'}}
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 3a01bf2..0e3a9ee 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -338,7 +338,7 @@
 
 // Tests the exact text used to note the candidates
 namespace test1 {
-  template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}}
+  template <class T> void foo(T t, unsigned N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}}
   void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}} 
   void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}}
   void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
diff --git a/test/SemaCXX/overload-member-call.cpp b/test/SemaCXX/overload-member-call.cpp
index e0f34d9..6e64b25 100644
--- a/test/SemaCXX/overload-member-call.cpp
+++ b/test/SemaCXX/overload-member-call.cpp
@@ -70,7 +70,7 @@
 // Tests the exact text used to note the candidates
 namespace test1 {
   class A {
-    template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}}
+    template <class T> void foo(T t, unsigned N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}}
     void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}} 
     void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}}
     void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
diff --git a/test/SemaCXX/printf-cstr.cpp b/test/SemaCXX/printf-cstr.cpp
index a7eeb06..32f4d98 100644
--- a/test/SemaCXX/printf-cstr.cpp
+++ b/test/SemaCXX/printf-cstr.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -Wformat -verify %s -Wno-error=non-pod-varargs
+// RUN: %clang_cc1 -fsyntax-only -Wformat -verify -std=c++98 %s -Wno-error=non-pod-varargs
+// RUN: %clang_cc1 -fsyntax-only -Wformat -verify -std=c++11 %s -Wno-error=non-pod-varargs
 
 #include <stdarg.h>
 
@@ -31,12 +33,39 @@
   int n = 10;
 
   printf("%d: %s\n", n, hcs.c_str());
-  printf("%d: %s\n", n, hcs); // expected-warning{{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}}
-  printf("%d: %s\n", n, hncs); // expected-warning{{cannot pass non-POD object of type 'HasNoCStr' to variadic function; expected type from format string was 'char *'}}
-  sprintf(str, "%d: %s", n, hcs); // expected-warning{{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}}
+  printf("%d: %s\n", n, hcs);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}}
+  // expected-note@-3 {{did you mean to call the c_str() method?}}
+#else
+  // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}}
+#endif
 
-  printf(formatString, hcs, hncs); // expected-warning{{cannot pass object of non-POD type 'HasCStr' through variadic function}} expected-warning{{cannot pass object of non-POD type 'HasNoCStr' through variadic function}}
-  printf(extstr, hcs, n); // expected-warning{{cannot pass object of non-POD type 'HasCStr' through variadic function}}
+  printf("%d: %s\n", n, hncs);
+#if __cplusplus <= 199711L
+ // expected-warning@-2 {{cannot pass non-POD object of type 'HasNoCStr' to variadic function; expected type from format string was 'char *'}}
+#else
+  // expected-warning@-4 {{format specifies type 'char *' but the argument has type 'HasNoCStr'}}
+#endif
+
+  sprintf(str, "%d: %s", n, hcs);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}}
+  // expected-note@-3 {{did you mean to call the c_str() method?}}
+#else
+  // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}}
+#endif
+
+  printf(formatString, hcs, hncs);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{cannot pass object of non-POD type 'HasCStr' through variadic function}}
+  // expected-warning@-3 {{cannot pass object of non-POD type 'HasNoCStr' through variadic function}}
+#endif
+
+  printf(extstr, hcs, n);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{cannot pass object of non-POD type 'HasCStr' through variadic function}}
+#endif
 }
 
 struct Printf {
@@ -49,5 +78,11 @@
   const char str[] = "test";
   HasCStr hcs(str);
   Printf p("%s %d %s", str, 10, 10); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
-  Printf q("%s %d", hcs, 10); // expected-warning {{cannot pass non-POD object of type 'HasCStr' to variadic constructor; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}}
+  Printf q("%s %d", hcs, 10);
+#if __cplusplus <= 199711L
+  // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic constructor; expected type from format string was 'char *'}}
+  // expected-note@-3 {{did you mean to call the c_str() method?}}
+#else
+  // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}}
+#endif
 }
diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp
index 45f1eaf..08938bf 100644
--- a/test/SemaCXX/pseudo-destructors.cpp
+++ b/test/SemaCXX/pseudo-destructors.cpp
@@ -89,3 +89,26 @@
 void AliasTemplate(int *p) {
   p->~Id<int>();
 }
+
+namespace dotPointerAccess {
+struct Base {
+  virtual ~Base() {}
+};
+
+struct Derived : Base {
+  ~Derived() {}
+};
+
+void test() {
+  Derived d;
+  static_cast<Base *>(&d).~Base(); // expected-error {{member reference type 'dotPointerAccess::Base *' is a pointer; did you mean to use '->'}}
+  d->~Derived(); // expected-error {{member reference type 'dotPointerAccess::Derived' is not a pointer; did you mean to use '.'}}
+}
+
+typedef Derived *Foo;
+
+void test2(Foo d) {
+  d.~Foo(); // This is ok
+  d.~Derived(); // expected-error {{member reference type 'dotPointerAccess::Foo' (aka 'dotPointerAccess::Derived *') is a pointer; did you mean to use '->'}}
+}
+}
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index 7c88dc0..6cc46d8 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -125,7 +125,7 @@
 
 namespace PR9564 {
   struct a { int a : 10; }; a x;
-  int *y = &reinterpret_cast<int&>(x.a); // expected-error {{not allowed}}
+  int *y = &reinterpret_cast<int&>(x.a); // expected-error {{reinterpret_cast from bit-field lvalue to reference type 'int &'}}
 
   __attribute((ext_vector_type(4))) typedef float v4;
   float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}}
diff --git a/test/SemaCXX/template-ambiguous-overload.cpp b/test/SemaCXX/template-ambiguous-overload.cpp
new file mode 100644
index 0000000..bbb7e39
--- /dev/null
+++ b/test/SemaCXX/template-ambiguous-overload.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace n {
+template <int>
+void f(); // expected-note{{explicit instantiation candidate function 'n::f<0>' template here [with $0 = 0]}}
+
+extern template void f<0>();
+}
+
+using namespace n;
+
+template <int>
+void f() {} // expected-note{{explicit instantiation candidate function 'f<0>' template here [with $0 = 0]}}
+
+template void f<0>(); // expected-error{{partial ordering for explicit instantiation of 'f' is ambiguous}}
+
diff --git a/test/SemaCXX/type-definition-in-specifier.cpp b/test/SemaCXX/type-definition-in-specifier.cpp
index 43443a0..2da649f 100644
--- a/test/SemaCXX/type-definition-in-specifier.cpp
+++ b/test/SemaCXX/type-definition-in-specifier.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -verify %s
 
 struct S0;
 struct S1;
@@ -30,7 +30,7 @@
 
 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'}}
+e19018_1 x2;
 
 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}}
@@ -53,14 +53,17 @@
 
 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'}}
+  en_2 x1;
   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'}}
+  enum en_3 x2;
 };
 
 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'}}
+  long foo5 (float foo6 = foo4);
 };
+
+// expected-error@+2 {{cannot be defined in a parameter type}}
+// expected-note@+1 {{previous definition is here}}
+void func_with_eh_and_type(struct type_in_eh {} o) throw(int) {}
+struct type_in_eh {}; // expected-error {{redefinition of 'type_in_eh'}}
diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp
index 59e6fdf..32151b7 100644
--- a/test/SemaCXX/undefined-internal.cpp
+++ b/test/SemaCXX/undefined-internal.cpp
@@ -186,10 +186,15 @@
   namespace {
     void f();
     void f(int); // expected-warning {{function 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not defined}}
+    void f(int, int); // expected-warning {{function 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not defined}}
   }
-  template<void x()> void t(int*) { x(); }
-  template<void x(int)> void t(long*) { x(10); } // expected-note {{used here}}
-  void g() { long a; t<f>(&a); }
+  template<void x()> void t() { x(); }
+  template<void x(int)> void t(int*) { x(10); }
+  template<void x(int, int)> void t(int*, int*) {}
+  void g(int n) {
+    t<f>(&n); // expected-note {{used here}}
+    t<f>(&n, &n); // expected-note {{used here}}
+  }
 }
 
 namespace test7 {
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 5769a0c..e4928b8 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -Wno-unused-value -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -Wno-unused-value -Wno-unused-lambda-capture -std=c++1z -verify %s
 
 // definitions for std::move
 namespace std {
@@ -1437,3 +1437,13 @@
     [fname]{};
   }
 }
+
+void if_switch_init_stmt(int k) {
+  if (int n = 0; (n == k || k > 5)) {}
+
+  if (int n; (n == k || k > 5)) {} // expected-warning {{uninitialized}} expected-note {{initialize}}
+
+  switch (int n = 0; (n == k || k > 5)) {} // expected-warning {{boolean}}
+
+  switch (int n; (n == k || k > 5)) {} // expected-warning {{uninitialized}} expected-note {{initialize}} expected-warning {{boolean}}
+}
diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp
index 3b2b8e1..d5cc3a0 100644
--- a/test/SemaCXX/using-decl-templates.cpp
+++ b/test/SemaCXX/using-decl-templates.cpp
@@ -90,7 +90,7 @@
   template<typename T> struct A { };
   template<typename T> using APtr = A<T*>; // expected-note{{previous use is here}}
 
-  template struct APtr<int>; // expected-error{{elaborated type refers to a type alias template}}
+  template struct APtr<int>; // expected-error{{type alias template 'APtr' cannot be referenced with a struct specifier}}
 }
 
 namespace DontDiagnoseInvalidTest {
diff --git a/test/SemaCXX/vartemplate-lambda.cpp b/test/SemaCXX/vartemplate-lambda.cpp
index 9dab6da..5b91e23 100644
--- a/test/SemaCXX/vartemplate-lambda.cpp
+++ b/test/SemaCXX/vartemplate-lambda.cpp
@@ -1,18 +1,36 @@
 // RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
-// expected-no-diagnostics
 
 template <class> auto fn0 = [] {};
 template <typename> void foo0() { fn0<char>(); }
 
 template<typename T> auto fn1 = [](auto a) { return a + T(1); };
+template<typename T> auto v1 = [](int a = T(1)) { return a; }();
+
+struct S {
+  template<class T>
+  static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{constexpr variable 't<int>' must be initialized by a constant expression}} expected-error{{a lambda expression may not appear inside of a constant expression}} expected-note{{cannot be used in a constant expression}}
+};
 
 template <typename X>
 int foo2() {
   X a = 0x61;
   fn1<char>(a);
+  (void)v1<int>;
+  (void)S::t<int>; // expected-note{{in instantiation of static data member 'S::t<int>' requested here}}
   return 0;
 }
 
+template<class C>
+int foo3() {
+  C::m1(); // expected-error{{type 'long long' cannot be used prior to '::' because it has no members}}
+  return 1;
+}
+
+template<class C>
+auto v2 = [](int a = foo3<C>()){};  // expected-note{{in instantiation of function template specialization 'foo3<long long>' requested here}}
+
 int main() {
+  v2<long long>();  // This line causes foo3<long long> to be instantiated.
+  v2<long long>(2); // This line does not.
   foo2<int>();
 }
diff --git a/test/SemaCXX/virtual-base-used.cpp b/test/SemaCXX/virtual-base-used.cpp
index c46cf5a..f0dcc96 100644
--- a/test/SemaCXX/virtual-base-used.cpp
+++ b/test/SemaCXX/virtual-base-used.cpp
@@ -1,89 +1,216 @@
 // RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++11 %s
 // RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++11 %s
 // PR7800
 
 // The Microsoft ABI doesn't have the concept of key functions, so we have different
 // expectations about when functions are first required for that case.
 
+class NoDestroy { ~NoDestroy(); };
+#if __cplusplus <= 199711L
+// expected-note@-2 3 {{declared private here}}
 #ifdef MSABI
-// expected-note@+2 3 {{declared private here}}
+// expected-note@-4 3 {{declared private here}}
 #endif
-class NoDestroy { ~NoDestroy(); }; // expected-note 3 {{declared private here}}
+#endif
+
 struct A {
   virtual ~A();
+#if __cplusplus >= 201103L
+  // expected-note@-2 3 {{overridden virtual function is here}}
+#endif
 };
 
-#ifdef MSABI
-// expected-error@+3 {{field of type 'NoDestroy' has private destructor}}
-#endif
 struct B : public virtual A {
-  NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
-};
-#ifdef MSABI
-// expected-note@+3 {{implicit default constructor for 'B' first required here}}
-// expected-note@+2 {{implicit destructor for 'B' first required here}}
+#if __cplusplus >= 201103L
+// expected-error@-2 {{deleted function '~B' cannot override a non-deleted function}}
+// expected-note@-3 {{overridden virtual function is here}}
 #endif
+
+  NoDestroy x;
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{field of type 'NoDestroy' has private destructor}}
+#ifdef MSABI
+  // expected-error@-4 {{field of type 'NoDestroy' has private destructor}}
+#endif
+#else
+  // expected-note@-7 {{destructor of 'B' is implicitly deleted because field 'x' has an inaccessible destructor}}
+#ifdef MSABI
+  // expected-note@-9 {{default constructor of 'B' is implicitly deleted because field 'x' has an inaccessible destructor}}
+#endif
+#endif
+};
+
 struct D : public virtual B {
+#if __cplusplus <= 199711L
+#ifdef MSABI
+// expected-note@-3 {{implicit default constructor for 'B' first required here}}
+// expected-note@-4 {{implicit destructor for 'B' first required here}}
+#endif
+#else
+#ifdef MSABI
+// expected-note@-8 {{default constructor of 'D' is implicitly deleted because base class 'B' has a deleted default constructor}}
+#endif
+#endif
   virtual void foo();
   ~D();
+#if __cplusplus >= 201103L
+  //expected-error@-2 {{non-deleted function '~D' cannot override a deleted function}}
+#endif
 };
+
 #ifdef MSABI
-D d; // expected-note {{implicit default constructor for 'D' first required here}}
+D d;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit default constructor for 'D' first required here}}
 #else
-void D::foo() { // expected-note {{implicit destructor for 'B' first required here}}
+// expected-error@-4 {{call to implicitly-deleted default constructor of 'D'}}
+#endif
+#else
+void D::foo() {
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'B' first required here}}
+#endif
 }
 #endif
 
-#ifdef MSABI
-// expected-error@+3 {{field of type 'NoDestroy' has private destructor}}
-#endif
 struct E : public virtual A {
-  NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
-};
-#ifdef MSABI
-// expected-note@+2 {{implicit default constructor for 'E' first required here}}
+#if __cplusplus >= 201103L
+// expected-error@-2 {{deleted function '~E' cannot override a non-deleted function}}
+// expected-note@-3 {{overridden virtual function is here}}
 #endif
-struct F : public E { // expected-note {{implicit destructor for 'E' first required here}}
-};
+
+  NoDestroy x;
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{field of type 'NoDestroy' has private destructor}}
 #ifdef MSABI
-// expected-note@+2 {{implicit default constructor for 'F' first required here}}
+  // expected-error@-4 {{field of type 'NoDestroy' has private destructor}}
 #endif
+#else
+  // expected-note@-7 {{destructor of 'E' is implicitly deleted because field 'x' has an inaccessible destructor}}
+#ifdef MSABI
+  // expected-note@-9 {{default constructor of 'E' is implicitly deleted because field 'x' has an inaccessible destructor}}
+#endif
+#endif
+};
+
+struct F : public E {
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'E' first required here}}
+#ifdef MSABI
+// expected-note@-4 {{implicit default constructor for 'E' first required here}}
+#endif
+#else
+// expected-error@-7 {{non-deleted function '~F' cannot override a deleted function}}
+// expected-note@-8 {{while declaring the implicit destructor for 'F'}}
+// expected-note@-9 {{overridden virtual function is here}}
+#ifdef MSABI
+// expected-note@-11 {{default constructor of 'F' is implicitly deleted because base class 'E' has a deleted default constructor}}
+#endif
+#endif
+};
+
+
 struct G : public virtual F {
+#ifdef MSABI
+#if __cplusplus <= 199711L
+// expected-note@-3 {{implicit default constructor for 'F' first required here}}
+#else
+// expected-note@-5 {{default constructor of 'G' is implicitly deleted because base class 'F' has a deleted default constructor}}
+#endif
+#endif
+
   virtual void foo();
   ~G();
+#if __cplusplus >= 201103L
+  //expected-error@-2 {{non-deleted function '~G' cannot override a deleted function}}
+#endif
 };
+
 #ifdef MSABI
-G g; // expected-note {{implicit default constructor for 'G' first required here}}
+G g;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit default constructor for 'G' first required here}}
 #else
-void G::foo() { // expected-note {{implicit destructor for 'F' first required here}}
+// expected-error@-4 {{call to implicitly-deleted default constructor of 'G'}}
+#endif
+#else
+void G::foo() {
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'F' first required here}}
+#endif
 }
 #endif
 
-#ifdef MSABI
-// expected-note@+3 {{'H' declared here}}
-// expected-error@+3 {{field of type 'NoDestroy' has private destructor}}
-#endif
 struct H : public virtual A {
-  NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
-};
+#if __cplusplus >= 201103L
+// expected-error@-2 {{deleted function '~H' cannot override a non-deleted function}}
+// expected-note@-3 {{overridden virtual function is here}}
+#else
 #ifdef MSABI
-// expected-error@+3 {{implicit default constructor for 'I' must explicitly initialize the base class 'H' which does not have a default constructor}}
-// expected-note@+2 {{implicit destructor for 'H' first required here}}
+// expected-note@-6 {{'H' declared here}}
 #endif
+#endif
+
+  NoDestroy x;
+#if __cplusplus <= 199711L
+  // expected-error@-2 {{field of type 'NoDestroy' has private destructor}}
+#ifdef MSABI
+  // expected-error@-4 {{field of type 'NoDestroy' has private destructor}}
+#endif
+#else
+  // expected-note@-7 {{destructor of 'H' is implicitly deleted because field 'x' has an inaccessible destructor}}
+#ifdef MSABI
+  // expected-note@-9 {{default constructor of 'H' is implicitly deleted because field 'x' has an inaccessible destructor}}
+#endif
+#endif
+};
+
 struct I : public virtual H {
-  ~I();
-};
 #ifdef MSABI
-// expected-note@+3 {{implicit default constructor for 'H' first required here}}
-// expected-note@+2 {{implicit default constructor for 'I' first required here}}
+#if __cplusplus <= 199711L
+// expected-error@-3 {{implicit default constructor for 'I' must explicitly initialize the base class 'H' which does not have a default constructor}}
+// expected-note@-4 {{implicit destructor for 'H' first required here}}
+#else
+// expected-note@-6 {{default constructor of 'I' is implicitly deleted because base class 'H' has a deleted default constructor}}
 #endif
+#endif
+
+  ~I();
+#if __cplusplus >= 201103L
+// expected-error@-2 {{non-deleted function '~I' cannot override a deleted function}}
+#endif
+};
+
 struct J : public I {
+#ifdef MSABI
+#if __cplusplus <= 199711L
+// expected-note@-3 {{implicit default constructor for 'H' first required here}}
+// expected-note@-4 {{implicit default constructor for 'I' first required here}}
+#else
+// expected-note@-6 {{default constructor of 'J' is implicitly deleted because base class 'I' has a deleted default constructor}}
+#endif
+#endif
+
   virtual void foo();
   ~J();
 };
+
 #ifdef MSABI
-J j; // expected-note {{implicit default constructor for 'J' first required here}}
+J j;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit default constructor for 'J' first required here}}
 #else
-void J::foo() { // expected-note {{implicit destructor for 'H' first required here}}
+// expected-error@-4 {{call to implicitly-deleted default constructor of 'J'}}
+#endif
+
+#else
+void J::foo() {
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'H' first required here}}
+#endif
 }
 #endif
diff --git a/test/SemaCXX/virtual-member-functions-key-function.cpp b/test/SemaCXX/virtual-member-functions-key-function.cpp
index 80ce029..d5bd10c 100644
--- a/test/SemaCXX/virtual-member-functions-key-function.cpp
+++ b/test/SemaCXX/virtual-member-functions-key-function.cpp
@@ -1,20 +1,51 @@
 // 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
+
 struct A {
   virtual ~A();
+#if __cplusplus >= 201103L
+// expected-note@-2 2 {{overridden virtual function is here}}
+#endif
 };
 
-struct B : A {  // expected-error {{no suitable member 'operator delete' in 'B'}}
-  B() { } // expected-note {{implicit destructor for 'B' first required here}}
-  void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
+struct B : A {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{no suitable member 'operator delete' in 'B'}}
+#else
+// expected-error@-4 {{deleted function '~B' cannot override a non-deleted function}}
+// expected-note@-5  {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+#endif
+  B() { }
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'B' first required here}}
+#endif
+
+  void operator delete(void *, int);
+#if __cplusplus <= 199711L
+// expected-note@-2 {{'operator delete' declared here}}
+#endif
 }; 
 
-struct C : A {  // expected-error {{no suitable member 'operator delete' in 'C'}}
-  void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
+struct C : A {
+#if __cplusplus <= 199711L
+// expected-error@-2 {{no suitable member 'operator delete' in 'C'}}
+#else
+// expected-error@-4 {{deleted function '~C' cannot override a non-deleted function}}
+// expected-note@-5  {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+#endif
+  void operator delete(void *, int);
+#if __cplusplus <= 199711L
+// expected-note@-2 {{'operator delete' declared here}}
+#endif
 }; 
 
 void f() {
   (void)new B; 
-  (void)new C; // expected-note {{implicit destructor for 'C' first required here}}
+  (void)new C;
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor for 'C' first required here}}
+#endif
 }
 
 // Make sure that the key-function computation is consistent when the
diff --git a/test/SemaCXX/warn-bool-conversion.cpp b/test/SemaCXX/warn-bool-conversion.cpp
index b0c8d0d..ab563aa 100644
--- a/test/SemaCXX/warn-bool-conversion.cpp
+++ b/test/SemaCXX/warn-bool-conversion.cpp
@@ -1,19 +1,66 @@
 // 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
 
 namespace BooleanFalse {
-int* j = false; // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+int* j = false;
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+#else
+// expected-error@-4 {{cannot initialize a variable of type 'int *' with an rvalue of type 'bool'}}
+#endif
 
-void foo(int* i, int *j=(false)) // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+#if __cplusplus <= 199711L
+// expected-warning@+6 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+#else
+// expected-error@+4 {{cannot initialize a parameter of type 'int *' with an rvalue of type 'bool'}}
+// expected-note@+3 {{passing argument to parameter 'j' here}}
+// expected-note@+2 6 {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+#endif
+void foo(int* i, int *j=(false))
 {
-  foo(false); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
-  foo((int*)false); // no-warning: explicit cast
-  foo(0); // no-warning: not a bool, even though its convertible to bool
+  foo(false);
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+#else
+// expected-error@-4 {{no matching function for call to 'foo'}}
+#endif
 
-  foo(false == true); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
-  foo((42 + 24) < 32); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+  foo((int*)false);
+#if __cplusplus <= 199711L
+// no-warning: explicit cast
+#else
+// expected-error@-4 {{no matching function for call to 'foo'}}
+#endif
+
+  foo(0);
+#if __cplusplus <= 199711L
+// no-warning: not a bool, even though its convertible to bool
+#else
+// expected-error@-4 {{no matching function for call to 'foo'}}
+#endif
+
+  foo(false == true);
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+#else
+// expected-error@-4 {{no matching function for call to 'foo'}}
+#endif
+
+  foo((42 + 24) < 32);
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+#else
+// expected-error@-4 {{no matching function for call to 'foo'}}
+#endif
 
   const bool kFlag = false;
-  foo(kFlag); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+  foo(kFlag);
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
+#else
+// expected-error@-4 {{no matching function for call to 'foo'}}
+#endif
 }
 
 char f(struct Undefined*);
diff --git a/test/SemaCXX/warn-inconsistent-missing-destructor-override b/test/SemaCXX/warn-inconsistent-missing-destructor-override
new file mode 100644
index 0000000..75e9ba8
--- /dev/null
+++ b/test/SemaCXX/warn-inconsistent-missing-destructor-override
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Winconsistent-missing-destructor-override
+
+class A {
+ public:
+  ~A() {}
+  void virtual run() {}
+};
+
+class B : public A {
+ public:
+  void run() override {}
+  ~B() {}
+};
+
+class C {
+ public:
+  virtual void run() {}
+  virtual ~C() {}  // expected-note 2{{overridden virtual function is here}}
+};
+
+class D : public C {
+ public:
+  void run() override {}
+  ~D() {}
+  // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}}
+};
+
+class E : public C {
+ public:
+  void run() override {}
+  virtual ~E() {}
+  // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}}
+};
diff --git a/test/SemaCXX/warn-missing-variable-declarations.cpp b/test/SemaCXX/warn-missing-variable-declarations.cpp
index ad23e04..5b88284 100644
--- a/test/SemaCXX/warn-missing-variable-declarations.cpp
+++ b/test/SemaCXX/warn-missing-variable-declarations.cpp
@@ -47,3 +47,8 @@
     static int x = 0; // no-warn
   }
 };
+
+// There is also no need to use static in anonymous namespaces.
+namespace {
+  int vgood4;
+}
diff --git a/test/SemaCXX/warn-shadow-in-lambdas.cpp b/test/SemaCXX/warn-shadow-in-lambdas.cpp
index 5756644..b0dcd12 100644
--- a/test/SemaCXX/warn-shadow-in-lambdas.cpp
+++ b/test/SemaCXX/warn-shadow-in-lambdas.cpp
@@ -137,3 +137,11 @@
   auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}}
    (auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
 }
+
+void avoidWarningWhenRedefining() {
+  int a = 1;
+  auto l = [b = a] { // expected-note {{previous definition is here}}
+    // Don't warn on redefinitions.
+    int b = 0; // expected-error {{redefinition of 'b'}}
+  };
+}
diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp
index 9d68fe7..1316b6d 100644
--- a/test/SemaCXX/warn-shadow.cpp
+++ b/test/SemaCXX/warn-shadow.cpp
@@ -97,3 +97,13 @@
 void test8() {
   int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
 }
+
+namespace rdar29067894 {
+
+void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition is here}}
+  int a = 0; // expected-note {{previous definition is here}}
+  int a = 1; // expected-error {{redefinition of 'a'}}
+  int b = 2; // expected-error {{redefinition of 'b'}}
+}
+
+}
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
index 6f9e7de..b43e24a 100644
--- a/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 %s
 
 #define LOCKABLE            __attribute__ ((lockable))
 #define SCOPED_LOCKABLE     __attribute__ ((scoped_lockable))
@@ -1266,8 +1268,11 @@
   void foo3(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { }
   void foo4(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu);
 
-  static void foo5()    EXCLUSIVE_LOCKS_REQUIRED(mu); // \
-    // expected-error {{invalid use of member 'mu' in static member function}}
+  static void foo5()    EXCLUSIVE_LOCKS_REQUIRED(mu);
+//FIXME: Bug 32066 - Error should be emitted irrespective of C++ dialect
+#if __cplusplus <= 199711L
+  // expected-error@-3 {{invalid use of member 'mu' in static member function}}
+#endif
 
   template <class T>
   void foo6() EXCLUSIVE_LOCKS_REQUIRED(T::statmu) { }
@@ -1461,15 +1466,24 @@
   mutable Mutex mu;
   int a GUARDED_BY(mu);
 
-  static int si GUARDED_BY(mu); // \
-    // expected-error {{invalid use of non-static data member 'mu'}}
+  static int si GUARDED_BY(mu);
+//FIXME: Bug 32066 - Error should be emitted irrespective of C++ dialect
+#if __cplusplus <= 199711L
+  // expected-error@-3 {{invalid use of non-static data member 'mu'}}
+#endif
 
-  static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \
-    // expected-error {{invalid use of member 'mu' in static member function}}
+  static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu);
+//FIXME: Bug 32066 - Error should be emitted irrespective of C++ dialect
+#if __cplusplus <= 199711L
+  // expected-error@-3 {{invalid use of member 'mu' in static member function}}
+#endif
 
   friend FooStream& operator<<(FooStream& s, const Foo& f)
-    EXCLUSIVE_LOCKS_REQUIRED(mu); // \
-    // expected-error {{invalid use of non-static data member 'mu'}}
+    EXCLUSIVE_LOCKS_REQUIRED(mu);
+//FIXME: Bug 32066 - Error should be emitted irrespective of C++ dialect
+#if __cplusplus <= 199711L
+    // expected-error@-3 {{invalid use of non-static data member 'mu'}}
+#endif
 };
 
 
diff --git a/test/SemaCXX/warn-unused-lambda-capture.cpp b/test/SemaCXX/warn-unused-lambda-capture.cpp
new file mode 100644
index 0000000..48f8bfe
--- /dev/null
+++ b/test/SemaCXX/warn-unused-lambda-capture.cpp
@@ -0,0 +1,188 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-lambda-capture -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++1z %s
+
+class NonTrivialConstructor {
+public:
+  NonTrivialConstructor() {}
+};
+
+class NonTrivialCopyConstructor {
+public:
+  NonTrivialCopyConstructor() = default;
+  NonTrivialCopyConstructor(const NonTrivialCopyConstructor &) {}
+};
+
+class NonTrivialDestructor {
+public:
+  ~NonTrivialDestructor() {}
+};
+
+class Trivial {
+public:
+  Trivial() = default;
+  Trivial(int a) {}
+};
+
+int side_effect() {
+  return 42;
+}
+
+void test() {
+  int i = 0;
+  const int k = 0;
+
+  auto captures_nothing = [] {};
+
+  auto captures_nothing_by_value = [=] {};
+  auto captures_nothing_by_reference = [&] {};
+
+  auto implicit_by_value = [=]() mutable { i++; };
+  auto implicit_by_reference = [&] { i++; };
+
+  auto explicit_by_value_used = [i] { return i + 1; };
+  auto explicit_by_value_used_void = [i] { (void)i; };
+  auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
+  auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
+  auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
+  auto explicit_by_value_unused_const = [k] { return k + 1; };         // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
+
+  auto explicit_by_reference_used = [&i] { i++; };
+  auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
+
+  auto explicit_initialized_reference_used = [&j = i] { return j + 1; };
+  auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}}
+
+  auto explicit_initialized_value_used = [j = 1] { return j + 1; };
+  auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}}
+  auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{};
+  auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{};
+  auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
+  auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
+  auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
+
+  auto nested = [&i] {
+    auto explicit_by_value_used = [i] { return i + 1; };
+    auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
+  };
+
+  Trivial trivial;
+  auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}}
+
+  NonTrivialConstructor cons;
+  auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}}
+
+  NonTrivialCopyConstructor copy_cons;
+  auto explicit_by_value_non_trivial_copy_constructor = [copy_cons] {};
+
+  NonTrivialDestructor dest;
+  auto explicit_by_value_non_trivial_destructor = [dest] {};
+
+  volatile int v;
+  auto explicit_by_value_volatile = [v] {};
+}
+
+class TrivialThis : Trivial {
+  void test() {
+    auto explicit_this_used = [this] { return i; };
+    auto explicit_this_used_void = [this] { (void)this; };
+    auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
+    auto explicit_star_this_used = [*this] { return i; };
+    auto explicit_star_this_used_void = [*this] { (void)this; };
+    auto explicit_star_this_unused = [*this] {}; // expected-warning{{lambda capture 'this' is not used}}
+  }
+  int i;
+};
+
+class NonTrivialConstructorThis : NonTrivialConstructor {
+  void test() {
+    auto explicit_this_used = [this] { return i; };
+    auto explicit_this_used_void = [this] { (void)this; };
+    auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
+    auto explicit_star_this_used = [*this] { return i; };
+    auto explicit_star_this_used_void = [*this] { (void)this; };
+    auto explicit_star_this_unused = [*this] {}; // expected-warning{{lambda capture 'this' is not used}}
+  }
+  int i;
+};
+
+class NonTrivialCopyConstructorThis : NonTrivialCopyConstructor {
+  void test() {
+    auto explicit_this_used = [this] { return i; };
+    auto explicit_this_used_void = [this] { (void)this; };
+    auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
+    auto explicit_star_this_used = [*this] { return i; };
+    auto explicit_star_this_used_void = [*this] { (void)this; };
+    auto explicit_star_this_unused = [*this] {};
+  }
+  int i;
+};
+
+class NonTrivialDestructorThis : NonTrivialDestructor {
+  void test() {
+    auto explicit_this_used = [this] { return i; };
+    auto explicit_this_used_void = [this] { (void)this; };
+    auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
+    auto explicit_star_this_used = [*this] { return i; };
+    auto explicit_star_this_used_void = [*this] { (void)this; };
+    auto explicit_star_this_unused = [*this] {};
+  }
+  int i;
+};
+
+template <typename T>
+void test_templated() {
+  int i = 0;
+  const int k = 0;
+
+  auto captures_nothing = [] {};
+
+  auto captures_nothing_by_value = [=] {};
+  auto captures_nothing_by_reference = [&] {};
+
+  auto implicit_by_value = [=]() mutable { i++; };
+  auto implicit_by_reference = [&] { i++; };
+
+  auto explicit_by_value_used = [i] { return i + 1; };
+  auto explicit_by_value_used_void = [i] { (void)i; };
+  auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
+  auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
+  auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}}
+  auto explicit_by_value_unused_const = [k] { return k + 1; };         // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
+
+  auto explicit_by_reference_used = [&i] { i++; };
+  auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
+
+  auto explicit_initialized_reference_used = [&j = i] { return j + 1; };
+  auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}}
+
+  auto explicit_initialized_value_used = [j = 1] { return j + 1; };
+  auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}}
+  auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{};
+  auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{};
+  auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
+  auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
+  auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
+
+  auto nested = [&i] {
+    auto explicit_by_value_used = [i] { return i + 1; };
+    auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
+  };
+
+  Trivial trivial;
+  auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}}
+
+  NonTrivialConstructor cons;
+  auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}}
+
+  NonTrivialCopyConstructor copy_cons;
+  auto explicit_by_value_non_trivial_copy_constructor = [copy_cons] {};
+
+  NonTrivialDestructor dest;
+  auto explicit_by_value_non_trivial_destructor = [dest] {};
+
+  volatile int v;
+  auto explicit_by_value_volatile = [v] {};
+}
+
+void test_use_template() {
+  test_templated<int>(); // expected-note{{in instantiation of function template specialization 'test_templated<int>' requested here}}
+}
diff --git a/test/SemaCXX/zero-length-arrays.cpp b/test/SemaCXX/zero-length-arrays.cpp
index d86ab86..cca883a 100644
--- a/test/SemaCXX/zero-length-arrays.cpp
+++ b/test/SemaCXX/zero-length-arrays.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 
 // <rdar://problem/10228639>
 class Foo {
@@ -12,6 +13,9 @@
 class Bar {
   int foo_count;
   Foo foos[0];
+#if __cplusplus >= 201103L
+// expected-note@-2 {{copy constructor of 'Bar' is implicitly deleted because field 'foos' has an inaccessible copy constructor}}
+#endif
   Foo foos2[0][2];
   Foo foos3[2][0];
 
@@ -23,5 +27,10 @@
 void testBar() {
   Bar b;
   Bar b2(b);
+#if __cplusplus >= 201103L
+// expected-error@-2 {{call to implicitly-deleted copy constructor of 'Bar}}
+#else
+// expected-no-diagnostics
+#endif
   b = b2;
 }
diff --git a/test/SemaObjC/arc-peformselector.m b/test/SemaObjC/arc-peformselector.m
index dec09e3..80fd6d8 100644
--- a/test/SemaObjC/arc-peformselector.m
+++ b/test/SemaObjC/arc-peformselector.m
@@ -27,6 +27,7 @@
   return [self performSelector : @selector(init)];
   return [self performSelector : sel1]; // expected-warning {{performSelector may cause a leak because its selector is unknown}} \
 					// expected-note {{used here}}
+  return [self performSelector: (@selector(PlusZero))];
 
   return [self performSelector : @selector(PlusZero)];
   return [self performSelector : @selector(PlusOne)]; // expected-error {{performSelector names a selector which retains the object}}
diff --git a/test/SemaObjC/arc-repeated-weak.mm b/test/SemaObjC/arc-repeated-weak.mm
index 11161a0..8e2828f 100644
--- a/test/SemaObjC/arc-repeated-weak.mm
+++ b/test/SemaObjC/arc-repeated-weak.mm
@@ -462,3 +462,16 @@
   use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
   use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}}
 }
+
+// This used to crash in the constructor of WeakObjectProfileTy when a
+// DeclRefExpr was passed that didn't reference a VarDecl.
+
+typedef INTF * INTFPtrTy;
+
+enum E {
+  e1
+};
+
+void foo1() {
+  INTFPtrTy tmp = (INTFPtrTy)e1; // expected-error{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}}
+}
diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m
index f463bb0..e90d0a8 100644
--- a/test/SemaObjC/arc.m
+++ b/test/SemaObjC/arc.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class -Wblock-capture-autoreleasing %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -Wno-objc-root-class -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 typedef unsigned long NSUInteger;
 typedef const void * CFTypeRef;
@@ -809,9 +810,36 @@
   TKAssertEqual(object, (id)nil);
 }
 
-void block_capture_autoreleasing(A * __autoreleasing *a, A **b) { // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+void block_capture_autoreleasing(A * __autoreleasing *a,
+                                 A **b, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 A * _Nullable *c, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 A * _Nullable __autoreleasing *d,
+                                 A ** _Nullable e, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 A * __autoreleasing * _Nullable f,
+                                 id __autoreleasing *g,
+                                 id *h, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 id _Nullable *i, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 id _Nullable __autoreleasing *j,
+                                 id * _Nullable k, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 id __autoreleasing * _Nullable l) {
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:37-[[@LINE-11]]:37}:" __autoreleasing "
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:47-[[@LINE-11]]:47}:" __autoreleasing"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:37-[[@LINE-10]]:37}:" __autoreleasing "
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:36-[[@LINE-8]]:36}:" __autoreleasing"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:46-[[@LINE-8]]:46}:" __autoreleasing"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:36-[[@LINE-7]]:36}:" __autoreleasing"
   ^{
     (void)*a;
     (void)*b; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*c; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*d;
+    (void)*e; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*f;
+    (void)*g;
+    (void)*h; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*i; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*j;
+    (void)*k; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*l;
   }();
 }
diff --git a/test/SemaObjC/block-omitted-return-type.m b/test/SemaObjC/block-omitted-return-type.m
index 20e32e0..93d5e05 100644
--- a/test/SemaObjC/block-omitted-return-type.m
+++ b/test/SemaObjC/block-omitted-return-type.m
@@ -24,7 +24,7 @@
     return;
   };
   void (^simpleBlock5)() = ^ const void { //expected-error {{incompatible block pointer types initializing 'void (^)()' with an expression of type 'const void (^)(void)'}}
-    return;
+    return; // expected-warning@-1 {{function cannot return qualified void type 'const void'}}
   };
   void (^simpleBlock6)() = ^ const (void) { //expected-warning {{'const' qualifier on omitted return type '<dependent type>' has no effect}}
     return;
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index 9377a6c..767d5ac 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -47,7 +47,7 @@
 
 void check_nslog(unsigned k) {
   NSLog(@"%d%%", k); // no-warning
-  NSLog(@"%s%lb%d", "unix", 10,20); // expected-warning {{invalid conversion specifier 'b'}}
+  NSLog(@"%s%lb%d", "unix", 10, 20); // expected-warning {{invalid conversion specifier 'b'}} expected-warning {{data argument not used by format string}}
 }
 
 // Check type validation
diff --git a/test/SemaObjC/objc-class-property.m b/test/SemaObjC/objc-class-property.m
index 5628597..f8d4911 100644
--- a/test/SemaObjC/objc-class-property.m
+++ b/test/SemaObjC/objc-class-property.m
@@ -21,6 +21,8 @@
 @property (class) int c2; // expected-note {{property declared here}} \
                           // expected-note {{property declared here}}
 @property (class) int x;
+@property (class, setter=customSet:) int customSetterProperty;
+@property (class, getter=customGet) int customGetterProperty;
 @end
 
 @implementation A // expected-warning {{class property 'c2' requires method 'c2' to be defined}} \
@@ -29,6 +31,8 @@
 @dynamic (class) x; // refers to the class property
 @synthesize z, c2; // expected-error {{@synthesize not allowed on a class property 'c2'}}
 @dynamic c; // refers to the class property
+@dynamic customSetterProperty;
+@dynamic customGetterProperty;
 @end
 
 int test() {
@@ -37,6 +41,11 @@
   return a.x + A.c;
 }
 
+void customSelectors() {
+  A.customSetterProperty = 1;
+  (void)A.customGetterProperty;
+}
+
 void message_id(id me) {
   [me y];
 }
diff --git a/test/SemaObjC/objcbridge-attribute-arc.m b/test/SemaObjC/objcbridge-attribute-arc.m
index 26dbce0..3bcfdf4 100644
--- a/test/SemaObjC/objcbridge-attribute-arc.m
+++ b/test/SemaObjC/objcbridge-attribute-arc.m
@@ -23,10 +23,7 @@
 
 typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}}
 
-// This error requires C11.
-#if __STDC_VERSION__ > 199901L
-typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}}

-#endif
+typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}}
 
 typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}}
 
diff --git a/test/SemaObjC/unsafe-perform-selector.m b/test/SemaObjC/unsafe-perform-selector.m
new file mode 100644
index 0000000..661ff36
--- /dev/null
+++ b/test/SemaObjC/unsafe-perform-selector.m
@@ -0,0 +1,127 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
+// rdar://12056271
+
+@class Thread;
+
+__attribute__((objc_root_class))
+@interface NSObject
+
+- (id)performSelector:(SEL)sel;
+- (void)performSelectorInBackground:(SEL)sel withObject:(id)arg;
+- (void)performSelectorOnMainThread:(SEL)sel;
+
+- (void)performSelectorOnMainThread:(SEL)aSelector
+                           onThread:(Thread *)thread
+                         withObject:(id)arg
+                      waitUntilDone:(int)wait
+                              modes:(id *)array;
+
+@end
+
+typedef struct { int x; int y; int width; int height; } Rectangle;
+
+struct Struct { Rectangle r; };
+
+typedef union { int x; float f; } Union;
+
+@interface Base : NSObject
+
+- (struct Struct)returnsStruct2; // expected-note {{method 'returnsStruct2' that returns 'struct Struct' declared here}}
+- (Union)returnsId;
+
+@end
+
+@protocol IP
+
+- (Union)returnsUnion; // expected-note 2 {{method 'returnsUnion' that returns 'Union' declared here}}
+
+@end
+
+typedef __attribute__((__ext_vector_type__(3))) float float3;
+typedef int int4 __attribute__ ((vector_size (16)));
+
+@interface I : Base<IP>
+
+- (Rectangle)returnsStruct; // expected-note 4 {{method 'returnsStruct' that returns 'Rectangle' declared here}}
+- (id)returnsId; // shadows base 'returnsId'
+- (int)returnsInt;
+- (I *)returnPtr;
+- (float3)returnsExtVector; // expected-note {{method 'returnsExtVector' that returns 'float3' (vector of 3 'float' values) declared here}}
+- (int4)returnsVector; // expected-note {{method 'returnsVector' that returns 'int4' (vector of 4 'int' values) declared here}}
+
++ (Rectangle)returnsStructClass; // expected-note 2 {{method 'returnsStructClass' that returns 'Rectangle' declared here}}
++ (void)returnsUnion; // Not really
+
+@end
+
+void foo(I *i) {
+  [i performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+  [i performSelectorInBackground: @selector(returnsStruct) withObject:0]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a struct type}}
+  [i performSelector: ((@selector(returnsUnion)))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a union type}}
+  [i performSelectorOnMainThread: @selector(returnsStruct2)]; // expected-warning {{'performSelectorOnMainThread:' is incompatible with selectors that return a struct type}}
+  [I performSelector: (@selector(returnsStructClass))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+
+  [i performSelector: @selector(returnsId)];
+  [i performSelector: @selector(returnsInt)];
+  [i performSelector: @selector(returnsPtr)];
+  [I performSelector: @selector(returnsUnion)]; // No warning expected
+
+  id obj = i;
+  [obj performSelector: @selector(returnsId)];
+  [obj performSelector: @selector(returnsStruct)];
+}
+
+@interface SubClass: I
+
+@end
+
+@interface SubClass ()
+- (struct Struct)returnsSubStructExt; // expected-note {{method 'returnsSubStructExt' that returns 'struct Struct' declared here}} expected-note {{method 'returnsSubStructExt' declared here}}
+@end
+
+@implementation SubClass // expected-warning {{method definition for 'returnsSubStructExt' not found}}
+
+- (struct Struct)returnsSubStructImpl { // expected-note {{method 'returnsSubStructImpl' that returns 'struct Struct' declared here}}
+  struct Struct Result;
+  return Result;
+}
+
+- (void)checkPrivateCalls {
+  [self performSelector: @selector(returnsSubStructExt)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+  [self performSelector: @selector(returnsSubStructImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+}
+
+- (void)checkSuperCalls {
+  [super performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+  [super performSelectorInBackground: @selector(returnsUnion) withObject: self]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a union type}}
+  [super performSelector: @selector(returnsId)];
+}
+
++ (struct Struct)returnsSubStructClassImpl { // expected-note {{method 'returnsSubStructClassImpl' that returns 'struct Struct' declared here}}
+  struct Struct Result;
+  return Result;
+}
+
++ (void)checkClassPrivateCalls {
+  [self performSelector: @selector(returnsSubStructClassImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+}
+
++ (void)checkClassSuperCalls {
+  [super performSelector: @selector(returnsStructClass)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+  [super performSelector: @selector(returnsUnion)]; // No warning expected
+}
+
+@end
+
+@implementation I (LongPerformSelectors)
+
+- (void)checkLongCallsFromCategory {
+  [self performSelectorOnMainThread: @selector(returnsStruct) onThread:0 withObject:self waitUntilDone:1 modes:0]; // expected-warning {{'performSelectorOnMainThread:onThread:withObject:waitUntilDone:modes:' is incompatible with selectors that return a struct type}}
+}
+
+- (void)checkVectorReturn {
+  [self performSelector: @selector(returnsExtVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}}
+  [self performSelector: @selector(returnsVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}}
+}
+
+@end
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-1.h b/test/SemaObjCXX/Inputs/nullability-consistency-1.h
index a99f091..f04b569 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-1.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-1.h
@@ -1,22 +1,32 @@
 void f1(int *ptr); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
 
 void f2(int * _Nonnull);
 
 #include "nullability-consistency-2.h"
 
 void f3(int *ptr) { // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
   int *other = ptr; // shouldn't warn
 }
 
 class X {
   void mf(int *ptr); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
   int X:: *memptr; // expected-warning{{member pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the member pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the member pointer should never be null}}
 };
 
 template <typename T>
 struct Typedefs {
   typedef T *Base; // no-warning
   typedef Base *type; // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
 };
 
 Typedefs<int> xx;
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-2.h b/test/SemaObjCXX/Inputs/nullability-consistency-2.h
index 5203146..72f22e2 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-2.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-2.h
@@ -1,11 +1,17 @@
 void g1(int * _Nonnull);
 
 void g2(int (^block)(int, int)); // expected-warning{{block pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the block pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the block pointer should never be null}}
 
 void g3(const
         id // expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
         volatile
         * // expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
         ); 
 
 @interface SomeClass
@@ -14,8 +20,12 @@
 - (nullable SomeClass *)method1;
 - (void)method2:(nonnull SomeClass *)param;
 @property (readonly, weak) SomeClass *property3; // expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
 @end
 
 @interface SomeClass ()
 @property (readonly, weak) SomeClass *property4; // expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
 @end
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-3.h b/test/SemaObjCXX/Inputs/nullability-consistency-3.h
index 520d1a4..e188151 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-3.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-3.h
@@ -1 +1,3 @@
 void double_declarator1(int *_Nonnull *); // expected-warning{{pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-4.h b/test/SemaObjCXX/Inputs/nullability-consistency-4.h
index ac227a0..935c093 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-4.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-4.h
@@ -1 +1,3 @@
 void double_declarator1(int * * _Nonnull); // expected-warning{{pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-5.h b/test/SemaObjCXX/Inputs/nullability-consistency-5.h
index 1c74ab8..30666c2 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-5.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-5.h
@@ -7,6 +7,8 @@
 void suppress1(SUPPRESS_NULLABILITY_WARNING(int *) ptr); // no warning
 
 void shouldwarn5(int *ptr); //expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
 
 void trigger5(int * _Nonnull);
 
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-6.h b/test/SemaObjCXX/Inputs/nullability-consistency-6.h
index d1764a8..e9b2f9b 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-6.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-6.h
@@ -1,8 +1,11 @@
 int *ptr; // expected-warning {{missing a nullability type specifier}}
-
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 #pragma clang assume_nonnull begin
 
 extern void **blah; // expected-warning 2{{missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
 
 __attribute__((objc_root_class))
 @interface ClassWithWeakProperties
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-7.h b/test/SemaObjCXX/Inputs/nullability-consistency-7.h
index ddbdfad..ed61666 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-7.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-7.h
@@ -33,7 +33,11 @@
 
 @interface C : A
 - (instancetype)init; // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 - (instancetype)initWithA:( A*)a __attribute__((objc_designated_initializer)); // expected-warning 2{{pointer is missing a nullability type specifier}}
+// expected-note@-1 2{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2{{insert '_Nonnull' if the pointer should never be null}}
 @end
 
 #endif
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-8.h b/test/SemaObjCXX/Inputs/nullability-consistency-8.h
index 2425a70..1f71315 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-8.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-8.h
@@ -8,10 +8,14 @@
 void func2(mynonnull i);
 
 void func3(int *); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 
 #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
 typedef void *CFTypeRef;
-void cf1(CFTypeRef * p CF_RETURNS_NOT_RETAINED); // expected-warning {{pointer is missing a nullability type specifier}}
+void cf1(CFTypeRef * p CF_RETURNS_NOT_RETAINED); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 
 void cf2(CFTypeRef * _Nullable p CF_RETURNS_NOT_RETAINED);
 void cf3(CFTypeRef * _Nonnull p CF_RETURNS_NOT_RETAINED);
@@ -23,5 +27,7 @@
 void cf7(CF_RETURNS_NOT_RETAINED CFTypeRef * _Nonnull p);
 
 typedef CFTypeRef _Nullable *CFTypeRefPtr;
-void cfp1(CFTypeRefPtr p CF_RETURNS_NOT_RETAINED); // expected-warning {{pointer is missing a nullability type specifier}}
+void cfp1(CFTypeRefPtr p CF_RETURNS_NOT_RETAINED); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 void cfp2(CFTypeRefPtr _Nonnull p CF_RETURNS_NOT_RETAINED);
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h b/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h
index 900930c..d0d5125 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-arrays.h
@@ -2,12 +2,16 @@
 
 void firstThingInTheFileThatNeedsNullabilityIsAnArray(int ints[]);
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
 
 int *secondThingInTheFileThatNeedsNullabilityIsAPointer;
 #if !ARRAYS_CHECKED
 // expected-warning@-2 {{pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-note@-3 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the pointer should never be null}}
 #endif
 
 int *_Nonnull triggerConsistencyWarnings;
@@ -15,21 +19,35 @@
 void test(
     int ints[],
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
     void *ptrs[], // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-4 {{array parameter is missing a nullability type specifier}}
+// expected-note@-5 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-6 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
     void **nestedPtrs[]); // expected-warning 2 {{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-4 {{array parameter is missing a nullability type specifier}}
+// expected-note@-5 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-6 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
 
 void testArraysOK(
     int ints[_Nonnull],
     void *ptrs[_Nonnull], // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
     void **nestedPtrs[_Nonnull]); // expected-warning 2 {{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
 void testAllOK(
     int ints[_Nonnull],
     void * _Nullable ptrs[_Nonnull],
@@ -57,7 +75,9 @@
 
 void nestedArrays(int x[5][1]) {}
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
 void nestedArraysOK(int x[_Nonnull 5][1]) {}
 
@@ -72,13 +92,17 @@
 void typedefTest(
     INTS x,
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
     INTS _Nonnull x2,
     _Nonnull INTS x3,
     INTS y[2],
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
     INTS y2[_Nonnull 2]);
 
@@ -87,15 +111,23 @@
 void testAssumeNonnull(
   int ints[],
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
   void *ptrs[],
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
   void **nestedPtrs[]); // expected-warning 2 {{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
 #if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-4 {{array parameter is missing a nullability type specifier}}
+// expected-note@-5 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-6 {{insert '_Nonnull' if the array parameter should never be null}}
 #endif
 
 void testAssumeNonnullAllOK(
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-system/nullability-consistency-system.h b/test/SemaObjCXX/Inputs/nullability-consistency-system/nullability-consistency-system.h
index 9161af1..43e29e0 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-system/nullability-consistency-system.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-system/nullability-consistency-system.h
@@ -3,6 +3,8 @@
 void system1(int *ptr);
 #if WARN_IN_SYSTEM_HEADERS
 // expected-warning@-2{{pointer is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the pointer should never be null}}
 #endif
 
 void system2(int * _Nonnull);
diff --git a/test/SemaObjCXX/Inputs/nullability-pragmas-1.h b/test/SemaObjCXX/Inputs/nullability-pragmas-1.h
index 4ac813d..91753ca 100644
--- a/test/SemaObjCXX/Inputs/nullability-pragmas-1.h
+++ b/test/SemaObjCXX/Inputs/nullability-pragmas-1.h
@@ -9,6 +9,8 @@
 struct X { };
 
 void f1(int *x); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 
 typedef struct __attribute__((objc_bridge(NSError))) __CFError *CFErrorRef;
 typedef NSError *NSErrorPtr;
@@ -39,15 +41,29 @@
 A * _Null_unspecified f16(void);
 void f17(CFErrorRef *error); // expected-note{{no known conversion from 'A * _Nonnull' to 'CFErrorRef  _Nullable * _Nullable' (aka '__CFError **') for 1st argument}}
 void f18(A **); // expected-warning 2{{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
 void f19(CFErrorRefPtr error); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 
 void g1(int (^)(int, int));
 void g2(int (^ *bp)(int, int)); // expected-warning{{block pointer is missing a nullability type specifier}}
-// expected-warning@-1{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the block pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the block pointer should never be null}}
+// expected-warning@-3{{pointer is missing a nullability type specifier}}
+// expected-note@-4{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-5{{insert '_Nonnull' if the pointer should never be null}}
 void g3(block_ptr *bp); // expected-warning{{block pointer is missing a nullability type specifier}}
-// expected-warning@-1{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the block pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the block pointer should never be null}}
+// expected-warning@-3{{pointer is missing a nullability type specifier}}
+// expected-note@-4{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-5{{insert '_Nonnull' if the pointer should never be null}}
 void g4(int (*fp)(int, int));
 void g5(int (**fp)(int, int)); // expected-warning 2{{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
 
 @interface A(Pragmas1)
 + (instancetype)aWithA:(A *)a;
@@ -57,9 +73,13 @@
 - (void)method4:(NSErrorPtr *)error; // expected-note{{passing argument to parameter 'error' here}}
 - (void)method5:(NSErrorPtrPtr)error;
 // expected-warning@-1{{pointer is missing a nullability type specifier}}
+// expected-note@-2{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-3{{insert '_Nonnull' if the pointer should never be null}}
 
 @property A *aProp;
 @property NSError **anError; // expected-warning 2{{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
 @end
 
 int *global_int_ptr;
@@ -68,6 +88,8 @@
 typedef int *int_ptr_2;
 
 typedef int * // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
             *int_ptr_ptr;
 
 static inline void f30(void) {
@@ -90,12 +112,22 @@
 #pragma clang assume_nonnull end
 
 void f20(A *a); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 void f21(int_ptr x); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 void f22(A_ptr y); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 void f23(int_ptr _Nullable x);
 void f24(A_ptr _Nullable y);
 void f25(int_ptr_2 x); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 
 @interface A(OutsidePragmas1)
 + (instancetype)aWithInt:(int)value; // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
 @end
diff --git a/test/SemaObjCXX/arc-system-header.mm b/test/SemaObjCXX/arc-system-header.mm
index 5f5445c..00ffad7 100644
--- a/test/SemaObjCXX/arc-system-header.mm
+++ b/test/SemaObjCXX/arc-system-header.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fobjc-arc -isystem %S/Inputs %s -verify
+// RUN: %clang_cc1 -std=gnu++98 -fobjc-arc -isystem %S/Inputs %s -verify
 
 #include <arc-system-header.h>
 
diff --git a/test/SemaObjCXX/arc-templates.mm b/test/SemaObjCXX/arc-templates.mm
index 97854df..2a7d11f 100644
--- a/test/SemaObjCXX/arc-templates.mm
+++ b/test/SemaObjCXX/arc-templates.mm
@@ -102,8 +102,8 @@
 template<typename T>
 struct make_weak_fail {
   typedef T T_type;
-  typedef __weak T_type type; // expected-error{{the type 'T_type' (aka '__weak id') is already explicitly ownership-qualified}} \
-  // expected-error{{the type 'T_type' (aka '__strong id') is already explicitly ownership-qualified}}
+  typedef __weak T_type type; // expected-error{{the type 'make_weak_fail<__weak id>::T_type' (aka '__weak id') is already explicitly ownership-qualified}} \
+  // expected-error{{the type 'make_weak_fail<id>::T_type' (aka '__strong id') is already explicitly ownership-qualified}}
 };
 
 int check_make_weak_fail0[is_same<make_weak_fail<__weak id>::type, __weak id>::value? 1 : -1]; // expected-note{{in instantiation of template class 'make_weak_fail<__weak id>' requested here}}
diff --git a/test/SemaObjCXX/blocks.mm b/test/SemaObjCXX/blocks.mm
index 09d614d..bdd5538 100644
--- a/test/SemaObjCXX/blocks.mm
+++ b/test/SemaObjCXX/blocks.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class -std=c++14 %s
 @protocol NSObject;
 
 void bar(id(^)(void));
@@ -144,3 +144,28 @@
 
   template void f<X>(X);
 }
+
+namespace GenericLambdaCapture {
+int test(int outerp) {
+  auto lambda =[&](auto p) {
+    return ^{
+      return p + outerp;
+    }();
+  };
+  return lambda(1);
+}
+}
+
+namespace MoveBlockVariable {
+struct B0 {
+};
+
+struct B1 { // expected-note 2 {{candidate constructor (the implicit}}
+  B1(B0&&); // expected-note {{candidate constructor not viable}}
+};
+
+B1 test_move() {
+  __block B0 b;
+  return b; // expected-error {{no viable conversion from returned value of type 'MoveBlockVariable::B0' to function return type 'MoveBlockVariable::B1'}}
+}
+}
diff --git a/test/SemaObjCXX/ivar-construct.mm b/test/SemaObjCXX/ivar-construct.mm
index 473c0bf..1498275 100644
--- a/test/SemaObjCXX/ivar-construct.mm
+++ b/test/SemaObjCXX/ivar-construct.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -std=gnu++98 -fsyntax-only -verify -Wno-objc-root-class %s
 struct Y { 
   Y(); 
 
diff --git a/test/SemaObjCXX/typo-correction.mm b/test/SemaObjCXX/typo-correction.mm
index a34a790..5e33bfb 100644
--- a/test/SemaObjCXX/typo-correction.mm
+++ b/test/SemaObjCXX/typo-correction.mm
@@ -21,3 +21,18 @@
   self.m_prop2 = new ClassB(m_prop1); // expected-error {{use of undeclared identifier 'm_prop1'; did you mean '_m_prop1'?}}
 }
 @end
+
+// rdar://30310772
+
+@interface InvalidNameInIvarAndPropertyBase
+{
+@public
+  float  _a;
+}
+@property float _b;
+@end
+
+void invalidNameInIvarAndPropertyBase() {
+  float a = ((InvalidNameInIvarAndPropertyBase*)node)->_a; // expected-error {{use of undeclared identifier 'node'}}
+  float b = ((InvalidNameInIvarAndPropertyBase*)node)._b; // expected-error {{use of undeclared identifier 'node'}}
+}
diff --git a/test/SemaOpenCL/access-qualifier.cl b/test/SemaOpenCL/access-qualifier.cl
index 7bc9741..35e838b 100644
--- a/test/SemaOpenCL/access-qualifier.cl
+++ b/test/SemaOpenCL/access-qualifier.cl
@@ -74,3 +74,7 @@
   myPipeWrite(p); // expected-error {{passing 'read_only pipe int' to parameter of incompatible type 'write_only pipe int'}}
 }
 #endif
+
+#if __OPENCL_C_VERSION__ < 200
+kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes extension to be enabled}}
+#endif
diff --git a/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl b/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl
index 97fd07a..73e29e7 100644
--- a/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl
+++ b/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl
@@ -18,14 +18,20 @@
 
 #ifdef GENERIC
 #define AS generic
+#define AS_COMP local
+#define AS_INCOMP constant
 #endif
 
 #ifdef GLOBAL
 #define AS global
+#define AS_COMP global
+#define AS_INCOMP local
 #endif
 
 #ifdef CONSTANT
 #define AS constant
+#define AS_COMP constant
+#define AS_INCOMP global
 #endif
 
 void f_glob(global int *arg_glob) {}
@@ -263,12 +269,16 @@
   var_void_gen = 0 ? var_cond : var_glob_ch;
 #ifdef CONSTANT
 // expected-error@-2{{conditional operator with the second and third operands of type  ('__constant int *' and '__global char *') which are pointers to non-overlapping address spaces}}
+#else
+// expected-warning-re@-4{{pointer type mismatch ('__{{global|generic}} int *' and '__global char *')}}
 #endif
 
   local char *var_loc_ch;
   var_void_gen = 0 ? var_cond : var_loc_ch;
 #ifndef GENERIC
 // expected-error-re@-2{{conditional operator with the second and third operands of type  ('__{{global|constant}} int *' and '__local char *') which are pointers to non-overlapping address spaces}}
+#else
+// expected-warning@-4{{pointer type mismatch ('__generic int *' and '__local char *')}}
 #endif
 
   constant void *var_void_const;
@@ -276,18 +286,45 @@
   var_void_const = 0 ? var_cond : var_const_ch;
 #ifndef CONSTANT
 // expected-error-re@-2{{conditional operator with the second and third operands of type  ('__{{global|generic}} int *' and '__constant char *') which are pointers to non-overlapping address spaces}}
+#else
+// expected-warning@-4{{pointer type mismatch ('__constant int *' and '__constant char *')}}
 #endif
 
   private char *var_priv_ch;
   var_void_gen = 0 ? var_cond : var_priv_ch;
 #ifndef GENERIC
 // expected-error-re@-2{{conditional operator with the second and third operands of type  ('__{{global|constant}} int *' and 'char *') which are pointers to non-overlapping address spaces}}
+#else
+// expected-warning@-4{{pointer type mismatch ('__generic int *' and 'char *')}}
 #endif
 
   generic char *var_gen_ch;
   var_void_gen = 0 ? var_cond : var_gen_ch;
 #ifdef CONSTANT
 // expected-error@-2{{conditional operator with the second and third operands of type  ('__constant int *' and '__generic char *') which are pointers to non-overlapping address spaces}}
+#else
+// expected-warning-re@-4{{pointer type mismatch ('__{{global|generic}} int *' and '__generic char *')}}
 #endif
 }
 
+void test_pointer_chains() {
+  AS int *AS *var_as_as_int;
+  AS int *AS_COMP *var_asc_as_int;
+  AS_INCOMP int *AS_COMP *var_asc_asn_int;
+  AS_COMP int *AS_COMP *var_asc_asc_int;
+
+  // Case 1:
+  //  * address spaces of corresponded most outer pointees overlaps, their canonical types are equal
+  //  * CVR, address spaces and canonical types of the rest of pointees are equivalent.
+  var_as_as_int = 0 ? var_as_as_int : var_asc_as_int;
+
+  // Case 2: Corresponded inner pointees has non-overlapping address spaces.
+  var_as_as_int = 0 ? var_as_as_int : var_asc_asn_int;
+// expected-warning-re@-1{{pointer type mismatch ('__{{(generic|global|constant)}} int *__{{(generic|global|constant)}} *' and '__{{(local|global|constant)}} int *__{{(constant|local|global)}} *')}}
+
+  // Case 3: Corresponded inner pointees has overlapping but not equivalent address spaces.
+#ifdef GENERIC
+  var_as_as_int = 0 ? var_as_as_int : var_asc_asc_int;
+// expected-warning-re@-1{{pointer type mismatch ('__{{(generic|global|constant)}} int *__{{(generic|global|constant)}} *' and '__{{(local|global|constant)}} int *__{{(local|global|constant)}} *')}}
+#endif
+}
diff --git a/test/SemaOpenCL/builtins-amdgcn-error-f16.cl b/test/SemaOpenCL/builtins-amdgcn-error-f16.cl
index 7fa4717..3487b1a 100644
--- a/test/SemaOpenCL/builtins-amdgcn-error-f16.cl
+++ b/test/SemaOpenCL/builtins-amdgcn-error-f16.cl
@@ -1,9 +1,10 @@
 // REQUIRES: amdgpu-registered-target
-// RUN: %clang_cc1 -triple amdgcn-- -target-cpu tahiti -verify -S -o - %s
+// RUN: %clang_cc1 -triple amdgcn-- -verify -S -o - %s
 
 #pragma OPENCL EXTENSION cl_khr_fp16 : enable
 
-void test_f16(global half *out, half a, half b, half c)
+__attribute__((target("arch=tahiti")))
+void test_f16_tahiti(global half *out, half a, half b, half c)
 {
   *out = __builtin_amdgcn_div_fixuph(a, b, c); // expected-error {{'__builtin_amdgcn_div_fixuph' needs target feature 16-bit-insts}}
   *out = __builtin_amdgcn_rcph(a); // expected-error {{'__builtin_amdgcn_rcph' needs target feature 16-bit-insts}}
@@ -15,4 +16,5 @@
   *out = __builtin_amdgcn_frexp_exph(a); // expected-error {{'__builtin_amdgcn_frexp_exph' needs target feature 16-bit-insts}}
   *out = __builtin_amdgcn_fracth(a); // expected-error {{'__builtin_amdgcn_fracth' needs target feature 16-bit-insts}}
   *out = __builtin_amdgcn_classh(a, b); // expected-error {{'__builtin_amdgcn_classh' needs target feature 16-bit-insts}}
+  *out = __builtin_amdgcn_fmed3h(a, b, c); // expected-error {{'__builtin_amdgcn_fmed3h' needs target feature gfx9-insts}}
 }
diff --git a/test/SemaOpenCL/builtins-amdgcn-error-gfx9.cl b/test/SemaOpenCL/builtins-amdgcn-error-gfx9.cl
new file mode 100644
index 0000000..c9fd8ab
--- /dev/null
+++ b/test/SemaOpenCL/builtins-amdgcn-error-gfx9.cl
@@ -0,0 +1,9 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-- -target-cpu fiji -verify -S -o - %s
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+void test_gfx9_fmed3h(global half *out, half a, half b, half c)
+{
+  *out = __builtin_amdgcn_fmed3h(a, b, c); // expected-error {{'__builtin_amdgcn_fmed3h' needs target feature gfx9-insts}}
+}
diff --git a/test/SemaOpenCL/builtins-amdgcn-error.cl b/test/SemaOpenCL/builtins-amdgcn-error.cl
index 83ccbef..2639bf2 100644
--- a/test/SemaOpenCL/builtins-amdgcn-error.cl
+++ b/test/SemaOpenCL/builtins-amdgcn-error.cl
@@ -1,16 +1,17 @@
 // REQUIRES: amdgpu-registered-target
 // RUN: %clang_cc1 -triple amdgcn-- -target-cpu tahiti -verify -S -o - %s
 
-// FIXME: We only get one error if the functions are the other order in the
-// file.
-
 #pragma OPENCL EXTENSION cl_khr_fp64 : enable
 typedef unsigned long ulong;
 typedef unsigned int uint;
 
-ulong test_s_memrealtime()
+// To get all errors for feature checking we need to put them in one function
+// since Clang will stop codegen for the next function if it finds error during
+// codegen of the previous function.
+void test_target_builtin(global int* out, int a)
 {
-  return __builtin_amdgcn_s_memrealtime(); // expected-error {{'__builtin_amdgcn_s_memrealtime' needs target feature s-memrealtime}}
+  __builtin_amdgcn_s_memrealtime(); // expected-error {{'__builtin_amdgcn_s_memrealtime' needs target feature s-memrealtime}}
+  *out = __builtin_amdgcn_mov_dpp(a, 0, 0, 0, false); // expected-error {{'__builtin_amdgcn_mov_dpp' needs target feature dpp}}
 }
 
 void test_s_sleep(int x)
@@ -18,6 +19,31 @@
   __builtin_amdgcn_s_sleep(x); // expected-error {{argument to '__builtin_amdgcn_s_sleep' must be a constant integer}}
 }
 
+void test_s_waitcnt(int x)
+{
+  __builtin_amdgcn_s_waitcnt(x); // expected-error {{argument to '__builtin_amdgcn_s_waitcnt' must be a constant integer}}
+}
+
+void test_s_sendmsg(int in)
+{
+  __builtin_amdgcn_s_sendmsg(in, 1); // expected-error {{argument to '__builtin_amdgcn_s_sendmsg' must be a constant integer}}
+}
+
+void test_s_sendmsg_var(int in1, int in2)
+{
+  __builtin_amdgcn_s_sendmsg(in1, in2); // expected-error {{argument to '__builtin_amdgcn_s_sendmsg' must be a constant integer}}
+}
+
+void test_s_sendmsghalt(int in)
+{
+  __builtin_amdgcn_s_sendmsghalt(in, 1); // expected-error {{argument to '__builtin_amdgcn_s_sendmsghalt' must be a constant integer}}
+}
+
+void test_s_sendmsghalt_var(int in1, int in2)
+{
+  __builtin_amdgcn_s_sendmsghalt(in1, in2); // expected-error {{argument to '__builtin_amdgcn_s_sendmsghalt' must be a constant integer}}
+}
+
 void test_s_incperflevel(int x)
 {
   __builtin_amdgcn_s_incperflevel(x); // expected-error {{argument to '__builtin_amdgcn_s_incperflevel' must be a constant integer}}
@@ -62,3 +88,17 @@
 {
   *out = __builtin_amdgcn_ds_swizzle(a, b); // expected-error {{argument to '__builtin_amdgcn_ds_swizzle' must be a constant integer}}
 }
+
+void test_s_getreg(global int* out, int a)
+{
+  *out = __builtin_amdgcn_s_getreg(a); // expected-error {{argument to '__builtin_amdgcn_s_getreg' must be a constant integer}}
+}
+
+void test_mov_dpp2(global int* out, int a, int b, int c, int d, bool e)
+{
+  *out = __builtin_amdgcn_mov_dpp(a, b, 0, 0, false); // expected-error {{argument to '__builtin_amdgcn_mov_dpp' must be a constant integer}}
+  *out = __builtin_amdgcn_mov_dpp(a, 0, c, 0, false); // expected-error {{argument to '__builtin_amdgcn_mov_dpp' must be a constant integer}}
+  *out = __builtin_amdgcn_mov_dpp(a, 0, 0, d, false); // expected-error {{argument to '__builtin_amdgcn_mov_dpp' must be a constant integer}}
+  *out = __builtin_amdgcn_mov_dpp(a, 0, 0, 0, e); // expected-error {{argument to '__builtin_amdgcn_mov_dpp' must be a constant integer}}
+}
+
diff --git a/test/SemaOpenCL/cl20-device-side-enqueue.cl b/test/SemaOpenCL/cl20-device-side-enqueue.cl
index c98145c..3e87cfc 100644
--- a/test/SemaOpenCL/cl20-device-side-enqueue.cl
+++ b/test/SemaOpenCL/cl20-device-side-enqueue.cl
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 %s -cl-std=CL2.0 -triple "spir-unknown-unknown" -verify -pedantic -fsyntax-only -DB32
 // RUN: %clang_cc1 %s -cl-std=CL2.0 -triple "spir64-unknown-unknown" -verify -pedantic -fsyntax-only -Wconversion -DWCONV
 
+typedef struct {int a;} ndrange_t;
 // Diagnostic tests for different overloads of enqueue_kernel from Table 6.13.17.1 of OpenCL 2.0 Spec.
 kernel void enqueue_kernel_tests() {
   queue_t default_queue;
@@ -30,7 +31,7 @@
 
   enqueue_kernel(default_queue, flags, ndrange, vptr); // expected-error{{illegal call to enqueue_kernel, expected block argument}}
 
-  enqueue_kernel(default_queue, flags, ndrange, ^(int i) { // expected-error{{blocks in this form of device side enqueue call are expected to have have no parameters}}
+  enqueue_kernel(default_queue, flags, ndrange, ^(int i) { // expected-error{{blocks with parameters are not accepted in this prototype of enqueue_kernel call}}
     return 0;
   });
 
@@ -111,7 +112,7 @@
 
   const bl_B_t block_B = (bl_B_t) ^ (local void *a, local int *b) {};
 
-  enqueue_kernel(default_queue, flags, ndrange, block_B, 1024, 1024); // expected-error{{blocks used in device side enqueue are expected to have parameters of type 'local void*'}}
+  enqueue_kernel(default_queue, flags, ndrange, block_B, 1024, 1024); // expected-error{{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
 
   enqueue_kernel(default_queue, flags, ndrange, // expected-error{{mismatch in number of block parameters and local size arguments passed}}
                  ^(local void *a, local void *b) {
@@ -177,12 +178,12 @@
   size = get_kernel_work_group_size(^(local void *a) {
     return;
   });
-  size = get_kernel_work_group_size(^(local int *a) { // expected-error {{blocks used in device side enqueue are expected to have parameters of type 'local void*'}}
+  size = get_kernel_work_group_size(^(local int *a) { // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
     return;
   });
-  size = get_kernel_work_group_size(block_B);   // expected-error {{blocks used in device side enqueue are expected to have parameters of type 'local void*'}}
-  size = get_kernel_work_group_size(block_D);   // expected-error {{blocks used in device side enqueue are expected to have parameters of type 'local void*'}}
-  size = get_kernel_work_group_size(^(int a) {  // expected-error {{blocks used in device side enqueue are expected to have parameters of type 'local void*'}}
+  size = get_kernel_work_group_size(block_B);   // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
+  size = get_kernel_work_group_size(block_D);   // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
+  size = get_kernel_work_group_size(^(int a) {  // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
     return;
   });
   size = get_kernel_work_group_size();          // expected-error {{too few arguments to function call, expected 1, have 0}}
@@ -194,14 +195,14 @@
   size = get_kernel_preferred_work_group_size_multiple(^(local void *a) {
     return;
   });
-  size = get_kernel_preferred_work_group_size_multiple(^(local int *a) { // expected-error {{blocks used in device side enqueue are expected to have parameters of type 'local void*'}}
+  size = get_kernel_preferred_work_group_size_multiple(^(local int *a) { // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
     return;
   });
-  size = get_kernel_preferred_work_group_size_multiple(^(int a) {  // expected-error {{blocks used in device side enqueue are expected to have parameters of type 'local void*'}}
+  size = get_kernel_preferred_work_group_size_multiple(^(int a) {  // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
     return;
   });
-  size = get_kernel_preferred_work_group_size_multiple(block_B);   // expected-error {{blocks used in device side enqueue are expected to have parameters of type 'local void*'}}
-  size = get_kernel_preferred_work_group_size_multiple(block_D);   // expected-error {{blocks used in device side enqueue are expected to have parameters of type 'local void*'}}
+  size = get_kernel_preferred_work_group_size_multiple(block_B);   // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
+  size = get_kernel_preferred_work_group_size_multiple(block_D);   // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
   size = get_kernel_preferred_work_group_size_multiple();          // expected-error {{too few arguments to function call, expected 1, have 0}}
   size = get_kernel_preferred_work_group_size_multiple(1);         // expected-error{{expected block argument}}
   size = get_kernel_preferred_work_group_size_multiple(block_A, 1); // expected-error{{too many arguments to function call, expected 1, have 2}}
diff --git a/test/SemaOpenCL/extension-begin.cl b/test/SemaOpenCL/extension-begin.cl
new file mode 100644
index 0000000..3393458
--- /dev/null
+++ b/test/SemaOpenCL/extension-begin.cl
@@ -0,0 +1,56 @@
+// Test this without pch.
+// RUN: %clang_cc1 %s -DHEADER -DHEADER_USER -triple spir-unknown-unknown -verify -pedantic -fsyntax-only
+
+// Test with pch.
+// RUN: %clang_cc1 %s -DHEADER -triple spir-unknown-unknown -emit-pch -o %t -verify -pedantic
+// RUN: %clang_cc1 %s -DHEADER_USER -triple spir-unknown-unknown -include-pch %t -fsyntax-only -verify -pedantic
+
+#if defined(HEADER) && !defined(INCLUDED)
+#define INCLUDED 
+
+#pragma OPENCL EXTENSION all : begin // expected-warning {{expected 'disable' - ignoring}}
+#pragma OPENCL EXTENSION all : end // expected-warning {{expected 'disable' - ignoring}}
+
+#pragma OPENCL EXTENSION my_ext : begin 
+
+struct A {
+  int a;
+};
+
+typedef struct A TypedefOfA;
+typedef const TypedefOfA* PointerOfA;
+
+void f(void);
+
+__attribute__((overloadable)) void g(long x);
+
+#pragma OPENCL EXTENSION my_ext : end
+#pragma OPENCL EXTENSION my_ext : end // expected-warning {{OpenCL extension end directive mismatches begin directive - ignoring}}
+
+__attribute__((overloadable)) void g(void);
+
+#endif // defined(HEADER) && !defined(INCLUDED)
+
+#ifdef HEADER_USER
+
+#pragma OPENCL EXTENSION my_ext : enable
+void test_f1(void) {
+  struct A test_A1;
+  f();
+  g(0);
+}
+
+#pragma OPENCL EXTENSION my_ext : disable 
+void test_f2(void) {
+  struct A test_A2; // expected-error {{use of type 'struct A' requires my_ext extension to be enabled}}
+  const struct A test_A_local; // expected-error {{use of type 'struct A' requires my_ext extension to be enabled}}
+  TypedefOfA test_typedef_A; // expected-error {{use of type 'TypedefOfA' (aka 'struct A') requires my_ext extension to be enabled}}
+  PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const struct A *') requires my_ext extension to be enabled}}
+  f(); // expected-error {{use of declaration requires my_ext extension to be enabled}}
+  g(0); // expected-error {{no matching function for call to 'g'}}
+        // expected-note@-26 {{candidate disabled due to OpenCL extension}}
+        // expected-note@-22 {{candidate function not viable: requires 0 arguments, but 1 was provided}}
+}
+
+#endif // HEADER_USER
+
diff --git a/test/SemaOpenCL/extensions.cl b/test/SemaOpenCL/extensions.cl
index 48e6e09..6afb11e 100644
--- a/test/SemaOpenCL/extensions.cl
+++ b/test/SemaOpenCL/extensions.cl
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.1
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.2 -DFP64
 
 // Test with a target not supporting fp64.
 // RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64 -DNOFP16
@@ -21,12 +22,37 @@
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -cl-ext=+cl_khr_fp64 -cl-ext=+cl_khr_fp16 -cl-ext=-cl_khr_fp64 -DNOFP64
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -cl-ext=+cl_khr_fp64,-cl_khr_fp64,+cl_khr_fp16 -DNOFP64
 
+// Test with -finclude-default-header, which includes opencl-c.h. opencl-c.h
+// disables all extensions by default, but supported core extensions for a
+// particular OpenCL version must be re-enabled (for example, cl_khr_fp64 is
+// enabled by default with -cl-std=CL2.0).
+//
+// RUN: %clang_cc1 %s -triple amdgcn-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL2.0 -finclude-default-header
 
+#ifdef _OPENCL_H_
+// expected-no-diagnostics
+#endif
 
+#ifdef FP64
+// expected-no-diagnostics
+#endif
+
+#if __OPENCL_C_VERSION__ < 120
 void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}}
   double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
   (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}}
 }
+#endif
+
+#ifndef _OPENCL_H_
+int isnan(float x) {
+    return __builtin_isnan(x);
+}
+
+int isfinite(float x) {
+    return __builtin_isfinite(x);
+}
+#endif
 
 #pragma OPENCL EXTENSION cl_khr_fp64 : enable
 #ifdef NOFP64
@@ -45,8 +71,9 @@
 #endif
 
   (void) 1.0;
+
 #ifdef NOFP64
-// expected-warning@-2{{double precision constant requires cl_khr_fp64, casting to single precision}}
+// expected-warning@-3{{double precision constant requires cl_khr_fp64, casting to single precision}}
 #endif
 }
 
@@ -55,6 +82,8 @@
 // expected-warning@-2{{unsupported OpenCL extension 'cl_khr_fp64' - ignoring}}
 #endif
 
+#if __OPENCL_C_VERSION__ < 120
 void f3(void) {
   double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
 }
+#endif
diff --git a/test/SemaOpenCL/extern.cl b/test/SemaOpenCL/extern.cl
index 5f1f9f8..66efd70 100644
--- a/test/SemaOpenCL/extern.cl
+++ b/test/SemaOpenCL/extern.cl
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -x cl -cl-opt-disable -cl-std=CL1.2 -emit-llvm -ffake-address-space-map %s -o - -verify | FileCheck %s
 // expected-no-diagnostics
 
-// CHECK: @foo = external addrspace(3) constant float
+// CHECK: @foo = external addrspace(2) constant float
 extern constant float foo;
 
 kernel void test(global float* buf) {
diff --git a/test/SemaOpenCL/invalid-block.cl b/test/SemaOpenCL/invalid-block.cl
index a9eac1c..89bf032 100644
--- a/test/SemaOpenCL/invalid-block.cl
+++ b/test/SemaOpenCL/invalid-block.cl
@@ -4,26 +4,34 @@
 void f0(int (^const bl)());
 // All blocks declarations must be const qualified and initialized.
 void f1() {
-  int (^bl1)() = ^() {return 1;};
-  int (^const bl2)() = ^(){return 1;};
+  int (^bl1)(void) = ^() {
+    return 1;
+  };
+  int (^const bl2)(void) = ^() {
+    return 1;
+  };
   f0(bl1);
   f0(bl2);
-  bl1 = bl2; // expected-error{{invalid operands to binary expression ('int (^const)()' and 'int (^const)()')}}
+  bl1 = bl2;          // expected-error{{invalid operands to binary expression ('int (__generic ^const)(void)' and 'int (__generic ^const)(void)')}}
   int (^const bl3)(); // expected-error{{invalid block variable declaration - must be initialized}}
 }
 
 // A block with extern storage class is not allowed.
-extern int (^bl)() = ^(){return 1;}; // expected-error{{invalid block variable declaration - using 'extern' storage class is disallowed}}
+extern int (^bl)(void) = ^() { // expected-error{{invalid block variable declaration - using 'extern' storage class is disallowed}}
+  return 1;
+};
 void f2() {
-  extern int (^bl)() = ^(){return 1;}; // expected-error{{invalid block variable declaration - using 'extern' storage class is disallowed}}
+  extern int (^bl)(void) = ^() { // expected-error{{invalid block variable declaration - using 'extern' storage class is disallowed}}
+    return 1;
+  };
 }
 
 // A block cannot be the return value of a function.
 typedef int (^bl_t)(void);
-bl_t f3(bl_t bl); // expected-error{{declaring function return value of type 'bl_t' (aka 'int (^const)(void)') is not allowed}}
+bl_t f3(bl_t bl); // expected-error{{declaring function return value of type 'bl_t' (aka 'int (__generic ^const)(void)') is not allowed}}
 
 struct bl_s {
-  int (^bl)(void); // expected-error {{the 'int (^const)(void)' type cannot be used to declare a structure or union field}}
+  int (^bl)(void); // expected-error {{the 'int (__generic ^const)(void)' type cannot be used to declare a structure or union field}}
 };
 
 void f4() {
@@ -45,16 +53,31 @@
   bl2_t bl2 = ^(int i) {
     return 2;
   };
-  bl2_t arr[] = {bl1, bl2}; // expected-error {{array of 'bl2_t' (aka 'int (^const)(int)') type is invalid in OpenCL}}
+  bl2_t arr[] = {bl1, bl2}; // expected-error {{array of 'bl2_t' (aka 'int (__generic ^const)(int)') type is invalid in OpenCL}}
   int tmp = i ? bl1(i)      // expected-error {{block type cannot be used as expression in ternary expression in OpenCL}}
               : bl2(i);     // expected-error {{block type cannot be used as expression in ternary expression in OpenCL}}
 }
 // A block pointer type and all pointer operations are disallowed
-void f6(bl2_t *bl_ptr) { // expected-error{{pointer to type '__generic bl2_t' (aka 'int (^const __generic)(int)') is invalid in OpenCL}}
+void f6(bl2_t *bl_ptr) { // expected-error{{pointer to type '__generic bl2_t' (aka 'int (__generic ^const __generic)(int)') is invalid in OpenCL}}
   bl2_t bl = ^(int i) {
     return 1;
   };
-  bl2_t *p; // expected-error {{pointer to type '__generic bl2_t' (aka 'int (^const __generic)(int)') is invalid in OpenCL}}
-  *bl;      // expected-error {{invalid argument type 'bl2_t' (aka 'int (^const)(int)') to unary expression}}
-  &bl;      // expected-error {{invalid argument type 'bl2_t' (aka 'int (^const)(int)') to unary expression}}
+  bl2_t *p; // expected-error {{pointer to type '__generic bl2_t' (aka 'int (__generic ^const __generic)(int)') is invalid in OpenCL}}
+  *bl;      // expected-error {{invalid argument type 'bl2_t' (aka 'int (__generic ^const)(int)') to unary expression}}
+  &bl;      // expected-error {{invalid argument type 'bl2_t' (aka 'int (__generic ^const)(int)') to unary expression}}
+}
+// A block can't reference another block
+kernel void f7() {
+  bl2_t bl1 = ^(int i) {
+    return 1;
+  };
+  void (^bl2)(void) = ^{
+    int i = bl1(1); // expected-error {{cannot refer to a block inside block}}
+  };
+  void (^bl3)(void) = ^{
+  };
+  void (^bl4)(void) = ^{
+    bl3(); // expected-error {{cannot refer to a block inside block}}
+  };
+  return;
 }
diff --git a/test/SemaOpenCL/invalid-kernel.cl b/test/SemaOpenCL/invalid-kernel.cl
index 9a50673..031f606 100644
--- a/test/SemaOpenCL/invalid-kernel.cl
+++ b/test/SemaOpenCL/invalid-kernel.cl
@@ -1,10 +1,11 @@
 // RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -cl-std=CL2.0 -verify %s
 
-kernel void no_ptrptr(global int **i) { } // expected-error{{kernel parameter cannot be declared as a pointer to a pointer}}
+kernel void no_ptrptr(global int * global *i) { } // expected-error{{kernel parameter cannot be declared as a pointer to a pointer}}
 
-__kernel void no_privateptr(__private int *i) { } // expected-error {{kernel parameter cannot be declared as a pointer to the __private address space}}
+__kernel void no_privateptr(__private int *i) { } // expected-error {{pointer arguments to kernel functions must reside in '__global', '__constant' or '__local' address space}}
 
-__kernel void no_privatearray(__private int i[]) { } // expected-error {{kernel parameter cannot be declared as a pointer to the __private address space}}
+__kernel void no_privatearray(__private int i[]) { } // expected-error {{pointer arguments to kernel functions must reside in '__global', '__constant' or '__local' address space}}
 
 kernel int bar()  { // expected-error {{kernel must have void return type}}
   return 6;
@@ -29,3 +30,6 @@
 int* constant x(int* x) { // expected-error {{return value cannot be qualified with address space}}
   return x + 1;
 }
+
+__kernel void testKernel(int *ptr) { // expected-error {{pointer arguments to kernel functions must reside in '__global', '__constant' or '__local' address space}}
+}
diff --git a/test/SemaOpenCL/invalid-logical-ops-1.1.cl b/test/SemaOpenCL/invalid-logical-ops-1.1.cl
deleted file mode 100644
index 2269dd3..0000000
--- a/test/SemaOpenCL/invalid-logical-ops-1.1.cl
+++ /dev/null
@@ -1,57 +0,0 @@
-// RUN: %clang_cc1 %s -verify -cl-std=CL1.1 -triple x86_64-unknown-linux-gnu
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-typedef __attribute__((ext_vector_type(4))) float float4;
-typedef __attribute__((ext_vector_type(4))) double double4;
-typedef __attribute__((ext_vector_type(4))) int int4;
-typedef __attribute__((ext_vector_type(4))) long long4;
-
-kernel void float_ops() {
-  int flaf = 0.0f && 0.0f; // expected-error {{invalid operands}}
-  int flof = 0.0f || 0.0f; // expected-error {{invalid operands}}
-  float fbaf = 0.0f & 0.0f; // expected-error {{invalid operands}}
-  float fbof = 0.0f | 0.0f; // expected-error {{invalid operands}}
-  float fbxf = 0.0f ^ 0.0f; // expected-error {{invalid operands}}
-  int flai = 0.0f && 0; // expected-error {{invalid operands}}
-  int floi = 0.0f || 0; // expected-error {{invalid operands}}
-  float ibaf = 0 & 0.0f; // expected-error {{invalid operands}}
-  float ibof = 0 | 0.0f; // expected-error {{invalid operands}}
-  float bnf = ~0.0f; // expected-error {{invalid argument type}}
-  float lnf = !0.0f; // expected-error {{invalid argument type}}
-}
-
-kernel void vec_float_ops() {
-  float4 f4 = (float4)(0, 0, 0, 0);
-  int4 f4laf = f4 && 0.0f; // expected-error {{invalid operands}}
-  int4 f4lof = f4 || 0.0f; // expected-error {{invalid operands}}
-  float4 f4baf = f4 & 0.0f; // expected-error {{invalid operands}}
-  float4 f4bof = f4 | 0.0f; // expected-error {{invalid operands}}
-  float4 f4bxf = f4 ^ 0.0f; // expected-error {{invalid operands}}
-  float bnf4 = ~f4; // expected-error {{invalid argument type}}
-  int4 lnf4 = !f4; // expected-error {{invalid argument type}}
-}
-
-kernel void double_ops() {
-  int flaf = 0.0 && 0.0; // expected-error {{invalid operands}}
-  int flof = 0.0 || 0.0; // expected-error {{invalid operands}}
-  double fbaf = 0.0 & 0.0; // expected-error {{invalid operands}}
-  double fbof = 0.0 | 0.0; // expected-error {{invalid operands}}
-  double fbxf = 0.0 ^ 0.0; // expected-error {{invalid operands}}
-  int flai = 0.0 && 0; // expected-error {{invalid operands}}
-  int floi = 0.0 || 0; // expected-error {{invalid operands}}
-  double ibaf = 0 & 0.0; // expected-error {{invalid operands}}
-  double ibof = 0 | 0.0; // expected-error {{invalid operands}}
-  double bnf = ~0.0; // expected-error {{invalid argument type}}
-  double lnf = !0.0; // expected-error {{invalid argument type}}
-}
-
-kernel void vec_double_ops() {
-  double4 f4 = (double4)(0, 0, 0, 0);
-  long4 f4laf = f4 && 0.0; // expected-error {{invalid operands}}
-  long4 f4lof = f4 || 0.0; // expected-error {{invalid operands}}
-  double4 f4baf = f4 & 0.0; // expected-error {{invalid operands}}
-  double4 f4bof = f4 | 0.0; // expected-error {{invalid operands}}
-  double4 f4bxf = f4 ^ 0.0; // expected-error {{invalid operands}}
-  double bnf4 = ~f4; // expected-error {{invalid argument type}}
-  long4 lnf4 = !f4; // expected-error {{invalid argument type}}
-}
diff --git a/test/SemaOpenCL/invalid-logical-ops-1.2.cl b/test/SemaOpenCL/invalid-logical-ops-1.2.cl
deleted file mode 100644
index bee5239..0000000
--- a/test/SemaOpenCL/invalid-logical-ops-1.2.cl
+++ /dev/null
@@ -1,58 +0,0 @@
-// RUN: %clang_cc1 %s -verify -cl-std=CL1.2 -triple x86_64-unknown-linux-gnu
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-typedef __attribute__((ext_vector_type(4))) float float4;
-typedef __attribute__((ext_vector_type(4))) double double4;
-typedef __attribute__((ext_vector_type(4))) int int4;
-typedef __attribute__((ext_vector_type(4))) long long4;
-
-kernel void float_ops() {
-  int flaf = 0.0f && 0.0f;
-  int flof = 0.0f || 0.0f;
-  float fbaf = 0.0f & 0.0f; // expected-error {{invalid operands}}
-  float fbof = 0.0f | 0.0f; // expected-error {{invalid operands}}
-  float fbxf = 0.0f ^ 0.0f; // expected-error {{invalid operands}}
-  int flai = 0.0f && 0;
-  int floi = 0.0f || 0;
-  float ibaf = 0 & 0.0f; // expected-error {{invalid operands}}
-  float ibof = 0 | 0.0f; // expected-error {{invalid operands}}
-  float bnf = ~0.0f;// expected-error {{invalid argument type}}
-  float lnf = !0.0f;
-}
-
-kernel void vec_float_ops() {
-  float4 f4 = (float4)(0, 0, 0, 0);
-  int4 f4laf = f4 && 0.0f;
-  int4 f4lof = f4 || 0.0f;
-  float4 f4baf = f4 & 0.0f; // expected-error {{invalid operands}}
-  float4 f4bof = f4 | 0.0f; // expected-error {{invalid operands}}
-  float4 f4bxf = f4 ^ 0.0f; // expected-error {{invalid operands}}
-  float bnf4 = ~f4; // expected-error {{invalid argument type}}
-  int4 lnf4 = !f4;
-}
-
-kernel void double_ops() {
-  int flaf = 0.0 && 0.0;
-  int flof = 0.0 || 0.0;
-  double fbaf = 0.0 & 0.0; // expected-error {{invalid operands}}
-  double fbof = 0.0 | 0.0; // expected-error {{invalid operands}}
-  double fbxf = 0.0 ^ 0.0; // expected-error {{invalid operands}}
-  int flai = 0.0 && 0;
-  int floi = 0.0 || 0;
-  double ibaf = 0 & 0.0; // expected-error {{invalid operands}}
-  double ibof = 0 | 0.0; // expected-error {{invalid operands}}
-  double bnf = ~0.0; // expected-error {{invalid argument type}}
-  double lnf = !0.0;
-}
-
-kernel void vec_double_ops() {
-  double4 f4 = (double4)(0, 0, 0, 0);
-  long4 f4laf = f4 && 0.0;
-  long4 f4lof = f4 || 0.0;
-  double4 f4baf = f4 & 0.0; // expected-error {{invalid operands}}
-  double4 f4bof = f4 | 0.0; // expected-error {{invalid operands}}
-  double4 f4bxf = f4 ^ 0.0; // expected-error {{invalid operands}}
-  double bnf4 = ~f4; // expected-error {{invalid argument type}}
-  long4 lnf4 = !f4;
-}
diff --git a/test/SemaOpenCL/logical-ops.cl b/test/SemaOpenCL/logical-ops.cl
new file mode 100644
index 0000000..42501b1
--- /dev/null
+++ b/test/SemaOpenCL/logical-ops.cl
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 %s -verify -cl-std=CL1.1 -triple x86_64-unknown-linux-gnu
+// RUN: %clang_cc1 %s -verify -cl-std=CL1.2 -triple x86_64-unknown-linux-gnu
+// RUN: %clang_cc1 %s -verify -cl-std=CL2.0 -triple x86_64-unknown-linux-gnu
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+typedef __attribute__((ext_vector_type(4))) float float4;
+typedef __attribute__((ext_vector_type(4))) double double4;
+typedef __attribute__((ext_vector_type(4))) int int4;
+typedef __attribute__((ext_vector_type(4))) long long4;
+
+kernel void float_ops() {
+  int flaf = 0.0f && 0.0f;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  int flof = 0.0f || 0.0f;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  float fbaf = 0.0f & 0.0f; // expected-error {{invalid operands}}
+  float fbof = 0.0f | 0.0f; // expected-error {{invalid operands}}
+  float fbxf = 0.0f ^ 0.0f; // expected-error {{invalid operands}}
+  int flai = 0.0f && 0;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  int floi = 0.0f || 0;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  float ibaf = 0 & 0.0f; // expected-error {{invalid operands}}
+  float ibof = 0 | 0.0f; // expected-error {{invalid operands}}
+  float bnf = ~0.0f;// expected-error {{invalid argument type}}
+  float lnf = !0.0f;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid argument type}}
+#endif
+}
+
+kernel void vec_float_ops() {
+  float4 f4 = (float4)(0, 0, 0, 0);
+  int4 f4laf = f4 && 0.0f;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  int4 f4lof = f4 || 0.0f;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  float4 f4baf = f4 & 0.0f; // expected-error {{invalid operands}}
+  float4 f4bof = f4 | 0.0f; // expected-error {{invalid operands}}
+  float4 f4bxf = f4 ^ 0.0f; // expected-error {{invalid operands}}
+  float bnf4 = ~f4; // expected-error {{invalid argument type}}
+  int4 lnf4 = !f4;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid argument type}}
+#endif
+}
+
+kernel void double_ops() {
+  int flaf = 0.0 && 0.0;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  int flof = 0.0 || 0.0;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  double fbaf = 0.0 & 0.0; // expected-error {{invalid operands}}
+  double fbof = 0.0 | 0.0; // expected-error {{invalid operands}}
+  double fbxf = 0.0 ^ 0.0; // expected-error {{invalid operands}}
+  int flai = 0.0 && 0;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  int floi = 0.0 || 0;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  double ibaf = 0 & 0.0; // expected-error {{invalid operands}}
+  double ibof = 0 | 0.0; // expected-error {{invalid operands}}
+  double bnf = ~0.0; // expected-error {{invalid argument type}}
+  double lnf = !0.0;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid argument type}}
+#endif
+}
+
+kernel void vec_double_ops() {
+  double4 f4 = (double4)(0, 0, 0, 0);
+  long4 f4laf = f4 && 0.0;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  long4 f4lof = f4 || 0.0;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid operands}}
+#endif
+  double4 f4baf = f4 & 0.0; // expected-error {{invalid operands}}
+  double4 f4bof = f4 | 0.0; // expected-error {{invalid operands}}
+  double4 f4bxf = f4 ^ 0.0; // expected-error {{invalid operands}}
+  double bnf4 = ~f4; // expected-error {{invalid argument type}}
+  long4 lnf4 = !f4;
+#if __OPENCL_C_VERSION__ < 120
+// expected-error@-2{{invalid argument type}}
+#endif
+}
+
+kernel void pointer_ops(){
+  global int* p;
+  bool b = !p;
+  b = p==0;
+  int i;
+  b = !&i;
+  b = &i==(int *)1;
+}
diff --git a/test/SemaOpenCL/null_queue.cl b/test/SemaOpenCL/null_queue.cl
new file mode 100644
index 0000000..518f713
--- /dev/null
+++ b/test/SemaOpenCL/null_queue.cl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only
+extern queue_t get_default_queue();
+
+bool compare() {
+  return 1 == get_default_queue() && // expected-error{{invalid operands to binary expression ('int' and 'queue_t')}}
+         get_default_queue() == 1; // expected-error{{invalid operands to binary expression ('queue_t' and 'int')}}
+}
+
+void init() {
+  queue_t q1 = 1; // expected-error{{initializing 'queue_t' with an expression of incompatible type 'int'}}
+  queue_t q = 0;
+}
diff --git a/test/SemaOpenCL/overload_addrspace_resolution.cl b/test/SemaOpenCL/overload_addrspace_resolution.cl
new file mode 100644
index 0000000..c7cf5fc
--- /dev/null
+++ b/test/SemaOpenCL/overload_addrspace_resolution.cl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - -triple x86_64-unknown-unknown %s | FileCheck %s
+
+void __attribute__((overloadable)) foo(global int *a, global int *b);
+void __attribute__((overloadable)) foo(generic int *a, generic int *b);
+void __attribute__((overloadable)) bar(generic int *global *a, generic int *global *b);
+void __attribute__((overloadable)) bar(generic int *generic *a, generic int *generic *b);
+
+void kernel ker() {
+  global int *a;
+  global int *b;
+  generic int *c;
+  local int *d;
+  generic int *generic *gengen;
+  generic int *local *genloc;
+  generic int *global *genglob;
+  // CHECK: call void @_Z3fooPU8CLglobaliS0_(i32* undef, i32* undef)
+  foo(a, b);
+  // CHECK: call void @_Z3fooPU9CLgenericiS0_(i32* undef, i32* undef)
+  foo(b, c);
+  // CHECK: call void @_Z3fooPU9CLgenericiS0_(i32* undef, i32* undef)
+  foo(a, d);
+
+  // CHECK: call void @_Z3barPU9CLgenericPU9CLgenericiS2_(i32** undef, i32** undef)
+  bar(gengen, genloc);
+  // CHECK: call void @_Z3barPU9CLgenericPU9CLgenericiS2_(i32** undef, i32** undef)
+  bar(gengen, genglob);
+  // CHECK: call void @_Z3barPU8CLglobalPU9CLgenericiS2_(i32** undef, i32** undef)
+  bar(genglob, genglob);
+}
diff --git a/test/SemaOpenCL/queue_t_overload.cl b/test/SemaOpenCL/queue_t_overload.cl
new file mode 100644
index 0000000..0048895
--- /dev/null
+++ b/test/SemaOpenCL/queue_t_overload.cl
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only
+
+void __attribute__((overloadable)) foo(queue_t, __local char *); // expected-note {{candidate function not viable: no known conversion from 'int' to 'queue_t' for 1st argument}} // expected-note {{candidate function}}
+void __attribute__((overloadable)) foo(queue_t, __local float *); // expected-note {{candidate function not viable: no known conversion from 'int' to 'queue_t' for 1st argument}} // expected-note {{candidate function}}
+
+void kernel ker(__local char *src1, __local float *src2, __global int *src3) {
+  queue_t q;
+  foo(q, src1);
+  foo(0, src2);
+  foo(q, src3); // expected-error {{call to 'foo' is ambiguous}}
+  foo(1, src3); // expected-error {{no matching function for call to 'foo'}}
+}
diff --git a/test/SemaOpenCL/unroll-hint.cl b/test/SemaOpenCL/unroll-hint.cl
index 9969866..41385c1 100644
--- a/test/SemaOpenCL/unroll-hint.cl
+++ b/test/SemaOpenCL/unroll-hint.cl
@@ -1,17 +1,5 @@
-//RUN: %clang_cc1 -O0 -fsyntax-only -verify %s
-//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify -DCL20 %s
+//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s
 
-kernel void D (global int *x) {
-  int i = 10;
-#ifndef CL20
-  // expected-error@+2 {{'opencl_unroll_hint' attribute requires OpenCL version 2.0 or above}}
-#endif
-  __attribute__((opencl_unroll_hint))
-  do {
-  } while(i--);
-}
-
-#ifdef CL20
 kernel void C (global int *x) {
   int I = 3;
   __attribute__((opencl_unroll_hint(I))) // expected-error {{'opencl_unroll_hint' attribute requires an integer constant}}
@@ -27,4 +15,3 @@
   __attribute__((opencl_unroll_hint(-1))) // expected-error {{'opencl_unroll_hint' attribute requires a positive integral compile time constant expression}}
   for(int i=0; i<100; i++);
 }
-#endif
diff --git a/test/SemaOpenCL/unsupported.cl b/test/SemaOpenCL/unsupported.cl
index a39a61b..a5fc570 100644
--- a/test/SemaOpenCL/unsupported.cl
+++ b/test/SemaOpenCL/unsupported.cl
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -verify %s
 
 struct {
-  int a : 1; // expected-error {{bitfields are not supported in OpenCL}}
+  int a : 1; // expected-error {{bit-fields are not supported in OpenCL}}
 };
 
 void no_vla(int n) {
diff --git a/test/SemaTemplate/alias-templates.cpp b/test/SemaTemplate/alias-templates.cpp
index bcdc84e..3b7548d 100644
--- a/test/SemaTemplate/alias-templates.cpp
+++ b/test/SemaTemplate/alias-templates.cpp
@@ -244,3 +244,24 @@
   template<typename = void> using A = int;
   A<> a; // ok
 }
+
+namespace PR31514 {
+  template<typename T, typename> using EnableTupleSize = T;
+
+  template<typename T> struct tuple_size { static const int value = 0; };
+  template<typename T> struct tuple_size<EnableTupleSize<const T, decltype(tuple_size<T>::value)>> {};
+  template<typename T> struct tuple_size<EnableTupleSize<volatile T, decltype(tuple_size<T>::value)>> {};
+
+  tuple_size<const int> t;
+}
+
+namespace an_alias_template_is_not_a_class_template {
+  template<typename T> using Foo = int; // expected-note 2{{here}}
+  Foo x; // expected-error {{use of alias template 'Foo' requires template arguments}}
+  Foo<> y; // expected-error {{too few template arguments for alias template 'Foo'}}
+
+  template<template<typename> class Bar> void f() { // expected-note 2{{here}}
+    Bar x; // expected-error {{use of template template parameter 'Bar' requires template arguments}}
+    Bar<> y; // expected-error {{too few template arguments for template template parameter 'Bar'}}
+  }
+}
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
index 86cace1..00e03ef 100644
--- a/test/SemaTemplate/class-template-spec.cpp
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -137,12 +137,16 @@
   A<int>::S<8, sizeof(int)> a; // ok
 
   template <typename T> struct B {
-    template <int N, int M> struct S; // expected-note {{declared here}}
-    template <int N> struct S<N, sizeof(T) +
-        N // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
-        > {};
+    template <int N, int M> struct S;
+    template <int N> struct S<N, sizeof(T) + N> {}; // ok (dr1315)
   };
-  B<int>::S<8, sizeof(int) + 8> s; // expected-error {{undefined}}
+  B<int>::S<8, sizeof(int) + 8> b;
+
+  template <typename T> struct C {
+    template <int N, int M> struct S;
+    template <int N> struct S<N, N ? **(T(*)[N])0 : 0> {}; // expected-error {{depends on a template parameter of the partial specialization}}
+  };
+  C<int> c; // expected-note {{in instantiation of}}
 
   template<int A> struct outer {
     template<int B, int C> struct inner {};
@@ -167,10 +171,16 @@
   // expected-warning@-2 {{variadic templates are a C++11 extension}}
 #endif
 
-  template<typename T, T ...N, T ...Extra> struct __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> {
+  // Note that the following seemingly-equivalent template parameter list is
+  // not OK; it would result in a partial specialization that is not more
+  // specialized than the primary template. (See NTTPTypeVsPartialOrder below.)
+  //
+  //    template<typename T, T ...N, T ...Extra>
+  template<typename T, T ...N, typename integer_sequence<T, N...>::value_type ...Extra>
 #if __cplusplus <= 199711L
-  // expected-warning@-2 2 {{variadic templates are a C++11 extension}}
+  // expected-warning@-2 2{{variadic templates are a C++11 extension}}
 #endif
+  struct __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> {
     typedef integer_sequence<T, N..., sizeof...(N) + N..., Extra...> type;
   };
 
@@ -193,13 +203,32 @@
 #endif
 }
 
+namespace NTTPTypeVsPartialOrder {
+  struct X { typedef int value_type; };
+  template<typename T> struct Y { typedef T value_type; };
+
+  template<typename T, typename T::value_type N> struct A;
+  template<int N> struct A<X, N> {};
+  template<typename T, T N> struct A<Y<T>, N> {};
+  A<X, 0> ax;
+  A<Y<int>, 0> ay;
+
+
+  template<int, typename T, typename T::value_type> struct B;
+  template<typename T, typename T::value_type N> struct B<0, T, N>;
+  template<int N> struct B<0, X, N> {};
+  template<typename T, T N> struct B<0, Y<T>, N> {};
+  B<0, X, 0> bx;
+  B<0, Y<int>, 0> by;
+}
+
 namespace DefaultArgVsPartialSpec {
   // Check that the diagnostic points at the partial specialization, not just at
   // the default argument.
   template<typename T, int N =
-      sizeof(T) // expected-note {{template parameter is used in default argument declared here}}
+      sizeof(T) // ok (dr1315)
   > struct X {};
-  template<typename T> struct X<T> {}; // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
+  template<typename T> struct X<T> {};
 
   template<typename T,
       T N = 0 // expected-note {{template parameter is declared here}}
diff --git a/test/SemaTemplate/constexpr-instantiate.cpp b/test/SemaTemplate/constexpr-instantiate.cpp
index e8e3e7d..dfb8a07 100644
--- a/test/SemaTemplate/constexpr-instantiate.cpp
+++ b/test/SemaTemplate/constexpr-instantiate.cpp
@@ -77,20 +77,19 @@
 }
 
 namespace Unevaluated {
-  // We follow g++ in treating any reference to a constexpr function template
-  // specialization as requiring an instantiation, even if it occurs in an
-  // unevaluated context.
+  // We follow the current proposed resolution of core issue 1581: a constexpr
+  // function template specialization requires a definition if:
+  //  * it is odr-used, or would be odr-used except that it appears within the
+  //    definition of a template, or
+  //  * it is used within a braced-init-list, where it may be necessary for
+  //    detecting narrowing conversions.
   //
-  // We go slightly further than g++, and also trigger the implicit definition
-  // of a defaulted special member in the same circumstances. This seems scary,
-  // since a lot of classes have constexpr special members in C++11, but the
-  // only observable impact should be the implicit instantiation of constexpr
-  // special member templates (defaulted special members should only be
-  // generated if they are well-formed, and non-constexpr special members in a
-  // base or member cause the class's special member to not be constexpr).
+  // We apply this both for instantiating constexpr function template
+  // specializations and for implicitly defining defaulted constexpr special
+  // member functions.
   //
-  // FIXME: None of this is required by the C++ standard. The rules in this
-  //        area are poorly specified, so this is subject to change.
+  // FIXME: None of this is required by the C++ standard yet. The rules in this
+  //        area are subject to change.
   namespace NotConstexpr {
     template<typename T> struct S {
       S() : n(0) {}
@@ -98,16 +97,35 @@
       int n;
     };
     struct U : S<int> {};
-    decltype(U(U())) u; // ok, don't instantiate S<int>::S() because it wasn't declared constexpr
+    decltype(U(U())) u;
   }
   namespace Constexpr {
     template<typename T> struct S {
       constexpr S() : n(0) {}
-      constexpr S(const S&) : n(T::error) {} // expected-error {{has no members}}
+      constexpr S(const S&) : n(T::error) {}
       int n;
     };
-    struct U : S<int> {}; // expected-note {{instantiation}}
-    decltype(U(U())) u; // expected-note {{here}}
+    struct U : S<int> {};
+    decltype(U(U())) u;
+  }
+  namespace ConstexprList {
+    template<int N> struct S {
+      constexpr S() : n(0) {
+        static_assert(N >= 0, "");
+      }
+      constexpr operator int() const { return 0; }
+      int n;
+    };
+    struct U : S<0> {};
+    // ok, trigger instantiation within a list
+    decltype(char{U()}) t0;
+    decltype(new char{S<1>()}) t1; // expected-warning {{side effects}}
+    decltype((char){S<2>()}) t2;
+    decltype(+(char[1]){{S<3>()}}) t3;
+    // do not trigger instantiation outside a list
+    decltype(char(S<-1>())) u1;
+    decltype(new char(S<-2>())) u2; // expected-warning {{side effects}}
+    decltype((char)(S<-3>())) u3;
   }
 
   namespace PR11851_Comment0 {
@@ -190,6 +208,32 @@
       constexpr duration max = duration();
     }
   }
+
+  // For variables, we instantiate when they are used in a context in which
+  // evaluation could be required (odr-used, used in a template whose
+  // instantiations would odr-use, or used in list initialization), if they
+  // can be used as a constant (const integral or constexpr).
+  namespace Variables {
+    template<int N> struct A {
+      static const int k;
+      static int n;
+    };
+    template<const int *N> struct B {};
+    template<int N> constexpr int A<N>::k = *(int[N]){N}; // expected-error 1+{{negative}}
+    template<int N> int A<N>::n = *(int[N]){0};
+
+    template <typename> void f() {
+      (void)A<-1>::n; // ok
+      (void)A<-1>::k; // expected-note {{instantiation of }}
+      B<&A<-2>::n> b1; // ok
+      B<&A<-2>::k> b2; // expected-note {{instantiation of }}
+    };
+
+    decltype(A<-3>::k) d1 = 0; // ok
+    decltype(char{A<-4>::k}) d2 = 0; // expected-note {{instantiation of }} expected-error {{narrow}} expected-note {{cast}}
+    decltype(char{A<1>::k}) d3 = 0; // ok
+    decltype(char{A<1 + (unsigned char)-1>::k}) d4 = 0; // expected-error {{narrow}} expected-note {{cast}}
+  }
 }
 
 namespace NoInstantiationWhenSelectingOverload {
@@ -201,10 +245,17 @@
     int n;
   };
 
-  int f(S);
-  int f(int);
+  constexpr int f(S) { return 0; }
+  constexpr int f(int) { return 0; }
 
   void g() { f(0); }
-  void h() { (void)sizeof(f(0)); }
-  void i() { (void)sizeof(f("oops")); } // expected-note {{instantiation of}}
+  void h() { (void)sizeof(char{f(0)}); }
+  void i() { (void)sizeof(char{f("oops")}); } // expected-note {{instantiation of}}
+}
+
+namespace PR20090 {
+  template <typename T> constexpr T fact(T n) {
+    return n == 0 ? 1 : [=] { return n * fact(n - 1); }();
+  }
+  static_assert(fact(0) == 1, "");
 }
diff --git a/test/SemaTemplate/cxx1z-using-declaration.cpp b/test/SemaTemplate/cxx1z-using-declaration.cpp
new file mode 100644
index 0000000..87ca748
--- /dev/null
+++ b/test/SemaTemplate/cxx1z-using-declaration.cpp
@@ -0,0 +1,230 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+// Test that we cope with failure to expand a pack.
+template<typename ...T> struct Unexpanded : T... {
+  using T::f; // expected-error {{unexpanded}}
+  using typename T::type; // expected-error {{unexpanded}}
+  template<typename ...U> void g(U ...u) { f(u...); } // expected-error {{undeclared identifier 'f'}}
+  void h() {
+    Unexpanded<type...> *p; // expected-error {{undeclared identifier 'type'}}
+  }
+};
+void test_Unexpanded() {
+  struct A { void f(); }; // expected-note {{must qualify}}
+  struct B { void f(int); }; // expected-note {{must qualify}}
+  Unexpanded<A, B>().g(0); // expected-note {{instantiation of}}
+}
+
+// Test using non-type members from pack of base classes.
+template<typename ...T> struct A : T... { // expected-note 2{{candidate}}
+  using T::T ...; // expected-note 2{{inherited here}}
+  using T::operator() ...;
+  using T::operator T* ...;
+  using T::h ...;
+
+  void f(int n) { h(n); } // expected-error {{ambiguous}}
+  void f(int n, int m) { h(n, m); } // expected-error {{member using declaration 'h' instantiates to an empty pack}}
+  void g(int n) { (*this)(n); } // expected-error {{ambiguous}}
+  void g(int n, int m) { (*this)(n, m); } // expected-error {{does not provide a call operator}}
+};
+
+namespace test_A {
+  struct X {
+    X();
+    X(int); // expected-note {{candidate}}
+    void operator()(int); // expected-note 2{{candidate}}
+    operator X *();
+    void h(int); // expected-note {{candidate}}
+  };
+  struct Y {
+    Y();
+    Y(int, int);
+    void operator()(int, int);
+    operator Y *();
+    void h(int, int); // expected-note {{not viable}}
+  };
+  struct Z {
+    Z();
+    Z(int); // expected-note {{candidate}}
+    void operator()(int); // expected-note 2{{candidate}}
+    operator Z *();
+    void h(int); // expected-note {{candidate}}
+  };
+
+  void f() {
+    A<> a;
+    a.f(0, 0); // expected-note {{instantiation of}}
+    a.g(0, 0); // expected-note {{instantiation of}}
+
+    A<X, Y> axy(0);
+    A<X, Y>(0, 0);
+    axy.f(0);
+    axy.f(0, 0);
+    axy.g(0);
+    axy.g(0, 0);
+    axy(0);
+    axy(0, 0);
+
+    A<X, Y, Z>(0); // expected-error {{ambiguous}}
+    A<X, Y, Z> axyz(0, 0);
+    axyz.f(0); // expected-note {{instantiation of}}
+    axyz.f(0, 0);
+    axyz.g(0); // expected-note {{instantiation of}}
+    axyz.g(0, 0);
+    axyz(0); // expected-error {{ambiguous}}
+    axyz(0, 0);
+
+    X *x;
+    x = a; // expected-error {{incompatible}}
+    x = axy;
+    x = axyz;
+    x = a.operator X*(); // expected-error {{no member}}
+    x = axy.operator X*();
+    x = axyz.operator X*();
+
+    Z *z;
+    z = axyz;
+    z = axyz.operator Z*();
+  }
+}
+
+// Test using pack of non-type members from single base class.
+template<typename X, typename Y, typename ...T> struct B : X, Y {
+  using X::operator T* ...;
+};
+
+namespace test_B {
+  struct X { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}}
+  struct Y { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}}
+  B<X, Y, int, float> bif;
+  int *pi = bif;
+  float *pf = bif;
+  char *pc = bif; // expected-error {{ambiguous}}
+}
+
+// Test using type member from pack of base classes.
+template<typename ...T> struct C : T... {
+  using typename T::type ...; // expected-error {{target of using declaration conflicts}}
+  void f() { type value; } // expected-error {{member using declaration 'type' instantiates to an empty pack}}
+};
+
+namespace test_C {
+  struct X { typedef int type; };
+  struct Y { typedef int type; }; // expected-note {{conflicting}}
+  struct Z { typedef float type; }; // expected-note {{target}}
+
+  void f() {
+    C<> c;
+    c.f(); // expected-note {{instantiation of}}
+
+    C<X, Y> cxy;
+    cxy.f();
+
+    C<X, Y, Z> cxyz; // expected-note {{instantiation of}}
+    cxyz.f();
+  }
+}
+
+// Test using pack of non-types at block scope.
+template<typename ...T> int fn1() {
+  using T::e ...; // expected-error 2{{class member}} expected-note 2{{instead}}
+  // expected-error@-1 2{{produces multiple values}}
+  return e; // expected-error {{using declaration 'e' instantiates to an empty pack}}
+}
+
+namespace test_fn1 {
+  struct X { static int e; };
+  struct Y { typedef int e; };
+  inline namespace P { enum E { e }; }
+  inline namespace Q { enum F { e }; }
+  void f() {
+    fn1<>(); // expected-note {{instantiation of}}
+    fn1<X>(); // expected-note {{instantiation of}}
+    fn1<Y>(); // expected-note {{instantiation of}}
+    fn1<E>();
+    fn1<E, F>(); // expected-note {{instantiation of}}
+    fn1<E, X>(); // expected-note {{instantiation of}}
+  }
+}
+
+// Test using pack of types at block scope.
+template<typename ...T> void fn2() {
+  // This cannot ever be valid: in order for T::type to be a type, T must be a
+  // class, and a class member cannot be named by a block-scope using declaration.
+  using typename T::type ...; // expected-error {{class member}}
+  type x; // expected-error {{unknown type name 'type'}}
+}
+
+// Test partial substitution into class-scope pack.
+template<typename ...T> auto lambda1() {
+  return [](auto x) {
+    struct A : T::template X<decltype(x)>... { // expected-note 1+{{instantiation of}}
+      using T::template X<decltype(x)>::f ...;
+      using typename T::template X<decltype(x)>::type ...;
+      void g(int n) { f(n); } // expected-error {{empty pack}} expected-error {{expected 2, have 1}} expected-error {{ambiguous}}
+      void h() { type value; } // expected-error {{empty pack}}
+    };
+    return A();
+  };
+}
+
+namespace test_lambda1 {
+  struct A {
+    template<typename> struct X {
+      void f(int); // expected-note {{candidate}}
+      using type = int;
+    };
+  };
+  struct B {
+    template<typename> struct X {
+      void f(int, int); // expected-note {{declared here}} expected-note {{not viable}}
+      using type = int;
+    };
+  };
+  struct C {
+    template<typename> struct X {
+      void f(int); // expected-note {{candidate}}
+      void f(int, int); // expected-note {{not viable}}
+      using type = int;
+    };
+  };
+
+  void f() {
+    lambda1<>() // expected-note 2{{instantiation of}}
+      (0)
+      // FIXME: This is poor error recovery
+      .g(0); // expected-error {{no member named 'g'}}
+    lambda1<A>()
+      (0)
+      .g(0);
+    lambda1<B>()
+      (0) // expected-note {{instantiation of}}
+      .g(0);
+    lambda1<A, B, C>()
+      (0) // expected-note {{instantiation of}}
+      .g(0);
+  }
+}
+
+namespace p0195r2_example {
+  template<typename ...Ts>
+  struct Overloader : Ts... {
+    using Ts::operator() ...;
+  };
+
+  template<typename ...Ts>
+  constexpr auto make_overloader(Ts &&...ts) {
+    return Overloader<Ts...>{static_cast<Ts&&>(ts)...};
+  }
+
+  void test() {
+    auto o = make_overloader(
+      [&](int &r) -> int & { return r; }, // expected-note {{candidate function}}
+      [&](float &r) -> float & { return r; } // expected-note {{candidate function}}
+    );
+    int a; float f; double d;
+    int &ra = o(a);
+    float &rf = o(f);
+    double &rd = o(d); // expected-error {{no matching function}}
+  }
+}
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp
index 7c7b0ab..8ac65aa 100644
--- a/test/SemaTemplate/deduction.cpp
+++ b/test/SemaTemplate/deduction.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1z
 
 // Template argument deduction with template template parameters.
 template<typename T, template<T> class A> 
@@ -266,10 +267,276 @@
 } // end ns2 
 }
 
+namespace multiple_deduction_different_type {
+  template<typename T, T v> struct X {};
+  template<template<typename T, T> class X, typename T, typename U, int N>
+    void f(X<T, N>, X<U, N>) {} // expected-note 2{{values of conflicting types}}
+  template<template<typename T, T> class X, typename T, typename U, const int *N>
+    void g(X<T, N>, X<U, N>) {} // expected-note 0-2{{values of conflicting types}}
+  int n;
+  void h() {
+    f(X<int, 1+1>(), X<unsigned int, 3-1>()); // expected-error {{no matching function}}
+    f(X<unsigned int, 1+1>(), X<int, 3-1>()); // expected-error {{no matching function}}
+#if __cplusplus > 201402L
+    g(X<const int*, &n>(), X<int*, &n + 1 - 1>()); // expected-error {{no matching function}}
+    g(X<int*, &n>(), X<const int*, &n + 1 - 1>()); // expected-error {{no matching function}}
+#endif
+  }
+
+  template<template<typename T, T> class X, typename T, typename U, T N>
+    void x(X<T, N>, int(*)[N], X<U, N>) {} // expected-note 1+{{candidate}}
+  template<template<typename T, T> class X, typename T, typename U, T N>
+    void x(int(*)[N], X<T, N>, X<U, N>) {} // expected-note 1+{{candidate}}
+  int arr[3];
+  void y() {
+    x(X<int, 3>(), &arr, X<int, 3>());
+    x(&arr, X<int, 3>(), X<int, 3>());
+
+    x(X<int, 3>(), &arr, X<char, 3>()); // expected-error {{no matching function}}
+    x(&arr, X<int, 3>(), X<char, 3>()); // expected-error {{no matching function}}
+
+    x(X<char, 3>(), &arr, X<char, 3>());
+    x(&arr, X<char, 3>(), X<char, 3>());
+  }
+}
+
 namespace nullptr_deduction {
+  using nullptr_t = decltype(nullptr);
+
   template<typename T, T v> struct X {};
   template<typename T, T v> void f(X<T, v>) {
     static_assert(!v, "");
   }
-  void g() { f(X<int*, nullptr>()); }
+  void g() {
+    f(X<int*, nullptr>());
+    f(X<nullptr_t, nullptr>());
+  }
+
+  template<template<typename T, T> class X, typename T, typename U, int *P>
+    void f1(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}
+  void h() {
+    f1(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
+    f1(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}
+  }
+
+  template<template<typename T, T> class X, typename T, typename U, nullptr_t P>
+    void f2(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}
+  void i() {
+    f2(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
+    f2(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}
+  }
+}
+
+namespace member_pointer {
+  struct A { void f(int); };
+  template<typename T, void (A::*F)(T)> struct B;
+  template<typename T> struct C;
+  template<typename T, void (A::*F)(T)> struct C<B<T, F>> {
+    C() { A a; T t; (a.*F)(t); }
+  };
+  C<B<int, &A::f>> c;
+}
+
+namespace deduction_substitution_failure {
+  template<typename T> struct Fail { typedef typename T::error error; }; // expected-error 2{{prior to '::'}}
+
+  template<typename T, typename U> struct A {};
+  template<typename T> struct A<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
+  A<int, int> ai; // expected-note {{during template argument deduction for class template partial specialization 'A<T, typename Fail<T>::error>' [with T = int]}} expected-note {{in instantiation of template class 'deduction_substitution_failure::A<int, int>'}}
+
+  template<typename T, typename U> int B; // expected-warning 0-1 {{extension}}
+  template<typename T> int B<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
+  int bi = B<char, char>; // expected-note {{during template argument deduction for variable template partial specialization 'B<T, typename Fail<T>::error>' [with T = char]}}
+}
+
+namespace deduction_after_explicit_pack {
+  template<typename ...T, typename U> int *f(T ...t, int &r, U *u) {
+    return u;
+  }
+  template<typename U, typename ...T> int *g(T ...t, int &r, U *u) {
+    return u;
+  }
+  void h(float a, double b, int c) {
+    f<float&, double&>(a, b, c, &c); // ok
+    g<int, float&, double&>(a, b, c, &c); // ok
+  }
+
+  template<class... ExtraArgs>
+  int test(ExtraArgs..., unsigned vla_size, const char *input);
+  int n = test(0, "");
+
+  template <typename... T> void i(T..., int, T..., ...); // expected-note 5{{deduced conflicting}}
+  void j() {
+    i(0);
+    i(0, 1); // expected-error {{no match}}
+    i(0, 1, 2); // expected-error {{no match}}
+    i<>(0);
+    i<>(0, 1); // expected-error {{no match}}
+    i<>(0, 1, 2); // expected-error {{no match}}
+    i<int, int>(0, 1, 2, 3, 4);
+    i<int, int>(0, 1, 2, 3, 4, 5); // expected-error {{no match}}
+  }
+
+  // GCC alarmingly accepts this by deducing T={int} by matching the second
+  // parameter against the first argument, then passing the first argument
+  // through the first parameter.
+  template<typename... T> struct X { X(int); operator int(); };
+  template<typename... T> void p(T..., X<T...>, ...); // expected-note {{deduced conflicting}}
+  void q() { p(X<int>(0), 0); } // expected-error {{no match}}
+
+  struct A {
+    template <typename T> void f(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}}
+    void f(); // expected-note 2{{requires 0}}
+
+    template <typename T> static void g(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}}
+    void g(); // expected-note 2{{requires 0}}
+
+    void h() {
+      f(1.0, 2.0); // expected-error {{no match}}
+      g(1.0, 2.0); // expected-error {{no match}}
+    }
+  };
+  void f(A a) {
+    a.f(1.0, 2.0); // expected-error {{no match}}
+    a.g(1.0, 2.0); // expected-error {{no match}}
+  }
+}
+
+namespace overload_vs_pack {
+  void f(int);
+  void f(float);
+  void g(double);
+
+  template<typename ...T> struct X {};
+  template<typename ...T> void x(T...);
+
+  template<typename ...T> struct Y { typedef int type(typename T::error...); };
+  template<> struct Y<int, float, double> { typedef int type; };
+
+  template<typename ...T> typename Y<T...>::type g1(X<T...>, void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
+  template<typename ...T> typename Y<T...>::type g2(void(*)(T...), void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
+
+  template<typename T> int &h1(decltype(g1(X<int, float, T>(), f, f, g)) *p);
+  template<typename T> float &h1(...);
+
+  template<typename T> int &h2(decltype(g2(x<int, float, T>, f, f, g)) *p);
+  template<typename T> float &h2(...);
+
+  int n1 = g1(X<int, float>(), f, g); // expected-error {{no matching function}}
+  int n2 = g2(x<int, float>, f, g); // expected-error {{no matching function}}
+
+  int &a1 = h1<double>(0); // ok, skip deduction for 'f's, deduce matching value from 'g'
+  int &a2 = h2<double>(0);
+
+  float &b1 = h1<float>(0); // deduce mismatching value from 'g', so we do not trigger instantiation of Y
+  float &b2 = h2<float>(0);
+
+  template<typename ...T> int partial_deduction(void (*...f)(T)); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
+  int pd1 = partial_deduction(f, g); // expected-error {{no matching function}}
+
+  template<typename ...T> int partial_deduction_2(void (*...f)(T), ...); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
+  int pd2 = partial_deduction_2(f, g); // expected-error {{no matching function}}
+
+  namespace cwg_example {
+    void f(char, char);
+    void f(int, int);
+    void x(int, char);
+
+    template<typename T, typename ...U> void j(void(*)(U...), void (*...fns)(T, U));
+    void test() { j(x, f, x); }
+  }
+}
+
+namespace b29946541 {
+  template<typename> class A {};
+  template<typename T, typename U, template<typename, typename> class C>
+  void f(C<T, U>); // expected-note {{failed template argument deduction}}
+  void g(A<int> a) { f(a); } // expected-error {{no match}}
+}
+
+namespace deduction_from_empty_list {
+  template<int M, int N = 5> void f(int (&&)[N], int (&&)[N]) { // expected-note {{1 vs. 2}}
+    static_assert(M == N, "");
+  }
+
+  void test() {
+    f<5>({}, {});
+    f<1>({}, {0});
+    f<1>({0}, {});
+    f<1>({0}, {0});
+    f<1>({0}, {0, 1}); // expected-error {{no matching}}
+  }
+}
+
+namespace check_extended_pack {
+  template<typename T> struct X { typedef int type; };
+  template<typename ...T> void f(typename X<T>::type...);
+  template<typename T> void f(T, int, int);
+  void g() {
+    f<int>(0, 0, 0);
+  }
+
+  template<int, int*> struct Y {};
+  template<int ...N> void g(Y<N...>); // expected-note {{deduced non-type template argument does not have the same type as the corresponding template parameter ('int *' vs 'int')}}
+  int n;
+  void h() { g<0>(Y<0, &n>()); } // expected-error {{no matching function}}
+}
+
+namespace dependent_template_template_param_non_type_param_type {
+  template<int N> struct A { // expected-note 2{{candidate}}
+    template<typename V = int, V M = 12, V (*Y)[M], template<V (*v)[M]> class W>
+    A(W<Y>); // expected-note {{[with V = int, M = 12, Y = &dependent_template_template_param_non_type_param_type::n]}}
+  };
+
+  int n[12];
+  template<int (*)[12]> struct Q {};
+  Q<&n> qn;
+  // FIXME: This should be accepted, but we somehow fail to deduce W.
+  A<0> a(qn); // expected-error {{no matching constructor for initialization}}
+}
+
+namespace dependent_list_deduction {
+  template<typename T, T V> void a(const int (&)[V]) {
+    static_assert(is_same<T, decltype(sizeof(0))>::value, "");
+    static_assert(V == 3, "");
+  }
+  template<typename T, T V> void b(const T (&)[V]) {
+    static_assert(is_same<T, int>::value, "");
+    static_assert(V == 3, "");
+  }
+  template<typename T, T V> void c(const T (&)[V]) {
+    static_assert(is_same<T, decltype(sizeof(0))>::value, "");
+    static_assert(V == 3, "");
+  }
+  void d() {
+    a({1, 2, 3});
+#if __cplusplus <= 201402L
+    // expected-error@-2 {{no match}} expected-note@-15 {{couldn't infer template argument 'T'}}
+#endif
+    b({1, 2, 3});
+    c({{}, {}, {}});
+#if __cplusplus <= 201402L
+    // expected-error@-2 {{no match}} expected-note@-12 {{couldn't infer template argument 'T'}}
+#endif
+  }
+
+  template<typename ...T> struct X;
+  template<int ...T> struct Y;
+  template<typename ...T, T ...V> void f(const T (&...p)[V]) {
+    static_assert(is_same<X<T...>, X<int, char, char>>::value, "");
+    static_assert(is_same<Y<V...>, Y<3, 2, 4>>::value, "");
+  }
+  template<typename ...T, T ...V> void g(const T (&...p)[V]) {
+    static_assert(is_same<X<T...>, X<int, decltype(sizeof(0))>>::value, "");
+    static_assert(is_same<Y<V...>, Y<2, 3>>::value, "");
+  }
+  void h() {
+    f({1, 2, 3}, {'a', 'b'}, "foo");
+    g({1, 2}, {{}, {}, {}});
+#if __cplusplus <= 201402
+    // expected-error@-2 {{no match}}
+    // expected-note@-9 {{deduced incomplete pack}}
+    // We deduce V$1 = (size_t)3, which in C++1z also deduces T$1 = size_t.
+#endif
+  }
 }
diff --git a/test/SemaTemplate/default-arguments-cxx0x.cpp b/test/SemaTemplate/default-arguments-cxx0x.cpp
index c52899a..d9fa2b4 100644
--- a/test/SemaTemplate/default-arguments-cxx0x.cpp
+++ b/test/SemaTemplate/default-arguments-cxx0x.cpp
@@ -50,6 +50,8 @@
     bar(T);
   };
 
+  bar<> foo{0};
+
   struct baz : public bar<> {
     using bar::bar;
   };
diff --git a/test/SemaTemplate/default-expr-arguments-3.cpp b/test/SemaTemplate/default-expr-arguments-3.cpp
new file mode 100644
index 0000000..173609c
--- /dev/null
+++ b/test/SemaTemplate/default-expr-arguments-3.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++14 -verify -ast-dump %s | FileCheck %s
+// expected-no-diagnostics
+
+// CHECK: FunctionDecl {{.*}} used func 'void (void)'
+// CHECK-NEXT: TemplateArgument type 'int'
+// CHECK: LambdaExpr {{.*}} 'class (lambda at
+// CHECK: ParmVarDecl {{.*}} used f 'enum foo' cinit
+// CHECK-NEXT: DeclRefExpr {{.*}} 'enum foo' EnumConstant {{.*}} 'a' 'enum foo'
+
+namespace PR28795 {
+  template<typename T>
+  void func() {
+    enum class foo { a, b };
+    auto bar = [](foo f = foo::a) { return f; };
+    bar();
+  }
+
+  void foo() {
+    func<int>();
+  }
+}
+
+// CHECK: ClassTemplateSpecializationDecl {{.*}} struct class2 definition
+// CHECK-NEXT: TemplateArgument type 'int'
+// CHECK: LambdaExpr {{.*}} 'class (lambda at
+// CHECK: ParmVarDecl {{.*}} used f 'enum foo' cinit
+// CHECK-NEXT: DeclRefExpr {{.*}} 'enum foo' EnumConstant {{.*}} 'a' 'enum foo'
+
+// Template struct case:
+template <class T> struct class2 {
+  void bar() {
+    enum class foo { a, b };
+    [](foo f = foo::a) { return f; }();
+  }
+};
+
+template struct class2<int>;
+
+// CHECK: FunctionTemplateDecl {{.*}} f1
+// CHECK-NEXT: TemplateTypeParmDecl {{.*}} typename depth 0 index 0 T
+// CHECK-NEXT: FunctionDecl {{.*}} f1 'void (void)'
+// CHECK: FunctionDecl {{.*}} f1 'void (void)'
+// CHECK-NEXT: TemplateArgument type 'int'
+// CHECK: ParmVarDecl {{.*}} n 'enum foo' cinit
+// CHECK-NEXT: DeclRefExpr {{.*}} 'enum foo' EnumConstant {{.*}} 'a' 'enum foo'
+
+template<typename T>
+void f1() {
+  enum class foo { a, b };
+  struct S {
+    int g1(foo n = foo::a);
+  };
+}
+
+template void f1<int>();
diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp
index 040a932..010716d 100644
--- a/test/SemaTemplate/explicit-instantiation.cpp
+++ b/test/SemaTemplate/explicit-instantiation.cpp
@@ -103,8 +103,8 @@
 // Test that we do not crash.
 class TC1 {
   class TC2 {
-    template // FIXME: error here.
-    void foo() { }
+    template
+    void foo() { } // expected-error{{expected '<' after 'template'}}
    };
 };
 
diff --git a/test/SemaTemplate/injected-class-name.cpp b/test/SemaTemplate/injected-class-name.cpp
index 7349fdf..93a7231 100644
--- a/test/SemaTemplate/injected-class-name.cpp
+++ b/test/SemaTemplate/injected-class-name.cpp
@@ -11,7 +11,10 @@
   typedef X<int***> *ptr;
 };
 
-X<float>::X<int> xi = x; // expected-error{{qualified reference to 'X' is a constructor name rather than a template name wherever a constructor can be declared}}
+X<float>::X<int> xi = x; // expected-error{{qualified reference to 'X' is a constructor name rather than a template name}}
+void f() {
+  X<float>::X<int> xi = x; // expected-error{{qualified reference to 'X' is a constructor name rather than a template name}}
+}
 
 // [temp.local]p1:
 
diff --git a/test/SemaTemplate/instantiate-c99.cpp b/test/SemaTemplate/instantiate-c99.cpp
index ae15528..07d3fc7 100644
--- a/test/SemaTemplate/instantiate-c99.cpp
+++ b/test/SemaTemplate/instantiate-c99.cpp
@@ -1,4 +1,6 @@
 // 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
 
 // Test template instantiation for C99-specific features.
 
@@ -9,8 +11,13 @@
 struct DesigInit0 {
   void f(XType x, YType y) {
     T agg = { 
+#if __cplusplus <= 199711L
       .y = y, // expected-error{{does not refer}}
       .x = x  // expected-error{{does not refer}}
+#else
+      .y = static_cast<float>(y), // expected-error{{does not refer}}
+      .x = static_cast<float>(x)  // expected-error{{does not refer}}
+#endif
     };
   }
 };
@@ -44,7 +51,11 @@
 struct DesigArrayInit0 {
   void f(Val1 val1, Val2 val2) {
     T array = {
+#if __cplusplus <= 199711L
       [Subscript1] = val1,
+#else
+      [Subscript1] = static_cast<int>(val1),
+#endif
       [Subscript2] = val2 // expected-error{{exceeds array bounds}}
     };
 
@@ -60,7 +71,11 @@
 struct DesigArrayRangeInit0 {
   void f(Val1 val1) {
     T array = {
+#if __cplusplus <= 199711L
       [Subscript1...Subscript2] = val1 // expected-error{{exceeds}}
+#else
+      [Subscript1...Subscript2] = static_cast<int>(val1) // expected-error{{exceeds}}
+#endif
     };
   }
 };
@@ -74,7 +89,11 @@
 template<typename T, typename Arg1, typename Arg2>
 struct CompoundLiteral0 {
   T f(Arg1 a1, Arg2 a2) {
+#if __cplusplus <= 199711L
     return (T){a1, a2};
+#else
+    return (T){static_cast<float>(a1), a2};
+#endif
   }
 };
 
diff --git a/test/SemaTemplate/instantiate-enum.cpp b/test/SemaTemplate/instantiate-enum.cpp
index 3da8eb4..701d191 100644
--- a/test/SemaTemplate/instantiate-enum.cpp
+++ b/test/SemaTemplate/instantiate-enum.cpp
@@ -29,13 +29,14 @@
 namespace EnumScoping {
 
 template <typename T>
-class C {
+struct C {
+  struct X {};
   enum {
     value = 42
   };
 };
 
-void f(int i, C<int>::C c) {
+void f(int i, C<int>::X c) {
   int value;
 }
 
diff --git a/test/SemaTemplate/instantiate-init.cpp b/test/SemaTemplate/instantiate-init.cpp
index e9be60d..244e94f 100644
--- a/test/SemaTemplate/instantiate-init.cpp
+++ b/test/SemaTemplate/instantiate-init.cpp
@@ -115,9 +115,8 @@
   struct A { explicit A(int); }; // expected-note{{here}}
   template<typename T> struct B { T a { 0 }; };
   B<A> b;
-  // expected-note@+1 {{in instantiation of default member initializer}}
   template<typename T> struct C { T a = { 0 }; }; // expected-error{{explicit}}
-  C<A> c; // expected-note{{here}}
+  C<A> c; // expected-note {{in instantiation of default member initializer}}
 }
 
 namespace PR16903 {
diff --git a/test/SemaTemplate/instantiate-local-class.cpp b/test/SemaTemplate/instantiate-local-class.cpp
index a61af7a..eaff4c4 100644
--- a/test/SemaTemplate/instantiate-local-class.cpp
+++ b/test/SemaTemplate/instantiate-local-class.cpp
@@ -475,3 +475,14 @@
   }
   template void bar<A>(); // expected-note {{in instantiation}}
 }
+
+namespace anon_union_default_member_init {
+  template<typename T> void f() {
+    struct S {
+      union {
+        int i = 0;
+      };
+    };
+  }
+  void g() { f<int>(); }
+}
diff --git a/test/SemaTemplate/instantiate-member-class.cpp b/test/SemaTemplate/instantiate-member-class.cpp
index 159bccb..5a9e2e3 100644
--- a/test/SemaTemplate/instantiate-member-class.cpp
+++ b/test/SemaTemplate/instantiate-member-class.cpp
@@ -39,8 +39,8 @@
 X<int>::C *c1;
 X<float>::C *c2;
 
-X<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}}
-X<float>::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}}
+X<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type}}
+X<float>::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type}}
 
 void test_naming() {
   c1 = c2; // expected-error{{assigning to 'X<int>::C *' from incompatible type 'X<float>::C *'}}
diff --git a/test/SemaTemplate/instantiation-default-1.cpp b/test/SemaTemplate/instantiation-default-1.cpp
index 99154a5..ab9eca7 100644
--- a/test/SemaTemplate/instantiation-default-1.cpp
+++ b/test/SemaTemplate/instantiation-default-1.cpp
@@ -36,7 +36,7 @@
 Def2<int_ref_t> *d2; // expected-note{{in instantiation of default argument for 'Def2<int &>' required here}}
 
 
-template<> struct Def1<const int, const int> { }; // expected-error{{redefinition of 'Def1<const int>'}}
+template<> struct Def1<const int> { }; // expected-error{{redefinition of 'Def1<const int, const int>'}}
 
 template<typename T, typename T2 = T&> struct Def3;
 
diff --git a/test/SemaTemplate/member-access-ambig.cpp b/test/SemaTemplate/member-access-ambig.cpp
index 5c2d761..a28698b 100644
--- a/test/SemaTemplate/member-access-ambig.cpp
+++ b/test/SemaTemplate/member-access-ambig.cpp
@@ -48,7 +48,7 @@
   typedef int (A::*P);
   template<typename T> struct S : T {
     void f() {
-      P(&T::X) // expected-error {{cannot cast from type 'int *' to member pointer type 'P'}}
+      P(&T::X) // expected-error {{cannot cast from type 'int *' to member pointer type 'AddrOfMember::P'}}
           == &A::X;
     }
   };
diff --git a/test/SemaTemplate/ms-class-specialization-class-scope.cpp b/test/SemaTemplate/ms-class-specialization-class-scope.cpp
index 3ebb1c9..fc51c23 100644
--- a/test/SemaTemplate/ms-class-specialization-class-scope.cpp
+++ b/test/SemaTemplate/ms-class-specialization-class-scope.cpp
@@ -19,7 +19,7 @@
   X<double>::y c;
 
   template<> struct X<float> {}; // expected-note {{previous definition is here}}
-  template<> struct X<float> {}; // expected-error {{redefinition of 'A::X<float>'}}
+  template<> struct X<float> {}; // expected-error {{redefinition of 'X<float>'}}
 };
 
 A::X<void>::x axv;
diff --git a/test/SemaTemplate/ms-sizeof-missing-typename.cpp b/test/SemaTemplate/ms-sizeof-missing-typename.cpp
index ff8984f..9bafe6c 100644
--- a/test/SemaTemplate/ms-sizeof-missing-typename.cpp
+++ b/test/SemaTemplate/ms-sizeof-missing-typename.cpp
@@ -53,7 +53,7 @@
 // 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}}
+  // expected-note@+1 {{class template declared here}}
   template <int> struct U {};
 };
 // expected-note-re@+1 {{in instantiation {{.*}} requested here}}
diff --git a/test/SemaTemplate/partial-order.cpp b/test/SemaTemplate/partial-order.cpp
new file mode 100644
index 0000000..0a151de
--- /dev/null
+++ b/test/SemaTemplate/partial-order.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+
+// expected-no-diagnostics
+
+namespace hana_enable_if_idiom {
+  template<bool> struct A {};
+  template<typename, typename = A<true>> struct B;
+  template<typename T, bool N> struct B<T, A<N>> {};
+  template<typename T> struct B<T, A<T::value>> {};
+  struct C {
+    static const bool value = true;
+  };
+  B<C> b;
+}
diff --git a/test/SemaTemplate/temp_arg.cpp b/test/SemaTemplate/temp_arg.cpp
index 052c19e..df5bf87 100644
--- a/test/SemaTemplate/temp_arg.cpp
+++ b/test/SemaTemplate/temp_arg.cpp
@@ -10,7 +10,7 @@
 
 A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}}
 A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}}
-A a3; // expected-error{{use of class template 'A' requires template arguments}}
+A a4; // expected-error{{use of class template 'A' requires template arguments}}
 
 namespace test0 {
   template <class t> class foo {};
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp
index 91b0c6e..8658fb0 100644
--- a/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/test/SemaTemplate/temp_arg_nontype.cpp
@@ -173,12 +173,16 @@
 }
 
 namespace PR6723 {
-  template<unsigned char C> void f(int (&a)[C]); // expected-note {{candidate template ignored}} \
-  // expected-note{{substitution failure [with C = '\x00']}}
+  template<unsigned char C> void f(int (&a)[C]); // expected-note 3{{candidate template ignored: substitution failure [with C = '\x00']}}
+  // expected-note@-1 {{not viable: no known conversion from 'int [512]' to 'int (&)[0]'}}
   void g() {
     int arr512[512];
     f(arr512); // expected-error{{no matching function for call}}
     f<512>(arr512); // expected-error{{no matching function for call}}
+
+    int arr0[0];
+    f(arr0); // expected-error{{no matching function for call}}
+    f<0>(arr0); // expected-error{{no matching function for call}}
   }
 }
 
@@ -364,3 +368,98 @@
 
   b<&a::i> c; // okay
 }
+
+namespace partial_order_different_types {
+  template<int, int, typename T, typename, T> struct A;
+  template<int N, typename T, typename U, T V> struct A<0, N, T, U, V>; // expected-note {{matches}}
+  // FIXME: It appears that this partial specialization should be ill-formed as
+  // it is not more specialized than the primary template. V is not deducible
+  // because it does not have the same type as the corresponding parameter.
+  template<int N, typename T, typename U, U V> struct A<0, N, T, U, V> {}; // expected-note {{matches}}
+  A<0, 0, int, int, 0> a; // expected-error {{ambiguous}}
+}
+
+namespace partial_order_references {
+  // FIXME: The standard does not appear to consider the second specialization
+  // to be more more specialized than the first! The problem is that deducing
+  // an 'int&' parameter from an argument 'R' results in a type mismatch,
+  // because the parameter has a reference type and the argument is an
+  // expression and thus does not have reference type. We resolve this by
+  // matching the type of an expression corresponding to the parameter rather
+  // than matching the parameter itself.
+  template <int, int, int &> struct A {};
+  template <int N, int &R> struct A<N, 0, R> {};
+  template <int &R> struct A<0, 0, R> {};
+  int N;
+  A<0, 0, N> a;
+
+  template<int, int &R> struct B; // expected-note 2{{template}}
+  template<const int &R> struct B<0, R> {};
+  // expected-error@-1 {{not more specialized than the primary}}
+  // expected-note@-2 {{'const int' vs 'int &'}}
+  B<0, N> b; // expected-error {{undefined}}
+
+  template<int, const int &R> struct C; // expected-note 2{{template}}
+  template<int &R> struct C<0, R> {};
+  // expected-error@-1 {{not more specialized than the primary}}
+  // expected-note@-2 {{'int' vs 'const int &'}}
+  C<0, N> c; // expected-error {{undefined}}
+
+  template<int, const int &R> struct D; // expected-note 2{{template}}
+  template<int N> struct D<0, N> {};
+  // expected-error@-1 {{not more specialized than the primary}}
+  // expected-note@-2 {{'int' vs 'const int &'}}
+  extern const int K = 5;
+  D<0, K> d; // expected-error {{undefined}}
+}
+
+namespace dependent_nested_partial_specialization {
+  template<typename> using X = int; // expected-warning {{C++11}}
+  template<typename T> using Y = T*; // expected-warning {{C++11}}
+  int n;
+
+  template<template<typename> class X> struct A {
+    template<typename T, X<T> N> struct B; // expected-note 2{{here}}
+    template<typename T> struct B<T, 0> {}; // expected-error {{specializes a template parameter with dependent type 'Y<T>'}}
+  };
+  A<X>::B<int, 0> ax;
+  A<Y>::B<int, &n> ay; // expected-error {{undefined}} expected-note {{instantiation of}}
+
+  template<template<typename> class X> struct C {
+    template<typename T, int N, int M> struct D; // expected-note {{here}}
+    template<typename T, X<T> N> struct D<T*, N, N + 1> {}; // expected-error {{type of specialized non-type template argument depends on}}
+  };
+  C<X>::D<int*, 0, 1> cx;
+  C<Y>::D<int*, 0, 1> cy; // expected-error {{undefined}} expected-note {{instantiation of}}
+
+  template<typename T> struct E {
+    template<typename U, U V> struct F; // expected-note {{template}}
+    template<typename W, T V> struct F<W, V> {}; // expected-error {{not more specialized than the primary}}
+  };
+  E<int>::F<int, 0> e1; // expected-note {{instantiation of}}
+}
+
+namespace nondependent_default_arg_ordering {
+  int n, m;
+  template<typename A, A B = &n> struct X {};
+  template<typename A> void f(X<A>); // expected-note {{candidate}}
+  template<typename A> void f(X<A, &m>); // expected-note {{candidate}}
+  template<typename A, A B> void f(X<A, B>); // expected-note 2{{candidate}}
+  template<template<typename U, U> class T, typename A, int *B> void f(T<A, B>); // expected-note 2{{candidate}}
+  void g() {
+    // FIXME: The first and second function templates above should be
+    // considered more specialized than the last two, but during partial
+    // ordering we fail to check that we actually deduced template arguments
+    // that make the deduced A identical to A.
+    X<int *, &n> x; f(x); // expected-error {{ambiguous}}
+    X<int *, &m> y; f(y); // expected-error {{ambiguous}}
+  }
+}
+
+namespace pointer_to_char_array {
+  typedef char T[4];
+  template<T *P> struct A { void f(); };
+  template<T *P> void A<P>::f() {}
+  T foo = "foo";
+  void g() { A<&foo>().f(); }
+}
diff --git a/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index aa4cc8c..cfaad0c 100644
--- a/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -27,3 +27,12 @@
 namespace Auto {
   template<auto> struct A { };  // expected-error {{until C++1z}}
 }
+
+namespace check_conversion_early {
+  struct X {};
+  template<int> struct A {};
+  template<X &x> struct A<x> {}; // expected-error {{not implicitly convertible}}
+
+  struct Y { constexpr operator int() const { return 0; } };
+  template<Y &y> struct A<y> {}; // expected-error {{cannot be deduced}} expected-note {{'y'}}
+}
diff --git a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index 59b05a1..c1fcedd 100644
--- a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -122,13 +122,13 @@
   int a_exp = a<3>(A<3>());
 
   template<decltype(nullptr)> struct B {};
-  template<int *P> int b(B<P>); // expected-note {{does not have the same type}} expected-note {{not implicitly convertible}}
+  template<int *P> int b(B<P>); // expected-error {{value of type 'int *' is not implicitly convertible to 'decltype(nullptr)'}}
   int b_imp = b(B<nullptr>()); // expected-error {{no matching function}}
   int b_exp = b<nullptr>(B<nullptr>()); // expected-error {{no matching function}}
 
   struct X { constexpr operator int() { return 0; } } x;
   template<X &> struct C {};
-  template<int N> int c(C<N>); // expected-note {{does not have the same type}} expected-note {{not implicitly convertible}}
+  template<int N> int c(C<N>); // expected-error {{value of type 'int' is not implicitly convertible to 'DeduceDifferentType::X &'}}
   int c_imp = c(C<x>()); // expected-error {{no matching function}}
   int c_exp = c<x>(C<x>()); // expected-error {{no matching function}}
 
@@ -137,7 +137,7 @@
   struct Z { constexpr operator Y&() { return y; } } z;
   constexpr Y::operator Z&() { return z; }
   template<Y &> struct D {};
-  template<Z &z> int d(D<z>); // expected-note {{does not have the same type}}
+  template<Z &z> int d(D<z>); // expected-note {{couldn't infer template argument 'z'}}
   int d_imp = d(D<y>()); // expected-error {{no matching function}}
   int d_exp = d<y>(D<y>());
 }
@@ -175,14 +175,33 @@
 
     // pointers
     template<auto v>    class B { };
-    template<auto* p>   class B<p> { };
+    template<auto* p>   class B<p> { }; // expected-note {{matches}}
     template<auto** pp> class B<pp> { };
-    template<auto* p0>   int &f(B<p0> b);
-    template<auto** pp0> float &f(B<pp0> b);
+    template<auto* p0>   int &f(B<p0> b); // expected-note {{candidate}}
+    template<auto** pp0> float &f(B<pp0> b); // expected-note {{candidate}}
 
     int a, *b = &a;
     int &r = f(B<&a>());
     float &s = f(B<&b>());
+
+    // pointers to members
+    template<typename T, auto *T::*p> struct B<p> {};
+    template<typename T, auto **T::*p> struct B<p> {};
+    template<typename T, auto *T::*p0>   char &f(B<p0> b); // expected-note {{candidate}}
+    template<typename T, auto **T::*pp0> short &f(B<pp0> b); // expected-note {{candidate}}
+
+    struct X { int n; int *p; int **pp; typedef int a, b; };
+    auto t = f(B<&X::n>()); // expected-error {{no match}}
+    char &u = f(B<&X::p>());
+    short &v = f(B<&X::pp>());
+
+    // A case where we need to do auto-deduction, and check whether the
+    // resulting dependent types match during partial ordering. These
+    // templates are not ordered due to the mismatching function parameter.
+    template<typename T, auto *(*f)(T, typename T::a)> struct B<f> {}; // expected-note {{matches}}
+    template<typename T, auto **(*f)(T, typename T::b)> struct B<f> {}; // expected-note {{matches}}
+    int **g(X, int);
+    B<&g> bg; // expected-error {{ambiguous}}
   }
 
   namespace Chained {
@@ -231,6 +250,23 @@
   }
 
   namespace Decomposition {
+    // Types of deduced non-type template arguments must match exactly, so
+    // partial ordering fails in both directions here.
+    template<auto> struct Any;
+    template<int N> struct Any<N> { typedef int Int; }; // expected-note 3{{match}}
+    template<short N> struct Any<N> { typedef int Short; }; // expected-note 3{{match}}
+    Any<0>::Int is_int; // expected-error {{ambiguous}}
+    Any<(short)0>::Short is_short; // expected-error {{ambiguous}}
+    Any<(char)0>::Short is_char; // expected-error {{ambiguous}}
+
+    template<int, auto> struct NestedAny;
+    template<auto N> struct NestedAny<0, N>; // expected-note 3{{match}}
+    template<int N> struct NestedAny<0, N> { typedef int Int; }; // expected-note 3{{match}}
+    template<short N> struct NestedAny<0, N> { typedef int Short; }; // expected-note 3{{match}}
+    NestedAny<0, 0>::Int nested_int; // expected-error {{ambiguous}}
+    NestedAny<0, (short)0>::Short nested_short; // expected-error {{ambiguous}}
+    NestedAny<0, (char)0>::Short nested_char; // expected-error {{ambiguous}}
+
     double foo(int, bool);
     template<auto& f> struct fn_result_type;
 
@@ -242,6 +278,12 @@
 
     using R1 = fn_result_type<foo>::type;
     using R1 = double;
+
+    template<int, auto &f> struct fn_result_type_partial_order;
+    template<auto &f> struct fn_result_type_partial_order<0, f>;
+    template<class R, class... Args, R (& f)(Args...)>
+    struct fn_result_type_partial_order<0, f> {};
+    fn_result_type_partial_order<0, foo> frtpo;
   }
 
   namespace Variadic {
@@ -265,3 +307,24 @@
     static_assert(nth_element_v<2, value_list<'a', 27U, false>> == false, "value mismatch");
   }
 }
+
+namespace Nested {
+  template<typename T> struct A {
+    template<auto X> struct B;
+    template<auto *P> struct B<P>;
+    template<auto **P> struct B<P> { using pointee = decltype(+**P); };
+    template<auto (*P)(T)> struct B<P> { using param = T; };
+    template<typename U, auto (*P)(T, U)> struct B<P> { using param2 = U; };
+  };
+
+  using Int = int;
+
+  int *n;
+  using Int = A<int>::B<&n>::pointee;
+
+  void f(int);
+  using Int = A<int>::B<&f>::param;
+
+  void g(int, int);
+  using Int = A<int>::B<&g>::param2;
+}
diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp
index 6d93f15..b0df914 100644
--- a/test/SemaTemplate/temp_arg_template.cpp
+++ b/test/SemaTemplate/temp_arg_template.cpp
@@ -6,11 +6,12 @@
 
 template<template<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}}
 
-template<template<int I> class X> struct C;  // expected-note{{previous non-type template parameter with type 'int' is here}}
+template<template<int I> class X> struct C;  // expected-note 2{{previous non-type template parameter with type 'int' is here}}
 
 template<class> struct X; // expected-note{{too few template parameters in template template argument}}
 template<int N> struct Y; // expected-note{{template parameter has a different kind in template argument}}
 template<long N> struct Ylong; // expected-note{{template non-type parameter has a different type 'long' in template argument}}
+template<const int &N> struct Yref; // expected-note{{template non-type parameter has a different type 'const int &' in template argument}}
 
 namespace N {
   template<class> struct Z;
@@ -27,6 +28,7 @@
 B<X> *a6; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
 C<Y> *a7;
 C<Ylong> *a8; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+C<Yref> *a9; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
 
 template<typename T> void f(int);
 
@@ -98,3 +100,9 @@
 void foo() {
   f7<identity>();
 }
+
+namespace CheckDependentNonTypeParamTypes {
+  template<template<typename T, typename U, T v> class> struct A {}; // expected-note {{previous}}
+  template<typename T, typename U, U v> struct B {}; // expected-note {{different type}}
+  A<B> ab; // expected-error {{different template parameters}}
+}
diff --git a/test/SemaTemplate/temp_arg_template_cxx1z.cpp b/test/SemaTemplate/temp_arg_template_cxx1z.cpp
new file mode 100644
index 0000000..e3f228e
--- /dev/null
+++ b/test/SemaTemplate/temp_arg_template_cxx1z.cpp
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -frelaxed-template-template-args %s
+
+// expected-note@temp_arg_template_cxx1z.cpp:* 1+{{}}
+
+template<template<int> typename> struct Ti;
+template<template<int...> typename> struct TPi;
+template<template<int, int...> typename> struct TiPi;
+template<template<int..., int...> typename> struct TPiPi; // FIXME: Why is this not ill-formed?
+
+template<typename T, template<T> typename> struct tT0;
+template<template<typename T, T> typename> struct Tt0;
+
+template<template<typename> typename> struct Tt;
+template<template<typename, typename...> typename> struct TtPt;
+
+template<int> struct i;
+template<int, int = 0> struct iDi;
+template<int, int> struct ii;
+template<int...> struct Pi;
+template<int, int, int...> struct iiPi;
+
+template<int, typename = int> struct iDt;
+template<int, typename> struct it;
+
+template<typename T, T v> struct t0;
+
+template<typename...> struct Pt;
+
+namespace IntParam {
+  using ok = Pt<Ti<i>,
+        Ti<iDi>,
+        Ti<Pi>,
+        Ti<iDt>>;
+  using err1 = Ti<ii>; // expected-error {{different template parameters}}
+  using err2 = Ti<iiPi>; // expected-error {{different template parameters}}
+  using err3 = Ti<t0>; // expected-error {{different template parameters}}
+  using err4 = Ti<it>; // expected-error {{different template parameters}}
+}
+
+// These are accepted by the backwards-compatibility "parameter pack in
+// parameter matches any number of parameters in arguments" rule.
+namespace IntPackParam {
+  using ok = TPi<Pi>;
+  using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>;
+  using err1 = TPi<t0>; // expected-error {{different template parameters}}
+  using err2 = TPi<iDt>; // expected-error {{different template parameters}}
+  using err3 = TPi<it>; // expected-error {{different template parameters}}
+}
+
+namespace IntAndPackParam {
+  using ok = TiPi<Pi>;
+  using ok_compat = Pt<TiPi<ii>, TiPi<iDi>, TiPi<iiPi>>;
+  using err = TiPi<iDi>;
+}
+
+namespace DependentType {
+  using ok = Pt<tT0<int, i>, tT0<int, iDi>>;
+  using err1 = tT0<int, ii>; // expected-error {{different template parameters}}
+  using err2 = tT0<short, i>; // FIXME: should this be OK?
+  using err2a = tT0<long long, i>; // FIXME: should this be OK (if long long is larger than int)?
+  using err2b = tT0<void*, i>; // expected-error {{different template parameters}}
+  using err3 = tT0<short, t0>; // expected-error {{different template parameters}}
+
+  using ok2 = Tt0<t0>;
+  using err4 = Tt0<it>; // expected-error {{different template parameters}}
+}
+
+namespace Auto {
+  template<template<int> typename T> struct TInt {};
+  template<template<int*> typename T> struct TIntPtr {};
+  template<template<auto> typename T> struct TAuto {};
+  template<template<auto*> typename T> struct TAutoPtr {};
+  template<template<decltype(auto)> typename T> struct TDecltypeAuto {};
+  template<auto> struct Auto;
+  template<auto*> struct AutoPtr;
+  template<decltype(auto)> struct DecltypeAuto;
+  template<int> struct Int;
+  template<int*> struct IntPtr;
+
+  TInt<Auto> ia;
+  TInt<AutoPtr> iap; // expected-error {{different template parameters}}
+  TInt<DecltypeAuto> ida;
+  TInt<Int> ii;
+  TInt<IntPtr> iip; // expected-error {{different template parameters}}
+
+  TIntPtr<Auto> ipa;
+  TIntPtr<AutoPtr> ipap;
+  TIntPtr<DecltypeAuto> ipda;
+  TIntPtr<Int> ipi; // expected-error {{different template parameters}}
+  TIntPtr<IntPtr> ipip;
+
+  TAuto<Auto> aa;
+  TAuto<AutoPtr> aap; // expected-error {{different template parameters}}
+  TAuto<Int> ai; // expected-error {{different template parameters}}
+  TAuto<IntPtr> aip; // expected-error {{different template parameters}}
+
+  TAutoPtr<Auto> apa;
+  TAutoPtr<AutoPtr> apap;
+  TAutoPtr<Int> api; // expected-error {{different template parameters}}
+  TAutoPtr<IntPtr> apip; // expected-error {{different template parameters}}
+
+  TDecltypeAuto<DecltypeAuto> dada;
+  TDecltypeAuto<Int> dai; // expected-error {{different template parameters}}
+  TDecltypeAuto<IntPtr> daip; // expected-error {{different template parameters}}
+
+  // FIXME: It's completely unclear what should happen here, but these results
+  // seem at least plausible:
+  TAuto<DecltypeAuto> ada;
+  TAutoPtr<DecltypeAuto> apda;
+  // Perhaps this case should be invalid, as there are valid 'decltype(auto)'
+  // parameters (such as 'user-defined-type &') that are not valid 'auto'
+  // parameters.
+  TDecltypeAuto<Auto> daa;
+  TDecltypeAuto<AutoPtr> daa; // expected-error {{different template parameters}}
+
+  int n;
+  template<auto A, decltype(A) B = &n> struct SubstFailure;
+  TInt<SubstFailure> isf; // FIXME: this should be ill-formed
+  TIntPtr<SubstFailure> ipsf;
+}
diff --git a/test/SemaTemplate/temp_class_spec_neg.cpp b/test/SemaTemplate/temp_class_spec_neg.cpp
index 1c77038..6366a52 100644
--- a/test/SemaTemplate/temp_class_spec_neg.cpp
+++ b/test/SemaTemplate/temp_class_spec_neg.cpp
@@ -20,9 +20,9 @@
 #endif
 
 // C++ [temp.class.spec]p9
-//   bullet 1
+//   bullet 1, as amended by DR1315
 template <int I, int J> struct A {}; 
-template <int I> struct A<I+5, I*2> {}; // expected-error{{depends on}} 
+template <int I> struct A<I+5, I*2> {}; // expected-error{{cannot be deduced}} expected-note {{'I'}}
 template <int I, int J> struct B {}; 
 template <int I> struct B<I, I> {}; //OK 
 
@@ -50,4 +50,4 @@
 
 template<typename T> struct Test1;
 template<typename T, typename U>  // expected-note{{non-deducible}}
-  struct Test1<T*> { }; // expected-warning{{never be used}}
+  struct Test1<T*> { }; // expected-error{{never be used}}
diff --git a/test/SemaTemplate/temp_explicit.cpp b/test/SemaTemplate/temp_explicit.cpp
index e8c9dfb..0bb0cfa 100644
--- a/test/SemaTemplate/temp_explicit.cpp
+++ b/test/SemaTemplate/temp_explicit.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -std=c++11 %s
 //
 // Tests explicit instantiation of templates.
 template<typename T, typename U = T> class X0 { };
@@ -98,7 +100,12 @@
 template struct X5<float&>::Inner2; // expected-note{{instantiation}}
 
 namespace N3 {
-  template struct N2::X5<int>::Inner2; // expected-warning {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
+  template struct N2::X5<int>::Inner2;
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
+#else
+// expected-error@-4 {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
+#endif
 }
 
 struct X6 {
@@ -145,7 +152,17 @@
 namespace N2 {
   using namespace N1;
 
-  template struct X7<double>; // expected-warning{{must occur in namespace}}
+  template struct X7<double>;
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{explicit instantiation of 'N1::X7' must occur in namespace 'N1'}}
+#else
+// expected-error@-4 {{explicit instantiation of 'N1::X7' must occur in namespace 'N1'}}
+#endif
 
-  template struct X9<float>; // expected-warning{{must occur at global scope}}
+  template struct X9<float>;
+#if __cplusplus <= 199711L
+// expected-warning@-2 {{explicit instantiation of 'X9' must occur at global scope}}
+#else
+// expected-error@-4 {{explicit instantiation of 'X9' must occur at global scope}}
+#endif
 }
diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp
index 499d289..4e6e224 100644
--- a/test/SemaTemplate/template-id-expr.cpp
+++ b/test/SemaTemplate/template-id-expr.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++03 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 // PR5336
 template<typename FromCl>
 struct isa_impl_cl {
@@ -98,7 +100,14 @@
 template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}}
 
 class C {};
-template <template <typename> class D>  // expected-note{{previous use is here}}
+template <template <typename> class D>
 class E {
-  template class D<C>;  // expected-error {{elaborated type refers to a template template argument}}
+  template class D<C>;  // expected-error {{expected '<' after 'template'}}
+  template<> class D<C>;  // expected-error {{cannot specialize a template template parameter}}
+  friend class D<C>; // expected-error {{type alias template 'D' cannot be referenced with a class specifier}}
 };
+#if __cplusplus <= 199711L
+// expected-warning@+2 {{extension}}
+#endif
+template<typename T> using D = int; // expected-note {{declared here}} 
+E<D> ed; // expected-note {{instantiation of}}
diff --git a/test/SemaTemplate/typename-specifier-3.cpp b/test/SemaTemplate/typename-specifier-3.cpp
index a463d88..dfab5a0 100644
--- a/test/SemaTemplate/typename-specifier-3.cpp
+++ b/test/SemaTemplate/typename-specifier-3.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // PR4364
-template<class T> struct a {
+template<class T> struct a { // expected-note {{here}}
   T b() {
     return typename T::x();
   }
@@ -17,3 +17,4 @@
 // Some extra tests for invalid cases
 template<class T> struct test2 { T b() { return typename T::a; } }; // expected-error{{expected '(' for function-style cast or type construction}}
 template<class T> struct test3 { T b() { return typename a; } }; // expected-error{{expected a qualified name after 'typename'}}
+template<class T> struct test4 { T b() { return typename ::a; } }; // expected-error{{refers to non-type member}} expected-error{{expected '(' for function-style cast or type construction}}
diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp
index b36a103..99326f6 100644
--- a/test/SemaTemplate/typename-specifier.cpp
+++ b/test/SemaTemplate/typename-specifier.cpp
@@ -102,7 +102,7 @@
 
 template<typename T> struct E {
   typedef typename T::foo foo;
-  typedef typename foo::bar bar;  // expected-error {{type 'foo' (aka 'double') cannot be used prior to '::' because it has no members}}
+  typedef typename foo::bar bar;  // expected-error {{type 'E<F>::foo' (aka 'double') cannot be used prior to '::' because it has no members}}
 };
 
 struct F {
diff --git a/test/SemaTemplate/undefined-template.cpp b/test/SemaTemplate/undefined-template.cpp
index a03d0b7..7dfe2fd 100644
--- a/test/SemaTemplate/undefined-template.cpp
+++ b/test/SemaTemplate/undefined-template.cpp
@@ -134,6 +134,14 @@
                         // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::C2<long>::tmeth_2<int>' is explicitly instantiated in another translation unit}}
 }
 
+namespace test_24 {
+  template <typename T> struct X {
+    friend void g(int);
+    operator int() { return 0; }
+  };
+  void h(X<int> x) { g(x); } // no warning for use of 'g' despite the declaration having been instantiated from a template
+}
+
 int main() {
   return 0;
 }
diff --git a/test/SemaTemplate/value-dependent-null-pointer-constant.cpp b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
index 223500e..29fd15e 100644
--- a/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
+++ b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
@@ -1,17 +1,30 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// 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
 
 template<typename T, int N>
 struct X0 {
   const char *f0(bool Cond) {
     return Cond? "honk" : N;
+#if __cplusplus >= 201103L
+// expected-error@-2 {{incompatible operand types ('const char *' and 'int')}}
+#else
+// expected-no-diagnostics
+#endif
   }
 
   const char *f1(bool Cond) {
     return Cond? N : "honk";
+#if __cplusplus >= 201103L
+// expected-error@-2 {{incompatible operand types ('int' and 'const char *')}}
+#endif
   }
   
   bool f2(const char *str) {
     return str == N;
+#if __cplusplus >= 201103L
+// expected-error@-2 {{comparison between pointer and integer ('const char *' and 'int')}}
+#endif
   }
 };
 
diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp
index 4044f9e..3578350 100644
--- a/test/SemaTemplate/virtual-member-functions.cpp
+++ b/test/SemaTemplate/virtual-member-functions.cpp
@@ -1,5 +1,9 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -std=c++98 -verify %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -std=c++11 -verify %s
 
 namespace PR5557 {
 template <class T> struct A {
@@ -76,34 +80,76 @@
 }
 
 namespace PR7114 {
-  class A { virtual ~A(); }; // expected-note{{declared private here}}
+  class A { virtual ~A(); };
+#if __cplusplus <= 199711L
+  // expected-note@-2{{declared private here}}
+#else
+  // expected-note@-4 3 {{overridden virtual function is here}}
+#endif
 
   template<typename T>
   class B {
   public:
-    class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}}
+    class Inner : public A { };
+#if __cplusplus <= 199711L
+// expected-error@-2{{base class 'PR7114::A' has private destructor}}
+#else
+// expected-error@-4 2 {{deleted function '~Inner' cannot override a non-deleted function}}
+// expected-note@-5 2 {{destructor of 'Inner' is implicitly deleted because base class 'PR7114::A' has an inaccessible destructor}}
+#ifdef MSABI
+// expected-note@-7 1 {{destructor of 'Inner' is implicitly deleted because base class 'PR7114::A' has an inaccessible destructor}}
+#endif
+#endif
+
     static Inner i;
     static const unsigned value = sizeof(i) == 4;
+#if __cplusplus >= 201103L
+// expected-note@-2 {{in instantiation of member class 'PR7114::B<int>::Inner' requested here}}
+// expected-note@-3 {{in instantiation of member class 'PR7114::B<float>::Inner' requested here}}
+#endif
   };
 
   int f() { return B<int>::value; }
+#if __cplusplus >= 201103L
+// expected-note@-2 {{in instantiation of template class 'PR7114::B<int>' requested here}}
+#endif
 
 #ifdef MSABI
-  void test_typeid(B<float>::Inner bfi) { // expected-note{{implicit destructor}}
+  void test_typeid(B<float>::Inner bfi) {
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor}}
+#else
+// expected-error@-4 {{attempt to use a deleted function}}
+// expected-note@-5 {{in instantiation of template class 'PR7114::B<float>' requested here}}
+#endif
+
     (void)typeid(bfi);
 #else
   void test_typeid(B<float>::Inner bfi) {
-    (void)typeid(bfi); // expected-note{{implicit destructor}}
+#if __cplusplus >= 201103L
+// expected-note@-2 {{in instantiation of template class 'PR7114::B<float>' requested here}}
+#endif
+    (void)typeid(bfi);
+#if __cplusplus <= 199711L
+// expected-note@-2 {{implicit destructor}}
+#endif
 #endif
   }
 
   template<typename T>
   struct X : A {
+#if __cplusplus >= 201103L
+// expected-error@-2 {{deleted function '~X' cannot override a non-deleted function}}
+// expected-note@-3  {{destructor of 'X<int>' is implicitly deleted because base class 'PR7114::A' has an inaccessible destructor}}
+#endif
     void f() { }
   };
 
   void test_X(X<int> &xi, X<float> &xf) {
     xi.f();
+#if __cplusplus >= 201103L
+// expected-note@-2 {{in instantiation of template class 'PR7114::X<int>' requested here}}
+#endif
   }
 }
 
diff --git a/test/Tooling/lit.local.cfg b/test/Tooling/lit.local.cfg
index da2a68b..4cd8ba7 100644
--- a/test/Tooling/lit.local.cfg
+++ b/test/Tooling/lit.local.cfg
@@ -1,2 +1,2 @@
-if config.root.clang_staticanalyzer == 0:
+if not config.root.clang_staticanalyzer:
     config.unsupported = True
diff --git a/test/Unit/lit.cfg b/test/Unit/lit.cfg
index 4fa6e78..39fad00 100644
--- a/test/Unit/lit.cfg
+++ b/test/Unit/lit.cfg
@@ -94,15 +94,16 @@
 elif platform.system() == 'Windows':
     shlibpath_var = 'PATH'
 
+# in stand-alone builds, shlibdir is clang's build tree
+# while llvm_libs_dir is installed LLVM (and possibly older clang)
+llvm_shlib_dir = getattr(config, 'shlibdir', None)
+if not llvm_shlib_dir:
+    lit_config.fatal('No shlibdir set!')
 # Point the dynamic loader at dynamic libraries in 'lib'.
 llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
 if not llvm_libs_dir:
     lit_config.fatal('No LLVM libs dir set!')
-shlibpath = os.path.pathsep.join((llvm_libs_dir,
+shlibpath = os.path.pathsep.join((llvm_shlib_dir, llvm_libs_dir,
                                  config.environment.get(shlibpath_var,'')))
 
-# 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/lit.cfg b/test/lit.cfg
index 7d8bebf..5beecb6 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -202,7 +202,7 @@
 # Plugins (loadable modules)
 # TODO: This should be supplied by Makefile or autoconf.
 if sys.platform in ['win32', 'cygwin']:
-    has_plugins = (config.enable_shared == 1)
+    has_plugins = config.enable_shared
 else:
     has_plugins = True
 
@@ -253,12 +253,14 @@
     if os == 'win32':
       # If the OS is win32, we're done.
       return triple
-    if isa.startswith('x86') or isa == 'amd64' or re.match(r'i\d86', isa): 
+    if isa.startswith('x86') or isa == 'amd64' or re.match(r'i\d86', isa):
       # For x86 ISAs, adjust the OS.
       return isa + '-' + vendor + '-win32'
     # -win32 is not supported for non-x86 targets; use a default.
     return 'i686-pc-win32'
 
+config.substitutions.append( ('%clang_analyze_cc1',
+                              '%clang_cc1 -analyze %analyze') )
 config.substitutions.append( ('%clang_cc1',
                               '%s -cc1 -internal-isystem %s -nostdsysteminc'
                               % (config.clang,
@@ -291,6 +293,9 @@
     (' clang-cc ',
      """*** Do not use 'clang-cc' in tests, use '%clang_cc1'. ***""") )
 config.substitutions.append(
+    (' clang -cc1 -analyze ',
+     """*** Do not use 'clang -cc1 -analyze' in tests, use '%clang_analyze_cc1'. ***""") )
+config.substitutions.append(
     (' clang -cc1 ',
      """*** Do not use 'clang -cc1' in tests, use '%clang_cc1'. ***""") )
 config.substitutions.append(
@@ -353,7 +358,7 @@
     config.available_features.add('default-cxx-stdlib-set')
 
 # Enabled/disabled features
-if config.clang_staticanalyzer != 0:
+if config.clang_staticanalyzer:
     config.available_features.add("staticanalyzer")
 
 # As of 2011.08, crash-recovery tests still do not pass on FreeBSD.
@@ -392,6 +397,10 @@
 if config.host_triple == config.target_triple:
     config.available_features.add("native")
 
+# Test Driver/arch-specific-libdir-rpath.c is restricted to x86_64-linux
+if re.match(r'^x86_64.*-linux', config.target_triple):
+    config.available_features.add("x86_64-linux")
+
 # Case-insensitive file system
 def is_filesystem_case_insensitive():
     handle, path = tempfile.mkstemp(prefix='case-test', dir=config.test_exec_root)
@@ -474,10 +483,10 @@
 else:
     config.available_features.add("not_ubsan")
 
-if config.enable_backtrace == "1":
+if config.enable_backtrace:
     config.available_features.add("backtrace")
 
-if config.have_zlib == "1":
+if config.have_zlib:
     config.available_features.add("zlib")
 else:
     config.available_features.add("nozlib")
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index 5e1471f..ec447b6 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -14,13 +14,13 @@
 config.host_triple = "@LLVM_HOST_TRIPLE@"
 config.target_triple = "@TARGET_TRIPLE@"
 config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
-config.have_zlib = "@HAVE_LIBZ@"
-config.clang_arcmt = @ENABLE_CLANG_ARCMT@
+config.have_zlib = @HAVE_LIBZ@
+config.clang_arcmt = @CLANG_ENABLE_ARCMT@
 config.clang_default_cxx_stdlib = "@CLANG_DEFAULT_CXX_STDLIB@"
-config.clang_staticanalyzer = @ENABLE_CLANG_STATIC_ANALYZER@
-config.clang_examples = @ENABLE_CLANG_EXAMPLES@
+config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@
+config.clang_examples = @CLANG_BUILD_EXAMPLES@
 config.enable_shared = @ENABLE_SHARED@
-config.enable_backtrace = "@ENABLE_BACKTRACES@"
+config.enable_backtrace = @ENABLE_BACKTRACES@
 config.host_arch = "@HOST_ARCH@"
 
 # Support substitution of the tools and libs dirs with user parameters. This is
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index b8850e4..b0c97f0 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -5,6 +5,7 @@
 add_clang_subdirectory(clang-format)
 add_clang_subdirectory(clang-format-vs)
 add_clang_subdirectory(clang-fuzzer)
+add_clang_subdirectory(clang-import-test)
 add_clang_subdirectory(clang-offload-bundler)
 
 add_clang_subdirectory(c-index-test)
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index e0df503..ad990e0 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -17,6 +17,7 @@
 if (LLVM_BUILD_STATIC)
   target_link_libraries(c-index-test
     libclang_static
+    clangCodeGen
     clangIndex
   )
 else()
@@ -24,8 +25,10 @@
     libclang
     clangAST
     clangBasic
+    clangCodeGen
     clangFrontend
     clangIndex
+    clangSerialization
   )
 endif()
 
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index de87351..b6e6ded 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1316,6 +1316,25 @@
     return CXVisit_Continue;
 }
 
+static void PrintTypeTemplateArgs(CXType T, const char *Format) {
+  int NumTArgs = clang_Type_getNumTemplateArguments(T);
+  if (NumTArgs != -1 && NumTArgs != 0) {
+    int i;
+    CXType TArg;
+    printf(Format, NumTArgs);
+    for (i = 0; i < NumTArgs; ++i) {
+      TArg = clang_Type_getTemplateArgumentAsType(T, i);
+      if (TArg.kind != CXType_Invalid) {
+        PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]");
+      }
+    }
+    /* Ensure that the returned type is invalid when indexing off-by-one. */
+    TArg = clang_Type_getTemplateArgumentAsType(T, i);
+    assert(TArg.kind == CXType_Invalid);
+    printf("]");
+  }
+}
+
 static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
                                          CXClientData d) {
   if (!clang_isInvalid(clang_getCursorKind(cursor))) {
@@ -1333,11 +1352,14 @@
       printf(" lvalue-ref-qualifier");
     if (RQ == CXRefQualifier_RValue)
       printf(" rvalue-ref-qualifier");
+    /* Print the template argument types if they exist. */
+    PrintTypeTemplateArgs(T, " [templateargs/%d=");
     /* Print the canonical type if it is different. */
     {
       CXType CT = clang_getCanonicalType(T);
       if (!clang_equalTypes(T, CT)) {
         PrintTypeAndTypeKind(CT, " [canonicaltype=%s] [canonicaltypekind=%s]");
+        PrintTypeTemplateArgs(CT, " [canonicaltemplateargs/%d=");
       }
     }
     /* Print the return type if it exists. */
@@ -1362,21 +1384,6 @@
         printf("]");
       }
     }
-    /* Print the template argument types if they exist. */
-    {
-      int NumTArgs = clang_Type_getNumTemplateArguments(T);
-      if (NumTArgs != -1 && NumTArgs != 0) {
-        int i;
-        printf(" [templateargs/%d=", NumTArgs);
-        for (i = 0; i < NumTArgs; ++i) {
-          CXType TArg = clang_Type_getTemplateArgumentAsType(T, i);
-          if (TArg.kind != CXType_Invalid) {
-            PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]");
-          }
-        }
-        printf("]");
-      }
-    }
     /* Print if this is a non-POD type. */
     printf(" [isPOD=%d]", clang_isPODType(T));
     /* Print the pointee type. */
@@ -4445,13 +4452,13 @@
   LIBXML_TEST_VERSION
 #endif
 
+  if (argc > 1 && strcmp(argv[1], "core") == 0)
+    return indextest_core_main(argc, argv);
+
   client_data.main_func = cindextest_main;
   client_data.argc = argc;
   client_data.argv = argv;
 
-  if (argc > 1 && strcmp(argv[1], "core") == 0)
-    client_data.main_func = indextest_core_main;
-
   if (getenv("CINDEXTEST_NOTHREADS"))
     return client_data.main_func(client_data.argc, client_data.argv);
 
diff --git a/tools/c-index-test/core_main.cpp b/tools/c-index-test/core_main.cpp
index 3e4052c..4f2c3cb 100644
--- a/tools/c-index-test/core_main.cpp
+++ b/tools/c-index-test/core_main.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
@@ -15,6 +16,7 @@
 #include "clang/Index/IndexDataConsumer.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Index/CodegenNameGenerator.h"
+#include "clang/Serialization/ASTReader.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/raw_ostream.h"
@@ -49,6 +51,20 @@
   "invocation\n"
 );
 
+static cl::opt<bool>
+DumpModuleImports("dump-imported-module-files",
+               cl::desc("Print symbols and input files from imported modules"));
+
+static cl::opt<bool>
+IncludeLocals("include-locals", cl::desc("Print local symbols"));
+
+static cl::opt<std::string>
+ModuleFilePath("module-file",
+               cl::desc("Path to module file to print symbols from"));
+static cl::opt<std::string>
+  ModuleFormat("fmodule-format", cl::init("raw"),
+        cl::desc("Container format for clang modules and PCH, 'raw' or 'obj'"));
+
 }
 } // anonymous namespace
 
@@ -134,30 +150,88 @@
 // Print Source Symbols
 //===----------------------------------------------------------------------===//
 
-static bool printSourceSymbols(ArrayRef<const char *> Args) {
+static void dumpModuleFileInputs(serialization::ModuleFile &Mod,
+                                 ASTReader &Reader,
+                                 raw_ostream &OS) {
+  OS << "---- Module Inputs ----\n";
+  Reader.visitInputFiles(Mod, /*IncludeSystem=*/true, /*Complain=*/false,
+                        [&](const serialization::InputFile &IF, bool isSystem) {
+    OS << (isSystem ? "system" : "user") << " | ";
+    OS << IF.getFile()->getName() << '\n';
+  });
+}
+
+static bool printSourceSymbols(ArrayRef<const char *> Args,
+                               bool dumpModuleImports,
+                               bool indexLocals) {
   SmallVector<const char *, 4> ArgsWithProgName;
   ArgsWithProgName.push_back("clang");
   ArgsWithProgName.append(Args.begin(), Args.end());
   IntrusiveRefCntPtr<DiagnosticsEngine>
     Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
-  IntrusiveRefCntPtr<CompilerInvocation>
-    CInvok(createInvocationFromCommandLine(ArgsWithProgName, Diags));
+  auto CInvok = createInvocationFromCommandLine(ArgsWithProgName, Diags);
   if (!CInvok)
     return true;
 
-  auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(outs());
+  raw_ostream &OS = outs();
+  auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(OS);
   IndexingOptions IndexOpts;
+  IndexOpts.IndexFunctionLocals = indexLocals;
   std::unique_ptr<FrontendAction> IndexAction;
   IndexAction = createIndexingAction(DataConsumer, IndexOpts,
                                      /*WrappedAction=*/nullptr);
 
   auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
   std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction(
-      CInvok.get(), PCHContainerOps, Diags, IndexAction.get()));
+      std::move(CInvok), PCHContainerOps, Diags, IndexAction.get()));
 
   if (!Unit)
     return true;
 
+  if (dumpModuleImports) {
+    if (auto Reader = Unit->getASTReader()) {
+      Reader->getModuleManager().visit([&](serialization::ModuleFile &Mod) -> bool {
+        OS << "==== Module " << Mod.ModuleName << " ====\n";
+        indexModuleFile(Mod, *Reader, DataConsumer, IndexOpts);
+        dumpModuleFileInputs(Mod, *Reader, OS);
+        return true; // skip module dependencies.
+      });
+    }
+  }
+
+  return false;
+}
+
+static bool printSourceSymbolsFromModule(StringRef modulePath,
+                                         StringRef format) {
+  FileSystemOptions FileSystemOpts;
+  auto pchContOps = std::make_shared<PCHContainerOperations>();
+  // Register the support for object-file-wrapped Clang modules.
+  pchContOps->registerReader(llvm::make_unique<ObjectFilePCHContainerReader>());
+  auto pchRdr = pchContOps->getReaderOrNull(format);
+  if (!pchRdr) {
+    errs() << "unknown module format: " << format << '\n';
+    return true;
+  }
+
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+      CompilerInstance::createDiagnostics(new DiagnosticOptions());
+  std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
+      modulePath, *pchRdr, Diags,
+      FileSystemOpts, /*UseDebugInfo=*/false,
+      /*OnlyLocalDecls=*/true, None,
+      /*CaptureDiagnostics=*/false,
+      /*AllowPCHWithCompilerErrors=*/true,
+      /*UserFilesAreVolatile=*/false);
+  if (!AU) {
+    errs() << "failed to create TU for: " << modulePath << '\n';
+    return true;
+  }
+
+  auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(outs());
+  IndexingOptions IndexOpts;
+  indexASTUnit(*AU, DataConsumer, IndexOpts);
+
   return false;
 }
 
@@ -167,6 +241,8 @@
 
 static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS) {
   OS << getSymbolKindString(SymInfo.Kind);
+  if (SymInfo.SubKind != SymbolSubKind::None)
+    OS << '/' << getSymbolSubKindString(SymInfo.SubKind);
   if (SymInfo.Properties) {
     OS << '(';
     printSymbolProperties(SymInfo.Properties, OS);
@@ -218,11 +294,15 @@
   }
 
   if (options::Action == ActionType::PrintSourceSymbols) {
+    if (!options::ModuleFilePath.empty()) {
+      return printSourceSymbolsFromModule(options::ModuleFilePath,
+                                          options::ModuleFormat);
+    }
     if (CompArgs.empty()) {
       errs() << "error: missing compiler args; pass '-- <compiler arguments>'\n";
       return 1;
     }
-    return printSourceSymbols(CompArgs);
+    return printSourceSymbols(CompArgs, options::DumpModuleImports, options::IncludeLocals);
   }
 
   return 0;
diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp
index b4177d4..dac11ff 100644
--- a/tools/clang-check/ClangCheck.cpp
+++ b/tools/clang-check/ClangCheck.cpp
@@ -140,6 +140,7 @@
       return clang::CreateASTDeclNodeLister();
     if (ASTDump)
       return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls=*/true,
+                                    /*Deserialize=*/false,
                                     /*DumpLookups=*/false);
     if (ASTPrint)
       return clang::CreateASTPrinter(nullptr, ASTDumpFilter);
diff --git a/tools/clang-format-vs/.gitignore b/tools/clang-format-vs/.gitignore
index 6453dd8..c9d25d9 100644
--- a/tools/clang-format-vs/.gitignore
+++ b/tools/clang-format-vs/.gitignore
@@ -1,5 +1,6 @@
 # Visual Studio files
 .vs/
+*.user
 /packages/
 /ClangFormat/obj/
 /ClangFormat/bin/
diff --git a/tools/clang-format-vs/CMakeLists.txt b/tools/clang-format-vs/CMakeLists.txt
index 6d2ef73..d07a4f6 100644
--- a/tools/clang-format-vs/CMakeLists.txt
+++ b/tools/clang-format-vs/CMakeLists.txt
@@ -11,8 +11,11 @@
       "${CLANG_SOURCE_DIR}/LICENSE.TXT"
       "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/license.txt")
 
+  # Build number added to Clang version to ensure that new VSIX can be upgraded
+  string(TIMESTAMP CLANG_FORMAT_VSIX_BUILD %y%m%d%H%M UTC)
+
   if (NOT CLANG_FORMAT_VS_VERSION)
-    set(CLANG_FORMAT_VS_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
+    set(CLANG_FORMAT_VS_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}.${CLANG_FORMAT_VSIX_BUILD}")
   endif()
 
   configure_file("source.extension.vsixmanifest.in"
diff --git a/tools/clang-format-vs/ClangFormat/ClangFormat.vsct b/tools/clang-format-vs/ClangFormat/ClangFormat.vsct
index 3e3e22e..7989577 100644
--- a/tools/clang-format-vs/ClangFormat/ClangFormat.vsct
+++ b/tools/clang-format-vs/ClangFormat/ClangFormat.vsct
@@ -61,15 +61,21 @@
               <CommandFlag>DynamicVisibility</CommandFlag>

           If you do not want an image next to your command, remove the Icon node /> -->

 

-      <Button guid="guidClangFormatCmdSet" id="cmdidClangFormat" priority="0x0100" type="Button">

+      <Button guid="guidClangFormatCmdSet" id="cmdidClangFormatSelection" priority="0x0100" type="Button">

         <Parent guid="guidClangFormatCmdSet" id="MyMenuGroup" />

         <Icon guid="guidImages" id="bmpPic1" />

         <Strings>

-          <ButtonText>ClangFormat</ButtonText>

+          <ButtonText>Clang Format Selection</ButtonText>

         </Strings>

       </Button>

 

-

+      <Button guid="guidClangFormatCmdSet" id="cmdidClangFormatDocument" priority="0x0101" type="Button">

+        <Parent guid="guidClangFormatCmdSet" id="MyMenuGroup" />

+        <Icon guid="guidImages" id="bmpPic2" />

+        <Strings>

+          <ButtonText>Clang Format Document</ButtonText>

+        </Strings>

+      </Button>

 

     </Buttons>

    

@@ -88,7 +94,8 @@
 

 

   <KeyBindings>

-    <KeyBinding guid="guidClangFormatCmdSet" id="cmdidClangFormat" editor="guidTextEditor" key1="R" mod1="Control" key2="F" mod2="Control"/>

+    <KeyBinding guid="guidClangFormatCmdSet" id="cmdidClangFormatSelection" editor="guidTextEditor" key1="R" mod1="Control" key2="F" mod2="Control"/>

+    <KeyBinding guid="guidClangFormatCmdSet" id="cmdidClangFormatDocument" editor="guidTextEditor" key1="R" mod1="Control" key2="D" mod2="Control"/>

   </KeyBindings>

 

 

@@ -101,7 +108,8 @@
     <GuidSymbol name="guidClangFormatCmdSet" value="{e39cbab1-0f96-4022-a2bc-da5a9db7eb78}">

 

       <IDSymbol name="MyMenuGroup" value="0x1020" />

-      <IDSymbol name="cmdidClangFormat" value="0x0100" />

+      <IDSymbol name="cmdidClangFormatSelection" value="0x0100" />

+      <IDSymbol name="cmdidClangFormatDocument" value="0x0101" />

     </GuidSymbol>

 

     <GuidSymbol name="guidTextEditor" value="{8B382828-6202-11d1-8870-0000F87579D2}" />

diff --git a/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs b/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
index 6af2fd1..c7eac42 100644
--- a/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
+++ b/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
@@ -180,15 +180,44 @@
             var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;

             if (commandService != null)

             {

-                var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormat);

-                var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);

-                commandService.AddCommand(menuItem);

+                {

+                    var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormatSelection);

+                    var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);

+                    commandService.AddCommand(menuItem);

+                }

+

+                {

+                    var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormatDocument);

+                    var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);

+                    commandService.AddCommand(menuItem);

+                }

             }

         }

         #endregion

 

         private void MenuItemCallback(object sender, EventArgs args)

         {

+            var mc = sender as System.ComponentModel.Design.MenuCommand;

+            if (mc == null)

+                return;

+

+            switch (mc.CommandID.ID)

+            {

+                case (int)PkgCmdIDList.cmdidClangFormatSelection:

+                    FormatSelection();

+                    break;

+

+                case (int)PkgCmdIDList.cmdidClangFormatDocument:

+                    FormatDocument();

+                    break;

+            }

+        }

+

+        /// <summary>

+        /// Runs clang-format on the current selection

+        /// </summary>

+        private void FormatSelection()

+        {

             IWpfTextView view = GetCurrentView();

             if (view == null)

                 // We're not in a text view.

@@ -197,24 +226,40 @@
             int start = view.Selection.Start.Position.GetContainingLine().Start.Position;

             int end = view.Selection.End.Position.GetContainingLine().End.Position;

             int length = end - start;

+            

             // clang-format doesn't support formatting a range that starts at the end

             // of the file.

             if (start >= text.Length && text.Length > 0)

                 start = text.Length - 1;

             string path = GetDocumentParent(view);

             string filePath = GetDocumentPath(view);

+

+            RunClangFormatAndApplyReplacements(text, start, length, path, filePath, view);

+        }

+

+        /// <summary>

+        /// Runs clang-format on the current document

+        /// </summary>

+        private void FormatDocument()

+        {

+            IWpfTextView view = GetCurrentView();

+            if (view == null)

+                // We're not in a text view.

+                return;

+

+            string filePath = GetDocumentPath(view);

+            var path = Path.GetDirectoryName(filePath);

+            string text = view.TextBuffer.CurrentSnapshot.GetText();

+

+            RunClangFormatAndApplyReplacements(text, 0, text.Length, path, filePath, view);

+        }

+

+        private void RunClangFormatAndApplyReplacements(string text, int offset, int length, string path, string filePath, IWpfTextView view)

+        {

             try

             {

-                var root = XElement.Parse(RunClangFormat(text, start, length, path, filePath));

-                var edit = view.TextBuffer.CreateEdit();

-                foreach (XElement replacement in root.Descendants("replacement"))

-                {

-                    var span = new Span(

-                        int.Parse(replacement.Attribute("offset").Value),

-                        int.Parse(replacement.Attribute("length").Value));

-                    edit.Replace(span, replacement.Value);

-                }

-                edit.Apply();

+                string replacements = RunClangFormat(text, offset, length, path, filePath);

+                ApplyClangFormatReplacements(replacements, view);

             }

             catch (Exception e)

             {

@@ -305,6 +350,27 @@
         }

 

         /// <summary>

+        /// Applies the clang-format replacements (xml) to the current view

+        /// </summary>

+        private void ApplyClangFormatReplacements(string replacements, IWpfTextView view)

+        {

+            // clang-format returns no replacements if input text is empty

+            if (replacements.Length == 0)

+                return;

+

+            var root = XElement.Parse(replacements);

+            var edit = view.TextBuffer.CreateEdit();

+            foreach (XElement replacement in root.Descendants("replacement"))

+            {

+                var span = new Span(

+                    int.Parse(replacement.Attribute("offset").Value),

+                    int.Parse(replacement.Attribute("length").Value));

+                edit.Replace(span, replacement.Value);

+            }

+            edit.Apply();

+        }

+

+        /// <summary>

         /// Returns the currently active view if it is a IWpfTextView.

         /// </summary>

         private IWpfTextView GetCurrentView()

diff --git a/tools/clang-format-vs/ClangFormat/PkgCmdID.cs b/tools/clang-format-vs/ClangFormat/PkgCmdID.cs
index bb6b455..fcc31ee 100644
--- a/tools/clang-format-vs/ClangFormat/PkgCmdID.cs
+++ b/tools/clang-format-vs/ClangFormat/PkgCmdID.cs
@@ -2,6 +2,7 @@
 {

     static class PkgCmdIDList

     {

-        public const uint cmdidClangFormat = 0x100;

+        public const uint cmdidClangFormatSelection = 0x100;

+        public const uint cmdidClangFormatDocument = 0x101;

     };

 }
\ No newline at end of file
diff --git a/tools/clang-format-vs/README.txt b/tools/clang-format-vs/README.txt
index edfffed..84e0b45 100644
--- a/tools/clang-format-vs/README.txt
+++ b/tools/clang-format-vs/README.txt
@@ -25,3 +25,27 @@
 ClangFormat/source.extension.vsixmanifest. Once the plug-in has been built with

 CMake once, it can be built manually from the ClangFormat.sln solution in Visual

 Studio.

+

+===========

+ Debugging

+===========

+

+Once you've built the clang_format_vsix project from LLVM.sln at least once,

+open ClangFormat.sln in Visual Studio, then:

+

+- Make sure the "Debug" target is selected

+- Open the ClangFormat project properties

+- Select the Debug tab

+- Set "Start external program:" to where your devenv.exe is installed. Typically

+  it's "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe"

+- Set "Command line arguments" to: /rootsuffix Exp

+- You can now set breakpoints if you like

+- Press F5 to build and run with debugger

+

+If all goes well, a new instance of Visual Studio will be launched in a special

+mode where it uses the experimental hive instead of the normal configuration hive.

+By default, when you build a VSIX project in Visual Studio, it auto-registers the

+extension in the experimental hive, allowing you to test it. In the new Visual Studio

+instance, open or create a C++ solution, and you should now see the Clang Format

+entries in the Tool menu. You can test it out, and any breakpoints you set will be

+hit where you can debug as usual.

diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index c097239..ac0d0a8 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -236,8 +236,15 @@
 
 // Returns true on error.
 static bool format(StringRef FileName) {
+  if (!OutputXML && Inplace && FileName == "-") {
+    errs() << "error: cannot use -i when reading from stdin.\n";
+    return false;
+  }
+  // On Windows, overwriting a file with an open file mapping doesn't work,
+  // so read the whole file into memory when formatting in-place.
   ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
-      MemoryBuffer::getFileOrSTDIN(FileName);
+      !OutputXML && Inplace ? MemoryBuffer::getFileAsStream(FileName) :
+                              MemoryBuffer::getFileOrSTDIN(FileName);
   if (std::error_code EC = CodeOrErr.getError()) {
     errs() << EC.message() << "\n";
     return true;
@@ -249,11 +256,18 @@
   if (fillRanges(Code.get(), Ranges))
     return true;
   StringRef AssumedFileName = (FileName == "-") ? AssumeFileName : FileName;
-  FormatStyle FormatStyle = getStyle(Style, AssumedFileName, FallbackStyle);
+
+  llvm::Expected<FormatStyle> FormatStyle =
+      getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer());
+  if (!FormatStyle) {
+    llvm::errs() << llvm::toString(FormatStyle.takeError()) << "\n";
+    return true;
+  }
+
   if (SortIncludes.getNumOccurrences() != 0)
-    FormatStyle.SortIncludes = SortIncludes;
+    FormatStyle->SortIncludes = SortIncludes;
   unsigned CursorPosition = Cursor;
-  Replacements Replaces = sortIncludes(FormatStyle, Code->getBuffer(), Ranges,
+  Replacements Replaces = sortIncludes(*FormatStyle, Code->getBuffer(), Ranges,
                                        AssumedFileName, &CursorPosition);
   auto ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces);
   if (!ChangedCode) {
@@ -263,7 +277,7 @@
   // Get new affected ranges after sorting `#includes`.
   Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
   bool IncompleteFormat = false;
-  Replacements FormatChanges = reformat(FormatStyle, *ChangedCode, Ranges,
+  Replacements FormatChanges = reformat(*FormatStyle, *ChangedCode, Ranges,
                                         AssumedFileName, &IncompleteFormat);
   Replaces = Replaces.merge(FormatChanges);
   if (OutputXML) {
@@ -290,9 +304,7 @@
     Rewriter Rewrite(Sources, LangOptions());
     tooling::applyAllReplacements(Replaces, Rewrite);
     if (Inplace) {
-      if (FileName == "-")
-        errs() << "error: cannot use -i when reading from stdin.\n";
-      else if (Rewrite.overwriteChangedFiles())
+      if (Rewrite.overwriteChangedFiles())
         return true;
     } else {
       if (Cursor.getNumOccurrences() != 0)
@@ -333,10 +345,15 @@
     cl::PrintHelpMessage();
 
   if (DumpConfig) {
-    std::string Config =
-        clang::format::configurationAsText(clang::format::getStyle(
+    llvm::Expected<clang::format::FormatStyle> FormatStyle =
+        clang::format::getStyle(
             Style, FileNames.empty() ? AssumeFileName : FileNames[0],
-            FallbackStyle));
+            FallbackStyle);
+    if (!FormatStyle) {
+      llvm::errs() << llvm::toString(FormatStyle.takeError()) << "\n";
+      return 1;
+    }
+    std::string Config = clang::format::configurationAsText(*FormatStyle);
     outs() << Config << "\n";
     return 0;
   }
diff --git a/tools/clang-format/clang-format-test.el b/tools/clang-format/clang-format-test.el
new file mode 100644
index 0000000..0e1f4dd
--- /dev/null
+++ b/tools/clang-format/clang-format-test.el
@@ -0,0 +1,126 @@
+;;; clang-format-test.el --- unit tests for clang-format.el  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  Google Inc.
+
+;; Author: Philipp Stephani <phst@google.com>
+
+;; This file is distributed under the University of Illinois Open Source
+;; License.  See LICENSE.TXT for details.
+
+;;; Commentary:
+
+;; Unit tests for clang-format.el.
+
+;;; Code:
+
+(require 'clang-format)
+
+(require 'cl-lib)
+(require 'ert)
+(require 'pcase)
+
+(ert-deftest clang-format-buffer--buffer-encoding ()
+  "Tests that encoded text is handled properly."
+  (cl-letf* ((call-process-args nil)
+             ((symbol-function 'call-process-region)
+              (lambda (&rest args)
+                (push args call-process-args)
+                (pcase-exhaustive args
+                  (`(,_start ,_end ,_program ,_delete (,stdout ,_stderr)
+                             ,_display . ,_args)
+                   (with-current-buffer stdout
+                     (insert "<?xml version='1.0'?>
+<replacements xml:space='preserve' incomplete_format='false'>
+<replacement offset='4' length='0'> </replacement>
+<replacement offset='10' length='0'> </replacement>
+</replacements>
+"))
+                   0)))))
+    (with-temp-buffer
+      (let ((buffer-file-name "foo.cpp")
+            (buffer-file-coding-system 'utf-8-with-signature-dos)
+            (default-process-coding-system 'latin-1-unix))
+        (insert "ä =ö;\nü= ß;\n")
+        (goto-char (point-min))
+        (end-of-line)
+        (clang-format-buffer))
+      (should (equal (buffer-string) "ä = ö;\nü = ß;\n"))
+      (should (eolp))
+      (should (equal (buffer-substring (point) (point-max))
+                     "\nü = ß;\n")))
+    (should-not (cdr call-process-args))
+    (pcase-exhaustive call-process-args
+      (`((,start ,end ,_program ,delete (,_stdout ,_stderr) ,display . ,args))
+       (should-not start)
+       (should-not end)
+       (should-not delete)
+       (should-not display)
+       (should (equal args
+                      '("-output-replacements-xml" "-assume-filename" "foo.cpp"
+                        "-style" "file"
+                        ;; Beginning of buffer, no byte-order mark.
+                        "-offset" "0"
+                        ;; We have two lines with 2×2 bytes for the umlauts,
+                        ;; 1 byte for the line ending, and 3 bytes for the
+                        ;; other ASCII characters each.
+                        "-length" "16"
+                        ;; Length of a single line (without line ending).
+                        "-cursor" "7")))))))
+
+(ert-deftest clang-format-buffer--process-encoding ()
+  "Tests that text is sent to the clang-format process in the
+right encoding."
+  (cl-letf* ((hexdump (executable-find "hexdump"))
+             (original-call-process-region
+              (symbol-function 'call-process-region))
+             (call-process-inputs nil)
+             ;; We redirect the input to hexdump so that we have guaranteed
+             ;; ASCII output.
+             ((symbol-function 'call-process-region)
+              (lambda (&rest args)
+                (pcase-exhaustive args
+                  (`(,start ,end ,_program ,_delete (,stdout ,_stderr)
+                            ,_display . ,_args)
+                   (with-current-buffer stdout
+                     (insert "<?xml version='1.0'?>
+<replacements xml:space='preserve' incomplete_format='false'>
+</replacements>
+"))
+                   (let ((stdin (current-buffer)))
+                     (with-temp-buffer
+                       (prog1
+                           (let ((stdout (current-buffer)))
+                             (with-current-buffer stdin
+                               (funcall original-call-process-region
+                                        start end hexdump nil stdout nil
+                                        "-v" "-e" "/1 \"%02x \"")))
+                         (push (buffer-string) call-process-inputs)))))))))
+    (skip-unless hexdump)
+    (with-temp-buffer
+      (let ((buffer-file-name "foo.cpp")
+            (buffer-file-coding-system 'utf-8-with-signature-dos)
+            (default-process-coding-system 'latin-1-unix))
+        (insert "ä\n")
+        (clang-format-buffer))
+      (should (equal (buffer-string) "ä\n"))
+      (should (eobp)))
+    (should (equal call-process-inputs '("c3 a4 0a ")))))
+
+(ert-deftest clang-format-buffer--end-to-end ()
+  "End-to-end test for ‘clang-format-buffer’.
+Actually calls the clang-format binary."
+  (skip-unless (file-executable-p clang-format-executable))
+  (with-temp-buffer
+    (let ((buffer-file-name "foo.cpp")
+          (buffer-file-coding-system 'utf-8-with-signature-dos)
+          (default-process-coding-system 'latin-1-unix))
+      (insert "ä =ö;\nü= ß;\n")
+      (goto-char (point-min))
+      (end-of-line)
+      (clang-format-buffer))
+    (should (equal (buffer-string) "ä = ö;\nü = ß;\n"))
+    (should (eolp))
+    (should (equal (buffer-substring (point) (point-max))
+                   "\nü = ß;\n"))))
+
+;;; clang-format-test.el ends here
diff --git a/tools/clang-format/clang-format.el b/tools/clang-format/clang-format.el
index 0ac2da3..aa9c3ff 100644
--- a/tools/clang-format/clang-format.el
+++ b/tools/clang-format/clang-format.el
@@ -95,9 +95,10 @@
 (defun clang-format--replace (offset length &optional text)
   "Replace the region defined by OFFSET and LENGTH with TEXT.
 OFFSET and LENGTH are measured in bytes, not characters.  OFFSET
-is a zero-based file offset."
-  (let ((start (clang-format--filepos-to-bufferpos offset 'exact))
-        (end (clang-format--filepos-to-bufferpos (+ offset length) 'exact)))
+is a zero-based file offset, assuming ‘utf-8-unix’ coding."
+  (let ((start (clang-format--filepos-to-bufferpos offset 'exact 'utf-8-unix))
+        (end (clang-format--filepos-to-bufferpos (+ offset length) 'exact
+                                                 'utf-8-unix)))
     (goto-char start)
     (delete-region start end)
     (when text
@@ -130,11 +131,18 @@
   (unless style
     (setq style clang-format-style))
 
-  (let ((file-start (clang-format--bufferpos-to-filepos start 'approximate))
-        (file-end (clang-format--bufferpos-to-filepos end 'approximate))
-        (cursor (clang-format--bufferpos-to-filepos (point) 'exact))
+  (let ((file-start (clang-format--bufferpos-to-filepos start 'approximate
+                                                        'utf-8-unix))
+        (file-end (clang-format--bufferpos-to-filepos end 'approximate
+                                                      'utf-8-unix))
+        (cursor (clang-format--bufferpos-to-filepos (point) 'exact 'utf-8-unix))
         (temp-buffer (generate-new-buffer " *clang-format-temp*"))
-        (temp-file (make-temp-file "clang-format")))
+        (temp-file (make-temp-file "clang-format"))
+        ;; Output is XML, which is always UTF-8.  Input encoding should match
+        ;; the encoding used to convert between buffer and file positions,
+        ;; otherwise the offsets calculated above are off.  For simplicity, we
+        ;; always use ‘utf-8-unix’ and ignore the buffer coding system.
+        (default-process-coding-system '(utf-8-unix . utf-8-unix)))
     (unwind-protect
         (let ((status (call-process-region
                        nil nil clang-format-executable
@@ -164,7 +172,8 @@
               (dolist (rpl replacements)
                 (apply #'clang-format--replace rpl)))
             (when cursor
-              (goto-char (clang-format--filepos-to-bufferpos cursor 'exact)))
+              (goto-char (clang-format--filepos-to-bufferpos cursor 'exact
+                                                             'utf-8-unix)))
             (if incomplete-format
                 (message "(clang-format: incomplete (syntax errors)%s)" stderr)
               (message "(clang-format: success%s)" stderr))))
diff --git a/tools/clang-format/clang-format.py b/tools/clang-format/clang-format.py
index aded301..ae8a6eb 100644
--- a/tools/clang-format/clang-format.py
+++ b/tools/clang-format/clang-format.py
@@ -29,6 +29,7 @@
 
 import difflib
 import json
+import platform
 import subprocess
 import sys
 import vim
@@ -48,10 +49,15 @@
 if vim.eval('exists("g:clang_format_fallback_style")') == "1":
   fallback_style = vim.eval('g:clang_format_fallback_style')
 
+def get_buffer(encoding):
+  if platform.python_version_tuple()[0] == '3':
+    return vim.current.buffer
+  return [ line.decode(encoding) for line in vim.current.buffer ]
+
 def main():
   # Get the current text.
   encoding = vim.eval("&encoding")
-  buf = [ line.decode(encoding) for line in vim.current.buffer ]
+  buf = get_buffer(encoding)
   text = '\n'.join(buf)
 
   # Determine range to format.
diff --git a/tools/clang-fuzzer/ClangFuzzer.cpp b/tools/clang-fuzzer/ClangFuzzer.cpp
index afe57d4..1692882 100644
--- a/tools/clang-fuzzer/ClangFuzzer.cpp
+++ b/tools/clang-fuzzer/ClangFuzzer.cpp
@@ -42,7 +42,7 @@
       tooling::newFrontendActionFactory<clang::SyntaxOnlyAction>());
   std::shared_ptr<PCHContainerOperations> PCHContainerOps =
       std::make_shared<PCHContainerOperations>();
-  action->runInvocation(Invocation.release(), Files.get(), PCHContainerOps,
+  action->runInvocation(std::move(Invocation), Files.get(), PCHContainerOps,
                         &Diags);
   return 0;
 }
diff --git a/tools/clang-import-test/CMakeLists.txt b/tools/clang-import-test/CMakeLists.txt
new file mode 100644
index 0000000..bd49196
--- /dev/null
+++ b/tools/clang-import-test/CMakeLists.txt
@@ -0,0 +1,27 @@
+set(LLVM_LINK_COMPONENTS
+  core
+  support
+)
+
+if(NOT CLANG_BUILT_STANDALONE)
+  set(tablegen_deps intrinsics_gen)
+endif()
+
+add_clang_tool(clang-import-test
+  clang-import-test.cpp
+  DEPENDS
+  ${tablegen_deps}
+  )
+
+set(CLANG_IMPORT_TEST_LIB_DEPS
+  clangAST
+  clangBasic
+  clangCodeGen
+  clangFrontend
+  clangLex
+  clangParse
+  )
+
+target_link_libraries(clang-import-test
+  ${CLANG_IMPORT_TEST_LIB_DEPS}
+  )
diff --git a/tools/clang-import-test/clang-import-test.cpp b/tools/clang-import-test/clang-import-test.cpp
new file mode 100644
index 0000000..33190af
--- /dev/null
+++ b/tools/clang-import-test/clang-import-test.cpp
@@ -0,0 +1,319 @@
+//===-- import-test.cpp - ASTImporter/ExternalASTSource testbed -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTImporter.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/ParseAST.h"
+
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Signals.h"
+
+#include <memory>
+#include <string>
+
+using namespace clang;
+
+static llvm::cl::opt<std::string> Expression(
+    "expression", llvm::cl::Required,
+    llvm::cl::desc("Path to a file containing the expression to parse"));
+
+static llvm::cl::list<std::string>
+    Imports("import", llvm::cl::ZeroOrMore,
+            llvm::cl::desc("Path to a file containing declarations to import"));
+
+static llvm::cl::list<std::string>
+    ClangArgs("Xcc", llvm::cl::ZeroOrMore,
+              llvm::cl::desc("Argument to pass to the CompilerInvocation"),
+              llvm::cl::CommaSeparated);
+
+namespace init_convenience {
+class TestDiagnosticConsumer : public DiagnosticConsumer {
+private:
+  std::unique_ptr<TextDiagnosticBuffer> Passthrough;
+  const LangOptions *LangOpts = nullptr;
+
+public:
+  TestDiagnosticConsumer()
+      : Passthrough(llvm::make_unique<TextDiagnosticBuffer>()) {}
+
+  virtual void BeginSourceFile(const LangOptions &LangOpts,
+                               const Preprocessor *PP = nullptr) override {
+    this->LangOpts = &LangOpts;
+    return Passthrough->BeginSourceFile(LangOpts, PP);
+  }
+
+  virtual void EndSourceFile() override {
+    this->LangOpts = nullptr;
+    Passthrough->EndSourceFile();
+  }
+
+  virtual bool IncludeInDiagnosticCounts() const override {
+    return Passthrough->IncludeInDiagnosticCounts();
+  }
+
+private:
+  static void PrintSourceForLocation(const SourceLocation &Loc,
+                                     SourceManager &SM) {
+    const char *LocData = SM.getCharacterData(Loc, /*Invalid=*/nullptr);
+    unsigned LocColumn =
+        SM.getSpellingColumnNumber(Loc, /*Invalid=*/nullptr) - 1;
+    FileID FID = SM.getFileID(Loc);
+    llvm::MemoryBuffer *Buffer = SM.getBuffer(FID, Loc, /*Invalid=*/nullptr);
+
+    assert(LocData >= Buffer->getBufferStart() &&
+           LocData < Buffer->getBufferEnd());
+
+    const char *LineBegin = LocData - LocColumn;
+
+    assert(LineBegin >= Buffer->getBufferStart());
+
+    const char *LineEnd = nullptr;
+
+    for (LineEnd = LineBegin; *LineEnd != '\n' && *LineEnd != '\r' &&
+                              LineEnd < Buffer->getBufferEnd();
+         ++LineEnd)
+      ;
+
+    llvm::StringRef LineString(LineBegin, LineEnd - LineBegin);
+
+    llvm::errs() << LineString << '\n';
+    llvm::errs().indent(LocColumn);
+    llvm::errs() << '^';
+  }
+
+  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                                const Diagnostic &Info) override {
+    if (Info.hasSourceManager() && LangOpts) {
+      SourceManager &SM = Info.getSourceManager();
+
+      if (Info.getLocation().isValid()) {
+        Info.getLocation().print(llvm::errs(), SM);
+        llvm::errs() << ": ";
+      }
+
+      SmallString<16> DiagText;
+      Info.FormatDiagnostic(DiagText);
+      llvm::errs() << DiagText << '\n';
+
+      if (Info.getLocation().isValid()) {
+        PrintSourceForLocation(Info.getLocation(), SM);
+      }
+
+      for (const CharSourceRange &Range : Info.getRanges()) {
+        bool Invalid = true;
+        StringRef Ref = Lexer::getSourceText(Range, SM, *LangOpts, &Invalid);
+        if (!Invalid) {
+          llvm::errs() << Ref << '\n';
+        }
+      }
+    }
+    DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
+  }
+};
+
+std::unique_ptr<CompilerInstance>
+BuildCompilerInstance(ArrayRef<const char *> ClangArgv) {
+  auto Ins = llvm::make_unique<CompilerInstance>();
+  auto DC = llvm::make_unique<TestDiagnosticConsumer>();
+  const bool ShouldOwnClient = true;
+  Ins->createDiagnostics(DC.release(), ShouldOwnClient);
+
+  auto Inv = llvm::make_unique<CompilerInvocation>();
+
+  CompilerInvocation::CreateFromArgs(*Inv, ClangArgv.data(),
+                                     &ClangArgv.data()[ClangArgv.size()],
+                                     Ins->getDiagnostics());
+
+  Inv->getLangOpts()->CPlusPlus = true;
+  Inv->getLangOpts()->CPlusPlus11 = true;
+  Inv->getHeaderSearchOpts().UseLibcxx = true;
+  Inv->getLangOpts()->Bool = true;
+  Inv->getLangOpts()->WChar = true;
+  Inv->getLangOpts()->Blocks = true;
+  Inv->getLangOpts()->DebuggerSupport = true;
+  Inv->getLangOpts()->SpellChecking = false;
+  Inv->getLangOpts()->ThreadsafeStatics = false;
+  Inv->getLangOpts()->AccessControl = false;
+  Inv->getLangOpts()->DollarIdents = true;
+  Inv->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
+  Inv->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
+
+  Ins->setInvocation(std::move(Inv));
+
+  TargetInfo *TI = TargetInfo::CreateTargetInfo(
+      Ins->getDiagnostics(), Ins->getInvocation().TargetOpts);
+  Ins->setTarget(TI);
+  Ins->getTarget().adjust(Ins->getLangOpts());
+  Ins->createFileManager();
+  Ins->createSourceManager(Ins->getFileManager());
+  Ins->createPreprocessor(TU_Complete);
+
+  return Ins;
+}
+
+std::unique_ptr<ASTContext>
+BuildASTContext(CompilerInstance &CI, SelectorTable &ST, Builtin::Context &BC) {
+  auto AST = llvm::make_unique<ASTContext>(
+      CI.getLangOpts(), CI.getSourceManager(),
+      CI.getPreprocessor().getIdentifierTable(), ST, BC);
+  AST->InitBuiltinTypes(CI.getTarget());
+  return AST;
+}
+
+std::unique_ptr<CodeGenerator> BuildCodeGen(CompilerInstance &CI,
+                                            llvm::LLVMContext &LLVMCtx) {
+  StringRef ModuleName("$__module");
+  return std::unique_ptr<CodeGenerator>(CreateLLVMCodeGen(
+      CI.getDiagnostics(), ModuleName, CI.getHeaderSearchOpts(),
+      CI.getPreprocessorOpts(), CI.getCodeGenOpts(), LLVMCtx));
+}
+} // end namespace
+
+namespace {
+class TestExternalASTSource : public ExternalASTSource {
+private:
+  llvm::ArrayRef<std::unique_ptr<CompilerInstance>> ImportCIs;
+  std::map<CompilerInstance *, std::unique_ptr<ASTImporter>> ForwardImporters;
+  std::map<CompilerInstance *, std::unique_ptr<ASTImporter>> ReverseImporters;
+
+public:
+  TestExternalASTSource(
+      CompilerInstance &ExpressionCI,
+      llvm::ArrayRef<std::unique_ptr<CompilerInstance>> ImportCIs)
+      : ImportCIs(ImportCIs) {
+    for (const std::unique_ptr<CompilerInstance> &ImportCI : ImportCIs) {
+      ForwardImporters[ImportCI.get()] = llvm::make_unique<ASTImporter>(
+          ExpressionCI.getASTContext(), ExpressionCI.getFileManager(),
+          ImportCI->getASTContext(), ImportCI->getFileManager(),
+          /*MinimalImport=*/true);
+      ReverseImporters[ImportCI.get()] = llvm::make_unique<ASTImporter>(
+          ImportCI->getASTContext(), ImportCI->getFileManager(),
+          ExpressionCI.getASTContext(), ExpressionCI.getFileManager(),
+          /*MinimalImport=*/true);
+    }
+  }
+
+  bool FindExternalVisibleDeclsByName(const DeclContext *DC,
+                                      DeclarationName Name) override {
+    llvm::SmallVector<NamedDecl *, 1> Decls;
+
+    if (isa<TranslationUnitDecl>(DC)) {
+      for (const std::unique_ptr<CompilerInstance> &I : ImportCIs) {
+        DeclarationName FromName = ReverseImporters[I.get()]->Import(Name);
+        DeclContextLookupResult Result =
+            I->getASTContext().getTranslationUnitDecl()->lookup(FromName);
+        for (NamedDecl *FromD : Result) {
+          NamedDecl *D =
+              llvm::cast<NamedDecl>(ForwardImporters[I.get()]->Import(FromD));
+          Decls.push_back(D);
+        }
+      }
+    }
+    if (Decls.empty()) {
+      return false;
+    } else {
+      SetExternalVisibleDeclsForName(DC, Name, Decls);
+      return true;
+    }
+  }
+};
+
+void AddExternalSource(
+    CompilerInstance &CI,
+    llvm::ArrayRef<std::unique_ptr<CompilerInstance>> Imports) {
+  ASTContext &AST = CI.getASTContext();
+  auto ES = llvm::make_unique<TestExternalASTSource>(CI, Imports);
+  AST.setExternalSource(ES.release());
+  AST.getTranslationUnitDecl()->setHasExternalVisibleStorage();
+}
+
+llvm::Error ParseSource(const std::string &Path, CompilerInstance &CI,
+                        CodeGenerator &CG) {
+  SourceManager &SM = CI.getSourceManager();
+  const FileEntry *FE = CI.getFileManager().getFile(Path);
+  if (!FE) {
+    return llvm::make_error<llvm::StringError>(
+        llvm::Twine("Couldn't open ", Path), std::error_code());
+  }
+  SM.setMainFileID(SM.createFileID(FE, SourceLocation(), SrcMgr::C_User));
+  ParseAST(CI.getPreprocessor(), &CG, CI.getASTContext());
+  return llvm::Error::success();
+}
+
+llvm::Expected<std::unique_ptr<CompilerInstance>>
+Parse(const std::string &Path,
+      llvm::ArrayRef<std::unique_ptr<CompilerInstance>> Imports) {
+  std::vector<const char *> ClangArgv(ClangArgs.size());
+  std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(),
+                 [](const std::string &s) -> const char * { return s.data(); });
+  std::unique_ptr<CompilerInstance> CI =
+      init_convenience::BuildCompilerInstance(ClangArgv);
+  auto ST = llvm::make_unique<SelectorTable>();
+  auto BC = llvm::make_unique<Builtin::Context>();
+  std::unique_ptr<ASTContext> AST =
+      init_convenience::BuildASTContext(*CI, *ST, *BC);
+  CI->setASTContext(AST.release());
+  AddExternalSource(*CI, Imports);
+
+  auto LLVMCtx = llvm::make_unique<llvm::LLVMContext>();
+  std::unique_ptr<CodeGenerator> CG =
+      init_convenience::BuildCodeGen(*CI, *LLVMCtx);
+  CG->Initialize(CI->getASTContext());
+
+  CI->getDiagnosticClient().BeginSourceFile(CI->getLangOpts(),
+                                            &CI->getPreprocessor());
+  if (llvm::Error PE = ParseSource(Path, *CI, *CG)) {
+    return std::move(PE);
+  }
+  CI->getDiagnosticClient().EndSourceFile();
+  if (CI->getDiagnosticClient().getNumErrors()) {
+    return llvm::make_error<llvm::StringError>(
+        "Errors occured while parsing the expression.", std::error_code());
+  } else {
+    return std::move(CI);
+  }
+}
+} // end namespace
+
+int main(int argc, const char **argv) {
+  const bool DisableCrashReporting = true;
+  llvm::sys::PrintStackTraceOnErrorSignal(argv[0], DisableCrashReporting);
+  llvm::cl::ParseCommandLineOptions(argc, argv);
+  std::vector<std::unique_ptr<CompilerInstance>> ImportCIs;
+  for (auto I : Imports) {
+    llvm::Expected<std::unique_ptr<CompilerInstance>> ImportCI = Parse(I, {});
+    if (auto E = ImportCI.takeError()) {
+      llvm::errs() << llvm::toString(std::move(E));
+      exit(-1);
+    } else {
+      ImportCIs.push_back(std::move(*ImportCI));
+    }
+  }
+  llvm::Expected<std::unique_ptr<CompilerInstance>> ExpressionCI =
+      Parse(Expression, ImportCIs);
+  if (auto E = ExpressionCI.takeError()) {
+    llvm::errs() << llvm::toString(std::move(E));
+    exit(-1);
+  } else {
+    return 0;
+  }
+}
diff --git a/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/tools/clang-offload-bundler/ClangOffloadBundler.cpp
index 20988b4..f37868f 100644
--- a/tools/clang-offload-bundler/ClangOffloadBundler.cpp
+++ b/tools/clang-offload-bundler/ClangOffloadBundler.cpp
@@ -514,7 +514,10 @@
     // Dump the contents of the temporary file if that was requested.
     if (DumpTemporaryFiles) {
       errs() << ";\n; Object file bundler IR file.\n;\n";
-      AuxModule.get()->dump();
+      AuxModule.get()->print(errs(), nullptr,
+                             /*ShouldPreserveUseListOrder=*/false,
+                             /*IsForDebug=*/true);
+      errs() << '\n';
     }
 
     // Find clang in order to create the bundle binary.
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index abbd3af..e6ea786 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -67,8 +67,8 @@
   SmallVector<const char *, 4> Args;
   Args.push_back("diagtool");
   Args.append(argv, argv + argc);
-  std::unique_ptr<CompilerInvocation> Invocation(
-      createInvocationFromCommandLine(Args, InterimDiags));
+  std::unique_ptr<CompilerInvocation> Invocation =
+      createInvocationFromCommandLine(Args, InterimDiags);
   if (!Invocation)
     return nullptr;
 
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 49bde94..f6e26fa 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -72,7 +72,7 @@
 
 # Configure plist creation for OS X.
 set (TOOL_INFO_PLIST "Info.plist" CACHE STRING "Plist name")
-if (APPLE)  
+if (APPLE)
   if (CLANG_VENDOR)
     set(TOOL_INFO_NAME "${CLANG_VENDOR} clang")
   else()
@@ -82,20 +82,19 @@
   set(TOOL_INFO_UTI "${CLANG_VENDOR_UTI}")
   set(TOOL_INFO_VERSION "${CLANG_VERSION}")
   set(TOOL_INFO_BUILD_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}")
-  
+
   set(TOOL_INFO_PLIST_OUT "${CMAKE_CURRENT_BINARY_DIR}/${TOOL_INFO_PLIST}")
   target_link_libraries(clang
     "-Wl,-sectcreate,__TEXT,__info_plist,${TOOL_INFO_PLIST_OUT}")
   configure_file("${TOOL_INFO_PLIST}.in" "${TOOL_INFO_PLIST_OUT}" @ONLY)
-  
+
   set(TOOL_INFO_UTI)
   set(TOOL_INFO_NAME)
   set(TOOL_INFO_VERSION)
   set(TOOL_INFO_BUILD_VERSION)
 endif()
 
-# the linker -order_file flag is only supported by ld64
-if(LD64_EXECUTABLE AND CLANG_ORDER_FILE)
+if(CLANG_ORDER_FILE AND (LD64_EXECUTABLE OR GOLD_EXECUTABLE))
   include(CMakePushCheckState)
 
   function(check_linker_flag flag out_var)
@@ -105,9 +104,14 @@
     cmake_pop_check_state()
   endfunction()
 
+  if (LD64_EXECUTABLE)
+    set(LINKER_ORDER_FILE_OPTION "-Wl,-order_file,${CLANG_ORDER_FILE}")
+  elseif (GOLD_EXECUTABLE)
+    set(LINKER_ORDER_FILE_OPTION "-Wl,--section-ordering-file,${CLANG_ORDER_FILE}")
+  endif()
+
   # This is a test to ensure the actual order file works with the linker.
-  check_linker_flag("-Wl,-order_file,${CLANG_ORDER_FILE}"
-    LINKER_ORDER_FILE_WORKS)
+  check_linker_flag(${LINKER_ORDER_FILE_OPTION} LINKER_ORDER_FILE_WORKS)
 
   # Passing an empty order file disables some linker layout optimizations.
   # To work around this and enable workflows for re-linking when the order file
@@ -117,7 +121,7 @@
   if("${ORDER_FILE}" STREQUAL "\n")
     set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CLANG_ORDER_FILE})
   elseif(LINKER_ORDER_FILE_WORKS)
-    target_link_libraries(clang "-Wl,-order_file,${CLANG_ORDER_FILE}")
+    target_link_libraries(clang ${LINKER_ORDER_FILE_OPTION})
     set_target_properties(clang PROPERTIES LINK_DEPENDS ${CLANG_ORDER_FILE})
   endif()
 endif()
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 2637513..2fa8edb 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -212,13 +212,11 @@
   // Frontend Options
   if (Args.hasArg(OPT_INPUT)) {
     bool First = true;
-    for (arg_iterator it = Args.filtered_begin(OPT_INPUT),
-                      ie = Args.filtered_end();
-         it != ie; ++it, First = false) {
-      const Arg *A = it;
-      if (First)
+    for (const Arg *A : Args.filtered(OPT_INPUT)) {
+      if (First) {
         Opts.InputFile = A->getValue();
-      else {
+        First = false;
+      } else {
         Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args);
         Success = false;
       }
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
index b597383..44a60c4 100644
--- a/tools/libclang/ARCMigrate.cpp
+++ b/tools/libclang/ARCMigrate.cpp
@@ -32,8 +32,6 @@
 // libClang public APIs.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
-
 CXRemapping clang_getRemappings(const char *migrate_dir_path) {
 #ifndef CLANG_ENABLE_ARCMT
   llvm::errs() << "error: feature not enabled in this build\n";
@@ -138,5 +136,3 @@
 void clang_remap_dispose(CXRemapping map) {
   delete static_cast<Remap *>(map);
 }
-
-} // end: extern "C"
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 04f812d..216322b 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -68,13 +68,14 @@
 using namespace clang::cxtu;
 using namespace clang::cxindex;
 
-CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
+CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
+                                              std::unique_ptr<ASTUnit> AU) {
   if (!AU)
     return nullptr;
   assert(CIdx);
   CXTranslationUnit D = new CXTranslationUnitImpl();
   D->CIdx = CIdx;
-  D->TheASTUnit = AU;
+  D->TheASTUnit = AU.release();
   D->StringPool = new cxstring::CXStringPool();
   D->Diagnostics = nullptr;
   D->OverridenCursorsPool = createOverridenCXCursorsPool();
@@ -1264,10 +1265,11 @@
   switch (Name.getName().getNameKind()) {
   case clang::DeclarationName::Identifier:
   case clang::DeclarationName::CXXLiteralOperatorName:
+  case clang::DeclarationName::CXXDeductionGuideName:
   case clang::DeclarationName::CXXOperatorName:
   case clang::DeclarationName::CXXUsingDirective:
     return false;
-      
+
   case clang::DeclarationName::CXXConstructorName:
   case clang::DeclarationName::CXXDestructorName:
   case clang::DeclarationName::CXXConversionFunctionName:
@@ -1491,7 +1493,6 @@
   case BuiltinType::OCLEvent:
   case BuiltinType::OCLClkEvent:
   case BuiltinType::OCLQueue:
-  case BuiltinType::OCLNDRange:
   case BuiltinType::OCLReserveID:
 #define BUILTIN_TYPE(Id, SingletonId)
 #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
@@ -1639,6 +1640,15 @@
   return Visit(TL.getOriginalLoc());
 }
 
+bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
+    DeducedTemplateSpecializationTypeLoc TL) {
+  if (VisitTemplateName(TL.getTypePtr()->getTemplateName(), 
+                        TL.getTemplateNameLoc()))
+    return true;
+  
+  return false;
+}
+
 bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
                                              TemplateSpecializationTypeLoc TL) {
   // Visit the template name.
@@ -2008,6 +2018,15 @@
       const OMPTeamsDistributeParallelForSimdDirective *D);
   void VisitOMPTeamsDistributeParallelForDirective(
       const OMPTeamsDistributeParallelForDirective *D);
+  void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
+  void VisitOMPTargetTeamsDistributeDirective(
+      const OMPTargetTeamsDistributeDirective *D);
+  void VisitOMPTargetTeamsDistributeParallelForDirective(
+      const OMPTargetTeamsDistributeParallelForDirective *D);
+  void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
+      const OMPTargetTeamsDistributeParallelForSimdDirective *D);
+  void VisitOMPTargetTeamsDistributeSimdDirective(
+      const OMPTargetTeamsDistributeSimdDirective *D);
 
 private:
   void AddDeclarationNameInfo(const Stmt *S);
@@ -2094,6 +2113,7 @@
 }
 
 void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
+  VisitOMPClauseWithPreInit(C);
   Visitor->AddStmt(C->getCondition());
 }
 
@@ -2102,6 +2122,7 @@
 }
 
 void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
+  VisitOMPClauseWithPreInit(C);
   Visitor->AddStmt(C->getNumThreads());
 }
 
@@ -2157,10 +2178,12 @@
 }
 
 void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
+  VisitOMPClauseWithPreInit(C);
   Visitor->AddStmt(C->getNumTeams());
 }
 
 void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
+  VisitOMPClauseWithPreInit(C);
   Visitor->AddStmt(C->getThreadLimit());
 }
 
@@ -2812,6 +2835,31 @@
   VisitOMPLoopDirective(D);
 }
 
+void EnqueueVisitor::VisitOMPTargetTeamsDirective(
+    const OMPTargetTeamsDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
+    const OMPTargetTeamsDistributeDirective *D) {
+  VisitOMPLoopDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
+    const OMPTargetTeamsDistributeParallelForDirective *D) {
+  VisitOMPLoopDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
+    const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
+  VisitOMPLoopDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
+    const OMPTargetTeamsDistributeSimdDirective *D) {
+  VisitOMPLoopDirective(D);
+}
+
 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
   EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
 }
@@ -3110,7 +3158,6 @@
 
 static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
 
-extern "C" {
 CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
                           int displayDiagnostics) {
   // We use crash recovery to make some of our APIs more reliable, implicitly
@@ -3205,7 +3252,7 @@
       /*CaptureDiagnostics=*/true,
       /*AllowPCHWithCompilerErrors=*/true,
       /*UserFilesAreVolatile=*/true);
-  *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
+  *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
   return *out_TU ? CXError_Success : CXError_Failure;
 }
 
@@ -3357,7 +3404,7 @@
   if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
     return CXError_ASTReadError;
 
-  *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
+  *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
   return *out_TU ? CXError_Success : CXError_Failure;
 }
 
@@ -3630,7 +3677,7 @@
     result->EvalType = CXEval_Float;
     bool ignored;
     llvm::APFloat apFloat = ER.Val.getFloat();
-    apFloat.convert(llvm::APFloat::IEEEdouble,
+    apFloat.convert(llvm::APFloat::IEEEdouble(),
                     llvm::APFloat::rmNearestTiesToEven, &ignored);
     result->EvalData.floatVal = apFloat.convertToDouble();
     return result.release();
@@ -3968,13 +4015,10 @@
   return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
 }
 
-} // end: extern "C"
-
 //===----------------------------------------------------------------------===//
 // CXFile Operations.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
 CXString clang_getFileName(CXFile SFile) {
   if (!SFile)
     return cxstring::createNull();
@@ -4043,8 +4087,6 @@
   return FEnt1->getUniqueID() == FEnt2->getUniqueID();
 }
 
-} // end: extern "C"
-
 //===----------------------------------------------------------------------===//
 // CXCursor Operations.
 //===----------------------------------------------------------------------===//
@@ -4429,7 +4471,8 @@
   }
 
   if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
-      C.kind == CXCursor_ConversionFunction) {
+      C.kind == CXCursor_ConversionFunction ||
+      C.kind == CXCursor_FunctionDecl) {
     if (pieceIndex > 0)
       return clang_getNullRange();
     if (const FunctionDecl *FD =
@@ -4979,6 +5022,17 @@
     return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
   case CXCursor_OMPTeamsDistributeParallelForDirective:
     return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
+  case CXCursor_OMPTargetTeamsDirective:
+    return cxstring::createRef("OMPTargetTeamsDirective");
+  case CXCursor_OMPTargetTeamsDistributeDirective:
+    return cxstring::createRef("OMPTargetTeamsDistributeDirective");
+  case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
+    return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
+  case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
+    return cxstring::createRef(
+        "OMPTargetTeamsDistributeParallelForSimdDirective");
+  case CXCursor_OMPTargetTeamsDistributeSimdDirective:
+    return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
   case CXCursor_OverloadCandidate:
       return cxstring::createRef("OverloadCandidate");
   case CXCursor_TypeAliasTemplateDecl:
@@ -5554,8 +5608,6 @@
   return getRawCursorExtent(C);
 }
 
-extern "C" {
-
 CXSourceRange clang_getCursorExtent(CXCursor C) {
   SourceRange R = getRawCursorExtent(C);
   if (R.isInvalid())
@@ -5730,6 +5782,7 @@
   case Decl::OMPCapturedExpr:
   case Decl::Label:  // FIXME: Is this right??
   case Decl::ClassScopeFunctionSpecialization:
+  case Decl::CXXDeductionGuide:
   case Decl::Import:
   case Decl::OMPThreadPrivate:
   case Decl::OMPDeclareReduction:
@@ -5737,6 +5790,7 @@
   case Decl::BuiltinTemplate:
   case Decl::PragmaComment:
   case Decl::PragmaDetectMismatch:
+  case Decl::UsingPack:
     return C;
 
   // Declaration kinds that don't make any sense here, but are
@@ -6048,8 +6102,6 @@
   llvm::llvm_execute_on_thread(fn, user_data, stack_size);
 }
 
-} // end: extern "C"
-
 //===----------------------------------------------------------------------===//
 // Token-based Operations.
 //===----------------------------------------------------------------------===//
@@ -6062,8 +6114,6 @@
  *   ptr_data: for identifiers and keywords, an IdentifierInfo*.
  *   otherwise unused.
  */
-extern "C" {
-
 CXTokenKind clang_getTokenKind(CXToken CXTok) {
   return static_cast<CXTokenKind>(CXTok.int_data[0]);
 }
@@ -6252,8 +6302,6 @@
   free(Tokens);
 }
 
-} // end: extern "C"
-
 //===----------------------------------------------------------------------===//
 // Token annotation APIs.
 //===----------------------------------------------------------------------===//
@@ -6921,8 +6969,6 @@
   }
 }
 
-extern "C" {
-
 void clang_annotateTokens(CXTranslationUnit TU,
                           CXToken *Tokens, unsigned NumTokens,
                           CXCursor *Cursors) {
@@ -6962,13 +7008,10 @@
   }
 }
 
-} // end: extern "C"
-
 //===----------------------------------------------------------------------===//
 // Operations for querying linkage of a cursor.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
 CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
   if (!clang_isDeclaration(cursor.kind))
     return CXLinkage_Invalid;
@@ -6985,13 +7028,11 @@
 
   return CXLinkage_Invalid;
 }
-} // end: extern "C"
 
 //===----------------------------------------------------------------------===//
 // Operations for querying visibility of a cursor.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
 CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
   if (!clang_isDeclaration(cursor.kind))
     return CXVisibility_Invalid;
@@ -7006,7 +7047,6 @@
 
   return CXVisibility_Invalid;
 }
-} // end: extern "C"
 
 //===----------------------------------------------------------------------===//
 // Operations for querying language of a cursor.
@@ -7062,8 +7102,6 @@
   return CXLanguage_C;
 }
 
-extern "C" {
-
 static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
   if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
     return CXAvailability_NotAvailable;
@@ -7533,14 +7571,10 @@
   return nullptr;
 }
 
-} // end: extern "C"
-
 //===----------------------------------------------------------------------===//
 // C++ AST instrospection.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
-
 unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
   if (!clang_isDeclaration(C.kind))
     return 0;
@@ -7641,13 +7675,11 @@
       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
   return (Method && Method->isVirtual()) ? 1 : 0;
 }
-} // end: extern "C"
 
 //===----------------------------------------------------------------------===//
 // Attribute introspection.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
 CXType clang_getIBOutletCollectionType(CXCursor C) {
   if (C.kind != CXCursor_IBOutletCollectionAttr)
     return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
@@ -7657,7 +7689,6 @@
   
   return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));  
 }
-} // end: extern "C"
 
 //===----------------------------------------------------------------------===//
 // Inspecting memory usage.
@@ -7672,8 +7703,6 @@
   entries.push_back(entry);
 }
 
-extern "C" {
-
 const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
   const char *str = "";
   switch (kind) {
@@ -7894,8 +7923,6 @@
   }
 }
 
-} // end extern "C"
-
 void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
   CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
   for (unsigned I = 0; I != Usage.numEntries; ++I)
@@ -8058,14 +8085,10 @@
   return checkForMacroInMacroDefinition(MI, Tok, TU);
 }
 
-extern "C" {
-
 CXString clang_getClangVersion() {
   return cxstring::createDup(getClangFullVersion());
 }
 
-} // end: extern "C"
-
 Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
   if (TU) {
     if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
index 78e89d9..028b64a 100644
--- a/tools/libclang/CIndexCXX.cpp
+++ b/tools/libclang/CIndexCXX.cpp
@@ -20,8 +20,6 @@
 using namespace clang;
 using namespace clang::cxcursor;
 
-extern "C" {
-
 unsigned clang_isVirtualBase(CXCursor C) {
   if (C.kind != CXCursor_CXXBaseSpecifier)
     return 0;
@@ -123,5 +121,3 @@
   
   return MakeCXCursor(Template, getCursorTU(C));
 }
-  
-} // end extern "C"
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 344ed27..ca68bc1 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -53,8 +53,6 @@
 using namespace clang;
 using namespace clang::cxindex;
 
-extern "C" {
-
 enum CXCompletionChunkKind
 clang_getCompletionChunkKind(CXCompletionString completion_string,
                              unsigned chunk_number) {
@@ -281,13 +279,12 @@
   SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
   
   /// \brief Allocator used to store globally cached code-completion results.
-  IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
-    CachedCompletionAllocator;
-  
+  std::shared_ptr<clang::GlobalCodeCompletionAllocator>
+      CachedCompletionAllocator;
+
   /// \brief Allocator used to store code completion results.
-  IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
-    CodeCompletionAllocator;
-  
+  std::shared_ptr<clang::GlobalCodeCompletionAllocator> CodeCompletionAllocator;
+
   /// \brief Context under which completion occurred.
   enum clang::CodeCompletionContext::Kind ContextKind;
   
@@ -317,15 +314,15 @@
 ///
 /// Used for debugging purposes only.
 static std::atomic<unsigned> CodeCompletionResultObjects;
-  
+
 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
     IntrusiveRefCntPtr<FileManager> FileMgr)
-    : CXCodeCompleteResults(),
-      DiagOpts(new DiagnosticOptions),
+    : CXCodeCompleteResults(), DiagOpts(new DiagnosticOptions),
       Diag(new DiagnosticsEngine(
           IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts)),
       FileMgr(FileMgr), SourceMgr(new SourceManager(*Diag, *FileMgr)),
-      CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
+      CodeCompletionAllocator(
+          std::make_shared<clang::GlobalCodeCompletionAllocator>()),
       Contexts(CXCompletionContext_Unknown),
       ContainerKind(CXCursor_InvalidCode), ContainerIsIncomplete(1) {
   if (getenv("LIBCLANG_OBJTRACKING"))
@@ -346,8 +343,6 @@
     fprintf(stderr, "--- %u completion results\n",
             --CodeCompletionResultObjects);
 }
-  
-} // end extern "C"
 
 static unsigned long long getContextsForContextKind(
                                           enum CodeCompletionContext::Kind kind, 
@@ -794,7 +789,6 @@
   return Results;
 }
 
-extern "C" {
 CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
                                             const char *complete_filename,
                                             unsigned complete_line,
@@ -916,8 +910,6 @@
   return cxstring::createDup(Results->Selector);
 }
   
-} // end extern "C"
-
 /// \brief Simple utility function that appends a \p New string to the given
 /// \p Old string, using the \p Buffer for storage.
 ///
@@ -990,9 +982,7 @@
   };
 }
 
-extern "C" {
-  void clang_sortCodeCompletionResults(CXCompletionResult *Results,
-                                       unsigned NumResults) {
-    std::stable_sort(Results, Results + NumResults, OrderCompletionResults());
-  }
+void clang_sortCodeCompletionResults(CXCompletionResult *Results,
+                                     unsigned NumResults) {
+  std::stable_sort(Results, Results + NumResults, OrderCompletionResults());
 }
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 18031e5..de223d3 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -205,8 +205,6 @@
 //-----------------------------------------------------------------------------
 // C Interface Routines
 //-----------------------------------------------------------------------------
-extern "C" {
-
 unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
   if (cxtu::isNotUsableTU(Unit)) {
     LOG_BAD_TU(Unit);
@@ -477,5 +475,3 @@
     return D->getNumDiagnostics();
   return 0;
 }
-
-} // end extern "C"
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index bec0e82..d4666c2 100644
--- a/tools/libclang/CIndexHigh.cpp
+++ b/tools/libclang/CIndexHigh.cpp
@@ -535,4 +535,3 @@
 }
 
 } // end: extern "C"
-
diff --git a/tools/libclang/CIndexInclusionStack.cpp b/tools/libclang/CIndexInclusionStack.cpp
index 5ebb5ec..4b021fc 100644
--- a/tools/libclang/CIndexInclusionStack.cpp
+++ b/tools/libclang/CIndexInclusionStack.cpp
@@ -68,7 +68,6 @@
 }
 
 
-extern "C" {
 void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
                          CXClientData clientData) {
   if (cxtu::isNotUsableTU(TU)) {
@@ -96,4 +95,3 @@
     getInclusions(&SourceManager::getLocalSLocEntry, n, TU, CB, clientData);
 
 }
-} // end extern C
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 69d60c9..7cd7b6f 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -36,8 +36,6 @@
   return generateUSRForDecl(D, Buf);
 }
 
-extern "C" {
-
 CXString clang_getCursorUSR(CXCursor C) {
   const CXCursorKind &K = clang_getCursorKind(C);
 
@@ -140,5 +138,3 @@
   generateUSRForObjCProperty(property, /*isClassProp=*/false, OS);
   return cxstring::createDup(OS.str());
 }
-
-} // end extern "C"
diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index c02eea9..028fdf1 100644
--- a/tools/libclang/CXComment.cpp
+++ b/tools/libclang/CXComment.cpp
@@ -26,8 +26,6 @@
 using namespace clang::comments;
 using namespace clang::cxcomment;
 
-extern "C" {
-
 CXComment clang_Cursor_getParsedComment(CXCursor C) {
   using namespace clang::cxcursor;
 
@@ -406,5 +404,3 @@
   return cxstring::createDup(XML.str());
 }
 
-} // end extern "C"
-
diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp
index 82498bf..c122ec8 100644
--- a/tools/libclang/CXCompilationDatabase.cpp
+++ b/tools/libclang/CXCompilationDatabase.cpp
@@ -6,8 +6,6 @@
 using namespace clang;
 using namespace clang::tooling;
 
-extern "C" {
-
 // FIXME: do something more useful with the error message
 CXCompilationDatabase
 clang_CompilationDatabase_fromDirectory(const char *BuildDir,
@@ -180,5 +178,3 @@
 
   return cxstring::createRef(Cmd->MappedSources[I].second.c_str());
 }
-
-} // end: extern "C"
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index e68d793..c19aa65 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
   case Stmt::CXXBindTemporaryExprClass:
@@ -243,6 +244,8 @@
   case Stmt::ChooseExprClass:
   case Stmt::DesignatedInitExprClass:
   case Stmt::DesignatedInitUpdateExprClass:
+  case Stmt::ArrayInitLoopExprClass:
+  case Stmt::ArrayInitIndexExprClass:
   case Stmt::ExprWithCleanupsClass:
   case Stmt::ExpressionTraitExprClass:
   case Stmt::ExtVectorElementExprClass:
@@ -665,6 +668,21 @@
   case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
     K = CXCursor_OMPTeamsDistributeParallelForDirective;
     break;
+  case Stmt::OMPTargetTeamsDirectiveClass:
+    K = CXCursor_OMPTargetTeamsDirective;
+    break;
+  case Stmt::OMPTargetTeamsDistributeDirectiveClass:
+    K = CXCursor_OMPTargetTeamsDistributeDirective;
+    break;
+  case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
+    K = CXCursor_OMPTargetTeamsDistributeParallelForDirective;
+    break;
+  case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
+    K = CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective;
+    break;
+  case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
+    K = CXCursor_OMPTargetTeamsDistributeSimdDirective;
+    break;
   }
 
   CXCursor C = { K, 0, { Parent, S, TU } };
@@ -1102,8 +1120,6 @@
 // libclang CXCursor APIs
 //===----------------------------------------------------------------------===//
 
-extern "C" {
-
 int clang_Cursor_isNull(CXCursor cursor) {
   return clang_equalCursors(cursor, clang_getNullCursor());
 }
@@ -1293,8 +1309,6 @@
   return TA.getAsIntegral().getZExtValue();
 }
 
-} // end: extern "C"
-
 //===----------------------------------------------------------------------===//
 // CXCursorSet.
 //===----------------------------------------------------------------------===//
@@ -1328,7 +1342,6 @@
 };
 }
 
-extern "C" {
 CXCursorSet clang_createCXCursorSet() {
   return packCXCursorSet(new CXCursorSet_Impl());
 }
@@ -1391,7 +1404,6 @@
   }
   return nullptr;
 }
-} // end: extern C.
 
 namespace {
   struct OverridenCursorsPool {
@@ -1416,7 +1428,6 @@
   delete static_cast<OverridenCursorsPool*>(pool);
 }
  
-extern "C" {
 void clang_getOverriddenCursors(CXCursor cursor,
                                 CXCursor **overridden,
                                 unsigned *num_overridden) {
@@ -1538,5 +1549,3 @@
 
   return cxtype::MakeCXType(QualType(), TU);
 }
-
-} // end: extern "C"
diff --git a/tools/libclang/CXIndexDataConsumer.cpp b/tools/libclang/CXIndexDataConsumer.cpp
index 45198dd..5d9776b 100644
--- a/tools/libclang/CXIndexDataConsumer.cpp
+++ b/tools/libclang/CXIndexDataConsumer.cpp
@@ -95,7 +95,7 @@
     if (isa<ObjCImplDecl>(LexicalDC) && !D->isThisDeclarationADefinition())
       DataConsumer.handleSynthesizedObjCMethod(D, DeclLoc, LexicalDC);
     else
-      DataConsumer.handleObjCMethod(D);
+      DataConsumer.handleObjCMethod(D, DeclLoc);
     return true;
   }
 
@@ -410,8 +410,8 @@
   cxtu::getASTUnit(CXTU)->setASTContext(&ctx);
 }
 
-void CXIndexDataConsumer::setPreprocessor(Preprocessor &PP) {
-  cxtu::getASTUnit(CXTU)->setPreprocessor(&PP);
+void CXIndexDataConsumer::setPreprocessor(std::shared_ptr<Preprocessor> PP) {
+  cxtu::getASTUnit(CXTU)->setPreprocessor(std::move(PP));
 }
 
 bool CXIndexDataConsumer::isFunctionLocalDecl(const Decl *D) {
@@ -801,7 +801,8 @@
   return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
 }
 
-bool CXIndexDataConsumer::handleObjCMethod(const ObjCMethodDecl *D) {
+bool CXIndexDataConsumer::handleObjCMethod(const ObjCMethodDecl *D,
+                                           SourceLocation Loc) {
   bool isDef = D->isThisDeclarationADefinition();
   bool isContainer = isDef;
   bool isSkipped = false;
@@ -814,7 +815,7 @@
   DeclInfo DInfo(!D->isCanonicalDecl(), isDef, isContainer);
   if (isSkipped)
     DInfo.flags |= CXIdxDeclFlag_Skipped;
-  return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
+  return handleDecl(D, Loc, getCursor(D), DInfo);
 }
 
 bool CXIndexDataConsumer::handleSynthesizedObjCProperty(
@@ -1293,6 +1294,7 @@
   case SymbolKind::Constructor: return CXIdxEntity_CXXConstructor;
   case SymbolKind::Destructor: return CXIdxEntity_CXXDestructor;
   case SymbolKind::ConversionFunction: return CXIdxEntity_CXXConversionFunction;
+  case SymbolKind::Parameter: return CXIdxEntity_Variable;
   }
   llvm_unreachable("invalid symbol kind");
 }
diff --git a/tools/libclang/CXIndexDataConsumer.h b/tools/libclang/CXIndexDataConsumer.h
index 406831f..16162cb 100644
--- a/tools/libclang/CXIndexDataConsumer.h
+++ b/tools/libclang/CXIndexDataConsumer.h
@@ -342,7 +342,7 @@
   CXTranslationUnit getCXTU() const { return CXTU; }
 
   void setASTContext(ASTContext &ctx);
-  void setPreprocessor(Preprocessor &PP);
+  void setPreprocessor(std::shared_ptr<Preprocessor> PP);
 
   bool shouldSuppressRefs() const {
     return IndexOptions & CXIndexOpt_SuppressRedundantRefs;
@@ -418,7 +418,7 @@
   bool handleObjCCategory(const ObjCCategoryDecl *D);
   bool handleObjCCategoryImpl(const ObjCCategoryImplDecl *D);
 
-  bool handleObjCMethod(const ObjCMethodDecl *D);
+  bool handleObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc);
 
   bool handleSynthesizedObjCProperty(const ObjCPropertyImplDecl *D);
   bool handleSynthesizedObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc,
diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp
index c866717..36c3dca 100644
--- a/tools/libclang/CXLoadedDiagnostic.cpp
+++ b/tools/libclang/CXLoadedDiagnostic.cpp
@@ -387,11 +387,9 @@
   return std::error_code();
 }
 
-extern "C" {
 CXDiagnosticSet clang_loadDiagnostics(const char *file,
                                       enum CXLoadDiag_Error *error,
                                       CXString *errorString) {
   DiagLoader L(error, errorString);
   return L.load(file);
 }
-} // end extern 'C'.
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index 68ecf38..2e0ea4e 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -38,8 +38,6 @@
 // Basic construction and comparison of CXSourceLocations and CXSourceRanges.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
-  
 CXSourceLocation clang_getNullLocation() {
   CXSourceLocation Result = { { nullptr, nullptr }, 0 };
   return Result;
@@ -110,14 +108,10 @@
   return Result;
 }
 
-} // end extern "C"
-
 //===----------------------------------------------------------------------===//
 //  Getting CXSourceLocations and CXSourceRanges from a translation unit.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
-  
 CXSourceLocation clang_getLocation(CXTranslationUnit TU,
                                    CXFile file,
                                    unsigned line,
@@ -174,8 +168,6 @@
   return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
 }
 
-} // end extern "C"
-
 //===----------------------------------------------------------------------===//
 // Routines for expanding and manipulating CXSourceLocations, regardless
 // of their origin.
@@ -205,8 +197,6 @@
     *offset = 0;
 }
 
-extern "C" {
-
 int clang_Location_isInSystemHeader(CXSourceLocation location) {
   const SourceLocation Loc =
     SourceLocation::getFromRawEncoding(location.int_data);
@@ -382,5 +372,3 @@
   if (offset)
     *offset = FileOffset;
 }
-
-} // end extern "C"
diff --git a/tools/libclang/CXString.cpp b/tools/libclang/CXString.cpp
index 2148181..4486031 100644
--- a/tools/libclang/CXString.cpp
+++ b/tools/libclang/CXString.cpp
@@ -161,7 +161,6 @@
 // libClang public APIs.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
 const char *clang_getCString(CXString string) {
   if (string.private_flags == (unsigned) CXS_StringBuf) {
     return static_cast<const cxstring::CXStringBuf *>(string.data)->Data.data();
@@ -191,5 +190,3 @@
   delete set;
 }
 
-} // end: extern "C"
-
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index 6022c9d..67c31d2 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -38,7 +38,8 @@
 namespace clang {
 namespace cxtu {
 
-CXTranslationUnitImpl *MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU);
+CXTranslationUnitImpl *MakeCXTranslationUnit(CIndexer *CIdx,
+                                             std::unique_ptr<ASTUnit> AU);
 
 static inline ASTUnit *getASTUnit(CXTranslationUnit TU) {
   if (!TU)
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index a07bbe0..54549ef 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -48,6 +48,7 @@
     BTCASE(Long);
     BTCASE(LongLong);
     BTCASE(Int128);
+    BTCASE(Half);
     BTCASE(Float);
     BTCASE(Double);
     BTCASE(LongDouble);
@@ -143,7 +144,44 @@
   return static_cast<CXTranslationUnit>(CT.data[1]);
 }
 
-extern "C" {
+static Optional<ArrayRef<TemplateArgument>>
+GetTemplateArguments(QualType Type) {
+  assert(!Type.isNull());
+  if (const auto *Specialization = Type->getAs<TemplateSpecializationType>())
+    return Specialization->template_arguments();
+
+  if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) {
+    const auto *TemplateDecl =
+      dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
+    if (TemplateDecl)
+      return TemplateDecl->getTemplateArgs().asArray();
+  }
+
+  return None;
+}
+
+static Optional<QualType> TemplateArgumentToQualType(const TemplateArgument &A) {
+  if (A.getKind() == TemplateArgument::Type)
+    return A.getAsType();
+  return None;
+}
+
+static Optional<QualType>
+FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) {
+  unsigned current = 0;
+  for (const auto &A : TA) {
+    if (A.getKind() == TemplateArgument::Pack) {
+      if (index < current + A.pack_size())
+        return TemplateArgumentToQualType(A.getPackAsArray()[index - current]);
+      current += A.pack_size();
+      continue;
+    }
+    if (current == index)
+      return TemplateArgumentToQualType(A);
+    current++;
+  }
+  return None;
+}
 
 CXType clang_getCursorType(CXCursor C) {
   using namespace cxcursor;
@@ -415,7 +453,8 @@
     break;
 
   case Type::Auto:
-    TP = cast<AutoType>(TP)->getDeducedType().getTypePtrOrNull();
+  case Type::DeducedTemplateSpecialization:
+    TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
     if (TP)
       goto try_again;
     break;
@@ -465,6 +504,7 @@
     TKIND(Long);
     TKIND(LongLong);
     TKIND(Int128);
+    TKIND(Half);
     TKIND(Float);
     TKIND(Double);
     TKIND(LongDouble);
@@ -920,33 +960,37 @@
   return cxstring::createDup(encoding);
 }
 
+static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) {
+  unsigned size = TA.size();
+  for (const auto &Arg : TA)
+    if (Arg.getKind() == TemplateArgument::Pack)
+      size += Arg.pack_size() - 1;
+  return size;
+}
+
 int clang_Type_getNumTemplateArguments(CXType CT) {
   QualType T = GetQualType(CT);
   if (T.isNull())
     return -1;
-  const TemplateSpecializationType *Specialization =
-    T->getAs<TemplateSpecializationType>();
-  if (!Specialization)
+
+  auto TA = GetTemplateArguments(T);
+  if (!TA)
     return -1;
-  return Specialization->template_arguments().size();
+
+  return GetTemplateArgumentArraySize(TA.getValue());
 }
 
-CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
+CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) {
   QualType T = GetQualType(CT);
   if (T.isNull())
     return MakeCXType(QualType(), GetTU(CT));
 
-  const TemplateSpecializationType *Specialization =
-    T->getAs<TemplateSpecializationType>();
-  if (!Specialization)
+  auto TA = GetTemplateArguments(T);
+  if (!TA)
     return MakeCXType(QualType(), GetTU(CT));
-  auto TA = Specialization->template_arguments();
-  if (TA.size() <= i)
-    return MakeCXType(QualType(), GetTU(CT));
-  const TemplateArgument &A = TA[i];
-  if (A.getKind() != TemplateArgument::Type)
-    return MakeCXType(QualType(), GetTU(CT));
-  return MakeCXType(A.getAsType(), GetTU(CT));
+
+  Optional<QualType> QT = FindTemplateArgumentTypeAt(TA.getValue(), index);
+  return MakeCXType(QT.getValueOr(QualType()), GetTU(CT));
 }
 
 unsigned clang_Type_visitFields(CXType PT,
@@ -995,5 +1039,3 @@
 
   return MakeCXType(QualType(), GetTU(CT));
 }
-
-} // end: extern "C"
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 878d75e..f98b258 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -371,7 +371,7 @@
     DataConsumer->setASTContext(CI.getASTContext());
     Preprocessor &PP = CI.getPreprocessor();
     PP.addPPCallbacks(llvm::make_unique<IndexPPCallbacks>(PP, *DataConsumer));
-    DataConsumer->setPreprocessor(PP);
+    DataConsumer->setPreprocessor(CI.getPreprocessorPtr());
 
     if (SKData) {
       auto *PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
@@ -476,17 +476,19 @@
   // present it will be unused.
   if (source_filename)
     Args->push_back(source_filename);
-  
-  IntrusiveRefCntPtr<CompilerInvocation>
-    CInvok(createInvocationFromCommandLine(*Args, Diags));
+
+  std::shared_ptr<CompilerInvocation> CInvok =
+      createInvocationFromCommandLine(*Args, Diags);
 
   if (!CInvok)
     return CXError_Failure;
 
   // Recover resources if we crash before exiting this function.
-  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation,
-    llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> >
-    CInvokCleanup(CInvok.get());
+  llvm::CrashRecoveryContextCleanupRegistrar<
+      std::shared_ptr<CompilerInvocation>,
+      llvm::CrashRecoveryContextDestructorCleanup<
+          std::shared_ptr<CompilerInvocation>>>
+      CInvokCleanup(&CInvok);
 
   if (CInvok->getFrontendOpts().Inputs.empty())
     return CXError_Failure;
@@ -518,13 +520,14 @@
   CInvok->getHeaderSearchOpts().ModuleFormat =
     CXXIdx->getPCHContainerOperations()->getRawReader().getFormat();
 
-  ASTUnit *Unit = ASTUnit::create(CInvok.get(), Diags, CaptureDiagnostics,
-                                  /*UserFilesAreVolatile=*/true);
+  auto Unit = ASTUnit::create(CInvok, Diags, CaptureDiagnostics,
+                              /*UserFilesAreVolatile=*/true);
   if (!Unit)
     return CXError_InvalidArguments;
 
+  auto *UPtr = Unit.get();
   std::unique_ptr<CXTUOwner> CXTU(
-      new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
+      new CXTUOwner(MakeCXTranslationUnit(CXXIdx, std::move(Unit))));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
@@ -583,16 +586,16 @@
       !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
   DiagnosticErrorTrap DiagTrap(*Diags);
   bool Success = ASTUnit::LoadFromCompilerInvocationAction(
-      CInvok.get(), CXXIdx->getPCHContainerOperations(), Diags,
-      IndexAction.get(), Unit, Persistent, CXXIdx->getClangResourcesPath(),
+      std::move(CInvok), CXXIdx->getPCHContainerOperations(), Diags,
+      IndexAction.get(), UPtr, Persistent, CXXIdx->getClangResourcesPath(),
       OnlyLocalDecls, CaptureDiagnostics, PrecompilePreambleAfterNParses,
       CacheCodeCompletionResults,
       /*IncludeBriefCommentsInCodeCompletion=*/false,
       /*UserFilesAreVolatile=*/true);
   if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
-    printDiagsToStderr(Unit);
+    printDiagsToStderr(UPtr);
 
-  if (isASTReadError(Unit))
+  if (isASTReadError(UPtr))
     return CXError_ASTReadError;
 
   if (!Success)
@@ -687,8 +690,6 @@
 // libclang public APIs.
 //===----------------------------------------------------------------------===//
 
-extern "C" {
-
 int clang_index_isEntityObjCContainerKind(CXIdxEntityKind K) {
   return CXIdxEntity_ObjCClass <= K && K <= CXIdxEntity_ObjCCategory;
 }
@@ -978,5 +979,3 @@
   return cxloc::translateSourceLocation(DataConsumer.getASTContext(), Loc);
 }
 
-} // end: extern "C"
-
diff --git a/tools/scan-build-py/bin/analyze-build b/tools/scan-build-py/bin/analyze-build
index 2cc9676..991cff0 100755
--- a/tools/scan-build-py/bin/analyze-build
+++ b/tools/scan-build-py/bin/analyze-build
@@ -13,5 +13,5 @@
 this_dir = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.dirname(this_dir))
 
-from libscanbuild.analyze import analyze_build_main
-sys.exit(analyze_build_main(this_dir, False))
+from libscanbuild.analyze import analyze_build
+sys.exit(analyze_build())
diff --git a/tools/scan-build-py/bin/analyze-build.bat b/tools/scan-build-py/bin/analyze-build.bat
deleted file mode 100644
index 05d81dd..0000000
--- a/tools/scan-build-py/bin/analyze-build.bat
+++ /dev/null
@@ -1 +0,0 @@
-python %~dp0analyze-build %*

diff --git a/tools/scan-build-py/bin/analyze-c++ b/tools/scan-build-py/bin/analyze-c++
index 15186d8..df1012d 100755
--- a/tools/scan-build-py/bin/analyze-c++
+++ b/tools/scan-build-py/bin/analyze-c++
@@ -10,5 +10,5 @@
 this_dir = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.dirname(this_dir))
 
-from libscanbuild.analyze import analyze_build_wrapper
-sys.exit(analyze_build_wrapper(True))
+from libscanbuild.analyze import analyze_compiler_wrapper
+sys.exit(analyze_compiler_wrapper())
diff --git a/tools/scan-build-py/bin/analyze-c++.bat b/tools/scan-build-py/bin/analyze-c++.bat
deleted file mode 100644
index f57032f..0000000
--- a/tools/scan-build-py/bin/analyze-c++.bat
+++ /dev/null
@@ -1 +0,0 @@
-python %~dp0analyze-c++ %*

diff --git a/tools/scan-build-py/bin/analyze-cc b/tools/scan-build-py/bin/analyze-cc
index 55519fb..df1012d 100755
--- a/tools/scan-build-py/bin/analyze-cc
+++ b/tools/scan-build-py/bin/analyze-cc
@@ -10,5 +10,5 @@
 this_dir = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.dirname(this_dir))
 
-from libscanbuild.analyze import analyze_build_wrapper
-sys.exit(analyze_build_wrapper(False))
+from libscanbuild.analyze import analyze_compiler_wrapper
+sys.exit(analyze_compiler_wrapper())
diff --git a/tools/scan-build-py/bin/analyze-cc.bat b/tools/scan-build-py/bin/analyze-cc.bat
deleted file mode 100644
index 41cd8f6..0000000
--- a/tools/scan-build-py/bin/analyze-cc.bat
+++ /dev/null
@@ -1 +0,0 @@
-python %~dp0analyze-cc %*

diff --git a/tools/scan-build-py/bin/intercept-build b/tools/scan-build-py/bin/intercept-build
index 164f2e6..2c3a26e 100755
--- a/tools/scan-build-py/bin/intercept-build
+++ b/tools/scan-build-py/bin/intercept-build
@@ -13,5 +13,5 @@
 this_dir = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.dirname(this_dir))
 
-from libscanbuild.intercept import intercept_build_main
-sys.exit(intercept_build_main(this_dir))
+from libscanbuild.intercept import intercept_build
+sys.exit(intercept_build())
diff --git a/tools/scan-build-py/bin/intercept-build.bat b/tools/scan-build-py/bin/intercept-build.bat
deleted file mode 100644
index 5c82463..0000000
--- a/tools/scan-build-py/bin/intercept-build.bat
+++ /dev/null
@@ -1 +0,0 @@
-python %~dp0intercept-build %*

diff --git a/tools/scan-build-py/bin/intercept-c++ b/tools/scan-build-py/bin/intercept-c++
index fc42228..67e076f 100755
--- a/tools/scan-build-py/bin/intercept-c++
+++ b/tools/scan-build-py/bin/intercept-c++
@@ -10,5 +10,5 @@
 this_dir = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.dirname(this_dir))
 
-from libscanbuild.intercept import intercept_build_wrapper
-sys.exit(intercept_build_wrapper(True))
+from libscanbuild.intercept import intercept_compiler_wrapper
+sys.exit(intercept_compiler_wrapper())
diff --git a/tools/scan-build-py/bin/intercept-c++.bat b/tools/scan-build-py/bin/intercept-c++.bat
deleted file mode 100644
index abbd4b1..0000000
--- a/tools/scan-build-py/bin/intercept-c++.bat
+++ /dev/null
@@ -1 +0,0 @@
-python %~dp0intercept-c++ %*

diff --git a/tools/scan-build-py/bin/intercept-cc b/tools/scan-build-py/bin/intercept-cc
index 69d57aa..67e076f 100755
--- a/tools/scan-build-py/bin/intercept-cc
+++ b/tools/scan-build-py/bin/intercept-cc
@@ -10,5 +10,5 @@
 this_dir = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.dirname(this_dir))
 
-from libscanbuild.intercept import intercept_build_wrapper
-sys.exit(intercept_build_wrapper(False))
+from libscanbuild.intercept import intercept_compiler_wrapper
+sys.exit(intercept_compiler_wrapper())
diff --git a/tools/scan-build-py/bin/intercept-cc.bat b/tools/scan-build-py/bin/intercept-cc.bat
deleted file mode 100644
index 23cbd8d..0000000
--- a/tools/scan-build-py/bin/intercept-cc.bat
+++ /dev/null
@@ -1 +0,0 @@
-python %~dp0intercept-cc %*

diff --git a/tools/scan-build-py/bin/scan-build b/tools/scan-build-py/bin/scan-build
index 601fe89..f0f3469 100755
--- a/tools/scan-build-py/bin/scan-build
+++ b/tools/scan-build-py/bin/scan-build
@@ -13,5 +13,5 @@
 this_dir = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.dirname(this_dir))
 
-from libscanbuild.analyze import analyze_build_main
-sys.exit(analyze_build_main(this_dir, True))
+from libscanbuild.analyze import scan_build
+sys.exit(scan_build())
diff --git a/tools/scan-build-py/bin/scan-build.bat b/tools/scan-build-py/bin/scan-build.bat
deleted file mode 100644
index 8caf240..0000000
--- a/tools/scan-build-py/bin/scan-build.bat
+++ /dev/null
@@ -1 +0,0 @@
-python %~dp0scan-build %*

diff --git a/tools/scan-build-py/libear/__init__.py b/tools/scan-build-py/libear/__init__.py
index 3e1c13c..421e2e7 100644
--- a/tools/scan-build-py/libear/__init__.py
+++ b/tools/scan-build-py/libear/__init__.py
@@ -207,9 +207,9 @@
             if m:
                 key = m.group(1)
                 if key not in definitions or not definitions[key]:
-                    return '/* #undef {} */\n'.format(key)
+                    return '/* #undef {0} */{1}'.format(key, os.linesep)
                 else:
-                    return '#define {}\n'.format(key)
+                    return '#define {0}{1}'.format(key, os.linesep)
             return line
 
         with open(template, 'r') as src_handle:
diff --git a/tools/scan-build-py/libscanbuild/__init__.py b/tools/scan-build-py/libscanbuild/__init__.py
index c020b4e..ca75174 100644
--- a/tools/scan-build-py/libscanbuild/__init__.py
+++ b/tools/scan-build-py/libscanbuild/__init__.py
@@ -3,10 +3,21 @@
 #
 # This file is distributed under the University of Illinois Open Source
 # License. See LICENSE.TXT for details.
-"""
-This module responsible to run the Clang static analyzer against any build
-and generate reports.
-"""
+""" This module is a collection of methods commonly used in this project. """
+import collections
+import functools
+import json
+import logging
+import os
+import os.path
+import re
+import shlex
+import subprocess
+import sys
+
+ENVIRONMENT_KEY = 'INTERCEPT_BUILD'
+
+Execution = collections.namedtuple('Execution', ['pid', 'cwd', 'cmd'])
 
 
 def duplicate_check(method):
@@ -33,41 +44,92 @@
 def tempdir():
     """ Return the default temorary directory. """
 
-    from os import getenv
-    return getenv('TMPDIR', getenv('TEMP', getenv('TMP', '/tmp')))
+    return os.getenv('TMPDIR', os.getenv('TEMP', os.getenv('TMP', '/tmp')))
 
 
-def initialize_logging(verbose_level):
-    """ Output content controlled by the verbosity level. """
+def run_build(command, *args, **kwargs):
+    """ Run and report build command execution
 
-    import sys
-    import os.path
-    import logging
+    :param command: array of tokens
+    :return: exit code of the process
+    """
+    environment = kwargs.get('env', os.environ)
+    logging.debug('run build %s, in environment: %s', command, environment)
+    exit_code = subprocess.call(command, *args, **kwargs)
+    logging.debug('build finished with exit code: %d', exit_code)
+    return exit_code
+
+
+def run_command(command, cwd=None):
+    """ Run a given command and report the execution.
+
+    :param command: array of tokens
+    :param cwd: the working directory where the command will be executed
+    :return: output of the command
+    """
+    def decode_when_needed(result):
+        """ check_output returns bytes or string depend on python version """
+        return result.decode('utf-8') if isinstance(result, bytes) else result
+
+    try:
+        directory = os.path.abspath(cwd) if cwd else os.getcwd()
+        logging.debug('exec command %s in %s', command, directory)
+        output = subprocess.check_output(command,
+                                         cwd=directory,
+                                         stderr=subprocess.STDOUT)
+        return decode_when_needed(output).splitlines()
+    except subprocess.CalledProcessError as ex:
+        ex.output = decode_when_needed(ex.output).splitlines()
+        raise ex
+
+
+def reconfigure_logging(verbose_level):
+    """ Reconfigure logging level and format based on the verbose flag.
+
+    :param verbose_level: number of `-v` flags received by the command
+    :return: no return value
+    """
+    # Exit when nothing to do.
+    if verbose_level == 0:
+        return
+
+    root = logging.getLogger()
+    # Tune logging level.
     level = logging.WARNING - min(logging.WARNING, (10 * verbose_level))
-
+    root.setLevel(level)
+    # Be verbose with messages.
     if verbose_level <= 3:
-        fmt_string = '{0}: %(levelname)s: %(message)s'
+        fmt_string = '%(name)s: %(levelname)s: %(message)s'
     else:
-        fmt_string = '{0}: %(levelname)s: %(funcName)s: %(message)s'
-
-    program = os.path.basename(sys.argv[0])
-    logging.basicConfig(format=fmt_string.format(program), level=level)
+        fmt_string = '%(name)s: %(levelname)s: %(funcName)s: %(message)s'
+    handler = logging.StreamHandler(sys.stdout)
+    handler.setFormatter(logging.Formatter(fmt=fmt_string))
+    root.handlers = [handler]
 
 
 def command_entry_point(function):
-    """ Decorator for command entry points. """
+    """ Decorator for command entry methods.
 
-    import functools
-    import logging
+    The decorator initialize/shutdown logging and guard on programming
+    errors (catch exceptions).
+
+    The decorated method can have arbitrary parameters, the return value will
+    be the exit code of the process. """
 
     @functools.wraps(function)
     def wrapper(*args, **kwargs):
+        """ Do housekeeping tasks and execute the wrapped method. """
 
-        exit_code = 127
         try:
-            exit_code = function(*args, **kwargs)
+            logging.basicConfig(format='%(name)s: %(message)s',
+                                level=logging.WARNING,
+                                stream=sys.stdout)
+            # This hack to get the executable name as %(name).
+            logging.getLogger().name = os.path.basename(sys.argv[0])
+            return function(*args, **kwargs)
         except KeyboardInterrupt:
-            logging.warning('Keyboard interupt')
+            logging.warning('Keyboard interrupt')
+            return 130  # Signal received exit code for bash.
         except Exception:
             logging.exception('Internal error.')
             if logging.getLogger().isEnabledFor(logging.DEBUG):
@@ -75,8 +137,75 @@
                               "to the bug report")
             else:
                 logging.error("Please run this command again and turn on "
-                              "verbose mode (add '-vvv' as argument).")
+                              "verbose mode (add '-vvvv' as argument).")
+            return 64  # Some non used exit code for internal errors.
         finally:
-            return exit_code
+            logging.shutdown()
 
     return wrapper
+
+
+def compiler_wrapper(function):
+    """ Implements compiler wrapper base functionality.
+
+    A compiler wrapper executes the real compiler, then implement some
+    functionality, then returns with the real compiler exit code.
+
+    :param function: the extra functionality what the wrapper want to
+    do on top of the compiler call. If it throws exception, it will be
+    caught and logged.
+    :return: the exit code of the real compiler.
+
+    The :param function: will receive the following arguments:
+
+    :param result:       the exit code of the compilation.
+    :param execution:    the command executed by the wrapper. """
+
+    def is_cxx_compiler():
+        """ Find out was it a C++ compiler call. Compiler wrapper names
+        contain the compiler type. C++ compiler wrappers ends with `c++`,
+        but might have `.exe` extension on windows. """
+
+        wrapper_command = os.path.basename(sys.argv[0])
+        return re.match(r'(.+)c\+\+(.*)', wrapper_command)
+
+    def run_compiler(executable):
+        """ Execute compilation with the real compiler. """
+
+        command = executable + sys.argv[1:]
+        logging.debug('compilation: %s', command)
+        result = subprocess.call(command)
+        logging.debug('compilation exit code: %d', result)
+        return result
+
+    # Get relevant parameters from environment.
+    parameters = json.loads(os.environ[ENVIRONMENT_KEY])
+    reconfigure_logging(parameters['verbose'])
+    # Execute the requested compilation. Do crash if anything goes wrong.
+    cxx = is_cxx_compiler()
+    compiler = parameters['cxx'] if cxx else parameters['cc']
+    result = run_compiler(compiler)
+    # Call the wrapped method and ignore it's return value.
+    try:
+        call = Execution(
+            pid=os.getpid(),
+            cwd=os.getcwd(),
+            cmd=['c++' if cxx else 'cc'] + sys.argv[1:])
+        function(result, call)
+    except:
+        logging.exception('Compiler wrapper failed complete.')
+    finally:
+        # Always return the real compiler exit code.
+        return result
+
+
+def wrapper_environment(args):
+    """ Set up environment for interpose compiler wrapper."""
+
+    return {
+        ENVIRONMENT_KEY: json.dumps({
+            'verbose': args.verbose,
+            'cc': shlex.split(args.cc),
+            'cxx': shlex.split(args.cxx)
+        })
+    }
diff --git a/tools/scan-build-py/libscanbuild/analyze.py b/tools/scan-build-py/libscanbuild/analyze.py
index 244c34b..0485ca8 100644
--- a/tools/scan-build-py/libscanbuild/analyze.py
+++ b/tools/scan-build-py/libscanbuild/analyze.py
@@ -11,72 +11,68 @@
  -- Analyze:   run the analyzer against the captured commands,
  -- Report:    create a cover report from the analyzer outputs.  """
 
-import sys
 import re
 import os
 import os.path
 import json
-import argparse
 import logging
-import subprocess
+import tempfile
 import multiprocessing
-from libscanbuild import initialize_logging, tempdir, command_entry_point
+import contextlib
+import datetime
+from libscanbuild import command_entry_point, compiler_wrapper, \
+    wrapper_environment, run_build
+from libscanbuild.arguments import parse_args_for_scan_build, \
+    parse_args_for_analyze_build
 from libscanbuild.runner import run
 from libscanbuild.intercept import capture
-from libscanbuild.report import report_directory, document
-from libscanbuild.clang import get_checkers
+from libscanbuild.report import document
 from libscanbuild.compilation import split_command
 
-__all__ = ['analyze_build_main', 'analyze_build_wrapper']
+__all__ = ['scan_build', 'analyze_build', 'analyze_compiler_wrapper']
 
 COMPILER_WRAPPER_CC = 'analyze-cc'
 COMPILER_WRAPPER_CXX = 'analyze-c++'
 
 
 @command_entry_point
-def analyze_build_main(bin_dir, from_build_command):
-    """ Entry point for 'analyze-build' and 'scan-build'. """
+def scan_build():
+    """ Entry point for scan-build command. """
 
-    parser = create_parser(from_build_command)
-    args = parser.parse_args()
-    validate(parser, args, from_build_command)
-
-    # setup logging
-    initialize_logging(args.verbose)
-    logging.debug('Parsed arguments: %s', args)
-
+    args = parse_args_for_scan_build()
     with report_directory(args.output, args.keep_empty) as target_dir:
-        if not from_build_command:
-            # run analyzer only and generate cover report
-            run_analyzer(args, target_dir)
-            number_of_bugs = document(args, target_dir, True)
-            return number_of_bugs if args.status_bugs else 0
-        elif args.intercept_first:
-            # run build command and capture compiler executions
-            exit_code = capture(args, bin_dir)
-            # next step to run the analyzer against the captured commands
+        # Run against a build command. there are cases, when analyzer run
+        # is not required. But we need to set up everything for the
+        # wrappers, because 'configure' needs to capture the CC/CXX values
+        # for the Makefile.
+        if args.intercept_first:
+            # Run build command with intercept module.
+            exit_code = capture(args)
+            # Run the analyzer against the captured commands.
             if need_analyzer(args.build):
                 run_analyzer(args, target_dir)
-                # cover report generation and bug counting
-                number_of_bugs = document(args, target_dir, True)
-                # remove the compilation database when it was not requested
-                if os.path.exists(args.cdb):
-                    os.unlink(args.cdb)
-                # set exit status as it was requested
-                return number_of_bugs if args.status_bugs else exit_code
-            else:
-                return exit_code
         else:
-            # run the build command with compiler wrappers which
-            # execute the analyzer too. (interposition)
-            environment = setup_environment(args, target_dir, bin_dir)
-            logging.debug('run build in environment: %s', environment)
-            exit_code = subprocess.call(args.build, env=environment)
-            logging.debug('build finished with exit code: %d', exit_code)
-            # cover report generation and bug counting
-            number_of_bugs = document(args, target_dir, False)
-            # set exit status as it was requested
-            return number_of_bugs if args.status_bugs else exit_code
+            # Run build command and analyzer with compiler wrappers.
+            environment = setup_environment(args, target_dir)
+            exit_code = run_build(args.build, env=environment)
+        # Cover report generation and bug counting.
+        number_of_bugs = document(args, target_dir, False)
+        # Set exit status as it was requested.
+        return number_of_bugs if args.status_bugs else exit_code
+
+
+@command_entry_point
+def analyze_build():
+    """ Entry point for analyze-build command. """
+
+    args = parse_args_for_analyze_build()
+    with report_directory(args.output, args.keep_empty) as target_dir:
+        # Run the analyzer against a compilation db.
+        run_analyzer(args, target_dir)
+        # Cover report generation and bug counting.
+        number_of_bugs = document(args, target_dir, True)
+        # Set exit status as it was requested.
+        return number_of_bugs if args.status_bugs else 0
 
 
 def need_analyzer(args):
@@ -124,17 +120,15 @@
         pool.join()
 
 
-def setup_environment(args, destination, bin_dir):
+def setup_environment(args, destination):
     """ Set up environment for build command to interpose compiler wrapper. """
 
     environment = dict(os.environ)
+    environment.update(wrapper_environment(args))
     environment.update({
-        'CC': os.path.join(bin_dir, COMPILER_WRAPPER_CC),
-        'CXX': os.path.join(bin_dir, COMPILER_WRAPPER_CXX),
-        'ANALYZE_BUILD_CC': args.cc,
-        'ANALYZE_BUILD_CXX': args.cxx,
+        'CC': COMPILER_WRAPPER_CC,
+        'CXX': COMPILER_WRAPPER_CXX,
         'ANALYZE_BUILD_CLANG': args.clang if need_analyzer(args.build) else '',
-        'ANALYZE_BUILD_VERBOSE': 'DEBUG' if args.verbose > 2 else 'WARNING',
         'ANALYZE_BUILD_REPORT_DIR': destination,
         'ANALYZE_BUILD_REPORT_FORMAT': args.output_format,
         'ANALYZE_BUILD_REPORT_FAILURES': 'yes' if args.output_failures else '',
@@ -144,51 +138,78 @@
     return environment
 
 
-def analyze_build_wrapper(cplusplus):
+@command_entry_point
+def analyze_compiler_wrapper():
     """ Entry point for `analyze-cc` and `analyze-c++` compiler wrappers. """
 
-    # initialize wrapper logging
-    logging.basicConfig(format='analyze: %(levelname)s: %(message)s',
-                        level=os.getenv('ANALYZE_BUILD_VERBOSE', 'INFO'))
-    # execute with real compiler
-    compiler = os.getenv('ANALYZE_BUILD_CXX', 'c++') if cplusplus \
-        else os.getenv('ANALYZE_BUILD_CC', 'cc')
-    compilation = [compiler] + sys.argv[1:]
-    logging.info('execute compiler: %s', compilation)
-    result = subprocess.call(compilation)
-    # exit when it fails, ...
+    return compiler_wrapper(analyze_compiler_wrapper_impl)
+
+
+def analyze_compiler_wrapper_impl(result, execution):
+    """ Implements analyzer compiler wrapper functionality. """
+
+    # don't run analyzer when compilation fails. or when it's not requested.
     if result or not os.getenv('ANALYZE_BUILD_CLANG'):
-        return result
-    # ... and run the analyzer if all went well.
+        return
+
+    # check is it a compilation?
+    compilation = split_command(execution.cmd)
+    if compilation is None:
+        return
+    # collect the needed parameters from environment, crash when missing
+    parameters = {
+        'clang': os.getenv('ANALYZE_BUILD_CLANG'),
+        'output_dir': os.getenv('ANALYZE_BUILD_REPORT_DIR'),
+        'output_format': os.getenv('ANALYZE_BUILD_REPORT_FORMAT'),
+        'output_failures': os.getenv('ANALYZE_BUILD_REPORT_FAILURES'),
+        'direct_args': os.getenv('ANALYZE_BUILD_PARAMETERS',
+                                 '').split(' '),
+        'force_debug': os.getenv('ANALYZE_BUILD_FORCE_DEBUG'),
+        'directory': execution.cwd,
+        'command': [execution.cmd[0], '-c'] + compilation.flags
+    }
+    # call static analyzer against the compilation
+    for source in compilation.files:
+        parameters.update({'file': source})
+        logging.debug('analyzer parameters %s', parameters)
+        current = run(parameters)
+        # display error message from the static analyzer
+        if current is not None:
+            for line in current['error_output']:
+                logging.info(line.rstrip())
+
+
+@contextlib.contextmanager
+def report_directory(hint, keep):
+    """ Responsible for the report directory.
+
+    hint -- could specify the parent directory of the output directory.
+    keep -- a boolean value to keep or delete the empty report directory. """
+
+    stamp_format = 'scan-build-%Y-%m-%d-%H-%M-%S-%f-'
+    stamp = datetime.datetime.now().strftime(stamp_format)
+    parent_dir = os.path.abspath(hint)
+    if not os.path.exists(parent_dir):
+        os.makedirs(parent_dir)
+    name = tempfile.mkdtemp(prefix=stamp, dir=parent_dir)
+
+    logging.info('Report directory created: %s', name)
+
     try:
-        # check is it a compilation
-        compilation = split_command(sys.argv)
-        if compilation is None:
-            return result
-        # collect the needed parameters from environment, crash when missing
-        parameters = {
-            'clang': os.getenv('ANALYZE_BUILD_CLANG'),
-            'output_dir': os.getenv('ANALYZE_BUILD_REPORT_DIR'),
-            'output_format': os.getenv('ANALYZE_BUILD_REPORT_FORMAT'),
-            'output_failures': os.getenv('ANALYZE_BUILD_REPORT_FAILURES'),
-            'direct_args': os.getenv('ANALYZE_BUILD_PARAMETERS',
-                                     '').split(' '),
-            'force_debug': os.getenv('ANALYZE_BUILD_FORCE_DEBUG'),
-            'directory': os.getcwd(),
-            'command': [sys.argv[0], '-c'] + compilation.flags
-        }
-        # call static analyzer against the compilation
-        for source in compilation.files:
-            parameters.update({'file': source})
-            logging.debug('analyzer parameters %s', parameters)
-            current = run(parameters)
-            # display error message from the static analyzer
-            if current is not None:
-                for line in current['error_output']:
-                    logging.info(line.rstrip())
-    except Exception:
-        logging.exception("run analyzer inside compiler wrapper failed.")
-    return result
+        yield name
+    finally:
+        if os.listdir(name):
+            msg = "Run 'scan-view %s' to examine bug reports."
+            keep = True
+        else:
+            if keep:
+                msg = "Report directory '%s' contains no report, but kept."
+            else:
+                msg = "Removing directory '%s' because it contains no report."
+        logging.warning(msg, name)
+
+        if not keep:
+            os.rmdir(name)
 
 
 def analyzer_params(args):
@@ -236,281 +257,3 @@
         result.append('-analyzer-viz-egraph-ubigraph')
 
     return prefix_with('-Xclang', result)
-
-
-def print_active_checkers(checkers):
-    """ Print active checkers to stdout. """
-
-    for name in sorted(name for name, (_, active) in checkers.items()
-                       if active):
-        print(name)
-
-
-def print_checkers(checkers):
-    """ Print verbose checker help to stdout. """
-
-    print('')
-    print('available checkers:')
-    print('')
-    for name in sorted(checkers.keys()):
-        description, active = checkers[name]
-        prefix = '+' if active else ' '
-        if len(name) > 30:
-            print(' {0} {1}'.format(prefix, name))
-            print(' ' * 35 + description)
-        else:
-            print(' {0} {1: <30}  {2}'.format(prefix, name, description))
-    print('')
-    print('NOTE: "+" indicates that an analysis is enabled by default.')
-    print('')
-
-
-def validate(parser, args, from_build_command):
-    """ Validation done by the parser itself, but semantic check still
-    needs to be done. This method is doing that. """
-
-    # Make plugins always a list. (It might be None when not specified.)
-    args.plugins = args.plugins if args.plugins else []
-
-    if args.help_checkers_verbose:
-        print_checkers(get_checkers(args.clang, args.plugins))
-        parser.exit()
-    elif args.help_checkers:
-        print_active_checkers(get_checkers(args.clang, args.plugins))
-        parser.exit()
-
-    if from_build_command and not args.build:
-        parser.error('missing build command')
-
-
-def create_parser(from_build_command):
-    """ Command line argument parser factory method. """
-
-    parser = argparse.ArgumentParser(
-        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
-
-    parser.add_argument(
-        '--verbose', '-v',
-        action='count',
-        default=0,
-        help="""Enable verbose output from '%(prog)s'. A second and third
-                flag increases verbosity.""")
-    parser.add_argument(
-        '--override-compiler',
-        action='store_true',
-        help="""Always resort to the compiler wrapper even when better
-                interposition methods are available.""")
-    parser.add_argument(
-        '--intercept-first',
-        action='store_true',
-        help="""Run the build commands only, build a compilation database,
-                then run the static analyzer afterwards.
-                Generally speaking it has better coverage on build commands.
-                With '--override-compiler' it use compiler wrapper, but does
-                not run the analyzer till the build is finished. """)
-    parser.add_argument(
-        '--cdb',
-        metavar='<file>',
-        default="compile_commands.json",
-        help="""The JSON compilation database.""")
-
-    parser.add_argument(
-        '--output', '-o',
-        metavar='<path>',
-        default=tempdir(),
-        help="""Specifies the output directory for analyzer reports.
-                Subdirectory will be created if default directory is targeted.
-                """)
-    parser.add_argument(
-        '--status-bugs',
-        action='store_true',
-        help="""By default, the exit status of '%(prog)s' is the same as the
-                executed build command. Specifying this option causes the exit
-                status of '%(prog)s' to be non zero if it found potential bugs
-                and zero otherwise.""")
-    parser.add_argument(
-        '--html-title',
-        metavar='<title>',
-        help="""Specify the title used on generated HTML pages.
-                If not specified, a default title will be used.""")
-    parser.add_argument(
-        '--analyze-headers',
-        action='store_true',
-        help="""Also analyze functions in #included files. By default, such
-                functions are skipped unless they are called by functions
-                within the main source file.""")
-    format_group = parser.add_mutually_exclusive_group()
-    format_group.add_argument(
-        '--plist', '-plist',
-        dest='output_format',
-        const='plist',
-        default='html',
-        action='store_const',
-        help="""This option outputs the results as a set of .plist files.""")
-    format_group.add_argument(
-        '--plist-html', '-plist-html',
-        dest='output_format',
-        const='plist-html',
-        default='html',
-        action='store_const',
-        help="""This option outputs the results as a set of .html and .plist
-                files.""")
-    # TODO: implement '-view '
-
-    advanced = parser.add_argument_group('advanced options')
-    advanced.add_argument(
-        '--keep-empty',
-        action='store_true',
-        help="""Don't remove the build results directory even if no issues
-                were reported.""")
-    advanced.add_argument(
-        '--no-failure-reports', '-no-failure-reports',
-        dest='output_failures',
-        action='store_false',
-        help="""Do not create a 'failures' subdirectory that includes analyzer
-                crash reports and preprocessed source files.""")
-    advanced.add_argument(
-        '--stats', '-stats',
-        action='store_true',
-        help="""Generates visitation statistics for the project being analyzed.
-                """)
-    advanced.add_argument(
-        '--internal-stats',
-        action='store_true',
-        help="""Generate internal analyzer statistics.""")
-    advanced.add_argument(
-        '--maxloop', '-maxloop',
-        metavar='<loop count>',
-        type=int,
-        help="""Specifiy the number of times a block can be visited before
-                giving up. Increase for more comprehensive coverage at a cost
-                of speed.""")
-    advanced.add_argument(
-        '--store', '-store',
-        metavar='<model>',
-        dest='store_model',
-        choices=['region', 'basic'],
-        help="""Specify the store model used by the analyzer.
-                'region' specifies a field- sensitive store model.
-                'basic' which is far less precise but can more quickly
-                analyze code. 'basic' was the default store model for
-                checker-0.221 and earlier.""")
-    advanced.add_argument(
-        '--constraints', '-constraints',
-        metavar='<model>',
-        dest='constraints_model',
-        choices=['range', 'basic'],
-        help="""Specify the contraint engine used by the analyzer. Specifying
-                'basic' uses a simpler, less powerful constraint model used by
-                checker-0.160 and earlier.""")
-    advanced.add_argument(
-        '--use-analyzer',
-        metavar='<path>',
-        dest='clang',
-        default='clang',
-        help="""'%(prog)s' uses the 'clang' executable relative to itself for
-                static analysis. One can override this behavior with this
-                option by using the 'clang' packaged with Xcode (on OS X) or
-                from the PATH.""")
-    advanced.add_argument(
-        '--use-cc',
-        metavar='<path>',
-        dest='cc',
-        default='cc',
-        help="""When '%(prog)s' analyzes a project by interposing a "fake
-                compiler", which executes a real compiler for compilation and
-                do other tasks (to run the static analyzer or just record the
-                compiler invocation). Because of this interposing, '%(prog)s'
-                does not know what compiler your project normally uses.
-                Instead, it simply overrides the CC environment variable, and
-                guesses your default compiler.
-
-                If you need '%(prog)s' to use a specific compiler for
-                *compilation* then you can use this option to specify a path
-                to that compiler.""")
-    advanced.add_argument(
-        '--use-c++',
-        metavar='<path>',
-        dest='cxx',
-        default='c++',
-        help="""This is the same as "--use-cc" but for C++ code.""")
-    advanced.add_argument(
-        '--analyzer-config', '-analyzer-config',
-        metavar='<options>',
-        help="""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""")
-    advanced.add_argument(
-        '--exclude',
-        metavar='<directory>',
-        dest='excludes',
-        action='append',
-        default=[],
-        help="""Do not run static analyzer against files found in this
-                directory. (You can specify this option multiple times.)
-                Could be usefull when project contains 3rd party libraries.
-                The directory path shall be absolute path as file names in
-                the compilation database.""")
-    advanced.add_argument(
-        '--force-analyze-debug-code',
-        dest='force_debug',
-        action='store_true',
-        help="""Tells analyzer to enable assertions in code even if they were
-                disabled during compilation, enabling more precise results.""")
-
-    plugins = parser.add_argument_group('checker options')
-    plugins.add_argument(
-        '--load-plugin', '-load-plugin',
-        metavar='<plugin library>',
-        dest='plugins',
-        action='append',
-        help="""Loading external checkers using the clang plugin interface.""")
-    plugins.add_argument(
-        '--enable-checker', '-enable-checker',
-        metavar='<checker name>',
-        action=AppendCommaSeparated,
-        help="""Enable specific checker.""")
-    plugins.add_argument(
-        '--disable-checker', '-disable-checker',
-        metavar='<checker name>',
-        action=AppendCommaSeparated,
-        help="""Disable specific checker.""")
-    plugins.add_argument(
-        '--help-checkers',
-        action='store_true',
-        help="""A default group of checkers is run unless explicitly disabled.
-                Exactly which checkers constitute the default group is a
-                function of the operating system in use. These can be printed
-                with this flag.""")
-    plugins.add_argument(
-        '--help-checkers-verbose',
-        action='store_true',
-        help="""Print all available checkers and mark the enabled ones.""")
-
-    if from_build_command:
-        parser.add_argument(
-            dest='build',
-            nargs=argparse.REMAINDER,
-            help="""Command to run.""")
-
-    return parser
-
-
-class AppendCommaSeparated(argparse.Action):
-    """ argparse Action class to support multiple comma separated lists. """
-
-    def __call__(self, __parser, namespace, values, __option_string):
-        # getattr(obj, attr, default) does not really returns default but none
-        if getattr(namespace, self.dest, None) is None:
-            setattr(namespace, self.dest, [])
-        # once it's fixed we can use as expected
-        actual = getattr(namespace, self.dest)
-        actual.extend(values.split(','))
-        setattr(namespace, self.dest, actual)
diff --git a/tools/scan-build-py/libscanbuild/arguments.py b/tools/scan-build-py/libscanbuild/arguments.py
new file mode 100644
index 0000000..fe5725d
--- /dev/null
+++ b/tools/scan-build-py/libscanbuild/arguments.py
@@ -0,0 +1,430 @@
+# -*- coding: utf-8 -*-
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+""" This module parses and validates arguments for command-line interfaces.
+
+It uses argparse module to create the command line parser. (This library is
+in the standard python library since 3.2 and backported to 2.7, but not
+earlier.)
+
+It also implements basic validation methods, related to the command.
+Validations are mostly calling specific help methods, or mangling values.
+"""
+
+import os
+import sys
+import argparse
+import logging
+from libscanbuild import reconfigure_logging, tempdir
+from libscanbuild.clang import get_checkers
+
+__all__ = ['parse_args_for_intercept_build', 'parse_args_for_analyze_build',
+           'parse_args_for_scan_build']
+
+
+def parse_args_for_intercept_build():
+    """ Parse and validate command-line arguments for intercept-build. """
+
+    parser = create_intercept_parser()
+    args = parser.parse_args()
+
+    reconfigure_logging(args.verbose)
+    logging.debug('Raw arguments %s', sys.argv)
+
+    # short validation logic
+    if not args.build:
+        parser.error(message='missing build command')
+
+    logging.debug('Parsed arguments: %s', args)
+    return args
+
+
+def parse_args_for_analyze_build():
+    """ Parse and validate command-line arguments for analyze-build. """
+
+    from_build_command = False
+    parser = create_analyze_parser(from_build_command)
+    args = parser.parse_args()
+
+    reconfigure_logging(args.verbose)
+    logging.debug('Raw arguments %s', sys.argv)
+
+    normalize_args_for_analyze(args, from_build_command)
+    validate_args_for_analyze(parser, args, from_build_command)
+    logging.debug('Parsed arguments: %s', args)
+    return args
+
+
+def parse_args_for_scan_build():
+    """ Parse and validate command-line arguments for scan-build. """
+
+    from_build_command = True
+    parser = create_analyze_parser(from_build_command)
+    args = parser.parse_args()
+
+    reconfigure_logging(args.verbose)
+    logging.debug('Raw arguments %s', sys.argv)
+
+    normalize_args_for_analyze(args, from_build_command)
+    validate_args_for_analyze(parser, args, from_build_command)
+    logging.debug('Parsed arguments: %s', args)
+    return args
+
+
+def normalize_args_for_analyze(args, from_build_command):
+    """ Normalize parsed arguments for analyze-build and scan-build.
+
+    :param args: Parsed argument object. (Will be mutated.)
+    :param from_build_command: Boolean value tells is the command suppose
+    to run the analyzer against a build command or a compilation db. """
+
+    # make plugins always a list. (it might be None when not specified.)
+    if args.plugins is None:
+        args.plugins = []
+
+    # make exclude directory list unique and absolute.
+    uniq_excludes = set(os.path.abspath(entry) for entry in args.excludes)
+    args.excludes = list(uniq_excludes)
+
+    # because shared codes for all tools, some common used methods are
+    # expecting some argument to be present. so, instead of query the args
+    # object about the presence of the flag, we fake it here. to make those
+    # methods more readable. (it's an arguable choice, took it only for those
+    # which have good default value.)
+    if from_build_command:
+        # add cdb parameter invisibly to make report module working.
+        args.cdb = 'compile_commands.json'
+
+
+def validate_args_for_analyze(parser, args, from_build_command):
+    """ Command line parsing is done by the argparse module, but semantic
+    validation still needs to be done. This method is doing it for
+    analyze-build and scan-build commands.
+
+    :param parser: The command line parser object.
+    :param args: Parsed argument object.
+    :param from_build_command: Boolean value tells is the command suppose
+    to run the analyzer against a build command or a compilation db.
+    :return: No return value, but this call might throw when validation
+    fails. """
+
+    if args.help_checkers_verbose:
+        print_checkers(get_checkers(args.clang, args.plugins))
+        parser.exit(status=0)
+    elif args.help_checkers:
+        print_active_checkers(get_checkers(args.clang, args.plugins))
+        parser.exit(status=0)
+    elif from_build_command and not args.build:
+        parser.error(message='missing build command')
+    elif not from_build_command and not os.path.exists(args.cdb):
+        parser.error(message='compilation database is missing')
+
+
+def create_intercept_parser():
+    """ Creates a parser for command-line arguments to 'intercept'. """
+
+    parser = create_default_parser()
+    parser_add_cdb(parser)
+
+    parser_add_prefer_wrapper(parser)
+    parser_add_compilers(parser)
+
+    advanced = parser.add_argument_group('advanced options')
+    group = advanced.add_mutually_exclusive_group()
+    group.add_argument(
+        '--append',
+        action='store_true',
+        help="""Extend existing compilation database with new entries.
+        Duplicate entries are detected and not present in the final output.
+        The output is not continuously updated, it's done when the build
+        command finished. """)
+
+    parser.add_argument(
+        dest='build', nargs=argparse.REMAINDER, help="""Command to run.""")
+    return parser
+
+
+def create_analyze_parser(from_build_command):
+    """ Creates a parser for command-line arguments to 'analyze'. """
+
+    parser = create_default_parser()
+
+    if from_build_command:
+        parser_add_prefer_wrapper(parser)
+        parser_add_compilers(parser)
+
+        parser.add_argument(
+            '--intercept-first',
+            action='store_true',
+            help="""Run the build commands first, intercept compiler
+            calls and then run the static analyzer afterwards.
+            Generally speaking it has better coverage on build commands.
+            With '--override-compiler' it use compiler wrapper, but does
+            not run the analyzer till the build is finished.""")
+    else:
+        parser_add_cdb(parser)
+
+    parser.add_argument(
+        '--status-bugs',
+        action='store_true',
+        help="""The exit status of '%(prog)s' is the same as the executed
+        build command. This option ignores the build exit status and sets to
+        be non zero if it found potential bugs or zero otherwise.""")
+    parser.add_argument(
+        '--exclude',
+        metavar='<directory>',
+        dest='excludes',
+        action='append',
+        default=[],
+        help="""Do not run static analyzer against files found in this
+        directory. (You can specify this option multiple times.)
+        Could be useful when project contains 3rd party libraries.""")
+
+    output = parser.add_argument_group('output control options')
+    output.add_argument(
+        '--output',
+        '-o',
+        metavar='<path>',
+        default=tempdir(),
+        help="""Specifies the output directory for analyzer reports.
+        Subdirectory will be created if default directory is targeted.""")
+    output.add_argument(
+        '--keep-empty',
+        action='store_true',
+        help="""Don't remove the build results directory even if no issues
+        were reported.""")
+    output.add_argument(
+        '--html-title',
+        metavar='<title>',
+        help="""Specify the title used on generated HTML pages.
+        If not specified, a default title will be used.""")
+    format_group = output.add_mutually_exclusive_group()
+    format_group.add_argument(
+        '--plist',
+        '-plist',
+        dest='output_format',
+        const='plist',
+        default='html',
+        action='store_const',
+        help="""Cause the results as a set of .plist files.""")
+    format_group.add_argument(
+        '--plist-html',
+        '-plist-html',
+        dest='output_format',
+        const='plist-html',
+        default='html',
+        action='store_const',
+        help="""Cause the results as a set of .html and .plist files.""")
+    # TODO: implement '-view '
+
+    advanced = parser.add_argument_group('advanced options')
+    advanced.add_argument(
+        '--use-analyzer',
+        metavar='<path>',
+        dest='clang',
+        default='clang',
+        help="""'%(prog)s' uses the 'clang' executable relative to itself for
+        static analysis. One can override this behavior with this option by
+        using the 'clang' packaged with Xcode (on OS X) or from the PATH.""")
+    advanced.add_argument(
+        '--no-failure-reports',
+        '-no-failure-reports',
+        dest='output_failures',
+        action='store_false',
+        help="""Do not create a 'failures' subdirectory that includes analyzer
+        crash reports and preprocessed source files.""")
+    parser.add_argument(
+        '--analyze-headers',
+        action='store_true',
+        help="""Also analyze functions in #included files. By default, such
+        functions are skipped unless they are called by functions within the
+        main source file.""")
+    advanced.add_argument(
+        '--stats',
+        '-stats',
+        action='store_true',
+        help="""Generates visitation statistics for the project.""")
+    advanced.add_argument(
+        '--internal-stats',
+        action='store_true',
+        help="""Generate internal analyzer statistics.""")
+    advanced.add_argument(
+        '--maxloop',
+        '-maxloop',
+        metavar='<loop count>',
+        type=int,
+        help="""Specifiy the number of times a block can be visited before
+        giving up. Increase for more comprehensive coverage at a cost of
+        speed.""")
+    advanced.add_argument(
+        '--store',
+        '-store',
+        metavar='<model>',
+        dest='store_model',
+        choices=['region', 'basic'],
+        help="""Specify the store model used by the analyzer. 'region'
+        specifies a field- sensitive store model. 'basic' which is far less
+        precise but can more quickly analyze code. 'basic' was the default
+        store model for checker-0.221 and earlier.""")
+    advanced.add_argument(
+        '--constraints',
+        '-constraints',
+        metavar='<model>',
+        dest='constraints_model',
+        choices=['range', 'basic'],
+        help="""Specify the constraint engine used by the analyzer. Specifying
+        'basic' uses a simpler, less powerful constraint model used by
+        checker-0.160 and earlier.""")
+    advanced.add_argument(
+        '--analyzer-config',
+        '-analyzer-config',
+        metavar='<options>',
+        help="""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""")
+    advanced.add_argument(
+        '--force-analyze-debug-code',
+        dest='force_debug',
+        action='store_true',
+        help="""Tells analyzer to enable assertions in code even if they were
+        disabled during compilation, enabling more precise results.""")
+
+    plugins = parser.add_argument_group('checker options')
+    plugins.add_argument(
+        '--load-plugin',
+        '-load-plugin',
+        metavar='<plugin library>',
+        dest='plugins',
+        action='append',
+        help="""Loading external checkers using the clang plugin interface.""")
+    plugins.add_argument(
+        '--enable-checker',
+        '-enable-checker',
+        metavar='<checker name>',
+        action=AppendCommaSeparated,
+        help="""Enable specific checker.""")
+    plugins.add_argument(
+        '--disable-checker',
+        '-disable-checker',
+        metavar='<checker name>',
+        action=AppendCommaSeparated,
+        help="""Disable specific checker.""")
+    plugins.add_argument(
+        '--help-checkers',
+        action='store_true',
+        help="""A default group of checkers is run unless explicitly disabled.
+        Exactly which checkers constitute the default group is a function of
+        the operating system in use. These can be printed with this flag.""")
+    plugins.add_argument(
+        '--help-checkers-verbose',
+        action='store_true',
+        help="""Print all available checkers and mark the enabled ones.""")
+
+    if from_build_command:
+        parser.add_argument(
+            dest='build', nargs=argparse.REMAINDER, help="""Command to run.""")
+    return parser
+
+
+def create_default_parser():
+    """ Creates command line parser for all build wrapper commands. """
+
+    parser = argparse.ArgumentParser(
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+
+    parser.add_argument(
+        '--verbose',
+        '-v',
+        action='count',
+        default=0,
+        help="""Enable verbose output from '%(prog)s'. A second, third and
+        fourth flags increases verbosity.""")
+    return parser
+
+
+def parser_add_cdb(parser):
+    parser.add_argument(
+        '--cdb',
+        metavar='<file>',
+        default="compile_commands.json",
+        help="""The JSON compilation database.""")
+
+
+def parser_add_prefer_wrapper(parser):
+    parser.add_argument(
+        '--override-compiler',
+        action='store_true',
+        help="""Always resort to the compiler wrapper even when better
+        intercept methods are available.""")
+
+
+def parser_add_compilers(parser):
+    parser.add_argument(
+        '--use-cc',
+        metavar='<path>',
+        dest='cc',
+        default=os.getenv('CC', 'cc'),
+        help="""When '%(prog)s' analyzes a project by interposing a compiler
+        wrapper, which executes a real compiler for compilation and do other
+        tasks (record the compiler invocation). Because of this interposing,
+        '%(prog)s' does not know what compiler your project normally uses.
+        Instead, it simply overrides the CC environment variable, and guesses
+        your default compiler.
+
+        If you need '%(prog)s' to use a specific compiler for *compilation*
+        then you can use this option to specify a path to that compiler.""")
+    parser.add_argument(
+        '--use-c++',
+        metavar='<path>',
+        dest='cxx',
+        default=os.getenv('CXX', 'c++'),
+        help="""This is the same as "--use-cc" but for C++ code.""")
+
+
+class AppendCommaSeparated(argparse.Action):
+    """ argparse Action class to support multiple comma separated lists. """
+
+    def __call__(self, __parser, namespace, values, __option_string):
+        # getattr(obj, attr, default) does not really returns default but none
+        if getattr(namespace, self.dest, None) is None:
+            setattr(namespace, self.dest, [])
+        # once it's fixed we can use as expected
+        actual = getattr(namespace, self.dest)
+        actual.extend(values.split(','))
+        setattr(namespace, self.dest, actual)
+
+
+def print_active_checkers(checkers):
+    """ Print active checkers to stdout. """
+
+    for name in sorted(name for name, (_, active) in checkers.items()
+                       if active):
+        print(name)
+
+
+def print_checkers(checkers):
+    """ Print verbose checker help to stdout. """
+
+    print('')
+    print('available checkers:')
+    print('')
+    for name in sorted(checkers.keys()):
+        description, active = checkers[name]
+        prefix = '+' if active else ' '
+        if len(name) > 30:
+            print(' {0} {1}'.format(prefix, name))
+            print(' ' * 35 + description)
+        else:
+            print(' {0} {1: <30}  {2}'.format(prefix, name, description))
+    print('')
+    print('NOTE: "+" indicates that an analysis is enabled by default.')
+    print('')
diff --git a/tools/scan-build-py/libscanbuild/clang.py b/tools/scan-build-py/libscanbuild/clang.py
index 833e77d..192e708 100644
--- a/tools/scan-build-py/libscanbuild/clang.py
+++ b/tools/scan-build-py/libscanbuild/clang.py
@@ -9,8 +9,7 @@
 a subset of that, it makes sense to create a function specific wrapper. """
 
 import re
-import subprocess
-import logging
+from libscanbuild import run_command
 from libscanbuild.shell import decode
 
 __all__ = ['get_version', 'get_arguments', 'get_checkers']
@@ -25,8 +24,9 @@
     :param clang:   the compiler we are using
     :return:        the version string printed to stderr """
 
-    output = subprocess.check_output([clang, '-v'], stderr=subprocess.STDOUT)
-    return output.decode('utf-8').splitlines()[0]
+    output = run_command([clang, '-v'])
+    # the relevant version info is in the first line
+    return output[0]
 
 
 def get_arguments(command, cwd):
@@ -38,12 +38,11 @@
 
     cmd = command[:]
     cmd.insert(1, '-###')
-    logging.debug('exec command in %s: %s', cwd, ' '.join(cmd))
 
-    output = subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT)
+    output = run_command(cmd, cwd=cwd)
     # The relevant information is in the last line of the output.
     # Don't check if finding last line fails, would throw exception anyway.
-    last_line = output.decode('utf-8').splitlines()[-1]
+    last_line = output[-1]
     if re.search(r'clang(.*): error:', last_line):
         raise Exception(last_line)
     return decode(last_line)
@@ -141,9 +140,7 @@
     load = [elem for plugin in plugins for elem in ['-load', plugin]]
     cmd = [clang, '-cc1'] + load + ['-analyzer-checker-help']
 
-    logging.debug('exec command: %s', ' '.join(cmd))
-    output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
-    lines = output.decode('utf-8').splitlines()
+    lines = run_command(cmd)
 
     is_active_checker = is_active(get_active_checkers(clang, plugins))
 
diff --git a/tools/scan-build-py/libscanbuild/intercept.py b/tools/scan-build-py/libscanbuild/intercept.py
index 6a9f753..71b957d 100644
--- a/tools/scan-build-py/libscanbuild/intercept.py
+++ b/tools/scan-build-py/libscanbuild/intercept.py
@@ -27,16 +27,16 @@
 import itertools
 import json
 import glob
-import argparse
 import logging
-import subprocess
 from libear import build_libear, TemporaryDirectory
-from libscanbuild import command_entry_point
-from libscanbuild import duplicate_check, tempdir, initialize_logging
+from libscanbuild import command_entry_point, compiler_wrapper, \
+    wrapper_environment, run_command, run_build
+from libscanbuild import duplicate_check, tempdir
 from libscanbuild.compilation import split_command
+from libscanbuild.arguments import parse_args_for_intercept_build
 from libscanbuild.shell import encode, decode
 
-__all__ = ['capture', 'intercept_build_main', 'intercept_build_wrapper']
+__all__ = ['capture', 'intercept_build', 'intercept_compiler_wrapper']
 
 GS = chr(0x1d)
 RS = chr(0x1e)
@@ -44,26 +44,19 @@
 
 COMPILER_WRAPPER_CC = 'intercept-cc'
 COMPILER_WRAPPER_CXX = 'intercept-c++'
+TRACE_FILE_EXTENSION = '.cmd'  # same as in ear.c
+WRAPPER_ONLY_PLATFORMS = frozenset({'win32', 'cygwin'})
 
 
 @command_entry_point
-def intercept_build_main(bin_dir):
+def intercept_build():
     """ Entry point for 'intercept-build' command. """
 
-    parser = create_parser()
-    args = parser.parse_args()
-
-    initialize_logging(args.verbose)
-    logging.debug('Parsed arguments: %s', args)
-
-    if not args.build:
-        parser.print_help()
-        return 0
-
-    return capture(args, bin_dir)
+    args = parse_args_for_intercept_build()
+    return capture(args)
 
 
-def capture(args, bin_dir):
+def capture(args):
     """ The entry point of build command interception. """
 
     def post_processing(commands):
@@ -93,26 +86,21 @@
 
     with TemporaryDirectory(prefix='intercept-', dir=tempdir()) as tmp_dir:
         # run the build command
-        environment = setup_environment(args, tmp_dir, bin_dir)
-        logging.debug('run build in environment: %s', environment)
-        exit_code = subprocess.call(args.build, env=environment)
-        logging.info('build finished with exit code: %d', exit_code)
+        environment = setup_environment(args, tmp_dir)
+        exit_code = run_build(args.build, env=environment)
         # read the intercepted exec calls
         exec_traces = itertools.chain.from_iterable(
             parse_exec_trace(os.path.join(tmp_dir, filename))
             for filename in sorted(glob.iglob(os.path.join(tmp_dir, '*.cmd'))))
-        # do post processing only if that was requested
-        if 'raw_entries' not in args or not args.raw_entries:
-            entries = post_processing(exec_traces)
-        else:
-            entries = exec_traces
+        # do post processing
+        entries = post_processing(exec_traces)
         # dump the compilation database
         with open(args.cdb, 'w+') as handle:
             json.dump(list(entries), handle, sort_keys=True, indent=4)
         return exit_code
 
 
-def setup_environment(args, destination, bin_dir):
+def setup_environment(args, destination):
     """ Sets up the environment for the build command.
 
     It sets the required environment variables and execute the given command.
@@ -130,12 +118,10 @@
 
     if not libear_path:
         logging.debug('intercept gonna use compiler wrappers')
+        environment.update(wrapper_environment(args))
         environment.update({
-            'CC': os.path.join(bin_dir, COMPILER_WRAPPER_CC),
-            'CXX': os.path.join(bin_dir, COMPILER_WRAPPER_CXX),
-            'INTERCEPT_BUILD_CC': c_compiler,
-            'INTERCEPT_BUILD_CXX': cxx_compiler,
-            'INTERCEPT_BUILD_VERBOSE': 'DEBUG' if args.verbose > 2 else 'INFO'
+            'CC': COMPILER_WRAPPER_CC,
+            'CXX': COMPILER_WRAPPER_CXX
         })
     elif sys.platform == 'darwin':
         logging.debug('intercept gonna preload libear on OSX')
@@ -150,42 +136,49 @@
     return environment
 
 
-def intercept_build_wrapper(cplusplus):
-    """ Entry point for `intercept-cc` and `intercept-c++` compiler wrappers.
+@command_entry_point
+def intercept_compiler_wrapper():
+    """ Entry point for `intercept-cc` and `intercept-c++`. """
 
-    It does generate execution report into target directory. And execute
-    the wrapped compilation with the real compiler. The parameters for
-    report and execution are from environment variables.
+    return compiler_wrapper(intercept_compiler_wrapper_impl)
 
-    Those parameters which for 'libear' library can't have meaningful
-    values are faked. """
 
-    # initialize wrapper logging
-    logging.basicConfig(format='intercept: %(levelname)s: %(message)s',
-                        level=os.getenv('INTERCEPT_BUILD_VERBOSE', 'INFO'))
-    # write report
+def intercept_compiler_wrapper_impl(_, execution):
+    """ Implement intercept compiler wrapper functionality.
+
+    It does generate execution report into target directory.
+    The target directory name is from environment variables. """
+
+    message_prefix = 'execution report might be incomplete: %s'
+
+    target_dir = os.getenv('INTERCEPT_BUILD_TARGET_DIR')
+    if not target_dir:
+        logging.warning(message_prefix, 'missing target directory')
+        return
+    # write current execution info to the pid file
     try:
-        target_dir = os.getenv('INTERCEPT_BUILD_TARGET_DIR')
-        if not target_dir:
-            raise UserWarning('exec report target directory not found')
-        pid = str(os.getpid())
-        target_file = os.path.join(target_dir, pid + '.cmd')
-        logging.debug('writing exec report to: %s', target_file)
-        with open(target_file, 'ab') as handler:
-            working_dir = os.getcwd()
-            command = US.join(sys.argv) + US
-            content = RS.join([pid, pid, 'wrapper', working_dir, command]) + GS
-            handler.write(content.encode('utf-8'))
+        target_file_name = str(os.getpid()) + TRACE_FILE_EXTENSION
+        target_file = os.path.join(target_dir, target_file_name)
+        logging.debug('writing execution report to: %s', target_file)
+        write_exec_trace(target_file, execution)
     except IOError:
-        logging.exception('writing exec report failed')
-    except UserWarning as warning:
-        logging.warning(warning)
-    # execute with real compiler
-    compiler = os.getenv('INTERCEPT_BUILD_CXX', 'c++') if cplusplus \
-        else os.getenv('INTERCEPT_BUILD_CC', 'cc')
-    compilation = [compiler] + sys.argv[1:]
-    logging.debug('execute compiler: %s', compilation)
-    return subprocess.call(compilation)
+        logging.warning(message_prefix, 'io problem')
+
+
+def write_exec_trace(filename, entry):
+    """ Write execution report file.
+
+    This method shall be sync with the execution report writer in interception
+    library. The entry in the file is a JSON objects.
+
+    :param filename:    path to the output execution trace file,
+    :param entry:       the Execution object to append to that file. """
+
+    with open(filename, 'ab') as handler:
+        pid = str(entry.pid)
+        command = US.join(entry.cmd) + US
+        content = RS.join([pid, pid, 'wrapper', entry.cwd, command]) + GS
+        handler.write(content.encode('utf-8'))
 
 
 def parse_exec_trace(filename):
@@ -238,24 +231,21 @@
     the path and, if so, (2) whether the output of executing 'csrutil status'
     contains 'System Integrity Protection status: enabled'.
 
-    Same problem on linux when SELinux is enabled. The status query program
-    'sestatus' and the output when it's enabled 'SELinux status: enabled'. """
+    :param platform: name of the platform (returned by sys.platform),
+    :return: True if library preload will fail by the dynamic linker. """
 
-    if platform == 'darwin':
-        pattern = re.compile(r'System Integrity Protection status:\s+enabled')
+    if platform in WRAPPER_ONLY_PLATFORMS:
+        return True
+    elif platform == 'darwin':
         command = ['csrutil', 'status']
-    elif platform in {'linux', 'linux2'}:
-        pattern = re.compile(r'SELinux status:\s+enabled')
-        command = ['sestatus']
+        pattern = re.compile(r'System Integrity Protection status:\s+enabled')
+        try:
+            return any(pattern.match(line) for line in run_command(command))
+        except:
+            return False
     else:
         return False
 
-    try:
-        lines = subprocess.check_output(command).decode('utf-8')
-        return any((pattern.match(line) for line in lines.splitlines()))
-    except:
-        return False
-
 
 def entry_hash(entry):
     """ Implement unique hash method for compilation database entries. """
@@ -271,69 +261,3 @@
     command = ' '.join(decode(entry['command'])[1:])
 
     return '<>'.join([filename, directory, command])
-
-
-def create_parser():
-    """ Command line argument parser factory method. """
-
-    parser = argparse.ArgumentParser(
-        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
-
-    parser.add_argument(
-        '--verbose', '-v',
-        action='count',
-        default=0,
-        help="""Enable verbose output from '%(prog)s'. A second and third
-                flag increases verbosity.""")
-    parser.add_argument(
-        '--cdb',
-        metavar='<file>',
-        default="compile_commands.json",
-        help="""The JSON compilation database.""")
-    group = parser.add_mutually_exclusive_group()
-    group.add_argument(
-        '--append',
-        action='store_true',
-        help="""Append new entries to existing compilation database.""")
-    group.add_argument(
-        '--disable-filter', '-n',
-        dest='raw_entries',
-        action='store_true',
-        help="""Intercepted child process creation calls (exec calls) are all
-                logged to the output. The output is not a compilation database.
-                This flag is for debug purposes.""")
-
-    advanced = parser.add_argument_group('advanced options')
-    advanced.add_argument(
-        '--override-compiler',
-        action='store_true',
-        help="""Always resort to the compiler wrapper even when better
-                intercept methods are available.""")
-    advanced.add_argument(
-        '--use-cc',
-        metavar='<path>',
-        dest='cc',
-        default='cc',
-        help="""When '%(prog)s' analyzes a project by interposing a compiler
-                wrapper, which executes a real compiler for compilation and
-                do other tasks (record the compiler invocation). Because of
-                this interposing, '%(prog)s' does not know what compiler your
-                project normally uses. Instead, it simply overrides the CC
-                environment variable, and guesses your default compiler.
-
-                If you need '%(prog)s' to use a specific compiler for
-                *compilation* then you can use this option to specify a path
-                to that compiler.""")
-    advanced.add_argument(
-        '--use-c++',
-        metavar='<path>',
-        dest='cxx',
-        default='c++',
-        help="""This is the same as "--use-cc" but for C++ code.""")
-
-    parser.add_argument(
-        dest='build',
-        nargs=argparse.REMAINDER,
-        help="""Command to run.""")
-
-    return parser
diff --git a/tools/scan-build-py/libscanbuild/report.py b/tools/scan-build-py/libscanbuild/report.py
index 766ddef..0817009 100644
--- a/tools/scan-build-py/libscanbuild/report.py
+++ b/tools/scan-build-py/libscanbuild/report.py
@@ -13,54 +13,15 @@
 import os.path
 import sys
 import shutil
-import time
-import tempfile
 import itertools
 import plistlib
 import glob
 import json
 import logging
-import contextlib
-import datetime
 from libscanbuild import duplicate_check
 from libscanbuild.clang import get_version
 
-__all__ = ['report_directory', 'document']
-
-
-@contextlib.contextmanager
-def report_directory(hint, keep):
-    """ Responsible for the report directory.
-
-    hint -- could specify the parent directory of the output directory.
-    keep -- a boolean value to keep or delete the empty report directory. """
-
-    stamp_format = 'scan-build-%Y-%m-%d-%H-%M-%S-%f-'
-    stamp = datetime.datetime.now().strftime(stamp_format)
-
-    parentdir = os.path.abspath(hint)
-    if not os.path.exists(parentdir):
-        os.makedirs(parentdir)
-
-    name = tempfile.mkdtemp(prefix=stamp, dir=parentdir)
-
-    logging.info('Report directory created: %s', name)
-
-    try:
-        yield name
-    finally:
-        if os.listdir(name):
-            msg = "Run 'scan-view %s' to examine bug reports."
-            keep = True
-        else:
-            if keep:
-                msg = "Report directory '%s' contans no report, but kept."
-            else:
-                msg = "Removing directory '%s' because it contains no report."
-        logging.warning(msg, name)
-
-        if not keep:
-            os.rmdir(name)
+__all__ = ['document']
 
 
 def document(args, output_dir, use_cdb):
@@ -375,11 +336,12 @@
 
     match = re.match(r'(.*)\.info\.txt', filename)
     name = match.group(1) if match else None
-    with open(filename) as handler:
-        lines = handler.readlines()
+    with open(filename, mode='rb') as handler:
+        # this is a workaround to fix windows read '\r\n' as new lines.
+        lines = [line.decode().rstrip() for line in handler.readlines()]
         return {
-            'source': lines[0].rstrip(),
-            'problem': lines[1].rstrip(),
+            'source': lines[0],
+            'problem': lines[1],
             'file': name,
             'info': name + '.info.txt',
             'stderr': name + '.stderr.txt'
diff --git a/tools/scan-build-py/libscanbuild/runner.py b/tools/scan-build-py/libscanbuild/runner.py
index 72d02c8..014b872 100644
--- a/tools/scan-build-py/libscanbuild/runner.py
+++ b/tools/scan-build-py/libscanbuild/runner.py
@@ -12,6 +12,7 @@
 import functools
 import subprocess
 import logging
+from libscanbuild import run_command
 from libscanbuild.compilation import classify_source, compiler_language
 from libscanbuild.clang import get_version, get_arguments
 from libscanbuild.shell import decode
@@ -100,7 +101,7 @@
 
 
 @require(['clang', 'directory', 'flags', 'file', 'output_dir', 'language',
-          'error_type', 'error_output', 'exit_code'])
+          'error_output', 'exit_code'])
 def report_failure(opts):
     """ Create report when analyzer failed.
 
@@ -108,30 +109,36 @@
     randomly. The compiler output also captured into '.stderr.txt' file.
     And some more execution context also saved into '.info.txt' file. """
 
-    def extension(opts):
+    def extension():
         """ Generate preprocessor file extension. """
 
         mapping = {'objective-c++': '.mii', 'objective-c': '.mi', 'c++': '.ii'}
         return mapping.get(opts['language'], '.i')
 
-    def destination(opts):
+    def destination():
         """ Creates failures directory if not exits yet. """
 
-        name = os.path.join(opts['output_dir'], 'failures')
-        if not os.path.isdir(name):
-            os.makedirs(name)
-        return name
+        failures_dir = os.path.join(opts['output_dir'], 'failures')
+        if not os.path.isdir(failures_dir):
+            os.makedirs(failures_dir)
+        return failures_dir
 
-    error = opts['error_type']
-    (handle, name) = tempfile.mkstemp(suffix=extension(opts),
+    # Classify error type: when Clang terminated by a signal it's a 'Crash'.
+    # (python subprocess Popen.returncode is negative when child terminated
+    # by signal.) Everything else is 'Other Error'.
+    error = 'crash' if opts['exit_code'] < 0 else 'other_error'
+    # Create preprocessor output file name. (This is blindly following the
+    # Perl implementation.)
+    (handle, name) = tempfile.mkstemp(suffix=extension(),
                                       prefix='clang_' + error + '_',
-                                      dir=destination(opts))
+                                      dir=destination())
     os.close(handle)
+    # Execute Clang again, but run the syntax check only.
     cwd = opts['directory']
-    cmd = get_arguments([opts['clang'], '-fsyntax-only', '-E'] +
-                        opts['flags'] + [opts['file'], '-o', name], cwd)
-    logging.debug('exec command in %s: %s', cwd, ' '.join(cmd))
-    subprocess.call(cmd, cwd=cwd)
+    cmd = get_arguments(
+        [opts['clang'], '-fsyntax-only', '-E'
+         ] + opts['flags'] + [opts['file'], '-o', name], cwd)
+    run_command(cmd, cwd=cwd)
     # write general information about the crash
     with open(name + '.info.txt', 'w') as handle:
         handle.write(opts['file'] + os.linesep)
@@ -144,11 +151,6 @@
     with open(name + '.stderr.txt', 'w') as handle:
         handle.writelines(opts['error_output'])
         handle.close()
-    # return with the previous step exit code and output
-    return {
-        'error_output': opts['error_output'],
-        'exit_code': opts['exit_code']
-    }
 
 
 @require(['clang', 'directory', 'flags', 'direct_args', 'file', 'output_dir',
@@ -158,7 +160,7 @@
     output of the analysis and returns with it. If failure reports are
     requested, it calls the continuation to generate it. """
 
-    def output():
+    def target():
         """ Creates output file name for reports. """
         if opts['output_format'] in {'plist', 'plist-html'}:
             (handle, name) = tempfile.mkstemp(prefix='report-',
@@ -168,30 +170,20 @@
             return name
         return opts['output_dir']
 
-    cwd = opts['directory']
-    cmd = get_arguments([opts['clang'], '--analyze'] + opts['direct_args'] +
-                        opts['flags'] + [opts['file'], '-o', output()],
-                        cwd)
-    logging.debug('exec command in %s: %s', cwd, ' '.join(cmd))
-    child = subprocess.Popen(cmd,
-                             cwd=cwd,
-                             universal_newlines=True,
-                             stdout=subprocess.PIPE,
-                             stderr=subprocess.STDOUT)
-    output = child.stdout.readlines()
-    child.stdout.close()
-    # do report details if it were asked
-    child.wait()
-    if opts.get('output_failures', False) and child.returncode:
-        error_type = 'crash' if child.returncode & 127 else 'other_error'
-        opts.update({
-            'error_type': error_type,
-            'error_output': output,
-            'exit_code': child.returncode
-        })
-        return continuation(opts)
-    # return the output for logging and exit code for testing
-    return {'error_output': output, 'exit_code': child.returncode}
+    try:
+        cwd = opts['directory']
+        cmd = get_arguments([opts['clang'], '--analyze'] +
+                            opts['direct_args'] + opts['flags'] +
+                            [opts['file'], '-o', target()],
+                            cwd)
+        output = run_command(cmd, cwd=cwd)
+        return {'error_output': output, 'exit_code': 0}
+    except subprocess.CalledProcessError as ex:
+        result = {'error_output': ex.output, 'exit_code': ex.returncode}
+        if opts.get('output_failures', False):
+            opts.update(result)
+            continuation(opts)
+        return result
 
 
 @require(['flags', 'force_debug'])
diff --git a/tools/scan-build-py/tests/unit/test_analyze.py b/tools/scan-build-py/tests/unit/test_analyze.py
index 481cc0c..5cfc121 100644
--- a/tools/scan-build-py/tests/unit/test_analyze.py
+++ b/tools/scan-build-py/tests/unit/test_analyze.py
@@ -4,4 +4,19 @@
 # This file is distributed under the University of Illinois Open Source
 # License. See LICENSE.TXT for details.
 
+import libear
 import libscanbuild.analyze as sut
+import unittest
+
+class ReportDirectoryTest(unittest.TestCase):
+
+    # Test that successive report directory names ascend in lexicographic
+    # order. This is required so that report directories from two runs of
+    # scan-build can be easily matched up to compare results.
+    def test_directory_name_comparison(self):
+        with libear.TemporaryDirectory() as tmpdir, \
+             sut.report_directory(tmpdir, False) as report_dir1, \
+             sut.report_directory(tmpdir, False) as report_dir2, \
+             sut.report_directory(tmpdir, False) as report_dir3:
+            self.assertLess(report_dir1, report_dir2)
+            self.assertLess(report_dir2, report_dir3)
diff --git a/tools/scan-build-py/tests/unit/test_intercept.py b/tools/scan-build-py/tests/unit/test_intercept.py
index 5b6ed2c..583d1c3 100644
--- a/tools/scan-build-py/tests/unit/test_intercept.py
+++ b/tools/scan-build-py/tests/unit/test_intercept.py
@@ -65,11 +65,10 @@
         DISABLED = 'disabled'
 
         OSX = 'darwin'
-        LINUX = 'linux'
 
         with libear.TemporaryDirectory() as tmpdir:
+            saved = os.environ['PATH']
             try:
-                saved = os.environ['PATH']
                 os.environ['PATH'] = tmpdir + ':' + saved
 
                 create_csrutil(tmpdir, ENABLED)
@@ -77,21 +76,14 @@
 
                 create_csrutil(tmpdir, DISABLED)
                 self.assertFalse(sut.is_preload_disabled(OSX))
-
-                create_sestatus(tmpdir, ENABLED)
-                self.assertTrue(sut.is_preload_disabled(LINUX))
-
-                create_sestatus(tmpdir, DISABLED)
-                self.assertFalse(sut.is_preload_disabled(LINUX))
             finally:
                 os.environ['PATH'] = saved
 
+        saved = os.environ['PATH']
         try:
-            saved = os.environ['PATH']
             os.environ['PATH'] = ''
             # shall be false when it's not in the path
             self.assertFalse(sut.is_preload_disabled(OSX))
-            self.assertFalse(sut.is_preload_disabled(LINUX))
 
             self.assertFalse(sut.is_preload_disabled('unix'))
         finally:
diff --git a/tools/scan-build-py/tests/unit/test_report.py b/tools/scan-build-py/tests/unit/test_report.py
index c82b559..3f249ce 100644
--- a/tools/scan-build-py/tests/unit/test_report.py
+++ b/tools/scan-build-py/tests/unit/test_report.py
@@ -146,16 +146,3 @@
     def test_empty(self):
         self.assertEqual(
             sut.commonprefix([]), '')
-
-class ReportDirectoryTest(unittest.TestCase):
-
-    # Test that successive report directory names ascend in lexicographic
-    # order. This is required so that report directories from two runs of
-    # scan-build can be easily matched up to compare results.
-    def test_directory_name_comparison(self):
-        with libear.TemporaryDirectory() as tmpdir, \
-             sut.report_directory(tmpdir, False) as report_dir1, \
-             sut.report_directory(tmpdir, False) as report_dir2, \
-             sut.report_directory(tmpdir, False) as report_dir3:
-            self.assertLess(report_dir1, report_dir2)
-            self.assertLess(report_dir2, report_dir3)
diff --git a/tools/scan-build-py/tests/unit/test_runner.py b/tools/scan-build-py/tests/unit/test_runner.py
index 2d09062..4b51e65 100644
--- a/tools/scan-build-py/tests/unit/test_runner.py
+++ b/tools/scan-build-py/tests/unit/test_runner.py
@@ -150,7 +150,6 @@
     def test_run_analyzer_crash_and_forwarded(self):
         content = "int div(int n, int d) { return n / d }"
         (_, fwds) = RunAnalyzerTest.run_analyzer(content, True)
-        self.assertEqual('crash', fwds['error_type'])
         self.assertEqual(1, fwds['exit_code'])
         self.assertTrue(len(fwds['error_output']) > 0)
 
diff --git a/tools/scan-view/share/Reporter.py b/tools/scan-view/share/Reporter.py
index 294e05b..800af03 100644
--- a/tools/scan-view/share/Reporter.py
+++ b/tools/scan-view/share/Reporter.py
@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """Methods for reporting bugs."""
 
 import subprocess, sys, os
diff --git a/tools/scan-view/share/startfile.py b/tools/scan-view/share/startfile.py
index e8fbe2d..6739359 100644
--- a/tools/scan-view/share/startfile.py
+++ b/tools/scan-view/share/startfile.py
@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """Utility for opening a file using the default application in a cross-platform
 manner. Modified from http://code.activestate.com/recipes/511443/.
 """
diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp
index dc4f914..e5a09a3 100644
--- a/unittests/AST/DeclPrinterTest.cpp
+++ b/unittests/AST/DeclPrinterTest.cpp
@@ -45,7 +45,7 @@
   PrintMatch() : NumFoundDecls(0) {}
 
   void run(const MatchFinder::MatchResult &Result) override {
-    const Decl *D = Result.Nodes.getDeclAs<Decl>("id");
+    const Decl *D = Result.Nodes.getNodeAs<Decl>("id");
     if (!D || D->isImplicit())
       return;
     NumFoundDecls++;
diff --git a/unittests/AST/ExternalASTSourceTest.cpp b/unittests/AST/ExternalASTSourceTest.cpp
index 4b3bb3e..513ff5b 100644
--- a/unittests/AST/ExternalASTSourceTest.cpp
+++ b/unittests/AST/ExternalASTSourceTest.cpp
@@ -49,14 +49,14 @@
   CompilerInstance Compiler;
   Compiler.createDiagnostics();
 
-  CompilerInvocation *Invocation = new CompilerInvocation;
+  auto Invocation = std::make_shared<CompilerInvocation>();
   Invocation->getPreprocessorOpts().addRemappedFile(
       "test.cc", MemoryBuffer::getMemBuffer(FileContents).release());
   const char *Args[] = { "test.cc" };
   CompilerInvocation::CreateFromArgs(*Invocation, Args,
                                      Args + array_lengthof(Args),
                                      Compiler.getDiagnostics());
-  Compiler.setInvocation(Invocation);
+  Compiler.setInvocation(std::move(Invocation));
 
   TestFrontendAction Action(Source);
   return Compiler.ExecuteAction(Action);
diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp
index add85c3..5f69c54 100644
--- a/unittests/AST/SourceLocationTest.cpp
+++ b/unittests/AST/SourceLocationTest.cpp
@@ -670,5 +670,72 @@
       Language::Lang_CXX11));
 }
 
+class ExceptionSpecRangeVerifier : public RangeVerifier<TypeLoc> {
+protected:
+  SourceRange getRange(const TypeLoc &Node) override {
+    auto T =
+      Node.getUnqualifiedLoc().castAs<FunctionProtoTypeLoc>();
+    assert(!T.isNull());
+    return T.getExceptionSpecRange();
+  }
+};
+
+class ParmVarExceptionSpecRangeVerifier : public RangeVerifier<ParmVarDecl> {
+protected:
+  SourceRange getRange(const ParmVarDecl &Node) override {
+    if (const TypeSourceInfo *TSI = Node.getTypeSourceInfo()) {
+      TypeLoc TL = TSI->getTypeLoc();
+      if (TL.getType()->isPointerType()) {
+        TL = TL.getNextTypeLoc().IgnoreParens();
+        if (auto FPTL = TL.getAs<FunctionProtoTypeLoc>()) {
+          return FPTL.getExceptionSpecRange();
+        }
+      }
+    }
+    return SourceRange();
+  }
+};
+
+TEST(FunctionDecl, ExceptionSpecifications) {
+  ExceptionSpecRangeVerifier Verifier;
+
+  Verifier.expectRange(1, 10, 1, 16);
+  EXPECT_TRUE(Verifier.match("void f() throw();\n", loc(functionType())));
+
+  Verifier.expectRange(1, 10, 1, 34);
+  EXPECT_TRUE(Verifier.match("void f() throw(void(void) throw());\n",
+                             loc(functionType())));
+
+  Verifier.expectRange(1, 10, 1, 19);
+  std::vector<std::string> Args;
+  Args.push_back("-fms-extensions");
+  EXPECT_TRUE(Verifier.match("void f() throw(...);\n", loc(functionType()),
+                             Args, Language::Lang_CXX));
+
+  Verifier.expectRange(1, 10, 1, 10);
+  EXPECT_TRUE(Verifier.match("void f() noexcept;\n", loc(functionType()),
+                             Language::Lang_CXX11));
+
+  Verifier.expectRange(1, 10, 1, 24);
+  EXPECT_TRUE(Verifier.match("void f() noexcept(false);\n", loc(functionType()),
+                             Language::Lang_CXX11));
+
+  Verifier.expectRange(1, 10, 1, 32);
+  EXPECT_TRUE(Verifier.match("void f() noexcept(noexcept(1+1));\n",
+                             loc(functionType()), Language::Lang_CXX11));
+
+  ParmVarExceptionSpecRangeVerifier Verifier2;
+  Verifier2.expectRange(1, 25, 1, 31);
+  EXPECT_TRUE(Verifier2.match("void g(void (*fp)(void) throw());\n",
+                              parmVarDecl(hasType(pointerType(pointee(
+                                  parenType(innerType(functionType()))))))));
+
+  Verifier2.expectRange(1, 25, 1, 38);
+  EXPECT_TRUE(Verifier2.match("void g(void (*fp)(void) noexcept(true));\n",
+                              parmVarDecl(hasType(pointerType(pointee(
+                                  parenType(innerType(functionType())))))),
+                              Language::Lang_CXX11));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
diff --git a/unittests/AST/StmtPrinterTest.cpp b/unittests/AST/StmtPrinterTest.cpp
index bc7fd54..12b2032 100644
--- a/unittests/AST/StmtPrinterTest.cpp
+++ b/unittests/AST/StmtPrinterTest.cpp
@@ -45,7 +45,7 @@
   PrintMatch() : NumFoundStmts(0) {}
 
   void run(const MatchFinder::MatchResult &Result) override {
-    const Stmt *S = Result.Nodes.getStmtAs<Stmt>("id");
+    const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");
     if (!S)
       return;
     NumFoundStmts++;
diff --git a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index b7ffd75..6037127 100644
--- a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1404,6 +1404,16 @@
                       fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));
 }
 
+TEST(Member, InClassInitializer) {
+  EXPECT_TRUE(
+      matches("class C { int a = 2; int b; };",
+              fieldDecl(hasInClassInitializer(integerLiteral(equals(2))),
+                        hasName("a"))));
+  EXPECT_TRUE(
+      notMatches("class C { int a = 2; int b; };",
+                 fieldDecl(hasInClassInitializer(anything()), hasName("b"))));
+}
+
 TEST(Member, UnderstandsAccess) {
   EXPECT_TRUE(matches(
     "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
diff --git a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 7899829..5957c7f 100644
--- a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -222,9 +222,12 @@
 }
 
 TEST(HasDeclaration, HasGetDeclTraitTest) {
-  EXPECT_TRUE(internal::has_getDecl<TypedefType>::value);
-  EXPECT_TRUE(internal::has_getDecl<RecordType>::value);
-  EXPECT_FALSE(internal::has_getDecl<TemplateSpecializationType>::value);
+  static_assert(internal::has_getDecl<TypedefType>::value,
+                "Expected TypedefType to have a getDecl.");
+  static_assert(internal::has_getDecl<RecordType>::value,
+                "Expected RecordType to have a getDecl.");
+  static_assert(!internal::has_getDecl<TemplateSpecializationType>::value,
+                "Expected TemplateSpecializationType to *not* have a getDecl.");
 }
 
 TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
@@ -688,7 +691,7 @@
       "};\n"
       "template<typename U>\n"
       "template<typename U2>\n"
-      "int Struct<U>::field<char> = 123;\n";
+      "int Struct<U>::field<U2*> = 123;\n";
   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2"))));
   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
@@ -703,7 +706,7 @@
       "};\n"
       "template<typename U>\n"
       "template<typename U2>\n"
-      "struct Class<U>::Struct<int> {};\n";
+      "struct Class<U>::Struct<U2*> {};\n";
   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2"))));
   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
diff --git a/unittests/Analysis/CFGTest.cpp b/unittests/Analysis/CFGTest.cpp
index e691110..768705f 100644
--- a/unittests/Analysis/CFGTest.cpp
+++ b/unittests/Analysis/CFGTest.cpp
@@ -35,7 +35,9 @@
     if (!Body)
       return;
     TheBuildResult = SawFunctionBody;
-    if (CFG::buildCFG(nullptr, Body, Result.Context, CFG::BuildOptions()))
+    CFG::BuildOptions Options;
+    Options.AddImplicitDtors = true;
+    if (CFG::buildCFG(nullptr, Body, Result.Context, Options))
         TheBuildResult = BuiltCFG;
   }
 };
@@ -75,6 +77,16 @@
   EXPECT_EQ(BuiltCFG, BuildCFG(Code));
 }
 
+// Constructing a CFG on a function template with a variable of incomplete type
+// should not crash.
+TEST(CFG, VariableOfIncompleteType) {
+  const char *Code = "template<class T> void f() {\n"
+                     "  class Undefined;\n"
+                     "  Undefined u;\n"
+                     "}\n";
+  EXPECT_EQ(BuiltCFG, BuildCFG(Code));
+}
+
 } // namespace
 } // namespace analysis
 } // namespace clang
diff --git a/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp
index f418761..a967b0e 100644
--- a/unittests/Basic/SourceManagerTest.cpp
+++ b/unittests/Basic/SourceManagerTest.cpp
@@ -78,10 +78,10 @@
   SourceMgr.setMainFileID(mainFileID);
 
   VoidModuleLoader ModLoader;
-  HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 
-                          &*Target);
-  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
-                  HeaderInfo, ModLoader,
+  HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+                          Diags, LangOpts, &*Target);
+  Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
+                  SourceMgr, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
@@ -198,10 +198,10 @@
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
 
   VoidModuleLoader ModLoader;
-  HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 
-                          &*Target);
-  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
-                  HeaderInfo, ModLoader,
+  HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+                          Diags, LangOpts, &*Target);
+  Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
+                  SourceMgr, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
@@ -298,10 +298,10 @@
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
 
   VoidModuleLoader ModLoader;
-  HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 
-                          &*Target);
-  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
-                  HeaderInfo, ModLoader,
+  HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+                          Diags, LangOpts, &*Target);
+  Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
+                  SourceMgr, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
diff --git a/unittests/Basic/VirtualFileSystemTest.cpp b/unittests/Basic/VirtualFileSystemTest.cpp
index 580343d..92e3663 100644
--- a/unittests/Basic/VirtualFileSystemTest.cpp
+++ b/unittests/Basic/VirtualFileSystemTest.cpp
@@ -305,6 +305,22 @@
   }
   operator StringRef() { return Path.str(); }
 };
+
+struct ScopedLink {
+  SmallString<128> Path;
+  ScopedLink(const Twine &To, const Twine &From) {
+    Path = From.str();
+    std::error_code EC = sys::fs::create_link(To, From);
+    if (EC)
+      Path = "";
+    EXPECT_FALSE(EC);
+  }
+  ~ScopedLink() {
+    if (Path != "")
+      EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+  }
+  operator StringRef() { return Path.str(); }
+};
 } // end anonymous namespace
 
 TEST(VirtualFileSystemTest, BasicRealFSIteration) {
@@ -334,6 +350,36 @@
   EXPECT_EQ(vfs::directory_iterator(), I);
 }
 
+#ifdef LLVM_ON_UNIX
+TEST(VirtualFileSystemTest, BrokenSymlinkRealFSIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  ScopedLink _a("no_such_file", TestDirectory + "/a");
+  ScopedDir _b(TestDirectory + "/b");
+  ScopedLink _c("no_such_file", TestDirectory + "/c");
+
+  std::error_code EC;
+  for (vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC), E;
+       I != E; I.increment(EC)) {
+    // Skip broken symlinks.
+    if (EC == std::errc::no_such_file_or_directory) {
+      EC = std::error_code();
+      continue;
+    }
+    // For bot debugging.
+    if (EC) {
+      outs() << "std::errc::no_such_file_or_directory: "
+             << (int)std::errc::no_such_file_or_directory << "\n";
+      outs() << "EC: " << EC.value() << "\n";
+      outs() << "EC message: " << EC.message() << "\n";
+    }
+    ASSERT_FALSE(EC);
+    EXPECT_TRUE(I->getName() == _b);
+  }
+}
+#endif
+
 TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) {
   ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true);
   IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
@@ -373,6 +419,50 @@
   EXPECT_EQ(1, Counts[3]); // d
 }
 
+#ifdef LLVM_ON_UNIX
+TEST(VirtualFileSystemTest, BrokenSymlinkRealFSRecursiveIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  ScopedLink _a("no_such_file", TestDirectory + "/a");
+  ScopedDir _b(TestDirectory + "/b");
+  ScopedLink _ba("no_such_file", TestDirectory + "/b/a");
+  ScopedDir _bb(TestDirectory + "/b/b");
+  ScopedLink _bc("no_such_file", TestDirectory + "/b/c");
+  ScopedLink _c("no_such_file", TestDirectory + "/c");
+  ScopedDir _d(TestDirectory + "/d");
+  ScopedDir _dd(TestDirectory + "/d/d");
+  ScopedDir _ddd(TestDirectory + "/d/d/d");
+  ScopedLink _e("no_such_file", TestDirectory + "/e");
+  std::vector<StringRef> Expected = {_b, _bb, _d, _dd, _ddd};
+
+  std::vector<std::string> Contents;
+  std::error_code EC;
+  for (vfs::recursive_directory_iterator I(*FS, Twine(TestDirectory), EC), E;
+       I != E; I.increment(EC)) {
+    // Skip broken symlinks.
+    if (EC == std::errc::no_such_file_or_directory) {
+      EC = std::error_code();
+      continue;
+    }
+    // For bot debugging.
+    if (EC) {
+      outs() << "std::errc::no_such_file_or_directory: "
+             << (int)std::errc::no_such_file_or_directory << "\n";
+      outs() << "EC: " << EC.value() << "\n";
+      outs() << "EC message: " << EC.message() << "\n";
+    }
+    ASSERT_FALSE(EC);
+    Contents.push_back(I->getName());
+  }
+
+  // Check sorted contents.
+  std::sort(Contents.begin(), Contents.end());
+  EXPECT_EQ(Expected.size(), Contents.size());
+  EXPECT_TRUE(std::equal(Contents.begin(), Contents.end(), Expected.begin()));
+}
+#endif
+
 template <typename DirIter>
 static void checkContents(DirIter I, ArrayRef<StringRef> ExpectedOut) {
   std::error_code EC;
diff --git a/unittests/Driver/CMakeLists.txt b/unittests/Driver/CMakeLists.txt
index b9c52f7..a4f75d2 100644
--- a/unittests/Driver/CMakeLists.txt
+++ b/unittests/Driver/CMakeLists.txt
@@ -1,5 +1,6 @@
 set(LLVM_LINK_COMPONENTS
   Support
+  Option
   )
 
 add_clang_unittest(ClangDriverTests
diff --git a/unittests/Format/CMakeLists.txt b/unittests/Format/CMakeLists.txt
index 240be6e..507d643 100644
--- a/unittests/Format/CMakeLists.txt
+++ b/unittests/Format/CMakeLists.txt
@@ -5,10 +5,13 @@
 add_clang_unittest(FormatTests
   CleanupTest.cpp
   FormatTest.cpp
-  FormatTestJava.cpp
+  FormatTestComments.cpp
   FormatTestJS.cpp
+  FormatTestJava.cpp
+  FormatTestObjC.cpp
   FormatTestProto.cpp
   FormatTestSelective.cpp
+  NamespaceEndCommentsFixerTest.cpp
   SortImportsTestJS.cpp
   SortIncludesTest.cpp
   )
diff --git a/unittests/Format/CleanupTest.cpp b/unittests/Format/CleanupTest.cpp
index dbf3f07..6ac5f69 100644
--- a/unittests/Format/CleanupTest.cpp
+++ b/unittests/Format/CleanupTest.cpp
@@ -714,6 +714,19 @@
   EXPECT_EQ(Expected, apply(Code, Replaces));
 }
 
+TEST_F(CleanUpReplacementsTest, FakeHeaderGuard) {
+  std::string Code = "// comment \n"
+                     "#ifndef X\n"
+                     "#define 1\n";
+  std::string Expected = "// comment \n"
+                         "#include <vector>\n"
+                         "#ifndef X\n"
+                         "#define 1\n";
+  tooling::Replacements Replaces =
+      toReplacements({createInsertion("#include <vector>")});
+  EXPECT_EQ(Expected, apply(Code, Replaces));
+}
+
 TEST_F(CleanUpReplacementsTest, HeaderGuardWithComment) {
   std::string Code = "// comment \n"
                      "#ifndef X // comment\n"
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index e851bb2..bcbdbbf 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -71,6 +71,13 @@
   void verifyFormat(llvm::StringRef Code,
                     const FormatStyle &Style = getLLVMStyle()) {
     EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
+    if (Style.Language == FormatStyle::LK_Cpp) {
+      // Objective-C++ is a superset of C++, so everything checked for C++
+      // needs to be checked for Objective-C++ as well.
+      FormatStyle ObjCStyle = Style;
+      ObjCStyle.Language = FormatStyle::LK_ObjC;
+      EXPECT_EQ(Code.str(), format(test::messUp(Code), ObjCStyle));
+    }
   }
 
   void verifyIncompleteFormat(llvm::StringRef Code,
@@ -139,6 +146,8 @@
   verifyFormat("::ns::SomeFunction(::ns::SomeOtherFunction())");
   verifyFormat("static constexpr bool Bar = decltype(bar())::value;");
   verifyFormat("bool a = 2 < ::SomeFunction();");
+  verifyFormat("ALWAYS_INLINE ::std::string getName();");
+  verifyFormat("some::string getName();");
 }
 
 TEST_F(FormatTest, OnlyGeneratesNecessaryReplacements) {
@@ -261,6 +270,15 @@
                    "}"));
 
   // FIXME: This is slightly inconsistent.
+  FormatStyle LLVMWithNoNamespaceFix = getLLVMStyle();
+  LLVMWithNoNamespaceFix.FixNamespaceComments = false;
+  EXPECT_EQ("namespace {\n"
+            "int i;\n"
+            "}",
+            format("namespace {\n"
+                   "int i;\n"
+                   "\n"
+                   "}", LLVMWithNoNamespaceFix));
   EXPECT_EQ("namespace {\n"
             "int i;\n"
             "}",
@@ -866,1061 +884,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Tests for comments.
-//===----------------------------------------------------------------------===//
-
-TEST_F(FormatTest, UnderstandsSingleLineComments) {
-  verifyFormat("//* */");
-  verifyFormat("// line 1\n"
-               "// line 2\n"
-               "void f() {}\n");
-
-  verifyFormat("void f() {\n"
-               "  // Doesn't do anything\n"
-               "}");
-  verifyFormat("SomeObject\n"
-               "    // Calling someFunction on SomeObject\n"
-               "    .someFunction();");
-  verifyFormat("auto result = SomeObject\n"
-               "                  // Calling someFunction on SomeObject\n"
-               "                  .someFunction();");
-  verifyFormat("void f(int i,  // some comment (probably for i)\n"
-               "       int j,  // some comment (probably for j)\n"
-               "       int k); // some comment (probably for k)");
-  verifyFormat("void f(int i,\n"
-               "       // some comment (probably for j)\n"
-               "       int j,\n"
-               "       // some comment (probably for k)\n"
-               "       int k);");
-
-  verifyFormat("int i    // This is a fancy variable\n"
-               "    = 5; // with nicely aligned comment.");
-
-  verifyFormat("// Leading comment.\n"
-               "int a; // Trailing comment.");
-  verifyFormat("int a; // Trailing comment\n"
-               "       // on 2\n"
-               "       // or 3 lines.\n"
-               "int b;");
-  verifyFormat("int a; // Trailing comment\n"
-               "\n"
-               "// Leading comment.\n"
-               "int b;");
-  verifyFormat("int a;    // Comment.\n"
-               "          // More details.\n"
-               "int bbbb; // Another comment.");
-  verifyFormat(
-      "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; // comment\n"
-      "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;   // comment\n"
-      "int cccccccccccccccccccccccccccccc;       // comment\n"
-      "int ddd;                     // looooooooooooooooooooooooong comment\n"
-      "int aaaaaaaaaaaaaaaaaaaaaaa; // comment\n"
-      "int bbbbbbbbbbbbbbbbbbbbb;   // comment\n"
-      "int ccccccccccccccccccc;     // comment");
-
-  verifyFormat("#include \"a\"     // comment\n"
-               "#include \"a/b/c\" // comment");
-  verifyFormat("#include <a>     // comment\n"
-               "#include <a/b/c> // comment");
-  EXPECT_EQ("#include \"a\"     // comment\n"
-            "#include \"a/b/c\" // comment",
-            format("#include \\\n"
-                   "  \"a\" // comment\n"
-                   "#include \"a/b/c\" // comment"));
-
-  verifyFormat("enum E {\n"
-               "  // comment\n"
-               "  VAL_A, // comment\n"
-               "  VAL_B\n"
-               "};");
-
-  verifyFormat(
-      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
-      "    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // Trailing comment");
-  verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
-               "    // Comment inside a statement.\n"
-               "    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;");
-  verifyFormat("SomeFunction(a,\n"
-               "             // comment\n"
-               "             b + x);");
-  verifyFormat("SomeFunction(a, a,\n"
-               "             // comment\n"
-               "             b + x);");
-  verifyFormat(
-      "bool aaaaaaaaaaaaa = // comment\n"
-      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
-      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
-
-  verifyFormat("int aaaa; // aaaaa\n"
-               "int aa;   // aaaaaaa",
-               getLLVMStyleWithColumns(20));
-
-  EXPECT_EQ("void f() { // This does something ..\n"
-            "}\n"
-            "int a; // This is unrelated",
-            format("void f()    {     // This does something ..\n"
-                   "  }\n"
-                   "int   a;     // This is unrelated"));
-  EXPECT_EQ("class C {\n"
-            "  void f() { // This does something ..\n"
-            "  }          // awesome..\n"
-            "\n"
-            "  int a; // This is unrelated\n"
-            "};",
-            format("class C{void f()    { // This does something ..\n"
-                   "      } // awesome..\n"
-                   " \n"
-                   "int a;    // This is unrelated\n"
-                   "};"));
-
-  EXPECT_EQ("int i; // single line trailing comment",
-            format("int i;\\\n// single line trailing comment"));
-
-  verifyGoogleFormat("int a;  // Trailing comment.");
-
-  verifyFormat("someFunction(anotherFunction( // Force break.\n"
-               "    parameter));");
-
-  verifyGoogleFormat("#endif  // HEADER_GUARD");
-
-  verifyFormat("const char *test[] = {\n"
-               "    // A\n"
-               "    \"aaaa\",\n"
-               "    // B\n"
-               "    \"aaaaa\"};");
-  verifyGoogleFormat(
-      "aaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
-      "    aaaaaaaaaaaaaaaaaaaaaa);  // 81_cols_with_this_comment");
-  EXPECT_EQ("D(a, {\n"
-            "  // test\n"
-            "  int a;\n"
-            "});",
-            format("D(a, {\n"
-                   "// test\n"
-                   "int a;\n"
-                   "});"));
-
-  EXPECT_EQ("lineWith(); // comment\n"
-            "// at start\n"
-            "otherLine();",
-            format("lineWith();   // comment\n"
-                   "// at start\n"
-                   "otherLine();"));
-  EXPECT_EQ("lineWith(); // comment\n"
-            "/*\n"
-            " * at start */\n"
-            "otherLine();",
-            format("lineWith();   // comment\n"
-                   "/*\n"
-                   " * at start */\n"
-                   "otherLine();"));
-  EXPECT_EQ("lineWith(); // comment\n"
-            "            // at start\n"
-            "otherLine();",
-            format("lineWith();   // comment\n"
-                   " // at start\n"
-                   "otherLine();"));
-
-  EXPECT_EQ("lineWith(); // comment\n"
-            "// at start\n"
-            "otherLine(); // comment",
-            format("lineWith();   // comment\n"
-                   "// at start\n"
-                   "otherLine();   // comment"));
-  EXPECT_EQ("lineWith();\n"
-            "// at start\n"
-            "otherLine(); // comment",
-            format("lineWith();\n"
-                   " // at start\n"
-                   "otherLine();   // comment"));
-  EXPECT_EQ("// first\n"
-            "// at start\n"
-            "otherLine(); // comment",
-            format("// first\n"
-                   " // at start\n"
-                   "otherLine();   // comment"));
-  EXPECT_EQ("f();\n"
-            "// first\n"
-            "// at start\n"
-            "otherLine(); // comment",
-            format("f();\n"
-                   "// first\n"
-                   " // at start\n"
-                   "otherLine();   // comment"));
-  verifyFormat("f(); // comment\n"
-               "// first\n"
-               "// at start\n"
-               "otherLine();");
-  EXPECT_EQ("f(); // comment\n"
-            "// first\n"
-            "// at start\n"
-            "otherLine();",
-            format("f();   // comment\n"
-                   "// first\n"
-                   " // at start\n"
-                   "otherLine();"));
-  EXPECT_EQ("f(); // comment\n"
-            "     // first\n"
-            "// at start\n"
-            "otherLine();",
-            format("f();   // comment\n"
-                   " // first\n"
-                   "// at start\n"
-                   "otherLine();"));
-  EXPECT_EQ("void f() {\n"
-            "  lineWith(); // comment\n"
-            "  // at start\n"
-            "}",
-            format("void              f() {\n"
-                   "  lineWith(); // comment\n"
-                   "  // at start\n"
-                   "}"));
-  EXPECT_EQ("int xy; // a\n"
-            "int z;  // b",
-            format("int xy;    // a\n"
-                   "int z;    //b"));
-  EXPECT_EQ("int xy; // a\n"
-            "int z; // bb",
-            format("int xy;    // a\n"
-                   "int z;    //bb",
-                   getLLVMStyleWithColumns(12)));
-
-  verifyFormat("#define A                                                  \\\n"
-               "  int i; /* iiiiiiiiiiiiiiiiiiiii */                       \\\n"
-               "  int jjjjjjjjjjjjjjjjjjjjjjjj; /* */",
-               getLLVMStyleWithColumns(60));
-  verifyFormat(
-      "#define A                                                   \\\n"
-      "  int i;                        /* iiiiiiiiiiiiiiiiiiiii */ \\\n"
-      "  int jjjjjjjjjjjjjjjjjjjjjjjj; /* */",
-      getLLVMStyleWithColumns(61));
-
-  verifyFormat("if ( // This is some comment\n"
-               "    x + 3) {\n"
-               "}");
-  EXPECT_EQ("if ( // This is some comment\n"
-            "     // spanning two lines\n"
-            "    x + 3) {\n"
-            "}",
-            format("if( // This is some comment\n"
-                   "     // spanning two lines\n"
-                   " x + 3) {\n"
-                   "}"));
-
-  verifyNoCrash("/\\\n/");
-  verifyNoCrash("/\\\n* */");
-  // The 0-character somehow makes the lexer return a proper comment.
-  verifyNoCrash(StringRef("/*\\\0\n/", 6));
-}
-
-TEST_F(FormatTest, KeepsParameterWithTrailingCommentsOnTheirOwnLine) {
-  EXPECT_EQ("SomeFunction(a,\n"
-            "             b, // comment\n"
-            "             c);",
-            format("SomeFunction(a,\n"
-                   "          b, // comment\n"
-                   "      c);"));
-  EXPECT_EQ("SomeFunction(a, b,\n"
-            "             // comment\n"
-            "             c);",
-            format("SomeFunction(a,\n"
-                   "          b,\n"
-                   "  // comment\n"
-                   "      c);"));
-  EXPECT_EQ("SomeFunction(a, b, // comment (unclear relation)\n"
-            "             c);",
-            format("SomeFunction(a, b, // comment (unclear relation)\n"
-                   "      c);"));
-  EXPECT_EQ("SomeFunction(a, // comment\n"
-            "             b,\n"
-            "             c); // comment",
-            format("SomeFunction(a,     // comment\n"
-                   "          b,\n"
-                   "      c); // comment"));
-  EXPECT_EQ("aaaaaaaaaa(aaaa(aaaa,\n"
-            "                aaaa), //\n"
-            "           aaaa, bbbbb);",
-            format("aaaaaaaaaa(aaaa(aaaa,\n"
-                   "aaaa), //\n"
-                   "aaaa, bbbbb);"));
-}
-
-TEST_F(FormatTest, RemovesTrailingWhitespaceOfComments) {
-  EXPECT_EQ("// comment", format("// comment  "));
-  EXPECT_EQ("int aaaaaaa, bbbbbbb; // comment",
-            format("int aaaaaaa, bbbbbbb; // comment                   ",
-                   getLLVMStyleWithColumns(33)));
-  EXPECT_EQ("// comment\\\n", format("// comment\\\n  \t \v   \f   "));
-  EXPECT_EQ("// comment    \\\n", format("// comment    \\\n  \t \v   \f   "));
-}
-
-TEST_F(FormatTest, UnderstandsBlockComments) {
-  verifyFormat("f(/*noSpaceAfterParameterNamingComment=*/true);");
-  verifyFormat("void f() { g(/*aaa=*/x, /*bbb=*/!y, /*c=*/::c); }");
-  EXPECT_EQ("f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n"
-            "  bbbbbbbbbbbbbbbbbbbbbbbbb);",
-            format("f(aaaaaaaaaaaaaaaaaaaaaaaaa ,   \\\n"
-                   "/* Trailing comment for aa... */\n"
-                   "  bbbbbbbbbbbbbbbbbbbbbbbbb);"));
-  EXPECT_EQ(
-      "f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-      "  /* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);",
-      format("f(aaaaaaaaaaaaaaaaaaaaaaaaa    ,   \n"
-             "/* Leading comment for bb... */   bbbbbbbbbbbbbbbbbbbbbbbbb);"));
-  EXPECT_EQ(
-      "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
-      "    aaaaaaaaaaaaaaaaaa,\n"
-      "    aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n"
-      "}",
-      format("void      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
-             "                      aaaaaaaaaaaaaaaaaa  ,\n"
-             "    aaaaaaaaaaaaaaaaaa) {   /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n"
-             "}"));
-  verifyFormat("f(/* aaaaaaaaaaaaaaaaaa = */\n"
-               "  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
-
-  FormatStyle NoBinPacking = getLLVMStyle();
-  NoBinPacking.BinPackParameters = false;
-  verifyFormat("aaaaaaaa(/* parameter 1 */ aaaaaa,\n"
-               "         /* parameter 2 */ aaaaaa,\n"
-               "         /* parameter 3 */ aaaaaa,\n"
-               "         /* parameter 4 */ aaaaaa);",
-               NoBinPacking);
-
-  // Aligning block comments in macros.
-  verifyGoogleFormat("#define A        \\\n"
-                     "  int i;   /*a*/ \\\n"
-                     "  int jjj; /*b*/");
-}
-
-TEST_F(FormatTest, AlignsBlockComments) {
-  EXPECT_EQ("/*\n"
-            " * Really multi-line\n"
-            " * comment.\n"
-            " */\n"
-            "void f() {}",
-            format("  /*\n"
-                   "   * Really multi-line\n"
-                   "   * comment.\n"
-                   "   */\n"
-                   "  void f() {}"));
-  EXPECT_EQ("class C {\n"
-            "  /*\n"
-            "   * Another multi-line\n"
-            "   * comment.\n"
-            "   */\n"
-            "  void f() {}\n"
-            "};",
-            format("class C {\n"
-                   "/*\n"
-                   " * Another multi-line\n"
-                   " * comment.\n"
-                   " */\n"
-                   "void f() {}\n"
-                   "};"));
-  EXPECT_EQ("/*\n"
-            "  1. This is a comment with non-trivial formatting.\n"
-            "     1.1. We have to indent/outdent all lines equally\n"
-            "         1.1.1. to keep the formatting.\n"
-            " */",
-            format("  /*\n"
-                   "    1. This is a comment with non-trivial formatting.\n"
-                   "       1.1. We have to indent/outdent all lines equally\n"
-                   "           1.1.1. to keep the formatting.\n"
-                   "   */"));
-  EXPECT_EQ("/*\n"
-            "Don't try to outdent if there's not enough indentation.\n"
-            "*/",
-            format("  /*\n"
-                   " Don't try to outdent if there's not enough indentation.\n"
-                   " */"));
-
-  EXPECT_EQ("int i; /* Comment with empty...\n"
-            "        *\n"
-            "        * line. */",
-            format("int i; /* Comment with empty...\n"
-                   "        *\n"
-                   "        * line. */"));
-  EXPECT_EQ("int foobar = 0; /* comment */\n"
-            "int bar = 0;    /* multiline\n"
-            "                   comment 1 */\n"
-            "int baz = 0;    /* multiline\n"
-            "                   comment 2 */\n"
-            "int bzz = 0;    /* multiline\n"
-            "                   comment 3 */",
-            format("int foobar = 0; /* comment */\n"
-                   "int bar = 0;    /* multiline\n"
-                   "                   comment 1 */\n"
-                   "int baz = 0; /* multiline\n"
-                   "                comment 2 */\n"
-                   "int bzz = 0;         /* multiline\n"
-                   "                        comment 3 */"));
-  EXPECT_EQ("int foobar = 0; /* comment */\n"
-            "int bar = 0;    /* multiline\n"
-            "   comment */\n"
-            "int baz = 0;    /* multiline\n"
-            "comment */",
-            format("int foobar = 0; /* comment */\n"
-                   "int bar = 0; /* multiline\n"
-                   "comment */\n"
-                   "int baz = 0;        /* multiline\n"
-                   "comment */"));
-}
-
-TEST_F(FormatTest, CommentReflowingCanBeTurnedOff) {
-  FormatStyle Style = getLLVMStyleWithColumns(20);
-  Style.ReflowComments = false;
-  verifyFormat("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style);
-  verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style);
-}
-
-TEST_F(FormatTest, CorrectlyHandlesLengthOfBlockComments) {
-  EXPECT_EQ("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-            "              aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */",
-            format("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-                   "              aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */"));
-  EXPECT_EQ(
-      "void ffffffffffff(\n"
-      "    int aaaaaaaa, int bbbbbbbb,\n"
-      "    int cccccccccccc) { /*\n"
-      "                           aaaaaaaaaa\n"
-      "                           aaaaaaaaaaaaa\n"
-      "                           bbbbbbbbbbbbbb\n"
-      "                           bbbbbbbbbb\n"
-      "                         */\n"
-      "}",
-      format("void ffffffffffff(int aaaaaaaa, int bbbbbbbb, int cccccccccccc)\n"
-             "{ /*\n"
-             "     aaaaaaaaaa aaaaaaaaaaaaa\n"
-             "     bbbbbbbbbbbbbb bbbbbbbbbb\n"
-             "   */\n"
-             "}",
-             getLLVMStyleWithColumns(40)));
-}
-
-TEST_F(FormatTest, DontBreakNonTrailingBlockComments) {
-  EXPECT_EQ("void ffffffffff(\n"
-            "    int aaaaa /* test */);",
-            format("void ffffffffff(int aaaaa /* test */);",
-                   getLLVMStyleWithColumns(35)));
-}
-
-TEST_F(FormatTest, SplitsLongCxxComments) {
-  EXPECT_EQ("// A comment that\n"
-            "// doesn't fit on\n"
-            "// one line",
-            format("// A comment that doesn't fit on one line",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("/// A comment that\n"
-            "/// doesn't fit on\n"
-            "/// one line",
-            format("/// A comment that doesn't fit on one line",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("//! A comment that\n"
-            "//! doesn't fit on\n"
-            "//! one line",
-            format("//! A comment that doesn't fit on one line",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("// a b c d\n"
-            "// e f  g\n"
-            "// h i j k",
-            format("// a b c d e f  g h i j k", getLLVMStyleWithColumns(10)));
-  EXPECT_EQ(
-      "// a b c d\n"
-      "// e f  g\n"
-      "// h i j k",
-      format("\\\n// a b c d e f  g h i j k", getLLVMStyleWithColumns(10)));
-  EXPECT_EQ("if (true) // A comment that\n"
-            "          // doesn't fit on\n"
-            "          // one line",
-            format("if (true) // A comment that doesn't fit on one line   ",
-                   getLLVMStyleWithColumns(30)));
-  EXPECT_EQ("//    Don't_touch_leading_whitespace",
-            format("//    Don't_touch_leading_whitespace",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("// Add leading\n"
-            "// whitespace",
-            format("//Add leading whitespace", getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("/// Add leading\n"
-            "/// whitespace",
-            format("///Add leading whitespace", getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("//! Add leading\n"
-            "//! whitespace",
-            format("//!Add leading whitespace", getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("// whitespace", format("//whitespace", getLLVMStyle()));
-  EXPECT_EQ("// Even if it makes the line exceed the column\n"
-            "// limit",
-            format("//Even if it makes the line exceed the column limit",
-                   getLLVMStyleWithColumns(51)));
-  EXPECT_EQ("//--But not here", format("//--But not here", getLLVMStyle()));
-
-  EXPECT_EQ("// aa bb cc dd",
-            format("// aa bb             cc dd                   ",
-                   getLLVMStyleWithColumns(15)));
-
-  EXPECT_EQ("// A comment before\n"
-            "// a macro\n"
-            "// definition\n"
-            "#define a b",
-            format("// A comment before a macro definition\n"
-                   "#define a b",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("void ffffff(\n"
-            "    int aaaaaaaaa,  // wwww\n"
-            "    int bbbbbbbbbb, // xxxxxxx\n"
-            "                    // yyyyyyyyyy\n"
-            "    int c, int d, int e) {}",
-            format("void ffffff(\n"
-                   "    int aaaaaaaaa, // wwww\n"
-                   "    int bbbbbbbbbb, // xxxxxxx yyyyyyyyyy\n"
-                   "    int c, int d, int e) {}",
-                   getLLVMStyleWithColumns(40)));
-  EXPECT_EQ("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-            format("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ(
-      "#define XXX // a b c d\n"
-      "            // e f g h",
-      format("#define XXX // a b c d e f g h", getLLVMStyleWithColumns(22)));
-  EXPECT_EQ(
-      "#define XXX // q w e r\n"
-      "            // t y u i",
-      format("#define XXX //q w e r t y u i", getLLVMStyleWithColumns(22)));
-}
-
-TEST_F(FormatTest, PreservesHangingIndentInCxxComments) {
-  EXPECT_EQ("//     A comment\n"
-            "//     that doesn't\n"
-            "//     fit on one\n"
-            "//     line",
-            format("//     A comment that doesn't fit on one line",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("///     A comment\n"
-            "///     that doesn't\n"
-            "///     fit on one\n"
-            "///     line",
-            format("///     A comment that doesn't fit on one line",
-                   getLLVMStyleWithColumns(20)));
-}
-
-TEST_F(FormatTest, DontSplitLineCommentsWithEscapedNewlines) {
-  EXPECT_EQ("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
-            "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
-            "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-            format("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
-                   "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
-                   "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
-  EXPECT_EQ("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-            "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-            "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
-            format("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-                   "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-                   "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
-                   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("double\n"
-            "    a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-            "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-            "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
-            format("double a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-                   "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-                   "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
-                   getLLVMStyleWithColumns(49)));
-}
-
-TEST_F(FormatTest, DontSplitLineCommentsWithPragmas) {
-  FormatStyle Pragmas = getLLVMStyleWithColumns(30);
-  Pragmas.CommentPragmas = "^ IWYU pragma:";
-  EXPECT_EQ(
-      "// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb",
-      format("// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", Pragmas));
-  EXPECT_EQ(
-      "/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */",
-      format("/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", Pragmas));
-}
-
-TEST_F(FormatTest, PriorityOfCommentBreaking) {
-  EXPECT_EQ("if (xxx ==\n"
-            "        yyy && // aaaaaaaaaaaa bbbbbbbbb\n"
-            "    zzz)\n"
-            "  q();",
-            format("if (xxx == yyy && // aaaaaaaaaaaa bbbbbbbbb\n"
-                   "    zzz) q();",
-                   getLLVMStyleWithColumns(40)));
-  EXPECT_EQ("if (xxxxxxxxxx ==\n"
-            "        yyy && // aaaaaa bbbbbbbb cccc\n"
-            "    zzz)\n"
-            "  q();",
-            format("if (xxxxxxxxxx == yyy && // aaaaaa bbbbbbbb cccc\n"
-                   "    zzz) q();",
-                   getLLVMStyleWithColumns(40)));
-  EXPECT_EQ("if (xxxxxxxxxx &&\n"
-            "        yyy || // aaaaaa bbbbbbbb cccc\n"
-            "    zzz)\n"
-            "  q();",
-            format("if (xxxxxxxxxx && yyy || // aaaaaa bbbbbbbb cccc\n"
-                   "    zzz) q();",
-                   getLLVMStyleWithColumns(40)));
-  EXPECT_EQ("fffffffff(\n"
-            "    &xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n"
-            "    zzz);",
-            format("fffffffff(&xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n"
-                   " zzz);",
-                   getLLVMStyleWithColumns(40)));
-}
-
-TEST_F(FormatTest, MultiLineCommentsInDefines) {
-  EXPECT_EQ("#define A(x) /* \\\n"
-            "  a comment     \\\n"
-            "  inside */     \\\n"
-            "  f();",
-            format("#define A(x) /* \\\n"
-                   "  a comment     \\\n"
-                   "  inside */     \\\n"
-                   "  f();",
-                   getLLVMStyleWithColumns(17)));
-  EXPECT_EQ("#define A(      \\\n"
-            "    x) /*       \\\n"
-            "  a comment     \\\n"
-            "  inside */     \\\n"
-            "  f();",
-            format("#define A(      \\\n"
-                   "    x) /*       \\\n"
-                   "  a comment     \\\n"
-                   "  inside */     \\\n"
-                   "  f();",
-                   getLLVMStyleWithColumns(17)));
-}
-
-TEST_F(FormatTest, ParsesCommentsAdjacentToPPDirectives) {
-  EXPECT_EQ("namespace {}\n// Test\n#define A",
-            format("namespace {}\n   // Test\n#define A"));
-  EXPECT_EQ("namespace {}\n/* Test */\n#define A",
-            format("namespace {}\n   /* Test */\n#define A"));
-  EXPECT_EQ("namespace {}\n/* Test */ #define A",
-            format("namespace {}\n   /* Test */    #define A"));
-}
-
-TEST_F(FormatTest, SplitsLongLinesInComments) {
-  EXPECT_EQ("/* This is a long\n"
-            " * comment that\n"
-            " * doesn't\n"
-            " * fit on one line.\n"
-            " */",
-            format("/* "
-                   "This is a long                                         "
-                   "comment that "
-                   "doesn't                                    "
-                   "fit on one line.  */",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ(
-      "/* a b c d\n"
-      " * e f  g\n"
-      " * h i j k\n"
-      " */",
-      format("/* a b c d e f  g h i j k */", getLLVMStyleWithColumns(10)));
-  EXPECT_EQ(
-      "/* a b c d\n"
-      " * e f  g\n"
-      " * h i j k\n"
-      " */",
-      format("\\\n/* a b c d e f  g h i j k */", getLLVMStyleWithColumns(10)));
-  EXPECT_EQ("/*\n"
-            "This is a long\n"
-            "comment that doesn't\n"
-            "fit on one line.\n"
-            "*/",
-            format("/*\n"
-                   "This is a long                                         "
-                   "comment that doesn't                                    "
-                   "fit on one line.                                      \n"
-                   "*/",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("/*\n"
-            " * This is a long\n"
-            " * comment that\n"
-            " * doesn't fit on\n"
-            " * one line.\n"
-            " */",
-            format("/*      \n"
-                   " * This is a long "
-                   "   comment that     "
-                   "   doesn't fit on   "
-                   "   one line.                                            \n"
-                   " */",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("/*\n"
-            " * This_is_a_comment_with_words_that_dont_fit_on_one_line\n"
-            " * so_it_should_be_broken\n"
-            " * wherever_a_space_occurs\n"
-            " */",
-            format("/*\n"
-                   " * This_is_a_comment_with_words_that_dont_fit_on_one_line "
-                   "   so_it_should_be_broken "
-                   "   wherever_a_space_occurs                             \n"
-                   " */",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("/*\n"
-            " *    This_comment_can_not_be_broken_into_lines\n"
-            " */",
-            format("/*\n"
-                   " *    This_comment_can_not_be_broken_into_lines\n"
-                   " */",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("{\n"
-            "  /*\n"
-            "  This is another\n"
-            "  long comment that\n"
-            "  doesn't fit on one\n"
-            "  line    1234567890\n"
-            "  */\n"
-            "}",
-            format("{\n"
-                   "/*\n"
-                   "This is another     "
-                   "  long comment that "
-                   "  doesn't fit on one"
-                   "  line    1234567890\n"
-                   "*/\n"
-                   "}",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("{\n"
-            "  /*\n"
-            "   * This        i s\n"
-            "   * another comment\n"
-            "   * t hat  doesn' t\n"
-            "   * fit on one l i\n"
-            "   * n e\n"
-            "   */\n"
-            "}",
-            format("{\n"
-                   "/*\n"
-                   " * This        i s"
-                   "   another comment"
-                   "   t hat  doesn' t"
-                   "   fit on one l i"
-                   "   n e\n"
-                   " */\n"
-                   "}",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("/*\n"
-            " * This is a long\n"
-            " * comment that\n"
-            " * doesn't fit on\n"
-            " * one line\n"
-            " */",
-            format("   /*\n"
-                   "    * This is a long comment that doesn't fit on one line\n"
-                   "    */",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("{\n"
-            "  if (something) /* This is a\n"
-            "                    long\n"
-            "                    comment */\n"
-            "    ;\n"
-            "}",
-            format("{\n"
-                   "  if (something) /* This is a long comment */\n"
-                   "    ;\n"
-                   "}",
-                   getLLVMStyleWithColumns(30)));
-
-  EXPECT_EQ("/* A comment before\n"
-            " * a macro\n"
-            " * definition */\n"
-            "#define a b",
-            format("/* A comment before a macro definition */\n"
-                   "#define a b",
-                   getLLVMStyleWithColumns(20)));
-
-  EXPECT_EQ("/* some comment\n"
-            "     *   a comment\n"
-            "* that we break\n"
-            " * another comment\n"
-            "* we have to break\n"
-            "* a left comment\n"
-            " */",
-            format("  /* some comment\n"
-                   "       *   a comment that we break\n"
-                   "   * another comment we have to break\n"
-                   "* a left comment\n"
-                   "   */",
-                   getLLVMStyleWithColumns(20)));
-
-  EXPECT_EQ("/**\n"
-            " * multiline block\n"
-            " * comment\n"
-            " *\n"
-            " */",
-            format("/**\n"
-                   " * multiline block comment\n"
-                   " *\n"
-                   " */",
-                   getLLVMStyleWithColumns(20)));
-
-  EXPECT_EQ("/*\n"
-            "\n"
-            "\n"
-            "    */\n",
-            format("  /*       \n"
-                   "      \n"
-                   "               \n"
-                   "      */\n"));
-
-  EXPECT_EQ("/* a a */",
-            format("/* a a            */", getLLVMStyleWithColumns(15)));
-  EXPECT_EQ("/* a a bc  */",
-            format("/* a a            bc  */", getLLVMStyleWithColumns(15)));
-  EXPECT_EQ("/* aaa aaa\n"
-            " * aaaaa */",
-            format("/* aaa aaa aaaaa       */", getLLVMStyleWithColumns(15)));
-  EXPECT_EQ("/* aaa aaa\n"
-            " * aaaaa     */",
-            format("/* aaa aaa aaaaa     */", getLLVMStyleWithColumns(15)));
-}
-
-TEST_F(FormatTest, SplitsLongLinesInCommentsInPreprocessor) {
-  EXPECT_EQ("#define X          \\\n"
-            "  /*               \\\n"
-            "   Test            \\\n"
-            "   Macro comment   \\\n"
-            "   with a long     \\\n"
-            "   line            \\\n"
-            "   */              \\\n"
-            "  A + B",
-            format("#define X \\\n"
-                   "  /*\n"
-                   "   Test\n"
-                   "   Macro comment with a long  line\n"
-                   "   */ \\\n"
-                   "  A + B",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("#define X          \\\n"
-            "  /* Macro comment \\\n"
-            "     with a long   \\\n"
-            "     line */       \\\n"
-            "  A + B",
-            format("#define X \\\n"
-                   "  /* Macro comment with a long\n"
-                   "     line */ \\\n"
-                   "  A + B",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("#define X          \\\n"
-            "  /* Macro comment \\\n"
-            "   * with a long   \\\n"
-            "   * line */       \\\n"
-            "  A + B",
-            format("#define X \\\n"
-                   "  /* Macro comment with a long  line */ \\\n"
-                   "  A + B",
-                   getLLVMStyleWithColumns(20)));
-}
-
-TEST_F(FormatTest, CommentsInStaticInitializers) {
-  EXPECT_EQ(
-      "static SomeType type = {aaaaaaaaaaaaaaaaaaaa, /* comment */\n"
-      "                        aaaaaaaaaaaaaaaaaaaa /* comment */,\n"
-      "                        /* comment */ aaaaaaaaaaaaaaaaaaaa,\n"
-      "                        aaaaaaaaaaaaaaaaaaaa, // comment\n"
-      "                        aaaaaaaaaaaaaaaaaaaa};",
-      format("static SomeType type = { aaaaaaaaaaaaaaaaaaaa  ,  /* comment */\n"
-             "                   aaaaaaaaaaaaaaaaaaaa   /* comment */ ,\n"
-             "                     /* comment */   aaaaaaaaaaaaaaaaaaaa ,\n"
-             "              aaaaaaaaaaaaaaaaaaaa ,   // comment\n"
-             "                  aaaaaaaaaaaaaaaaaaaa };"));
-  verifyFormat("static SomeType type = {aaaaaaaaaaa, // comment for aa...\n"
-               "                        bbbbbbbbbbb, ccccccccccc};");
-  verifyFormat("static SomeType type = {aaaaaaaaaaa,\n"
-               "                        // comment for bb....\n"
-               "                        bbbbbbbbbbb, ccccccccccc};");
-  verifyGoogleFormat(
-      "static SomeType type = {aaaaaaaaaaa,  // comment for aa...\n"
-      "                        bbbbbbbbbbb, ccccccccccc};");
-  verifyGoogleFormat("static SomeType type = {aaaaaaaaaaa,\n"
-                     "                        // comment for bb....\n"
-                     "                        bbbbbbbbbbb, ccccccccccc};");
-
-  verifyFormat("S s = {{a, b, c},  // Group #1\n"
-               "       {d, e, f},  // Group #2\n"
-               "       {g, h, i}}; // Group #3");
-  verifyFormat("S s = {{// Group #1\n"
-               "        a, b, c},\n"
-               "       {// Group #2\n"
-               "        d, e, f},\n"
-               "       {// Group #3\n"
-               "        g, h, i}};");
-
-  EXPECT_EQ("S s = {\n"
-            "    // Some comment\n"
-            "    a,\n"
-            "\n"
-            "    // Comment after empty line\n"
-            "    b}",
-            format("S s =    {\n"
-                   "      // Some comment\n"
-                   "  a,\n"
-                   "  \n"
-                   "     // Comment after empty line\n"
-                   "      b\n"
-                   "}"));
-  EXPECT_EQ("S s = {\n"
-            "    /* Some comment */\n"
-            "    a,\n"
-            "\n"
-            "    /* Comment after empty line */\n"
-            "    b}",
-            format("S s =    {\n"
-                   "      /* Some comment */\n"
-                   "  a,\n"
-                   "  \n"
-                   "     /* Comment after empty line */\n"
-                   "      b\n"
-                   "}"));
-  verifyFormat("const uint8_t aaaaaaaaaaaaaaaaaaaaaa[0] = {\n"
-               "    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n"
-               "    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n"
-               "    0x00, 0x00, 0x00, 0x00};            // comment\n");
-}
-
-TEST_F(FormatTest, IgnoresIf0Contents) {
-  EXPECT_EQ("#if 0\n"
-            "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
-            "#endif\n"
-            "void f() {}",
-            format("#if 0\n"
-                   "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
-                   "#endif\n"
-                   "void f(  ) {  }"));
-  EXPECT_EQ("#if false\n"
-            "void f(  ) {  }\n"
-            "#endif\n"
-            "void g() {}\n",
-            format("#if false\n"
-                   "void f(  ) {  }\n"
-                   "#endif\n"
-                   "void g(  ) {  }\n"));
-  EXPECT_EQ("enum E {\n"
-            "  One,\n"
-            "  Two,\n"
-            "#if 0\n"
-            "Three,\n"
-            "      Four,\n"
-            "#endif\n"
-            "  Five\n"
-            "};",
-            format("enum E {\n"
-                   "  One,Two,\n"
-                   "#if 0\n"
-                   "Three,\n"
-                   "      Four,\n"
-                   "#endif\n"
-                   "  Five};"));
-  EXPECT_EQ("enum F {\n"
-            "  One,\n"
-            "#if 1\n"
-            "  Two,\n"
-            "#if 0\n"
-            "Three,\n"
-            "      Four,\n"
-            "#endif\n"
-            "  Five\n"
-            "#endif\n"
-            "};",
-            format("enum F {\n"
-                   "One,\n"
-                   "#if 1\n"
-                   "Two,\n"
-                   "#if 0\n"
-                   "Three,\n"
-                   "      Four,\n"
-                   "#endif\n"
-                   "Five\n"
-                   "#endif\n"
-                   "};"));
-  EXPECT_EQ("enum G {\n"
-            "  One,\n"
-            "#if 0\n"
-            "Two,\n"
-            "#else\n"
-            "  Three,\n"
-            "#endif\n"
-            "  Four\n"
-            "};",
-            format("enum G {\n"
-                   "One,\n"
-                   "#if 0\n"
-                   "Two,\n"
-                   "#else\n"
-                   "Three,\n"
-                   "#endif\n"
-                   "Four\n"
-                   "};"));
-  EXPECT_EQ("enum H {\n"
-            "  One,\n"
-            "#if 0\n"
-            "#ifdef Q\n"
-            "Two,\n"
-            "#else\n"
-            "Three,\n"
-            "#endif\n"
-            "#endif\n"
-            "  Four\n"
-            "};",
-            format("enum H {\n"
-                   "One,\n"
-                   "#if 0\n"
-                   "#ifdef Q\n"
-                   "Two,\n"
-                   "#else\n"
-                   "Three,\n"
-                   "#endif\n"
-                   "#endif\n"
-                   "Four\n"
-                   "};"));
-  EXPECT_EQ("enum I {\n"
-            "  One,\n"
-            "#if /* test */ 0 || 1\n"
-            "Two,\n"
-            "Three,\n"
-            "#endif\n"
-            "  Four\n"
-            "};",
-            format("enum I {\n"
-                   "One,\n"
-                   "#if /* test */ 0 || 1\n"
-                   "Two,\n"
-                   "Three,\n"
-                   "#endif\n"
-                   "Four\n"
-                   "};"));
-  EXPECT_EQ("enum J {\n"
-            "  One,\n"
-            "#if 0\n"
-            "#if 0\n"
-            "Two,\n"
-            "#else\n"
-            "Three,\n"
-            "#endif\n"
-            "Four,\n"
-            "#endif\n"
-            "  Five\n"
-            "};",
-            format("enum J {\n"
-                   "One,\n"
-                   "#if 0\n"
-                   "#if 0\n"
-                   "Two,\n"
-                   "#else\n"
-                   "Three,\n"
-                   "#endif\n"
-                   "Four,\n"
-                   "#endif\n"
-                   "Five\n"
-                   "};"));
-}
-
-//===----------------------------------------------------------------------===//
 // Tests for classes, namespaces, etc.
 //===----------------------------------------------------------------------===//
 
@@ -2066,6 +1029,17 @@
   verifyFormat("class ::A::B {};");
 }
 
+TEST_F(FormatTest, BreakBeforeInheritanceComma) {
+  FormatStyle StyleWithInheritanceBreak = getLLVMStyle();
+  StyleWithInheritanceBreak.BreakBeforeInheritanceComma = true;
+
+  verifyFormat("class MyClass : public X {};", StyleWithInheritanceBreak);
+  verifyFormat("class MyClass\n"
+               "    : public X\n"
+               "    , public Y {};",
+               StyleWithInheritanceBreak);
+}
+
 TEST_F(FormatTest, FormatsVariableDeclarationsAfterStructOrClass) {
   verifyFormat("class A {\n} a, b;");
   verifyFormat("struct A {\n} a, b;");
@@ -2243,33 +1217,43 @@
 }
 
 TEST_F(FormatTest, FormatsNamespaces) {
+  FormatStyle LLVMWithNoNamespaceFix = getLLVMStyle();
+  LLVMWithNoNamespaceFix.FixNamespaceComments = false;
+
   verifyFormat("namespace some_namespace {\n"
                "class A {};\n"
                "void f() { f(); }\n"
-               "}");
+               "}",
+               LLVMWithNoNamespaceFix);
   verifyFormat("namespace {\n"
                "class A {};\n"
                "void f() { f(); }\n"
-               "}");
+               "}",
+               LLVMWithNoNamespaceFix);
   verifyFormat("inline namespace X {\n"
                "class A {};\n"
                "void f() { f(); }\n"
-               "}");
+               "}",
+               LLVMWithNoNamespaceFix);
   verifyFormat("using namespace some_namespace;\n"
                "class A {};\n"
-               "void f() { f(); }");
+               "void f() { f(); }",
+               LLVMWithNoNamespaceFix);
 
   // This code is more common than we thought; if we
   // layout this correctly the semicolon will go into
   // its own line, which is undesirable.
-  verifyFormat("namespace {};");
+  verifyFormat("namespace {};",
+               LLVMWithNoNamespaceFix);
   verifyFormat("namespace {\n"
                "class A {};\n"
-               "};");
+               "};",
+               LLVMWithNoNamespaceFix);
 
   verifyFormat("namespace {\n"
                "int SomeVariable = 0; // comment\n"
-               "} // namespace");
+               "} // namespace",
+               LLVMWithNoNamespaceFix);
   EXPECT_EQ("#ifndef HEADER_GUARD\n"
             "#define HEADER_GUARD\n"
             "namespace my_namespace {\n"
@@ -2281,14 +1265,16 @@
                    "   namespace my_namespace {\n"
                    "int i;\n"
                    "}    // my_namespace\n"
-                   "#endif    // HEADER_GUARD"));
+                   "#endif    // HEADER_GUARD",
+                   LLVMWithNoNamespaceFix));
 
   EXPECT_EQ("namespace A::B {\n"
             "class C {};\n"
             "}",
             format("namespace A::B {\n"
                    "class C {};\n"
-                   "}"));
+                   "}",
+                   LLVMWithNoNamespaceFix));
 
   FormatStyle Style = getLLVMStyle();
   Style.NamespaceIndentation = FormatStyle::NI_All;
@@ -2296,14 +1282,14 @@
             "  int i;\n"
             "  namespace in {\n"
             "    int i;\n"
-            "  } // namespace\n"
-            "} // namespace",
+            "  } // namespace in\n"
+            "} // namespace out",
             format("namespace out {\n"
                    "int i;\n"
                    "namespace in {\n"
                    "int i;\n"
-                   "} // namespace\n"
-                   "} // namespace",
+                   "} // namespace in\n"
+                   "} // namespace out",
                    Style));
 
   Style.NamespaceIndentation = FormatStyle::NI_Inner;
@@ -2311,14 +1297,14 @@
             "int i;\n"
             "namespace in {\n"
             "  int i;\n"
-            "} // namespace\n"
-            "} // namespace",
+            "} // namespace in\n"
+            "} // namespace out",
             format("namespace out {\n"
                    "int i;\n"
                    "namespace in {\n"
                    "int i;\n"
-                   "} // namespace\n"
-                   "} // namespace",
+                   "} // namespace in\n"
+                   "} // namespace out",
                    Style));
 }
 
@@ -2493,42 +1479,6 @@
                Style);
 }
 
-TEST_F(FormatTest, FormatObjCTryCatch) {
-  verifyFormat("@try {\n"
-               "  f();\n"
-               "} @catch (NSException e) {\n"
-               "  @throw;\n"
-               "} @finally {\n"
-               "  exit(42);\n"
-               "}");
-  verifyFormat("DEBUG({\n"
-               "  @try {\n"
-               "  } @finally {\n"
-               "  }\n"
-               "});\n");
-}
-
-TEST_F(FormatTest, FormatObjCAutoreleasepool) {
-  FormatStyle Style = getLLVMStyle();
-  verifyFormat("@autoreleasepool {\n"
-               "  f();\n"
-               "}\n"
-               "@autoreleasepool {\n"
-               "  f();\n"
-               "}\n",
-               Style);
-  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
-  verifyFormat("@autoreleasepool\n"
-               "{\n"
-               "  f();\n"
-               "}\n"
-               "@autoreleasepool\n"
-               "{\n"
-               "  f();\n"
-               "}\n",
-               Style);
-}
-
 TEST_F(FormatTest, StaticInitializers) {
   verifyFormat("static SomeClass SC = {1, 'a'};");
 
@@ -2858,11 +1808,11 @@
   EXPECT_EQ("SOME_MACRO\n"
             "namespace {\n"
             "void f();\n"
-            "}",
+            "} // namespace",
             format("SOME_MACRO\n"
                    "  namespace    {\n"
                    "void   f(  );\n"
-                   "}"));
+                   "} // namespace"));
   // Only if the identifier contains at least 5 characters.
   EXPECT_EQ("HTTP f();", format("HTTP\nf();"));
   EXPECT_EQ("MACRO\nf();", format("MACRO\nf();"));
@@ -3057,21 +2007,10 @@
       format("#define A \\\nint i;\\\n  int j;", getLLVMStyleWithColumns(11)));
   EXPECT_EQ("#define A\n\nint i;", format("#define A \\\n\n int i;"));
   EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();"));
-  EXPECT_EQ("/* \\  \\  \\\n*/", format("\\\n/* \\  \\  \\\n*/"));
+  EXPECT_EQ("/* \\  \\  \\\n */", format("\\\n/* \\  \\  \\\n */"));
   EXPECT_EQ("<a\n\\\\\n>", format("<a\n\\\\\n>"));
 }
 
-TEST_F(FormatTest, DontCrashOnBlockComments) {
-  EXPECT_EQ(
-      "int xxxxxxxxx; /* "
-      "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n"
-      "zzzzzz\n"
-      "0*/",
-      format("int xxxxxxxxx;                          /* "
-             "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzz\n"
-             "0*/"));
-}
-
 TEST_F(FormatTest, CalculateSpaceOnConsecutiveLinesInMacro) {
   verifyFormat("#define A \\\n"
                "  int v(  \\\n"
@@ -3389,9 +2328,10 @@
       "    aaaaaaaaaaaaaaaaaaaaaaaa<\n"
       "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>,\n"
       "    aaaaaaaaaaaaaaaaaaaaaaaa>;");
-  verifyFormat("int a = bbbb && ccc && fffff(\n"
+  verifyFormat("int a = bbbb && ccc &&\n"
+               "        fffff(\n"
                "#define A Just forcing a new line\n"
-               "                           ddd);");
+               "            ddd);");
 }
 
 TEST_F(FormatTest, LineBreakingInBinaryExpressions) {
@@ -3474,6 +2414,12 @@
       "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
       "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}",
       OnePerLine);
+
+  verifyFormat("int i = someFunction(aaaaaaa, 0)\n"
+               "                .aaa(aaaaaaaaaaaaa) *\n"
+               "            aaaaaaa +\n"
+               "        aaaaaaa;",
+               getLLVMStyleWithColumns(40));
 }
 
 TEST_F(FormatTest, ExpressionIndentation) {
@@ -3499,9 +2445,14 @@
                "            aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n"
                "        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}");
   verifyFormat("if () {\n"
+               "} else if (aaaaa && bbbbb > // break\n"
+               "                        ccccc) {\n"
+               "}");
+  verifyFormat("if () {\n"
                "} else if (aaaaa &&\n"
                "           bbbbb > // break\n"
-               "               ccccc) {\n"
+               "               ccccc &&\n"
+               "           ddddd) {\n"
                "}");
 
   // Presence of a trailing comment used to change indentation of b.
@@ -3585,9 +2536,22 @@
                Style);
 }
 
+TEST_F(FormatTest, EnforcedOperatorWraps) {
+  // Here we'd like to wrap after the || operators, but a comment is forcing an
+  // earlier wrap.
+  verifyFormat("bool x = aaaaa //\n"
+               "         || bbbbb\n"
+               "         //\n"
+               "         || cccc;");
+}
+
 TEST_F(FormatTest, NoOperandAlignment) {
   FormatStyle Style = getLLVMStyle();
   Style.AlignOperands = false;
+  verifyFormat("aaaaaaaaaaaaaa(aaaaaaaaaaaa,\n"
+               "               aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n"
+               "                   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);",
+               Style);
   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
   verifyFormat("bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
                "            + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
@@ -3606,7 +2570,7 @@
                Style);
   verifyFormat("int a = aa\n"
                "    + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
-               "        * cccccccccccccccccccccccccccccccccccc;",
+               "        * cccccccccccccccccccccccccccccccccccc;\n",
                Style);
 
   Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
@@ -4080,8 +3044,9 @@
                "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa));");
 
   verifyFormat(
-      "aaaaaaaa(aaaaaaaaaaaaa, aaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
-      "                            aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)),\n"
+      "aaaaaaaa(aaaaaaaaaaaaa,\n"
+      "         aaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+      "             aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)),\n"
       "         aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
       "             aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)));");
 
@@ -4099,6 +3064,11 @@
   verifyFormat(
       "aaaaaa(aaa, new Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
       "                aaaaaaaaaaaaaaaaaaaaaaaaaaaaa));");
+  verifyFormat(
+      "aaaaaa(aaa,\n"
+      "       new Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+      "           aaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n"
+      "       aaaa);");
   verifyFormat("aaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n"
                "                      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
                "                  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
@@ -4577,11 +3547,18 @@
 
 TEST_F(FormatTest, BreaksConditionalExpressions) {
   verifyFormat(
-      "aaaa(aaaaaaaaaaaaaaaaaaaa,\n"
+      "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "                               ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "                               : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+  verifyFormat(
+      "aaaa(aaaaaaaaaa, aaaaaaaa,\n"
       "     aaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
       "                                : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
   verifyFormat(
-      "aaaa(aaaaaaaaaaaaaaaaaaaa,\n"
+      "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "                                   : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+  verifyFormat(
+      "aaaa(aaaaaaaaa, aaaaaaaaa,\n"
       "     aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
       "             : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
   verifyFormat(
@@ -4656,10 +3633,9 @@
       "                                            aaaaaaaaaaaaaaaaaaaaa\n"
       "                                      : aaaaaaaaaa;");
   verifyFormat(
-      "aaaaaa = aaaaaaaaaaaa\n"
-      "             ? aaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "                          : aaaaaaaaaaaaaaaaaaaaaa\n"
-      "             : aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+      "aaaaaa = aaaaaaaaaaaa ? aaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "                                   : aaaaaaaaaaaaaaaaaaaaaa\n"
+      "                      : aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
 
   FormatStyle NoBinPacking = getLLVMStyle();
   NoBinPacking.BinPackArguments = false;
@@ -4713,12 +3689,21 @@
   Style.BreakBeforeTernaryOperators = false;
   Style.ColumnLimit = 70;
   verifyFormat(
-      "aaaa(aaaaaaaaaaaaaaaaaaaa,\n"
+      "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa ?\n"
+      "                               aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n"
+      "                               aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);",
+      Style);
+  verifyFormat(
+      "aaaa(aaaaaaaaaa, aaaaaaaa,\n"
       "     aaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n"
       "                                  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);",
       Style);
   verifyFormat(
-      "aaaa(aaaaaaaaaaaaaaaaaaaa,\n"
+      "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n"
+      "                                     aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);",
+      Style);
+  verifyFormat(
+      "aaaa(aaaaaaaa, aaaaaaaaaa,\n"
       "     aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n"
       "               aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);",
       Style);
@@ -4859,7 +3844,7 @@
   EXPECT_EQ("fun + \"1243\" /* comment */\n"
             "      \"5678\";",
             format("fun + \"1243\" /* comment */\n"
-                   "      \"5678\";",
+                   "    \"5678\";",
                    getLLVMStyleWithColumns(28)));
   EXPECT_EQ(
       "aaaaaa = \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa \"\n"
@@ -5128,6 +4113,9 @@
       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
       "                                 << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
   verifyFormat(
+      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n"
+      "    << aaaaaaaaaaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+  verifyFormat(
       "llvm::outs() << \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
       "                \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"\n"
       "             << \"ccccccccccccccccccccccccccccccccccccccccccccccccc\";");
@@ -5145,29 +4133,6 @@
       "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
       "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
 
-  verifyFormat("return out << \"somepacket = {\\n\"\n"
-               "           << \" aaaaaa = \" << pkt.aaaaaa << \"\\n\"\n"
-               "           << \" bbbb = \" << pkt.bbbb << \"\\n\"\n"
-               "           << \" cccccc = \" << pkt.cccccc << \"\\n\"\n"
-               "           << \" ddd = [\" << pkt.ddd << \"]\\n\"\n"
-               "           << \"}\";");
-
-  verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaa\n"
-               "             << \"aaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaa\n"
-               "             << \"aaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaa;");
-  verifyFormat(
-      "llvm::outs() << \"aaaaaaaaaaaaaaaaa = \" << aaaaaaaaaaaaaaaaa\n"
-      "             << \"bbbbbbbbbbbbbbbbb = \" << bbbbbbbbbbbbbbbbb\n"
-      "             << \"ccccccccccccccccc = \" << ccccccccccccccccc\n"
-      "             << \"ddddddddddddddddd = \" << ddddddddddddddddd\n"
-      "             << \"eeeeeeeeeeeeeeeee = \" << eeeeeeeeeeeeeeeee;");
-  verifyFormat("llvm::outs() << aaaaaaaaaaaaaaaaaaaaaaaa << \"=\"\n"
-               "             << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;");
-  verifyFormat(
-      "void f() {\n"
-      "  llvm::outs() << \"aaaaaaaaaaaaaaaaaaaa: \"\n"
-      "               << aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n"
-      "}");
   verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \"\n"
                "             << aaaaaaaa.aaaaaaaaaaaa(aaa)->aaaaaaaaaaaaaa();");
   verifyFormat("llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
@@ -5178,22 +4143,6 @@
                "       bbb)\n"
                "    << a << b;");
 
-  // Breaking before the first "<<" is generally not desirable.
-  verifyFormat(
-      "llvm::errs()\n"
-      "    << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
-      getLLVMStyleWithColumns(70));
-  verifyFormat("llvm::errs() << \"aaaaaaaaaaaaaaaaaaa: \"\n"
-               "             << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-               "             << \"aaaaaaaaaaaaaaaaaaa: \"\n"
-               "             << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-               "             << \"aaaaaaaaaaaaaaaaaaa: \"\n"
-               "             << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
-               getLLVMStyleWithColumns(70));
-
   // But sometimes, breaking before the first "<<" is desirable.
   verifyFormat("Diag(aaaaaaaaaaaaaaaaaaaa, aaaaaaaa)\n"
                "    << aaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa);");
@@ -5239,6 +4188,65 @@
   verifyFormat("llvm::errs() << \"\\n\" << bbbbbbbbbbbbbbbbbbbbbb << \"\\n\";");
 }
 
+TEST_F(FormatTest, KeepStringLabelValuePairsOnALine) {
+  verifyFormat("return out << \"somepacket = {\\n\"\n"
+               "           << \" aaaaaa = \" << pkt.aaaaaa << \"\\n\"\n"
+               "           << \" bbbb = \" << pkt.bbbb << \"\\n\"\n"
+               "           << \" cccccc = \" << pkt.cccccc << \"\\n\"\n"
+               "           << \" ddd = [\" << pkt.ddd << \"]\\n\"\n"
+               "           << \"}\";");
+
+  verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaa\n"
+               "             << \"aaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaa\n"
+               "             << \"aaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaa;");
+  verifyFormat(
+      "llvm::outs() << \"aaaaaaaaaaaaaaaaa = \" << aaaaaaaaaaaaaaaaa\n"
+      "             << \"bbbbbbbbbbbbbbbbb = \" << bbbbbbbbbbbbbbbbb\n"
+      "             << \"ccccccccccccccccc = \" << ccccccccccccccccc\n"
+      "             << \"ddddddddddddddddd = \" << ddddddddddddddddd\n"
+      "             << \"eeeeeeeeeeeeeeeee = \" << eeeeeeeeeeeeeeeee;");
+  verifyFormat("llvm::outs() << aaaaaaaaaaaaaaaaaaaaaaaa << \"=\"\n"
+               "             << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;");
+  verifyFormat(
+      "void f() {\n"
+      "  llvm::outs() << \"aaaaaaaaaaaaaaaaaaaa: \"\n"
+      "               << aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n"
+      "}");
+
+  // Breaking before the first "<<" is generally not desirable.
+  verifyFormat(
+      "llvm::errs()\n"
+      "    << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "    << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "    << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "    << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
+      getLLVMStyleWithColumns(70));
+  verifyFormat("llvm::errs() << \"aaaaaaaaaaaaaaaaaaa: \"\n"
+               "             << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+               "             << \"aaaaaaaaaaaaaaaaaaa: \"\n"
+               "             << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+               "             << \"aaaaaaaaaaaaaaaaaaa: \"\n"
+               "             << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
+               getLLVMStyleWithColumns(70));
+
+  verifyFormat("string v = \"aaaaaaaaaaaaaaaa: \" + aaaaaaaaaaaaaaaa +\n"
+               "           \"aaaaaaaaaaaaaaaa: \" + aaaaaaaaaaaaaaaa +\n"
+               "           \"aaaaaaaaaaaaaaaa: \" + aaaaaaaaaaaaaaaa;");
+  verifyFormat("string v = StrCat(\"aaaaaaaaaaaaaaaa: \", aaaaaaaaaaaaaaaa,\n"
+               "                  \"aaaaaaaaaaaaaaaa: \", aaaaaaaaaaaaaaaa,\n"
+               "                  \"aaaaaaaaaaaaaaaa: \", aaaaaaaaaaaaaaaa);");
+  verifyFormat("string v = \"aaaaaaaaaaaaaaaa: \" +\n"
+               "           (aaaa + aaaa);",
+               getLLVMStyleWithColumns(40));
+  verifyFormat("string v = StrCat(\"aaaaaaaaaaaa: \" +\n"
+               "                  (aaaaaaa + aaaaa));",
+               getLLVMStyleWithColumns(40));
+  verifyFormat(
+      "string v = StrCat(\"aaaaaaaaaaaaaaaaaaaaaaaaaaa: \",\n"
+      "                  SomeFunction(aaaaaaaaaaaa, aaaaaaaa.aaaaaaa),\n"
+      "                  bbbbbbbbbbbbbbbbbbbbbbb);");
+}
+
 TEST_F(FormatTest, UnderstandsEquals) {
   verifyFormat(
       "aaaaaaaaaaaaaaaaa =\n"
@@ -5438,6 +4446,44 @@
                "};");
 }
 
+TEST_F(FormatTest, WrapsTemplateParameters) {
+  FormatStyle Style = getLLVMStyle();
+  Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
+  Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
+  verifyFormat(
+      "template <typename... a> struct q {};\n"
+      "extern q<aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa,\n"
+      "    aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>\n"
+      "    y;",
+      Style);
+  Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
+  Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
+  verifyFormat(
+      "template <typename... a> struct r {};\n"
+      "extern r<aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa,\n"
+      "    aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>\n"
+      "    y;",
+      Style);
+  Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
+  Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
+  verifyFormat(
+      "template <typename... a> struct s {};\n"
+      "extern s<\n"
+      "    aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n"
+      "    aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa>\n"
+      "    y;",
+      Style);
+  Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
+  Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
+  verifyFormat(
+      "template <typename... a> struct t {};\n"
+      "extern t<\n"
+      "    aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n"
+      "    aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa>\n"
+      "    y;",
+      Style);
+}
+
 TEST_F(FormatTest, WrapsAtNestedNameSpecifiers) {
   verifyFormat(
       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n"
@@ -5463,8 +4509,9 @@
       "    aaaaaaaaaaaaaaaaaaaaaaa);");
 
   verifyFormat(
-      "aaaaaaaaaaaaaaaaaa(aaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n"
-      "                                 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+      "aaaaaaaaaaaaaaaaaa(aaaaaaaa,\n"
+      "                   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n"
+      "                       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
       "                   aaaaaaaaaaaaaaaaaaaaa);",
       getLLVMStyleWithColumns(74));
 
@@ -5793,6 +4840,10 @@
   verifyGoogleFormat("MACRO Constructor(const int& i) : a(a), b(b) {}");
   verifyFormat("void f() { f(a, c * d); }");
   verifyFormat("void f() { f(new a(), c * d); }");
+  verifyFormat("void f(const MyOverride &override);");
+  verifyFormat("void f(const MyFinal &final);");
+  verifyIndependentOfContext("bool a = f() && override.f();");
+  verifyIndependentOfContext("bool a = f() && final.f();");
 
   verifyIndependentOfContext("InvalidRegions[*R] = 0;");
 
@@ -5902,10 +4953,17 @@
   verifyFormat("foo<b & 1>();");
   verifyFormat("decltype(*::std::declval<const T &>()) void F();");
   verifyFormat(
+      "template <class T, class = typename std::enable_if<\n"
+      "                       std::is_integral<T>::value &&\n"
+      "                       (sizeof(T) > 1 || sizeof(T) < 8)>::type>\n"
+      "void F();",
+      getLLVMStyleWithColumns(70));
+  verifyFormat(
       "template <class T,\n"
       "          class = typename std::enable_if<\n"
       "              std::is_integral<T>::value &&\n"
-      "              (sizeof(T) > 1 || sizeof(T) < 8)>::type>\n"
+      "              (sizeof(T) > 1 || sizeof(T) < 8)>::type,\n"
+      "          class U>\n"
       "void F();",
       getLLVMStyleWithColumns(70));
   verifyFormat(
@@ -5918,6 +4976,7 @@
   verifyIndependentOfContext("MACRO(int *i);");
   verifyIndependentOfContext("MACRO(auto *a);");
   verifyIndependentOfContext("MACRO(const A *a);");
+  verifyIndependentOfContext("MACRO(A *const a);");
   verifyIndependentOfContext("MACRO('0' <= c && c <= '9');");
   verifyFormat("void f() { f(float{1}, a * a); }");
   // FIXME: Is there a way to make this work?
@@ -6182,6 +5241,11 @@
                "    LoooooooooooooooooooooooooooooooooooooooongVariable({});");
   verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
                "    LoooooooooooooooooooooooooooooooooooooongVariable([A a]);");
+
+  // Lambdas should not confuse the variable declaration heuristic.
+  verifyFormat("LooooooooooooooooongType\n"
+               "    variable(nullptr, [](A *a) {});",
+               getLLVMStyleWithColumns(40));
 }
 
 TEST_F(FormatTest, BreaksLongDeclarations) {
@@ -6273,6 +5337,11 @@
                "    vector<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n"
                "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>>\n"
                "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+
+  verifyFormat("template <typename T> // Templates on own line.\n"
+               "static int            // Some comment.\n"
+               "MyFunction(int a);",
+               getLLVMStyle());
 }
 
 TEST_F(FormatTest, FormatsArrays) {
@@ -6342,6 +5411,11 @@
 
   verifyFormat("#define MY_IMPORT <a/b>");
 
+  verifyFormat("#if __has_include(<a/b>)");
+  verifyFormat("#if __has_include_next(<a/b>)");
+  verifyFormat("#define F __has_include(<a/b>)");
+  verifyFormat("#define F __has_include_next(<a/b>)");
+
   // Protocol buffer definition or missing "#".
   verifyFormat("import \"aaaaaaaaaaaaaaaaa/aaaaaaaaaaaaaaa\";",
                getLLVMStyleWithColumns(30));
@@ -6402,7 +5476,7 @@
   EXPECT_EQ("namespace N {\n"
             "void f() {}\n"
             "void g()\n"
-            "}",
+            "} // namespace N",
             format("namespace N  { void f( ) { } void g( ) }"));
 }
 
@@ -6462,7 +5536,7 @@
   verifyIncompleteFormat("namespace {\n"
                          "class Foo { Foo (\n"
                          "};\n"
-                         "} // comment");
+                         "} // namespace");
 }
 
 TEST_F(FormatTest, IncorrectCodeErrorDetection) {
@@ -6540,6 +5614,19 @@
                "};");
   verifyFormat("#define A {a, a},");
 
+  // Cases where distinguising braced lists and blocks is hard.
+  verifyFormat("vector<int> v{12} GUARDED_BY(mutex);");
+  verifyFormat("void f() {\n"
+               "  return; // comment\n"
+               "}\n"
+               "SomeType t;");
+  verifyFormat("void f() {\n"
+               "  if (a) {\n"
+               "    f();\n"
+               "  }\n"
+               "}\n"
+               "SomeType t;");
+
   // In combination with BinPackArguments = false.
   FormatStyle NoBinPacking = getLLVMStyle();
   NoBinPacking.BinPackArguments = false;
@@ -6654,7 +5741,7 @@
       "std::this_thread::sleep_for(\n"
       "    std::chrono::nanoseconds{ std::chrono::seconds{ 1 } } / 5);",
       ExtraSpaces);
-  verifyFormat("std::vector<MyValues> aaaaaaaaaaaaaaaaaaa{\n"
+  verifyFormat("std::vector<MyValues> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{\n"
                "    aaaaaaa,\n"
                "    aaaaaaaaaa,\n"
                "    aaaaa,\n"
@@ -6792,6 +5879,37 @@
       "                          1, 22, 333, 4444, 55555, 666666, 7777777,\n"
       "                          1, 22, 333, 4444, 55555, 666666, 7777777,\n"
       "                          1, 22, 333, 4444, 55555, 666666, 7777777});");
+
+  // Allow "single-column" layout even if that violates the column limit. There
+  // isn't going to be a better way.
+  verifyFormat("std::vector<int> a = {\n"
+               "    aaaaaaaa,\n"
+               "    aaaaaaaa,\n"
+               "    aaaaaaaa,\n"
+               "    aaaaaaaa,\n"
+               "    aaaaaaaaaa,\n"
+               "    aaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaa};",
+               getLLVMStyleWithColumns(30));
+  verifyFormat("vector<int> aaaa = {\n"
+               "    aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaa.aaaaaaa,\n"
+               "    aaaaaa.aaaaaaa,\n"
+               "    aaaaaa.aaaaaaa,\n"
+               "    aaaaaa.aaaaaaa,\n"
+               "};");
+
+  // Don't create hanging lists.
+  verifyFormat("someFunction(Param, {List1, List2,\n"
+               "                     List3});",
+               getLLVMStyleWithColumns(35));
+  verifyFormat("someFunction(Param, Param,\n"
+               "             {List1, List2,\n"
+               "              List3});",
+               getLLVMStyleWithColumns(35));
+  verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaa, {},\n"
+               "                               aaaaaaaaaaaaaaaaaaaaaaa);");
 }
 
 TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
@@ -7027,188 +6145,6 @@
                ShortMergedIf);
 }
 
-TEST_F(FormatTest, BlockCommentsInControlLoops) {
-  verifyFormat("if (0) /* a comment in a strange place */ {\n"
-               "  f();\n"
-               "}");
-  verifyFormat("if (0) /* a comment in a strange place */ {\n"
-               "  f();\n"
-               "} /* another comment */ else /* comment #3 */ {\n"
-               "  g();\n"
-               "}");
-  verifyFormat("while (0) /* a comment in a strange place */ {\n"
-               "  f();\n"
-               "}");
-  verifyFormat("for (;;) /* a comment in a strange place */ {\n"
-               "  f();\n"
-               "}");
-  verifyFormat("do /* a comment in a strange place */ {\n"
-               "  f();\n"
-               "} /* another comment */ while (0);");
-}
-
-TEST_F(FormatTest, BlockComments) {
-  EXPECT_EQ("/* */ /* */ /* */\n/* */ /* */ /* */",
-            format("/* *//* */  /* */\n/* *//* */  /* */"));
-  EXPECT_EQ("/* */ a /* */ b;", format("  /* */  a/* */  b;"));
-  EXPECT_EQ("#define A /*123*/ \\\n"
-            "  b\n"
-            "/* */\n"
-            "someCall(\n"
-            "    parameter);",
-            format("#define A /*123*/ b\n"
-                   "/* */\n"
-                   "someCall(parameter);",
-                   getLLVMStyleWithColumns(15)));
-
-  EXPECT_EQ("#define A\n"
-            "/* */ someCall(\n"
-            "    parameter);",
-            format("#define A\n"
-                   "/* */someCall(parameter);",
-                   getLLVMStyleWithColumns(15)));
-  EXPECT_EQ("/*\n**\n*/", format("/*\n**\n*/"));
-  EXPECT_EQ("/*\n"
-            "*\n"
-            " * aaaaaa\n"
-            " * aaaaaa\n"
-            "*/",
-            format("/*\n"
-                   "*\n"
-                   " * aaaaaa aaaaaa\n"
-                   "*/",
-                   getLLVMStyleWithColumns(10)));
-  EXPECT_EQ("/*\n"
-            "**\n"
-            "* aaaaaa\n"
-            "*aaaaaa\n"
-            "*/",
-            format("/*\n"
-                   "**\n"
-                   "* aaaaaa aaaaaa\n"
-                   "*/",
-                   getLLVMStyleWithColumns(10)));
-  EXPECT_EQ("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
-            "    /* line 1\n"
-            "       bbbbbbbbbbbb */\n"
-            "    bbbbbbbbbbbbbbbbbbbbbbbbbbbb;",
-            format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
-                   "    /* line 1\n"
-                   "       bbbbbbbbbbbb */ bbbbbbbbbbbbbbbbbbbbbbbbbbbb;",
-            getLLVMStyleWithColumns(50)));
-
-  FormatStyle NoBinPacking = getLLVMStyle();
-  NoBinPacking.BinPackParameters = false;
-  EXPECT_EQ("someFunction(1, /* comment 1 */\n"
-            "             2, /* comment 2 */\n"
-            "             3, /* comment 3 */\n"
-            "             aaaa,\n"
-            "             bbbb);",
-            format("someFunction (1,   /* comment 1 */\n"
-                   "                2, /* comment 2 */  \n"
-                   "               3,   /* comment 3 */\n"
-                   "aaaa, bbbb );",
-                   NoBinPacking));
-  verifyFormat(
-      "bool aaaaaaaaaaaaa = /* comment: */ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
-      "                     aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
-  EXPECT_EQ(
-      "bool aaaaaaaaaaaaa = /* trailing comment */\n"
-      "    aaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
-      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaa;",
-      format(
-          "bool       aaaaaaaaaaaaa =       /* trailing comment */\n"
-          "    aaaaaaaaaaaaaaaaaaaaaaaaaaa||aaaaaaaaaaaaaaaaaaaaaaaaa    ||\n"
-          "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa   || aaaaaaaaaaaaaaaaaaaaaaaaaa;"));
-  EXPECT_EQ(
-      "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n"
-      "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;   /* comment */\n"
-      "int cccccccccccccccccccccccccccccc;       /* comment */\n",
-      format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n"
-             "int      bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n"
-             "int    cccccccccccccccccccccccccccccc;  /* comment */\n"));
-
-  verifyFormat("void f(int * /* unused */) {}");
-
-  EXPECT_EQ("/*\n"
-            " **\n"
-            " */",
-            format("/*\n"
-                   " **\n"
-                   " */"));
-  EXPECT_EQ("/*\n"
-            " *q\n"
-            " */",
-            format("/*\n"
-                   " *q\n"
-                   " */"));
-  EXPECT_EQ("/*\n"
-            " * q\n"
-            " */",
-            format("/*\n"
-                   " * q\n"
-                   " */"));
-  EXPECT_EQ("/*\n"
-            " **/",
-            format("/*\n"
-                   " **/"));
-  EXPECT_EQ("/*\n"
-            " ***/",
-            format("/*\n"
-                   " ***/"));
-}
-
-TEST_F(FormatTest, BlockCommentsInMacros) {
-  EXPECT_EQ("#define A          \\\n"
-            "  {                \\\n"
-            "    /* one line */ \\\n"
-            "    someCall();",
-            format("#define A {        \\\n"
-                   "  /* one line */   \\\n"
-                   "  someCall();",
-                   getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("#define A          \\\n"
-            "  {                \\\n"
-            "    /* previous */ \\\n"
-            "    /* one line */ \\\n"
-            "    someCall();",
-            format("#define A {        \\\n"
-                   "  /* previous */   \\\n"
-                   "  /* one line */   \\\n"
-                   "  someCall();",
-                   getLLVMStyleWithColumns(20)));
-}
-
-TEST_F(FormatTest, BlockCommentsAtEndOfLine) {
-  EXPECT_EQ("a = {\n"
-            "    1111 /*    */\n"
-            "};",
-            format("a = {1111 /*    */\n"
-                   "};",
-                   getLLVMStyleWithColumns(15)));
-  EXPECT_EQ("a = {\n"
-            "    1111 /*      */\n"
-            "};",
-            format("a = {1111 /*      */\n"
-                   "};",
-                   getLLVMStyleWithColumns(15)));
-
-  // FIXME: The formatting is still wrong here.
-  EXPECT_EQ("a = {\n"
-            "    1111 /*      a\n"
-            "            */\n"
-            "};",
-            format("a = {1111 /*      a */\n"
-                   "};",
-                   getLLVMStyleWithColumns(15)));
-}
-
-TEST_F(FormatTest, IndentLineCommentsInStartOfBlockAtEndOfFile) {
-  verifyFormat("{\n"
-               "  // a\n"
-               "  // b");
-}
-
 TEST_F(FormatTest, FormatStarDependingOnContext) {
   verifyFormat("void f(int *a);");
   verifyFormat("void f() { f(fint * b); }");
@@ -7220,8 +6156,8 @@
                "  void f() {}\n"
                "  int *a;\n"
                "};\n"
-               "}\n"
-               "}");
+               "} // namespace b\n"
+               "} // namespace a");
 }
 
 TEST_F(FormatTest, SpecialTokensAtEndOfLine) {
@@ -7323,704 +6259,6 @@
   verifyGoogleFormat("- foo:(int)foo;");
 }
 
-TEST_F(FormatTest, FormatObjCInterface) {
-  verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
-               "@public\n"
-               "  int field1;\n"
-               "@protected\n"
-               "  int field2;\n"
-               "@private\n"
-               "  int field3;\n"
-               "@package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyGoogleFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
-                     " @public\n"
-                     "  int field1;\n"
-                     " @protected\n"
-                     "  int field2;\n"
-                     " @private\n"
-                     "  int field3;\n"
-                     " @package\n"
-                     "  int field4;\n"
-                     "}\n"
-                     "+ (id)init;\n"
-                     "@end");
-
-  verifyFormat("@interface /* wait for it */ Foo\n"
-               "+ (id)init;\n"
-               "// Look, a comment!\n"
-               "- (int)answerWith:(int)i;\n"
-               "@end");
-
-  verifyFormat("@interface Foo\n"
-               "@end\n"
-               "@interface Bar\n"
-               "@end");
-
-  verifyFormat("@interface Foo : Bar\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo : /**/ Bar /**/ <Baz, /**/ Quux>\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyGoogleFormat("@interface Foo : Bar<Baz, Quux>\n"
-                     "+ (id)init;\n"
-                     "@end");
-
-  verifyFormat("@interface Foo (HackStuff)\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo ()\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyGoogleFormat("@interface Foo (HackStuff)<MyProtocol>\n"
-                     "+ (id)init;\n"
-                     "@end");
-
-  verifyFormat("@interface Foo {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo : Bar {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo : Bar <Baz, Quux> {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff) {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo () {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff) <MyProtocol> {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  FormatStyle OnePerLine = getGoogleStyle();
-  OnePerLine.BinPackParameters = false;
-  verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
-               "}",
-               OnePerLine);
-}
-
-TEST_F(FormatTest, FormatObjCImplementation) {
-  verifyFormat("@implementation Foo : NSObject {\n"
-               "@public\n"
-               "  int field1;\n"
-               "@protected\n"
-               "  int field2;\n"
-               "@private\n"
-               "  int field3;\n"
-               "@package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-
-  verifyGoogleFormat("@implementation Foo : NSObject {\n"
-                     " @public\n"
-                     "  int field1;\n"
-                     " @protected\n"
-                     "  int field2;\n"
-                     " @private\n"
-                     "  int field3;\n"
-                     " @package\n"
-                     "  int field4;\n"
-                     "}\n"
-                     "+ (id)init {\n}\n"
-                     "@end");
-
-  verifyFormat("@implementation Foo\n"
-               "+ (id)init {\n"
-               "  if (true)\n"
-               "    return nil;\n"
-               "}\n"
-               "// Look, a comment!\n"
-               "- (int)answerWith:(int)i {\n"
-               "  return i;\n"
-               "}\n"
-               "+ (int)answerWith:(int)i {\n"
-               "  return i;\n"
-               "}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo\n"
-               "@end\n"
-               "@implementation Bar\n"
-               "@end");
-
-  EXPECT_EQ("@implementation Foo : Bar\n"
-            "+ (id)init {\n}\n"
-            "- (void)foo {\n}\n"
-            "@end",
-            format("@implementation Foo : Bar\n"
-                   "+(id)init{}\n"
-                   "-(void)foo{}\n"
-                   "@end"));
-
-  verifyFormat("@implementation Foo {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo : Bar {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo (HackStuff)\n"
-               "+ (id)init {\n}\n"
-               "@end");
-  verifyFormat("@implementation ObjcClass\n"
-               "- (void)method;\n"
-               "{}\n"
-               "@end");
-}
-
-TEST_F(FormatTest, FormatObjCProtocol) {
-  verifyFormat("@protocol Foo\n"
-               "@property(weak) id delegate;\n"
-               "- (NSUInteger)numberOfThings;\n"
-               "@end");
-
-  verifyFormat("@protocol MyProtocol <NSObject>\n"
-               "- (NSUInteger)numberOfThings;\n"
-               "@end");
-
-  verifyGoogleFormat("@protocol MyProtocol<NSObject>\n"
-                     "- (NSUInteger)numberOfThings;\n"
-                     "@end");
-
-  verifyFormat("@protocol Foo;\n"
-               "@protocol Bar;\n");
-
-  verifyFormat("@protocol Foo\n"
-               "@end\n"
-               "@protocol Bar\n"
-               "@end");
-
-  verifyFormat("@protocol myProtocol\n"
-               "- (void)mandatoryWithInt:(int)i;\n"
-               "@optional\n"
-               "- (void)optional;\n"
-               "@required\n"
-               "- (void)required;\n"
-               "@optional\n"
-               "@property(assign) int madProp;\n"
-               "@end\n");
-
-  verifyFormat("@property(nonatomic, assign, readonly)\n"
-               "    int *looooooooooooooooooooooooooooongNumber;\n"
-               "@property(nonatomic, assign, readonly)\n"
-               "    NSString *looooooooooooooooooooooooooooongName;");
-
-  verifyFormat("@implementation PR18406\n"
-               "}\n"
-               "@end");
-}
-
-TEST_F(FormatTest, FormatObjCMethodDeclarations) {
-  verifyFormat("- (void)doSomethingWith:(GTMFoo *)theFoo\n"
-               "                   rect:(NSRect)theRect\n"
-               "               interval:(float)theInterval {\n"
-               "}");
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "      longKeyword:(NSRect)theRect\n"
-               "    longerKeyword:(float)theInterval\n"
-               "            error:(NSError **)theError {\n"
-               "}");
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "          longKeyword:(NSRect)theRect\n"
-               "    evenLongerKeyword:(float)theInterval\n"
-               "                error:(NSError **)theError {\n"
-               "}");
-  verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n"
-               "                         y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n"
-               "    NS_DESIGNATED_INITIALIZER;",
-               getLLVMStyleWithColumns(60));
-
-  // Continuation indent width should win over aligning colons if the function
-  // name is long.
-  FormatStyle continuationStyle = getGoogleStyle();
-  continuationStyle.ColumnLimit = 40;
-  continuationStyle.IndentWrappedFunctionNames = true;
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "    dontAlignNamef:(NSRect)theRect {\n"
-               "}",
-               continuationStyle);
-
-  // Make sure we don't break aligning for short parameter names.
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "       aShortf:(NSRect)theRect {\n"
-               "}",
-               continuationStyle);
-
-  // Format pairs correctly.
-  verifyFormat("- (void)drawRectOn:(id)surface\n"
-               "            ofSize:(aaaaaaaa)height\n"
-               "                  :(size_t)width\n"
-               "          atOrigin:(size_t)x\n"
-               "                  :(size_t)y\n"
-               "             aaaaa:(a)yyy\n"
-               "               bbb:(d)cccc;");
-  verifyFormat("- (void)drawRectOn:(id)surface ofSize:(aaa)height:(bbb)width;");
-  verifyFormat("- (void)drawRectOn:(id)surface\n"
-               "            ofSize:(size_t)height\n"
-               "                  :(size_t)width;",
-               getLLVMStyleWithColumns(60));
-}
-
-TEST_F(FormatTest, FormatObjCMethodExpr) {
-  verifyFormat("[foo bar:baz];");
-  verifyFormat("return [foo bar:baz];");
-  verifyFormat("return (a)[foo bar:baz];");
-  verifyFormat("f([foo bar:baz]);");
-  verifyFormat("f(2, [foo bar:baz]);");
-  verifyFormat("f(2, a ? b : c);");
-  verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];");
-
-  // Unary operators.
-  verifyFormat("int a = +[foo bar:baz];");
-  verifyFormat("int a = -[foo bar:baz];");
-  verifyFormat("int a = ![foo bar:baz];");
-  verifyFormat("int a = ~[foo bar:baz];");
-  verifyFormat("int a = ++[foo bar:baz];");
-  verifyFormat("int a = --[foo bar:baz];");
-  verifyFormat("int a = sizeof [foo bar:baz];");
-  verifyFormat("int a = alignof [foo bar:baz];", getGoogleStyle());
-  verifyFormat("int a = &[foo bar:baz];");
-  verifyFormat("int a = *[foo bar:baz];");
-  // FIXME: Make casts work, without breaking f()[4].
-  // verifyFormat("int a = (int)[foo bar:baz];");
-  // verifyFormat("return (int)[foo bar:baz];");
-  // verifyFormat("(void)[foo bar:baz];");
-  verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];");
-
-  // Binary operators.
-  verifyFormat("[foo bar:baz], [foo bar:baz];");
-  verifyFormat("[foo bar:baz] = [foo bar:baz];");
-  verifyFormat("[foo bar:baz] *= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] /= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] %= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] += [foo bar:baz];");
-  verifyFormat("[foo bar:baz] -= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] <<= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] >>= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] &= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] ^= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] |= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];");
-  verifyFormat("[foo bar:baz] || [foo bar:baz];");
-  verifyFormat("[foo bar:baz] && [foo bar:baz];");
-  verifyFormat("[foo bar:baz] | [foo bar:baz];");
-  verifyFormat("[foo bar:baz] ^ [foo bar:baz];");
-  verifyFormat("[foo bar:baz] & [foo bar:baz];");
-  verifyFormat("[foo bar:baz] == [foo bar:baz];");
-  verifyFormat("[foo bar:baz] != [foo bar:baz];");
-  verifyFormat("[foo bar:baz] >= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] <= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] > [foo bar:baz];");
-  verifyFormat("[foo bar:baz] < [foo bar:baz];");
-  verifyFormat("[foo bar:baz] >> [foo bar:baz];");
-  verifyFormat("[foo bar:baz] << [foo bar:baz];");
-  verifyFormat("[foo bar:baz] - [foo bar:baz];");
-  verifyFormat("[foo bar:baz] + [foo bar:baz];");
-  verifyFormat("[foo bar:baz] * [foo bar:baz];");
-  verifyFormat("[foo bar:baz] / [foo bar:baz];");
-  verifyFormat("[foo bar:baz] % [foo bar:baz];");
-  // Whew!
-
-  verifyFormat("return in[42];");
-  verifyFormat("for (auto v : in[1]) {\n}");
-  verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}");
-  verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}");
-  verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}");
-  verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}");
-  verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}");
-  verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"
-               "}");
-  verifyFormat("[self aaaaa:MACRO(a, b:, c:)];");
-  verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];");
-  verifyFormat("[self aaaaa:(Type)a bbbbb:3];");
-
-  verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");
-  verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");
-  verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");
-  verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];");
-  verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]");
-  verifyFormat("[button setAction:@selector(zoomOut:)];");
-  verifyFormat("[color getRed:&r green:&g blue:&b alpha:&a];");
-
-  verifyFormat("arr[[self indexForFoo:a]];");
-  verifyFormat("throw [self errorFor:a];");
-  verifyFormat("@throw [self errorFor:a];");
-
-  verifyFormat("[(id)foo bar:(id)baz quux:(id)snorf];");
-  verifyFormat("[(id)foo bar:(id) ? baz : quux];");
-  verifyFormat("4 > 4 ? (id)a : (id)baz;");
-
-  // This tests that the formatter doesn't break after "backing" but before ":",
-  // which would be at 80 columns.
-  verifyFormat(
-      "void f() {\n"
-      "  if ((self = [super initWithContentRect:contentRect\n"
-      "                               styleMask:styleMask ?: otherMask\n"
-      "                                 backing:NSBackingStoreBuffered\n"
-      "                                   defer:YES]))");
-
-  verifyFormat(
-      "[foo checkThatBreakingAfterColonWorksOk:\n"
-      "         [bar ifItDoes:reduceOverallLineLengthLikeInThisCase]];");
-
-  verifyFormat("[myObj short:arg1 // Force line break\n"
-               "          longKeyword:arg2 != nil ? arg2 : @\"longKeyword\"\n"
-               "    evenLongerKeyword:arg3 ?: @\"evenLongerKeyword\"\n"
-               "                error:arg4];");
-  verifyFormat(
-      "void f() {\n"
-      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
-      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
-      "                                     pos.width(), pos.height())\n"
-      "                styleMask:NSBorderlessWindowMask\n"
-      "                  backing:NSBackingStoreBuffered\n"
-      "                    defer:NO]);\n"
-      "}");
-  verifyFormat(
-      "void f() {\n"
-      "  popup_wdow_.reset([[RenderWidgetPopupWindow alloc]\n"
-      "      iniithContentRect:NSMakRet(origin_global.x, origin_global.y,\n"
-      "                                 pos.width(), pos.height())\n"
-      "                syeMask:NSBorderlessWindowMask\n"
-      "                  bking:NSBackingStoreBuffered\n"
-      "                    der:NO]);\n"
-      "}",
-      getLLVMStyleWithColumns(70));
-  verifyFormat(
-      "void f() {\n"
-      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
-      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
-      "                                     pos.width(), pos.height())\n"
-      "                styleMask:NSBorderlessWindowMask\n"
-      "                  backing:NSBackingStoreBuffered\n"
-      "                    defer:NO]);\n"
-      "}",
-      getChromiumStyle(FormatStyle::LK_Cpp));
-  verifyFormat("[contentsContainer replaceSubview:[subviews objectAtIndex:0]\n"
-               "                             with:contentsNativeView];");
-
-  verifyFormat(
-      "[pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]\n"
-      "           owner:nillllll];");
-
-  verifyFormat(
-      "[pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]\n"
-      "        forType:kBookmarkButtonDragType];");
-
-  verifyFormat("[defaultCenter addObserver:self\n"
-               "                  selector:@selector(willEnterFullscreen)\n"
-               "                      name:kWillEnterFullscreenNotification\n"
-               "                    object:nil];");
-  verifyFormat("[image_rep drawInRect:drawRect\n"
-               "             fromRect:NSZeroRect\n"
-               "            operation:NSCompositeCopy\n"
-               "             fraction:1.0\n"
-               "       respectFlipped:NO\n"
-               "                hints:nil];");
-  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
-  verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
-  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n"
-               "    aaaaaaaaaaaaaaaaaaaaaa];");
-  verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n"
-               "        .aaaaaaaa];", // FIXME: Indentation seems off.
-               getLLVMStyleWithColumns(60));
-
-  verifyFormat(
-      "scoped_nsobject<NSTextField> message(\n"
-      "    // The frame will be fixed up when |-setMessageText:| is called.\n"
-      "    [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);");
-  verifyFormat("[self aaaaaa:bbbbbbbbbbbbb\n"
-               "    aaaaaaaaaa:bbbbbbbbbbbbbbbbb\n"
-               "         aaaaa:bbbbbbbbbbb + bbbbbbbbbbbb\n"
-               "          aaaa:bbb];");
-  verifyFormat("[self param:function( //\n"
-               "                parameter)]");
-  verifyFormat(
-      "[self aaaaaaaaaa:aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
-      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
-      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];");
-
-  // FIXME: This violates the column limit.
-  verifyFormat(
-      "[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    aaaaaaaaaaaaaaaaa:aaaaaaaa\n"
-      "                  aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];",
-      getLLVMStyleWithColumns(60));
-
-  // Variadic parameters.
-  verifyFormat(
-      "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];");
-  verifyFormat(
-      "[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
-      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
-      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];");
-  verifyFormat("[self // break\n"
-               "      a:a\n"
-               "    aaa:aaa];");
-  verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
-               "          [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
-
-  // Formats pair-parameters.
-  verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
-  verifyFormat("[I drawRectOn:surface //\n"
-               "        ofSize:aa:bbb\n"
-               "      atOrigin:cc:dd];");
-}
-
-TEST_F(FormatTest, ObjCAt) {
-  verifyFormat("@autoreleasepool");
-  verifyFormat("@catch");
-  verifyFormat("@class");
-  verifyFormat("@compatibility_alias");
-  verifyFormat("@defs");
-  verifyFormat("@dynamic");
-  verifyFormat("@encode");
-  verifyFormat("@end");
-  verifyFormat("@finally");
-  verifyFormat("@implementation");
-  verifyFormat("@import");
-  verifyFormat("@interface");
-  verifyFormat("@optional");
-  verifyFormat("@package");
-  verifyFormat("@private");
-  verifyFormat("@property");
-  verifyFormat("@protected");
-  verifyFormat("@protocol");
-  verifyFormat("@public");
-  verifyFormat("@required");
-  verifyFormat("@selector");
-  verifyFormat("@synchronized");
-  verifyFormat("@synthesize");
-  verifyFormat("@throw");
-  verifyFormat("@try");
-
-  EXPECT_EQ("@interface", format("@ interface"));
-
-  // The precise formatting of this doesn't matter, nobody writes code like
-  // this.
-  verifyFormat("@ /*foo*/ interface");
-}
-
-TEST_F(FormatTest, ObjCSnippets) {
-  verifyFormat("@autoreleasepool {\n"
-               "  foo();\n"
-               "}");
-  verifyFormat("@class Foo, Bar;");
-  verifyFormat("@compatibility_alias AliasName ExistingClass;");
-  verifyFormat("@dynamic textColor;");
-  verifyFormat("char *buf1 = @encode(int *);");
-  verifyFormat("char *buf1 = @encode(typeof(4 * 5));");
-  verifyFormat("char *buf1 = @encode(int **);");
-  verifyFormat("Protocol *proto = @protocol(p1);");
-  verifyFormat("SEL s = @selector(foo:);");
-  verifyFormat("@synchronized(self) {\n"
-               "  f();\n"
-               "}");
-
-  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
-  verifyGoogleFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
-
-  verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");
-  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
-  verifyGoogleFormat("@property(assign, getter=isEditable) BOOL editable;");
-  verifyFormat("@property (assign, getter=isEditable) BOOL editable;",
-               getMozillaStyle());
-  verifyFormat("@property BOOL editable;", getMozillaStyle());
-  verifyFormat("@property (assign, getter=isEditable) BOOL editable;",
-               getWebKitStyle());
-  verifyFormat("@property BOOL editable;", getWebKitStyle());
-
-  verifyFormat("@import foo.bar;\n"
-               "@import baz;");
-}
-
-TEST_F(FormatTest, ObjCForIn) {
-  verifyFormat("- (void)test {\n"
-               "  for (NSString *n in arrayOfStrings) {\n"
-               "    foo(n);\n"
-               "  }\n"
-               "}");
-  verifyFormat("- (void)test {\n"
-               "  for (NSString *n in (__bridge NSArray *)arrayOfStrings) {\n"
-               "    foo(n);\n"
-               "  }\n"
-               "}");
-}
-
-TEST_F(FormatTest, ObjCLiterals) {
-  verifyFormat("@\"String\"");
-  verifyFormat("@1");
-  verifyFormat("@+4.8");
-  verifyFormat("@-4");
-  verifyFormat("@1LL");
-  verifyFormat("@.5");
-  verifyFormat("@'c'");
-  verifyFormat("@true");
-
-  verifyFormat("NSNumber *smallestInt = @(-INT_MAX - 1);");
-  verifyFormat("NSNumber *piOverTwo = @(M_PI / 2);");
-  verifyFormat("NSNumber *favoriteColor = @(Green);");
-  verifyFormat("NSString *path = @(getenv(\"PATH\"));");
-
-  verifyFormat("[dictionary setObject:@(1) forKey:@\"number\"];");
-}
-
-TEST_F(FormatTest, ObjCDictLiterals) {
-  verifyFormat("@{");
-  verifyFormat("@{}");
-  verifyFormat("@{@\"one\" : @1}");
-  verifyFormat("return @{@\"one\" : @1;");
-  verifyFormat("@{@\"one\" : @1}");
-
-  verifyFormat("@{@\"one\" : @{@2 : @1}}");
-  verifyFormat("@{\n"
-               "  @\"one\" : @{@2 : @1},\n"
-               "}");
-
-  verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");
-  verifyIncompleteFormat("[self setDict:@{}");
-  verifyIncompleteFormat("[self setDict:@{@1 : @2}");
-  verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");
-  verifyFormat(
-      "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");
-  verifyFormat(
-      "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};");
-
-  verifyFormat("NSDictionary *d = @{\n"
-               "  @\"nam\" : NSUserNam(),\n"
-               "  @\"dte\" : [NSDate date],\n"
-               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
-               "};");
-  verifyFormat(
-      "@{\n"
-      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
-      "regularFont,\n"
-      "};");
-  verifyGoogleFormat(
-      "@{\n"
-      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
-      "regularFont,\n"
-      "};");
-  verifyFormat(
-      "@{\n"
-      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n"
-      "      reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n"
-      "};");
-
-  // We should try to be robust in case someone forgets the "@".
-  verifyFormat("NSDictionary *d = {\n"
-               "  @\"nam\" : NSUserNam(),\n"
-               "  @\"dte\" : [NSDate date],\n"
-               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
-               "};");
-  verifyFormat("NSMutableDictionary *dictionary =\n"
-               "    [NSMutableDictionary dictionaryWithDictionary:@{\n"
-               "      aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"
-               "      bbbbbbbbbbbbbbbbbb : bbbbb,\n"
-               "      cccccccccccccccc : ccccccccccccccc\n"
-               "    }];");
-
-  // Ensure that casts before the key are kept on the same line as the key.
-  verifyFormat(
-      "NSDictionary *d = @{\n"
-      "  (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n"
-      "  (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n"
-      "};");
-}
-
-TEST_F(FormatTest, ObjCArrayLiterals) {
-  verifyIncompleteFormat("@[");
-  verifyFormat("@[]");
-  verifyFormat(
-      "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");
-  verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];");
-  verifyFormat("NSArray *array = @[ [foo description] ];");
-
-  verifyFormat(
-      "NSArray *some_variable = @[\n"
-      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaaa\",\n"
-      "];");
-  verifyFormat(
-      "NSArray *some_variable = @[\n"
-      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\"\n"
-      "];");
-  verifyFormat("NSArray *some_variable = @[\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "];");
-  verifyFormat("NSArray *array = @[\n"
-               "  @\"a\",\n"
-               "  @\"a\",\n" // Trailing comma -> one per line.
-               "];");
-
-  // We should try to be robust in case someone forgets the "@".
-  verifyFormat("NSArray *some_variable = [\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "];");
-  verifyFormat(
-      "- (NSAttributedString *)attributedStringForSegment:(NSUInteger)segment\n"
-      "                                             index:(NSUInteger)index\n"
-      "                                nonDigitAttributes:\n"
-      "                                    (NSDictionary *)noDigitAttributes;");
-  verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
-               "  NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
-               "]];");
-}
 
 TEST_F(FormatTest, BreaksStringLiterals) {
   EXPECT_EQ("\"some text \"\n"
@@ -8244,8 +6482,9 @@
       "_T(\"aaaaaaaaaaaaaa\")\n"
       "_T(\"aaaaaaaaaaaa\")",
       format("  _T(\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\")", Style));
-  EXPECT_EQ("f(x, _T(\"aaaaaaaaa\")\n"
-            "     _T(\"aaaaaa\"),\n"
+  EXPECT_EQ("f(x,\n"
+            "  _T(\"aaaaaaaaaaaa\")\n"
+            "  _T(\"aaa\"),\n"
             "  z);",
             format("f(x, _T(\"aaaaaaaaaaaaaaa\"), z);", Style));
 
@@ -8277,6 +6516,90 @@
                    "_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\"));"));
 }
 
+TEST_F(FormatTest, BreaksStringLiteralOperands) {
+  // In a function call with two operands, the second can be broken with no line
+  // break before it.
+  EXPECT_EQ("func(a, \"long long \"\n"
+            "        \"long long\");",
+            format("func(a, \"long long long long\");",
+                   getLLVMStyleWithColumns(24)));
+  // In a function call with three operands, the second must be broken with a
+  // line break before it.
+  EXPECT_EQ("func(a,\n"
+            "     \"long long long \"\n"
+            "     \"long\",\n"
+            "     c);",
+            format("func(a, \"long long long long\", c);",
+                   getLLVMStyleWithColumns(24)));
+  // In a function call with three operands, the third must be broken with a
+  // line break before it.
+  EXPECT_EQ("func(a, b,\n"
+            "     \"long long long \"\n"
+            "     \"long\");",
+            format("func(a, b, \"long long long long\");",
+                   getLLVMStyleWithColumns(24)));
+  // In a function call with three operands, both the second and the third must
+  // be broken with a line break before them.
+  EXPECT_EQ("func(a,\n"
+            "     \"long long long \"\n"
+            "     \"long\",\n"
+            "     \"long long long \"\n"
+            "     \"long\");",
+            format("func(a, \"long long long long\", \"long long long long\");",
+                   getLLVMStyleWithColumns(24)));
+  // In a chain of << with two operands, the second can be broken with no line
+  // break before it.
+  EXPECT_EQ("a << \"line line \"\n"
+            "     \"line\";",
+            format("a << \"line line line\";",
+                   getLLVMStyleWithColumns(20)));
+  // In a chain of << with three operands, the second can be broken with no line
+  // break before it.
+  EXPECT_EQ("abcde << \"line \"\n"
+            "         \"line line\"\n"
+            "      << c;",
+            format("abcde << \"line line line\" << c;",
+                   getLLVMStyleWithColumns(20)));
+  // In a chain of << with three operands, the third must be broken with a line
+  // break before it.
+  EXPECT_EQ("a << b\n"
+            "  << \"line line \"\n"
+            "     \"line\";",
+            format("a << b << \"line line line\";",
+                   getLLVMStyleWithColumns(20)));
+  // In a chain of << with three operands, the second can be broken with no line
+  // break before it and the third must be broken with a line break before it.
+  EXPECT_EQ("abcd << \"line line \"\n"
+            "        \"line\"\n"
+            "     << \"line line \"\n"
+            "        \"line\";",
+            format("abcd << \"line line line\" << \"line line line\";",
+                   getLLVMStyleWithColumns(20)));
+  // In a chain of binary operators with two operands, the second can be broken
+  // with no line break before it.
+  EXPECT_EQ("abcd + \"line line \"\n"
+            "       \"line line\";",
+            format("abcd + \"line line line line\";",
+                   getLLVMStyleWithColumns(20)));
+  // In a chain of binary operators with three operands, the second must be
+  // broken with a line break before it.
+  EXPECT_EQ("abcd +\n"
+            "    \"line line \"\n"
+            "    \"line line\" +\n"
+            "    e;",
+            format("abcd + \"line line line line\" + e;",
+                   getLLVMStyleWithColumns(20)));
+  // In a function call with two operands, with AlignAfterOpenBracket enabled,
+  // the first must be broken with a line break before it.
+  FormatStyle Style = getLLVMStyleWithColumns(25);
+  Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
+  EXPECT_EQ("someFunction(\n"
+            "    \"long long long \"\n"
+            "    \"long\",\n"
+            "    a);",
+            format("someFunction(\"long long long long\", a);", Style));
+}
+
 TEST_F(FormatTest, DontSplitStringLiteralsWithEscapedNewlines) {
   EXPECT_EQ(
       "aaaaaaaaaaa = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
@@ -9653,6 +7976,7 @@
 TEST_F(FormatTest, MozillaBraceBreaking) {
   FormatStyle MozillaBraceStyle = getLLVMStyle();
   MozillaBraceStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
+  MozillaBraceStyle.FixNamespaceComments = false;
   verifyFormat("namespace a {\n"
                "class A\n"
                "{\n"
@@ -9711,7 +8035,7 @@
                "struct B {\n"
                "  int x;\n"
                "};\n"
-               "}\n",
+               "} // namespace a\n",
                StroustrupBraceStyle);
 
   verifyFormat("void foo()\n"
@@ -10069,6 +8393,7 @@
 TEST_F(FormatTest, WebKitBraceBreaking) {
   FormatStyle WebKitBraceStyle = getLLVMStyle();
   WebKitBraceStyle.BreakBeforeBraces = FormatStyle::BS_WebKit;
+  WebKitBraceStyle.FixNamespaceComments = false;
   verifyFormat("namespace a {\n"
                "class A {\n"
                "  void f()\n"
@@ -10268,6 +8593,7 @@
   CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
   CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma);
   CHECK_PARSE_BOOL(BreakStringLiterals);
+  CHECK_PARSE_BOOL(BreakBeforeInheritanceComma)
   CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine);
   CHECK_PARSE_BOOL(DerivePointerAlignment);
   CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding");
@@ -11069,10 +9395,11 @@
                "             << std::count_if(v.begin(), v.end(), [](int x) {\n"
                "                  return x == 2; // force break\n"
                "                });");
-  verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa([=](\n"
-               "    int iiiiiiiiiiii) {\n"
-               "  return aaaaaaaaaaaaaaaaaaaaaaa != aaaaaaaaaaaaaaaaaaaaaaa;\n"
-               "});",
+  verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+               "    [=](int iiiiiiiiiiii) {\n"
+               "      return aaaaaaaaaaaaaaaaaaaaaaa !=\n"
+               "             aaaaaaaaaaaaaaaaaaaaaaa;\n"
+               "    });",
                getLLVMStyleWithColumns(60));
   verifyFormat("SomeFunction({[&] {\n"
                "                // comment\n"
@@ -11158,6 +9485,15 @@
                "#endif\n"
                "      ;\n"
                "};");
+
+  // Lambdas with complex multiline introducers.
+  verifyFormat(
+      "aaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+      "    [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]()\n"
+      "        -> ::std::unordered_set<\n"
+      "            aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
+      "      //\n"
+      "    });");
 }
 
 TEST_F(FormatTest, FormatsBlocks) {
@@ -11585,6 +9921,26 @@
                    "  int j;\n"
                    " /* clang-format on */\n"
                    "   int   k;"));
+
+  // Don't reflow comments within disabled regions.
+  EXPECT_EQ(
+      "// clang-format off\n"
+      "// long long long long long long line\n"
+      "/* clang-format on */\n"
+      "/* long long long\n"
+      " * long long long\n"
+      " * line */\n"
+      "int i;\n"
+      "/* clang-format off */\n"
+      "/* long long long long long long line */\n",
+      format("// clang-format off\n"
+             "// long long long long long long line\n"
+             "/* clang-format on */\n"
+             "/* long long long long long long line */\n"
+             "int i;\n"
+             "/* clang-format off */\n"
+             "/* long long long long long long line */\n",
+             getLLVMStyleWithColumns(20)));
 }
 
 TEST_F(FormatTest, DoNotCrashOnInvalidInput) {
@@ -11618,10 +9974,6 @@
             format("auto a = unique_ptr < Foo < Bar>[10]> ;", Spaces));
 }
 
-// Since this test case uses UNIX-style file path. We disable it for MS
-// compiler.
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-
 TEST(FormatStyle, GetStyleOfFile) {
   vfs::InMemoryFileSystem FS;
   // Test 1: format file in the same directory.
@@ -11630,14 +9982,34 @@
                  llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
   ASSERT_TRUE(
       FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style1 = getStyle("file", "/a/.clang-format", "Google", &FS);
-  ASSERT_EQ(Style1, getLLVMStyle());
+  auto Style1 = getStyle("file", "/a/.clang-format", "Google", "", &FS);
+  ASSERT_TRUE((bool)Style1);
+  ASSERT_EQ(*Style1, getLLVMStyle());
 
-  // Test 2: fallback to default.
+  // Test 2.1: fallback to default.
   ASSERT_TRUE(
       FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", &FS);
-  ASSERT_EQ(Style2, getMozillaStyle());
+  auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", "", &FS);
+  ASSERT_TRUE((bool)Style2);
+  ASSERT_EQ(*Style2, getMozillaStyle());
+
+  // Test 2.2: no format on 'none' fallback style.
+  Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
+  ASSERT_TRUE((bool)Style2);
+  ASSERT_EQ(*Style2, getNoStyle());
+
+  // Test 2.3: format if config is found with no based style while fallback is
+  // 'none'.
+  ASSERT_TRUE(FS.addFile("/b/.clang-format", 0,
+                         llvm::MemoryBuffer::getMemBuffer("IndentWidth: 2")));
+  Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
+  ASSERT_TRUE((bool)Style2);
+  ASSERT_EQ(*Style2, getLLVMStyle());
+
+  // Test 2.4: format if yaml with no based style, while fallback is 'none'.
+  Style2 = getStyle("{}", "a.h", "none", "", &FS);
+  ASSERT_TRUE((bool)Style2);
+  ASSERT_EQ(*Style2, getLLVMStyle());
 
   // Test 3: format file in parent directory.
   ASSERT_TRUE(
@@ -11645,11 +10017,36 @@
                  llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
   ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0,
                          llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", &FS);
-  ASSERT_EQ(Style3, getGoogleStyle());
-}
+  auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE((bool)Style3);
+  ASSERT_EQ(*Style3, getGoogleStyle());
 
-#endif // _MSC_VER
+  // Test 4: error on invalid fallback style
+  auto Style4 = getStyle("file", "a.h", "KungFu", "", &FS);
+  ASSERT_FALSE((bool)Style4);
+  llvm::consumeError(Style4.takeError());
+
+  // Test 5: error on invalid yaml on command line
+  auto Style5 = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS);
+  ASSERT_FALSE((bool)Style5);
+  llvm::consumeError(Style5.takeError());
+
+  // Test 6: error on invalid style
+  auto Style6 = getStyle("KungFu", "a.h", "LLVM", "", &FS);
+  ASSERT_FALSE((bool)Style6);
+  llvm::consumeError(Style6.takeError());
+
+  // Test 7: found config file, error on parsing it
+  ASSERT_TRUE(
+      FS.addFile("/d/.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM\n"
+                                                  "InvalidKey: InvalidValue")));
+  ASSERT_TRUE(
+      FS.addFile("/d/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style7 = getStyle("file", "/d/.clang-format", "LLVM", "", &FS);
+  ASSERT_FALSE((bool)Style7);
+  llvm::consumeError(Style7.takeError());
+}
 
 TEST_F(ReplacementTest, FormatCodeAfterReplacements) {
   // Column limit is 20.
@@ -11714,17 +10111,6 @@
   EXPECT_EQ(Expected, *Result);
 }
 
-TEST_F(FormatTest, AllignTrailingComments) {
-  EXPECT_EQ("#define MACRO(V)                       \\\n"
-            "  V(Rt2) /* one more char */           \\\n"
-            "  V(Rs)  /* than here  */              \\\n"
-            "/* comment 3 */\n",
-            format("#define MACRO(V)\\\n"
-                   "V(Rt2)  /* one more char */ \\\n"
-                   "V(Rs) /* than here  */    \\\n"
-                   "/* comment 3 */         \\\n",
-                   getLLVMStyleWithColumns(40)));
-}
 } // end namespace
 } // end namespace format
 } // end namespace clang
diff --git a/unittests/Format/FormatTestComments.cpp b/unittests/Format/FormatTestComments.cpp
new file mode 100644
index 0000000..df24abe
--- /dev/null
+++ b/unittests/Format/FormatTestComments.cpp
@@ -0,0 +1,2373 @@
+//===- unittest/Format/FormatTestComments.cpp - Formatting unit tests -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Format/Format.h"
+
+#include "../Tooling/ReplacementTest.h"
+#include "FormatTestUtils.h"
+
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+using clang::tooling::ReplacementTest;
+
+namespace clang {
+namespace format {
+namespace {
+
+FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); }
+
+class FormatTestComments : public ::testing::Test {
+protected:
+  enum IncompleteCheck {
+    IC_ExpectComplete,
+    IC_ExpectIncomplete,
+    IC_DoNotCheck
+  };
+
+  std::string format(llvm::StringRef Code,
+                     const FormatStyle &Style = getLLVMStyle(),
+                     IncompleteCheck CheckIncomplete = IC_ExpectComplete) {
+    DEBUG(llvm::errs() << "---\n");
+    DEBUG(llvm::errs() << Code << "\n\n");
+    std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
+    bool IncompleteFormat = false;
+    tooling::Replacements Replaces =
+        reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
+    if (CheckIncomplete != IC_DoNotCheck) {
+      bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete;
+      EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n";
+    }
+    ReplacementCount = Replaces.size();
+    auto Result = applyAllReplacements(Code, Replaces);
+    EXPECT_TRUE(static_cast<bool>(Result));
+    DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+    return *Result;
+  }
+
+  FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) {
+    FormatStyle Style = getLLVMStyle();
+    Style.ColumnLimit = ColumnLimit;
+    return Style;
+  }
+
+  void verifyFormat(llvm::StringRef Code,
+                    const FormatStyle &Style = getLLVMStyle()) {
+    EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
+  }
+
+  void verifyGoogleFormat(llvm::StringRef Code) {
+    verifyFormat(Code, getGoogleStyle());
+  }
+
+  /// \brief Verify that clang-format does not crash on the given input.
+  void verifyNoCrash(llvm::StringRef Code,
+                     const FormatStyle &Style = getLLVMStyle()) {
+    format(Code, Style, IC_DoNotCheck);
+  }
+
+  int ReplacementCount;
+};
+
+//===----------------------------------------------------------------------===//
+// Tests for comments.
+//===----------------------------------------------------------------------===//
+
+TEST_F(FormatTestComments, UnderstandsSingleLineComments) {
+  verifyFormat("//* */");
+  verifyFormat("// line 1\n"
+               "// line 2\n"
+               "void f() {}\n");
+
+  verifyFormat("void f() {\n"
+               "  // Doesn't do anything\n"
+               "}");
+  verifyFormat("SomeObject\n"
+               "    // Calling someFunction on SomeObject\n"
+               "    .someFunction();");
+  verifyFormat("auto result = SomeObject\n"
+               "                  // Calling someFunction on SomeObject\n"
+               "                  .someFunction();");
+  verifyFormat("void f(int i,  // some comment (probably for i)\n"
+               "       int j,  // some comment (probably for j)\n"
+               "       int k); // some comment (probably for k)");
+  verifyFormat("void f(int i,\n"
+               "       // some comment (probably for j)\n"
+               "       int j,\n"
+               "       // some comment (probably for k)\n"
+               "       int k);");
+
+  verifyFormat("int i    // This is a fancy variable\n"
+               "    = 5; // with nicely aligned comment.");
+
+  verifyFormat("// Leading comment.\n"
+               "int a; // Trailing comment.");
+  verifyFormat("int a; // Trailing comment\n"
+               "       // on 2\n"
+               "       // or 3 lines.\n"
+               "int b;");
+  verifyFormat("int a; // Trailing comment\n"
+               "\n"
+               "// Leading comment.\n"
+               "int b;");
+  verifyFormat("int a;    // Comment.\n"
+               "          // More details.\n"
+               "int bbbb; // Another comment.");
+  verifyFormat(
+      "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; // comment\n"
+      "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;   // comment\n"
+      "int cccccccccccccccccccccccccccccc;       // comment\n"
+      "int ddd;                     // looooooooooooooooooooooooong comment\n"
+      "int aaaaaaaaaaaaaaaaaaaaaaa; // comment\n"
+      "int bbbbbbbbbbbbbbbbbbbbb;   // comment\n"
+      "int ccccccccccccccccccc;     // comment");
+
+  verifyFormat("#include \"a\"     // comment\n"
+               "#include \"a/b/c\" // comment");
+  verifyFormat("#include <a>     // comment\n"
+               "#include <a/b/c> // comment");
+  EXPECT_EQ("#include \"a\"     // comment\n"
+            "#include \"a/b/c\" // comment",
+            format("#include \\\n"
+                   "  \"a\" // comment\n"
+                   "#include \"a/b/c\" // comment"));
+
+  verifyFormat("enum E {\n"
+               "  // comment\n"
+               "  VAL_A, // comment\n"
+               "  VAL_B\n"
+               "};");
+
+  EXPECT_EQ("enum A {\n"
+            "  // line a\n"
+            "  a,\n"
+            "  b, // line b\n"
+            "\n"
+            "  // line c\n"
+            "  c\n"
+            "};",
+            format("enum A {\n"
+                   "  // line a\n"
+                   "  a,\n"
+                   "  b, // line b\n"
+                   "\n"
+                   "  // line c\n"
+                   "  c\n"
+                   "};",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("enum A {\n"
+            "  a, // line 1\n"
+            "  // line 2\n"
+            "};",
+            format("enum A {\n"
+                   "  a, // line 1\n"
+                   "  // line 2\n"
+                   "};",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("enum A {\n"
+            "  a, // line 1\n"
+            "     // line 2\n"
+            "};",
+            format("enum A {\n"
+                   "  a, // line 1\n"
+                   "   // line 2\n"
+                   "};",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("enum A {\n"
+            "  a, // line 1\n"
+            "  // line 2\n"
+            "  b\n"
+            "};",
+            format("enum A {\n"
+                   "  a, // line 1\n"
+                   "  // line 2\n"
+                   "  b\n"
+                   "};",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("enum A {\n"
+            "  a, // line 1\n"
+            "     // line 2\n"
+            "  b\n"
+            "};",
+            format("enum A {\n"
+                   "  a, // line 1\n"
+                   "   // line 2\n"
+                   "  b\n"
+                   "};",
+                   getLLVMStyleWithColumns(20)));
+  verifyFormat(
+      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
+      "    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // Trailing comment");
+  verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
+               "    // Comment inside a statement.\n"
+               "    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;");
+  verifyFormat("SomeFunction(a,\n"
+               "             // comment\n"
+               "             b + x);");
+  verifyFormat("SomeFunction(a, a,\n"
+               "             // comment\n"
+               "             b + x);");
+  verifyFormat(
+      "bool aaaaaaaaaaaaa = // comment\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+
+  verifyFormat("int aaaa; // aaaaa\n"
+               "int aa;   // aaaaaaa",
+               getLLVMStyleWithColumns(20));
+
+  EXPECT_EQ("void f() { // This does something ..\n"
+            "}\n"
+            "int a; // This is unrelated",
+            format("void f()    {     // This does something ..\n"
+                   "  }\n"
+                   "int   a;     // This is unrelated"));
+  EXPECT_EQ("class C {\n"
+            "  void f() { // This does something ..\n"
+            "  }          // awesome..\n"
+            "\n"
+            "  int a; // This is unrelated\n"
+            "};",
+            format("class C{void f()    { // This does something ..\n"
+                   "      } // awesome..\n"
+                   " \n"
+                   "int a;    // This is unrelated\n"
+                   "};"));
+
+  EXPECT_EQ("int i; // single line trailing comment",
+            format("int i;\\\n// single line trailing comment"));
+
+  verifyGoogleFormat("int a;  // Trailing comment.");
+
+  verifyFormat("someFunction(anotherFunction( // Force break.\n"
+               "    parameter));");
+
+  verifyGoogleFormat("#endif  // HEADER_GUARD");
+
+  verifyFormat("const char *test[] = {\n"
+               "    // A\n"
+               "    \"aaaa\",\n"
+               "    // B\n"
+               "    \"aaaaa\"};");
+  verifyGoogleFormat(
+      "aaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+      "    aaaaaaaaaaaaaaaaaaaaaa);  // 81_cols_with_this_comment");
+  EXPECT_EQ("D(a, {\n"
+            "  // test\n"
+            "  int a;\n"
+            "});",
+            format("D(a, {\n"
+                   "// test\n"
+                   "int a;\n"
+                   "});"));
+
+  EXPECT_EQ("lineWith(); // comment\n"
+            "// at start\n"
+            "otherLine();",
+            format("lineWith();   // comment\n"
+                   "// at start\n"
+                   "otherLine();"));
+  EXPECT_EQ("lineWith(); // comment\n"
+            "/*\n"
+            " * at start */\n"
+            "otherLine();",
+            format("lineWith();   // comment\n"
+                   "/*\n"
+                   " * at start */\n"
+                   "otherLine();"));
+  EXPECT_EQ("lineWith(); // comment\n"
+            "            // at start\n"
+            "otherLine();",
+            format("lineWith();   // comment\n"
+                   " // at start\n"
+                   "otherLine();"));
+
+  EXPECT_EQ("lineWith(); // comment\n"
+            "// at start\n"
+            "otherLine(); // comment",
+            format("lineWith();   // comment\n"
+                   "// at start\n"
+                   "otherLine();   // comment"));
+  EXPECT_EQ("lineWith();\n"
+            "// at start\n"
+            "otherLine(); // comment",
+            format("lineWith();\n"
+                   " // at start\n"
+                   "otherLine();   // comment"));
+  EXPECT_EQ("// first\n"
+            "// at start\n"
+            "otherLine(); // comment",
+            format("// first\n"
+                   " // at start\n"
+                   "otherLine();   // comment"));
+  EXPECT_EQ("f();\n"
+            "// first\n"
+            "// at start\n"
+            "otherLine(); // comment",
+            format("f();\n"
+                   "// first\n"
+                   " // at start\n"
+                   "otherLine();   // comment"));
+  verifyFormat("f(); // comment\n"
+               "// first\n"
+               "// at start\n"
+               "otherLine();");
+  EXPECT_EQ("f(); // comment\n"
+            "// first\n"
+            "// at start\n"
+            "otherLine();",
+            format("f();   // comment\n"
+                   "// first\n"
+                   " // at start\n"
+                   "otherLine();"));
+  EXPECT_EQ("f(); // comment\n"
+            "     // first\n"
+            "// at start\n"
+            "otherLine();",
+            format("f();   // comment\n"
+                   " // first\n"
+                   "// at start\n"
+                   "otherLine();"));
+  EXPECT_EQ("void f() {\n"
+            "  lineWith(); // comment\n"
+            "  // at start\n"
+            "}",
+            format("void              f() {\n"
+                   "  lineWith(); // comment\n"
+                   "  // at start\n"
+                   "}"));
+  EXPECT_EQ("int xy; // a\n"
+            "int z;  // b",
+            format("int xy;    // a\n"
+                   "int z;    //b"));
+  EXPECT_EQ("int xy; // a\n"
+            "int z; // bb",
+            format("int xy;    // a\n"
+                   "int z;    //bb",
+                   getLLVMStyleWithColumns(12)));
+
+  verifyFormat("#define A                                                  \\\n"
+               "  int i; /* iiiiiiiiiiiiiiiiiiiii */                       \\\n"
+               "  int jjjjjjjjjjjjjjjjjjjjjjjj; /* */",
+               getLLVMStyleWithColumns(60));
+  verifyFormat(
+      "#define A                                                   \\\n"
+      "  int i;                        /* iiiiiiiiiiiiiiiiiiiii */ \\\n"
+      "  int jjjjjjjjjjjjjjjjjjjjjjjj; /* */",
+      getLLVMStyleWithColumns(61));
+
+  verifyFormat("if ( // This is some comment\n"
+               "    x + 3) {\n"
+               "}");
+  EXPECT_EQ("if ( // This is some comment\n"
+            "     // spanning two lines\n"
+            "    x + 3) {\n"
+            "}",
+            format("if( // This is some comment\n"
+                   "     // spanning two lines\n"
+                   " x + 3) {\n"
+                   "}"));
+
+  verifyNoCrash("/\\\n/");
+  verifyNoCrash("/\\\n* */");
+  // The 0-character somehow makes the lexer return a proper comment.
+  verifyNoCrash(StringRef("/*\\\0\n/", 6));
+}
+
+TEST_F(FormatTestComments, KeepsParameterWithTrailingCommentsOnTheirOwnLine) {
+  EXPECT_EQ("SomeFunction(a,\n"
+            "             b, // comment\n"
+            "             c);",
+            format("SomeFunction(a,\n"
+                   "          b, // comment\n"
+                   "      c);"));
+  EXPECT_EQ("SomeFunction(a, b,\n"
+            "             // comment\n"
+            "             c);",
+            format("SomeFunction(a,\n"
+                   "          b,\n"
+                   "  // comment\n"
+                   "      c);"));
+  EXPECT_EQ("SomeFunction(a, b, // comment (unclear relation)\n"
+            "             c);",
+            format("SomeFunction(a, b, // comment (unclear relation)\n"
+                   "      c);"));
+  EXPECT_EQ("SomeFunction(a, // comment\n"
+            "             b,\n"
+            "             c); // comment",
+            format("SomeFunction(a,     // comment\n"
+                   "          b,\n"
+                   "      c); // comment"));
+  EXPECT_EQ("aaaaaaaaaa(aaaa(aaaa,\n"
+            "                aaaa), //\n"
+            "           aaaa, bbbbb);",
+            format("aaaaaaaaaa(aaaa(aaaa,\n"
+                   "aaaa), //\n"
+                   "aaaa, bbbbb);"));
+}
+
+TEST_F(FormatTestComments, RemovesTrailingWhitespaceOfComments) {
+  EXPECT_EQ("// comment", format("// comment  "));
+  EXPECT_EQ("int aaaaaaa, bbbbbbb; // comment",
+            format("int aaaaaaa, bbbbbbb; // comment                   ",
+                   getLLVMStyleWithColumns(33)));
+  EXPECT_EQ("// comment\\\n", format("// comment\\\n  \t \v   \f   "));
+  EXPECT_EQ("// comment    \\\n", format("// comment    \\\n  \t \v   \f   "));
+}
+
+TEST_F(FormatTestComments, UnderstandsBlockComments) {
+  verifyFormat("f(/*noSpaceAfterParameterNamingComment=*/true);");
+  verifyFormat("void f() { g(/*aaa=*/x, /*bbb=*/!y, /*c=*/::c); }");
+  EXPECT_EQ("f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n"
+            "  bbbbbbbbbbbbbbbbbbbbbbbbb);",
+            format("f(aaaaaaaaaaaaaaaaaaaaaaaaa ,   \\\n"
+                   "/* Trailing comment for aa... */\n"
+                   "  bbbbbbbbbbbbbbbbbbbbbbbbb);"));
+  EXPECT_EQ(
+      "f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+      "  /* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);",
+      format("f(aaaaaaaaaaaaaaaaaaaaaaaaa    ,   \n"
+             "/* Leading comment for bb... */   bbbbbbbbbbbbbbbbbbbbbbbbb);"));
+  EXPECT_EQ(
+      "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+      "    aaaaaaaaaaaaaaaaaa,\n"
+      "    aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n"
+      "}",
+      format("void      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+             "                      aaaaaaaaaaaaaaaaaa  ,\n"
+             "    aaaaaaaaaaaaaaaaaa) {   /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n"
+             "}"));
+  verifyFormat("f(/* aaaaaaaaaaaaaaaaaa = */\n"
+               "  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+
+  FormatStyle NoBinPacking = getLLVMStyle();
+  NoBinPacking.BinPackParameters = false;
+  verifyFormat("aaaaaaaa(/* parameter 1 */ aaaaaa,\n"
+               "         /* parameter 2 */ aaaaaa,\n"
+               "         /* parameter 3 */ aaaaaa,\n"
+               "         /* parameter 4 */ aaaaaa);",
+               NoBinPacking);
+
+  // Aligning block comments in macros.
+  verifyGoogleFormat("#define A        \\\n"
+                     "  int i;   /*a*/ \\\n"
+                     "  int jjj; /*b*/");
+}
+
+TEST_F(FormatTestComments, AlignsBlockComments) {
+  EXPECT_EQ("/*\n"
+            " * Really multi-line\n"
+            " * comment.\n"
+            " */\n"
+            "void f() {}",
+            format("  /*\n"
+                   "   * Really multi-line\n"
+                   "   * comment.\n"
+                   "   */\n"
+                   "  void f() {}"));
+  EXPECT_EQ("class C {\n"
+            "  /*\n"
+            "   * Another multi-line\n"
+            "   * comment.\n"
+            "   */\n"
+            "  void f() {}\n"
+            "};",
+            format("class C {\n"
+                   "/*\n"
+                   " * Another multi-line\n"
+                   " * comment.\n"
+                   " */\n"
+                   "void f() {}\n"
+                   "};"));
+  EXPECT_EQ("/*\n"
+            "  1. This is a comment with non-trivial formatting.\n"
+            "     1.1. We have to indent/outdent all lines equally\n"
+            "         1.1.1. to keep the formatting.\n"
+            " */",
+            format("  /*\n"
+                   "    1. This is a comment with non-trivial formatting.\n"
+                   "       1.1. We have to indent/outdent all lines equally\n"
+                   "           1.1.1. to keep the formatting.\n"
+                   "   */"));
+  EXPECT_EQ("/*\n"
+            "Don't try to outdent if there's not enough indentation.\n"
+            "*/",
+            format("  /*\n"
+                   " Don't try to outdent if there's not enough indentation.\n"
+                   " */"));
+
+  EXPECT_EQ("int i; /* Comment with empty...\n"
+            "        *\n"
+            "        * line. */",
+            format("int i; /* Comment with empty...\n"
+                   "        *\n"
+                   "        * line. */"));
+  EXPECT_EQ("int foobar = 0; /* comment */\n"
+            "int bar = 0;    /* multiline\n"
+            "                   comment 1 */\n"
+            "int baz = 0;    /* multiline\n"
+            "                   comment 2 */\n"
+            "int bzz = 0;    /* multiline\n"
+            "                   comment 3 */",
+            format("int foobar = 0; /* comment */\n"
+                   "int bar = 0;    /* multiline\n"
+                   "                   comment 1 */\n"
+                   "int baz = 0; /* multiline\n"
+                   "                comment 2 */\n"
+                   "int bzz = 0;         /* multiline\n"
+                   "                        comment 3 */"));
+  EXPECT_EQ("int foobar = 0; /* comment */\n"
+            "int bar = 0;    /* multiline\n"
+            "   comment */\n"
+            "int baz = 0;    /* multiline\n"
+            "comment */",
+            format("int foobar = 0; /* comment */\n"
+                   "int bar = 0; /* multiline\n"
+                   "comment */\n"
+                   "int baz = 0;        /* multiline\n"
+                   "comment */"));
+}
+
+TEST_F(FormatTestComments, CommentReflowingCanBeTurnedOff) {
+  FormatStyle Style = getLLVMStyleWithColumns(20);
+  Style.ReflowComments = false;
+  verifyFormat("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style);
+  verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style);
+}
+
+TEST_F(FormatTestComments, CorrectlyHandlesLengthOfBlockComments) {
+  EXPECT_EQ("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+            "              aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */",
+            format("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+                   "              aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */"));
+  EXPECT_EQ(
+      "void ffffffffffff(\n"
+      "    int aaaaaaaa, int bbbbbbbb,\n"
+      "    int cccccccccccc) { /*\n"
+      "                           aaaaaaaaaa\n"
+      "                           aaaaaaaaaaaaa\n"
+      "                           bbbbbbbbbbbbbb\n"
+      "                           bbbbbbbbbb\n"
+      "                         */\n"
+      "}",
+      format("void ffffffffffff(int aaaaaaaa, int bbbbbbbb, int cccccccccccc)\n"
+             "{ /*\n"
+             "     aaaaaaaaaa aaaaaaaaaaaaa\n"
+             "     bbbbbbbbbbbbbb bbbbbbbbbb\n"
+             "   */\n"
+             "}",
+             getLLVMStyleWithColumns(40)));
+}
+
+TEST_F(FormatTestComments, DontBreakNonTrailingBlockComments) {
+  EXPECT_EQ("void ffffffffff(\n"
+            "    int aaaaa /* test */);",
+            format("void ffffffffff(int aaaaa /* test */);",
+                   getLLVMStyleWithColumns(35)));
+}
+
+TEST_F(FormatTestComments, SplitsLongCxxComments) {
+  EXPECT_EQ("// A comment that\n"
+            "// doesn't fit on\n"
+            "// one line",
+            format("// A comment that doesn't fit on one line",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/// A comment that\n"
+            "/// doesn't fit on\n"
+            "/// one line",
+            format("/// A comment that doesn't fit on one line",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("//! A comment that\n"
+            "//! doesn't fit on\n"
+            "//! one line",
+            format("//! A comment that doesn't fit on one line",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// a b c d\n"
+            "// e f  g\n"
+            "// h i j k",
+            format("// a b c d e f  g h i j k", getLLVMStyleWithColumns(10)));
+  EXPECT_EQ(
+      "// a b c d\n"
+      "// e f  g\n"
+      "// h i j k",
+      format("\\\n// a b c d e f  g h i j k", getLLVMStyleWithColumns(10)));
+  EXPECT_EQ("if (true) // A comment that\n"
+            "          // doesn't fit on\n"
+            "          // one line",
+            format("if (true) // A comment that doesn't fit on one line   ",
+                   getLLVMStyleWithColumns(30)));
+  EXPECT_EQ("//    Don't_touch_leading_whitespace",
+            format("//    Don't_touch_leading_whitespace",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// Add leading\n"
+            "// whitespace",
+            format("//Add leading whitespace", getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/// Add leading\n"
+            "/// whitespace",
+            format("///Add leading whitespace", getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("//! Add leading\n"
+            "//! whitespace",
+            format("//!Add leading whitespace", getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// whitespace", format("//whitespace", getLLVMStyle()));
+  EXPECT_EQ("// Even if it makes the line exceed the column\n"
+            "// limit",
+            format("//Even if it makes the line exceed the column limit",
+                   getLLVMStyleWithColumns(51)));
+  EXPECT_EQ("//--But not here", format("//--But not here", getLLVMStyle()));
+  EXPECT_EQ("/// line 1\n"
+            "// add leading whitespace",
+            format("/// line 1\n"
+                   "//add leading whitespace",
+                   getLLVMStyleWithColumns(30)));
+  EXPECT_EQ("/// line 1\n"
+            "/// line 2\n"
+            "//! line 3\n"
+            "//! line 4\n"
+            "//! line 5\n"
+            "// line 6\n"
+            "// line 7",
+            format("///line 1\n"
+                   "///line 2\n"
+                   "//! line 3\n"
+                   "//!line 4\n"
+                   "//!line 5\n"
+                   "// line 6\n"
+                   "//line 7", getLLVMStyleWithColumns(20)));
+
+  EXPECT_EQ("// aa bb cc dd",
+            format("// aa bb             cc dd                   ",
+                   getLLVMStyleWithColumns(15)));
+
+  EXPECT_EQ("// A comment before\n"
+            "// a macro\n"
+            "// definition\n"
+            "#define a b",
+            format("// A comment before a macro definition\n"
+                   "#define a b",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("void ffffff(\n"
+            "    int aaaaaaaaa,  // wwww\n"
+            "    int bbbbbbbbbb, // xxxxxxx\n"
+            "                    // yyyyyyyyyy\n"
+            "    int c, int d, int e) {}",
+            format("void ffffff(\n"
+                   "    int aaaaaaaaa, // wwww\n"
+                   "    int bbbbbbbbbb, // xxxxxxx yyyyyyyyyy\n"
+                   "    int c, int d, int e) {}",
+                   getLLVMStyleWithColumns(40)));
+  EXPECT_EQ("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+            format("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ(
+      "#define XXX // a b c d\n"
+      "            // e f g h",
+      format("#define XXX // a b c d e f g h", getLLVMStyleWithColumns(22)));
+  EXPECT_EQ(
+      "#define XXX // q w e r\n"
+      "            // t y u i",
+      format("#define XXX //q w e r t y u i", getLLVMStyleWithColumns(22)));
+  EXPECT_EQ("{\n"
+            "  //\n"
+            "  //\\\n"
+            "  // long 1 2 3 4\n"
+            "  // 5\n"
+            "}",
+            format("{\n"
+                   "  //\n"
+                   "  //\\\n"
+                   "  // long 1 2 3 4 5\n"
+                   "}",
+                   getLLVMStyleWithColumns(20)));
+}
+
+TEST_F(FormatTestComments, PreservesHangingIndentInCxxComments) {
+  EXPECT_EQ("//     A comment\n"
+            "//     that doesn't\n"
+            "//     fit on one\n"
+            "//     line",
+            format("//     A comment that doesn't fit on one line",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("///     A comment\n"
+            "///     that doesn't\n"
+            "///     fit on one\n"
+            "///     line",
+            format("///     A comment that doesn't fit on one line",
+                   getLLVMStyleWithColumns(20)));
+}
+
+TEST_F(FormatTestComments, DontSplitLineCommentsWithEscapedNewlines) {
+  EXPECT_EQ("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
+            "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
+            "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+            format("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
+                   "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
+                   "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
+  EXPECT_EQ("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+            "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+            "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+            format("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+                   "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+                   "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+                   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("double\n"
+            "    a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+            "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+            "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+            format("double a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+                   "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+                   "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+                   getLLVMStyleWithColumns(49)));
+}
+
+TEST_F(FormatTestComments, DontSplitLineCommentsWithPragmas) {
+  FormatStyle Pragmas = getLLVMStyleWithColumns(30);
+  Pragmas.CommentPragmas = "^ IWYU pragma:";
+  EXPECT_EQ(
+      "// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb",
+      format("// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", Pragmas));
+  EXPECT_EQ(
+      "/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */",
+      format("/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", Pragmas));
+}
+
+TEST_F(FormatTestComments, PriorityOfCommentBreaking) {
+  EXPECT_EQ("if (xxx ==\n"
+            "        yyy && // aaaaaaaaaaaa bbbbbbbbb\n"
+            "    zzz)\n"
+            "  q();",
+            format("if (xxx == yyy && // aaaaaaaaaaaa bbbbbbbbb\n"
+                   "    zzz) q();",
+                   getLLVMStyleWithColumns(40)));
+  EXPECT_EQ("if (xxxxxxxxxx ==\n"
+            "        yyy && // aaaaaa bbbbbbbb cccc\n"
+            "    zzz)\n"
+            "  q();",
+            format("if (xxxxxxxxxx == yyy && // aaaaaa bbbbbbbb cccc\n"
+                   "    zzz) q();",
+                   getLLVMStyleWithColumns(40)));
+  EXPECT_EQ("if (xxxxxxxxxx &&\n"
+            "        yyy || // aaaaaa bbbbbbbb cccc\n"
+            "    zzz)\n"
+            "  q();",
+            format("if (xxxxxxxxxx && yyy || // aaaaaa bbbbbbbb cccc\n"
+                   "    zzz) q();",
+                   getLLVMStyleWithColumns(40)));
+  EXPECT_EQ("fffffffff(\n"
+            "    &xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n"
+            "    zzz);",
+            format("fffffffff(&xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n"
+                   " zzz);",
+                   getLLVMStyleWithColumns(40)));
+}
+
+TEST_F(FormatTestComments, MultiLineCommentsInDefines) {
+  EXPECT_EQ("#define A(x) /* \\\n"
+            "  a comment     \\\n"
+            "  inside */     \\\n"
+            "  f();",
+            format("#define A(x) /* \\\n"
+                   "  a comment     \\\n"
+                   "  inside */     \\\n"
+                   "  f();",
+                   getLLVMStyleWithColumns(17)));
+  EXPECT_EQ("#define A(      \\\n"
+            "    x) /*       \\\n"
+            "  a comment     \\\n"
+            "  inside */     \\\n"
+            "  f();",
+            format("#define A(      \\\n"
+                   "    x) /*       \\\n"
+                   "  a comment     \\\n"
+                   "  inside */     \\\n"
+                   "  f();",
+                   getLLVMStyleWithColumns(17)));
+}
+
+TEST_F(FormatTestComments, ParsesCommentsAdjacentToPPDirectives) {
+  EXPECT_EQ("namespace {}\n// Test\n#define A",
+            format("namespace {}\n   // Test\n#define A"));
+  EXPECT_EQ("namespace {}\n/* Test */\n#define A",
+            format("namespace {}\n   /* Test */\n#define A"));
+  EXPECT_EQ("namespace {}\n/* Test */ #define A",
+            format("namespace {}\n   /* Test */    #define A"));
+}
+
+TEST_F(FormatTestComments, SplitsLongLinesInComments) {
+  EXPECT_EQ("/* This is a long\n"
+            " * comment that\n"
+            " * doesn't\n"
+            " * fit on one line.\n"
+            " */",
+            format("/* "
+                   "This is a long                                         "
+                   "comment that "
+                   "doesn't                                    "
+                   "fit on one line.  */",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ(
+      "/* a b c d\n"
+      " * e f  g\n"
+      " * h i j k\n"
+      " */",
+      format("/* a b c d e f  g h i j k */", getLLVMStyleWithColumns(10)));
+  EXPECT_EQ(
+      "/* a b c d\n"
+      " * e f  g\n"
+      " * h i j k\n"
+      " */",
+      format("\\\n/* a b c d e f  g h i j k */", getLLVMStyleWithColumns(10)));
+  EXPECT_EQ("/*\n"
+            "This is a long\n"
+            "comment that doesn't\n"
+            "fit on one line.\n"
+            "*/",
+            format("/*\n"
+                   "This is a long                                         "
+                   "comment that doesn't                                    "
+                   "fit on one line.                                      \n"
+                   "*/",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/*\n"
+            " * This is a long\n"
+            " * comment that\n"
+            " * doesn't fit on\n"
+            " * one line.\n"
+            " */",
+            format("/*      \n"
+                   " * This is a long "
+                   "   comment that     "
+                   "   doesn't fit on   "
+                   "   one line.                                            \n"
+                   " */",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/*\n"
+            " * This_is_a_comment_with_words_that_dont_fit_on_one_line\n"
+            " * so_it_should_be_broken\n"
+            " * wherever_a_space_occurs\n"
+            " */",
+            format("/*\n"
+                   " * This_is_a_comment_with_words_that_dont_fit_on_one_line "
+                   "   so_it_should_be_broken "
+                   "   wherever_a_space_occurs                             \n"
+                   " */",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/*\n"
+            " *    This_comment_can_not_be_broken_into_lines\n"
+            " */",
+            format("/*\n"
+                   " *    This_comment_can_not_be_broken_into_lines\n"
+                   " */",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("{\n"
+            "  /*\n"
+            "  This is another\n"
+            "  long comment that\n"
+            "  doesn't fit on one\n"
+            "  line    1234567890\n"
+            "  */\n"
+            "}",
+            format("{\n"
+                   "/*\n"
+                   "This is another     "
+                   "  long comment that "
+                   "  doesn't fit on one"
+                   "  line    1234567890\n"
+                   "*/\n"
+                   "}",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("{\n"
+            "  /*\n"
+            "   * This        i s\n"
+            "   * another comment\n"
+            "   * t hat  doesn' t\n"
+            "   * fit on one l i\n"
+            "   * n e\n"
+            "   */\n"
+            "}",
+            format("{\n"
+                   "/*\n"
+                   " * This        i s"
+                   "   another comment"
+                   "   t hat  doesn' t"
+                   "   fit on one l i"
+                   "   n e\n"
+                   " */\n"
+                   "}",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/*\n"
+            " * This is a long\n"
+            " * comment that\n"
+            " * doesn't fit on\n"
+            " * one line\n"
+            " */",
+            format("   /*\n"
+                   "    * This is a long comment that doesn't fit on one line\n"
+                   "    */",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("{\n"
+            "  if (something) /* This is a\n"
+            "                    long\n"
+            "                    comment */\n"
+            "    ;\n"
+            "}",
+            format("{\n"
+                   "  if (something) /* This is a long comment */\n"
+                   "    ;\n"
+                   "}",
+                   getLLVMStyleWithColumns(30)));
+
+  EXPECT_EQ("/* A comment before\n"
+            " * a macro\n"
+            " * definition */\n"
+            "#define a b",
+            format("/* A comment before a macro definition */\n"
+                   "#define a b",
+                   getLLVMStyleWithColumns(20)));
+
+  EXPECT_EQ("/* some comment\n"
+            " *   a comment that\n"
+            " * we break another\n"
+            " * comment we have\n"
+            " * to break a left\n"
+            " * comment\n"
+            " */",
+            format("  /* some comment\n"
+                   "       *   a comment that we break\n"
+                   "   * another comment we have to break\n"
+                   "* a left comment\n"
+                   "   */",
+                   getLLVMStyleWithColumns(20)));
+
+  EXPECT_EQ("/**\n"
+            " * multiline block\n"
+            " * comment\n"
+            " *\n"
+            " */",
+            format("/**\n"
+                   " * multiline block comment\n"
+                   " *\n"
+                   " */",
+                   getLLVMStyleWithColumns(20)));
+
+  EXPECT_EQ("/*\n"
+            "\n"
+            "\n"
+            "    */\n",
+            format("  /*       \n"
+                   "      \n"
+                   "               \n"
+                   "      */\n"));
+
+  EXPECT_EQ("/* a a */",
+            format("/* a a            */", getLLVMStyleWithColumns(15)));
+  EXPECT_EQ("/* a a bc  */",
+            format("/* a a            bc  */", getLLVMStyleWithColumns(15)));
+  EXPECT_EQ("/* aaa aaa\n"
+            " * aaaaa */",
+            format("/* aaa aaa aaaaa       */", getLLVMStyleWithColumns(15)));
+  EXPECT_EQ("/* aaa aaa\n"
+            " * aaaaa     */",
+            format("/* aaa aaa aaaaa     */", getLLVMStyleWithColumns(15)));
+}
+
+TEST_F(FormatTestComments, SplitsLongLinesInCommentsInPreprocessor) {
+  EXPECT_EQ("#define X          \\\n"
+            "  /*               \\\n"
+            "   Test            \\\n"
+            "   Macro comment   \\\n"
+            "   with a long     \\\n"
+            "   line            \\\n"
+            "   */              \\\n"
+            "  A + B",
+            format("#define X \\\n"
+                   "  /*\n"
+                   "   Test\n"
+                   "   Macro comment with a long  line\n"
+                   "   */ \\\n"
+                   "  A + B",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("#define X          \\\n"
+            "  /* Macro comment \\\n"
+            "     with a long   \\\n"
+            "     line */       \\\n"
+            "  A + B",
+            format("#define X \\\n"
+                   "  /* Macro comment with a long\n"
+                   "     line */ \\\n"
+                   "  A + B",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("#define X          \\\n"
+            "  /* Macro comment \\\n"
+            "   * with a long   \\\n"
+            "   * line */       \\\n"
+            "  A + B",
+            format("#define X \\\n"
+                   "  /* Macro comment with a long  line */ \\\n"
+                   "  A + B",
+                   getLLVMStyleWithColumns(20)));
+}
+
+TEST_F(FormatTestComments, CommentsInStaticInitializers) {
+  EXPECT_EQ(
+      "static SomeType type = {aaaaaaaaaaaaaaaaaaaa, /* comment */\n"
+      "                        aaaaaaaaaaaaaaaaaaaa /* comment */,\n"
+      "                        /* comment */ aaaaaaaaaaaaaaaaaaaa,\n"
+      "                        aaaaaaaaaaaaaaaaaaaa, // comment\n"
+      "                        aaaaaaaaaaaaaaaaaaaa};",
+      format("static SomeType type = { aaaaaaaaaaaaaaaaaaaa  ,  /* comment */\n"
+             "                   aaaaaaaaaaaaaaaaaaaa   /* comment */ ,\n"
+             "                     /* comment */   aaaaaaaaaaaaaaaaaaaa ,\n"
+             "              aaaaaaaaaaaaaaaaaaaa ,   // comment\n"
+             "                  aaaaaaaaaaaaaaaaaaaa };"));
+  verifyFormat("static SomeType type = {aaaaaaaaaaa, // comment for aa...\n"
+               "                        bbbbbbbbbbb, ccccccccccc};");
+  verifyFormat("static SomeType type = {aaaaaaaaaaa,\n"
+               "                        // comment for bb....\n"
+               "                        bbbbbbbbbbb, ccccccccccc};");
+  verifyGoogleFormat(
+      "static SomeType type = {aaaaaaaaaaa,  // comment for aa...\n"
+      "                        bbbbbbbbbbb, ccccccccccc};");
+  verifyGoogleFormat("static SomeType type = {aaaaaaaaaaa,\n"
+                     "                        // comment for bb....\n"
+                     "                        bbbbbbbbbbb, ccccccccccc};");
+
+  verifyFormat("S s = {{a, b, c},  // Group #1\n"
+               "       {d, e, f},  // Group #2\n"
+               "       {g, h, i}}; // Group #3");
+  verifyFormat("S s = {{// Group #1\n"
+               "        a, b, c},\n"
+               "       {// Group #2\n"
+               "        d, e, f},\n"
+               "       {// Group #3\n"
+               "        g, h, i}};");
+
+  EXPECT_EQ("S s = {\n"
+            "    // Some comment\n"
+            "    a,\n"
+            "\n"
+            "    // Comment after empty line\n"
+            "    b}",
+            format("S s =    {\n"
+                   "      // Some comment\n"
+                   "  a,\n"
+                   "  \n"
+                   "     // Comment after empty line\n"
+                   "      b\n"
+                   "}"));
+  EXPECT_EQ("S s = {\n"
+            "    /* Some comment */\n"
+            "    a,\n"
+            "\n"
+            "    /* Comment after empty line */\n"
+            "    b}",
+            format("S s =    {\n"
+                   "      /* Some comment */\n"
+                   "  a,\n"
+                   "  \n"
+                   "     /* Comment after empty line */\n"
+                   "      b\n"
+                   "}"));
+  verifyFormat("const uint8_t aaaaaaaaaaaaaaaaaaaaaa[0] = {\n"
+               "    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n"
+               "    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n"
+               "    0x00, 0x00, 0x00, 0x00};            // comment\n");
+}
+
+TEST_F(FormatTestComments, LineCommentsAfterRightBrace) {
+  EXPECT_EQ("if (true) { // comment about branch\n"
+            "  // comment about f\n"
+            "  f();\n"
+            "}",
+            format("if (true) { // comment about branch\n"
+                   "  // comment about f\n"
+                   "  f();\n"
+                   "}",
+                   getLLVMStyleWithColumns(80)));
+  EXPECT_EQ("if (1) { // if line 1\n"
+            "         // if line 2\n"
+            "         // if line 3\n"
+            "  // f line 1\n"
+            "  // f line 2\n"
+            "  f();\n"
+            "} else { // else line 1\n"
+            "         // else line 2\n"
+            "         // else line 3\n"
+            "  // g line 1\n"
+            "  g();\n"
+            "}",
+            format("if (1) { // if line 1\n"
+                   "          // if line 2\n"
+                   "        // if line 3\n"
+                   "  // f line 1\n"
+                   "    // f line 2\n"
+                   "  f();\n"
+                   "} else { // else line 1\n"
+                   "        // else line 2\n"
+                   "         // else line 3\n"
+                   "  // g line 1\n"
+                   "  g();\n"
+                   "}"));
+  EXPECT_EQ("do { // line 1\n"
+            "     // line 2\n"
+            "     // line 3\n"
+            "  f();\n"
+            "} while (true);",
+            format("do { // line 1\n"
+                   "     // line 2\n"
+                   "   // line 3\n"
+                   "  f();\n"
+                   "} while (true);",
+                   getLLVMStyleWithColumns(80)));
+  EXPECT_EQ("while (a < b) { // line 1\n"
+            "  // line 2\n"
+            "  // line 3\n"
+            "  f();\n"
+            "}",
+            format("while (a < b) {// line 1\n"
+                   "  // line 2\n"
+                   "  // line 3\n"
+                   "  f();\n"
+                   "}",
+                   getLLVMStyleWithColumns(80)));
+}
+
+TEST_F(FormatTestComments, ReflowsComments) {
+  // Break a long line and reflow with the full next line.
+  EXPECT_EQ("// long long long\n"
+            "// long long",
+            format("// long long long long\n"
+                   "// long",
+                   getLLVMStyleWithColumns(20)));
+
+  // Keep the trailing newline while reflowing.
+  EXPECT_EQ("// long long long\n"
+            "// long long\n",
+            format("// long long long long\n"
+                   "// long\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Break a long line and reflow with a part of the next line.
+  EXPECT_EQ("// long long long\n"
+            "// long long\n"
+            "// long_long",
+            format("// long long long long\n"
+                   "// long long_long",
+                   getLLVMStyleWithColumns(20)));
+
+  // Break but do not reflow if the first word from the next line is too long.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "// long_long_long\n",
+            format("// long long long long\n"
+                   "// long_long_long\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't break or reflow short lines.
+  verifyFormat("// long\n"
+               "// long long long lo\n"
+               "// long long long lo\n"
+               "// long",
+               getLLVMStyleWithColumns(20));
+
+  // Keep prefixes and decorations while reflowing.
+  EXPECT_EQ("/// long long long\n"
+            "/// long long\n",
+            format("/// long long long long\n"
+                   "/// long\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("//! long long long\n"
+            "//! long long\n",
+            format("//! long long long long\n"
+                   "//! long\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/* long long long\n"
+            " * long long */",
+            format("/* long long long long\n"
+                   " * long */",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't bring leading whitespace up while reflowing.
+  EXPECT_EQ("/*  long long long\n"
+            " * long long long\n"
+            " */",
+            format("/*  long long long long\n"
+                   " *  long long\n"
+                   " */",
+                   getLLVMStyleWithColumns(20)));
+
+  // Reflow the last line of a block comment with its trailing '*/'.
+  EXPECT_EQ("/* long long long\n"
+            "   long long */",
+            format("/* long long long long\n"
+                   "   long */",
+                   getLLVMStyleWithColumns(20)));
+
+  // Reflow two short lines; keep the postfix of the last one.
+  EXPECT_EQ("/* long long long\n"
+            " * long long long */",
+            format("/* long long long long\n"
+                   " * long\n"
+                   " * long */",
+                   getLLVMStyleWithColumns(20)));
+
+  // Put the postfix of the last short reflow line on a newline if it doesn't
+  // fit.
+  EXPECT_EQ("/* long long long\n"
+            " * long long longg\n"
+            " */",
+            format("/* long long long long\n"
+                   " * long\n"
+                   " * longg */",
+                   getLLVMStyleWithColumns(20)));
+
+  // Reflow lines with leading whitespace.
+  EXPECT_EQ("{\n"
+            "  /*\n"
+            "   * long long long\n"
+            "   * long long long\n"
+            "   * long long long\n"
+            "   */\n"
+            "}",
+            format("{\n"
+                   "/*\n"
+                   " * long long long long\n"
+                   " *   long\n"
+                   " * long long long long\n"
+                   " */\n"
+                   "}",
+                   getLLVMStyleWithColumns(20)));
+
+  // Break single line block comments that are first in the line with ' *'
+  // decoration.
+  EXPECT_EQ("/* long long long\n"
+            " * long */",
+            format("/* long long long long */", getLLVMStyleWithColumns(20)));
+
+  // Break single line block comment that are not first in the line with '  '
+  // decoration.
+  EXPECT_EQ("int i; /* long long\n"
+            "          long */",
+            format("int i; /* long long long */", getLLVMStyleWithColumns(20)));
+
+  // Reflow a line that goes just over the column limit.
+  EXPECT_EQ("// long long long\n"
+            "// lon long",
+            format("// long long long lon\n"
+                   "// long",
+                   getLLVMStyleWithColumns(20)));
+
+  // Stop reflowing if the next line has a different indentation than the
+  // previous line.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "//  long long\n"
+            "//  long",
+            format("// long long long long\n"
+                   "//  long long\n"
+                   "//  long",
+                   getLLVMStyleWithColumns(20)));
+
+  // Reflow into the last part of a really long line that has been broken into
+  // multiple lines.
+  EXPECT_EQ("// long long long\n"
+            "// long long long\n"
+            "// long long long\n",
+            format("// long long long long long long long long\n"
+                   "// long\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Break the first line, then reflow the beginning of the second and third
+  // line up.
+  EXPECT_EQ("// long long long\n"
+            "// lon1 lon2 lon2\n"
+            "// lon2 lon3 lon3",
+            format("// long long long lon1\n"
+                   "// lon2 lon2 lon2\n"
+                   "// lon3 lon3",
+                   getLLVMStyleWithColumns(20)));
+
+  // Reflow the beginning of the second line, then break the rest.
+  EXPECT_EQ("// long long long\n"
+            "// lon1 lon2 lon2\n"
+            "// lon2 lon2 lon2\n"
+            "// lon3",
+            format("// long long long lon1\n"
+                   "// lon2 lon2 lon2 lon2 lon2 lon3",
+                   getLLVMStyleWithColumns(20)));
+
+  // Shrink the first line, then reflow the second line up.
+  EXPECT_EQ("// long long long", format("// long              long\n"
+                                        "// long",
+                                        getLLVMStyleWithColumns(20)));
+
+  // Don't shrink leading whitespace.
+  EXPECT_EQ("int i; ///           a",
+            format("int i; ///           a", getLLVMStyleWithColumns(20)));
+
+  // Shrink trailing whitespace if there is no postfix and reflow.
+  EXPECT_EQ("// long long long\n"
+            "// long long",
+            format("// long long long long    \n"
+                   "// long",
+                   getLLVMStyleWithColumns(20)));
+
+  // Shrink trailing whitespace to a single one if there is postfix.
+  EXPECT_EQ("/* long long long */",
+            format("/* long long long     */", getLLVMStyleWithColumns(20)));
+
+  // Break a block comment postfix if exceeding the line limit.
+  EXPECT_EQ("/*               long\n"
+            " */",
+            format("/*               long */", getLLVMStyleWithColumns(20)));
+
+  // Reflow indented comments.
+  EXPECT_EQ("{\n"
+            "  // long long long\n"
+            "  // long long\n"
+            "  int i; /* long lon\n"
+            "            g long\n"
+            "          */\n"
+            "}",
+            format("{\n"
+                   "  // long long long long\n"
+                   "  // long\n"
+                   "  int i; /* long lon g\n"
+                   "            long */\n"
+                   "}",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't realign trailing comments after reflow has happened.
+  EXPECT_EQ("// long long long\n"
+            "// long long\n"
+            "long i; // long",
+            format("// long long long long\n"
+                   "// long\n"
+                   "long i; // long",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("// long long long\n"
+            "// longng long long\n"
+            "// long lo",
+            format("// long long long longng\n"
+                   "// long long long\n"
+                   "// lo",
+                   getLLVMStyleWithColumns(20)));
+
+  // Reflow lines after a broken line.
+  EXPECT_EQ("int a; // Trailing\n"
+            "       // comment on\n"
+            "       // 2 or 3\n"
+            "       // lines.\n",
+            format("int a; // Trailing comment\n"
+                   "       // on 2\n"
+                   "       // or 3\n"
+                   "       // lines.\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/// This long line\n"
+            "/// gets reflown.\n",
+            format("/// This long line gets\n"
+                   "/// reflown.\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("//! This long line\n"
+            "//! gets reflown.\n",
+            format(" //! This long line gets\n"
+                   " //! reflown.\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/* This long line\n"
+            " * gets reflown.\n"
+            " */\n",
+            format("/* This long line gets\n"
+                   " * reflown.\n"
+                   " */\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Reflow after indentation makes a line too long.
+  EXPECT_EQ("{\n"
+            "  // long long long\n"
+            "  // lo long\n"
+            "}\n",
+            format("{\n"
+                   "// long long long lo\n"
+                   "// long\n"
+                   "}\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Break and reflow multiple lines.
+  EXPECT_EQ("/*\n"
+            " * Reflow the end of\n"
+            " * line by 11 22 33\n"
+            " * 4.\n"
+            " */\n",
+            format("/*\n"
+                   " * Reflow the end of line\n"
+                   " * by\n"
+                   " * 11\n"
+                   " * 22\n"
+                   " * 33\n"
+                   " * 4.\n"
+                   " */\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/// First line gets\n"
+            "/// broken. Second\n"
+            "/// line gets\n"
+            "/// reflown and\n"
+            "/// broken. Third\n"
+            "/// gets reflown.\n",
+            format("/// First line gets broken.\n"
+                   "/// Second line gets reflown and broken.\n"
+                   "/// Third gets reflown.\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("int i; // first long\n"
+            "       // long snd\n"
+            "       // long.\n",
+            format("int i; // first long long\n"
+                   "       // snd long.\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("{\n"
+            "  // first long line\n"
+            "  // line second\n"
+            "  // long line line\n"
+            "  // third long line\n"
+            "  // line\n"
+            "}\n",
+            format("{\n"
+                   "  // first long line line\n"
+                   "  // second long line line\n"
+                   "  // third long line line\n"
+                   "}\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("int i; /* first line\n"
+            "        * second\n"
+            "        * line third\n"
+            "        * line\n"
+            "        */",
+            format("int i; /* first line\n"
+                   "        * second line\n"
+                   "        * third line\n"
+                   "        */",
+                   getLLVMStyleWithColumns(20)));
+
+  // Reflow the last two lines of a section that starts with a line having
+  // different indentation.
+  EXPECT_EQ(
+      "//     long\n"
+      "// long long long\n"
+      "// long long",
+      format("//     long\n"
+             "// long long long long\n"
+             "// long",
+             getLLVMStyleWithColumns(20)));
+
+  // Keep the block comment endling '*/' while reflowing.
+  EXPECT_EQ("/* Long long long\n"
+            " * line short */\n",
+            format("/* Long long long line\n"
+                   " * short */\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't reflow between separate blocks of comments.
+  EXPECT_EQ("/* First comment\n"
+            " * block will */\n"
+            "/* Snd\n"
+            " */\n",
+            format("/* First comment block\n"
+                   " * will */\n"
+                   "/* Snd\n"
+                   " */\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't reflow across blank comment lines.
+  EXPECT_EQ("int i; // This long\n"
+            "       // line gets\n"
+            "       // broken.\n"
+            "       //\n"
+            "       // keep.\n",
+            format("int i; // This long line gets broken.\n"
+                   "       //  \n"
+                   "       // keep.\n",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("{\n"
+            "  /// long long long\n"
+            "  /// long long\n"
+            "  ///\n"
+            "  /// long\n"
+            "}",
+            format("{\n"
+                   "  /// long long long long\n"
+                   "  /// long\n"
+                   "  ///\n"
+                   "  /// long\n"
+                   "}",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("//! long long long\n"
+            "//! long\n"
+            "\n"
+            "//! long",
+            format("//! long long long long\n"
+                   "\n"
+                   "//! long",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/* long long long\n"
+            "   long\n"
+            "\n"
+            "   long */",
+            format("/* long long long long\n"
+                   "\n"
+                   "   long */",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/* long long long\n"
+            " * long\n"
+            " *\n"
+            " * long */",
+            format("/* long long long long\n"
+                   " *\n"
+                   " * long */",
+                   getLLVMStyleWithColumns(20)));
+  
+  // Don't reflow lines having content that is a single character.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "// l",
+            format("// long long long long\n"
+                   "// l",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't reflow lines starting with two punctuation characters.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "// ... --- ...",
+            format(
+                "// long long long long\n"
+                "// ... --- ...",
+                getLLVMStyleWithColumns(20)));
+
+  // Don't reflow lines starting with '@'.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "// @param arg",
+            format("// long long long long\n"
+                   "// @param arg",
+                   getLLVMStyleWithColumns(20)));
+  
+  // Don't reflow lines starting with 'TODO'.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "// TODO: long",
+            format("// long long long long\n"
+                   "// TODO: long",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't reflow lines starting with 'FIXME'.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "// FIXME: long",
+            format("// long long long long\n"
+                   "// FIXME: long",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't reflow lines starting with 'XXX'.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "// XXX: long",
+            format("// long long long long\n"
+                   "// XXX: long",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't reflow comment pragmas.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "// IWYU pragma:",
+            format("// long long long long\n"
+                   "// IWYU pragma:",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/* long long long\n"
+            " * long\n"
+            " * IWYU pragma:\n"
+            " */",
+            format("/* long long long long\n"
+                   " * IWYU pragma:\n"
+                   " */",
+                   getLLVMStyleWithColumns(20)));
+
+  // Reflow lines that have a non-punctuation character among their first 2
+  // characters.
+  EXPECT_EQ("// long long long\n"
+            "// long 'long'",
+            format(
+                "// long long long long\n"
+                "// 'long'",
+                getLLVMStyleWithColumns(20)));
+
+  // Don't reflow between separate blocks of comments.
+  EXPECT_EQ("/* First comment\n"
+            " * block will */\n"
+            "/* Snd\n"
+            " */\n",
+            format("/* First comment block\n"
+                   " * will */\n"
+                   "/* Snd\n"
+                   " */\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't reflow lines having different indentation.
+  EXPECT_EQ("// long long long\n"
+            "// long\n"
+            "//  long",
+            format("// long long long long\n"
+                   "//  long",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't break or reflow after implicit string literals.
+  verifyFormat("#include <t> // l l l\n"
+               "             // l",
+               getLLVMStyleWithColumns(20));
+
+  // Don't break or reflow comments on import lines.
+  EXPECT_EQ("#include \"t\" /* l l l\n"
+            "                * l */",
+            format("#include \"t\" /* l l l\n"
+                   "                * l */",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't reflow between different trailing comment sections.
+  EXPECT_EQ("int i; // long long\n"
+            "       // long\n"
+            "int j; // long long\n"
+            "       // long\n",
+            format("int i; // long long long\n"
+                   "int j; // long long long\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Don't reflow if the first word on the next line is longer than the
+  // available space at current line.
+  EXPECT_EQ("int i; // trigger\n"
+            "       // reflow\n"
+            "       // longsec\n",
+            format("int i; // trigger reflow\n"
+                   "       // longsec\n",
+                   getLLVMStyleWithColumns(20)));
+
+  // Keep empty comment lines.
+  EXPECT_EQ("/**/", format(" /**/", getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/* */", format(" /* */", getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("/*  */", format(" /*  */", getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("//", format(" //  ", getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("///", format(" ///  ", getLLVMStyleWithColumns(20)));
+}
+
+TEST_F(FormatTestComments, IgnoresIf0Contents) {
+  EXPECT_EQ("#if 0\n"
+            "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
+            "#endif\n"
+            "void f() {}",
+            format("#if 0\n"
+                   "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
+                   "#endif\n"
+                   "void f(  ) {  }"));
+  EXPECT_EQ("#if false\n"
+            "void f(  ) {  }\n"
+            "#endif\n"
+            "void g() {}\n",
+            format("#if false\n"
+                   "void f(  ) {  }\n"
+                   "#endif\n"
+                   "void g(  ) {  }\n"));
+  EXPECT_EQ("enum E {\n"
+            "  One,\n"
+            "  Two,\n"
+            "#if 0\n"
+            "Three,\n"
+            "      Four,\n"
+            "#endif\n"
+            "  Five\n"
+            "};",
+            format("enum E {\n"
+                   "  One,Two,\n"
+                   "#if 0\n"
+                   "Three,\n"
+                   "      Four,\n"
+                   "#endif\n"
+                   "  Five};"));
+  EXPECT_EQ("enum F {\n"
+            "  One,\n"
+            "#if 1\n"
+            "  Two,\n"
+            "#if 0\n"
+            "Three,\n"
+            "      Four,\n"
+            "#endif\n"
+            "  Five\n"
+            "#endif\n"
+            "};",
+            format("enum F {\n"
+                   "One,\n"
+                   "#if 1\n"
+                   "Two,\n"
+                   "#if 0\n"
+                   "Three,\n"
+                   "      Four,\n"
+                   "#endif\n"
+                   "Five\n"
+                   "#endif\n"
+                   "};"));
+  EXPECT_EQ("enum G {\n"
+            "  One,\n"
+            "#if 0\n"
+            "Two,\n"
+            "#else\n"
+            "  Three,\n"
+            "#endif\n"
+            "  Four\n"
+            "};",
+            format("enum G {\n"
+                   "One,\n"
+                   "#if 0\n"
+                   "Two,\n"
+                   "#else\n"
+                   "Three,\n"
+                   "#endif\n"
+                   "Four\n"
+                   "};"));
+  EXPECT_EQ("enum H {\n"
+            "  One,\n"
+            "#if 0\n"
+            "#ifdef Q\n"
+            "Two,\n"
+            "#else\n"
+            "Three,\n"
+            "#endif\n"
+            "#endif\n"
+            "  Four\n"
+            "};",
+            format("enum H {\n"
+                   "One,\n"
+                   "#if 0\n"
+                   "#ifdef Q\n"
+                   "Two,\n"
+                   "#else\n"
+                   "Three,\n"
+                   "#endif\n"
+                   "#endif\n"
+                   "Four\n"
+                   "};"));
+  EXPECT_EQ("enum I {\n"
+            "  One,\n"
+            "#if /* test */ 0 || 1\n"
+            "Two,\n"
+            "Three,\n"
+            "#endif\n"
+            "  Four\n"
+            "};",
+            format("enum I {\n"
+                   "One,\n"
+                   "#if /* test */ 0 || 1\n"
+                   "Two,\n"
+                   "Three,\n"
+                   "#endif\n"
+                   "Four\n"
+                   "};"));
+  EXPECT_EQ("enum J {\n"
+            "  One,\n"
+            "#if 0\n"
+            "#if 0\n"
+            "Two,\n"
+            "#else\n"
+            "Three,\n"
+            "#endif\n"
+            "Four,\n"
+            "#endif\n"
+            "  Five\n"
+            "};",
+            format("enum J {\n"
+                   "One,\n"
+                   "#if 0\n"
+                   "#if 0\n"
+                   "Two,\n"
+                   "#else\n"
+                   "Three,\n"
+                   "#endif\n"
+                   "Four,\n"
+                   "#endif\n"
+                   "Five\n"
+                   "};"));
+
+  // Ignore stuff in SWIG-blocks.
+  EXPECT_EQ("#ifdef SWIG\n"
+            "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
+            "#endif\n"
+            "void f() {}",
+            format("#ifdef SWIG\n"
+                   "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
+                   "#endif\n"
+                   "void f(  ) {  }"));
+  EXPECT_EQ("#ifndef SWIG\n"
+            "void f() {}\n"
+            "#endif",
+            format("#ifndef SWIG\n"
+                   "void f(      ) {       }\n"
+                   "#endif"));
+}
+
+TEST_F(FormatTestComments, DontCrashOnBlockComments) {
+  EXPECT_EQ(
+      "int xxxxxxxxx; /* "
+      "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n"
+      "zzzzzz\n"
+      "0*/",
+      format("int xxxxxxxxx;                          /* "
+             "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzz\n"
+             "0*/"));
+}
+
+TEST_F(FormatTestComments, BlockCommentsInControlLoops) {
+  verifyFormat("if (0) /* a comment in a strange place */ {\n"
+               "  f();\n"
+               "}");
+  verifyFormat("if (0) /* a comment in a strange place */ {\n"
+               "  f();\n"
+               "} /* another comment */ else /* comment #3 */ {\n"
+               "  g();\n"
+               "}");
+  verifyFormat("while (0) /* a comment in a strange place */ {\n"
+               "  f();\n"
+               "}");
+  verifyFormat("for (;;) /* a comment in a strange place */ {\n"
+               "  f();\n"
+               "}");
+  verifyFormat("do /* a comment in a strange place */ {\n"
+               "  f();\n"
+               "} /* another comment */ while (0);");
+}
+
+TEST_F(FormatTestComments, BlockComments) {
+  EXPECT_EQ("/* */ /* */ /* */\n/* */ /* */ /* */",
+            format("/* *//* */  /* */\n/* *//* */  /* */"));
+  EXPECT_EQ("/* */ a /* */ b;", format("  /* */  a/* */  b;"));
+  EXPECT_EQ("#define A /*123*/ \\\n"
+            "  b\n"
+            "/* */\n"
+            "someCall(\n"
+            "    parameter);",
+            format("#define A /*123*/ b\n"
+                   "/* */\n"
+                   "someCall(parameter);",
+                   getLLVMStyleWithColumns(15)));
+
+  EXPECT_EQ("#define A\n"
+            "/* */ someCall(\n"
+            "    parameter);",
+            format("#define A\n"
+                   "/* */someCall(parameter);",
+                   getLLVMStyleWithColumns(15)));
+  EXPECT_EQ("/*\n**\n*/", format("/*\n**\n*/"));
+  EXPECT_EQ("/*\n"
+            " *\n"
+            " * aaaaaa\n"
+            " * aaaaaa\n"
+            " */",
+            format("/*\n"
+                   "*\n"
+                   " * aaaaaa aaaaaa\n"
+                   "*/",
+                   getLLVMStyleWithColumns(10)));
+  EXPECT_EQ("/*\n"
+            "**\n"
+            "* aaaaaa\n"
+            "*aaaaaa\n"
+            "*/",
+            format("/*\n"
+                   "**\n"
+                   "* aaaaaa aaaaaa\n"
+                   "*/",
+                   getLLVMStyleWithColumns(10)));
+  EXPECT_EQ("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
+            "    /* line 1\n"
+            "       bbbbbbbbbbbb */\n"
+            "    bbbbbbbbbbbbbbbbbbbbbbbbbbbb;",
+            format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
+                   "    /* line 1\n"
+                   "       bbbbbbbbbbbb */ bbbbbbbbbbbbbbbbbbbbbbbbbbbb;",
+            getLLVMStyleWithColumns(50)));
+
+  FormatStyle NoBinPacking = getLLVMStyle();
+  NoBinPacking.BinPackParameters = false;
+  EXPECT_EQ("someFunction(1, /* comment 1 */\n"
+            "             2, /* comment 2 */\n"
+            "             3, /* comment 3 */\n"
+            "             aaaa,\n"
+            "             bbbb);",
+            format("someFunction (1,   /* comment 1 */\n"
+                   "                2, /* comment 2 */  \n"
+                   "               3,   /* comment 3 */\n"
+                   "aaaa, bbbb );",
+                   NoBinPacking));
+  verifyFormat(
+      "bool aaaaaaaaaaaaa = /* comment: */ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
+      "                     aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+  EXPECT_EQ(
+      "bool aaaaaaaaaaaaa = /* trailing comment */\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaa;",
+      format(
+          "bool       aaaaaaaaaaaaa =       /* trailing comment */\n"
+          "    aaaaaaaaaaaaaaaaaaaaaaaaaaa||aaaaaaaaaaaaaaaaaaaaaaaaa    ||\n"
+          "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa   || aaaaaaaaaaaaaaaaaaaaaaaaaa;"));
+  EXPECT_EQ(
+      "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n"
+      "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;   /* comment */\n"
+      "int cccccccccccccccccccccccccccccc;       /* comment */\n",
+      format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n"
+             "int      bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n"
+             "int    cccccccccccccccccccccccccccccc;  /* comment */\n"));
+
+  verifyFormat("void f(int * /* unused */) {}");
+
+  EXPECT_EQ("/*\n"
+            " **\n"
+            " */",
+            format("/*\n"
+                   " **\n"
+                   " */"));
+  EXPECT_EQ("/*\n"
+            " *q\n"
+            " */",
+            format("/*\n"
+                   " *q\n"
+                   " */"));
+  EXPECT_EQ("/*\n"
+            " * q\n"
+            " */",
+            format("/*\n"
+                   " * q\n"
+                   " */"));
+  EXPECT_EQ("/*\n"
+            " **/",
+            format("/*\n"
+                   " **/"));
+  EXPECT_EQ("/*\n"
+            " ***/",
+            format("/*\n"
+                   " ***/"));
+}
+
+TEST_F(FormatTestComments, BlockCommentsInMacros) {
+  EXPECT_EQ("#define A          \\\n"
+            "  {                \\\n"
+            "    /* one line */ \\\n"
+            "    someCall();",
+            format("#define A {        \\\n"
+                   "  /* one line */   \\\n"
+                   "  someCall();",
+                   getLLVMStyleWithColumns(20)));
+  EXPECT_EQ("#define A          \\\n"
+            "  {                \\\n"
+            "    /* previous */ \\\n"
+            "    /* one line */ \\\n"
+            "    someCall();",
+            format("#define A {        \\\n"
+                   "  /* previous */   \\\n"
+                   "  /* one line */   \\\n"
+                   "  someCall();",
+                   getLLVMStyleWithColumns(20)));
+}
+
+TEST_F(FormatTestComments, BlockCommentsAtEndOfLine) {
+  EXPECT_EQ("a = {\n"
+            "    1111 /*    */\n"
+            "};",
+            format("a = {1111 /*    */\n"
+                   "};",
+                   getLLVMStyleWithColumns(15)));
+  EXPECT_EQ("a = {\n"
+            "    1111 /*      */\n"
+            "};",
+            format("a = {1111 /*      */\n"
+                   "};",
+                   getLLVMStyleWithColumns(15)));
+  EXPECT_EQ("a = {\n"
+            "    1111 /*      a\n"
+            "          */\n"
+            "};",
+            format("a = {1111 /*      a */\n"
+                   "};",
+                   getLLVMStyleWithColumns(15)));
+}
+
+TEST_F(FormatTestComments, IndentLineCommentsInStartOfBlockAtEndOfFile) {
+  verifyFormat("{\n"
+               "  // a\n"
+               "  // b");
+}
+
+TEST_F(FormatTestComments, AlignTrailingComments) {
+  EXPECT_EQ("#define MACRO(V)                       \\\n"
+            "  V(Rt2) /* one more char */           \\\n"
+            "  V(Rs)  /* than here  */              \\\n"
+            "/* comment 3 */\n",
+            format("#define MACRO(V)\\\n"
+                   "V(Rt2)  /* one more char */ \\\n"
+                   "V(Rs) /* than here  */    \\\n"
+                   "/* comment 3 */         \\\n",
+                   getLLVMStyleWithColumns(40)));
+  EXPECT_EQ("int i = f(abc, // line 1\n"
+            "          d,   // line 2\n"
+            "               // line 3\n"
+            "          b);",
+            format("int i = f(abc, // line 1\n"
+                   "          d, // line 2\n"
+                   "             // line 3\n"
+                   "          b);",
+                   getLLVMStyleWithColumns(40)));
+
+  // Align newly broken trailing comments.
+  EXPECT_EQ("int ab; // line\n"
+            "int a;  // long\n"
+            "        // long\n",
+            format("int ab; // line\n"
+                   "int a; // long long\n",
+                   getLLVMStyleWithColumns(15)));
+  EXPECT_EQ("int ab; // line\n"
+            "int a;  // long\n"
+            "        // long\n"
+            "        // long",
+            format("int ab; // line\n"
+                   "int a; // long long\n"
+                   "       // long",
+                   getLLVMStyleWithColumns(15)));
+  EXPECT_EQ("int ab; // line\n"
+            "int a;  // long\n"
+            "        // long\n"
+            "pt c;   // long",
+            format("int ab; // line\n"
+                   "int a; // long long\n"
+                   "pt c; // long",
+                   getLLVMStyleWithColumns(15)));
+  EXPECT_EQ("int ab; // line\n"
+            "int a;  // long\n"
+            "        // long\n"
+            "\n"
+            "// long",
+            format("int ab; // line\n"
+                   "int a; // long long\n"
+                   "\n"
+                   "// long",
+                   getLLVMStyleWithColumns(15)));
+
+  // Align comment line sections aligned with the next token with the next
+  // token.
+  EXPECT_EQ("class A {\n"
+            "public: // public comment\n"
+            "  // comment about a\n"
+            "  int a;\n"
+            "};",
+            format("class A {\n"
+                   "public: // public comment\n"
+                   "  // comment about a\n"
+                   "  int a;\n"
+                   "};",
+                   getLLVMStyleWithColumns(40)));
+  EXPECT_EQ("class A {\n"
+            "public: // public comment 1\n"
+            "        // public comment 2\n"
+            "  // comment 1 about a\n"
+            "  // comment 2 about a\n"
+            "  int a;\n"
+            "};",
+            format("class A {\n"
+                   "public: // public comment 1\n"
+                   "   // public comment 2\n"
+                   "  // comment 1 about a\n"
+                   "  // comment 2 about a\n"
+                   "  int a;\n"
+                   "};",
+                   getLLVMStyleWithColumns(40)));
+  EXPECT_EQ("int f(int n) { // comment line 1 on f\n"
+            "               // comment line 2 on f\n"
+            "  // comment line 1 before return\n"
+            "  // comment line 2 before return\n"
+            "  return n; // comment line 1 on return\n"
+            "            // comment line 2 on return\n"
+            "  // comment line 1 after return\n"
+            "}",
+            format("int f(int n) { // comment line 1 on f\n"
+                   "   // comment line 2 on f\n"
+                   "  // comment line 1 before return\n"
+                   "  // comment line 2 before return\n"
+                   "  return n; // comment line 1 on return\n"
+                   "   // comment line 2 on return\n"
+                   "  // comment line 1 after return\n"
+                   "}",
+                   getLLVMStyleWithColumns(40)));
+  EXPECT_EQ("int f(int n) {\n"
+            "  switch (n) { // comment line 1 on switch\n"
+            "               // comment line 2 on switch\n"
+            "  // comment line 1 before case 1\n"
+            "  // comment line 2 before case 1\n"
+            "  case 1: // comment line 1 on case 1\n"
+            "          // comment line 2 on case 1\n"
+            "    // comment line 1 before return 1\n"
+            "    // comment line 2 before return 1\n"
+            "    return 1; // comment line 1 on return 1\n"
+            "              // comment line 2 on return 1\n"
+            "  // comment line 1 before default\n"
+            "  // comment line 2 before default\n"
+            "  default: // comment line 1 on default\n"
+            "           // comment line 2 on default\n"
+            "    // comment line 1 before return 2\n"
+            "    return 2 * f(n - 1); // comment line 1 on return 2\n"
+            "                         // comment line 2 on return 2\n"
+            "    // comment line 1 after return\n"
+            "    // comment line 2 after return\n"
+            "  }\n"
+            "}",
+            format("int f(int n) {\n"
+                   "  switch (n) { // comment line 1 on switch\n"
+                   "              // comment line 2 on switch\n"
+                   "    // comment line 1 before case 1\n"
+                   "    // comment line 2 before case 1\n"
+                   "    case 1: // comment line 1 on case 1\n"
+                   "              // comment line 2 on case 1\n"
+                   "    // comment line 1 before return 1\n"
+                   "    // comment line 2 before return 1\n"
+                   "    return 1;  // comment line 1 on return 1\n"
+                   "             // comment line 2 on return 1\n"
+                   "    // comment line 1 before default\n"
+                   "    // comment line 2 before default\n"
+                   "    default:   // comment line 1 on default\n"
+                   "                // comment line 2 on default\n"
+                   "    // comment line 1 before return 2\n"
+                   "    return 2 * f(n - 1); // comment line 1 on return 2\n"
+                   "                        // comment line 2 on return 2\n"
+                   "    // comment line 1 after return\n"
+                   "     // comment line 2 after return\n"
+                   "  }\n"
+                   "}",
+                   getLLVMStyleWithColumns(80)));
+
+  // If all the lines in a sequence of line comments are aligned with the next
+  // token, the first line belongs to the previous token and the other lines
+  // belong to the next token.
+  EXPECT_EQ("int a; // line about a\n"
+            "long b;",
+            format("int a; // line about a\n"
+                   "       long b;",
+                   getLLVMStyleWithColumns(80)));
+  EXPECT_EQ("int a; // line about a\n"
+            "// line about b\n"
+            "long b;",
+            format("int a; // line about a\n"
+                   "       // line about b\n"
+                   "       long b;",
+                   getLLVMStyleWithColumns(80)));
+  EXPECT_EQ("int a; // line about a\n"
+            "// line 1 about b\n"
+            "// line 2 about b\n"
+            "long b;",
+            format("int a; // line about a\n"
+                   "       // line 1 about b\n"
+                   "       // line 2 about b\n"
+                   "       long b;",
+                   getLLVMStyleWithColumns(80)));
+}
+
+TEST_F(FormatTestComments, AlignsBlockCommentDecorations) {
+  EXPECT_EQ("/*\n"
+            " */",
+            format("/*\n"
+                   "*/", getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " */",
+            format("/*\n"
+                   " */", getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " */",
+            format("/*\n"
+                   "  */", getLLVMStyle()));
+
+  // Align a single line.
+  EXPECT_EQ("/*\n"
+            " * line */",
+            format("/*\n"
+                   "* line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line */",
+            format("/*\n"
+                   " * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line */",
+            format("/*\n"
+                   "  * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line */",
+            format("/*\n"
+                   "   * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   "* line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   " * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   "  * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   "   * line */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/**\n"
+            " * line */",
+            format("/**\n"
+                   "    * line */",
+                   getLLVMStyle()));
+
+  // Align the end '*/' after a line.
+  EXPECT_EQ("/*\n"
+            " * line\n"
+            " */",
+            format("/*\n"
+                   "* line\n"
+                   "*/", getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line\n"
+            " */",
+            format("/*\n"
+                   "   * line\n"
+                   "  */", getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            " * line\n"
+            " */",
+            format("/*\n"
+                   "  * line\n"
+                   "  */", getLLVMStyle()));
+
+  // Align two lines.
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   " * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   "* line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   "  * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   "   * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2 */",
+            format("/* line 1\n"
+                   "    * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("int i; /* line 1\n"
+            "        * line 2 */",
+            format("int i; /* line 1\n"
+                   "* line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("int i; /* line 1\n"
+            "        * line 2 */",
+            format("int i; /* line 1\n"
+                   "        * line 2 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("int i; /* line 1\n"
+            "        * line 2 */",
+            format("int i; /* line 1\n"
+                   "             * line 2 */",
+                   getLLVMStyle()));
+
+  // Align several lines.
+  EXPECT_EQ("/* line 1\n"
+            " * line 2\n"
+            " * line 3 */",
+            format("/* line 1\n"
+                   " * line 2\n"
+                   "* line 3 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/* line 1\n"
+            " * line 2\n"
+            " * line 3 */",
+            format("/* line 1\n"
+                   "  * line 2\n"
+                   "* line 3 */",
+                   getLLVMStyle()));
+  EXPECT_EQ("/*\n"
+            "** line 1\n"
+            "** line 2\n"
+            "*/",
+            format("/*\n"
+                   "** line 1\n"
+                   " ** line 2\n"
+                   "*/",
+                   getLLVMStyle()));
+
+  // Align with different indent after the decorations.
+  EXPECT_EQ("/*\n"
+            " * line 1\n"
+            " *  line 2\n"
+            " * line 3\n"
+            " *   line 4\n"
+            " */",
+            format("/*\n"
+                   "* line 1\n"
+                   "  *  line 2\n"
+                   "   * line 3\n"
+                   "*   line 4\n"
+                   "*/", getLLVMStyle()));
+
+  // Align empty or blank lines.
+  EXPECT_EQ("/**\n"
+            " *\n"
+            " *\n"
+            " *\n"
+            " */",
+            format("/**\n"
+                   "*  \n"
+                   " * \n"
+                   "  *\n"
+                   "*/", getLLVMStyle()));
+
+  // Align while breaking and reflowing.
+  EXPECT_EQ("/*\n"
+            " * long long long\n"
+            " * long long\n"
+            " *\n"
+            " * long */",
+            format("/*\n"
+                   " * long long long long\n"
+                   " * long\n"
+                   "  *\n"
+                   "* long */",
+                   getLLVMStyleWithColumns(20)));
+}
+} // end namespace
+} // end namespace format
+} // end namespace clang
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
index 6f494db..62d7ec8 100644
--- a/unittests/Format/FormatTestJS.cpp
+++ b/unittests/Format/FormatTestJS.cpp
@@ -240,6 +240,18 @@
                "};");
   verifyFormat("var x = {y: (a) => a};");
 
+  // Methods in object literals.
+  verifyFormat("var x = {\n"
+               "  y(a: string): number {\n"
+               "    return a;\n"
+               "  }\n"
+               "};");
+  verifyFormat("var x = {\n"
+               "  y(a: string) {\n"
+               "    return a;\n"
+               "  }\n"
+               "};");
+
   // Computed keys.
   verifyFormat("var x = {[a]: 1, b: 2, [c]: 3};");
   verifyFormat("var x = {\n"
@@ -266,6 +278,11 @@
                "  aaa,\n"
                "  aaa,\n"
                "};");
+  verifyFormat("return {\n"
+               "  a,\n"
+               "  b: 'b',\n"
+               "  c,\n"
+               "};");
 }
 
 TEST_F(FormatTestJS, MethodsInObjectLiterals) {
@@ -377,6 +394,16 @@
       "declare function\n"
       "x();",  // TODO(martinprobst): should ideally be indented.
       NineCols);
+  verifyFormat("declare function foo();\n"
+               "let x = 1;\n");
+  verifyFormat("declare function foo(): string;\n"
+               "let x = 1;\n");
+  verifyFormat("declare function foo(): {x: number};\n"
+               "let x = 1;\n");
+  verifyFormat("declare class X {}\n"
+               "let x = 1;\n");
+  verifyFormat("declare interface Y {}\n"
+               "let x = 1;\n");
   verifyFormat(
       "declare enum X {\n"
       "}",
@@ -441,6 +468,8 @@
   verifyFormat("export async function f() {\n"
                "  return fetch(x);\n"
                "}");
+  verifyFormat("let x = async () => f();");
+  verifyFormat("let x = async();");
   verifyFormat("class X {\n"
                "  async asyncMethod() {\n"
                "    return fetch(1);\n"
@@ -487,6 +516,11 @@
                "    [];");
 
   verifyFormat("someFunction([], {a: a});");
+
+  verifyFormat("var string = [\n"
+               "  'aaaaaa',\n"
+               "  'bbbbbb',\n"
+               "].join('+');");
 }
 
 TEST_F(FormatTestJS, ColumnLayoutForArrayLiterals) {
@@ -531,8 +565,8 @@
                "      foo();\n"
                "      bar();\n"
                "    },\n"
-               "    this, arg1IsReallyLongAndNeeedsLineBreaks,\n"
-               "    arg3IsReallyLongAndNeeedsLineBreaks);");
+               "    this, arg1IsReallyLongAndNeedsLineBreaks,\n"
+               "    arg3IsReallyLongAndNeedsLineBreaks);");
   verifyFormat("var closure = goog.bind(function() {  // comment\n"
                "  foo();\n"
                "  bar();\n"
@@ -577,6 +611,11 @@
                "  doSomething();\n"
                "}, this));");
 
+  verifyFormat("SomeFunction(function() {\n"
+               "  foo();\n"
+               "  bar();\n"
+               "}.bind(this));");
+
   // FIXME: This is bad, we should be wrapping before "function() {".
   verifyFormat("someFunction(function() {\n"
                "  doSomething();  // break\n"
@@ -848,6 +887,44 @@
                "return 1",
                "a = null\n"
                "  return   1");
+  // Below "class Y {}" should ideally be on its own line.
+  verifyFormat(
+      "x = {\n"
+      "  a: 1\n"
+      "} class Y {}",
+      "  x  =  {a  : 1}\n"
+      "   class  Y {  }");
+  verifyFormat(
+      "if (x) {\n"
+      "}\n"
+      "return 1",
+      "if (x) {}\n"
+      " return   1");
+  verifyFormat(
+      "if (x) {\n"
+      "}\n"
+      "class X {}",
+      "if (x) {}\n"
+      " class X {}");
+}
+
+TEST_F(FormatTestJS, ImportExportASI) {
+  verifyFormat(
+      "import {x} from 'y'\n"
+      "export function z() {}",
+      "import   {x} from 'y'\n"
+      "  export function z() {}");
+  // Below "class Y {}" should ideally be on its own line.
+  verifyFormat(
+      "export {x} class Y {}",
+      "  export {x}\n"
+      "  class  Y {\n}");
+  verifyFormat(
+      "if (x) {\n"
+      "}\n"
+      "export class Y {}",
+      "if ( x ) { }\n"
+      " export class Y {}");
 }
 
 TEST_F(FormatTestJS, ClosureStyleCasts) {
@@ -883,6 +960,7 @@
   verifyFormat("var x = a ? /abc/ : /abc/;");
   verifyFormat("for (var i = 0; /abc/.test(s[i]); i++) {\n}");
   verifyFormat("var x = !/abc/.test(y);");
+  verifyFormat("var x = foo()! / 10;");
   verifyFormat("var x = a && /abc/.test(y);");
   verifyFormat("var x = a || /abc/.test(y);");
   verifyFormat("var x = a + /abc/.search(y);");
@@ -988,6 +1066,15 @@
   verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);");
 }
 
+TEST_F(FormatTestJS, IgnoresMpegTS) {
+  std::string MpegTS(200, ' ');
+  MpegTS.replace(0, strlen("nearlyLooks  +   like +   ts + code;  "),
+                 "nearlyLooks  +   like +   ts + code;  ");
+  MpegTS[0] = 0x47;
+  MpegTS[188] = 0x47;
+  verifyFormat(MpegTS, MpegTS);
+}
+
 TEST_F(FormatTestJS, TypeAnnotations) {
   verifyFormat("var x: string;");
   verifyFormat("var x: {a: string; b: number;} = {};");
@@ -1015,6 +1102,9 @@
   verifyFormat("function someFunc(args: string[]):\n"
                "    {longReturnValue: string[]} {}",
                getGoogleJSStyleWithColumns(60));
+  verifyFormat(
+      "var someValue = (v as aaaaaaaaaaaaaaaaaaaa<T>[])\n"
+      "                    .someFunction(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
 }
 
 TEST_F(FormatTestJS, UnionIntersectionTypes) {
@@ -1042,6 +1132,10 @@
   verifyFormat("class C {\n  static x(): string {\n    return 'asd';\n  }\n}");
   verifyFormat("class C extends P implements I {}");
   verifyFormat("class C extends p.P implements i.I {}");
+  verifyFormat(
+      "x(class {\n"
+      "  a(): A {}\n"
+      "});");
   verifyFormat("class Test {\n"
                "  aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaa):\n"
                "      aaaaaaaaaaaaaaaaaaaaaa {}\n"
@@ -1134,6 +1228,20 @@
                "class C {}");
 }
 
+TEST_F(FormatTestJS, TypeInterfaceLineWrapping) {
+  const FormatStyle &Style = getGoogleJSStyleWithColumns(20);
+  verifyFormat("type LongTypeIsReallyUnreasonablyLong =\n"
+               "    string;\n",
+               "type LongTypeIsReallyUnreasonablyLong = string;\n",
+               Style);
+  verifyFormat(
+      "interface AbstractStrategyFactoryProvider {\n"
+      "  a: number\n"
+      "}\n",
+      "interface AbstractStrategyFactoryProvider { a: number }\n",
+      Style);
+}
+
 TEST_F(FormatTestJS, Modules) {
   verifyFormat("import SomeThing from 'some/module.js';");
   verifyFormat("import {X, Y} from 'some/module.js';");
@@ -1321,6 +1429,62 @@
                "var y;");
   // Escaped dollar.
   verifyFormat("var x = ` \\${foo}`;\n");
+
+  // The token stream can contain two string_literals in sequence, but that
+  // doesn't mean that they are implicitly concatenated in JavaScript.
+  verifyFormat("var f = `aaaa ${a ? 'a' : 'b'}`;");
+
+  // Ensure that scopes are appropriately set around evaluated expressions in
+  // template strings.
+  verifyFormat("var f = `aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa\n"
+               "         aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa`;",
+               "var f = `aaaaaaaaaaaaa:${aaaaaaa.  aaaaa} aaaaaaaa\n"
+               "         aaaaaaaaaaaaa:${  aaaaaaa. aaaaa} aaaaaaaa`;");
+  verifyFormat("var x = someFunction(`${})`)  //\n"
+               "            .oooooooooooooooooon();");
+  verifyFormat("var x = someFunction(`${aaaa}${\n"
+               "                               aaaaa(  //\n"
+               "                                   aaaaa)\n"
+               "                             })`);");
+}
+
+TEST_F(FormatTestJS, TemplateStringMultiLineExpression) {
+  verifyFormat("var f = `aaaaaaaaaaaaaaaaaa: ${\n"
+               "                               aaaaa +  //\n"
+               "                               bbbb\n"
+               "                             }`;",
+               "var f = `aaaaaaaaaaaaaaaaaa: ${aaaaa +  //\n"
+               "                               bbbb}`;");
+  verifyFormat("var f = `\n"
+               "  aaaaaaaaaaaaaaaaaa: ${\n"
+               "                        aaaaa +  //\n"
+               "                        bbbb\n"
+               "                      }`;",
+               "var f  =  `\n"
+               "  aaaaaaaaaaaaaaaaaa: ${   aaaaa  +  //\n"
+               "                        bbbb }`;");
+  verifyFormat("var f = `\n"
+               "  aaaaaaaaaaaaaaaaaa: ${\n"
+               "                        someFunction(\n"
+               "                            aaaaa +  //\n"
+               "                            bbbb)\n"
+               "                      }`;",
+               "var f  =  `\n"
+               "  aaaaaaaaaaaaaaaaaa: ${someFunction (\n"
+               "                            aaaaa  +   //\n"
+               "                            bbbb)}`;");
+
+  // It might be preferable to wrap before "someFunction".
+  verifyFormat("var f = `\n"
+               "  aaaaaaaaaaaaaaaaaa: ${someFunction({\n"
+               "                          aaaa: aaaaa,\n"
+               "                          bbbb: bbbbb,\n"
+               "                        })}`;",
+               "var f  =  `\n"
+               "  aaaaaaaaaaaaaaaaaa: ${someFunction ({\n"
+               "                          aaaa:  aaaaa,\n"
+               "                          bbbb:  bbbbb,\n"
+               "                        })}`;");
 }
 
 TEST_F(FormatTestJS, TemplateStringASI) {
@@ -1357,6 +1521,9 @@
   verifyFormat("x = x as {a: string};");
   verifyFormat("x = x as (string);");
   verifyFormat("x = x! as (string);");
+  verifyFormat("var x = something.someFunction() as\n"
+               "    something;",
+               getGoogleJSStyleWithColumns(40));
 }
 
 TEST_F(FormatTestJS, TypeArguments) {
@@ -1430,6 +1597,58 @@
                " * @export {this.is.a.long.path.to.a.Type}\n"
                " */",
                getGoogleJSStyleWithColumns(20));
+  verifyFormat("/**\n"
+               " * @mods {this.is.a.long.path.to.a.Type}\n"
+               " */",
+               "/**\n"
+               " * @mods {this.is.a.long.path.to.a.Type}\n"
+               " */",
+               getGoogleJSStyleWithColumns(20));
+  verifyFormat("/**\n"
+               " * @param {this.is.a.long.path.to.a.Type}\n"
+               " */",
+               "/**\n"
+               " * @param {this.is.a.long.path.to.a.Type}\n"
+               " */",
+               getGoogleJSStyleWithColumns(20));
+  verifyFormat("/**\n"
+               " * @see http://very/very/long/url/is/long\n"
+               " */",
+               "/**\n"
+               " * @see http://very/very/long/url/is/long\n"
+               " */",
+               getGoogleJSStyleWithColumns(20));
+  verifyFormat(
+      "/**\n"
+      " * @param This is a\n"
+      " * long comment but\n"
+      " * no type\n"
+      " */",
+      "/**\n"
+      " * @param This is a long comment but no type\n"
+      " */",
+      getGoogleJSStyleWithColumns(20));
+  // Don't break @param line, but reindent it and reflow unrelated lines.
+  verifyFormat("{\n"
+               "  /**\n"
+               "   * long long long\n"
+               "   * long\n"
+               "   * @param {this.is.a.long.path.to.a.Type} a\n"
+               "   * long long long\n"
+               "   * long long\n"
+               "   */\n"
+               "  function f(a) {}\n"
+               "}",
+               "{\n"
+               "/**\n"
+               " * long long long long\n"
+               " * @param {this.is.a.long.path.to.a.Type} a\n"
+               " * long long long long\n"
+               " * long\n"
+               " */\n"
+               "  function f(a) {}\n"
+               "}",
+               getGoogleJSStyleWithColumns(20));
 }
 
 TEST_F(FormatTestJS, RequoteStringsSingle) {
@@ -1502,6 +1721,12 @@
   verifyFormat("let x = (foo)!;\n");
   verifyFormat("let x = foo! - 1;\n");
   verifyFormat("let x = {foo: 1}!;\n");
+  verifyFormat(
+      "let x = hello.foo()!\n"
+      "            .foo()!\n"
+      "            .foo()!\n"
+      "            .foo()!;\n",
+      getGoogleJSStyleWithColumns(20));
 }
 
 TEST_F(FormatTestJS, Conditional) {
@@ -1518,6 +1743,5 @@
                getGoogleJSStyleWithColumns(25));
   verifyFormat("// taze: x from 'location'", getGoogleJSStyleWithColumns(10));
 }
-
 } // end namespace tooling
 } // end namespace clang
diff --git a/unittests/Format/FormatTestJava.cpp b/unittests/Format/FormatTestJava.cpp
index dfc3deb..ee09ca9 100644
--- a/unittests/Format/FormatTestJava.cpp
+++ b/unittests/Format/FormatTestJava.cpp
@@ -225,6 +225,13 @@
                "    }\n"
                "  };\n"
                "}");
+  verifyFormat("public enum VeryLongEnum {\n"
+               "  ENUM_WITH_MANY_PARAMETERS(\n"
+               "      \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaa\", \"bbbbbbbbbbbbbbbb\", "
+               "\"cccccccccccccccccccccccc\"),\n"
+               "  SECOND_ENUM(\"a\", \"b\", \"c\");\n"
+               "  private VeryLongEnum(String a, String b, String c) {}\n"
+               "}\n");
 }
 
 TEST_F(FormatTestJava, ArrayInitializers) {
diff --git a/unittests/Format/FormatTestObjC.cpp b/unittests/Format/FormatTestObjC.cpp
new file mode 100644
index 0000000..680ff92
--- /dev/null
+++ b/unittests/Format/FormatTestObjC.cpp
@@ -0,0 +1,826 @@
+//===- unittest/Format/FormatTestObjC.cpp - Formatting unit tests----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Format/Format.h"
+
+#include "../Tooling/ReplacementTest.h"
+#include "FormatTestUtils.h"
+
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+using clang::tooling::ReplacementTest;
+using clang::tooling::toReplacements;
+
+namespace clang {
+namespace format {
+namespace {
+
+class FormatTestObjC : public ::testing::Test {
+protected:
+  FormatTestObjC() {
+    Style = getLLVMStyle();
+    Style.Language = FormatStyle::LK_ObjC;
+  }
+
+  enum IncompleteCheck {
+    IC_ExpectComplete,
+    IC_ExpectIncomplete,
+    IC_DoNotCheck
+  };
+
+  std::string format(llvm::StringRef Code,
+                     IncompleteCheck CheckIncomplete = IC_ExpectComplete) {
+    DEBUG(llvm::errs() << "---\n");
+    DEBUG(llvm::errs() << Code << "\n\n");
+    std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
+    bool IncompleteFormat = false;
+    tooling::Replacements Replaces =
+        reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
+    if (CheckIncomplete != IC_DoNotCheck) {
+      bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete;
+      EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n";
+    }
+    auto Result = applyAllReplacements(Code, Replaces);
+    EXPECT_TRUE(static_cast<bool>(Result));
+    DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+    return *Result;
+  }
+
+  void verifyFormat(StringRef Code) {
+    EXPECT_EQ(Code.str(), format(test::messUp(Code)));
+  }
+
+  void verifyIncompleteFormat(StringRef Code) {
+    EXPECT_EQ(Code.str(), format(test::messUp(Code), IC_ExpectIncomplete));
+  }
+
+  FormatStyle Style;
+};
+
+TEST(FormatTestObjCStyle, DetectsObjCInHeaders) {
+  auto Style = getStyle("LLVM", "a.h", "none", "@interface\n"
+                                               "- (id)init;");
+  ASSERT_TRUE((bool)Style);
+  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
+  Style = getStyle("LLVM", "a.h", "none", "@interface\n"
+                                          "+ (id)init;");
+  ASSERT_TRUE((bool)Style);
+  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
+  // No recognizable ObjC.
+  Style = getStyle("LLVM", "a.h", "none", "void f() {}");
+  ASSERT_TRUE((bool)Style);
+  EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
+}
+
+TEST_F(FormatTestObjC, FormatObjCTryCatch) {
+  verifyFormat("@try {\n"
+               "  f();\n"
+               "} @catch (NSException e) {\n"
+               "  @throw;\n"
+               "} @finally {\n"
+               "  exit(42);\n"
+               "}");
+  verifyFormat("DEBUG({\n"
+               "  @try {\n"
+               "  } @finally {\n"
+               "  }\n"
+               "});\n");
+}
+
+TEST_F(FormatTestObjC, FormatObjCAutoreleasepool) {
+  verifyFormat("@autoreleasepool {\n"
+               "  f();\n"
+               "}\n"
+               "@autoreleasepool {\n"
+               "  f();\n"
+               "}\n");
+  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+  verifyFormat("@autoreleasepool\n"
+               "{\n"
+               "  f();\n"
+               "}\n"
+               "@autoreleasepool\n"
+               "{\n"
+               "  f();\n"
+               "}\n");
+}
+
+TEST_F(FormatTestObjC, FormatObjCInterface) {
+  verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
+               "@public\n"
+               "  int field1;\n"
+               "@protected\n"
+               "  int field2;\n"
+               "@private\n"
+               "  int field3;\n"
+               "@package\n"
+               "  int field4;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface /* wait for it */ Foo\n"
+               "+ (id)init;\n"
+               "// Look, a comment!\n"
+               "- (int)answerWith:(int)i;\n"
+               "@end");
+
+  verifyFormat("@interface Foo\n"
+               "@end\n"
+               "@interface Bar\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : /**/ Bar /**/ <Baz, /**/ Quux>\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff)\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo ()\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar <Baz, Quux> {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff) {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo () {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff) <MyProtocol> {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
+  verifyFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
+               " @public\n"
+               "  int field1;\n"
+               " @protected\n"
+               "  int field2;\n"
+               " @private\n"
+               "  int field3;\n"
+               " @package\n"
+               "  int field4;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+  verifyFormat("@interface Foo : Bar<Baz, Quux>\n"
+               "+ (id)init;\n"
+               "@end");
+  verifyFormat("@interface Foo (HackStuff)<MyProtocol>\n"
+               "+ (id)init;\n"
+               "@end");
+  Style.BinPackParameters = false;
+  Style.ColumnLimit = 80;
+  verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
+               "}");
+}
+
+TEST_F(FormatTestObjC, FormatObjCImplementation) {
+  verifyFormat("@implementation Foo : NSObject {\n"
+               "@public\n"
+               "  int field1;\n"
+               "@protected\n"
+               "  int field2;\n"
+               "@private\n"
+               "  int field3;\n"
+               "@package\n"
+               "  int field4;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo\n"
+               "+ (id)init {\n"
+               "  if (true)\n"
+               "    return nil;\n"
+               "}\n"
+               "// Look, a comment!\n"
+               "- (int)answerWith:(int)i {\n"
+               "  return i;\n"
+               "}\n"
+               "+ (int)answerWith:(int)i {\n"
+               "  return i;\n"
+               "}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo\n"
+               "@end\n"
+               "@implementation Bar\n"
+               "@end");
+
+  EXPECT_EQ("@implementation Foo : Bar\n"
+            "+ (id)init {\n}\n"
+            "- (void)foo {\n}\n"
+            "@end",
+            format("@implementation Foo : Bar\n"
+                   "+(id)init{}\n"
+                   "-(void)foo{}\n"
+                   "@end"));
+
+  verifyFormat("@implementation Foo {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo : Bar {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo (HackStuff)\n"
+               "+ (id)init {\n}\n"
+               "@end");
+  verifyFormat("@implementation ObjcClass\n"
+               "- (void)method;\n"
+               "{}\n"
+               "@end");
+
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
+  verifyFormat("@implementation Foo : NSObject {\n"
+               " @public\n"
+               "  int field1;\n"
+               " @protected\n"
+               "  int field2;\n"
+               " @private\n"
+               "  int field3;\n"
+               " @package\n"
+               "  int field4;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+}
+
+TEST_F(FormatTestObjC, FormatObjCProtocol) {
+  verifyFormat("@protocol Foo\n"
+               "@property(weak) id delegate;\n"
+               "- (NSUInteger)numberOfThings;\n"
+               "@end");
+
+  verifyFormat("@protocol MyProtocol <NSObject>\n"
+               "- (NSUInteger)numberOfThings;\n"
+               "@end");
+
+  verifyFormat("@protocol Foo;\n"
+               "@protocol Bar;\n");
+
+  verifyFormat("@protocol Foo\n"
+               "@end\n"
+               "@protocol Bar\n"
+               "@end");
+
+  verifyFormat("@protocol myProtocol\n"
+               "- (void)mandatoryWithInt:(int)i;\n"
+               "@optional\n"
+               "- (void)optional;\n"
+               "@required\n"
+               "- (void)required;\n"
+               "@optional\n"
+               "@property(assign) int madProp;\n"
+               "@end\n");
+
+  verifyFormat("@property(nonatomic, assign, readonly)\n"
+               "    int *looooooooooooooooooooooooooooongNumber;\n"
+               "@property(nonatomic, assign, readonly)\n"
+               "    NSString *looooooooooooooooooooooooooooongName;");
+
+  verifyFormat("@implementation PR18406\n"
+               "}\n"
+               "@end");
+
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
+  verifyFormat("@protocol MyProtocol<NSObject>\n"
+               "- (NSUInteger)numberOfThings;\n"
+               "@end");
+}
+
+TEST_F(FormatTestObjC, FormatObjCMethodDeclarations) {
+  verifyFormat("- (void)doSomethingWith:(GTMFoo *)theFoo\n"
+               "                   rect:(NSRect)theRect\n"
+               "               interval:(float)theInterval {\n"
+               "}");
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "      longKeyword:(NSRect)theRect\n"
+               "    longerKeyword:(float)theInterval\n"
+               "            error:(NSError **)theError {\n"
+               "}");
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "          longKeyword:(NSRect)theRect\n"
+               "    evenLongerKeyword:(float)theInterval\n"
+               "                error:(NSError **)theError {\n"
+               "}");
+  Style.ColumnLimit = 60;
+  verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n"
+               "                         y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n"
+               "    NS_DESIGNATED_INITIALIZER;");
+  verifyFormat("- (void)drawRectOn:(id)surface\n"
+               "            ofSize:(size_t)height\n"
+               "                  :(size_t)width;");
+
+  // Continuation indent width should win over aligning colons if the function
+  // name is long.
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
+  Style.ColumnLimit = 40;
+  Style.IndentWrappedFunctionNames = true;
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "    dontAlignNamef:(NSRect)theRect {\n"
+               "}");
+
+  // Make sure we don't break aligning for short parameter names.
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "       aShortf:(NSRect)theRect {\n"
+               "}");
+
+  // Format pairs correctly.
+  Style.ColumnLimit = 80;
+  verifyFormat("- (void)drawRectOn:(id)surface\n"
+               "            ofSize:(aaaaaaaa)height\n"
+               "                  :(size_t)width\n"
+               "          atOrigin:(size_t)x\n"
+               "                  :(size_t)y\n"
+               "             aaaaa:(a)yyy\n"
+               "               bbb:(d)cccc;");
+  verifyFormat("- (void)drawRectOn:(id)surface ofSize:(aaa)height:(bbb)width;");
+}
+
+TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
+  verifyFormat("[foo bar:baz];");
+  verifyFormat("return [foo bar:baz];");
+  verifyFormat("return (a)[foo bar:baz];");
+  verifyFormat("f([foo bar:baz]);");
+  verifyFormat("f(2, [foo bar:baz]);");
+  verifyFormat("f(2, a ? b : c);");
+  verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];");
+
+  // Unary operators.
+  verifyFormat("int a = +[foo bar:baz];");
+  verifyFormat("int a = -[foo bar:baz];");
+  verifyFormat("int a = ![foo bar:baz];");
+  verifyFormat("int a = ~[foo bar:baz];");
+  verifyFormat("int a = ++[foo bar:baz];");
+  verifyFormat("int a = --[foo bar:baz];");
+  verifyFormat("int a = sizeof [foo bar:baz];");
+  verifyFormat("int a = alignof [foo bar:baz];");
+  verifyFormat("int a = &[foo bar:baz];");
+  verifyFormat("int a = *[foo bar:baz];");
+  // FIXME: Make casts work, without breaking f()[4].
+  // verifyFormat("int a = (int)[foo bar:baz];");
+  // verifyFormat("return (int)[foo bar:baz];");
+  // verifyFormat("(void)[foo bar:baz];");
+  verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];");
+
+  // Binary operators.
+  verifyFormat("[foo bar:baz], [foo bar:baz];");
+  verifyFormat("[foo bar:baz] = [foo bar:baz];");
+  verifyFormat("[foo bar:baz] *= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] /= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] %= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] += [foo bar:baz];");
+  verifyFormat("[foo bar:baz] -= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] <<= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] >>= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] &= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] ^= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] |= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];");
+  verifyFormat("[foo bar:baz] || [foo bar:baz];");
+  verifyFormat("[foo bar:baz] && [foo bar:baz];");
+  verifyFormat("[foo bar:baz] | [foo bar:baz];");
+  verifyFormat("[foo bar:baz] ^ [foo bar:baz];");
+  verifyFormat("[foo bar:baz] & [foo bar:baz];");
+  verifyFormat("[foo bar:baz] == [foo bar:baz];");
+  verifyFormat("[foo bar:baz] != [foo bar:baz];");
+  verifyFormat("[foo bar:baz] >= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] <= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] > [foo bar:baz];");
+  verifyFormat("[foo bar:baz] < [foo bar:baz];");
+  verifyFormat("[foo bar:baz] >> [foo bar:baz];");
+  verifyFormat("[foo bar:baz] << [foo bar:baz];");
+  verifyFormat("[foo bar:baz] - [foo bar:baz];");
+  verifyFormat("[foo bar:baz] + [foo bar:baz];");
+  verifyFormat("[foo bar:baz] * [foo bar:baz];");
+  verifyFormat("[foo bar:baz] / [foo bar:baz];");
+  verifyFormat("[foo bar:baz] % [foo bar:baz];");
+  // Whew!
+
+  verifyFormat("return in[42];");
+  verifyFormat("for (auto v : in[1]) {\n}");
+  verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}");
+  verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}");
+  verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}");
+  verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}");
+  verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}");
+  verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"
+               "}");
+  verifyFormat("[self aaaaa:MACRO(a, b:, c:)];");
+  verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];");
+  verifyFormat("[self aaaaa:(Type)a bbbbb:3];");
+
+  verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");
+  verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");
+  verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");
+  verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];");
+  verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]");
+  verifyFormat("[button setAction:@selector(zoomOut:)];");
+  verifyFormat("[color getRed:&r green:&g blue:&b alpha:&a];");
+
+  verifyFormat("arr[[self indexForFoo:a]];");
+  verifyFormat("throw [self errorFor:a];");
+  verifyFormat("@throw [self errorFor:a];");
+
+  verifyFormat("[(id)foo bar:(id)baz quux:(id)snorf];");
+  verifyFormat("[(id)foo bar:(id) ? baz : quux];");
+  verifyFormat("4 > 4 ? (id)a : (id)baz;");
+
+  // This tests that the formatter doesn't break after "backing" but before ":",
+  // which would be at 80 columns.
+  verifyFormat(
+      "void f() {\n"
+      "  if ((self = [super initWithContentRect:contentRect\n"
+      "                               styleMask:styleMask ?: otherMask\n"
+      "                                 backing:NSBackingStoreBuffered\n"
+      "                                   defer:YES]))");
+
+  verifyFormat(
+      "[foo checkThatBreakingAfterColonWorksOk:\n"
+      "         [bar ifItDoes:reduceOverallLineLengthLikeInThisCase]];");
+
+  verifyFormat("[myObj short:arg1 // Force line break\n"
+               "          longKeyword:arg2 != nil ? arg2 : @\"longKeyword\"\n"
+               "    evenLongerKeyword:arg3 ?: @\"evenLongerKeyword\"\n"
+               "                error:arg4];");
+  verifyFormat(
+      "void f() {\n"
+      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
+      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
+      "                                     pos.width(), pos.height())\n"
+      "                styleMask:NSBorderlessWindowMask\n"
+      "                  backing:NSBackingStoreBuffered\n"
+      "                    defer:NO]);\n"
+      "}");
+  verifyFormat("[contentsContainer replaceSubview:[subviews objectAtIndex:0]\n"
+               "                             with:contentsNativeView];");
+
+  verifyFormat(
+      "[pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]\n"
+      "           owner:nillllll];");
+
+  verifyFormat(
+      "[pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]\n"
+      "        forType:kBookmarkButtonDragType];");
+
+  verifyFormat("[defaultCenter addObserver:self\n"
+               "                  selector:@selector(willEnterFullscreen)\n"
+               "                      name:kWillEnterFullscreenNotification\n"
+               "                    object:nil];");
+  verifyFormat("[image_rep drawInRect:drawRect\n"
+               "             fromRect:NSZeroRect\n"
+               "            operation:NSCompositeCopy\n"
+               "             fraction:1.0\n"
+               "       respectFlipped:NO\n"
+               "                hints:nil];");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n"
+               "    aaaaaaaaaaaaaaaaaaaaaa];");
+
+  verifyFormat(
+      "scoped_nsobject<NSTextField> message(\n"
+      "    // The frame will be fixed up when |-setMessageText:| is called.\n"
+      "    [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);");
+  verifyFormat("[self aaaaaa:bbbbbbbbbbbbb\n"
+               "    aaaaaaaaaa:bbbbbbbbbbbbbbbbb\n"
+               "         aaaaa:bbbbbbbbbbb + bbbbbbbbbbbb\n"
+               "          aaaa:bbb];");
+  verifyFormat("[self param:function( //\n"
+               "                parameter)]");
+  verifyFormat(
+      "[self aaaaaaaaaa:aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
+      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
+      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];");
+
+  // Variadic parameters.
+  verifyFormat(
+      "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];");
+  verifyFormat(
+      "[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
+      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
+      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];");
+  verifyFormat("[self // break\n"
+               "      a:a\n"
+               "    aaa:aaa];");
+  verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
+               "          [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
+
+  // Formats pair-parameters.
+  verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
+  verifyFormat("[I drawRectOn:surface //\n"
+               "        ofSize:aa:bbb\n"
+               "      atOrigin:cc:dd];");
+
+  Style.ColumnLimit = 70;
+  verifyFormat(
+      "void f() {\n"
+      "  popup_wdow_.reset([[RenderWidgetPopupWindow alloc]\n"
+      "      iniithContentRect:NSMakRet(origin_global.x, origin_global.y,\n"
+      "                                 pos.width(), pos.height())\n"
+      "                syeMask:NSBorderlessWindowMask\n"
+      "                  bking:NSBackingStoreBuffered\n"
+      "                    der:NO]);\n"
+      "}");
+
+  Style.ColumnLimit = 60;
+  verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n"
+               "        .aaaaaaaa];"); // FIXME: Indentation seems off.
+  // FIXME: This violates the column limit.
+  verifyFormat(
+      "[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "    aaaaaaaaaaaaaaaaa:aaaaaaaa\n"
+      "                  aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+
+  Style = getChromiumStyle(FormatStyle::LK_ObjC);
+  Style.ColumnLimit = 80;
+  verifyFormat(
+      "void f() {\n"
+      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
+      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
+      "                                     pos.width(), pos.height())\n"
+      "                styleMask:NSBorderlessWindowMask\n"
+      "                  backing:NSBackingStoreBuffered\n"
+      "                    defer:NO]);\n"
+      "}");
+}
+
+TEST_F(FormatTestObjC, ObjCAt) {
+  verifyFormat("@autoreleasepool");
+  verifyFormat("@catch");
+  verifyFormat("@class");
+  verifyFormat("@compatibility_alias");
+  verifyFormat("@defs");
+  verifyFormat("@dynamic");
+  verifyFormat("@encode");
+  verifyFormat("@end");
+  verifyFormat("@finally");
+  verifyFormat("@implementation");
+  verifyFormat("@import");
+  verifyFormat("@interface");
+  verifyFormat("@optional");
+  verifyFormat("@package");
+  verifyFormat("@private");
+  verifyFormat("@property");
+  verifyFormat("@protected");
+  verifyFormat("@protocol");
+  verifyFormat("@public");
+  verifyFormat("@required");
+  verifyFormat("@selector");
+  verifyFormat("@synchronized");
+  verifyFormat("@synthesize");
+  verifyFormat("@throw");
+  verifyFormat("@try");
+
+  EXPECT_EQ("@interface", format("@ interface"));
+
+  // The precise formatting of this doesn't matter, nobody writes code like
+  // this.
+  verifyFormat("@ /*foo*/ interface");
+}
+
+TEST_F(FormatTestObjC, ObjCSnippets) {
+  verifyFormat("@autoreleasepool {\n"
+               "  foo();\n"
+               "}");
+  verifyFormat("@class Foo, Bar;");
+  verifyFormat("@compatibility_alias AliasName ExistingClass;");
+  verifyFormat("@dynamic textColor;");
+  verifyFormat("char *buf1 = @encode(int *);");
+  verifyFormat("char *buf1 = @encode(typeof(4 * 5));");
+  verifyFormat("char *buf1 = @encode(int **);");
+  verifyFormat("Protocol *proto = @protocol(p1);");
+  verifyFormat("SEL s = @selector(foo:);");
+  verifyFormat("@synchronized(self) {\n"
+               "  f();\n"
+               "}");
+
+  verifyFormat("@import foo.bar;\n"
+               "@import baz;");
+
+  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
+
+  verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");
+  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
+
+  Style = getMozillaStyle();
+  verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
+  verifyFormat("@property BOOL editable;");
+
+  Style = getWebKitStyle();
+  verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
+  verifyFormat("@property BOOL editable;");
+
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
+  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
+  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
+}
+
+TEST_F(FormatTestObjC, ObjCForIn) {
+  verifyFormat("- (void)test {\n"
+               "  for (NSString *n in arrayOfStrings) {\n"
+               "    foo(n);\n"
+               "  }\n"
+               "}");
+  verifyFormat("- (void)test {\n"
+               "  for (NSString *n in (__bridge NSArray *)arrayOfStrings) {\n"
+               "    foo(n);\n"
+               "  }\n"
+               "}");
+}
+
+TEST_F(FormatTestObjC, ObjCLiterals) {
+  verifyFormat("@\"String\"");
+  verifyFormat("@1");
+  verifyFormat("@+4.8");
+  verifyFormat("@-4");
+  verifyFormat("@1LL");
+  verifyFormat("@.5");
+  verifyFormat("@'c'");
+  verifyFormat("@true");
+
+  verifyFormat("NSNumber *smallestInt = @(-INT_MAX - 1);");
+  verifyFormat("NSNumber *piOverTwo = @(M_PI / 2);");
+  verifyFormat("NSNumber *favoriteColor = @(Green);");
+  verifyFormat("NSString *path = @(getenv(\"PATH\"));");
+
+  verifyFormat("[dictionary setObject:@(1) forKey:@\"number\"];");
+}
+
+TEST_F(FormatTestObjC, ObjCDictLiterals) {
+  verifyFormat("@{");
+  verifyFormat("@{}");
+  verifyFormat("@{@\"one\" : @1}");
+  verifyFormat("return @{@\"one\" : @1;");
+  verifyFormat("@{@\"one\" : @1}");
+
+  verifyFormat("@{@\"one\" : @{@2 : @1}}");
+  verifyFormat("@{\n"
+               "  @\"one\" : @{@2 : @1},\n"
+               "}");
+
+  verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");
+  verifyIncompleteFormat("[self setDict:@{}");
+  verifyIncompleteFormat("[self setDict:@{@1 : @2}");
+  verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");
+  verifyFormat(
+      "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");
+  verifyFormat(
+      "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};");
+
+  verifyFormat("NSDictionary *d = @{\n"
+               "  @\"nam\" : NSUserNam(),\n"
+               "  @\"dte\" : [NSDate date],\n"
+               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
+               "};");
+  verifyFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
+      "regularFont,\n"
+      "};");
+  verifyFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n"
+      "      reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n"
+      "};");
+
+  // We should try to be robust in case someone forgets the "@".
+  verifyFormat("NSDictionary *d = {\n"
+               "  @\"nam\" : NSUserNam(),\n"
+               "  @\"dte\" : [NSDate date],\n"
+               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
+               "};");
+  verifyFormat("NSMutableDictionary *dictionary =\n"
+               "    [NSMutableDictionary dictionaryWithDictionary:@{\n"
+               "      aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"
+               "      bbbbbbbbbbbbbbbbbb : bbbbb,\n"
+               "      cccccccccccccccc : ccccccccccccccc\n"
+               "    }];");
+
+  // Ensure that casts before the key are kept on the same line as the key.
+  verifyFormat(
+      "NSDictionary *d = @{\n"
+      "  (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+      "  (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n"
+      "};");
+
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
+  verifyFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
+      "regularFont,\n"
+      "};");
+}
+
+TEST_F(FormatTestObjC, ObjCArrayLiterals) {
+  verifyIncompleteFormat("@[");
+  verifyFormat("@[]");
+  verifyFormat(
+      "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");
+  verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];");
+  verifyFormat("NSArray *array = @[ [foo description] ];");
+
+  verifyFormat(
+      "NSArray *some_variable = @[\n"
+      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaaa\",\n"
+      "];");
+  verifyFormat(
+      "NSArray *some_variable = @[\n"
+      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\"\n"
+      "];");
+  verifyFormat("NSArray *some_variable = @[\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "];");
+  verifyFormat("NSArray *array = @[\n"
+               "  @\"a\",\n"
+               "  @\"a\",\n" // Trailing comma -> one per line.
+               "];");
+
+  // We should try to be robust in case someone forgets the "@".
+  verifyFormat("NSArray *some_variable = [\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "];");
+  verifyFormat(
+      "- (NSAttributedString *)attributedStringForSegment:(NSUInteger)segment\n"
+      "                                             index:(NSUInteger)index\n"
+      "                                nonDigitAttributes:\n"
+      "                                    (NSDictionary *)noDigitAttributes;");
+  verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
+               "  NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
+               "]];");
+}
+} // end namespace
+} // end namespace format
+} // end namespace clang
diff --git a/unittests/Format/FormatTestProto.cpp b/unittests/Format/FormatTestProto.cpp
index 6881af4..d174c65 100644
--- a/unittests/Format/FormatTestProto.cpp
+++ b/unittests/Format/FormatTestProto.cpp
@@ -135,6 +135,16 @@
                "    key: 'a'  //\n"
                "  }\n"
                "];");
+  verifyFormat("optional string test = 1 [default =\n"
+               "                              \"test\"\n"
+               "                              \"test\"];");
+  verifyFormat("optional Aaaaaaaa aaaaaaaa = 12 [\n"
+               "  (aaa) = aaaa,\n"
+               "  (bbbbbbbbbbbbbbbbbbbbbbbbbb) = {\n"
+               "    aaaaaaaaaaaaaaaaa: true,\n"
+               "    aaaaaaaaaaaaaaaa: true\n"
+               "  }\n"
+               "];");
 }
 
 TEST_F(FormatTestProto, DoesntWrapFileOptions) {
diff --git a/unittests/Format/FormatTestSelective.cpp b/unittests/Format/FormatTestSelective.cpp
index 2bc60fd..367dbaf 100644
--- a/unittests/Format/FormatTestSelective.cpp
+++ b/unittests/Format/FormatTestSelective.cpp
@@ -111,13 +111,19 @@
             format("int   a; // comment\n"
                    "int    b; // comment",
                    0, 0));
-  EXPECT_EQ("int   a; // comment\n"
-            "         // line 2\n"
+  EXPECT_EQ("int a; // comment\n"
+            "       // line 2\n"
             "int b;",
             format("int   a; // comment\n"
                    "            // line 2\n"
                    "int b;",
                    28, 0));
+  EXPECT_EQ("int   a; // comment\n"
+            "// comment 2\n"
+            "int b;",
+            format("int   a; // comment\n"
+                   "// comment 2\n"
+                   "int b;", 28, 0));
   EXPECT_EQ("int aaaaaa; // comment\n"
             "int b;\n"
             "int c; // unrelated comment",
diff --git a/unittests/Format/NamespaceEndCommentsFixerTest.cpp b/unittests/Format/NamespaceEndCommentsFixerTest.cpp
new file mode 100644
index 0000000..48ecdb0
--- /dev/null
+++ b/unittests/Format/NamespaceEndCommentsFixerTest.cpp
@@ -0,0 +1,587 @@
+//===- NamespaceEndCommentsFixerTest.cpp - Formatting unit tests ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Format/Format.h"
+
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "namespace-end-comments-fixer-test"
+
+namespace clang {
+namespace format {
+namespace {
+
+class NamespaceEndCommentsFixerTest : public ::testing::Test {
+protected:
+  std::string
+  fixNamespaceEndComments(llvm::StringRef Code,
+                          std::vector<tooling::Range> Ranges,
+                          const FormatStyle &Style = getLLVMStyle()) {
+    DEBUG(llvm::errs() << "---\n");
+    DEBUG(llvm::errs() << Code << "\n\n");
+    tooling::Replacements Replaces =
+        clang::format::fixNamespaceEndComments(Style, Code, Ranges, "<stdin>");
+    auto Result = applyAllReplacements(Code, Replaces);
+    EXPECT_TRUE(static_cast<bool>(Result));
+    DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+    return *Result;
+  }
+
+  std::string
+  fixNamespaceEndComments(llvm::StringRef Code,
+                          const FormatStyle &Style = getLLVMStyle()) {
+    return fixNamespaceEndComments(
+        Code,
+        /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
+  }
+};
+
+TEST_F(NamespaceEndCommentsFixerTest, AddsEndComment) {
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "}"));
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace\n",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "}\n"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "}"));
+  EXPECT_EQ("inline namespace A {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace A",
+            fixNamespaceEndComments("inline namespace A {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "}"));
+  EXPECT_EQ("namespace ::A {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace ::A",
+            fixNamespaceEndComments("namespace ::A {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "}"));
+  EXPECT_EQ("namespace ::A::B {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace ::A::B",
+            fixNamespaceEndComments("namespace ::A::B {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "}"));
+  EXPECT_EQ("namespace /**/::/**/A/**/::/**/B/**/ {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace ::A::B",
+            fixNamespaceEndComments("namespace /**/::/**/A/**/::/**/B/**/ {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "}"));
+  EXPECT_EQ("namespace A {\n"
+            "namespace B {\n"
+            "  int i;\n"
+            "}\n"
+            "}// namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "namespace B {\n"
+                                    "  int i;\n"
+                                    "}\n"
+                                    "}"));
+  EXPECT_EQ("namespace A {\n"
+            "namespace B {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace B\n"
+            "}// namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "namespace B {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "}\n"
+                                    "}"));
+  EXPECT_EQ("namespace A {\n"
+            "  int a;\n"
+            "  int b;\n"
+            "}// namespace A\n"
+            "namespace B {\n"
+            "  int b;\n"
+            "  int a;\n"
+            "}// namespace B",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int a;\n"
+                                    "  int b;\n"
+                                    "}\n"
+                                    "namespace B {\n"
+                                    "  int b;\n"
+                                    "  int a;\n"
+                                    "}"));
+  EXPECT_EQ("namespace A {\n"
+            "  int a1;\n"
+            "  int a2;\n"
+            "}// namespace A\n"
+            "namespace A {\n"
+            "  int a2;\n"
+            "  int a1;\n"
+            "}// namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int a1;\n"
+                                    "  int a2;\n"
+                                    "}\n"
+                                    "namespace A {\n"
+                                    "  int a2;\n"
+                                    "  int a1;\n"
+                                    "}"));
+  EXPECT_EQ("namespace A {\n"
+            "  int a;\n"
+            "  int b;\n"
+            "}// namespace A\n"
+            "// comment about b\n"
+            "int b;",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int a;\n"
+                                    "  int b;\n"
+                                    "}\n"
+                                    "// comment about b\n"
+                                    "int b;"));
+
+  EXPECT_EQ("namespace A {\n"
+            "namespace B {\n"
+            "namespace C {\n"
+            "namespace D {\n"
+            "}\n"
+            "}// namespace C\n"
+            "}// namespace B\n"
+            "}// namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "namespace B {\n"
+                                    "namespace C {\n"
+                                    "namespace D {\n"
+                                    "}\n"
+                                    "}\n"
+                                    "}\n"
+                                    "}"));
+
+  // Adds an end comment after a semicolon.
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "};// namespace",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "};"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "};// namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "};"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "};// namespace A\n"
+            "// unrelated",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "};\n"
+                                    "// unrelated"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) {
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace A\n"
+            " int k;",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "} int k;"));
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace\n"
+            " int k;",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "} int k;"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace A\n"
+            " namespace B {\n"
+            "  int j;\n"
+            "  int k;\n"
+            "}// namespace B",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "} namespace B {\n"
+                                    "  int j;\n"
+                                    "  int k;\n"
+                                    "}"));
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "};// namespace\n"
+            "int k;",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "};int k;"));
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "};// namespace\n"
+            ";",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "};;"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForShortNamespace) {
+  EXPECT_EQ("namespace {}", fixNamespaceEndComments("namespace {}"));
+  EXPECT_EQ("namespace A {}", fixNamespaceEndComments("namespace A {}"));
+  EXPECT_EQ("namespace A { a }",
+            fixNamespaceEndComments("namespace A { a }"));
+  EXPECT_EQ("namespace A { a };",
+            fixNamespaceEndComments("namespace A { a };"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterUnaffectedRBrace) {
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "}",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "}",
+                                    // The range (16, 3) spans the 'int' above.
+                                    /*Ranges=*/{1, tooling::Range(16, 3)}));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "};",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "};",
+                                    // The range (16, 3) spans the 'int' above.
+                                    /*Ranges=*/{1, tooling::Range(16, 3)}));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterRBraceInPPDirective) {
+  EXPECT_EQ("#define SAD \\\n"
+            "namespace A { \\\n"
+            "  int i; \\\n"
+            "}",
+            fixNamespaceEndComments("#define SAD \\\n"
+                                    "namespace A { \\\n"
+                                    "  int i; \\\n"
+                                    "}"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, KeepsValidEndComment) {
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "} // end anonymous namespace",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "} // end anonymous namespace"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "} /* end of namespace A */",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "} /* end of namespace A */"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "}   //   namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "}   //   namespace A"));
+  EXPECT_EQ("namespace A::B {\n"
+            "  int i;\n"
+            "} // end namespace A::B",
+            fixNamespaceEndComments("namespace A::B {\n"
+                                    "  int i;\n"
+                                    "} // end namespace A::B"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "}; // end namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "}; // end namespace A"));
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "}; /* unnamed namespace */",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "}; /* unnamed namespace */"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) {
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "} // namespace",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "} // namespace A"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "} // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "} // namespace"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "} // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "} //"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "} // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "} //"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "} // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "} // banamespace A"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "}; // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "}; // banamespace A"));
+  // Updates invalid line comments even for short namespaces.
+  EXPECT_EQ("namespace A {} // namespace A",
+            fixNamespaceEndComments("namespace A {} // namespace"));
+  EXPECT_EQ("namespace A {}; // namespace A",
+            fixNamespaceEndComments("namespace A {}; // namespace"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) {
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "} // namespace",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "} /* namespace A */"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "}  // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "}  /* end namespace */"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "} // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "} /**/"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "} // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "} /* end unnamed namespace */"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "} // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "} /* banamespace A */"));
+  EXPECT_EQ("namespace A {\n"
+            "  int i;\n"
+            "}; // namespace A",
+            fixNamespaceEndComments("namespace A {\n"
+                                    "  int i;\n"
+                                    "}; /* banamespace A */"));
+  EXPECT_EQ("namespace A {} // namespace A",
+            fixNamespaceEndComments("namespace A {} /**/"));
+  EXPECT_EQ("namespace A {}; // namespace A",
+            fixNamespaceEndComments("namespace A {}; /**/"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest,
+       DoesNotAddEndCommentForNamespacesControlledByMacros) {
+  EXPECT_EQ("#ifdef 1\n"
+            "namespace A {\n"
+            "#elseif\n"
+            "namespace B {\n"
+            "#endif\n"
+            "  int i;\n"
+            "}\n"
+            "}\n",
+            fixNamespaceEndComments("#ifdef 1\n"
+                                    "namespace A {\n"
+                                    "#elseif\n"
+                                    "namespace B {\n"
+                                    "#endif\n"
+                                    "  int i;\n"
+                                    "}\n"
+                                    "}\n"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest,
+       DoesNotAddEndCommentForNamespacesInMacroDeclarations) {
+  EXPECT_EQ("#ifdef 1\n"
+            "namespace A {\n"
+            "#elseif\n"
+            "namespace B {\n"
+            "#endif\n"
+            "  int i;\n"
+            "}\n"
+            "}\n",
+            fixNamespaceEndComments("#ifdef 1\n"
+                                    "namespace A {\n"
+                                    "#elseif\n"
+                                    "namespace B {\n"
+                                    "#endif\n"
+                                    "  int i;\n"
+                                    "}\n"
+                                    "}\n"));
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "  int j;\n"
+            "}// namespace\n"
+            "#if A\n"
+            "  int i;\n"
+            "#else\n"
+            "  int j;\n"
+            "#endif",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "  int j;\n"
+                                    "}\n"
+                                    "#if A\n"
+                                    "  int i;\n"
+                                    "#else\n"
+                                    "  int j;\n"
+                                    "#endif"));
+  EXPECT_EQ("#if A\n"
+            "namespace A {\n"
+            "#else\n"
+            "namespace B {\n"
+            "#endif\n"
+            "int i;\n"
+            "int j;\n"
+            "}",
+            fixNamespaceEndComments("#if A\n"
+                                    "namespace A {\n"
+                                    "#else\n"
+                                    "namespace B {\n"
+                                    "#endif\n"
+                                    "int i;\n"
+                                    "int j;\n"
+                                    "}"));
+  EXPECT_EQ("#if A\n"
+            "namespace A {\n"
+            "#else\n"
+            "namespace B {\n"
+            "#endif\n"
+            "int i;\n"
+            "int j;\n"
+            "} // namespace A",
+            fixNamespaceEndComments("#if A\n"
+                                    "namespace A {\n"
+                                    "#else\n"
+                                    "namespace B {\n"
+                                    "#endif\n"
+                                    "int i;\n"
+                                    "int j;\n"
+                                    "} // namespace A"));
+  EXPECT_EQ("#if A\n"
+            "namespace A {\n"
+            "#else\n"
+            "namespace B {\n"
+            "#endif\n"
+            "int i;\n"
+            "int j;\n"
+            "} // namespace B",
+            fixNamespaceEndComments("#if A\n"
+                                    "namespace A {\n"
+                                    "#else\n"
+                                    "namespace B {\n"
+                                    "#endif\n"
+                                    "int i;\n"
+                                    "int j;\n"
+                                    "} // namespace B"));
+  EXPECT_EQ("namespace A\n"
+            "int i;\n"
+            "int j;\n"
+            "#if A\n"
+            "}\n"
+            "#else\n"
+            "}\n"
+            "#endif",
+            fixNamespaceEndComments("namespace A\n"
+                                    "int i;\n"
+                                    "int j;\n"
+                                    "#if A\n"
+                                    "}\n"
+                                    "#else\n"
+                                    "}\n"
+                                    "#endif"));
+  EXPECT_EQ("namespace A\n"
+            "int i;\n"
+            "int j;\n"
+            "#if A\n"
+            "} // namespace A\n"
+            "#else\n"
+            "} // namespace A\n"
+            "#endif",
+            fixNamespaceEndComments("namespace A\n"
+                                    "int i;\n"
+                                    "int j;\n"
+                                    "#if A\n"
+                                    "} // namespace A\n"
+                                    "#else\n"
+                                    "} // namespace A\n"
+                                    "#endif"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest,
+       DoesNotAddEndCommentForUnbalancedRBracesAfterNamespaceEnd) {
+  EXPECT_EQ("namespace {\n"
+            "  int i;\n"
+            "} // namespace\n"
+            "}",
+            fixNamespaceEndComments("namespace {\n"
+                                    "  int i;\n"
+                                    "} // namespace\n"
+                                    "}"));
+}
+} // end namespace
+} // end namespace format
+} // end namespace clang
diff --git a/unittests/Frontend/CodeGenActionTest.cpp b/unittests/Frontend/CodeGenActionTest.cpp
index 356b513..1d2a50c 100644
--- a/unittests/Frontend/CodeGenActionTest.cpp
+++ b/unittests/Frontend/CodeGenActionTest.cpp
@@ -41,7 +41,7 @@
 
 
 TEST(CodeGenTest, TestNullCodeGen) {
-  CompilerInvocation *Invocation = new CompilerInvocation;
+  auto Invocation = std::make_shared<CompilerInvocation>();
   Invocation->getPreprocessorOpts().addRemappedFile(
       "test.cc",
       MemoryBuffer::getMemBuffer("").release());
@@ -50,7 +50,7 @@
   Invocation->getFrontendOpts().ProgramAction = EmitLLVM;
   Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
   CompilerInstance Compiler;
-  Compiler.setInvocation(Invocation);
+  Compiler.setInvocation(std::move(Invocation));
   Compiler.createDiagnostics();
   EXPECT_TRUE(Compiler.hasDiagnostics());
 
diff --git a/unittests/Frontend/FrontendActionTest.cpp b/unittests/Frontend/FrontendActionTest.cpp
index c3e6adb..dd6be5f 100644
--- a/unittests/Frontend/FrontendActionTest.cpp
+++ b/unittests/Frontend/FrontendActionTest.cpp
@@ -79,7 +79,7 @@
 };
 
 TEST(ASTFrontendAction, Sanity) {
-  CompilerInvocation *invocation = new CompilerInvocation;
+  auto invocation = std::make_shared<CompilerInvocation>();
   invocation->getPreprocessorOpts().addRemappedFile(
       "test.cc",
       MemoryBuffer::getMemBuffer("int main() { float x; }").release());
@@ -88,7 +88,7 @@
   invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
   invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
   CompilerInstance compiler;
-  compiler.setInvocation(invocation);
+  compiler.setInvocation(std::move(invocation));
   compiler.createDiagnostics();
 
   TestASTFrontendAction test_action;
@@ -99,7 +99,7 @@
 }
 
 TEST(ASTFrontendAction, IncrementalParsing) {
-  CompilerInvocation *invocation = new CompilerInvocation;
+  auto invocation = std::make_shared<CompilerInvocation>();
   invocation->getPreprocessorOpts().addRemappedFile(
       "test.cc",
       MemoryBuffer::getMemBuffer("int main() { float x; }").release());
@@ -108,7 +108,7 @@
   invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
   invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
   CompilerInstance compiler;
-  compiler.setInvocation(invocation);
+  compiler.setInvocation(std::move(invocation));
   compiler.createDiagnostics();
 
   TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true);
@@ -119,7 +119,7 @@
 }
 
 TEST(ASTFrontendAction, LateTemplateIncrementalParsing) {
-  CompilerInvocation *invocation = new CompilerInvocation;
+  auto invocation = std::make_shared<CompilerInvocation>();
   invocation->getLangOpts()->CPlusPlus = true;
   invocation->getLangOpts()->DelayedTemplateParsing = true;
   invocation->getPreprocessorOpts().addRemappedFile(
@@ -135,7 +135,7 @@
   invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
   invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
   CompilerInstance compiler;
-  compiler.setInvocation(invocation);
+  compiler.setInvocation(std::move(invocation));
   compiler.createDiagnostics();
 
   TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true,
@@ -172,7 +172,7 @@
 };
 
 TEST(PreprocessorFrontendAction, EndSourceFile) {
-  CompilerInvocation *Invocation = new CompilerInvocation;
+  auto Invocation = std::make_shared<CompilerInvocation>();
   Invocation->getPreprocessorOpts().addRemappedFile(
       "test.cc",
       MemoryBuffer::getMemBuffer("int main() { float x; }").release());
@@ -181,7 +181,7 @@
   Invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
   Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
   CompilerInstance Compiler;
-  Compiler.setInvocation(Invocation);
+  Compiler.setInvocation(std::move(Invocation));
   Compiler.createDiagnostics();
 
   TestPPCallbacks *Callbacks = new TestPPCallbacks;
@@ -231,7 +231,7 @@
 };
 
 TEST(ASTFrontendAction, ExternalSemaSource) {
-  auto *Invocation = new CompilerInvocation;
+  auto Invocation = std::make_shared<CompilerInvocation>();
   Invocation->getLangOpts()->CPlusPlus = true;
   Invocation->getPreprocessorOpts().addRemappedFile(
       "test.cc", MemoryBuffer::getMemBuffer("void fooo();\n"
@@ -242,7 +242,7 @@
   Invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
   Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
   CompilerInstance Compiler;
-  Compiler.setInvocation(Invocation);
+  Compiler.setInvocation(std::move(Invocation));
   auto *TDC = new TypoDiagnosticConsumer;
   Compiler.createDiagnostics(TDC, /*ShouldOwnClient=*/true);
   Compiler.setExternalSemaSource(new TypoExternalSemaSource(Compiler));
diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index 2046018..918167b 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -64,10 +64,10 @@
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
     VoidModuleLoader ModLoader;
-    HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
-                            Target.get());
-    Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
-                    HeaderInfo, ModLoader, /*IILookup =*/nullptr,
+    HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+                            Diags, LangOpts, Target.get());
+    Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
+                    SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
     PP.EnterMainSourceFile();
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index cbce5c6..064abaf 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -162,13 +162,12 @@
 
     VoidModuleLoader ModLoader;
 
-    IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts = new HeaderSearchOptions();
-    HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts,
-                            Target.get());
+    HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+                            Diags, LangOpts, Target.get());
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
 
-    IntrusiveRefCntPtr<PreprocessorOptions> PPOpts = new PreprocessorOptions();
-    Preprocessor PP(PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader,
+    Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
+                    SourceMgr, HeaderInfo, ModLoader,
                     /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
@@ -199,11 +198,12 @@
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf)));
 
     VoidModuleLoader ModLoader;
-    HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, 
-                            OpenCLLangOpts, Target.get());
+    HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+                            Diags, OpenCLLangOpts, Target.get());
 
-    Preprocessor PP(new PreprocessorOptions(), Diags, OpenCLLangOpts, SourceMgr,
-                    HeaderInfo, ModLoader, /*IILookup =*/nullptr,
+    Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags,
+                    OpenCLLangOpts, SourceMgr, HeaderInfo, ModLoader,
+                    /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
 
diff --git a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index bceeac5..dccfffd 100644
--- a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -93,10 +93,10 @@
   SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
   VoidModuleLoader ModLoader;
-  HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 
-                          Target.get());
-  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
-                  HeaderInfo, ModLoader,
+  HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+                          Diags, LangOpts, Target.get());
+  Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
+                  SourceMgr, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
diff --git a/unittests/Tooling/CMakeLists.txt b/unittests/Tooling/CMakeLists.txt
index 185f43b..b5af99b 100644
--- a/unittests/Tooling/CMakeLists.txt
+++ b/unittests/Tooling/CMakeLists.txt
@@ -13,7 +13,7 @@
 add_clang_unittest(ToolingTests
   CommentHandlerTest.cpp
   CompilationDatabaseTest.cpp
-  FixItTest.cpp  
+  FixItTest.cpp
   LookupTest.cpp
   QualTypeNamesTest.cpp
   RecursiveASTVisitorTest.cpp
@@ -38,4 +38,5 @@
   clangRewrite
   clangTooling
   clangToolingCore
+  clangToolingRefactor
   )
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index a2aedb6..7e08f96 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -133,25 +133,6 @@
     "};\n"));
 }
 
-// Check to ensure that VarDecls are visited.
-class VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> {
-public:
-  bool VisitVarDecl(VarDecl *VD) {
-    Match(VD->getNameAsString(), VD->getLocStart());
-    return true;
-  }
-};
-
-TEST(RecursiveASTVisitor, ArrayInitializersAreVisited) {
-  VarDeclVisitor Visitor;
-  Visitor.ExpectMatch("__i0", 1, 8);
-  EXPECT_TRUE(
-      Visitor.runOver("struct MyClass {\n"
-                      "  int c[1];\n"
-                      "  static MyClass Create() { return MyClass(); }\n"
-                      "};\n"));
-}
-
 // Check to ensure that implicit default argument expressions are visited.
 class IntegerLiteralVisitor
     : public ExpectedLocationVisitor<IntegerLiteralVisitor> {
diff --git a/unittests/Tooling/RefactoringTest.cpp b/unittests/Tooling/RefactoringTest.cpp
index c29f8d7..c5633d3 100644
--- a/unittests/Tooling/RefactoringTest.cpp
+++ b/unittests/Tooling/RefactoringTest.cpp
@@ -26,6 +26,7 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Refactoring/AtomicChange.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/SmallString.h"
 #include "gtest/gtest.h"
@@ -102,10 +103,10 @@
 
 // Checks that an llvm::Error instance contains a ReplacementError with expected
 // error code, expected new replacement, and expected existing replacement.
-static bool checkReplacementError(
-    llvm::Error&& Error, replacement_error ExpectedErr,
-    llvm::Optional<Replacement> ExpectedExisting,
-    llvm::Optional<Replacement> ExpectedNew) {
+static bool checkReplacementError(llvm::Error &&Error,
+                                  replacement_error ExpectedErr,
+                                  llvm::Optional<Replacement> ExpectedExisting,
+                                  llvm::Optional<Replacement> ExpectedNew) {
   if (!Error) {
     llvm::errs() << "Error is a success.";
     return false;
@@ -1089,5 +1090,205 @@
   EXPECT_TRUE(FileToReplaces.empty());
 }
 
+class AtomicChangeTest : public ::testing::Test {
+  protected:
+    void setUp() {
+      DefaultFileID = Context.createInMemoryFile("input.cpp", DefaultCode);
+      DefaultLoc = Context.Sources.getLocForStartOfFile(DefaultFileID)
+                       .getLocWithOffset(20);
+      assert(DefaultLoc.isValid() && "Default location must be valid.");
+    }
+
+    RewriterTestContext Context;
+    std::string DefaultCode = std::string(100, 'a');
+    unsigned DefaultOffset = 20;
+    SourceLocation DefaultLoc;
+    FileID DefaultFileID;
+};
+
+TEST_F(AtomicChangeTest, AtomicChangeToYAML) {
+  setUp();
+  AtomicChange Change(Context.Sources, DefaultLoc);
+  llvm::Error Err =
+      Change.insert(Context.Sources, DefaultLoc, "aa", /*InsertAfter=*/false);
+  ASSERT_TRUE(!Err);
+  Err = Change.insert(Context.Sources, DefaultLoc.getLocWithOffset(10), "bb",
+                    /*InsertAfter=*/false);
+  ASSERT_TRUE(!Err);
+  Change.addHeader("a.h");
+  Change.removeHeader("b.h");
+  std::string YAMLString = Change.toYAMLString();
+
+  // NOTE: If this test starts to fail for no obvious reason, check whitespace.
+  ASSERT_STREQ("---\n"
+               "Key:             'input.cpp:20'\n"
+               "FilePath:        input.cpp\n"
+               "Error:           ''\n"
+               "InsertedHeaders: [ a.h ]\n"
+               "RemovedHeaders:  [ b.h ]\n"
+               "Replacements:    \n" // Extra whitespace here!
+               "  - FilePath:        input.cpp\n"
+               "    Offset:          20\n"
+               "    Length:          0\n"
+               "    ReplacementText: aa\n"
+               "  - FilePath:        input.cpp\n"
+               "    Offset:          30\n"
+               "    Length:          0\n"
+               "    ReplacementText: bb\n"
+               "...\n",
+               YAMLString.c_str());
+}
+
+TEST_F(AtomicChangeTest, YAMLToAtomicChange) {
+  setUp();
+  std::string YamlContent = "---\n"
+                            "Key:             'input.cpp:20'\n"
+                            "FilePath:        input.cpp\n"
+                            "Error:           'ok'\n"
+                            "InsertedHeaders: [ a.h ]\n"
+                            "RemovedHeaders:  [ b.h ]\n"
+                            "Replacements:    \n" // Extra whitespace here!
+                            "  - FilePath:        input.cpp\n"
+                            "    Offset:          20\n"
+                            "    Length:          0\n"
+                            "    ReplacementText: aa\n"
+                            "  - FilePath:        input.cpp\n"
+                            "    Offset:          30\n"
+                            "    Length:          0\n"
+                            "    ReplacementText: bb\n"
+                            "...\n";
+  AtomicChange ExpectedChange(Context.Sources, DefaultLoc);
+  llvm::Error Err = ExpectedChange.insert(Context.Sources, DefaultLoc, "aa",
+                                        /*InsertAfter=*/false);
+  ASSERT_TRUE(!Err);
+  Err = ExpectedChange.insert(Context.Sources, DefaultLoc.getLocWithOffset(10),
+                            "bb", /*InsertAfter=*/false);
+  ASSERT_TRUE(!Err);
+
+  ExpectedChange.addHeader("a.h");
+  ExpectedChange.removeHeader("b.h");
+  ExpectedChange.setError("ok");
+
+  AtomicChange ActualChange = AtomicChange::convertFromYAML(YamlContent);
+  EXPECT_EQ(ExpectedChange.getKey(), ActualChange.getKey());
+  EXPECT_EQ(ExpectedChange.getFilePath(), ActualChange.getFilePath());
+  EXPECT_EQ(ExpectedChange.getError(), ActualChange.getError());
+  EXPECT_EQ(ExpectedChange.getInsertedHeaders(),
+            ActualChange.getInsertedHeaders());
+  EXPECT_EQ(ExpectedChange.getRemovedHeaders(),
+            ActualChange.getRemovedHeaders());
+  EXPECT_EQ(ExpectedChange.getReplacements().size(),
+            ActualChange.getReplacements().size());
+  EXPECT_EQ(2u, ActualChange.getReplacements().size());
+  EXPECT_EQ(*ExpectedChange.getReplacements().begin(),
+            *ActualChange.getReplacements().begin());
+  EXPECT_EQ(*(++ExpectedChange.getReplacements().begin()),
+            *(++ActualChange.getReplacements().begin()));
+}
+
+TEST_F(AtomicChangeTest, CheckKeyAndKeyFile) {
+  setUp();
+  AtomicChange Change(Context.Sources, DefaultLoc);
+  EXPECT_EQ("input.cpp:20", Change.getKey());
+  EXPECT_EQ("input.cpp", Change.getFilePath());
+}
+
+TEST_F(AtomicChangeTest, Replace) {
+  setUp();
+  AtomicChange Change(Context.Sources, DefaultLoc);
+  llvm::Error Err = Change.replace(Context.Sources, DefaultLoc, 2, "aa");
+  ASSERT_TRUE(!Err);
+  EXPECT_EQ(Change.getReplacements().size(), 1u);
+  EXPECT_EQ(*Change.getReplacements().begin(),
+            Replacement(Context.Sources, DefaultLoc, 2, "aa"));
+
+  // Add a new replacement that conflicts with the existing one.
+  Err = Change.replace(Context.Sources, DefaultLoc, 3, "ab");
+  EXPECT_TRUE((bool)Err);
+  llvm::consumeError(std::move(Err));
+  EXPECT_EQ(Change.getReplacements().size(), 1u);
+}
+
+TEST_F(AtomicChangeTest, InsertBefore) {
+  setUp();
+  AtomicChange Change(Context.Sources, DefaultLoc);
+  llvm::Error Err = Change.insert(Context.Sources, DefaultLoc, "aa");
+  ASSERT_TRUE(!Err);
+  EXPECT_EQ(Change.getReplacements().size(), 1u);
+  EXPECT_EQ(*Change.getReplacements().begin(),
+            Replacement(Context.Sources, DefaultLoc, 0, "aa"));
+  Err = Change.insert(Context.Sources, DefaultLoc, "b", /*InsertAfter=*/false);
+  ASSERT_TRUE(!Err);
+  EXPECT_EQ(Change.getReplacements().size(), 1u);
+  EXPECT_EQ(*Change.getReplacements().begin(),
+            Replacement(Context.Sources, DefaultLoc, 0, "baa"));
+}
+
+TEST_F(AtomicChangeTest, InsertAfter) {
+  setUp();
+  AtomicChange Change(Context.Sources, DefaultLoc);
+  llvm::Error Err = Change.insert(Context.Sources, DefaultLoc, "aa");
+  ASSERT_TRUE(!Err);
+  EXPECT_EQ(Change.getReplacements().size(), 1u);
+  EXPECT_EQ(*Change.getReplacements().begin(),
+            Replacement(Context.Sources, DefaultLoc, 0, "aa"));
+  Err = Change.insert(Context.Sources, DefaultLoc, "b");
+  ASSERT_TRUE(!Err);
+  EXPECT_EQ(Change.getReplacements().size(), 1u);
+  EXPECT_EQ(*Change.getReplacements().begin(),
+            Replacement(Context.Sources, DefaultLoc, 0, "aab"));
+}
+
+TEST_F(AtomicChangeTest, InsertBeforeWithInvalidLocation) {
+  setUp();
+  AtomicChange Change(Context.Sources, DefaultLoc);
+  llvm::Error Err =
+      Change.insert(Context.Sources, DefaultLoc, "a", /*InsertAfter=*/false);
+  ASSERT_TRUE(!Err);
+
+  // Invalid location.
+  Err = Change.insert(Context.Sources, SourceLocation(), "a",
+                    /*InsertAfter=*/false);
+  ASSERT_TRUE((bool)Err);
+  EXPECT_TRUE(checkReplacementError(
+      std::move(Err), replacement_error::wrong_file_path,
+      Replacement(Context.Sources, DefaultLoc, 0, "a"),
+      Replacement(Context.Sources, SourceLocation(), 0, "a")));
+
+}
+
+TEST_F(AtomicChangeTest, InsertBeforeToWrongFile) {
+  setUp();
+  AtomicChange Change(Context.Sources, DefaultLoc);
+  llvm::Error Err =
+      Change.insert(Context.Sources, DefaultLoc, "a", /*InsertAfter=*/false);
+  ASSERT_TRUE(!Err);
+
+  // Inserting at a different file.
+  FileID NewID = Context.createInMemoryFile("extra.cpp", DefaultCode);
+  SourceLocation NewLoc = Context.Sources.getLocForStartOfFile(NewID);
+  Err = Change.insert(Context.Sources, NewLoc, "b", /*InsertAfter=*/false);
+  ASSERT_TRUE((bool)Err);
+  EXPECT_TRUE(
+      checkReplacementError(std::move(Err), replacement_error::wrong_file_path,
+                            Replacement(Context.Sources, DefaultLoc, 0, "a"),
+                            Replacement(Context.Sources, NewLoc, 0, "b")));
+}
+
+TEST_F(AtomicChangeTest, InsertAfterWithInvalidLocation) {
+  setUp();
+  AtomicChange Change(Context.Sources, DefaultLoc);
+  llvm::Error Err = Change.insert(Context.Sources, DefaultLoc, "a");
+  ASSERT_TRUE(!Err);
+
+  // Invalid location.
+  Err = Change.insert(Context.Sources, SourceLocation(), "b");
+  ASSERT_TRUE((bool)Err);
+  EXPECT_TRUE(checkReplacementError(
+      std::move(Err), replacement_error::wrong_file_path,
+      Replacement(Context.Sources, DefaultLoc, 0, "a"),
+      Replacement(Context.Sources, SourceLocation(), 0, "b")));
+}
+
 } // end namespace tooling
 } // end namespace clang
diff --git a/unittests/Tooling/ReplacementTest.h b/unittests/Tooling/ReplacementTest.h
index 91530f0..b6fe5c7 100644
--- a/unittests/Tooling/ReplacementTest.h
+++ b/unittests/Tooling/ReplacementTest.h
@@ -24,7 +24,7 @@
 /// \brief Converts a set of replacements to Replacements class.
 /// \return A Replacements class containing \p Replaces on success; otherwise,
 /// an empty Replacements is returned.
-static tooling::Replacements
+inline tooling::Replacements
 toReplacements(const std::set<tooling::Replacement> &Replaces) {
   tooling::Replacements Result;
   for (const auto &R : Replaces) {
diff --git a/unittests/Tooling/ReplacementsYamlTest.cpp b/unittests/Tooling/ReplacementsYamlTest.cpp
index a20dde7..3e4193d 100644
--- a/unittests/Tooling/ReplacementsYamlTest.cpp
+++ b/unittests/Tooling/ReplacementsYamlTest.cpp
@@ -22,11 +22,8 @@
   TranslationUnitReplacements Doc;
 
   Doc.MainSourceFile = "/path/to/source.cpp";
-  Doc.Context = "some context";
-  Doc.Replacements
-      .push_back(Replacement("/path/to/file1.h", 232, 56, "replacement #1"));
-  Doc.Replacements
-      .push_back(Replacement("/path/to/file2.h", 301, 2, "replacement #2"));
+  Doc.Replacements.emplace_back("/path/to/file1.h", 232, 56, "replacement #1");
+  Doc.Replacements.emplace_back("/path/to/file2.h", 301, 2, "replacement #2");
 
   std::string YamlContent;
   llvm::raw_string_ostream YamlContentStream(YamlContent);
@@ -37,7 +34,6 @@
   // NOTE: If this test starts to fail for no obvious reason, check whitespace.
   ASSERT_STREQ("---\n"
                "MainSourceFile:  /path/to/source.cpp\n"
-               "Context:         some context\n"
                "Replacements:    \n" // Extra whitespace here!
                "  - FilePath:        /path/to/file1.h\n"
                "    Offset:          232\n"
@@ -54,7 +50,6 @@
 TEST(ReplacementsYamlTest, deserializesReplacements) {
   std::string YamlContent = "---\n"
                             "MainSourceFile:      /path/to/source.cpp\n"
-                            "Context:             some context\n"
                             "Replacements:\n"
                             "  - FilePath:        /path/to/file1.h\n"
                             "    Offset:          232\n"
@@ -71,7 +66,6 @@
   ASSERT_FALSE(YAML.error());
   ASSERT_EQ(2u, DocActual.Replacements.size());
   ASSERT_EQ("/path/to/source.cpp", DocActual.MainSourceFile);
-  ASSERT_EQ("some context", DocActual.Context);
   ASSERT_EQ("/path/to/file1.h", DocActual.Replacements[0].getFilePath());
   ASSERT_EQ(232u, DocActual.Replacements[0].getOffset());
   ASSERT_EQ(56u, DocActual.Replacements[0].getLength());
@@ -98,7 +92,6 @@
   ASSERT_FALSE(YAML.error());
   ASSERT_EQ("/path/to/source.cpp", DocActual.MainSourceFile);
   ASSERT_EQ(1u, DocActual.Replacements.size());
-  ASSERT_EQ(std::string(), DocActual.Context);
   ASSERT_EQ("target_file.h", DocActual.Replacements[0].getFilePath());
   ASSERT_EQ(1u, DocActual.Replacements[0].getOffset());
   ASSERT_EQ(10u, DocActual.Replacements[0].getLength());
diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt
index 29a1eed..c8e9537 100644
--- a/utils/TableGen/CMakeLists.txt
+++ b/utils/TableGen/CMakeLists.txt
@@ -7,6 +7,7 @@
   ClangCommentHTMLNamedCharacterReferenceEmitter.cpp
   ClangCommentHTMLTagsEmitter.cpp
   ClangDiagnosticsEmitter.cpp
+  ClangOptionDocEmitter.cpp
   ClangSACheckersEmitter.cpp
   NeonEmitter.cpp
   TableGen.cpp
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index d65794e..990b860 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -90,13 +90,13 @@
 
 static std::string ReadPCHRecord(StringRef type) {
   return StringSwitch<std::string>(type)
-    .EndsWith("Decl *", "GetLocalDeclAs<" 
-              + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])")
-    .Case("TypeSourceInfo *", "GetTypeSourceInfo(F, Record, Idx)")
-    .Case("Expr *", "ReadExpr(F)")
-    .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
-    .Case("StringRef", "ReadString(Record, Idx)")
-    .Default("Record[Idx++]");
+    .EndsWith("Decl *", "Record.GetLocalDeclAs<" 
+              + std::string(type, 0, type.size()-1) + ">(Record.readInt())")
+    .Case("TypeSourceInfo *", "Record.getTypeSourceInfo()")
+    .Case("Expr *", "Record.readExpr()")
+    .Case("IdentifierInfo *", "Record.getIdentifierInfo()")
+    .Case("StringRef", "Record.readString()")
+    .Default("Record.readInt()");
 }
 
 // Get a type that is suitable for storing an object of the specified type.
@@ -133,10 +133,9 @@
   return Name.trim("_");
 }
 
-// Normalize attribute spelling only if the spelling has both leading
-// and trailing underscores. For example, __ms_struct__ will be 
-// normalized to "ms_struct"; __cdecl will remain intact.
-static StringRef NormalizeAttrSpelling(StringRef AttrSpelling) {
+// Normalize the spelling of a GNU attribute (i.e. "x" in "__attribute__((x))"),
+// removing "__" if it appears at the beginning and end of the attribute's name.
+static StringRef NormalizeGNUAttrSpelling(StringRef AttrSpelling) {
   if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) {
     AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4);
   }
@@ -414,7 +413,7 @@
 
     void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "    std::string " << getLowerName()
-         << "= ReadString(Record, Idx);\n";
+         << "= Record.readString();\n";
     }
 
     void writePCHReadArgs(raw_ostream &OS) const override {
@@ -540,13 +539,13 @@
     }
 
     void writePCHReadDecls(raw_ostream &OS) const override {
-      OS << "    bool is" << getLowerName() << "Expr = Record[Idx++];\n";
+      OS << "    bool is" << getLowerName() << "Expr = Record.readInt();\n";
       OS << "    void *" << getLowerName() << "Ptr;\n";
       OS << "    if (is" << getLowerName() << "Expr)\n";
-      OS << "      " << getLowerName() << "Ptr = ReadExpr(F);\n";
+      OS << "      " << getLowerName() << "Ptr = Record.readExpr();\n";
       OS << "    else\n";
       OS << "      " << getLowerName()
-         << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
+         << "Ptr = Record.getTypeSourceInfo();\n";
     }
 
     void writePCHWrite(raw_ostream &OS) const override {
@@ -659,7 +658,7 @@
     }
 
     void writePCHReadDecls(raw_ostream &OS) const override {
-      OS << "    unsigned " << getLowerName() << "Size = Record[Idx++];\n";
+      OS << "    unsigned " << getLowerName() << "Size = Record.readInt();\n";
       OS << "    SmallVector<" << getType() << ", 4> "
          << getLowerName() << ";\n";
       OS << "    " << getLowerName() << ".reserve(" << getLowerName()
@@ -784,7 +783,7 @@
     void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "    " << getAttrName() << "Attr::" << type << " " << getLowerName()
          << "(static_cast<" << getAttrName() << "Attr::" << type
-         << ">(Record[Idx++]));\n";
+         << ">(Record.readInt()));\n";
     }
 
     void writePCHReadArgs(raw_ostream &OS) const override {
@@ -907,14 +906,14 @@
     }
 
     void writePCHReadDecls(raw_ostream &OS) const override {
-      OS << "    unsigned " << getLowerName() << "Size = Record[Idx++];\n";
+      OS << "    unsigned " << getLowerName() << "Size = Record.readInt();\n";
       OS << "    SmallVector<" << QualifiedTypeName << ", 4> " << getLowerName()
          << ";\n";
       OS << "    " << getLowerName() << ".reserve(" << getLowerName()
          << "Size);\n";
       OS << "    for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
       OS << "      " << getLowerName() << ".push_back(" << "static_cast<"
-         << QualifiedTypeName << ">(Record[Idx++]));\n";
+         << QualifiedTypeName << ">(Record.readInt()));\n";
     }
 
     void writePCHWrite(raw_ostream &OS) const override {
@@ -997,7 +996,7 @@
 
     void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "    VersionTuple " << getLowerName()
-         << "= ReadVersionTuple(Record, Idx);\n";
+         << "= Record.readVersionTuple();\n";
     }
 
     void writePCHReadArgs(raw_ostream &OS) const override {
@@ -2127,9 +2126,9 @@
     
     OS << "  case attr::" << R.getName() << ": {\n";
     if (R.isSubClassOf(InhClass))
-      OS << "    bool isInherited = Record[Idx++];\n";
-    OS << "    bool isImplicit = Record[Idx++];\n";
-    OS << "    unsigned Spelling = Record[Idx++];\n";
+      OS << "    bool isInherited = Record.readInt();\n";
+    OS << "    bool isImplicit = Record.readInt();\n";
+    OS << "    unsigned Spelling = Record.readInt();\n";
     ArgRecords = R.getValueAsListOfDefs("Args");
     Args.clear();
     for (const auto *Arg : ArgRecords) {
@@ -3045,7 +3044,11 @@
 
         assert(Matches && "Unsupported spelling variety found");
 
-        Spelling += NormalizeAttrSpelling(RawSpelling);
+        if (Variety == "GNU")
+          Spelling += NormalizeGNUAttrSpelling(RawSpelling);
+        else
+          Spelling += RawSpelling;
+
         if (SemaHandler)
           Matches->push_back(StringMatcher::StringPair(Spelling,
                               "return AttributeList::AT_" + AttrName + ";"));
diff --git a/utils/TableGen/ClangOptionDocEmitter.cpp b/utils/TableGen/ClangOptionDocEmitter.cpp
new file mode 100644
index 0000000..aa7502e
--- /dev/null
+++ b/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -0,0 +1,391 @@
+//===- ClangOptionDocEmitter.cpp - Documentation for command line flags ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+// FIXME: Once this has stabilized, consider moving it to LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/TableGen/Error.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <cctype>
+#include <cstring>
+#include <map>
+
+using namespace llvm;
+
+namespace clang {
+namespace docs {
+namespace {
+struct DocumentedOption {
+  Record *Option;
+  std::vector<Record*> Aliases;
+};
+struct DocumentedGroup;
+struct Documentation {
+  std::vector<DocumentedGroup> Groups;
+  std::vector<DocumentedOption> Options;
+};
+struct DocumentedGroup : Documentation {
+  Record *Group;
+};
+
+// Reorganize the records into a suitable form for emitting documentation.
+Documentation extractDocumentation(RecordKeeper &Records) {
+  Documentation Result;
+
+  // Build the tree of groups. The root in the tree is the fake option group
+  // (Record*)nullptr, which contains all top-level groups and options.
+  std::map<Record*, std::vector<Record*> > OptionsInGroup;
+  std::map<Record*, std::vector<Record*> > GroupsInGroup;
+  std::map<Record*, std::vector<Record*> > Aliases;
+
+  std::map<std::string, Record*> OptionsByName;
+  for (Record *R : Records.getAllDerivedDefinitions("Option"))
+    OptionsByName[R->getValueAsString("Name")] = R;
+
+  auto Flatten = [](Record *R) {
+    return R->getValue("DocFlatten") && R->getValueAsBit("DocFlatten");
+  };
+
+  auto SkipFlattened = [&](Record *R) -> Record* {
+    while (R && Flatten(R)) {
+      auto *G = dyn_cast<DefInit>(R->getValueInit("Group"));
+      if (!G)
+        return nullptr;
+      R = G->getDef();
+    }
+    return R;
+  };
+
+  for (Record *R : Records.getAllDerivedDefinitions("OptionGroup")) {
+    if (Flatten(R))
+      continue;
+
+    Record *Group = nullptr;
+    if (auto *G = dyn_cast<DefInit>(R->getValueInit("Group")))
+      Group = SkipFlattened(G->getDef());
+    GroupsInGroup[Group].push_back(R);
+  }
+
+  for (Record *R : Records.getAllDerivedDefinitions("Option")) {
+    if (auto *A = dyn_cast<DefInit>(R->getValueInit("Alias"))) {
+      Aliases[A->getDef()].push_back(R);
+      continue;
+    }
+
+    // Pretend no-X and Xno-Y options are aliases of X and XY.
+    auto Name = R->getValueAsString("Name");
+    if (Name.size() >= 4) {
+      if (Name.substr(0, 3) == "no-" && OptionsByName[Name.substr(3)]) {
+        Aliases[OptionsByName[Name.substr(3)]].push_back(R);
+        continue;
+      }
+      if (Name.substr(1, 3) == "no-" && OptionsByName[Name[0] + Name.substr(4)]) {
+        Aliases[OptionsByName[Name[0] + Name.substr(4)]].push_back(R);
+        continue;
+      }
+    }
+
+    Record *Group = nullptr;
+    if (auto *G = dyn_cast<DefInit>(R->getValueInit("Group")))
+      Group = SkipFlattened(G->getDef());
+    OptionsInGroup[Group].push_back(R);
+  }
+
+  auto CompareByName = [](Record *A, Record *B) {
+    return A->getValueAsString("Name") < B->getValueAsString("Name");
+  };
+
+  auto CompareByLocation = [](Record *A, Record *B) {
+    return A->getLoc()[0].getPointer() < B->getLoc()[0].getPointer();
+  };
+
+  auto DocumentationForOption = [&](Record *R) -> DocumentedOption {
+    auto &A = Aliases[R];
+    std::sort(A.begin(), A.end(), CompareByName);
+    return {R, std::move(A)};
+  };
+
+  std::function<Documentation(Record *)> DocumentationForGroup =
+      [&](Record *R) -> Documentation {
+    Documentation D;
+
+    auto &Groups = GroupsInGroup[R];
+    std::sort(Groups.begin(), Groups.end(), CompareByLocation);
+    for (Record *G : Groups) {
+      D.Groups.emplace_back();
+      D.Groups.back().Group = G;
+      Documentation &Base = D.Groups.back();
+      Base = DocumentationForGroup(G);
+    }
+
+    auto &Options = OptionsInGroup[R];
+    std::sort(Options.begin(), Options.end(), CompareByName);
+    for (Record *O : Options)
+      D.Options.push_back(DocumentationForOption(O));
+
+    return D;
+  };
+
+  return DocumentationForGroup(nullptr);
+}
+
+// Get the first and successive separators to use for an OptionKind.
+std::pair<StringRef,StringRef> getSeparatorsForKind(const Record *OptionKind) {
+  return StringSwitch<std::pair<StringRef, StringRef>>(OptionKind->getName())
+    .Cases("KIND_JOINED", "KIND_JOINED_OR_SEPARATE",
+           "KIND_JOINED_AND_SEPARATE",
+           "KIND_REMAINING_ARGS_JOINED", {"", " "})
+    .Case("KIND_COMMAJOINED", {"", ","})
+    .Default({" ", " "});
+}
+
+const unsigned UnlimitedArgs = unsigned(-1);
+
+// Get the number of arguments expected for an option, or -1 if any number of
+// arguments are accepted.
+unsigned getNumArgsForKind(Record *OptionKind, const Record *Option) {
+  return StringSwitch<unsigned>(OptionKind->getName())
+    .Cases("KIND_JOINED", "KIND_JOINED_OR_SEPARATE", "KIND_SEPARATE", 1)
+    .Cases("KIND_REMAINING_ARGS", "KIND_REMAINING_ARGS_JOINED",
+           "KIND_COMMAJOINED", UnlimitedArgs)
+    .Case("KIND_JOINED_AND_SEPARATE", 2)
+    .Case("KIND_MULTIARG", Option->getValueAsInt("NumArgs"))
+    .Default(0);
+}
+
+bool hasFlag(const Record *OptionOrGroup, StringRef OptionFlag) {
+  for (const Record *Flag : OptionOrGroup->getValueAsListOfDefs("Flags"))
+    if (Flag->getName() == OptionFlag)
+      return true;
+  return false;
+}
+
+bool isExcluded(const Record *OptionOrGroup, const Record *DocInfo) {
+  // FIXME: Provide a flag to specify the set of exclusions.
+  for (StringRef Exclusion : DocInfo->getValueAsListOfStrings("ExcludedFlags"))
+    if (hasFlag(OptionOrGroup, Exclusion))
+      return true;
+  return false;
+}
+
+std::string escapeRST(StringRef Str) {
+  std::string Out;
+  for (auto K : Str) {
+    if (StringRef("`*|_[]\\").count(K))
+      Out.push_back('\\');
+    Out.push_back(K);
+  }
+  return Out;
+}
+
+StringRef getSphinxOptionID(StringRef OptionName) {
+  for (auto I = OptionName.begin(), E = OptionName.end(); I != E; ++I)
+    if (!isalnum(*I) && *I != '-')
+      return OptionName.substr(0, I - OptionName.begin());
+  return OptionName;
+}
+
+bool canSphinxCopeWithOption(const Record *Option) {
+  // HACK: Work arond sphinx's inability to cope with punctuation-only options
+  // such as /? by suppressing them from the option list.
+  for (char C : Option->getValueAsString("Name"))
+    if (isalnum(C))
+      return true;
+  return false;
+}
+
+void emitHeading(int Depth, std::string Heading, raw_ostream &OS) {
+  assert(Depth < 8 && "groups nested too deeply");
+  OS << Heading << '\n'
+     << std::string(Heading.size(), "=~-_'+<>"[Depth]) << "\n";
+}
+
+/// Get the value of field \p Primary, if possible. If \p Primary does not
+/// exist, get the value of \p Fallback and escape it for rST emission.
+std::string getRSTStringWithTextFallback(const Record *R, StringRef Primary,
+                                         StringRef Fallback) {
+  for (auto Field : {Primary, Fallback}) {
+    if (auto *V = R->getValue(Field)) {
+      StringRef Value;
+      if (auto *SV = dyn_cast_or_null<StringInit>(V->getValue()))
+        Value = SV->getValue();
+      else if (auto *CV = dyn_cast_or_null<CodeInit>(V->getValue()))
+        Value = CV->getValue();
+      if (!Value.empty())
+        return Field == Primary ? Value.str() : escapeRST(Value);
+    }
+  }
+  return StringRef();
+}
+
+void emitOptionWithArgs(StringRef Prefix, const Record *Option,
+                        ArrayRef<std::string> Args, raw_ostream &OS) {
+  OS << Prefix << escapeRST(Option->getValueAsString("Name"));
+
+  std::pair<StringRef, StringRef> Separators =
+      getSeparatorsForKind(Option->getValueAsDef("Kind"));
+
+  StringRef Separator = Separators.first;
+  for (auto Arg : Args) {
+    OS << Separator << escapeRST(Arg);
+    Separator = Separators.second;
+  }
+}
+
+void emitOptionName(StringRef Prefix, const Record *Option, raw_ostream &OS) {
+  // Find the arguments to list after the option.
+  unsigned NumArgs = getNumArgsForKind(Option->getValueAsDef("Kind"), Option);
+
+  std::vector<std::string> Args;
+  if (!Option->isValueUnset("MetaVarName"))
+    Args.push_back(Option->getValueAsString("MetaVarName"));
+  else if (NumArgs == 1)
+    Args.push_back("<arg>");
+
+  while (Args.size() < NumArgs) {
+    Args.push_back(("<arg" + Twine(Args.size() + 1) + ">").str());
+    // Use '--args <arg1> <arg2>...' if any number of args are allowed.
+    if (Args.size() == 2 && NumArgs == UnlimitedArgs) {
+      Args.back() += "...";
+      break;
+    }
+  }
+
+  emitOptionWithArgs(Prefix, Option, Args, OS);
+
+  auto AliasArgs = Option->getValueAsListOfStrings("AliasArgs");
+  if (!AliasArgs.empty()) {
+    Record *Alias = Option->getValueAsDef("Alias");
+    OS << " (equivalent to ";
+    emitOptionWithArgs(Alias->getValueAsListOfStrings("Prefixes").front(),
+                       Alias, Option->getValueAsListOfStrings("AliasArgs"), OS);
+    OS << ")";
+  }
+}
+
+bool emitOptionNames(const Record *Option, raw_ostream &OS, bool EmittedAny) {
+  for (auto &Prefix : Option->getValueAsListOfStrings("Prefixes")) {
+    if (EmittedAny)
+      OS << ", ";
+    emitOptionName(Prefix, Option, OS);
+    EmittedAny = true;
+  }
+  return EmittedAny;
+}
+
+template <typename Fn>
+void forEachOptionName(const DocumentedOption &Option, const Record *DocInfo,
+                       Fn F) {
+  F(Option.Option);
+
+  for (auto *Alias : Option.Aliases)
+    if (!isExcluded(Alias, DocInfo) && canSphinxCopeWithOption(Option.Option))
+      F(Alias);
+}
+
+void emitOption(const DocumentedOption &Option, const Record *DocInfo,
+                raw_ostream &OS) {
+  if (isExcluded(Option.Option, DocInfo))
+    return;
+  if (Option.Option->getValueAsDef("Kind")->getName() == "KIND_UNKNOWN" ||
+      Option.Option->getValueAsDef("Kind")->getName() == "KIND_INPUT")
+    return;
+  if (!canSphinxCopeWithOption(Option.Option))
+    return;
+
+  // HACK: Emit a different program name with each option to work around
+  // sphinx's inability to cope with options that differ only by punctuation
+  // (eg -ObjC vs -ObjC++, -G vs -G=).
+  std::vector<std::string> SphinxOptionIDs;
+  forEachOptionName(Option, DocInfo, [&](const Record *Option) {
+    for (auto &Prefix : Option->getValueAsListOfStrings("Prefixes"))
+      SphinxOptionIDs.push_back(
+          getSphinxOptionID(Prefix + Option->getValueAsString("Name")));
+  });
+  assert(!SphinxOptionIDs.empty() && "no flags for option");
+  static std::map<std::string, int> NextSuffix;
+  int SphinxWorkaroundSuffix = NextSuffix[*std::max_element(
+      SphinxOptionIDs.begin(), SphinxOptionIDs.end(),
+      [&](const std::string &A, const std::string &B) {
+        return NextSuffix[A] < NextSuffix[B];
+      })];
+  for (auto &S : SphinxOptionIDs)
+    NextSuffix[S] = SphinxWorkaroundSuffix + 1;
+  if (SphinxWorkaroundSuffix)
+    OS << ".. program:: " << DocInfo->getValueAsString("Program")
+       << SphinxWorkaroundSuffix << "\n";
+
+  // Emit the names of the option.
+  OS << ".. option:: ";
+  bool EmittedAny = false;
+  forEachOptionName(Option, DocInfo, [&](const Record *Option) {
+    EmittedAny = emitOptionNames(Option, OS, EmittedAny);
+  });
+  if (SphinxWorkaroundSuffix)
+    OS << "\n.. program:: " << DocInfo->getValueAsString("Program");
+  OS << "\n\n";
+
+  // Emit the description, if we have one.
+  std::string Description =
+      getRSTStringWithTextFallback(Option.Option, "DocBrief", "HelpText");
+  if (!Description.empty())
+    OS << Description << "\n\n";
+}
+
+void emitDocumentation(int Depth, const Documentation &Doc,
+                       const Record *DocInfo, raw_ostream &OS);
+
+void emitGroup(int Depth, const DocumentedGroup &Group, const Record *DocInfo,
+               raw_ostream &OS) {
+  if (isExcluded(Group.Group, DocInfo))
+    return;
+
+  emitHeading(Depth,
+              getRSTStringWithTextFallback(Group.Group, "DocName", "Name"), OS);
+
+  // Emit the description, if we have one.
+  std::string Description =
+      getRSTStringWithTextFallback(Group.Group, "DocBrief", "HelpText");
+  if (!Description.empty())
+    OS << Description << "\n\n";
+
+  // Emit contained options and groups.
+  emitDocumentation(Depth + 1, Group, DocInfo, OS);
+}
+
+void emitDocumentation(int Depth, const Documentation &Doc,
+                       const Record *DocInfo, raw_ostream &OS) {
+  for (auto &O : Doc.Options)
+    emitOption(O, DocInfo, OS);
+  for (auto &G : Doc.Groups)
+    emitGroup(Depth, G, DocInfo, OS);
+}
+
+}  // namespace
+}  // namespace docs
+
+void EmitClangOptDocs(RecordKeeper &Records, raw_ostream &OS) {
+  using namespace docs;
+
+  const Record *DocInfo = Records.getDef("GlobalDocumentation");
+  if (!DocInfo) {
+    PrintFatalError("The GlobalDocumentation top-level definition is missing, "
+                    "no documentation will be generated.");
+    return;
+  }
+  OS << DocInfo->getValueAsString("Intro") << "\n";
+  OS << ".. program:: " << DocInfo->getValueAsString("Program") << "\n";
+
+  emitDocumentation(0, extractDocumentation(Records), DocInfo, OS);
+}
+} // end namespace clang
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 6fb5b00..fd7999b 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -53,7 +53,8 @@
   GenArmNeonSema,
   GenArmNeonTest,
   GenAttrDocs,
-  GenDiagDocs
+  GenDiagDocs,
+  GenOptDocs
 };
 
 namespace {
@@ -135,7 +136,9 @@
         clEnumValN(GenAttrDocs, "gen-attr-docs",
                    "Generate attribute documentation"),
         clEnumValN(GenDiagDocs, "gen-diag-docs",
-                   "Generate attribute documentation")));
+                   "Generate diagnostic documentation"),
+        clEnumValN(GenOptDocs, "gen-opt-docs",
+                   "Generate option documentation")));
 
 cl::opt<std::string>
 ClangComponent("clang-component",
@@ -238,6 +241,9 @@
   case GenDiagDocs:
     EmitClangDiagDocs(Records, OS);
     break;
+  case GenOptDocs:
+    EmitClangOptDocs(Records, OS);
+    break;
   }
 
   return false;
diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h
index 0305ed1..033cb78 100644
--- a/utils/TableGen/TableGenBackends.h
+++ b/utils/TableGen/TableGenBackends.h
@@ -70,6 +70,7 @@
 
 void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangOptDocs(RecordKeeper &Records, raw_ostream &OS);
 
 } // end namespace clang
 
diff --git a/utils/perf-training/CMakeLists.txt b/utils/perf-training/CMakeLists.txt
index 07d9024..c046a1d 100644
--- a/utils/perf-training/CMakeLists.txt
+++ b/utils/perf-training/CMakeLists.txt
@@ -40,7 +40,7 @@
 endif()
 
 find_program(DTRACE dtrace)
-if(DTRACE)
+if(APPLE AND DTRACE)
   configure_lit_site_cfg(
     ${CMAKE_CURRENT_SOURCE_DIR}/order-files.lit.site.cfg.in
     ${CMAKE_CURRENT_BINARY_DIR}/order-files/lit.site.cfg
@@ -56,6 +56,10 @@
     COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} dtrace
     COMMENT "Clearing old dtrace data")
 
+  if(NOT CLANG_ORDER_FILE)
+    message(FATAL_ERROR "Output clang order file is not set")
+  endif()
+
   add_custom_target(generate-order-file
     COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py gen-order-file --binary $<TARGET_FILE:clang> --output ${CLANG_ORDER_FILE} ${CMAKE_CURRENT_BINARY_DIR}
     COMMENT "Generating order file"
diff --git a/utils/perf-training/lit.cfg b/utils/perf-training/lit.cfg
index 85d3551..edae551 100644
--- a/utils/perf-training/lit.cfg
+++ b/utils/perf-training/lit.cfg
@@ -31,7 +31,7 @@
 use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
 config.test_format = lit.formats.ShTest(use_lit_shell == "0")
 config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags)))
-config.substitutions.append( ('%clang_cpp', ' %s --driver-mode=cpp %s ' % (config.clang, sysroot_flags)))
+config.substitutions.append( ('%clang_cpp', ' %s --driver-mode=g++ %s ' % (config.clang, sysroot_flags)))
 config.substitutions.append( ('%clang_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags)))
 config.substitutions.append( ('%clang', ' %s %s ' % (config.clang, sysroot_flags) ) )
 config.substitutions.append( ('%test_root', config.test_exec_root ) )
diff --git a/utils/perf-training/order-files.lit.cfg b/utils/perf-training/order-files.lit.cfg
index e38d264..a4fd812 100644
--- a/utils/perf-training/order-files.lit.cfg
+++ b/utils/perf-training/order-files.lit.cfg
@@ -37,10 +37,9 @@
 
 use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
 config.test_format = lit.formats.ShTest(use_lit_shell == "0")
-config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s --driver-mode=cpp %s ' % (dtrace_wrapper_cc1, config.clang, sysroot_flags)))
-config.substitutions.append( ('%clang_cpp', ' %s %s --driver-mode=cpp %s ' % (dtrace_wrapper, config.clang, sysroot_flags)))
+config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s --driver-mode=g++ %s ' % (dtrace_wrapper_cc1, config.clang, sysroot_flags)))
+config.substitutions.append( ('%clang_cpp', ' %s %s --driver-mode=g++ %s ' % (dtrace_wrapper, config.clang, sysroot_flags)))
 config.substitutions.append( ('%clang_skip_driver', ' %s %s %s ' % (dtrace_wrapper_cc1, config.clang, sysroot_flags)))
 config.substitutions.append( ('%clang', ' %s %s %s ' % (dtrace_wrapper, config.clang, sysroot_flags) ) )
 config.substitutions.append( ('%test_root', config.test_exec_root ) )
 
-
diff --git a/www/analyzer/alpha_checks.html b/www/analyzer/alpha_checks.html
index 0312d16..ce9392b 100644
--- a/www/analyzer/alpha_checks.html
+++ b/www/analyzer/alpha_checks.html
@@ -910,6 +910,30 @@
 }
 </pre></div></div></td></tr>
 
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.cstring.BlockInCriticalSection</span><span class="lang">
+(C)</span><div class="descr">
+Check for calls to blocking functions inside a critical section; applies
+to:<div class=functions>
+lock, unlock<br>
+sleep<br>
+getc<br>
+fgets<br>
+read<br>
+recv<br>
+pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock<br>
+mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock<br>
+</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void testBlockInCriticalSection() {
+  std::mutex m;
+  m.lock();
+  sleep(3); // warn
+  m.unlock();
+}
+</pre></div></div></td></tr>
 </tbody></table>
 
 </div> <!-- page -->
diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html
index 98c560d..87a3620 100644
--- a/www/cxx_dr_status.html
+++ b/www/cxx_dr_status.html
@@ -207,7 +207,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#28">28</a></td>
     <td>CD1</td>
     <td>'exit', 'signal' and static object destruction</td>
-    <td class="na" align="center">N/A</td>
+    <td class="na" align="center">N/A (Library DR)</td>
   </tr>
   <tr id="29">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#29">29</a></td>
@@ -589,9 +589,9 @@
   </tr>
   <tr id="92">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#92">92</a></td>
-    <td>accepted</td>
+    <td>WP</td>
     <td>Should <I>exception-specification</I>s be part of the type system?</td>
-    <td class="svn" align="center">SVN (C++17 onwards)</td>
+    <td class="svn" align="center">Clang 4 (C++17 onwards)</td>
   </tr>
   <tr id="93">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#93">93</a></td>
@@ -663,7 +663,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#104">104</a></td>
     <td>NAD</td>
     <td>Destroying the exception temp when no handler is found</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A (Library DR)</td>
   </tr>
   <tr id="105">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#105">105</a></td>
@@ -747,7 +747,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#118">118</a></td>
     <td>CD1</td>
     <td>Calls via pointers to virtual member functions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="119">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#119">119</a></td>
@@ -921,7 +921,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#147">147</a></td>
     <td>TC1</td>
     <td>Naming the constructor</td>
-    <td class="none" align="center">No</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="148">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#148">148</a></td>
@@ -987,7 +987,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#158">158</a></td>
     <td>CD1</td>
     <td>Aliasing and qualification conversions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="159">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#159">159</a></td>
@@ -1309,8 +1309,8 @@
     <td class="full" align="center">Yes</td>
   </tr>
   <tr id="212">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#212">212</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#212">212</a></td>
+    <td>DR</td>
     <td>Implicit instantiation is not described clearly enough</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -1465,8 +1465,8 @@
     <td class="full" align="center">Duplicate of <a href="#470">470</a></td>
   </tr>
   <tr id="238">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#238">238</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#238">238</a></td>
+    <td>DR</td>
     <td>Precision and accuracy constraints on floating point</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -1489,8 +1489,8 @@
     <td class="full" align="center">Yes</td>
   </tr>
   <tr id="242">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#242">242</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#242">242</a></td>
+    <td>DR</td>
     <td>Interpretation of old-style casts</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -1594,7 +1594,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#259">259</a></td>
     <td>CD1</td>
     <td>Restrictions on explicit specialization and instantiation</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr class="open" id="260">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#260">260</a></td>
@@ -1923,7 +1923,7 @@
   </tr>
   <tr class="open" id="314">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#314">314</a></td>
-    <td>review</td>
+    <td>drafting</td>
     <td><TT>template</TT> in base class specifier</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -1937,7 +1937,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#316">316</a></td>
     <td>NAD</td>
     <td>Injected-class-name of template used as template template parameter</td>
-    <td class="none" align="center">Superseded by <a href="#1004">1004</a></td>
+    <td class="svn" align="center">Superseded by <a href="#1004">1004</a></td>
   </tr>
   <tr id="317">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#317">317</a></td>
@@ -1949,7 +1949,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#318">318</a></td>
     <td>CD1</td>
     <td><TT>struct A::A</TT> should not name the constructor of <TT>A</TT></td>
-    <td class="none" align="center">Superseded by <a href="#1310">1310</a></td>
+    <td class="svn" align="center">Superseded by <a href="#1310">1310</a></td>
   </tr>
   <tr id="319">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#319">319</a></td>
@@ -2097,7 +2097,7 @@
   </tr>
   <tr class="open" id="343">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#343">343</a></td>
-    <td>review</td>
+    <td>drafting</td>
     <td>Make <TT>template</TT> optional in contexts that require a type</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -2595,7 +2595,7 @@
   </tr>
   <tr class="open" id="426">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#426">426</a></td>
-    <td>drafting</td>
+    <td>review</td>
     <td>Identically-named variables, one internally and one externally linked, allowed?</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -3541,7 +3541,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#583">583</a></td>
     <td>CD3</td>
     <td>Relational pointer comparisons against the null pointer constant</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr id="584">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#584">584</a></td>
@@ -3739,7 +3739,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#616">616</a></td>
     <td>CD3</td>
     <td>Definition of &#8220;indeterminate value&#8221;</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr class="open" id="617">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#617">617</a></td>
@@ -4195,7 +4195,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#692">692</a></td>
     <td>C++11</td>
     <td>Partial ordering of variadic class template partial specializations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
   <tr id="693">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#693">693</a></td>
@@ -5839,7 +5839,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1004">1004</a></td>
     <td>C++11</td>
     <td>Injected-class-names as arguments for template template parameters</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr id="1005">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1005">1005</a></td>
@@ -6507,11 +6507,11 @@
     <td>C-compatible alignment specification</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="1116">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1116">1116</a></td>
-    <td>drafting</td>
+  <tr id="1116">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1116">1116</a></td>
+    <td>DRWP</td>
     <td>Aliasing of union members</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1117">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1117">1117</a></td>
@@ -7093,7 +7093,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1213">1213</a></td>
     <td>CD3</td>
     <td>Array subscripting and xvalues</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr id="1214">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1214">1214</a></td>
@@ -7405,7 +7405,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1265">1265</a></td>
     <td>CD3</td>
     <td>Mixed use of the <TT>auto</TT> specifier</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr class="open" id="1266">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1266">1266</a></td>
@@ -7457,7 +7457,7 @@
   </tr>
   <tr id="1274">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1274">1274</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Common nonterminal for <I>expression</I> and <I>braced-init-list</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -7516,8 +7516,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="1284">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1284">1284</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1284">1284</a></td>
+    <td>DR</td>
     <td>Should the lifetime of an array be independent of that of its elements?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -7585,7 +7585,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1295">1295</a></td>
     <td>CD3</td>
     <td>Binding a reference to an rvalue bit-field</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr id="1296">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1296">1296</a></td>
@@ -7675,7 +7675,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1310">1310</a></td>
     <td>CD3</td>
     <td>What is an &#8220;acceptable lookup result?&#8221;</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr id="1311">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1311">1311</a></td>
@@ -7702,10 +7702,10 @@
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1315">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1315">1315</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1315">1315</a></td>
+    <td>DR</td>
     <td>Restrictions on non-type template arguments in partial specializations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="partial" align="center">Partial</td>
   </tr>
   <tr id="1316">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1316">1316</a></td>
@@ -7795,7 +7795,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1330">1330</a></td>
     <td>CD3</td>
     <td>Delayed instantiation of <TT>noexcept</TT> specifiers</td>
-    <td class="svn" align="center">SVN (C++11 onwards)</td>
+    <td class="svn" align="center">Clang 4 (C++11 onwards)</td>
   </tr>
   <tr class="open" id="1331">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1331">1331</a></td>
@@ -7869,11 +7869,11 @@
     <td>Order of initialization with multiple declarators</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="1343">
+  <tr id="1343">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1343">1343</a></td>
-    <td>drafting</td>
+    <td>tentatively ready</td>
     <td>Sequencing of non-class initialization</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1344">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1344">1344</a></td>
@@ -7897,7 +7897,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1347">1347</a></td>
     <td>CD3</td>
     <td>Consistency of <TT>auto</TT> in multiple-declarator declarations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr class="open" id="1348">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1348">1348</a></td>
@@ -8143,7 +8143,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1388">1388</a></td>
     <td>CD3</td>
     <td>Missing non-deduced context following a function parameter pack</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr id="1389">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1389">1389</a></td>
@@ -8159,9 +8159,9 @@
   </tr>
   <tr id="1391">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1391">1391</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Conversions to parameter types with non-deduced template arguments</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="partial" align="center">Partial</td>
   </tr>
   <tr id="1392">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1392">1392</a></td>
@@ -8181,11 +8181,11 @@
     <td>Incomplete types as parameters of deleted functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="1395">
+  <tr id="1395">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1395">1395</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Partial ordering of variadic templates reconsidered</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="1396">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1396">1396</a></td>
@@ -8209,7 +8209,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1399">1399</a></td>
     <td>CD3</td>
     <td>Deduction with multiple function parameter packs</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">Duplicate of <a href="#1388">1388</a></td>
   </tr>
   <tr id="1400">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1400">1400</a></td>
@@ -8785,11 +8785,11 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1495">1495</a></td>
     <td>CD3</td>
     <td>Partial specialization of variadic class template</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr id="1496">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1496">1496</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1496">1496</a></td>
+    <td>DR</td>
     <td>Triviality with deleted and missing default constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -8887,7 +8887,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1512">1512</a></td>
     <td>CD3</td>
     <td>Pointer comparison vs qualification conversions</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr class="open" id="1513">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1513">1513</a></td>
@@ -8919,11 +8919,11 @@
     <td>Unclear/missing description of behavior during construction/destruction</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="1518">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1518">1518</a></td>
-    <td>review</td>
+  <tr id="1518">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1518">1518</a></td>
+    <td>DRWP</td>
     <td>Explicit default constructors and copy-list-initialization</td>
-    <td align="center">Not resolved</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr id="1519">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1519">1519</a></td>
@@ -9137,7 +9137,7 @@
   </tr>
   <tr class="open" id="1554">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554">1554</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Access and alias templates</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -9481,7 +9481,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1611">1611</a></td>
     <td>C++14</td>
     <td>Deleted default constructor for abstract class</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">Duplicate of <a href="#1658">1658</a></td>
   </tr>
   <tr id="1612">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1612">1612</a></td>
@@ -9640,10 +9640,10 @@
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1638">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1638">1638</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1638">1638</a></td>
+    <td>DR</td>
     <td>Declaring an explicit specialization of a scoped enumeration</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="1639">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1639">1639</a></td>
@@ -9683,7 +9683,7 @@
   </tr>
   <tr id="1645">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1645">1645</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Identical inheriting constructors via default arguments</td>
     <td class="full" align="center">Clang 3.9</td>
   </tr>
@@ -9731,9 +9731,9 @@
   </tr>
   <tr id="1653">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1653">1653</a></td>
-    <td>accepted</td>
+    <td>WP</td>
     <td>Removing deprecated increment of <TT>bool</TT></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">Clang 4 (C++17 onwards)</td>
   </tr>
   <tr id="1654">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1654">1654</a></td>
@@ -9763,7 +9763,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1658">1658</a></td>
     <td>C++14</td>
     <td>Deleted default constructor for abstract class via destructor</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr class="open" id="1659">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1659">1659</a></td>
@@ -10103,7 +10103,7 @@
   </tr>
   <tr id="1715">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1715">1715</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Access and inherited constructor templates</td>
     <td class="full" align="center">Clang 3.9</td>
   </tr>
@@ -10145,7 +10145,7 @@
   </tr>
   <tr id="1722">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1722">1722</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Should lambda to function pointer conversion function be <TT>noexcept</TT>?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -10216,8 +10216,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="1734">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1734">1734</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1734">1734</a></td>
+    <td>DR</td>
     <td>Nontrivial deleted copy functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -10229,7 +10229,7 @@
   </tr>
   <tr id="1736">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1736">1736</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Inheriting constructor templates in a local class</td>
     <td class="full" align="center">Clang 3.9</td>
   </tr>
@@ -10467,11 +10467,11 @@
     <td>Undefined behavior of line splice in raw string literal</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="1776">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1776">1776</a></td>
-    <td>drafting</td>
+  <tr id="1776">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1776">1776</a></td>
+    <td>DRWP</td>
     <td>Replacement of class objects containing reference members</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1777">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1777">1777</a></td>
@@ -10577,7 +10577,7 @@
   </tr>
   <tr class="open" id="1794">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1794">1794</a></td>
-    <td>review</td>
+    <td>drafting</td>
     <td><TT>template</TT> keyword and alias templates</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -10661,7 +10661,7 @@
   </tr>
   <tr class="open" id="1808">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1808">1808</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Constructor templates vs default constructors</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -10685,7 +10685,7 @@
   </tr>
   <tr class="open" id="1812">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1812">1812</a></td>
-    <td>review</td>
+    <td>drafting</td>
     <td>Omission of <TT>template</TT> in a <I>typename-specifier</I></td>
     <td align="center">Not resolved</td>
   </tr>
@@ -10761,11 +10761,11 @@
     <td>Completeness of return type vs point of instantiation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="1825">
+  <tr id="1825">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1825">1825</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Partial ordering between variadic and non-variadic function templates</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1826">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1826">1826</a></td>
@@ -10895,7 +10895,7 @@
   </tr>
   <tr id="1847">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1847">1847</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Clarifying compatibility during partial ordering</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -10973,15 +10973,15 @@
   </tr>
   <tr class="open" id="1860">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1860">1860</a></td>
-    <td>drafting</td>
+    <td>review</td>
     <td>What is a &#8220;direct member?&#8221;</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="1861">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1861">1861</a></td>
-    <td>drafting</td>
+  <tr id="1861">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1861">1861</a></td>
+    <td>DRWP</td>
     <td>Values of a bit-field</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="1862">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1862">1862</a></td>
@@ -10991,7 +10991,7 @@
   </tr>
   <tr id="1863">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1863">1863</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Requirements on thrown object type to support <TT>std::current_exception()</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11044,8 +11044,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="1872">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1872">1872</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1872">1872</a></td>
+    <td>DR</td>
     <td>Instantiations of <TT>constexpr</TT> templates that cannot appear in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11161,7 +11161,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1891">1891</a></td>
     <td>DRWP</td>
     <td>Move constructor/assignment for closure class</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="svn" align="center">Clang 4</td>
   </tr>
   <tr id="1892">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1892">1892</a></td>
@@ -11182,8 +11182,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="1895">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1895">1895</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1895">1895</a></td>
+    <td>DR</td>
     <td>Deleted conversions in conditional operator operands</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11231,7 +11231,7 @@
   </tr>
   <tr id="1903">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1903">1903</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>What declarations are introduced by a non-member <I>using-declaration</I>?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11255,7 +11255,7 @@
   </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>drafting</td>
     <td><I>using-declaration</I>s and default arguments</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -11392,8 +11392,8 @@
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1930">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1930">1930</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1930">1930</a></td>
+    <td>DR</td>
     <td><I>init-declarator-list</I> vs <I>member-declarator-list</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11404,8 +11404,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="1932">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1932">1932</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1932">1932</a></td>
+    <td>DR</td>
     <td>Bit-field results of conditional operators</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11459,7 +11459,7 @@
   </tr>
   <tr id="1941">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1941">1941</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>SFINAE and inherited constructor default arguments</td>
     <td class="full" align="center">Clang 3.9</td>
   </tr>
@@ -11489,7 +11489,7 @@
   </tr>
   <tr id="1946">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1946">1946</a></td>
-    <td>accepted</td>
+    <td>WP</td>
     <td><I>exception-specification</I>s vs pointer dereference</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11507,7 +11507,7 @@
   </tr>
   <tr id="1949">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1949">1949</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>&#8220;sequenced after&#8221; instead of &#8220;sequenced before&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11542,8 +11542,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="1955">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1955">1955</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1955">1955</a></td>
+    <td>DR</td>
     <td><TT>#elif</TT> with invalid controlling expression</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11567,7 +11567,7 @@
   </tr>
   <tr id="1959">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1959">1959</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Inadvertently inherited copy constructor</td>
     <td class="full" align="center">Clang 3.9</td>
   </tr>
@@ -11577,11 +11577,11 @@
     <td>Visibility of entity named in class-scope <I>using-declaration</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="1961">
+  <tr id="1961">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1961">1961</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Potentially-concurrent actions within a signal handler</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="1962">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1962">1962</a></td>
@@ -11663,7 +11663,7 @@
   </tr>
   <tr id="1975">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1975">1975</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Permissible declarations for <I>exception-specification</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11699,7 +11699,7 @@
   </tr>
   <tr id="1981">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1981">1981</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Implicit contextual conversions and <TT>explicit</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11753,25 +11753,25 @@
   </tr>
   <tr id="1990">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1990">1990</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Ambiguity due to optional <I>decl-specifier-seq</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1991">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1991">1991</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Inheriting constructors vs default arguments</td>
     <td class="full" align="center">Clang 3.9</td>
   </tr>
   <tr id="1992">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1992">1992</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1992">1992</a></td>
+    <td>DR</td>
     <td><TT>new (std::nothrow) int[N]</TT> can throw</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="1993">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1993">1993</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Use of <TT>template&lt;&gt;</TT> defining member of explicit specialization</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -11783,7 +11783,7 @@
   </tr>
   <tr id="1995">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1995">1995</a></td>
-    <td>accepted</td>
+    <td>WP</td>
     <td><I>exception-specification</I>s and non-type template parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11813,13 +11813,13 @@
   </tr>
   <tr id="2000">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2000">2000</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td><I>header-name</I> outside <TT>#include</TT> directive</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2001">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2001">2001</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2001">2001</a></td>
+    <td>DR</td>
     <td><I>non-directive</I> is underspecified</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11837,7 +11837,7 @@
   </tr>
   <tr id="2004">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2004">2004</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Unions with mutable members in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11849,7 +11849,7 @@
   </tr>
   <tr id="2006">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2006">2006</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Cv-qualified <TT>void</TT> types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11860,8 +11860,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2008">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2008">2008</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2008">2008</a></td>
+    <td>DR</td>
     <td>Default <I>template-argument</I>s underspecified</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11873,19 +11873,19 @@
   </tr>
   <tr id="2010">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2010">2010</a></td>
-    <td>accepted</td>
+    <td>WP</td>
     <td><I>exception-specification</I>s and conversion operators</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2011">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2011">2011</a></td>
-    <td>review</td>
+    <td>drafting</td>
     <td>Unclear effect of reference capture of reference</td>
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2012">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2012">2012</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2012">2012</a></td>
+    <td>DR</td>
     <td>Lifetime of references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11903,19 +11903,19 @@
   </tr>
   <tr id="2015">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2015">2015</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>odr-use of deleted virtual functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2016">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2016">2016</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Confusing wording in description of conversion function</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2017">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2017">2017</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2017">2017</a></td>
+    <td>DR</td>
     <td>Flowing off end is not equivalent to no-expression return</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11927,7 +11927,7 @@
   </tr>
   <tr id="2019">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2019">2019</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Member references omitted from description of storage duration</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11943,11 +11943,11 @@
     <td>Function template redeclaration via alias template</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2022">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2022">2022</a></td>
-    <td>drafting</td>
+  <tr id="2022">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2022">2022</a></td>
+    <td>DRWP</td>
     <td>Copy elision in constant expressions</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2023">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2023">2023</a></td>
@@ -11957,7 +11957,7 @@
   </tr>
   <tr id="2024">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2024">2024</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Dependent types and unexpanded parameter packs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11969,13 +11969,13 @@
   </tr>
   <tr id="2026">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2026">2026</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Zero-initialization and <TT>constexpr</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2027">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2027">2027</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Unclear requirements for multiple <TT>alignas</TT> specifiers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -11999,19 +11999,19 @@
   </tr>
   <tr id="2031">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2031">2031</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Missing incompatibility for <TT>&amp;&amp;</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2032">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2032">2032</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2032">2032</a></td>
+    <td>DR</td>
     <td>Default <I>template-argument</I>s of variable templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2033">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2033">2033</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2033">2033</a></td>
+    <td>DR</td>
     <td>Redundant restriction on partial specialization argument</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12021,11 +12021,11 @@
     <td>Deprecating <TT>uncaught_exception()</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2035">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2035">2035</a></td>
-    <td>review</td>
+  <tr id="2035">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2035">2035</a></td>
+    <td>CD3</td>
     <td>Multi-section example is confusing</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2036">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2036">2036</a></td>
@@ -12040,32 +12040,32 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2038">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2038">2038</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2038">2038</a></td>
+    <td>DR</td>
     <td>Document C++14 incompatibility of new braced deduction rule</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2039">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2039">2039</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2039">2039</a></td>
+    <td>DR</td>
     <td>Constant conversions to <TT>bool</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2040">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2040">2040</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2040">2040</a></td>
+    <td>DR</td>
     <td><I>trailing-return-type</I> no longer ambiguous</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2041">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2041">2041</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2041">2041</a></td>
+    <td>DR</td>
     <td>Namespace for explicit class template specialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2042">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2042">2042</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Exceptions and deallocation functions</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12076,8 +12076,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2044">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2044">2044</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2044">2044</a></td>
+    <td>DR</td>
     <td><TT>decltype(auto)</TT> and <TT>void</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12094,8 +12094,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2047">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2047">2047</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2047">2047</a></td>
+    <td>DR</td>
     <td>Coordinating &#8220;throws anything&#8221; specifications</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12125,7 +12125,7 @@
   </tr>
   <tr id="2052">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2052">2052</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Template argument deduction vs overloaded operators</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12143,7 +12143,7 @@
   </tr>
   <tr class="open" id="2055">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2055">2055</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Explicitly-specified non-deduced parameter packs</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12155,7 +12155,7 @@
   </tr>
   <tr class="open" id="2057">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2057">2057</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Template template arguments with default arguments</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12167,7 +12167,7 @@
   </tr>
   <tr class="open" id="2059">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2059">2059</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Linkage and deduced return types</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12178,8 +12178,8 @@
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2061">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2061">2061</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2061">2061</a></td>
+    <td>DR</td>
     <td>Inline namespace after simplifications</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12190,14 +12190,14 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2063">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2063">2063</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2063">2063</a></td>
+    <td>DR</td>
     <td>Type/nontype hiding in class scope</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2064">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2064">2064</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2064">2064</a></td>
+    <td>DR</td>
     <td>Conflicting specifications for dependent <I>decltype-specifier</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12208,8 +12208,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2066">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2066">2066</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2066">2066</a></td>
+    <td>DR</td>
     <td>Does type-dependent imply value-dependent?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12220,14 +12220,14 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2068">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2068">2068</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2068">2068</a></td>
+    <td>DR</td>
     <td>When can/must a defaulted virtual destructor be defined?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2069">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2069">2069</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2069">2069</a></td>
+    <td>DR</td>
     <td>Do destructors have names?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12238,8 +12238,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2071">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2071">2071</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2071">2071</a></td>
+    <td>DR</td>
     <td><TT>typedef</TT> with no declarator</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12251,7 +12251,7 @@
   </tr>
   <tr class="open" id="2073">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2073">2073</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Allocating memory for exception objects</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12263,19 +12263,19 @@
   </tr>
   <tr id="2075">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2075">2075</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Passing short initializer lists to array reference parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2076">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2076">2076</a></td>
-    <td>open</td>
+  <tr id="2076">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2076">2076</a></td>
+    <td>DRWP</td>
     <td>List-initialization of arguments for constructor parameters</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2077">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2077">2077</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Overload resolution and invalid rvalue-reference initialization</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12286,8 +12286,8 @@
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2079">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2079">2079</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2079">2079</a></td>
+    <td>DR</td>
     <td><TT>[[</TT> appearing in a <I>balanced-token-seq</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12304,26 +12304,26 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2082">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2082">2082</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2082">2082</a></td>
+    <td>DR</td>
     <td>Referring to parameters in unevaluated operands of default arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2083">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2083">2083</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Incorrect cases of odr-use</td>
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2084">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2084">2084</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2084">2084</a></td>
+    <td>DR</td>
     <td>NSDMIs and deleted union default constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2085">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2085">2085</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2085">2085</a></td>
+    <td>DR</td>
     <td>Invalid example of adding special member function via default argument</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12341,7 +12341,7 @@
   </tr>
   <tr class="open" id="2088">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2088">2088</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Late tiebreakers in partial ordering</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12357,39 +12357,39 @@
     <td>Dependency via non-dependent base class</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2091">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2091">2091</a></td>
-    <td>open</td>
+  <tr id="2091">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2091">2091</a></td>
+    <td>DRWP</td>
     <td>Deducing reference non-type template arguments</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2092">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2092">2092</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Deduction failure and overload resolution</td>
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2093">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2093">2093</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2093">2093</a></td>
+    <td>DR</td>
     <td>Qualification conversion for pointer-to-member handler matching</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2094">
+  <tr id="2094">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2094">2094</a></td>
-    <td>open</td>
+    <td>tentatively ready</td>
     <td>Trivial copy/move constructor for class with volatile member</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2095">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2095">2095</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2095">2095</a></td>
+    <td>DR</td>
     <td>Capturing rvalue references to functions by copy</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2096">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2096">2096</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2096">2096</a></td>
+    <td>DR</td>
     <td>Constraints on literal unions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12400,26 +12400,26 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2098">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2098">2098</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2098">2098</a></td>
+    <td>DR</td>
     <td>Is <TT>uncaught_exceptions()</TT> per-thread?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2099">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2099">2099</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2099">2099</a></td>
+    <td>DR</td>
     <td>Inferring the bound of an array static data member</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2100">
+  <tr id="2100">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2100">2100</a></td>
-    <td>open</td>
+    <td>tentatively ready</td>
     <td>Value-dependent address of static data member of class template</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2101">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2101">2101</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Incorrect description of type- and value-dependence</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12436,8 +12436,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2104">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2104">2104</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2104">2104</a></td>
+    <td>DR</td>
     <td>Internal-linkage <TT>constexpr</TT> references and ODR requirements</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12448,26 +12448,26 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2106">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2106">2106</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2106">2106</a></td>
+    <td>DR</td>
     <td>Unclear restrictions on use of function-type template arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2107">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2107">2107</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2107">2107</a></td>
+    <td>DR</td>
     <td>Lifetime of temporaries for default arguments in array copying</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2108">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2108">2108</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Conversions to non-class prvalues in reference initialization</td>
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2109">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2109">2109</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2109">2109</a></td>
+    <td>DR</td>
     <td>Value dependence underspecified</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12478,8 +12478,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr class="open" id="2111">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2111">2111</a></td>
-    <td>open</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2111">2111</a></td>
+    <td>extension</td>
     <td>Array temporaries in reference binding</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12490,20 +12490,20 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2113">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2113">2113</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2113">2113</a></td>
+    <td>DR</td>
     <td>Incompete specification of types for declarators</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2114">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2114">2114</a></td>
-    <td>review</td>
+  <tr id="2114">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2114">2114</a></td>
+    <td>CD3</td>
     <td>Missing description of incompatibility from aggregate NSDMIs</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2115">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2115">2115</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Order of implicit destruction vs release of automatic storage</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12533,7 +12533,7 @@
   </tr>
   <tr id="2120">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2120">2120</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Array as first non-static data member in standard-layout class</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12544,8 +12544,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2122">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2122">2122</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2122">2122</a></td>
+    <td>DR</td>
     <td>Glvalues of <TT>void</TT> type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12556,8 +12556,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2124">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2124">2124</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2124">2124</a></td>
+    <td>DR</td>
     <td>Signature of constructor template</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12586,14 +12586,14 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2129">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2129">2129</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2129">2129</a></td>
+    <td>DR</td>
     <td>Non-object prvalues and constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2130">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2130">2130</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2130">2130</a></td>
+    <td>DR</td>
     <td>Over-aligned types in <I>new-expression</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12633,17 +12633,17 @@
     <td>Argument-dependent lookup and initializer lists</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2137">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2137">2137</a></td>
-    <td>drafting</td>
+  <tr id="2137">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2137">2137</a></td>
+    <td>DRWP</td>
     <td>List-initialization from object of same type</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2138">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2138">2138</a></td>
-    <td>open</td>
+  <tr id="2138">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2138">2138</a></td>
+    <td>NAD</td>
     <td>Explicit member specialization vs implicit instantiation</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2139">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2139">2139</a></td>
@@ -12652,14 +12652,14 @@
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2140">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2140">2140</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2140">2140</a></td>
+    <td>DR</td>
     <td>Lvalue-to-rvalue conversion of <TT>std::nullptr_t</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2141">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2141">2141</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2141">2141</a></td>
+    <td>DR</td>
     <td>Ambiguity in <I>new-expression</I> with <I>elaborated-type-specifier</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12671,7 +12671,7 @@
   </tr>
   <tr id="2143">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2143">2143</a></td>
-    <td>tentatively ready</td>
+    <td>ready</td>
     <td>Value-dependency via injected-class-name</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12681,21 +12681,21 @@
     <td>Function/variable declaration ambiguity</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2145">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2145">2145</a></td>
-    <td>drafting</td>
+  <tr id="2145">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2145">2145</a></td>
+    <td>DRWP</td>
     <td>Parenthesized declarator in function definition</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2146">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2146">2146</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2146">2146</a></td>
+    <td>DR</td>
     <td>Scalar object vs memory location in definition of &#8220;unsequenced&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2147">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2147">2147</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2147">2147</a></td>
+    <td>DR</td>
     <td>Initializer-list arguments and pack deduction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12711,11 +12711,11 @@
     <td>Brace elision and array length deduction</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2150">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2150">2150</a></td>
-    <td>review</td>
+  <tr id="2150">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2150">2150</a></td>
+    <td>CD3</td>
     <td>Initializer list array lifetime</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2151">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2151">2151</a></td>
@@ -12730,32 +12730,32 @@
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2153">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2153">2153</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2153">2153</a></td>
+    <td>DR</td>
     <td><I>pure-specifier</I> in friend declaration</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2154">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2154">2154</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2154">2154</a></td>
+    <td>DR</td>
     <td>Ambiguity of <I>pure-specifier</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2155">
+  <tr id="2155">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2155">2155</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Defining classes and enumerations via <I>using-declaration</I>s</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2156">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2156">2156</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2156">2156</a></td>
+    <td>DR</td>
     <td>Definition of enumeration declared by <I>using-declaration</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2157">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2157">2157</a></td>
-    <td>ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2157">2157</a></td>
+    <td>DR</td>
     <td>Further disambiguation of enumeration <I>elaborated-type-specifier</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12784,14 +12784,14 @@
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2162">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2162">2162</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2162">2162</a></td>
+    <td>CD3</td>
     <td>Capturing <TT>this</TT> by reference</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2163">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2163">2163</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2163">2163</a></td>
+    <td>DR</td>
     <td>Labels in <TT>constexpr</TT> functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12814,8 +12814,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2167">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2167">2167</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2167">2167</a></td>
+    <td>DR</td>
     <td>Non-member references with lifetimes within the current evaluation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12826,8 +12826,8 @@
     <td align="center">Not resolved</td>
   </tr>
   <tr class="open" id="2169">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2169">2169</a></td>
-    <td>open</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2169">2169</a></td>
+    <td>extension</td>
     <td>Narrowing conversions and overload resolution</td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12837,11 +12837,11 @@
     <td>Unclear definition of odr-use for arrays</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2171">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2171">2171</a></td>
-    <td>drafting</td>
+  <tr id="2171">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2171">2171</a></td>
+    <td>DRWP</td>
     <td>Triviality of copy constructor with less-qualified parameter</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2172">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2172">2172</a></td>
@@ -12857,19 +12857,19 @@
   </tr>
   <tr class="open" id="2174">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2174">2174</a></td>
-    <td>review</td>
+    <td>drafting</td>
     <td>Unclear rules for friend definitions in templates</td>
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2175">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2175">2175</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2175">2175</a></td>
+    <td>DR</td>
     <td>Ambiguity with attribute in conversion operator declaration</td>
     <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2176">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2176">2176</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2176">2176</a></td>
+    <td>DR</td>
     <td>Destroying the returned object when a destructor throws</td>
     <td class="none" align="center">Unknown</td>
   </tr>
@@ -12879,45 +12879,45 @@
     <td>Placement <TT>operator delete</TT> and parameter copies</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="2178">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2178">2178</a></td>
-    <td>open</td>
+  <tr id="2178">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2178">2178</a></td>
+    <td>NAD</td>
     <td>Substitution of dependent template arguments in default template arguments</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2179">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2179">2179</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Required diagnostic for partial specialization after first use</td>
     <td align="center">Not resolved</td>
   </tr>
   <tr id="2180">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2180">2180</a></td>
-    <td>tentatively ready</td>
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2180">2180</a></td>
+    <td>DR</td>
     <td>Virtual bases in destructors and defaulted assignment operators</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr class="open" id="2181">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2181">2181</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Normative requirements in an informative Annex</td>
     <td align="center">Not resolved</td>
   </tr>
   <tr class="open" id="2182">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2182">2182</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Pointer arithmetic in array-like containers</td>
     <td align="center">Not resolved</td>
   </tr>
   <tr class="open" id="2183">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2183">2183</a></td>
-    <td>open</td>
+    <td>review</td>
     <td>Problems in description of potential exceptions</td>
     <td align="center">Not resolved</td>
   </tr>
   <tr class="open" id="2184">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2184">2184</a></td>
-    <td>open</td>
+    <td>review</td>
     <td>Missing C compatibility entry for decrement of <TT>bool</TT></td>
     <td align="center">Not resolved</td>
   </tr>
@@ -12929,10 +12929,520 @@
   </tr>
   <tr class="open" id="2186">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2186">2186</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Unclear point that &#8220;preceding initialization&#8221; must precede</td>
     <td align="center">Not resolved</td>
   </tr>
+  <tr class="open" id="2187">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2187">2187</a></td>
+    <td>open</td>
+    <td>Protected members and access via <I>qualified-id</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2188">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2188">2188</a></td>
+    <td>open</td>
+    <td><I>empty-declaration</I> ambiguity</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2189">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2189">2189</a></td>
+    <td>open</td>
+    <td>Surrogate call template</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2190">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2190">2190</a></td>
+    <td>open</td>
+    <td>Insufficient specification of <TT>__has_include</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2191">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2191">2191</a></td>
+    <td>open</td>
+    <td>Incorrect result for <TT>noexcept(typeid(v))</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2192">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2192">2192</a></td>
+    <td>open</td>
+    <td>Constant expressions and order-of-eval undefined behavior</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2193">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2193">2193</a></td>
+    <td>open</td>
+    <td><TT>numeric_limits&lt;int&gt;::radix</TT> and <TT>digits</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2194">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2194">2194</a></td>
+    <td>open</td>
+    <td>Impossible case in list initialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2195">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2195">2195</a></td>
+    <td>open</td>
+    <td>Unsolicited reading of trailing volatile members</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2196">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2196">2196</a></td>
+    <td>open</td>
+    <td>Zero-initialization with virtual base classes</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2197">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2197">2197</a></td>
+    <td>open</td>
+    <td>Overload resolution and deleted special member functions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2198">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2198">2198</a></td>
+    <td>open</td>
+    <td>Linkage of enumerators</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2199">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2199">2199</a></td>
+    <td>open</td>
+    <td>Typedefs and tags</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2200">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2200">2200</a></td>
+    <td>open</td>
+    <td>Conversions in template argument deduction</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2201">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2201">2201</a></td>
+    <td>open</td>
+    <td>Cv-qualification of array types</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2202">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2202">2202</a></td>
+    <td>open</td>
+    <td>When does default argument instantiation occur?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2203">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2203">2203</a></td>
+    <td>open</td>
+    <td>Defaulted copy/move constructors and UDCs</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2204">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2204">2204</a></td>
+    <td>open</td>
+    <td>Naming delegated constructors</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2205">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2205">2205</a></td>
+    <td>open</td>
+    <td>Restrictions on use of <TT>alignas</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2206">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2206">2206</a></td>
+    <td>open</td>
+    <td>Composite type of object and function pointers</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2207">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2207">2207</a></td>
+    <td>open</td>
+    <td>Alignment of allocation function return value</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="2208">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2208">2208</a></td>
+    <td>NAD</td>
+    <td><I>static_assert-declaration</I> does not declare a member</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="2209">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2209">2209</a></td>
+    <td>NAD</td>
+    <td>Destruction of constructed array elements</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="2210">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2210">2210</a></td>
+    <td>NAD</td>
+    <td>Principal/target constructor confusion</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="2211">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2211">2211</a></td>
+    <td>open</td>
+    <td>Hiding by lambda captures and parameters</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2212">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2212">2212</a></td>
+    <td>open</td>
+    <td>Typedef changing linkage after use</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2213">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2213">2213</a></td>
+    <td>open</td>
+    <td>Forward declaration of partial specializations</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2214">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2214">2214</a></td>
+    <td>open</td>
+    <td>Missing requirement on representation of integer values</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2215">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2215">2215</a></td>
+    <td>open</td>
+    <td>Redundant description of language linkage in function call</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2216">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2216">2216</a></td>
+    <td>open</td>
+    <td>Exception specifications in unevaluated contexts</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2217">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2217">2217</a></td>
+    <td>open</td>
+    <td><TT>constexpr</TT> constructors for non-literal types</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2218">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2218">2218</a></td>
+    <td>open</td>
+    <td>Ambiguity and namespace aliases</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2219">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2219">2219</a></td>
+    <td>open</td>
+    <td>Dynamically-unreachable handlers</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2220">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2220">2220</a></td>
+    <td>open</td>
+    <td>Hiding index variable in range-based <TT>for</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2221">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2221">2221</a></td>
+    <td>open</td>
+    <td>Copying volatile objects</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2222">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2222">2222</a></td>
+    <td>open</td>
+    <td>Additional contexts where instantiation is not required</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2223">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2223">2223</a></td>
+    <td>open</td>
+    <td>Multiple <TT>alignas</TT> specifiers</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2224">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2224">2224</a></td>
+    <td>open</td>
+    <td>Member subobjects and base-class casts</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2225">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2225">2225</a></td>
+    <td>open</td>
+    <td><TT>reinterpret_cast</TT> to same floating-point type</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2226">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2226">2226</a></td>
+    <td>open</td>
+    <td>Xvalues vs lvalues in conditional expressions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2227">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2227">2227</a></td>
+    <td>open</td>
+    <td>Destructor access and default member initializers</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2228">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2228">2228</a></td>
+    <td>open</td>
+    <td>Ambiguity resolution for cast to function type</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2229">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2229">2229</a></td>
+    <td>open</td>
+    <td>Volatile unnamed bit-fields</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2230">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2230">2230</a></td>
+    <td>open</td>
+    <td>Linkage of <TT>extern "C"</TT> function in unnamed namespace</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2231">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2231">2231</a></td>
+    <td>open</td>
+    <td>Class member access to static data member template</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2232">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2232">2232</a></td>
+    <td>open</td>
+    <td><TT>thread_local</TT> anonymous unions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2233">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2233">2233</a></td>
+    <td>open</td>
+    <td>Function parameter packs following default arguments</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2234">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2234">2234</a></td>
+    <td>open</td>
+    <td>Missing rules for <I>simple-template-id</I> as <I>class-name</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2235">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2235">2235</a></td>
+    <td>open</td>
+    <td>Partial ordering and non-dependent types</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2236">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2236">2236</a></td>
+    <td>open</td>
+    <td>When is an alias template specialization dependent?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2237">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2237">2237</a></td>
+    <td>open</td>
+    <td>Can a <I>template-id</I> name a constructor?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2238">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2238">2238</a></td>
+    <td>open</td>
+    <td>Contradictory alignment requirements for allocation</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2239">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2239">2239</a></td>
+    <td>open</td>
+    <td>Sized deallocation with a trivial destructor</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2240">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2240">2240</a></td>
+    <td>open</td>
+    <td><TT>this</TT> is not odr-used in a constant expression</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2241">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2241">2241</a></td>
+    <td>open</td>
+    <td>Overload resolution is not invoked with a single function</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2242">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2242">2242</a></td>
+    <td>drafting</td>
+    <td>ODR violation with constant initialization possibly omitted</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2243">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2243">2243</a></td>
+    <td>open</td>
+    <td>Incorrect use of implicit conversion sequence</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2244">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2244">2244</a></td>
+    <td>open</td>
+    <td>Base class access in aggregate initialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2245">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2245">2245</a></td>
+    <td>open</td>
+    <td>Point of instantiation of incomplete class template</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2246">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2246">2246</a></td>
+    <td>open</td>
+    <td>Access of indirect virtual base class constructors</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2247">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2247">2247</a></td>
+    <td>open</td>
+    <td>Lambda capture and variable argument list</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2248">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2248">2248</a></td>
+    <td>open</td>
+    <td>Problems with sized delete</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2249">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2249">2249</a></td>
+    <td>open</td>
+    <td><I>identifier</I>s and <I>id-expression</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2250">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2250">2250</a></td>
+    <td>open</td>
+    <td>Implicit instantiation, destruction, and TUs</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2251">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2251">2251</a></td>
+    <td>open</td>
+    <td>Unreachable enumeration list-initialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2252">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2252">2252</a></td>
+    <td>open</td>
+    <td>Enumeration list-initialization from the same type</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2253">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2253">2253</a></td>
+    <td>open</td>
+    <td>Unnamed bit-fields and zero-initialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2254">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2254">2254</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="2255">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2255">2255</a></td>
+    <td>open</td>
+    <td>Instantiated static data member templates</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2256">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2256">2256</a></td>
+    <td>open</td>
+    <td>Lifetime of trivially-destructible objects</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2257">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2257">2257</a></td>
+    <td>open</td>
+    <td>Lifetime extension of references vs exceptions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2258">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2258">2258</a></td>
+    <td>open</td>
+    <td>Storage deallocation during period of destruction</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2259">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2259">2259</a></td>
+    <td>open</td>
+    <td>Unclear context describing ambiguity</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2260">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2260">2260</a></td>
+    <td>open</td>
+    <td>Explicit specializations of deleted member functions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2261">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2261">2261</a></td>
+    <td>open</td>
+    <td>Explicit instantiation of in-class <TT>friend</TT> definition</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2262">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2262">2262</a></td>
+    <td>open</td>
+    <td>Attributes for <I>asm-definition</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2263">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2263">2263</a></td>
+    <td>open</td>
+    <td>Default argument instantiation for <TT>friend</TT>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2264">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2264">2264</a></td>
+    <td>open</td>
+    <td>Memberwise copying with indeterminate value</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2265">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2265">2265</a></td>
+    <td>open</td>
+    <td>Delayed pack expansion and member redeclarations</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2266">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2266">2266</a></td>
+    <td>open</td>
+    <td>Has dependent type vs is type-dependent</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2267">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2267">2267</a></td>
+    <td>open</td>
+    <td>Copy-initialization of temporary in reference direct-initialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2268">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2268">2268</a></td>
+    <td>open</td>
+    <td>Unions with mutable members in constant expressions revisited</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2269">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2269">2269</a></td>
+    <td>open</td>
+    <td>Additional recursive references in aggregate DMIs</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="2270">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2270">2270</a></td>
+    <td>open</td>
+    <td>Non-inline functions and explicit instantiation declarations</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="2271">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2271">2271</a></td>
+    <td>ready</td>
+    <td>Aliasing <TT>this</TT></td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
 </table>
 
 </div>
diff --git a/www/cxx_status.html b/www/cxx_status.html
index 9e6b675..736a085 100644
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -612,7 +612,7 @@
     <tr>
       <td>Make exception specifications part of the type system</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html">P0012R1</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="svn" align="center">Clang 4</td>
     </tr>
     <tr>
       <td><tt>__has_include</tt> in preprocessor conditionals</td>
@@ -648,7 +648,7 @@
     <tr>
       <td><tt>constexpr</tt> lambda expressions</td>
       <td><a href="http://wg21.link/p0170r1">P0170R1</a></td>
-      <td class="none" align="center">No</td>
+      <td class="svn" align="center">SVN</td>
     </tr>
     <tr>
       <td>Differing <tt>begin</tt> and <tt>end</tt> types in range-based <tt>for</tt></td>
@@ -679,27 +679,30 @@
     <tr>
       <td>Dynamic memory allocation for over-aligned data</td>
       <td><a href="http://wg21.link/p0035r4">P0035R4</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="svn" align="center">Clang 4</td>
     </tr>
     <tr>
-      <td>Template argument deduction for class templates</td>
+      <td rowspan="2">Template argument deduction for class templates</td>
       <td><a href="http://wg21.link/p0091r3">P0091R3</a></td>
-      <td class="none" align="center">No</td>
+      <td rowspan="2" class="svn" align="center">SVN</td>
     </tr>
+      <tr> <!-- from Issaquah -->
+        <td><a href="http://wg21.link/p0512r0">P0512R0</a></td>
+      </tr>
     <tr>
       <td>Non-type template parameters with <tt>auto</tt> type</td>
       <td><a href="http://wg21.link/p0127r2">P0127R2</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="svn" align="center">Clang 4</td>
     </tr>
     <tr>
       <td>Guaranteed copy elision</td>
       <td><a href="http://wg21.link/p0135r1">P0135R1</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="svn" align="center">Clang 4</td>
     </tr>
     <tr>
       <td rowspan=2>Stricter expression evaluation order</td>
       <td><a href="http://wg21.link/p0145r3">P0145R3</a></td>
-      <td class="svn" align="center" rowspan=2>SVN <a href="#p0145">(10)</a></td>
+      <td class="svn" align="center" rowspan=2>Clang 4 <a href="#p0145">(10)</a></td>
     </tr>
     <tr>
       <td><a href="http://wg21.link/p0400r0">P0400R0</a></td>
@@ -722,9 +725,7 @@
     <tr>
       <td>Structured bindings</td>
       <td><a href="http://wg21.link/p0217r3">P0217R3</a></td>
-      <td class="partial" align="center">Partial</td>
-      <!-- We don't implement structured bindings of arrays yet, anticipating
-           this being removed from the working draft -->
+      <td class="svn" align="center">Clang 4</td>
     </tr>
     <tr>
       <td>Separate variable and condition for <tt>if</tt> and <tt>switch</tt></td>
@@ -735,17 +736,17 @@
     <tr>
       <td>Matching template template parameters to compatible arguments</td>
       <td><a href="http://wg21.link/p0522r0">P0522R0</a></td>
-      <td class="none" align="center">No <a href="#p0522">(12)</a></td>
+      <td class="partial" align="center">Partial <a href="#p0522">(12)</a></td>
     </tr>
     <tr>
       <td>Removing deprecated dynamic exception specifications</td>
       <td><a href="http://wg21.link/p0003r5">P0003R5</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="svn" align="center">Clang 4</td>
     </tr>
     <tr>
       <td>Pack expansions in <em>using-declarations</em></td>
       <td><a href="http://wg21.link/p0195r2">P0195R2</a></td>
-      <td class="none" align="center">No</td>
+      <td class="svn" align="center">Clang 4</td>
     </tr>
 </table>
 
@@ -765,8 +766,12 @@
 functions using expression syntax are no longer guaranteed to be destroyed in
 reverse construction order in that ABI.
 </span><br>
-<span id="p0522">(12): This is the resolution to a Defect Report, so will be
-applied to all language versions.
+<span id="p0522">(12): Despite being the the resolution to a Defect Report, this
+feature is disabled by default in all language versions, and can be enabled
+explicitly with the flag <tt>-frelaxed-template-template-args</tt> in Clang 4.
+The change to the standard lacks a corresponding change for template partial
+ordering, resulting in ambiguity errors for reasonable and previously-valid
+code. This issue is expected to be rectified soon.
 </span>
 </p>
 </details>
@@ -800,8 +805,8 @@
       </td>
     </tr>
     <tr>
-      <td class="svn" align="center">
-        SVN (<a href="http://wg21.link/p0096r3">P0096R3</a>)</a>
+      <td class="full" align="center">
+        Clang 4 (<a href="http://wg21.link/p0096r3">P0096R3</a>)</a>
       </td>
     </tr>
     <!-- FIXME: Implement latest recommendations.
diff --git a/www/index.html b/www/index.html
index 62354fe..9a40501 100644
--- a/www/index.html
+++ b/www/index.html
@@ -15,10 +15,10 @@
   <h1>clang: a C language family frontend for LLVM</h1>
   <!--*********************************************************************-->
   
-  <p>The goal of the Clang project is to create a new C, C++, Objective C and
-  Objective C++ front-end for the <a href="http://www.llvm.org/">LLVM</a>
-  compiler.  You can <a href="get_started.html">get and build</a> the source
-  today.</p>
+  <p>The goal of the Clang project is to create a new C based language
+  front-end: C, C++, Objective C/C++, OpenCL C and others for the
+  <a href="http://www.llvm.org/">LLVM</a> compiler.  You can
+  <a href="get_started.html">get and build</a> the source  today.</p>
   
   <!--=====================================================================-->
   <h2 id="goals">Features and Goals</h2>
diff --git a/www/make_cxx_dr_status b/www/make_cxx_dr_status
index 3f37217..8a05d41 100755
--- a/www/make_cxx_dr_status
+++ b/www/make_cxx_dr_status
@@ -108,10 +108,13 @@
   if status == 'unknown':
     avail = 'Unknown'
     avail_style = ' class="none"'
-  elif status == '4.0':
+  elif status == '5':
     avail = 'SVN'
     avail_style = ' class="svn"'
-  elif re.match('^[0-9]+\.', status):
+  elif status == '4':
+    avail = 'Clang 4'
+    avail_style = ' class="svn"'
+  elif re.match('^[0-9]+\.?[0-9]*', status):
     avail = 'Clang %s' % status
     avail_style = ' class="full"'
   elif status == 'yes':
@@ -126,6 +129,9 @@
   elif status == 'na':
     avail = 'N/A'
     avail_style = ' class="na"'
+  elif status == 'na lib':
+    avail = 'N/A (Library DR)'
+    avail_style = ' class="na"'
   elif status.startswith('sup '):
     dup = status.split(' ', 1)[1]
     avail = 'Superseded by <a href="#%s">%s</a>' % (dup, dup)